a2acalling 0.6.73 → 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 (134) 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 +40 -16
  6. package/CONVENTIONS.md +39 -6
  7. package/biome.json +27 -0
  8. package/coverage/base.css +224 -0
  9. package/coverage/block-navigation.js +87 -0
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +146 -0
  12. package/coverage/prettify.css +1 -0
  13. package/coverage/prettify.js +2 -0
  14. package/coverage/sort-arrow-sprite.png +0 -0
  15. package/coverage/sorter.js +210 -0
  16. package/coverage/src/index.html +131 -0
  17. package/coverage/src/index.js.html +313 -0
  18. package/coverage/src/lib/agent-card.js.html +418 -0
  19. package/coverage/src/lib/call-monitor.js.html +700 -0
  20. package/coverage/src/lib/callbook.js.html +1183 -0
  21. package/coverage/src/lib/claude-subagent.js.html +2173 -0
  22. package/coverage/src/lib/client.js.html +2134 -0
  23. package/coverage/src/lib/config.js.html +1525 -0
  24. package/coverage/src/lib/conversation-driver.js.html +1909 -0
  25. package/coverage/src/lib/conversations.js.html +2575 -0
  26. package/coverage/src/lib/crypto.js.html +424 -0
  27. package/coverage/src/lib/dashboard-events.js.html +724 -0
  28. package/coverage/src/lib/disclosure.js.html +2461 -0
  29. package/coverage/src/lib/external-ip.js.html +718 -0
  30. package/coverage/src/lib/index.html +506 -0
  31. package/coverage/src/lib/invite-host.js.html +754 -0
  32. package/coverage/src/lib/local-request.js.html +292 -0
  33. package/coverage/src/lib/logger.js.html +2116 -0
  34. package/coverage/src/lib/openclaw-integration.js.html +1102 -0
  35. package/coverage/src/lib/pid-file.js.html +394 -0
  36. package/coverage/src/lib/port-scanner.js.html +334 -0
  37. package/coverage/src/lib/prompt-template.js.html +1150 -0
  38. package/coverage/src/lib/runtime-adapter.js.html +2188 -0
  39. package/coverage/src/lib/summarizer.js.html +553 -0
  40. package/coverage/src/lib/summary-formatter.js.html +589 -0
  41. package/coverage/src/lib/summary-prompt.js.html +694 -0
  42. package/coverage/src/lib/tokens.js.html +2689 -0
  43. package/coverage/src/lib/turn-timeout.js.html +241 -0
  44. package/coverage/src/lib/update-checker.js.html +364 -0
  45. package/coverage/src/lib/update-manager.js.html +1024 -0
  46. package/coverage/src/routes/a2a.js.html +3724 -0
  47. package/coverage/src/routes/callbook.js.html +511 -0
  48. package/coverage/src/routes/dashboard.js.html +4819 -0
  49. package/coverage/src/routes/index.html +146 -0
  50. package/coverage/src/server.js.html +3622 -0
  51. package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
  52. package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
  53. package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
  54. package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
  55. package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
  56. package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
  57. package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
  58. package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
  59. package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
  60. package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
  61. package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
  62. package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
  63. package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
  64. package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
  65. package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
  66. package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
  67. package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
  68. package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
  69. package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
  70. package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
  71. package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
  72. package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
  73. package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
  74. package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
  75. package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
  76. package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
  77. package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
  78. package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
  79. package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
  80. package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
  81. package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
  82. package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
  83. package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
  84. package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
  85. package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
  86. package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
  87. package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
  88. package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
  89. package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
  90. package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
  91. package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
  92. package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
  93. package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
  94. package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
  95. package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
  96. package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
  97. package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
  98. package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
  99. package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
  100. package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
  101. package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
  102. package/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  103. package/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  104. package/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  105. package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
  106. package/docs/signing-setup.md +49 -0
  107. package/eslint.config.js +16 -0
  108. package/knip.json +17 -0
  109. package/native/macos/certs/appldevcert.cer +0 -0
  110. package/native/macos/src-tauri/binaries/.gitkeep +0 -0
  111. package/native/macos/src-tauri/capabilities/default.json +11 -1
  112. package/native/macos/src-tauri/entitlements.plist +14 -0
  113. package/native/macos/src-tauri/src/discovery.rs +14 -3
  114. package/native/macos/src-tauri/src/health.rs +4 -0
  115. package/native/macos/src-tauri/src/lib.rs +52 -11
  116. package/native/macos/src-tauri/src/server.rs +262 -26
  117. package/native/macos/src-tauri/tauri.conf.json +13 -4
  118. package/package.json +16 -2
  119. package/pkg.config.json +14 -0
  120. package/scripts/build-standalone.sh +106 -0
  121. package/scripts/install-openclaw.js +3 -5
  122. package/scripts/smoke-test-standalone.sh +101 -0
  123. package/scripts/sync-version.sh +28 -0
  124. package/scripts/verify-app-bundle.sh +34 -0
  125. package/src/lib/agent-card.js +111 -0
  126. package/src/lib/client.js +290 -49
  127. package/src/lib/conversations.js +2 -0
  128. package/src/lib/local-request.js +69 -0
  129. package/src/lib/logger.js +2 -0
  130. package/src/lib/runtime-adapter.js +41 -1
  131. package/src/routes/a2a.js +393 -66
  132. package/src/routes/dashboard.js +1 -27
  133. package/src/server.js +19 -0
  134. package/.maestro/inbox/release-workflow-spam.md +0 -25
@@ -0,0 +1,1102 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/lib/openclaw-integration.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> openclaw-integration.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">98.82% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>335/339</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">82.25% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>51/62</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>6/6</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">98.82% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>335/339</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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">20x</span>
406
+ <span class="cline-any cline-yes">20x</span>
407
+ <span class="cline-any cline-yes">20x</span>
408
+ <span class="cline-any cline-yes">20x</span>
409
+ <span class="cline-any cline-yes">20x</span>
410
+ <span class="cline-any cline-yes">20x</span>
411
+ <span class="cline-any cline-yes">20x</span>
412
+ <span class="cline-any cline-yes">20x</span>
413
+ <span class="cline-any cline-yes">20x</span>
414
+ <span class="cline-any cline-yes">20x</span>
415
+ <span class="cline-any cline-yes">20x</span>
416
+ <span class="cline-any cline-yes">20x</span>
417
+ <span class="cline-any cline-yes">20x</span>
418
+ <span class="cline-any cline-yes">20x</span>
419
+ <span class="cline-any cline-yes">20x</span>
420
+ <span class="cline-any cline-yes">20x</span>
421
+ <span class="cline-any cline-yes">20x</span>
422
+ <span class="cline-any cline-yes">20x</span>
423
+ <span class="cline-any cline-yes">20x</span>
424
+ <span class="cline-any cline-yes">17x</span>
425
+ <span class="cline-any cline-yes">17x</span>
426
+ <span class="cline-any cline-yes">17x</span>
427
+ <span class="cline-any cline-yes">17x</span>
428
+ <span class="cline-any cline-yes">17x</span>
429
+ <span class="cline-any cline-yes">17x</span>
430
+ <span class="cline-any cline-yes">17x</span>
431
+ <span class="cline-any cline-yes">17x</span>
432
+ <span class="cline-any cline-yes">17x</span>
433
+ <span class="cline-any cline-yes">17x</span>
434
+ <span class="cline-any cline-yes">17x</span>
435
+ <span class="cline-any cline-yes">1x</span>
436
+ <span class="cline-any cline-yes">1x</span>
437
+ <span class="cline-any cline-yes">17x</span>
438
+ <span class="cline-any cline-yes">17x</span>
439
+ <span class="cline-any cline-yes">17x</span>
440
+ <span class="cline-any cline-yes">17x</span>
441
+ <span class="cline-any cline-yes">4x</span>
442
+ <span class="cline-any cline-yes">4x</span>
443
+ <span class="cline-any cline-yes">4x</span>
444
+ <span class="cline-any cline-yes">3x</span>
445
+ <span class="cline-any cline-yes">3x</span>
446
+ <span class="cline-any cline-yes">1x</span>
447
+ <span class="cline-any cline-yes">1x</span>
448
+ <span class="cline-any cline-yes">1x</span>
449
+ <span class="cline-any cline-yes">1x</span>
450
+ <span class="cline-any cline-yes">1x</span>
451
+ <span class="cline-any cline-yes">1x</span>
452
+ <span class="cline-any cline-yes">3x</span>
453
+ <span class="cline-any cline-yes">4x</span>
454
+ <span class="cline-any cline-yes">4x</span>
455
+ <span class="cline-any cline-yes">4x</span>
456
+ <span class="cline-any cline-yes">1x</span>
457
+ <span class="cline-any cline-yes">1x</span>
458
+ <span class="cline-any cline-yes">1x</span>
459
+ <span class="cline-any cline-yes">1x</span>
460
+ <span class="cline-any cline-yes">1x</span>
461
+ <span class="cline-any cline-yes">1x</span>
462
+ <span class="cline-any cline-yes">4x</span>
463
+ <span class="cline-any cline-yes">17x</span>
464
+ <span class="cline-any cline-yes">17x</span>
465
+ <span class="cline-any cline-yes">17x</span>
466
+ <span class="cline-any cline-yes">17x</span>
467
+ <span class="cline-any cline-yes">1x</span>
468
+ <span class="cline-any cline-yes">1x</span>
469
+ <span class="cline-any cline-yes">1x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">1x</span>
472
+ <span class="cline-any cline-yes">1x</span>
473
+ <span class="cline-any cline-yes">1x</span>
474
+ <span class="cline-any cline-yes">3x</span>
475
+ <span class="cline-any cline-yes">3x</span>
476
+ <span class="cline-any cline-yes">1x</span>
477
+ <span class="cline-any cline-yes">1x</span>
478
+ <span class="cline-any cline-yes">17x</span>
479
+ <span class="cline-any cline-yes">17x</span>
480
+ <span class="cline-any cline-yes">17x</span>
481
+ <span class="cline-any cline-yes">17x</span>
482
+ <span class="cline-any cline-yes">1x</span>
483
+ <span class="cline-any cline-yes">1x</span>
484
+ <span class="cline-any cline-yes">1x</span>
485
+ <span class="cline-any cline-yes">17x</span>
486
+ <span class="cline-any cline-yes">17x</span>
487
+ <span class="cline-any cline-yes">17x</span>
488
+ <span class="cline-any cline-yes">20x</span>
489
+ <span class="cline-any cline-yes">20x</span>
490
+ <span class="cline-any cline-yes">20x</span>
491
+ <span class="cline-any cline-yes">20x</span>
492
+ <span class="cline-any cline-yes">20x</span>
493
+ <span class="cline-any cline-yes">20x</span>
494
+ <span class="cline-any cline-yes">20x</span>
495
+ <span class="cline-any cline-yes">20x</span>
496
+ <span class="cline-any cline-yes">14x</span>
497
+ <span class="cline-any cline-yes">14x</span>
498
+ <span class="cline-any cline-yes">14x</span>
499
+ <span class="cline-any cline-yes">15x</span>
500
+ <span class="cline-any cline-yes">15x</span>
501
+ <span class="cline-any cline-yes">14x</span>
502
+ <span class="cline-any cline-yes">14x</span>
503
+ <span class="cline-any cline-yes">14x</span>
504
+ <span class="cline-any cline-yes">14x</span>
505
+ <span class="cline-any cline-yes">14x</span>
506
+ <span class="cline-any cline-yes">14x</span>
507
+ <span class="cline-any cline-yes">14x</span>
508
+ <span class="cline-any cline-yes">14x</span>
509
+ <span class="cline-any cline-yes">14x</span>
510
+ <span class="cline-any cline-yes">14x</span>
511
+ <span class="cline-any cline-yes">14x</span>
512
+ <span class="cline-any cline-yes">14x</span>
513
+ <span class="cline-any cline-yes">14x</span>
514
+ <span class="cline-any cline-yes">14x</span>
515
+ <span class="cline-any cline-yes">14x</span>
516
+ <span class="cline-any cline-yes">14x</span>
517
+ <span class="cline-any cline-yes">14x</span>
518
+ <span class="cline-any cline-yes">14x</span>
519
+ <span class="cline-any cline-yes">14x</span>
520
+ <span class="cline-any cline-yes">20x</span>
521
+ <span class="cline-any cline-yes">20x</span>
522
+ <span class="cline-any cline-yes">20x</span>
523
+ <span class="cline-any cline-yes">20x</span>
524
+ <span class="cline-any cline-yes">20x</span>
525
+ <span class="cline-any cline-yes">5x</span>
526
+ <span class="cline-any cline-yes">5x</span>
527
+ <span class="cline-any cline-yes">5x</span>
528
+ <span class="cline-any cline-yes">5x</span>
529
+ <span class="cline-any cline-yes">5x</span>
530
+ <span class="cline-any cline-yes">5x</span>
531
+ <span class="cline-any cline-yes">5x</span>
532
+ <span class="cline-any cline-yes">5x</span>
533
+ <span class="cline-any cline-yes">5x</span>
534
+ <span class="cline-any cline-yes">5x</span>
535
+ <span class="cline-any cline-yes">5x</span>
536
+ <span class="cline-any cline-yes">5x</span>
537
+ <span class="cline-any cline-yes">5x</span>
538
+ <span class="cline-any cline-yes">5x</span>
539
+ <span class="cline-any cline-yes">5x</span>
540
+ <span class="cline-any cline-yes">5x</span>
541
+ <span class="cline-any cline-yes">5x</span>
542
+ <span class="cline-any cline-yes">5x</span>
543
+ <span class="cline-any cline-yes">5x</span>
544
+ <span class="cline-any cline-yes">5x</span>
545
+ <span class="cline-any cline-yes">5x</span>
546
+ <span class="cline-any cline-yes">5x</span>
547
+ <span class="cline-any cline-yes">3x</span>
548
+ <span class="cline-any cline-yes">3x</span>
549
+ <span class="cline-any cline-yes">1x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">1x</span>
552
+ <span class="cline-any cline-yes">1x</span>
553
+ <span class="cline-any cline-yes">1x</span>
554
+ <span class="cline-any cline-yes">1x</span>
555
+ <span class="cline-any cline-yes">1x</span>
556
+ <span class="cline-any cline-yes">1x</span>
557
+ <span class="cline-any cline-yes">1x</span>
558
+ <span class="cline-any cline-yes">1x</span>
559
+ <span class="cline-any cline-yes">1x</span>
560
+ <span class="cline-any cline-yes">1x</span>
561
+ <span class="cline-any cline-yes">1x</span>
562
+ <span class="cline-any cline-yes">1x</span>
563
+ <span class="cline-any cline-yes">1x</span>
564
+ <span class="cline-any cline-yes">1x</span>
565
+ <span class="cline-any cline-yes">1x</span>
566
+ <span class="cline-any cline-yes">1x</span>
567
+ <span class="cline-any cline-yes">1x</span>
568
+ <span class="cline-any cline-yes">1x</span>
569
+ <span class="cline-any cline-yes">1x</span>
570
+ <span class="cline-any cline-yes">1x</span>
571
+ <span class="cline-any cline-yes">5x</span>
572
+ <span class="cline-any cline-yes">5x</span>
573
+ <span class="cline-any cline-yes">5x</span>
574
+ <span class="cline-any cline-yes">5x</span>
575
+ <span class="cline-any cline-yes">5x</span>
576
+ <span class="cline-any cline-yes">5x</span>
577
+ <span class="cline-any cline-yes">20x</span>
578
+ <span class="cline-any cline-yes">20x</span>
579
+ <span class="cline-any cline-yes">20x</span>
580
+ <span class="cline-any cline-yes">20x</span>
581
+ <span class="cline-any cline-yes">20x</span>
582
+ <span class="cline-any cline-yes">3x</span>
583
+ <span class="cline-any cline-yes">3x</span>
584
+ <span class="cline-any cline-yes">3x</span>
585
+ <span class="cline-any cline-yes">3x</span>
586
+ <span class="cline-any cline-yes">3x</span>
587
+ <span class="cline-any cline-yes">3x</span>
588
+ <span class="cline-any cline-yes">3x</span>
589
+ <span class="cline-any cline-yes">3x</span>
590
+ <span class="cline-any cline-yes">3x</span>
591
+ <span class="cline-any cline-yes">3x</span>
592
+ <span class="cline-any cline-yes">3x</span>
593
+ <span class="cline-any cline-yes">3x</span>
594
+ <span class="cline-any cline-yes">3x</span>
595
+ <span class="cline-any cline-yes">3x</span>
596
+ <span class="cline-any cline-yes">3x</span>
597
+ <span class="cline-any cline-yes">3x</span>
598
+ <span class="cline-any cline-yes">3x</span>
599
+ <span class="cline-any cline-yes">3x</span>
600
+ <span class="cline-any cline-yes">3x</span>
601
+ <span class="cline-any cline-yes">3x</span>
602
+ <span class="cline-any cline-yes">2x</span>
603
+ <span class="cline-any cline-yes">2x</span>
604
+ <span class="cline-any cline-yes">2x</span>
605
+ <span class="cline-any cline-yes">2x</span>
606
+ <span class="cline-any cline-yes">2x</span>
607
+ <span class="cline-any cline-yes">2x</span>
608
+ <span class="cline-any cline-no">&nbsp;</span>
609
+ <span class="cline-any cline-no">&nbsp;</span>
610
+ <span class="cline-any cline-yes">2x</span>
611
+ <span class="cline-any cline-yes">3x</span>
612
+ <span class="cline-any cline-yes">3x</span>
613
+ <span class="cline-any cline-yes">3x</span>
614
+ <span class="cline-any cline-yes">1x</span>
615
+ <span class="cline-any cline-yes">1x</span>
616
+ <span class="cline-any cline-yes">1x</span>
617
+ <span class="cline-any cline-yes">1x</span>
618
+ <span class="cline-any cline-yes">1x</span>
619
+ <span class="cline-any cline-yes">1x</span>
620
+ <span class="cline-any cline-yes">1x</span>
621
+ <span class="cline-any cline-yes">1x</span>
622
+ <span class="cline-any cline-yes">1x</span>
623
+ <span class="cline-any cline-yes">1x</span>
624
+ <span class="cline-any cline-yes">1x</span>
625
+ <span class="cline-any cline-yes">3x</span>
626
+ <span class="cline-any cline-yes">3x</span>
627
+ <span class="cline-any cline-yes">3x</span>
628
+ <span class="cline-any cline-yes">3x</span>
629
+ <span class="cline-any cline-yes">3x</span>
630
+ <span class="cline-any cline-yes">3x</span>
631
+ <span class="cline-any cline-yes">3x</span>
632
+ <span class="cline-any cline-yes">20x</span>
633
+ <span class="cline-any cline-yes">20x</span>
634
+ <span class="cline-any cline-yes">20x</span>
635
+ <span class="cline-any cline-yes">20x</span>
636
+ <span class="cline-any cline-yes">20x</span>
637
+ <span class="cline-any cline-yes">3x</span>
638
+ <span class="cline-any cline-yes">3x</span>
639
+ <span class="cline-any cline-yes">3x</span>
640
+ <span class="cline-any cline-yes">3x</span>
641
+ <span class="cline-any cline-yes">3x</span>
642
+ <span class="cline-any cline-yes">3x</span>
643
+ <span class="cline-any cline-yes">3x</span>
644
+ <span class="cline-any cline-yes">3x</span>
645
+ <span class="cline-any cline-yes">3x</span>
646
+ <span class="cline-any cline-yes">3x</span>
647
+ <span class="cline-any cline-yes">3x</span>
648
+ <span class="cline-any cline-yes">3x</span>
649
+ <span class="cline-any cline-yes">3x</span>
650
+ <span class="cline-any cline-yes">3x</span>
651
+ <span class="cline-any cline-yes">3x</span>
652
+ <span class="cline-any cline-yes">3x</span>
653
+ <span class="cline-any cline-yes">3x</span>
654
+ <span class="cline-any cline-yes">3x</span>
655
+ <span class="cline-any cline-yes">3x</span>
656
+ <span class="cline-any cline-yes">3x</span>
657
+ <span class="cline-any cline-yes">3x</span>
658
+ <span class="cline-any cline-yes">3x</span>
659
+ <span class="cline-any cline-yes">3x</span>
660
+ <span class="cline-any cline-yes">3x</span>
661
+ <span class="cline-any cline-yes">2x</span>
662
+ <span class="cline-any cline-yes">2x</span>
663
+ <span class="cline-any cline-yes">2x</span>
664
+ <span class="cline-any cline-yes">2x</span>
665
+ <span class="cline-any cline-yes">2x</span>
666
+ <span class="cline-any cline-yes">2x</span>
667
+ <span class="cline-any cline-yes">2x</span>
668
+ <span class="cline-any cline-no">&nbsp;</span>
669
+ <span class="cline-any cline-no">&nbsp;</span>
670
+ <span class="cline-any cline-yes">2x</span>
671
+ <span class="cline-any cline-yes">3x</span>
672
+ <span class="cline-any cline-yes">3x</span>
673
+ <span class="cline-any cline-yes">3x</span>
674
+ <span class="cline-any cline-yes">1x</span>
675
+ <span class="cline-any cline-yes">1x</span>
676
+ <span class="cline-any cline-yes">1x</span>
677
+ <span class="cline-any cline-yes">1x</span>
678
+ <span class="cline-any cline-yes">1x</span>
679
+ <span class="cline-any cline-yes">1x</span>
680
+ <span class="cline-any cline-yes">1x</span>
681
+ <span class="cline-any cline-yes">1x</span>
682
+ <span class="cline-any cline-yes">1x</span>
683
+ <span class="cline-any cline-yes">1x</span>
684
+ <span class="cline-any cline-yes">1x</span>
685
+ <span class="cline-any cline-yes">3x</span>
686
+ <span class="cline-any cline-yes">3x</span>
687
+ <span class="cline-any cline-yes">3x</span>
688
+ <span class="cline-any cline-yes">3x</span>
689
+ <span class="cline-any cline-yes">3x</span>
690
+ <span class="cline-any cline-yes">3x</span>
691
+ <span class="cline-any cline-yes">3x</span>
692
+ <span class="cline-any cline-yes">20x</span>
693
+ <span class="cline-any cline-yes">20x</span>
694
+ <span class="cline-any cline-yes">20x</span>
695
+ <span class="cline-any cline-yes">20x</span>
696
+ <span class="cline-any cline-yes">3x</span>
697
+ <span class="cline-any cline-yes">3x</span>
698
+ <span class="cline-any cline-yes">3x</span>
699
+ <span class="cline-any cline-yes">3x</span>
700
+ <span class="cline-any cline-yes">3x</span>
701
+ <span class="cline-any cline-yes">1x</span>
702
+ <span class="cline-any cline-yes">1x</span>
703
+ <span class="cline-any cline-yes">1x</span>
704
+ <span class="cline-any cline-yes">1x</span>
705
+ <span class="cline-any cline-yes">1x</span>
706
+ <span class="cline-any cline-yes">1x</span>
707
+ <span class="cline-any cline-yes">1x</span>
708
+ <span class="cline-any cline-yes">1x</span>
709
+ <span class="cline-any cline-yes">1x</span>
710
+ <span class="cline-any cline-yes">1x</span>
711
+ <span class="cline-any cline-yes">1x</span>
712
+ <span class="cline-any cline-yes">2x</span>
713
+ <span class="cline-any cline-yes">2x</span>
714
+ <span class="cline-any cline-yes">3x</span>
715
+ <span class="cline-any cline-yes">1x</span>
716
+ <span class="cline-any cline-yes">1x</span>
717
+ <span class="cline-any cline-yes">1x</span>
718
+ <span class="cline-any cline-yes">1x</span>
719
+ <span class="cline-any cline-yes">1x</span>
720
+ <span class="cline-any cline-yes">1x</span>
721
+ <span class="cline-any cline-yes">1x</span>
722
+ <span class="cline-any cline-yes">1x</span>
723
+ <span class="cline-any cline-yes">1x</span>
724
+ <span class="cline-any cline-yes">1x</span>
725
+ <span class="cline-any cline-yes">1x</span>
726
+ <span class="cline-any cline-yes">1x</span>
727
+ <span class="cline-any cline-yes">1x</span>
728
+ <span class="cline-any cline-yes">1x</span>
729
+ <span class="cline-any cline-yes">1x</span>
730
+ <span class="cline-any cline-yes">1x</span>
731
+ <span class="cline-any cline-yes">1x</span>
732
+ <span class="cline-any cline-yes">1x</span>
733
+ <span class="cline-any cline-yes">1x</span>
734
+ <span class="cline-any cline-yes">3x</span>
735
+ <span class="cline-any cline-yes">20x</span>
736
+ <span class="cline-any cline-yes">20x</span>
737
+ <span class="cline-any cline-yes">20x</span>
738
+ <span class="cline-any cline-yes">20x</span>
739
+ <span class="cline-any cline-yes">20x</span>
740
+ <span class="cline-any cline-yes">20x</span>
741
+ <span class="cline-any cline-yes">20x</span>
742
+ <span class="cline-any cline-yes">20x</span>
743
+ <span class="cline-any cline-yes">20x</span>
744
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
745
+ * OpenClaw Integration for A2A
746
+ *
747
+ * Provides owner-context summarization using OpenClaw's agent system.
748
+ */
749
+ &nbsp;
750
+ const fs = require('fs');
751
+ const path = require('path');
752
+ const { createLogger } = require('./logger');
753
+ const { buildUnifiedSummaryPrompt } = require('./summary-prompt');
754
+ &nbsp;
755
+ const logger = createLogger({ component: 'a2a.openclaw-integration' });
756
+ &nbsp;
757
+ /**
758
+ * Load owner context from OpenClaw workspace files
759
+ * @param {string} workspaceDir - Path to workspace
760
+ * @param {Object} options
761
+ * @param {string[]} options.tierGoals - Goals from config tier (takes priority over USER.md)
762
+ */
763
+ function loadOwnerContext(workspaceDir = process.cwd(), options = {}) {
764
+ const context = {
765
+ goals: [],
766
+ interests: [],
767
+ context: '',
768
+ user: null,
769
+ memory: null
770
+ };
771
+ &nbsp;
772
+ // Tier goals from config take priority
773
+ if (options.tierGoals &amp;&amp; options.tierGoals.length &gt; 0) {
774
+ context.goals = [...options.tierGoals];
775
+ }
776
+ &nbsp;
777
+ // Load USER.md
778
+ const userPath = path.join(workspaceDir, 'USER.md');
779
+ if (fs.existsSync(userPath)) {
780
+ context.user = fs.readFileSync(userPath, 'utf8');
781
+ // Extract goals from USER.md (fallback if no tier goals from config)
782
+ if (context.goals.length === 0) {
783
+ const goalsMatch = context.user.match(/##\s*(?:Goals|Current|Seeking)[^\n]*\n([\s\S]*?)(?=\n##|$)/i);
784
+ if (goalsMatch) {
785
+ context.goals = goalsMatch[1]
786
+ .split('\n')
787
+ .filter(l =&gt; l.trim().startsWith('-') || l.trim().startsWith('*'))
788
+ .map(l =&gt; l.replace(/^[\s\-\*]+/, '').trim())
789
+ .filter(Boolean);
790
+ }
791
+ }
792
+ // Extract interests
793
+ const interestsMatch = context.user.match(/##\s*(?:Interests|Projects)[^\n]*\n([\s\S]*?)(?=\n##|$)/i);
794
+ if (interestsMatch) {
795
+ context.interests = interestsMatch[1]
796
+ .split('\n')
797
+ .filter(l =&gt; l.trim().startsWith('-') || l.trim().startsWith('*'))
798
+ .map(l =&gt; l.replace(/^[\s\-\*]+/, '').trim())
799
+ .filter(Boolean);
800
+ }
801
+ }
802
+ &nbsp;
803
+ // Load recent memory
804
+ const memoryDir = path.join(workspaceDir, 'memory');
805
+ if (fs.existsSync(memoryDir)) {
806
+ const files = fs.readdirSync(memoryDir)
807
+ .filter(f =&gt; f.endsWith('.md'))
808
+ .sort()
809
+ .reverse()
810
+ .slice(0, 3); // Last 3 memory files
811
+
812
+ context.memory = files.map(f =&gt; {
813
+ const content = fs.readFileSync(path.join(memoryDir, f), 'utf8');
814
+ return `## ${f}\n${content}`;
815
+ }).join('\n\n');
816
+ }
817
+ &nbsp;
818
+ // Load MEMORY.md if exists
819
+ const mainMemoryPath = path.join(workspaceDir, 'MEMORY.md');
820
+ if (fs.existsSync(mainMemoryPath)) {
821
+ const mainMemory = fs.readFileSync(mainMemoryPath, 'utf8');
822
+ context.memory = mainMemory + '\n\n' + (context.memory <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>;
823
+ }
824
+ &nbsp;
825
+ return context;
826
+ }
827
+ &nbsp;
828
+ /**
829
+ * Build summary prompt for agent
830
+ *
831
+ * Philosophy: A2A is collaborative AND adversarial. Each agent tries
832
+ * to maximize value for their owner while finding genuine mutual wins.
833
+ * Track the exchange balance AND surface partnership opportunities.
834
+ */
835
+ function buildSummaryPrompt(messages, ownerContext, callerInfo = {}) {
836
+ // Build transcript in unified format
837
+ const transcript = messages.map(m =&gt; ({
838
+ direction: m.direction,
839
+ content: m.content
840
+ }));
841
+ &nbsp;
842
+ // Map ownerContext (which has .user, .goals, .interests from USER.md) into unified format
843
+ const unifiedOwnerContext = {
844
+ agentName: null,
845
+ ownerName: null,
846
+ goals: ownerContext?.goals || []
847
+ };
848
+ &nbsp;
849
+ return buildUnifiedSummaryPrompt({
850
+ transcript,
851
+ callerInfo: {
852
+ name: callerInfo.name || null,
853
+ owner: callerInfo.owner || null,
854
+ context: callerInfo.context || null
855
+ },
856
+ ownerContext: unifiedOwnerContext
857
+ });
858
+ }
859
+ &nbsp;
860
+ /**
861
+ * Create an OpenClaw summarizer that uses exec to call the agent
862
+ * This works by writing a prompt file and using openclaw's CLI
863
+ */
864
+ function createExecSummarizer(workspaceDir = process.cwd()) {
865
+ const { execSync } = require('child_process');
866
+
867
+ return async function(messages, callerInfo = {}) {
868
+ const ownerContext = loadOwnerContext(workspaceDir);
869
+ const prompt = buildSummaryPrompt(messages, ownerContext, callerInfo);
870
+
871
+ // Write prompt to temp file
872
+ const tmpFile = `/tmp/a2a-summary-${Date.now()}.txt`;
873
+ fs.writeFileSync(tmpFile, prompt);
874
+
875
+ try {
876
+ // Call openclaw CLI to get agent response
877
+ // This assumes openclaw has a way to do single-shot prompts
878
+ const result = execSync(
879
+ `cat "${tmpFile}" | openclaw prompt --json 2&gt;/dev/null || echo '{}'`,
880
+ { encoding: 'utf8', timeout: 30000 }
881
+ );
882
+
883
+ // Parse JSON from response
884
+ const jsonMatch = result.match(/\{[\s\S]*\}/);
885
+ if (jsonMatch) {
886
+ return JSON.parse(jsonMatch[0]);
887
+ }
888
+
889
+ return {
890
+ summary: result.slice(0, 500),
891
+ ownerSummary: null,
892
+ relevance: 'unknown',
893
+ goalsTouched: [],
894
+ actionItems: [],
895
+ followUp: null,
896
+ notes: null
897
+ };
898
+ } catch (err) {
899
+ logger.error('Exec summarizer failed', {
900
+ event: 'exec_summary_failed',
901
+ trace_id: callerInfo?.trace_id || callerInfo?.traceId || null,
902
+ error: err,
903
+ error_code: 'OPENCLAW_EXEC_SUMMARIZER_FAILED',
904
+ hint: 'Verify `openclaw prompt --json` is available and returns valid JSON.',
905
+ data: {
906
+ workspace_dir: workspaceDir
907
+ }
908
+ });
909
+ return { summary: null };
910
+ }<span class="branch-0 cbranch-no" title="branch not covered" > f</span>inally {
911
+ // Cleanup
912
+ try { fs.unlinkSync(tmpFile); } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {}</span>
913
+ }
914
+ };
915
+ }
916
+ &nbsp;
917
+ /**
918
+ * Create a summarizer that posts to a local HTTP endpoint
919
+ * OpenClaw can expose an internal summarization endpoint
920
+ */
921
+ function createHttpSummarizer(endpoint = 'http://localhost:3000/api/summarize') {
922
+ const http = require('http');
923
+ const https = require('https');
924
+
925
+ return async function(messages, callerInfo = {}) {
926
+ const ownerContext = loadOwnerContext();
927
+ const prompt = buildSummaryPrompt(messages, ownerContext, callerInfo);
928
+
929
+ return new Promise((resolve) =&gt; {
930
+ const url = new URL(endpoint);
931
+ const client = url.protocol === 'https:' <span class="branch-0 cbranch-no" title="branch not covered" >? https </span>: http;
932
+
933
+ const req = client.request({
934
+ hostname: url.hostname,
935
+ port: url.port,
936
+ path: url.pathname,
937
+ method: 'POST',
938
+ headers: { 'Content-Type': 'application/json' },
939
+ timeout: 30000
940
+ }, (res) =&gt; {
941
+ let data = '';
942
+ res.on('data', chunk =&gt; data += chunk);
943
+ res.on('end', () =&gt; {
944
+ try {
945
+ resolve(JSON.parse(data));
946
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
947
+ <span class="cstat-no" title="statement not covered" > resolve({ summary: data.slice(0, 500) });</span>
948
+ <span class="cstat-no" title="statement not covered" > }</span>
949
+ });
950
+ });
951
+
952
+ req.on('error', (err) =&gt; {
953
+ logger.error('HTTP summarizer failed', {
954
+ event: 'http_summary_failed',
955
+ trace_id: callerInfo?.trace_id || callerInfo?.traceId || null,
956
+ error: err,
957
+ error_code: 'OPENCLAW_HTTP_SUMMARIZER_FAILED',
958
+ hint: 'Check summarizer endpoint reachability and response format.',
959
+ data: {
960
+ endpoint
961
+ }
962
+ });
963
+ resolve({ summary: null });
964
+ });
965
+
966
+ req.write(JSON.stringify({ prompt, messages, callerInfo }));
967
+ req.end();
968
+ });
969
+ };
970
+ }
971
+ &nbsp;
972
+ /**
973
+ * Create a summarizer using sessions_send to the main OpenClaw session
974
+ * This is the preferred method when running inside OpenClaw
975
+ */
976
+ function createSessionSummarizer(gatewayUrl, gatewayToken) {
977
+ const http = require('http');
978
+ const https = require('https');
979
+
980
+ return async function(messages, callerInfo = {}) {
981
+ const ownerContext = loadOwnerContext();
982
+ const prompt = buildSummaryPrompt(messages, ownerContext, callerInfo);
983
+
984
+ // Send to OpenClaw gateway's internal API
985
+ return new Promise((resolve) =&gt; {
986
+ const url = new URL(gatewayUrl <span class="branch-0 cbranch-no" title="branch not covered" >|| 'http://localhost:3000')</span>;
987
+ const client = url.protocol === 'https:' <span class="branch-0 cbranch-no" title="branch not covered" >? https </span>: http;
988
+
989
+ const req = client.request({
990
+ hostname: url.hostname,
991
+ port: url.port,
992
+ path: '/api/internal/summarize',
993
+ method: 'POST',
994
+ headers: {
995
+ 'Content-Type': 'application/json',
996
+ 'Authorization': `Bearer ${gatewayToken || process.env.OPENCLAW_TOKEN}`
997
+ },
998
+ timeout: 60000
999
+ }, (res) =&gt; {
1000
+ let data = '';
1001
+ res.on('data', chunk =&gt; data += chunk);
1002
+ res.on('end', () =&gt; {
1003
+ try {
1004
+ const result = JSON.parse(data);
1005
+ resolve(result.summary <span class="branch-0 cbranch-no" title="branch not covered" >|| result)</span>;
1006
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1007
+ <span class="cstat-no" title="statement not covered" > resolve({ summary: data.slice(0, 500) });</span>
1008
+ <span class="cstat-no" title="statement not covered" > }</span>
1009
+ });
1010
+ });
1011
+
1012
+ req.on('error', (err) =&gt; {
1013
+ logger.error('Session summarizer failed', {
1014
+ event: 'session_summary_failed',
1015
+ trace_id: callerInfo?.trace_id || callerInfo?.traceId || null,
1016
+ error: err,
1017
+ error_code: 'OPENCLAW_SESSION_SUMMARIZER_FAILED',
1018
+ hint: 'Verify OpenClaw gateway URL/token and /api/internal/summarize availability.',
1019
+ data: {
1020
+ gateway_url: gatewayUrl <span class="branch-0 cbranch-no" title="branch not covered" >|| 'http://localhost:3000'</span>
1021
+ }
1022
+ });
1023
+ resolve({ summary: null });
1024
+ });
1025
+
1026
+ req.write(JSON.stringify({ prompt }));
1027
+ req.end();
1028
+ });
1029
+ };
1030
+ }
1031
+ &nbsp;
1032
+ /**
1033
+ * Auto-detect best summarizer based on environment
1034
+ */
1035
+ function createAutoSummarizer(options = {}) {
1036
+ const workspaceDir = options.workspaceDir || process.env.OPENCLAW_WORKSPACE || process.cwd();
1037
+
1038
+ // If gateway URL provided, use session summarizer
1039
+ if (options.gatewayUrl || process.env.OPENCLAW_GATEWAY_URL) {
1040
+ logger.info('Using session summarizer', {
1041
+ event: 'summary_mode_selected',
1042
+ data: {
1043
+ mode: 'session'
1044
+ }
1045
+ });
1046
+ return createSessionSummarizer(
1047
+ options.gatewayUrl <span class="branch-0 cbranch-no" title="branch not covered" >|| process.env.OPENCLAW_GATEWAY_URL,</span>
1048
+ options.gatewayToken || process.env.OPENCLAW_TOKEN
1049
+ );
1050
+ }
1051
+
1052
+ // If HTTP endpoint provided, use that
1053
+ if (options.summaryEndpoint) {
1054
+ logger.info('Using HTTP summarizer', {
1055
+ event: 'summary_mode_selected',
1056
+ data: {
1057
+ mode: 'http',
1058
+ endpoint: options.summaryEndpoint
1059
+ }
1060
+ });
1061
+ return createHttpSummarizer(options.summaryEndpoint);
1062
+ }
1063
+
1064
+ // Fall back to exec summarizer
1065
+ logger.info('Using exec summarizer', {
1066
+ event: 'summary_mode_selected',
1067
+ data: {
1068
+ mode: 'exec',
1069
+ workspace_dir: workspaceDir
1070
+ }
1071
+ });
1072
+ return createExecSummarizer(workspaceDir);
1073
+ }
1074
+ &nbsp;
1075
+ module.exports = {
1076
+ loadOwnerContext,
1077
+ buildSummaryPrompt,
1078
+ createExecSummarizer,
1079
+ createHttpSummarizer,
1080
+ createSessionSummarizer,
1081
+ createAutoSummarizer
1082
+ };
1083
+ &nbsp;</pre></td></tr></table></pre>
1084
+
1085
+ <div class='push'></div><!-- for sticky footer -->
1086
+ </div><!-- /wrapper -->
1087
+ <div class='footer quiet pad2 space-top1 center small'>
1088
+ Code coverage generated by
1089
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1090
+ at 2026-03-03T22:25:10.857Z
1091
+ </div>
1092
+ <script src="../../prettify.js"></script>
1093
+ <script>
1094
+ window.onload = function () {
1095
+ prettyPrint();
1096
+ };
1097
+ </script>
1098
+ <script src="../../sorter.js"></script>
1099
+ <script src="../../block-navigation.js"></script>
1100
+ </body>
1101
+ </html>
1102
+