@serve.zone/dcrouter 11.17.0 → 11.19.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.
- package/dist_serve/bundle.js +2 -2
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/ops-view-vpn.js +62 -28
- package/package.json +1 -1
- package/readme.md +90 -26
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/ops-view-vpn.ts +64 -28
package/dist_serve/bundle.js
CHANGED
|
@@ -41407,7 +41407,7 @@ Customer Support Team`}};async onActivate(b){this.appui=b.appui,this.appui.setCo
|
|
|
41407
41407
|
<dees-input-text .key=${"description"} .label=${"Description"}></dees-input-text>
|
|
41408
41408
|
<dees-input-text .key=${"tags"} .label=${"Server-Defined Tags (comma-separated)"}></dees-input-text>
|
|
41409
41409
|
</dees-form>
|
|
41410
|
-
`,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async p=>await p.destroy(),"action")},{name:"Create",iconName:"lucide:plus",action:i(async p=>{let f=p.shadowRoot?.querySelector(".content")?.querySelector("dees-form");if(!f)return;let u=await f.collectFormData();if(!u.clientId)return;let g=u.tags?u.tags.split(",").map(v=>v.trim()).filter(Boolean):void 0;await Lr.dispatchAction(b1a,{clientId:u.clientId,description:u.description||void 0,serverDefinedClientTags:g}),await p.destroy()},"action")}]})},"actionFunc")},{name:"Toggle",iconName:"lucide:power",type:["contextmenu","inRow"],actionFunc:i(async h=>{await Lr.dispatchAction(x1a,{clientId:
|
|
41410
|
+
`,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async p=>await p.destroy(),"action")},{name:"Create",iconName:"lucide:plus",action:i(async p=>{let f=p.shadowRoot?.querySelector(".content")?.querySelector("dees-form");if(!f)return;let u=await f.collectFormData();if(!u.clientId)return;let g=u.tags?u.tags.split(",").map(v=>v.trim()).filter(Boolean):void 0;await Lr.dispatchAction(b1a,{clientId:u.clientId,description:u.description||void 0,serverDefinedClientTags:g}),await p.destroy()},"action")}]})},"actionFunc")},{name:"Toggle",iconName:"lucide:power",type:["contextmenu","inRow"],actionFunc:i(async h=>{let p=h.item;await Lr.dispatchAction(x1a,{clientId:p.clientId,enabled:!p.enabled})},"actionFunc")},{name:"Export Config",iconName:"lucide:download",type:["contextmenu","inRow"],actionFunc:i(async h=>{let p=h.item,{DeesModal:f,DeesToast:u}=await Promise.resolve().then(()=>(ja(),Va)),g=i(async v=>{try{let b=await new bt.plugins.typedrequest.TypedRequest("/typedrequest","exportVpnClientConfig").fire({identity:Aa.getState().identity,clientId:p.clientId,format:v});if(b.success&&b.config){let m=v==="wireguard"?"conf":"json",y=new Blob([b.config],{type:"text/plain"}),M=URL.createObjectURL(y),k=document.createElement("a");k.href=M,k.download=`${p.clientId}.${m}`,k.click(),URL.revokeObjectURL(M),u.createAndShow({message:`${v} config downloaded`,type:"success",duration:3e3})}else u.createAndShow({message:b.message||"Export failed",type:"error",duration:5e3})}catch(x){u.createAndShow({message:x.message||"Export failed",type:"error",duration:5e3})}},"exportConfig");f.createAndShow({heading:`Export Config: ${p.clientId}`,content:w`<p>Choose a config format to download.</p>`,menuOptions:[{name:"WireGuard (.conf)",iconName:"lucide:shield",action:i(async v=>{await v.destroy(),await g("wireguard")},"action")},{name:"SmartVPN (.json)",iconName:"lucide:braces",action:i(async v=>{await v.destroy(),await g("smartvpn")},"action")},{name:"Cancel",iconName:"lucide:x",action:i(async v=>await v.destroy(),"action")}]})},"actionFunc")},{name:"Rotate Keys",iconName:"lucide:rotate-cw",type:["contextmenu"],actionFunc:i(async h=>{let p=h.item,{DeesModal:f,DeesToast:u}=await Promise.resolve().then(()=>(ja(),Va));f.createAndShow({heading:"Rotate Client Keys",content:w`<p>Generate new keys for "${p.clientId}"? The old keys will be invalidated and the client will need the new config to reconnect.</p>`,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async g=>await g.destroy(),"action")},{name:"Rotate",iconName:"lucide:rotate-cw",action:i(async g=>{try{let x=await new bt.plugins.typedrequest.TypedRequest("/typedrequest","rotateVpnClientKey").fire({identity:Aa.getState().identity,clientId:p.clientId});x.success&&x.wireguardConfig&&Lr.setState({...Lr.getState(),newClientConfig:x.wireguardConfig}),await g.destroy()}catch(v){u.createAndShow({message:v.message||"Rotate failed",type:"error",duration:5e3})}},"action")}]})},"actionFunc")},{name:"Delete",iconName:"lucide:trash2",type:["contextmenu"],actionFunc:i(async h=>{let p=h.item,{DeesModal:f}=await Promise.resolve().then(()=>(ja(),Va));f.createAndShow({heading:"Delete VPN Client",content:w`<p>Are you sure you want to delete client "${p.clientId}"?</p>`,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async u=>await u.destroy(),"action")},{name:"Delete",iconName:"lucide:trash2",action:i(async u=>{await Lr.dispatchAction(v1a,p.clientId),await u.destroy()},"action")}]})},"actionFunc")}]}
|
|
41411
41411
|
></dees-table>
|
|
41412
41412
|
</div>
|
|
41413
41413
|
`}};Du=$a(mra),Oqe=new WeakMap,xt(Du,4,"vpnState",hra,_l,Oqe),_l=xt(Du,0,"OpsViewVpn",gra,_l),i(_l,"OpsViewVpn"),ta(_l,"styles",[d.defaultStyles,n1,Z`
|
|
@@ -43361,4 +43361,4 @@ ibantools/jsnext/ibantools.js:
|
|
|
43361
43361
|
* @preferred
|
|
43362
43362
|
*)
|
|
43363
43363
|
*/
|
|
43364
|
-
//# sourceMappingURL=bundle-
|
|
43364
|
+
//# sourceMappingURL=bundle-1774891496876.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.19.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.19.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|
|
@@ -342,7 +342,8 @@ let OpsViewVpn = (() => {
|
|
|
342
342
|
name: 'Toggle',
|
|
343
343
|
iconName: 'lucide:power',
|
|
344
344
|
type: ['contextmenu', 'inRow'],
|
|
345
|
-
actionFunc: async (
|
|
345
|
+
actionFunc: async (actionData) => {
|
|
346
|
+
const client = actionData.item;
|
|
346
347
|
await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
|
|
347
348
|
clientId: client.clientId,
|
|
348
349
|
enabled: !client.enabled,
|
|
@@ -353,39 +354,71 @@ let OpsViewVpn = (() => {
|
|
|
353
354
|
name: 'Export Config',
|
|
354
355
|
iconName: 'lucide:download',
|
|
355
356
|
type: ['contextmenu', 'inRow'],
|
|
356
|
-
actionFunc: async (
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
357
|
+
actionFunc: async (actionData) => {
|
|
358
|
+
const client = actionData.item;
|
|
359
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
360
|
+
const exportConfig = async (format) => {
|
|
361
|
+
try {
|
|
362
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'exportVpnClientConfig');
|
|
363
|
+
const response = await request.fire({
|
|
364
|
+
identity: appstate.loginStatePart.getState().identity,
|
|
365
|
+
clientId: client.clientId,
|
|
366
|
+
format,
|
|
367
|
+
});
|
|
368
|
+
if (response.success && response.config) {
|
|
369
|
+
const ext = format === 'wireguard' ? 'conf' : 'json';
|
|
370
|
+
const blob = new Blob([response.config], { type: 'text/plain' });
|
|
371
|
+
const url = URL.createObjectURL(blob);
|
|
372
|
+
const a = document.createElement('a');
|
|
373
|
+
a.href = url;
|
|
374
|
+
a.download = `${client.clientId}.${ext}`;
|
|
375
|
+
a.click();
|
|
376
|
+
URL.revokeObjectURL(url);
|
|
377
|
+
DeesToast.createAndShow({ message: `${format} config downloaded`, type: 'success', duration: 3000 });
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
|
|
381
|
+
}
|
|
374
382
|
}
|
|
375
|
-
|
|
376
|
-
DeesToast.createAndShow({ message:
|
|
383
|
+
catch (err) {
|
|
384
|
+
DeesToast.createAndShow({ message: err.message || 'Export failed', type: 'error', duration: 5000 });
|
|
377
385
|
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
386
|
+
};
|
|
387
|
+
DeesModal.createAndShow({
|
|
388
|
+
heading: `Export Config: ${client.clientId}`,
|
|
389
|
+
content: html `<p>Choose a config format to download.</p>`,
|
|
390
|
+
menuOptions: [
|
|
391
|
+
{
|
|
392
|
+
name: 'WireGuard (.conf)',
|
|
393
|
+
iconName: 'lucide:shield',
|
|
394
|
+
action: async (modalArg) => {
|
|
395
|
+
await modalArg.destroy();
|
|
396
|
+
await exportConfig('wireguard');
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: 'SmartVPN (.json)',
|
|
401
|
+
iconName: 'lucide:braces',
|
|
402
|
+
action: async (modalArg) => {
|
|
403
|
+
await modalArg.destroy();
|
|
404
|
+
await exportConfig('smartvpn');
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
name: 'Cancel',
|
|
409
|
+
iconName: 'lucide:x',
|
|
410
|
+
action: async (modalArg) => await modalArg.destroy(),
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
});
|
|
382
414
|
},
|
|
383
415
|
},
|
|
384
416
|
{
|
|
385
417
|
name: 'Rotate Keys',
|
|
386
418
|
iconName: 'lucide:rotate-cw',
|
|
387
419
|
type: ['contextmenu'],
|
|
388
|
-
actionFunc: async (
|
|
420
|
+
actionFunc: async (actionData) => {
|
|
421
|
+
const client = actionData.item;
|
|
389
422
|
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
390
423
|
DeesModal.createAndShow({
|
|
391
424
|
heading: 'Rotate Client Keys',
|
|
@@ -423,7 +456,8 @@ let OpsViewVpn = (() => {
|
|
|
423
456
|
name: 'Delete',
|
|
424
457
|
iconName: 'lucide:trash2',
|
|
425
458
|
type: ['contextmenu'],
|
|
426
|
-
actionFunc: async (
|
|
459
|
+
actionFunc: async (actionData) => {
|
|
460
|
+
const client = actionData.item;
|
|
427
461
|
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
428
462
|
DeesModal.createAndShow({
|
|
429
463
|
heading: 'Delete VPN Client',
|
|
@@ -454,4 +488,4 @@ let OpsViewVpn = (() => {
|
|
|
454
488
|
return OpsViewVpn = _classThis;
|
|
455
489
|
})();
|
|
456
490
|
export { OpsViewVpn };
|
|
457
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctdnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL2VsZW1lbnRzL29wcy12aWV3LXZwbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osYUFBYSxFQUViLEdBQUcsRUFDSCxLQUFLLEVBQ0wsVUFBVSxHQUNYLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxLQUFLLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEtBQUssVUFBVSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQW1CLE1BQU0sNkJBQTZCLENBQUM7SUFTakQsVUFBVTs0QkFEdEIsYUFBYSxDQUFDLGNBQWMsQ0FBQzs7OztzQkFDRSxXQUFXOzs7OzBCQUFuQixTQUFRLFdBQVc7Ozs7b0NBQ3hDLEtBQUssRUFBRTtZQUNSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFBeUQ7WUFGNUUsNktBMFlDOzs7O1FBeFlDLDZFQUF3QyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRyxFQUFDO1FBQTFFLElBQVMsUUFBUSw4Q0FBeUQ7UUFBMUUsSUFBUyxRQUFRLG9EQUF5RDtRQUUxRTtZQUNFLEtBQUssRUFBRSxDQUFDOztZQUNSLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2hFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7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
|
|
491
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctdnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL2VsZW1lbnRzL29wcy12aWV3LXZwbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osYUFBYSxFQUViLEdBQUcsRUFDSCxLQUFLLEVBQ0wsVUFBVSxHQUNYLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxLQUFLLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEtBQUssVUFBVSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQW1CLE1BQU0sNkJBQTZCLENBQUM7SUFTakQsVUFBVTs0QkFEdEIsYUFBYSxDQUFDLGNBQWMsQ0FBQzs7OztzQkFDRSxXQUFXOzs7OzBCQUFuQixTQUFRLFdBQVc7Ozs7b0NBQ3hDLEtBQUssRUFBRTtZQUNSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFBeUQ7WUFGNUUsNktBOGFDOzs7O1FBNWFDLDZFQUF3QyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRyxFQUFDO1FBQTFFLElBQVMsUUFBUSw4Q0FBeUQ7UUFBMUUsSUFBUyxRQUFRLG9EQUF5RDtRQUUxRTtZQUNFLEtBQUssRUFBRSxDQUFDOztZQUNSLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2hFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDaEM7UUFFRCxLQUFLLENBQUMsaUJBQWlCO1lBQ3JCLE1BQU0sS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDaEMsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLENBQUM7UUFFTSxNQUFNLENBQUMsTUFBTSxHQUFHO1lBQ3JCLFVBQVUsQ0FBQyxhQUFhO1lBQ3hCLFdBQVc7WUFDWCxHQUFHLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7c0JBbUJlLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQztpQkFDN0MsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs7O3NCQUluQyxVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7aUJBQzdDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQzs7Ozs7c0JBS25DLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQzs0QkFDbEMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs7Ozs7OztzQkFROUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7aUJBZTdDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQzs7Ozs7Ozs7OztzQkFVbkMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDO2lCQUM3QyxVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7Ozs7Ozs7OztzQkFTbkMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs0QkFFbEMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs7Ozs7Ozs7Ozs7OztpQkFjbkQsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDOzs7Ozs7aUJBTXhDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQzs7S0FFcEQ7U0FDRixDQUFDO1FBRUYsTUFBTTtZQUNKLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQ3BDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1lBQ3RDLE1BQU0sY0FBYyxHQUFHLE1BQU0sRUFBRSxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7WUFDckQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztZQUNwQyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUU3RCxNQUFNLFVBQVUsR0FBaUI7Z0JBQy9CO29CQUNFLEVBQUUsRUFBRSxjQUFjO29CQUNsQixLQUFLLEVBQUUsZUFBZTtvQkFDdEIsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsS0FBSyxFQUFFLFlBQVk7b0JBQ25CLElBQUksRUFBRSxjQUFjO29CQUNwQixXQUFXLEVBQUUsd0JBQXdCO29CQUNyQyxLQUFLLEVBQUUsU0FBUztpQkFDakI7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLGtCQUFrQjtvQkFDdEIsS0FBSyxFQUFFLFdBQVc7b0JBQ2xCLElBQUksRUFBRSxRQUFRO29CQUNkLEtBQUssRUFBRSxjQUFjO29CQUNyQixJQUFJLEVBQUUsYUFBYTtvQkFDbkIsV0FBVyxFQUFFLHFCQUFxQjtvQkFDbEMsS0FBSyxFQUFFLFNBQVM7aUJBQ2pCO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxnQkFBZ0I7b0JBQ3BCLEtBQUssRUFBRSxTQUFTO29CQUNoQixJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsY0FBYztvQkFDckIsSUFBSSxFQUFFLG9CQUFvQjtvQkFDMUIsV0FBVyxFQUFFLDZCQUE2QjtvQkFDMUMsS0FBSyxFQUFFLFNBQVM7aUJBQ2pCO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxjQUFjO29CQUNsQixLQUFLLEVBQUUsUUFBUTtvQkFDZixJQUFJLEVBQUUsTUFBTTtvQkFDWixLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO29CQUM5QyxJQUFJLEVBQUUsZUFBZTtvQkFDckIsV0FBVyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsd0JBQXdCO29CQUNsRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO2lCQUMvQzthQUNGLENBQUM7WUFFRixPQUFPLElBQUksQ0FBQTs7OztRQUlQLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7Ozs7aUJBSTNCLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZTs7cUJBRXpCLEtBQUssSUFBSSxFQUFFO2dCQUNsQixJQUFJLFNBQVMsQ0FBQyxTQUFTLElBQUksT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDLFNBQVMsS0FBSyxVQUFVLEVBQUUsQ0FBQztvQkFDL0UsTUFBTSxTQUFTLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWdCLENBQUMsQ0FBQztnQkFDdEUsQ0FBQztnQkFDRCxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsNkJBQTZCLENBQUMsQ0FBQztnQkFDbEUsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3RHLENBQUM7OztxQkFHUSxHQUFHLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWdCLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN0QyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN0QyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztnQkFDYixDQUFDLENBQUMsUUFBUSxHQUFHLGdCQUFnQixDQUFDO2dCQUM5QixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ1YsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQixDQUFDOzs7cUJBR1EsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLDBCQUEwQixFQUFFLElBQUksQ0FBQzs7O09BR25HLENBQUMsQ0FBQyxDQUFDLEVBQUU7OytCQUVtQixVQUFVOztRQUVqQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTs7OztzQ0FJaUIsTUFBTSxDQUFDLE1BQU07Ozs7c0NBSWIsTUFBTSxDQUFDLFlBQVk7O1lBRTdDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFBOzs7d0ZBRzhDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXOztXQUVoSCxDQUFDLENBQUMsQ0FBQyxFQUFFOztPQUVULENBQUMsQ0FBQyxDQUFDLEVBQUU7OztvQkFHUSxhQUFhO29CQUNiLG9EQUFvRDtnQkFDeEQsT0FBTzsyQkFDSSxDQUFDLE1BQWtDLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzFELFdBQVcsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDNUIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxPQUFPO29CQUN0QixDQUFDLENBQUMsSUFBSSxDQUFBLGtEQUFrRDtvQkFDeEQsQ0FBQyxDQUFDLElBQUksQ0FBQSxvREFBb0Q7Z0JBQzVELFFBQVEsRUFBRSxNQUFNLENBQUMsVUFBVSxJQUFJLEdBQUc7Z0JBQ2xDLE1BQU0sRUFBRSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsTUFBTTtvQkFDNUMsQ0FBQyxDQUFDLElBQUksQ0FBQSxHQUFHLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUEsMEJBQTBCLENBQUMsU0FBUyxDQUFDLEVBQUU7b0JBQzVGLENBQUMsQ0FBQyxHQUFHO2dCQUNQLGFBQWEsRUFBRSxNQUFNLENBQUMsV0FBVyxJQUFJLEdBQUc7Z0JBQ3hDLFNBQVMsRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsa0JBQWtCLEVBQUU7YUFDM0QsQ0FBQzt1QkFDYTtnQkFDYjtvQkFDRSxJQUFJLEVBQUUsZUFBZTtvQkFDckIsUUFBUSxFQUFFLGFBQWE7b0JBQ3ZCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEIsVUFBVSxFQUFFLEtBQUssSUFBSSxFQUFFO3dCQUNyQixNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsNkJBQTZCLENBQUMsQ0FBQzt3QkFDbEUsTUFBTSxTQUFTLENBQUMsYUFBYSxDQUFDOzRCQUM1QixPQUFPLEVBQUUsbUJBQW1COzRCQUM1QixPQUFPLEVBQUUsSUFBSSxDQUFBOzs0Q0FFZSxVQUFVLFdBQVcsV0FBVyxjQUFjLElBQUk7NENBQ2xELGFBQWEsV0FBVyxhQUFhOzRDQUNyQyxNQUFNLFdBQVcsdUNBQXVDOztpQkFFbkY7NEJBQ0QsV0FBVyxFQUFFO2dDQUNYO29DQUNFLElBQUksRUFBRSxRQUFRO29DQUNkLFFBQVEsRUFBRSxVQUFVO29DQUNwQixNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWEsRUFBRSxFQUFFLENBQUMsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFO2lDQUMxRDtnQ0FDRDtvQ0FDRSxJQUFJLEVBQUUsUUFBUTtvQ0FDZCxRQUFRLEVBQUUsYUFBYTtvQ0FDdkIsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFhLEVBQUUsRUFBRTt3Q0FDOUIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUUsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO3dDQUN4RixJQUFJLENBQUMsSUFBSTs0Q0FBRSxPQUFPO3dDQUNsQixNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzt3Q0FDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFROzRDQUFFLE9BQU87d0NBQzNCLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDLElBQUk7NENBQ3ZDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7NENBQ25FLENBQUMsQ0FBQyxTQUFTLENBQUM7d0NBQ2QsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7NENBQ3pFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTs0Q0FDdkIsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksU0FBUzs0Q0FDMUMsdUJBQXVCO3lDQUN4QixDQUFDLENBQUM7d0NBQ0gsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7b0NBQzNCLENBQUM7aUNBQ0Y7NkJBQ0Y7eUJBQ0YsQ0FBQyxDQUFDO29CQUNMLENBQUM7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsUUFBUSxFQUFFLGNBQWM7b0JBQ3hCLElBQUksRUFBRSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUM7b0JBQzlCLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBZSxFQUFFLEVBQUU7d0JBQ3BDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFrQyxDQUFDO3dCQUM3RCxNQUFNLFFBQVEsQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTs0QkFDekUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFROzRCQUN6QixPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTzt5QkFDekIsQ0FBQyxDQUFDO29CQUNMLENBQUM7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGVBQWU7b0JBQ3JCLFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLElBQUksRUFBRSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUM7b0JBQzlCLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBZSxFQUFFLEVBQUU7d0JBQ3BDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFrQyxDQUFDO3dCQUM3RCxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUM7d0JBRTdFLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxNQUFnQyxFQUFFLEVBQUU7NEJBQzlELElBQUksQ0FBQztnQ0FDSCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBRXBFLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO2dDQUM1QyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0NBQ2xDLFFBQVEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRyxDQUFDLFFBQVM7b0NBQ3ZELFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtvQ0FDekIsTUFBTTtpQ0FDUCxDQUFDLENBQUM7Z0NBQ0gsSUFBSSxRQUFRLENBQUMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQ0FDeEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7b0NBQ3JELE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7b0NBQ2pFLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7b0NBQ3RDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7b0NBQ3RDLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO29DQUNiLENBQUMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLEdBQUcsRUFBRSxDQUFDO29DQUN6QyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7b0NBQ1YsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQ0FDekIsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sb0JBQW9CLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQ0FDdkcsQ0FBQztxQ0FBTSxDQUFDO29DQUNOLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sSUFBSSxlQUFlLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQ0FDM0csQ0FBQzs0QkFDSCxDQUFDOzRCQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7Z0NBQ2xCLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sSUFBSSxlQUFlLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzs0QkFDdEcsQ0FBQzt3QkFDSCxDQUFDLENBQUM7d0JBRUYsU0FBUyxDQUFDLGFBQWEsQ0FBQzs0QkFDdEIsT0FBTyxFQUFFLGtCQUFrQixNQUFNLENBQUMsUUFBUSxFQUFFOzRCQUM1QyxPQUFPLEVBQUUsSUFBSSxDQUFBLDRDQUE0Qzs0QkFDekQsV0FBVyxFQUFFO2dDQUNYO29DQUNFLElBQUksRUFBRSxtQkFBbUI7b0NBQ3pCLFFBQVEsRUFBRSxlQUFlO29DQUN6QixNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWEsRUFBRSxFQUFFO3dDQUM5QixNQUFNLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3Q0FDekIsTUFBTSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7b0NBQ2xDLENBQUM7aUNBQ0Y7Z0NBQ0Q7b0NBQ0UsSUFBSSxFQUFFLGtCQUFrQjtvQ0FDeEIsUUFBUSxFQUFFLGVBQWU7b0NBQ3pCLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBYSxFQUFFLEVBQUU7d0NBQzlCLE1BQU0sUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO3dDQUN6QixNQUFNLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztvQ0FDakMsQ0FBQztpQ0FDRjtnQ0FDRDtvQ0FDRSxJQUFJLEVBQUUsUUFBUTtvQ0FDZCxRQUFRLEVBQUUsVUFBVTtvQ0FDcEIsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFhLEVBQUUsRUFBRSxDQUFDLE1BQU0sUUFBUSxDQUFDLE9BQU8sRUFBRTtpQ0FDMUQ7NkJBQ0Y7eUJBQ0YsQ0FBQyxDQUFDO29CQUNMLENBQUM7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLElBQUksRUFBRSxDQUFDLGFBQWEsQ0FBQztvQkFDckIsVUFBVSxFQUFFLEtBQUssRUFBRSxVQUFlLEVBQUUsRUFBRTt3QkFDcEMsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLElBQWtDLENBQUM7d0JBQzdELE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsNkJBQTZCLENBQUMsQ0FBQzt3QkFDN0UsU0FBUyxDQUFDLGFBQWEsQ0FBQzs0QkFDdEIsT0FBTyxFQUFFLG9CQUFvQjs0QkFDN0IsT0FBTyxFQUFFLElBQUksQ0FBQSw2QkFBNkIsTUFBTSxDQUFDLFFBQVEsK0ZBQStGOzRCQUN4SixXQUFXLEVBQUU7Z0NBQ1gsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFhLEVBQUUsRUFBRSxDQUFDLE1BQU0sUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dDQUNuRztvQ0FDRSxJQUFJLEVBQUUsUUFBUTtvQ0FDZCxRQUFRLEVBQUUsa0JBQWtCO29DQUM1QixNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWEsRUFBRSxFQUFFO3dDQUM5QixJQUFJLENBQUM7NENBQ0gsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUVwRSxlQUFlLEVBQUUsb0JBQW9CLENBQUMsQ0FBQzs0Q0FDekMsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDO2dEQUNsQyxRQUFRLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUcsQ0FBQyxRQUFTO2dEQUN2RCxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7NkNBQzFCLENBQUMsQ0FBQzs0Q0FDSCxJQUFJLFFBQVEsQ0FBQyxPQUFPLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dEQUNqRCxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztvREFDN0IsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRztvREFDcEMsZUFBZSxFQUFFLFFBQVEsQ0FBQyxlQUFlO2lEQUMxQyxDQUFDLENBQUM7NENBQ0wsQ0FBQzs0Q0FDRCxNQUFNLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3Q0FDM0IsQ0FBQzt3Q0FBQyxPQUFPLEdBQVEsRUFBRSxDQUFDOzRDQUNsQixTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLElBQUksZUFBZSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7d0NBQ3RHLENBQUM7b0NBQ0gsQ0FBQztpQ0FDRjs2QkFDRjt5QkFDRixDQUFDLENBQUM7b0JBQ0wsQ0FBQztpQkFDRjtnQkFDRDtvQkFDRSxJQUFJLEVBQUUsUUFBUTtvQkFDZCxRQUFRLEVBQUUsZUFBZTtvQkFDekIsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDO29CQUNyQixVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQWUsRUFBRSxFQUFFO3dCQUNwQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsSUFBa0MsQ0FBQzt3QkFDN0QsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUM7d0JBQ2xFLFNBQVMsQ0FBQyxhQUFhLENBQUM7NEJBQ3RCLE9BQU8sRUFBRSxtQkFBbUI7NEJBQzVCLE9BQU8sRUFBRSxJQUFJLENBQUEsOENBQThDLE1BQU0sQ0FBQyxRQUFRLFFBQVE7NEJBQ2xGLFdBQVcsRUFBRTtnQ0FDWCxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWEsRUFBRSxFQUFFLENBQUMsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0NBQ25HO29DQUNFLElBQUksRUFBRSxRQUFRO29DQUNkLFFBQVEsRUFBRSxlQUFlO29DQUN6QixNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWEsRUFBRSxFQUFFO3dDQUM5QixNQUFNLFFBQVEsQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7d0NBQzVGLE1BQU0sUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO29DQUMzQixDQUFDO2lDQUNGOzZCQUNGO3lCQUNGLENBQUMsQ0FBQztvQkFDTCxDQUFDO2lCQUNGO2FBQ0Y7OztLQUdKLENBQUM7UUFDSixDQUFDOztZQTdhVSx1REFBVTs7Ozs7U0FBVixVQUFVIn0=
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -77,10 +77,13 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
77
77
|
### 🔐 VPN Access Control (powered by [smartvpn](https://code.foss.global/push.rocks/smartvpn))
|
|
78
78
|
- **WireGuard + native transports** — standard WireGuard clients (iOS, Android, macOS, Windows, Linux) plus custom WebSocket/QUIC tunnels
|
|
79
79
|
- **Route-level VPN gating** — mark any route with `vpn: { required: true }` to restrict access to VPN clients only
|
|
80
|
-
- **
|
|
81
|
-
- **
|
|
80
|
+
- **Tag-based access control** — assign `serverDefinedClientTags` to clients and restrict routes with `allowedServerDefinedClientTags`
|
|
81
|
+
- **Constructor-defined clients** — pre-define VPN clients with tags in config for declarative, code-driven setup
|
|
82
|
+
- **Rootless operation** — uses userspace NAT (smoltcp) with no root required
|
|
83
|
+
- **Destination policy** — configurable `forceTarget`, `block`, or `allow` with allowList/blockList for granular traffic control
|
|
84
|
+
- **Client management** — create, enable, disable, rotate keys, export WireGuard/SmartVPN configs via OpsServer API and dashboard
|
|
82
85
|
- **IP-based enforcement** — VPN clients get IPs from a configurable subnet; SmartProxy enforces `ipAllowList` per route
|
|
83
|
-
- **PROXY protocol v2** —
|
|
86
|
+
- **PROXY protocol v2** — the NAT engine sends PP v2 on outbound connections to preserve VPN client identity
|
|
84
87
|
|
|
85
88
|
### ⚡ High Performance
|
|
86
89
|
- **Rust-powered proxy engine** via SmartProxy for maximum throughput
|
|
@@ -261,7 +264,9 @@ const router = new DcRouter({
|
|
|
261
264
|
vpnConfig: {
|
|
262
265
|
enabled: true,
|
|
263
266
|
serverEndpoint: 'vpn.example.com',
|
|
264
|
-
|
|
267
|
+
clients: [
|
|
268
|
+
{ clientId: 'dev-laptop', serverDefinedClientTags: ['engineering'] },
|
|
269
|
+
],
|
|
265
270
|
},
|
|
266
271
|
|
|
267
272
|
// Persistent storage
|
|
@@ -456,7 +461,17 @@ interface IDcRouterOptions {
|
|
|
456
461
|
wgListenPort?: number; // default: 51820
|
|
457
462
|
dns?: string[]; // DNS servers pushed to VPN clients
|
|
458
463
|
serverEndpoint?: string; // Hostname in generated client configs
|
|
459
|
-
|
|
464
|
+
clients?: Array<{ // Pre-defined VPN clients
|
|
465
|
+
clientId: string;
|
|
466
|
+
serverDefinedClientTags?: string[];
|
|
467
|
+
description?: string;
|
|
468
|
+
}>;
|
|
469
|
+
destinationPolicy?: { // Traffic routing policy
|
|
470
|
+
default: 'forceTarget' | 'block' | 'allow';
|
|
471
|
+
target?: string; // IP for forceTarget (default: '127.0.0.1')
|
|
472
|
+
allowList?: string[]; // Pass through directly
|
|
473
|
+
blockList?: string[]; // Always block (overrides allowList)
|
|
474
|
+
};
|
|
460
475
|
};
|
|
461
476
|
|
|
462
477
|
// ── HTTP/3 (QUIC) ────────────────────────────────────────────
|
|
@@ -1014,17 +1029,33 @@ DcRouter integrates [`@push.rocks/smartvpn`](https://code.foss.global/push.rocks
|
|
|
1014
1029
|
|
|
1015
1030
|
1. **SmartVPN daemon** runs inside dcrouter with a Rust data plane (WireGuard via `boringtun`, custom protocol via Noise IK)
|
|
1016
1031
|
2. Clients connect and get assigned an IP from the VPN subnet (e.g. `10.8.0.0/24`)
|
|
1017
|
-
3. Routes with `vpn: { required: true }` get `security.ipAllowList` automatically injected
|
|
1018
|
-
4.
|
|
1032
|
+
3. Routes with `vpn: { required: true }` get `security.ipAllowList` automatically injected
|
|
1033
|
+
4. When `allowedServerDefinedClientTags` is set, only matching client IPs are injected (not the whole subnet)
|
|
1034
|
+
5. SmartProxy enforces the allowlist — only authorized VPN clients can access protected routes
|
|
1035
|
+
6. All VPN traffic is forced through SmartProxy via userspace NAT with PROXY protocol v2 — no root required
|
|
1019
1036
|
|
|
1020
|
-
###
|
|
1037
|
+
### Destination Policy
|
|
1021
1038
|
|
|
1022
|
-
|
|
1023
|
-
|------|---------------|-------------|
|
|
1024
|
-
| **TUN** (`forwardingMode: 'tun'`) | Yes | Kernel TUN device — VPN traffic enters the network stack with real VPN IPs |
|
|
1025
|
-
| **Socket** (`forwardingMode: 'socket'`) | No | Userspace NAT via smoltcp — outbound connections send PROXY protocol v2 to preserve VPN client IPs |
|
|
1039
|
+
By default, VPN client traffic is redirected to localhost (SmartProxy) via `forceTarget`. You can customize this with a destination policy:
|
|
1026
1040
|
|
|
1027
|
-
|
|
1041
|
+
```typescript
|
|
1042
|
+
// Default: all traffic → SmartProxy
|
|
1043
|
+
destinationPolicy: { default: 'forceTarget', target: '127.0.0.1' }
|
|
1044
|
+
|
|
1045
|
+
// Allow direct access to a backend subnet
|
|
1046
|
+
destinationPolicy: {
|
|
1047
|
+
default: 'forceTarget',
|
|
1048
|
+
target: '127.0.0.1',
|
|
1049
|
+
allowList: ['192.168.190.*'], // direct access to this subnet
|
|
1050
|
+
blockList: ['192.168.190.1'], // except the gateway
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// Block everything except specific IPs
|
|
1054
|
+
destinationPolicy: {
|
|
1055
|
+
default: 'block',
|
|
1056
|
+
allowList: ['10.0.0.*', '192.168.1.*'],
|
|
1057
|
+
}
|
|
1058
|
+
```
|
|
1028
1059
|
|
|
1029
1060
|
### Configuration
|
|
1030
1061
|
|
|
@@ -1032,26 +1063,47 @@ DcRouter auto-detects: if running as root, it uses TUN mode; otherwise, it falls
|
|
|
1032
1063
|
const router = new DcRouter({
|
|
1033
1064
|
vpnConfig: {
|
|
1034
1065
|
enabled: true,
|
|
1035
|
-
subnet: '10.8.0.0/24',
|
|
1036
|
-
wgListenPort: 51820,
|
|
1066
|
+
subnet: '10.8.0.0/24', // VPN client IP pool (default)
|
|
1067
|
+
wgListenPort: 51820, // WireGuard UDP port (default)
|
|
1037
1068
|
serverEndpoint: 'vpn.example.com', // Hostname in generated client configs
|
|
1038
|
-
dns: ['1.1.1.1', '8.8.8.8'],
|
|
1039
|
-
|
|
1069
|
+
dns: ['1.1.1.1', '8.8.8.8'], // DNS servers pushed to clients
|
|
1070
|
+
|
|
1071
|
+
// Pre-define VPN clients with server-defined tags
|
|
1072
|
+
clients: [
|
|
1073
|
+
{ clientId: 'alice-laptop', serverDefinedClientTags: ['engineering'], description: 'Dev laptop' },
|
|
1074
|
+
{ clientId: 'bob-phone', serverDefinedClientTags: ['engineering', 'mobile'] },
|
|
1075
|
+
{ clientId: 'carol-desktop', serverDefinedClientTags: ['finance'] },
|
|
1076
|
+
],
|
|
1077
|
+
|
|
1078
|
+
// Optional: customize destination policy (default: forceTarget → localhost)
|
|
1079
|
+
// destinationPolicy: { default: 'forceTarget', target: '127.0.0.1', allowList: ['192.168.1.*'] },
|
|
1040
1080
|
},
|
|
1041
1081
|
smartProxyConfig: {
|
|
1042
1082
|
routes: [
|
|
1043
|
-
//
|
|
1083
|
+
// 🔐 VPN-only: any VPN client can access
|
|
1044
1084
|
{
|
|
1045
|
-
name: '
|
|
1046
|
-
match: { domains: ['
|
|
1085
|
+
name: 'internal-app',
|
|
1086
|
+
match: { domains: ['internal.example.com'], ports: [443] },
|
|
1047
1087
|
action: {
|
|
1048
1088
|
type: 'forward',
|
|
1049
1089
|
targets: [{ host: '192.168.1.50', port: 8080 }],
|
|
1050
1090
|
tls: { mode: 'terminate', certificate: 'auto' },
|
|
1051
1091
|
},
|
|
1052
|
-
vpn: { required: true },
|
|
1092
|
+
vpn: { required: true },
|
|
1053
1093
|
},
|
|
1054
|
-
//
|
|
1094
|
+
// 🔐 VPN + tag-restricted: only 'engineering' tagged clients
|
|
1095
|
+
{
|
|
1096
|
+
name: 'eng-dashboard',
|
|
1097
|
+
match: { domains: ['eng.example.com'], ports: [443] },
|
|
1098
|
+
action: {
|
|
1099
|
+
type: 'forward',
|
|
1100
|
+
targets: [{ host: '192.168.1.51', port: 8080 }],
|
|
1101
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
1102
|
+
},
|
|
1103
|
+
vpn: { required: true, allowedServerDefinedClientTags: ['engineering'] },
|
|
1104
|
+
// → alice + bob can access, carol cannot
|
|
1105
|
+
},
|
|
1106
|
+
// 🌐 Public: no VPN required
|
|
1055
1107
|
{
|
|
1056
1108
|
name: 'public-site',
|
|
1057
1109
|
match: { domains: ['example.com'], ports: [443] },
|
|
@@ -1066,17 +1118,29 @@ const router = new DcRouter({
|
|
|
1066
1118
|
});
|
|
1067
1119
|
```
|
|
1068
1120
|
|
|
1069
|
-
### Client
|
|
1121
|
+
### Client Tags
|
|
1122
|
+
|
|
1123
|
+
SmartVPN distinguishes between two types of client tags:
|
|
1124
|
+
|
|
1125
|
+
| Tag Type | Set By | Purpose |
|
|
1126
|
+
|----------|--------|---------|
|
|
1127
|
+
| `serverDefinedClientTags` | Admin (via config or API) | **Trusted** — used for route access control |
|
|
1128
|
+
| `clientDefinedClientTags` | Connecting client | **Informational** — displayed in dashboard, never used for security |
|
|
1129
|
+
|
|
1130
|
+
Routes with `allowedServerDefinedClientTags` only permit VPN clients whose admin-assigned tags match. Clients cannot influence their own server-defined tags.
|
|
1131
|
+
|
|
1132
|
+
### Client Management via OpsServer
|
|
1070
1133
|
|
|
1071
|
-
|
|
1134
|
+
The OpsServer dashboard and API provide full VPN client lifecycle management:
|
|
1072
1135
|
|
|
1073
1136
|
- **Create client** — generates WireGuard keypairs, assigns IP, returns a ready-to-use `.conf` file
|
|
1074
1137
|
- **Enable / Disable** — toggle client access without deleting
|
|
1075
1138
|
- **Rotate keys** — generate fresh keypairs (invalidates old ones)
|
|
1076
|
-
- **Export config** —
|
|
1139
|
+
- **Export config** — download in WireGuard (`.conf`) or SmartVPN (`.json`) format
|
|
1077
1140
|
- **Telemetry** — per-client bytes sent/received, keepalives, rate limiting
|
|
1141
|
+
- **Delete** — remove a client and revoke access
|
|
1078
1142
|
|
|
1079
|
-
Standard WireGuard clients on any platform (iOS, Android, macOS, Windows, Linux) can connect using the generated `.conf` file
|
|
1143
|
+
Standard WireGuard clients on any platform (iOS, Android, macOS, Windows, Linux) can connect using the generated `.conf` file — no custom VPN software needed.
|
|
1080
1144
|
|
|
1081
1145
|
## Certificate Management
|
|
1082
1146
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -308,7 +308,8 @@ export class OpsViewVpn extends DeesElement {
|
|
|
308
308
|
name: 'Toggle',
|
|
309
309
|
iconName: 'lucide:power',
|
|
310
310
|
type: ['contextmenu', 'inRow'],
|
|
311
|
-
actionFunc: async (
|
|
311
|
+
actionFunc: async (actionData: any) => {
|
|
312
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
312
313
|
await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
|
|
313
314
|
clientId: client.clientId,
|
|
314
315
|
enabled: !client.enabled,
|
|
@@ -319,39 +320,73 @@ export class OpsViewVpn extends DeesElement {
|
|
|
319
320
|
name: 'Export Config',
|
|
320
321
|
iconName: 'lucide:download',
|
|
321
322
|
type: ['contextmenu', 'inRow'],
|
|
322
|
-
actionFunc: async (
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
323
|
+
actionFunc: async (actionData: any) => {
|
|
324
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
325
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
326
|
+
|
|
327
|
+
const exportConfig = async (format: 'wireguard' | 'smartvpn') => {
|
|
328
|
+
try {
|
|
329
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
330
|
+
interfaces.requests.IReq_ExportVpnClientConfig
|
|
331
|
+
>('/typedrequest', 'exportVpnClientConfig');
|
|
332
|
+
const response = await request.fire({
|
|
333
|
+
identity: appstate.loginStatePart.getState()!.identity!,
|
|
334
|
+
clientId: client.clientId,
|
|
335
|
+
format,
|
|
336
|
+
});
|
|
337
|
+
if (response.success && response.config) {
|
|
338
|
+
const ext = format === 'wireguard' ? 'conf' : 'json';
|
|
339
|
+
const blob = new Blob([response.config], { type: 'text/plain' });
|
|
340
|
+
const url = URL.createObjectURL(blob);
|
|
341
|
+
const a = document.createElement('a');
|
|
342
|
+
a.href = url;
|
|
343
|
+
a.download = `${client.clientId}.${ext}`;
|
|
344
|
+
a.click();
|
|
345
|
+
URL.revokeObjectURL(url);
|
|
346
|
+
DeesToast.createAndShow({ message: `${format} config downloaded`, type: 'success', duration: 3000 });
|
|
347
|
+
} else {
|
|
348
|
+
DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
|
|
349
|
+
}
|
|
350
|
+
} catch (err: any) {
|
|
351
|
+
DeesToast.createAndShow({ message: err.message || 'Export failed', type: 'error', duration: 5000 });
|
|
344
352
|
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
DeesModal.createAndShow({
|
|
356
|
+
heading: `Export Config: ${client.clientId}`,
|
|
357
|
+
content: html`<p>Choose a config format to download.</p>`,
|
|
358
|
+
menuOptions: [
|
|
359
|
+
{
|
|
360
|
+
name: 'WireGuard (.conf)',
|
|
361
|
+
iconName: 'lucide:shield',
|
|
362
|
+
action: async (modalArg: any) => {
|
|
363
|
+
await modalArg.destroy();
|
|
364
|
+
await exportConfig('wireguard');
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'SmartVPN (.json)',
|
|
369
|
+
iconName: 'lucide:braces',
|
|
370
|
+
action: async (modalArg: any) => {
|
|
371
|
+
await modalArg.destroy();
|
|
372
|
+
await exportConfig('smartvpn');
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: 'Cancel',
|
|
377
|
+
iconName: 'lucide:x',
|
|
378
|
+
action: async (modalArg: any) => await modalArg.destroy(),
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
});
|
|
348
382
|
},
|
|
349
383
|
},
|
|
350
384
|
{
|
|
351
385
|
name: 'Rotate Keys',
|
|
352
386
|
iconName: 'lucide:rotate-cw',
|
|
353
387
|
type: ['contextmenu'],
|
|
354
|
-
actionFunc: async (
|
|
388
|
+
actionFunc: async (actionData: any) => {
|
|
389
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
355
390
|
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
356
391
|
DeesModal.createAndShow({
|
|
357
392
|
heading: 'Rotate Client Keys',
|
|
@@ -390,7 +425,8 @@ export class OpsViewVpn extends DeesElement {
|
|
|
390
425
|
name: 'Delete',
|
|
391
426
|
iconName: 'lucide:trash2',
|
|
392
427
|
type: ['contextmenu'],
|
|
393
|
-
actionFunc: async (
|
|
428
|
+
actionFunc: async (actionData: any) => {
|
|
429
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
394
430
|
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
395
431
|
DeesModal.createAndShow({
|
|
396
432
|
heading: 'Delete VPN Client',
|