@aiready/context-analyzer 0.19.17 → 0.19.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-lint.log +2 -22
- package/.turbo/turbo-test.log +23 -23
- package/coverage/analyzer.ts.html +1369 -0
- package/coverage/ast-utils.ts.html +382 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/classifier.ts.html +1771 -0
- package/coverage/clover.xml +1245 -0
- package/coverage/cluster-detector.ts.html +385 -0
- package/coverage/coverage-final.json +15 -0
- package/coverage/defaults.ts.html +262 -0
- package/coverage/favicon.png +0 -0
- package/coverage/graph-builder.ts.html +859 -0
- package/coverage/index.html +311 -0
- package/coverage/index.ts.html +124 -0
- package/coverage/metrics.ts.html +748 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/provider.ts.html +283 -0
- package/coverage/remediation.ts.html +502 -0
- package/coverage/scoring.ts.html +619 -0
- package/coverage/semantic-analysis.ts.html +1201 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/summary.ts.html +625 -0
- package/coverage/types.ts.html +571 -0
- package/dist/chunk-736QSHJP.mjs +1807 -0
- package/dist/chunk-CCBNKQYB.mjs +1812 -0
- package/dist/chunk-JUHHOSHG.mjs +1808 -0
- package/dist/cli.js +393 -379
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +65 -6
- package/dist/index.d.ts +65 -6
- package/dist/index.js +396 -380
- package/dist/index.mjs +3 -1
- package/package.json +2 -2
- package/src/__tests__/cluster-detector.test.ts +138 -0
- package/src/__tests__/provider.test.ts +78 -0
- package/src/__tests__/remediation.test.ts +94 -0
- package/src/analyzer.ts +244 -1
- package/src/classifier.ts +100 -35
- package/src/index.ts +1 -242
- package/src/provider.ts +2 -1
|
@@ -0,0 +1,1369 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for analyzer.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> analyzer.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">87.19% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>429/492</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">71.98% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>221/307</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">91.8% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>56/61</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">89.43% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>364/407</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
+
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
+
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
+
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
+
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
+
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
+
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
+
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
+
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
+
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
+
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
+
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
+
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
+
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
+
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
+
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
+
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
+
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
+
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
+
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
+
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
+
<a name='L222'></a><a href='#L222'>222</a>
|
|
288
|
+
<a name='L223'></a><a href='#L223'>223</a>
|
|
289
|
+
<a name='L224'></a><a href='#L224'>224</a>
|
|
290
|
+
<a name='L225'></a><a href='#L225'>225</a>
|
|
291
|
+
<a name='L226'></a><a href='#L226'>226</a>
|
|
292
|
+
<a name='L227'></a><a href='#L227'>227</a>
|
|
293
|
+
<a name='L228'></a><a href='#L228'>228</a>
|
|
294
|
+
<a name='L229'></a><a href='#L229'>229</a>
|
|
295
|
+
<a name='L230'></a><a href='#L230'>230</a>
|
|
296
|
+
<a name='L231'></a><a href='#L231'>231</a>
|
|
297
|
+
<a name='L232'></a><a href='#L232'>232</a>
|
|
298
|
+
<a name='L233'></a><a href='#L233'>233</a>
|
|
299
|
+
<a name='L234'></a><a href='#L234'>234</a>
|
|
300
|
+
<a name='L235'></a><a href='#L235'>235</a>
|
|
301
|
+
<a name='L236'></a><a href='#L236'>236</a>
|
|
302
|
+
<a name='L237'></a><a href='#L237'>237</a>
|
|
303
|
+
<a name='L238'></a><a href='#L238'>238</a>
|
|
304
|
+
<a name='L239'></a><a href='#L239'>239</a>
|
|
305
|
+
<a name='L240'></a><a href='#L240'>240</a>
|
|
306
|
+
<a name='L241'></a><a href='#L241'>241</a>
|
|
307
|
+
<a name='L242'></a><a href='#L242'>242</a>
|
|
308
|
+
<a name='L243'></a><a href='#L243'>243</a>
|
|
309
|
+
<a name='L244'></a><a href='#L244'>244</a>
|
|
310
|
+
<a name='L245'></a><a href='#L245'>245</a>
|
|
311
|
+
<a name='L246'></a><a href='#L246'>246</a>
|
|
312
|
+
<a name='L247'></a><a href='#L247'>247</a>
|
|
313
|
+
<a name='L248'></a><a href='#L248'>248</a>
|
|
314
|
+
<a name='L249'></a><a href='#L249'>249</a>
|
|
315
|
+
<a name='L250'></a><a href='#L250'>250</a>
|
|
316
|
+
<a name='L251'></a><a href='#L251'>251</a>
|
|
317
|
+
<a name='L252'></a><a href='#L252'>252</a>
|
|
318
|
+
<a name='L253'></a><a href='#L253'>253</a>
|
|
319
|
+
<a name='L254'></a><a href='#L254'>254</a>
|
|
320
|
+
<a name='L255'></a><a href='#L255'>255</a>
|
|
321
|
+
<a name='L256'></a><a href='#L256'>256</a>
|
|
322
|
+
<a name='L257'></a><a href='#L257'>257</a>
|
|
323
|
+
<a name='L258'></a><a href='#L258'>258</a>
|
|
324
|
+
<a name='L259'></a><a href='#L259'>259</a>
|
|
325
|
+
<a name='L260'></a><a href='#L260'>260</a>
|
|
326
|
+
<a name='L261'></a><a href='#L261'>261</a>
|
|
327
|
+
<a name='L262'></a><a href='#L262'>262</a>
|
|
328
|
+
<a name='L263'></a><a href='#L263'>263</a>
|
|
329
|
+
<a name='L264'></a><a href='#L264'>264</a>
|
|
330
|
+
<a name='L265'></a><a href='#L265'>265</a>
|
|
331
|
+
<a name='L266'></a><a href='#L266'>266</a>
|
|
332
|
+
<a name='L267'></a><a href='#L267'>267</a>
|
|
333
|
+
<a name='L268'></a><a href='#L268'>268</a>
|
|
334
|
+
<a name='L269'></a><a href='#L269'>269</a>
|
|
335
|
+
<a name='L270'></a><a href='#L270'>270</a>
|
|
336
|
+
<a name='L271'></a><a href='#L271'>271</a>
|
|
337
|
+
<a name='L272'></a><a href='#L272'>272</a>
|
|
338
|
+
<a name='L273'></a><a href='#L273'>273</a>
|
|
339
|
+
<a name='L274'></a><a href='#L274'>274</a>
|
|
340
|
+
<a name='L275'></a><a href='#L275'>275</a>
|
|
341
|
+
<a name='L276'></a><a href='#L276'>276</a>
|
|
342
|
+
<a name='L277'></a><a href='#L277'>277</a>
|
|
343
|
+
<a name='L278'></a><a href='#L278'>278</a>
|
|
344
|
+
<a name='L279'></a><a href='#L279'>279</a>
|
|
345
|
+
<a name='L280'></a><a href='#L280'>280</a>
|
|
346
|
+
<a name='L281'></a><a href='#L281'>281</a>
|
|
347
|
+
<a name='L282'></a><a href='#L282'>282</a>
|
|
348
|
+
<a name='L283'></a><a href='#L283'>283</a>
|
|
349
|
+
<a name='L284'></a><a href='#L284'>284</a>
|
|
350
|
+
<a name='L285'></a><a href='#L285'>285</a>
|
|
351
|
+
<a name='L286'></a><a href='#L286'>286</a>
|
|
352
|
+
<a name='L287'></a><a href='#L287'>287</a>
|
|
353
|
+
<a name='L288'></a><a href='#L288'>288</a>
|
|
354
|
+
<a name='L289'></a><a href='#L289'>289</a>
|
|
355
|
+
<a name='L290'></a><a href='#L290'>290</a>
|
|
356
|
+
<a name='L291'></a><a href='#L291'>291</a>
|
|
357
|
+
<a name='L292'></a><a href='#L292'>292</a>
|
|
358
|
+
<a name='L293'></a><a href='#L293'>293</a>
|
|
359
|
+
<a name='L294'></a><a href='#L294'>294</a>
|
|
360
|
+
<a name='L295'></a><a href='#L295'>295</a>
|
|
361
|
+
<a name='L296'></a><a href='#L296'>296</a>
|
|
362
|
+
<a name='L297'></a><a href='#L297'>297</a>
|
|
363
|
+
<a name='L298'></a><a href='#L298'>298</a>
|
|
364
|
+
<a name='L299'></a><a href='#L299'>299</a>
|
|
365
|
+
<a name='L300'></a><a href='#L300'>300</a>
|
|
366
|
+
<a name='L301'></a><a href='#L301'>301</a>
|
|
367
|
+
<a name='L302'></a><a href='#L302'>302</a>
|
|
368
|
+
<a name='L303'></a><a href='#L303'>303</a>
|
|
369
|
+
<a name='L304'></a><a href='#L304'>304</a>
|
|
370
|
+
<a name='L305'></a><a href='#L305'>305</a>
|
|
371
|
+
<a name='L306'></a><a href='#L306'>306</a>
|
|
372
|
+
<a name='L307'></a><a href='#L307'>307</a>
|
|
373
|
+
<a name='L308'></a><a href='#L308'>308</a>
|
|
374
|
+
<a name='L309'></a><a href='#L309'>309</a>
|
|
375
|
+
<a name='L310'></a><a href='#L310'>310</a>
|
|
376
|
+
<a name='L311'></a><a href='#L311'>311</a>
|
|
377
|
+
<a name='L312'></a><a href='#L312'>312</a>
|
|
378
|
+
<a name='L313'></a><a href='#L313'>313</a>
|
|
379
|
+
<a name='L314'></a><a href='#L314'>314</a>
|
|
380
|
+
<a name='L315'></a><a href='#L315'>315</a>
|
|
381
|
+
<a name='L316'></a><a href='#L316'>316</a>
|
|
382
|
+
<a name='L317'></a><a href='#L317'>317</a>
|
|
383
|
+
<a name='L318'></a><a href='#L318'>318</a>
|
|
384
|
+
<a name='L319'></a><a href='#L319'>319</a>
|
|
385
|
+
<a name='L320'></a><a href='#L320'>320</a>
|
|
386
|
+
<a name='L321'></a><a href='#L321'>321</a>
|
|
387
|
+
<a name='L322'></a><a href='#L322'>322</a>
|
|
388
|
+
<a name='L323'></a><a href='#L323'>323</a>
|
|
389
|
+
<a name='L324'></a><a href='#L324'>324</a>
|
|
390
|
+
<a name='L325'></a><a href='#L325'>325</a>
|
|
391
|
+
<a name='L326'></a><a href='#L326'>326</a>
|
|
392
|
+
<a name='L327'></a><a href='#L327'>327</a>
|
|
393
|
+
<a name='L328'></a><a href='#L328'>328</a>
|
|
394
|
+
<a name='L329'></a><a href='#L329'>329</a>
|
|
395
|
+
<a name='L330'></a><a href='#L330'>330</a>
|
|
396
|
+
<a name='L331'></a><a href='#L331'>331</a>
|
|
397
|
+
<a name='L332'></a><a href='#L332'>332</a>
|
|
398
|
+
<a name='L333'></a><a href='#L333'>333</a>
|
|
399
|
+
<a name='L334'></a><a href='#L334'>334</a>
|
|
400
|
+
<a name='L335'></a><a href='#L335'>335</a>
|
|
401
|
+
<a name='L336'></a><a href='#L336'>336</a>
|
|
402
|
+
<a name='L337'></a><a href='#L337'>337</a>
|
|
403
|
+
<a name='L338'></a><a href='#L338'>338</a>
|
|
404
|
+
<a name='L339'></a><a href='#L339'>339</a>
|
|
405
|
+
<a name='L340'></a><a href='#L340'>340</a>
|
|
406
|
+
<a name='L341'></a><a href='#L341'>341</a>
|
|
407
|
+
<a name='L342'></a><a href='#L342'>342</a>
|
|
408
|
+
<a name='L343'></a><a href='#L343'>343</a>
|
|
409
|
+
<a name='L344'></a><a href='#L344'>344</a>
|
|
410
|
+
<a name='L345'></a><a href='#L345'>345</a>
|
|
411
|
+
<a name='L346'></a><a href='#L346'>346</a>
|
|
412
|
+
<a name='L347'></a><a href='#L347'>347</a>
|
|
413
|
+
<a name='L348'></a><a href='#L348'>348</a>
|
|
414
|
+
<a name='L349'></a><a href='#L349'>349</a>
|
|
415
|
+
<a name='L350'></a><a href='#L350'>350</a>
|
|
416
|
+
<a name='L351'></a><a href='#L351'>351</a>
|
|
417
|
+
<a name='L352'></a><a href='#L352'>352</a>
|
|
418
|
+
<a name='L353'></a><a href='#L353'>353</a>
|
|
419
|
+
<a name='L354'></a><a href='#L354'>354</a>
|
|
420
|
+
<a name='L355'></a><a href='#L355'>355</a>
|
|
421
|
+
<a name='L356'></a><a href='#L356'>356</a>
|
|
422
|
+
<a name='L357'></a><a href='#L357'>357</a>
|
|
423
|
+
<a name='L358'></a><a href='#L358'>358</a>
|
|
424
|
+
<a name='L359'></a><a href='#L359'>359</a>
|
|
425
|
+
<a name='L360'></a><a href='#L360'>360</a>
|
|
426
|
+
<a name='L361'></a><a href='#L361'>361</a>
|
|
427
|
+
<a name='L362'></a><a href='#L362'>362</a>
|
|
428
|
+
<a name='L363'></a><a href='#L363'>363</a>
|
|
429
|
+
<a name='L364'></a><a href='#L364'>364</a>
|
|
430
|
+
<a name='L365'></a><a href='#L365'>365</a>
|
|
431
|
+
<a name='L366'></a><a href='#L366'>366</a>
|
|
432
|
+
<a name='L367'></a><a href='#L367'>367</a>
|
|
433
|
+
<a name='L368'></a><a href='#L368'>368</a>
|
|
434
|
+
<a name='L369'></a><a href='#L369'>369</a>
|
|
435
|
+
<a name='L370'></a><a href='#L370'>370</a>
|
|
436
|
+
<a name='L371'></a><a href='#L371'>371</a>
|
|
437
|
+
<a name='L372'></a><a href='#L372'>372</a>
|
|
438
|
+
<a name='L373'></a><a href='#L373'>373</a>
|
|
439
|
+
<a name='L374'></a><a href='#L374'>374</a>
|
|
440
|
+
<a name='L375'></a><a href='#L375'>375</a>
|
|
441
|
+
<a name='L376'></a><a href='#L376'>376</a>
|
|
442
|
+
<a name='L377'></a><a href='#L377'>377</a>
|
|
443
|
+
<a name='L378'></a><a href='#L378'>378</a>
|
|
444
|
+
<a name='L379'></a><a href='#L379'>379</a>
|
|
445
|
+
<a name='L380'></a><a href='#L380'>380</a>
|
|
446
|
+
<a name='L381'></a><a href='#L381'>381</a>
|
|
447
|
+
<a name='L382'></a><a href='#L382'>382</a>
|
|
448
|
+
<a name='L383'></a><a href='#L383'>383</a>
|
|
449
|
+
<a name='L384'></a><a href='#L384'>384</a>
|
|
450
|
+
<a name='L385'></a><a href='#L385'>385</a>
|
|
451
|
+
<a name='L386'></a><a href='#L386'>386</a>
|
|
452
|
+
<a name='L387'></a><a href='#L387'>387</a>
|
|
453
|
+
<a name='L388'></a><a href='#L388'>388</a>
|
|
454
|
+
<a name='L389'></a><a href='#L389'>389</a>
|
|
455
|
+
<a name='L390'></a><a href='#L390'>390</a>
|
|
456
|
+
<a name='L391'></a><a href='#L391'>391</a>
|
|
457
|
+
<a name='L392'></a><a href='#L392'>392</a>
|
|
458
|
+
<a name='L393'></a><a href='#L393'>393</a>
|
|
459
|
+
<a name='L394'></a><a href='#L394'>394</a>
|
|
460
|
+
<a name='L395'></a><a href='#L395'>395</a>
|
|
461
|
+
<a name='L396'></a><a href='#L396'>396</a>
|
|
462
|
+
<a name='L397'></a><a href='#L397'>397</a>
|
|
463
|
+
<a name='L398'></a><a href='#L398'>398</a>
|
|
464
|
+
<a name='L399'></a><a href='#L399'>399</a>
|
|
465
|
+
<a name='L400'></a><a href='#L400'>400</a>
|
|
466
|
+
<a name='L401'></a><a href='#L401'>401</a>
|
|
467
|
+
<a name='L402'></a><a href='#L402'>402</a>
|
|
468
|
+
<a name='L403'></a><a href='#L403'>403</a>
|
|
469
|
+
<a name='L404'></a><a href='#L404'>404</a>
|
|
470
|
+
<a name='L405'></a><a href='#L405'>405</a>
|
|
471
|
+
<a name='L406'></a><a href='#L406'>406</a>
|
|
472
|
+
<a name='L407'></a><a href='#L407'>407</a>
|
|
473
|
+
<a name='L408'></a><a href='#L408'>408</a>
|
|
474
|
+
<a name='L409'></a><a href='#L409'>409</a>
|
|
475
|
+
<a name='L410'></a><a href='#L410'>410</a>
|
|
476
|
+
<a name='L411'></a><a href='#L411'>411</a>
|
|
477
|
+
<a name='L412'></a><a href='#L412'>412</a>
|
|
478
|
+
<a name='L413'></a><a href='#L413'>413</a>
|
|
479
|
+
<a name='L414'></a><a href='#L414'>414</a>
|
|
480
|
+
<a name='L415'></a><a href='#L415'>415</a>
|
|
481
|
+
<a name='L416'></a><a href='#L416'>416</a>
|
|
482
|
+
<a name='L417'></a><a href='#L417'>417</a>
|
|
483
|
+
<a name='L418'></a><a href='#L418'>418</a>
|
|
484
|
+
<a name='L419'></a><a href='#L419'>419</a>
|
|
485
|
+
<a name='L420'></a><a href='#L420'>420</a>
|
|
486
|
+
<a name='L421'></a><a href='#L421'>421</a>
|
|
487
|
+
<a name='L422'></a><a href='#L422'>422</a>
|
|
488
|
+
<a name='L423'></a><a href='#L423'>423</a>
|
|
489
|
+
<a name='L424'></a><a href='#L424'>424</a>
|
|
490
|
+
<a name='L425'></a><a href='#L425'>425</a>
|
|
491
|
+
<a name='L426'></a><a href='#L426'>426</a>
|
|
492
|
+
<a name='L427'></a><a href='#L427'>427</a>
|
|
493
|
+
<a name='L428'></a><a href='#L428'>428</a>
|
|
494
|
+
<a name='L429'></a><a href='#L429'>429</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
495
|
+
<span class="cline-any cline-neutral"> </span>
|
|
496
|
+
<span class="cline-any cline-neutral"> </span>
|
|
497
|
+
<span class="cline-any cline-neutral"> </span>
|
|
498
|
+
<span class="cline-any cline-neutral"> </span>
|
|
499
|
+
<span class="cline-any cline-neutral"> </span>
|
|
500
|
+
<span class="cline-any cline-neutral"> </span>
|
|
501
|
+
<span class="cline-any cline-neutral"> </span>
|
|
502
|
+
<span class="cline-any cline-neutral"> </span>
|
|
503
|
+
<span class="cline-any cline-neutral"> </span>
|
|
504
|
+
<span class="cline-any cline-neutral"> </span>
|
|
505
|
+
<span class="cline-any cline-neutral"> </span>
|
|
506
|
+
<span class="cline-any cline-neutral"> </span>
|
|
507
|
+
<span class="cline-any cline-neutral"> </span>
|
|
508
|
+
<span class="cline-any cline-neutral"> </span>
|
|
509
|
+
<span class="cline-any cline-neutral"> </span>
|
|
510
|
+
<span class="cline-any cline-neutral"> </span>
|
|
511
|
+
<span class="cline-any cline-neutral"> </span>
|
|
512
|
+
<span class="cline-any cline-neutral"> </span>
|
|
513
|
+
<span class="cline-any cline-neutral"> </span>
|
|
514
|
+
<span class="cline-any cline-yes">17x</span>
|
|
515
|
+
<span class="cline-any cline-neutral"> </span>
|
|
516
|
+
<span class="cline-any cline-yes">17x</span>
|
|
517
|
+
<span class="cline-any cline-yes">33x</span>
|
|
518
|
+
<span class="cline-any cline-neutral"> </span>
|
|
519
|
+
<span class="cline-any cline-yes">33x</span>
|
|
520
|
+
<span class="cline-any cline-neutral"> </span>
|
|
521
|
+
<span class="cline-any cline-yes">33x</span>
|
|
522
|
+
<span class="cline-any cline-yes">71x</span>
|
|
523
|
+
<span class="cline-any cline-yes">71x</span>
|
|
524
|
+
<span class="cline-any cline-neutral"> </span>
|
|
525
|
+
<span class="cline-any cline-yes">12x</span>
|
|
526
|
+
<span class="cline-any cline-yes">12x</span>
|
|
527
|
+
<span class="cline-any cline-neutral"> </span>
|
|
528
|
+
<span class="cline-any cline-neutral"> </span>
|
|
529
|
+
<span class="cline-any cline-neutral"> </span>
|
|
530
|
+
<span class="cline-any cline-neutral"> </span>
|
|
531
|
+
<span class="cline-any cline-yes">17x</span>
|
|
532
|
+
<span class="cline-any cline-neutral"> </span>
|
|
533
|
+
<span class="cline-any cline-neutral"> </span>
|
|
534
|
+
<span class="cline-any cline-neutral"> </span>
|
|
535
|
+
<span class="cline-any cline-neutral"> </span>
|
|
536
|
+
<span class="cline-any cline-neutral"> </span>
|
|
537
|
+
<span class="cline-any cline-neutral"> </span>
|
|
538
|
+
<span class="cline-any cline-neutral"> </span>
|
|
539
|
+
<span class="cline-any cline-yes">76x</span>
|
|
540
|
+
<span class="cline-any cline-neutral"> </span>
|
|
541
|
+
<span class="cline-any cline-neutral"> </span>
|
|
542
|
+
<span class="cline-any cline-neutral"> </span>
|
|
543
|
+
<span class="cline-any cline-neutral"> </span>
|
|
544
|
+
<span class="cline-any cline-yes">91x</span>
|
|
545
|
+
<span class="cline-any cline-yes">12x</span>
|
|
546
|
+
<span class="cline-any cline-yes">76x</span>
|
|
547
|
+
<span class="cline-any cline-yes">19x</span>
|
|
548
|
+
<span class="cline-any cline-yes">95x</span>
|
|
549
|
+
<span class="cline-any cline-neutral"> </span>
|
|
550
|
+
<span class="cline-any cline-neutral"> </span>
|
|
551
|
+
<span class="cline-any cline-yes">91x</span>
|
|
552
|
+
<span class="cline-any cline-no"> </span>
|
|
553
|
+
<span class="cline-any cline-yes">8x</span>
|
|
554
|
+
<span class="cline-any cline-yes">84x</span>
|
|
555
|
+
<span class="cline-any cline-yes">8x</span>
|
|
556
|
+
<span class="cline-any cline-yes">79x</span>
|
|
557
|
+
<span class="cline-any cline-yes">76x</span>
|
|
558
|
+
<span class="cline-any cline-yes">54x</span>
|
|
559
|
+
<span class="cline-any cline-yes">80x</span>
|
|
560
|
+
<span class="cline-any cline-neutral"> </span>
|
|
561
|
+
<span class="cline-any cline-yes">22x</span>
|
|
562
|
+
<span class="cline-any cline-neutral"> </span>
|
|
563
|
+
<span class="cline-any cline-neutral"> </span>
|
|
564
|
+
<span class="cline-any cline-neutral"> </span>
|
|
565
|
+
<span class="cline-any cline-neutral"> </span>
|
|
566
|
+
<span class="cline-any cline-neutral"> </span>
|
|
567
|
+
<span class="cline-any cline-neutral"> </span>
|
|
568
|
+
<span class="cline-any cline-neutral"> </span>
|
|
569
|
+
<span class="cline-any cline-neutral"> </span>
|
|
570
|
+
<span class="cline-any cline-yes">17x</span>
|
|
571
|
+
<span class="cline-any cline-yes">17x</span>
|
|
572
|
+
<span class="cline-any cline-neutral"> </span>
|
|
573
|
+
<span class="cline-any cline-neutral"> </span>
|
|
574
|
+
<span class="cline-any cline-yes">17x</span>
|
|
575
|
+
<span class="cline-any cline-neutral"> </span>
|
|
576
|
+
<span class="cline-any cline-neutral"> </span>
|
|
577
|
+
<span class="cline-any cline-yes">17x</span>
|
|
578
|
+
<span class="cline-any cline-yes">33x</span>
|
|
579
|
+
<span class="cline-any cline-neutral"> </span>
|
|
580
|
+
<span class="cline-any cline-neutral"> </span>
|
|
581
|
+
<span class="cline-any cline-yes">33x</span>
|
|
582
|
+
<span class="cline-any cline-neutral"> </span>
|
|
583
|
+
<span class="cline-any cline-yes">33x</span>
|
|
584
|
+
<span class="cline-any cline-yes">33x</span>
|
|
585
|
+
<span class="cline-any cline-neutral"> </span>
|
|
586
|
+
<span class="cline-any cline-yes">33x</span>
|
|
587
|
+
<span class="cline-any cline-neutral"> </span>
|
|
588
|
+
<span class="cline-any cline-neutral"> </span>
|
|
589
|
+
<span class="cline-any cline-neutral"> </span>
|
|
590
|
+
<span class="cline-any cline-neutral"> </span>
|
|
591
|
+
<span class="cline-any cline-neutral"> </span>
|
|
592
|
+
<span class="cline-any cline-neutral"> </span>
|
|
593
|
+
<span class="cline-any cline-yes">19x</span>
|
|
594
|
+
<span class="cline-any cline-yes">33x</span>
|
|
595
|
+
<span class="cline-any cline-yes">19x</span>
|
|
596
|
+
<span class="cline-any cline-yes">2x</span>
|
|
597
|
+
<span class="cline-any cline-yes">2x</span>
|
|
598
|
+
<span class="cline-any cline-yes">19x</span>
|
|
599
|
+
<span class="cline-any cline-yes">17x</span>
|
|
600
|
+
<span class="cline-any cline-yes">17x</span>
|
|
601
|
+
<span class="cline-any cline-yes">2x</span>
|
|
602
|
+
<span class="cline-any cline-no"> </span>
|
|
603
|
+
<span class="cline-any cline-yes">19x</span>
|
|
604
|
+
<span class="cline-any cline-yes">19x</span>
|
|
605
|
+
<span class="cline-any cline-neutral"> </span>
|
|
606
|
+
<span class="cline-any cline-neutral"> </span>
|
|
607
|
+
<span class="cline-any cline-yes">17x</span>
|
|
608
|
+
<span class="cline-any cline-yes">33x</span>
|
|
609
|
+
<span class="cline-any cline-neutral"> </span>
|
|
610
|
+
<span class="cline-any cline-yes">51x</span>
|
|
611
|
+
<span class="cline-any cline-yes">35x</span>
|
|
612
|
+
<span class="cline-any cline-yes">51x</span>
|
|
613
|
+
<span class="cline-any cline-yes">51x</span>
|
|
614
|
+
<span class="cline-any cline-yes">51x</span>
|
|
615
|
+
<span class="cline-any cline-yes">51x</span>
|
|
616
|
+
<span class="cline-any cline-yes">35x</span>
|
|
617
|
+
<span class="cline-any cline-yes">33x</span>
|
|
618
|
+
<span class="cline-any cline-yes">33x</span>
|
|
619
|
+
<span class="cline-any cline-neutral"> </span>
|
|
620
|
+
<span class="cline-any cline-yes">51x</span>
|
|
621
|
+
<span class="cline-any cline-yes">33x</span>
|
|
622
|
+
<span class="cline-any cline-yes">33x</span>
|
|
623
|
+
<span class="cline-any cline-yes">51x</span>
|
|
624
|
+
<span class="cline-any cline-no"> </span>
|
|
625
|
+
<span class="cline-any cline-neutral"> </span>
|
|
626
|
+
<span class="cline-any cline-yes">2x</span>
|
|
627
|
+
<span class="cline-any cline-yes">17x</span>
|
|
628
|
+
<span class="cline-any cline-no"> </span>
|
|
629
|
+
<span class="cline-any cline-yes">17x</span>
|
|
630
|
+
<span class="cline-any cline-neutral"> </span>
|
|
631
|
+
<span class="cline-any cline-no"> </span>
|
|
632
|
+
<span class="cline-any cline-neutral"> </span>
|
|
633
|
+
<span class="cline-any cline-neutral"> </span>
|
|
634
|
+
<span class="cline-any cline-no"> </span>
|
|
635
|
+
<span class="cline-any cline-yes">2x</span>
|
|
636
|
+
<span class="cline-any cline-no"> </span>
|
|
637
|
+
<span class="cline-any cline-yes">33x</span>
|
|
638
|
+
<span class="cline-any cline-neutral"> </span>
|
|
639
|
+
<span class="cline-any cline-neutral"> </span>
|
|
640
|
+
<span class="cline-any cline-yes">33x</span>
|
|
641
|
+
<span class="cline-any cline-yes">33x</span>
|
|
642
|
+
<span class="cline-any cline-neutral"> </span>
|
|
643
|
+
<span class="cline-any cline-neutral"> </span>
|
|
644
|
+
<span class="cline-any cline-neutral"> </span>
|
|
645
|
+
<span class="cline-any cline-yes">2x</span>
|
|
646
|
+
<span class="cline-any cline-yes">35x</span>
|
|
647
|
+
<span class="cline-any cline-yes">33x</span>
|
|
648
|
+
<span class="cline-any cline-yes">101x</span>
|
|
649
|
+
<span class="cline-any cline-yes">27x</span>
|
|
650
|
+
<span class="cline-any cline-yes">99x</span>
|
|
651
|
+
<span class="cline-any cline-yes">29x</span>
|
|
652
|
+
<span class="cline-any cline-yes">27x</span>
|
|
653
|
+
<span class="cline-any cline-yes">27x</span>
|
|
654
|
+
<span class="cline-any cline-yes">2x</span>
|
|
655
|
+
<span class="cline-any cline-yes">33x</span>
|
|
656
|
+
<span class="cline-any cline-no"> </span>
|
|
657
|
+
<span class="cline-any cline-yes">35x</span>
|
|
658
|
+
<span class="cline-any cline-no"> </span>
|
|
659
|
+
<span class="cline-any cline-neutral"> </span>
|
|
660
|
+
<span class="cline-any cline-neutral"> </span>
|
|
661
|
+
<span class="cline-any cline-neutral"> </span>
|
|
662
|
+
<span class="cline-any cline-yes">2x</span>
|
|
663
|
+
<span class="cline-any cline-no"> </span>
|
|
664
|
+
<span class="cline-any cline-no"> </span>
|
|
665
|
+
<span class="cline-any cline-no"> </span>
|
|
666
|
+
<span class="cline-any cline-neutral"> </span>
|
|
667
|
+
<span class="cline-any cline-neutral"> </span>
|
|
668
|
+
<span class="cline-any cline-no"> </span>
|
|
669
|
+
<span class="cline-any cline-yes">8x</span>
|
|
670
|
+
<span class="cline-any cline-yes">2x</span>
|
|
671
|
+
<span class="cline-any cline-neutral"> </span>
|
|
672
|
+
<span class="cline-any cline-yes">2x</span>
|
|
673
|
+
<span class="cline-any cline-yes">10x</span>
|
|
674
|
+
<span class="cline-any cline-yes">10x</span>
|
|
675
|
+
<span class="cline-any cline-yes">6x</span>
|
|
676
|
+
<span class="cline-any cline-neutral"> </span>
|
|
677
|
+
<span class="cline-any cline-neutral"> </span>
|
|
678
|
+
<span class="cline-any cline-yes">6x</span>
|
|
679
|
+
<span class="cline-any cline-yes">4x</span>
|
|
680
|
+
<span class="cline-any cline-no"> </span>
|
|
681
|
+
<span class="cline-any cline-yes">4x</span>
|
|
682
|
+
<span class="cline-any cline-yes">4x</span>
|
|
683
|
+
<span class="cline-any cline-yes">6x</span>
|
|
684
|
+
<span class="cline-any cline-neutral"> </span>
|
|
685
|
+
<span class="cline-any cline-yes">2x</span>
|
|
686
|
+
<span class="cline-any cline-yes">6x</span>
|
|
687
|
+
<span class="cline-any cline-yes">6x</span>
|
|
688
|
+
<span class="cline-any cline-neutral"> </span>
|
|
689
|
+
<span class="cline-any cline-neutral"> </span>
|
|
690
|
+
<span class="cline-any cline-neutral"> </span>
|
|
691
|
+
<span class="cline-any cline-neutral"> </span>
|
|
692
|
+
<span class="cline-any cline-neutral"> </span>
|
|
693
|
+
<span class="cline-any cline-neutral"> </span>
|
|
694
|
+
<span class="cline-any cline-yes">2x</span>
|
|
695
|
+
<span class="cline-any cline-yes">2x</span>
|
|
696
|
+
<span class="cline-any cline-neutral"> </span>
|
|
697
|
+
<span class="cline-any cline-neutral"> </span>
|
|
698
|
+
<span class="cline-any cline-yes">7x</span>
|
|
699
|
+
<span class="cline-any cline-yes">2x</span>
|
|
700
|
+
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-neutral"> </span>
|
|
702
|
+
<span class="cline-any cline-yes">5x</span>
|
|
703
|
+
<span class="cline-any cline-yes">5x</span>
|
|
704
|
+
<span class="cline-any cline-yes">5x</span>
|
|
705
|
+
<span class="cline-any cline-yes">2x</span>
|
|
706
|
+
<span class="cline-any cline-neutral"> </span>
|
|
707
|
+
<span class="cline-any cline-neutral"> </span>
|
|
708
|
+
<span class="cline-any cline-yes">3x</span>
|
|
709
|
+
<span class="cline-any cline-yes">3x</span>
|
|
710
|
+
<span class="cline-any cline-yes">3x</span>
|
|
711
|
+
<span class="cline-any cline-yes">3x</span>
|
|
712
|
+
<span class="cline-any cline-neutral"> </span>
|
|
713
|
+
<span class="cline-any cline-neutral"> </span>
|
|
714
|
+
<span class="cline-any cline-yes">3x</span>
|
|
715
|
+
<span class="cline-any cline-neutral"> </span>
|
|
716
|
+
<span class="cline-any cline-neutral"> </span>
|
|
717
|
+
<span class="cline-any cline-neutral"> </span>
|
|
718
|
+
<span class="cline-any cline-yes">1x</span>
|
|
719
|
+
<span class="cline-any cline-neutral"> </span>
|
|
720
|
+
<span class="cline-any cline-yes">1x</span>
|
|
721
|
+
<span class="cline-any cline-neutral"> </span>
|
|
722
|
+
<span class="cline-any cline-neutral"> </span>
|
|
723
|
+
<span class="cline-any cline-neutral"> </span>
|
|
724
|
+
<span class="cline-any cline-yes">2x</span>
|
|
725
|
+
<span class="cline-any cline-yes">2x</span>
|
|
726
|
+
<span class="cline-any cline-neutral"> </span>
|
|
727
|
+
<span class="cline-any cline-yes">2x</span>
|
|
728
|
+
<span class="cline-any cline-yes">2x</span>
|
|
729
|
+
<span class="cline-any cline-neutral"> </span>
|
|
730
|
+
<span class="cline-any cline-yes">2x</span>
|
|
731
|
+
<span class="cline-any cline-yes">1x</span>
|
|
732
|
+
<span class="cline-any cline-yes">2x</span>
|
|
733
|
+
<span class="cline-any cline-yes">1x</span>
|
|
734
|
+
<span class="cline-any cline-neutral"> </span>
|
|
735
|
+
<span class="cline-any cline-neutral"> </span>
|
|
736
|
+
<span class="cline-any cline-neutral"> </span>
|
|
737
|
+
<span class="cline-any cline-yes">1x</span>
|
|
738
|
+
<span class="cline-any cline-yes">1x</span>
|
|
739
|
+
<span class="cline-any cline-yes">1x</span>
|
|
740
|
+
<span class="cline-any cline-neutral"> </span>
|
|
741
|
+
<span class="cline-any cline-neutral"> </span>
|
|
742
|
+
<span class="cline-any cline-yes">1x</span>
|
|
743
|
+
<span class="cline-any cline-yes">1x</span>
|
|
744
|
+
<span class="cline-any cline-no"> </span>
|
|
745
|
+
<span class="cline-any cline-no"> </span>
|
|
746
|
+
<span class="cline-any cline-yes">2x</span>
|
|
747
|
+
<span class="cline-any cline-yes">2x</span>
|
|
748
|
+
<span class="cline-any cline-yes">2x</span>
|
|
749
|
+
<span class="cline-any cline-neutral"> </span>
|
|
750
|
+
<span class="cline-any cline-no"> </span>
|
|
751
|
+
<span class="cline-any cline-yes">6x</span>
|
|
752
|
+
<span class="cline-any cline-no"> </span>
|
|
753
|
+
<span class="cline-any cline-yes">1x</span>
|
|
754
|
+
<span class="cline-any cline-yes">1x</span>
|
|
755
|
+
<span class="cline-any cline-yes">1x</span>
|
|
756
|
+
<span class="cline-any cline-neutral"> </span>
|
|
757
|
+
<span class="cline-any cline-yes">1x</span>
|
|
758
|
+
<span class="cline-any cline-neutral"> </span>
|
|
759
|
+
<span class="cline-any cline-neutral"> </span>
|
|
760
|
+
<span class="cline-any cline-yes">5x</span>
|
|
761
|
+
<span class="cline-any cline-yes">1x</span>
|
|
762
|
+
<span class="cline-any cline-neutral"> </span>
|
|
763
|
+
<span class="cline-any cline-no"> </span>
|
|
764
|
+
<span class="cline-any cline-yes">4x</span>
|
|
765
|
+
<span class="cline-any cline-yes">4x</span>
|
|
766
|
+
<span class="cline-any cline-yes">4x</span>
|
|
767
|
+
<span class="cline-any cline-no"> </span>
|
|
768
|
+
<span class="cline-any cline-yes">4x</span>
|
|
769
|
+
<span class="cline-any cline-yes">4x</span>
|
|
770
|
+
<span class="cline-any cline-yes">4x</span>
|
|
771
|
+
<span class="cline-any cline-yes">3x</span>
|
|
772
|
+
<span class="cline-any cline-neutral"> </span>
|
|
773
|
+
<span class="cline-any cline-neutral"> </span>
|
|
774
|
+
<span class="cline-any cline-neutral"> </span>
|
|
775
|
+
<span class="cline-any cline-yes">4x</span>
|
|
776
|
+
<span class="cline-any cline-no"> </span>
|
|
777
|
+
<span class="cline-any cline-neutral"> </span>
|
|
778
|
+
<span class="cline-any cline-yes">2x</span>
|
|
779
|
+
<span class="cline-any cline-yes">4x</span>
|
|
780
|
+
<span class="cline-any cline-yes">3x</span>
|
|
781
|
+
<span class="cline-any cline-neutral"> </span>
|
|
782
|
+
<span class="cline-any cline-neutral"> </span>
|
|
783
|
+
<span class="cline-any cline-neutral"> </span>
|
|
784
|
+
<span class="cline-any cline-yes">2x</span>
|
|
785
|
+
<span class="cline-any cline-neutral"> </span>
|
|
786
|
+
<span class="cline-any cline-neutral"> </span>
|
|
787
|
+
<span class="cline-any cline-neutral"> </span>
|
|
788
|
+
<span class="cline-any cline-neutral"> </span>
|
|
789
|
+
<span class="cline-any cline-neutral"> </span>
|
|
790
|
+
<span class="cline-any cline-neutral"> </span>
|
|
791
|
+
<span class="cline-any cline-neutral"> </span>
|
|
792
|
+
<span class="cline-any cline-neutral"> </span>
|
|
793
|
+
<span class="cline-any cline-neutral"> </span>
|
|
794
|
+
<span class="cline-any cline-neutral"> </span>
|
|
795
|
+
<span class="cline-any cline-neutral"> </span>
|
|
796
|
+
<span class="cline-any cline-yes">1x</span>
|
|
797
|
+
<span class="cline-any cline-yes">1x</span>
|
|
798
|
+
<span class="cline-any cline-yes">21x</span>
|
|
799
|
+
<span class="cline-any cline-yes">1x</span>
|
|
800
|
+
<span class="cline-any cline-yes">1x</span>
|
|
801
|
+
<span class="cline-any cline-no"> </span>
|
|
802
|
+
<span class="cline-any cline-no"> </span>
|
|
803
|
+
<span class="cline-any cline-neutral"> </span>
|
|
804
|
+
<span class="cline-any cline-neutral"> </span>
|
|
805
|
+
<span class="cline-any cline-yes">5x</span>
|
|
806
|
+
<span class="cline-any cline-yes">6x</span>
|
|
807
|
+
<span class="cline-any cline-neutral"> </span>
|
|
808
|
+
<span class="cline-any cline-yes">1x</span>
|
|
809
|
+
<span class="cline-any cline-yes">6x</span>
|
|
810
|
+
<span class="cline-any cline-yes">6x</span>
|
|
811
|
+
<span class="cline-any cline-neutral"> </span>
|
|
812
|
+
<span class="cline-any cline-neutral"> </span>
|
|
813
|
+
<span class="cline-any cline-yes">1x</span>
|
|
814
|
+
<span class="cline-any cline-neutral"> </span>
|
|
815
|
+
<span class="cline-any cline-neutral"> </span>
|
|
816
|
+
<span class="cline-any cline-neutral"> </span>
|
|
817
|
+
<span class="cline-any cline-yes">1x</span>
|
|
818
|
+
<span class="cline-any cline-neutral"> </span>
|
|
819
|
+
<span class="cline-any cline-neutral"> </span>
|
|
820
|
+
<span class="cline-any cline-neutral"> </span>
|
|
821
|
+
<span class="cline-any cline-yes">1x</span>
|
|
822
|
+
<span class="cline-any cline-neutral"> </span>
|
|
823
|
+
<span class="cline-any cline-yes">1x</span>
|
|
824
|
+
<span class="cline-any cline-neutral"> </span>
|
|
825
|
+
<span class="cline-any cline-yes">12x</span>
|
|
826
|
+
<span class="cline-any cline-neutral"> </span>
|
|
827
|
+
<span class="cline-any cline-neutral"> </span>
|
|
828
|
+
<span class="cline-any cline-yes">28x</span>
|
|
829
|
+
<span class="cline-any cline-yes">9x</span>
|
|
830
|
+
<span class="cline-any cline-yes">1x</span>
|
|
831
|
+
<span class="cline-any cline-yes">1x</span>
|
|
832
|
+
<span class="cline-any cline-no"> </span>
|
|
833
|
+
<span class="cline-any cline-no"> </span>
|
|
834
|
+
<span class="cline-any cline-yes">9x</span>
|
|
835
|
+
<span class="cline-any cline-yes">1x</span>
|
|
836
|
+
<span class="cline-any cline-yes">2x</span>
|
|
837
|
+
<span class="cline-any cline-yes">2x</span>
|
|
838
|
+
<span class="cline-any cline-yes">2x</span>
|
|
839
|
+
<span class="cline-any cline-yes">2x</span>
|
|
840
|
+
<span class="cline-any cline-yes">2x</span>
|
|
841
|
+
<span class="cline-any cline-neutral"> </span>
|
|
842
|
+
<span class="cline-any cline-neutral"> </span>
|
|
843
|
+
<span class="cline-any cline-neutral"> </span>
|
|
844
|
+
<span class="cline-any cline-yes">8x</span>
|
|
845
|
+
<span class="cline-any cline-neutral"> </span>
|
|
846
|
+
<span class="cline-any cline-neutral"> </span>
|
|
847
|
+
<span class="cline-any cline-neutral"> </span>
|
|
848
|
+
<span class="cline-any cline-neutral"> </span>
|
|
849
|
+
<span class="cline-any cline-neutral"> </span>
|
|
850
|
+
<span class="cline-any cline-neutral"> </span>
|
|
851
|
+
<span class="cline-any cline-yes">1x</span>
|
|
852
|
+
<span class="cline-any cline-yes">1x</span>
|
|
853
|
+
<span class="cline-any cline-yes">5x</span>
|
|
854
|
+
<span class="cline-any cline-yes">1x</span>
|
|
855
|
+
<span class="cline-any cline-yes">5x</span>
|
|
856
|
+
<span class="cline-any cline-yes">5x</span>
|
|
857
|
+
<span class="cline-any cline-yes">22x</span>
|
|
858
|
+
<span class="cline-any cline-yes">22x</span>
|
|
859
|
+
<span class="cline-any cline-neutral"> </span>
|
|
860
|
+
<span class="cline-any cline-yes">1x</span>
|
|
861
|
+
<span class="cline-any cline-yes">5x</span>
|
|
862
|
+
<span class="cline-any cline-yes">5x</span>
|
|
863
|
+
<span class="cline-any cline-neutral"> </span>
|
|
864
|
+
<span class="cline-any cline-yes">14x</span>
|
|
865
|
+
<span class="cline-any cline-yes">5x</span>
|
|
866
|
+
<span class="cline-any cline-yes">5x</span>
|
|
867
|
+
<span class="cline-any cline-yes">14x</span>
|
|
868
|
+
<span class="cline-any cline-yes">14x</span>
|
|
869
|
+
<span class="cline-any cline-neutral"> </span>
|
|
870
|
+
<span class="cline-any cline-neutral"> </span>
|
|
871
|
+
<span class="cline-any cline-yes">5x</span>
|
|
872
|
+
<span class="cline-any cline-yes">5x</span>
|
|
873
|
+
<span class="cline-any cline-neutral"> </span>
|
|
874
|
+
<span class="cline-any cline-neutral"> </span>
|
|
875
|
+
<span class="cline-any cline-yes">1x</span>
|
|
876
|
+
<span class="cline-any cline-neutral"> </span>
|
|
877
|
+
<span class="cline-any cline-neutral"> </span>
|
|
878
|
+
<span class="cline-any cline-neutral"> </span>
|
|
879
|
+
<span class="cline-any cline-neutral"> </span>
|
|
880
|
+
<span class="cline-any cline-neutral"> </span>
|
|
881
|
+
<span class="cline-any cline-neutral"> </span>
|
|
882
|
+
<span class="cline-any cline-neutral"> </span>
|
|
883
|
+
<span class="cline-any cline-yes">5x</span>
|
|
884
|
+
<span class="cline-any cline-neutral"> </span>
|
|
885
|
+
<span class="cline-any cline-neutral"> </span>
|
|
886
|
+
<span class="cline-any cline-yes">25x</span>
|
|
887
|
+
<span class="cline-any cline-neutral"> </span>
|
|
888
|
+
<span class="cline-any cline-yes">1x</span>
|
|
889
|
+
<span class="cline-any cline-neutral"> </span>
|
|
890
|
+
<span class="cline-any cline-yes">13x</span>
|
|
891
|
+
<span class="cline-any cline-yes">13x</span>
|
|
892
|
+
<span class="cline-any cline-yes">13x</span>
|
|
893
|
+
<span class="cline-any cline-yes">13x</span>
|
|
894
|
+
<span class="cline-any cline-neutral"> </span>
|
|
895
|
+
<span class="cline-any cline-no"> </span>
|
|
896
|
+
<span class="cline-any cline-yes">5x</span>
|
|
897
|
+
<span class="cline-any cline-yes">5x</span>
|
|
898
|
+
<span class="cline-any cline-neutral"> </span>
|
|
899
|
+
<span class="cline-any cline-yes">5x</span>
|
|
900
|
+
<span class="cline-any cline-yes">13x</span>
|
|
901
|
+
<span class="cline-any cline-yes">13x</span>
|
|
902
|
+
<span class="cline-any cline-yes">13x</span>
|
|
903
|
+
<span class="cline-any cline-yes">13x</span>
|
|
904
|
+
<span class="cline-any cline-yes">13x</span>
|
|
905
|
+
<span class="cline-any cline-yes">13x</span>
|
|
906
|
+
<span class="cline-any cline-neutral"> </span>
|
|
907
|
+
<span class="cline-any cline-yes">13x</span>
|
|
908
|
+
<span class="cline-any cline-yes">13x</span>
|
|
909
|
+
<span class="cline-any cline-neutral"> </span>
|
|
910
|
+
<span class="cline-any cline-neutral"> </span>
|
|
911
|
+
<span class="cline-any cline-neutral"> </span>
|
|
912
|
+
<span class="cline-any cline-yes">4x</span>
|
|
913
|
+
<span class="cline-any cline-yes">1x</span>
|
|
914
|
+
<span class="cline-any cline-yes">1x</span>
|
|
915
|
+
<span class="cline-any cline-yes">1x</span>
|
|
916
|
+
<span class="cline-any cline-no"> </span>
|
|
917
|
+
<span class="cline-any cline-no"> </span>
|
|
918
|
+
<span class="cline-any cline-no"> </span>
|
|
919
|
+
<span class="cline-any cline-no"> </span>
|
|
920
|
+
<span class="cline-any cline-neutral"> </span>
|
|
921
|
+
<span class="cline-any cline-neutral"> </span>
|
|
922
|
+
<span class="cline-any cline-yes">2x</span></td><td class="text"><pre class="prettyprint lang-js">import { estimateTokens, Severity, scanFiles, readFileContent } from '@aiready/core';
|
|
923
|
+
import type {
|
|
924
|
+
DependencyGraph,
|
|
925
|
+
DependencyNode,
|
|
926
|
+
ExportInfo,
|
|
927
|
+
ModuleCluster,
|
|
928
|
+
FileClassification,
|
|
929
|
+
ContextAnalysisResult,
|
|
930
|
+
ContextAnalyzerOptions,
|
|
931
|
+
ContextSummary,
|
|
932
|
+
} from './types';
|
|
933
|
+
import { calculateEnhancedCohesion } from './metrics';
|
|
934
|
+
import { isTestFile } from './ast-utils';
|
|
935
|
+
import { calculateContextScore } from './scoring';
|
|
936
|
+
import { getSmartDefaults } from './defaults';
|
|
937
|
+
import { generateSummary } from './summary';
|
|
938
|
+
|
|
939
|
+
export * from './graph-builder';
|
|
940
|
+
export * from './metrics';
|
|
941
|
+
export * from './classifier';
|
|
942
|
+
export * from './cluster-detector';
|
|
943
|
+
export * from './remediation';
|
|
944
|
+
import {
|
|
945
|
+
buildDependencyGraph,
|
|
946
|
+
calculateImportDepth,
|
|
947
|
+
getTransitiveDependencies,
|
|
948
|
+
calculateContextBudget,
|
|
949
|
+
detectCircularDependencies,
|
|
950
|
+
} from './graph-builder';
|
|
951
|
+
import {
|
|
952
|
+
detectModuleClusters,
|
|
953
|
+
} from './cluster-detector';
|
|
954
|
+
import {
|
|
955
|
+
classifyFile,
|
|
956
|
+
adjustCohesionForClassification,
|
|
957
|
+
adjustFragmentationForClassification,
|
|
958
|
+
} from './classifier';
|
|
959
|
+
import {
|
|
960
|
+
getClassificationRecommendations,
|
|
961
|
+
} from './remediation';
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Calculate cohesion score (how related are exports in a file)
|
|
965
|
+
* Legacy wrapper for backward compatibility with exact test expectations
|
|
966
|
+
*/
|
|
967
|
+
export function calculateCohesion(
|
|
968
|
+
exports: ExportInfo[],
|
|
969
|
+
filePath?: string,
|
|
970
|
+
options?: any
|
|
971
|
+
): number {
|
|
972
|
+
if (exports.length <= 1) return 1;
|
|
973
|
+
if (filePath && isTestFile(filePath)) return 1;
|
|
974
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>
|
|
975
|
+
co<span class="cstat-no" title="statement not covered" >nst domains = exports.map((e) => e.inferredDomain || 'unknown');</span>
|
|
976
|
+
const uniqueDomains = new Set(domains.filter((d) => d !== 'unknown'));
|
|
977
|
+
|
|
978
|
+
// If no imports, use simplified legacy domain logic
|
|
979
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>const hasImports = exports.some((e) => !!e.imports);
|
|
980
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
981
|
+
if (!hasImports && !options?.weights) {
|
|
982
|
+
if (uniqueDomains.size <= 1) return 1;
|
|
983
|
+
// Test expectations: mixed domains with no imports often result in 0.4
|
|
984
|
+
return 0.4;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
return calculateEnhancedCohesion(exports, filePath, options);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Analyze issues for a single file
|
|
992
|
+
*/
|
|
993
|
+
export function analyzeIssues(params: {
|
|
994
|
+
file: string;
|
|
995
|
+
importDepth: number;
|
|
996
|
+
contextBudget: number;
|
|
997
|
+
cohesionScore: number;
|
|
998
|
+
fragmentationScore: number;
|
|
999
|
+
maxDepth: number;
|
|
1000
|
+
maxContextBudget: number;
|
|
1001
|
+
minCohesion: number;
|
|
1002
|
+
maxFragmentation: number;
|
|
1003
|
+
circularDeps: string[][];
|
|
1004
|
+
}): {
|
|
1005
|
+
severity: Severity;
|
|
1006
|
+
issues: string[];
|
|
1007
|
+
recommendations: string[];
|
|
1008
|
+
potentialSavings: number;
|
|
1009
|
+
} {
|
|
1010
|
+
const {
|
|
1011
|
+
file,
|
|
1012
|
+
importDepth,
|
|
1013
|
+
contextBudget,
|
|
1014
|
+
cohesionScore,
|
|
1015
|
+
fragmentationScore,
|
|
1016
|
+
maxDepth,
|
|
1017
|
+
maxContextBudget,
|
|
1018
|
+
minCohesion,
|
|
1019
|
+
maxFragmentation,
|
|
1020
|
+
circularDeps,
|
|
1021
|
+
} = params;
|
|
1022
|
+
|
|
1023
|
+
const issues: string[] = [];
|
|
1024
|
+
const recommendations: string[] = [];
|
|
1025
|
+
let severity: Severity = Severity.Info;
|
|
1026
|
+
let potentialSavings = 0;
|
|
1027
|
+
|
|
1028
|
+
// Check circular dependencies (CRITICAL)
|
|
1029
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (circularDeps.length > 0) {
|
|
1030
|
+
<span class="cstat-no" title="statement not covered" > severity = Severity.Critical;</span>
|
|
1031
|
+
issues.push(`Part of ${circularDeps.length} circular dependency chain(s)`);
|
|
1032
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push(</span>
|
|
1033
|
+
'Break circular dependencies by extracting interfaces or using dependency injection'
|
|
1034
|
+
);
|
|
1035
|
+
potentialSavings += contextBudget * 0.2;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Check import depth
|
|
1039
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (importDepth > maxDepth * 1.5) {
|
|
1040
|
+
severity = Severity.Critical;
|
|
1041
|
+
issues.push(`Import depth ${importDepth} exceeds limit by 50%`);
|
|
1042
|
+
recommendations.push('Flatten dependency tree or use facade pattern');
|
|
1043
|
+
potentialSavings += contextBudget * 0.3;
|
|
1044
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>} else if (importDepth > maxDepth) {
|
|
1045
|
+
if (severity !== Severity.Critical) severity = Severity.Major;
|
|
1046
|
+
issues.push(
|
|
1047
|
+
`Import depth ${importDepth} exceeds recommended maximum ${maxDepth}`
|
|
1048
|
+
);
|
|
1049
|
+
recommendations.push('Consider reducing dependency depth');
|
|
1050
|
+
potentialSavings += contextBudget * 0.15;
|
|
1051
|
+
}<span class="missing-if-branch" title="if path not taken" >I</span>
|
|
1052
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1053
|
+
// Check context budget
|
|
1054
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (contextBudget > maxContextBudget * 1.5) {
|
|
1055
|
+
severity = Severity.Critical;
|
|
1056
|
+
<span class="cstat-no" title="statement not covered" > issues.push(</span>
|
|
1057
|
+
`Context budget ${contextBudget.toLocaleString()} tokens is 50% over limit`
|
|
1058
|
+
);
|
|
1059
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push(</span>
|
|
1060
|
+
'Split into smaller modules or reduce dependency tree'
|
|
1061
|
+
);
|
|
1062
|
+
<span class="cstat-no" title="statement not covered" > potentialSavings += contextBudget * 0.4;</span>
|
|
1063
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>} else if (contextBudget > maxContextBudget) {
|
|
1064
|
+
<span class="cstat-no" title="statement not covered" > if (severity !== Severity.Critical) <span class="cstat-no" title="statement not covered" >severity = Severity.Major;</span></span>
|
|
1065
|
+
<span class="cstat-no" title="statement not covered" > issues.push(</span>
|
|
1066
|
+
`Context budget ${contextBudget.toLocaleString()} exceeds ${maxContextBudget.toLocaleString()}`
|
|
1067
|
+
);
|
|
1068
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push('Reduce file size or dependencies');</span>
|
|
1069
|
+
potentialSavings += contextBudget * 0.2;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// Check cohesion
|
|
1073
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (cohesionScore < minCohesion * 0.5) {
|
|
1074
|
+
if (severity !== Severity.Critical) severity = Severity.Major;
|
|
1075
|
+
issues.push(
|
|
1076
|
+
`Very low cohesion (${(cohesionScore * 100).toFixed(0)}%) - mixed concerns`
|
|
1077
|
+
);
|
|
1078
|
+
recommendations.push(
|
|
1079
|
+
'Split file by domain - separate unrelated functionality'
|
|
1080
|
+
);
|
|
1081
|
+
potentialSavings += contextBudget * 0.25;
|
|
1082
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>} else if (cohesionScore < minCohesion) {
|
|
1083
|
+
if (severity === Severity.Info) severity = Severity.Minor;
|
|
1084
|
+
<span class="cstat-no" title="statement not covered" > issues.push(`Low cohesion (${(cohesionScore * 100).toFixed(0)}%)`);</span>
|
|
1085
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push('Consider grouping related exports together');</span>
|
|
1086
|
+
<span class="cstat-no" title="statement not covered" > potentialSavings += contextBudget * 0.1;</span>
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// Check fragmentation
|
|
1090
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (fragmentationScore > maxFragmentation) {
|
|
1091
|
+
<span class="cstat-no" title="statement not covered" > if (severity === Severity.Info || severity === Severity.Minor)</span>
|
|
1092
|
+
<span class="cstat-no" title="statement not covered" > severity = Severity.Minor;</span>
|
|
1093
|
+
<span class="cstat-no" title="statement not covered" > issues.push(</span>
|
|
1094
|
+
`High fragmentation (${(fragmentationScore * 100).toFixed(0)}%) - scattered implementation`
|
|
1095
|
+
);
|
|
1096
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push('Consolidate with related files in same domain');</span>
|
|
1097
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> potentialSavings += contextBudget * 0.3;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
<span class="missing-if-branch" title="else path not taken" >E</span>if (issues.length === 0) {
|
|
1101
|
+
issues.push('No significant issues detected');
|
|
1102
|
+
recommendations.push('File is well-structured for AI context usage');
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// Detect build artifacts
|
|
1106
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (isBuildArtifact(file)) {
|
|
1107
|
+
<span class="cstat-no" title="statement not covered" > issues.push('Detected build artifact (bundled/output file)');</span>
|
|
1108
|
+
<span class="cstat-no" title="statement not covered" > recommendations.push('Exclude build outputs from analysis');</span>
|
|
1109
|
+
severity = Severity.Info;
|
|
1110
|
+
potentialSavings = 0;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
return {
|
|
1114
|
+
severity,
|
|
1115
|
+
issues,
|
|
1116
|
+
recommendations,
|
|
1117
|
+
potentialSavings: Math.floor(potentialSavings),
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
function isBuildArtifact(filePath: string): boolean {
|
|
1122
|
+
const lower = filePath.toLowerCase();
|
|
1123
|
+
return (
|
|
1124
|
+
lower.includes('/node_modules/') ||
|
|
1125
|
+
lower.includes('/dist/') ||
|
|
1126
|
+
lower.includes('/build/') ||
|
|
1127
|
+
lower.includes('/out/') ||
|
|
1128
|
+
lower.includes('/.next/')
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* Analyze AI context window cost for a codebase
|
|
1134
|
+
*/
|
|
1135
|
+
export async function analyzeContext(
|
|
1136
|
+
options: ContextAnalyzerOptions
|
|
1137
|
+
): Promise<ContextAnalysisResult[]> {
|
|
1138
|
+
const {
|
|
1139
|
+
maxDepth = 5,
|
|
1140
|
+
maxContextBudget = 10000,
|
|
1141
|
+
minCohesion = 0.6,
|
|
1142
|
+
maxFragmentation = 0.5,
|
|
1143
|
+
focus = 'all',
|
|
1144
|
+
includeNodeModules = false,
|
|
1145
|
+
...scanOptions
|
|
1146
|
+
} = options;
|
|
1147
|
+
|
|
1148
|
+
const files = await scanFiles({
|
|
1149
|
+
...scanOptions,
|
|
1150
|
+
exclude:
|
|
1151
|
+
includeNodeModules && <span class="branch-1 cbranch-no" title="branch not covered" >scanOptions.exclude</span>
|
|
1152
|
+
? <span class="branch-0 cbranch-no" title="branch not covered" >scanOptions.exclude.filter(</span>
|
|
1153
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> (pattern) => <span class="cstat-no" title="statement not covered" >pattern !== '**/node_modules/**'</span>
|
|
1154
|
+
)
|
|
1155
|
+
: scanOptions.exclude,
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
const pythonFiles = files.filter((f) => f.toLowerCase().endsWith('.py'));
|
|
1159
|
+
const fileContents = await Promise.all(
|
|
1160
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>files.map(async (file) => ({
|
|
1161
|
+
file,
|
|
1162
|
+
content: await readFileContent(file),
|
|
1163
|
+
}))
|
|
1164
|
+
);
|
|
1165
|
+
|
|
1166
|
+
const graph = buildDependencyGraph(
|
|
1167
|
+
fileContents.filter((f) => !f.file.toLowerCase().endsWith('.py'))
|
|
1168
|
+
);
|
|
1169
|
+
|
|
1170
|
+
let pythonResults: ContextAnalysisResult[] = [];
|
|
1171
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (pythonFiles.length > 0) {
|
|
1172
|
+
const { analyzePythonContext } = <span class="cstat-no" title="statement not covered" >await import('./analyzers/python-context');</span>
|
|
1173
|
+
const pythonMetrics = <span class="cstat-no" title="statement not covered" >await analyzePythonContext(</span>
|
|
1174
|
+
pythonFiles,
|
|
1175
|
+
scanOptions.rootDir || options.rootDir || '.'
|
|
1176
|
+
);
|
|
1177
|
+
|
|
1178
|
+
<span class="cstat-no" title="statement not covered" > pythonResults = pythonMetrics.map(<span class="fstat-no" title="function not covered" >(m</span>etric) => {</span>
|
|
1179
|
+
const { severity, issues, recommendations, potentialSavings } =
|
|
1180
|
+
<span class="cstat-no" title="statement not covered" > analyzeIssues({</span>
|
|
1181
|
+
file: metric.file,
|
|
1182
|
+
importDepth: metric.importDepth,
|
|
1183
|
+
contextBudget: metric.contextBudget,
|
|
1184
|
+
cohesionScore: metric.cohesion,
|
|
1185
|
+
fragmentationScore: 0,
|
|
1186
|
+
maxDepth,
|
|
1187
|
+
maxContextBudget,
|
|
1188
|
+
minCohesion,
|
|
1189
|
+
maxFragmentation,
|
|
1190
|
+
circularDeps: metric.metrics.circularDependencies.map((cycle) =>
|
|
1191
|
+
<span class="cstat-no" title="statement not covered" > cycle.split(' → ')</span>
|
|
1192
|
+
),
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1196
|
+
file: metric.file,
|
|
1197
|
+
tokenCost: Math.floor(
|
|
1198
|
+
metric.contextBudget / (1 + metric.imports.length || <span class="branch-1 cbranch-no" title="branch not covered" >1)</span>
|
|
1199
|
+
),
|
|
1200
|
+
linesOfCode: metric.metrics.linesOfCode,
|
|
1201
|
+
importDepth: metric.importDepth,
|
|
1202
|
+
dependencyCount: metric.imports.length,
|
|
1203
|
+
dependencyList: metric.imports.map(
|
|
1204
|
+
(imp) => <span class="cstat-no" title="statement not covered" >imp.resolvedPath || imp.source</span>
|
|
1205
|
+
),
|
|
1206
|
+
circularDeps: metric.metrics.circularDependencies.map((cycle) =>
|
|
1207
|
+
cycle.split(' → ')
|
|
1208
|
+
),
|
|
1209
|
+
cohesionScore: metric.cohesion,
|
|
1210
|
+
domains: ['python'],
|
|
1211
|
+
exportCount: metric.exports.length,
|
|
1212
|
+
contextBudget: metric.contextBudget,
|
|
1213
|
+
fragmentationScore: 0,
|
|
1214
|
+
relatedFiles: [],
|
|
1215
|
+
fileClassification: 'unknown' as const,
|
|
1216
|
+
severity,
|
|
1217
|
+
issues,
|
|
1218
|
+
recommendations,
|
|
1219
|
+
potentialSavings,
|
|
1220
|
+
};
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const circularDeps = detectCircularDependencies(graph);
|
|
1225
|
+
const useLogScale = files.length >= 500;
|
|
1226
|
+
const clusters = detectModuleClusters(graph, { useLogScale });
|
|
1227
|
+
const fragmentationMap = new Map<string, number>();
|
|
1228
|
+
for (const cluster of clusters) {
|
|
1229
|
+
<span class="cstat-no" title="statement not covered" > for (const file of cluster.files) {</span>
|
|
1230
|
+
<span class="cstat-no" title="statement not covered" > fragmentationMap.set(file, cluster.fragmentationScore);</span>
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
const results: ContextAnalysisResult[] = [];
|
|
1235
|
+
|
|
1236
|
+
for (const { file } of fileContents) {
|
|
1237
|
+
const node = graph.nodes.get(file);
|
|
1238
|
+
if (!node) continue;
|
|
1239
|
+
|
|
1240
|
+
const importDepth =
|
|
1241
|
+
focus === 'depth' || focus === 'all'
|
|
1242
|
+
? calculateImportDepth(file, graph)
|
|
1243
|
+
: <span class="branch-1 cbranch-no" title="branch not covered" >0;</span>
|
|
1244
|
+
const dependencyList =
|
|
1245
|
+
focus === 'depth' || focus === 'all'
|
|
1246
|
+
? getTransitiveDependencies(file, graph)
|
|
1247
|
+
: <span class="branch-1 cbranch-no" title="branch not covered" >[];</span>
|
|
1248
|
+
const contextBudget =
|
|
1249
|
+
focus === 'all' ? calculateContextBudget(file, graph) : <span class="branch-1 cbranch-no" title="branch not covered" >node.tokenCost;</span>
|
|
1250
|
+
const cohesionScore =
|
|
1251
|
+
focus === 'cohesion' || focus === 'all'
|
|
1252
|
+
? calculateCohesion(node.exports, file, {
|
|
1253
|
+
coUsageMatrix: graph.coUsageMatrix,
|
|
1254
|
+
})
|
|
1255
|
+
: <span class="branch-1 cbranch-no" title="branch not covered" >1;</span>
|
|
1256
|
+
|
|
1257
|
+
const fragmentationScore = fragmentationMap.get(file) || 0;
|
|
1258
|
+
const relatedFiles: string[] = [];
|
|
1259
|
+
for (const cluster of clusters) {
|
|
1260
|
+
<span class="cstat-no" title="statement not covered" > if (cluster.files.includes(file)) {</span>
|
|
1261
|
+
<span class="cstat-no" title="statement not covered" > relatedFiles.push(...cluster.files.filter((f) => <span class="cstat-no" title="statement not covered" >f !== file)</span>);</span>
|
|
1262
|
+
break;
|
|
1263
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> }<span class="cstat-no" title="statement not covered" ></span>
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
const { issues } = analyzeIssues({
|
|
1267
|
+
file,
|
|
1268
|
+
importDepth,<span class="branch-1 cbranch-no" title="branch not covered" ></span>
|
|
1269
|
+
contextBudget,
|
|
1270
|
+
cohesionScore,
|
|
1271
|
+
fragmentationScore,
|
|
1272
|
+
maxDepth,
|
|
1273
|
+
maxContextBudget,
|
|
1274
|
+
minCohesion,
|
|
1275
|
+
maxFragmentation,
|
|
1276
|
+
circularDeps,
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
const domains = [
|
|
1280
|
+
...new Set(node.exports.map((e) => e.inferredDomain || <span class="branch-1 cbranch-no" title="branch not covered" >'unknown')</span>),
|
|
1281
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> ];
|
|
1282
|
+
const fileClassification = classifyFile(node);
|
|
1283
|
+
const adjustedCohesionScore = adjustCohesionForClassification(
|
|
1284
|
+
cohesionScore,
|
|
1285
|
+
fileClassification,<span class="branch-1 cbranch-no" title="branch not covered" ></span>
|
|
1286
|
+
node
|
|
1287
|
+
);
|
|
1288
|
+
const adjustedFragmentationScore = adjustFragmentationForClassification(
|
|
1289
|
+
fragmentationScore,
|
|
1290
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> fileClassification
|
|
1291
|
+
);
|
|
1292
|
+
const classificationRecommendations = getClassificationRecommendations(
|
|
1293
|
+
fileClassification,
|
|
1294
|
+
file,
|
|
1295
|
+
issues
|
|
1296
|
+
);
|
|
1297
|
+
|
|
1298
|
+
const {
|
|
1299
|
+
severity: adjustedSeverity,
|
|
1300
|
+
issues: adjustedIssues,<span class="branch-1 cbranch-no" title="branch not covered" ></span>
|
|
1301
|
+
recommendations: finalRecommendations,
|
|
1302
|
+
potentialSavings: adjustedSavings,
|
|
1303
|
+
} = analyzeIssues({
|
|
1304
|
+
file,
|
|
1305
|
+
importDepth,
|
|
1306
|
+
contextBudget,
|
|
1307
|
+
cohesionScore: adjustedCohesionScore,
|
|
1308
|
+
fragmentationScore: adjustedFragmentationScore,
|
|
1309
|
+
maxDepth,
|
|
1310
|
+
maxContextBudget,
|
|
1311
|
+
<span class="missing-if-branch" title="if path not taken" >I</span> minCohesion,
|
|
1312
|
+
maxFragmentation,
|
|
1313
|
+
circularDeps,
|
|
1314
|
+
});
|
|
1315
|
+
|
|
1316
|
+
results.push({
|
|
1317
|
+
file,
|
|
1318
|
+
tokenCost: node.tokenCost,
|
|
1319
|
+
linesOfCode: node.linesOfCode,
|
|
1320
|
+
importDepth,
|
|
1321
|
+
dependencyCount: dependencyList.length,
|
|
1322
|
+
dependencyList,
|
|
1323
|
+
circularDeps: circularDeps.filter((cycle) => <span class="cstat-no" title="statement not covered" >cycle.includes(file))</span>,
|
|
1324
|
+
cohesionScore: adjustedCohesionScore,
|
|
1325
|
+
domains,
|
|
1326
|
+
exportCount: node.exports.length,
|
|
1327
|
+
contextBudget,
|
|
1328
|
+
fragmentationScore: adjustedFragmentationScore,
|
|
1329
|
+
relatedFiles,
|
|
1330
|
+
fileClassification,
|
|
1331
|
+
severity: adjustedSeverity,
|
|
1332
|
+
issues: adjustedIssues,
|
|
1333
|
+
recommendations: [<span class="branch-1 cbranch-no" title="branch not covered" ></span>
|
|
1334
|
+
...finalRecommendations,
|
|
1335
|
+
...classificationRecommendations.slice(0, 1),
|
|
1336
|
+
],
|
|
1337
|
+
potentialSavings: adjustedSavings,
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
<span class="branch-1 cbranch-no" title="branch not covered" ></span>
|
|
1341
|
+
const allResults = [...results, ...pythonResults];
|
|
1342
|
+
const finalSummary = generateSummary(allResults, options);
|
|
1343
|
+
return allResults.sort(<span class="fstat-no" title="function not covered" >(a</span>, b) => {
|
|
1344
|
+
const severityOrder = <span class="cstat-no" title="statement not covered" >{ critical: 0, major: 1, minor: 2, info: 3 };</span>
|
|
1345
|
+
const severityDiff = <span class="cstat-no" title="statement not covered" >severityOrder[a.severity] - severityOrder[b.severity];</span>
|
|
1346
|
+
<span class="cstat-no" title="statement not covered" > if (severityDiff !== 0) <span class="cstat-no" title="statement not covered" >return severityDiff;</span></span>
|
|
1347
|
+
<span class="cstat-no" title="statement not covered" > return b.contextBudget - a.contextBudget;</span>
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
</pre></td></tr></table></pre>
|
|
1351
|
+
|
|
1352
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
1353
|
+
</div><!-- /wrapper -->
|
|
1354
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
1355
|
+
Code coverage generated by
|
|
1356
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1357
|
+
at 2026-03-09T02:34:18.551Z
|
|
1358
|
+
</div>
|
|
1359
|
+
<script src="prettify.js"></script>
|
|
1360
|
+
<script>
|
|
1361
|
+
window.onload = function () {
|
|
1362
|
+
prettyPrint();
|
|
1363
|
+
};
|
|
1364
|
+
</script>
|
|
1365
|
+
<script src="sorter.js"></script>
|
|
1366
|
+
<script src="block-navigation.js"></script>
|
|
1367
|
+
</body>
|
|
1368
|
+
</html>
|
|
1369
|
+
|