@serve.zone/dcrouter 13.17.0 → 13.17.3

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 (388) hide show
  1. package/dist_serve/bundle.js +3 -3
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/acme/index.d.ts +1 -0
  5. package/dist_ts/acme/index.js +2 -0
  6. package/dist_ts/acme/manager.acme-config.d.ts +48 -0
  7. package/dist_ts/acme/manager.acme-config.js +156 -0
  8. package/dist_ts/classes.cert-provision-scheduler.d.ts +52 -0
  9. package/dist_ts/classes.cert-provision-scheduler.js +138 -0
  10. package/dist_ts/classes.dcrouter.d.ts +401 -0
  11. package/dist_ts/classes.dcrouter.js +1852 -0
  12. package/dist_ts/classes.storage-cert-manager.d.ts +15 -0
  13. package/dist_ts/classes.storage-cert-manager.js +53 -0
  14. package/dist_ts/config/classes.api-token-manager.d.ts +44 -0
  15. package/dist_ts/config/classes.api-token-manager.js +180 -0
  16. package/dist_ts/config/classes.db-seeder.d.ts +25 -0
  17. package/dist_ts/config/classes.db-seeder.js +69 -0
  18. package/dist_ts/config/classes.reference-resolver.d.ts +80 -0
  19. package/dist_ts/config/classes.reference-resolver.js +483 -0
  20. package/dist_ts/config/classes.route-config-manager.d.ts +54 -0
  21. package/dist_ts/config/classes.route-config-manager.js +370 -0
  22. package/dist_ts/config/classes.target-profile-manager.d.ts +82 -0
  23. package/dist_ts/config/classes.target-profile-manager.js +349 -0
  24. package/dist_ts/config/index.d.ts +6 -0
  25. package/dist_ts/config/index.js +8 -0
  26. package/dist_ts/config/validator.d.ts +104 -0
  27. package/dist_ts/config/validator.js +152 -0
  28. package/dist_ts/db/classes.cache.cleaner.d.ts +47 -0
  29. package/dist_ts/db/classes.cache.cleaner.js +130 -0
  30. package/dist_ts/db/classes.cached.document.d.ts +76 -0
  31. package/dist_ts/db/classes.cached.document.js +100 -0
  32. package/dist_ts/db/classes.dcrouter-db.d.ts +70 -0
  33. package/dist_ts/db/classes.dcrouter-db.js +146 -0
  34. package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +32 -0
  35. package/dist_ts/db/documents/classes.accounting-session.doc.js +214 -0
  36. package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +13 -0
  37. package/dist_ts/db/documents/classes.acme-cert.doc.js +109 -0
  38. package/dist_ts/db/documents/classes.acme-config.doc.d.ts +22 -0
  39. package/dist_ts/db/documents/classes.acme-config.doc.js +121 -0
  40. package/dist_ts/db/documents/classes.api-token.doc.d.ts +18 -0
  41. package/dist_ts/db/documents/classes.api-token.doc.js +127 -0
  42. package/dist_ts/db/documents/classes.cached.email.d.ts +125 -0
  43. package/dist_ts/db/documents/classes.cached.email.js +337 -0
  44. package/dist_ts/db/documents/classes.cached.ip.reputation.d.ts +119 -0
  45. package/dist_ts/db/documents/classes.cached.ip.reputation.js +323 -0
  46. package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +11 -0
  47. package/dist_ts/db/documents/classes.cert-backoff.doc.js +97 -0
  48. package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +22 -0
  49. package/dist_ts/db/documents/classes.dns-provider.doc.js +134 -0
  50. package/dist_ts/db/documents/classes.dns-record.doc.d.ts +21 -0
  51. package/dist_ts/db/documents/classes.dns-record.doc.js +143 -0
  52. package/dist_ts/db/documents/classes.domain.doc.d.ts +22 -0
  53. package/dist_ts/db/documents/classes.domain.doc.js +146 -0
  54. package/dist_ts/db/documents/classes.email-domain.doc.d.ts +17 -0
  55. package/dist_ts/db/documents/classes.email-domain.doc.js +124 -0
  56. package/dist_ts/db/documents/classes.network-target.doc.d.ts +15 -0
  57. package/dist_ts/db/documents/classes.network-target.doc.js +118 -0
  58. package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +12 -0
  59. package/dist_ts/db/documents/classes.proxy-cert.doc.js +103 -0
  60. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +17 -0
  61. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +130 -0
  62. package/dist_ts/db/documents/classes.route.doc.d.ts +18 -0
  63. package/dist_ts/db/documents/classes.route.doc.js +121 -0
  64. package/dist_ts/db/documents/classes.source-profile.doc.d.ts +15 -0
  65. package/dist_ts/db/documents/classes.source-profile.doc.js +115 -0
  66. package/dist_ts/db/documents/classes.target-profile.doc.d.ts +16 -0
  67. package/dist_ts/db/documents/classes.target-profile.doc.js +121 -0
  68. package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +15 -0
  69. package/dist_ts/db/documents/classes.vlan-mappings.doc.js +77 -0
  70. package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +23 -0
  71. package/dist_ts/db/documents/classes.vpn-client.doc.js +172 -0
  72. package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +10 -0
  73. package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +94 -0
  74. package/dist_ts/db/documents/index.d.ts +20 -0
  75. package/dist_ts/db/documents/index.js +30 -0
  76. package/dist_ts/db/index.d.ts +4 -0
  77. package/dist_ts/db/index.js +9 -0
  78. package/dist_ts/dns/index.d.ts +2 -0
  79. package/dist_ts/dns/index.js +3 -0
  80. package/dist_ts/dns/manager.dns.d.ts +267 -0
  81. package/dist_ts/dns/manager.dns.js +906 -0
  82. package/dist_ts/dns/providers/cloudflare.provider.d.ts +21 -0
  83. package/dist_ts/dns/providers/cloudflare.provider.js +106 -0
  84. package/dist_ts/dns/providers/factory.d.ts +23 -0
  85. package/dist_ts/dns/providers/factory.js +47 -0
  86. package/dist_ts/dns/providers/index.d.ts +3 -0
  87. package/dist_ts/dns/providers/index.js +4 -0
  88. package/dist_ts/dns/providers/interfaces.d.ts +54 -0
  89. package/dist_ts/dns/providers/interfaces.js +2 -0
  90. package/dist_ts/email/classes.email-domain.manager.d.ts +46 -0
  91. package/dist_ts/email/classes.email-domain.manager.js +276 -0
  92. package/dist_ts/email/index.d.ts +1 -0
  93. package/dist_ts/email/index.js +2 -0
  94. package/dist_ts/errors/base.errors.d.ts +224 -0
  95. package/dist_ts/errors/base.errors.js +320 -0
  96. package/dist_ts/errors/error-handler.d.ts +98 -0
  97. package/dist_ts/errors/error-handler.js +282 -0
  98. package/dist_ts/errors/error.codes.d.ts +115 -0
  99. package/dist_ts/errors/error.codes.js +136 -0
  100. package/dist_ts/errors/index.d.ts +54 -0
  101. package/dist_ts/errors/index.js +136 -0
  102. package/dist_ts/errors/reputation.errors.d.ts +183 -0
  103. package/dist_ts/errors/reputation.errors.js +292 -0
  104. package/dist_ts/http3/http3-route-augmentation.d.ts +50 -0
  105. package/dist_ts/http3/http3-route-augmentation.js +98 -0
  106. package/dist_ts/http3/index.d.ts +1 -0
  107. package/dist_ts/http3/index.js +2 -0
  108. package/dist_ts/index.d.ts +8 -0
  109. package/dist_ts/index.js +29 -0
  110. package/dist_ts/logger.d.ts +21 -0
  111. package/dist_ts/logger.js +81 -0
  112. package/dist_ts/monitoring/classes.metricscache.d.ts +32 -0
  113. package/dist_ts/monitoring/classes.metricscache.js +63 -0
  114. package/dist_ts/monitoring/classes.metricsmanager.d.ts +235 -0
  115. package/dist_ts/monitoring/classes.metricsmanager.js +875 -0
  116. package/dist_ts/monitoring/index.d.ts +1 -0
  117. package/dist_ts/monitoring/index.js +2 -0
  118. package/dist_ts/opsserver/classes.opsserver.d.ts +47 -0
  119. package/dist_ts/opsserver/classes.opsserver.js +105 -0
  120. package/dist_ts/opsserver/handlers/acme-config.handler.d.ts +16 -0
  121. package/dist_ts/opsserver/handlers/acme-config.handler.js +77 -0
  122. package/dist_ts/opsserver/handlers/admin.handler.d.ts +40 -0
  123. package/dist_ts/opsserver/handlers/admin.handler.js +191 -0
  124. package/dist_ts/opsserver/handlers/api-token.handler.d.ts +6 -0
  125. package/dist_ts/opsserver/handlers/api-token.handler.js +62 -0
  126. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +77 -0
  127. package/dist_ts/opsserver/handlers/certificate.handler.js +574 -0
  128. package/dist_ts/opsserver/handlers/config.handler.d.ts +7 -0
  129. package/dist_ts/opsserver/handlers/config.handler.js +200 -0
  130. package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +16 -0
  131. package/dist_ts/opsserver/handlers/dns-provider.handler.js +156 -0
  132. package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +13 -0
  133. package/dist_ts/opsserver/handlers/dns-record.handler.js +98 -0
  134. package/dist_ts/opsserver/handlers/domain.handler.d.ts +13 -0
  135. package/dist_ts/opsserver/handlers/domain.handler.js +137 -0
  136. package/dist_ts/opsserver/handlers/email-domain.handler.d.ts +16 -0
  137. package/dist_ts/opsserver/handlers/email-domain.handler.js +150 -0
  138. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +30 -0
  139. package/dist_ts/opsserver/handlers/email-ops.handler.js +227 -0
  140. package/dist_ts/opsserver/handlers/index.d.ts +21 -0
  141. package/dist_ts/opsserver/handlers/index.js +22 -0
  142. package/dist_ts/opsserver/handlers/logs.handler.d.ts +25 -0
  143. package/dist_ts/opsserver/handlers/logs.handler.js +264 -0
  144. package/dist_ts/opsserver/handlers/network-target.handler.d.ts +10 -0
  145. package/dist_ts/opsserver/handlers/network-target.handler.js +117 -0
  146. package/dist_ts/opsserver/handlers/radius.handler.d.ts +6 -0
  147. package/dist_ts/opsserver/handlers/radius.handler.js +295 -0
  148. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +6 -0
  149. package/dist_ts/opsserver/handlers/remoteingress.handler.js +156 -0
  150. package/dist_ts/opsserver/handlers/route-management.handler.d.ts +14 -0
  151. package/dist_ts/opsserver/handlers/route-management.handler.js +98 -0
  152. package/dist_ts/opsserver/handlers/security.handler.d.ts +9 -0
  153. package/dist_ts/opsserver/handlers/security.handler.js +237 -0
  154. package/dist_ts/opsserver/handlers/source-profile.handler.d.ts +10 -0
  155. package/dist_ts/opsserver/handlers/source-profile.handler.js +119 -0
  156. package/dist_ts/opsserver/handlers/stats.handler.d.ts +11 -0
  157. package/dist_ts/opsserver/handlers/stats.handler.js +461 -0
  158. package/dist_ts/opsserver/handlers/target-profile.handler.d.ts +10 -0
  159. package/dist_ts/opsserver/handlers/target-profile.handler.js +117 -0
  160. package/dist_ts/opsserver/handlers/users.handler.d.ts +12 -0
  161. package/dist_ts/opsserver/handlers/users.handler.js +24 -0
  162. package/dist_ts/opsserver/handlers/vpn.handler.d.ts +6 -0
  163. package/dist_ts/opsserver/handlers/vpn.handler.js +262 -0
  164. package/dist_ts/opsserver/helpers/guards.d.ts +27 -0
  165. package/dist_ts/opsserver/helpers/guards.js +43 -0
  166. package/dist_ts/opsserver/index.d.ts +1 -0
  167. package/dist_ts/opsserver/index.js +2 -0
  168. package/dist_ts/paths.d.ts +25 -0
  169. package/dist_ts/paths.js +44 -0
  170. package/dist_ts/plugins.d.ts +81 -0
  171. package/dist_ts/plugins.js +115 -0
  172. package/dist_ts/radius/classes.accounting.manager.d.ts +223 -0
  173. package/dist_ts/radius/classes.accounting.manager.js +449 -0
  174. package/dist_ts/radius/classes.radius.server.d.ts +169 -0
  175. package/dist_ts/radius/classes.radius.server.js +384 -0
  176. package/dist_ts/radius/classes.vlan.manager.d.ts +124 -0
  177. package/dist_ts/radius/classes.vlan.manager.js +272 -0
  178. package/dist_ts/radius/index.d.ts +13 -0
  179. package/dist_ts/radius/index.js +14 -0
  180. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +92 -0
  181. package/dist_ts/remoteingress/classes.remoteingress-manager.js +291 -0
  182. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +59 -0
  183. package/dist_ts/remoteingress/classes.tunnel-manager.js +165 -0
  184. package/dist_ts/remoteingress/index.d.ts +2 -0
  185. package/dist_ts/remoteingress/index.js +3 -0
  186. package/dist_ts/security/classes.contentscanner.d.ts +164 -0
  187. package/dist_ts/security/classes.contentscanner.js +642 -0
  188. package/dist_ts/security/classes.ipreputationchecker.d.ts +145 -0
  189. package/dist_ts/security/classes.ipreputationchecker.js +458 -0
  190. package/dist_ts/security/classes.securitylogger.d.ts +144 -0
  191. package/dist_ts/security/classes.securitylogger.js +235 -0
  192. package/dist_ts/security/index.d.ts +3 -0
  193. package/dist_ts/security/index.js +4 -0
  194. package/dist_ts/sms/classes.smsservice.d.ts +15 -0
  195. package/dist_ts/sms/classes.smsservice.js +72 -0
  196. package/dist_ts/sms/config/sms.config.d.ts +93 -0
  197. package/dist_ts/sms/config/sms.config.js +2 -0
  198. package/dist_ts/sms/config/sms.schema.d.ts +5 -0
  199. package/dist_ts/sms/config/sms.schema.js +121 -0
  200. package/dist_ts/sms/index.d.ts +1 -0
  201. package/dist_ts/sms/index.js +2 -0
  202. package/dist_ts/vpn/classes.vpn-manager.d.ts +159 -0
  203. package/dist_ts/vpn/classes.vpn-manager.js +459 -0
  204. package/dist_ts/vpn/index.d.ts +1 -0
  205. package/dist_ts/vpn/index.js +2 -0
  206. package/dist_ts_apiclient/classes.apitoken.d.ts +41 -0
  207. package/dist_ts_apiclient/classes.apitoken.js +115 -0
  208. package/dist_ts_apiclient/classes.certificate.d.ts +57 -0
  209. package/dist_ts_apiclient/classes.certificate.js +69 -0
  210. package/dist_ts_apiclient/classes.config.d.ts +7 -0
  211. package/dist_ts_apiclient/classes.config.js +11 -0
  212. package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +41 -0
  213. package/dist_ts_apiclient/classes.dcrouterapiclient.js +81 -0
  214. package/dist_ts_apiclient/classes.email.d.ts +30 -0
  215. package/dist_ts_apiclient/classes.email.js +52 -0
  216. package/dist_ts_apiclient/classes.logs.d.ts +21 -0
  217. package/dist_ts_apiclient/classes.logs.js +14 -0
  218. package/dist_ts_apiclient/classes.radius.d.ts +59 -0
  219. package/dist_ts_apiclient/classes.radius.js +95 -0
  220. package/dist_ts_apiclient/classes.remoteingress.d.ts +54 -0
  221. package/dist_ts_apiclient/classes.remoteingress.js +136 -0
  222. package/dist_ts_apiclient/classes.route.d.ts +39 -0
  223. package/dist_ts_apiclient/classes.route.js +125 -0
  224. package/dist_ts_apiclient/classes.stats.d.ts +47 -0
  225. package/dist_ts_apiclient/classes.stats.js +38 -0
  226. package/dist_ts_apiclient/index.d.ts +10 -0
  227. package/dist_ts_apiclient/index.js +14 -0
  228. package/dist_ts_apiclient/plugins.d.ts +3 -0
  229. package/dist_ts_apiclient/plugins.js +5 -0
  230. package/dist_ts_interfaces/data/acme-config.d.ts +25 -0
  231. package/dist_ts_interfaces/data/acme-config.js +2 -0
  232. package/dist_ts_interfaces/data/auth.d.ts +8 -0
  233. package/dist_ts_interfaces/data/auth.js +2 -0
  234. package/dist_ts_interfaces/data/dns-provider.d.ts +136 -0
  235. package/dist_ts_interfaces/data/dns-provider.js +41 -0
  236. package/dist_ts_interfaces/data/dns-record.d.ts +42 -0
  237. package/dist_ts_interfaces/data/dns-record.js +2 -0
  238. package/dist_ts_interfaces/data/domain.d.ts +35 -0
  239. package/dist_ts_interfaces/data/domain.js +2 -0
  240. package/dist_ts_interfaces/data/email-domain.d.ts +70 -0
  241. package/dist_ts_interfaces/data/email-domain.js +2 -0
  242. package/dist_ts_interfaces/data/index.d.ts +11 -0
  243. package/dist_ts_interfaces/data/index.js +12 -0
  244. package/dist_ts_interfaces/data/remoteingress.d.ts +60 -0
  245. package/dist_ts_interfaces/data/remoteingress.js +2 -0
  246. package/dist_ts_interfaces/data/route-management.d.ts +110 -0
  247. package/dist_ts_interfaces/data/route-management.js +2 -0
  248. package/dist_ts_interfaces/data/stats.d.ts +239 -0
  249. package/dist_ts_interfaces/data/stats.js +2 -0
  250. package/dist_ts_interfaces/data/target-profile.d.ts +28 -0
  251. package/dist_ts_interfaces/data/target-profile.js +2 -0
  252. package/dist_ts_interfaces/data/vpn.d.ts +61 -0
  253. package/dist_ts_interfaces/data/vpn.js +2 -0
  254. package/dist_ts_interfaces/index.d.ts +5 -0
  255. package/dist_ts_interfaces/index.js +8 -0
  256. package/dist_ts_interfaces/plugins.d.ts +2 -0
  257. package/dist_ts_interfaces/plugins.js +4 -0
  258. package/dist_ts_interfaces/requests/acme-config.d.ts +42 -0
  259. package/dist_ts_interfaces/requests/acme-config.js +2 -0
  260. package/dist_ts_interfaces/requests/admin.d.ts +31 -0
  261. package/dist_ts_interfaces/requests/admin.js +3 -0
  262. package/dist_ts_interfaces/requests/api-tokens.d.ts +79 -0
  263. package/dist_ts_interfaces/requests/api-tokens.js +2 -0
  264. package/dist_ts_interfaces/requests/certificate.d.ts +111 -0
  265. package/dist_ts_interfaces/requests/certificate.js +3 -0
  266. package/dist_ts_interfaces/requests/combined.stats.d.ts +28 -0
  267. package/dist_ts_interfaces/requests/combined.stats.js +2 -0
  268. package/dist_ts_interfaces/requests/config.d.ts +90 -0
  269. package/dist_ts_interfaces/requests/config.js +3 -0
  270. package/dist_ts_interfaces/requests/dns-providers.d.ts +117 -0
  271. package/dist_ts_interfaces/requests/dns-providers.js +2 -0
  272. package/dist_ts_interfaces/requests/dns-records.d.ts +89 -0
  273. package/dist_ts_interfaces/requests/dns-records.js +2 -0
  274. package/dist_ts_interfaces/requests/domains.d.ts +142 -0
  275. package/dist_ts_interfaces/requests/domains.js +2 -0
  276. package/dist_ts_interfaces/requests/email-domains.d.ts +142 -0
  277. package/dist_ts_interfaces/requests/email-domains.js +2 -0
  278. package/dist_ts_interfaces/requests/email-ops.d.ts +82 -0
  279. package/dist_ts_interfaces/requests/email-ops.js +3 -0
  280. package/dist_ts_interfaces/requests/index.d.ts +21 -0
  281. package/dist_ts_interfaces/requests/index.js +22 -0
  282. package/dist_ts_interfaces/requests/logs.d.ts +41 -0
  283. package/dist_ts_interfaces/requests/logs.js +4 -0
  284. package/dist_ts_interfaces/requests/network-targets.d.ts +102 -0
  285. package/dist_ts_interfaces/requests/network-targets.js +2 -0
  286. package/dist_ts_interfaces/requests/radius.d.ts +268 -0
  287. package/dist_ts_interfaces/requests/radius.js +3 -0
  288. package/dist_ts_interfaces/requests/remoteingress.d.ts +108 -0
  289. package/dist_ts_interfaces/requests/remoteingress.js +3 -0
  290. package/dist_ts_interfaces/requests/route-management.d.ts +85 -0
  291. package/dist_ts_interfaces/requests/route-management.js +2 -0
  292. package/dist_ts_interfaces/requests/source-profiles.d.ts +102 -0
  293. package/dist_ts_interfaces/requests/source-profiles.js +2 -0
  294. package/dist_ts_interfaces/requests/stats.d.ts +177 -0
  295. package/dist_ts_interfaces/requests/stats.js +4 -0
  296. package/dist_ts_interfaces/requests/target-profiles.d.ts +103 -0
  297. package/dist_ts_interfaces/requests/target-profiles.js +2 -0
  298. package/dist_ts_interfaces/requests/users.d.ts +19 -0
  299. package/dist_ts_interfaces/requests/users.js +3 -0
  300. package/dist_ts_interfaces/requests/vpn.d.ts +177 -0
  301. package/dist_ts_interfaces/requests/vpn.js +3 -0
  302. package/dist_ts_migrations/index.d.ts +28 -0
  303. package/dist_ts_migrations/index.js +82 -0
  304. package/dist_ts_oci_container/index.d.ts +8 -0
  305. package/dist_ts_oci_container/index.js +110 -0
  306. package/dist_ts_oci_container/plugins.d.ts +3 -0
  307. package/dist_ts_oci_container/plugins.js +4 -0
  308. package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
  309. package/dist_ts_web/00_commitinfo_data.js +9 -0
  310. package/dist_ts_web/appstate.d.ts +478 -0
  311. package/dist_ts_web/appstate.js +1968 -0
  312. package/dist_ts_web/elements/access/index.d.ts +2 -0
  313. package/dist_ts_web/elements/access/index.js +3 -0
  314. package/dist_ts_web/elements/access/ops-view-apitokens.d.ts +13 -0
  315. package/dist_ts_web/elements/access/ops-view-apitokens.js +372 -0
  316. package/dist_ts_web/elements/access/ops-view-users.d.ts +11 -0
  317. package/dist_ts_web/elements/access/ops-view-users.js +190 -0
  318. package/dist_ts_web/elements/domains/dns-provider-form.d.ts +60 -0
  319. package/dist_ts_web/elements/domains/dns-provider-form.js +259 -0
  320. package/dist_ts_web/elements/domains/index.d.ts +5 -0
  321. package/dist_ts_web/elements/domains/index.js +6 -0
  322. package/dist_ts_web/elements/domains/ops-view-certificates.d.ts +25 -0
  323. package/dist_ts_web/elements/domains/ops-view-certificates.js +669 -0
  324. package/dist_ts_web/elements/domains/ops-view-dns.d.ts +17 -0
  325. package/dist_ts_web/elements/domains/ops-view-dns.js +305 -0
  326. package/dist_ts_web/elements/domains/ops-view-domains.d.ts +19 -0
  327. package/dist_ts_web/elements/domains/ops-view-domains.js +456 -0
  328. package/dist_ts_web/elements/domains/ops-view-providers.d.ts +21 -0
  329. package/dist_ts_web/elements/domains/ops-view-providers.js +330 -0
  330. package/dist_ts_web/elements/email/index.d.ts +3 -0
  331. package/dist_ts_web/elements/email/index.js +4 -0
  332. package/dist_ts_web/elements/email/ops-view-email-domains.d.ts +19 -0
  333. package/dist_ts_web/elements/email/ops-view-email-domains.js +410 -0
  334. package/dist_ts_web/elements/email/ops-view-email-security.d.ts +14 -0
  335. package/dist_ts_web/elements/email/ops-view-email-security.js +178 -0
  336. package/dist_ts_web/elements/email/ops-view-emails.d.ts +21 -0
  337. package/dist_ts_web/elements/email/ops-view-emails.js +165 -0
  338. package/dist_ts_web/elements/index.d.ts +9 -0
  339. package/dist_ts_web/elements/index.js +10 -0
  340. package/dist_ts_web/elements/network/index.d.ts +7 -0
  341. package/dist_ts_web/elements/network/index.js +8 -0
  342. package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +60 -0
  343. package/dist_ts_web/elements/network/ops-view-network-activity.js +754 -0
  344. package/dist_ts_web/elements/network/ops-view-networktargets.d.ts +17 -0
  345. package/dist_ts_web/elements/network/ops-view-networktargets.js +255 -0
  346. package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +20 -0
  347. package/dist_ts_web/elements/network/ops-view-remoteingress.js +497 -0
  348. package/dist_ts_web/elements/network/ops-view-routes.d.ts +17 -0
  349. package/dist_ts_web/elements/network/ops-view-routes.js +700 -0
  350. package/dist_ts_web/elements/network/ops-view-sourceprofiles.d.ts +17 -0
  351. package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +278 -0
  352. package/dist_ts_web/elements/network/ops-view-targetprofiles.d.ts +21 -0
  353. package/dist_ts_web/elements/network/ops-view-targetprofiles.js +420 -0
  354. package/dist_ts_web/elements/network/ops-view-vpn.d.ts +31 -0
  355. package/dist_ts_web/elements/network/ops-view-vpn.js +873 -0
  356. package/dist_ts_web/elements/ops-dashboard.d.ts +31 -0
  357. package/dist_ts_web/elements/ops-dashboard.js +405 -0
  358. package/dist_ts_web/elements/ops-view-logs.d.ts +13 -0
  359. package/dist_ts_web/elements/ops-view-logs.js +159 -0
  360. package/dist_ts_web/elements/overview/index.d.ts +2 -0
  361. package/dist_ts_web/elements/overview/index.js +3 -0
  362. package/dist_ts_web/elements/overview/ops-view-config.d.ts +19 -0
  363. package/dist_ts_web/elements/overview/ops-view-config.js +339 -0
  364. package/dist_ts_web/elements/overview/ops-view-overview.d.ts +24 -0
  365. package/dist_ts_web/elements/overview/ops-view-overview.js +545 -0
  366. package/dist_ts_web/elements/security/index.d.ts +3 -0
  367. package/dist_ts_web/elements/security/index.js +4 -0
  368. package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +13 -0
  369. package/dist_ts_web/elements/security/ops-view-security-authentication.js +157 -0
  370. package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +15 -0
  371. package/dist_ts_web/elements/security/ops-view-security-blocked.js +153 -0
  372. package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +16 -0
  373. package/dist_ts_web/elements/security/ops-view-security-overview.js +205 -0
  374. package/dist_ts_web/elements/shared/css.d.ts +1 -0
  375. package/dist_ts_web/elements/shared/css.js +10 -0
  376. package/dist_ts_web/elements/shared/index.d.ts +1 -0
  377. package/dist_ts_web/elements/shared/index.js +2 -0
  378. package/dist_ts_web/index.d.ts +1 -0
  379. package/dist_ts_web/index.js +10 -0
  380. package/dist_ts_web/plugins.d.ts +7 -0
  381. package/dist_ts_web/plugins.js +13 -0
  382. package/dist_ts_web/router.d.ts +21 -0
  383. package/dist_ts_web/router.js +151 -0
  384. package/package.json +1 -1
  385. package/ts/00_commitinfo_data.ts +1 -1
  386. package/ts/monitoring/classes.metricsmanager.ts +0 -25
  387. package/ts_web/00_commitinfo_data.ts +1 -1
  388. package/ts_web/elements/network/ops-view-routes.ts +9 -1
@@ -0,0 +1,873 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { DeesElement, html, customElement, css, state, cssManager, } from '@design.estate/dees-element';
36
+ import * as plugins from '../../plugins.js';
37
+ import * as appstate from '../../appstate.js';
38
+ import * as interfaces from '../../../dist_ts_interfaces/index.js';
39
+ import { viewHostCss } from '../shared/css.js';
40
+ import {} from '@design.estate/dees-catalog';
41
+ /**
42
+ * Toggle form field visibility based on checkbox states.
43
+ * Used in Create and Edit VPN client dialogs.
44
+ */
45
+ function setupFormVisibility(formEl) {
46
+ const show = 'flex'; // match dees-form's flex layout
47
+ const updateVisibility = async () => {
48
+ const data = await formEl.collectFormData();
49
+ const contentEl = formEl.closest('.content') || formEl.parentElement;
50
+ if (!contentEl)
51
+ return;
52
+ const hostIpGroup = contentEl.querySelector('.hostIpGroup');
53
+ const hostIpDetails = contentEl.querySelector('.hostIpDetails');
54
+ const staticIpGroup = contentEl.querySelector('.staticIpGroup');
55
+ const vlanIdGroup = contentEl.querySelector('.vlanIdGroup');
56
+ const aclGroup = contentEl.querySelector('.aclGroup');
57
+ if (hostIpGroup)
58
+ hostIpGroup.style.display = show; // always show (forceTarget is always on)
59
+ if (hostIpDetails)
60
+ hostIpDetails.style.display = data.useHostIp ? show : 'none';
61
+ if (staticIpGroup)
62
+ staticIpGroup.style.display = data.useDhcp ? 'none' : show;
63
+ if (vlanIdGroup)
64
+ vlanIdGroup.style.display = data.forceVlan ? show : 'none';
65
+ if (aclGroup)
66
+ aclGroup.style.display = data.allowAdditionalAcls ? show : 'none';
67
+ };
68
+ formEl.changeSubject.subscribe(() => updateVisibility());
69
+ updateVisibility();
70
+ }
71
+ let OpsViewVpn = (() => {
72
+ let _classDecorators = [customElement('ops-view-vpn')];
73
+ let _classDescriptor;
74
+ let _classExtraInitializers = [];
75
+ let _classThis;
76
+ let _classSuper = DeesElement;
77
+ let _vpnState_decorators;
78
+ let _vpnState_initializers = [];
79
+ let _vpnState_extraInitializers = [];
80
+ var OpsViewVpn = class extends _classSuper {
81
+ static { _classThis = this; }
82
+ static {
83
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
84
+ _vpnState_decorators = [state()];
85
+ __esDecorate(this, null, _vpnState_decorators, { kind: "accessor", name: "vpnState", static: false, private: false, access: { has: obj => "vpnState" in obj, get: obj => obj.vpnState, set: (obj, value) => { obj.vpnState = value; } }, metadata: _metadata }, _vpnState_initializers, _vpnState_extraInitializers);
86
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
87
+ OpsViewVpn = _classThis = _classDescriptor.value;
88
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
89
+ }
90
+ #vpnState_accessor_storage = __runInitializers(this, _vpnState_initializers, appstate.vpnStatePart.getState());
91
+ get vpnState() { return this.#vpnState_accessor_storage; }
92
+ set vpnState(value) { this.#vpnState_accessor_storage = value; }
93
+ constructor() {
94
+ super();
95
+ __runInitializers(this, _vpnState_extraInitializers);
96
+ const sub = appstate.vpnStatePart.select().subscribe((newState) => {
97
+ this.vpnState = newState;
98
+ });
99
+ this.rxSubscriptions.push(sub);
100
+ }
101
+ async connectedCallback() {
102
+ await super.connectedCallback();
103
+ await appstate.vpnStatePart.dispatchAction(appstate.fetchVpnAction, null);
104
+ // Ensure target profiles are loaded for autocomplete candidates
105
+ await appstate.targetProfilesStatePart.dispatchAction(appstate.fetchTargetProfilesAction, null);
106
+ }
107
+ static styles = [
108
+ cssManager.defaultStyles,
109
+ viewHostCss,
110
+ css `
111
+ .vpnContainer {
112
+ display: flex;
113
+ flex-direction: column;
114
+ gap: 24px;
115
+ }
116
+
117
+ .statusBadge {
118
+ display: inline-flex;
119
+ align-items: center;
120
+ padding: 3px 10px;
121
+ border-radius: 12px;
122
+ font-size: 12px;
123
+ font-weight: 600;
124
+ letter-spacing: 0.02em;
125
+ text-transform: uppercase;
126
+ }
127
+
128
+ .statusBadge.enabled {
129
+ background: ${cssManager.bdTheme('#dcfce7', '#14532d')};
130
+ color: ${cssManager.bdTheme('#166534', '#4ade80')};
131
+ }
132
+
133
+ .statusBadge.disabled {
134
+ background: ${cssManager.bdTheme('#fef2f2', '#450a0a')};
135
+ color: ${cssManager.bdTheme('#991b1b', '#f87171')};
136
+ }
137
+
138
+ .configDialog {
139
+ padding: 16px;
140
+ background: ${cssManager.bdTheme('#fffbeb', '#1c1917')};
141
+ border: 1px solid ${cssManager.bdTheme('#fbbf24', '#92400e')};
142
+ border-radius: 8px;
143
+ margin-bottom: 16px;
144
+ }
145
+
146
+ .configDialog pre {
147
+ display: block;
148
+ padding: 12px;
149
+ background: ${cssManager.bdTheme('#1f2937', '#111827')};
150
+ color: #10b981;
151
+ border-radius: 4px;
152
+ font-family: monospace;
153
+ font-size: 12px;
154
+ white-space: pre-wrap;
155
+ word-break: break-all;
156
+ margin: 8px 0;
157
+ user-select: all;
158
+ max-height: 300px;
159
+ overflow-y: auto;
160
+ }
161
+
162
+ .configDialog .warning {
163
+ font-size: 12px;
164
+ color: ${cssManager.bdTheme('#92400e', '#fbbf24')};
165
+ margin-top: 8px;
166
+ }
167
+
168
+ .tagBadge {
169
+ display: inline-flex;
170
+ padding: 2px 8px;
171
+ border-radius: 4px;
172
+ font-size: 12px;
173
+ font-weight: 500;
174
+ background: ${cssManager.bdTheme('#eff6ff', '#172554')};
175
+ color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};
176
+ margin-right: 4px;
177
+ }
178
+
179
+ .serverInfo {
180
+ display: grid;
181
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
182
+ gap: 12px;
183
+ padding: 16px;
184
+ background: ${cssManager.bdTheme('#f9fafb', '#111827')};
185
+ border-radius: 8px;
186
+ border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#1f2937')};
187
+ }
188
+
189
+ .serverInfo .infoItem {
190
+ display: flex;
191
+ flex-direction: column;
192
+ gap: 4px;
193
+ }
194
+
195
+ .serverInfo .infoLabel {
196
+ font-size: 11px;
197
+ font-weight: 600;
198
+ text-transform: uppercase;
199
+ letter-spacing: 0.05em;
200
+ color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
201
+ }
202
+
203
+ .serverInfo .infoValue {
204
+ font-size: 14px;
205
+ font-family: monospace;
206
+ color: ${cssManager.bdTheme('#111827', '#f9fafb')};
207
+ }
208
+ `,
209
+ ];
210
+ /** Look up connected client info by clientId or assignedIp */
211
+ getConnectedInfo(client) {
212
+ return this.vpnState.connectedClients?.find(c => c.clientId === client.clientId || (client.assignedIp && c.assignedIp === client.assignedIp));
213
+ }
214
+ render() {
215
+ const status = this.vpnState.status;
216
+ const clients = this.vpnState.clients;
217
+ const connectedClients = this.vpnState.connectedClients || [];
218
+ const connectedCount = connectedClients.length;
219
+ const totalClients = clients.length;
220
+ const enabledClients = clients.filter(c => c.enabled).length;
221
+ const statsTiles = [
222
+ {
223
+ id: 'totalClients',
224
+ title: 'Total Clients',
225
+ type: 'number',
226
+ value: totalClients,
227
+ icon: 'lucide:users',
228
+ description: 'Registered VPN clients',
229
+ color: '#3b82f6',
230
+ },
231
+ {
232
+ id: 'connectedClients',
233
+ title: 'Connected',
234
+ type: 'number',
235
+ value: connectedCount,
236
+ icon: 'lucide:link',
237
+ description: 'Currently connected',
238
+ color: '#10b981',
239
+ },
240
+ {
241
+ id: 'enabledClients',
242
+ title: 'Enabled',
243
+ type: 'number',
244
+ value: enabledClients,
245
+ icon: 'lucide:shieldCheck',
246
+ description: 'Active client registrations',
247
+ color: '#8b5cf6',
248
+ },
249
+ {
250
+ id: 'serverStatus',
251
+ title: 'Server',
252
+ type: 'text',
253
+ value: status?.running ? 'Running' : 'Stopped',
254
+ icon: 'lucide:server',
255
+ description: status?.running ? 'Active' : 'VPN server not running',
256
+ color: status?.running ? '#10b981' : '#ef4444',
257
+ },
258
+ ];
259
+ return html `
260
+ <dees-heading level="3">VPN</dees-heading>
261
+ <div class="vpnContainer">
262
+
263
+ ${this.vpnState.newClientConfig ? html `
264
+ <div class="configDialog">
265
+ <strong>Client created successfully!</strong>
266
+ <div class="warning">Copy the WireGuard config now. It contains private keys that won't be shown again.</div>
267
+ <pre>${this.vpnState.newClientConfig}</pre>
268
+ <dees-button
269
+ @click=${async () => {
270
+ if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
271
+ await navigator.clipboard.writeText(this.vpnState.newClientConfig);
272
+ }
273
+ const { DeesToast } = await import('@design.estate/dees-catalog');
274
+ DeesToast.createAndShow({ message: 'Config copied to clipboard', type: 'success', duration: 3000 });
275
+ }}
276
+ >Copy to Clipboard</dees-button>
277
+ <dees-button
278
+ @click=${() => {
279
+ const blob = new Blob([this.vpnState.newClientConfig], { type: 'text/plain' });
280
+ const url = URL.createObjectURL(blob);
281
+ const a = document.createElement('a');
282
+ a.href = url;
283
+ a.download = 'wireguard.conf';
284
+ a.click();
285
+ URL.revokeObjectURL(url);
286
+ }}
287
+ >Download .conf</dees-button>
288
+ <dees-button
289
+ @click=${async () => {
290
+ const dataUrl = await plugins.qrcode.toDataURL(this.vpnState.newClientConfig, { width: 400, margin: 2 });
291
+ const { DeesModal } = await import('@design.estate/dees-catalog');
292
+ DeesModal.createAndShow({
293
+ heading: 'WireGuard QR Code',
294
+ content: html `
295
+ <div style="text-align: center; padding: 16px;">
296
+ <img src="${dataUrl}" style="max-width: 100%; image-rendering: pixelated;" />
297
+ <p style="margin-top: 12px; font-size: 13px; color: #9ca3af;">
298
+ Scan with the WireGuard app on your phone
299
+ </p>
300
+ </div>
301
+ `,
302
+ menuOptions: [
303
+ { name: 'Close', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
304
+ ],
305
+ });
306
+ }}
307
+ >Show QR Code</dees-button>
308
+ <dees-button
309
+ @click=${() => appstate.vpnStatePart.dispatchAction(appstate.clearNewClientConfigAction, null)}
310
+ >Dismiss</dees-button>
311
+ </div>
312
+ ` : ''}
313
+
314
+ <dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
315
+
316
+ ${status ? html `
317
+ <div class="serverInfo">
318
+ <div class="infoItem">
319
+ <span class="infoLabel">Subnet</span>
320
+ <span class="infoValue">${status.subnet}</span>
321
+ </div>
322
+ <div class="infoItem">
323
+ <span class="infoLabel">WireGuard Port</span>
324
+ <span class="infoValue">${status.wgListenPort}</span>
325
+ </div>
326
+ ${status.serverPublicKeys ? html `
327
+ <div class="infoItem">
328
+ <span class="infoLabel">WG Public Key</span>
329
+ <span class="infoValue" style="font-size: 11px; word-break: break-all;">${status.serverPublicKeys.wgPublicKey}</span>
330
+ </div>
331
+ ` : ''}
332
+ </div>
333
+ ` : ''}
334
+
335
+ <dees-table
336
+ .heading1=${'VPN Clients'}
337
+ .heading2=${'Manage WireGuard and SmartVPN client registrations'}
338
+ .data=${clients}
339
+ .rowKey=${'clientId'}
340
+ .highlightUpdates=${'flash'}
341
+ .showColumnFilters=${true}
342
+ .displayFunction=${(client) => {
343
+ const conn = this.getConnectedInfo(client);
344
+ let statusHtml;
345
+ if (!client.enabled) {
346
+ statusHtml = html `<span class="statusBadge disabled">disabled</span>`;
347
+ }
348
+ else if (conn) {
349
+ const since = new Date(conn.connectedSince).toLocaleString();
350
+ statusHtml = html `<span class="statusBadge enabled" title="Since ${since}">connected</span>`;
351
+ }
352
+ else {
353
+ statusHtml = html `<span class="statusBadge enabled" style="background: ${cssManager.bdTheme('#eff6ff', '#172554')}; color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};">offline</span>`;
354
+ }
355
+ let routingHtml;
356
+ if (client.useHostIp) {
357
+ routingHtml = html `<span class="statusBadge" style="background: ${cssManager.bdTheme('#f3e8ff', '#3b0764')}; color: ${cssManager.bdTheme('#7c3aed', '#c084fc')};">Host IP</span>`;
358
+ }
359
+ else {
360
+ routingHtml = html `<span class="statusBadge" style="background: ${cssManager.bdTheme('#eff6ff', '#172554')}; color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};">Direct</span>`;
361
+ }
362
+ return {
363
+ 'Client ID': client.clientId,
364
+ 'Status': statusHtml,
365
+ 'Routing': routingHtml,
366
+ 'VPN IP': client.assignedIp || '-',
367
+ 'Target Profiles': client.targetProfileIds?.length
368
+ ? html `${client.targetProfileIds.map(id => {
369
+ const profileState = appstate.targetProfilesStatePart.getState();
370
+ const profile = profileState?.profiles.find(p => p.id === id);
371
+ return html `<span class="tagBadge">${profile?.name || id}</span>`;
372
+ })}`
373
+ : '-',
374
+ 'Description': client.description || '-',
375
+ 'Created': new Date(client.createdAt).toLocaleDateString(),
376
+ };
377
+ }}
378
+ .dataActions=${[
379
+ {
380
+ name: 'Create Client',
381
+ iconName: 'lucide:plus',
382
+ type: ['header'],
383
+ actionFunc: async () => {
384
+ const { DeesModal } = await import('@design.estate/dees-catalog');
385
+ const profileCandidates = this.getTargetProfileCandidates();
386
+ const createModal = await DeesModal.createAndShow({
387
+ heading: 'Create VPN Client',
388
+ content: html `
389
+ <dees-form>
390
+ <dees-input-text .key=${'clientId'} .label=${'Client ID'} .required=${true}></dees-input-text>
391
+ <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
392
+ <dees-input-list .key=${'targetProfileNames'} .label=${'Target Profiles'} .placeholder=${'Type to search profiles...'} .candidates=${profileCandidates} .allowFreeform=${false}></dees-input-list>
393
+ <div class="hostIpGroup" style="display: flex; flex-direction: column; gap: 16px;">
394
+ <dees-input-checkbox .key=${'useHostIp'} .label=${'Get Host IP'} .value=${false}></dees-input-checkbox>
395
+ <div class="hostIpDetails" style="display: none; flex-direction: column; gap: 16px;">
396
+ <dees-input-checkbox .key=${'useDhcp'} .label=${'Get IP through DHCP'} .value=${false}></dees-input-checkbox>
397
+ <div class="staticIpGroup" style="display: flex; flex-direction: column; gap: 16px;">
398
+ <dees-input-text .key=${'staticIp'} .label=${'Static IP'}></dees-input-text>
399
+ </div>
400
+ <dees-input-checkbox .key=${'forceVlan'} .label=${'Force VLAN'} .value=${false}></dees-input-checkbox>
401
+ <div class="vlanIdGroup" style="display: none; flex-direction: column; gap: 16px;">
402
+ <dees-input-text .key=${'vlanId'} .label=${'VLAN ID'}></dees-input-text>
403
+ </div>
404
+ </div>
405
+ </div>
406
+ <dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${false}></dees-input-checkbox>
407
+ <div class="aclGroup" style="display: none; flex-direction: column; gap: 16px;">
408
+ <dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List'} .description=${'Comma-separated IPs or CIDRs'}></dees-input-text>
409
+ <dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List'} .description=${'Comma-separated IPs or CIDRs'}></dees-input-text>
410
+ </div>
411
+ </dees-form>
412
+ `,
413
+ menuOptions: [
414
+ {
415
+ name: 'Cancel',
416
+ iconName: 'lucide:x',
417
+ action: async (modalArg) => await modalArg.destroy(),
418
+ },
419
+ {
420
+ name: 'Create',
421
+ iconName: 'lucide:plus',
422
+ action: async (modalArg) => {
423
+ const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
424
+ if (!form)
425
+ return;
426
+ const data = await form.collectFormData();
427
+ if (!data.clientId)
428
+ return;
429
+ const targetProfileIds = this.resolveProfileNamesToIds(Array.isArray(data.targetProfileNames) ? data.targetProfileNames : []);
430
+ // Apply conditional logic based on checkbox states
431
+ const useHostIp = data.useHostIp ?? false;
432
+ const useDhcp = useHostIp && (data.useDhcp ?? false);
433
+ const staticIp = useHostIp && !useDhcp && data.staticIp ? data.staticIp : undefined;
434
+ const forceVlan = useHostIp && (data.forceVlan ?? false);
435
+ const vlanId = forceVlan && data.vlanId ? parseInt(data.vlanId, 10) : undefined;
436
+ const allowAcls = data.allowAdditionalAcls ?? false;
437
+ const destinationAllowList = allowAcls && data.destinationAllowList
438
+ ? data.destinationAllowList.split(',').map((s) => s.trim()).filter(Boolean)
439
+ : undefined;
440
+ const destinationBlockList = allowAcls && data.destinationBlockList
441
+ ? data.destinationBlockList.split(',').map((s) => s.trim()).filter(Boolean)
442
+ : undefined;
443
+ await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
444
+ clientId: data.clientId,
445
+ description: data.description || undefined,
446
+ targetProfileIds,
447
+ useHostIp: useHostIp || undefined,
448
+ useDhcp: useDhcp || undefined,
449
+ staticIp,
450
+ forceVlan: forceVlan || undefined,
451
+ vlanId,
452
+ destinationAllowList,
453
+ destinationBlockList,
454
+ });
455
+ await modalArg.destroy();
456
+ },
457
+ },
458
+ ],
459
+ });
460
+ // Setup conditional form visibility after modal renders
461
+ const createForm = createModal?.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
462
+ if (createForm) {
463
+ await createForm.updateComplete;
464
+ setupFormVisibility(createForm);
465
+ }
466
+ },
467
+ },
468
+ {
469
+ name: 'Detail',
470
+ iconName: 'lucide:info',
471
+ type: ['doubleClick'],
472
+ actionFunc: async (actionData) => {
473
+ const client = actionData.item;
474
+ const conn = this.getConnectedInfo(client);
475
+ const { DeesModal } = await import('@design.estate/dees-catalog');
476
+ // Fetch telemetry on-demand
477
+ let telemetryHtml = html `<p style="color: #9ca3af;">Loading telemetry...</p>`;
478
+ try {
479
+ const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'getVpnClientTelemetry');
480
+ const response = await request.fire({
481
+ identity: appstate.loginStatePart.getState().identity,
482
+ clientId: client.clientId,
483
+ });
484
+ const t = response.telemetry;
485
+ if (t) {
486
+ const formatBytes = (b) => b > 1048576 ? `${(b / 1048576).toFixed(1)} MB` : b > 1024 ? `${(b / 1024).toFixed(1)} KB` : `${b} B`;
487
+ telemetryHtml = html `
488
+ <div class="serverInfo" style="margin-top: 12px;">
489
+ <div class="infoItem"><span class="infoLabel">Bytes Sent</span><span class="infoValue">${formatBytes(t.bytesSent)}</span></div>
490
+ <div class="infoItem"><span class="infoLabel">Bytes Received</span><span class="infoValue">${formatBytes(t.bytesReceived)}</span></div>
491
+ <div class="infoItem"><span class="infoLabel">Keepalives</span><span class="infoValue">${t.keepalivesReceived}</span></div>
492
+ <div class="infoItem"><span class="infoLabel">Last Keepalive</span><span class="infoValue">${t.lastKeepaliveAt ? new Date(t.lastKeepaliveAt).toLocaleString() : '-'}</span></div>
493
+ <div class="infoItem"><span class="infoLabel">Packets Dropped</span><span class="infoValue">${t.packetsDropped}</span></div>
494
+ </div>
495
+ `;
496
+ }
497
+ else {
498
+ telemetryHtml = html `<p style="color: #9ca3af;">No telemetry available (client not connected)</p>`;
499
+ }
500
+ }
501
+ catch {
502
+ telemetryHtml = html `<p style="color: #9ca3af;">Telemetry unavailable</p>`;
503
+ }
504
+ DeesModal.createAndShow({
505
+ heading: `Client: ${client.clientId}`,
506
+ content: html `
507
+ <div class="serverInfo">
508
+ <div class="infoItem"><span class="infoLabel">Client ID</span><span class="infoValue">${client.clientId}</span></div>
509
+ <div class="infoItem"><span class="infoLabel">VPN IP</span><span class="infoValue">${client.assignedIp || '-'}</span></div>
510
+ <div class="infoItem"><span class="infoLabel">Status</span><span class="infoValue">${!client.enabled ? 'Disabled' : conn ? 'Connected' : 'Offline'}</span></div>
511
+ ${conn ? html `
512
+ <div class="infoItem"><span class="infoLabel">Connected Since</span><span class="infoValue">${new Date(conn.connectedSince).toLocaleString()}</span></div>
513
+ <div class="infoItem"><span class="infoLabel">Transport</span><span class="infoValue">${conn.transport}</span></div>
514
+ ` : ''}
515
+ <div class="infoItem"><span class="infoLabel">Description</span><span class="infoValue">${client.description || '-'}</span></div>
516
+ <div class="infoItem"><span class="infoLabel">Target Profiles</span><span class="infoValue">${this.resolveProfileIdsToNames(client.targetProfileIds)?.join(', ') || '-'}</span></div>
517
+ <div class="infoItem"><span class="infoLabel">Routing</span><span class="infoValue">${client.useHostIp ? 'Host IP' : 'SmartProxy'}</span></div>
518
+ ${client.useHostIp ? html `
519
+ <div class="infoItem"><span class="infoLabel">Host IP</span><span class="infoValue">${client.useDhcp ? 'DHCP' : client.staticIp ? `Static: ${client.staticIp}` : 'Not configured'}</span></div>
520
+ <div class="infoItem"><span class="infoLabel">VLAN</span><span class="infoValue">${client.forceVlan && client.vlanId != null ? `VLAN ${client.vlanId}` : 'No VLAN'}</span></div>
521
+ ` : ''}
522
+ <div class="infoItem"><span class="infoLabel">Allow List</span><span class="infoValue">${client.destinationAllowList?.length ? client.destinationAllowList.join(', ') : 'None'}</span></div>
523
+ <div class="infoItem"><span class="infoLabel">Block List</span><span class="infoValue">${client.destinationBlockList?.length ? client.destinationBlockList.join(', ') : 'None'}</span></div>
524
+ <div class="infoItem"><span class="infoLabel">Created</span><span class="infoValue">${new Date(client.createdAt).toLocaleString()}</span></div>
525
+ <div class="infoItem"><span class="infoLabel">Updated</span><span class="infoValue">${new Date(client.updatedAt).toLocaleString()}</span></div>
526
+ </div>
527
+ <h3 style="margin: 16px 0 4px; font-size: 14px;">Telemetry</h3>
528
+ ${telemetryHtml}
529
+ `,
530
+ menuOptions: [
531
+ { name: 'Close', iconName: 'lucide:x', action: async (m) => await m.destroy() },
532
+ ],
533
+ });
534
+ },
535
+ },
536
+ {
537
+ name: 'Enable',
538
+ iconName: 'lucide:power',
539
+ type: ['contextmenu', 'inRow'],
540
+ actionRelevancyCheckFunc: (actionData) => !actionData.item.enabled,
541
+ actionFunc: async (actionData) => {
542
+ const client = actionData.item;
543
+ await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
544
+ clientId: client.clientId,
545
+ enabled: true,
546
+ });
547
+ },
548
+ },
549
+ {
550
+ name: 'Disable',
551
+ iconName: 'lucide:power',
552
+ type: ['contextmenu', 'inRow'],
553
+ actionRelevancyCheckFunc: (actionData) => actionData.item.enabled,
554
+ actionFunc: async (actionData) => {
555
+ const client = actionData.item;
556
+ await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
557
+ clientId: client.clientId,
558
+ enabled: false,
559
+ });
560
+ },
561
+ },
562
+ {
563
+ name: 'Export Config',
564
+ iconName: 'lucide:download',
565
+ type: ['contextmenu', 'inRow'],
566
+ actionFunc: async (actionData) => {
567
+ const client = actionData.item;
568
+ const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
569
+ const exportConfig = async (format) => {
570
+ try {
571
+ const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'exportVpnClientConfig');
572
+ const response = await request.fire({
573
+ identity: appstate.loginStatePart.getState().identity,
574
+ clientId: client.clientId,
575
+ format,
576
+ });
577
+ if (response.success && response.config) {
578
+ const ext = format === 'wireguard' ? 'conf' : 'json';
579
+ const blob = new Blob([response.config], { type: 'text/plain' });
580
+ const url = URL.createObjectURL(blob);
581
+ const a = document.createElement('a');
582
+ a.href = url;
583
+ a.download = `${client.clientId}.${ext}`;
584
+ a.click();
585
+ URL.revokeObjectURL(url);
586
+ DeesToast.createAndShow({ message: `${format} config downloaded`, type: 'success', duration: 3000 });
587
+ }
588
+ else {
589
+ DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
590
+ }
591
+ }
592
+ catch (err) {
593
+ DeesToast.createAndShow({ message: err.message || 'Export failed', type: 'error', duration: 5000 });
594
+ }
595
+ };
596
+ const showQrCode = async () => {
597
+ try {
598
+ const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'exportVpnClientConfig');
599
+ const response = await request.fire({
600
+ identity: appstate.loginStatePart.getState().identity,
601
+ clientId: client.clientId,
602
+ format: 'wireguard',
603
+ });
604
+ if (response.success && response.config) {
605
+ const dataUrl = await plugins.qrcode.toDataURL(response.config, { width: 400, margin: 2 });
606
+ DeesModal.createAndShow({
607
+ heading: `QR Code: ${client.clientId}`,
608
+ content: html `
609
+ <div style="text-align: center; padding: 16px;">
610
+ <img src="${dataUrl}" style="max-width: 100%; image-rendering: pixelated;" />
611
+ <p style="margin-top: 12px; font-size: 13px; color: #9ca3af;">
612
+ Scan with the WireGuard app on your phone
613
+ </p>
614
+ </div>
615
+ `,
616
+ menuOptions: [
617
+ { name: 'Close', iconName: 'lucide:x', action: async (m) => await m.destroy() },
618
+ ],
619
+ });
620
+ }
621
+ else {
622
+ DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
623
+ }
624
+ }
625
+ catch (err) {
626
+ DeesToast.createAndShow({ message: err.message || 'QR generation failed', type: 'error', duration: 5000 });
627
+ }
628
+ };
629
+ DeesModal.createAndShow({
630
+ heading: `Export Config: ${client.clientId}`,
631
+ content: html `<p>Choose a config format to download.</p>`,
632
+ menuOptions: [
633
+ {
634
+ name: 'WireGuard (.conf)',
635
+ iconName: 'lucide:shield',
636
+ action: async (modalArg) => {
637
+ await modalArg.destroy();
638
+ await exportConfig('wireguard');
639
+ },
640
+ },
641
+ {
642
+ name: 'SmartVPN (.json)',
643
+ iconName: 'lucide:braces',
644
+ action: async (modalArg) => {
645
+ await modalArg.destroy();
646
+ await exportConfig('smartvpn');
647
+ },
648
+ },
649
+ {
650
+ name: 'QR Code (WireGuard)',
651
+ iconName: 'lucide:qr-code',
652
+ action: async (modalArg) => {
653
+ await modalArg.destroy();
654
+ await showQrCode();
655
+ },
656
+ },
657
+ {
658
+ name: 'Cancel',
659
+ iconName: 'lucide:x',
660
+ action: async (modalArg) => await modalArg.destroy(),
661
+ },
662
+ ],
663
+ });
664
+ },
665
+ },
666
+ {
667
+ name: 'Edit',
668
+ iconName: 'lucide:pencil',
669
+ type: ['contextmenu', 'inRow'],
670
+ actionFunc: async (actionData) => {
671
+ const client = actionData.item;
672
+ const { DeesModal } = await import('@design.estate/dees-catalog');
673
+ const currentDescription = client.description ?? '';
674
+ const currentTargetProfileNames = this.resolveProfileIdsToNames(client.targetProfileIds) || [];
675
+ const profileCandidates = this.getTargetProfileCandidates();
676
+ const currentUseHostIp = client.useHostIp ?? false;
677
+ const currentUseDhcp = client.useDhcp ?? false;
678
+ const currentStaticIp = client.staticIp ?? '';
679
+ const currentForceVlan = client.forceVlan ?? false;
680
+ const currentVlanId = client.vlanId != null ? String(client.vlanId) : '';
681
+ const currentAllowList = client.destinationAllowList?.join(', ') ?? '';
682
+ const currentBlockList = client.destinationBlockList?.join(', ') ?? '';
683
+ const currentAllowAcls = (client.destinationAllowList?.length ?? 0) > 0
684
+ || (client.destinationBlockList?.length ?? 0) > 0;
685
+ const editModal = await DeesModal.createAndShow({
686
+ heading: `Edit: ${client.clientId}`,
687
+ content: html `
688
+ <dees-form>
689
+ <dees-input-text .key=${'description'} .label=${'Description'} .value=${currentDescription}></dees-input-text>
690
+ <dees-input-list .key=${'targetProfileNames'} .label=${'Target Profiles'} .placeholder=${'Type to search profiles...'} .candidates=${profileCandidates} .allowFreeform=${false} .value=${currentTargetProfileNames}></dees-input-list>
691
+ <div class="hostIpGroup" style="display: flex; flex-direction: column; gap: 16px;">
692
+ <dees-input-checkbox .key=${'useHostIp'} .label=${'Get Host IP'} .value=${currentUseHostIp}></dees-input-checkbox>
693
+ <div class="hostIpDetails" style="display: ${currentUseHostIp ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
694
+ <dees-input-checkbox .key=${'useDhcp'} .label=${'Get IP through DHCP'} .value=${currentUseDhcp}></dees-input-checkbox>
695
+ <div class="staticIpGroup" style="display: ${currentUseDhcp ? 'none' : 'flex'}; flex-direction: column; gap: 16px;">
696
+ <dees-input-text .key=${'staticIp'} .label=${'Static IP'} .value=${currentStaticIp}></dees-input-text>
697
+ </div>
698
+ <dees-input-checkbox .key=${'forceVlan'} .label=${'Force VLAN'} .value=${currentForceVlan}></dees-input-checkbox>
699
+ <div class="vlanIdGroup" style="display: ${currentForceVlan ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
700
+ <dees-input-text .key=${'vlanId'} .label=${'VLAN ID'} .value=${currentVlanId}></dees-input-text>
701
+ </div>
702
+ </div>
703
+ </div>
704
+ <dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${currentAllowAcls}></dees-input-checkbox>
705
+ <div class="aclGroup" style="display: ${currentAllowAcls ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
706
+ <dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List'} .description=${'Comma-separated IPs or CIDRs'} .value=${currentAllowList}></dees-input-text>
707
+ <dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List'} .description=${'Comma-separated IPs or CIDRs'} .value=${currentBlockList}></dees-input-text>
708
+ </div>
709
+ </dees-form>
710
+ `,
711
+ menuOptions: [
712
+ { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
713
+ {
714
+ name: 'Save',
715
+ iconName: 'lucide:check',
716
+ action: async (modalArg) => {
717
+ const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
718
+ if (!form)
719
+ return;
720
+ const data = await form.collectFormData();
721
+ const targetProfileIds = this.resolveProfileNamesToIds(Array.isArray(data.targetProfileNames) ? data.targetProfileNames : []);
722
+ // Apply conditional logic based on checkbox states
723
+ const useHostIp = data.useHostIp ?? false;
724
+ const useDhcp = useHostIp && (data.useDhcp ?? false);
725
+ const staticIp = useHostIp && !useDhcp && data.staticIp ? data.staticIp : undefined;
726
+ const forceVlan = useHostIp && (data.forceVlan ?? false);
727
+ const vlanId = forceVlan && data.vlanId ? parseInt(data.vlanId, 10) : undefined;
728
+ const allowAcls = data.allowAdditionalAcls ?? false;
729
+ const destinationAllowList = allowAcls && data.destinationAllowList
730
+ ? data.destinationAllowList.split(',').map((s) => s.trim()).filter(Boolean)
731
+ : [];
732
+ const destinationBlockList = allowAcls && data.destinationBlockList
733
+ ? data.destinationBlockList.split(',').map((s) => s.trim()).filter(Boolean)
734
+ : [];
735
+ await appstate.vpnStatePart.dispatchAction(appstate.updateVpnClientAction, {
736
+ clientId: client.clientId,
737
+ description: data.description || undefined,
738
+ targetProfileIds,
739
+ useHostIp: useHostIp || undefined,
740
+ useDhcp: useDhcp || undefined,
741
+ staticIp,
742
+ forceVlan: forceVlan || undefined,
743
+ vlanId,
744
+ destinationAllowList,
745
+ destinationBlockList,
746
+ });
747
+ await modalArg.destroy();
748
+ },
749
+ },
750
+ ],
751
+ });
752
+ // Setup conditional form visibility for edit dialog
753
+ const editForm = editModal?.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
754
+ if (editForm) {
755
+ await editForm.updateComplete;
756
+ setupFormVisibility(editForm);
757
+ }
758
+ },
759
+ },
760
+ {
761
+ name: 'Rotate Keys',
762
+ iconName: 'lucide:rotate-cw',
763
+ type: ['contextmenu'],
764
+ actionFunc: async (actionData) => {
765
+ const client = actionData.item;
766
+ const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
767
+ DeesModal.createAndShow({
768
+ heading: 'Rotate Client Keys',
769
+ content: html `<p>Generate new keys for "${client.clientId}"? The old keys will be invalidated and the client will need the new config to reconnect.</p>`,
770
+ menuOptions: [
771
+ { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
772
+ {
773
+ name: 'Rotate',
774
+ iconName: 'lucide:rotate-cw',
775
+ action: async (modalArg) => {
776
+ try {
777
+ const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'rotateVpnClientKey');
778
+ const response = await request.fire({
779
+ identity: appstate.loginStatePart.getState().identity,
780
+ clientId: client.clientId,
781
+ });
782
+ if (response.success && response.wireguardConfig) {
783
+ appstate.vpnStatePart.setState({
784
+ ...appstate.vpnStatePart.getState(),
785
+ newClientConfig: response.wireguardConfig,
786
+ });
787
+ }
788
+ await modalArg.destroy();
789
+ }
790
+ catch (err) {
791
+ DeesToast.createAndShow({ message: err.message || 'Rotate failed', type: 'error', duration: 5000 });
792
+ }
793
+ },
794
+ },
795
+ ],
796
+ });
797
+ },
798
+ },
799
+ {
800
+ name: 'Delete',
801
+ iconName: 'lucide:trash2',
802
+ type: ['contextmenu'],
803
+ actionFunc: async (actionData) => {
804
+ const client = actionData.item;
805
+ const { DeesModal } = await import('@design.estate/dees-catalog');
806
+ DeesModal.createAndShow({
807
+ heading: 'Delete VPN Client',
808
+ content: html `<p>Are you sure you want to delete client "${client.clientId}"?</p>`,
809
+ menuOptions: [
810
+ { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
811
+ {
812
+ name: 'Delete',
813
+ iconName: 'lucide:trash2',
814
+ action: async (modalArg) => {
815
+ await appstate.vpnStatePart.dispatchAction(appstate.deleteVpnClientAction, client.clientId);
816
+ await modalArg.destroy();
817
+ },
818
+ },
819
+ ],
820
+ });
821
+ },
822
+ },
823
+ ]}
824
+ ></dees-table>
825
+ </div>
826
+ `;
827
+ }
828
+ /**
829
+ * Build autocomplete candidates from loaded target profiles.
830
+ * viewKey = profile name (displayed), payload = { id } (carried for resolution).
831
+ */
832
+ getTargetProfileCandidates() {
833
+ const profileState = appstate.targetProfilesStatePart.getState();
834
+ const profiles = profileState?.profiles || [];
835
+ return profiles.map((p) => ({ viewKey: p.name, payload: { id: p.id } }));
836
+ }
837
+ /**
838
+ * Convert profile IDs to profile names (for populating edit form values).
839
+ */
840
+ resolveProfileIdsToNames(ids) {
841
+ if (!ids?.length)
842
+ return undefined;
843
+ const profileState = appstate.targetProfilesStatePart.getState();
844
+ const profiles = profileState?.profiles || [];
845
+ return ids.map((id) => {
846
+ const profile = profiles.find((p) => p.id === id);
847
+ return profile?.name || id;
848
+ });
849
+ }
850
+ /**
851
+ * Convert profile names back to IDs (for saving form data).
852
+ * Uses the dees-input-list candidates' payload when available.
853
+ */
854
+ resolveProfileNamesToIds(names) {
855
+ if (!names.length)
856
+ return undefined;
857
+ const profileState = appstate.targetProfilesStatePart.getState();
858
+ const profiles = profileState?.profiles || [];
859
+ return names
860
+ .map((name) => {
861
+ const profile = profiles.find((p) => p.name === name);
862
+ return profile?.id;
863
+ })
864
+ .filter((id) => !!id);
865
+ }
866
+ static {
867
+ __runInitializers(_classThis, _classExtraInitializers);
868
+ }
869
+ };
870
+ return OpsViewVpn = _classThis;
871
+ })();
872
+ export { OpsViewVpn };
873
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctdnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHNfd2ViL2VsZW1lbnRzL25ldHdvcmsvb3BzLXZpZXctdnBuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLElBQUksRUFDSixhQUFhLEVBRWIsR0FBRyxFQUNILEtBQUssRUFDTCxVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0FBRTlEOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBVztJQUN0QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxnQ0FBZ0M7SUFDckQsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLElBQUksRUFBRTtRQUNsQyxNQUFNLElBQUksR0FBRyxNQUFNLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1QyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxhQUFhLENBQUM7UUFDckUsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPO1FBQ3ZCLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFnQixDQUFDO1FBQzNFLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQWdCLENBQUM7UUFDL0UsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxnQkFB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