projax 3.3.20 → 3.3.22

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 (66) hide show
  1. package/coverage/base.css +224 -0
  2. package/coverage/block-navigation.js +87 -0
  3. package/coverage/core-bridge.ts.html +268 -0
  4. package/coverage/favicon.png +0 -0
  5. package/coverage/index.html +176 -0
  6. package/coverage/lcov-report/base.css +224 -0
  7. package/coverage/lcov-report/block-navigation.js +87 -0
  8. package/coverage/lcov-report/core-bridge.ts.html +268 -0
  9. package/coverage/lcov-report/favicon.png +0 -0
  10. package/coverage/lcov-report/index.html +176 -0
  11. package/coverage/lcov-report/port-extractor.ts.html +1174 -0
  12. package/coverage/lcov-report/port-scanner.ts.html +301 -0
  13. package/coverage/lcov-report/port-utils.ts.html +670 -0
  14. package/coverage/lcov-report/prettify.css +1 -0
  15. package/coverage/lcov-report/prettify.js +2 -0
  16. package/coverage/lcov-report/script-runner.ts.html +3055 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +210 -0
  19. package/coverage/lcov.info +1117 -0
  20. package/coverage/port-extractor.ts.html +1174 -0
  21. package/coverage/port-scanner.ts.html +301 -0
  22. package/coverage/port-utils.ts.html +670 -0
  23. package/coverage/prettify.css +1 -0
  24. package/coverage/prettify.js +2 -0
  25. package/coverage/script-runner.ts.html +3055 -0
  26. package/coverage/sort-arrow-sprite.png +0 -0
  27. package/coverage/sorter.js +210 -0
  28. package/dist/__tests__/port-scanner.test.d.ts +1 -0
  29. package/dist/__tests__/port-scanner.test.js +170 -0
  30. package/dist/__tests__/port-utils.test.d.ts +1 -0
  31. package/dist/__tests__/port-utils.test.js +127 -0
  32. package/dist/__tests__/script-runner.test.d.ts +1 -0
  33. package/dist/__tests__/script-runner.test.js +491 -0
  34. package/dist/api/__tests__/database.test.d.ts +2 -0
  35. package/dist/api/__tests__/database.test.d.ts.map +1 -0
  36. package/dist/api/__tests__/database.test.js +485 -0
  37. package/dist/api/__tests__/database.test.js.map +1 -0
  38. package/dist/api/__tests__/routes.test.d.ts +2 -0
  39. package/dist/api/__tests__/routes.test.d.ts.map +1 -0
  40. package/dist/api/__tests__/routes.test.js +473 -0
  41. package/dist/api/__tests__/routes.test.js.map +1 -0
  42. package/dist/api/__tests__/scanner.test.d.ts +2 -0
  43. package/dist/api/__tests__/scanner.test.d.ts.map +1 -0
  44. package/dist/api/__tests__/scanner.test.js +402 -0
  45. package/dist/api/__tests__/scanner.test.js.map +1 -0
  46. package/dist/api/database.d.ts +1 -0
  47. package/dist/api/database.d.ts.map +1 -1
  48. package/dist/api/database.js +4 -0
  49. package/dist/api/database.js.map +1 -1
  50. package/dist/api/package.json +9 -1
  51. package/dist/api/routes/projects.d.ts.map +1 -1
  52. package/dist/api/routes/projects.js +8 -1
  53. package/dist/api/routes/projects.js.map +1 -1
  54. package/dist/api/routes/settings.d.ts.map +1 -1
  55. package/dist/api/routes/settings.js +2 -1
  56. package/dist/api/routes/settings.js.map +1 -1
  57. package/dist/api/services/scanner.d.ts.map +1 -1
  58. package/dist/api/services/scanner.js +7 -12
  59. package/dist/api/services/scanner.js.map +1 -1
  60. package/dist/electron/port-scanner.js +2 -2
  61. package/dist/electron/renderer/assets/index-C1SRt6Jx.js +62 -0
  62. package/dist/electron/renderer/assets/index-D1jmaGv5.css +1 -0
  63. package/dist/electron/renderer/index.html +2 -2
  64. package/dist/port-scanner.js +2 -2
  65. package/jest.config.js +18 -0
  66. package/package.json +7 -1
@@ -0,0 +1,1174 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for port-extractor.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> port-extractor.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">2.09% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>3/143</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/62</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/9</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">2.18% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>3/137</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
430
+ <span class="cline-any cline-yes">1x</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-neutral">&nbsp;</span>
433
+ <span class="cline-any cline-neutral">&nbsp;</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-neutral">&nbsp;</span>
437
+ <span class="cline-any cline-neutral">&nbsp;</span>
438
+ <span class="cline-any cline-neutral">&nbsp;</span>
439
+ <span class="cline-any cline-neutral">&nbsp;</span>
440
+ <span class="cline-any cline-neutral">&nbsp;</span>
441
+ <span class="cline-any cline-yes">1x</span>
442
+ <span class="cline-any cline-no">&nbsp;</span>
443
+ <span class="cline-any cline-neutral">&nbsp;</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-no">&nbsp;</span>
446
+ <span class="cline-any cline-no">&nbsp;</span>
447
+ <span class="cline-any cline-neutral">&nbsp;</span>
448
+ <span class="cline-any cline-neutral">&nbsp;</span>
449
+ <span class="cline-any cline-no">&nbsp;</span>
450
+ <span class="cline-any cline-no">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-no">&nbsp;</span>
454
+ <span class="cline-any cline-no">&nbsp;</span>
455
+ <span class="cline-any cline-neutral">&nbsp;</span>
456
+ <span class="cline-any cline-neutral">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-no">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-no">&nbsp;</span>
462
+ <span class="cline-any cline-no">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-neutral">&nbsp;</span>
465
+ <span class="cline-any cline-no">&nbsp;</span>
466
+ <span class="cline-any cline-no">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-neutral">&nbsp;</span>
469
+ <span class="cline-any cline-no">&nbsp;</span>
470
+ <span class="cline-any cline-no">&nbsp;</span>
471
+ <span class="cline-any cline-neutral">&nbsp;</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-no">&nbsp;</span>
474
+ <span class="cline-any cline-no">&nbsp;</span>
475
+ <span class="cline-any cline-neutral">&nbsp;</span>
476
+ <span class="cline-any cline-neutral">&nbsp;</span>
477
+ <span class="cline-any cline-no">&nbsp;</span>
478
+ <span class="cline-any cline-neutral">&nbsp;</span>
479
+ <span class="cline-any cline-neutral">&nbsp;</span>
480
+ <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-neutral">&nbsp;</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
483
+ <span class="cline-any cline-neutral">&nbsp;</span>
484
+ <span class="cline-any cline-no">&nbsp;</span>
485
+ <span class="cline-any cline-no">&nbsp;</span>
486
+ <span class="cline-any cline-neutral">&nbsp;</span>
487
+ <span class="cline-any cline-no">&nbsp;</span>
488
+ <span class="cline-any cline-no">&nbsp;</span>
489
+ <span class="cline-any cline-neutral">&nbsp;</span>
490
+ <span class="cline-any cline-neutral">&nbsp;</span>
491
+ <span class="cline-any cline-no">&nbsp;</span>
492
+ <span class="cline-any cline-no">&nbsp;</span>
493
+ <span class="cline-any cline-no">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-no">&nbsp;</span>
496
+ <span class="cline-any cline-no">&nbsp;</span>
497
+ <span class="cline-any cline-neutral">&nbsp;</span>
498
+ <span class="cline-any cline-no">&nbsp;</span>
499
+ <span class="cline-any cline-neutral">&nbsp;</span>
500
+ <span class="cline-any cline-neutral">&nbsp;</span>
501
+ <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-neutral">&nbsp;</span>
505
+ <span class="cline-any cline-neutral">&nbsp;</span>
506
+ <span class="cline-any cline-neutral">&nbsp;</span>
507
+ <span class="cline-any cline-no">&nbsp;</span>
508
+ <span class="cline-any cline-no">&nbsp;</span>
509
+ <span class="cline-any cline-no">&nbsp;</span>
510
+ <span class="cline-any cline-no">&nbsp;</span>
511
+ <span class="cline-any cline-no">&nbsp;</span>
512
+ <span class="cline-any cline-no">&nbsp;</span>
513
+ <span class="cline-any cline-neutral">&nbsp;</span>
514
+ <span class="cline-any cline-neutral">&nbsp;</span>
515
+ <span class="cline-any cline-neutral">&nbsp;</span>
516
+ <span class="cline-any cline-neutral">&nbsp;</span>
517
+ <span class="cline-any cline-no">&nbsp;</span>
518
+ <span class="cline-any cline-neutral">&nbsp;</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-neutral">&nbsp;</span>
522
+ <span class="cline-any cline-neutral">&nbsp;</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-neutral">&nbsp;</span>
525
+ <span class="cline-any cline-neutral">&nbsp;</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-no">&nbsp;</span>
528
+ <span class="cline-any cline-neutral">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-neutral">&nbsp;</span>
532
+ <span class="cline-any cline-neutral">&nbsp;</span>
533
+ <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-no">&nbsp;</span>
535
+ <span class="cline-any cline-no">&nbsp;</span>
536
+ <span class="cline-any cline-neutral">&nbsp;</span>
537
+ <span class="cline-any cline-neutral">&nbsp;</span>
538
+ <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-neutral">&nbsp;</span>
542
+ <span class="cline-any cline-no">&nbsp;</span>
543
+ <span class="cline-any cline-no">&nbsp;</span>
544
+ <span class="cline-any cline-no">&nbsp;</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-no">&nbsp;</span>
547
+ <span class="cline-any cline-no">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-no">&nbsp;</span>
551
+ <span class="cline-any cline-neutral">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-neutral">&nbsp;</span>
554
+ <span class="cline-any cline-neutral">&nbsp;</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-neutral">&nbsp;</span>
557
+ <span class="cline-any cline-no">&nbsp;</span>
558
+ <span class="cline-any cline-no">&nbsp;</span>
559
+ <span class="cline-any cline-no">&nbsp;</span>
560
+ <span class="cline-any cline-no">&nbsp;</span>
561
+ <span class="cline-any cline-no">&nbsp;</span>
562
+ <span class="cline-any cline-no">&nbsp;</span>
563
+ <span class="cline-any cline-neutral">&nbsp;</span>
564
+ <span class="cline-any cline-neutral">&nbsp;</span>
565
+ <span class="cline-any cline-neutral">&nbsp;</span>
566
+ <span class="cline-any cline-neutral">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-neutral">&nbsp;</span>
569
+ <span class="cline-any cline-neutral">&nbsp;</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-neutral">&nbsp;</span>
572
+ <span class="cline-any cline-neutral">&nbsp;</span>
573
+ <span class="cline-any cline-neutral">&nbsp;</span>
574
+ <span class="cline-any cline-neutral">&nbsp;</span>
575
+ <span class="cline-any cline-neutral">&nbsp;</span>
576
+ <span class="cline-any cline-no">&nbsp;</span>
577
+ <span class="cline-any cline-neutral">&nbsp;</span>
578
+ <span class="cline-any cline-neutral">&nbsp;</span>
579
+ <span class="cline-any cline-neutral">&nbsp;</span>
580
+ <span class="cline-any cline-neutral">&nbsp;</span>
581
+ <span class="cline-any cline-neutral">&nbsp;</span>
582
+ <span class="cline-any cline-neutral">&nbsp;</span>
583
+ <span class="cline-any cline-no">&nbsp;</span>
584
+ <span class="cline-any cline-no">&nbsp;</span>
585
+ <span class="cline-any cline-neutral">&nbsp;</span>
586
+ <span class="cline-any cline-no">&nbsp;</span>
587
+ <span class="cline-any cline-no">&nbsp;</span>
588
+ <span class="cline-any cline-no">&nbsp;</span>
589
+ <span class="cline-any cline-neutral">&nbsp;</span>
590
+ <span class="cline-any cline-no">&nbsp;</span>
591
+ <span class="cline-any cline-no">&nbsp;</span>
592
+ <span class="cline-any cline-neutral">&nbsp;</span>
593
+ <span class="cline-any cline-neutral">&nbsp;</span>
594
+ <span class="cline-any cline-no">&nbsp;</span>
595
+ <span class="cline-any cline-neutral">&nbsp;</span>
596
+ <span class="cline-any cline-neutral">&nbsp;</span>
597
+ <span class="cline-any cline-neutral">&nbsp;</span>
598
+ <span class="cline-any cline-neutral">&nbsp;</span>
599
+ <span class="cline-any cline-no">&nbsp;</span>
600
+ <span class="cline-any cline-no">&nbsp;</span>
601
+ <span class="cline-any cline-no">&nbsp;</span>
602
+ <span class="cline-any cline-no">&nbsp;</span>
603
+ <span class="cline-any cline-no">&nbsp;</span>
604
+ <span class="cline-any cline-no">&nbsp;</span>
605
+ <span class="cline-any cline-neutral">&nbsp;</span>
606
+ <span class="cline-any cline-neutral">&nbsp;</span>
607
+ <span class="cline-any cline-neutral">&nbsp;</span>
608
+ <span class="cline-any cline-neutral">&nbsp;</span>
609
+ <span class="cline-any cline-no">&nbsp;</span>
610
+ <span class="cline-any cline-neutral">&nbsp;</span>
611
+ <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-neutral">&nbsp;</span>
613
+ <span class="cline-any cline-neutral">&nbsp;</span>
614
+ <span class="cline-any cline-neutral">&nbsp;</span>
615
+ <span class="cline-any cline-neutral">&nbsp;</span>
616
+ <span class="cline-any cline-neutral">&nbsp;</span>
617
+ <span class="cline-any cline-neutral">&nbsp;</span>
618
+ <span class="cline-any cline-no">&nbsp;</span>
619
+ <span class="cline-any cline-neutral">&nbsp;</span>
620
+ <span class="cline-any cline-neutral">&nbsp;</span>
621
+ <span class="cline-any cline-neutral">&nbsp;</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-neutral">&nbsp;</span>
624
+ <span class="cline-any cline-neutral">&nbsp;</span>
625
+ <span class="cline-any cline-no">&nbsp;</span>
626
+ <span class="cline-any cline-no">&nbsp;</span>
627
+ <span class="cline-any cline-neutral">&nbsp;</span>
628
+ <span class="cline-any cline-no">&nbsp;</span>
629
+ <span class="cline-any cline-no">&nbsp;</span>
630
+ <span class="cline-any cline-no">&nbsp;</span>
631
+ <span class="cline-any cline-neutral">&nbsp;</span>
632
+ <span class="cline-any cline-no">&nbsp;</span>
633
+ <span class="cline-any cline-no">&nbsp;</span>
634
+ <span class="cline-any cline-neutral">&nbsp;</span>
635
+ <span class="cline-any cline-neutral">&nbsp;</span>
636
+ <span class="cline-any cline-no">&nbsp;</span>
637
+ <span class="cline-any cline-neutral">&nbsp;</span>
638
+ <span class="cline-any cline-neutral">&nbsp;</span>
639
+ <span class="cline-any cline-neutral">&nbsp;</span>
640
+ <span class="cline-any cline-neutral">&nbsp;</span>
641
+ <span class="cline-any cline-no">&nbsp;</span>
642
+ <span class="cline-any cline-no">&nbsp;</span>
643
+ <span class="cline-any cline-no">&nbsp;</span>
644
+ <span class="cline-any cline-no">&nbsp;</span>
645
+ <span class="cline-any cline-no">&nbsp;</span>
646
+ <span class="cline-any cline-no">&nbsp;</span>
647
+ <span class="cline-any cline-neutral">&nbsp;</span>
648
+ <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-neutral">&nbsp;</span>
650
+ <span class="cline-any cline-neutral">&nbsp;</span>
651
+ <span class="cline-any cline-no">&nbsp;</span>
652
+ <span class="cline-any cline-neutral">&nbsp;</span>
653
+ <span class="cline-any cline-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-neutral">&nbsp;</span>
655
+ <span class="cline-any cline-neutral">&nbsp;</span>
656
+ <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-neutral">&nbsp;</span>
658
+ <span class="cline-any cline-neutral">&nbsp;</span>
659
+ <span class="cline-any cline-neutral">&nbsp;</span>
660
+ <span class="cline-any cline-no">&nbsp;</span>
661
+ <span class="cline-any cline-neutral">&nbsp;</span>
662
+ <span class="cline-any cline-neutral">&nbsp;</span>
663
+ <span class="cline-any cline-neutral">&nbsp;</span>
664
+ <span class="cline-any cline-neutral">&nbsp;</span>
665
+ <span class="cline-any cline-neutral">&nbsp;</span>
666
+ <span class="cline-any cline-neutral">&nbsp;</span>
667
+ <span class="cline-any cline-no">&nbsp;</span>
668
+ <span class="cline-any cline-no">&nbsp;</span>
669
+ <span class="cline-any cline-neutral">&nbsp;</span>
670
+ <span class="cline-any cline-no">&nbsp;</span>
671
+ <span class="cline-any cline-no">&nbsp;</span>
672
+ <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-neutral">&nbsp;</span>
674
+ <span class="cline-any cline-no">&nbsp;</span>
675
+ <span class="cline-any cline-no">&nbsp;</span>
676
+ <span class="cline-any cline-neutral">&nbsp;</span>
677
+ <span class="cline-any cline-neutral">&nbsp;</span>
678
+ <span class="cline-any cline-no">&nbsp;</span>
679
+ <span class="cline-any cline-no">&nbsp;</span>
680
+ <span class="cline-any cline-no">&nbsp;</span>
681
+ <span class="cline-any cline-no">&nbsp;</span>
682
+ <span class="cline-any cline-no">&nbsp;</span>
683
+ <span class="cline-any cline-no">&nbsp;</span>
684
+ <span class="cline-any cline-no">&nbsp;</span>
685
+ <span class="cline-any cline-no">&nbsp;</span>
686
+ <span class="cline-any cline-neutral">&nbsp;</span>
687
+ <span class="cline-any cline-neutral">&nbsp;</span>
688
+ <span class="cline-any cline-neutral">&nbsp;</span>
689
+ <span class="cline-any cline-neutral">&nbsp;</span>
690
+ <span class="cline-any cline-neutral">&nbsp;</span>
691
+ <span class="cline-any cline-neutral">&nbsp;</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span>
693
+ <span class="cline-any cline-neutral">&nbsp;</span>
694
+ <span class="cline-any cline-neutral">&nbsp;</span>
695
+ <span class="cline-any cline-neutral">&nbsp;</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-no">&nbsp;</span>
698
+ <span class="cline-any cline-neutral">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-neutral">&nbsp;</span>
701
+ <span class="cline-any cline-neutral">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-neutral">&nbsp;</span>
704
+ <span class="cline-any cline-no">&nbsp;</span>
705
+ <span class="cline-any cline-no">&nbsp;</span>
706
+ <span class="cline-any cline-neutral">&nbsp;</span>
707
+ <span class="cline-any cline-no">&nbsp;</span>
708
+ <span class="cline-any cline-no">&nbsp;</span>
709
+ <span class="cline-any cline-no">&nbsp;</span>
710
+ <span class="cline-any cline-neutral">&nbsp;</span>
711
+ <span class="cline-any cline-no">&nbsp;</span>
712
+ <span class="cline-any cline-no">&nbsp;</span>
713
+ <span class="cline-any cline-neutral">&nbsp;</span>
714
+ <span class="cline-any cline-neutral">&nbsp;</span>
715
+ <span class="cline-any cline-no">&nbsp;</span>
716
+ <span class="cline-any cline-neutral">&nbsp;</span>
717
+ <span class="cline-any cline-neutral">&nbsp;</span>
718
+ <span class="cline-any cline-neutral">&nbsp;</span>
719
+ <span class="cline-any cline-neutral">&nbsp;</span>
720
+ <span class="cline-any cline-no">&nbsp;</span>
721
+ <span class="cline-any cline-no">&nbsp;</span>
722
+ <span class="cline-any cline-no">&nbsp;</span>
723
+ <span class="cline-any cline-no">&nbsp;</span>
724
+ <span class="cline-any cline-no">&nbsp;</span>
725
+ <span class="cline-any cline-no">&nbsp;</span>
726
+ <span class="cline-any cline-neutral">&nbsp;</span>
727
+ <span class="cline-any cline-neutral">&nbsp;</span>
728
+ <span class="cline-any cline-neutral">&nbsp;</span>
729
+ <span class="cline-any cline-neutral">&nbsp;</span>
730
+ <span class="cline-any cline-no">&nbsp;</span>
731
+ <span class="cline-any cline-neutral">&nbsp;</span>
732
+ <span class="cline-any cline-neutral">&nbsp;</span>
733
+ <span class="cline-any cline-neutral">&nbsp;</span>
734
+ <span class="cline-any cline-neutral">&nbsp;</span>
735
+ <span class="cline-any cline-neutral">&nbsp;</span>
736
+ <span class="cline-any cline-neutral">&nbsp;</span>
737
+ <span class="cline-any cline-neutral">&nbsp;</span>
738
+ <span class="cline-any cline-neutral">&nbsp;</span>
739
+ <span class="cline-any cline-no">&nbsp;</span>
740
+ <span class="cline-any cline-neutral">&nbsp;</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-neutral">&nbsp;</span>
743
+ <span class="cline-any cline-neutral">&nbsp;</span>
744
+ <span class="cline-any cline-neutral">&nbsp;</span>
745
+ <span class="cline-any cline-neutral">&nbsp;</span>
746
+ <span class="cline-any cline-no">&nbsp;</span>
747
+ <span class="cline-any cline-no">&nbsp;</span>
748
+ <span class="cline-any cline-neutral">&nbsp;</span>
749
+ <span class="cline-any cline-no">&nbsp;</span>
750
+ <span class="cline-any cline-no">&nbsp;</span>
751
+ <span class="cline-any cline-no">&nbsp;</span>
752
+ <span class="cline-any cline-neutral">&nbsp;</span>
753
+ <span class="cline-any cline-no">&nbsp;</span>
754
+ <span class="cline-any cline-no">&nbsp;</span>
755
+ <span class="cline-any cline-no">&nbsp;</span>
756
+ <span class="cline-any cline-neutral">&nbsp;</span>
757
+ <span class="cline-any cline-no">&nbsp;</span>
758
+ <span class="cline-any cline-neutral">&nbsp;</span>
759
+ <span class="cline-any cline-no">&nbsp;</span>
760
+ <span class="cline-any cline-neutral">&nbsp;</span>
761
+ <span class="cline-any cline-neutral">&nbsp;</span>
762
+ <span class="cline-any cline-no">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-neutral">&nbsp;</span>
765
+ <span class="cline-any cline-neutral">&nbsp;</span>
766
+ <span class="cline-any cline-neutral">&nbsp;</span>
767
+ <span class="cline-any cline-neutral">&nbsp;</span>
768
+ <span class="cline-any cline-neutral">&nbsp;</span>
769
+ <span class="cline-any cline-no">&nbsp;</span>
770
+ <span class="cline-any cline-no">&nbsp;</span>
771
+ <span class="cline-any cline-no">&nbsp;</span>
772
+ <span class="cline-any cline-no">&nbsp;</span>
773
+ <span class="cline-any cline-no">&nbsp;</span>
774
+ <span class="cline-any cline-no">&nbsp;</span>
775
+ <span class="cline-any cline-neutral">&nbsp;</span>
776
+ <span class="cline-any cline-neutral">&nbsp;</span>
777
+ <span class="cline-any cline-neutral">&nbsp;</span>
778
+ <span class="cline-any cline-neutral">&nbsp;</span>
779
+ <span class="cline-any cline-no">&nbsp;</span>
780
+ <span class="cline-any cline-neutral">&nbsp;</span>
781
+ <span class="cline-any cline-neutral">&nbsp;</span>
782
+ <span class="cline-any cline-neutral">&nbsp;</span>
783
+ <span class="cline-any cline-neutral">&nbsp;</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-neutral">&nbsp;</span>
786
+ <span class="cline-any cline-neutral">&nbsp;</span>
787
+ <span class="cline-any cline-neutral">&nbsp;</span>
788
+ <span class="cline-any cline-neutral">&nbsp;</span>
789
+ <span class="cline-any cline-no">&nbsp;</span>
790
+ <span class="cline-any cline-neutral">&nbsp;</span>
791
+ <span class="cline-any cline-neutral">&nbsp;</span>
792
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import * as fs from 'fs';
793
+ import * as path from 'path';
794
+ &nbsp;
795
+ export interface PortInfo {
796
+ port: number;
797
+ script: string | null;
798
+ source: string;
799
+ }
800
+ &nbsp;
801
+ /**
802
+ * Extract ports from a project's configuration files
803
+ */
804
+ export async function <span class="fstat-no" title="function not covered" >extractPortsFromProject(</span>projectPath: string): Promise&lt;PortInfo[]&gt; {
805
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
806
+ &nbsp;
807
+ // Extract from package.json scripts
808
+ const packageJsonPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromPackageJson(projectPath);</span>
809
+ <span class="cstat-no" title="statement not covered" > ports.push(...packageJsonPorts);</span>
810
+ &nbsp;
811
+ // Extract from vite.config.js/ts
812
+ const vitePorts = <span class="cstat-no" title="statement not covered" >extractPortsFromViteConfig(projectPath);</span>
813
+ <span class="cstat-no" title="statement not covered" > ports.push(...vitePorts);</span>
814
+ &nbsp;
815
+ // Extract from next.config.js/ts
816
+ const nextPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromNextConfig(projectPath);</span>
817
+ <span class="cstat-no" title="statement not covered" > ports.push(...nextPorts);</span>
818
+ &nbsp;
819
+ // Extract from webpack.config.js
820
+ const webpackPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromWebpackConfig(projectPath);</span>
821
+ <span class="cstat-no" title="statement not covered" > ports.push(...webpackPorts);</span>
822
+ &nbsp;
823
+ // Extract from angular.json
824
+ const angularPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromAngularConfig(projectPath);</span>
825
+ <span class="cstat-no" title="statement not covered" > ports.push(...angularPorts);</span>
826
+ &nbsp;
827
+ // Extract from nuxt.config.js/ts
828
+ const nuxtPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromNuxtConfig(projectPath);</span>
829
+ <span class="cstat-no" title="statement not covered" > ports.push(...nuxtPorts);</span>
830
+ &nbsp;
831
+ // Extract from .env files
832
+ const envPorts = <span class="cstat-no" title="statement not covered" >extractPortsFromEnvFiles(projectPath);</span>
833
+ <span class="cstat-no" title="statement not covered" > ports.push(...envPorts);</span>
834
+ &nbsp;
835
+ // Remove duplicates (same port and script)
836
+ const uniquePorts = <span class="cstat-no" title="statement not covered" >Array.from(</span>
837
+ new Map(ports.map(<span class="fstat-no" title="function not covered" >p </span>=&gt; <span class="cstat-no" title="statement not covered" >[`${p.port}-${p.script || ''}`, p])</span>).values()
838
+ );
839
+ &nbsp;
840
+ <span class="cstat-no" title="statement not covered" > return uniquePorts;</span>
841
+ }
842
+ &nbsp;
843
+ /**
844
+ * Extract ports from package.json scripts
845
+ */
846
+ function <span class="fstat-no" title="function not covered" >extractPortsFromPackageJson(</span>projectPath: string): PortInfo[] {
847
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
848
+ const packageJsonPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, 'package.json');</span>
849
+ &nbsp;
850
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(packageJsonPath)) {</span>
851
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
852
+ }
853
+ &nbsp;
854
+ <span class="cstat-no" title="statement not covered" > try {</span>
855
+ const packageJson = <span class="cstat-no" title="statement not covered" >JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));</span>
856
+ const scripts = <span class="cstat-no" title="statement not covered" >packageJson.scripts || {};</span>
857
+ &nbsp;
858
+ <span class="cstat-no" title="statement not covered" > for (const [scriptName, scriptCommand] of Object.entries(scripts)) {</span>
859
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof scriptCommand === 'string') {</span>
860
+ // Look for --port, -p, PORT= patterns
861
+ const portPatterns = <span class="cstat-no" title="statement not covered" >[</span>
862
+ /--port\s+(\d+)/i,
863
+ /-p\s+(\d+)/i,
864
+ /PORT\s*=\s*(\d+)/i,
865
+ /VITE_PORT\s*=\s*(\d+)/i,
866
+ /NEXT_PORT\s*=\s*(\d+)/i,
867
+ /PORT=(\d+)/i,
868
+ ];
869
+ &nbsp;
870
+ <span class="cstat-no" title="statement not covered" > for (const pattern of portPatterns) {</span>
871
+ const match = <span class="cstat-no" title="statement not covered" >scriptCommand.match(pattern);</span>
872
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
873
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
874
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
875
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
876
+ port,
877
+ script: scriptName,
878
+ source: 'package.json',
879
+ });
880
+ <span class="cstat-no" title="statement not covered" > break; </span>// Only add once per script
881
+ }
882
+ }
883
+ }
884
+ }
885
+ }
886
+ } catch (error) {
887
+ // Ignore parsing errors
888
+ }
889
+ &nbsp;
890
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
891
+ }
892
+ &nbsp;
893
+ /**
894
+ * Extract ports from vite.config.js/ts
895
+ */
896
+ function <span class="fstat-no" title="function not covered" >extractPortsFromViteConfig(</span>projectPath: string): PortInfo[] {
897
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
898
+ const configFiles = <span class="cstat-no" title="statement not covered" >[</span>
899
+ 'vite.config.js',
900
+ 'vite.config.ts',
901
+ 'vite.config.mjs',
902
+ 'vite.config.cjs',
903
+ ];
904
+ &nbsp;
905
+ <span class="cstat-no" title="statement not covered" > for (const configFile of configFiles) {</span>
906
+ const configPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, configFile);</span>
907
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(configPath)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
908
+ &nbsp;
909
+ <span class="cstat-no" title="statement not covered" > try {</span>
910
+ const content = <span class="cstat-no" title="statement not covered" >fs.readFileSync(configPath, 'utf-8');</span>
911
+
912
+ // Try to extract from server.port
913
+ const patterns = <span class="cstat-no" title="statement not covered" >[</span>
914
+ /server\s*:\s*\{[^}]*port\s*:\s*(\d+)/i,
915
+ /server\s*:\s*\{[^}]*port\s*:\s*['"](\d+)['"]/i,
916
+ /port\s*:\s*(\d+)/i,
917
+ /port\s*:\s*['"](\d+)['"]/i,
918
+ ];
919
+ &nbsp;
920
+ <span class="cstat-no" title="statement not covered" > for (const pattern of patterns) {</span>
921
+ const match = <span class="cstat-no" title="statement not covered" >content.match(pattern);</span>
922
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
923
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
924
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
925
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
926
+ port,
927
+ script: null,
928
+ source: configFile,
929
+ });
930
+ <span class="cstat-no" title="statement not covered" > break;</span>
931
+ }
932
+ }
933
+ }
934
+ } catch (error) {
935
+ // Ignore parsing errors
936
+ }
937
+ }
938
+ &nbsp;
939
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
940
+ }
941
+ &nbsp;
942
+ /**
943
+ * Extract ports from next.config.js/ts
944
+ */
945
+ function <span class="fstat-no" title="function not covered" >extractPortsFromNextConfig(</span>projectPath: string): PortInfo[] {
946
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
947
+ const configFiles = <span class="cstat-no" title="statement not covered" >['next.config.js', 'next.config.ts', 'next.config.mjs'];</span>
948
+ &nbsp;
949
+ <span class="cstat-no" title="statement not covered" > for (const configFile of configFiles) {</span>
950
+ const configPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, configFile);</span>
951
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(configPath)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
952
+ &nbsp;
953
+ <span class="cstat-no" title="statement not covered" > try {</span>
954
+ const content = <span class="cstat-no" title="statement not covered" >fs.readFileSync(configPath, 'utf-8');</span>
955
+
956
+ // Next.js doesn't typically configure port in config, but check for devServer
957
+ const patterns = <span class="cstat-no" title="statement not covered" >[</span>
958
+ /devServer\s*:\s*\{[^}]*port\s*:\s*(\d+)/i,
959
+ /port\s*:\s*(\d+)/i,
960
+ ];
961
+ &nbsp;
962
+ <span class="cstat-no" title="statement not covered" > for (const pattern of patterns) {</span>
963
+ const match = <span class="cstat-no" title="statement not covered" >content.match(pattern);</span>
964
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
965
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
966
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
967
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
968
+ port,
969
+ script: null,
970
+ source: configFile,
971
+ });
972
+ <span class="cstat-no" title="statement not covered" > break;</span>
973
+ }
974
+ }
975
+ }
976
+ } catch (error) {
977
+ // Ignore parsing errors
978
+ }
979
+ }
980
+ &nbsp;
981
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
982
+ }
983
+ &nbsp;
984
+ /**
985
+ * Extract ports from webpack.config.js
986
+ */
987
+ function <span class="fstat-no" title="function not covered" >extractPortsFromWebpackConfig(</span>projectPath: string): PortInfo[] {
988
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
989
+ const configFiles = <span class="cstat-no" title="statement not covered" >['webpack.config.js', 'webpack.config.ts'];</span>
990
+ &nbsp;
991
+ <span class="cstat-no" title="statement not covered" > for (const configFile of configFiles) {</span>
992
+ const configPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, configFile);</span>
993
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(configPath)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
994
+ &nbsp;
995
+ <span class="cstat-no" title="statement not covered" > try {</span>
996
+ const content = <span class="cstat-no" title="statement not covered" >fs.readFileSync(configPath, 'utf-8');</span>
997
+
998
+ // Look for devServer.port
999
+ const patterns = <span class="cstat-no" title="statement not covered" >[</span>
1000
+ /devServer\s*:\s*\{[^}]*port\s*:\s*(\d+)/i,
1001
+ /devServer\s*:\s*\{[^}]*port\s*:\s*['"](\d+)['"]/i,
1002
+ ];
1003
+ &nbsp;
1004
+ <span class="cstat-no" title="statement not covered" > for (const pattern of patterns) {</span>
1005
+ const match = <span class="cstat-no" title="statement not covered" >content.match(pattern);</span>
1006
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
1007
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
1008
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
1009
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
1010
+ port,
1011
+ script: null,
1012
+ source: configFile,
1013
+ });
1014
+ <span class="cstat-no" title="statement not covered" > break;</span>
1015
+ }
1016
+ }
1017
+ }
1018
+ } catch (error) {
1019
+ // Ignore parsing errors
1020
+ }
1021
+ }
1022
+ &nbsp;
1023
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
1024
+ }
1025
+ &nbsp;
1026
+ /**
1027
+ * Extract ports from angular.json
1028
+ */
1029
+ function <span class="fstat-no" title="function not covered" >extractPortsFromAngularConfig(</span>projectPath: string): PortInfo[] {
1030
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
1031
+ const configPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, 'angular.json');</span>
1032
+ &nbsp;
1033
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(configPath)) {</span>
1034
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
1035
+ }
1036
+ &nbsp;
1037
+ <span class="cstat-no" title="statement not covered" > try {</span>
1038
+ const angularJson = <span class="cstat-no" title="statement not covered" >JSON.parse(fs.readFileSync(configPath, 'utf-8'));</span>
1039
+
1040
+ // Navigate through projects -&gt; architect -&gt; serve -&gt; options -&gt; port
1041
+ const projects = <span class="cstat-no" title="statement not covered" >angularJson.projects || {};</span>
1042
+ <span class="cstat-no" title="statement not covered" > for (const projectName of Object.keys(projects)) {</span>
1043
+ const project = <span class="cstat-no" title="statement not covered" >projects[projectName];</span>
1044
+ const serve = <span class="cstat-no" title="statement not covered" >project?.architect?.serve;</span>
1045
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (serve?.options?.port) {</span>
1046
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(serve.options.port, 10);</span>
1047
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
1048
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
1049
+ port,
1050
+ script: null,
1051
+ source: 'angular.json',
1052
+ });
1053
+ }
1054
+ }
1055
+ }
1056
+ } catch (error) {
1057
+ // Ignore parsing errors
1058
+ }
1059
+ &nbsp;
1060
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
1061
+ }
1062
+ &nbsp;
1063
+ /**
1064
+ * Extract ports from nuxt.config.js/ts
1065
+ */
1066
+ function <span class="fstat-no" title="function not covered" >extractPortsFromNuxtConfig(</span>projectPath: string): PortInfo[] {
1067
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
1068
+ const configFiles = <span class="cstat-no" title="statement not covered" >['nuxt.config.js', 'nuxt.config.ts'];</span>
1069
+ &nbsp;
1070
+ <span class="cstat-no" title="statement not covered" > for (const configFile of configFiles) {</span>
1071
+ const configPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, configFile);</span>
1072
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(configPath)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
1073
+ &nbsp;
1074
+ <span class="cstat-no" title="statement not covered" > try {</span>
1075
+ const content = <span class="cstat-no" title="statement not covered" >fs.readFileSync(configPath, 'utf-8');</span>
1076
+
1077
+ // Look for server.port
1078
+ const patterns = <span class="cstat-no" title="statement not covered" >[</span>
1079
+ /server\s*:\s*\{[^}]*port\s*:\s*(\d+)/i,
1080
+ /server\s*:\s*\{[^}]*port\s*:\s*['"](\d+)['"]/i,
1081
+ ];
1082
+ &nbsp;
1083
+ <span class="cstat-no" title="statement not covered" > for (const pattern of patterns) {</span>
1084
+ const match = <span class="cstat-no" title="statement not covered" >content.match(pattern);</span>
1085
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
1086
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
1087
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
1088
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
1089
+ port,
1090
+ script: null,
1091
+ source: configFile,
1092
+ });
1093
+ <span class="cstat-no" title="statement not covered" > break;</span>
1094
+ }
1095
+ }
1096
+ }
1097
+ } catch (error) {
1098
+ // Ignore parsing errors
1099
+ }
1100
+ }
1101
+ &nbsp;
1102
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
1103
+ }
1104
+ &nbsp;
1105
+ /**
1106
+ * Extract ports from .env files
1107
+ */
1108
+ function <span class="fstat-no" title="function not covered" >extractPortsFromEnvFiles(</span>projectPath: string): PortInfo[] {
1109
+ const ports: PortInfo[] = <span class="cstat-no" title="statement not covered" >[];</span>
1110
+ const envFiles = <span class="cstat-no" title="statement not covered" >['.env', '.env.local', '.env.development', '.env.production'];</span>
1111
+ &nbsp;
1112
+ <span class="cstat-no" title="statement not covered" > for (const envFile of envFiles) {</span>
1113
+ const envPath = <span class="cstat-no" title="statement not covered" >path.join(projectPath, envFile);</span>
1114
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fs.existsSync(envPath)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
1115
+ &nbsp;
1116
+ <span class="cstat-no" title="statement not covered" > try {</span>
1117
+ const content = <span class="cstat-no" title="statement not covered" >fs.readFileSync(envPath, 'utf-8');</span>
1118
+ const lines = <span class="cstat-no" title="statement not covered" >content.split('\n');</span>
1119
+ &nbsp;
1120
+ <span class="cstat-no" title="statement not covered" > for (const line of lines) {</span>
1121
+ // Skip comments
1122
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (line.trim().startsWith('#')) <span class="cstat-no" title="statement not covered" >continue;</span></span>
1123
+ &nbsp;
1124
+ // Look for PORT=, VITE_PORT=, NEXT_PORT=, etc.
1125
+ const patterns = <span class="cstat-no" title="statement not covered" >[</span>
1126
+ /^PORT\s*=\s*(\d+)/i,
1127
+ /^VITE_PORT\s*=\s*(\d+)/i,
1128
+ /^NEXT_PORT\s*=\s*(\d+)/i,
1129
+ /^REACT_APP_PORT\s*=\s*(\d+)/i,
1130
+ ];
1131
+ &nbsp;
1132
+ <span class="cstat-no" title="statement not covered" > for (const pattern of patterns) {</span>
1133
+ const match = <span class="cstat-no" title="statement not covered" >line.match(pattern);</span>
1134
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (match &amp;&amp; match[1]) {</span>
1135
+ const port = <span class="cstat-no" title="statement not covered" >parseInt(match[1], 10);</span>
1136
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!isNaN(port) &amp;&amp; port &gt; 0 &amp;&amp; port &lt;= 65535) {</span>
1137
+ <span class="cstat-no" title="statement not covered" > ports.push({</span>
1138
+ port,
1139
+ script: null,
1140
+ source: envFile,
1141
+ });
1142
+ <span class="cstat-no" title="statement not covered" > break;</span>
1143
+ }
1144
+ }
1145
+ }
1146
+ }
1147
+ } catch (error) {
1148
+ // Ignore parsing errors
1149
+ }
1150
+ }
1151
+ &nbsp;
1152
+ <span class="cstat-no" title="statement not covered" > return ports;</span>
1153
+ }
1154
+ &nbsp;
1155
+ &nbsp;</pre></td></tr></table></pre>
1156
+
1157
+ <div class='push'></div><!-- for sticky footer -->
1158
+ </div><!-- /wrapper -->
1159
+ <div class='footer quiet pad2 space-top1 center small'>
1160
+ Code coverage generated by
1161
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1162
+ at 2025-11-20T01:55:35.186Z
1163
+ </div>
1164
+ <script src="prettify.js"></script>
1165
+ <script>
1166
+ window.onload = function () {
1167
+ prettyPrint();
1168
+ };
1169
+ </script>
1170
+ <script src="sorter.js"></script>
1171
+ <script src="block-navigation.js"></script>
1172
+ </body>
1173
+ </html>
1174
+