@contractkit/plugin-typescript 0.27.0 → 0.28.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 (41) hide show
  1. package/.turbo/turbo-build$colon$ci.log +3 -3
  2. package/.turbo/turbo-test$colon$ci.log +19 -18
  3. package/CHANGELOG.md +14 -0
  4. package/dist/codegen-contract.d.ts.map +1 -1
  5. package/dist/codegen-sdk.d.ts.map +1 -1
  6. package/dist/index.js +239 -215
  7. package/dist/index.js.map +1 -1
  8. package/dist/path-utils.d.ts.map +1 -1
  9. package/dist/ts-render.d.ts +6 -0
  10. package/dist/ts-render.d.ts.map +1 -1
  11. package/package.json +4 -4
  12. package/src/codegen-contract.ts +7 -4
  13. package/src/codegen-operation.ts +9 -9
  14. package/src/codegen-plain-types.ts +17 -14
  15. package/src/codegen-sdk.ts +5 -4
  16. package/src/path-utils.ts +37 -20
  17. package/src/ts-render.ts +21 -6
  18. package/tests/codegen-contract.test.ts +4 -0
  19. package/tests/codegen-operation.test.ts +5 -5
  20. package/tests/codegen-sdk.test.ts +8 -0
  21. package/tests/escaping-security.test.ts +143 -0
  22. package/coverage/base.css +0 -224
  23. package/coverage/block-navigation.js +0 -87
  24. package/coverage/clover.xml +0 -2213
  25. package/coverage/coverage-final.json +0 -9
  26. package/coverage/favicon.png +0 -0
  27. package/coverage/index.html +0 -131
  28. package/coverage/prettify.css +0 -1
  29. package/coverage/prettify.js +0 -2
  30. package/coverage/sort-arrow-sprite.png +0 -0
  31. package/coverage/sorter.js +0 -210
  32. package/coverage/src/codegen-contract.ts.html +0 -3661
  33. package/coverage/src/codegen-operation.ts.html +0 -2584
  34. package/coverage/src/codegen-plain-types.ts.html +0 -997
  35. package/coverage/src/codegen-sdk.ts.html +0 -3901
  36. package/coverage/src/index.html +0 -206
  37. package/coverage/src/index.ts.html +0 -2761
  38. package/coverage/src/path-utils.ts.html +0 -745
  39. package/coverage/src/ts-render.ts.html +0 -592
  40. package/coverage/tests/helpers.ts.html +0 -826
  41. package/coverage/tests/index.html +0 -116
@@ -1,2584 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for src/codegen-operation.ts</title>
7
- <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
- <meta name="viewport" content="width=device-width, initial-scale=1" />
12
- <style type='text/css'>
13
- .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
15
- }
16
- </style>
17
- </head>
18
-
19
- <body>
20
- <div class='wrapper'>
21
- <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> codegen-operation.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">78.41% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>367/468</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">74.7% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>257/344</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">78.94% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>60/76</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">79.9% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>322/403</span>
50
- </div>
51
-
52
-
53
- </div>
54
- <p class="quiet">
55
- Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
- </p>
57
- <template id="filterTemplate">
58
- <div class="quiet">
59
- Filter:
60
- <input type="search" id="fileSearch">
61
- </div>
62
- </template>
63
- </div>
64
- <div class='status-line medium'></div>
65
- <pre><table class="coverage">
66
- <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
- <a name='L2'></a><a href='#L2'>2</a>
68
- <a name='L3'></a><a href='#L3'>3</a>
69
- <a name='L4'></a><a href='#L4'>4</a>
70
- <a name='L5'></a><a href='#L5'>5</a>
71
- <a name='L6'></a><a href='#L6'>6</a>
72
- <a name='L7'></a><a href='#L7'>7</a>
73
- <a name='L8'></a><a href='#L8'>8</a>
74
- <a name='L9'></a><a href='#L9'>9</a>
75
- <a name='L10'></a><a href='#L10'>10</a>
76
- <a name='L11'></a><a href='#L11'>11</a>
77
- <a name='L12'></a><a href='#L12'>12</a>
78
- <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a>
80
- <a name='L15'></a><a href='#L15'>15</a>
81
- <a name='L16'></a><a href='#L16'>16</a>
82
- <a name='L17'></a><a href='#L17'>17</a>
83
- <a name='L18'></a><a href='#L18'>18</a>
84
- <a name='L19'></a><a href='#L19'>19</a>
85
- <a name='L20'></a><a href='#L20'>20</a>
86
- <a name='L21'></a><a href='#L21'>21</a>
87
- <a name='L22'></a><a href='#L22'>22</a>
88
- <a name='L23'></a><a href='#L23'>23</a>
89
- <a name='L24'></a><a href='#L24'>24</a>
90
- <a name='L25'></a><a href='#L25'>25</a>
91
- <a name='L26'></a><a href='#L26'>26</a>
92
- <a name='L27'></a><a href='#L27'>27</a>
93
- <a name='L28'></a><a href='#L28'>28</a>
94
- <a name='L29'></a><a href='#L29'>29</a>
95
- <a name='L30'></a><a href='#L30'>30</a>
96
- <a name='L31'></a><a href='#L31'>31</a>
97
- <a name='L32'></a><a href='#L32'>32</a>
98
- <a name='L33'></a><a href='#L33'>33</a>
99
- <a name='L34'></a><a href='#L34'>34</a>
100
- <a name='L35'></a><a href='#L35'>35</a>
101
- <a name='L36'></a><a href='#L36'>36</a>
102
- <a name='L37'></a><a href='#L37'>37</a>
103
- <a name='L38'></a><a href='#L38'>38</a>
104
- <a name='L39'></a><a href='#L39'>39</a>
105
- <a name='L40'></a><a href='#L40'>40</a>
106
- <a name='L41'></a><a href='#L41'>41</a>
107
- <a name='L42'></a><a href='#L42'>42</a>
108
- <a name='L43'></a><a href='#L43'>43</a>
109
- <a name='L44'></a><a href='#L44'>44</a>
110
- <a name='L45'></a><a href='#L45'>45</a>
111
- <a name='L46'></a><a href='#L46'>46</a>
112
- <a name='L47'></a><a href='#L47'>47</a>
113
- <a name='L48'></a><a href='#L48'>48</a>
114
- <a name='L49'></a><a href='#L49'>49</a>
115
- <a name='L50'></a><a href='#L50'>50</a>
116
- <a name='L51'></a><a href='#L51'>51</a>
117
- <a name='L52'></a><a href='#L52'>52</a>
118
- <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a>
120
- <a name='L55'></a><a href='#L55'>55</a>
121
- <a name='L56'></a><a href='#L56'>56</a>
122
- <a name='L57'></a><a href='#L57'>57</a>
123
- <a name='L58'></a><a href='#L58'>58</a>
124
- <a name='L59'></a><a href='#L59'>59</a>
125
- <a name='L60'></a><a href='#L60'>60</a>
126
- <a name='L61'></a><a href='#L61'>61</a>
127
- <a name='L62'></a><a href='#L62'>62</a>
128
- <a name='L63'></a><a href='#L63'>63</a>
129
- <a name='L64'></a><a href='#L64'>64</a>
130
- <a name='L65'></a><a href='#L65'>65</a>
131
- <a name='L66'></a><a href='#L66'>66</a>
132
- <a name='L67'></a><a href='#L67'>67</a>
133
- <a name='L68'></a><a href='#L68'>68</a>
134
- <a name='L69'></a><a href='#L69'>69</a>
135
- <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a>
137
- <a name='L72'></a><a href='#L72'>72</a>
138
- <a name='L73'></a><a href='#L73'>73</a>
139
- <a name='L74'></a><a href='#L74'>74</a>
140
- <a name='L75'></a><a href='#L75'>75</a>
141
- <a name='L76'></a><a href='#L76'>76</a>
142
- <a name='L77'></a><a href='#L77'>77</a>
143
- <a name='L78'></a><a href='#L78'>78</a>
144
- <a name='L79'></a><a href='#L79'>79</a>
145
- <a name='L80'></a><a href='#L80'>80</a>
146
- <a name='L81'></a><a href='#L81'>81</a>
147
- <a name='L82'></a><a href='#L82'>82</a>
148
- <a name='L83'></a><a href='#L83'>83</a>
149
- <a name='L84'></a><a href='#L84'>84</a>
150
- <a name='L85'></a><a href='#L85'>85</a>
151
- <a name='L86'></a><a href='#L86'>86</a>
152
- <a name='L87'></a><a href='#L87'>87</a>
153
- <a name='L88'></a><a href='#L88'>88</a>
154
- <a name='L89'></a><a href='#L89'>89</a>
155
- <a name='L90'></a><a href='#L90'>90</a>
156
- <a name='L91'></a><a href='#L91'>91</a>
157
- <a name='L92'></a><a href='#L92'>92</a>
158
- <a name='L93'></a><a href='#L93'>93</a>
159
- <a name='L94'></a><a href='#L94'>94</a>
160
- <a name='L95'></a><a href='#L95'>95</a>
161
- <a name='L96'></a><a href='#L96'>96</a>
162
- <a name='L97'></a><a href='#L97'>97</a>
163
- <a name='L98'></a><a href='#L98'>98</a>
164
- <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a>
166
- <a name='L101'></a><a href='#L101'>101</a>
167
- <a name='L102'></a><a href='#L102'>102</a>
168
- <a name='L103'></a><a href='#L103'>103</a>
169
- <a name='L104'></a><a href='#L104'>104</a>
170
- <a name='L105'></a><a href='#L105'>105</a>
171
- <a name='L106'></a><a href='#L106'>106</a>
172
- <a name='L107'></a><a href='#L107'>107</a>
173
- <a name='L108'></a><a href='#L108'>108</a>
174
- <a name='L109'></a><a href='#L109'>109</a>
175
- <a name='L110'></a><a href='#L110'>110</a>
176
- <a name='L111'></a><a href='#L111'>111</a>
177
- <a name='L112'></a><a href='#L112'>112</a>
178
- <a name='L113'></a><a href='#L113'>113</a>
179
- <a name='L114'></a><a href='#L114'>114</a>
180
- <a name='L115'></a><a href='#L115'>115</a>
181
- <a name='L116'></a><a href='#L116'>116</a>
182
- <a name='L117'></a><a href='#L117'>117</a>
183
- <a name='L118'></a><a href='#L118'>118</a>
184
- <a name='L119'></a><a href='#L119'>119</a>
185
- <a name='L120'></a><a href='#L120'>120</a>
186
- <a name='L121'></a><a href='#L121'>121</a>
187
- <a name='L122'></a><a href='#L122'>122</a>
188
- <a name='L123'></a><a href='#L123'>123</a>
189
- <a name='L124'></a><a href='#L124'>124</a>
190
- <a name='L125'></a><a href='#L125'>125</a>
191
- <a name='L126'></a><a href='#L126'>126</a>
192
- <a name='L127'></a><a href='#L127'>127</a>
193
- <a name='L128'></a><a href='#L128'>128</a>
194
- <a name='L129'></a><a href='#L129'>129</a>
195
- <a name='L130'></a><a href='#L130'>130</a>
196
- <a name='L131'></a><a href='#L131'>131</a>
197
- <a name='L132'></a><a href='#L132'>132</a>
198
- <a name='L133'></a><a href='#L133'>133</a>
199
- <a name='L134'></a><a href='#L134'>134</a>
200
- <a name='L135'></a><a href='#L135'>135</a>
201
- <a name='L136'></a><a href='#L136'>136</a>
202
- <a name='L137'></a><a href='#L137'>137</a>
203
- <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a>
205
- <a name='L140'></a><a href='#L140'>140</a>
206
- <a name='L141'></a><a href='#L141'>141</a>
207
- <a name='L142'></a><a href='#L142'>142</a>
208
- <a name='L143'></a><a href='#L143'>143</a>
209
- <a name='L144'></a><a href='#L144'>144</a>
210
- <a name='L145'></a><a href='#L145'>145</a>
211
- <a name='L146'></a><a href='#L146'>146</a>
212
- <a name='L147'></a><a href='#L147'>147</a>
213
- <a name='L148'></a><a href='#L148'>148</a>
214
- <a name='L149'></a><a href='#L149'>149</a>
215
- <a name='L150'></a><a href='#L150'>150</a>
216
- <a name='L151'></a><a href='#L151'>151</a>
217
- <a name='L152'></a><a href='#L152'>152</a>
218
- <a name='L153'></a><a href='#L153'>153</a>
219
- <a name='L154'></a><a href='#L154'>154</a>
220
- <a name='L155'></a><a href='#L155'>155</a>
221
- <a name='L156'></a><a href='#L156'>156</a>
222
- <a name='L157'></a><a href='#L157'>157</a>
223
- <a name='L158'></a><a href='#L158'>158</a>
224
- <a name='L159'></a><a href='#L159'>159</a>
225
- <a name='L160'></a><a href='#L160'>160</a>
226
- <a name='L161'></a><a href='#L161'>161</a>
227
- <a name='L162'></a><a href='#L162'>162</a>
228
- <a name='L163'></a><a href='#L163'>163</a>
229
- <a name='L164'></a><a href='#L164'>164</a>
230
- <a name='L165'></a><a href='#L165'>165</a>
231
- <a name='L166'></a><a href='#L166'>166</a>
232
- <a name='L167'></a><a href='#L167'>167</a>
233
- <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a>
235
- <a name='L170'></a><a href='#L170'>170</a>
236
- <a name='L171'></a><a href='#L171'>171</a>
237
- <a name='L172'></a><a href='#L172'>172</a>
238
- <a name='L173'></a><a href='#L173'>173</a>
239
- <a name='L174'></a><a href='#L174'>174</a>
240
- <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a>
242
- <a name='L177'></a><a href='#L177'>177</a>
243
- <a name='L178'></a><a href='#L178'>178</a>
244
- <a name='L179'></a><a href='#L179'>179</a>
245
- <a name='L180'></a><a href='#L180'>180</a>
246
- <a name='L181'></a><a href='#L181'>181</a>
247
- <a name='L182'></a><a href='#L182'>182</a>
248
- <a name='L183'></a><a href='#L183'>183</a>
249
- <a name='L184'></a><a href='#L184'>184</a>
250
- <a name='L185'></a><a href='#L185'>185</a>
251
- <a name='L186'></a><a href='#L186'>186</a>
252
- <a name='L187'></a><a href='#L187'>187</a>
253
- <a name='L188'></a><a href='#L188'>188</a>
254
- <a name='L189'></a><a href='#L189'>189</a>
255
- <a name='L190'></a><a href='#L190'>190</a>
256
- <a name='L191'></a><a href='#L191'>191</a>
257
- <a name='L192'></a><a href='#L192'>192</a>
258
- <a name='L193'></a><a href='#L193'>193</a>
259
- <a name='L194'></a><a href='#L194'>194</a>
260
- <a name='L195'></a><a href='#L195'>195</a>
261
- <a name='L196'></a><a href='#L196'>196</a>
262
- <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a>
264
- <a name='L199'></a><a href='#L199'>199</a>
265
- <a name='L200'></a><a href='#L200'>200</a>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
393
- <a name='L328'></a><a href='#L328'>328</a>
394
- <a name='L329'></a><a href='#L329'>329</a>
395
- <a name='L330'></a><a href='#L330'>330</a>
396
- <a name='L331'></a><a href='#L331'>331</a>
397
- <a name='L332'></a><a href='#L332'>332</a>
398
- <a name='L333'></a><a href='#L333'>333</a>
399
- <a name='L334'></a><a href='#L334'>334</a>
400
- <a name='L335'></a><a href='#L335'>335</a>
401
- <a name='L336'></a><a href='#L336'>336</a>
402
- <a name='L337'></a><a href='#L337'>337</a>
403
- <a name='L338'></a><a href='#L338'>338</a>
404
- <a name='L339'></a><a href='#L339'>339</a>
405
- <a name='L340'></a><a href='#L340'>340</a>
406
- <a name='L341'></a><a href='#L341'>341</a>
407
- <a name='L342'></a><a href='#L342'>342</a>
408
- <a name='L343'></a><a href='#L343'>343</a>
409
- <a name='L344'></a><a href='#L344'>344</a>
410
- <a name='L345'></a><a href='#L345'>345</a>
411
- <a name='L346'></a><a href='#L346'>346</a>
412
- <a name='L347'></a><a href='#L347'>347</a>
413
- <a name='L348'></a><a href='#L348'>348</a>
414
- <a name='L349'></a><a href='#L349'>349</a>
415
- <a name='L350'></a><a href='#L350'>350</a>
416
- <a name='L351'></a><a href='#L351'>351</a>
417
- <a name='L352'></a><a href='#L352'>352</a>
418
- <a name='L353'></a><a href='#L353'>353</a>
419
- <a name='L354'></a><a href='#L354'>354</a>
420
- <a name='L355'></a><a href='#L355'>355</a>
421
- <a name='L356'></a><a href='#L356'>356</a>
422
- <a name='L357'></a><a href='#L357'>357</a>
423
- <a name='L358'></a><a href='#L358'>358</a>
424
- <a name='L359'></a><a href='#L359'>359</a>
425
- <a name='L360'></a><a href='#L360'>360</a>
426
- <a name='L361'></a><a href='#L361'>361</a>
427
- <a name='L362'></a><a href='#L362'>362</a>
428
- <a name='L363'></a><a href='#L363'>363</a>
429
- <a name='L364'></a><a href='#L364'>364</a>
430
- <a name='L365'></a><a href='#L365'>365</a>
431
- <a name='L366'></a><a href='#L366'>366</a>
432
- <a name='L367'></a><a href='#L367'>367</a>
433
- <a name='L368'></a><a href='#L368'>368</a>
434
- <a name='L369'></a><a href='#L369'>369</a>
435
- <a name='L370'></a><a href='#L370'>370</a>
436
- <a name='L371'></a><a href='#L371'>371</a>
437
- <a name='L372'></a><a href='#L372'>372</a>
438
- <a name='L373'></a><a href='#L373'>373</a>
439
- <a name='L374'></a><a href='#L374'>374</a>
440
- <a name='L375'></a><a href='#L375'>375</a>
441
- <a name='L376'></a><a href='#L376'>376</a>
442
- <a name='L377'></a><a href='#L377'>377</a>
443
- <a name='L378'></a><a href='#L378'>378</a>
444
- <a name='L379'></a><a href='#L379'>379</a>
445
- <a name='L380'></a><a href='#L380'>380</a>
446
- <a name='L381'></a><a href='#L381'>381</a>
447
- <a name='L382'></a><a href='#L382'>382</a>
448
- <a name='L383'></a><a href='#L383'>383</a>
449
- <a name='L384'></a><a href='#L384'>384</a>
450
- <a name='L385'></a><a href='#L385'>385</a>
451
- <a name='L386'></a><a href='#L386'>386</a>
452
- <a name='L387'></a><a href='#L387'>387</a>
453
- <a name='L388'></a><a href='#L388'>388</a>
454
- <a name='L389'></a><a href='#L389'>389</a>
455
- <a name='L390'></a><a href='#L390'>390</a>
456
- <a name='L391'></a><a href='#L391'>391</a>
457
- <a name='L392'></a><a href='#L392'>392</a>
458
- <a name='L393'></a><a href='#L393'>393</a>
459
- <a name='L394'></a><a href='#L394'>394</a>
460
- <a name='L395'></a><a href='#L395'>395</a>
461
- <a name='L396'></a><a href='#L396'>396</a>
462
- <a name='L397'></a><a href='#L397'>397</a>
463
- <a name='L398'></a><a href='#L398'>398</a>
464
- <a name='L399'></a><a href='#L399'>399</a>
465
- <a name='L400'></a><a href='#L400'>400</a>
466
- <a name='L401'></a><a href='#L401'>401</a>
467
- <a name='L402'></a><a href='#L402'>402</a>
468
- <a name='L403'></a><a href='#L403'>403</a>
469
- <a name='L404'></a><a href='#L404'>404</a>
470
- <a name='L405'></a><a href='#L405'>405</a>
471
- <a name='L406'></a><a href='#L406'>406</a>
472
- <a name='L407'></a><a href='#L407'>407</a>
473
- <a name='L408'></a><a href='#L408'>408</a>
474
- <a name='L409'></a><a href='#L409'>409</a>
475
- <a name='L410'></a><a href='#L410'>410</a>
476
- <a name='L411'></a><a href='#L411'>411</a>
477
- <a name='L412'></a><a href='#L412'>412</a>
478
- <a name='L413'></a><a href='#L413'>413</a>
479
- <a name='L414'></a><a href='#L414'>414</a>
480
- <a name='L415'></a><a href='#L415'>415</a>
481
- <a name='L416'></a><a href='#L416'>416</a>
482
- <a name='L417'></a><a href='#L417'>417</a>
483
- <a name='L418'></a><a href='#L418'>418</a>
484
- <a name='L419'></a><a href='#L419'>419</a>
485
- <a name='L420'></a><a href='#L420'>420</a>
486
- <a name='L421'></a><a href='#L421'>421</a>
487
- <a name='L422'></a><a href='#L422'>422</a>
488
- <a name='L423'></a><a href='#L423'>423</a>
489
- <a name='L424'></a><a href='#L424'>424</a>
490
- <a name='L425'></a><a href='#L425'>425</a>
491
- <a name='L426'></a><a href='#L426'>426</a>
492
- <a name='L427'></a><a href='#L427'>427</a>
493
- <a name='L428'></a><a href='#L428'>428</a>
494
- <a name='L429'></a><a href='#L429'>429</a>
495
- <a name='L430'></a><a href='#L430'>430</a>
496
- <a name='L431'></a><a href='#L431'>431</a>
497
- <a name='L432'></a><a href='#L432'>432</a>
498
- <a name='L433'></a><a href='#L433'>433</a>
499
- <a name='L434'></a><a href='#L434'>434</a>
500
- <a name='L435'></a><a href='#L435'>435</a>
501
- <a name='L436'></a><a href='#L436'>436</a>
502
- <a name='L437'></a><a href='#L437'>437</a>
503
- <a name='L438'></a><a href='#L438'>438</a>
504
- <a name='L439'></a><a href='#L439'>439</a>
505
- <a name='L440'></a><a href='#L440'>440</a>
506
- <a name='L441'></a><a href='#L441'>441</a>
507
- <a name='L442'></a><a href='#L442'>442</a>
508
- <a name='L443'></a><a href='#L443'>443</a>
509
- <a name='L444'></a><a href='#L444'>444</a>
510
- <a name='L445'></a><a href='#L445'>445</a>
511
- <a name='L446'></a><a href='#L446'>446</a>
512
- <a name='L447'></a><a href='#L447'>447</a>
513
- <a name='L448'></a><a href='#L448'>448</a>
514
- <a name='L449'></a><a href='#L449'>449</a>
515
- <a name='L450'></a><a href='#L450'>450</a>
516
- <a name='L451'></a><a href='#L451'>451</a>
517
- <a name='L452'></a><a href='#L452'>452</a>
518
- <a name='L453'></a><a href='#L453'>453</a>
519
- <a name='L454'></a><a href='#L454'>454</a>
520
- <a name='L455'></a><a href='#L455'>455</a>
521
- <a name='L456'></a><a href='#L456'>456</a>
522
- <a name='L457'></a><a href='#L457'>457</a>
523
- <a name='L458'></a><a href='#L458'>458</a>
524
- <a name='L459'></a><a href='#L459'>459</a>
525
- <a name='L460'></a><a href='#L460'>460</a>
526
- <a name='L461'></a><a href='#L461'>461</a>
527
- <a name='L462'></a><a href='#L462'>462</a>
528
- <a name='L463'></a><a href='#L463'>463</a>
529
- <a name='L464'></a><a href='#L464'>464</a>
530
- <a name='L465'></a><a href='#L465'>465</a>
531
- <a name='L466'></a><a href='#L466'>466</a>
532
- <a name='L467'></a><a href='#L467'>467</a>
533
- <a name='L468'></a><a href='#L468'>468</a>
534
- <a name='L469'></a><a href='#L469'>469</a>
535
- <a name='L470'></a><a href='#L470'>470</a>
536
- <a name='L471'></a><a href='#L471'>471</a>
537
- <a name='L472'></a><a href='#L472'>472</a>
538
- <a name='L473'></a><a href='#L473'>473</a>
539
- <a name='L474'></a><a href='#L474'>474</a>
540
- <a name='L475'></a><a href='#L475'>475</a>
541
- <a name='L476'></a><a href='#L476'>476</a>
542
- <a name='L477'></a><a href='#L477'>477</a>
543
- <a name='L478'></a><a href='#L478'>478</a>
544
- <a name='L479'></a><a href='#L479'>479</a>
545
- <a name='L480'></a><a href='#L480'>480</a>
546
- <a name='L481'></a><a href='#L481'>481</a>
547
- <a name='L482'></a><a href='#L482'>482</a>
548
- <a name='L483'></a><a href='#L483'>483</a>
549
- <a name='L484'></a><a href='#L484'>484</a>
550
- <a name='L485'></a><a href='#L485'>485</a>
551
- <a name='L486'></a><a href='#L486'>486</a>
552
- <a name='L487'></a><a href='#L487'>487</a>
553
- <a name='L488'></a><a href='#L488'>488</a>
554
- <a name='L489'></a><a href='#L489'>489</a>
555
- <a name='L490'></a><a href='#L490'>490</a>
556
- <a name='L491'></a><a href='#L491'>491</a>
557
- <a name='L492'></a><a href='#L492'>492</a>
558
- <a name='L493'></a><a href='#L493'>493</a>
559
- <a name='L494'></a><a href='#L494'>494</a>
560
- <a name='L495'></a><a href='#L495'>495</a>
561
- <a name='L496'></a><a href='#L496'>496</a>
562
- <a name='L497'></a><a href='#L497'>497</a>
563
- <a name='L498'></a><a href='#L498'>498</a>
564
- <a name='L499'></a><a href='#L499'>499</a>
565
- <a name='L500'></a><a href='#L500'>500</a>
566
- <a name='L501'></a><a href='#L501'>501</a>
567
- <a name='L502'></a><a href='#L502'>502</a>
568
- <a name='L503'></a><a href='#L503'>503</a>
569
- <a name='L504'></a><a href='#L504'>504</a>
570
- <a name='L505'></a><a href='#L505'>505</a>
571
- <a name='L506'></a><a href='#L506'>506</a>
572
- <a name='L507'></a><a href='#L507'>507</a>
573
- <a name='L508'></a><a href='#L508'>508</a>
574
- <a name='L509'></a><a href='#L509'>509</a>
575
- <a name='L510'></a><a href='#L510'>510</a>
576
- <a name='L511'></a><a href='#L511'>511</a>
577
- <a name='L512'></a><a href='#L512'>512</a>
578
- <a name='L513'></a><a href='#L513'>513</a>
579
- <a name='L514'></a><a href='#L514'>514</a>
580
- <a name='L515'></a><a href='#L515'>515</a>
581
- <a name='L516'></a><a href='#L516'>516</a>
582
- <a name='L517'></a><a href='#L517'>517</a>
583
- <a name='L518'></a><a href='#L518'>518</a>
584
- <a name='L519'></a><a href='#L519'>519</a>
585
- <a name='L520'></a><a href='#L520'>520</a>
586
- <a name='L521'></a><a href='#L521'>521</a>
587
- <a name='L522'></a><a href='#L522'>522</a>
588
- <a name='L523'></a><a href='#L523'>523</a>
589
- <a name='L524'></a><a href='#L524'>524</a>
590
- <a name='L525'></a><a href='#L525'>525</a>
591
- <a name='L526'></a><a href='#L526'>526</a>
592
- <a name='L527'></a><a href='#L527'>527</a>
593
- <a name='L528'></a><a href='#L528'>528</a>
594
- <a name='L529'></a><a href='#L529'>529</a>
595
- <a name='L530'></a><a href='#L530'>530</a>
596
- <a name='L531'></a><a href='#L531'>531</a>
597
- <a name='L532'></a><a href='#L532'>532</a>
598
- <a name='L533'></a><a href='#L533'>533</a>
599
- <a name='L534'></a><a href='#L534'>534</a>
600
- <a name='L535'></a><a href='#L535'>535</a>
601
- <a name='L536'></a><a href='#L536'>536</a>
602
- <a name='L537'></a><a href='#L537'>537</a>
603
- <a name='L538'></a><a href='#L538'>538</a>
604
- <a name='L539'></a><a href='#L539'>539</a>
605
- <a name='L540'></a><a href='#L540'>540</a>
606
- <a name='L541'></a><a href='#L541'>541</a>
607
- <a name='L542'></a><a href='#L542'>542</a>
608
- <a name='L543'></a><a href='#L543'>543</a>
609
- <a name='L544'></a><a href='#L544'>544</a>
610
- <a name='L545'></a><a href='#L545'>545</a>
611
- <a name='L546'></a><a href='#L546'>546</a>
612
- <a name='L547'></a><a href='#L547'>547</a>
613
- <a name='L548'></a><a href='#L548'>548</a>
614
- <a name='L549'></a><a href='#L549'>549</a>
615
- <a name='L550'></a><a href='#L550'>550</a>
616
- <a name='L551'></a><a href='#L551'>551</a>
617
- <a name='L552'></a><a href='#L552'>552</a>
618
- <a name='L553'></a><a href='#L553'>553</a>
619
- <a name='L554'></a><a href='#L554'>554</a>
620
- <a name='L555'></a><a href='#L555'>555</a>
621
- <a name='L556'></a><a href='#L556'>556</a>
622
- <a name='L557'></a><a href='#L557'>557</a>
623
- <a name='L558'></a><a href='#L558'>558</a>
624
- <a name='L559'></a><a href='#L559'>559</a>
625
- <a name='L560'></a><a href='#L560'>560</a>
626
- <a name='L561'></a><a href='#L561'>561</a>
627
- <a name='L562'></a><a href='#L562'>562</a>
628
- <a name='L563'></a><a href='#L563'>563</a>
629
- <a name='L564'></a><a href='#L564'>564</a>
630
- <a name='L565'></a><a href='#L565'>565</a>
631
- <a name='L566'></a><a href='#L566'>566</a>
632
- <a name='L567'></a><a href='#L567'>567</a>
633
- <a name='L568'></a><a href='#L568'>568</a>
634
- <a name='L569'></a><a href='#L569'>569</a>
635
- <a name='L570'></a><a href='#L570'>570</a>
636
- <a name='L571'></a><a href='#L571'>571</a>
637
- <a name='L572'></a><a href='#L572'>572</a>
638
- <a name='L573'></a><a href='#L573'>573</a>
639
- <a name='L574'></a><a href='#L574'>574</a>
640
- <a name='L575'></a><a href='#L575'>575</a>
641
- <a name='L576'></a><a href='#L576'>576</a>
642
- <a name='L577'></a><a href='#L577'>577</a>
643
- <a name='L578'></a><a href='#L578'>578</a>
644
- <a name='L579'></a><a href='#L579'>579</a>
645
- <a name='L580'></a><a href='#L580'>580</a>
646
- <a name='L581'></a><a href='#L581'>581</a>
647
- <a name='L582'></a><a href='#L582'>582</a>
648
- <a name='L583'></a><a href='#L583'>583</a>
649
- <a name='L584'></a><a href='#L584'>584</a>
650
- <a name='L585'></a><a href='#L585'>585</a>
651
- <a name='L586'></a><a href='#L586'>586</a>
652
- <a name='L587'></a><a href='#L587'>587</a>
653
- <a name='L588'></a><a href='#L588'>588</a>
654
- <a name='L589'></a><a href='#L589'>589</a>
655
- <a name='L590'></a><a href='#L590'>590</a>
656
- <a name='L591'></a><a href='#L591'>591</a>
657
- <a name='L592'></a><a href='#L592'>592</a>
658
- <a name='L593'></a><a href='#L593'>593</a>
659
- <a name='L594'></a><a href='#L594'>594</a>
660
- <a name='L595'></a><a href='#L595'>595</a>
661
- <a name='L596'></a><a href='#L596'>596</a>
662
- <a name='L597'></a><a href='#L597'>597</a>
663
- <a name='L598'></a><a href='#L598'>598</a>
664
- <a name='L599'></a><a href='#L599'>599</a>
665
- <a name='L600'></a><a href='#L600'>600</a>
666
- <a name='L601'></a><a href='#L601'>601</a>
667
- <a name='L602'></a><a href='#L602'>602</a>
668
- <a name='L603'></a><a href='#L603'>603</a>
669
- <a name='L604'></a><a href='#L604'>604</a>
670
- <a name='L605'></a><a href='#L605'>605</a>
671
- <a name='L606'></a><a href='#L606'>606</a>
672
- <a name='L607'></a><a href='#L607'>607</a>
673
- <a name='L608'></a><a href='#L608'>608</a>
674
- <a name='L609'></a><a href='#L609'>609</a>
675
- <a name='L610'></a><a href='#L610'>610</a>
676
- <a name='L611'></a><a href='#L611'>611</a>
677
- <a name='L612'></a><a href='#L612'>612</a>
678
- <a name='L613'></a><a href='#L613'>613</a>
679
- <a name='L614'></a><a href='#L614'>614</a>
680
- <a name='L615'></a><a href='#L615'>615</a>
681
- <a name='L616'></a><a href='#L616'>616</a>
682
- <a name='L617'></a><a href='#L617'>617</a>
683
- <a name='L618'></a><a href='#L618'>618</a>
684
- <a name='L619'></a><a href='#L619'>619</a>
685
- <a name='L620'></a><a href='#L620'>620</a>
686
- <a name='L621'></a><a href='#L621'>621</a>
687
- <a name='L622'></a><a href='#L622'>622</a>
688
- <a name='L623'></a><a href='#L623'>623</a>
689
- <a name='L624'></a><a href='#L624'>624</a>
690
- <a name='L625'></a><a href='#L625'>625</a>
691
- <a name='L626'></a><a href='#L626'>626</a>
692
- <a name='L627'></a><a href='#L627'>627</a>
693
- <a name='L628'></a><a href='#L628'>628</a>
694
- <a name='L629'></a><a href='#L629'>629</a>
695
- <a name='L630'></a><a href='#L630'>630</a>
696
- <a name='L631'></a><a href='#L631'>631</a>
697
- <a name='L632'></a><a href='#L632'>632</a>
698
- <a name='L633'></a><a href='#L633'>633</a>
699
- <a name='L634'></a><a href='#L634'>634</a>
700
- <a name='L635'></a><a href='#L635'>635</a>
701
- <a name='L636'></a><a href='#L636'>636</a>
702
- <a name='L637'></a><a href='#L637'>637</a>
703
- <a name='L638'></a><a href='#L638'>638</a>
704
- <a name='L639'></a><a href='#L639'>639</a>
705
- <a name='L640'></a><a href='#L640'>640</a>
706
- <a name='L641'></a><a href='#L641'>641</a>
707
- <a name='L642'></a><a href='#L642'>642</a>
708
- <a name='L643'></a><a href='#L643'>643</a>
709
- <a name='L644'></a><a href='#L644'>644</a>
710
- <a name='L645'></a><a href='#L645'>645</a>
711
- <a name='L646'></a><a href='#L646'>646</a>
712
- <a name='L647'></a><a href='#L647'>647</a>
713
- <a name='L648'></a><a href='#L648'>648</a>
714
- <a name='L649'></a><a href='#L649'>649</a>
715
- <a name='L650'></a><a href='#L650'>650</a>
716
- <a name='L651'></a><a href='#L651'>651</a>
717
- <a name='L652'></a><a href='#L652'>652</a>
718
- <a name='L653'></a><a href='#L653'>653</a>
719
- <a name='L654'></a><a href='#L654'>654</a>
720
- <a name='L655'></a><a href='#L655'>655</a>
721
- <a name='L656'></a><a href='#L656'>656</a>
722
- <a name='L657'></a><a href='#L657'>657</a>
723
- <a name='L658'></a><a href='#L658'>658</a>
724
- <a name='L659'></a><a href='#L659'>659</a>
725
- <a name='L660'></a><a href='#L660'>660</a>
726
- <a name='L661'></a><a href='#L661'>661</a>
727
- <a name='L662'></a><a href='#L662'>662</a>
728
- <a name='L663'></a><a href='#L663'>663</a>
729
- <a name='L664'></a><a href='#L664'>664</a>
730
- <a name='L665'></a><a href='#L665'>665</a>
731
- <a name='L666'></a><a href='#L666'>666</a>
732
- <a name='L667'></a><a href='#L667'>667</a>
733
- <a name='L668'></a><a href='#L668'>668</a>
734
- <a name='L669'></a><a href='#L669'>669</a>
735
- <a name='L670'></a><a href='#L670'>670</a>
736
- <a name='L671'></a><a href='#L671'>671</a>
737
- <a name='L672'></a><a href='#L672'>672</a>
738
- <a name='L673'></a><a href='#L673'>673</a>
739
- <a name='L674'></a><a href='#L674'>674</a>
740
- <a name='L675'></a><a href='#L675'>675</a>
741
- <a name='L676'></a><a href='#L676'>676</a>
742
- <a name='L677'></a><a href='#L677'>677</a>
743
- <a name='L678'></a><a href='#L678'>678</a>
744
- <a name='L679'></a><a href='#L679'>679</a>
745
- <a name='L680'></a><a href='#L680'>680</a>
746
- <a name='L681'></a><a href='#L681'>681</a>
747
- <a name='L682'></a><a href='#L682'>682</a>
748
- <a name='L683'></a><a href='#L683'>683</a>
749
- <a name='L684'></a><a href='#L684'>684</a>
750
- <a name='L685'></a><a href='#L685'>685</a>
751
- <a name='L686'></a><a href='#L686'>686</a>
752
- <a name='L687'></a><a href='#L687'>687</a>
753
- <a name='L688'></a><a href='#L688'>688</a>
754
- <a name='L689'></a><a href='#L689'>689</a>
755
- <a name='L690'></a><a href='#L690'>690</a>
756
- <a name='L691'></a><a href='#L691'>691</a>
757
- <a name='L692'></a><a href='#L692'>692</a>
758
- <a name='L693'></a><a href='#L693'>693</a>
759
- <a name='L694'></a><a href='#L694'>694</a>
760
- <a name='L695'></a><a href='#L695'>695</a>
761
- <a name='L696'></a><a href='#L696'>696</a>
762
- <a name='L697'></a><a href='#L697'>697</a>
763
- <a name='L698'></a><a href='#L698'>698</a>
764
- <a name='L699'></a><a href='#L699'>699</a>
765
- <a name='L700'></a><a href='#L700'>700</a>
766
- <a name='L701'></a><a href='#L701'>701</a>
767
- <a name='L702'></a><a href='#L702'>702</a>
768
- <a name='L703'></a><a href='#L703'>703</a>
769
- <a name='L704'></a><a href='#L704'>704</a>
770
- <a name='L705'></a><a href='#L705'>705</a>
771
- <a name='L706'></a><a href='#L706'>706</a>
772
- <a name='L707'></a><a href='#L707'>707</a>
773
- <a name='L708'></a><a href='#L708'>708</a>
774
- <a name='L709'></a><a href='#L709'>709</a>
775
- <a name='L710'></a><a href='#L710'>710</a>
776
- <a name='L711'></a><a href='#L711'>711</a>
777
- <a name='L712'></a><a href='#L712'>712</a>
778
- <a name='L713'></a><a href='#L713'>713</a>
779
- <a name='L714'></a><a href='#L714'>714</a>
780
- <a name='L715'></a><a href='#L715'>715</a>
781
- <a name='L716'></a><a href='#L716'>716</a>
782
- <a name='L717'></a><a href='#L717'>717</a>
783
- <a name='L718'></a><a href='#L718'>718</a>
784
- <a name='L719'></a><a href='#L719'>719</a>
785
- <a name='L720'></a><a href='#L720'>720</a>
786
- <a name='L721'></a><a href='#L721'>721</a>
787
- <a name='L722'></a><a href='#L722'>722</a>
788
- <a name='L723'></a><a href='#L723'>723</a>
789
- <a name='L724'></a><a href='#L724'>724</a>
790
- <a name='L725'></a><a href='#L725'>725</a>
791
- <a name='L726'></a><a href='#L726'>726</a>
792
- <a name='L727'></a><a href='#L727'>727</a>
793
- <a name='L728'></a><a href='#L728'>728</a>
794
- <a name='L729'></a><a href='#L729'>729</a>
795
- <a name='L730'></a><a href='#L730'>730</a>
796
- <a name='L731'></a><a href='#L731'>731</a>
797
- <a name='L732'></a><a href='#L732'>732</a>
798
- <a name='L733'></a><a href='#L733'>733</a>
799
- <a name='L734'></a><a href='#L734'>734</a>
800
- <a name='L735'></a><a href='#L735'>735</a>
801
- <a name='L736'></a><a href='#L736'>736</a>
802
- <a name='L737'></a><a href='#L737'>737</a>
803
- <a name='L738'></a><a href='#L738'>738</a>
804
- <a name='L739'></a><a href='#L739'>739</a>
805
- <a name='L740'></a><a href='#L740'>740</a>
806
- <a name='L741'></a><a href='#L741'>741</a>
807
- <a name='L742'></a><a href='#L742'>742</a>
808
- <a name='L743'></a><a href='#L743'>743</a>
809
- <a name='L744'></a><a href='#L744'>744</a>
810
- <a name='L745'></a><a href='#L745'>745</a>
811
- <a name='L746'></a><a href='#L746'>746</a>
812
- <a name='L747'></a><a href='#L747'>747</a>
813
- <a name='L748'></a><a href='#L748'>748</a>
814
- <a name='L749'></a><a href='#L749'>749</a>
815
- <a name='L750'></a><a href='#L750'>750</a>
816
- <a name='L751'></a><a href='#L751'>751</a>
817
- <a name='L752'></a><a href='#L752'>752</a>
818
- <a name='L753'></a><a href='#L753'>753</a>
819
- <a name='L754'></a><a href='#L754'>754</a>
820
- <a name='L755'></a><a href='#L755'>755</a>
821
- <a name='L756'></a><a href='#L756'>756</a>
822
- <a name='L757'></a><a href='#L757'>757</a>
823
- <a name='L758'></a><a href='#L758'>758</a>
824
- <a name='L759'></a><a href='#L759'>759</a>
825
- <a name='L760'></a><a href='#L760'>760</a>
826
- <a name='L761'></a><a href='#L761'>761</a>
827
- <a name='L762'></a><a href='#L762'>762</a>
828
- <a name='L763'></a><a href='#L763'>763</a>
829
- <a name='L764'></a><a href='#L764'>764</a>
830
- <a name='L765'></a><a href='#L765'>765</a>
831
- <a name='L766'></a><a href='#L766'>766</a>
832
- <a name='L767'></a><a href='#L767'>767</a>
833
- <a name='L768'></a><a href='#L768'>768</a>
834
- <a name='L769'></a><a href='#L769'>769</a>
835
- <a name='L770'></a><a href='#L770'>770</a>
836
- <a name='L771'></a><a href='#L771'>771</a>
837
- <a name='L772'></a><a href='#L772'>772</a>
838
- <a name='L773'></a><a href='#L773'>773</a>
839
- <a name='L774'></a><a href='#L774'>774</a>
840
- <a name='L775'></a><a href='#L775'>775</a>
841
- <a name='L776'></a><a href='#L776'>776</a>
842
- <a name='L777'></a><a href='#L777'>777</a>
843
- <a name='L778'></a><a href='#L778'>778</a>
844
- <a name='L779'></a><a href='#L779'>779</a>
845
- <a name='L780'></a><a href='#L780'>780</a>
846
- <a name='L781'></a><a href='#L781'>781</a>
847
- <a name='L782'></a><a href='#L782'>782</a>
848
- <a name='L783'></a><a href='#L783'>783</a>
849
- <a name='L784'></a><a href='#L784'>784</a>
850
- <a name='L785'></a><a href='#L785'>785</a>
851
- <a name='L786'></a><a href='#L786'>786</a>
852
- <a name='L787'></a><a href='#L787'>787</a>
853
- <a name='L788'></a><a href='#L788'>788</a>
854
- <a name='L789'></a><a href='#L789'>789</a>
855
- <a name='L790'></a><a href='#L790'>790</a>
856
- <a name='L791'></a><a href='#L791'>791</a>
857
- <a name='L792'></a><a href='#L792'>792</a>
858
- <a name='L793'></a><a href='#L793'>793</a>
859
- <a name='L794'></a><a href='#L794'>794</a>
860
- <a name='L795'></a><a href='#L795'>795</a>
861
- <a name='L796'></a><a href='#L796'>796</a>
862
- <a name='L797'></a><a href='#L797'>797</a>
863
- <a name='L798'></a><a href='#L798'>798</a>
864
- <a name='L799'></a><a href='#L799'>799</a>
865
- <a name='L800'></a><a href='#L800'>800</a>
866
- <a name='L801'></a><a href='#L801'>801</a>
867
- <a name='L802'></a><a href='#L802'>802</a>
868
- <a name='L803'></a><a href='#L803'>803</a>
869
- <a name='L804'></a><a href='#L804'>804</a>
870
- <a name='L805'></a><a href='#L805'>805</a>
871
- <a name='L806'></a><a href='#L806'>806</a>
872
- <a name='L807'></a><a href='#L807'>807</a>
873
- <a name='L808'></a><a href='#L808'>808</a>
874
- <a name='L809'></a><a href='#L809'>809</a>
875
- <a name='L810'></a><a href='#L810'>810</a>
876
- <a name='L811'></a><a href='#L811'>811</a>
877
- <a name='L812'></a><a href='#L812'>812</a>
878
- <a name='L813'></a><a href='#L813'>813</a>
879
- <a name='L814'></a><a href='#L814'>814</a>
880
- <a name='L815'></a><a href='#L815'>815</a>
881
- <a name='L816'></a><a href='#L816'>816</a>
882
- <a name='L817'></a><a href='#L817'>817</a>
883
- <a name='L818'></a><a href='#L818'>818</a>
884
- <a name='L819'></a><a href='#L819'>819</a>
885
- <a name='L820'></a><a href='#L820'>820</a>
886
- <a name='L821'></a><a href='#L821'>821</a>
887
- <a name='L822'></a><a href='#L822'>822</a>
888
- <a name='L823'></a><a href='#L823'>823</a>
889
- <a name='L824'></a><a href='#L824'>824</a>
890
- <a name='L825'></a><a href='#L825'>825</a>
891
- <a name='L826'></a><a href='#L826'>826</a>
892
- <a name='L827'></a><a href='#L827'>827</a>
893
- <a name='L828'></a><a href='#L828'>828</a>
894
- <a name='L829'></a><a href='#L829'>829</a>
895
- <a name='L830'></a><a href='#L830'>830</a>
896
- <a name='L831'></a><a href='#L831'>831</a>
897
- <a name='L832'></a><a href='#L832'>832</a>
898
- <a name='L833'></a><a href='#L833'>833</a>
899
- <a name='L834'></a><a href='#L834'>834</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
900
- <span class="cline-any cline-neutral">&nbsp;</span>
901
- <span class="cline-any cline-neutral">&nbsp;</span>
902
- <span class="cline-any cline-neutral">&nbsp;</span>
903
- <span class="cline-any cline-neutral">&nbsp;</span>
904
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
913
- <span class="cline-any cline-neutral">&nbsp;</span>
914
- <span class="cline-any cline-neutral">&nbsp;</span>
915
- <span class="cline-any cline-neutral">&nbsp;</span>
916
- <span class="cline-any cline-neutral">&nbsp;</span>
917
- <span class="cline-any cline-yes">23x</span>
918
- <span class="cline-any cline-neutral">&nbsp;</span>
919
- <span class="cline-any cline-yes">2x</span>
920
- <span class="cline-any cline-neutral">&nbsp;</span>
921
- <span class="cline-any cline-yes">2x</span>
922
- <span class="cline-any cline-neutral">&nbsp;</span>
923
- <span class="cline-any cline-yes">1x</span>
924
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
928
- <span class="cline-any cline-no">&nbsp;</span>
929
- <span class="cline-any cline-neutral">&nbsp;</span>
930
- <span class="cline-any cline-yes">18x</span>
931
- <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
936
- <span class="cline-any cline-neutral">&nbsp;</span>
937
- <span class="cline-any cline-neutral">&nbsp;</span>
938
- <span class="cline-any cline-neutral">&nbsp;</span>
939
- <span class="cline-any cline-yes">18x</span>
940
- <span class="cline-any cline-yes">18x</span>
941
- <span class="cline-any cline-neutral">&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-neutral">&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-no">&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-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-no">&nbsp;</span>
956
- <span class="cline-any cline-neutral">&nbsp;</span>
957
- <span class="cline-any cline-neutral">&nbsp;</span>
958
- <span class="cline-any cline-no">&nbsp;</span>
959
- <span class="cline-any cline-no">&nbsp;</span>
960
- <span class="cline-any cline-neutral">&nbsp;</span>
961
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
965
- <span class="cline-any cline-neutral">&nbsp;</span>
966
- <span class="cline-any cline-neutral">&nbsp;</span>
967
- <span class="cline-any cline-no">&nbsp;</span>
968
- <span class="cline-any cline-no">&nbsp;</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-no">&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-no">&nbsp;</span>
976
- <span class="cline-any cline-neutral">&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-yes">18x</span>
980
- <span class="cline-any cline-yes">18x</span>
981
- <span class="cline-any cline-neutral">&nbsp;</span>
982
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
986
- <span class="cline-any cline-neutral">&nbsp;</span>
987
- <span class="cline-any cline-no">&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-no">&nbsp;</span>
991
- <span class="cline-any cline-no">&nbsp;</span>
992
- <span class="cline-any cline-no">&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-neutral">&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-neutral">&nbsp;</span>
1001
- <span class="cline-any cline-neutral">&nbsp;</span>
1002
- <span class="cline-any cline-neutral">&nbsp;</span>
1003
- <span class="cline-any cline-neutral">&nbsp;</span>
1004
- <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
1015
- <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</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-neutral">&nbsp;</span>
1022
- <span class="cline-any cline-neutral">&nbsp;</span>
1023
- <span class="cline-any cline-neutral">&nbsp;</span>
1024
- <span class="cline-any cline-neutral">&nbsp;</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-yes">111x</span>
1030
- <span class="cline-any cline-yes">111x</span>
1031
- <span class="cline-any cline-yes">111x</span>
1032
- <span class="cline-any cline-yes">111x</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-yes">111x</span>
1037
- <span class="cline-any cline-yes">111x</span>
1038
- <span class="cline-any cline-yes">111x</span>
1039
- <span class="cline-any cline-yes">111x</span>
1040
- <span class="cline-any cline-yes">111x</span>
1041
- <span class="cline-any cline-yes">111x</span>
1042
- <span class="cline-any cline-yes">111x</span>
1043
- <span class="cline-any cline-neutral">&nbsp;</span>
1044
- <span class="cline-any cline-yes">111x</span>
1045
- <span class="cline-any cline-yes">110x</span>
1046
- <span class="cline-any cline-yes">110x</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-yes">111x</span>
1050
- <span class="cline-any cline-yes">47x</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-yes">111x</span>
1054
- <span class="cline-any cline-yes">2x</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-yes">111x</span>
1058
- <span class="cline-any cline-yes">50x</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-yes">111x</span>
1062
- <span class="cline-any cline-yes">2x</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-yes">111x</span>
1066
- <span class="cline-any cline-yes">111x</span>
1067
- <span class="cline-any cline-no">&nbsp;</span>
1068
- <span class="cline-any cline-neutral">&nbsp;</span>
1069
- <span class="cline-any cline-yes">111x</span>
1070
- <span class="cline-any cline-yes">1x</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-yes">111x</span>
1075
- <span class="cline-any cline-no">&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-neutral">&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">111x</span>
1082
- <span class="cline-any cline-neutral">&nbsp;</span>
1083
- <span class="cline-any cline-yes">111x</span>
1084
- <span class="cline-any cline-yes">111x</span>
1085
- <span class="cline-any cline-yes">111x</span>
1086
- <span class="cline-any cline-yes">111x</span>
1087
- <span class="cline-any cline-yes">111x</span>
1088
- <span class="cline-any cline-yes">111x</span>
1089
- <span class="cline-any cline-yes">111x</span>
1090
- <span class="cline-any cline-neutral">&nbsp;</span>
1091
- <span class="cline-any cline-yes">111x</span>
1092
- <span class="cline-any cline-yes">111x</span>
1093
- <span class="cline-any cline-yes">111x</span>
1094
- <span class="cline-any cline-yes">113x</span>
1095
- <span class="cline-any cline-yes">112x</span>
1096
- <span class="cline-any cline-yes">112x</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-yes">111x</span>
1101
- <span class="cline-any cline-yes">111x</span>
1102
- <span class="cline-any cline-yes">111x</span>
1103
- <span class="cline-any cline-neutral">&nbsp;</span>
1104
- <span class="cline-any cline-neutral">&nbsp;</span>
1105
- <span class="cline-any cline-neutral">&nbsp;</span>
1106
- <span class="cline-any cline-neutral">&nbsp;</span>
1107
- <span class="cline-any cline-neutral">&nbsp;</span>
1108
- <span class="cline-any cline-yes">112x</span>
1109
- <span class="cline-any cline-yes">112x</span>
1110
- <span class="cline-any cline-yes">112x</span>
1111
- <span class="cline-any cline-yes">112x</span>
1112
- <span class="cline-any cline-neutral">&nbsp;</span>
1113
- <span class="cline-any cline-yes">112x</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-yes">112x</span>
1117
- <span class="cline-any cline-yes">112x</span>
1118
- <span class="cline-any cline-yes">2x</span>
1119
- <span class="cline-any cline-neutral">&nbsp;</span>
1120
- <span class="cline-any cline-neutral">&nbsp;</span>
1121
- <span class="cline-any cline-yes">112x</span>
1122
- <span class="cline-any cline-yes">112x</span>
1123
- <span class="cline-any cline-neutral">&nbsp;</span>
1124
- <span class="cline-any cline-neutral">&nbsp;</span>
1125
- <span class="cline-any cline-yes">112x</span>
1126
- <span class="cline-any cline-yes">112x</span>
1127
- <span class="cline-any cline-yes">3x</span>
1128
- <span class="cline-any cline-neutral">&nbsp;</span>
1129
- <span class="cline-any cline-neutral">&nbsp;</span>
1130
- <span class="cline-any cline-neutral">&nbsp;</span>
1131
- <span class="cline-any cline-yes">112x</span>
1132
- <span class="cline-any cline-yes">112x</span>
1133
- <span class="cline-any cline-yes">112x</span>
1134
- <span class="cline-any cline-neutral">&nbsp;</span>
1135
- <span class="cline-any cline-yes">112x</span>
1136
- <span class="cline-any cline-neutral">&nbsp;</span>
1137
- <span class="cline-any cline-yes">112x</span>
1138
- <span class="cline-any cline-yes">112x</span>
1139
- <span class="cline-any cline-yes">112x</span>
1140
- <span class="cline-any cline-yes">112x</span>
1141
- <span class="cline-any cline-yes">112x</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-yes">112x</span>
1145
- <span class="cline-any cline-yes">112x</span>
1146
- <span class="cline-any cline-yes">109x</span>
1147
- <span class="cline-any cline-neutral">&nbsp;</span>
1148
- <span class="cline-any cline-yes">109x</span>
1149
- <span class="cline-any cline-neutral">&nbsp;</span>
1150
- <span class="cline-any cline-neutral">&nbsp;</span>
1151
- <span class="cline-any cline-neutral">&nbsp;</span>
1152
- <span class="cline-any cline-neutral">&nbsp;</span>
1153
- <span class="cline-any cline-yes">109x</span>
1154
- <span class="cline-any cline-neutral">&nbsp;</span>
1155
- <span class="cline-any cline-yes">112x</span>
1156
- <span class="cline-any cline-yes">23x</span>
1157
- <span class="cline-any cline-yes">23x</span>
1158
- <span class="cline-any cline-yes">20x</span>
1159
- <span class="cline-any cline-neutral">&nbsp;</span>
1160
- <span class="cline-any cline-yes">112x</span>
1161
- <span class="cline-any cline-yes">6x</span>
1162
- <span class="cline-any cline-neutral">&nbsp;</span>
1163
- <span class="cline-any cline-neutral">&nbsp;</span>
1164
- <span class="cline-any cline-yes">6x</span>
1165
- <span class="cline-any cline-neutral">&nbsp;</span>
1166
- <span class="cline-any cline-yes">112x</span>
1167
- <span class="cline-any cline-neutral">&nbsp;</span>
1168
- <span class="cline-any cline-yes">112x</span>
1169
- <span class="cline-any cline-neutral">&nbsp;</span>
1170
- <span class="cline-any cline-neutral">&nbsp;</span>
1171
- <span class="cline-any cline-yes">112x</span>
1172
- <span class="cline-any cline-yes">112x</span>
1173
- <span class="cline-any cline-yes">112x</span>
1174
- <span class="cline-any cline-neutral">&nbsp;</span>
1175
- <span class="cline-any cline-neutral">&nbsp;</span>
1176
- <span class="cline-any cline-yes">112x</span>
1177
- <span class="cline-any cline-yes">20x</span>
1178
- <span class="cline-any cline-yes">1x</span>
1179
- <span class="cline-any cline-yes">1x</span>
1180
- <span class="cline-any cline-yes">19x</span>
1181
- <span class="cline-any cline-yes">16x</span>
1182
- <span class="cline-any cline-yes">16x</span>
1183
- <span class="cline-any cline-yes">6x</span>
1184
- <span class="cline-any cline-neutral">&nbsp;</span>
1185
- <span class="cline-any cline-yes">2x</span>
1186
- <span class="cline-any cline-yes">2x</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-yes">1x</span>
1190
- <span class="cline-any cline-neutral">&nbsp;</span>
1191
- <span class="cline-any cline-yes">2x</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-yes">1x</span>
1195
- <span class="cline-any cline-yes">1x</span>
1196
- <span class="cline-any cline-yes">1x</span>
1197
- <span class="cline-any cline-yes">2x</span>
1198
- <span class="cline-any cline-yes">2x</span>
1199
- <span class="cline-any cline-yes">1x</span>
1200
- <span class="cline-any cline-neutral">&nbsp;</span>
1201
- <span class="cline-any cline-yes">1x</span>
1202
- <span class="cline-any cline-neutral">&nbsp;</span>
1203
- <span class="cline-any cline-yes">2x</span>
1204
- <span class="cline-any cline-neutral">&nbsp;</span>
1205
- <span class="cline-any cline-yes">1x</span>
1206
- <span class="cline-any cline-yes">1x</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-yes">112x</span>
1212
- <span class="cline-any cline-yes">112x</span>
1213
- <span class="cline-any cline-yes">112x</span>
1214
- <span class="cline-any cline-yes">112x</span>
1215
- <span class="cline-any cline-yes">112x</span>
1216
- <span class="cline-any cline-neutral">&nbsp;</span>
1217
- <span class="cline-any cline-yes">5x</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-yes">112x</span>
1222
- <span class="cline-any cline-yes">22x</span>
1223
- <span class="cline-any cline-yes">22x</span>
1224
- <span class="cline-any cline-no">&nbsp;</span>
1225
- <span class="cline-any cline-neutral">&nbsp;</span>
1226
- <span class="cline-any cline-yes">22x</span>
1227
- <span class="cline-any cline-yes">22x</span>
1228
- <span class="cline-any cline-yes">3x</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-yes">19x</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-yes">90x</span>
1236
- <span class="cline-any cline-yes">90x</span>
1237
- <span class="cline-any cline-yes">1x</span>
1238
- <span class="cline-any cline-neutral">&nbsp;</span>
1239
- <span class="cline-any cline-yes">89x</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-yes">112x</span>
1244
- <span class="cline-any cline-yes">112x</span>
1245
- <span class="cline-any cline-neutral">&nbsp;</span>
1246
- <span class="cline-any cline-yes">112x</span>
1247
- <span class="cline-any cline-yes">4x</span>
1248
- <span class="cline-any cline-yes">5x</span>
1249
- <span class="cline-any cline-yes">5x</span>
1250
- <span class="cline-any cline-yes">1x</span>
1251
- <span class="cline-any cline-neutral">&nbsp;</span>
1252
- <span class="cline-any cline-yes">4x</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-yes">112x</span>
1258
- <span class="cline-any cline-yes">20x</span>
1259
- <span class="cline-any cline-yes">20x</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-yes">112x</span>
1263
- <span class="cline-any cline-neutral">&nbsp;</span>
1264
- <span class="cline-any cline-yes">112x</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-yes">112x</span>
1272
- <span class="cline-any cline-yes">5x</span>
1273
- <span class="cline-any cline-yes">5x</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-yes">107x</span>
1278
- <span class="cline-any cline-yes">107x</span>
1279
- <span class="cline-any cline-yes">107x</span>
1280
- <span class="cline-any cline-yes">107x</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-yes">107x</span>
1285
- <span class="cline-any cline-yes">107x</span>
1286
- <span class="cline-any cline-neutral">&nbsp;</span>
1287
- <span class="cline-any cline-yes">81x</span>
1288
- <span class="cline-any cline-neutral">&nbsp;</span>
1289
- <span class="cline-any cline-yes">21x</span>
1290
- <span class="cline-any cline-neutral">&nbsp;</span>
1291
- <span class="cline-any cline-yes">1x</span>
1292
- <span class="cline-any cline-neutral">&nbsp;</span>
1293
- <span class="cline-any cline-yes">1x</span>
1294
- <span class="cline-any cline-neutral">&nbsp;</span>
1295
- <span class="cline-any cline-yes">3x</span>
1296
- <span class="cline-any cline-neutral">&nbsp;</span>
1297
- <span class="cline-any cline-no">&nbsp;</span>
1298
- <span class="cline-any cline-neutral">&nbsp;</span>
1299
- <span class="cline-any cline-neutral">&nbsp;</span>
1300
- <span class="cline-any cline-neutral">&nbsp;</span>
1301
- <span class="cline-any cline-neutral">&nbsp;</span>
1302
- <span class="cline-any cline-yes">112x</span>
1303
- <span class="cline-any cline-neutral">&nbsp;</span>
1304
- <span class="cline-any cline-yes">112x</span>
1305
- <span class="cline-any cline-yes">13x</span>
1306
- <span class="cline-any cline-yes">12x</span>
1307
- <span class="cline-any cline-neutral">&nbsp;</span>
1308
- <span class="cline-any cline-yes">1x</span>
1309
- <span class="cline-any cline-neutral">&nbsp;</span>
1310
- <span class="cline-any cline-neutral">&nbsp;</span>
1311
- <span class="cline-any cline-neutral">&nbsp;</span>
1312
- <span class="cline-any cline-yes">112x</span>
1313
- <span class="cline-any cline-yes">20x</span>
1314
- <span class="cline-any cline-yes">20x</span>
1315
- <span class="cline-any cline-yes">20x</span>
1316
- <span class="cline-any cline-neutral">&nbsp;</span>
1317
- <span class="cline-any cline-neutral">&nbsp;</span>
1318
- <span class="cline-any cline-yes">112x</span>
1319
- <span class="cline-any cline-neutral">&nbsp;</span>
1320
- <span class="cline-any cline-yes">112x</span>
1321
- <span class="cline-any cline-yes">112x</span>
1322
- <span class="cline-any cline-neutral">&nbsp;</span>
1323
- <span class="cline-any cline-neutral">&nbsp;</span>
1324
- <span class="cline-any cline-neutral">&nbsp;</span>
1325
- <span class="cline-any cline-yes">26x</span>
1326
- <span class="cline-any cline-yes">4x</span>
1327
- <span class="cline-any cline-yes">4x</span>
1328
- <span class="cline-any cline-neutral">&nbsp;</span>
1329
- <span class="cline-any cline-yes">22x</span>
1330
- <span class="cline-any cline-yes">22x</span>
1331
- <span class="cline-any cline-yes">22x</span>
1332
- <span class="cline-any cline-neutral">&nbsp;</span>
1333
- <span class="cline-any cline-no">&nbsp;</span>
1334
- <span class="cline-any cline-neutral">&nbsp;</span>
1335
- <span class="cline-any cline-no">&nbsp;</span>
1336
- <span class="cline-any cline-no">&nbsp;</span>
1337
- <span class="cline-any cline-neutral">&nbsp;</span>
1338
- <span class="cline-any cline-neutral">&nbsp;</span>
1339
- <span class="cline-any cline-neutral">&nbsp;</span>
1340
- <span class="cline-any cline-neutral">&nbsp;</span>
1341
- <span class="cline-any cline-neutral">&nbsp;</span>
1342
- <span class="cline-any cline-neutral">&nbsp;</span>
1343
- <span class="cline-any cline-neutral">&nbsp;</span>
1344
- <span class="cline-any cline-neutral">&nbsp;</span>
1345
- <span class="cline-any cline-neutral">&nbsp;</span>
1346
- <span class="cline-any cline-neutral">&nbsp;</span>
1347
- <span class="cline-any cline-neutral">&nbsp;</span>
1348
- <span class="cline-any cline-neutral">&nbsp;</span>
1349
- <span class="cline-any cline-neutral">&nbsp;</span>
1350
- <span class="cline-any cline-yes">336x</span>
1351
- <span class="cline-any cline-yes">31x</span>
1352
- <span class="cline-any cline-yes">31x</span>
1353
- <span class="cline-any cline-yes">31x</span>
1354
- <span class="cline-any cline-neutral">&nbsp;</span>
1355
- <span class="cline-any cline-yes">4x</span>
1356
- <span class="cline-any cline-yes">4x</span>
1357
- <span class="cline-any cline-yes">4x</span>
1358
- <span class="cline-any cline-yes">27x</span>
1359
- <span class="cline-any cline-neutral">&nbsp;</span>
1360
- <span class="cline-any cline-yes">23x</span>
1361
- <span class="cline-any cline-neutral">&nbsp;</span>
1362
- <span class="cline-any cline-neutral">&nbsp;</span>
1363
- <span class="cline-any cline-yes">23x</span>
1364
- <span class="cline-any cline-yes">23x</span>
1365
- <span class="cline-any cline-yes">23x</span>
1366
- <span class="cline-any cline-yes">23x</span>
1367
- <span class="cline-any cline-yes">23x</span>
1368
- <span class="cline-any cline-yes">28x</span>
1369
- <span class="cline-any cline-yes">28x</span>
1370
- <span class="cline-any cline-yes">1x</span>
1371
- <span class="cline-any cline-yes">1x</span>
1372
- <span class="cline-any cline-neutral">&nbsp;</span>
1373
- <span class="cline-any cline-yes">27x</span>
1374
- <span class="cline-any cline-neutral">&nbsp;</span>
1375
- <span class="cline-any cline-neutral">&nbsp;</span>
1376
- <span class="cline-any cline-yes">23x</span>
1377
- <span class="cline-any cline-yes">23x</span>
1378
- <span class="cline-any cline-yes">23x</span>
1379
- <span class="cline-any cline-neutral">&nbsp;</span>
1380
- <span class="cline-any cline-neutral">&nbsp;</span>
1381
- <span class="cline-any cline-neutral">&nbsp;</span>
1382
- <span class="cline-any cline-neutral">&nbsp;</span>
1383
- <span class="cline-any cline-yes">4x</span>
1384
- <span class="cline-any cline-yes">4x</span>
1385
- <span class="cline-any cline-yes">4x</span>
1386
- <span class="cline-any cline-neutral">&nbsp;</span>
1387
- <span class="cline-any cline-yes">31x</span>
1388
- <span class="cline-any cline-neutral">&nbsp;</span>
1389
- <span class="cline-any cline-neutral">&nbsp;</span>
1390
- <span class="cline-any cline-neutral">&nbsp;</span>
1391
- <span class="cline-any cline-neutral">&nbsp;</span>
1392
- <span class="cline-any cline-neutral">&nbsp;</span>
1393
- <span class="cline-any cline-neutral">&nbsp;</span>
1394
- <span class="cline-any cline-neutral">&nbsp;</span>
1395
- <span class="cline-any cline-neutral">&nbsp;</span>
1396
- <span class="cline-any cline-neutral">&nbsp;</span>
1397
- <span class="cline-any cline-neutral">&nbsp;</span>
1398
- <span class="cline-any cline-neutral">&nbsp;</span>
1399
- <span class="cline-any cline-yes">47x</span>
1400
- <span class="cline-any cline-yes">47x</span>
1401
- <span class="cline-any cline-neutral">&nbsp;</span>
1402
- <span class="cline-any cline-yes">47x</span>
1403
- <span class="cline-any cline-neutral">&nbsp;</span>
1404
- <span class="cline-any cline-yes">2x</span>
1405
- <span class="cline-any cline-yes">2x</span>
1406
- <span class="cline-any cline-neutral">&nbsp;</span>
1407
- <span class="cline-any cline-yes">2x</span>
1408
- <span class="cline-any cline-yes">2x</span>
1409
- <span class="cline-any cline-yes">2x</span>
1410
- <span class="cline-any cline-no">&nbsp;</span>
1411
- <span class="cline-any cline-no">&nbsp;</span>
1412
- <span class="cline-any cline-no">&nbsp;</span>
1413
- <span class="cline-any cline-neutral">&nbsp;</span>
1414
- <span class="cline-any cline-yes">2x</span>
1415
- <span class="cline-any cline-neutral">&nbsp;</span>
1416
- <span class="cline-any cline-neutral">&nbsp;</span>
1417
- <span class="cline-any cline-neutral">&nbsp;</span>
1418
- <span class="cline-any cline-neutral">&nbsp;</span>
1419
- <span class="cline-any cline-yes">2x</span>
1420
- <span class="cline-any cline-yes">2x</span>
1421
- <span class="cline-any cline-no">&nbsp;</span>
1422
- <span class="cline-any cline-no">&nbsp;</span>
1423
- <span class="cline-any cline-no">&nbsp;</span>
1424
- <span class="cline-any cline-no">&nbsp;</span>
1425
- <span class="cline-any cline-neutral">&nbsp;</span>
1426
- <span class="cline-any cline-neutral">&nbsp;</span>
1427
- <span class="cline-any cline-neutral">&nbsp;</span>
1428
- <span class="cline-any cline-yes">2x</span>
1429
- <span class="cline-any cline-yes">2x</span>
1430
- <span class="cline-any cline-yes">2x</span>
1431
- <span class="cline-any cline-neutral">&nbsp;</span>
1432
- <span class="cline-any cline-neutral">&nbsp;</span>
1433
- <span class="cline-any cline-neutral">&nbsp;</span>
1434
- <span class="cline-any cline-yes">45x</span>
1435
- <span class="cline-any cline-yes">45x</span>
1436
- <span class="cline-any cline-neutral">&nbsp;</span>
1437
- <span class="cline-any cline-neutral">&nbsp;</span>
1438
- <span class="cline-any cline-yes">47x</span>
1439
- <span class="cline-any cline-neutral">&nbsp;</span>
1440
- <span class="cline-any cline-neutral">&nbsp;</span>
1441
- <span class="cline-any cline-neutral">&nbsp;</span>
1442
- <span class="cline-any cline-neutral">&nbsp;</span>
1443
- <span class="cline-any cline-neutral">&nbsp;</span>
1444
- <span class="cline-any cline-yes">111x</span>
1445
- <span class="cline-any cline-yes">111x</span>
1446
- <span class="cline-any cline-yes">111x</span>
1447
- <span class="cline-any cline-yes">111x</span>
1448
- <span class="cline-any cline-yes">111x</span>
1449
- <span class="cline-any cline-yes">113x</span>
1450
- <span class="cline-any cline-yes">20x</span>
1451
- <span class="cline-any cline-yes">23x</span>
1452
- <span class="cline-any cline-yes">23x</span>
1453
- <span class="cline-any cline-neutral">&nbsp;</span>
1454
- <span class="cline-any cline-neutral">&nbsp;</span>
1455
- <span class="cline-any cline-yes">113x</span>
1456
- <span class="cline-any cline-yes">25x</span>
1457
- <span class="cline-any cline-yes">23x</span>
1458
- <span class="cline-any cline-yes">23x</span>
1459
- <span class="cline-any cline-neutral">&nbsp;</span>
1460
- <span class="cline-any cline-yes">25x</span>
1461
- <span class="cline-any cline-yes">4x</span>
1462
- <span class="cline-any cline-yes">5x</span>
1463
- <span class="cline-any cline-yes">5x</span>
1464
- <span class="cline-any cline-neutral">&nbsp;</span>
1465
- <span class="cline-any cline-neutral">&nbsp;</span>
1466
- <span class="cline-any cline-neutral">&nbsp;</span>
1467
- <span class="cline-any cline-yes">113x</span>
1468
- <span class="cline-any cline-yes">113x</span>
1469
- <span class="cline-any cline-yes">113x</span>
1470
- <span class="cline-any cline-yes">113x</span>
1471
- <span class="cline-any cline-neutral">&nbsp;</span>
1472
- <span class="cline-any cline-neutral">&nbsp;</span>
1473
- <span class="cline-any cline-yes">111x</span>
1474
- <span class="cline-any cline-neutral">&nbsp;</span>
1475
- <span class="cline-any cline-neutral">&nbsp;</span>
1476
- <span class="cline-any cline-neutral">&nbsp;</span>
1477
- <span class="cline-any cline-neutral">&nbsp;</span>
1478
- <span class="cline-any cline-yes">29x</span>
1479
- <span class="cline-any cline-yes">4x</span>
1480
- <span class="cline-any cline-neutral">&nbsp;</span>
1481
- <span class="cline-any cline-yes">3x</span>
1482
- <span class="cline-any cline-yes">3x</span>
1483
- <span class="cline-any cline-neutral">&nbsp;</span>
1484
- <span class="cline-any cline-yes">1x</span>
1485
- <span class="cline-any cline-yes">1x</span>
1486
- <span class="cline-any cline-neutral">&nbsp;</span>
1487
- <span class="cline-any cline-no">&nbsp;</span>
1488
- <span class="cline-any cline-no">&nbsp;</span>
1489
- <span class="cline-any cline-neutral">&nbsp;</span>
1490
- <span class="cline-any cline-no">&nbsp;</span>
1491
- <span class="cline-any cline-no">&nbsp;</span>
1492
- <span class="cline-any cline-no">&nbsp;</span>
1493
- <span class="cline-any cline-neutral">&nbsp;</span>
1494
- <span class="cline-any cline-no">&nbsp;</span>
1495
- <span class="cline-any cline-no">&nbsp;</span>
1496
- <span class="cline-any cline-neutral">&nbsp;</span>
1497
- <span class="cline-any cline-no">&nbsp;</span>
1498
- <span class="cline-any cline-no">&nbsp;</span>
1499
- <span class="cline-any cline-neutral">&nbsp;</span>
1500
- <span class="cline-any cline-no">&nbsp;</span>
1501
- <span class="cline-any cline-no">&nbsp;</span>
1502
- <span class="cline-any cline-neutral">&nbsp;</span>
1503
- <span class="cline-any cline-no">&nbsp;</span>
1504
- <span class="cline-any cline-no">&nbsp;</span>
1505
- <span class="cline-any cline-neutral">&nbsp;</span>
1506
- <span class="cline-any cline-no">&nbsp;</span>
1507
- <span class="cline-any cline-no">&nbsp;</span>
1508
- <span class="cline-any cline-neutral">&nbsp;</span>
1509
- <span class="cline-any cline-neutral">&nbsp;</span>
1510
- <span class="cline-any cline-neutral">&nbsp;</span>
1511
- <span class="cline-any cline-neutral">&nbsp;</span>
1512
- <span class="cline-any cline-yes">337x</span>
1513
- <span class="cline-any cline-yes">30x</span>
1514
- <span class="cline-any cline-yes">4x</span>
1515
- <span class="cline-any cline-yes">26x</span>
1516
- <span class="cline-any cline-yes">22x</span>
1517
- <span class="cline-any cline-yes">27x</span>
1518
- <span class="cline-any cline-neutral">&nbsp;</span>
1519
- <span class="cline-any cline-neutral">&nbsp;</span>
1520
- <span class="cline-any cline-yes">4x</span>
1521
- <span class="cline-any cline-neutral">&nbsp;</span>
1522
- <span class="cline-any cline-neutral">&nbsp;</span>
1523
- <span class="cline-any cline-neutral">&nbsp;</span>
1524
- <span class="cline-any cline-neutral">&nbsp;</span>
1525
- <span class="cline-any cline-neutral">&nbsp;</span>
1526
- <span class="cline-any cline-yes">337x</span>
1527
- <span class="cline-any cline-yes">3x</span>
1528
- <span class="cline-any cline-no">&nbsp;</span>
1529
- <span class="cline-any cline-yes">3x</span>
1530
- <span class="cline-any cline-yes">2x</span>
1531
- <span class="cline-any cline-neutral">&nbsp;</span>
1532
- <span class="cline-any cline-neutral">&nbsp;</span>
1533
- <span class="cline-any cline-neutral">&nbsp;</span>
1534
- <span class="cline-any cline-neutral">&nbsp;</span>
1535
- <span class="cline-any cline-neutral">&nbsp;</span>
1536
- <span class="cline-any cline-yes">30x</span>
1537
- <span class="cline-any cline-yes">8x</span>
1538
- <span class="cline-any cline-neutral">&nbsp;</span>
1539
- <span class="cline-any cline-yes">4x</span>
1540
- <span class="cline-any cline-yes">4x</span>
1541
- <span class="cline-any cline-neutral">&nbsp;</span>
1542
- <span class="cline-any cline-no">&nbsp;</span>
1543
- <span class="cline-any cline-no">&nbsp;</span>
1544
- <span class="cline-any cline-neutral">&nbsp;</span>
1545
- <span class="cline-any cline-no">&nbsp;</span>
1546
- <span class="cline-any cline-no">&nbsp;</span>
1547
- <span class="cline-any cline-neutral">&nbsp;</span>
1548
- <span class="cline-any cline-no">&nbsp;</span>
1549
- <span class="cline-any cline-no">&nbsp;</span>
1550
- <span class="cline-any cline-no">&nbsp;</span>
1551
- <span class="cline-any cline-neutral">&nbsp;</span>
1552
- <span class="cline-any cline-no">&nbsp;</span>
1553
- <span class="cline-any cline-no">&nbsp;</span>
1554
- <span class="cline-any cline-neutral">&nbsp;</span>
1555
- <span class="cline-any cline-no">&nbsp;</span>
1556
- <span class="cline-any cline-no">&nbsp;</span>
1557
- <span class="cline-any cline-neutral">&nbsp;</span>
1558
- <span class="cline-any cline-yes">4x</span>
1559
- <span class="cline-any cline-yes">2x</span>
1560
- <span class="cline-any cline-neutral">&nbsp;</span>
1561
- <span class="cline-any cline-no">&nbsp;</span>
1562
- <span class="cline-any cline-no">&nbsp;</span>
1563
- <span class="cline-any cline-neutral">&nbsp;</span>
1564
- <span class="cline-any cline-yes">1x</span>
1565
- <span class="cline-any cline-yes">1x</span>
1566
- <span class="cline-any cline-neutral">&nbsp;</span>
1567
- <span class="cline-any cline-neutral">&nbsp;</span>
1568
- <span class="cline-any cline-neutral">&nbsp;</span>
1569
- <span class="cline-any cline-neutral">&nbsp;</span>
1570
- <span class="cline-any cline-yes">98x</span>
1571
- <span class="cline-any cline-neutral">&nbsp;</span>
1572
- <span class="cline-any cline-yes">54x</span>
1573
- <span class="cline-any cline-yes">54x</span>
1574
- <span class="cline-any cline-neutral">&nbsp;</span>
1575
- <span class="cline-any cline-yes">6x</span>
1576
- <span class="cline-any cline-yes">6x</span>
1577
- <span class="cline-any cline-neutral">&nbsp;</span>
1578
- <span class="cline-any cline-no">&nbsp;</span>
1579
- <span class="cline-any cline-no">&nbsp;</span>
1580
- <span class="cline-any cline-neutral">&nbsp;</span>
1581
- <span class="cline-any cline-no">&nbsp;</span>
1582
- <span class="cline-any cline-no">&nbsp;</span>
1583
- <span class="cline-any cline-no">&nbsp;</span>
1584
- <span class="cline-any cline-neutral">&nbsp;</span>
1585
- <span class="cline-any cline-no">&nbsp;</span>
1586
- <span class="cline-any cline-no">&nbsp;</span>
1587
- <span class="cline-any cline-neutral">&nbsp;</span>
1588
- <span class="cline-any cline-no">&nbsp;</span>
1589
- <span class="cline-any cline-no">&nbsp;</span>
1590
- <span class="cline-any cline-neutral">&nbsp;</span>
1591
- <span class="cline-any cline-yes">8x</span>
1592
- <span class="cline-any cline-yes">4x</span>
1593
- <span class="cline-any cline-neutral">&nbsp;</span>
1594
- <span class="cline-any cline-no">&nbsp;</span>
1595
- <span class="cline-any cline-no">&nbsp;</span>
1596
- <span class="cline-any cline-neutral">&nbsp;</span>
1597
- <span class="cline-any cline-yes">2x</span>
1598
- <span class="cline-any cline-yes">2x</span>
1599
- <span class="cline-any cline-neutral">&nbsp;</span>
1600
- <span class="cline-any cline-neutral">&nbsp;</span>
1601
- <span class="cline-any cline-neutral">&nbsp;</span>
1602
- <span class="cline-any cline-neutral">&nbsp;</span>
1603
- <span class="cline-any cline-yes">334x</span>
1604
- <span class="cline-any cline-yes">30x</span>
1605
- <span class="cline-any cline-yes">27x</span>
1606
- <span class="cline-any cline-yes">4x</span>
1607
- <span class="cline-any cline-neutral">&nbsp;</span>
1608
- <span class="cline-any cline-neutral">&nbsp;</span>
1609
- <span class="cline-any cline-neutral">&nbsp;</span>
1610
- <span class="cline-any cline-yes">111x</span>
1611
- <span class="cline-any cline-neutral">&nbsp;</span>
1612
- <span class="cline-any cline-yes">111x</span>
1613
- <span class="cline-any cline-neutral">&nbsp;</span>
1614
- <span class="cline-any cline-neutral">&nbsp;</span>
1615
- <span class="cline-any cline-yes">112x</span>
1616
- <span class="cline-any cline-neutral">&nbsp;</span>
1617
- <span class="cline-any cline-neutral">&nbsp;</span>
1618
- <span class="cline-any cline-neutral">&nbsp;</span>
1619
- <span class="cline-any cline-neutral">&nbsp;</span>
1620
- <span class="cline-any cline-neutral">&nbsp;</span>
1621
- <span class="cline-any cline-neutral">&nbsp;</span>
1622
- <span class="cline-any cline-neutral">&nbsp;</span>
1623
- <span class="cline-any cline-neutral">&nbsp;</span>
1624
- <span class="cline-any cline-yes">1010x</span>
1625
- <span class="cline-any cline-yes">90x</span>
1626
- <span class="cline-any cline-yes">81x</span>
1627
- <span class="cline-any cline-yes">12x</span>
1628
- <span class="cline-any cline-neutral">&nbsp;</span>
1629
- <span class="cline-any cline-neutral">&nbsp;</span>
1630
- <span class="cline-any cline-neutral">&nbsp;</span>
1631
- <span class="cline-any cline-yes">333x</span>
1632
- <span class="cline-any cline-neutral">&nbsp;</span>
1633
- <span class="cline-any cline-yes">333x</span>
1634
- <span class="cline-any cline-neutral">&nbsp;</span>
1635
- <span class="cline-any cline-neutral">&nbsp;</span>
1636
- <span class="cline-any cline-yes">339x</span>
1637
- <span class="cline-any cline-neutral">&nbsp;</span>
1638
- <span class="cline-any cline-neutral">&nbsp;</span>
1639
- <span class="cline-any cline-neutral">&nbsp;</span>
1640
- <span class="cline-any cline-neutral">&nbsp;</span>
1641
- <span class="cline-any cline-neutral">&nbsp;</span>
1642
- <span class="cline-any cline-neutral">&nbsp;</span>
1643
- <span class="cline-any cline-neutral">&nbsp;</span>
1644
- <span class="cline-any cline-neutral">&nbsp;</span>
1645
- <span class="cline-any cline-yes">111x</span>
1646
- <span class="cline-any cline-yes">111x</span>
1647
- <span class="cline-any cline-neutral">&nbsp;</span>
1648
- <span class="cline-any cline-yes">111x</span>
1649
- <span class="cline-any cline-yes">111x</span>
1650
- <span class="cline-any cline-yes">113x</span>
1651
- <span class="cline-any cline-yes">5x</span>
1652
- <span class="cline-any cline-neutral">&nbsp;</span>
1653
- <span class="cline-any cline-yes">108x</span>
1654
- <span class="cline-any cline-neutral">&nbsp;</span>
1655
- <span class="cline-any cline-neutral">&nbsp;</span>
1656
- <span class="cline-any cline-neutral">&nbsp;</span>
1657
- <span class="cline-any cline-yes">111x</span>
1658
- <span class="cline-any cline-neutral">&nbsp;</span>
1659
- <span class="cline-any cline-neutral">&nbsp;</span>
1660
- <span class="cline-any cline-neutral">&nbsp;</span>
1661
- <span class="cline-any cline-yes">260x</span>
1662
- <span class="cline-any cline-yes">30x</span>
1663
- <span class="cline-any cline-yes">26x</span>
1664
- <span class="cline-any cline-yes">4x</span>
1665
- <span class="cline-any cline-neutral">&nbsp;</span>
1666
- <span class="cline-any cline-neutral">&nbsp;</span>
1667
- <span class="cline-any cline-neutral">&nbsp;</span>
1668
- <span class="cline-any cline-yes">111x</span>
1669
- <span class="cline-any cline-yes">111x</span>
1670
- <span class="cline-any cline-neutral">&nbsp;</span>
1671
- <span class="cline-any cline-neutral">&nbsp;</span>
1672
- <span class="cline-any cline-neutral">&nbsp;</span>
1673
- <span class="cline-any cline-neutral">&nbsp;</span>
1674
- <span class="cline-any cline-yes">111x</span>
1675
- <span class="cline-any cline-neutral">&nbsp;</span>
1676
- <span class="cline-any cline-neutral">&nbsp;</span>
1677
- <span class="cline-any cline-neutral">&nbsp;</span>
1678
- <span class="cline-any cline-yes">113x</span>
1679
- <span class="cline-any cline-neutral">&nbsp;</span>
1680
- <span class="cline-any cline-neutral">&nbsp;</span>
1681
- <span class="cline-any cline-neutral">&nbsp;</span>
1682
- <span class="cline-any cline-yes">111x</span>
1683
- <span class="cline-any cline-yes">113x</span>
1684
- <span class="cline-any cline-neutral">&nbsp;</span>
1685
- <span class="cline-any cline-neutral">&nbsp;</span>
1686
- <span class="cline-any cline-neutral">&nbsp;</span>
1687
- <span class="cline-any cline-neutral">&nbsp;</span>
1688
- <span class="cline-any cline-yes">28x</span>
1689
- <span class="cline-any cline-neutral">&nbsp;</span>
1690
- <span class="cline-any cline-neutral">&nbsp;</span>
1691
- <span class="cline-any cline-neutral">&nbsp;</span>
1692
- <span class="cline-any cline-neutral">&nbsp;</span>
1693
- <span class="cline-any cline-neutral">&nbsp;</span>
1694
- <span class="cline-any cline-neutral">&nbsp;</span>
1695
- <span class="cline-any cline-yes">441x</span>
1696
- <span class="cline-any cline-neutral">&nbsp;</span>
1697
- <span class="cline-any cline-neutral">&nbsp;</span>
1698
- <span class="cline-any cline-neutral">&nbsp;</span>
1699
- <span class="cline-any cline-neutral">&nbsp;</span>
1700
- <span class="cline-any cline-yes">441x</span>
1701
- <span class="cline-any cline-neutral">&nbsp;</span>
1702
- <span class="cline-any cline-yes">453x</span>
1703
- <span class="cline-any cline-neutral">&nbsp;</span>
1704
- <span class="cline-any cline-neutral">&nbsp;</span>
1705
- <span class="cline-any cline-neutral">&nbsp;</span>
1706
- <span class="cline-any cline-neutral">&nbsp;</span>
1707
- <span class="cline-any cline-yes">223x</span>
1708
- <span class="cline-any cline-neutral">&nbsp;</span>
1709
- <span class="cline-any cline-neutral">&nbsp;</span>
1710
- <span class="cline-any cline-neutral">&nbsp;</span>
1711
- <span class="cline-any cline-neutral">&nbsp;</span>
1712
- <span class="cline-any cline-yes">109x</span>
1713
- <span class="cline-any cline-yes">112x</span>
1714
- <span class="cline-any cline-yes">109x</span>
1715
- <span class="cline-any cline-yes">2x</span>
1716
- <span class="cline-any cline-neutral">&nbsp;</span>
1717
- <span class="cline-any cline-yes">107x</span>
1718
- <span class="cline-any cline-neutral">&nbsp;</span>
1719
- <span class="cline-any cline-neutral">&nbsp;</span>
1720
- <span class="cline-any cline-neutral">&nbsp;</span>
1721
- <span class="cline-any cline-neutral">&nbsp;</span>
1722
- <span class="cline-any cline-yes">45x</span>
1723
- <span class="cline-any cline-neutral">&nbsp;</span>
1724
- <span class="cline-any cline-neutral">&nbsp;</span>
1725
- <span class="cline-any cline-neutral">&nbsp;</span>
1726
- <span class="cline-any cline-yes">45x</span>
1727
- <span class="cline-any cline-yes">45x</span>
1728
- <span class="cline-any cline-yes">1x</span>
1729
- <span class="cline-any cline-neutral">&nbsp;</span>
1730
- <span class="cline-any cline-yes">44x</span>
1731
- <span class="cline-any cline-neutral">&nbsp;</span>
1732
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type { OpRootNode, OpRouteNode, OpOperationNode, ContractTypeNode, ParamSource, ObjectMode } from '@contractkit/core';
1733
- import { resolveModifiers, resolveSecurity, SECURITY_NONE, classifyContentType } from '@contractkit/core';
1734
- import {
1735
- renderType,
1736
- renderInputType,
1737
- renderQueryType,
1738
- pascalToDotCase,
1739
- typeNeedsDateTime,
1740
- typeNeedsScalar,
1741
- modeToWrapper,
1742
- } from './codegen-contract.js';
1743
- import { renderOutputTsType, quoteKey, headerNameToProperty } from './ts-render.js';
1744
- import { basename, dirname, relative } from 'path';
1745
- &nbsp;
1746
- // ─── Content-type helpers ──────────────────────────────────────────────────
1747
- &nbsp;
1748
- /** Map a request MIME type to the koa-bodyparser parser token used in middleware. */
1749
- function bodyParserToken(contentType: string): string {
1750
- switch (classifyContentType(contentType)) {
1751
- case 'urlencoded':
1752
- return 'urlencoded';
1753
- case 'multipart':
1754
- return 'multipart';
1755
- case 'text':
1756
- return 'text';
1757
- <span class="branch-3 cbranch-no" title="branch not covered" > case 'binary':</span>
1758
- // koa-bodyparser has no native binary token; fall back to text so the body is
1759
- // still readable as a string. Services handling binary uploads should switch to
1760
- // multipart/form-data.
1761
- <span class="cstat-no" title="statement not covered" > return 'text';</span>
1762
- default:
1763
- return 'json';
1764
- }
1765
- }
1766
- &nbsp;
1767
- /**
1768
- * Deep structural equality on ContractTypeNode, ignoring source locations on inline fields.
1769
- * Used to decide whether multiple declared request MIMEs can share a single validate path.
1770
- */
1771
- export function bodyTypesStructurallyEqual(a: ContractTypeNode, b: ContractTypeNode): boolean {
1772
- <span class="missing-if-branch" title="if path not taken" >I</span>if (a.kind !== b.kind) <span class="cstat-no" title="statement not covered" >return false;</span>
1773
- switch (a.kind) {
1774
- <span class="branch-0 cbranch-no" title="branch not covered" > case 'scalar': {</span>
1775
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1776
- <span class="cstat-no" title="statement not covered" > return a.name === bb.name &amp;&amp; a.min === bb.min &amp;&amp; a.max === bb.max &amp;&amp; a.len === bb.len &amp;&amp; a.regex === bb.regex &amp;&amp; a.format === bb.format;</span>
1777
- }
1778
- <span class="branch-1 cbranch-no" title="branch not covered" > case 'array': {</span>
1779
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1780
- <span class="cstat-no" title="statement not covered" > return a.min === bb.min &amp;&amp; a.max === bb.max &amp;&amp; bodyTypesStructurallyEqual(a.item, bb.item);</span>
1781
- }
1782
- <span class="branch-2 cbranch-no" title="branch not covered" > case 'tuple': {</span>
1783
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1784
- <span class="cstat-no" title="statement not covered" > return a.items.length === bb.items.length &amp;&amp; a.items.every(<span class="fstat-no" title="function not covered" >(x</span>, i) =&gt; <span class="cstat-no" title="statement not covered" >bodyTypesStructurallyEqual(x, bb.items[i]!));</span></span>
1785
- }
1786
- <span class="branch-3 cbranch-no" title="branch not covered" > case 'record': {</span>
1787
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1788
- <span class="cstat-no" title="statement not covered" > return bodyTypesStructurallyEqual(a.key, bb.key) &amp;&amp; bodyTypesStructurallyEqual(a.value, bb.value);</span>
1789
- }
1790
- <span class="branch-4 cbranch-no" title="branch not covered" > case 'enum': {</span>
1791
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1792
- <span class="cstat-no" title="statement not covered" > return a.values.length === bb.values.length &amp;&amp; a.values.every(<span class="fstat-no" title="function not covered" >(v</span>, i) =&gt; <span class="cstat-no" title="statement not covered" >v === bb.values[i])</span>;</span>
1793
- }
1794
- <span class="branch-5 cbranch-no" title="branch not covered" > case 'literal': {</span>
1795
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1796
- <span class="cstat-no" title="statement not covered" > return a.value === bb.value;</span>
1797
- }
1798
- <span class="branch-6 cbranch-no" title="branch not covered" > case 'union':</span>
1799
- <span class="branch-7 cbranch-no" title="branch not covered" > case 'intersection': {</span>
1800
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1801
- <span class="cstat-no" title="statement not covered" > return a.members.length === bb.members.length &amp;&amp; a.members.every(<span class="fstat-no" title="function not covered" >(m</span>, i) =&gt; <span class="cstat-no" title="statement not covered" >bodyTypesStructurallyEqual(m, bb.members[i]!));</span></span>
1802
- }
1803
- <span class="branch-8 cbranch-no" title="branch not covered" > case 'discriminatedUnion': {</span>
1804
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1805
- <span class="cstat-no" title="statement not covered" > return (</span>
1806
- a.discriminator === bb.discriminator &amp;&amp;
1807
- a.members.length === bb.members.length &amp;&amp;
1808
- a.members.every(<span class="fstat-no" title="function not covered" >(m</span>, i) =&gt; <span class="cstat-no" title="statement not covered" >bodyTypesStructurallyEqual(m, bb.members[i]!))</span>
1809
- );
1810
- }
1811
- case 'ref': {
1812
- const bb = b as typeof a;
1813
- return a.name === bb.name &amp;&amp; !!a.lazy === !!bb.lazy;
1814
- }
1815
- <span class="branch-10 cbranch-no" title="branch not covered" > case 'lazy': {</span>
1816
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1817
- <span class="cstat-no" title="statement not covered" > return bodyTypesStructurallyEqual(a.inner, bb.inner);</span>
1818
- }
1819
- <span class="branch-11 cbranch-no" title="branch not covered" > case 'inlineObject': {</span>
1820
- const bb = <span class="cstat-no" title="statement not covered" >b as typeof a;</span>
1821
- <span class="cstat-no" title="statement not covered" > if (a.mode !== bb.mode) <span class="cstat-no" title="statement not covered" >return false;</span></span>
1822
- <span class="cstat-no" title="statement not covered" > if (a.fields.length !== bb.fields.length) <span class="cstat-no" title="statement not covered" >return false;</span></span>
1823
- <span class="cstat-no" title="statement not covered" > return a.fields.every(<span class="fstat-no" title="function not covered" >(f</span>, i) =&gt; {</span>
1824
- const g = <span class="cstat-no" title="statement not covered" >bb.fields[i]!</span>;
1825
- <span class="cstat-no" title="statement not covered" > return (</span>
1826
- f.name === g.name &amp;&amp;
1827
- f.optional === g.optional &amp;&amp;
1828
- f.nullable === g.nullable &amp;&amp;
1829
- f.visibility === g.visibility &amp;&amp;
1830
- f.default === g.default &amp;&amp;
1831
- !!f.deprecated === !!g.deprecated &amp;&amp;
1832
- bodyTypesStructurallyEqual(f.type, g.type)
1833
- );
1834
- });
1835
- }
1836
- }
1837
- }
1838
- &nbsp;
1839
- // ─── Public entry point ────────────────────────────────────────────────────
1840
- &nbsp;
1841
- export interface OpCodegenOptions {
1842
- servicePathTemplate?: string;
1843
- typeImportPathTemplate?: string;
1844
- outPath?: string;
1845
- /** Map from model name → absolute output file path (for cross-module type imports) */
1846
- modelOutPaths?: Map&lt;string, string&gt;;
1847
- /** Set of model names that have Input variants (models with visibility modifiers) */
1848
- modelsWithInput?: Set&lt;string&gt;;
1849
- /** Set of model names that have Output variants (models with format(output=...)) */
1850
- modelsWithOutput?: Set&lt;string&gt;;
1851
- /**
1852
- * Whether to emit handlers for operations marked `internal`. Defaults to `true` because
1853
- * the server still needs routes for internal endpoints; set to `false` to omit them
1854
- * from the generated router entirely.
1855
- */
1856
- includeInternal?: boolean;
1857
- }
1858
- &nbsp;
1859
- /** Generate a Koa router module for every operation in `root`, including the imports, type aliases, and handler list. */
1860
- export function generateOp(root: OpRootNode, options: OpCodegenOptions = {}): string {
1861
- // Collect all referenced types across all routes
1862
- const types = collectTypes(root, options.modelsWithInput, options.modelsWithOutput);
1863
- const services = collectServices(root);
1864
- const routerName = deriveRouterName(root.file);
1865
- const needsParseAndValidate = routeNeedsValidation(root);
1866
- &nbsp;
1867
- // Generate the body first so we can detect whether `z.` is actually referenced
1868
- // before deciding whether to emit the zod import.
1869
- const body: string[] = [];
1870
- const needsSignature = fileNeedsSignature(root);
1871
- const needsPolicy = fileNeedsPolicy(root);
1872
- const koaImports = ['ServerKitRouter', 'bodyParserMiddleware'];
1873
- if (needsPolicy) koaImports.push('requirePolicy');
1874
- if (needsSignature) koaImports.push('requireSignature');
1875
- body.push(`import { ${koaImports.join(', ')} } from '@maroonedsoftware/koa';`);
1876
- &nbsp;
1877
- for (const svc of services) {
1878
- const modulePath = root.services?.[svc] ?? root.meta[svc] ?? deriveModulePath(svc, options.servicePathTemplate);
1879
- body.push(`import { ${svc} } from '${modulePath}';`);
1880
- }
1881
- &nbsp;
1882
- if (types.length &gt; 0) {
1883
- body.push(...generateTypeImports(types, root.file, options));
1884
- }
1885
- &nbsp;
1886
- if (opNeedsDateTime(root)) {
1887
- body.push(`import { DateTime } from 'luxon';`);
1888
- }
1889
- &nbsp;
1890
- if (needsParseAndValidate) {
1891
- body.push(`import { parseAndValidate } from '@maroonedsoftware/zod';`);
1892
- }
1893
- &nbsp;
1894
- if (fileUsesMultipart(root)) {
1895
- body.push(`import { MultipartBody } from '@maroonedsoftware/multipart';`);
1896
- }
1897
- &nbsp;
1898
- const helpers: string[] = [];
1899
- <span class="missing-if-branch" title="if path not taken" >I</span>if (opNeedsScalar(root, 'binary')) {
1900
- <span class="cstat-no" title="statement not covered" > helpers.push(`const _ZodBinary = z.custom&lt;Buffer&gt;((val) =&gt; Buffer.isBuffer(val), { error: 'Must be binary data' });`);</span>
1901
- }
1902
- if (opNeedsScalar(root, 'datetime')) {
1903
- helpers.push(
1904
- `const _ZodDatetime = z.preprocess((val) =&gt; typeof val === 'string' ? DateTime.fromISO(val) : val, z.custom&lt;DateTime&gt;((val) =&gt; val instanceof DateTime &amp;&amp; val.isValid, { message: 'Must be in ISO 8601 format' }));`,
1905
- );
1906
- }
1907
- <span class="missing-if-branch" title="if path not taken" >I</span>if (opNeedsScalar(root, 'json')) {
1908
- <span class="cstat-no" title="statement not covered" > helpers.push(`type _JsonValue = string | number | boolean | null | _JsonValue[] | { [key: string]: _JsonValue };`);</span>
1909
- <span class="cstat-no" title="statement not covered" > helpers.push(</span>
1910
- `const _ZodJson: z.ZodType&lt;_JsonValue&gt; = z.lazy(() =&gt; z.union([z.string(), z.number(), z.boolean(), z.null(), z.array(_ZodJson), z.record(z.string(), _ZodJson)]));`,
1911
- );
1912
- }
1913
- &nbsp;
1914
- const lines: string[] = [];
1915
- &nbsp;
1916
- lines.push('');
1917
- lines.push('/**');
1918
- const relFile = options.outPath ? relative(dirname(options.outPath), root.file) : root.file;
1919
- lines.push(` * generated from [${basename(root.file)}](file://./${relFile})`);
1920
- lines.push('*/');
1921
- lines.push(`export const ${routerName} = ServerKitRouter();`);
1922
- lines.push('');
1923
- &nbsp;
1924
- const includeInternal = options.includeInternal ?? true;
1925
- for (const route of root.routes) {
1926
- for (const op of route.operations) {
1927
- if (!includeInternal &amp;&amp; resolveModifiers(route, op).includes('internal')) continue;
1928
- lines.push(...generateHandler(route, op, root, options));
1929
- lines.push('');
1930
- }
1931
- }
1932
- &nbsp;
1933
- const allContent = [...body, ...(helpers.length ? ['', ...helpers] : []), ...lines].join('\n');
1934
- const needsZod = /\bz\./.test(allContent);
1935
- return (needsZod ? `import { z } from 'zod';\n` : '') + allContent;
1936
- }
1937
- &nbsp;
1938
- // ─── Handler generation ────────────────────────────────────────────────────
1939
- &nbsp;
1940
- function generateHandler(route: OpRouteNode, op: OpOperationNode, root: OpRootNode, options: OpCodegenOptions): string[] {
1941
- const lines: string[] = [];
1942
- const file = root.file;
1943
- const outPath = options.outPath;
1944
- const modelsWithInput = options.modelsWithInput;
1945
- &nbsp;
1946
- lines.push('/**');
1947
- &nbsp;
1948
- // JSDoc from description
1949
- const desc = op.description ?? route.description;
1950
- if (desc) {
1951
- lines.push(` * ${desc}`);
1952
- }
1953
- // Source location comment
1954
- const relFile = outPath ? relative(dirname(outPath), file) : file;
1955
- lines.push(` * from [${basename(file)}](file://./${relFile}#L${op.loc.line})`);
1956
- &nbsp;
1957
- // Security annotation (operation-level wins; falls back to route → file level)
1958
- const effectiveSecurity = resolveSecurity(route, op, root);
1959
- if (effectiveSecurity === SECURITY_NONE) {
1960
- lines.push(` * anonymous access, no security required`);
1961
- }
1962
- &nbsp;
1963
- // Modifier annotations
1964
- const mods = resolveModifiers(route, op);
1965
- if (mods.includes('internal')) lines.push(` * @internal`);
1966
- if (mods.includes('deprecated')) lines.push(` * @deprecated`);
1967
- &nbsp;
1968
- lines.push('*/');
1969
- &nbsp;
1970
- const method = op.method;
1971
- const path = route.path.replace(/\{(\w+)\}/g, ':$1');
1972
- const bodies = op.request?.bodies ?? [];
1973
- const hasBody = bodies.length &gt; 0;
1974
- const isSingleMultipart = bodies.length === 1 &amp;&amp; bodies[0]!.contentType === 'multipart/form-data';
1975
- &nbsp;
1976
- // Middleware list
1977
- const middlewares: string[] = [];
1978
- if (effectiveSecurity !== SECURITY_NONE) {
1979
- const policy = effectiveSecurity?.policy;
1980
- const args =
1981
- policy === undefined
1982
- ? ''
1983
- : policy === false
1984
- ? '{ policy: false }'
1985
- : `{ policy: '${policy}' }`;
1986
- middlewares.push(`requirePolicy(${args})`);
1987
- }
1988
- if (hasBody) {
1989
- const parserTokens = Array.from(new Set(bodies.map(b =&gt; bodyParserToken(b.contentType))));
1990
- const tokensExpr = parserTokens.map(t =&gt; `'${t}'`).join(', ');
1991
- middlewares.push(`bodyParserMiddleware([${tokensExpr}])`);
1992
- }
1993
- if (op.signature) {
1994
- const sigArgs = op.signaturePolicy
1995
- ? `'${op.signature}', { policy: '${op.signaturePolicy}' }`
1996
- : `'${op.signature}'`;
1997
- middlewares.push(`requireSignature(${sigArgs})`);
1998
- }
1999
- const middlewareStr = middlewares.length &gt; 0 ? `, ${middlewares.join(', ')},` : ',';
2000
- &nbsp;
2001
- lines.push(`${deriveRouterName(file)}.${method}('${path}'${middlewareStr} async (ctx, next) =&gt; {`);
2002
- &nbsp;
2003
- // Params / query / headers validation (request-side — use Input variants)
2004
- lines.push(...generateParamValidation(route.params, 'ctx.params', 'params', route.paramsMode ?? 'strict', '', modelsWithInput));
2005
- lines.push(...generateParamValidation(op.query, 'ctx.query', 'query', op.queryMode ?? 'strict', '', modelsWithInput));
2006
- lines.push(...generateParamValidation(op.headers, 'ctx.headers', 'headers', op.headersMode ?? 'strip', '', modelsWithInput));
2007
- &nbsp;
2008
- // Body validation (request-side — use Input variants)
2009
- if (hasBody &amp;&amp; op.request) {
2010
- if (isSingleMultipart) {
2011
- lines.push(` const multipartBody = ctx.body as MultipartBody;`);
2012
- lines.push('');
2013
- } else if (bodies.length === 1) {
2014
- lines.push(` const body = await parseAndValidate(ctx.body, ${renderInputType(bodies[0]!.bodyType, modelsWithInput)});`);
2015
- lines.push('');
2016
- } else if (bodies.every(b =&gt; bodyTypesStructurallyEqual(b.bodyType, bodies[0]!.bodyType))) {
2017
- // All declared MIMEs share the same body shape — single validation suffices
2018
- lines.push(` const body = await parseAndValidate(ctx.body, ${renderInputType(bodies[0]!.bodyType, modelsWithInput)});`);
2019
- lines.push('');
2020
- } else {
2021
- // Different body types per MIME — dispatch on Content-Type
2022
- const annotation = bodies
2023
- .map(b =&gt;
2024
- b.contentType === 'multipart/form-data' ? 'MultipartBody' : `z.infer&lt;typeof ${renderInputType(b.bodyType, modelsWithInput)}&gt;`,
2025
- )
2026
- .join(' | ');
2027
- lines.push(` let body!: ${annotation};`);
2028
- lines.push(` switch (ctx.request.type) {`);
2029
- for (const b of bodies) {
2030
- lines.push(` case '${b.contentType}':`);
2031
- if (b.contentType === 'multipart/form-data') {
2032
- lines.push(` body = ctx.body as MultipartBody;`);
2033
- } else {
2034
- lines.push(` body = await parseAndValidate(ctx.body, ${renderInputType(b.bodyType, modelsWithInput)});`);
2035
- }
2036
- lines.push(` break;`);
2037
- }
2038
- lines.push(` }`);
2039
- lines.push('');
2040
- }
2041
- }
2042
- &nbsp;
2043
- // Service call — use the first response with a body as the primary response
2044
- const primaryResponse = op.responses.find(r =&gt; r.bodyType) ?? op.responses[0];
2045
- const serviceParts = inferService(op, route, file);
2046
- const respHeaders = primaryResponse?.headers ?? [];
2047
- const hasRespHeaders = respHeaders.length &gt; 0;
2048
- const headersAnnotation = hasRespHeaders
2049
- ? `{ ${respHeaders
2050
- .map(h =&gt; `${quoteKey(headerNameToProperty(h.name))}${h.optional ? '?' : ''}: ${renderOutputTsType(h.type, options.modelsWithOutput)}`)
2051
- .join('; ')} }`
2052
- : '';
2053
- &nbsp;
2054
- if (primaryResponse?.bodyType) {
2055
- const { annotation, prelude } = formatTypeAnnotation(primaryResponse.bodyType!, options.modelsWithOutput);
2056
- <span class="missing-if-branch" title="if path not taken" >I</span>if (prelude) {
2057
- <span class="cstat-no" title="statement not covered" > lines.push(` ${prelude}`);</span>
2058
- }
2059
- lines.push(` const service = ctx.container.get(${serviceParts.className});`);
2060
- if (hasRespHeaders) {
2061
- lines.push(
2062
- ` const result: { body: ${annotation}; headers: ${headersAnnotation} } = await service.${serviceParts.methodName}(${buildArgs(route, op)});`,
2063
- );
2064
- } else {
2065
- lines.push(` const result: ${annotation} = await service.${serviceParts.methodName}(${buildArgs(route, op)});`);
2066
- }
2067
- } else {
2068
- lines.push(` const service = ctx.container.get(${serviceParts.className});`);
2069
- if (hasRespHeaders) {
2070
- lines.push(` const result: { headers: ${headersAnnotation} } = await service.${serviceParts.methodName}(${buildArgs(route, op)});`);
2071
- } else {
2072
- lines.push(` await service.${serviceParts.methodName}(${buildArgs(route, op)});`);
2073
- }
2074
- }
2075
- &nbsp;
2076
- lines.push('');
2077
- lines.push(` ctx.status = ${primaryResponse?.statusCode ?? 200};`);
2078
- &nbsp;
2079
- if (hasRespHeaders) {
2080
- for (const h of respHeaders) {
2081
- const accessor = `result.headers[${JSON.stringify(headerNameToProperty(h.name))}]`;
2082
- if (h.optional) {
2083
- lines.push(` if (${accessor} !== undefined) ctx.set('${h.name}', String(${accessor}));`);
2084
- } else {
2085
- lines.push(` ctx.set('${h.name}', String(${accessor}));`);
2086
- }
2087
- }
2088
- }
2089
- &nbsp;
2090
- if (primaryResponse?.bodyType &amp;&amp; primaryResponse.contentType) {
2091
- lines.push(` ctx.type = '${primaryResponse.contentType}';`);
2092
- lines.push(` ctx.body = ${hasRespHeaders ? 'result.body' : 'result'};`);
2093
- }
2094
- &nbsp;
2095
- lines.push(`});`);
2096
- &nbsp;
2097
- return lines;
2098
- }
2099
- &nbsp;
2100
- // ─── Inference helpers ─────────────────────────────────────────────────────
2101
- &nbsp;
2102
- function inferService(op: OpOperationNode, route: OpRouteNode, file: string): { className: string; methodName: string } {
2103
- // If explicitly declared: service: ServiceClass.methodName
2104
- if (op.service) {
2105
- const [cls = '', method] = op.service.split('.');
2106
- return { className: cls, methodName: method ?? <span class="branch-1 cbranch-no" title="branch not covered" >'handle' }</span>;
2107
- }
2108
- &nbsp;
2109
- // Infer from file name + method + path
2110
- const baseName = deriveBaseName(file); // e.g. "ledger.categories" -&gt; "LedgerCategories"
2111
- const className = `${baseName}Service`;
2112
- const methodName = inferMethodName(op.method, route.path);
2113
- return { className, methodName };
2114
- }
2115
- &nbsp;
2116
- function inferMethodName(method: string, path: string): string {
2117
- const hasParam = path.includes('{');
2118
- switch (method) {
2119
- case 'get':
2120
- return hasParam ? 'getById' : 'list';
2121
- case 'post':
2122
- return 'create';
2123
- case 'put':
2124
- return 'replace';
2125
- case 'patch':
2126
- return 'update';
2127
- case 'delete':
2128
- return 'delete';
2129
- <span class="branch-5 cbranch-no" title="branch not covered" > default:</span>
2130
- <span class="cstat-no" title="statement not covered" > return 'handle';</span>
2131
- }
2132
- }
2133
- &nbsp;
2134
- function buildArgs(route: OpRouteNode, op: OpOperationNode): string {
2135
- const args: string[] = [];
2136
- // Path params: spread individually (inline) or pass 'params' object (type-ref/ContractTypeNode)
2137
- if (route.params) {
2138
- if (route.params.kind === 'params') {
2139
- args.push(...route.params.nodes.map(p =&gt; p.name));
2140
- } else {
2141
- args.push('params');
2142
- }
2143
- }
2144
- // Body
2145
- if (op.request &amp;&amp; op.request.bodies.length &gt; 0) {
2146
- const bodies = op.request.bodies;
2147
- const isSingleMultipart = bodies.length === 1 &amp;&amp; bodies[0]!.contentType === 'multipart/form-data';
2148
- args.push(isSingleMultipart ? 'multipartBody' : 'body');
2149
- }
2150
- // Query
2151
- if (op.query) args.push('query');
2152
- // Headers
2153
- if (op.headers) args.push('headers');
2154
- return args.join(', ');
2155
- }
2156
- &nbsp;
2157
- function formatTypeAnnotation(bodyType: ContractTypeNode, modelsWithOutput?: Set&lt;string&gt;): { annotation: string; prelude?: string } {
2158
- if (bodyType.kind === 'array') {
2159
- const inner = formatTypeAnnotation(bodyType.item, modelsWithOutput);
2160
- return { annotation: `${inner.annotation}[]`, prelude: inner.prelude };
2161
- }
2162
- <span class="missing-if-branch" title="else path not taken" >E</span>if (bodyType.kind === 'ref') {
2163
- const name = modelsWithOutput?.has(bodyType.name) ? `${bodyType.name}Output` : bodyType.name;
2164
- return { annotation: name };
2165
- }
2166
- <span class="cstat-no" title="statement not covered" > if (bodyType.kind === 'scalar') <span class="cstat-no" title="statement not covered" >return { annotation: bodyType.name };</span></span>
2167
- // For complex types, extract schema into a variable so the result line stays readable
2168
- const <span class="cstat-no" title="statement not covered" >schema = renderType(bodyType);</span>
2169
- <span class="cstat-no" title="statement not covered" > return {</span>
2170
- annotation: 'z.infer&lt;typeof resultType&gt;',
2171
- prelude: `const resultType = ${schema};`,
2172
- };
2173
- }
2174
- &nbsp;
2175
- function generateParamValidation(
2176
- source: ParamSource | undefined,
2177
- ctxExpr: string,
2178
- varName: string,
2179
- mode: ObjectMode,
2180
- suffix = '',
2181
- modelsWithInput?: Set&lt;string&gt;,
2182
- ): string[] {
2183
- if (!source) return [];
2184
- const lines: string[] = [];
2185
- const isQuery = ctxExpr === 'ctx.query';
2186
- if (source.kind === 'ref') {
2187
- // Type reference — apply mode as a method call on the schema
2188
- const typeName = modelsWithInput?.has(source.name) ? <span class="branch-0 cbranch-no" title="branch not covered" >`${source.name}Input` </span>: source.name;
2189
- lines.push(` const ${varName} = await parseAndValidate(${ctxExpr}, ${typeName}.${mode}());`);
2190
- lines.push('');
2191
- } else if (source.kind === 'params') {
2192
- // Inline param declarations — wrap with the appropriate z.*Object constructor
2193
- <span class="missing-if-branch" title="else path not taken" >E</span>if (source.nodes.length &gt; 0) {
2194
- // Destructure only for params (spread individually in service call);
2195
- // query/headers are passed as whole objects.
2196
- const lhs = varName === 'params' ? `{ ${source.nodes.map(p =&gt; p.name).join(', ')} }` : varName;
2197
- lines.push(` const ${lhs} = await parseAndValidate(`);
2198
- lines.push(` ${ctxExpr},`);
2199
- lines.push(` ${modeToWrapper(mode)}({`);
2200
- for (const param of source.nodes) {
2201
- const key = isValidIdentifier(param.name) ? param.name : `'${param.name}'`;
2202
- if (isQuery &amp;&amp; param.type.kind === 'array') {
2203
- const inner = renderType(param.type);
2204
- lines.push(` ${key}: z.preprocess((v) =&gt; typeof v === 'string' ? v.split(',') : v, ${inner}),`);
2205
- } else {
2206
- lines.push(` ${key}: ${renderType(param.type)},`);
2207
- }
2208
- }
2209
- lines.push(` })${suffix},`);
2210
- lines.push(` );`);
2211
- lines.push('');
2212
- }
2213
- } else {
2214
- // ContractTypeNode — use query-aware rendering for query params (coerces single string → array),
2215
- // otherwise use Input variant rendering; apply mode as a method call
2216
- const schema = isQuery ? renderQueryType(source.node, <span class="branch-1 cbranch-no" title="branch not covered" >modelsWithInput) : renderInputType(source.node, modelsWithInput);</span>
2217
- lines.push(` const ${varName} = await parseAndValidate(${ctxExpr}, (${schema}).${mode}());`);
2218
- lines.push('');
2219
- }
2220
- return lines;
2221
- }
2222
- &nbsp;
2223
- // ─── Type import resolution ────────────────────────────────────────────────
2224
- &nbsp;
2225
- /**
2226
- * Generate per-file type import statements.
2227
- * When modelOutPaths is available, groups types by their actual output file
2228
- * and computes correct relative paths. Falls back to the template-based
2229
- * single-import approach for types not found in the map.
2230
- */
2231
- function generateTypeImports(types: string[], opFile: string, options: OpCodegenOptions): string[] {
2232
- const lines: string[] = [];
2233
- const { modelOutPaths, outPath } = options;
2234
- &nbsp;
2235
- if (modelOutPaths &amp;&amp; outPath) {
2236
- // Group types by their output file
2237
- const byFile = new Map&lt;string, string[]&gt;();
2238
- const unresolved: string[] = [];
2239
- &nbsp;
2240
- for (const type of types) {
2241
- const typeOutPath = modelOutPaths.get(type);
2242
- <span class="missing-if-branch" title="if path not taken" >I</span>if (typeOutPath) {
2243
- const group = <span class="cstat-no" title="statement not covered" >byFile.get(typeOutPath) ?? [];</span>
2244
- <span class="cstat-no" title="statement not covered" > group.push(type);</span>
2245
- <span class="cstat-no" title="statement not covered" > byFile.set(typeOutPath, group);</span>
2246
- } else {
2247
- unresolved.push(type);
2248
- }
2249
- }
2250
- &nbsp;
2251
- // Emit one import per source file with a relative path
2252
- const fromDir = dirname(outPath);
2253
- for (const [typeOutPath, names] of byFile) {
2254
- let <span class="cstat-no" title="statement not covered" >rel = relative(fromDir, typeOutPath);</span>
2255
- <span class="cstat-no" title="statement not covered" > rel = rel.replace(/\.ts$/, '.js');</span>
2256
- <span class="cstat-no" title="statement not covered" > if (!rel.startsWith('.')) <span class="cstat-no" title="statement not covered" >rel = './' + rel;</span></span>
2257
- <span class="cstat-no" title="statement not covered" > lines.push(`import { ${names.sort().join(', ')} } from '${rel}';`);</span>
2258
- }
2259
- &nbsp;
2260
- // Fallback for types not in the map
2261
- for (const type of unresolved) {
2262
- const moduleName = pascalToDotCase(type);
2263
- lines.push(`import { ${type} } from './${moduleName}.js';`);
2264
- }
2265
- } else {
2266
- // No resolution context — fall back to template-based single import
2267
- const typeImport = deriveTypeImportPath(opFile, options.typeImportPathTemplate);
2268
- lines.push(`import { ${types.join(', ')} } from '${typeImport}';`);
2269
- }
2270
- &nbsp;
2271
- return lines;
2272
- }
2273
- &nbsp;
2274
- // ─── Collection helpers ────────────────────────────────────────────────────
2275
- &nbsp;
2276
- function collectTypes(root: OpRootNode, modelsWithInput?: Set&lt;string&gt;, modelsWithOutput?: Set&lt;string&gt;): string[] {
2277
- const types = new Set&lt;string&gt;();
2278
- for (const route of root.routes) {
2279
- collectParamSourceRefs(route.params, types);
2280
- collectParamSourceInputRefs(route.params, types, modelsWithInput);
2281
- for (const op of route.operations) {
2282
- if (op.request) {
2283
- for (const body of op.request.bodies) {
2284
- collectTypeNodeRefs(body.bodyType, types);
2285
- collectInputTypeNodeRefs(body.bodyType, types, modelsWithInput);
2286
- }
2287
- }
2288
- for (const resp of op.responses) {
2289
- if (resp.bodyType) {
2290
- collectTypeNodeRefs(resp.bodyType, types);
2291
- collectOutputTypeNodeRefs(resp.bodyType, types, modelsWithOutput);
2292
- }
2293
- if (resp.headers) {
2294
- for (const h of resp.headers) {
2295
- collectTypeNodeRefs(h.type, types);
2296
- collectOutputTypeNodeRefs(h.type, types, modelsWithOutput);
2297
- }
2298
- }
2299
- }
2300
- collectParamSourceRefs(op.query, types);
2301
- collectParamSourceInputRefs(op.query, types, modelsWithInput);
2302
- collectParamSourceRefs(op.headers, types);
2303
- collectParamSourceInputRefs(op.headers, types, modelsWithInput);
2304
- }
2305
- }
2306
- return [...types].sort();
2307
- }
2308
- &nbsp;
2309
- /** Collect Output variant refs for response-side ContractTypeNode types. */
2310
- function collectOutputTypeNodeRefs(type: ContractTypeNode, out: Set&lt;string&gt;, modelsWithOutput?: Set&lt;string&gt;): void {
2311
- if (!modelsWithOutput) return;
2312
- switch (type.kind) {
2313
- case 'ref':
2314
- if (modelsWithOutput.has(type.name)) out.add(`${type.name}Output`);
2315
- break;
2316
- case 'array':
2317
- collectOutputTypeNodeRefs(type.item, out, modelsWithOutput);
2318
- break;
2319
- <span class="branch-2 cbranch-no" title="branch not covered" > case 'tuple':</span>
2320
- <span class="cstat-no" title="statement not covered" > type.items.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectOutputTypeNodeRefs(t, out, modelsWithOutput));</span></span>
2321
- <span class="cstat-no" title="statement not covered" > break;</span>
2322
- <span class="branch-3 cbranch-no" title="branch not covered" > case 'record':</span>
2323
- <span class="cstat-no" title="statement not covered" > collectOutputTypeNodeRefs(type.key, out, modelsWithOutput);</span>
2324
- <span class="cstat-no" title="statement not covered" > collectOutputTypeNodeRefs(type.value, out, modelsWithOutput);</span>
2325
- <span class="cstat-no" title="statement not covered" > break;</span>
2326
- <span class="branch-4 cbranch-no" title="branch not covered" > case 'union':</span>
2327
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectOutputTypeNodeRefs(t, out, modelsWithOutput));</span></span>
2328
- <span class="cstat-no" title="statement not covered" > break;</span>
2329
- <span class="branch-5 cbranch-no" title="branch not covered" > case 'discriminatedUnion':</span>
2330
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectOutputTypeNodeRefs(t, out, modelsWithOutput));</span></span>
2331
- <span class="cstat-no" title="statement not covered" > break;</span>
2332
- <span class="branch-6 cbranch-no" title="branch not covered" > case 'intersection':</span>
2333
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectOutputTypeNodeRefs(t, out, modelsWithOutput));</span></span>
2334
- <span class="cstat-no" title="statement not covered" > break;</span>
2335
- <span class="branch-7 cbranch-no" title="branch not covered" > case 'lazy':</span>
2336
- <span class="cstat-no" title="statement not covered" > collectOutputTypeNodeRefs(type.inner, out, modelsWithOutput);</span>
2337
- <span class="cstat-no" title="statement not covered" > break;</span>
2338
- <span class="branch-8 cbranch-no" title="branch not covered" > case 'inlineObject':</span>
2339
- <span class="cstat-no" title="statement not covered" > type.fields.forEach(<span class="fstat-no" title="function not covered" >f =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectOutputTypeNodeRefs(f.type, out, modelsWithOutput));</span></span>
2340
- <span class="cstat-no" title="statement not covered" > break;</span>
2341
- }
2342
- }
2343
- &nbsp;
2344
- function collectParamSourceRefs(source: ParamSource | undefined, out: Set&lt;string&gt;): void {
2345
- if (!source) return;
2346
- if (source.kind === 'ref') {
2347
- <span class="missing-if-branch" title="else path not taken" >E</span>if (/^[A-Z]/.test(source.name)) out.add(source.name);
2348
- } else if (source.kind === 'params') {
2349
- for (const param of source.nodes) {
2350
- collectTypeNodeRefs(param.type, out);
2351
- }
2352
- } else {
2353
- collectTypeNodeRefs(source.node, out);
2354
- }
2355
- }
2356
- &nbsp;
2357
- /** Collect Input variant refs for request-side ParamSource types. */
2358
- function collectParamSourceInputRefs(source: ParamSource | undefined, out: Set&lt;string&gt;, modelsWithInput?: Set&lt;string&gt;): void {
2359
- if (!source || !modelsWithInput) return;
2360
- <span class="missing-if-branch" title="if path not taken" >I</span>if (source.kind === 'ref') {
2361
- <span class="cstat-no" title="statement not covered" > if (modelsWithInput.has(source.name)) <span class="cstat-no" title="statement not covered" >out.add(`${source.name}Input`);</span></span>
2362
- } else if (source.kind === 'type') {
2363
- collectInputTypeNodeRefs(source.node, out, modelsWithInput);
2364
- }
2365
- }
2366
- &nbsp;
2367
- /** Collect Input variant refs for request-side ContractTypeNode types. */
2368
- function collectInputTypeNodeRefs(type: ContractTypeNode, out: Set&lt;string&gt;, modelsWithInput?: Set&lt;string&gt;): void {
2369
- if (!modelsWithInput) return;
2370
- switch (type.kind) {
2371
- case 'ref':
2372
- if (modelsWithInput.has(type.name)) out.add(`${type.name}Input`);
2373
- break;
2374
- <span class="branch-1 cbranch-no" title="branch not covered" > case 'array':</span>
2375
- <span class="cstat-no" title="statement not covered" > collectInputTypeNodeRefs(type.item, out, modelsWithInput);</span>
2376
- <span class="cstat-no" title="statement not covered" > break;</span>
2377
- <span class="branch-2 cbranch-no" title="branch not covered" > case 'tuple':</span>
2378
- <span class="cstat-no" title="statement not covered" > type.items.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectInputTypeNodeRefs(t, out, modelsWithInput));</span></span>
2379
- <span class="cstat-no" title="statement not covered" > break;</span>
2380
- <span class="branch-3 cbranch-no" title="branch not covered" > case 'record':</span>
2381
- <span class="cstat-no" title="statement not covered" > collectInputTypeNodeRefs(type.key, out, modelsWithInput);</span>
2382
- <span class="cstat-no" title="statement not covered" > collectInputTypeNodeRefs(type.value, out, modelsWithInput);</span>
2383
- <span class="cstat-no" title="statement not covered" > break;</span>
2384
- <span class="branch-4 cbranch-no" title="branch not covered" > case 'union':</span>
2385
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectInputTypeNodeRefs(t, out, modelsWithInput));</span></span>
2386
- <span class="cstat-no" title="statement not covered" > break;</span>
2387
- <span class="branch-5 cbranch-no" title="branch not covered" > case 'discriminatedUnion':</span>
2388
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectInputTypeNodeRefs(t, out, modelsWithInput));</span></span>
2389
- <span class="cstat-no" title="statement not covered" > break;</span>
2390
- case 'intersection':
2391
- type.members.forEach(t =&gt; collectInputTypeNodeRefs(t, out, modelsWithInput));
2392
- break;
2393
- <span class="branch-7 cbranch-no" title="branch not covered" > case 'lazy':</span>
2394
- <span class="cstat-no" title="statement not covered" > collectInputTypeNodeRefs(type.inner, out, modelsWithInput);</span>
2395
- <span class="cstat-no" title="statement not covered" > break;</span>
2396
- case 'inlineObject':
2397
- type.fields.forEach(f =&gt; collectInputTypeNodeRefs(f.type, out, modelsWithInput));
2398
- break;
2399
- }
2400
- }
2401
- &nbsp;
2402
- function collectTypeNodeRefs(type: ContractTypeNode, out: Set&lt;string&gt;): void {
2403
- switch (type.kind) {
2404
- case 'ref':
2405
- <span class="missing-if-branch" title="else path not taken" >E</span>if (/^[A-Z]/.test(type.name)) out.add(type.name);
2406
- break;
2407
- case 'array':
2408
- collectTypeNodeRefs(type.item, out);
2409
- break;
2410
- <span class="branch-2 cbranch-no" title="branch not covered" > case 'tuple':</span>
2411
- <span class="cstat-no" title="statement not covered" > type.items.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectTypeNodeRefs(t, out));</span></span>
2412
- <span class="cstat-no" title="statement not covered" > break;</span>
2413
- <span class="branch-3 cbranch-no" title="branch not covered" > case 'record':</span>
2414
- <span class="cstat-no" title="statement not covered" > collectTypeNodeRefs(type.key, out);</span>
2415
- <span class="cstat-no" title="statement not covered" > collectTypeNodeRefs(type.value, out);</span>
2416
- <span class="cstat-no" title="statement not covered" > break;</span>
2417
- <span class="branch-4 cbranch-no" title="branch not covered" > case 'union':</span>
2418
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectTypeNodeRefs(t, out));</span></span>
2419
- <span class="cstat-no" title="statement not covered" > break;</span>
2420
- <span class="branch-5 cbranch-no" title="branch not covered" > case 'discriminatedUnion':</span>
2421
- <span class="cstat-no" title="statement not covered" > type.members.forEach(<span class="fstat-no" title="function not covered" >t =&gt; <span class="cstat-no" title="statement not covered" >c</span>ollectTypeNodeRefs(t, out));</span></span>
2422
- <span class="cstat-no" title="statement not covered" > break;</span>
2423
- case 'intersection':
2424
- type.members.forEach(t =&gt; collectTypeNodeRefs(t, out));
2425
- break;
2426
- <span class="branch-7 cbranch-no" title="branch not covered" > case 'lazy':</span>
2427
- <span class="cstat-no" title="statement not covered" > collectTypeNodeRefs(type.inner, out);</span>
2428
- <span class="cstat-no" title="statement not covered" > break;</span>
2429
- case 'inlineObject':
2430
- type.fields.forEach(f =&gt; collectTypeNodeRefs(f.type, out));
2431
- break;
2432
- }
2433
- }
2434
- &nbsp;
2435
- function paramSourceNeedsDateTime(source: ParamSource | undefined): boolean {
2436
- if (!source) return false;
2437
- if (source.kind === 'ref') return false;
2438
- if (source.kind === 'params') return source.nodes.some(p =&gt; typeNeedsDateTime(p.type));
2439
- return typeNeedsDateTime(source.node);
2440
- }
2441
- &nbsp;
2442
- function opNeedsDateTime(root: OpRootNode): boolean {
2443
- return root.routes.some(
2444
- route =&gt;
2445
- paramSourceNeedsDateTime(route.params) ||
2446
- route.operations.some(
2447
- op =&gt;
2448
- !!op.request?.bodies.some(b =&gt; typeNeedsDateTime(b.bodyType)) ||
2449
- op.responses.some(r =&gt; r.bodyType &amp;&amp; typeNeedsDateTime(r.bodyType)) ||
2450
- paramSourceNeedsDateTime(op.query) ||
2451
- paramSourceNeedsDateTime(op.headers),
2452
- ),
2453
- );
2454
- }
2455
- &nbsp;
2456
- function paramSourceNeedsScalar(source: ParamSource | undefined, name: string): boolean {
2457
- if (!source) return false;
2458
- if (source.kind === 'ref') return false;
2459
- if (source.kind === 'params') return source.nodes.some(p =&gt; typeNeedsScalar(p.type, name));
2460
- return typeNeedsScalar(source.node, name);
2461
- }
2462
- &nbsp;
2463
- function opNeedsScalar(root: OpRootNode, name: string): boolean {
2464
- return root.routes.some(
2465
- route =&gt;
2466
- paramSourceNeedsScalar(route.params, name) ||
2467
- route.operations.some(
2468
- op =&gt;
2469
- !!op.request?.bodies.some(b =&gt; typeNeedsScalar(b.bodyType, name)) ||
2470
- op.responses.some(r =&gt; r.bodyType &amp;&amp; typeNeedsScalar(r.bodyType, name)) ||
2471
- paramSourceNeedsScalar(op.query, name) ||
2472
- paramSourceNeedsScalar(op.headers, name),
2473
- ),
2474
- );
2475
- }
2476
- &nbsp;
2477
- function collectServices(root: OpRootNode): string[] {
2478
- const services = new Set&lt;string&gt;();
2479
- const inferredService = `${deriveBaseName(root.file)}Service`;
2480
- &nbsp;
2481
- for (const route of root.routes) {
2482
- for (const op of route.operations) {
2483
- if (op.service) {
2484
- services.add(op.service.split('.')[0] ?? <span class="branch-1 cbranch-no" title="branch not covered" >op.service)</span>;
2485
- } else {
2486
- services.add(inferredService);
2487
- }
2488
- }
2489
- }
2490
- return [...services].sort();
2491
- }
2492
- &nbsp;
2493
- function hasParamSource(source?: ParamSource): boolean {
2494
- if (!source) return false;
2495
- if (source.kind === 'ref') return true;
2496
- if (source.kind === 'params') return source.nodes.length &gt; 0;
2497
- return true; // type
2498
- }
2499
- &nbsp;
2500
- function routeNeedsValidation(root: OpRootNode): boolean {
2501
- return root.routes.some(
2502
- r =&gt; hasParamSource(r.params) || r.operations.some(op =&gt; !!op.request || hasParamSource(op.query) || hasParamSource(op.headers)),
2503
- );
2504
- }
2505
- &nbsp;
2506
- function fileNeedsPolicy(root: OpRootNode): boolean {
2507
- return root.routes.some(route =&gt; route.operations.some(op =&gt; resolveSecurity(route, op, root) !== SECURITY_NONE));
2508
- }
2509
- &nbsp;
2510
- function fileNeedsSignature(root: OpRootNode): boolean {
2511
- return root.routes.some(route =&gt; route.operations.some(op =&gt; !!op.signature));
2512
- }
2513
- &nbsp;
2514
- function fileUsesMultipart(root: OpRootNode): boolean {
2515
- return root.routes.some(route =&gt;
2516
- route.operations.some(op =&gt; (op.request?.bodies ?? []).some(b =&gt; b.contentType === 'multipart/form-data')),
2517
- );
2518
- }
2519
- &nbsp;
2520
- function isValidIdentifier(name: string): boolean {
2521
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
2522
- }
2523
- &nbsp;
2524
- // ─── Naming conventions ────────────────────────────────────────────────────
2525
- &nbsp;
2526
- function deriveBaseName(file: string): string {
2527
- const base =
2528
- file
2529
- .split('/')
2530
- .pop()
2531
- ?.replace(/\.(op|ck)$/, '') ?? <span class="branch-1 cbranch-no" title="branch not covered" >'Resource';</span>
2532
- // ledger.categories -&gt; LedgerCategories
2533
- return base
2534
- .split('.')
2535
- .map(s =&gt; s.charAt(0).toUpperCase() + s.slice(1))
2536
- .join('');
2537
- }
2538
- &nbsp;
2539
- function deriveRouterName(file: string): string {
2540
- return `${deriveBaseName(file)}Router`;
2541
- }
2542
- &nbsp;
2543
- function deriveModulePath(serviceName: string, template?: string): string {
2544
- // LedgerService -&gt; #modules/ledger/ledger.service.js
2545
- const base = serviceName.replace(/Service$/, '');
2546
- const kebab = base.replace(/([A-Z])/g, m =&gt; `-${m.toLowerCase()}`).replace(/^-/, '');
2547
- if (template) {
2548
- return template.replace(/\{name\}/g, base).replace(/\{kebab\}/g, kebab);
2549
- }
2550
- return `#modules/${kebab}/${kebab}.service.js`;
2551
- }
2552
- &nbsp;
2553
- function deriveTypeImportPath(file: string, template?: string): string {
2554
- const base =
2555
- file
2556
- .split('/')
2557
- .pop()
2558
- ?.replace(/\.(op|ck)$/, '') ?? <span class="branch-1 cbranch-no" title="branch not covered" >'resource';</span>
2559
- const module = base.split('.')[0] ?? <span class="branch-1 cbranch-no" title="branch not covered" >base;</span>
2560
- if (template) {
2561
- return template.replace(/\{module\}/g, module).replace(/\{base\}/g, base);
2562
- }
2563
- return `#modules/${module}/types/index.js`;
2564
- }
2565
- &nbsp;</pre></td></tr></table></pre>
2566
-
2567
- <div class='push'></div><!-- for sticky footer -->
2568
- </div><!-- /wrapper -->
2569
- <div class='footer quiet pad2 space-top1 center small'>
2570
- Code coverage generated by
2571
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2572
- at 2026-06-16T15:55:46.002Z
2573
- </div>
2574
- <script src="../prettify.js"></script>
2575
- <script>
2576
- window.onload = function () {
2577
- prettyPrint();
2578
- };
2579
- </script>
2580
- <script src="../sorter.js"></script>
2581
- <script src="../block-navigation.js"></script>
2582
- </body>
2583
- </html>
2584
-