@arela/uploader 1.0.2 → 1.0.4

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 (61) hide show
  1. package/.env.local +316 -0
  2. package/.env.template +70 -0
  3. package/coverage/IdentifyCommand.js.html +1462 -0
  4. package/coverage/PropagateCommand.js.html +1507 -0
  5. package/coverage/PushCommand.js.html +1504 -0
  6. package/coverage/ScanCommand.js.html +1654 -0
  7. package/coverage/UploadCommand.js.html +1846 -0
  8. package/coverage/WatchCommand.js.html +4111 -0
  9. package/coverage/base.css +224 -0
  10. package/coverage/block-navigation.js +87 -0
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +191 -0
  13. package/coverage/lcov-report/IdentifyCommand.js.html +1462 -0
  14. package/coverage/lcov-report/PropagateCommand.js.html +1507 -0
  15. package/coverage/lcov-report/PushCommand.js.html +1504 -0
  16. package/coverage/lcov-report/ScanCommand.js.html +1654 -0
  17. package/coverage/lcov-report/UploadCommand.js.html +1846 -0
  18. package/coverage/lcov-report/WatchCommand.js.html +4111 -0
  19. package/coverage/lcov-report/base.css +224 -0
  20. package/coverage/lcov-report/block-navigation.js +87 -0
  21. package/coverage/lcov-report/favicon.png +0 -0
  22. package/coverage/lcov-report/index.html +191 -0
  23. package/coverage/lcov-report/prettify.css +1 -0
  24. package/coverage/lcov-report/prettify.js +2 -0
  25. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  26. package/coverage/lcov-report/sorter.js +210 -0
  27. package/coverage/lcov.info +1937 -0
  28. package/coverage/prettify.css +1 -0
  29. package/coverage/prettify.js +2 -0
  30. package/coverage/sort-arrow-sprite.png +0 -0
  31. package/coverage/sorter.js +210 -0
  32. package/docs/API_RETRY_MECHANISM.md +338 -0
  33. package/docs/ARELA_IDENTIFY_IMPLEMENTATION.md +489 -0
  34. package/docs/ARELA_IDENTIFY_QUICKREF.md +186 -0
  35. package/docs/ARELA_PROPAGATE_IMPLEMENTATION.md +581 -0
  36. package/docs/ARELA_PROPAGATE_QUICKREF.md +272 -0
  37. package/docs/ARELA_PUSH_IMPLEMENTATION.md +577 -0
  38. package/docs/ARELA_PUSH_QUICKREF.md +322 -0
  39. package/docs/ARELA_SCAN_IMPLEMENTATION.md +373 -0
  40. package/docs/ARELA_SCAN_QUICKREF.md +139 -0
  41. package/docs/CROSS_PLATFORM_PATH_HANDLING.md +593 -0
  42. package/docs/DETECTION_ATTEMPT_TRACKING.md +414 -0
  43. package/docs/MIGRATION_UPLOADER_TO_FILE_STATS.md +1020 -0
  44. package/docs/MULTI_LEVEL_DIRECTORY_SCANNING.md +494 -0
  45. package/docs/STATS_COMMAND_SEQUENCE_DIAGRAM.md +287 -0
  46. package/docs/STATS_COMMAND_SIMPLE.md +93 -0
  47. package/package.json +31 -3
  48. package/src/commands/IdentifyCommand.js +459 -0
  49. package/src/commands/PropagateCommand.js +474 -0
  50. package/src/commands/PushCommand.js +473 -0
  51. package/src/commands/ScanCommand.js +523 -0
  52. package/src/config/config.js +154 -7
  53. package/src/file-detection.js +9 -10
  54. package/src/index.js +150 -0
  55. package/src/services/ScanApiService.js +645 -0
  56. package/src/utils/PathNormalizer.js +220 -0
  57. package/tests/commands/IdentifyCommand.test.js +570 -0
  58. package/tests/commands/PropagateCommand.test.js +568 -0
  59. package/tests/commands/PushCommand.test.js +754 -0
  60. package/tests/commands/ScanCommand.test.js +382 -0
  61. package/tests/unit/PathAndTableNameGeneration.test.js +1211 -0
@@ -0,0 +1,1654 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for ScanCommand.js</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> ScanCommand.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">91.66% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>165/180</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">73.77% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>45/61</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>4/4</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">91.62% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>164/179</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a>
535
+ <a name='L470'></a><a href='#L470'>470</a>
536
+ <a name='L471'></a><a href='#L471'>471</a>
537
+ <a name='L472'></a><a href='#L472'>472</a>
538
+ <a name='L473'></a><a href='#L473'>473</a>
539
+ <a name='L474'></a><a href='#L474'>474</a>
540
+ <a name='L475'></a><a href='#L475'>475</a>
541
+ <a name='L476'></a><a href='#L476'>476</a>
542
+ <a name='L477'></a><a href='#L477'>477</a>
543
+ <a name='L478'></a><a href='#L478'>478</a>
544
+ <a name='L479'></a><a href='#L479'>479</a>
545
+ <a name='L480'></a><a href='#L480'>480</a>
546
+ <a name='L481'></a><a href='#L481'>481</a>
547
+ <a name='L482'></a><a href='#L482'>482</a>
548
+ <a name='L483'></a><a href='#L483'>483</a>
549
+ <a name='L484'></a><a href='#L484'>484</a>
550
+ <a name='L485'></a><a href='#L485'>485</a>
551
+ <a name='L486'></a><a href='#L486'>486</a>
552
+ <a name='L487'></a><a href='#L487'>487</a>
553
+ <a name='L488'></a><a href='#L488'>488</a>
554
+ <a name='L489'></a><a href='#L489'>489</a>
555
+ <a name='L490'></a><a href='#L490'>490</a>
556
+ <a name='L491'></a><a href='#L491'>491</a>
557
+ <a name='L492'></a><a href='#L492'>492</a>
558
+ <a name='L493'></a><a href='#L493'>493</a>
559
+ <a name='L494'></a><a href='#L494'>494</a>
560
+ <a name='L495'></a><a href='#L495'>495</a>
561
+ <a name='L496'></a><a href='#L496'>496</a>
562
+ <a name='L497'></a><a href='#L497'>497</a>
563
+ <a name='L498'></a><a href='#L498'>498</a>
564
+ <a name='L499'></a><a href='#L499'>499</a>
565
+ <a name='L500'></a><a href='#L500'>500</a>
566
+ <a name='L501'></a><a href='#L501'>501</a>
567
+ <a name='L502'></a><a href='#L502'>502</a>
568
+ <a name='L503'></a><a href='#L503'>503</a>
569
+ <a name='L504'></a><a href='#L504'>504</a>
570
+ <a name='L505'></a><a href='#L505'>505</a>
571
+ <a name='L506'></a><a href='#L506'>506</a>
572
+ <a name='L507'></a><a href='#L507'>507</a>
573
+ <a name='L508'></a><a href='#L508'>508</a>
574
+ <a name='L509'></a><a href='#L509'>509</a>
575
+ <a name='L510'></a><a href='#L510'>510</a>
576
+ <a name='L511'></a><a href='#L511'>511</a>
577
+ <a name='L512'></a><a href='#L512'>512</a>
578
+ <a name='L513'></a><a href='#L513'>513</a>
579
+ <a name='L514'></a><a href='#L514'>514</a>
580
+ <a name='L515'></a><a href='#L515'>515</a>
581
+ <a name='L516'></a><a href='#L516'>516</a>
582
+ <a name='L517'></a><a href='#L517'>517</a>
583
+ <a name='L518'></a><a href='#L518'>518</a>
584
+ <a name='L519'></a><a href='#L519'>519</a>
585
+ <a name='L520'></a><a href='#L520'>520</a>
586
+ <a name='L521'></a><a href='#L521'>521</a>
587
+ <a name='L522'></a><a href='#L522'>522</a>
588
+ <a name='L523'></a><a href='#L523'>523</a>
589
+ <a name='L524'></a><a href='#L524'>524</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span>
591
+ <span class="cline-any cline-neutral">&nbsp;</span>
592
+ <span class="cline-any cline-neutral">&nbsp;</span>
593
+ <span class="cline-any cline-neutral">&nbsp;</span>
594
+ <span class="cline-any cline-neutral">&nbsp;</span>
595
+ <span class="cline-any cline-neutral">&nbsp;</span>
596
+ <span class="cline-any cline-neutral">&nbsp;</span>
597
+ <span class="cline-any cline-neutral">&nbsp;</span>
598
+ <span class="cline-any cline-neutral">&nbsp;</span>
599
+ <span class="cline-any cline-neutral">&nbsp;</span>
600
+ <span class="cline-any cline-neutral">&nbsp;</span>
601
+ <span class="cline-any cline-neutral">&nbsp;</span>
602
+ <span class="cline-any cline-neutral">&nbsp;</span>
603
+ <span class="cline-any cline-neutral">&nbsp;</span>
604
+ <span class="cline-any cline-neutral">&nbsp;</span>
605
+ <span class="cline-any cline-neutral">&nbsp;</span>
606
+ <span class="cline-any cline-neutral">&nbsp;</span>
607
+ <span class="cline-any cline-neutral">&nbsp;</span>
608
+ <span class="cline-any cline-neutral">&nbsp;</span>
609
+ <span class="cline-any cline-yes">25x</span>
610
+ <span class="cline-any cline-yes">25x</span>
611
+ <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-neutral">&nbsp;</span>
613
+ <span class="cline-any cline-neutral">&nbsp;</span>
614
+ <span class="cline-any cline-neutral">&nbsp;</span>
615
+ <span class="cline-any cline-neutral">&nbsp;</span>
616
+ <span class="cline-any cline-neutral">&nbsp;</span>
617
+ <span class="cline-any cline-neutral">&nbsp;</span>
618
+ <span class="cline-any cline-neutral">&nbsp;</span>
619
+ <span class="cline-any cline-yes">19x</span>
620
+ <span class="cline-any cline-neutral">&nbsp;</span>
621
+ <span class="cline-any cline-yes">19x</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-yes">19x</span>
624
+ <span class="cline-any cline-neutral">&nbsp;</span>
625
+ <span class="cline-any cline-neutral">&nbsp;</span>
626
+ <span class="cline-any cline-yes">17x</span>
627
+ <span class="cline-any cline-neutral">&nbsp;</span>
628
+ <span class="cline-any cline-neutral">&nbsp;</span>
629
+ <span class="cline-any cline-yes">17x</span>
630
+ <span class="cline-any cline-neutral">&nbsp;</span>
631
+ <span class="cline-any cline-yes">17x</span>
632
+ <span class="cline-any cline-neutral">&nbsp;</span>
633
+ <span class="cline-any cline-yes">17x</span>
634
+ <span class="cline-any cline-neutral">&nbsp;</span>
635
+ <span class="cline-any cline-yes">17x</span>
636
+ <span class="cline-any cline-yes">17x</span>
637
+ <span class="cline-any cline-yes">17x</span>
638
+ <span class="cline-any cline-yes">17x</span>
639
+ <span class="cline-any cline-yes">17x</span>
640
+ <span class="cline-any cline-neutral">&nbsp;</span>
641
+ <span class="cline-any cline-neutral">&nbsp;</span>
642
+ <span class="cline-any cline-yes">17x</span>
643
+ <span class="cline-any cline-yes">17x</span>
644
+ <span class="cline-any cline-neutral">&nbsp;</span>
645
+ <span class="cline-any cline-neutral">&nbsp;</span>
646
+ <span class="cline-any cline-neutral">&nbsp;</span>
647
+ <span class="cline-any cline-yes">17x</span>
648
+ <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-neutral">&nbsp;</span>
650
+ <span class="cline-any cline-neutral">&nbsp;</span>
651
+ <span class="cline-any cline-neutral">&nbsp;</span>
652
+ <span class="cline-any cline-yes">17x</span>
653
+ <span class="cline-any cline-yes">17x</span>
654
+ <span class="cline-any cline-yes">17x</span>
655
+ <span class="cline-any cline-neutral">&nbsp;</span>
656
+ <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-yes">22x</span>
658
+ <span class="cline-any cline-neutral">&nbsp;</span>
659
+ <span class="cline-any cline-yes">22x</span>
660
+ <span class="cline-any cline-neutral">&nbsp;</span>
661
+ <span class="cline-any cline-neutral">&nbsp;</span>
662
+ <span class="cline-any cline-neutral">&nbsp;</span>
663
+ <span class="cline-any cline-neutral">&nbsp;</span>
664
+ <span class="cline-any cline-neutral">&nbsp;</span>
665
+ <span class="cline-any cline-yes">21x</span>
666
+ <span class="cline-any cline-neutral">&nbsp;</span>
667
+ <span class="cline-any cline-yes">21x</span>
668
+ <span class="cline-any cline-no">&nbsp;</span>
669
+ <span class="cline-any cline-neutral">&nbsp;</span>
670
+ <span class="cline-any cline-yes">21x</span>
671
+ <span class="cline-any cline-neutral">&nbsp;</span>
672
+ <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-neutral">&nbsp;</span>
674
+ <span class="cline-any cline-neutral">&nbsp;</span>
675
+ <span class="cline-any cline-neutral">&nbsp;</span>
676
+ <span class="cline-any cline-neutral">&nbsp;</span>
677
+ <span class="cline-any cline-yes">16x</span>
678
+ <span class="cline-any cline-yes">16x</span>
679
+ <span class="cline-any cline-yes">1x</span>
680
+ <span class="cline-any cline-yes">1x</span>
681
+ <span class="cline-any cline-yes">1x</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-yes">16x</span>
686
+ <span class="cline-any cline-yes">16x</span>
687
+ <span class="cline-any cline-neutral">&nbsp;</span>
688
+ <span class="cline-any cline-neutral">&nbsp;</span>
689
+ <span class="cline-any cline-neutral">&nbsp;</span>
690
+ <span class="cline-any cline-neutral">&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-yes">16x</span>
694
+ <span class="cline-any cline-yes">21x</span>
695
+ <span class="cline-any cline-yes">21x</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-neutral">&nbsp;</span>
698
+ <span class="cline-any cline-neutral">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-neutral">&nbsp;</span>
701
+ <span class="cline-any cline-neutral">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-yes">21x</span>
704
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span>
709
+ <span class="cline-any cline-yes">21x</span>
710
+ <span class="cline-any cline-yes">21x</span>
711
+ <span class="cline-any cline-yes">21x</span>
712
+ <span class="cline-any cline-yes">21x</span>
713
+ <span class="cline-any cline-neutral">&nbsp;</span>
714
+ <span class="cline-any cline-neutral">&nbsp;</span>
715
+ <span class="cline-any cline-yes">16x</span>
716
+ <span class="cline-any cline-yes">16x</span>
717
+ <span class="cline-any cline-neutral">&nbsp;</span>
718
+ <span class="cline-any cline-yes">16x</span>
719
+ <span class="cline-any cline-yes">16x</span>
720
+ <span class="cline-any cline-yes">16x</span>
721
+ <span class="cline-any cline-yes">16x</span>
722
+ <span class="cline-any cline-neutral">&nbsp;</span>
723
+ <span class="cline-any cline-neutral">&nbsp;</span>
724
+ <span class="cline-any cline-yes">16x</span>
725
+ <span class="cline-any cline-neutral">&nbsp;</span>
726
+ <span class="cline-any cline-neutral">&nbsp;</span>
727
+ <span class="cline-any cline-yes">16x</span>
728
+ <span class="cline-any cline-neutral">&nbsp;</span>
729
+ <span class="cline-any cline-neutral">&nbsp;</span>
730
+ <span class="cline-any cline-yes">16x</span>
731
+ <span class="cline-any cline-yes">16x</span>
732
+ <span class="cline-any cline-yes">16x</span>
733
+ <span class="cline-any cline-yes">16x</span>
734
+ <span class="cline-any cline-yes">16x</span>
735
+ <span class="cline-any cline-yes">21x</span>
736
+ <span class="cline-any cline-neutral">&nbsp;</span>
737
+ <span class="cline-any cline-neutral">&nbsp;</span>
738
+ <span class="cline-any cline-yes">16x</span>
739
+ <span class="cline-any cline-neutral">&nbsp;</span>
740
+ <span class="cline-any cline-yes">21x</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-neutral">&nbsp;</span>
743
+ <span class="cline-any cline-neutral">&nbsp;</span>
744
+ <span class="cline-any cline-yes">3x</span>
745
+ <span class="cline-any cline-yes">3x</span>
746
+ <span class="cline-any cline-neutral">&nbsp;</span>
747
+ <span class="cline-any cline-neutral">&nbsp;</span>
748
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
752
+ <span class="cline-any cline-neutral">&nbsp;</span>
753
+ <span class="cline-any cline-neutral">&nbsp;</span>
754
+ <span class="cline-any cline-neutral">&nbsp;</span>
755
+ <span class="cline-any cline-neutral">&nbsp;</span>
756
+ <span class="cline-any cline-neutral">&nbsp;</span>
757
+ <span class="cline-any cline-neutral">&nbsp;</span>
758
+ <span class="cline-any cline-neutral">&nbsp;</span>
759
+ <span class="cline-any cline-neutral">&nbsp;</span>
760
+ <span class="cline-any cline-neutral">&nbsp;</span>
761
+ <span class="cline-any cline-neutral">&nbsp;</span>
762
+ <span class="cline-any cline-neutral">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-yes">17x</span>
765
+ <span class="cline-any cline-yes">17x</span>
766
+ <span class="cline-any cline-neutral">&nbsp;</span>
767
+ <span class="cline-any cline-yes">17x</span>
768
+ <span class="cline-any cline-neutral">&nbsp;</span>
769
+ <span class="cline-any cline-yes">15x</span>
770
+ <span class="cline-any cline-neutral">&nbsp;</span>
771
+ <span class="cline-any cline-yes">18x</span>
772
+ <span class="cline-any cline-neutral">&nbsp;</span>
773
+ <span class="cline-any cline-yes">18x</span>
774
+ <span class="cline-any cline-yes">18x</span>
775
+ <span class="cline-any cline-neutral">&nbsp;</span>
776
+ <span class="cline-any cline-neutral">&nbsp;</span>
777
+ <span class="cline-any cline-neutral">&nbsp;</span>
778
+ <span class="cline-any cline-neutral">&nbsp;</span>
779
+ <span class="cline-any cline-yes">2x</span>
780
+ <span class="cline-any cline-yes">2x</span>
781
+ <span class="cline-any cline-neutral">&nbsp;</span>
782
+ <span class="cline-any cline-yes">2x</span>
783
+ <span class="cline-any cline-yes">2x</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-neutral">&nbsp;</span>
786
+ <span class="cline-any cline-yes">2x</span>
787
+ <span class="cline-any cline-neutral">&nbsp;</span>
788
+ <span class="cline-any cline-neutral">&nbsp;</span>
789
+ <span class="cline-any cline-yes">2x</span>
790
+ <span class="cline-any cline-yes">3x</span>
791
+ <span class="cline-any cline-yes">4x</span>
792
+ <span class="cline-any cline-neutral">&nbsp;</span>
793
+ <span class="cline-any cline-yes">2x</span>
794
+ <span class="cline-any cline-neutral">&nbsp;</span>
795
+ <span class="cline-any cline-neutral">&nbsp;</span>
796
+ <span class="cline-any cline-yes">2x</span>
797
+ <span class="cline-any cline-neutral">&nbsp;</span>
798
+ <span class="cline-any cline-neutral">&nbsp;</span>
799
+ <span class="cline-any cline-yes">2x</span>
800
+ <span class="cline-any cline-yes">2x</span>
801
+ <span class="cline-any cline-yes">2x</span>
802
+ <span class="cline-any cline-neutral">&nbsp;</span>
803
+ <span class="cline-any cline-yes">2x</span>
804
+ <span class="cline-any cline-neutral">&nbsp;</span>
805
+ <span class="cline-any cline-neutral">&nbsp;</span>
806
+ <span class="cline-any cline-yes">2x</span>
807
+ <span class="cline-any cline-neutral">&nbsp;</span>
808
+ <span class="cline-any cline-neutral">&nbsp;</span>
809
+ <span class="cline-any cline-neutral">&nbsp;</span>
810
+ <span class="cline-any cline-neutral">&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-neutral">&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-neutral">&nbsp;</span>
817
+ <span class="cline-any cline-neutral">&nbsp;</span>
818
+ <span class="cline-any cline-neutral">&nbsp;</span>
819
+ <span class="cline-any cline-neutral">&nbsp;</span>
820
+ <span class="cline-any cline-no">&nbsp;</span>
821
+ <span class="cline-any cline-neutral">&nbsp;</span>
822
+ <span class="cline-any cline-neutral">&nbsp;</span>
823
+ <span class="cline-any cline-yes">2x</span>
824
+ <span class="cline-any cline-neutral">&nbsp;</span>
825
+ <span class="cline-any cline-neutral">&nbsp;</span>
826
+ <span class="cline-any cline-neutral">&nbsp;</span>
827
+ <span class="cline-any cline-neutral">&nbsp;</span>
828
+ <span class="cline-any cline-neutral">&nbsp;</span>
829
+ <span class="cline-any cline-neutral">&nbsp;</span>
830
+ <span class="cline-any cline-neutral">&nbsp;</span>
831
+ <span class="cline-any cline-neutral">&nbsp;</span>
832
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
836
+ <span class="cline-any cline-yes">5x</span>
837
+ <span class="cline-any cline-yes">5x</span>
838
+ <span class="cline-any cline-neutral">&nbsp;</span>
839
+ <span class="cline-any cline-yes">5x</span>
840
+ <span class="cline-any cline-neutral">&nbsp;</span>
841
+ <span class="cline-any cline-yes">3x</span>
842
+ <span class="cline-any cline-yes">3x</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-yes">2x</span>
846
+ <span class="cline-any cline-yes">2x</span>
847
+ <span class="cline-any cline-neutral">&nbsp;</span>
848
+ <span class="cline-any cline-yes">2x</span>
849
+ <span class="cline-any cline-yes">4x</span>
850
+ <span class="cline-any cline-yes">3x</span>
851
+ <span class="cline-any cline-yes">3x</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-yes">3x</span>
858
+ <span class="cline-any cline-neutral">&nbsp;</span>
859
+ <span class="cline-any cline-neutral">&nbsp;</span>
860
+ <span class="cline-any cline-neutral">&nbsp;</span>
861
+ <span class="cline-any cline-yes">2x</span>
862
+ <span class="cline-any cline-neutral">&nbsp;</span>
863
+ <span class="cline-any cline-neutral">&nbsp;</span>
864
+ <span class="cline-any cline-neutral">&nbsp;</span>
865
+ <span class="cline-any cline-neutral">&nbsp;</span>
866
+ <span class="cline-any cline-neutral">&nbsp;</span>
867
+ <span class="cline-any cline-neutral">&nbsp;</span>
868
+ <span class="cline-any cline-neutral">&nbsp;</span>
869
+ <span class="cline-any cline-yes">1x</span>
870
+ <span class="cline-any cline-yes">1x</span>
871
+ <span class="cline-any cline-neutral">&nbsp;</span>
872
+ <span class="cline-any cline-yes">1x</span>
873
+ <span class="cline-any cline-yes">1x</span>
874
+ <span class="cline-any cline-yes">1x</span>
875
+ <span class="cline-any cline-neutral">&nbsp;</span>
876
+ <span class="cline-any cline-neutral">&nbsp;</span>
877
+ <span class="cline-any cline-neutral">&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-yes">1x</span>
881
+ <span class="cline-any cline-no">&nbsp;</span>
882
+ <span class="cline-any cline-no">&nbsp;</span>
883
+ <span class="cline-any cline-neutral">&nbsp;</span>
884
+ <span class="cline-any cline-neutral">&nbsp;</span>
885
+ <span class="cline-any cline-neutral">&nbsp;</span>
886
+ <span class="cline-any cline-neutral">&nbsp;</span>
887
+ <span class="cline-any cline-yes">1x</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-neutral">&nbsp;</span>
891
+ <span class="cline-any cline-neutral">&nbsp;</span>
892
+ <span class="cline-any cline-neutral">&nbsp;</span>
893
+ <span class="cline-any cline-neutral">&nbsp;</span>
894
+ <span class="cline-any cline-neutral">&nbsp;</span>
895
+ <span class="cline-any cline-neutral">&nbsp;</span>
896
+ <span class="cline-any cline-neutral">&nbsp;</span>
897
+ <span class="cline-any cline-neutral">&nbsp;</span>
898
+ <span class="cline-any cline-neutral">&nbsp;</span>
899
+ <span class="cline-any cline-neutral">&nbsp;</span>
900
+ <span class="cline-any cline-neutral">&nbsp;</span>
901
+ <span class="cline-any cline-yes">21x</span>
902
+ <span class="cline-any cline-yes">21x</span>
903
+ <span class="cline-any cline-neutral">&nbsp;</span>
904
+ <span class="cline-any cline-yes">21x</span>
905
+ <span class="cline-any cline-yes">21x</span>
906
+ <span class="cline-any cline-yes">21x</span>
907
+ <span class="cline-any cline-yes">21x</span>
908
+ <span class="cline-any cline-yes">21x</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-yes">21x</span>
912
+ <span class="cline-any cline-neutral">&nbsp;</span>
913
+ <span class="cline-any cline-yes">21x</span>
914
+ <span class="cline-any cline-neutral">&nbsp;</span>
915
+ <span class="cline-any cline-yes">21x</span>
916
+ <span class="cline-any cline-neutral">&nbsp;</span>
917
+ <span class="cline-any cline-neutral">&nbsp;</span>
918
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
922
+ <span class="cline-any cline-neutral">&nbsp;</span>
923
+ <span class="cline-any cline-yes">21x</span>
924
+ <span class="cline-any cline-neutral">&nbsp;</span>
925
+ <span class="cline-any cline-yes">9x</span>
926
+ <span class="cline-any cline-yes">9x</span>
927
+ <span class="cline-any cline-neutral">&nbsp;</span>
928
+ <span class="cline-any cline-neutral">&nbsp;</span>
929
+ <span class="cline-any cline-yes">9x</span>
930
+ <span class="cline-any cline-yes">1x</span>
931
+ <span class="cline-any cline-yes">1x</span>
932
+ <span class="cline-any cline-neutral">&nbsp;</span>
933
+ <span class="cline-any cline-neutral">&nbsp;</span>
934
+ <span class="cline-any cline-neutral">&nbsp;</span>
935
+ <span class="cline-any cline-yes">8x</span>
936
+ <span class="cline-any cline-yes">8x</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-neutral">&nbsp;</span>
941
+ <span class="cline-any cline-neutral">&nbsp;</span>
942
+ <span class="cline-any cline-neutral">&nbsp;</span>
943
+ <span class="cline-any cline-yes">8x</span>
944
+ <span class="cline-any cline-neutral">&nbsp;</span>
945
+ <span class="cline-any cline-neutral">&nbsp;</span>
946
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
950
+ <span class="cline-any cline-yes">8x</span>
951
+ <span class="cline-any cline-yes">8x</span>
952
+ <span class="cline-any cline-yes">8x</span>
953
+ <span class="cline-any cline-neutral">&nbsp;</span>
954
+ <span class="cline-any cline-neutral">&nbsp;</span>
955
+ <span class="cline-any cline-yes">8x</span>
956
+ <span class="cline-any cline-no">&nbsp;</span>
957
+ <span class="cline-any cline-neutral">&nbsp;</span>
958
+ <span class="cline-any cline-neutral">&nbsp;</span>
959
+ <span class="cline-any cline-yes">8x</span>
960
+ <span class="cline-any cline-yes">8x</span>
961
+ <span class="cline-any cline-yes">8x</span>
962
+ <span class="cline-any cline-neutral">&nbsp;</span>
963
+ <span class="cline-any cline-neutral">&nbsp;</span>
964
+ <span class="cline-any cline-neutral">&nbsp;</span>
965
+ <span class="cline-any cline-yes">8x</span>
966
+ <span class="cline-any cline-yes">2x</span>
967
+ <span class="cline-any cline-yes">2x</span>
968
+ <span class="cline-any cline-yes">2x</span>
969
+ <span class="cline-any cline-neutral">&nbsp;</span>
970
+ <span class="cline-any cline-neutral">&nbsp;</span>
971
+ <span class="cline-any cline-neutral">&nbsp;</span>
972
+ <span class="cline-any cline-no">&nbsp;</span>
973
+ <span class="cline-any cline-neutral">&nbsp;</span>
974
+ <span class="cline-any cline-neutral">&nbsp;</span>
975
+ <span class="cline-any cline-neutral">&nbsp;</span>
976
+ <span class="cline-any cline-yes">21x</span>
977
+ <span class="cline-any cline-yes">4x</span>
978
+ <span class="cline-any cline-yes">4x</span>
979
+ <span class="cline-any cline-neutral">&nbsp;</span>
980
+ <span class="cline-any cline-neutral">&nbsp;</span>
981
+ <span class="cline-any cline-yes">21x</span>
982
+ <span class="cline-any cline-neutral">&nbsp;</span>
983
+ <span class="cline-any cline-yes">21x</span>
984
+ <span class="cline-any cline-neutral">&nbsp;</span>
985
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
989
+ <span class="cline-any cline-neutral">&nbsp;</span>
990
+ <span class="cline-any cline-neutral">&nbsp;</span>
991
+ <span class="cline-any cline-neutral">&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-yes">6x</span>
997
+ <span class="cline-any cline-yes">6x</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-neutral">&nbsp;</span>
1001
+ <span class="cline-any cline-yes">5x</span>
1002
+ <span class="cline-any cline-neutral">&nbsp;</span>
1003
+ <span class="cline-any cline-yes">1x</span>
1004
+ <span class="cline-any cline-yes">1x</span>
1005
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
1011
+ <span class="cline-any cline-neutral">&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-yes">8x</span>
1015
+ <span class="cline-any cline-yes">8x</span>
1016
+ <span class="cline-any cline-neutral">&nbsp;</span>
1017
+ <span class="cline-any cline-neutral">&nbsp;</span>
1018
+ <span class="cline-any cline-yes">8x</span>
1019
+ <span class="cline-any cline-neutral">&nbsp;</span>
1020
+ <span class="cline-any cline-neutral">&nbsp;</span>
1021
+ <span class="cline-any cline-yes">8x</span>
1022
+ <span class="cline-any cline-yes">8x</span>
1023
+ <span class="cline-any cline-neutral">&nbsp;</span>
1024
+ <span class="cline-any cline-yes">8x</span>
1025
+ <span class="cline-any cline-neutral">&nbsp;</span>
1026
+ <span class="cline-any cline-neutral">&nbsp;</span>
1027
+ <span class="cline-any cline-neutral">&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-neutral">&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-yes">9x</span>
1042
+ <span class="cline-any cline-neutral">&nbsp;</span>
1043
+ <span class="cline-any cline-yes">9x</span>
1044
+ <span class="cline-any cline-neutral">&nbsp;</span>
1045
+ <span class="cline-any cline-yes">7x</span>
1046
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
1050
+ <span class="cline-any cline-yes">7x</span>
1051
+ <span class="cline-any cline-yes">7x</span>
1052
+ <span class="cline-any cline-yes">1x</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-yes">8x</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-yes">21x</span>
1065
+ <span class="cline-any cline-neutral">&nbsp;</span>
1066
+ <span class="cline-any cline-no">&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-neutral">&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-neutral">&nbsp;</span>
1073
+ <span class="cline-any cline-neutral">&nbsp;</span>
1074
+ <span class="cline-any cline-neutral">&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-no">&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-neutral">&nbsp;</span>
1081
+ <span class="cline-any cline-yes">21x</span>
1082
+ <span class="cline-any cline-neutral">&nbsp;</span>
1083
+ <span class="cline-any cline-neutral">&nbsp;</span>
1084
+ <span class="cline-any cline-neutral">&nbsp;</span>
1085
+ <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-neutral">&nbsp;</span>
1087
+ <span class="cline-any cline-neutral">&nbsp;</span>
1088
+ <span class="cline-any cline-neutral">&nbsp;</span>
1089
+ <span class="cline-any cline-neutral">&nbsp;</span>
1090
+ <span class="cline-any cline-yes">21x</span>
1091
+ <span class="cline-any cline-yes">21x</span>
1092
+ <span class="cline-any cline-yes">21x</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-neutral">&nbsp;</span>
1095
+ <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-neutral">&nbsp;</span>
1097
+ <span class="cline-any cline-neutral">&nbsp;</span>
1098
+ <span class="cline-any cline-neutral">&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-yes">16x</span>
1102
+ <span class="cline-any cline-neutral">&nbsp;</span>
1103
+ <span class="cline-any cline-yes">4x</span>
1104
+ <span class="cline-any cline-yes">4x</span>
1105
+ <span class="cline-any cline-yes">4x</span>
1106
+ <span class="cline-any cline-neutral">&nbsp;</span>
1107
+ <span class="cline-any cline-yes">4x</span>
1108
+ <span class="cline-any cline-neutral">&nbsp;</span>
1109
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import cliProgress from 'cli-progress';
1113
+ import { globbyStream } from 'globby';
1114
+ import path from 'path';
1115
+ import { Transform } from 'stream';
1116
+ import { pipeline } from 'stream/promises';
1117
+ &nbsp;
1118
+ import logger from '../services/LoggingService.js';
1119
+ &nbsp;
1120
+ import appConfig from '../config/config.js';
1121
+ import ErrorHandler from '../errors/ErrorHandler.js';
1122
+ import { ConfigurationError } from '../errors/ErrorTypes.js';
1123
+ import FileOperations from '../utils/FileOperations.js';
1124
+ import PathNormalizer from '../utils/PathNormalizer.js';
1125
+ &nbsp;
1126
+ /**
1127
+ * Scan Command Handler
1128
+ * Handles the optimized arela scan command with streaming support
1129
+ */
1130
+ export class ScanCommand {
1131
+ constructor() {
1132
+ this.errorHandler = new ErrorHandler(logger);
1133
+ this.scanApiService = null; // Will be initialized in execute
1134
+ }
1135
+ &nbsp;
1136
+ /**
1137
+ * Execute the scan command
1138
+ * @param {Object} options - Command options
1139
+ * @param {boolean} options.countFirst - Count files first for percentage-based progress
1140
+ */
1141
+ async execute(options = {}) {
1142
+ const startTime = Date.now();
1143
+ &nbsp;
1144
+ try {
1145
+ // Validate scan configuration
1146
+ appConfig.validateScanConfig();
1147
+ &nbsp;
1148
+ // Import ScanApiService dynamically
1149
+ const { default: ScanApiService } = await import(
1150
+ '../services/ScanApiService.js'
1151
+ );
1152
+ this.scanApiService = new ScanApiService();
1153
+ &nbsp;
1154
+ const scanConfig = appConfig.getScanConfig();
1155
+ // Ensure basePath is absolute for scan operations
1156
+ const basePath = PathNormalizer.toAbsolutePath(appConfig.getBasePath());
1157
+ &nbsp;
1158
+ logger.info('🔍 Starting arela scan command');
1159
+ logger.info(`📦 Company: ${scanConfig.companySlug}`);
1160
+ logger.info(`🖥️ Server: ${scanConfig.serverId}`);
1161
+ logger.info(`📂 Base Path: ${basePath}`);
1162
+ logger.info(`📊 Directory Level: ${scanConfig.directoryLevel}`);
1163
+ &nbsp;
1164
+ // Step 1: Discover directories at specified level
1165
+ logger.info('\n🔍 Discovering directories...');
1166
+ const directories = await this.#discoverDirectories(
1167
+ basePath,
1168
+ scanConfig.directoryLevel,
1169
+ );
1170
+ logger.info(
1171
+ `📁 Found ${directories.length} director${directories.length === 1 ? 'y' : 'ies'} to scan`,
1172
+ );
1173
+ &nbsp;
1174
+ // Step 2: Register instances for each directory
1175
+ logger.info('\n📝 Registering scan instances...');
1176
+ const registrations = [];
1177
+ for (const dir of directories) {
1178
+ // dir.path is already absolute from #discoverDirectories
1179
+ // Use the absolute path as basePathLabel (simplifies everything!)
1180
+ const absolutePath = dir.path;
1181
+ &nbsp;
1182
+ const registration = await this.scanApiService.registerInstance({
1183
+ companySlug: scanConfig.companySlug,
1184
+ serverId: scanConfig.serverId,
1185
+ basePathFull: absolutePath,
1186
+ });
1187
+ &nbsp;
1188
+ registrations.push({ ...registration, directory: dir });
1189
+ &nbsp;
1190
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (registration.existed) {
1191
+ <span class="cstat-no" title="statement not covered" > logger.info(` ✓ ${dir.label || 'root'}: ${registration.tableName}`);</span>
1192
+ } else {
1193
+ logger.success(
1194
+ ` ✓ ${dir.label || 'root'}: ${registration.tableName} (new)`,
1195
+ );
1196
+ }
1197
+ }
1198
+ &nbsp;
1199
+ // Optional: Count files first for percentage-based progress
1200
+ let totalFiles = null;
1201
+ if (options.countFirst) {
1202
+ logger.info('\n🔢 Counting files...');
1203
+ totalFiles = await this.#countFiles(basePath, scanConfig);
1204
+ logger.info(`📊 Found ${totalFiles.toLocaleString()} files to scan`);
1205
+ }
1206
+ &nbsp;
1207
+ // Step 3: Stream files and upload stats for each directory
1208
+ logger.info('\n🚀 Starting file scan...');
1209
+ let totalStats = {
1210
+ filesScanned: 0,
1211
+ filesInserted: 0,
1212
+ filesSkipped: 0,
1213
+ totalSize: 0,
1214
+ };
1215
+ &nbsp;
1216
+ for (const reg of registrations) {
1217
+ logger.info(`\n📂 Scanning: ${reg.directory.label || 'root'}`);
1218
+ const stats = await this.#streamScanDirectory(
1219
+ reg.directory.path,
1220
+ scanConfig,
1221
+ reg.tableName,
1222
+ null, // Don't use percentage for individual directories
1223
+ );
1224
+ &nbsp;
1225
+ // Step 4: Complete scan for this directory
1226
+ await this.scanApiService.completeScan({
1227
+ tableName: reg.tableName,
1228
+ totalFiles: stats.filesScanned,
1229
+ totalSizeBytes: stats.totalSize,
1230
+ });
1231
+ &nbsp;
1232
+ totalStats.filesScanned += stats.filesScanned;
1233
+ totalStats.filesInserted += stats.filesInserted;
1234
+ totalStats.filesSkipped += stats.filesSkipped;
1235
+ totalStats.totalSize += stats.totalSize;
1236
+ }
1237
+ &nbsp;
1238
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
1239
+ const filesPerSec = (totalStats.filesScanned / duration).toFixed(2);
1240
+ &nbsp;
1241
+ logger.success('\n✅ Scan completed successfully!');
1242
+ logger.info(`\n📊 Scan Statistics:`);
1243
+ logger.info(` Directories scanned: ${registrations.length}`);
1244
+ logger.info(
1245
+ ` Files scanned: ${totalStats.filesScanned.toLocaleString()}`,
1246
+ );
1247
+ logger.info(
1248
+ ` Files inserted: ${totalStats.filesInserted.toLocaleString()}`,
1249
+ );
1250
+ logger.info(
1251
+ ` Files skipped: ${totalStats.filesSkipped.toLocaleString()} (excluded patterns)`,
1252
+ );
1253
+ logger.info(` Total size: ${this.#formatBytes(totalStats.totalSize)}`);
1254
+ logger.info(` Duration: ${duration}s`);
1255
+ logger.info(` Throughput: ${filesPerSec} files/sec`);
1256
+ logger.info(`\n📋 Tables created:`);
1257
+ for (const reg of registrations) {
1258
+ logger.info(` - ${reg.tableName}`);
1259
+ }
1260
+ &nbsp;
1261
+ return {
1262
+ success: true,
1263
+ tables: registrations.map((r) =&gt; r.tableName),
1264
+ stats: totalStats,
1265
+ };
1266
+ } catch (error) {
1267
+ this.errorHandler.handleError(error, 'scan');
1268
+ return {
1269
+ success: false,
1270
+ error: error.message,
1271
+ stats: {
1272
+ filesScanned: 0,
1273
+ filesInserted: 0,
1274
+ filesSkipped: 0,
1275
+ totalSize: 0,
1276
+ },
1277
+ };
1278
+ }
1279
+ }
1280
+ &nbsp;
1281
+ /**
1282
+ * Discover directories at specified level
1283
+ * @private
1284
+ */
1285
+ async #discoverDirectories(basePath, level) {
1286
+ // Get sources, defaults to ['.'] if not configured
1287
+ const sources = appConfig.getUploadSources();
1288
+ const isDefaultSource = sources.length === 1 &amp;&amp; sources[0] === '.';
1289
+ &nbsp;
1290
+ if (level === 0) {
1291
+ // Level 0: Create one entry per source
1292
+ return sources.map((source) =&gt; {
1293
+ const sourcePath =
1294
+ source === '.' ? basePath : path.resolve(basePath, source);
1295
+ // Label is relative path for display purposes only
1296
+ const label = source === '.' ? '' : source;
1297
+ return { path: sourcePath, label };
1298
+ });
1299
+ }
1300
+ &nbsp;
1301
+ // For level &gt; 0: First discover directories at the base path, then combine with sources
1302
+ const fs = await import('fs/promises');
1303
+ const directories = [];
1304
+ &nbsp;
1305
+ try {
1306
+ const fs = await import('fs/promises');
1307
+ &nbsp;
1308
+ // Step 1: Discover directories at the specified level from base path
1309
+ const levelDirs = await this.#getDirectoriesAtLevel(basePath, level, '');
1310
+ &nbsp;
1311
+ // Step 2: For each discovered directory, create entries for each source
1312
+ for (const levelDir of levelDirs) {
1313
+ for (const source of sources) {
1314
+ if (source === '.') {
1315
+ // Source is current directory, use discovered path as-is
1316
+ directories.push(levelDir);
1317
+ } else {
1318
+ // Append source to path
1319
+ const combinedPath = path.resolve(levelDir.path, source);
1320
+ &nbsp;
1321
+ // Only add if the combined path actually exists
1322
+ try {
1323
+ const stats = await fs.stat(combinedPath);
1324
+ if (stats.isDirectory()) {
1325
+ // Label for display
1326
+ const label = levelDir.label
1327
+ ? `${levelDir.label}/${source}`
1328
+ : <span class="branch-1 cbranch-no" title="branch not covered" >source;</span>
1329
+ directories.push({
1330
+ path: combinedPath,
1331
+ label,
1332
+ });
1333
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
1334
+ <span class="cstat-no" title="statement not covered" > logger.debug(`⏭️ Skipping ${combinedPath} (not a directory)`);</span>
1335
+ }
1336
+ } catch (error) {
1337
+ <span class="cstat-no" title="statement not covered" > logger.debug(`⏭️ Skipping ${combinedPath} (does not exist)`);</span>
1338
+ }
1339
+ }
1340
+ }
1341
+ }
1342
+ } catch (error) {
1343
+ <span class="cstat-no" title="statement not covered" > logger.warn(`⚠️ Could not discover directories: ${error.message}`);</span>
1344
+ }
1345
+ &nbsp;
1346
+ return directories;
1347
+ }
1348
+ &nbsp;
1349
+ /**
1350
+ * Recursively get directories at specified level
1351
+ * @private
1352
+ */
1353
+ async #getDirectoriesAtLevel(
1354
+ basePath,
1355
+ targetLevel,
1356
+ currentPath,
1357
+ currentLevel = 0,
1358
+ ) {
1359
+ const fs = await import('fs/promises');
1360
+ const fullPath = path.join(basePath, currentPath);
1361
+ &nbsp;
1362
+ if (currentLevel === targetLevel) {
1363
+ // Label is the relative path for display
1364
+ const label = currentPath || <span class="branch-1 cbranch-no" title="branch not covered" >'';</span>
1365
+ return [{ path: fullPath, label }];
1366
+ }
1367
+ &nbsp;
1368
+ const directories = [];
1369
+ const entries = await fs.readdir(fullPath, { withFileTypes: true });
1370
+ &nbsp;
1371
+ for (const entry of entries) {
1372
+ if (entry.isDirectory()) {
1373
+ const subPath = path.join(currentPath, entry.name);
1374
+ const subDirs = await this.#getDirectoriesAtLevel(
1375
+ basePath,
1376
+ targetLevel,
1377
+ subPath,
1378
+ currentLevel + 1,
1379
+ );
1380
+ directories.push(...subDirs);
1381
+ }
1382
+ }
1383
+ &nbsp;
1384
+ return directories;
1385
+ }
1386
+ &nbsp;
1387
+ /**
1388
+ * Count files for percentage-based progress
1389
+ * @private
1390
+ */
1391
+ async #countFiles(basePath, scanConfig) {
1392
+ const sources = appConfig.getUploadSources();
1393
+ let totalCount = 0;
1394
+ &nbsp;
1395
+ for (const source of sources) {
1396
+ const sourcePath = path.resolve(basePath, source);
1397
+ const files = await globbyStream('**/*', {
1398
+ cwd: sourcePath,
1399
+ onlyFiles: true,
1400
+ absolute: true,
1401
+ });
1402
+ &nbsp;
1403
+ for await (const file of files) {
1404
+ <span class="cstat-no" title="statement not covered" > if (!this.#shouldExcludeFile(file, scanConfig.excludePatterns)) {</span>
1405
+ <span class="cstat-no" title="statement not covered" > totalCount++;</span>
1406
+ }
1407
+ }
1408
+ }
1409
+ &nbsp;
1410
+ return totalCount;
1411
+ }
1412
+ &nbsp;
1413
+ /**
1414
+ * Stream files from a single directory and upload stats in batches
1415
+ * @private
1416
+ */
1417
+ async #streamScanDirectory(
1418
+ dirPath,
1419
+ scanConfig,
1420
+ tableName,
1421
+ totalFiles = <span class="branch-0 cbranch-no" title="branch not covered" >null,</span>
1422
+ ) {
1423
+ // For directory-level scanning, we scan the directory directly
1424
+ const batchSize = scanConfig.batchSize || <span class="branch-1 cbranch-no" title="branch not covered" >2000;</span>
1425
+ const scanTimestamp = new Date().toISOString();
1426
+ &nbsp;
1427
+ let filesScanned = 0;
1428
+ let filesInserted = 0;
1429
+ let filesSkipped = 0;
1430
+ let totalSize = 0;
1431
+ let currentBatch = [];
1432
+ &nbsp;
1433
+ // Create progress bar
1434
+ const progressBar = this.#createProgressBar(totalFiles);
1435
+ &nbsp;
1436
+ try {
1437
+ // Create stream with stats option
1438
+ const fileStream = globbyStream('**/*', {
1439
+ cwd: dirPath,
1440
+ onlyFiles: true,
1441
+ absolute: true,
1442
+ stats: true, // Get file stats during discovery
1443
+ });
1444
+ &nbsp;
1445
+ // Process each file from stream
1446
+ for await (const entry of fileStream) {
1447
+ // globby with stats:true returns {path, stats} objects
1448
+ const filePath = typeof entry === 'string' ? <span class="branch-0 cbranch-no" title="branch not covered" >entry </span>: entry.path;
1449
+ const stats = typeof entry === 'object' ? entry.stats : <span class="branch-1 cbranch-no" title="branch not covered" >null;</span>
1450
+ &nbsp;
1451
+ // Check if file should be excluded
1452
+ if (this.#shouldExcludeFile(filePath, scanConfig.excludePatterns)) {
1453
+ filesSkipped++;
1454
+ continue;
1455
+ }
1456
+ &nbsp;
1457
+ // Get file stats (use from globby or fetch manually)
1458
+ const fileStats = stats || <span class="branch-1 cbranch-no" title="branch not covered" >FileOperations.getFileStats(filePath);</span>
1459
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!fileStats) {
1460
+ <span class="cstat-no" title="statement not covered" > logger.debug(`⚠️ Could not read stats: ${filePath}`);</span>
1461
+ <span class="cstat-no" title="statement not covered" > filesSkipped++;</span>
1462
+ <span class="cstat-no" title="statement not covered" > continue;</span>
1463
+ }
1464
+ &nbsp;
1465
+ // Normalize file record
1466
+ const record = this.#normalizeFileRecord(
1467
+ filePath,
1468
+ fileStats,
1469
+ dirPath,
1470
+ scanTimestamp,
1471
+ );
1472
+ &nbsp;
1473
+ currentBatch.push(record);
1474
+ filesScanned++;
1475
+ totalSize += record.sizeBytes;
1476
+ &nbsp;
1477
+ // Update progress
1478
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (totalFiles) {
1479
+ <span class="cstat-no" title="statement not covered" > progressBar.update(filesScanned);</span>
1480
+ } else {
1481
+ // Show throughput instead of percentage
1482
+ const elapsed = (Date.now() - progressBar.startTime) / 1000;
1483
+ const rate = (filesScanned / elapsed).toFixed(1);
1484
+ progressBar.update(filesScanned, { rate });
1485
+ }
1486
+ &nbsp;
1487
+ // Upload batch when full
1488
+ if (currentBatch.length &gt;= batchSize) {
1489
+ const inserted = await this.#uploadBatch(tableName, currentBatch);
1490
+ filesInserted += inserted;
1491
+ currentBatch = [];
1492
+ }
1493
+ }
1494
+ } catch (error) {
1495
+ <span class="cstat-no" title="statement not covered" > logger.error(`❌ Error scanning directory: ${error.message}`);</span>
1496
+ }
1497
+ &nbsp;
1498
+ // Upload remaining files
1499
+ if (currentBatch.length &gt; 0) {
1500
+ const inserted = await this.#uploadBatch(tableName, currentBatch);
1501
+ filesInserted += inserted;
1502
+ }
1503
+ &nbsp;
1504
+ progressBar.stop();
1505
+ &nbsp;
1506
+ return {
1507
+ filesScanned,
1508
+ filesInserted,
1509
+ filesSkipped,
1510
+ totalSize,
1511
+ };
1512
+ }
1513
+ &nbsp;
1514
+ /**
1515
+ * Upload a batch of file records
1516
+ * @private
1517
+ */
1518
+ async #uploadBatch(tableName, records) {
1519
+ try {
1520
+ const result = await this.scanApiService.batchInsertStats(
1521
+ tableName,
1522
+ records,
1523
+ );
1524
+ return result.inserted;
1525
+ } catch (error) {
1526
+ logger.error(`❌ Failed to upload batch: ${error.message}`);
1527
+ return 0;
1528
+ }
1529
+ }
1530
+ &nbsp;
1531
+ /**
1532
+ * Normalize file record for database insertion
1533
+ * Stores paths with forward slashes for consistency but keeps them absolute
1534
+ * @private
1535
+ */
1536
+ #normalizeFileRecord(filePath, fileStats, basePath, scanTimestamp) {
1537
+ const fileName = path.basename(filePath);
1538
+ const fileExtension = path.extname(filePath).toLowerCase().replace('.', '');
1539
+ &nbsp;
1540
+ // Normalize separators to forward slashes for consistency
1541
+ const directoryPath = PathNormalizer.normalizeSeparators(
1542
+ path.dirname(filePath),
1543
+ );
1544
+ const relativePath = PathNormalizer.getRelativePath(filePath, basePath);
1545
+ const absolutePath = PathNormalizer.normalizeSeparators(filePath);
1546
+ &nbsp;
1547
+ return {
1548
+ fileName,
1549
+ fileExtension,
1550
+ directoryPath,
1551
+ relativePath,
1552
+ absolutePath,
1553
+ sizeBytes: Number(fileStats.size),
1554
+ modifiedAt: fileStats.mtime.toISOString(),
1555
+ scanTimestamp,
1556
+ };
1557
+ }
1558
+ &nbsp;
1559
+ /**
1560
+ * Check if file should be excluded based on patterns
1561
+ * @private
1562
+ */
1563
+ #shouldExcludeFile(filePath, excludePatterns) {
1564
+ const fileName = path.basename(filePath);
1565
+ &nbsp;
1566
+ for (const pattern of excludePatterns) {
1567
+ // Convert glob pattern to regex
1568
+ const regexPattern = pattern
1569
+ .replace(/\./g, '\\.') // Escape dots
1570
+ .replace(/\*/g, '.*') // * to .*
1571
+ .replace(/\?/g, '.'); // ? to .
1572
+ &nbsp;
1573
+ const regex = new RegExp(`^${regexPattern}$`, 'i');
1574
+ if (regex.test(fileName)) {
1575
+ return true;
1576
+ }
1577
+ }
1578
+ &nbsp;
1579
+ return false;
1580
+ }
1581
+ &nbsp;
1582
+ /**
1583
+ * Create progress bar
1584
+ * @private
1585
+ */
1586
+ #createProgressBar(totalFiles) {
1587
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (totalFiles) {
1588
+ // Percentage-based progress
1589
+ const bar = <span class="cstat-no" title="statement not covered" >new cliProgress.SingleBar(</span>
1590
+ {
1591
+ format:
1592
+ '📊 Scanning |{bar}| {percentage}% | {value}/{total} files | {rate} files/sec',
1593
+ barCompleteChar: '\u2588',
1594
+ barIncompleteChar: '\u2591',
1595
+ hideCursor: true,
1596
+ },
1597
+ cliProgress.Presets.shades_classic,
1598
+ );
1599
+ <span class="cstat-no" title="statement not covered" > bar.start(totalFiles, 0, { rate: '0.0' });</span>
1600
+ <span class="cstat-no" title="statement not covered" > bar.startTime = Date.now();</span>
1601
+ <span class="cstat-no" title="statement not covered" > return bar;</span>
1602
+ } else {
1603
+ // Throughput-based progress
1604
+ const bar = new cliProgress.SingleBar(
1605
+ {
1606
+ format: '📊 Scanning | {value} files | {rate} files/sec',
1607
+ hideCursor: true,
1608
+ clearOnComplete: false,
1609
+ stopOnComplete: false,
1610
+ },
1611
+ cliProgress.Presets.legacy,
1612
+ );
1613
+ bar.start(0, 0, { rate: '0.0' });
1614
+ bar.startTime = Date.now();
1615
+ return bar;
1616
+ }
1617
+ }
1618
+ &nbsp;
1619
+ /**
1620
+ * Format bytes to human-readable size
1621
+ * @private
1622
+ */
1623
+ #formatBytes(bytes) {
1624
+ if (bytes === 0) return '0 Bytes';
1625
+ &nbsp;
1626
+ const k = 1024;
1627
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
1628
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1629
+ &nbsp;
1630
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
1631
+ }
1632
+ }
1633
+ &nbsp;
1634
+ export default new ScanCommand();
1635
+ &nbsp;</pre></td></tr></table></pre>
1636
+
1637
+ <div class='push'></div><!-- for sticky footer -->
1638
+ </div><!-- /wrapper -->
1639
+ <div class='footer quiet pad2 space-top1 center small'>
1640
+ Code coverage generated by
1641
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1642
+ at 2026-01-20T02:38:34.273Z
1643
+ </div>
1644
+ <script src="prettify.js"></script>
1645
+ <script>
1646
+ window.onload = function () {
1647
+ prettyPrint();
1648
+ };
1649
+ </script>
1650
+ <script src="sorter.js"></script>
1651
+ <script src="block-navigation.js"></script>
1652
+ </body>
1653
+ </html>
1654
+