a2acalling 0.6.74 → 0.6.75
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/.a2a-manifest.json +2 -2
- package/.c8rc.json +16 -0
- package/.node-version +1 -0
- package/.serena/project.yml +126 -0
- package/ARCHITECTURE.md +11 -0
- package/CONVENTIONS.md +9 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +146 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/index.html +131 -0
- package/coverage/src/index.js.html +313 -0
- package/coverage/src/lib/agent-card.js.html +418 -0
- package/coverage/src/lib/call-monitor.js.html +700 -0
- package/coverage/src/lib/callbook.js.html +1183 -0
- package/coverage/src/lib/claude-subagent.js.html +2173 -0
- package/coverage/src/lib/client.js.html +2134 -0
- package/coverage/src/lib/config.js.html +1525 -0
- package/coverage/src/lib/conversation-driver.js.html +1909 -0
- package/coverage/src/lib/conversations.js.html +2575 -0
- package/coverage/src/lib/crypto.js.html +424 -0
- package/coverage/src/lib/dashboard-events.js.html +724 -0
- package/coverage/src/lib/disclosure.js.html +2461 -0
- package/coverage/src/lib/external-ip.js.html +718 -0
- package/coverage/src/lib/index.html +506 -0
- package/coverage/src/lib/invite-host.js.html +754 -0
- package/coverage/src/lib/local-request.js.html +292 -0
- package/coverage/src/lib/logger.js.html +2116 -0
- package/coverage/src/lib/openclaw-integration.js.html +1102 -0
- package/coverage/src/lib/pid-file.js.html +394 -0
- package/coverage/src/lib/port-scanner.js.html +334 -0
- package/coverage/src/lib/prompt-template.js.html +1150 -0
- package/coverage/src/lib/runtime-adapter.js.html +2188 -0
- package/coverage/src/lib/summarizer.js.html +553 -0
- package/coverage/src/lib/summary-formatter.js.html +589 -0
- package/coverage/src/lib/summary-prompt.js.html +694 -0
- package/coverage/src/lib/tokens.js.html +2689 -0
- package/coverage/src/lib/turn-timeout.js.html +241 -0
- package/coverage/src/lib/update-checker.js.html +364 -0
- package/coverage/src/lib/update-manager.js.html +1024 -0
- package/coverage/src/routes/a2a.js.html +3724 -0
- package/coverage/src/routes/callbook.js.html +511 -0
- package/coverage/src/routes/dashboard.js.html +4819 -0
- package/coverage/src/routes/index.html +146 -0
- package/coverage/src/server.js.html +3622 -0
- package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
- package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
- package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
- package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
- package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
- package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
- package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
- package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
- package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
- package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
- package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
- package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
- package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
- package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
- package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
- package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
- package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
- package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
- package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
- package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
- package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
- package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
- package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
- package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
- package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
- package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
- package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
- package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
- package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
- package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
- package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
- package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
- package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
- package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
- package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
- package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
- package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
- package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
- package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
- package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
- package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
- package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
- package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
- package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
- package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
- package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
- package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
- package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
- package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
- package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
- package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
- package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
- package/docs/signing-setup.md +49 -0
- package/native/macos/certs/appldevcert.cer +0 -0
- package/native/macos/src-tauri/binaries/.gitkeep +0 -0
- package/native/macos/src-tauri/capabilities/default.json +11 -1
- package/native/macos/src-tauri/entitlements.plist +14 -0
- package/native/macos/src-tauri/src/discovery.rs +14 -3
- package/native/macos/src-tauri/src/health.rs +4 -0
- package/native/macos/src-tauri/src/lib.rs +52 -11
- package/native/macos/src-tauri/src/server.rs +262 -26
- package/native/macos/src-tauri/tauri.conf.json +13 -4
- package/package.json +7 -2
- package/pkg.config.json +14 -0
- package/scripts/build-standalone.sh +106 -0
- package/scripts/smoke-test-standalone.sh +101 -0
- package/scripts/sync-version.sh +28 -0
- package/scripts/verify-app-bundle.sh +34 -0
- package/.maestro/inbox/release-workflow-spam.md +0 -25
|
@@ -0,0 +1,2134 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/lib/client.js</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/lib</a> client.js</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">93.11% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>636/683</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">78.28% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>137/175</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>24/24</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">93.11% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>636/683</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
+
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
+
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
+
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
+
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
+
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
+
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
+
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
+
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
+
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
+
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
+
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
+
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
+
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
+
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
+
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
+
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
+
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
+
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
+
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
+
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
+
<a name='L222'></a><a href='#L222'>222</a>
|
|
288
|
+
<a name='L223'></a><a href='#L223'>223</a>
|
|
289
|
+
<a name='L224'></a><a href='#L224'>224</a>
|
|
290
|
+
<a name='L225'></a><a href='#L225'>225</a>
|
|
291
|
+
<a name='L226'></a><a href='#L226'>226</a>
|
|
292
|
+
<a name='L227'></a><a href='#L227'>227</a>
|
|
293
|
+
<a name='L228'></a><a href='#L228'>228</a>
|
|
294
|
+
<a name='L229'></a><a href='#L229'>229</a>
|
|
295
|
+
<a name='L230'></a><a href='#L230'>230</a>
|
|
296
|
+
<a name='L231'></a><a href='#L231'>231</a>
|
|
297
|
+
<a name='L232'></a><a href='#L232'>232</a>
|
|
298
|
+
<a name='L233'></a><a href='#L233'>233</a>
|
|
299
|
+
<a name='L234'></a><a href='#L234'>234</a>
|
|
300
|
+
<a name='L235'></a><a href='#L235'>235</a>
|
|
301
|
+
<a name='L236'></a><a href='#L236'>236</a>
|
|
302
|
+
<a name='L237'></a><a href='#L237'>237</a>
|
|
303
|
+
<a name='L238'></a><a href='#L238'>238</a>
|
|
304
|
+
<a name='L239'></a><a href='#L239'>239</a>
|
|
305
|
+
<a name='L240'></a><a href='#L240'>240</a>
|
|
306
|
+
<a name='L241'></a><a href='#L241'>241</a>
|
|
307
|
+
<a name='L242'></a><a href='#L242'>242</a>
|
|
308
|
+
<a name='L243'></a><a href='#L243'>243</a>
|
|
309
|
+
<a name='L244'></a><a href='#L244'>244</a>
|
|
310
|
+
<a name='L245'></a><a href='#L245'>245</a>
|
|
311
|
+
<a name='L246'></a><a href='#L246'>246</a>
|
|
312
|
+
<a name='L247'></a><a href='#L247'>247</a>
|
|
313
|
+
<a name='L248'></a><a href='#L248'>248</a>
|
|
314
|
+
<a name='L249'></a><a href='#L249'>249</a>
|
|
315
|
+
<a name='L250'></a><a href='#L250'>250</a>
|
|
316
|
+
<a name='L251'></a><a href='#L251'>251</a>
|
|
317
|
+
<a name='L252'></a><a href='#L252'>252</a>
|
|
318
|
+
<a name='L253'></a><a href='#L253'>253</a>
|
|
319
|
+
<a name='L254'></a><a href='#L254'>254</a>
|
|
320
|
+
<a name='L255'></a><a href='#L255'>255</a>
|
|
321
|
+
<a name='L256'></a><a href='#L256'>256</a>
|
|
322
|
+
<a name='L257'></a><a href='#L257'>257</a>
|
|
323
|
+
<a name='L258'></a><a href='#L258'>258</a>
|
|
324
|
+
<a name='L259'></a><a href='#L259'>259</a>
|
|
325
|
+
<a name='L260'></a><a href='#L260'>260</a>
|
|
326
|
+
<a name='L261'></a><a href='#L261'>261</a>
|
|
327
|
+
<a name='L262'></a><a href='#L262'>262</a>
|
|
328
|
+
<a name='L263'></a><a href='#L263'>263</a>
|
|
329
|
+
<a name='L264'></a><a href='#L264'>264</a>
|
|
330
|
+
<a name='L265'></a><a href='#L265'>265</a>
|
|
331
|
+
<a name='L266'></a><a href='#L266'>266</a>
|
|
332
|
+
<a name='L267'></a><a href='#L267'>267</a>
|
|
333
|
+
<a name='L268'></a><a href='#L268'>268</a>
|
|
334
|
+
<a name='L269'></a><a href='#L269'>269</a>
|
|
335
|
+
<a name='L270'></a><a href='#L270'>270</a>
|
|
336
|
+
<a name='L271'></a><a href='#L271'>271</a>
|
|
337
|
+
<a name='L272'></a><a href='#L272'>272</a>
|
|
338
|
+
<a name='L273'></a><a href='#L273'>273</a>
|
|
339
|
+
<a name='L274'></a><a href='#L274'>274</a>
|
|
340
|
+
<a name='L275'></a><a href='#L275'>275</a>
|
|
341
|
+
<a name='L276'></a><a href='#L276'>276</a>
|
|
342
|
+
<a name='L277'></a><a href='#L277'>277</a>
|
|
343
|
+
<a name='L278'></a><a href='#L278'>278</a>
|
|
344
|
+
<a name='L279'></a><a href='#L279'>279</a>
|
|
345
|
+
<a name='L280'></a><a href='#L280'>280</a>
|
|
346
|
+
<a name='L281'></a><a href='#L281'>281</a>
|
|
347
|
+
<a name='L282'></a><a href='#L282'>282</a>
|
|
348
|
+
<a name='L283'></a><a href='#L283'>283</a>
|
|
349
|
+
<a name='L284'></a><a href='#L284'>284</a>
|
|
350
|
+
<a name='L285'></a><a href='#L285'>285</a>
|
|
351
|
+
<a name='L286'></a><a href='#L286'>286</a>
|
|
352
|
+
<a name='L287'></a><a href='#L287'>287</a>
|
|
353
|
+
<a name='L288'></a><a href='#L288'>288</a>
|
|
354
|
+
<a name='L289'></a><a href='#L289'>289</a>
|
|
355
|
+
<a name='L290'></a><a href='#L290'>290</a>
|
|
356
|
+
<a name='L291'></a><a href='#L291'>291</a>
|
|
357
|
+
<a name='L292'></a><a href='#L292'>292</a>
|
|
358
|
+
<a name='L293'></a><a href='#L293'>293</a>
|
|
359
|
+
<a name='L294'></a><a href='#L294'>294</a>
|
|
360
|
+
<a name='L295'></a><a href='#L295'>295</a>
|
|
361
|
+
<a name='L296'></a><a href='#L296'>296</a>
|
|
362
|
+
<a name='L297'></a><a href='#L297'>297</a>
|
|
363
|
+
<a name='L298'></a><a href='#L298'>298</a>
|
|
364
|
+
<a name='L299'></a><a href='#L299'>299</a>
|
|
365
|
+
<a name='L300'></a><a href='#L300'>300</a>
|
|
366
|
+
<a name='L301'></a><a href='#L301'>301</a>
|
|
367
|
+
<a name='L302'></a><a href='#L302'>302</a>
|
|
368
|
+
<a name='L303'></a><a href='#L303'>303</a>
|
|
369
|
+
<a name='L304'></a><a href='#L304'>304</a>
|
|
370
|
+
<a name='L305'></a><a href='#L305'>305</a>
|
|
371
|
+
<a name='L306'></a><a href='#L306'>306</a>
|
|
372
|
+
<a name='L307'></a><a href='#L307'>307</a>
|
|
373
|
+
<a name='L308'></a><a href='#L308'>308</a>
|
|
374
|
+
<a name='L309'></a><a href='#L309'>309</a>
|
|
375
|
+
<a name='L310'></a><a href='#L310'>310</a>
|
|
376
|
+
<a name='L311'></a><a href='#L311'>311</a>
|
|
377
|
+
<a name='L312'></a><a href='#L312'>312</a>
|
|
378
|
+
<a name='L313'></a><a href='#L313'>313</a>
|
|
379
|
+
<a name='L314'></a><a href='#L314'>314</a>
|
|
380
|
+
<a name='L315'></a><a href='#L315'>315</a>
|
|
381
|
+
<a name='L316'></a><a href='#L316'>316</a>
|
|
382
|
+
<a name='L317'></a><a href='#L317'>317</a>
|
|
383
|
+
<a name='L318'></a><a href='#L318'>318</a>
|
|
384
|
+
<a name='L319'></a><a href='#L319'>319</a>
|
|
385
|
+
<a name='L320'></a><a href='#L320'>320</a>
|
|
386
|
+
<a name='L321'></a><a href='#L321'>321</a>
|
|
387
|
+
<a name='L322'></a><a href='#L322'>322</a>
|
|
388
|
+
<a name='L323'></a><a href='#L323'>323</a>
|
|
389
|
+
<a name='L324'></a><a href='#L324'>324</a>
|
|
390
|
+
<a name='L325'></a><a href='#L325'>325</a>
|
|
391
|
+
<a name='L326'></a><a href='#L326'>326</a>
|
|
392
|
+
<a name='L327'></a><a href='#L327'>327</a>
|
|
393
|
+
<a name='L328'></a><a href='#L328'>328</a>
|
|
394
|
+
<a name='L329'></a><a href='#L329'>329</a>
|
|
395
|
+
<a name='L330'></a><a href='#L330'>330</a>
|
|
396
|
+
<a name='L331'></a><a href='#L331'>331</a>
|
|
397
|
+
<a name='L332'></a><a href='#L332'>332</a>
|
|
398
|
+
<a name='L333'></a><a href='#L333'>333</a>
|
|
399
|
+
<a name='L334'></a><a href='#L334'>334</a>
|
|
400
|
+
<a name='L335'></a><a href='#L335'>335</a>
|
|
401
|
+
<a name='L336'></a><a href='#L336'>336</a>
|
|
402
|
+
<a name='L337'></a><a href='#L337'>337</a>
|
|
403
|
+
<a name='L338'></a><a href='#L338'>338</a>
|
|
404
|
+
<a name='L339'></a><a href='#L339'>339</a>
|
|
405
|
+
<a name='L340'></a><a href='#L340'>340</a>
|
|
406
|
+
<a name='L341'></a><a href='#L341'>341</a>
|
|
407
|
+
<a name='L342'></a><a href='#L342'>342</a>
|
|
408
|
+
<a name='L343'></a><a href='#L343'>343</a>
|
|
409
|
+
<a name='L344'></a><a href='#L344'>344</a>
|
|
410
|
+
<a name='L345'></a><a href='#L345'>345</a>
|
|
411
|
+
<a name='L346'></a><a href='#L346'>346</a>
|
|
412
|
+
<a name='L347'></a><a href='#L347'>347</a>
|
|
413
|
+
<a name='L348'></a><a href='#L348'>348</a>
|
|
414
|
+
<a name='L349'></a><a href='#L349'>349</a>
|
|
415
|
+
<a name='L350'></a><a href='#L350'>350</a>
|
|
416
|
+
<a name='L351'></a><a href='#L351'>351</a>
|
|
417
|
+
<a name='L352'></a><a href='#L352'>352</a>
|
|
418
|
+
<a name='L353'></a><a href='#L353'>353</a>
|
|
419
|
+
<a name='L354'></a><a href='#L354'>354</a>
|
|
420
|
+
<a name='L355'></a><a href='#L355'>355</a>
|
|
421
|
+
<a name='L356'></a><a href='#L356'>356</a>
|
|
422
|
+
<a name='L357'></a><a href='#L357'>357</a>
|
|
423
|
+
<a name='L358'></a><a href='#L358'>358</a>
|
|
424
|
+
<a name='L359'></a><a href='#L359'>359</a>
|
|
425
|
+
<a name='L360'></a><a href='#L360'>360</a>
|
|
426
|
+
<a name='L361'></a><a href='#L361'>361</a>
|
|
427
|
+
<a name='L362'></a><a href='#L362'>362</a>
|
|
428
|
+
<a name='L363'></a><a href='#L363'>363</a>
|
|
429
|
+
<a name='L364'></a><a href='#L364'>364</a>
|
|
430
|
+
<a name='L365'></a><a href='#L365'>365</a>
|
|
431
|
+
<a name='L366'></a><a href='#L366'>366</a>
|
|
432
|
+
<a name='L367'></a><a href='#L367'>367</a>
|
|
433
|
+
<a name='L368'></a><a href='#L368'>368</a>
|
|
434
|
+
<a name='L369'></a><a href='#L369'>369</a>
|
|
435
|
+
<a name='L370'></a><a href='#L370'>370</a>
|
|
436
|
+
<a name='L371'></a><a href='#L371'>371</a>
|
|
437
|
+
<a name='L372'></a><a href='#L372'>372</a>
|
|
438
|
+
<a name='L373'></a><a href='#L373'>373</a>
|
|
439
|
+
<a name='L374'></a><a href='#L374'>374</a>
|
|
440
|
+
<a name='L375'></a><a href='#L375'>375</a>
|
|
441
|
+
<a name='L376'></a><a href='#L376'>376</a>
|
|
442
|
+
<a name='L377'></a><a href='#L377'>377</a>
|
|
443
|
+
<a name='L378'></a><a href='#L378'>378</a>
|
|
444
|
+
<a name='L379'></a><a href='#L379'>379</a>
|
|
445
|
+
<a name='L380'></a><a href='#L380'>380</a>
|
|
446
|
+
<a name='L381'></a><a href='#L381'>381</a>
|
|
447
|
+
<a name='L382'></a><a href='#L382'>382</a>
|
|
448
|
+
<a name='L383'></a><a href='#L383'>383</a>
|
|
449
|
+
<a name='L384'></a><a href='#L384'>384</a>
|
|
450
|
+
<a name='L385'></a><a href='#L385'>385</a>
|
|
451
|
+
<a name='L386'></a><a href='#L386'>386</a>
|
|
452
|
+
<a name='L387'></a><a href='#L387'>387</a>
|
|
453
|
+
<a name='L388'></a><a href='#L388'>388</a>
|
|
454
|
+
<a name='L389'></a><a href='#L389'>389</a>
|
|
455
|
+
<a name='L390'></a><a href='#L390'>390</a>
|
|
456
|
+
<a name='L391'></a><a href='#L391'>391</a>
|
|
457
|
+
<a name='L392'></a><a href='#L392'>392</a>
|
|
458
|
+
<a name='L393'></a><a href='#L393'>393</a>
|
|
459
|
+
<a name='L394'></a><a href='#L394'>394</a>
|
|
460
|
+
<a name='L395'></a><a href='#L395'>395</a>
|
|
461
|
+
<a name='L396'></a><a href='#L396'>396</a>
|
|
462
|
+
<a name='L397'></a><a href='#L397'>397</a>
|
|
463
|
+
<a name='L398'></a><a href='#L398'>398</a>
|
|
464
|
+
<a name='L399'></a><a href='#L399'>399</a>
|
|
465
|
+
<a name='L400'></a><a href='#L400'>400</a>
|
|
466
|
+
<a name='L401'></a><a href='#L401'>401</a>
|
|
467
|
+
<a name='L402'></a><a href='#L402'>402</a>
|
|
468
|
+
<a name='L403'></a><a href='#L403'>403</a>
|
|
469
|
+
<a name='L404'></a><a href='#L404'>404</a>
|
|
470
|
+
<a name='L405'></a><a href='#L405'>405</a>
|
|
471
|
+
<a name='L406'></a><a href='#L406'>406</a>
|
|
472
|
+
<a name='L407'></a><a href='#L407'>407</a>
|
|
473
|
+
<a name='L408'></a><a href='#L408'>408</a>
|
|
474
|
+
<a name='L409'></a><a href='#L409'>409</a>
|
|
475
|
+
<a name='L410'></a><a href='#L410'>410</a>
|
|
476
|
+
<a name='L411'></a><a href='#L411'>411</a>
|
|
477
|
+
<a name='L412'></a><a href='#L412'>412</a>
|
|
478
|
+
<a name='L413'></a><a href='#L413'>413</a>
|
|
479
|
+
<a name='L414'></a><a href='#L414'>414</a>
|
|
480
|
+
<a name='L415'></a><a href='#L415'>415</a>
|
|
481
|
+
<a name='L416'></a><a href='#L416'>416</a>
|
|
482
|
+
<a name='L417'></a><a href='#L417'>417</a>
|
|
483
|
+
<a name='L418'></a><a href='#L418'>418</a>
|
|
484
|
+
<a name='L419'></a><a href='#L419'>419</a>
|
|
485
|
+
<a name='L420'></a><a href='#L420'>420</a>
|
|
486
|
+
<a name='L421'></a><a href='#L421'>421</a>
|
|
487
|
+
<a name='L422'></a><a href='#L422'>422</a>
|
|
488
|
+
<a name='L423'></a><a href='#L423'>423</a>
|
|
489
|
+
<a name='L424'></a><a href='#L424'>424</a>
|
|
490
|
+
<a name='L425'></a><a href='#L425'>425</a>
|
|
491
|
+
<a name='L426'></a><a href='#L426'>426</a>
|
|
492
|
+
<a name='L427'></a><a href='#L427'>427</a>
|
|
493
|
+
<a name='L428'></a><a href='#L428'>428</a>
|
|
494
|
+
<a name='L429'></a><a href='#L429'>429</a>
|
|
495
|
+
<a name='L430'></a><a href='#L430'>430</a>
|
|
496
|
+
<a name='L431'></a><a href='#L431'>431</a>
|
|
497
|
+
<a name='L432'></a><a href='#L432'>432</a>
|
|
498
|
+
<a name='L433'></a><a href='#L433'>433</a>
|
|
499
|
+
<a name='L434'></a><a href='#L434'>434</a>
|
|
500
|
+
<a name='L435'></a><a href='#L435'>435</a>
|
|
501
|
+
<a name='L436'></a><a href='#L436'>436</a>
|
|
502
|
+
<a name='L437'></a><a href='#L437'>437</a>
|
|
503
|
+
<a name='L438'></a><a href='#L438'>438</a>
|
|
504
|
+
<a name='L439'></a><a href='#L439'>439</a>
|
|
505
|
+
<a name='L440'></a><a href='#L440'>440</a>
|
|
506
|
+
<a name='L441'></a><a href='#L441'>441</a>
|
|
507
|
+
<a name='L442'></a><a href='#L442'>442</a>
|
|
508
|
+
<a name='L443'></a><a href='#L443'>443</a>
|
|
509
|
+
<a name='L444'></a><a href='#L444'>444</a>
|
|
510
|
+
<a name='L445'></a><a href='#L445'>445</a>
|
|
511
|
+
<a name='L446'></a><a href='#L446'>446</a>
|
|
512
|
+
<a name='L447'></a><a href='#L447'>447</a>
|
|
513
|
+
<a name='L448'></a><a href='#L448'>448</a>
|
|
514
|
+
<a name='L449'></a><a href='#L449'>449</a>
|
|
515
|
+
<a name='L450'></a><a href='#L450'>450</a>
|
|
516
|
+
<a name='L451'></a><a href='#L451'>451</a>
|
|
517
|
+
<a name='L452'></a><a href='#L452'>452</a>
|
|
518
|
+
<a name='L453'></a><a href='#L453'>453</a>
|
|
519
|
+
<a name='L454'></a><a href='#L454'>454</a>
|
|
520
|
+
<a name='L455'></a><a href='#L455'>455</a>
|
|
521
|
+
<a name='L456'></a><a href='#L456'>456</a>
|
|
522
|
+
<a name='L457'></a><a href='#L457'>457</a>
|
|
523
|
+
<a name='L458'></a><a href='#L458'>458</a>
|
|
524
|
+
<a name='L459'></a><a href='#L459'>459</a>
|
|
525
|
+
<a name='L460'></a><a href='#L460'>460</a>
|
|
526
|
+
<a name='L461'></a><a href='#L461'>461</a>
|
|
527
|
+
<a name='L462'></a><a href='#L462'>462</a>
|
|
528
|
+
<a name='L463'></a><a href='#L463'>463</a>
|
|
529
|
+
<a name='L464'></a><a href='#L464'>464</a>
|
|
530
|
+
<a name='L465'></a><a href='#L465'>465</a>
|
|
531
|
+
<a name='L466'></a><a href='#L466'>466</a>
|
|
532
|
+
<a name='L467'></a><a href='#L467'>467</a>
|
|
533
|
+
<a name='L468'></a><a href='#L468'>468</a>
|
|
534
|
+
<a name='L469'></a><a href='#L469'>469</a>
|
|
535
|
+
<a name='L470'></a><a href='#L470'>470</a>
|
|
536
|
+
<a name='L471'></a><a href='#L471'>471</a>
|
|
537
|
+
<a name='L472'></a><a href='#L472'>472</a>
|
|
538
|
+
<a name='L473'></a><a href='#L473'>473</a>
|
|
539
|
+
<a name='L474'></a><a href='#L474'>474</a>
|
|
540
|
+
<a name='L475'></a><a href='#L475'>475</a>
|
|
541
|
+
<a name='L476'></a><a href='#L476'>476</a>
|
|
542
|
+
<a name='L477'></a><a href='#L477'>477</a>
|
|
543
|
+
<a name='L478'></a><a href='#L478'>478</a>
|
|
544
|
+
<a name='L479'></a><a href='#L479'>479</a>
|
|
545
|
+
<a name='L480'></a><a href='#L480'>480</a>
|
|
546
|
+
<a name='L481'></a><a href='#L481'>481</a>
|
|
547
|
+
<a name='L482'></a><a href='#L482'>482</a>
|
|
548
|
+
<a name='L483'></a><a href='#L483'>483</a>
|
|
549
|
+
<a name='L484'></a><a href='#L484'>484</a>
|
|
550
|
+
<a name='L485'></a><a href='#L485'>485</a>
|
|
551
|
+
<a name='L486'></a><a href='#L486'>486</a>
|
|
552
|
+
<a name='L487'></a><a href='#L487'>487</a>
|
|
553
|
+
<a name='L488'></a><a href='#L488'>488</a>
|
|
554
|
+
<a name='L489'></a><a href='#L489'>489</a>
|
|
555
|
+
<a name='L490'></a><a href='#L490'>490</a>
|
|
556
|
+
<a name='L491'></a><a href='#L491'>491</a>
|
|
557
|
+
<a name='L492'></a><a href='#L492'>492</a>
|
|
558
|
+
<a name='L493'></a><a href='#L493'>493</a>
|
|
559
|
+
<a name='L494'></a><a href='#L494'>494</a>
|
|
560
|
+
<a name='L495'></a><a href='#L495'>495</a>
|
|
561
|
+
<a name='L496'></a><a href='#L496'>496</a>
|
|
562
|
+
<a name='L497'></a><a href='#L497'>497</a>
|
|
563
|
+
<a name='L498'></a><a href='#L498'>498</a>
|
|
564
|
+
<a name='L499'></a><a href='#L499'>499</a>
|
|
565
|
+
<a name='L500'></a><a href='#L500'>500</a>
|
|
566
|
+
<a name='L501'></a><a href='#L501'>501</a>
|
|
567
|
+
<a name='L502'></a><a href='#L502'>502</a>
|
|
568
|
+
<a name='L503'></a><a href='#L503'>503</a>
|
|
569
|
+
<a name='L504'></a><a href='#L504'>504</a>
|
|
570
|
+
<a name='L505'></a><a href='#L505'>505</a>
|
|
571
|
+
<a name='L506'></a><a href='#L506'>506</a>
|
|
572
|
+
<a name='L507'></a><a href='#L507'>507</a>
|
|
573
|
+
<a name='L508'></a><a href='#L508'>508</a>
|
|
574
|
+
<a name='L509'></a><a href='#L509'>509</a>
|
|
575
|
+
<a name='L510'></a><a href='#L510'>510</a>
|
|
576
|
+
<a name='L511'></a><a href='#L511'>511</a>
|
|
577
|
+
<a name='L512'></a><a href='#L512'>512</a>
|
|
578
|
+
<a name='L513'></a><a href='#L513'>513</a>
|
|
579
|
+
<a name='L514'></a><a href='#L514'>514</a>
|
|
580
|
+
<a name='L515'></a><a href='#L515'>515</a>
|
|
581
|
+
<a name='L516'></a><a href='#L516'>516</a>
|
|
582
|
+
<a name='L517'></a><a href='#L517'>517</a>
|
|
583
|
+
<a name='L518'></a><a href='#L518'>518</a>
|
|
584
|
+
<a name='L519'></a><a href='#L519'>519</a>
|
|
585
|
+
<a name='L520'></a><a href='#L520'>520</a>
|
|
586
|
+
<a name='L521'></a><a href='#L521'>521</a>
|
|
587
|
+
<a name='L522'></a><a href='#L522'>522</a>
|
|
588
|
+
<a name='L523'></a><a href='#L523'>523</a>
|
|
589
|
+
<a name='L524'></a><a href='#L524'>524</a>
|
|
590
|
+
<a name='L525'></a><a href='#L525'>525</a>
|
|
591
|
+
<a name='L526'></a><a href='#L526'>526</a>
|
|
592
|
+
<a name='L527'></a><a href='#L527'>527</a>
|
|
593
|
+
<a name='L528'></a><a href='#L528'>528</a>
|
|
594
|
+
<a name='L529'></a><a href='#L529'>529</a>
|
|
595
|
+
<a name='L530'></a><a href='#L530'>530</a>
|
|
596
|
+
<a name='L531'></a><a href='#L531'>531</a>
|
|
597
|
+
<a name='L532'></a><a href='#L532'>532</a>
|
|
598
|
+
<a name='L533'></a><a href='#L533'>533</a>
|
|
599
|
+
<a name='L534'></a><a href='#L534'>534</a>
|
|
600
|
+
<a name='L535'></a><a href='#L535'>535</a>
|
|
601
|
+
<a name='L536'></a><a href='#L536'>536</a>
|
|
602
|
+
<a name='L537'></a><a href='#L537'>537</a>
|
|
603
|
+
<a name='L538'></a><a href='#L538'>538</a>
|
|
604
|
+
<a name='L539'></a><a href='#L539'>539</a>
|
|
605
|
+
<a name='L540'></a><a href='#L540'>540</a>
|
|
606
|
+
<a name='L541'></a><a href='#L541'>541</a>
|
|
607
|
+
<a name='L542'></a><a href='#L542'>542</a>
|
|
608
|
+
<a name='L543'></a><a href='#L543'>543</a>
|
|
609
|
+
<a name='L544'></a><a href='#L544'>544</a>
|
|
610
|
+
<a name='L545'></a><a href='#L545'>545</a>
|
|
611
|
+
<a name='L546'></a><a href='#L546'>546</a>
|
|
612
|
+
<a name='L547'></a><a href='#L547'>547</a>
|
|
613
|
+
<a name='L548'></a><a href='#L548'>548</a>
|
|
614
|
+
<a name='L549'></a><a href='#L549'>549</a>
|
|
615
|
+
<a name='L550'></a><a href='#L550'>550</a>
|
|
616
|
+
<a name='L551'></a><a href='#L551'>551</a>
|
|
617
|
+
<a name='L552'></a><a href='#L552'>552</a>
|
|
618
|
+
<a name='L553'></a><a href='#L553'>553</a>
|
|
619
|
+
<a name='L554'></a><a href='#L554'>554</a>
|
|
620
|
+
<a name='L555'></a><a href='#L555'>555</a>
|
|
621
|
+
<a name='L556'></a><a href='#L556'>556</a>
|
|
622
|
+
<a name='L557'></a><a href='#L557'>557</a>
|
|
623
|
+
<a name='L558'></a><a href='#L558'>558</a>
|
|
624
|
+
<a name='L559'></a><a href='#L559'>559</a>
|
|
625
|
+
<a name='L560'></a><a href='#L560'>560</a>
|
|
626
|
+
<a name='L561'></a><a href='#L561'>561</a>
|
|
627
|
+
<a name='L562'></a><a href='#L562'>562</a>
|
|
628
|
+
<a name='L563'></a><a href='#L563'>563</a>
|
|
629
|
+
<a name='L564'></a><a href='#L564'>564</a>
|
|
630
|
+
<a name='L565'></a><a href='#L565'>565</a>
|
|
631
|
+
<a name='L566'></a><a href='#L566'>566</a>
|
|
632
|
+
<a name='L567'></a><a href='#L567'>567</a>
|
|
633
|
+
<a name='L568'></a><a href='#L568'>568</a>
|
|
634
|
+
<a name='L569'></a><a href='#L569'>569</a>
|
|
635
|
+
<a name='L570'></a><a href='#L570'>570</a>
|
|
636
|
+
<a name='L571'></a><a href='#L571'>571</a>
|
|
637
|
+
<a name='L572'></a><a href='#L572'>572</a>
|
|
638
|
+
<a name='L573'></a><a href='#L573'>573</a>
|
|
639
|
+
<a name='L574'></a><a href='#L574'>574</a>
|
|
640
|
+
<a name='L575'></a><a href='#L575'>575</a>
|
|
641
|
+
<a name='L576'></a><a href='#L576'>576</a>
|
|
642
|
+
<a name='L577'></a><a href='#L577'>577</a>
|
|
643
|
+
<a name='L578'></a><a href='#L578'>578</a>
|
|
644
|
+
<a name='L579'></a><a href='#L579'>579</a>
|
|
645
|
+
<a name='L580'></a><a href='#L580'>580</a>
|
|
646
|
+
<a name='L581'></a><a href='#L581'>581</a>
|
|
647
|
+
<a name='L582'></a><a href='#L582'>582</a>
|
|
648
|
+
<a name='L583'></a><a href='#L583'>583</a>
|
|
649
|
+
<a name='L584'></a><a href='#L584'>584</a>
|
|
650
|
+
<a name='L585'></a><a href='#L585'>585</a>
|
|
651
|
+
<a name='L586'></a><a href='#L586'>586</a>
|
|
652
|
+
<a name='L587'></a><a href='#L587'>587</a>
|
|
653
|
+
<a name='L588'></a><a href='#L588'>588</a>
|
|
654
|
+
<a name='L589'></a><a href='#L589'>589</a>
|
|
655
|
+
<a name='L590'></a><a href='#L590'>590</a>
|
|
656
|
+
<a name='L591'></a><a href='#L591'>591</a>
|
|
657
|
+
<a name='L592'></a><a href='#L592'>592</a>
|
|
658
|
+
<a name='L593'></a><a href='#L593'>593</a>
|
|
659
|
+
<a name='L594'></a><a href='#L594'>594</a>
|
|
660
|
+
<a name='L595'></a><a href='#L595'>595</a>
|
|
661
|
+
<a name='L596'></a><a href='#L596'>596</a>
|
|
662
|
+
<a name='L597'></a><a href='#L597'>597</a>
|
|
663
|
+
<a name='L598'></a><a href='#L598'>598</a>
|
|
664
|
+
<a name='L599'></a><a href='#L599'>599</a>
|
|
665
|
+
<a name='L600'></a><a href='#L600'>600</a>
|
|
666
|
+
<a name='L601'></a><a href='#L601'>601</a>
|
|
667
|
+
<a name='L602'></a><a href='#L602'>602</a>
|
|
668
|
+
<a name='L603'></a><a href='#L603'>603</a>
|
|
669
|
+
<a name='L604'></a><a href='#L604'>604</a>
|
|
670
|
+
<a name='L605'></a><a href='#L605'>605</a>
|
|
671
|
+
<a name='L606'></a><a href='#L606'>606</a>
|
|
672
|
+
<a name='L607'></a><a href='#L607'>607</a>
|
|
673
|
+
<a name='L608'></a><a href='#L608'>608</a>
|
|
674
|
+
<a name='L609'></a><a href='#L609'>609</a>
|
|
675
|
+
<a name='L610'></a><a href='#L610'>610</a>
|
|
676
|
+
<a name='L611'></a><a href='#L611'>611</a>
|
|
677
|
+
<a name='L612'></a><a href='#L612'>612</a>
|
|
678
|
+
<a name='L613'></a><a href='#L613'>613</a>
|
|
679
|
+
<a name='L614'></a><a href='#L614'>614</a>
|
|
680
|
+
<a name='L615'></a><a href='#L615'>615</a>
|
|
681
|
+
<a name='L616'></a><a href='#L616'>616</a>
|
|
682
|
+
<a name='L617'></a><a href='#L617'>617</a>
|
|
683
|
+
<a name='L618'></a><a href='#L618'>618</a>
|
|
684
|
+
<a name='L619'></a><a href='#L619'>619</a>
|
|
685
|
+
<a name='L620'></a><a href='#L620'>620</a>
|
|
686
|
+
<a name='L621'></a><a href='#L621'>621</a>
|
|
687
|
+
<a name='L622'></a><a href='#L622'>622</a>
|
|
688
|
+
<a name='L623'></a><a href='#L623'>623</a>
|
|
689
|
+
<a name='L624'></a><a href='#L624'>624</a>
|
|
690
|
+
<a name='L625'></a><a href='#L625'>625</a>
|
|
691
|
+
<a name='L626'></a><a href='#L626'>626</a>
|
|
692
|
+
<a name='L627'></a><a href='#L627'>627</a>
|
|
693
|
+
<a name='L628'></a><a href='#L628'>628</a>
|
|
694
|
+
<a name='L629'></a><a href='#L629'>629</a>
|
|
695
|
+
<a name='L630'></a><a href='#L630'>630</a>
|
|
696
|
+
<a name='L631'></a><a href='#L631'>631</a>
|
|
697
|
+
<a name='L632'></a><a href='#L632'>632</a>
|
|
698
|
+
<a name='L633'></a><a href='#L633'>633</a>
|
|
699
|
+
<a name='L634'></a><a href='#L634'>634</a>
|
|
700
|
+
<a name='L635'></a><a href='#L635'>635</a>
|
|
701
|
+
<a name='L636'></a><a href='#L636'>636</a>
|
|
702
|
+
<a name='L637'></a><a href='#L637'>637</a>
|
|
703
|
+
<a name='L638'></a><a href='#L638'>638</a>
|
|
704
|
+
<a name='L639'></a><a href='#L639'>639</a>
|
|
705
|
+
<a name='L640'></a><a href='#L640'>640</a>
|
|
706
|
+
<a name='L641'></a><a href='#L641'>641</a>
|
|
707
|
+
<a name='L642'></a><a href='#L642'>642</a>
|
|
708
|
+
<a name='L643'></a><a href='#L643'>643</a>
|
|
709
|
+
<a name='L644'></a><a href='#L644'>644</a>
|
|
710
|
+
<a name='L645'></a><a href='#L645'>645</a>
|
|
711
|
+
<a name='L646'></a><a href='#L646'>646</a>
|
|
712
|
+
<a name='L647'></a><a href='#L647'>647</a>
|
|
713
|
+
<a name='L648'></a><a href='#L648'>648</a>
|
|
714
|
+
<a name='L649'></a><a href='#L649'>649</a>
|
|
715
|
+
<a name='L650'></a><a href='#L650'>650</a>
|
|
716
|
+
<a name='L651'></a><a href='#L651'>651</a>
|
|
717
|
+
<a name='L652'></a><a href='#L652'>652</a>
|
|
718
|
+
<a name='L653'></a><a href='#L653'>653</a>
|
|
719
|
+
<a name='L654'></a><a href='#L654'>654</a>
|
|
720
|
+
<a name='L655'></a><a href='#L655'>655</a>
|
|
721
|
+
<a name='L656'></a><a href='#L656'>656</a>
|
|
722
|
+
<a name='L657'></a><a href='#L657'>657</a>
|
|
723
|
+
<a name='L658'></a><a href='#L658'>658</a>
|
|
724
|
+
<a name='L659'></a><a href='#L659'>659</a>
|
|
725
|
+
<a name='L660'></a><a href='#L660'>660</a>
|
|
726
|
+
<a name='L661'></a><a href='#L661'>661</a>
|
|
727
|
+
<a name='L662'></a><a href='#L662'>662</a>
|
|
728
|
+
<a name='L663'></a><a href='#L663'>663</a>
|
|
729
|
+
<a name='L664'></a><a href='#L664'>664</a>
|
|
730
|
+
<a name='L665'></a><a href='#L665'>665</a>
|
|
731
|
+
<a name='L666'></a><a href='#L666'>666</a>
|
|
732
|
+
<a name='L667'></a><a href='#L667'>667</a>
|
|
733
|
+
<a name='L668'></a><a href='#L668'>668</a>
|
|
734
|
+
<a name='L669'></a><a href='#L669'>669</a>
|
|
735
|
+
<a name='L670'></a><a href='#L670'>670</a>
|
|
736
|
+
<a name='L671'></a><a href='#L671'>671</a>
|
|
737
|
+
<a name='L672'></a><a href='#L672'>672</a>
|
|
738
|
+
<a name='L673'></a><a href='#L673'>673</a>
|
|
739
|
+
<a name='L674'></a><a href='#L674'>674</a>
|
|
740
|
+
<a name='L675'></a><a href='#L675'>675</a>
|
|
741
|
+
<a name='L676'></a><a href='#L676'>676</a>
|
|
742
|
+
<a name='L677'></a><a href='#L677'>677</a>
|
|
743
|
+
<a name='L678'></a><a href='#L678'>678</a>
|
|
744
|
+
<a name='L679'></a><a href='#L679'>679</a>
|
|
745
|
+
<a name='L680'></a><a href='#L680'>680</a>
|
|
746
|
+
<a name='L681'></a><a href='#L681'>681</a>
|
|
747
|
+
<a name='L682'></a><a href='#L682'>682</a>
|
|
748
|
+
<a name='L683'></a><a href='#L683'>683</a>
|
|
749
|
+
<a name='L684'></a><a href='#L684'>684</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">117x</span>
|
|
750
|
+
<span class="cline-any cline-yes">117x</span>
|
|
751
|
+
<span class="cline-any cline-yes">117x</span>
|
|
752
|
+
<span class="cline-any cline-yes">117x</span>
|
|
753
|
+
<span class="cline-any cline-yes">117x</span>
|
|
754
|
+
<span class="cline-any cline-yes">117x</span>
|
|
755
|
+
<span class="cline-any cline-yes">117x</span>
|
|
756
|
+
<span class="cline-any cline-yes">117x</span>
|
|
757
|
+
<span class="cline-any cline-yes">117x</span>
|
|
758
|
+
<span class="cline-any cline-yes">117x</span>
|
|
759
|
+
<span class="cline-any cline-yes">117x</span>
|
|
760
|
+
<span class="cline-any cline-yes">117x</span>
|
|
761
|
+
<span class="cline-any cline-yes">117x</span>
|
|
762
|
+
<span class="cline-any cline-yes">117x</span>
|
|
763
|
+
<span class="cline-any cline-yes">117x</span>
|
|
764
|
+
<span class="cline-any cline-yes">117x</span>
|
|
765
|
+
<span class="cline-any cline-yes">117x</span>
|
|
766
|
+
<span class="cline-any cline-yes">117x</span>
|
|
767
|
+
<span class="cline-any cline-yes">117x</span>
|
|
768
|
+
<span class="cline-any cline-yes">117x</span>
|
|
769
|
+
<span class="cline-any cline-yes">117x</span>
|
|
770
|
+
<span class="cline-any cline-yes">117x</span>
|
|
771
|
+
<span class="cline-any cline-yes">117x</span>
|
|
772
|
+
<span class="cline-any cline-yes">117x</span>
|
|
773
|
+
<span class="cline-any cline-yes">117x</span>
|
|
774
|
+
<span class="cline-any cline-yes">117x</span>
|
|
775
|
+
<span class="cline-any cline-yes">234x</span>
|
|
776
|
+
<span class="cline-any cline-yes">234x</span>
|
|
777
|
+
<span class="cline-any cline-yes">234x</span>
|
|
778
|
+
<span class="cline-any cline-no"> </span>
|
|
779
|
+
<span class="cline-any cline-yes">234x</span>
|
|
780
|
+
<span class="cline-any cline-yes">234x</span>
|
|
781
|
+
<span class="cline-any cline-yes">117x</span>
|
|
782
|
+
<span class="cline-any cline-yes">117x</span>
|
|
783
|
+
<span class="cline-any cline-yes">117x</span>
|
|
784
|
+
<span class="cline-any cline-yes">117x</span>
|
|
785
|
+
<span class="cline-any cline-yes">117x</span>
|
|
786
|
+
<span class="cline-any cline-yes">117x</span>
|
|
787
|
+
<span class="cline-any cline-yes">36x</span>
|
|
788
|
+
<span class="cline-any cline-yes">36x</span>
|
|
789
|
+
<span class="cline-any cline-yes">36x</span>
|
|
790
|
+
<span class="cline-any cline-yes">27x</span>
|
|
791
|
+
<span class="cline-any cline-no"> </span>
|
|
792
|
+
<span class="cline-any cline-no"> </span>
|
|
793
|
+
<span class="cline-any cline-yes">27x</span>
|
|
794
|
+
<span class="cline-any cline-yes">36x</span>
|
|
795
|
+
<span class="cline-any cline-yes">36x</span>
|
|
796
|
+
<span class="cline-any cline-yes">36x</span>
|
|
797
|
+
<span class="cline-any cline-yes">36x</span>
|
|
798
|
+
<span class="cline-any cline-no"> </span>
|
|
799
|
+
<span class="cline-any cline-no"> </span>
|
|
800
|
+
<span class="cline-any cline-no"> </span>
|
|
801
|
+
<span class="cline-any cline-no"> </span>
|
|
802
|
+
<span class="cline-any cline-no"> </span>
|
|
803
|
+
<span class="cline-any cline-no"> </span>
|
|
804
|
+
<span class="cline-any cline-no"> </span>
|
|
805
|
+
<span class="cline-any cline-yes">36x</span>
|
|
806
|
+
<span class="cline-any cline-yes">117x</span>
|
|
807
|
+
<span class="cline-any cline-yes">117x</span>
|
|
808
|
+
<span class="cline-any cline-yes">36x</span>
|
|
809
|
+
<span class="cline-any cline-yes">36x</span>
|
|
810
|
+
<span class="cline-any cline-yes">36x</span>
|
|
811
|
+
<span class="cline-any cline-yes">36x</span>
|
|
812
|
+
<span class="cline-any cline-yes">36x</span>
|
|
813
|
+
<span class="cline-any cline-yes">36x</span>
|
|
814
|
+
<span class="cline-any cline-yes">117x</span>
|
|
815
|
+
<span class="cline-any cline-yes">117x</span>
|
|
816
|
+
<span class="cline-any cline-yes">16x</span>
|
|
817
|
+
<span class="cline-any cline-yes">16x</span>
|
|
818
|
+
<span class="cline-any cline-yes">16x</span>
|
|
819
|
+
<span class="cline-any cline-yes">11x</span>
|
|
820
|
+
<span class="cline-any cline-yes">11x</span>
|
|
821
|
+
<span class="cline-any cline-yes">11x</span>
|
|
822
|
+
<span class="cline-any cline-yes">11x</span>
|
|
823
|
+
<span class="cline-any cline-yes">16x</span>
|
|
824
|
+
<span class="cline-any cline-yes">9x</span>
|
|
825
|
+
<span class="cline-any cline-yes">9x</span>
|
|
826
|
+
<span class="cline-any cline-yes">16x</span>
|
|
827
|
+
<span class="cline-any cline-yes">117x</span>
|
|
828
|
+
<span class="cline-any cline-yes">117x</span>
|
|
829
|
+
<span class="cline-any cline-yes">117x</span>
|
|
830
|
+
<span class="cline-any cline-yes">36x</span>
|
|
831
|
+
<span class="cline-any cline-yes">36x</span>
|
|
832
|
+
<span class="cline-any cline-yes">36x</span>
|
|
833
|
+
<span class="cline-any cline-yes">36x</span>
|
|
834
|
+
<span class="cline-any cline-yes">36x</span>
|
|
835
|
+
<span class="cline-any cline-yes">36x</span>
|
|
836
|
+
<span class="cline-any cline-yes">17x</span>
|
|
837
|
+
<span class="cline-any cline-yes">17x</span>
|
|
838
|
+
<span class="cline-any cline-yes">19x</span>
|
|
839
|
+
<span class="cline-any cline-yes">19x</span>
|
|
840
|
+
<span class="cline-any cline-yes">19x</span>
|
|
841
|
+
<span class="cline-any cline-yes">19x</span>
|
|
842
|
+
<span class="cline-any cline-yes">19x</span>
|
|
843
|
+
<span class="cline-any cline-yes">19x</span>
|
|
844
|
+
<span class="cline-any cline-yes">19x</span>
|
|
845
|
+
<span class="cline-any cline-yes">19x</span>
|
|
846
|
+
<span class="cline-any cline-yes">19x</span>
|
|
847
|
+
<span class="cline-any cline-yes">19x</span>
|
|
848
|
+
<span class="cline-any cline-yes">19x</span>
|
|
849
|
+
<span class="cline-any cline-yes">18x</span>
|
|
850
|
+
<span class="cline-any cline-yes">18x</span>
|
|
851
|
+
<span class="cline-any cline-yes">18x</span>
|
|
852
|
+
<span class="cline-any cline-yes">16x</span>
|
|
853
|
+
<span class="cline-any cline-yes">16x</span>
|
|
854
|
+
<span class="cline-any cline-no"> </span>
|
|
855
|
+
<span class="cline-any cline-no"> </span>
|
|
856
|
+
<span class="cline-any cline-no"> </span>
|
|
857
|
+
<span class="cline-any cline-no"> </span>
|
|
858
|
+
<span class="cline-any cline-no"> </span>
|
|
859
|
+
<span class="cline-any cline-yes">16x</span>
|
|
860
|
+
<span class="cline-any cline-yes">18x</span>
|
|
861
|
+
<span class="cline-any cline-yes">18x</span>
|
|
862
|
+
<span class="cline-any cline-yes">18x</span>
|
|
863
|
+
<span class="cline-any cline-yes">9x</span>
|
|
864
|
+
<span class="cline-any cline-yes">9x</span>
|
|
865
|
+
<span class="cline-any cline-yes">9x</span>
|
|
866
|
+
<span class="cline-any cline-yes">9x</span>
|
|
867
|
+
<span class="cline-any cline-yes">9x</span>
|
|
868
|
+
<span class="cline-any cline-yes">9x</span>
|
|
869
|
+
<span class="cline-any cline-yes">9x</span>
|
|
870
|
+
<span class="cline-any cline-yes">9x</span>
|
|
871
|
+
<span class="cline-any cline-yes">9x</span>
|
|
872
|
+
<span class="cline-any cline-yes">18x</span>
|
|
873
|
+
<span class="cline-any cline-yes">1x</span>
|
|
874
|
+
<span class="cline-any cline-yes">1x</span>
|
|
875
|
+
<span class="cline-any cline-yes">1x</span>
|
|
876
|
+
<span class="cline-any cline-yes">18x</span>
|
|
877
|
+
<span class="cline-any cline-yes">19x</span>
|
|
878
|
+
<span class="cline-any cline-yes">19x</span>
|
|
879
|
+
<span class="cline-any cline-yes">19x</span>
|
|
880
|
+
<span class="cline-any cline-yes">1x</span>
|
|
881
|
+
<span class="cline-any cline-yes">1x</span>
|
|
882
|
+
<span class="cline-any cline-yes">19x</span>
|
|
883
|
+
<span class="cline-any cline-yes">19x</span>
|
|
884
|
+
<span class="cline-any cline-no"> </span>
|
|
885
|
+
<span class="cline-any cline-no"> </span>
|
|
886
|
+
<span class="cline-any cline-no"> </span>
|
|
887
|
+
<span class="cline-any cline-yes">19x</span>
|
|
888
|
+
<span class="cline-any cline-yes">19x</span>
|
|
889
|
+
<span class="cline-any cline-yes">19x</span>
|
|
890
|
+
<span class="cline-any cline-yes">36x</span>
|
|
891
|
+
<span class="cline-any cline-yes">117x</span>
|
|
892
|
+
<span class="cline-any cline-yes">117x</span>
|
|
893
|
+
<span class="cline-any cline-yes">12x</span>
|
|
894
|
+
<span class="cline-any cline-yes">12x</span>
|
|
895
|
+
<span class="cline-any cline-yes">12x</span>
|
|
896
|
+
<span class="cline-any cline-yes">12x</span>
|
|
897
|
+
<span class="cline-any cline-yes">12x</span>
|
|
898
|
+
<span class="cline-any cline-yes">12x</span>
|
|
899
|
+
<span class="cline-any cline-yes">12x</span>
|
|
900
|
+
<span class="cline-any cline-yes">12x</span>
|
|
901
|
+
<span class="cline-any cline-yes">12x</span>
|
|
902
|
+
<span class="cline-any cline-yes">12x</span>
|
|
903
|
+
<span class="cline-any cline-yes">12x</span>
|
|
904
|
+
<span class="cline-any cline-yes">12x</span>
|
|
905
|
+
<span class="cline-any cline-yes">12x</span>
|
|
906
|
+
<span class="cline-any cline-yes">12x</span>
|
|
907
|
+
<span class="cline-any cline-yes">12x</span>
|
|
908
|
+
<span class="cline-any cline-yes">12x</span>
|
|
909
|
+
<span class="cline-any cline-yes">12x</span>
|
|
910
|
+
<span class="cline-any cline-yes">12x</span>
|
|
911
|
+
<span class="cline-any cline-yes">117x</span>
|
|
912
|
+
<span class="cline-any cline-yes">117x</span>
|
|
913
|
+
<span class="cline-any cline-yes">14x</span>
|
|
914
|
+
<span class="cline-any cline-yes">14x</span>
|
|
915
|
+
<span class="cline-any cline-yes">14x</span>
|
|
916
|
+
<span class="cline-any cline-yes">2x</span>
|
|
917
|
+
<span class="cline-any cline-yes">2x</span>
|
|
918
|
+
<span class="cline-any cline-yes">12x</span>
|
|
919
|
+
<span class="cline-any cline-yes">14x</span>
|
|
920
|
+
<span class="cline-any cline-yes">14x</span>
|
|
921
|
+
<span class="cline-any cline-yes">14x</span>
|
|
922
|
+
<span class="cline-any cline-yes">16x</span>
|
|
923
|
+
<span class="cline-any cline-yes">14x</span>
|
|
924
|
+
<span class="cline-any cline-yes">14x</span>
|
|
925
|
+
<span class="cline-any cline-yes">16x</span>
|
|
926
|
+
<span class="cline-any cline-yes">12x</span>
|
|
927
|
+
<span class="cline-any cline-yes">12x</span>
|
|
928
|
+
<span class="cline-any cline-yes">12x</span>
|
|
929
|
+
<span class="cline-any cline-yes">12x</span>
|
|
930
|
+
<span class="cline-any cline-yes">12x</span>
|
|
931
|
+
<span class="cline-any cline-yes">12x</span>
|
|
932
|
+
<span class="cline-any cline-yes">12x</span>
|
|
933
|
+
<span class="cline-any cline-yes">14x</span>
|
|
934
|
+
<span class="cline-any cline-yes">14x</span>
|
|
935
|
+
<span class="cline-any cline-yes">14x</span>
|
|
936
|
+
<span class="cline-any cline-yes">14x</span>
|
|
937
|
+
<span class="cline-any cline-yes">117x</span>
|
|
938
|
+
<span class="cline-any cline-yes">117x</span>
|
|
939
|
+
<span class="cline-any cline-yes">11x</span>
|
|
940
|
+
<span class="cline-any cline-yes">11x</span>
|
|
941
|
+
<span class="cline-any cline-yes">11x</span>
|
|
942
|
+
<span class="cline-any cline-yes">11x</span>
|
|
943
|
+
<span class="cline-any cline-yes">11x</span>
|
|
944
|
+
<span class="cline-any cline-yes">11x</span>
|
|
945
|
+
<span class="cline-any cline-yes">10x</span>
|
|
946
|
+
<span class="cline-any cline-yes">10x</span>
|
|
947
|
+
<span class="cline-any cline-yes">10x</span>
|
|
948
|
+
<span class="cline-any cline-yes">1x</span>
|
|
949
|
+
<span class="cline-any cline-yes">1x</span>
|
|
950
|
+
<span class="cline-any cline-yes">1x</span>
|
|
951
|
+
<span class="cline-any cline-yes">11x</span>
|
|
952
|
+
<span class="cline-any cline-yes">11x</span>
|
|
953
|
+
<span class="cline-any cline-yes">11x</span>
|
|
954
|
+
<span class="cline-any cline-yes">11x</span>
|
|
955
|
+
<span class="cline-any cline-yes">11x</span>
|
|
956
|
+
<span class="cline-any cline-yes">11x</span>
|
|
957
|
+
<span class="cline-any cline-yes">11x</span>
|
|
958
|
+
<span class="cline-any cline-yes">11x</span>
|
|
959
|
+
<span class="cline-any cline-yes">11x</span>
|
|
960
|
+
<span class="cline-any cline-yes">117x</span>
|
|
961
|
+
<span class="cline-any cline-yes">117x</span>
|
|
962
|
+
<span class="cline-any cline-yes">27x</span>
|
|
963
|
+
<span class="cline-any cline-yes">27x</span>
|
|
964
|
+
<span class="cline-any cline-yes">27x</span>
|
|
965
|
+
<span class="cline-any cline-yes">27x</span>
|
|
966
|
+
<span class="cline-any cline-yes">27x</span>
|
|
967
|
+
<span class="cline-any cline-yes">36x</span>
|
|
968
|
+
<span class="cline-any cline-yes">36x</span>
|
|
969
|
+
<span class="cline-any cline-yes">36x</span>
|
|
970
|
+
<span class="cline-any cline-yes">18x</span>
|
|
971
|
+
<span class="cline-any cline-yes">18x</span>
|
|
972
|
+
<span class="cline-any cline-yes">18x</span>
|
|
973
|
+
<span class="cline-any cline-yes">18x</span>
|
|
974
|
+
<span class="cline-any cline-yes">18x</span>
|
|
975
|
+
<span class="cline-any cline-yes">7x</span>
|
|
976
|
+
<span class="cline-any cline-yes">18x</span>
|
|
977
|
+
<span class="cline-any cline-yes">18x</span>
|
|
978
|
+
<span class="cline-any cline-yes">18x</span>
|
|
979
|
+
<span class="cline-any cline-yes">9x</span>
|
|
980
|
+
<span class="cline-any cline-yes">9x</span>
|
|
981
|
+
<span class="cline-any cline-yes">9x</span>
|
|
982
|
+
<span class="cline-any cline-yes">9x</span>
|
|
983
|
+
<span class="cline-any cline-yes">9x</span>
|
|
984
|
+
<span class="cline-any cline-yes">9x</span>
|
|
985
|
+
<span class="cline-any cline-yes">9x</span>
|
|
986
|
+
<span class="cline-any cline-yes">9x</span>
|
|
987
|
+
<span class="cline-any cline-yes">9x</span>
|
|
988
|
+
<span class="cline-any cline-yes">9x</span>
|
|
989
|
+
<span class="cline-any cline-yes">9x</span>
|
|
990
|
+
<span class="cline-any cline-yes">9x</span>
|
|
991
|
+
<span class="cline-any cline-yes">9x</span>
|
|
992
|
+
<span class="cline-any cline-yes">9x</span>
|
|
993
|
+
<span class="cline-any cline-yes">9x</span>
|
|
994
|
+
<span class="cline-any cline-yes">18x</span>
|
|
995
|
+
<span class="cline-any cline-no"> </span>
|
|
996
|
+
<span class="cline-any cline-no"> </span>
|
|
997
|
+
<span class="cline-any cline-yes">18x</span>
|
|
998
|
+
<span class="cline-any cline-yes">36x</span>
|
|
999
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1000
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1001
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1002
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1003
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1004
|
+
<span class="cline-any cline-yes">93x</span>
|
|
1005
|
+
<span class="cline-any cline-yes">93x</span>
|
|
1006
|
+
<span class="cline-any cline-yes">93x</span>
|
|
1007
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1008
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1009
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1010
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1011
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1012
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1013
|
+
<span class="cline-any cline-yes">91x</span>
|
|
1014
|
+
<span class="cline-any cline-yes">91x</span>
|
|
1015
|
+
<span class="cline-any cline-yes">91x</span>
|
|
1016
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1017
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1018
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1019
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1020
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1021
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1022
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1023
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1024
|
+
<span class="cline-any cline-yes">88x</span>
|
|
1025
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1026
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1027
|
+
<span class="cline-any cline-yes">95x</span>
|
|
1028
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1029
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1030
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1031
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1032
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1033
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1034
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1035
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1036
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1037
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1038
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1039
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1040
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1041
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1042
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1043
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1044
|
+
<span class="cline-any cline-yes">51x</span>
|
|
1045
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1046
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1047
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1048
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1049
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1050
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1051
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1052
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1053
|
+
<span class="cline-any cline-yes">286x</span>
|
|
1054
|
+
<span class="cline-any cline-yes">286x</span>
|
|
1055
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1056
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1057
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1058
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1059
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1060
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1061
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1062
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1063
|
+
<span class="cline-any cline-yes">282x</span>
|
|
1064
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1065
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1066
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1067
|
+
<span class="cline-any cline-yes">26x</span>
|
|
1068
|
+
<span class="cline-any cline-yes">26x</span>
|
|
1069
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1070
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1071
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1072
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1073
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1074
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1075
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1076
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1077
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1078
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1079
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1080
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1081
|
+
<span class="cline-any cline-yes">62x</span>
|
|
1082
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1083
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1084
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1085
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1086
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1087
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1088
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1089
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1090
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1091
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1092
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1093
|
+
<span class="cline-any cline-yes">30x</span>
|
|
1094
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1095
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1096
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1097
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1098
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1099
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1100
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1101
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1102
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1103
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1104
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1105
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1106
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1107
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1108
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1109
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1110
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1111
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1112
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1113
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1114
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1115
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1116
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1117
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1118
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1119
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1120
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1121
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1122
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1123
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1124
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1125
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1126
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1127
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1128
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1129
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1130
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1131
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1132
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1133
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1134
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1135
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1136
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1137
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1138
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1139
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1140
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1141
|
+
<span class="cline-any cline-no"> </span>
|
|
1142
|
+
<span class="cline-any cline-no"> </span>
|
|
1143
|
+
<span class="cline-any cline-no"> </span>
|
|
1144
|
+
<span class="cline-any cline-no"> </span>
|
|
1145
|
+
<span class="cline-any cline-no"> </span>
|
|
1146
|
+
<span class="cline-any cline-no"> </span>
|
|
1147
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1148
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1149
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1150
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1151
|
+
<span class="cline-any cline-no"> </span>
|
|
1152
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1153
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1154
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1155
|
+
<span class="cline-any cline-no"> </span>
|
|
1156
|
+
<span class="cline-any cline-no"> </span>
|
|
1157
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1158
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1159
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1160
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1161
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1162
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1163
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1164
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1165
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1166
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1167
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1168
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1169
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1170
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1171
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1172
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1173
|
+
<span class="cline-any cline-yes">18x</span>
|
|
1174
|
+
<span class="cline-any cline-yes">18x</span>
|
|
1175
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1176
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1177
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1178
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1179
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1180
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1181
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1182
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1183
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1184
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1185
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1186
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1187
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1188
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1189
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1190
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1191
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1192
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1193
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1194
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1195
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1196
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1197
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1198
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1199
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1200
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1201
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1202
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1203
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1204
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1205
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1206
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1207
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1208
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1209
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1210
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1211
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1212
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1213
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1214
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1215
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1216
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1217
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1218
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1219
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1220
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1221
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1222
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1223
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1224
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1225
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1226
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1227
|
+
<span class="cline-any cline-no"> </span>
|
|
1228
|
+
<span class="cline-any cline-no"> </span>
|
|
1229
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1230
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1231
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1232
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1233
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1234
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1235
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1236
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1237
|
+
<span class="cline-any cline-no"> </span>
|
|
1238
|
+
<span class="cline-any cline-no"> </span>
|
|
1239
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1240
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1241
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1242
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1243
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1244
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1245
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1246
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1247
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1248
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1249
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1250
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1251
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1252
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1253
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1254
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1255
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1256
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1257
|
+
<span class="cline-any cline-no"> </span>
|
|
1258
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1259
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1260
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1261
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1262
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1263
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1264
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1265
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1266
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1267
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1268
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1269
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1270
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1271
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1272
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1273
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1274
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1275
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1276
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1277
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1278
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1279
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1280
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1281
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1282
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1283
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1284
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1285
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1286
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1287
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1288
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1289
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1290
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1291
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1292
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1293
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1294
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1295
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1296
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1297
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1298
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1299
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1300
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1301
|
+
<span class="cline-any cline-no"> </span>
|
|
1302
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1303
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1304
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1305
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1306
|
+
<span class="cline-any cline-no"> </span>
|
|
1307
|
+
<span class="cline-any cline-no"> </span>
|
|
1308
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1309
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1310
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1311
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1312
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1313
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1314
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1315
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1316
|
+
<span class="cline-any cline-no"> </span>
|
|
1317
|
+
<span class="cline-any cline-no"> </span>
|
|
1318
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1319
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1320
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1321
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1322
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1323
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1324
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1325
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1326
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1327
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1328
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1329
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1330
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1331
|
+
<span class="cline-any cline-no"> </span>
|
|
1332
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1333
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1334
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1335
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1336
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1337
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1338
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1339
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1340
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1341
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1342
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1343
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1344
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1345
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1346
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1347
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1348
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1349
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1350
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1351
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1352
|
+
<span class="cline-any cline-no"> </span>
|
|
1353
|
+
<span class="cline-any cline-no"> </span>
|
|
1354
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1355
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1356
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1357
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1358
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1359
|
+
<span class="cline-any cline-no"> </span>
|
|
1360
|
+
<span class="cline-any cline-no"> </span>
|
|
1361
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1362
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1363
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1364
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1365
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1366
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1367
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1368
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1369
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1370
|
+
<span class="cline-any cline-no"> </span>
|
|
1371
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1372
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1373
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1374
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1375
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1376
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1377
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1378
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1379
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1380
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1381
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1382
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1383
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1384
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1385
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1386
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1387
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1388
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1389
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1390
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1391
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1392
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1393
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1394
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1395
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1396
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1397
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1398
|
+
<span class="cline-any cline-no"> </span>
|
|
1399
|
+
<span class="cline-any cline-no"> </span>
|
|
1400
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1401
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1402
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1403
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1404
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1405
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1406
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1407
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1408
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1409
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1410
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1411
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1412
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1413
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1414
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1415
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1416
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1417
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1418
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1419
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1420
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1421
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1422
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1423
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1424
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1425
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1426
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1427
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1428
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1429
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1430
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1431
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1432
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">/**
|
|
1433
|
+
* A2A Client - Make calls to remote agents
|
|
1434
|
+
*/
|
|
1435
|
+
|
|
1436
|
+
const https = require('https');
|
|
1437
|
+
const http = require('http');
|
|
1438
|
+
const { signRequest } = require('./crypto');
|
|
1439
|
+
// A2A-54: structured logging for retry warnings and size-cap violations
|
|
1440
|
+
const { createLogger } = require('./logger');
|
|
1441
|
+
|
|
1442
|
+
const logger = createLogger({ component: 'a2a.client' });
|
|
1443
|
+
|
|
1444
|
+
// A2A-54: response size cap prevents OOM from unbounded accumulation
|
|
1445
|
+
const MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
1446
|
+
|
|
1447
|
+
// A2A-54: only transient network errors are retryable — HTTP 4xx/5xx are not
|
|
1448
|
+
const RETRYABLE_CODES = ['ECONNRESET', 'ECONNREFUSED', 'EPIPE', 'ENOTFOUND', 'EAI_AGAIN'];
|
|
1449
|
+
|
|
1450
|
+
// A2A-54: exponential backoff — first retry is immediate, then 1s, then 2s
|
|
1451
|
+
const RETRY_DELAYS = [0, 1000, 2000];
|
|
1452
|
+
|
|
1453
|
+
// A2A-80: Agent Card cache — module-level Map with TTL and prune-on-access
|
|
1454
|
+
// Each entry: { card: object|null, cachedAt: number }
|
|
1455
|
+
// null card = negative cache (failed fetch)
|
|
1456
|
+
const _agentCardCache = new Map();
|
|
1457
|
+
|
|
1458
|
+
function _readPositiveIntEnv(name, defaultVal) {
|
|
1459
|
+
const raw = process.env[name];
|
|
1460
|
+
if (!raw) return defaultVal;
|
|
1461
|
+
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" > const n = Number.parseInt(raw, 10);</span></span>
|
|
1462
|
+
return Number.isFinite(n) && n > 0 <span class="branch-0 cbranch-no" title="branch not covered" >? n <span class="branch-0 cbranch-no" title="branch not covered" ></span>: defaultVal;</span>
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
const AGENT_CARD_TTL_MS = _readPositiveIntEnv('A2A_AGENT_CARD_TTL_MS', 300000);
|
|
1466
|
+
const AGENT_CARD_MAX_ENTRIES = _readPositiveIntEnv('A2A_AGENT_CARD_MAX_ENTRIES', 200);
|
|
1467
|
+
const AGENT_CARD_FETCH_TIMEOUT_MS = 3000;
|
|
1468
|
+
|
|
1469
|
+
// A2A-80: Prune-on-access eviction (pattern from A2A-69, NOT imported)
|
|
1470
|
+
function _pruneAgentCardCache() {
|
|
1471
|
+
const now = Date.now();
|
|
1472
|
+
for (const [key, entry] of _agentCardCache.entries()) {
|
|
1473
|
+
if (now - entry.cachedAt > AGENT_CARD_TTL_MS) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1474
|
+
<span class="cstat-no" title="statement not covered" > _agentCardCache.delete(key);</span>
|
|
1475
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
if (_agentCardCache.size <= AGENT_CARD_MAX_ENTRIES) {
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
1481
|
+
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span>
|
|
1482
|
+
<span class="cstat-no" title="statement not covered" > const oldest = Array.from(_agentCardCache.entries())</span>
|
|
1483
|
+
<span class="cstat-no" title="statement not covered" > .sort((a, b) => a[1].cachedAt - b[1].cachedAt);</span>
|
|
1484
|
+
<span class="cstat-no" title="statement not covered" > const toDelete = _agentCardCache.size - AGENT_CARD_MAX_ENTRIES;</span>
|
|
1485
|
+
<span class="cstat-no" title="statement not covered" > for (let i = 0; i < toDelete; i++) {</span>
|
|
1486
|
+
<span class="cstat-no" title="statement not covered" > _agentCardCache.delete(oldest[i][0]);</span>
|
|
1487
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
// A2A-80: Cache key is always hostname:port
|
|
1491
|
+
function _agentCardCacheKey(host) {
|
|
1492
|
+
const parsed = splitHostPort(host);
|
|
1493
|
+
const hostname = parsed.hostname;
|
|
1494
|
+
const port = Number.isFinite(parsed.port) ? parsed.port <span class="branch-0 cbranch-no" title="branch not covered" >: 80;</span>
|
|
1495
|
+
return `${hostname}:${port}`;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// A2A-80: Validate Agent Card — needs non-empty interfaces[] with { type: 'rest' }
|
|
1499
|
+
function _parseAgentCard(json) {
|
|
1500
|
+
if (!json || typeof json !== 'object') return null;
|
|
1501
|
+
if (!Array.isArray(json.interfaces) || json.interfaces.length === 0) return null;
|
|
1502
|
+
|
|
1503
|
+
const restInterface = json.interfaces.find(
|
|
1504
|
+
iface => iface && iface.type === 'rest'
|
|
1505
|
+
);
|
|
1506
|
+
if (!restInterface) return null;
|
|
1507
|
+
|
|
1508
|
+
return json;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// A2A-80: Fetch Agent Card (GET /.well-known/a2a-agent-card, 3s timeout, cached with TTL).
|
|
1512
|
+
// TODO: Concurrent call() to same uncached host may duplicate Agent Card fetches.
|
|
1513
|
+
function fetchRemoteAgentCard(host) {
|
|
1514
|
+
_pruneAgentCardCache();
|
|
1515
|
+
|
|
1516
|
+
const cacheKey = _agentCardCacheKey(host);
|
|
1517
|
+
const cached = _agentCardCache.get(cacheKey);
|
|
1518
|
+
if (cached) {
|
|
1519
|
+
return Promise.resolve(cached.card);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
const { protocol, hostname, port } = resolveProtocolAndPort(host);
|
|
1523
|
+
|
|
1524
|
+
return new Promise((resolve) => {
|
|
1525
|
+
const req = protocol.request({
|
|
1526
|
+
hostname,
|
|
1527
|
+
port,
|
|
1528
|
+
path: '/.well-known/a2a-agent-card',
|
|
1529
|
+
method: 'GET',
|
|
1530
|
+
timeout: AGENT_CARD_FETCH_TIMEOUT_MS
|
|
1531
|
+
}, (res) => {
|
|
1532
|
+
let data = '';
|
|
1533
|
+
let bytes = 0;
|
|
1534
|
+
res.on('data', (chunk) => {
|
|
1535
|
+
bytes += chunk.length;
|
|
1536
|
+
if (bytes > MAX_RESPONSE_BYTES) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1537
|
+
<span class="cstat-no" title="statement not covered" > res.destroy();</span>
|
|
1538
|
+
<span class="cstat-no" title="statement not covered" > _agentCardCache.set(cacheKey, { card: null, cachedAt: Date.now() });</span>
|
|
1539
|
+
<span class="cstat-no" title="statement not covered" > resolve(null);</span>
|
|
1540
|
+
<span class="cstat-no" title="statement not covered" > return;</span>
|
|
1541
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1542
|
+
data += chunk;
|
|
1543
|
+
});
|
|
1544
|
+
res.on('end', () => {
|
|
1545
|
+
if (res.statusCode !== 200) {
|
|
1546
|
+
_agentCardCache.set(cacheKey, { card: null, cachedAt: Date.now() });
|
|
1547
|
+
resolve(null);
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
try {
|
|
1551
|
+
const json = JSON.parse(data);
|
|
1552
|
+
const card = _parseAgentCard(json);
|
|
1553
|
+
_agentCardCache.set(cacheKey, { card, cachedAt: Date.now() });
|
|
1554
|
+
resolve(card);
|
|
1555
|
+
} catch {
|
|
1556
|
+
_agentCardCache.set(cacheKey, { card: null, cachedAt: Date.now() });
|
|
1557
|
+
resolve(null);
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
});
|
|
1561
|
+
|
|
1562
|
+
req.on('error', () => {
|
|
1563
|
+
_agentCardCache.set(cacheKey, { card: null, cachedAt: Date.now() });
|
|
1564
|
+
resolve(null);
|
|
1565
|
+
});
|
|
1566
|
+
req.on('timeout', () => {
|
|
1567
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
1568
|
+
<span class="cstat-no" title="statement not covered" > _agentCardCache.set(cacheKey, { card: null, cachedAt: Date.now() });</span>
|
|
1569
|
+
<span class="cstat-no" title="statement not covered" > resolve(null);</span>
|
|
1570
|
+
});
|
|
1571
|
+
req.end();
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
// A2A-80: Build Google A2A message/send body (ref: a2a.js translateInternalToGoogle)
|
|
1576
|
+
function _translateToGoogleRequest(message, conversationId, options = {}, caller = {}) {
|
|
1577
|
+
return {
|
|
1578
|
+
message: {
|
|
1579
|
+
role: 'user',
|
|
1580
|
+
parts: [{ content: { text: message } }],
|
|
1581
|
+
...(conversationId ? { context_id: conversationId } : {})
|
|
1582
|
+
},
|
|
1583
|
+
metadata: {
|
|
1584
|
+
caller_name: String(caller.name || '').slice(0, 100),
|
|
1585
|
+
caller_owner: String(caller.owner || '').slice(0, 100),
|
|
1586
|
+
caller_instance: String(caller.instance || '').slice(0, 200)
|
|
1587
|
+
},
|
|
1588
|
+
configuration: {
|
|
1589
|
+
timeout_seconds: options.timeoutSeconds || 60,
|
|
1590
|
+
blocking: true
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
// A2A-80: Translate Google A2A Task response to internal format (ref: a2a.js translateGoogleToInternal)
|
|
1596
|
+
function _translateGoogleResponse(taskResponse) {
|
|
1597
|
+
const task = taskResponse?.task;
|
|
1598
|
+
if (!task || !task.status) {
|
|
1599
|
+
throw new A2AError('google_a2a_error', 'Invalid Google A2A response: missing task or status');
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
const parts = task.status.message?.parts <span class="branch-0 cbranch-no" title="branch not covered" >|| [];</span>
|
|
1603
|
+
const textParts = [];
|
|
1604
|
+
for (const part of parts) {
|
|
1605
|
+
if (part?.content && typeof part.content.text === 'string') {
|
|
1606
|
+
textParts.push(part.content.text);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
const response = textParts.join('\n');
|
|
1611
|
+
const state = task.status.state;
|
|
1612
|
+
const canContinue = state === 'input-required';
|
|
1613
|
+
|
|
1614
|
+
return {
|
|
1615
|
+
response,
|
|
1616
|
+
conversation_id: task.context_id || null,
|
|
1617
|
+
can_continue: canContinue
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
// A2A-80: Resolve message:send URL from Agent Card REST interface (trailing slash stripped)
|
|
1622
|
+
function _resolveGoogleA2AUrl(agentCard, host) {
|
|
1623
|
+
const restInterface = agentCard.interfaces.find(
|
|
1624
|
+
iface => iface && iface.type === 'rest'
|
|
1625
|
+
);
|
|
1626
|
+
|
|
1627
|
+
if (restInterface && restInterface.url) {
|
|
1628
|
+
const baseUrl = restInterface.url.replace(/\/+$/, '');
|
|
1629
|
+
return `${baseUrl}/message:send`;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
// Fallback: build from host
|
|
1633
|
+
const { hostname, port } = splitHostPort(host);
|
|
1634
|
+
const effectivePort = Number.isFinite(port) ? port <span class="branch-0 cbranch-no" title="branch not covered" >: 80;</span>
|
|
1635
|
+
const isLocalhost = hostname === 'localhost' <span class="branch-0 cbranch-no" title="branch not covered" >||</span>
|
|
1636
|
+
hostname === '127.0.0.1' <span class="branch-0 cbranch-no" title="branch not covered" >||</span>
|
|
1637
|
+
hostname === '::1' <span class="branch-0 cbranch-no" title="branch not covered" >||</span>
|
|
1638
|
+
hostname.startsWith('127.');
|
|
1639
|
+
const scheme = (isLocalhost <span class="branch-0 cbranch-no" title="branch not covered" >|| effectivePort === 80 <span class="branch-0 cbranch-no" title="branch not covered" ></span>|| (Number.isFinite(port) && port !== 443))</span>
|
|
1640
|
+
? 'http' <span class="branch-0 cbranch-no" title="branch not covered" >: 'https';</span>
|
|
1641
|
+
return `${scheme}://${hostname}:${effectivePort}/message:send`;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// A2A-54: Retry on transient network errors only (not HTTP 4xx/5xx)
|
|
1645
|
+
async function withRetry(fn, options = {}) {
|
|
1646
|
+
const delays = options.delays <span class="branch-0 cbranch-no" title="branch not covered" >|| RETRY_DELAYS;</span>
|
|
1647
|
+
const maxAttempts = delays.length + 1;
|
|
1648
|
+
|
|
1649
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1650
|
+
try {
|
|
1651
|
+
return await fn();
|
|
1652
|
+
} catch (err) {
|
|
1653
|
+
// A2A-54: only retry transient network errors and timeouts.
|
|
1654
|
+
// HTTP 4xx/5xx errors have err.code set to the server's error code
|
|
1655
|
+
// (e.g. 'bad_request'), so they won't match network_error or timeout.
|
|
1656
|
+
const isRetryable = err instanceof A2AError && (
|
|
1657
|
+
(err.code === 'network_error' && RETRYABLE_CODES.some(c => err.message.includes(c))) ||
|
|
1658
|
+
err.code === 'timeout'
|
|
1659
|
+
);
|
|
1660
|
+
|
|
1661
|
+
if (!isRetryable || attempt >= maxAttempts) {
|
|
1662
|
+
throw err;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// A2A-54: log each retry at warn level for operator visibility
|
|
1666
|
+
const delay = delays[attempt - 1];
|
|
1667
|
+
logger.warn(`Retrying request (attempt ${attempt + 1}/${maxAttempts})`, {
|
|
1668
|
+
event: 'retry',
|
|
1669
|
+
data: {
|
|
1670
|
+
error_code: err.code,
|
|
1671
|
+
error_message: err.message,
|
|
1672
|
+
attempt: attempt + 1,
|
|
1673
|
+
delay_ms: delay
|
|
1674
|
+
}
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
if (delay > 0) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1678
|
+
<span class="cstat-no" title="statement not covered" > await new Promise(resolve => setTimeout(resolve, delay));</span>
|
|
1679
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
function splitHostPort(rawHost) {
|
|
1685
|
+
const host = String(rawHost || '').trim();
|
|
1686
|
+
if (!host) return { hostname: '', port: null };
|
|
1687
|
+
|
|
1688
|
+
// IPv6 in brackets: [::1]:3001
|
|
1689
|
+
const bracketed = host.match(/^\[([^\]]+)\](?::(\d+))?$/);
|
|
1690
|
+
if (bracketed) {
|
|
1691
|
+
return {
|
|
1692
|
+
hostname: bracketed[1],
|
|
1693
|
+
port: bracketed[2] ? Number.parseInt(bracketed[2], 10) : null
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// Only treat the last ":" as a port separator when there's exactly one colon.
|
|
1698
|
+
const lastColon = host.lastIndexOf(':');
|
|
1699
|
+
if (lastColon !== -1 && host.indexOf(':') === lastColon) {
|
|
1700
|
+
const maybePort = host.slice(lastColon + 1);
|
|
1701
|
+
if (/^\d+$/.test(maybePort)) {
|
|
1702
|
+
return {
|
|
1703
|
+
hostname: host.slice(0, lastColon),
|
|
1704
|
+
port: Number.parseInt(maybePort, 10)
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
return { hostname: host, port: null };
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
function resolveProtocolAndPort(host) {
|
|
1713
|
+
const parsed = splitHostPort(host);
|
|
1714
|
+
const hostname = parsed.hostname;
|
|
1715
|
+
const hasExplicitPort = Number.isFinite(parsed.port);
|
|
1716
|
+
const isLocalhost = hostname === 'localhost' ||
|
|
1717
|
+
hostname === '127.0.0.1' ||
|
|
1718
|
+
hostname === '::1' ||
|
|
1719
|
+
hostname.startsWith('127.');
|
|
1720
|
+
|
|
1721
|
+
const port = hasExplicitPort ? parsed.port : 80;
|
|
1722
|
+
// Use HTTP for localhost or explicit non-443 ports, HTTPS otherwise.
|
|
1723
|
+
const useHttp = isLocalhost || port === 80 || (hasExplicitPort && port !== 443);
|
|
1724
|
+
const protocol = useHttp ? http : https;
|
|
1725
|
+
|
|
1726
|
+
return { protocol, hostname, port };
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
// A2A-54: Size-capped response handler — destroys socket if cap exceeded
|
|
1730
|
+
function handleSizeCappedResponse(res, resolve, reject, onComplete) {
|
|
1731
|
+
let data = '';
|
|
1732
|
+
let bytes = 0;
|
|
1733
|
+
let destroyed = false;
|
|
1734
|
+
|
|
1735
|
+
res.on('data', (chunk) => {
|
|
1736
|
+
bytes += chunk.length;
|
|
1737
|
+
if (bytes > MAX_RESPONSE_BYTES) {
|
|
1738
|
+
if (!destroyed) {
|
|
1739
|
+
destroyed = true;
|
|
1740
|
+
res.destroy();
|
|
1741
|
+
// A2A-54: reject immediately — the remote sent more data than we allow
|
|
1742
|
+
reject(new A2AError('response_too_large', `Response exceeded ${MAX_RESPONSE_BYTES} bytes`));
|
|
1743
|
+
}
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
data += chunk;
|
|
1747
|
+
});
|
|
1748
|
+
|
|
1749
|
+
res.on('end', () => {
|
|
1750
|
+
if (destroyed) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
|
|
1751
|
+
onComplete(data, res.statusCode);
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
class A2AClient {
|
|
1756
|
+
constructor(options = {}) {
|
|
1757
|
+
this.timeout = options.timeout || 60000;
|
|
1758
|
+
this.caller = options.caller || {};
|
|
1759
|
+
// A2A-52: Ed25519 identity keys for request signing
|
|
1760
|
+
this.privateKey = options.privateKey || null;
|
|
1761
|
+
this.publicKey = options.publicKey || null;
|
|
1762
|
+
// A2A-54: allow configurable retry delays for testing (fast tests use [0,0,0])
|
|
1763
|
+
this._retryDelays = options._retryDelays || RETRY_DELAYS;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// A2A-52: Build signature headers if keypair available
|
|
1767
|
+
_signHeaders(method, endpoint, body) {
|
|
1768
|
+
if (!this.privateKey || !this.publicKey) return {};
|
|
1769
|
+
return signRequest({
|
|
1770
|
+
privateKey: this.privateKey,
|
|
1771
|
+
publicKey: this.publicKey,
|
|
1772
|
+
method,
|
|
1773
|
+
endpoint,
|
|
1774
|
+
body
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
static parseInvite(inviteUrl) {
|
|
1779
|
+
const match = inviteUrl.match(/^a2a:\/\/([^/]+)\/(.+)$/);
|
|
1780
|
+
if (!match) {
|
|
1781
|
+
throw new Error(`Invalid invite URL: ${inviteUrl}`);
|
|
1782
|
+
}
|
|
1783
|
+
return { host: match[1], token: match[2] };
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
// A2A-80: Send message via Google A2A protocol (message/send format)
|
|
1787
|
+
_callGoogleA2A(host, token, body, agentCard) {
|
|
1788
|
+
const url = _resolveGoogleA2AUrl(agentCard, host);
|
|
1789
|
+
// Parse the URL to extract components for http/https request
|
|
1790
|
+
const parsed = new URL(url);
|
|
1791
|
+
const proto = parsed.protocol === 'https:' <span class="branch-0 cbranch-no" title="branch not covered" >? https </span>: http;
|
|
1792
|
+
const path = parsed.pathname;
|
|
1793
|
+
|
|
1794
|
+
// A2A-52: attach signature headers when keypair available
|
|
1795
|
+
const sigHeaders = this._signHeaders('POST', path, body);
|
|
1796
|
+
|
|
1797
|
+
const makeRequest = () => new Promise((resolve, reject) => {
|
|
1798
|
+
const req = proto.request({
|
|
1799
|
+
hostname: parsed.hostname,
|
|
1800
|
+
port: parsed.port <span class="branch-0 cbranch-no" title="branch not covered" >|| (parsed.protocol === 'https:' ? 443 : 80),</span>
|
|
1801
|
+
path,
|
|
1802
|
+
method: 'POST',
|
|
1803
|
+
headers: {
|
|
1804
|
+
'Authorization': `Bearer ${token}`,
|
|
1805
|
+
'Content-Type': 'application/json',
|
|
1806
|
+
'Content-Length': Buffer.byteLength(body),
|
|
1807
|
+
...sigHeaders
|
|
1808
|
+
},
|
|
1809
|
+
timeout: this.timeout
|
|
1810
|
+
}, (res) => {
|
|
1811
|
+
handleSizeCappedResponse(res, resolve, reject, (data, statusCode) => {
|
|
1812
|
+
try {
|
|
1813
|
+
const json = JSON.parse(data);
|
|
1814
|
+
if (statusCode >= 400) {
|
|
1815
|
+
// A2A-80: map Google A2A error format to A2AError
|
|
1816
|
+
const errObj = json.error <span class="branch-0 cbranch-no" title="branch not covered" >|| {};</span>
|
|
1817
|
+
const code = errObj.code <span class="branch-0 cbranch-no" title="branch not covered" >|| json.error <span class="branch-0 cbranch-no" title="branch not covered" ></span>|| 'google_a2a_error';</span>
|
|
1818
|
+
const message = errObj.message <span class="branch-0 cbranch-no" title="branch not covered" >|| json.message <span class="branch-0 cbranch-no" title="branch not covered" ></span>|| data;</span>
|
|
1819
|
+
reject(new A2AError(String(code), message, statusCode));
|
|
1820
|
+
} else {
|
|
1821
|
+
resolve(_translateGoogleResponse(json));
|
|
1822
|
+
}
|
|
1823
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
|
|
1824
|
+
<span class="cstat-no" title="statement not covered" > if (e instanceof A2AError) {</span>
|
|
1825
|
+
<span class="cstat-no" title="statement not covered" > reject(e);</span>
|
|
1826
|
+
<span class="cstat-no" title="statement not covered" > } else {</span>
|
|
1827
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('parse_error', `Failed to parse Google A2A response: ${data}`, statusCode));</span>
|
|
1828
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1829
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1830
|
+
});
|
|
1831
|
+
});
|
|
1832
|
+
|
|
1833
|
+
req.on('error', (e) => {
|
|
1834
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('network_error', e.code ? `${e.code}: ${e.message}` : e.message));</span>
|
|
1835
|
+
});
|
|
1836
|
+
|
|
1837
|
+
req.on('timeout', () => {
|
|
1838
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
1839
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('timeout', 'Request timed out'));</span>
|
|
1840
|
+
});
|
|
1841
|
+
|
|
1842
|
+
req.write(body);
|
|
1843
|
+
req.end();
|
|
1844
|
+
});
|
|
1845
|
+
|
|
1846
|
+
return withRetry(makeRequest, { delays: this._retryDelays });
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
// Call a remote agent — auto-detects Google A2A via Agent Card
|
|
1850
|
+
async call(endpoint, message, options = {}) {
|
|
1851
|
+
let host, token;
|
|
1852
|
+
|
|
1853
|
+
if (typeof endpoint === 'string') {
|
|
1854
|
+
({ host, token } = A2AClient.parseInvite(endpoint));
|
|
1855
|
+
} else {
|
|
1856
|
+
({ host, token } = endpoint);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
const { conversationId, context, timeoutSeconds } = options;
|
|
1860
|
+
|
|
1861
|
+
// A2A-80: check Agent Card to decide Google A2A vs proprietary format
|
|
1862
|
+
const agentCard = await fetchRemoteAgentCard(host);
|
|
1863
|
+
|
|
1864
|
+
if (agentCard) {
|
|
1865
|
+
// Google A2A format path
|
|
1866
|
+
const googleBody = JSON.stringify(
|
|
1867
|
+
_translateToGoogleRequest(message, conversationId, { timeoutSeconds }, this.caller)
|
|
1868
|
+
);
|
|
1869
|
+
return this._callGoogleA2A(host, token, googleBody, agentCard);
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
// Proprietary format path (unchanged)
|
|
1873
|
+
const body = JSON.stringify({
|
|
1874
|
+
message,
|
|
1875
|
+
conversation_id: conversationId,
|
|
1876
|
+
caller: this.caller,
|
|
1877
|
+
context,
|
|
1878
|
+
timeout_seconds: timeoutSeconds || 60
|
|
1879
|
+
});
|
|
1880
|
+
|
|
1881
|
+
const { protocol, hostname, port } = resolveProtocolAndPort(host);
|
|
1882
|
+
// A2A-52: attach signature headers when keypair available
|
|
1883
|
+
const sigHeaders = this._signHeaders('POST', '/api/a2a/invoke', body);
|
|
1884
|
+
|
|
1885
|
+
// A2A-54: wrap with retry for transient network failures
|
|
1886
|
+
const makeRequest = () => new Promise((resolve, reject) => {
|
|
1887
|
+
const req = protocol.request({
|
|
1888
|
+
hostname,
|
|
1889
|
+
port,
|
|
1890
|
+
path: '/api/a2a/invoke',
|
|
1891
|
+
method: 'POST',
|
|
1892
|
+
headers: {
|
|
1893
|
+
'Authorization': `Bearer ${token}`,
|
|
1894
|
+
'Content-Type': 'application/json',
|
|
1895
|
+
'Content-Length': Buffer.byteLength(body),
|
|
1896
|
+
...sigHeaders
|
|
1897
|
+
},
|
|
1898
|
+
timeout: this.timeout
|
|
1899
|
+
}, (res) => {
|
|
1900
|
+
// A2A-54: size-capped response accumulation
|
|
1901
|
+
handleSizeCappedResponse(res, resolve, reject, (data, statusCode) => {
|
|
1902
|
+
try {
|
|
1903
|
+
const json = JSON.parse(data);
|
|
1904
|
+
if (statusCode >= 400) {
|
|
1905
|
+
reject(new A2AError(json.error <span class="branch-0 cbranch-no" title="branch not covered" >|| 'request_failed',</span> json.message <span class="branch-0 cbranch-no" title="branch not covered" >|| data,</span> statusCode));
|
|
1906
|
+
} else {
|
|
1907
|
+
resolve(json);
|
|
1908
|
+
}
|
|
1909
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
|
|
1910
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('parse_error', `Failed to parse response: ${data}`, statusCode));</span>
|
|
1911
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1912
|
+
});
|
|
1913
|
+
});
|
|
1914
|
+
|
|
1915
|
+
req.on('error', (e) => {
|
|
1916
|
+
reject(new A2AError('network_error', e.code ? `${e.code}: ${e.message}` <span class="branch-0 cbranch-no" title="branch not covered" >: e.message)</span>);
|
|
1917
|
+
});
|
|
1918
|
+
|
|
1919
|
+
req.on('timeout', () => {
|
|
1920
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
1921
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('timeout', 'Request timed out'));</span>
|
|
1922
|
+
});
|
|
1923
|
+
|
|
1924
|
+
req.write(body);
|
|
1925
|
+
req.end();
|
|
1926
|
+
});
|
|
1927
|
+
|
|
1928
|
+
return withRetry(makeRequest, { delays: this._retryDelays });
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
// End a remote conversation — no-op for Google A2A remotes
|
|
1932
|
+
async end(endpoint, conversationId) {
|
|
1933
|
+
if (!conversationId) {
|
|
1934
|
+
throw new A2AError('missing_conversation_id', 'conversationId is required');
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
let host, token;
|
|
1938
|
+
|
|
1939
|
+
if (typeof endpoint === 'string') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1940
|
+
<span class="cstat-no" title="statement not covered" > ({ host, token } = A2AClient.parseInvite(endpoint));</span>
|
|
1941
|
+
} else {
|
|
1942
|
+
({ host, token } = endpoint);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
// A2A-80: Google A2A remotes don't have an end endpoint — return synthetic response
|
|
1946
|
+
const agentCard = await fetchRemoteAgentCard(host);
|
|
1947
|
+
if (agentCard) {
|
|
1948
|
+
logger.info('Skipping end() for Google A2A remote', {
|
|
1949
|
+
event: 'google_a2a_end_skipped',
|
|
1950
|
+
data: { conversationId, host }
|
|
1951
|
+
});
|
|
1952
|
+
return { ended: true, summary: null };
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
// Proprietary format path (unchanged)
|
|
1956
|
+
const body = JSON.stringify({
|
|
1957
|
+
conversation_id: conversationId
|
|
1958
|
+
});
|
|
1959
|
+
|
|
1960
|
+
const { protocol, hostname, port } = resolveProtocolAndPort(host);
|
|
1961
|
+
// A2A-52: attach signature headers when keypair available
|
|
1962
|
+
const sigHeaders = this._signHeaders('POST', '/api/a2a/end', body);
|
|
1963
|
+
|
|
1964
|
+
// A2A-54: wrap with retry for transient network failures
|
|
1965
|
+
const makeRequest = () => new Promise((resolve, reject) => {
|
|
1966
|
+
const req = protocol.request({
|
|
1967
|
+
hostname,
|
|
1968
|
+
port,
|
|
1969
|
+
path: '/api/a2a/end',
|
|
1970
|
+
method: 'POST',
|
|
1971
|
+
headers: {
|
|
1972
|
+
'Authorization': `Bearer ${token}`,
|
|
1973
|
+
'Content-Type': 'application/json',
|
|
1974
|
+
'Content-Length': Buffer.byteLength(body),
|
|
1975
|
+
...sigHeaders
|
|
1976
|
+
},
|
|
1977
|
+
timeout: this.timeout
|
|
1978
|
+
}, (res) => {
|
|
1979
|
+
// A2A-54: size-capped response accumulation
|
|
1980
|
+
handleSizeCappedResponse(res, resolve, reject, (data, statusCode) => {
|
|
1981
|
+
try {
|
|
1982
|
+
const json = JSON.parse(data);
|
|
1983
|
+
if (statusCode >= 400) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1984
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError(json.error || 'request_failed', json.message || data, statusCode));</span>
|
|
1985
|
+
} else {
|
|
1986
|
+
resolve(json);
|
|
1987
|
+
}
|
|
1988
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
|
|
1989
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('parse_error', `Failed to parse response: ${data}`, statusCode));</span>
|
|
1990
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1991
|
+
});
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
req.on('error', (e) => {
|
|
1995
|
+
reject(new A2AError('network_error', e.code ? `${e.code}: ${e.message}` <span class="branch-0 cbranch-no" title="branch not covered" >: e.message)</span>);
|
|
1996
|
+
});
|
|
1997
|
+
|
|
1998
|
+
req.on('timeout', () => {
|
|
1999
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
2000
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('timeout', 'Request timed out'));</span>
|
|
2001
|
+
});
|
|
2002
|
+
|
|
2003
|
+
req.write(body);
|
|
2004
|
+
req.end();
|
|
2005
|
+
});
|
|
2006
|
+
|
|
2007
|
+
return withRetry(makeRequest, { delays: this._retryDelays });
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
async ping(endpoint) {
|
|
2011
|
+
let host;
|
|
2012
|
+
|
|
2013
|
+
if (typeof endpoint === 'string') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2014
|
+
<span class="cstat-no" title="statement not covered" > ({ host } = A2AClient.parseInvite(endpoint));</span>
|
|
2015
|
+
} else {
|
|
2016
|
+
({ host } = endpoint);
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
const { protocol, hostname, port } = resolveProtocolAndPort(host);
|
|
2020
|
+
|
|
2021
|
+
// A2A-54: no retry for ping — it's a lightweight probe, not a critical call
|
|
2022
|
+
return new Promise((resolve, reject) => {
|
|
2023
|
+
const req = protocol.request({
|
|
2024
|
+
hostname,
|
|
2025
|
+
port,
|
|
2026
|
+
path: '/api/a2a/ping',
|
|
2027
|
+
method: 'GET',
|
|
2028
|
+
timeout: 5000
|
|
2029
|
+
}, (res) => {
|
|
2030
|
+
// A2A-54: size-capped response accumulation
|
|
2031
|
+
handleSizeCappedResponse(res, resolve, reject, (data, statusCode) => {
|
|
2032
|
+
try {
|
|
2033
|
+
resolve(JSON.parse(data));
|
|
2034
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch {</span>
|
|
2035
|
+
<span class="cstat-no" title="statement not covered" > resolve({ pong: statusCode === 200 });</span>
|
|
2036
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2037
|
+
});
|
|
2038
|
+
});
|
|
2039
|
+
|
|
2040
|
+
req.on('error', () => resolve({ pong: false }));
|
|
2041
|
+
req.on('timeout', () => {
|
|
2042
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
2043
|
+
<span class="cstat-no" title="statement not covered" > resolve({ pong: false });</span>
|
|
2044
|
+
});
|
|
2045
|
+
req.end();
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
async status(endpoint) {
|
|
2050
|
+
let host;
|
|
2051
|
+
|
|
2052
|
+
if (typeof endpoint === 'string') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2053
|
+
<span class="cstat-no" title="statement not covered" > ({ host } = A2AClient.parseInvite(endpoint));</span>
|
|
2054
|
+
} else {
|
|
2055
|
+
({ host } = endpoint);
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
const { protocol, hostname, port } = resolveProtocolAndPort(host);
|
|
2059
|
+
|
|
2060
|
+
// A2A-54: no retry for status — read-only probe, not a stateful operation
|
|
2061
|
+
return new Promise((resolve, reject) => {
|
|
2062
|
+
const req = protocol.request({
|
|
2063
|
+
hostname,
|
|
2064
|
+
port,
|
|
2065
|
+
path: '/api/a2a/status',
|
|
2066
|
+
method: 'GET',
|
|
2067
|
+
timeout: 5000
|
|
2068
|
+
}, (res) => {
|
|
2069
|
+
// A2A-54: size-capped response accumulation
|
|
2070
|
+
handleSizeCappedResponse(res, resolve, reject, (data) => {
|
|
2071
|
+
try {
|
|
2072
|
+
resolve(JSON.parse(data));
|
|
2073
|
+
} catch {
|
|
2074
|
+
reject(new A2AError('parse_error', 'Invalid status response'));
|
|
2075
|
+
}
|
|
2076
|
+
});
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
req.on('error', (e) => reject(new A2AError('network_error', e.code ? `${e.code}: ${e.message}` <span class="branch-0 cbranch-no" title="branch not covered" >: e.message)</span>));
|
|
2080
|
+
req.on('timeout', () => {
|
|
2081
|
+
<span class="cstat-no" title="statement not covered" > req.destroy();</span>
|
|
2082
|
+
<span class="cstat-no" title="statement not covered" > reject(new A2AError('timeout', 'Request timed out'));</span>
|
|
2083
|
+
});
|
|
2084
|
+
req.end();
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
class A2AError extends Error {
|
|
2090
|
+
constructor(code, message, statusCode = null) {
|
|
2091
|
+
super(message);
|
|
2092
|
+
this.name = 'A2AError';
|
|
2093
|
+
this.code = code;
|
|
2094
|
+
this.statusCode = statusCode;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
// A2A-54: export internals for testing (splitHostPort, resolveProtocolAndPort, constants)
|
|
2099
|
+
// A2A-80: export Agent Card cache and helpers for testing
|
|
2100
|
+
module.exports = {
|
|
2101
|
+
A2AClient,
|
|
2102
|
+
A2AError,
|
|
2103
|
+
_splitHostPort: splitHostPort,
|
|
2104
|
+
_resolveProtocolAndPort: resolveProtocolAndPort,
|
|
2105
|
+
_MAX_RESPONSE_BYTES: MAX_RESPONSE_BYTES,
|
|
2106
|
+
_RETRYABLE_CODES: RETRYABLE_CODES,
|
|
2107
|
+
_RETRY_DELAYS: RETRY_DELAYS,
|
|
2108
|
+
_agentCardCache,
|
|
2109
|
+
_parseAgentCard,
|
|
2110
|
+
_translateToGoogleRequest,
|
|
2111
|
+
_translateGoogleResponse,
|
|
2112
|
+
_resolveGoogleA2AUrl,
|
|
2113
|
+
fetchRemoteAgentCard
|
|
2114
|
+
};
|
|
2115
|
+
</pre></td></tr></table></pre>
|
|
2116
|
+
|
|
2117
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
2118
|
+
</div><!-- /wrapper -->
|
|
2119
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
2120
|
+
Code coverage generated by
|
|
2121
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2122
|
+
at 2026-03-03T22:25:10.857Z
|
|
2123
|
+
</div>
|
|
2124
|
+
<script src="../../prettify.js"></script>
|
|
2125
|
+
<script>
|
|
2126
|
+
window.onload = function () {
|
|
2127
|
+
prettyPrint();
|
|
2128
|
+
};
|
|
2129
|
+
</script>
|
|
2130
|
+
<script src="../../sorter.js"></script>
|
|
2131
|
+
<script src="../../block-navigation.js"></script>
|
|
2132
|
+
</body>
|
|
2133
|
+
</html>
|
|
2134
|
+
|