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,2689 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/lib/tokens.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> tokens.js</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">87.09% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>756/868</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">73.07% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>190/260</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">77.41% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>24/31</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">87.09% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>756/868</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>
|
|
750
|
+
<a name='L685'></a><a href='#L685'>685</a>
|
|
751
|
+
<a name='L686'></a><a href='#L686'>686</a>
|
|
752
|
+
<a name='L687'></a><a href='#L687'>687</a>
|
|
753
|
+
<a name='L688'></a><a href='#L688'>688</a>
|
|
754
|
+
<a name='L689'></a><a href='#L689'>689</a>
|
|
755
|
+
<a name='L690'></a><a href='#L690'>690</a>
|
|
756
|
+
<a name='L691'></a><a href='#L691'>691</a>
|
|
757
|
+
<a name='L692'></a><a href='#L692'>692</a>
|
|
758
|
+
<a name='L693'></a><a href='#L693'>693</a>
|
|
759
|
+
<a name='L694'></a><a href='#L694'>694</a>
|
|
760
|
+
<a name='L695'></a><a href='#L695'>695</a>
|
|
761
|
+
<a name='L696'></a><a href='#L696'>696</a>
|
|
762
|
+
<a name='L697'></a><a href='#L697'>697</a>
|
|
763
|
+
<a name='L698'></a><a href='#L698'>698</a>
|
|
764
|
+
<a name='L699'></a><a href='#L699'>699</a>
|
|
765
|
+
<a name='L700'></a><a href='#L700'>700</a>
|
|
766
|
+
<a name='L701'></a><a href='#L701'>701</a>
|
|
767
|
+
<a name='L702'></a><a href='#L702'>702</a>
|
|
768
|
+
<a name='L703'></a><a href='#L703'>703</a>
|
|
769
|
+
<a name='L704'></a><a href='#L704'>704</a>
|
|
770
|
+
<a name='L705'></a><a href='#L705'>705</a>
|
|
771
|
+
<a name='L706'></a><a href='#L706'>706</a>
|
|
772
|
+
<a name='L707'></a><a href='#L707'>707</a>
|
|
773
|
+
<a name='L708'></a><a href='#L708'>708</a>
|
|
774
|
+
<a name='L709'></a><a href='#L709'>709</a>
|
|
775
|
+
<a name='L710'></a><a href='#L710'>710</a>
|
|
776
|
+
<a name='L711'></a><a href='#L711'>711</a>
|
|
777
|
+
<a name='L712'></a><a href='#L712'>712</a>
|
|
778
|
+
<a name='L713'></a><a href='#L713'>713</a>
|
|
779
|
+
<a name='L714'></a><a href='#L714'>714</a>
|
|
780
|
+
<a name='L715'></a><a href='#L715'>715</a>
|
|
781
|
+
<a name='L716'></a><a href='#L716'>716</a>
|
|
782
|
+
<a name='L717'></a><a href='#L717'>717</a>
|
|
783
|
+
<a name='L718'></a><a href='#L718'>718</a>
|
|
784
|
+
<a name='L719'></a><a href='#L719'>719</a>
|
|
785
|
+
<a name='L720'></a><a href='#L720'>720</a>
|
|
786
|
+
<a name='L721'></a><a href='#L721'>721</a>
|
|
787
|
+
<a name='L722'></a><a href='#L722'>722</a>
|
|
788
|
+
<a name='L723'></a><a href='#L723'>723</a>
|
|
789
|
+
<a name='L724'></a><a href='#L724'>724</a>
|
|
790
|
+
<a name='L725'></a><a href='#L725'>725</a>
|
|
791
|
+
<a name='L726'></a><a href='#L726'>726</a>
|
|
792
|
+
<a name='L727'></a><a href='#L727'>727</a>
|
|
793
|
+
<a name='L728'></a><a href='#L728'>728</a>
|
|
794
|
+
<a name='L729'></a><a href='#L729'>729</a>
|
|
795
|
+
<a name='L730'></a><a href='#L730'>730</a>
|
|
796
|
+
<a name='L731'></a><a href='#L731'>731</a>
|
|
797
|
+
<a name='L732'></a><a href='#L732'>732</a>
|
|
798
|
+
<a name='L733'></a><a href='#L733'>733</a>
|
|
799
|
+
<a name='L734'></a><a href='#L734'>734</a>
|
|
800
|
+
<a name='L735'></a><a href='#L735'>735</a>
|
|
801
|
+
<a name='L736'></a><a href='#L736'>736</a>
|
|
802
|
+
<a name='L737'></a><a href='#L737'>737</a>
|
|
803
|
+
<a name='L738'></a><a href='#L738'>738</a>
|
|
804
|
+
<a name='L739'></a><a href='#L739'>739</a>
|
|
805
|
+
<a name='L740'></a><a href='#L740'>740</a>
|
|
806
|
+
<a name='L741'></a><a href='#L741'>741</a>
|
|
807
|
+
<a name='L742'></a><a href='#L742'>742</a>
|
|
808
|
+
<a name='L743'></a><a href='#L743'>743</a>
|
|
809
|
+
<a name='L744'></a><a href='#L744'>744</a>
|
|
810
|
+
<a name='L745'></a><a href='#L745'>745</a>
|
|
811
|
+
<a name='L746'></a><a href='#L746'>746</a>
|
|
812
|
+
<a name='L747'></a><a href='#L747'>747</a>
|
|
813
|
+
<a name='L748'></a><a href='#L748'>748</a>
|
|
814
|
+
<a name='L749'></a><a href='#L749'>749</a>
|
|
815
|
+
<a name='L750'></a><a href='#L750'>750</a>
|
|
816
|
+
<a name='L751'></a><a href='#L751'>751</a>
|
|
817
|
+
<a name='L752'></a><a href='#L752'>752</a>
|
|
818
|
+
<a name='L753'></a><a href='#L753'>753</a>
|
|
819
|
+
<a name='L754'></a><a href='#L754'>754</a>
|
|
820
|
+
<a name='L755'></a><a href='#L755'>755</a>
|
|
821
|
+
<a name='L756'></a><a href='#L756'>756</a>
|
|
822
|
+
<a name='L757'></a><a href='#L757'>757</a>
|
|
823
|
+
<a name='L758'></a><a href='#L758'>758</a>
|
|
824
|
+
<a name='L759'></a><a href='#L759'>759</a>
|
|
825
|
+
<a name='L760'></a><a href='#L760'>760</a>
|
|
826
|
+
<a name='L761'></a><a href='#L761'>761</a>
|
|
827
|
+
<a name='L762'></a><a href='#L762'>762</a>
|
|
828
|
+
<a name='L763'></a><a href='#L763'>763</a>
|
|
829
|
+
<a name='L764'></a><a href='#L764'>764</a>
|
|
830
|
+
<a name='L765'></a><a href='#L765'>765</a>
|
|
831
|
+
<a name='L766'></a><a href='#L766'>766</a>
|
|
832
|
+
<a name='L767'></a><a href='#L767'>767</a>
|
|
833
|
+
<a name='L768'></a><a href='#L768'>768</a>
|
|
834
|
+
<a name='L769'></a><a href='#L769'>769</a>
|
|
835
|
+
<a name='L770'></a><a href='#L770'>770</a>
|
|
836
|
+
<a name='L771'></a><a href='#L771'>771</a>
|
|
837
|
+
<a name='L772'></a><a href='#L772'>772</a>
|
|
838
|
+
<a name='L773'></a><a href='#L773'>773</a>
|
|
839
|
+
<a name='L774'></a><a href='#L774'>774</a>
|
|
840
|
+
<a name='L775'></a><a href='#L775'>775</a>
|
|
841
|
+
<a name='L776'></a><a href='#L776'>776</a>
|
|
842
|
+
<a name='L777'></a><a href='#L777'>777</a>
|
|
843
|
+
<a name='L778'></a><a href='#L778'>778</a>
|
|
844
|
+
<a name='L779'></a><a href='#L779'>779</a>
|
|
845
|
+
<a name='L780'></a><a href='#L780'>780</a>
|
|
846
|
+
<a name='L781'></a><a href='#L781'>781</a>
|
|
847
|
+
<a name='L782'></a><a href='#L782'>782</a>
|
|
848
|
+
<a name='L783'></a><a href='#L783'>783</a>
|
|
849
|
+
<a name='L784'></a><a href='#L784'>784</a>
|
|
850
|
+
<a name='L785'></a><a href='#L785'>785</a>
|
|
851
|
+
<a name='L786'></a><a href='#L786'>786</a>
|
|
852
|
+
<a name='L787'></a><a href='#L787'>787</a>
|
|
853
|
+
<a name='L788'></a><a href='#L788'>788</a>
|
|
854
|
+
<a name='L789'></a><a href='#L789'>789</a>
|
|
855
|
+
<a name='L790'></a><a href='#L790'>790</a>
|
|
856
|
+
<a name='L791'></a><a href='#L791'>791</a>
|
|
857
|
+
<a name='L792'></a><a href='#L792'>792</a>
|
|
858
|
+
<a name='L793'></a><a href='#L793'>793</a>
|
|
859
|
+
<a name='L794'></a><a href='#L794'>794</a>
|
|
860
|
+
<a name='L795'></a><a href='#L795'>795</a>
|
|
861
|
+
<a name='L796'></a><a href='#L796'>796</a>
|
|
862
|
+
<a name='L797'></a><a href='#L797'>797</a>
|
|
863
|
+
<a name='L798'></a><a href='#L798'>798</a>
|
|
864
|
+
<a name='L799'></a><a href='#L799'>799</a>
|
|
865
|
+
<a name='L800'></a><a href='#L800'>800</a>
|
|
866
|
+
<a name='L801'></a><a href='#L801'>801</a>
|
|
867
|
+
<a name='L802'></a><a href='#L802'>802</a>
|
|
868
|
+
<a name='L803'></a><a href='#L803'>803</a>
|
|
869
|
+
<a name='L804'></a><a href='#L804'>804</a>
|
|
870
|
+
<a name='L805'></a><a href='#L805'>805</a>
|
|
871
|
+
<a name='L806'></a><a href='#L806'>806</a>
|
|
872
|
+
<a name='L807'></a><a href='#L807'>807</a>
|
|
873
|
+
<a name='L808'></a><a href='#L808'>808</a>
|
|
874
|
+
<a name='L809'></a><a href='#L809'>809</a>
|
|
875
|
+
<a name='L810'></a><a href='#L810'>810</a>
|
|
876
|
+
<a name='L811'></a><a href='#L811'>811</a>
|
|
877
|
+
<a name='L812'></a><a href='#L812'>812</a>
|
|
878
|
+
<a name='L813'></a><a href='#L813'>813</a>
|
|
879
|
+
<a name='L814'></a><a href='#L814'>814</a>
|
|
880
|
+
<a name='L815'></a><a href='#L815'>815</a>
|
|
881
|
+
<a name='L816'></a><a href='#L816'>816</a>
|
|
882
|
+
<a name='L817'></a><a href='#L817'>817</a>
|
|
883
|
+
<a name='L818'></a><a href='#L818'>818</a>
|
|
884
|
+
<a name='L819'></a><a href='#L819'>819</a>
|
|
885
|
+
<a name='L820'></a><a href='#L820'>820</a>
|
|
886
|
+
<a name='L821'></a><a href='#L821'>821</a>
|
|
887
|
+
<a name='L822'></a><a href='#L822'>822</a>
|
|
888
|
+
<a name='L823'></a><a href='#L823'>823</a>
|
|
889
|
+
<a name='L824'></a><a href='#L824'>824</a>
|
|
890
|
+
<a name='L825'></a><a href='#L825'>825</a>
|
|
891
|
+
<a name='L826'></a><a href='#L826'>826</a>
|
|
892
|
+
<a name='L827'></a><a href='#L827'>827</a>
|
|
893
|
+
<a name='L828'></a><a href='#L828'>828</a>
|
|
894
|
+
<a name='L829'></a><a href='#L829'>829</a>
|
|
895
|
+
<a name='L830'></a><a href='#L830'>830</a>
|
|
896
|
+
<a name='L831'></a><a href='#L831'>831</a>
|
|
897
|
+
<a name='L832'></a><a href='#L832'>832</a>
|
|
898
|
+
<a name='L833'></a><a href='#L833'>833</a>
|
|
899
|
+
<a name='L834'></a><a href='#L834'>834</a>
|
|
900
|
+
<a name='L835'></a><a href='#L835'>835</a>
|
|
901
|
+
<a name='L836'></a><a href='#L836'>836</a>
|
|
902
|
+
<a name='L837'></a><a href='#L837'>837</a>
|
|
903
|
+
<a name='L838'></a><a href='#L838'>838</a>
|
|
904
|
+
<a name='L839'></a><a href='#L839'>839</a>
|
|
905
|
+
<a name='L840'></a><a href='#L840'>840</a>
|
|
906
|
+
<a name='L841'></a><a href='#L841'>841</a>
|
|
907
|
+
<a name='L842'></a><a href='#L842'>842</a>
|
|
908
|
+
<a name='L843'></a><a href='#L843'>843</a>
|
|
909
|
+
<a name='L844'></a><a href='#L844'>844</a>
|
|
910
|
+
<a name='L845'></a><a href='#L845'>845</a>
|
|
911
|
+
<a name='L846'></a><a href='#L846'>846</a>
|
|
912
|
+
<a name='L847'></a><a href='#L847'>847</a>
|
|
913
|
+
<a name='L848'></a><a href='#L848'>848</a>
|
|
914
|
+
<a name='L849'></a><a href='#L849'>849</a>
|
|
915
|
+
<a name='L850'></a><a href='#L850'>850</a>
|
|
916
|
+
<a name='L851'></a><a href='#L851'>851</a>
|
|
917
|
+
<a name='L852'></a><a href='#L852'>852</a>
|
|
918
|
+
<a name='L853'></a><a href='#L853'>853</a>
|
|
919
|
+
<a name='L854'></a><a href='#L854'>854</a>
|
|
920
|
+
<a name='L855'></a><a href='#L855'>855</a>
|
|
921
|
+
<a name='L856'></a><a href='#L856'>856</a>
|
|
922
|
+
<a name='L857'></a><a href='#L857'>857</a>
|
|
923
|
+
<a name='L858'></a><a href='#L858'>858</a>
|
|
924
|
+
<a name='L859'></a><a href='#L859'>859</a>
|
|
925
|
+
<a name='L860'></a><a href='#L860'>860</a>
|
|
926
|
+
<a name='L861'></a><a href='#L861'>861</a>
|
|
927
|
+
<a name='L862'></a><a href='#L862'>862</a>
|
|
928
|
+
<a name='L863'></a><a href='#L863'>863</a>
|
|
929
|
+
<a name='L864'></a><a href='#L864'>864</a>
|
|
930
|
+
<a name='L865'></a><a href='#L865'>865</a>
|
|
931
|
+
<a name='L866'></a><a href='#L866'>866</a>
|
|
932
|
+
<a name='L867'></a><a href='#L867'>867</a>
|
|
933
|
+
<a name='L868'></a><a href='#L868'>868</a>
|
|
934
|
+
<a name='L869'></a><a href='#L869'>869</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">183x</span>
|
|
935
|
+
<span class="cline-any cline-yes">183x</span>
|
|
936
|
+
<span class="cline-any cline-yes">183x</span>
|
|
937
|
+
<span class="cline-any cline-yes">183x</span>
|
|
938
|
+
<span class="cline-any cline-yes">183x</span>
|
|
939
|
+
<span class="cline-any cline-yes">183x</span>
|
|
940
|
+
<span class="cline-any cline-yes">183x</span>
|
|
941
|
+
<span class="cline-any cline-yes">183x</span>
|
|
942
|
+
<span class="cline-any cline-yes">183x</span>
|
|
943
|
+
<span class="cline-any cline-yes">183x</span>
|
|
944
|
+
<span class="cline-any cline-yes">183x</span>
|
|
945
|
+
<span class="cline-any cline-yes">183x</span>
|
|
946
|
+
<span class="cline-any cline-yes">183x</span>
|
|
947
|
+
<span class="cline-any cline-yes">183x</span>
|
|
948
|
+
<span class="cline-any cline-yes">183x</span>
|
|
949
|
+
<span class="cline-any cline-yes">183x</span>
|
|
950
|
+
<span class="cline-any cline-yes">183x</span>
|
|
951
|
+
<span class="cline-any cline-yes">21x</span>
|
|
952
|
+
<span class="cline-any cline-yes">21x</span>
|
|
953
|
+
<span class="cline-any cline-yes">21x</span>
|
|
954
|
+
<span class="cline-any cline-yes">21x</span>
|
|
955
|
+
<span class="cline-any cline-yes">21x</span>
|
|
956
|
+
<span class="cline-any cline-yes">21x</span>
|
|
957
|
+
<span class="cline-any cline-yes">20x</span>
|
|
958
|
+
<span class="cline-any cline-yes">20x</span>
|
|
959
|
+
<span class="cline-any cline-yes">1x</span>
|
|
960
|
+
<span class="cline-any cline-yes">1x</span>
|
|
961
|
+
<span class="cline-any cline-yes">1x</span>
|
|
962
|
+
<span class="cline-any cline-yes">1x</span>
|
|
963
|
+
<span class="cline-any cline-yes">1x</span>
|
|
964
|
+
<span class="cline-any cline-yes">21x</span>
|
|
965
|
+
<span class="cline-any cline-no"> </span>
|
|
966
|
+
<span class="cline-any cline-no"> </span>
|
|
967
|
+
<span class="cline-any cline-no"> </span>
|
|
968
|
+
<span class="cline-any cline-no"> </span>
|
|
969
|
+
<span class="cline-any cline-no"> </span>
|
|
970
|
+
<span class="cline-any cline-no"> </span>
|
|
971
|
+
<span class="cline-any cline-no"> </span>
|
|
972
|
+
<span class="cline-any cline-no"> </span>
|
|
973
|
+
<span class="cline-any cline-no"> </span>
|
|
974
|
+
<span class="cline-any cline-no"> </span>
|
|
975
|
+
<span class="cline-any cline-no"> </span>
|
|
976
|
+
<span class="cline-any cline-no"> </span>
|
|
977
|
+
<span class="cline-any cline-no"> </span>
|
|
978
|
+
<span class="cline-any cline-no"> </span>
|
|
979
|
+
<span class="cline-any cline-no"> </span>
|
|
980
|
+
<span class="cline-any cline-no"> </span>
|
|
981
|
+
<span class="cline-any cline-no"> </span>
|
|
982
|
+
<span class="cline-any cline-no"> </span>
|
|
983
|
+
<span class="cline-any cline-no"> </span>
|
|
984
|
+
<span class="cline-any cline-no"> </span>
|
|
985
|
+
<span class="cline-any cline-no"> </span>
|
|
986
|
+
<span class="cline-any cline-no"> </span>
|
|
987
|
+
<span class="cline-any cline-no"> </span>
|
|
988
|
+
<span class="cline-any cline-yes">1x</span>
|
|
989
|
+
<span class="cline-any cline-yes">1x</span>
|
|
990
|
+
<span class="cline-any cline-yes">21x</span>
|
|
991
|
+
<span class="cline-any cline-yes">183x</span>
|
|
992
|
+
<span class="cline-any cline-yes">448x</span>
|
|
993
|
+
<span class="cline-any cline-yes">448x</span>
|
|
994
|
+
<span class="cline-any cline-yes">448x</span>
|
|
995
|
+
<span class="cline-any cline-yes">448x</span>
|
|
996
|
+
<span class="cline-any cline-yes">183x</span>
|
|
997
|
+
<span class="cline-any cline-yes">183x</span>
|
|
998
|
+
<span class="cline-any cline-yes">183x</span>
|
|
999
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1000
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1001
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1002
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1003
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1004
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1005
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1006
|
+
<span class="cline-any cline-no"> </span>
|
|
1007
|
+
<span class="cline-any cline-no"> </span>
|
|
1008
|
+
<span class="cline-any cline-yes">175x</span>
|
|
1009
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1010
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1011
|
+
<span class="cline-any cline-yes">414x</span>
|
|
1012
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1013
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1014
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1015
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1016
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1017
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1018
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1019
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1020
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1021
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1022
|
+
<span class="cline-any cline-no"> </span>
|
|
1023
|
+
<span class="cline-any cline-no"> </span>
|
|
1024
|
+
<span class="cline-any cline-no"> </span>
|
|
1025
|
+
<span class="cline-any cline-no"> </span>
|
|
1026
|
+
<span class="cline-any cline-no"> </span>
|
|
1027
|
+
<span class="cline-any cline-no"> </span>
|
|
1028
|
+
<span class="cline-any cline-no"> </span>
|
|
1029
|
+
<span class="cline-any cline-no"> </span>
|
|
1030
|
+
<span class="cline-any cline-no"> </span>
|
|
1031
|
+
<span class="cline-any cline-no"> </span>
|
|
1032
|
+
<span class="cline-any cline-no"> </span>
|
|
1033
|
+
<span class="cline-any cline-no"> </span>
|
|
1034
|
+
<span class="cline-any cline-no"> </span>
|
|
1035
|
+
<span class="cline-any cline-no"> </span>
|
|
1036
|
+
<span class="cline-any cline-no"> </span>
|
|
1037
|
+
<span class="cline-any cline-no"> </span>
|
|
1038
|
+
<span class="cline-any cline-no"> </span>
|
|
1039
|
+
<span class="cline-any cline-no"> </span>
|
|
1040
|
+
<span class="cline-any cline-no"> </span>
|
|
1041
|
+
<span class="cline-any cline-no"> </span>
|
|
1042
|
+
<span class="cline-any cline-no"> </span>
|
|
1043
|
+
<span class="cline-any cline-no"> </span>
|
|
1044
|
+
<span class="cline-any cline-no"> </span>
|
|
1045
|
+
<span class="cline-any cline-no"> </span>
|
|
1046
|
+
<span class="cline-any cline-yes">287x</span>
|
|
1047
|
+
<span class="cline-any cline-yes">287x</span>
|
|
1048
|
+
<span class="cline-any cline-yes">287x</span>
|
|
1049
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1050
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1051
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1052
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1053
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1054
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1055
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1056
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1057
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1058
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1059
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1060
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1061
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1062
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1063
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1064
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1065
|
+
<span class="cline-any cline-yes">288x</span>
|
|
1066
|
+
<span class="cline-any cline-yes">126x</span>
|
|
1067
|
+
<span class="cline-any cline-yes">414x</span>
|
|
1068
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1069
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1070
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1071
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1072
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1073
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1074
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1075
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1076
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1077
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1078
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1079
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1080
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1081
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1082
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1083
|
+
<span class="cline-any cline-no"> </span>
|
|
1084
|
+
<span class="cline-any cline-no"> </span>
|
|
1085
|
+
<span class="cline-any cline-yes">306x</span>
|
|
1086
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1087
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1088
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1089
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1090
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1091
|
+
<span class="cline-any cline-yes">213x</span>
|
|
1092
|
+
<span class="cline-any cline-yes">213x</span>
|
|
1093
|
+
<span class="cline-any cline-yes">213x</span>
|
|
1094
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1095
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1096
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1097
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1098
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1099
|
+
<span class="cline-any cline-yes">261x</span>
|
|
1100
|
+
<span class="cline-any cline-yes">261x</span>
|
|
1101
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1102
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1103
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1104
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1105
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1106
|
+
<span class="cline-any cline-yes">122x</span>
|
|
1107
|
+
<span class="cline-any cline-yes">107x</span>
|
|
1108
|
+
<span class="cline-any cline-yes">117x</span>
|
|
1109
|
+
<span class="cline-any cline-yes">105x</span>
|
|
1110
|
+
<span class="cline-any cline-yes">105x</span>
|
|
1111
|
+
<span class="cline-any cline-yes">122x</span>
|
|
1112
|
+
<span class="cline-any cline-yes">122x</span>
|
|
1113
|
+
<span class="cline-any cline-yes">122x</span>
|
|
1114
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1115
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1116
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1117
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1118
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1119
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1120
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1121
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1122
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1123
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1124
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1125
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1126
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1127
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1128
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1129
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1130
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1131
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1132
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1133
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1134
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1135
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1136
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1137
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1138
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1139
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1140
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1141
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1142
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1143
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1144
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1145
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1146
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1147
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1148
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1149
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1150
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1151
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1152
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1153
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1154
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1155
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1156
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1157
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1158
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1159
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1160
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1161
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1162
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1163
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1164
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1165
|
+
<span class="cline-any cline-no"> </span>
|
|
1166
|
+
<span class="cline-any cline-no"> </span>
|
|
1167
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1168
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1169
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1170
|
+
<span class="cline-any cline-yes">112x</span>
|
|
1171
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1172
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1173
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1174
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1175
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1176
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1177
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1178
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1179
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1180
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1181
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1182
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1183
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1184
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1185
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1186
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1187
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1188
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1189
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1190
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1191
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1192
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1193
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1194
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1195
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1196
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1197
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1198
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1199
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1200
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1201
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1202
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1203
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1204
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1205
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1206
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1207
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1208
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1209
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1210
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1211
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1212
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1213
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1214
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1215
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1216
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1217
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1218
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1219
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1220
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1221
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1222
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1223
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1224
|
+
<span class="cline-any cline-yes">115x</span>
|
|
1225
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1226
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1227
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1228
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1229
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1230
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1231
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1232
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1233
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1234
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1235
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1236
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1237
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1238
|
+
<span class="cline-any cline-yes">17x</span>
|
|
1239
|
+
<span class="cline-any cline-yes">17x</span>
|
|
1240
|
+
<span class="cline-any cline-yes">17x</span>
|
|
1241
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1242
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1243
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1244
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1245
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1246
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1247
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1248
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1249
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1250
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1251
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1252
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1253
|
+
<span class="cline-any cline-yes">120x</span>
|
|
1254
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1255
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1256
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1257
|
+
<span class="cline-any cline-yes">118x</span>
|
|
1258
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1259
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1260
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1261
|
+
<span class="cline-any cline-yes">116x</span>
|
|
1262
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1263
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1264
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1265
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1266
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1267
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1268
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1269
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1270
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1271
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1272
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1273
|
+
<span class="cline-any cline-no"> </span>
|
|
1274
|
+
<span class="cline-any cline-no"> </span>
|
|
1275
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1276
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1277
|
+
<span class="cline-any cline-yes">113x</span>
|
|
1278
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1279
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1280
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1281
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1282
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1283
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1284
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1285
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1286
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1287
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1288
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1289
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1290
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1291
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1292
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1293
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1294
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1295
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1296
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1297
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1298
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1299
|
+
<span class="cline-any cline-yes">123x</span>
|
|
1300
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1301
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1302
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1303
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1304
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1305
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1306
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1307
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1308
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1309
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1310
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1311
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1312
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1313
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1314
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1315
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1316
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1317
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1318
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1319
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1320
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1321
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1322
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1323
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1324
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1325
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1326
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1327
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1328
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1329
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1330
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1331
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1332
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1333
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1334
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1335
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1336
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1337
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1338
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1339
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1340
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1341
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1342
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1343
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1344
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1345
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1346
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1347
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1348
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1349
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1350
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1351
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1352
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1353
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1354
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1355
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1356
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1357
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1358
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1359
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1360
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1361
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1362
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1363
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1364
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1365
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1366
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1367
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1368
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1369
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1370
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1371
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1372
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1373
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1374
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1375
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1376
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1377
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1378
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1379
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1380
|
+
<span class="cline-any cline-no"> </span>
|
|
1381
|
+
<span class="cline-any cline-no"> </span>
|
|
1382
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1383
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1384
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1385
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1386
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1387
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1388
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1389
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1390
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1391
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1392
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1393
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1394
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1395
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1396
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1397
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1398
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1399
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1400
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1401
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1402
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1403
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1404
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1405
|
+
<span class="cline-any cline-yes">22x</span>
|
|
1406
|
+
<span class="cline-any cline-yes">22x</span>
|
|
1407
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1408
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1409
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1410
|
+
<span class="cline-any cline-yes">22x</span>
|
|
1411
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1412
|
+
<span class="cline-any cline-no"> </span>
|
|
1413
|
+
<span class="cline-any cline-no"> </span>
|
|
1414
|
+
<span class="cline-any cline-no"> </span>
|
|
1415
|
+
<span class="cline-any cline-no"> </span>
|
|
1416
|
+
<span class="cline-any cline-no"> </span>
|
|
1417
|
+
<span class="cline-any cline-no"> </span>
|
|
1418
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1419
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1420
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1421
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1422
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1423
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1424
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1425
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1426
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1427
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1428
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1429
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1430
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1431
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1432
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1433
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1434
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1435
|
+
<span class="cline-any cline-yes">372x</span>
|
|
1436
|
+
<span class="cline-any cline-yes">372x</span>
|
|
1437
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1438
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1439
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1440
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1441
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1442
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1443
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1444
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1445
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1446
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1447
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1448
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1449
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1450
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1451
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1452
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1453
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1454
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1455
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1456
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1457
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1458
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1459
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1460
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1461
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1462
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1463
|
+
<span class="cline-any cline-yes">23x</span>
|
|
1464
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1465
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1466
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1467
|
+
<span class="cline-any cline-no"> </span>
|
|
1468
|
+
<span class="cline-any cline-no"> </span>
|
|
1469
|
+
<span class="cline-any cline-no"> </span>
|
|
1470
|
+
<span class="cline-any cline-no"> </span>
|
|
1471
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1472
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1473
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1474
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1475
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1476
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1477
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1478
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1479
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1480
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1481
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1482
|
+
<span class="cline-any cline-no"> </span>
|
|
1483
|
+
<span class="cline-any cline-no"> </span>
|
|
1484
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1485
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1486
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1487
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1488
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1489
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1490
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1491
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1492
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1493
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1494
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1495
|
+
<span class="cline-any cline-yes">282x</span>
|
|
1496
|
+
<span class="cline-any cline-yes">282x</span>
|
|
1497
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1498
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1499
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1500
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1501
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1502
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1503
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1504
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1505
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1506
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1507
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1508
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1509
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1510
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1511
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1512
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1513
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1514
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1515
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1516
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1517
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1518
|
+
<span class="cline-any cline-yes">28x</span>
|
|
1519
|
+
<span class="cline-any cline-yes">28x</span>
|
|
1520
|
+
<span class="cline-any cline-yes">28x</span>
|
|
1521
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1522
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1523
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1524
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1525
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1526
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1527
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1528
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1529
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1530
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1531
|
+
<span class="cline-any cline-yes">40x</span>
|
|
1532
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1533
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1534
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1535
|
+
<span class="cline-any cline-no"> </span>
|
|
1536
|
+
<span class="cline-any cline-no"> </span>
|
|
1537
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1538
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1539
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1540
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1541
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1542
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1543
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1544
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1545
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1546
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1547
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1548
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1549
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1550
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1551
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1552
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1553
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1554
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1555
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1556
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1557
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1558
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1559
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1560
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1561
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1562
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1563
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1564
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1565
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1566
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1567
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1568
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1569
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1570
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1571
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1572
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1573
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1574
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1575
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1576
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1577
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1578
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1579
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1580
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1581
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1582
|
+
<span class="cline-any cline-no"> </span>
|
|
1583
|
+
<span class="cline-any cline-no"> </span>
|
|
1584
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1585
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1586
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1587
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1588
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1589
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1590
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1591
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1592
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1593
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1594
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1595
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1596
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1597
|
+
<span class="cline-any cline-no"> </span>
|
|
1598
|
+
<span class="cline-any cline-no"> </span>
|
|
1599
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1600
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1601
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1602
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1603
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1604
|
+
<span class="cline-any cline-yes">36x</span>
|
|
1605
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1606
|
+
<span class="cline-any cline-no"> </span>
|
|
1607
|
+
<span class="cline-any cline-no"> </span>
|
|
1608
|
+
<span class="cline-any cline-no"> </span>
|
|
1609
|
+
<span class="cline-any cline-no"> </span>
|
|
1610
|
+
<span class="cline-any cline-no"> </span>
|
|
1611
|
+
<span class="cline-any cline-no"> </span>
|
|
1612
|
+
<span class="cline-any cline-no"> </span>
|
|
1613
|
+
<span class="cline-any cline-no"> </span>
|
|
1614
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1615
|
+
<span class="cline-any cline-no"> </span>
|
|
1616
|
+
<span class="cline-any cline-no"> </span>
|
|
1617
|
+
<span class="cline-any cline-no"> </span>
|
|
1618
|
+
<span class="cline-any cline-no"> </span>
|
|
1619
|
+
<span class="cline-any cline-no"> </span>
|
|
1620
|
+
<span class="cline-any cline-no"> </span>
|
|
1621
|
+
<span class="cline-any cline-no"> </span>
|
|
1622
|
+
<span class="cline-any cline-no"> </span>
|
|
1623
|
+
<span class="cline-any cline-no"> </span>
|
|
1624
|
+
<span class="cline-any cline-no"> </span>
|
|
1625
|
+
<span class="cline-any cline-no"> </span>
|
|
1626
|
+
<span class="cline-any cline-no"> </span>
|
|
1627
|
+
<span class="cline-any cline-no"> </span>
|
|
1628
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1629
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1630
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1631
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1632
|
+
<span class="cline-any cline-yes">36x</span>
|
|
1633
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1634
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1635
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1636
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1637
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1638
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1639
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1640
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1641
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1642
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1643
|
+
<span class="cline-any cline-no"> </span>
|
|
1644
|
+
<span class="cline-any cline-no"> </span>
|
|
1645
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1646
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1647
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1648
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1649
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1650
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1651
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1652
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1653
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1654
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1655
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1656
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1657
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1658
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1659
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1660
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1661
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1662
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1663
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1664
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1665
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1666
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1667
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1668
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1669
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1670
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1671
|
+
<span class="cline-any cline-no"> </span>
|
|
1672
|
+
<span class="cline-any cline-no"> </span>
|
|
1673
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1674
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1675
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1676
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1677
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1678
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1679
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1680
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1681
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1682
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1683
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1684
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1685
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1686
|
+
<span class="cline-any cline-no"> </span>
|
|
1687
|
+
<span class="cline-any cline-no"> </span>
|
|
1688
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1689
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1690
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1691
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1692
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1693
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1694
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1695
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1696
|
+
<span class="cline-any cline-no"> </span>
|
|
1697
|
+
<span class="cline-any cline-no"> </span>
|
|
1698
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1699
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1700
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1701
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1702
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1703
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1704
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1705
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1706
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1707
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1708
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1709
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1710
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1711
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1712
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1713
|
+
<span class="cline-any cline-yes">65x</span>
|
|
1714
|
+
<span class="cline-any cline-yes">65x</span>
|
|
1715
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1716
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1717
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1718
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1719
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1720
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1721
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1722
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1723
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1724
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1725
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1726
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1727
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1728
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1729
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1730
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1731
|
+
<span class="cline-any cline-yes">21x</span>
|
|
1732
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1733
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1734
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1735
|
+
<span class="cline-any cline-no"> </span>
|
|
1736
|
+
<span class="cline-any cline-no"> </span>
|
|
1737
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1738
|
+
<span class="cline-any cline-no"> </span>
|
|
1739
|
+
<span class="cline-any cline-no"> </span>
|
|
1740
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1741
|
+
<span class="cline-any cline-no"> </span>
|
|
1742
|
+
<span class="cline-any cline-no"> </span>
|
|
1743
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1744
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1745
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1746
|
+
<span class="cline-any cline-no"> </span>
|
|
1747
|
+
<span class="cline-any cline-no"> </span>
|
|
1748
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1749
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1750
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1751
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1752
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1753
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1754
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1755
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1756
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1757
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1758
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1759
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1760
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1761
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1762
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1763
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1764
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1765
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1766
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1767
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1768
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1769
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1770
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1771
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1772
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1773
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1774
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1775
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1776
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1777
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1778
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1779
|
+
<span class="cline-any cline-yes">86x</span>
|
|
1780
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1781
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1782
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1783
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1784
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1785
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1786
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1787
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1788
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1789
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1790
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1791
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1792
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1793
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1794
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1795
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1796
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1797
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1798
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1799
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1800
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1801
|
+
<span class="cline-any cline-yes">183x</span>
|
|
1802
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">/**
|
|
1803
|
+
* Token management for A2A
|
|
1804
|
+
*/
|
|
1805
|
+
|
|
1806
|
+
const fs = require('fs');
|
|
1807
|
+
const path = require('path');
|
|
1808
|
+
const crypto = require('crypto');
|
|
1809
|
+
const { createLogger } = require('./logger');
|
|
1810
|
+
|
|
1811
|
+
// Default config path
|
|
1812
|
+
const DEFAULT_CONFIG_DIR = process.env.A2A_CONFIG_DIR ||
|
|
1813
|
+
process.env.OPENCLAW_CONFIG_DIR ||
|
|
1814
|
+
path.join(process.env.HOME <span class="branch-0 cbranch-no" title="branch not covered" >|| '/tmp',</span> '.config', 'openclaw');
|
|
1815
|
+
|
|
1816
|
+
const DB_FILENAME = 'a2a.json';
|
|
1817
|
+
const logger = createLogger({ component: 'a2a.tokens' });
|
|
1818
|
+
|
|
1819
|
+
function sanitizeCustomFields(fields, options = {}) {
|
|
1820
|
+
const maxFields = Number.isFinite(options.maxFields) <span class="branch-0 cbranch-no" title="branch not covered" >? options.maxFields </span>: 200;
|
|
1821
|
+
const keyMaxLength = Number.isFinite(options.keyMaxLength) <span class="branch-0 cbranch-no" title="branch not covered" >? options.keyMaxLength </span>: 80;
|
|
1822
|
+
const valMaxLength = Number.isFinite(options.valMaxLength) <span class="branch-0 cbranch-no" title="branch not covered" >? options.valMaxLength </span>: 800;
|
|
1823
|
+
|
|
1824
|
+
if (!fields || typeof fields !== 'object' || Array.isArray(fields)) {
|
|
1825
|
+
return {};
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
const cleaned = {};
|
|
1829
|
+
const keys = Object.keys(fields);
|
|
1830
|
+
let count = 0;
|
|
1831
|
+
|
|
1832
|
+
for (const rawKey of keys) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1833
|
+
<span class="cstat-no" title="statement not covered" > if (count >= maxFields) break;</span>
|
|
1834
|
+
<span class="cstat-no" title="statement not covered" > const key = String(rawKey || '').replace(/\s+/g, ' ').trim().slice(0, keyMaxLength);</span>
|
|
1835
|
+
<span class="cstat-no" title="statement not covered" > if (!key) continue;</span>
|
|
1836
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1837
|
+
<span class="cstat-no" title="statement not covered" > const rawVal = fields[rawKey];</span>
|
|
1838
|
+
<span class="cstat-no" title="statement not covered" > let value = '';</span>
|
|
1839
|
+
<span class="cstat-no" title="statement not covered" > if (rawVal === null || rawVal === undefined) {</span>
|
|
1840
|
+
<span class="cstat-no" title="statement not covered" > value = '';</span>
|
|
1841
|
+
<span class="cstat-no" title="statement not covered" > } else if (typeof rawVal === 'string') {</span>
|
|
1842
|
+
<span class="cstat-no" title="statement not covered" > value = rawVal;</span>
|
|
1843
|
+
<span class="cstat-no" title="statement not covered" > } else if (typeof rawVal === 'number' || typeof rawVal === 'boolean') {</span>
|
|
1844
|
+
<span class="cstat-no" title="statement not covered" > value = String(rawVal);</span>
|
|
1845
|
+
<span class="cstat-no" title="statement not covered" > } else {</span>
|
|
1846
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1847
|
+
<span class="cstat-no" title="statement not covered" > value = JSON.stringify(rawVal);</span>
|
|
1848
|
+
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
|
|
1849
|
+
<span class="cstat-no" title="statement not covered" > value = String(rawVal);</span>
|
|
1850
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1851
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1852
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1853
|
+
<span class="cstat-no" title="statement not covered" > cleaned[key] = String(value).replace(/\s+/g, ' ').trim().slice(0, valMaxLength);</span>
|
|
1854
|
+
<span class="cstat-no" title="statement not covered" > count++;</span>
|
|
1855
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1856
|
+
|
|
1857
|
+
return cleaned;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
function parsePositiveTimeoutMs(value) {
|
|
1861
|
+
const parsed = Number.parseInt(String(value ?? ''), 10);
|
|
1862
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
class TokenStore {
|
|
1866
|
+
constructor(configDir = DEFAULT_CONFIG_DIR) {
|
|
1867
|
+
this.configDir = configDir;
|
|
1868
|
+
this.dbPath = path.join(configDir, DB_FILENAME);
|
|
1869
|
+
this._ensureDir();
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
_ensureDir() {
|
|
1873
|
+
if (!fs.existsSync(this.configDir)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1874
|
+
<span class="cstat-no" title="statement not covered" > fs.mkdirSync(this.configDir, { recursive: true });</span>
|
|
1875
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
_load() {
|
|
1879
|
+
if (fs.existsSync(this.dbPath)) {
|
|
1880
|
+
try {
|
|
1881
|
+
const parsed = JSON.parse(fs.readFileSync(this.dbPath, 'utf8'));
|
|
1882
|
+
const db = parsed && typeof parsed === 'object' ? parsed <span class="branch-0 cbranch-no" title="branch not covered" >: {};</span>
|
|
1883
|
+
db.tokens = Array.isArray(db.tokens) ? db.tokens <span class="branch-0 cbranch-no" title="branch not covered" >: [];</span>
|
|
1884
|
+
db.calls = Array.isArray(db.calls) ? db.calls <span class="branch-0 cbranch-no" title="branch not covered" >: [];</span>
|
|
1885
|
+
db.contacts = Array.isArray(db.contacts) ? db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >: [];</span>
|
|
1886
|
+
|
|
1887
|
+
// Backward compat: legacy "remotes" is now "contacts".
|
|
1888
|
+
const legacyRemotes = Array.isArray(db.remotes) <span class="branch-0 cbranch-no" title="branch not covered" >? db.remotes </span>: [];
|
|
1889
|
+
if (legacyRemotes.length) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1890
|
+
<span class="cstat-no" title="statement not covered" > const keyFor = <span class="fstat-no" title="function not covered" >(row) => {</span></span>
|
|
1891
|
+
<span class="cstat-no" title="statement not covered" > if (!row || typeof row !== 'object') return null;</span>
|
|
1892
|
+
<span class="cstat-no" title="statement not covered" > if (row.id) return `id:${row.id}`;</span>
|
|
1893
|
+
<span class="cstat-no" title="statement not covered" > const host = row.host ? String(row.host) : '';</span>
|
|
1894
|
+
<span class="cstat-no" title="statement not covered" > const hash = row.token_hash ? String(row.token_hash) : '';</span>
|
|
1895
|
+
<span class="cstat-no" title="statement not covered" > if (host && hash) return `hosthash:${host}#${hash}`;</span>
|
|
1896
|
+
<span class="cstat-no" title="statement not covered" > if (host) return `host:${host}`;</span>
|
|
1897
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1898
|
+
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1899
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1900
|
+
<span class="cstat-no" title="statement not covered" > const merged = db.contacts.slice();</span>
|
|
1901
|
+
<span class="cstat-no" title="statement not covered" > const seen = new Set();</span>
|
|
1902
|
+
<span class="cstat-no" title="statement not covered" > for (const row of merged) {</span>
|
|
1903
|
+
<span class="cstat-no" title="statement not covered" > const key = keyFor(row);</span>
|
|
1904
|
+
<span class="cstat-no" title="statement not covered" > if (key) seen.add(key);</span>
|
|
1905
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1906
|
+
<span class="cstat-no" title="statement not covered" > for (const row of legacyRemotes) {</span>
|
|
1907
|
+
<span class="cstat-no" title="statement not covered" > const key = keyFor(row);</span>
|
|
1908
|
+
<span class="cstat-no" title="statement not covered" > if (key && seen.has(key)) continue;</span>
|
|
1909
|
+
<span class="cstat-no" title="statement not covered" > if (key) seen.add(key);</span>
|
|
1910
|
+
<span class="cstat-no" title="statement not covered" > merged.push(row);</span>
|
|
1911
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1912
|
+
<span class="cstat-no" title="statement not covered" > db.contacts = merged;</span>
|
|
1913
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1914
|
+
|
|
1915
|
+
// Persisted schema is intentionally minimal during prototyping.
|
|
1916
|
+
return { tokens: db.tokens, contacts: db.contacts, calls: db.calls };
|
|
1917
|
+
} catch (e) {
|
|
1918
|
+
// Corrupted file - backup and start fresh
|
|
1919
|
+
const backupPath = `${this.dbPath}.corrupt.${Date.now()}`;
|
|
1920
|
+
fs.renameSync(this.dbPath, backupPath);
|
|
1921
|
+
logger.error('Token database was corrupted and moved to backup', {
|
|
1922
|
+
event: 'token_db_corrupt_backup_created',
|
|
1923
|
+
error: e,
|
|
1924
|
+
error_code: 'TOKEN_DB_CORRUPTED',
|
|
1925
|
+
hint: 'Inspect the backup file, then restore valid JSON schema in a2a.json.',
|
|
1926
|
+
data: {
|
|
1927
|
+
db_path: this.dbPath,
|
|
1928
|
+
backup_path: backupPath
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
return { tokens: [], contacts: [], calls: [] };
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
return { tokens: [], contacts: [], calls: [] };
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
_save(db) {
|
|
1938
|
+
const persisted = {
|
|
1939
|
+
tokens: Array.isArray(db.tokens) ? db.tokens <span class="branch-0 cbranch-no" title="branch not covered" >: [],</span>
|
|
1940
|
+
contacts: Array.isArray(db.contacts) ? db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >: [],</span>
|
|
1941
|
+
calls: Array.isArray(db.calls) ? db.calls <span class="branch-0 cbranch-no" title="branch not covered" >: []</span>
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1944
|
+
// Atomic write: write to temp file, then rename
|
|
1945
|
+
const tmpPath = `${this.dbPath}.tmp.${process.pid}`;
|
|
1946
|
+
fs.writeFileSync(tmpPath, JSON.stringify(persisted, null, 2), { mode: 0o600 });
|
|
1947
|
+
fs.renameSync(tmpPath, this.dbPath);
|
|
1948
|
+
try {
|
|
1949
|
+
fs.chmodSync(this.dbPath, 0o600);
|
|
1950
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
1951
|
+
<span class="cstat-no" title="statement not covered" > // Best effort - ignore on platforms without chmod support.</span>
|
|
1952
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
/**
|
|
1956
|
+
* Generate a secure A2A token
|
|
1957
|
+
*/
|
|
1958
|
+
static generateToken() {
|
|
1959
|
+
const bytes = crypto.randomBytes(24);
|
|
1960
|
+
return 'fed_' + bytes.toString('base64url');
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
/**
|
|
1964
|
+
* Hash a token for storage
|
|
1965
|
+
*/
|
|
1966
|
+
static hashToken(token) {
|
|
1967
|
+
return crypto.createHash('sha256').update(token).digest('hex');
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
/**
|
|
1971
|
+
* Parse duration string (1h, 1d, 7d, 30d, never) to milliseconds
|
|
1972
|
+
*/
|
|
1973
|
+
static parseDuration(str) {
|
|
1974
|
+
if (!str || str === 'never') return null;
|
|
1975
|
+
const match = str.match(/^(\d+)(h|d)$/);
|
|
1976
|
+
if (!match) throw new Error(`Invalid duration: ${str}`);
|
|
1977
|
+
const [, num, unit] = match;
|
|
1978
|
+
return unit === 'h'
|
|
1979
|
+
? parseInt(num) * 60 * 60 * 1000
|
|
1980
|
+
: parseInt(num) * 24 * 60 * 60 * 1000;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
/**
|
|
1984
|
+
* Create a new A2A token
|
|
1985
|
+
*
|
|
1986
|
+
* Default limits (anti-abuse):
|
|
1987
|
+
* - Expires in 1 day
|
|
1988
|
+
* - Max 100 calls total
|
|
1989
|
+
* - Rate limited: 10/min, 100/hr, 1000/day (enforced server-side)
|
|
1990
|
+
* - Timeout: 5-300 seconds (enforced server-side)
|
|
1991
|
+
*/
|
|
1992
|
+
create(options = {}) {
|
|
1993
|
+
// A2A-41: disclosure field removed from tokens. Was never used by
|
|
1994
|
+
// prompt generation. Existing tokens with disclosure field are harmless
|
|
1995
|
+
// — the field is simply not read.
|
|
1996
|
+
const {
|
|
1997
|
+
name = 'unnamed',
|
|
1998
|
+
owner = null,
|
|
1999
|
+
expires = '1d',
|
|
2000
|
+
permissions = 'public',
|
|
2001
|
+
notify = 'all',
|
|
2002
|
+
maxCalls = 100, // Default limit, not unlimited
|
|
2003
|
+
capabilities = null, // Array of capability strings, snapshotted at creation
|
|
2004
|
+
// Snapshot of actual capabilities at creation time
|
|
2005
|
+
allowedTopics = null, // Array of topic strings, e.g. ['chat', 'calendar.read']
|
|
2006
|
+
allowedGoals = null, // Array of goal strings, e.g. ['grow-network', 'find-collaborators']
|
|
2007
|
+
allowedTools = null, // Array of tool names, e.g. ['Read', 'Grep', 'Glob']
|
|
2008
|
+
tierSettings = null, // Object with tier-specific settings
|
|
2009
|
+
timeoutMs = null
|
|
2010
|
+
} = options;
|
|
2011
|
+
|
|
2012
|
+
const tier = String(permissions <span class="branch-0 cbranch-no" title="branch not covered" >|| 'public')</span>.trim() <span class="branch-0 cbranch-no" title="branch not covered" >|| 'public';</span>
|
|
2013
|
+
if (!TokenStore.VALID_TIERS.includes(tier)) {
|
|
2014
|
+
throw new Error(`Invalid permissions tier: ${tier}. Expected: ${TokenStore.VALID_TIERS.join('|')}`);
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
const token = TokenStore.generateToken();
|
|
2018
|
+
const tokenHash = TokenStore.hashToken(token);
|
|
2019
|
+
const durationMs = TokenStore.parseDuration(expires);
|
|
2020
|
+
const expiresAt = durationMs ? new Date(Date.now() + durationMs).toISOString() : null;
|
|
2021
|
+
|
|
2022
|
+
// Load tier definitions from config (if available)
|
|
2023
|
+
let configTiers = {};
|
|
2024
|
+
try {
|
|
2025
|
+
const configPath = path.join(this.configDir, 'a2a-config.json');
|
|
2026
|
+
if (fs.existsSync(configPath)) {
|
|
2027
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
2028
|
+
if (config.tiers) {
|
|
2029
|
+
configTiers = config.tiers;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
|
|
2033
|
+
<span class="cstat-no" title="statement not covered" > // Config not available, use defaults</span>
|
|
2034
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2035
|
+
|
|
2036
|
+
// Default topics based on tier label (snapshot at creation)
|
|
2037
|
+
// User config overrides these defaults
|
|
2038
|
+
const defaultTopics = {
|
|
2039
|
+
'public': configTiers.public?.topics || ['chat'],
|
|
2040
|
+
'friends': configTiers.friends?.topics || ['chat', 'calendar.read', 'email.read', 'search'],
|
|
2041
|
+
'family': configTiers.family?.topics || ['chat', 'calendar', 'email', 'search', 'tools'],
|
|
2042
|
+
'custom': configTiers.custom?.topics || ['chat']
|
|
2043
|
+
};
|
|
2044
|
+
|
|
2045
|
+
// Default goals based on tier label (snapshot at creation)
|
|
2046
|
+
const defaultGoals = {
|
|
2047
|
+
'public': configTiers.public?.goals || [],
|
|
2048
|
+
'friends': configTiers.friends?.goals || [],
|
|
2049
|
+
'family': configTiers.family?.goals || [],
|
|
2050
|
+
'custom': configTiers.custom?.goals || []
|
|
2051
|
+
};
|
|
2052
|
+
|
|
2053
|
+
// Default tool allowlist based on tier label (snapshot at creation).
|
|
2054
|
+
const defaultTools = {
|
|
2055
|
+
'public': configTiers.public?.allowed_tools || TokenStore.DEFAULT_ALLOWED_TOOLS.public,
|
|
2056
|
+
'friends': configTiers.friends?.allowed_tools || TokenStore.DEFAULT_ALLOWED_TOOLS.friends,
|
|
2057
|
+
'family': configTiers.family?.allowed_tools || TokenStore.DEFAULT_ALLOWED_TOOLS.family,
|
|
2058
|
+
'custom': configTiers.custom?.allowed_tools || TokenStore.DEFAULT_ALLOWED_TOOLS.custom
|
|
2059
|
+
};
|
|
2060
|
+
|
|
2061
|
+
// Resolve capabilities: explicit > config > defaults
|
|
2062
|
+
const defaultCapabilities = (configTiers[tier]?.capabilities?.length)
|
|
2063
|
+
? configTiers[tier].capabilities
|
|
2064
|
+
: (TokenStore.DEFAULT_CAPABILITIES[tier] <span class="branch-0 cbranch-no" title="branch not covered" >|| ['context-read'])</span>;
|
|
2065
|
+
|
|
2066
|
+
// Use separate random ID (not derived from token) to prevent prefix attacks
|
|
2067
|
+
const record = {
|
|
2068
|
+
id: 'tok_' + crypto.randomBytes(8).toString('hex'),
|
|
2069
|
+
token_hash: tokenHash,
|
|
2070
|
+
name,
|
|
2071
|
+
owner,
|
|
2072
|
+
tier,
|
|
2073
|
+
capabilities: capabilities || defaultCapabilities,
|
|
2074
|
+
allowed_topics: allowedTopics || defaultTopics[tier] <span class="branch-0 cbranch-no" title="branch not covered" >|| ['chat'],</span>
|
|
2075
|
+
allowed_goals: allowedGoals || defaultGoals[tier] <span class="branch-0 cbranch-no" title="branch not covered" >|| [],</span>
|
|
2076
|
+
allowed_tools: allowedTools || defaultTools[tier] <span class="branch-0 cbranch-no" title="branch not covered" >|| TokenStore.DEFAULT_ALLOWED_TOOLS.public,</span>
|
|
2077
|
+
timeout_ms: parsePositiveTimeoutMs(timeoutMs),
|
|
2078
|
+
tier_settings: tierSettings || {}, // Snapshot of settings at creation
|
|
2079
|
+
notify,
|
|
2080
|
+
max_calls: maxCalls,
|
|
2081
|
+
calls_made: 0,
|
|
2082
|
+
created_at: new Date().toISOString(),
|
|
2083
|
+
expires_at: expiresAt,
|
|
2084
|
+
revoked: false
|
|
2085
|
+
};
|
|
2086
|
+
|
|
2087
|
+
const db = this._load();
|
|
2088
|
+
db.tokens.push(record);
|
|
2089
|
+
this._save(db);
|
|
2090
|
+
|
|
2091
|
+
return { token, record };
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
/**
|
|
2095
|
+
* List all tokens (optionally including revoked)
|
|
2096
|
+
*/
|
|
2097
|
+
list(includeRevoked = false) {
|
|
2098
|
+
const db = this._load();
|
|
2099
|
+
return includeRevoked ? db.tokens : db.tokens.filter(t => !t.revoked);
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
/**
|
|
2103
|
+
* Find a token by ID prefix
|
|
2104
|
+
*/
|
|
2105
|
+
findById(idPrefix) {
|
|
2106
|
+
const db = this._load();
|
|
2107
|
+
return db.tokens.find(t => t.id === idPrefix || t.id.startsWith(idPrefix));
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
/**
|
|
2111
|
+
* Validate an incoming token, returns validation result
|
|
2112
|
+
*/
|
|
2113
|
+
validate(token) {
|
|
2114
|
+
const db = this._load();
|
|
2115
|
+
const tokenHash = TokenStore.hashToken(token);
|
|
2116
|
+
const record = db.tokens.find(t => t.token_hash === tokenHash);
|
|
2117
|
+
|
|
2118
|
+
if (!record) {
|
|
2119
|
+
return { valid: false, error: 'token_not_found' };
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
if (record.revoked) {
|
|
2123
|
+
return { valid: false, error: 'token_revoked' };
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
if (record.expires_at && new Date(record.expires_at) < new Date()) {
|
|
2127
|
+
return { valid: false, error: 'token_expired' };
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
if (record.max_calls && record.calls_made >= record.max_calls) {
|
|
2131
|
+
return { valid: false, error: 'max_calls_exceeded' };
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// Increment call count
|
|
2135
|
+
record.calls_made++;
|
|
2136
|
+
record.last_used = new Date().toISOString();
|
|
2137
|
+
this._save(db);
|
|
2138
|
+
|
|
2139
|
+
const tier = record.tier <span class="branch-0 cbranch-no" title="branch not covered" >|| 'public';</span>
|
|
2140
|
+
if (!TokenStore.VALID_TIERS.includes(tier)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2141
|
+
<span class="cstat-no" title="statement not covered" > return { valid: false, error: 'invalid_token_tier' };</span>
|
|
2142
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2143
|
+
|
|
2144
|
+
// Resolve capabilities: stored > defaults
|
|
2145
|
+
const capabilities = record.capabilities
|
|
2146
|
+
<span class="branch-0 cbranch-no" title="branch not covered" > || TokenStore.DEFAULT_CAPABILITIES[tier]</span>
|
|
2147
|
+
<span class="branch-0 cbranch-no" title="branch not covered" > || ['context-read'];</span>
|
|
2148
|
+
|
|
2149
|
+
const timeoutMs = parsePositiveTimeoutMs(record.timeout_ms)
|
|
2150
|
+
|| parsePositiveTimeoutMs(record.tier_settings?.timeout_ms)
|
|
2151
|
+
|| parsePositiveTimeoutMs(record.tier_settings?.timeoutMs);
|
|
2152
|
+
|
|
2153
|
+
return {
|
|
2154
|
+
valid: true,
|
|
2155
|
+
id: record.id,
|
|
2156
|
+
name: record.name,
|
|
2157
|
+
tier,
|
|
2158
|
+
capabilities,
|
|
2159
|
+
allowed_topics: record.allowed_topics <span class="branch-0 cbranch-no" title="branch not covered" >|| ['chat'],</span>
|
|
2160
|
+
allowed_goals: record.allowed_goals <span class="branch-0 cbranch-no" title="branch not covered" >|| [],</span>
|
|
2161
|
+
allowed_tools: record.allowed_tools <span class="branch-0 cbranch-no" title="branch not covered" >|| TokenStore.DEFAULT_ALLOWED_TOOLS[tier] <span class="branch-0 cbranch-no" title="branch not covered" ></span>|| TokenStore.DEFAULT_ALLOWED_TOOLS.public,</span>
|
|
2162
|
+
timeout_ms: timeoutMs,
|
|
2163
|
+
tier_settings: record.tier_settings <span class="branch-0 cbranch-no" title="branch not covered" >|| {},</span>
|
|
2164
|
+
notify: record.notify,
|
|
2165
|
+
calls_remaining: record.max_calls ? record.max_calls - record.calls_made <span class="branch-0 cbranch-no" title="branch not covered" >: null</span>
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
/**
|
|
2170
|
+
* Revoke a token by ID
|
|
2171
|
+
*/
|
|
2172
|
+
revoke(idPrefix) {
|
|
2173
|
+
const db = this._load();
|
|
2174
|
+
const record = db.tokens.find(t => t.id === idPrefix || t.id.startsWith(idPrefix));
|
|
2175
|
+
|
|
2176
|
+
if (!record) {
|
|
2177
|
+
return { success: false, error: 'not_found' };
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
record.revoked = true;
|
|
2181
|
+
record.revoked_at = new Date().toISOString();
|
|
2182
|
+
this._save(db);
|
|
2183
|
+
|
|
2184
|
+
return { success: true, record };
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
/**
|
|
2188
|
+
* A2A-65: Remove expired and old-revoked tokens from the store.
|
|
2189
|
+
*
|
|
2190
|
+
* - Tokens expired for >1 hour are removed (grace period for in-flight calls)
|
|
2191
|
+
* - Tokens revoked >token_expiry_grace_days ago are removed
|
|
2192
|
+
* - Valid and recently-expired tokens are preserved
|
|
2193
|
+
*
|
|
2194
|
+
* @param {object} [options]
|
|
2195
|
+
* @param {number} [options.token_expiry_grace_days=30] - Days after revocation before removal
|
|
2196
|
+
* @returns {{ removed_expired: number, removed_revoked: number }}
|
|
2197
|
+
*/
|
|
2198
|
+
cleanupExpired(options = {}) {
|
|
2199
|
+
const graceDays = Number.isFinite(options.token_expiry_grace_days)
|
|
2200
|
+
? options.token_expiry_grace_days
|
|
2201
|
+
: 30;
|
|
2202
|
+
|
|
2203
|
+
const db = this._load();
|
|
2204
|
+
const now = Date.now();
|
|
2205
|
+
const oneHourMs = 60 * 60 * 1000;
|
|
2206
|
+
const gracePeriodMs = graceDays * 24 * 60 * 60 * 1000;
|
|
2207
|
+
|
|
2208
|
+
let removed_expired = 0;
|
|
2209
|
+
let removed_revoked = 0;
|
|
2210
|
+
|
|
2211
|
+
const original = db.tokens.length;
|
|
2212
|
+
|
|
2213
|
+
db.tokens = db.tokens.filter(token => {
|
|
2214
|
+
// Remove tokens expired for > 1 hour
|
|
2215
|
+
if (token.expires_at) {
|
|
2216
|
+
const expiresAt = new Date(token.expires_at).getTime();
|
|
2217
|
+
if (expiresAt < now - oneHourMs) {
|
|
2218
|
+
removed_expired++;
|
|
2219
|
+
return false;
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// Remove tokens revoked > graceDays ago
|
|
2224
|
+
if (token.revoked && token.revoked_at) {
|
|
2225
|
+
const revokedAt = new Date(token.revoked_at).getTime();
|
|
2226
|
+
if (revokedAt < now - gracePeriodMs) {
|
|
2227
|
+
removed_revoked++;
|
|
2228
|
+
return false;
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
return true;
|
|
2233
|
+
});
|
|
2234
|
+
|
|
2235
|
+
// Only write if something changed
|
|
2236
|
+
if (db.tokens.length < original) {
|
|
2237
|
+
this._save(db);
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// A2A-65: Log cleanup results (best effort)
|
|
2241
|
+
try {
|
|
2242
|
+
const cleanupLogger = require('./logger').createLogger({ component: 'a2a.cleanup' });
|
|
2243
|
+
cleanupLogger.info('Token cleanup completed', {
|
|
2244
|
+
event: 'tokens_cleaned',
|
|
2245
|
+
data: { removed_expired, removed_revoked, remaining: db.tokens.length, grace_days: graceDays }
|
|
2246
|
+
});
|
|
2247
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (_) {</span>
|
|
2248
|
+
<span class="cstat-no" title="statement not covered" > // Best effort</span>
|
|
2249
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2250
|
+
|
|
2251
|
+
return { removed_expired, removed_revoked };
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
/**
|
|
2255
|
+
* Add a remote agent endpoint (contact)
|
|
2256
|
+
* Note: Token is encrypted at rest using a derived key
|
|
2257
|
+
*
|
|
2258
|
+
* @param {string} inviteUrl - a2a://host/token format
|
|
2259
|
+
* @param {object} options - Contact metadata
|
|
2260
|
+
* @param {string} options.name - Agent name
|
|
2261
|
+
* @param {string} options.owner - Human owner name
|
|
2262
|
+
* @param {string} options.server_name - Server label (owner-local / optional)
|
|
2263
|
+
* @param {string} options.notes - Freeform notes
|
|
2264
|
+
* @param {string[]} options.tags - Grouping tags
|
|
2265
|
+
* @param {object} options.fields - Flexible CRM-like fields (key/value)
|
|
2266
|
+
* @param {string} options.trust - Trust level (trusted, verified, unknown)
|
|
2267
|
+
*/
|
|
2268
|
+
addContact(inviteUrl, options = {}) {
|
|
2269
|
+
const match = String(inviteUrl <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>.match(/^a2a:\/\/([^/]+)\/(.+)$/);
|
|
2270
|
+
if (!match) {
|
|
2271
|
+
throw new Error(`Invalid invite URL: ${inviteUrl}. Expected format: a2a://host/token`);
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
const [, host, token] = match;
|
|
2275
|
+
const agentName = options.name <span class="branch-0 cbranch-no" title="branch not covered" >|| host;</span>
|
|
2276
|
+
const rawMine = options.is_mine !== undefined ? options.is_mine : options.isMine;
|
|
2277
|
+
const isMine = (() => {
|
|
2278
|
+
if (rawMine === null || rawMine === undefined) return false;
|
|
2279
|
+
if (typeof rawMine === 'boolean') return rawMine;
|
|
2280
|
+
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" > if (typeof rawMine === 'string') {</span></span>
|
|
2281
|
+
<span class="cstat-no" title="statement not covered" > const s = rawMine.trim().toLowerCase();</span>
|
|
2282
|
+
<span class="cstat-no" title="statement not covered" > if (['true', '1', 'yes', 'y', 'on'].includes(s)) return true;</span>
|
|
2283
|
+
<span class="cstat-no" title="statement not covered" > if (['false', '0', 'no', 'n', 'off', ''].includes(s)) return false;</span>
|
|
2284
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2285
|
+
<span class="cstat-no" title="statement not covered" > return Boolean(rawMine);</span>
|
|
2286
|
+
})();
|
|
2287
|
+
|
|
2288
|
+
const db = this._load();
|
|
2289
|
+
|
|
2290
|
+
// Check for duplicate by host + token hash
|
|
2291
|
+
const tokenHash = TokenStore.hashToken(token);
|
|
2292
|
+
const existing = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(r => r.host === host && r.token_hash === tokenHash);
|
|
2293
|
+
if (existing) {
|
|
2294
|
+
return { success: false, error: 'duplicate', existing };
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// Encrypt token for storage (simple XOR with derived key - not production-grade but better than plaintext).
|
|
2298
|
+
// Keep using the legacy key suffix so older "remotes" records remain decryptable.
|
|
2299
|
+
const encryptionKey = crypto.createHash('sha256').update(this.dbPath + TokenStore.LEGACY_REMOTE_KEY_SUFFIX).digest();
|
|
2300
|
+
const tokenBuffer = Buffer.from(token, 'utf8');
|
|
2301
|
+
const encrypted = Buffer.alloc(tokenBuffer.length);
|
|
2302
|
+
for (let i = 0; i < tokenBuffer.length; i++) {
|
|
2303
|
+
encrypted[i] = tokenBuffer[i] ^ encryptionKey[i % encryptionKey.length];
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
const contact = {
|
|
2307
|
+
id: crypto.randomBytes(8).toString('hex'),
|
|
2308
|
+
name: agentName,
|
|
2309
|
+
owner: options.owner || null,
|
|
2310
|
+
is_mine: isMine,
|
|
2311
|
+
host,
|
|
2312
|
+
token_hash: tokenHash,
|
|
2313
|
+
token_enc: encrypted.toString('base64'),
|
|
2314
|
+
server_name: options.server_name || options.serverName || null,
|
|
2315
|
+
notes: options.notes || null,
|
|
2316
|
+
tags: Array.isArray(options.tags) ? options.tags : [],
|
|
2317
|
+
fields: sanitizeCustomFields(options.fields || options.custom_fields || options.customFields),
|
|
2318
|
+
linked_token_id: options.linkedTokenId || options.linked_token_id || null, // Token you gave them
|
|
2319
|
+
public_key: options.public_key || options.publicKey || null, // A2A-52: Ed25519 public key (base64 DER)
|
|
2320
|
+
status: 'unknown',
|
|
2321
|
+
last_seen: null,
|
|
2322
|
+
added_at: new Date().toISOString(),
|
|
2323
|
+
updated_at: null
|
|
2324
|
+
};
|
|
2325
|
+
|
|
2326
|
+
db.contacts = db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [];</span>
|
|
2327
|
+
db.contacts.push(contact);
|
|
2328
|
+
this._save(db);
|
|
2329
|
+
|
|
2330
|
+
return { success: true, contact: { ...contact, token: undefined, token_enc: undefined } };
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
// Legacy wrapper.
|
|
2334
|
+
<span class="fstat-no" title="function not covered" > addRemote(inviteUrl, options = {}) {</span>
|
|
2335
|
+
<span class="cstat-no" title="statement not covered" > const result = this.addContact(inviteUrl, options);</span>
|
|
2336
|
+
<span class="cstat-no" title="statement not covered" > if (!result.success) return result;</span>
|
|
2337
|
+
<span class="cstat-no" title="statement not covered" > return { success: true, remote: result.contact };</span>
|
|
2338
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2339
|
+
|
|
2340
|
+
/**
|
|
2341
|
+
* Decrypt a contact token
|
|
2342
|
+
*/
|
|
2343
|
+
_decryptContactToken(contact) {
|
|
2344
|
+
if (!contact.token_enc) return null;
|
|
2345
|
+
|
|
2346
|
+
let encrypted;
|
|
2347
|
+
try {
|
|
2348
|
+
encrypted = Buffer.from(contact.token_enc, 'base64');
|
|
2349
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
2350
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
2351
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2352
|
+
|
|
2353
|
+
// Try legacy key first, then the newer "contact-key" suffix (in case we ever wrote it).
|
|
2354
|
+
const suffixes = [
|
|
2355
|
+
TokenStore.LEGACY_REMOTE_KEY_SUFFIX,
|
|
2356
|
+
TokenStore.CONTACT_KEY_SUFFIX
|
|
2357
|
+
].filter(Boolean);
|
|
2358
|
+
|
|
2359
|
+
for (const suffix of [...new Set(suffixes)]) {
|
|
2360
|
+
const encryptionKey = crypto.createHash('sha256').update(this.dbPath + suffix).digest();
|
|
2361
|
+
const decrypted = Buffer.alloc(encrypted.length);
|
|
2362
|
+
for (let i = 0; i < encrypted.length; i++) {
|
|
2363
|
+
decrypted[i] = encrypted[i] ^ encryptionKey[i % encryptionKey.length];
|
|
2364
|
+
}
|
|
2365
|
+
const token = decrypted.toString('utf8');
|
|
2366
|
+
if (/^fed_[A-Za-z0-9_-]{10,}$/.test(token)) {
|
|
2367
|
+
return token;
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
return null;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
/**
|
|
2375
|
+
* List contacts (optionally with linked token info / secrets)
|
|
2376
|
+
*/
|
|
2377
|
+
listContacts(options = {}) {
|
|
2378
|
+
const includeLinkedToken = options.includeLinkedToken !== false;
|
|
2379
|
+
const includeSecrets = options.includeSecrets === true;
|
|
2380
|
+
const db = this._load();
|
|
2381
|
+
|
|
2382
|
+
const contacts = Array.isArray(db.contacts) ? db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >: [];</span>
|
|
2383
|
+
return contacts.map(row => {
|
|
2384
|
+
const base = { ...row };
|
|
2385
|
+
if (!includeSecrets) {
|
|
2386
|
+
base.token_hash = undefined;
|
|
2387
|
+
base.token_enc = undefined;
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
if (includeLinkedToken && base.linked_token_id) {
|
|
2391
|
+
const token = (db.tokens <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(t => t.id === base.linked_token_id);
|
|
2392
|
+
if (token) {
|
|
2393
|
+
base.linked_token = token;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
return base;
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
// Legacy wrapper.
|
|
2402
|
+
<span class="fstat-no" title="function not covered" > listRemotes(options = {}) {</span>
|
|
2403
|
+
<span class="cstat-no" title="statement not covered" > return this.listContacts(options);</span>
|
|
2404
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2405
|
+
|
|
2406
|
+
/**
|
|
2407
|
+
* Link a token to a contact
|
|
2408
|
+
*/
|
|
2409
|
+
linkTokenToContact(contactNameOrId, tokenId) {
|
|
2410
|
+
const db = this._load();
|
|
2411
|
+
const remote = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(r =>
|
|
2412
|
+
r.name === contactNameOrId <span class="branch-0 cbranch-no" title="branch not covered" >|| r.id === contactNameOrId</span>
|
|
2413
|
+
);
|
|
2414
|
+
const token = db.tokens.find(t =>
|
|
2415
|
+
t.id === tokenId <span class="branch-0 cbranch-no" title="branch not covered" >|| t.id.startsWith(tokenId)</span>
|
|
2416
|
+
);
|
|
2417
|
+
|
|
2418
|
+
if (!remote) <span class="branch-0 cbranch-no" title="branch not covered" >return { success: false, error: 'contact_not_found' };</span>
|
|
2419
|
+
if (!token) <span class="branch-0 cbranch-no" title="branch not covered" >return { success: false, error: 'token_not_found' };</span>
|
|
2420
|
+
|
|
2421
|
+
remote.linked_token_id = token.id;
|
|
2422
|
+
this._save(db);
|
|
2423
|
+
return { success: true, contact: remote, remote, token };
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
/**
|
|
2427
|
+
* Get a contact by name/host/id (with decrypted token)
|
|
2428
|
+
*/
|
|
2429
|
+
getContact(nameOrHost) {
|
|
2430
|
+
const db = this._load();
|
|
2431
|
+
const remote = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(r =>
|
|
2432
|
+
r.name === nameOrHost ||
|
|
2433
|
+
r.host === nameOrHost ||
|
|
2434
|
+
r.id === nameOrHost
|
|
2435
|
+
);
|
|
2436
|
+
if (!remote) return null;
|
|
2437
|
+
|
|
2438
|
+
// Return with decrypted token
|
|
2439
|
+
return {
|
|
2440
|
+
...remote,
|
|
2441
|
+
token: this._decryptContactToken(remote),
|
|
2442
|
+
token_enc: undefined
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
/**
|
|
2447
|
+
* Legacy wrapper.
|
|
2448
|
+
*/
|
|
2449
|
+
<span class="fstat-no" title="function not covered" > getRemote(nameOrHost) {</span>
|
|
2450
|
+
<span class="cstat-no" title="statement not covered" > return this.getContact(nameOrHost);</span>
|
|
2451
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2452
|
+
|
|
2453
|
+
/**
|
|
2454
|
+
* Update a contact's metadata
|
|
2455
|
+
*/
|
|
2456
|
+
updateContact(nameOrHost, updates) {
|
|
2457
|
+
const db = this._load();
|
|
2458
|
+
const remote = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(r =>
|
|
2459
|
+
r.name === nameOrHost ||
|
|
2460
|
+
r.host === nameOrHost ||
|
|
2461
|
+
r.id === nameOrHost
|
|
2462
|
+
);
|
|
2463
|
+
|
|
2464
|
+
if (!remote) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2465
|
+
<span class="cstat-no" title="statement not covered" > return { success: false, error: 'not_found' };</span>
|
|
2466
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2467
|
+
|
|
2468
|
+
// Only allow updating specific fields
|
|
2469
|
+
// A2A-52: 'public_key' added for Ed25519 identity verification (TOFU pinning)
|
|
2470
|
+
const allowed = ['name', 'owner', 'is_mine', 'notes', 'tags', 'linked_token_id', 'server_name', 'fields', 'public_key'];
|
|
2471
|
+
for (const key of allowed) {
|
|
2472
|
+
if (updates[key] !== undefined) {
|
|
2473
|
+
if (key === 'fields') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2474
|
+
<span class="cstat-no" title="statement not covered" > if (updates.fields === null) {</span>
|
|
2475
|
+
<span class="cstat-no" title="statement not covered" > remote.fields = {};</span>
|
|
2476
|
+
<span class="cstat-no" title="statement not covered" > } else {</span>
|
|
2477
|
+
<span class="cstat-no" title="statement not covered" > remote.fields = {</span>
|
|
2478
|
+
<span class="cstat-no" title="statement not covered" > ...(remote.fields && typeof remote.fields === 'object' ? remote.fields : {}),</span>
|
|
2479
|
+
<span class="cstat-no" title="statement not covered" > ...sanitizeCustomFields(updates.fields)</span>
|
|
2480
|
+
<span class="cstat-no" title="statement not covered" > };</span>
|
|
2481
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2482
|
+
} else if (key === 'is_mine') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2483
|
+
<span class="cstat-no" title="statement not covered" > const raw = updates.is_mine;</span>
|
|
2484
|
+
<span class="cstat-no" title="statement not covered" > if (raw === null) {</span>
|
|
2485
|
+
<span class="cstat-no" title="statement not covered" > remote.is_mine = false;</span>
|
|
2486
|
+
<span class="cstat-no" title="statement not covered" > } else if (typeof raw === 'boolean') {</span>
|
|
2487
|
+
<span class="cstat-no" title="statement not covered" > remote.is_mine = raw;</span>
|
|
2488
|
+
<span class="cstat-no" title="statement not covered" > } else if (typeof raw === 'string') {</span>
|
|
2489
|
+
<span class="cstat-no" title="statement not covered" > const s = raw.trim().toLowerCase();</span>
|
|
2490
|
+
<span class="cstat-no" title="statement not covered" > if (['true', '1', 'yes', 'y', 'on'].includes(s)) remote.is_mine = true;</span>
|
|
2491
|
+
<span class="cstat-no" title="statement not covered" > else if (['false', '0', 'no', 'n', 'off', ''].includes(s)) remote.is_mine = false;</span>
|
|
2492
|
+
<span class="cstat-no" title="statement not covered" > else remote.is_mine = Boolean(raw);</span>
|
|
2493
|
+
<span class="cstat-no" title="statement not covered" > } else {</span>
|
|
2494
|
+
<span class="cstat-no" title="statement not covered" > remote.is_mine = Boolean(raw);</span>
|
|
2495
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2496
|
+
} else {
|
|
2497
|
+
remote[key] = updates[key];
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
remote.updated_at = new Date().toISOString();
|
|
2502
|
+
|
|
2503
|
+
this._save(db);
|
|
2504
|
+
return { success: true, contact: remote, remote };
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
/**
|
|
2508
|
+
* Legacy wrapper.
|
|
2509
|
+
*/
|
|
2510
|
+
<span class="fstat-no" title="function not covered" > updateRemote(nameOrHost, updates) {</span>
|
|
2511
|
+
<span class="cstat-no" title="statement not covered" > return this.updateContact(nameOrHost, updates);</span>
|
|
2512
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2513
|
+
|
|
2514
|
+
/**
|
|
2515
|
+
* Update contact status after ping/call
|
|
2516
|
+
*/
|
|
2517
|
+
updateContactStatus(nameOrHost, status, error = null) {
|
|
2518
|
+
const db = this._load();
|
|
2519
|
+
const remote = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(r =>
|
|
2520
|
+
r.name === nameOrHost ||
|
|
2521
|
+
r.host === nameOrHost ||
|
|
2522
|
+
r.id === nameOrHost
|
|
2523
|
+
);
|
|
2524
|
+
|
|
2525
|
+
if (!remote) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
|
|
2526
|
+
|
|
2527
|
+
remote.status = status; // 'online', 'offline', 'error'
|
|
2528
|
+
remote.last_seen = status === 'online' ? new Date().toISOString() : remote.last_seen;
|
|
2529
|
+
remote.last_error = error;
|
|
2530
|
+
remote.last_check = new Date().toISOString();
|
|
2531
|
+
|
|
2532
|
+
this._save(db);
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
/**
|
|
2536
|
+
* Legacy wrapper.
|
|
2537
|
+
*/
|
|
2538
|
+
<span class="fstat-no" title="function not covered" > updateRemoteStatus(nameOrHost, status, error = null) {</span>
|
|
2539
|
+
<span class="cstat-no" title="statement not covered" > return this.updateContactStatus(nameOrHost, status, error);</span>
|
|
2540
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2541
|
+
|
|
2542
|
+
/**
|
|
2543
|
+
* Remove a contact
|
|
2544
|
+
*/
|
|
2545
|
+
removeContact(nameOrHost) {
|
|
2546
|
+
const db = this._load();
|
|
2547
|
+
const idx = (db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.findIndex(r =>
|
|
2548
|
+
r.name === nameOrHost ||
|
|
2549
|
+
r.host === nameOrHost ||
|
|
2550
|
+
r.id === nameOrHost
|
|
2551
|
+
);
|
|
2552
|
+
|
|
2553
|
+
if (idx === -1) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2554
|
+
<span class="cstat-no" title="statement not covered" > return { success: false, error: 'not_found' };</span>
|
|
2555
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2556
|
+
|
|
2557
|
+
const [removed] = db.contacts.splice(idx, 1);
|
|
2558
|
+
this._save(db);
|
|
2559
|
+
return { success: true, contact: removed, remote: removed };
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
// Legacy wrapper.
|
|
2563
|
+
<span class="fstat-no" title="function not covered" > removeRemote(nameOrHost) {</span>
|
|
2564
|
+
<span class="cstat-no" title="statement not covered" > return this.removeContact(nameOrHost);</span>
|
|
2565
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* Ensure an inbound caller is present in contacts.
|
|
2569
|
+
*
|
|
2570
|
+
* Inbound callers authenticate with a token we issued; we usually don't
|
|
2571
|
+
* have their endpoint URL, so these records are "placeholders" with:
|
|
2572
|
+
* - host: "inbound"
|
|
2573
|
+
* - no token stored
|
|
2574
|
+
* - linked_token_id: token id used to call us (tok_...)
|
|
2575
|
+
*
|
|
2576
|
+
* This allows mapping call history (SQLite contact_id=tok_...) to a contact
|
|
2577
|
+
* row in the dashboard via linked_token_id.
|
|
2578
|
+
*/
|
|
2579
|
+
ensureInboundContact(caller, tokenId) {
|
|
2580
|
+
if (!caller || !caller.name) {
|
|
2581
|
+
return null;
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2584
|
+
const name = String(caller.name <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>.trim().slice(0, 120);
|
|
2585
|
+
const owner = caller.owner ? String(caller.owner).trim().slice(0, 120) : null;
|
|
2586
|
+
|
|
2587
|
+
const db = this._load();
|
|
2588
|
+
db.contacts = db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [];</span>
|
|
2589
|
+
|
|
2590
|
+
// Prefer stable linking by the token used for inbound auth.
|
|
2591
|
+
let remote = tokenId
|
|
2592
|
+
? db.contacts.find(r => r.linked_token_id === tokenId)
|
|
2593
|
+
<span class="branch-0 cbranch-no" title="branch not covered" > : null;</span>
|
|
2594
|
+
|
|
2595
|
+
// Fallback match by agent name/owner (less reliable, but helpful).
|
|
2596
|
+
if (!remote) {
|
|
2597
|
+
remote = db.contacts.find(r => r.name === name || (owner && r.owner === owner));
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
if (remote) {
|
|
2601
|
+
remote.name = remote.name <span class="branch-0 cbranch-no" title="branch not covered" >|| name;</span>
|
|
2602
|
+
if (owner && !remote.owner) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2603
|
+
<span class="cstat-no" title="statement not covered" > remote.owner = owner;</span>
|
|
2604
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2605
|
+
if (remote.is_mine === undefined) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2606
|
+
<span class="cstat-no" title="statement not covered" > remote.is_mine = false;</span>
|
|
2607
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2608
|
+
if (tokenId && !remote.linked_token_id) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2609
|
+
<span class="cstat-no" title="statement not covered" > remote.linked_token_id = tokenId;</span>
|
|
2610
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2611
|
+
remote.host = remote.host <span class="branch-0 cbranch-no" title="branch not covered" >|| 'inbound';</span>
|
|
2612
|
+
remote.tags = Array.isArray(remote.tags) ? remote.tags <span class="branch-0 cbranch-no" title="branch not covered" >: [];</span>
|
|
2613
|
+
if (!remote.tags.includes('inbound')) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
2614
|
+
<span class="cstat-no" title="statement not covered" > remote.tags.push('inbound');</span>
|
|
2615
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2616
|
+
remote.fields = remote.fields && typeof remote.fields === 'object' ? remote.fields <span class="branch-0 cbranch-no" title="branch not covered" >: {};</span>
|
|
2617
|
+
remote.server_name = remote.server_name || null;
|
|
2618
|
+
remote.status = remote.status <span class="branch-0 cbranch-no" title="branch not covered" >|| 'unknown';</span>
|
|
2619
|
+
remote.updated_at = new Date().toISOString();
|
|
2620
|
+
this._save(db);
|
|
2621
|
+
return remote;
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
const contact = {
|
|
2625
|
+
id: crypto.randomBytes(8).toString('hex'),
|
|
2626
|
+
name,
|
|
2627
|
+
owner,
|
|
2628
|
+
is_mine: false,
|
|
2629
|
+
host: 'inbound',
|
|
2630
|
+
token_hash: null,
|
|
2631
|
+
token_enc: null,
|
|
2632
|
+
server_name: null,
|
|
2633
|
+
notes: tokenId ? `Inbound caller via token ${tokenId}` <span class="branch-0 cbranch-no" title="branch not covered" >: 'Inbound caller',</span>
|
|
2634
|
+
tags: ['inbound'],
|
|
2635
|
+
fields: {},
|
|
2636
|
+
linked_token_id: tokenId <span class="branch-0 cbranch-no" title="branch not covered" >|| null,</span>
|
|
2637
|
+
public_key: null, // A2A-52: populated via TOFU on first verified call
|
|
2638
|
+
status: 'unknown',
|
|
2639
|
+
last_seen: null,
|
|
2640
|
+
added_at: new Date().toISOString(),
|
|
2641
|
+
updated_at: null
|
|
2642
|
+
};
|
|
2643
|
+
|
|
2644
|
+
db.contacts.push(contact);
|
|
2645
|
+
this._save(db);
|
|
2646
|
+
return contact;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
TokenStore.VALID_TIERS = ['public', 'friends', 'family', 'custom'];
|
|
2651
|
+
TokenStore.LEGACY_REMOTE_KEY_SUFFIX = 'remote-key';
|
|
2652
|
+
TokenStore.CONTACT_KEY_SUFFIX = 'contact-key';
|
|
2653
|
+
|
|
2654
|
+
// Default capabilities per tier label (used when config has none)
|
|
2655
|
+
TokenStore.DEFAULT_CAPABILITIES = {
|
|
2656
|
+
'public': ['context-read'],
|
|
2657
|
+
'friends': ['context-read', 'calendar.read', 'email.read', 'search'],
|
|
2658
|
+
'family': ['context-read', 'calendar', 'email', 'search', 'tools', 'memory'],
|
|
2659
|
+
'custom': ['context-read']
|
|
2660
|
+
};
|
|
2661
|
+
|
|
2662
|
+
TokenStore.DEFAULT_ALLOWED_TOOLS = {
|
|
2663
|
+
'public': ['Read', 'Grep', 'Glob'],
|
|
2664
|
+
'friends': ['Bash(readonly)', 'Read', 'Grep', 'Glob', 'WebSearch', 'WebFetch'],
|
|
2665
|
+
'family': ['Bash', 'Read', 'Grep', 'Glob', 'WebSearch', 'WebFetch'],
|
|
2666
|
+
'custom': ['Read', 'Grep', 'Glob']
|
|
2667
|
+
};
|
|
2668
|
+
|
|
2669
|
+
module.exports = { TokenStore };
|
|
2670
|
+
</pre></td></tr></table></pre>
|
|
2671
|
+
|
|
2672
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
2673
|
+
</div><!-- /wrapper -->
|
|
2674
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
2675
|
+
Code coverage generated by
|
|
2676
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2677
|
+
at 2026-03-03T22:25:10.857Z
|
|
2678
|
+
</div>
|
|
2679
|
+
<script src="../../prettify.js"></script>
|
|
2680
|
+
<script>
|
|
2681
|
+
window.onload = function () {
|
|
2682
|
+
prettyPrint();
|
|
2683
|
+
};
|
|
2684
|
+
</script>
|
|
2685
|
+
<script src="../../sorter.js"></script>
|
|
2686
|
+
<script src="../../block-navigation.js"></script>
|
|
2687
|
+
</body>
|
|
2688
|
+
</html>
|
|
2689
|
+
|