@hsuite/native-connect-angular 1.0.0

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 (276) hide show
  1. package/README.md +48 -0
  2. package/USAGE_EXAMPLES.md +476 -0
  3. package/assets/wallets/extension.svg +7 -0
  4. package/assets/wallets/hashpack.svg +6 -0
  5. package/assets/wallets/hsuite.svg +11 -0
  6. package/assets/wallets/kabila.svg +11 -0
  7. package/assets/wallets/walletconnect.svg +13 -0
  8. package/coverage/base.css +224 -0
  9. package/coverage/block-navigation.js +87 -0
  10. package/coverage/coverage-summary.json +50 -0
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +476 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +476 -0
  17. package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
  18. package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +116 -0
  19. package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
  20. package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +116 -0
  21. package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +685 -0
  22. package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +766 -0
  23. package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
  24. package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +116 -0
  25. package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1495 -0
  26. package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1588 -0
  27. package/coverage/lcov-report/lib/components/account-selector/index.html +161 -0
  28. package/coverage/lcov-report/lib/components/wallet-account-display/index.html +116 -0
  29. package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
  30. package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +116 -0
  31. package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
  32. package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +116 -0
  33. package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
  34. package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +116 -0
  35. package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
  36. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
  37. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
  38. package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +116 -0
  39. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
  40. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
  41. package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
  42. package/coverage/lcov-report/lib/components/wallet-session-display/index.html +116 -0
  43. package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
  44. package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +116 -0
  45. package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
  46. package/coverage/lcov-report/lib/directives/index.html +146 -0
  47. package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +670 -0
  48. package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +547 -0
  49. package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +781 -0
  50. package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +715 -0
  51. package/coverage/lcov-report/lib/index.html +116 -0
  52. package/coverage/lcov-report/lib/models/connection-config.model.ts.html +280 -0
  53. package/coverage/lcov-report/lib/models/index.html +131 -0
  54. package/coverage/lcov-report/lib/models/provider-types.ts.html +577 -0
  55. package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +1138 -0
  56. package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
  57. package/coverage/lcov-report/lib/providers/hsuite-native/index.html +116 -0
  58. package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +2347 -0
  59. package/coverage/lcov-report/lib/providers/index.html +146 -0
  60. package/coverage/lcov-report/lib/providers/p2p-native/index.html +131 -0
  61. package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
  62. package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
  63. package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1132 -0
  64. package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +176 -0
  65. package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +673 -0
  66. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
  67. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
  68. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
  69. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
  70. package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
  71. package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +146 -0
  72. package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
  73. package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
  74. package/coverage/lcov-report/lib/services/index.html +191 -0
  75. package/coverage/lcov-report/lib/services/logger.service.ts.html +463 -0
  76. package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
  77. package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
  78. package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
  79. package/coverage/lcov-report/lib/services/transaction-builders/index.html +161 -0
  80. package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
  81. package/coverage/lcov-report/lib/services/transaction.service.ts.html +1123 -0
  82. package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +2641 -0
  83. package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +637 -0
  84. package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +643 -0
  85. package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +496 -0
  86. package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +823 -0
  87. package/coverage/lcov-report/lib/transports/index.html +116 -0
  88. package/coverage/lcov-report/lib/utils/index.html +116 -0
  89. package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +319 -0
  90. package/coverage/lcov-report/prettify.css +1 -0
  91. package/coverage/lcov-report/prettify.js +2 -0
  92. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  93. package/coverage/lcov-report/sorter.js +210 -0
  94. package/coverage/lcov.info +19252 -0
  95. package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
  96. package/coverage/lib/components/account-selector/account-actions/index.html +116 -0
  97. package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
  98. package/coverage/lib/components/account-selector/account-filter/index.html +116 -0
  99. package/coverage/lib/components/account-selector/account-formatting.service.ts.html +685 -0
  100. package/coverage/lib/components/account-selector/account-grouping.service.ts.html +766 -0
  101. package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
  102. package/coverage/lib/components/account-selector/account-list/index.html +116 -0
  103. package/coverage/lib/components/account-selector/account-selector.component.ts.html +1495 -0
  104. package/coverage/lib/components/account-selector/account-selector.service.ts.html +1588 -0
  105. package/coverage/lib/components/account-selector/index.html +161 -0
  106. package/coverage/lib/components/wallet-account-display/index.html +116 -0
  107. package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
  108. package/coverage/lib/components/wallet-connect-button/index.html +116 -0
  109. package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
  110. package/coverage/lib/components/wallet-connect-prompt/index.html +116 -0
  111. package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
  112. package/coverage/lib/components/wallet-connected-guard/index.html +116 -0
  113. package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
  114. package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
  115. package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
  116. package/coverage/lib/components/wallet-connection-modal/index.html +116 -0
  117. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
  118. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
  119. package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
  120. package/coverage/lib/components/wallet-session-display/index.html +116 -0
  121. package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
  122. package/coverage/lib/components/wallet-transaction-status/index.html +116 -0
  123. package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
  124. package/coverage/lib/directives/index.html +146 -0
  125. package/coverage/lib/directives/wallet-connected.directive.ts.html +670 -0
  126. package/coverage/lib/directives/wallet-context.directive.ts.html +547 -0
  127. package/coverage/lib/directives/wallet-events.directive.ts.html +781 -0
  128. package/coverage/lib/hsuite-wallet.module.ts.html +715 -0
  129. package/coverage/lib/index.html +116 -0
  130. package/coverage/lib/models/connection-config.model.ts.html +280 -0
  131. package/coverage/lib/models/index.html +131 -0
  132. package/coverage/lib/models/provider-types.ts.html +577 -0
  133. package/coverage/lib/providers/base-wallet-provider.ts.html +1138 -0
  134. package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
  135. package/coverage/lib/providers/hsuite-native/index.html +116 -0
  136. package/coverage/lib/providers/hsuite-native-provider.ts.html +2347 -0
  137. package/coverage/lib/providers/index.html +146 -0
  138. package/coverage/lib/providers/p2p-native/index.html +131 -0
  139. package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
  140. package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
  141. package/coverage/lib/providers/wallet-error-handler.ts.html +1132 -0
  142. package/coverage/lib/providers/walletconnect/core/index.html +176 -0
  143. package/coverage/lib/providers/walletconnect/core/session-health.ts.html +673 -0
  144. package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
  145. package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
  146. package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
  147. package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
  148. package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
  149. package/coverage/lib/providers/walletconnect/signers/index.html +146 -0
  150. package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
  151. package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
  152. package/coverage/lib/services/index.html +191 -0
  153. package/coverage/lib/services/logger.service.ts.html +463 -0
  154. package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
  155. package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
  156. package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
  157. package/coverage/lib/services/transaction-builders/index.html +161 -0
  158. package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
  159. package/coverage/lib/services/transaction.service.ts.html +1123 -0
  160. package/coverage/lib/services/unified-wallet.service.ts.html +2641 -0
  161. package/coverage/lib/services/wallet-context.service.ts.html +637 -0
  162. package/coverage/lib/services/wallet-event-bus.service.ts.html +643 -0
  163. package/coverage/lib/services/wallet-providers.service.ts.html +496 -0
  164. package/coverage/lib/transports/chrome-extension-transport.ts.html +823 -0
  165. package/coverage/lib/transports/index.html +116 -0
  166. package/coverage/lib/utils/index.html +116 -0
  167. package/coverage/lib/utils/ledger-icons.util.ts.html +319 -0
  168. package/coverage/prettify.css +1 -0
  169. package/coverage/prettify.js +2 -0
  170. package/coverage/sort-arrow-sprite.png +0 -0
  171. package/coverage/sorter.js +210 -0
  172. package/dist/README.md +48 -0
  173. package/dist/fesm2022/hsuite-native-connect-angular.mjs +14592 -0
  174. package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -0
  175. package/dist/index.d.ts +6949 -0
  176. package/examples/minimal-connect.ts +178 -0
  177. package/examples/multi-protocol.ts +495 -0
  178. package/examples/transaction-signing.ts +361 -0
  179. package/jest.config.json +45 -0
  180. package/karma.conf.js +42 -0
  181. package/ng-package.json +20 -0
  182. package/package.json +60 -0
  183. package/src/index.ts +203 -0
  184. package/src/lib/components/account-selector/account-actions/account-actions.component.ts +261 -0
  185. package/src/lib/components/account-selector/account-filter/account-filter.component.ts +401 -0
  186. package/src/lib/components/account-selector/account-formatting.service.ts +200 -0
  187. package/src/lib/components/account-selector/account-grouping.service.ts +227 -0
  188. package/src/lib/components/account-selector/account-list/account-list.component.ts +470 -0
  189. package/src/lib/components/account-selector/account-selector.component.html +135 -0
  190. package/src/lib/components/account-selector/account-selector.component.scss +2039 -0
  191. package/src/lib/components/account-selector/account-selector.component.ts +470 -0
  192. package/src/lib/components/account-selector/account-selector.service.ts +501 -0
  193. package/src/lib/components/wallet-account-display/wallet-account-display.component.html +34 -0
  194. package/src/lib/components/wallet-account-display/wallet-account-display.component.scss +99 -0
  195. package/src/lib/components/wallet-account-display/wallet-account-display.component.ts +140 -0
  196. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.html +14 -0
  197. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.scss +272 -0
  198. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.ts +240 -0
  199. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.html +24 -0
  200. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.scss +50 -0
  201. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts +108 -0
  202. package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.html +24 -0
  203. package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts +73 -0
  204. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.html +56 -0
  205. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.scss +218 -0
  206. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts +117 -0
  207. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.html +94 -0
  208. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.scss +272 -0
  209. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts +734 -0
  210. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.html +197 -0
  211. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.scss +678 -0
  212. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +730 -0
  213. package/src/lib/components/wallet-session-display/wallet-session-display.component.html +110 -0
  214. package/src/lib/components/wallet-session-display/wallet-session-display.component.scss +179 -0
  215. package/src/lib/components/wallet-session-display/wallet-session-display.component.ts +197 -0
  216. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.html +65 -0
  217. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.scss +254 -0
  218. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts +206 -0
  219. package/src/lib/directives/wallet-connected.directive.ts +195 -0
  220. package/src/lib/directives/wallet-context.directive.ts +154 -0
  221. package/src/lib/directives/wallet-events.directive.ts +232 -0
  222. package/src/lib/hsuite-wallet.module.ts +210 -0
  223. package/src/lib/models/connection-config.model.ts +65 -0
  224. package/src/lib/models/provider-types.ts +164 -0
  225. package/src/lib/models/unified-account.model.ts +76 -0
  226. package/src/lib/models/wallet-context.model.ts +121 -0
  227. package/src/lib/models/wallet-events.model.ts +158 -0
  228. package/src/lib/providers/base-wallet-provider.ts +351 -0
  229. package/src/lib/providers/hsuite-native/channel-client.service.spec.ts +73 -0
  230. package/src/lib/providers/hsuite-native/channel-client.service.ts +862 -0
  231. package/src/lib/providers/hsuite-native/index.ts +8 -0
  232. package/src/lib/providers/hsuite-native-provider.ts +754 -0
  233. package/src/lib/providers/mobile-native/mobile-native.provider.spec.ts +19 -0
  234. package/src/lib/providers/p2p-native/index.ts +30 -0
  235. package/src/lib/providers/p2p-native/p2p-native.provider.spec.ts +523 -0
  236. package/src/lib/providers/p2p-native/p2p-native.provider.ts +723 -0
  237. package/src/lib/providers/p2p-native/p2p-session-manager.ts +695 -0
  238. package/src/lib/providers/wallet-error-handler.ts +349 -0
  239. package/src/lib/providers/walletconnect/core/base-signer.interface.ts +122 -0
  240. package/src/lib/providers/walletconnect/core/session-health.ts +196 -0
  241. package/src/lib/providers/walletconnect/core/walletconnect-client-manager.ts +364 -0
  242. package/src/lib/providers/walletconnect/core/walletconnect-provider.integration.spec.ts +348 -0
  243. package/src/lib/providers/walletconnect/core/walletconnect-provider.ts +826 -0
  244. package/src/lib/providers/walletconnect/core/walletconnect-session-store.ts +273 -0
  245. package/src/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts +299 -0
  246. package/src/lib/providers/walletconnect/core/walletconnect-types.ts +48 -0
  247. package/src/lib/providers/walletconnect/index.ts +33 -0
  248. package/src/lib/providers/walletconnect/signers/hedera-signer.spec.ts +367 -0
  249. package/src/lib/providers/walletconnect/signers/hedera-signer.ts +610 -0
  250. package/src/lib/providers/walletconnect/signers/signer-factory.spec.ts +62 -0
  251. package/src/lib/providers/walletconnect/signers/signer-factory.ts +120 -0
  252. package/src/lib/providers/walletconnect/signers/xrpl-signer.spec.ts +296 -0
  253. package/src/lib/providers/walletconnect/signers/xrpl-signer.ts +478 -0
  254. package/src/lib/services/logger.service.ts +126 -0
  255. package/src/lib/services/transaction-builders/base-transaction-builder.service.ts +585 -0
  256. package/src/lib/services/transaction-builders/hedera-amount-utils.ts +84 -0
  257. package/src/lib/services/transaction-builders/hedera-transaction-builder.service.spec.ts +741 -0
  258. package/src/lib/services/transaction-builders/hedera-transaction-builder.service.ts +1285 -0
  259. package/src/lib/services/transaction-builders/index.ts +54 -0
  260. package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.spec.ts +937 -0
  261. package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.ts +832 -0
  262. package/src/lib/services/transaction.service.ts +346 -0
  263. package/src/lib/services/unified-wallet.service.spec.ts +1382 -0
  264. package/src/lib/services/unified-wallet.service.ts +852 -0
  265. package/src/lib/services/wallet-context.service.ts +184 -0
  266. package/src/lib/services/wallet-event-bus.service.ts +186 -0
  267. package/src/lib/services/wallet-providers.service.ts +137 -0
  268. package/src/lib/transports/chrome-extension-transport.ts +246 -0
  269. package/src/lib/utils/index.ts +14 -0
  270. package/src/lib/utils/ledger-icons.util.ts +78 -0
  271. package/test/test-setup.ts +21 -0
  272. package/test-setup.ts +63 -0
  273. package/tsconfig.build.json +11 -0
  274. package/tsconfig.json +29 -0
  275. package/tsconfig.spec.json +15 -0
  276. package/vitest.config.ts +48 -0
@@ -0,0 +1,2254 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for lib/providers/p2p-native/p2p-native.provider.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../../prettify.css" />
9
+ <link rel="stylesheet" href="../../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../../index.html">All files</a> / <a href="index.html">lib/providers/p2p-native</a> p2p-native.provider.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">86.58% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>626/723</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">69.81% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>37/53</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">80% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>16/20</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">86.58% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>626/723</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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
790
+ <span class="cline-any cline-yes">1x</span>
791
+ <span class="cline-any cline-yes">1x</span>
792
+ <span class="cline-any cline-yes">1x</span>
793
+ <span class="cline-any cline-yes">1x</span>
794
+ <span class="cline-any cline-yes">1x</span>
795
+ <span class="cline-any cline-yes">1x</span>
796
+ <span class="cline-any cline-yes">1x</span>
797
+ <span class="cline-any cline-yes">1x</span>
798
+ <span class="cline-any cline-yes">1x</span>
799
+ <span class="cline-any cline-yes">1x</span>
800
+ <span class="cline-any cline-yes">1x</span>
801
+ <span class="cline-any cline-yes">1x</span>
802
+ <span class="cline-any cline-yes">1x</span>
803
+ <span class="cline-any cline-yes">1x</span>
804
+ <span class="cline-any cline-yes">1x</span>
805
+ <span class="cline-any cline-yes">1x</span>
806
+ <span class="cline-any cline-yes">1x</span>
807
+ <span class="cline-any cline-yes">1x</span>
808
+ <span class="cline-any cline-yes">1x</span>
809
+ <span class="cline-any cline-yes">1x</span>
810
+ <span class="cline-any cline-yes">1x</span>
811
+ <span class="cline-any cline-yes">1x</span>
812
+ <span class="cline-any cline-yes">1x</span>
813
+ <span class="cline-any cline-yes">1x</span>
814
+ <span class="cline-any cline-yes">1x</span>
815
+ <span class="cline-any cline-yes">1x</span>
816
+ <span class="cline-any cline-yes">1x</span>
817
+ <span class="cline-any cline-yes">1x</span>
818
+ <span class="cline-any cline-yes">1x</span>
819
+ <span class="cline-any cline-yes">1x</span>
820
+ <span class="cline-any cline-yes">1x</span>
821
+ <span class="cline-any cline-yes">1x</span>
822
+ <span class="cline-any cline-yes">1x</span>
823
+ <span class="cline-any cline-yes">1x</span>
824
+ <span class="cline-any cline-yes">1x</span>
825
+ <span class="cline-any cline-yes">1x</span>
826
+ <span class="cline-any cline-yes">1x</span>
827
+ <span class="cline-any cline-yes">1x</span>
828
+ <span class="cline-any cline-yes">1x</span>
829
+ <span class="cline-any cline-yes">1x</span>
830
+ <span class="cline-any cline-yes">1x</span>
831
+ <span class="cline-any cline-yes">1x</span>
832
+ <span class="cline-any cline-yes">1x</span>
833
+ <span class="cline-any cline-yes">1x</span>
834
+ <span class="cline-any cline-yes">1x</span>
835
+ <span class="cline-any cline-yes">1x</span>
836
+ <span class="cline-any cline-yes">1x</span>
837
+ <span class="cline-any cline-yes">1x</span>
838
+ <span class="cline-any cline-yes">1x</span>
839
+ <span class="cline-any cline-yes">1x</span>
840
+ <span class="cline-any cline-yes">1x</span>
841
+ <span class="cline-any cline-yes">1x</span>
842
+ <span class="cline-any cline-yes">1x</span>
843
+ <span class="cline-any cline-yes">1x</span>
844
+ <span class="cline-any cline-yes">1x</span>
845
+ <span class="cline-any cline-yes">1x</span>
846
+ <span class="cline-any cline-yes">1x</span>
847
+ <span class="cline-any cline-yes">1x</span>
848
+ <span class="cline-any cline-yes">1x</span>
849
+ <span class="cline-any cline-yes">1x</span>
850
+ <span class="cline-any cline-yes">1x</span>
851
+ <span class="cline-any cline-yes">1x</span>
852
+ <span class="cline-any cline-yes">1x</span>
853
+ <span class="cline-any cline-yes">1x</span>
854
+ <span class="cline-any cline-yes">1x</span>
855
+ <span class="cline-any cline-yes">1x</span>
856
+ <span class="cline-any cline-yes">1x</span>
857
+ <span class="cline-any cline-yes">1x</span>
858
+ <span class="cline-any cline-yes">10x</span>
859
+ <span class="cline-any cline-yes">10x</span>
860
+ <span class="cline-any cline-yes">10x</span>
861
+ <span class="cline-any cline-yes">10x</span>
862
+ <span class="cline-any cline-yes">10x</span>
863
+ <span class="cline-any cline-yes">10x</span>
864
+ <span class="cline-any cline-yes">10x</span>
865
+ <span class="cline-any cline-yes">10x</span>
866
+ <span class="cline-any cline-yes">10x</span>
867
+ <span class="cline-any cline-no">&nbsp;</span>
868
+ <span class="cline-any cline-no">&nbsp;</span>
869
+ <span class="cline-any cline-yes">10x</span>
870
+ <span class="cline-any cline-yes">1x</span>
871
+ <span class="cline-any cline-yes">1x</span>
872
+ <span class="cline-any cline-yes">1x</span>
873
+ <span class="cline-any cline-yes">1x</span>
874
+ <span class="cline-any cline-yes">1x</span>
875
+ <span class="cline-any cline-yes">27x</span>
876
+ <span class="cline-any cline-yes">27x</span>
877
+ <span class="cline-any cline-yes">27x</span>
878
+ <span class="cline-any cline-yes">27x</span>
879
+ <span class="cline-any cline-no">&nbsp;</span>
880
+ <span class="cline-any cline-yes">27x</span>
881
+ <span class="cline-any cline-no">&nbsp;</span>
882
+ <span class="cline-any cline-no">&nbsp;</span>
883
+ <span class="cline-any cline-no">&nbsp;</span>
884
+ <span class="cline-any cline-no">&nbsp;</span>
885
+ <span class="cline-any cline-no">&nbsp;</span>
886
+ <span class="cline-any cline-no">&nbsp;</span>
887
+ <span class="cline-any cline-no">&nbsp;</span>
888
+ <span class="cline-any cline-no">&nbsp;</span>
889
+ <span class="cline-any cline-no">&nbsp;</span>
890
+ <span class="cline-any cline-yes">27x</span>
891
+ <span class="cline-any cline-yes">1x</span>
892
+ <span class="cline-any cline-yes">1x</span>
893
+ <span class="cline-any cline-yes">1x</span>
894
+ <span class="cline-any cline-yes">1x</span>
895
+ <span class="cline-any cline-yes">1x</span>
896
+ <span class="cline-any cline-yes">3x</span>
897
+ <span class="cline-any cline-yes">3x</span>
898
+ <span class="cline-any cline-yes">3x</span>
899
+ <span class="cline-any cline-yes">3x</span>
900
+ <span class="cline-any cline-yes">3x</span>
901
+ <span class="cline-any cline-no">&nbsp;</span>
902
+ <span class="cline-any cline-no">&nbsp;</span>
903
+ <span class="cline-any cline-yes">3x</span>
904
+ <span class="cline-any cline-yes">1x</span>
905
+ <span class="cline-any cline-yes">1x</span>
906
+ <span class="cline-any cline-yes">1x</span>
907
+ <span class="cline-any cline-yes">1x</span>
908
+ <span class="cline-any cline-yes">1x</span>
909
+ <span class="cline-any cline-no">&nbsp;</span>
910
+ <span class="cline-any cline-no">&nbsp;</span>
911
+ <span class="cline-any cline-no">&nbsp;</span>
912
+ <span class="cline-any cline-no">&nbsp;</span>
913
+ <span class="cline-any cline-no">&nbsp;</span>
914
+ <span class="cline-any cline-no">&nbsp;</span>
915
+ <span class="cline-any cline-no">&nbsp;</span>
916
+ <span class="cline-any cline-yes">1x</span>
917
+ <span class="cline-any cline-yes">1x</span>
918
+ <span class="cline-any cline-yes">1x</span>
919
+ <span class="cline-any cline-yes">1x</span>
920
+ <span class="cline-any cline-yes">1x</span>
921
+ <span class="cline-any cline-yes">1x</span>
922
+ <span class="cline-any cline-yes">1x</span>
923
+ <span class="cline-any cline-yes">1x</span>
924
+ <span class="cline-any cline-yes">1x</span>
925
+ <span class="cline-any cline-yes">1x</span>
926
+ <span class="cline-any cline-yes">1x</span>
927
+ <span class="cline-any cline-yes">1x</span>
928
+ <span class="cline-any cline-yes">1x</span>
929
+ <span class="cline-any cline-yes">1x</span>
930
+ <span class="cline-any cline-yes">1x</span>
931
+ <span class="cline-any cline-yes">1x</span>
932
+ <span class="cline-any cline-yes">1x</span>
933
+ <span class="cline-any cline-yes">1x</span>
934
+ <span class="cline-any cline-yes">1x</span>
935
+ <span class="cline-any cline-yes">1x</span>
936
+ <span class="cline-any cline-yes">1x</span>
937
+ <span class="cline-any cline-yes">1x</span>
938
+ <span class="cline-any cline-yes">1x</span>
939
+ <span class="cline-any cline-yes">1x</span>
940
+ <span class="cline-any cline-yes">1x</span>
941
+ <span class="cline-any cline-yes">1x</span>
942
+ <span class="cline-any cline-yes">1x</span>
943
+ <span class="cline-any cline-yes">1x</span>
944
+ <span class="cline-any cline-yes">1x</span>
945
+ <span class="cline-any cline-yes">1x</span>
946
+ <span class="cline-any cline-yes">1x</span>
947
+ <span class="cline-any cline-yes">1x</span>
948
+ <span class="cline-any cline-yes">1x</span>
949
+ <span class="cline-any cline-yes">1x</span>
950
+ <span class="cline-any cline-yes">1x</span>
951
+ <span class="cline-any cline-yes">1x</span>
952
+ <span class="cline-any cline-yes">1x</span>
953
+ <span class="cline-any cline-yes">1x</span>
954
+ <span class="cline-any cline-yes">1x</span>
955
+ <span class="cline-any cline-yes">1x</span>
956
+ <span class="cline-any cline-yes">1x</span>
957
+ <span class="cline-any cline-yes">1x</span>
958
+ <span class="cline-any cline-yes">1x</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">1x</span>
965
+ <span class="cline-any cline-yes">1x</span>
966
+ <span class="cline-any cline-yes">1x</span>
967
+ <span class="cline-any cline-yes">1x</span>
968
+ <span class="cline-any cline-yes">1x</span>
969
+ <span class="cline-any cline-yes">1x</span>
970
+ <span class="cline-any cline-yes">1x</span>
971
+ <span class="cline-any cline-yes">1x</span>
972
+ <span class="cline-any cline-yes">1x</span>
973
+ <span class="cline-any cline-yes">1x</span>
974
+ <span class="cline-any cline-yes">1x</span>
975
+ <span class="cline-any cline-yes">1x</span>
976
+ <span class="cline-any cline-yes">27x</span>
977
+ <span class="cline-any cline-yes">27x</span>
978
+ <span class="cline-any cline-yes">27x</span>
979
+ <span class="cline-any cline-yes">27x</span>
980
+ <span class="cline-any cline-yes">27x</span>
981
+ <span class="cline-any cline-yes">27x</span>
982
+ <span class="cline-any cline-yes">27x</span>
983
+ <span class="cline-any cline-yes">27x</span>
984
+ <span class="cline-any cline-yes">27x</span>
985
+ <span class="cline-any cline-yes">27x</span>
986
+ <span class="cline-any cline-yes">27x</span>
987
+ <span class="cline-any cline-yes">27x</span>
988
+ <span class="cline-any cline-yes">27x</span>
989
+ <span class="cline-any cline-yes">27x</span>
990
+ <span class="cline-any cline-yes">27x</span>
991
+ <span class="cline-any cline-yes">27x</span>
992
+ <span class="cline-any cline-yes">27x</span>
993
+ <span class="cline-any cline-yes">27x</span>
994
+ <span class="cline-any cline-yes">27x</span>
995
+ <span class="cline-any cline-yes">27x</span>
996
+ <span class="cline-any cline-yes">27x</span>
997
+ <span class="cline-any cline-yes">27x</span>
998
+ <span class="cline-any cline-yes">27x</span>
999
+ <span class="cline-any cline-yes">27x</span>
1000
+ <span class="cline-any cline-yes">27x</span>
1001
+ <span class="cline-any cline-yes">27x</span>
1002
+ <span class="cline-any cline-yes">27x</span>
1003
+ <span class="cline-any cline-yes">27x</span>
1004
+ <span class="cline-any cline-yes">27x</span>
1005
+ <span class="cline-any cline-yes">27x</span>
1006
+ <span class="cline-any cline-yes">27x</span>
1007
+ <span class="cline-any cline-yes">27x</span>
1008
+ <span class="cline-any cline-yes">27x</span>
1009
+ <span class="cline-any cline-yes">27x</span>
1010
+ <span class="cline-any cline-yes">27x</span>
1011
+ <span class="cline-any cline-yes">27x</span>
1012
+ <span class="cline-any cline-yes">27x</span>
1013
+ <span class="cline-any cline-yes">27x</span>
1014
+ <span class="cline-any cline-yes">27x</span>
1015
+ <span class="cline-any cline-yes">27x</span>
1016
+ <span class="cline-any cline-yes">27x</span>
1017
+ <span class="cline-any cline-yes">27x</span>
1018
+ <span class="cline-any cline-yes">27x</span>
1019
+ <span class="cline-any cline-yes">27x</span>
1020
+ <span class="cline-any cline-yes">27x</span>
1021
+ <span class="cline-any cline-yes">27x</span>
1022
+ <span class="cline-any cline-yes">27x</span>
1023
+ <span class="cline-any cline-yes">27x</span>
1024
+ <span class="cline-any cline-yes">27x</span>
1025
+ <span class="cline-any cline-yes">27x</span>
1026
+ <span class="cline-any cline-yes">27x</span>
1027
+ <span class="cline-any cline-yes">27x</span>
1028
+ <span class="cline-any cline-yes">27x</span>
1029
+ <span class="cline-any cline-yes">27x</span>
1030
+ <span class="cline-any cline-yes">27x</span>
1031
+ <span class="cline-any cline-yes">27x</span>
1032
+ <span class="cline-any cline-yes">27x</span>
1033
+ <span class="cline-any cline-yes">27x</span>
1034
+ <span class="cline-any cline-yes">27x</span>
1035
+ <span class="cline-any cline-yes">27x</span>
1036
+ <span class="cline-any cline-yes">27x</span>
1037
+ <span class="cline-any cline-yes">27x</span>
1038
+ <span class="cline-any cline-yes">27x</span>
1039
+ <span class="cline-any cline-yes">27x</span>
1040
+ <span class="cline-any cline-yes">27x</span>
1041
+ <span class="cline-any cline-yes">27x</span>
1042
+ <span class="cline-any cline-yes">27x</span>
1043
+ <span class="cline-any cline-yes">27x</span>
1044
+ <span class="cline-any cline-yes">27x</span>
1045
+ <span class="cline-any cline-yes">27x</span>
1046
+ <span class="cline-any cline-yes">27x</span>
1047
+ <span class="cline-any cline-yes">27x</span>
1048
+ <span class="cline-any cline-yes">27x</span>
1049
+ <span class="cline-any cline-yes">27x</span>
1050
+ <span class="cline-any cline-yes">27x</span>
1051
+ <span class="cline-any cline-yes">27x</span>
1052
+ <span class="cline-any cline-yes">27x</span>
1053
+ <span class="cline-any cline-yes">27x</span>
1054
+ <span class="cline-any cline-yes">27x</span>
1055
+ <span class="cline-any cline-yes">27x</span>
1056
+ <span class="cline-any cline-yes">27x</span>
1057
+ <span class="cline-any cline-yes">27x</span>
1058
+ <span class="cline-any cline-yes">27x</span>
1059
+ <span class="cline-any cline-yes">27x</span>
1060
+ <span class="cline-any cline-yes">27x</span>
1061
+ <span class="cline-any cline-yes">27x</span>
1062
+ <span class="cline-any cline-yes">27x</span>
1063
+ <span class="cline-any cline-yes">27x</span>
1064
+ <span class="cline-any cline-yes">27x</span>
1065
+ <span class="cline-any cline-yes">27x</span>
1066
+ <span class="cline-any cline-no">&nbsp;</span>
1067
+ <span class="cline-any cline-no">&nbsp;</span>
1068
+ <span class="cline-any cline-no">&nbsp;</span>
1069
+ <span class="cline-any cline-no">&nbsp;</span>
1070
+ <span class="cline-any cline-no">&nbsp;</span>
1071
+ <span class="cline-any cline-no">&nbsp;</span>
1072
+ <span class="cline-any cline-no">&nbsp;</span>
1073
+ <span class="cline-any cline-no">&nbsp;</span>
1074
+ <span class="cline-any cline-no">&nbsp;</span>
1075
+ <span class="cline-any cline-no">&nbsp;</span>
1076
+ <span class="cline-any cline-no">&nbsp;</span>
1077
+ <span class="cline-any cline-no">&nbsp;</span>
1078
+ <span class="cline-any cline-no">&nbsp;</span>
1079
+ <span class="cline-any cline-no">&nbsp;</span>
1080
+ <span class="cline-any cline-no">&nbsp;</span>
1081
+ <span class="cline-any cline-yes">27x</span>
1082
+ <span class="cline-any cline-yes">27x</span>
1083
+ <span class="cline-any cline-yes">27x</span>
1084
+ <span class="cline-any cline-yes">27x</span>
1085
+ <span class="cline-any cline-yes">27x</span>
1086
+ <span class="cline-any cline-yes">27x</span>
1087
+ <span class="cline-any cline-yes">27x</span>
1088
+ <span class="cline-any cline-yes">27x</span>
1089
+ <span class="cline-any cline-yes">27x</span>
1090
+ <span class="cline-any cline-yes">27x</span>
1091
+ <span class="cline-any cline-yes">27x</span>
1092
+ <span class="cline-any cline-yes">27x</span>
1093
+ <span class="cline-any cline-yes">27x</span>
1094
+ <span class="cline-any cline-yes">27x</span>
1095
+ <span class="cline-any cline-yes">27x</span>
1096
+ <span class="cline-any cline-yes">27x</span>
1097
+ <span class="cline-any cline-yes">27x</span>
1098
+ <span class="cline-any cline-yes">27x</span>
1099
+ <span class="cline-any cline-yes">27x</span>
1100
+ <span class="cline-any cline-yes">27x</span>
1101
+ <span class="cline-any cline-yes">27x</span>
1102
+ <span class="cline-any cline-yes">27x</span>
1103
+ <span class="cline-any cline-yes">8x</span>
1104
+ <span class="cline-any cline-yes">8x</span>
1105
+ <span class="cline-any cline-yes">8x</span>
1106
+ <span class="cline-any cline-yes">8x</span>
1107
+ <span class="cline-any cline-yes">8x</span>
1108
+ <span class="cline-any cline-yes">8x</span>
1109
+ <span class="cline-any cline-yes">8x</span>
1110
+ <span class="cline-any cline-yes">8x</span>
1111
+ <span class="cline-any cline-yes">8x</span>
1112
+ <span class="cline-any cline-yes">8x</span>
1113
+ <span class="cline-any cline-yes">8x</span>
1114
+ <span class="cline-any cline-yes">8x</span>
1115
+ <span class="cline-any cline-yes">8x</span>
1116
+ <span class="cline-any cline-yes">8x</span>
1117
+ <span class="cline-any cline-yes">8x</span>
1118
+ <span class="cline-any cline-yes">8x</span>
1119
+ <span class="cline-any cline-yes">8x</span>
1120
+ <span class="cline-any cline-yes">8x</span>
1121
+ <span class="cline-any cline-yes">7x</span>
1122
+ <span class="cline-any cline-yes">7x</span>
1123
+ <span class="cline-any cline-yes">7x</span>
1124
+ <span class="cline-any cline-yes">7x</span>
1125
+ <span class="cline-any cline-yes">7x</span>
1126
+ <span class="cline-any cline-yes">7x</span>
1127
+ <span class="cline-any cline-yes">7x</span>
1128
+ <span class="cline-any cline-yes">7x</span>
1129
+ <span class="cline-any cline-yes">7x</span>
1130
+ <span class="cline-any cline-yes">7x</span>
1131
+ <span class="cline-any cline-yes">7x</span>
1132
+ <span class="cline-any cline-yes">7x</span>
1133
+ <span class="cline-any cline-yes">7x</span>
1134
+ <span class="cline-any cline-yes">7x</span>
1135
+ <span class="cline-any cline-yes">7x</span>
1136
+ <span class="cline-any cline-yes">7x</span>
1137
+ <span class="cline-any cline-yes">7x</span>
1138
+ <span class="cline-any cline-yes">8x</span>
1139
+ <span class="cline-any cline-yes">1x</span>
1140
+ <span class="cline-any cline-yes">1x</span>
1141
+ <span class="cline-any cline-yes">1x</span>
1142
+ <span class="cline-any cline-yes">1x</span>
1143
+ <span class="cline-any cline-yes">1x</span>
1144
+ <span class="cline-any cline-yes">1x</span>
1145
+ <span class="cline-any cline-yes">8x</span>
1146
+ <span class="cline-any cline-yes">27x</span>
1147
+ <span class="cline-any cline-yes">27x</span>
1148
+ <span class="cline-any cline-yes">27x</span>
1149
+ <span class="cline-any cline-yes">27x</span>
1150
+ <span class="cline-any cline-yes">27x</span>
1151
+ <span class="cline-any cline-yes">27x</span>
1152
+ <span class="cline-any cline-yes">27x</span>
1153
+ <span class="cline-any cline-yes">27x</span>
1154
+ <span class="cline-any cline-yes">1x</span>
1155
+ <span class="cline-any cline-yes">1x</span>
1156
+ <span class="cline-any cline-yes">1x</span>
1157
+ <span class="cline-any cline-yes">1x</span>
1158
+ <span class="cline-any cline-yes">1x</span>
1159
+ <span class="cline-any cline-yes">1x</span>
1160
+ <span class="cline-any cline-yes">1x</span>
1161
+ <span class="cline-any cline-yes">27x</span>
1162
+ <span class="cline-any cline-yes">27x</span>
1163
+ <span class="cline-any cline-yes">27x</span>
1164
+ <span class="cline-any cline-yes">27x</span>
1165
+ <span class="cline-any cline-yes">27x</span>
1166
+ <span class="cline-any cline-yes">27x</span>
1167
+ <span class="cline-any cline-yes">27x</span>
1168
+ <span class="cline-any cline-yes">1x</span>
1169
+ <span class="cline-any cline-yes">1x</span>
1170
+ <span class="cline-any cline-yes">1x</span>
1171
+ <span class="cline-any cline-yes">1x</span>
1172
+ <span class="cline-any cline-yes">27x</span>
1173
+ <span class="cline-any cline-yes">27x</span>
1174
+ <span class="cline-any cline-yes">27x</span>
1175
+ <span class="cline-any cline-yes">27x</span>
1176
+ <span class="cline-any cline-yes">27x</span>
1177
+ <span class="cline-any cline-yes">27x</span>
1178
+ <span class="cline-any cline-yes">27x</span>
1179
+ <span class="cline-any cline-yes">27x</span>
1180
+ <span class="cline-any cline-yes">27x</span>
1181
+ <span class="cline-any cline-yes">27x</span>
1182
+ <span class="cline-any cline-yes">27x</span>
1183
+ <span class="cline-any cline-yes">27x</span>
1184
+ <span class="cline-any cline-yes">27x</span>
1185
+ <span class="cline-any cline-yes">27x</span>
1186
+ <span class="cline-any cline-yes">27x</span>
1187
+ <span class="cline-any cline-yes">27x</span>
1188
+ <span class="cline-any cline-yes">27x</span>
1189
+ <span class="cline-any cline-yes">27x</span>
1190
+ <span class="cline-any cline-yes">27x</span>
1191
+ <span class="cline-any cline-yes">27x</span>
1192
+ <span class="cline-any cline-yes">27x</span>
1193
+ <span class="cline-any cline-yes">27x</span>
1194
+ <span class="cline-any cline-no">&nbsp;</span>
1195
+ <span class="cline-any cline-no">&nbsp;</span>
1196
+ <span class="cline-any cline-no">&nbsp;</span>
1197
+ <span class="cline-any cline-no">&nbsp;</span>
1198
+ <span class="cline-any cline-no">&nbsp;</span>
1199
+ <span class="cline-any cline-no">&nbsp;</span>
1200
+ <span class="cline-any cline-no">&nbsp;</span>
1201
+ <span class="cline-any cline-no">&nbsp;</span>
1202
+ <span class="cline-any cline-no">&nbsp;</span>
1203
+ <span class="cline-any cline-no">&nbsp;</span>
1204
+ <span class="cline-any cline-no">&nbsp;</span>
1205
+ <span class="cline-any cline-no">&nbsp;</span>
1206
+ <span class="cline-any cline-no">&nbsp;</span>
1207
+ <span class="cline-any cline-no">&nbsp;</span>
1208
+ <span class="cline-any cline-no">&nbsp;</span>
1209
+ <span class="cline-any cline-no">&nbsp;</span>
1210
+ <span class="cline-any cline-no">&nbsp;</span>
1211
+ <span class="cline-any cline-no">&nbsp;</span>
1212
+ <span class="cline-any cline-no">&nbsp;</span>
1213
+ <span class="cline-any cline-no">&nbsp;</span>
1214
+ <span class="cline-any cline-no">&nbsp;</span>
1215
+ <span class="cline-any cline-no">&nbsp;</span>
1216
+ <span class="cline-any cline-no">&nbsp;</span>
1217
+ <span class="cline-any cline-no">&nbsp;</span>
1218
+ <span class="cline-any cline-no">&nbsp;</span>
1219
+ <span class="cline-any cline-no">&nbsp;</span>
1220
+ <span class="cline-any cline-no">&nbsp;</span>
1221
+ <span class="cline-any cline-yes">27x</span>
1222
+ <span class="cline-any cline-yes">27x</span>
1223
+ <span class="cline-any cline-yes">27x</span>
1224
+ <span class="cline-any cline-yes">27x</span>
1225
+ <span class="cline-any cline-yes">27x</span>
1226
+ <span class="cline-any cline-yes">27x</span>
1227
+ <span class="cline-any cline-yes">27x</span>
1228
+ <span class="cline-any cline-yes">27x</span>
1229
+ <span class="cline-any cline-yes">27x</span>
1230
+ <span class="cline-any cline-yes">27x</span>
1231
+ <span class="cline-any cline-yes">27x</span>
1232
+ <span class="cline-any cline-yes">27x</span>
1233
+ <span class="cline-any cline-yes">27x</span>
1234
+ <span class="cline-any cline-yes">27x</span>
1235
+ <span class="cline-any cline-yes">27x</span>
1236
+ <span class="cline-any cline-yes">27x</span>
1237
+ <span class="cline-any cline-yes">27x</span>
1238
+ <span class="cline-any cline-yes">27x</span>
1239
+ <span class="cline-any cline-yes">27x</span>
1240
+ <span class="cline-any cline-yes">27x</span>
1241
+ <span class="cline-any cline-yes">27x</span>
1242
+ <span class="cline-any cline-yes">27x</span>
1243
+ <span class="cline-any cline-no">&nbsp;</span>
1244
+ <span class="cline-any cline-no">&nbsp;</span>
1245
+ <span class="cline-any cline-no">&nbsp;</span>
1246
+ <span class="cline-any cline-no">&nbsp;</span>
1247
+ <span class="cline-any cline-no">&nbsp;</span>
1248
+ <span class="cline-any cline-no">&nbsp;</span>
1249
+ <span class="cline-any cline-no">&nbsp;</span>
1250
+ <span class="cline-any cline-no">&nbsp;</span>
1251
+ <span class="cline-any cline-no">&nbsp;</span>
1252
+ <span class="cline-any cline-no">&nbsp;</span>
1253
+ <span class="cline-any cline-no">&nbsp;</span>
1254
+ <span class="cline-any cline-no">&nbsp;</span>
1255
+ <span class="cline-any cline-no">&nbsp;</span>
1256
+ <span class="cline-any cline-no">&nbsp;</span>
1257
+ <span class="cline-any cline-no">&nbsp;</span>
1258
+ <span class="cline-any cline-no">&nbsp;</span>
1259
+ <span class="cline-any cline-no">&nbsp;</span>
1260
+ <span class="cline-any cline-no">&nbsp;</span>
1261
+ <span class="cline-any cline-no">&nbsp;</span>
1262
+ <span class="cline-any cline-no">&nbsp;</span>
1263
+ <span class="cline-any cline-no">&nbsp;</span>
1264
+ <span class="cline-any cline-no">&nbsp;</span>
1265
+ <span class="cline-any cline-no">&nbsp;</span>
1266
+ <span class="cline-any cline-no">&nbsp;</span>
1267
+ <span class="cline-any cline-no">&nbsp;</span>
1268
+ <span class="cline-any cline-no">&nbsp;</span>
1269
+ <span class="cline-any cline-no">&nbsp;</span>
1270
+ <span class="cline-any cline-no">&nbsp;</span>
1271
+ <span class="cline-any cline-yes">27x</span>
1272
+ <span class="cline-any cline-yes">27x</span>
1273
+ <span class="cline-any cline-yes">27x</span>
1274
+ <span class="cline-any cline-yes">27x</span>
1275
+ <span class="cline-any cline-yes">27x</span>
1276
+ <span class="cline-any cline-yes">27x</span>
1277
+ <span class="cline-any cline-yes">27x</span>
1278
+ <span class="cline-any cline-yes">27x</span>
1279
+ <span class="cline-any cline-yes">27x</span>
1280
+ <span class="cline-any cline-yes">1x</span>
1281
+ <span class="cline-any cline-yes">1x</span>
1282
+ <span class="cline-any cline-yes">1x</span>
1283
+ <span class="cline-any cline-yes">1x</span>
1284
+ <span class="cline-any cline-yes">1x</span>
1285
+ <span class="cline-any cline-yes">1x</span>
1286
+ <span class="cline-any cline-yes">1x</span>
1287
+ <span class="cline-any cline-yes">1x</span>
1288
+ <span class="cline-any cline-yes">1x</span>
1289
+ <span class="cline-any cline-yes">1x</span>
1290
+ <span class="cline-any cline-yes">1x</span>
1291
+ <span class="cline-any cline-yes">1x</span>
1292
+ <span class="cline-any cline-yes">1x</span>
1293
+ <span class="cline-any cline-yes">1x</span>
1294
+ <span class="cline-any cline-yes">1x</span>
1295
+ <span class="cline-any cline-yes">27x</span>
1296
+ <span class="cline-any cline-yes">27x</span>
1297
+ <span class="cline-any cline-yes">27x</span>
1298
+ <span class="cline-any cline-yes">27x</span>
1299
+ <span class="cline-any cline-yes">27x</span>
1300
+ <span class="cline-any cline-yes">27x</span>
1301
+ <span class="cline-any cline-yes">27x</span>
1302
+ <span class="cline-any cline-yes">27x</span>
1303
+ <span class="cline-any cline-yes">27x</span>
1304
+ <span class="cline-any cline-yes">27x</span>
1305
+ <span class="cline-any cline-yes">27x</span>
1306
+ <span class="cline-any cline-yes">27x</span>
1307
+ <span class="cline-any cline-yes">27x</span>
1308
+ <span class="cline-any cline-yes">27x</span>
1309
+ <span class="cline-any cline-yes">27x</span>
1310
+ <span class="cline-any cline-yes">27x</span>
1311
+ <span class="cline-any cline-yes">2x</span>
1312
+ <span class="cline-any cline-yes">1x</span>
1313
+ <span class="cline-any cline-yes">1x</span>
1314
+ <span class="cline-any cline-yes">1x</span>
1315
+ <span class="cline-any cline-yes">1x</span>
1316
+ <span class="cline-any cline-yes">1x</span>
1317
+ <span class="cline-any cline-yes">1x</span>
1318
+ <span class="cline-any cline-yes">1x</span>
1319
+ <span class="cline-any cline-yes">1x</span>
1320
+ <span class="cline-any cline-yes">1x</span>
1321
+ <span class="cline-any cline-yes">1x</span>
1322
+ <span class="cline-any cline-yes">1x</span>
1323
+ <span class="cline-any cline-yes">1x</span>
1324
+ <span class="cline-any cline-yes">1x</span>
1325
+ <span class="cline-any cline-yes">1x</span>
1326
+ <span class="cline-any cline-yes">1x</span>
1327
+ <span class="cline-any cline-yes">1x</span>
1328
+ <span class="cline-any cline-yes">1x</span>
1329
+ <span class="cline-any cline-yes">2x</span>
1330
+ <span class="cline-any cline-yes">27x</span>
1331
+ <span class="cline-any cline-yes">27x</span>
1332
+ <span class="cline-any cline-yes">27x</span>
1333
+ <span class="cline-any cline-yes">27x</span>
1334
+ <span class="cline-any cline-yes">27x</span>
1335
+ <span class="cline-any cline-yes">27x</span>
1336
+ <span class="cline-any cline-yes">27x</span>
1337
+ <span class="cline-any cline-yes">27x</span>
1338
+ <span class="cline-any cline-yes">27x</span>
1339
+ <span class="cline-any cline-yes">27x</span>
1340
+ <span class="cline-any cline-yes">27x</span>
1341
+ <span class="cline-any cline-yes">27x</span>
1342
+ <span class="cline-any cline-yes">27x</span>
1343
+ <span class="cline-any cline-yes">27x</span>
1344
+ <span class="cline-any cline-yes">27x</span>
1345
+ <span class="cline-any cline-yes">27x</span>
1346
+ <span class="cline-any cline-yes">1x</span>
1347
+ <span class="cline-any cline-no">&nbsp;</span>
1348
+ <span class="cline-any cline-no">&nbsp;</span>
1349
+ <span class="cline-any cline-yes">1x</span>
1350
+ <span class="cline-any cline-yes">1x</span>
1351
+ <span class="cline-any cline-yes">1x</span>
1352
+ <span class="cline-any cline-yes">1x</span>
1353
+ <span class="cline-any cline-yes">1x</span>
1354
+ <span class="cline-any cline-yes">1x</span>
1355
+ <span class="cline-any cline-yes">1x</span>
1356
+ <span class="cline-any cline-yes">1x</span>
1357
+ <span class="cline-any cline-yes">1x</span>
1358
+ <span class="cline-any cline-yes">1x</span>
1359
+ <span class="cline-any cline-yes">1x</span>
1360
+ <span class="cline-any cline-yes">1x</span>
1361
+ <span class="cline-any cline-yes">1x</span>
1362
+ <span class="cline-any cline-yes">1x</span>
1363
+ <span class="cline-any cline-yes">1x</span>
1364
+ <span class="cline-any cline-yes">1x</span>
1365
+ <span class="cline-any cline-yes">1x</span>
1366
+ <span class="cline-any cline-yes">1x</span>
1367
+ <span class="cline-any cline-yes">1x</span>
1368
+ <span class="cline-any cline-yes">27x</span>
1369
+ <span class="cline-any cline-yes">27x</span>
1370
+ <span class="cline-any cline-yes">27x</span>
1371
+ <span class="cline-any cline-yes">27x</span>
1372
+ <span class="cline-any cline-yes">27x</span>
1373
+ <span class="cline-any cline-yes">27x</span>
1374
+ <span class="cline-any cline-yes">27x</span>
1375
+ <span class="cline-any cline-yes">27x</span>
1376
+ <span class="cline-any cline-yes">27x</span>
1377
+ <span class="cline-any cline-yes">27x</span>
1378
+ <span class="cline-any cline-yes">27x</span>
1379
+ <span class="cline-any cline-yes">27x</span>
1380
+ <span class="cline-any cline-yes">27x</span>
1381
+ <span class="cline-any cline-yes">27x</span>
1382
+ <span class="cline-any cline-yes">27x</span>
1383
+ <span class="cline-any cline-yes">27x</span>
1384
+ <span class="cline-any cline-yes">27x</span>
1385
+ <span class="cline-any cline-no">&nbsp;</span>
1386
+ <span class="cline-any cline-no">&nbsp;</span>
1387
+ <span class="cline-any cline-yes">27x</span>
1388
+ <span class="cline-any cline-yes">27x</span>
1389
+ <span class="cline-any cline-yes">27x</span>
1390
+ <span class="cline-any cline-yes">27x</span>
1391
+ <span class="cline-any cline-yes">27x</span>
1392
+ <span class="cline-any cline-yes">27x</span>
1393
+ <span class="cline-any cline-yes">27x</span>
1394
+ <span class="cline-any cline-yes">27x</span>
1395
+ <span class="cline-any cline-yes">27x</span>
1396
+ <span class="cline-any cline-yes">27x</span>
1397
+ <span class="cline-any cline-yes">27x</span>
1398
+ <span class="cline-any cline-yes">27x</span>
1399
+ <span class="cline-any cline-yes">27x</span>
1400
+ <span class="cline-any cline-yes">27x</span>
1401
+ <span class="cline-any cline-yes">27x</span>
1402
+ <span class="cline-any cline-yes">27x</span>
1403
+ <span class="cline-any cline-yes">1x</span>
1404
+ <span class="cline-any cline-no">&nbsp;</span>
1405
+ <span class="cline-any cline-no">&nbsp;</span>
1406
+ <span class="cline-any cline-yes">1x</span>
1407
+ <span class="cline-any cline-yes">1x</span>
1408
+ <span class="cline-any cline-yes">1x</span>
1409
+ <span class="cline-any cline-yes">1x</span>
1410
+ <span class="cline-any cline-yes">1x</span>
1411
+ <span class="cline-any cline-yes">1x</span>
1412
+ <span class="cline-any cline-yes">1x</span>
1413
+ <span class="cline-any cline-yes">1x</span>
1414
+ <span class="cline-any cline-yes">1x</span>
1415
+ <span class="cline-any cline-yes">1x</span>
1416
+ <span class="cline-any cline-yes">1x</span>
1417
+ <span class="cline-any cline-yes">1x</span>
1418
+ <span class="cline-any cline-yes">1x</span>
1419
+ <span class="cline-any cline-yes">1x</span>
1420
+ <span class="cline-any cline-yes">1x</span>
1421
+ <span class="cline-any cline-yes">1x</span>
1422
+ <span class="cline-any cline-yes">1x</span>
1423
+ <span class="cline-any cline-yes">27x</span>
1424
+ <span class="cline-any cline-yes">27x</span>
1425
+ <span class="cline-any cline-yes">27x</span>
1426
+ <span class="cline-any cline-yes">27x</span>
1427
+ <span class="cline-any cline-yes">27x</span>
1428
+ <span class="cline-any cline-yes">27x</span>
1429
+ <span class="cline-any cline-yes">27x</span>
1430
+ <span class="cline-any cline-yes">27x</span>
1431
+ <span class="cline-any cline-yes">27x</span>
1432
+ <span class="cline-any cline-yes">27x</span>
1433
+ <span class="cline-any cline-yes">27x</span>
1434
+ <span class="cline-any cline-yes">2x</span>
1435
+ <span class="cline-any cline-yes">2x</span>
1436
+ <span class="cline-any cline-yes">2x</span>
1437
+ <span class="cline-any cline-yes">27x</span>
1438
+ <span class="cline-any cline-yes">27x</span>
1439
+ <span class="cline-any cline-yes">27x</span>
1440
+ <span class="cline-any cline-yes">27x</span>
1441
+ <span class="cline-any cline-yes">27x</span>
1442
+ <span class="cline-any cline-yes">27x</span>
1443
+ <span class="cline-any cline-yes">27x</span>
1444
+ <span class="cline-any cline-yes">27x</span>
1445
+ <span class="cline-any cline-yes">27x</span>
1446
+ <span class="cline-any cline-yes">27x</span>
1447
+ <span class="cline-any cline-yes">10x</span>
1448
+ <span class="cline-any cline-yes">10x</span>
1449
+ <span class="cline-any cline-yes">10x</span>
1450
+ <span class="cline-any cline-yes">10x</span>
1451
+ <span class="cline-any cline-yes">10x</span>
1452
+ <span class="cline-any cline-yes">10x</span>
1453
+ <span class="cline-any cline-yes">10x</span>
1454
+ <span class="cline-any cline-yes">10x</span>
1455
+ <span class="cline-any cline-yes">10x</span>
1456
+ <span class="cline-any cline-yes">10x</span>
1457
+ <span class="cline-any cline-yes">10x</span>
1458
+ <span class="cline-any cline-yes">10x</span>
1459
+ <span class="cline-any cline-yes">10x</span>
1460
+ <span class="cline-any cline-yes">10x</span>
1461
+ <span class="cline-any cline-yes">10x</span>
1462
+ <span class="cline-any cline-yes">10x</span>
1463
+ <span class="cline-any cline-yes">10x</span>
1464
+ <span class="cline-any cline-yes">27x</span>
1465
+ <span class="cline-any cline-yes">27x</span>
1466
+ <span class="cline-any cline-yes">27x</span>
1467
+ <span class="cline-any cline-yes">27x</span>
1468
+ <span class="cline-any cline-yes">2x</span>
1469
+ <span class="cline-any cline-yes">2x</span>
1470
+ <span class="cline-any cline-yes">2x</span>
1471
+ <span class="cline-any cline-yes">2x</span>
1472
+ <span class="cline-any cline-yes">2x</span>
1473
+ <span class="cline-any cline-yes">2x</span>
1474
+ <span class="cline-any cline-yes">2x</span>
1475
+ <span class="cline-any cline-yes">2x</span>
1476
+ <span class="cline-any cline-yes">2x</span>
1477
+ <span class="cline-any cline-yes">27x</span>
1478
+ <span class="cline-any cline-yes">27x</span>
1479
+ <span class="cline-any cline-yes">27x</span>
1480
+ <span class="cline-any cline-yes">27x</span>
1481
+ <span class="cline-any cline-yes">1x</span>
1482
+ <span class="cline-any cline-yes">1x</span>
1483
+ <span class="cline-any cline-yes">1x</span>
1484
+ <span class="cline-any cline-yes">1x</span>
1485
+ <span class="cline-any cline-yes">1x</span>
1486
+ <span class="cline-any cline-yes">1x</span>
1487
+ <span class="cline-any cline-yes">27x</span>
1488
+ <span class="cline-any cline-yes">27x</span>
1489
+ <span class="cline-any cline-yes">27x</span>
1490
+ <span class="cline-any cline-yes">27x</span>
1491
+ <span class="cline-any cline-yes">1x</span>
1492
+ <span class="cline-any cline-yes">1x</span>
1493
+ <span class="cline-any cline-yes">1x</span>
1494
+ <span class="cline-any cline-yes">1x</span>
1495
+ <span class="cline-any cline-yes">1x</span>
1496
+ <span class="cline-any cline-yes">27x</span>
1497
+ <span class="cline-any cline-yes">27x</span>
1498
+ <span class="cline-any cline-yes">27x</span>
1499
+ <span class="cline-any cline-yes">27x</span>
1500
+ <span class="cline-any cline-yes">27x</span>
1501
+ <span class="cline-any cline-yes">27x</span>
1502
+ <span class="cline-any cline-yes">27x</span>
1503
+ <span class="cline-any cline-yes">27x</span>
1504
+ <span class="cline-any cline-yes">11x</span>
1505
+ <span class="cline-any cline-yes">10x</span>
1506
+ <span class="cline-any cline-yes">10x</span>
1507
+ <span class="cline-any cline-yes">10x</span>
1508
+ <span class="cline-any cline-yes">10x</span>
1509
+ <span class="cline-any cline-yes">11x</span>
1510
+ <span class="cline-any cline-yes">11x</span>
1511
+ <span class="cline-any cline-yes">27x</span>
1512
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1513
+ * HSuite Native Connect
1514
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
1515
+ *
1516
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
1517
+ *
1518
+ * This file is part of HSuite Native Connect. For commercial licensing,
1519
+ * visit https://hsuite.finance/licensing
1520
+ */
1521
+ &nbsp;
1522
+ /**
1523
+ * @file p2p-native.provider.ts
1524
+ * @description P2P Native Provider for wallet connections (Nostr-first with P2P upgrade)
1525
+ *
1526
+ * Implements BaseWalletProvider for P2P connections using the Nostr-first protocol.
1527
+ * Enables single-QR scanning for cross-device wallet connections (both mobile and desktop).
1528
+ *
1529
+ * **Key Features:**
1530
+ * - Single QR code scanning (no answer QR needed!)
1531
+ * - Nostr-first communication with automatic P2P upgrade
1532
+ * - End-to-end encrypted (AES-GCM over Nostr, DTLS over WebRTC)
1533
+ * - No intermediary servers required
1534
+ * - Works on any network (WiFi, cellular, etc.)
1535
+ *
1536
+ * **Connection Flow:**
1537
+ * 1. dApp generates compact channel invite (hsc:connect?i=...)
1538
+ * 2. User scans QR with wallet (or clicks hsc: link on desktop)
1539
+ * 3. Wallet connects via Nostr relays
1540
+ * 4. User approves session in wallet
1541
+ * 5. P2P upgrade happens automatically in background
1542
+ */
1543
+ &nbsp;
1544
+ import { Injectable, NgZone, signal, computed, type Signal } from '@angular/core';
1545
+ import { getLogger } from '@hsuite/native-connect-sdk';
1546
+ &nbsp;
1547
+ import type { ConnectionStatus, ProviderMetadata, ProviderType } from '../../models/provider-types';
1548
+ import type { ConnectionConfig } from '../../models/provider-types';
1549
+ import type { UnifiedAccount } from '../../models/unified-account.model';
1550
+ import {
1551
+ BaseWalletProvider,
1552
+ type SignTransactionOptions,
1553
+ type SubmitTransactionOptions,
1554
+ type SignResult,
1555
+ type SubmitResult,
1556
+ type SignMessageOptions,
1557
+ type SignMessageResult,
1558
+ } from '../base-wallet-provider';
1559
+ &nbsp;
1560
+ import { P2PSessionManager, type P2PSession } from './p2p-session-manager';
1561
+ &nbsp;
1562
+ const logger = getLogger().scoped?.('P2PNativeProvider'<span class="branch-0 cbranch-no" title="branch not covered" >) ?? getLogger();</span>
1563
+ &nbsp;
1564
+ /**
1565
+ * Storage key for mobile session metadata (separate from hsuite-native)
1566
+ */
1567
+ const P2P_SESSION_STORAGE_KEY = 'hsuite.p2p.session';
1568
+ &nbsp;
1569
+ /**
1570
+ * Mobile Session Persistence
1571
+ *
1572
+ * Stores mobile P2P session metadata to localStorage for dApp reconnection.
1573
+ * Uses a separate key from hsuite-native to avoid conflicts.
1574
+ */
1575
+ class P2PSessionPersistence {
1576
+ /**
1577
+ * @param session
1578
+ * Persist mobile session to localStorage.
1579
+ */
1580
+ save(session: P2PSession): void {
1581
+ try {
1582
+ if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
1583
+ const payload = {
1584
+ ...session,
1585
+ timestamp: Date.now(),
1586
+ };
1587
+ window.localStorage.setItem(P2P_SESSION_STORAGE_KEY, JSON.stringify(payload));
1588
+ logger.debug('Mobile session persisted', { sessionId: session.sessionId });
1589
+ <span class="branch-0 cbranch-no" title="branch not covered" > } catch (error) {</span>
1590
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to persist mobile session', { error });</span>
1591
+ <span class="cstat-no" title="statement not covered" > }</span>
1592
+ }
1593
+ &nbsp;
1594
+ /**
1595
+ * Restore mobile session from localStorage.
1596
+ */
1597
+ restore(): (P2PSession &amp; { timestamp: number }) | null {
1598
+ try {
1599
+ if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return null;</span>
1600
+ const raw = window.localStorage.getItem(P2P_SESSION_STORAGE_KEY);
1601
+ if (!raw) return <span class="branch-0 cbranch-no" title="branch not covered" >null;</span>
1602
+ <span class="cstat-no" title="statement not covered" > const stored = JSON.parse(raw) as P2PSession &amp; { timestamp: number };</span>
1603
+ if (!stored?.sessionId) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1604
+ <span class="cstat-no" title="statement not covered" > this.clear();</span>
1605
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1606
+ <span class="cstat-no" title="statement not covered" > }</span>
1607
+ <span class="cstat-no" title="statement not covered" > logger.info('Restored mobile session metadata', { sessionId: stored.sessionId });</span>
1608
+ <span class="cstat-no" title="statement not covered" > return stored;</span>
1609
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
1610
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to restore mobile session', { error });</span>
1611
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1612
+ <span class="cstat-no" title="statement not covered" > }</span>
1613
+ }
1614
+ &nbsp;
1615
+ /**
1616
+ * Clear persisted mobile session.
1617
+ */
1618
+ clear(): void {
1619
+ try {
1620
+ if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
1621
+ window.localStorage.removeItem(P2P_SESSION_STORAGE_KEY);
1622
+ logger.debug('Mobile session cleared');
1623
+ <span class="branch-0 cbranch-no" title="branch not covered" > } catch (error) {</span>
1624
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to clear mobile session', { error });</span>
1625
+ <span class="cstat-no" title="statement not covered" > }</span>
1626
+ }
1627
+ &nbsp;
1628
+ /**
1629
+ * Check if a mobile session is stored.
1630
+ */
1631
+ <span class="fstat-no" title="function not covered" > hasStoredSession(): boolean {</span>
1632
+ <span class="cstat-no" title="statement not covered" > try {</span>
1633
+ <span class="cstat-no" title="statement not covered" > if (typeof window === 'undefined') return false;</span>
1634
+ <span class="cstat-no" title="statement not covered" > return !!window.localStorage.getItem(P2P_SESSION_STORAGE_KEY);</span>
1635
+ <span class="cstat-no" title="statement not covered" > } catch {</span>
1636
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1637
+ <span class="cstat-no" title="statement not covered" > }</span>
1638
+ <span class="cstat-no" title="statement not covered" > }</span>
1639
+ }
1640
+ &nbsp;
1641
+ /**
1642
+ * Connection state for the mobile native provider.
1643
+ *
1644
+ * States:
1645
+ * - disconnected: No connection
1646
+ * - generating_offer: Creating WebRTC offer for QR display
1647
+ * - awaiting_scan: QR displayed, waiting for wallet to scan
1648
+ * - connecting: WebRTC handshake in progress
1649
+ * - pending_approval: WebRTC connected, waiting for wallet user to approve
1650
+ * - connected: Session approved and fully connected
1651
+ * - error: An error occurred
1652
+ */
1653
+ export type P2PNativeConnectionState =
1654
+ | 'disconnected'
1655
+ | 'generating_offer'
1656
+ | 'awaiting_scan'
1657
+ | 'connecting'
1658
+ | 'pending_approval'
1659
+ | 'connected'
1660
+ | 'error';
1661
+ &nbsp;
1662
+ /**
1663
+ * Pairing offer result containing QR data
1664
+ */
1665
+ export interface PairingOfferResult {
1666
+ /** Encoded channel invite for QR code display (hsc:connect?i=...) */
1667
+ qrData: string;
1668
+ /** Session ID for this connection */
1669
+ sessionId?: string;
1670
+ /** Expiry timestamp */
1671
+ expiresAt: number;
1672
+ }
1673
+ &nbsp;
1674
+ /**
1675
+ * P2P Native Provider for cross-device wallet connections.
1676
+ *
1677
+ * @description
1678
+ * Enables secure P2P wallet connections via WebRTC for mobile and cross-device
1679
+ * scenarios. The dApp generates a QR code containing a channel invite, which
1680
+ * the mobile wallet scans to establish a direct encrypted connection.
1681
+ *
1682
+ * Key Features:
1683
+ * - **Single QR Code Flow**: No answer QR needed - just scan and connect
1684
+ * - **Nostr-First**: Uses Nostr relays for signaling and fallback
1685
+ * - **Automatic P2P Upgrade**: Upgrades to WebRTC for lower latency
1686
+ * - **End-to-End Encrypted**: AES-GCM over Nostr, DTLS over WebRTC
1687
+ * - **Session Persistence**: Supports reconnection after page reload
1688
+ *
1689
+ * Transport States (via `transportState` signal):
1690
+ * - `'nostr-only'` - Connected via Nostr relay only
1691
+ * - `'upgrading'` - P2P upgrade in progress
1692
+ * - `'p2p-connected'` - Direct P2P connection established
1693
+ * - `'p2p-failed'` - P2P upgrade failed, using Nostr fallback
1694
+ *
1695
+ * @publicApi
1696
+ */
1697
+ @Injectable({ providedIn: 'root' })
1698
+ export class P2PNativeProvider extends BaseWalletProvider {
1699
+ readonly id = 'mobile-native';
1700
+ &nbsp;
1701
+ readonly metadata: ProviderMetadata = {
1702
+ name: 'HSuite Mobile',
1703
+ type: 'mobile-native' as ProviderType,
1704
+ icon: 'phone-portrait-outline',
1705
+ description: 'Connect via QR code (P2P)',
1706
+ features: [
1707
+ 'Direct P2P connection',
1708
+ 'End-to-end encrypted',
1709
+ 'No server required',
1710
+ 'Works on any network',
1711
+ ],
1712
+ };
1713
+ &nbsp;
1714
+ // Internal state signals
1715
+ private readonly _status = signal&lt;ConnectionStatus&gt;('disconnected');
1716
+ private readonly _accounts = signal&lt;UnifiedAccount[]&gt;([]);
1717
+ private readonly _error = signal&lt;string | null&gt;(null);
1718
+ private readonly _connectionState = signal&lt;P2PNativeConnectionState&gt;('disconnected');
1719
+ private readonly _pairingOffer = signal&lt;PairingOfferResult | null&gt;(null);
1720
+ &nbsp;
1721
+ /** Session persistence for page reload recovery */
1722
+ private readonly sessionPersistence = new P2PSessionPersistence();
1723
+ &nbsp;
1724
+ // Public readonly signals
1725
+ readonly status: Signal&lt;ConnectionStatus&gt; = this._status.asReadonly();
1726
+ readonly accounts: Signal&lt;UnifiedAccount[]&gt; = this._accounts.asReadonly();
1727
+ readonly error: Signal&lt;string | null&gt; = this._error.asReadonly();
1728
+ &nbsp;
1729
+ /**
1730
+ * Current detailed connection state
1731
+ */
1732
+ readonly connectionState: Signal&lt;P2PNativeConnectionState&gt; = this._connectionState.asReadonly();
1733
+ &nbsp;
1734
+ /**
1735
+ * Current pairing offer (if awaiting scan)
1736
+ */
1737
+ readonly pairingOffer: Signal&lt;PairingOfferResult | null&gt; = this._pairingOffer.asReadonly();
1738
+ &nbsp;
1739
+ /**
1740
+ * Whether currently awaiting wallet to scan QR
1741
+ */
1742
+ readonly isAwaitingScan = computed(() =&gt; this._connectionState() === 'awaiting_scan');
1743
+ &nbsp;
1744
+ /**
1745
+ * Whether a pairing offer is available
1746
+ */
1747
+ readonly hasPairingOffer = computed(() =&gt; this._pairingOffer() !== null);
1748
+ &nbsp;
1749
+ /**
1750
+ * Whether a persisted session exists
1751
+ */
1752
+ readonly hasPersistedSession = computed(() =&gt; this.sessionPersistence.hasStoredSession());
1753
+ &nbsp;
1754
+ /**
1755
+ * Transport state for the P2P connection.
1756
+ * Values: 'nostr-only' | 'upgrading' | 'p2p-connected' | 'p2p-failed'
1757
+ *
1758
+ * This allows the UI to show the current transport layer being used.
1759
+ */
1760
+ readonly transportState = computed(() =&gt; this.sessionManager.p2pState());
1761
+ &nbsp;
1762
+ /**
1763
+ * @param sessionManager
1764
+ * @param ngZone
1765
+ */
1766
+ constructor(
1767
+ private readonly sessionManager: P2PSessionManager,
1768
+ private readonly ngZone: NgZone,
1769
+ ) {
1770
+ super();
1771
+ // CRITICAL: Pass NgZone to session manager so signal updates from
1772
+ // Nostr/WebSocket callbacks (which fire outside Angular zone) trigger
1773
+ // Angular change detection. Without this, walletContext.activeAccount
1774
+ // stays null after session approval.
1775
+ this.sessionManager.setNgZone(this.ngZone);
1776
+ this.setupSessionManagerListeners();
1777
+ this.restorePersistedSession();
1778
+ }
1779
+ &nbsp;
1780
+ /**
1781
+ * Restore session from localStorage on page load.
1782
+ * Sets accounts and status from persisted data.
1783
+ * Note: This only restores metadata - the actual WebRTC connection
1784
+ * will need to be re-established via QR pairing.
1785
+ */
1786
+ private restorePersistedSession(): void {
1787
+ const stored = this.sessionPersistence.restore();
1788
+ if (stored) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1789
+ <span class="cstat-no" title="statement not covered" > logger.info('Restoring persisted mobile session', {</span>
1790
+ <span class="cstat-no" title="statement not covered" > sessionId: stored.sessionId,</span>
1791
+ <span class="cstat-no" title="statement not covered" > accountCount: stored.accounts?.length ?? 0,</span>
1792
+ <span class="cstat-no" title="statement not covered" > });</span>
1793
+ <span class="cstat-no" title="statement not covered" ></span>
1794
+ <span class="cstat-no" title="statement not covered" > // Restore accounts with proper providerId</span>
1795
+ <span class="cstat-no" title="statement not covered" > if (stored.accounts?.length) {</span>
1796
+ <span class="cstat-no" title="statement not covered" > const accountsWithProvider = this.ensureProviderIdOnAccounts(stored.accounts);</span>
1797
+ <span class="cstat-no" title="statement not covered" > this._accounts.set(accountsWithProvider);</span>
1798
+ <span class="cstat-no" title="statement not covered" > }</span>
1799
+ <span class="cstat-no" title="statement not covered" ></span>
1800
+ <span class="cstat-no" title="statement not covered" > // Note: We don't set connected status because WebRTC needs re-pairing</span>
1801
+ <span class="cstat-no" title="statement not covered" > // The persisted data is for account info only</span>
1802
+ <span class="cstat-no" title="statement not covered" > logger.debug('Mobile session metadata restored (requires re-pairing for connection)');</span>
1803
+ <span class="cstat-no" title="statement not covered" > }</span>
1804
+ }
1805
+ &nbsp;
1806
+ /**
1807
+ * Creates a pairing offer for QR code display.
1808
+ *
1809
+ * @description
1810
+ * Generates a channel invite encoded for QR display. The mobile wallet
1811
+ * scans this QR code to establish a connection via Nostr relays with
1812
+ * automatic P2P upgrade.
1813
+ *
1814
+ * The returned `qrData` is a compact `hsc:connect?i=...` URL that contains:
1815
+ * - Channel ID and encryption keys
1816
+ * - App metadata (name, ID)
1817
+ * - Relay endpoints for communication
1818
+ *
1819
+ * @param config - Connection configuration specifying ledger and network
1820
+ *
1821
+ * @returns Promise resolving to pairing offer containing QR data and expiry
1822
+ *
1823
+ * @throws {Error} If offer generation fails
1824
+ */
1825
+ async createPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {
1826
+ logger.info('Creating pairing offer', { config });
1827
+ &nbsp;
1828
+ try {
1829
+ this._connectionState.set('generating_offer');
1830
+ this._error.set(null);
1831
+ &nbsp;
1832
+ // Extract common properties based on config type
1833
+ const appId = 'appId' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >appId ?? 'hsuite-dapp') : '</span>hsuite-dapp';
1834
+ const appName = 'appName' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >appName ?? 'HSuite dApp') : '</span>HSuite dApp';
1835
+ const ledgerId = 'ledgerId' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >ledgerId ?? 'hedera') : '</span>hedera';
1836
+ const networkId = config.<span class="branch-0 cbranch-no" title="branch not covered" >networkId ?? 'testnet';</span>
1837
+ &nbsp;
1838
+ const result = await this.sessionManager.createPairingOffer({
1839
+ appId,
1840
+ appName,
1841
+ ledgerId,
1842
+ networkId,
1843
+ });
1844
+ &nbsp;
1845
+ const offerResult: PairingOfferResult = {
1846
+ qrData: result.qrData,
1847
+ sessionId: result.sessionId,
1848
+ expiresAt: Date.now() + 120 * 1000, // 2 minutes
1849
+ };
1850
+ &nbsp;
1851
+ this._pairingOffer.set(offerResult);
1852
+ this._connectionState.set('awaiting_scan');
1853
+ this._status.set('connecting');
1854
+ &nbsp;
1855
+ logger.info('Pairing offer created', {
1856
+ qrDataLength: result.qrData.length,
1857
+ expiresAt: offerResult.expiresAt,
1858
+ });
1859
+ &nbsp;
1860
+ return offerResult;
1861
+ } catch (error) {
1862
+ logger.error('Failed to create pairing offer', { error });
1863
+ this._connectionState.set('error');
1864
+ this._status.set('error');
1865
+ this._error.set(error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : 'Failed to create pairing offer')</span>;
1866
+ throw error;
1867
+ }
1868
+ }
1869
+ &nbsp;
1870
+ /**
1871
+ * Refresh the pairing offer (e.g., when expired).
1872
+ *
1873
+ * @param config - Connection configuration
1874
+ * @returns Promise resolving to new pairing offer
1875
+ */
1876
+ async refreshPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {
1877
+ logger.debug('Refreshing pairing offer');
1878
+ &nbsp;
1879
+ // Cancel any existing offer
1880
+ await this.sessionManager.cancelPairingOffer();
1881
+ &nbsp;
1882
+ return this.createPairingOffer(config);
1883
+ }
1884
+ &nbsp;
1885
+ /**
1886
+ * Register callback for when peer connects.
1887
+ *
1888
+ * @param callback - Function to call when connection is established
1889
+ */
1890
+ onPeerConnected(callback: () =&gt; void): void {
1891
+ this.sessionManager.onConnected(() =&gt; {
1892
+ callback();
1893
+ });
1894
+ }
1895
+ &nbsp;
1896
+ /**
1897
+ * Waits for the wallet to connect and approve the session.
1898
+ *
1899
+ * @description
1900
+ * Call this after {@link createPairingOffer} to block until the wallet user
1901
+ * completes the connection flow. This is the single-QR flow - no answer
1902
+ * scanning is required.
1903
+ *
1904
+ * The method resolves when all of the following occur:
1905
+ * 1. Wallet scans the QR code
1906
+ * 2. Wallet connects via Nostr relay
1907
+ * 3. User approves the session in the wallet
1908
+ *
1909
+ * Upon success, the session is automatically persisted for reconnection.
1910
+ *
1911
+ * @returns Promise resolving to the approved session with account information
1912
+ *
1913
+ * @throws {Error} If connection fails or is rejected
1914
+ * @throws {Error} If no pairing offer was created
1915
+ */
1916
+ <span class="fstat-no" title="function not covered" > async waitForSessionApproval(): Promise&lt;P2PSession&gt; {</span>
1917
+ <span class="cstat-no" title="statement not covered" > logger.info('Waiting for wallet to connect and approve session');</span>
1918
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('pending_approval');</span>
1919
+ <span class="cstat-no" title="statement not covered" ></span>
1920
+ <span class="cstat-no" title="statement not covered" > try {</span>
1921
+ <span class="cstat-no" title="statement not covered" > // This blocks until wallet connects via Nostr and user approves</span>
1922
+ <span class="cstat-no" title="statement not covered" > const session = await this.sessionManager.waitForSessionApproval();</span>
1923
+ <span class="cstat-no" title="statement not covered" ></span>
1924
+ <span class="cstat-no" title="statement not covered" > // Connection state will be updated by sessionManager callbacks, but also set here for immediate update</span>
1925
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('connected');</span>
1926
+ <span class="cstat-no" title="statement not covered" > this._status.set('connected');</span>
1927
+ <span class="cstat-no" title="statement not covered" ></span>
1928
+ <span class="cstat-no" title="statement not covered" > // Ensure accounts have providerId set correctly</span>
1929
+ <span class="cstat-no" title="statement not covered" > if (session?.accounts) {</span>
1930
+ <span class="cstat-no" title="statement not covered" > const accountsWithProvider = this.ensureProviderIdOnAccounts(session.accounts);</span>
1931
+ <span class="cstat-no" title="statement not covered" > this._accounts.set(accountsWithProvider);</span>
1932
+ <span class="cstat-no" title="statement not covered" > }</span>
1933
+ <span class="cstat-no" title="statement not covered" ></span>
1934
+ <span class="cstat-no" title="statement not covered" > // Persist session for page reload recovery</span>
1935
+ <span class="cstat-no" title="statement not covered" > this.sessionPersistence.save(session);</span>
1936
+ <span class="cstat-no" title="statement not covered" ></span>
1937
+ <span class="cstat-no" title="statement not covered" > return session;</span>
1938
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
1939
+ <span class="cstat-no" title="statement not covered" > logger.error('Session approval failed', { error });</span>
1940
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('error');</span>
1941
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
1942
+ <span class="cstat-no" title="statement not covered" > }</span>
1943
+ <span class="cstat-no" title="statement not covered" > }</span>
1944
+ &nbsp;
1945
+ // ========== BaseWalletProvider Implementation ==========
1946
+ &nbsp;
1947
+ /**
1948
+ * Connects to a wallet via the P2P pairing flow.
1949
+ *
1950
+ * @description
1951
+ * Initiates the pairing offer flow and waits for connection. For more
1952
+ * control over QR display timing, use {@link createPairingOffer} and
1953
+ * {@link waitForSessionApproval} separately.
1954
+ *
1955
+ * This method:
1956
+ * 1. Creates a pairing offer
1957
+ * 2. Updates `pairingOffer` signal with QR data
1958
+ * 3. Waits up to 2 minutes for wallet to connect
1959
+ *
1960
+ * @param config - Connection configuration
1961
+ *
1962
+ * @throws {Error} If already connected (no-op)
1963
+ * @throws {Error} If connection times out (2 minutes)
1964
+ */
1965
+ <span class="fstat-no" title="function not covered" > async connect(config: ConnectionConfig): Promise&lt;void&gt; {</span>
1966
+ <span class="cstat-no" title="statement not covered" > logger.info('Connect called', { config });</span>
1967
+ <span class="cstat-no" title="statement not covered" ></span>
1968
+ <span class="cstat-no" title="statement not covered" > // If already connected, no-op</span>
1969
+ <span class="cstat-no" title="statement not covered" > if (this._status() === 'connected') {</span>
1970
+ <span class="cstat-no" title="statement not covered" > logger.debug('Already connected');</span>
1971
+ <span class="cstat-no" title="statement not covered" > return;</span>
1972
+ <span class="cstat-no" title="statement not covered" > }</span>
1973
+ <span class="cstat-no" title="statement not covered" ></span>
1974
+ <span class="cstat-no" title="statement not covered" > // Create pairing offer and wait for connection</span>
1975
+ <span class="cstat-no" title="statement not covered" > await this.createPairingOffer(config);</span>
1976
+ <span class="cstat-no" title="statement not covered" ></span>
1977
+ <span class="cstat-no" title="statement not covered" > // Wait for connection to complete</span>
1978
+ <span class="cstat-no" title="statement not covered" > return new Promise((resolve, reject) =&gt; {</span>
1979
+ <span class="cstat-no" title="statement not covered" > const timeout = setTimeout(() =&gt; {</span>
1980
+ <span class="cstat-no" title="statement not covered" > reject(new Error('Connection timeout'));</span>
1981
+ <span class="cstat-no" title="statement not covered" > }, 120000); // 2 minute timeout</span>
1982
+ <span class="cstat-no" title="statement not covered" ></span>
1983
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onConnected(() =&gt; {</span>
1984
+ <span class="cstat-no" title="statement not covered" > clearTimeout(timeout);</span>
1985
+ <span class="cstat-no" title="statement not covered" > resolve();</span>
1986
+ <span class="cstat-no" title="statement not covered" > });</span>
1987
+ <span class="cstat-no" title="statement not covered" ></span>
1988
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onError((error: Error) =&gt; {</span>
1989
+ <span class="cstat-no" title="statement not covered" > clearTimeout(timeout);</span>
1990
+ <span class="cstat-no" title="statement not covered" > reject(error);</span>
1991
+ <span class="cstat-no" title="statement not covered" > });</span>
1992
+ <span class="cstat-no" title="statement not covered" > });</span>
1993
+ <span class="cstat-no" title="statement not covered" > }</span>
1994
+ &nbsp;
1995
+ /**
1996
+ * Disconnects from the wallet and clears session.
1997
+ *
1998
+ * @description
1999
+ * Terminates the P2P session, clears all state signals, and removes
2000
+ * persisted session data. The wallet is notified of the disconnection.
2001
+ */
2002
+ async disconnect(): Promise&lt;void&gt; {
2003
+ logger.info('Disconnecting');
2004
+ &nbsp;
2005
+ try {
2006
+ await this.sessionManager.terminateSession();
2007
+ } finally {
2008
+ this._status.set('disconnected');
2009
+ this._connectionState.set('disconnected');
2010
+ this._accounts.set([]);
2011
+ this._pairingOffer.set(null);
2012
+ this._error.set(null);
2013
+ &nbsp;
2014
+ // Clear persisted session
2015
+ this.sessionPersistence.clear();
2016
+ }
2017
+ }
2018
+ &nbsp;
2019
+ /**
2020
+ * Signs a transaction without submitting it.
2021
+ *
2022
+ * @description
2023
+ * Sends the transaction to the connected wallet for signing. The wallet
2024
+ * displays transaction details and prompts the user for approval.
2025
+ *
2026
+ * @param options - Transaction signing options
2027
+ *
2028
+ * @returns Promise resolving to signed payload and signature
2029
+ *
2030
+ * @throws {Error} If not connected to wallet
2031
+ * @throws {Error} If user rejects signing
2032
+ */
2033
+ async signTransaction(options: SignTransactionOptions): Promise&lt;SignResult&gt; {
2034
+ if (this._status() !== 'connected') {
2035
+ throw new Error('Not connected to wallet');
2036
+ }
2037
+ &nbsp;
2038
+ logger.info('Signing transaction', { account: options.accountAddress });
2039
+ &nbsp;
2040
+ const result = await this.sessionManager.signTransaction({
2041
+ accountAddress: options.accountAddress,
2042
+ payload: options.payload,
2043
+ ledgerId: options.ledgerId,
2044
+ networkId: options.networkId,
2045
+ });
2046
+ &nbsp;
2047
+ return {
2048
+ signedPayload: result.signedPayload,
2049
+ signature: result.signature,
2050
+ metadata: result.metadata,
2051
+ };
2052
+ }
2053
+ &nbsp;
2054
+ /**
2055
+ * Signs and submits a transaction to the blockchain.
2056
+ *
2057
+ * @description
2058
+ * Performs atomic sign and submit in a single operation. Supports batch
2059
+ * transactions when isBatch is true.
2060
+ *
2061
+ * @param options - Transaction submission options
2062
+ *
2063
+ * @returns Promise resolving to transaction ID and hash
2064
+ *
2065
+ * @throws {Error} If not connected to wallet
2066
+ * @throws {Error} If user rejects or transaction fails
2067
+ */
2068
+ async submitTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {
2069
+ if (this._status() !== 'connected') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2070
+ <span class="cstat-no" title="statement not covered" > throw new Error('Not connected to wallet');</span>
2071
+ <span class="cstat-no" title="statement not covered" > }</span>
2072
+ &nbsp;
2073
+ logger.info('Submitting transaction', { account: options.accountAddress });
2074
+ &nbsp;
2075
+ const result = await this.sessionManager.submitTransaction({
2076
+ accountAddress: options.accountAddress,
2077
+ payload: options.payload,
2078
+ ledgerId: options.ledgerId,
2079
+ networkId: options.networkId,
2080
+ isBatch: options.isBatch,
2081
+ batchKey: options.batchKey,
2082
+ innerTransactions: options.innerTransactions,
2083
+ });
2084
+ &nbsp;
2085
+ return {
2086
+ transactionId: result.transactionId,
2087
+ transactionHash: result.transactionHash,
2088
+ metadata: result.metadata,
2089
+ };
2090
+ }
2091
+ &nbsp;
2092
+ /**
2093
+ * Signs and executes a transaction atomically in a single prompt.
2094
+ *
2095
+ * @description
2096
+ * Delegates to {@link submitTransaction}. This method exists so that
2097
+ * {@link UnifiedWalletService.signAndExecuteTransaction} can detect native
2098
+ * atomic sign+submit support on the provider (via duck-typing) and avoid
2099
+ * its fallback path that chains separate signTransaction + submitTransaction
2100
+ * calls. Mirrors the pattern used by HsuiteNativeProvider and the
2101
+ * WalletConnect signers.
2102
+ *
2103
+ * @param options - Transaction submission options
2104
+ *
2105
+ * @returns Promise resolving to submission result with transaction ID
2106
+ */
2107
+ <span class="fstat-no" title="function not covered" > async signAndExecuteTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {</span>
2108
+ <span class="cstat-no" title="statement not covered" > return this.submitTransaction(options);</span>
2109
+ <span class="cstat-no" title="statement not covered" > }</span>
2110
+ &nbsp;
2111
+ /**
2112
+ * Signs an arbitrary message for authentication or verification.
2113
+ *
2114
+ * @description
2115
+ * Requests the wallet to sign a non-transaction message. Used for
2116
+ * authentication challenges, DAO voting, or off-chain signatures.
2117
+ *
2118
+ * @param options - Message signing options
2119
+ *
2120
+ * @returns Promise resolving to signature and public key
2121
+ *
2122
+ * @throws {Error} If not connected to wallet
2123
+ * @throws {Error} If user rejects signing
2124
+ */
2125
+ async signMessage(options: SignMessageOptions): Promise&lt;SignMessageResult&gt; {
2126
+ if (this._status() !== 'connected') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2127
+ <span class="cstat-no" title="statement not covered" > throw new Error('Not connected to wallet');</span>
2128
+ <span class="cstat-no" title="statement not covered" > }</span>
2129
+ &nbsp;
2130
+ logger.info('Signing message', { account: options.accountAddress });
2131
+ &nbsp;
2132
+ const result = await this.sessionManager.signMessage({
2133
+ accountAddress: options.accountAddress,
2134
+ message: options.message,
2135
+ encoding: options.encoding,
2136
+ ledgerId: options.ledgerId,
2137
+ networkId: options.networkId,
2138
+ });
2139
+ &nbsp;
2140
+ return {
2141
+ signature: result.signature,
2142
+ publicKey: result.publicKey,
2143
+ metadata: result.metadata,
2144
+ };
2145
+ }
2146
+ &nbsp;
2147
+ /**
2148
+ * Checks if P2P provider is available in the current environment.
2149
+ *
2150
+ * @description
2151
+ * P2P Native requires WebRTC support (RTCPeerConnection). This is available
2152
+ * in all modern browsers and most mobile WebViews.
2153
+ *
2154
+ * @returns Promise resolving to true if WebRTC is available
2155
+ */
2156
+ async isAvailable(): Promise&lt;boolean&gt; {
2157
+ // Check for WebRTC support
2158
+ return typeof RTCPeerConnection !== 'undefined';
2159
+ }
2160
+ &nbsp;
2161
+ // ========== Private Methods ==========
2162
+ &nbsp;
2163
+ /**
2164
+ * Set up listeners for session manager events
2165
+ */
2166
+ private setupSessionManagerListeners(): void {
2167
+ // Connection established — wrap in NgZone to ensure Angular change
2168
+ // detection picks up signal updates from Nostr/WebSocket callbacks
2169
+ this.sessionManager.onConnected((session) =&gt; {
2170
+ logger.info('Session connected', { sessionId: session?.id });
2171
+ this.ngZone.run(() =&gt; {
2172
+ this._connectionState.set('connected');
2173
+ this._status.set('connected');
2174
+ this._pairingOffer.set(null);
2175
+ &nbsp;
2176
+ // Update accounts from session - ensure providerId is set
2177
+ if (session?.accounts) {
2178
+ const accountsWithProvider = this.ensureProviderIdOnAccounts(session.accounts);
2179
+ this._accounts.set(accountsWithProvider);
2180
+ }
2181
+ });
2182
+ &nbsp;
2183
+ // Persist session for page reload recovery
2184
+ if (session) {
2185
+ this.sessionPersistence.save(session);
2186
+ }
2187
+ });
2188
+ &nbsp;
2189
+ // Session terminated
2190
+ this.sessionManager.onDisconnected(() =&gt; {
2191
+ logger.info('Session disconnected');
2192
+ this.ngZone.run(() =&gt; {
2193
+ this._connectionState.set('disconnected');
2194
+ this._status.set('disconnected');
2195
+ this._accounts.set([]);
2196
+ });
2197
+ &nbsp;
2198
+ // Clear persisted session
2199
+ this.sessionPersistence.clear();
2200
+ });
2201
+ &nbsp;
2202
+ // Error occurred
2203
+ this.sessionManager.onError((error: Error) =&gt; {
2204
+ logger.error('Session error', { error });
2205
+ this.ngZone.run(() =&gt; {
2206
+ this._connectionState.set('error');
2207
+ this._status.set('error');
2208
+ this._error.set(error.message);
2209
+ });
2210
+ });
2211
+ &nbsp;
2212
+ // Accounts updated
2213
+ this.sessionManager.onAccountsChanged((accounts) =&gt; {
2214
+ logger.debug('Accounts updated', { count: accounts.length });
2215
+ this.ngZone.run(() =&gt; {
2216
+ const accountsWithProvider = this.ensureProviderIdOnAccounts(accounts);
2217
+ this._accounts.set(accountsWithProvider);
2218
+ });
2219
+ });
2220
+ }
2221
+ &nbsp;
2222
+ /**
2223
+ * Ensure all accounts have providerId and providerType set correctly
2224
+ * @param accounts
2225
+ */
2226
+ private ensureProviderIdOnAccounts(accounts: UnifiedAccount[]): UnifiedAccount[] {
2227
+ return accounts.map((account) =&gt; ({
2228
+ ...account,
2229
+ id: account.id || `${this.id}-${account.address}`,
2230
+ providerId: this.id,
2231
+ providerType: this.metadata.type,
2232
+ }));
2233
+ }
2234
+ }
2235
+ &nbsp;</pre></td></tr></table></pre>
2236
+
2237
+ <div class='push'></div><!-- for sticky footer -->
2238
+ </div><!-- /wrapper -->
2239
+ <div class='footer quiet pad2 space-top1 center small'>
2240
+ Code coverage generated by
2241
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2242
+ at 2026-06-02T14:30:38.257Z
2243
+ </div>
2244
+ <script src="../../../prettify.js"></script>
2245
+ <script>
2246
+ window.onload = function () {
2247
+ prettyPrint();
2248
+ };
2249
+ </script>
2250
+ <script src="../../../sorter.js"></script>
2251
+ <script src="../../../block-navigation.js"></script>
2252
+ </body>
2253
+ </html>
2254
+