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.
Files changed (118) hide show
  1. package/.a2a-manifest.json +2 -2
  2. package/.c8rc.json +16 -0
  3. package/.node-version +1 -0
  4. package/.serena/project.yml +126 -0
  5. package/ARCHITECTURE.md +11 -0
  6. package/CONVENTIONS.md +9 -0
  7. package/coverage/base.css +224 -0
  8. package/coverage/block-navigation.js +87 -0
  9. package/coverage/favicon.png +0 -0
  10. package/coverage/index.html +146 -0
  11. package/coverage/prettify.css +1 -0
  12. package/coverage/prettify.js +2 -0
  13. package/coverage/sort-arrow-sprite.png +0 -0
  14. package/coverage/sorter.js +210 -0
  15. package/coverage/src/index.html +131 -0
  16. package/coverage/src/index.js.html +313 -0
  17. package/coverage/src/lib/agent-card.js.html +418 -0
  18. package/coverage/src/lib/call-monitor.js.html +700 -0
  19. package/coverage/src/lib/callbook.js.html +1183 -0
  20. package/coverage/src/lib/claude-subagent.js.html +2173 -0
  21. package/coverage/src/lib/client.js.html +2134 -0
  22. package/coverage/src/lib/config.js.html +1525 -0
  23. package/coverage/src/lib/conversation-driver.js.html +1909 -0
  24. package/coverage/src/lib/conversations.js.html +2575 -0
  25. package/coverage/src/lib/crypto.js.html +424 -0
  26. package/coverage/src/lib/dashboard-events.js.html +724 -0
  27. package/coverage/src/lib/disclosure.js.html +2461 -0
  28. package/coverage/src/lib/external-ip.js.html +718 -0
  29. package/coverage/src/lib/index.html +506 -0
  30. package/coverage/src/lib/invite-host.js.html +754 -0
  31. package/coverage/src/lib/local-request.js.html +292 -0
  32. package/coverage/src/lib/logger.js.html +2116 -0
  33. package/coverage/src/lib/openclaw-integration.js.html +1102 -0
  34. package/coverage/src/lib/pid-file.js.html +394 -0
  35. package/coverage/src/lib/port-scanner.js.html +334 -0
  36. package/coverage/src/lib/prompt-template.js.html +1150 -0
  37. package/coverage/src/lib/runtime-adapter.js.html +2188 -0
  38. package/coverage/src/lib/summarizer.js.html +553 -0
  39. package/coverage/src/lib/summary-formatter.js.html +589 -0
  40. package/coverage/src/lib/summary-prompt.js.html +694 -0
  41. package/coverage/src/lib/tokens.js.html +2689 -0
  42. package/coverage/src/lib/turn-timeout.js.html +241 -0
  43. package/coverage/src/lib/update-checker.js.html +364 -0
  44. package/coverage/src/lib/update-manager.js.html +1024 -0
  45. package/coverage/src/routes/a2a.js.html +3724 -0
  46. package/coverage/src/routes/callbook.js.html +511 -0
  47. package/coverage/src/routes/dashboard.js.html +4819 -0
  48. package/coverage/src/routes/index.html +146 -0
  49. package/coverage/src/server.js.html +3622 -0
  50. package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
  51. package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
  52. package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
  53. package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
  54. package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
  55. package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
  56. package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
  57. package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
  58. package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
  59. package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
  60. package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
  61. package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
  62. package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
  63. package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
  64. package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
  65. package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
  66. package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
  67. package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
  68. package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
  69. package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
  70. package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
  71. package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
  72. package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
  73. package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
  74. package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
  75. package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
  76. package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
  77. package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
  78. package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
  79. package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
  80. package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
  81. package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
  82. package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
  83. package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
  84. package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
  85. package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
  86. package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
  87. package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
  88. package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
  89. package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
  90. package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
  91. package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
  92. package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
  93. package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
  94. package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
  95. package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
  96. package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
  97. package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
  98. package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
  99. package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
  100. package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
  101. package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
  102. package/docs/signing-setup.md +49 -0
  103. package/native/macos/certs/appldevcert.cer +0 -0
  104. package/native/macos/src-tauri/binaries/.gitkeep +0 -0
  105. package/native/macos/src-tauri/capabilities/default.json +11 -1
  106. package/native/macos/src-tauri/entitlements.plist +14 -0
  107. package/native/macos/src-tauri/src/discovery.rs +14 -3
  108. package/native/macos/src-tauri/src/health.rs +4 -0
  109. package/native/macos/src-tauri/src/lib.rs +52 -11
  110. package/native/macos/src-tauri/src/server.rs +262 -26
  111. package/native/macos/src-tauri/tauri.conf.json +13 -4
  112. package/package.json +7 -2
  113. package/pkg.config.json +14 -0
  114. package/scripts/build-standalone.sh +106 -0
  115. package/scripts/smoke-test-standalone.sh +101 -0
  116. package/scripts/sync-version.sh +28 -0
  117. package/scripts/verify-app-bundle.sh +34 -0
  118. 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">&nbsp;</span>
966
+ <span class="cline-any cline-no">&nbsp;</span>
967
+ <span class="cline-any cline-no">&nbsp;</span>
968
+ <span class="cline-any cline-no">&nbsp;</span>
969
+ <span class="cline-any cline-no">&nbsp;</span>
970
+ <span class="cline-any cline-no">&nbsp;</span>
971
+ <span class="cline-any cline-no">&nbsp;</span>
972
+ <span class="cline-any cline-no">&nbsp;</span>
973
+ <span class="cline-any cline-no">&nbsp;</span>
974
+ <span class="cline-any cline-no">&nbsp;</span>
975
+ <span class="cline-any cline-no">&nbsp;</span>
976
+ <span class="cline-any cline-no">&nbsp;</span>
977
+ <span class="cline-any cline-no">&nbsp;</span>
978
+ <span class="cline-any cline-no">&nbsp;</span>
979
+ <span class="cline-any cline-no">&nbsp;</span>
980
+ <span class="cline-any cline-no">&nbsp;</span>
981
+ <span class="cline-any cline-no">&nbsp;</span>
982
+ <span class="cline-any cline-no">&nbsp;</span>
983
+ <span class="cline-any cline-no">&nbsp;</span>
984
+ <span class="cline-any cline-no">&nbsp;</span>
985
+ <span class="cline-any cline-no">&nbsp;</span>
986
+ <span class="cline-any cline-no">&nbsp;</span>
987
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1007
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1023
+ <span class="cline-any cline-no">&nbsp;</span>
1024
+ <span class="cline-any cline-no">&nbsp;</span>
1025
+ <span class="cline-any cline-no">&nbsp;</span>
1026
+ <span class="cline-any cline-no">&nbsp;</span>
1027
+ <span class="cline-any cline-no">&nbsp;</span>
1028
+ <span class="cline-any cline-no">&nbsp;</span>
1029
+ <span class="cline-any cline-no">&nbsp;</span>
1030
+ <span class="cline-any cline-no">&nbsp;</span>
1031
+ <span class="cline-any cline-no">&nbsp;</span>
1032
+ <span class="cline-any cline-no">&nbsp;</span>
1033
+ <span class="cline-any cline-no">&nbsp;</span>
1034
+ <span class="cline-any cline-no">&nbsp;</span>
1035
+ <span class="cline-any cline-no">&nbsp;</span>
1036
+ <span class="cline-any cline-no">&nbsp;</span>
1037
+ <span class="cline-any cline-no">&nbsp;</span>
1038
+ <span class="cline-any cline-no">&nbsp;</span>
1039
+ <span class="cline-any cline-no">&nbsp;</span>
1040
+ <span class="cline-any cline-no">&nbsp;</span>
1041
+ <span class="cline-any cline-no">&nbsp;</span>
1042
+ <span class="cline-any cline-no">&nbsp;</span>
1043
+ <span class="cline-any cline-no">&nbsp;</span>
1044
+ <span class="cline-any cline-no">&nbsp;</span>
1045
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1084
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1166
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1274
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1381
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1413
+ <span class="cline-any cline-no">&nbsp;</span>
1414
+ <span class="cline-any cline-no">&nbsp;</span>
1415
+ <span class="cline-any cline-no">&nbsp;</span>
1416
+ <span class="cline-any cline-no">&nbsp;</span>
1417
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1468
+ <span class="cline-any cline-no">&nbsp;</span>
1469
+ <span class="cline-any cline-no">&nbsp;</span>
1470
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1483
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1536
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1583
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1598
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1607
+ <span class="cline-any cline-no">&nbsp;</span>
1608
+ <span class="cline-any cline-no">&nbsp;</span>
1609
+ <span class="cline-any cline-no">&nbsp;</span>
1610
+ <span class="cline-any cline-no">&nbsp;</span>
1611
+ <span class="cline-any cline-no">&nbsp;</span>
1612
+ <span class="cline-any cline-no">&nbsp;</span>
1613
+ <span class="cline-any cline-no">&nbsp;</span>
1614
+ <span class="cline-any cline-yes">5x</span>
1615
+ <span class="cline-any cline-no">&nbsp;</span>
1616
+ <span class="cline-any cline-no">&nbsp;</span>
1617
+ <span class="cline-any cline-no">&nbsp;</span>
1618
+ <span class="cline-any cline-no">&nbsp;</span>
1619
+ <span class="cline-any cline-no">&nbsp;</span>
1620
+ <span class="cline-any cline-no">&nbsp;</span>
1621
+ <span class="cline-any cline-no">&nbsp;</span>
1622
+ <span class="cline-any cline-no">&nbsp;</span>
1623
+ <span class="cline-any cline-no">&nbsp;</span>
1624
+ <span class="cline-any cline-no">&nbsp;</span>
1625
+ <span class="cline-any cline-no">&nbsp;</span>
1626
+ <span class="cline-any cline-no">&nbsp;</span>
1627
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1644
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1672
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1687
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1697
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1736
+ <span class="cline-any cline-no">&nbsp;</span>
1737
+ <span class="cline-any cline-yes">11x</span>
1738
+ <span class="cline-any cline-no">&nbsp;</span>
1739
+ <span class="cline-any cline-no">&nbsp;</span>
1740
+ <span class="cline-any cline-yes">11x</span>
1741
+ <span class="cline-any cline-no">&nbsp;</span>
1742
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span>
1747
+ <span class="cline-any cline-no">&nbsp;</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">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1803
+ * Token management for A2A
1804
+ */
1805
+ &nbsp;
1806
+ const fs = require('fs');
1807
+ const path = require('path');
1808
+ const crypto = require('crypto');
1809
+ const { createLogger } = require('./logger');
1810
+ &nbsp;
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
+ &nbsp;
1816
+ const DB_FILENAME = 'a2a.json';
1817
+ const logger = createLogger({ component: 'a2a.tokens' });
1818
+ &nbsp;
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
+ &nbsp;
1824
+ if (!fields || typeof fields !== 'object' || Array.isArray(fields)) {
1825
+ return {};
1826
+ }
1827
+ &nbsp;
1828
+ const cleaned = {};
1829
+ const keys = Object.keys(fields);
1830
+ let count = 0;
1831
+ &nbsp;
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 &gt;= 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
+ &nbsp;
1857
+ return cleaned;
1858
+ }
1859
+ &nbsp;
1860
+ function parsePositiveTimeoutMs(value) {
1861
+ const parsed = Number.parseInt(String(value ?? ''), 10);
1862
+ return Number.isFinite(parsed) &amp;&amp; parsed &gt; 0 ? parsed : null;
1863
+ }
1864
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
1878
+ _load() {
1879
+ if (fs.existsSync(this.dbPath)) {
1880
+ try {
1881
+ const parsed = JSON.parse(fs.readFileSync(this.dbPath, 'utf8'));
1882
+ const db = parsed &amp;&amp; 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
+ &nbsp;
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) =&gt; {</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 &amp;&amp; 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 &amp;&amp; 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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
1963
+ /**
1964
+ * Hash a token for storage
1965
+ */
1966
+ static hashToken(token) {
1967
+ return crypto.createHash('sha256').update(token).digest('hex');
1968
+ }
1969
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
2061
+ // Resolve capabilities: explicit &gt; config &gt; 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
+ &nbsp;
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
+ &nbsp;
2087
+ const db = this._load();
2088
+ db.tokens.push(record);
2089
+ this._save(db);
2090
+ &nbsp;
2091
+ return { token, record };
2092
+ }
2093
+ &nbsp;
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 =&gt; !t.revoked);
2100
+ }
2101
+ &nbsp;
2102
+ /**
2103
+ * Find a token by ID prefix
2104
+ */
2105
+ findById(idPrefix) {
2106
+ const db = this._load();
2107
+ return db.tokens.find(t =&gt; t.id === idPrefix || t.id.startsWith(idPrefix));
2108
+ }
2109
+ &nbsp;
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 =&gt; t.token_hash === tokenHash);
2117
+ &nbsp;
2118
+ if (!record) {
2119
+ return { valid: false, error: 'token_not_found' };
2120
+ }
2121
+ &nbsp;
2122
+ if (record.revoked) {
2123
+ return { valid: false, error: 'token_revoked' };
2124
+ }
2125
+ &nbsp;
2126
+ if (record.expires_at &amp;&amp; new Date(record.expires_at) &lt; new Date()) {
2127
+ return { valid: false, error: 'token_expired' };
2128
+ }
2129
+ &nbsp;
2130
+ if (record.max_calls &amp;&amp; record.calls_made &gt;= record.max_calls) {
2131
+ return { valid: false, error: 'max_calls_exceeded' };
2132
+ }
2133
+ &nbsp;
2134
+ // Increment call count
2135
+ record.calls_made++;
2136
+ record.last_used = new Date().toISOString();
2137
+ this._save(db);
2138
+ &nbsp;
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
+ &nbsp;
2144
+ // Resolve capabilities: stored &gt; 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
+ &nbsp;
2149
+ const timeoutMs = parsePositiveTimeoutMs(record.timeout_ms)
2150
+ || parsePositiveTimeoutMs(record.tier_settings?.timeout_ms)
2151
+ || parsePositiveTimeoutMs(record.tier_settings?.timeoutMs);
2152
+ &nbsp;
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
+ &nbsp;
2169
+ /**
2170
+ * Revoke a token by ID
2171
+ */
2172
+ revoke(idPrefix) {
2173
+ const db = this._load();
2174
+ const record = db.tokens.find(t =&gt; t.id === idPrefix || t.id.startsWith(idPrefix));
2175
+
2176
+ if (!record) {
2177
+ return { success: false, error: 'not_found' };
2178
+ }
2179
+ &nbsp;
2180
+ record.revoked = true;
2181
+ record.revoked_at = new Date().toISOString();
2182
+ this._save(db);
2183
+ &nbsp;
2184
+ return { success: true, record };
2185
+ }
2186
+ &nbsp;
2187
+ /**
2188
+ * A2A-65: Remove expired and old-revoked tokens from the store.
2189
+ *
2190
+ * - Tokens expired for &gt;1 hour are removed (grace period for in-flight calls)
2191
+ * - Tokens revoked &gt;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
+ &nbsp;
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
+ &nbsp;
2208
+ let removed_expired = 0;
2209
+ let removed_revoked = 0;
2210
+ &nbsp;
2211
+ const original = db.tokens.length;
2212
+ &nbsp;
2213
+ db.tokens = db.tokens.filter(token =&gt; {
2214
+ // Remove tokens expired for &gt; 1 hour
2215
+ if (token.expires_at) {
2216
+ const expiresAt = new Date(token.expires_at).getTime();
2217
+ if (expiresAt &lt; now - oneHourMs) {
2218
+ removed_expired++;
2219
+ return false;
2220
+ }
2221
+ }
2222
+ &nbsp;
2223
+ // Remove tokens revoked &gt; graceDays ago
2224
+ if (token.revoked &amp;&amp; token.revoked_at) {
2225
+ const revokedAt = new Date(token.revoked_at).getTime();
2226
+ if (revokedAt &lt; now - gracePeriodMs) {
2227
+ removed_revoked++;
2228
+ return false;
2229
+ }
2230
+ }
2231
+ &nbsp;
2232
+ return true;
2233
+ });
2234
+ &nbsp;
2235
+ // Only write if something changed
2236
+ if (db.tokens.length &lt; original) {
2237
+ this._save(db);
2238
+ }
2239
+ &nbsp;
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
+ &nbsp;
2251
+ return { removed_expired, removed_revoked };
2252
+ }
2253
+ &nbsp;
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
+ &nbsp;
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 = (() =&gt; {
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
+ &nbsp;
2288
+ const db = this._load();
2289
+ &nbsp;
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 =&gt; r.host === host &amp;&amp; r.token_hash === tokenHash);
2293
+ if (existing) {
2294
+ return { success: false, error: 'duplicate', existing };
2295
+ }
2296
+ &nbsp;
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 &lt; tokenBuffer.length; i++) {
2303
+ encrypted[i] = tokenBuffer[i] ^ encryptionKey[i % encryptionKey.length];
2304
+ }
2305
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
2330
+ return { success: true, contact: { ...contact, token: undefined, token_enc: undefined } };
2331
+ }
2332
+ &nbsp;
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
+ &nbsp;
2340
+ /**
2341
+ * Decrypt a contact token
2342
+ */
2343
+ _decryptContactToken(contact) {
2344
+ if (!contact.token_enc) return null;
2345
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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 &lt; 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
+ &nbsp;
2371
+ return null;
2372
+ }
2373
+ &nbsp;
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
+ &nbsp;
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 =&gt; {
2384
+ const base = { ...row };
2385
+ if (!includeSecrets) {
2386
+ base.token_hash = undefined;
2387
+ base.token_enc = undefined;
2388
+ }
2389
+ &nbsp;
2390
+ if (includeLinkedToken &amp;&amp; base.linked_token_id) {
2391
+ const token = (db.tokens <span class="branch-0 cbranch-no" title="branch not covered" >|| [])</span>.find(t =&gt; t.id === base.linked_token_id);
2392
+ if (token) {
2393
+ base.linked_token = token;
2394
+ }
2395
+ }
2396
+ &nbsp;
2397
+ return base;
2398
+ });
2399
+ }
2400
+ &nbsp;
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
+ &nbsp;
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 =&gt;
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 =&gt;
2415
+ t.id === tokenId <span class="branch-0 cbranch-no" title="branch not covered" >|| t.id.startsWith(tokenId)</span>
2416
+ );
2417
+ &nbsp;
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
+ &nbsp;
2421
+ remote.linked_token_id = token.id;
2422
+ this._save(db);
2423
+ return { success: true, contact: remote, remote, token };
2424
+ }
2425
+ &nbsp;
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 =&gt;
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
+ &nbsp;
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
+ &nbsp;
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 =&gt;
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
+ &nbsp;
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 &amp;&amp; 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
+ &nbsp;
2503
+ this._save(db);
2504
+ return { success: true, contact: remote, remote };
2505
+ }
2506
+ &nbsp;
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
+ &nbsp;
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 =&gt;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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 =&gt;
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
+ &nbsp;
2557
+ const [removed] = db.contacts.splice(idx, 1);
2558
+ this._save(db);
2559
+ return { success: true, contact: removed, remote: removed };
2560
+ }
2561
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
2587
+ const db = this._load();
2588
+ db.contacts = db.contacts <span class="branch-0 cbranch-no" title="branch not covered" >|| [];</span>
2589
+ &nbsp;
2590
+ // Prefer stable linking by the token used for inbound auth.
2591
+ let remote = tokenId
2592
+ ? db.contacts.find(r =&gt; r.linked_token_id === tokenId)
2593
+ <span class="branch-0 cbranch-no" title="branch not covered" > : null;</span>
2594
+ &nbsp;
2595
+ // Fallback match by agent name/owner (less reliable, but helpful).
2596
+ if (!remote) {
2597
+ remote = db.contacts.find(r =&gt; r.name === name || (owner &amp;&amp; r.owner === owner));
2598
+ }
2599
+ &nbsp;
2600
+ if (remote) {
2601
+ remote.name = remote.name <span class="branch-0 cbranch-no" title="branch not covered" >|| name;</span>
2602
+ if (owner &amp;&amp; !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 &amp;&amp; !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 &amp;&amp; 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
+ &nbsp;
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
+ &nbsp;
2644
+ db.contacts.push(contact);
2645
+ this._save(db);
2646
+ return contact;
2647
+ }
2648
+ }
2649
+ &nbsp;
2650
+ TokenStore.VALID_TIERS = ['public', 'friends', 'family', 'custom'];
2651
+ TokenStore.LEGACY_REMOTE_KEY_SUFFIX = 'remote-key';
2652
+ TokenStore.CONTACT_KEY_SUFFIX = 'contact-key';
2653
+ &nbsp;
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
+ &nbsp;
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
+ &nbsp;
2669
+ module.exports = { TokenStore };
2670
+ &nbsp;</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
+