@lifeready/core 1.0.4 → 1.0.5
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/README.md +62 -62
- package/bundles/lifeready-core.umd.js +15445 -15445
- package/bundles/lifeready-core.umd.js.map +1 -1
- package/bundles/lifeready-core.umd.min.js.map +1 -1
- package/esm2015/lib/_common/ast.js +40 -40
- package/esm2015/lib/_common/deferred-promise.js +24 -24
- package/esm2015/lib/_common/exceptions.js +157 -157
- package/esm2015/lib/_common/queries.gql.js +190 -190
- package/esm2015/lib/_common/run-outside-angular.js +79 -79
- package/esm2015/lib/_common/types.js +1 -1
- package/esm2015/lib/_common/utils.js +44 -44
- package/esm2015/lib/api/contact-card.gql.js +79 -79
- package/esm2015/lib/api/contact-card.service.js +154 -154
- package/esm2015/lib/api/contact-card2.gql.js +60 -60
- package/esm2015/lib/api/contact-card2.service.js +103 -103
- package/esm2015/lib/api/file.service.js +74 -74
- package/esm2015/lib/api/item2.gql.js +110 -110
- package/esm2015/lib/api/item2.service.js +311 -311
- package/esm2015/lib/api/key-exchange.gql.js +188 -188
- package/esm2015/lib/api/key-exchange.service.js +442 -442
- package/esm2015/lib/api/key-exchange.types.js +18 -18
- package/esm2015/lib/api/key-exchange2.gql.js +171 -171
- package/esm2015/lib/api/key-exchange2.service.js +479 -479
- package/esm2015/lib/api/lock.gql.js +40 -40
- package/esm2015/lib/api/lock.service.js +64 -64
- package/esm2015/lib/api/lr-apollo.service.js +46 -46
- package/esm2015/lib/api/lr-graphql/index.js +6 -6
- package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
- package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
- package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
- package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
- package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
- package/esm2015/lib/api/message.service.js +138 -138
- package/esm2015/lib/api/persist.service.js +181 -181
- package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
- package/esm2015/lib/api/query-processor/index.js +3 -3
- package/esm2015/lib/api/query-processor/query-processor.service.js +192 -192
- package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
- package/esm2015/lib/api/shared-contact-card.service.js +119 -119
- package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
- package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
- package/esm2015/lib/api/time.service.js +146 -146
- package/esm2015/lib/api/types/graphql.types.js +7 -7
- package/esm2015/lib/api/types/index.js +3 -3
- package/esm2015/lib/api/types/lr-graphql.types.js +71 -71
- package/esm2015/lib/auth/auth.config.js +57 -57
- package/esm2015/lib/auth/auth.gql.js +48 -48
- package/esm2015/lib/auth/auth.types.js +27 -27
- package/esm2015/lib/auth/idle.service.js +168 -168
- package/esm2015/lib/auth/idle.types.js +7 -7
- package/esm2015/lib/auth/lbop.service.js +355 -355
- package/esm2015/lib/auth/life-ready-auth.service.js +500 -500
- package/esm2015/lib/auth/password.service.js +320 -320
- package/esm2015/lib/auth/register.service.js +172 -172
- package/esm2015/lib/auth/two-factor.service.js +74 -74
- package/esm2015/lib/category/category-meta.service.js +99 -99
- package/esm2015/lib/category/category.gql.js +406 -406
- package/esm2015/lib/category/category.service.js +390 -390
- package/esm2015/lib/category/category.types.js +29 -29
- package/esm2015/lib/cryptography/cryptography.types.js +11 -11
- package/esm2015/lib/cryptography/encryption.service.js +189 -189
- package/esm2015/lib/cryptography/key-factory.service.js +237 -237
- package/esm2015/lib/cryptography/key-graph.service.js +280 -280
- package/esm2015/lib/cryptography/key-meta.service.js +200 -200
- package/esm2015/lib/cryptography/key.service.js +124 -124
- package/esm2015/lib/cryptography/slip39.service.js +169 -169
- package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
- package/esm2015/lib/life-ready.config.js +84 -84
- package/esm2015/lib/life-ready.module.js +74 -74
- package/esm2015/lib/plan/plan.gql.js +123 -123
- package/esm2015/lib/plan/plan.service.js +149 -149
- package/esm2015/lib/plan/plan.types.js +11 -11
- package/esm2015/lib/record/record-attachment.service.js +101 -101
- package/esm2015/lib/record/record.gql.js +179 -179
- package/esm2015/lib/record/record.service.js +206 -206
- package/esm2015/lib/record/record.types.js +15 -15
- package/esm2015/lib/record-type/record-type.service.js +75 -75
- package/esm2015/lib/record-type/record-type.types.js +28 -28
- package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -105
- package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -1
- package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -300
- package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -52
- package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -97
- package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -1
- package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -150
- package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -229
- package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -1
- package/esm2015/lib/scenario/scenario-setup.service.js +269 -269
- package/esm2015/lib/scenario/scenario.gql.js +368 -368
- package/esm2015/lib/scenario/scenario.service.js +611 -611
- package/esm2015/lib/scenario/scenario.types.js +64 -64
- package/esm2015/lib/search/search.gql.js +62 -62
- package/esm2015/lib/search/search.service.js +156 -156
- package/esm2015/lib/search/search.types.js +6 -6
- package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -112
- package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
- package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
- package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -232
- package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -299
- package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
- package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
- package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
- package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
- package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
- package/esm2015/lib/users/profile-details.service.js +214 -214
- package/esm2015/lib/users/profile.gql.js +97 -97
- package/esm2015/lib/users/profile.service.js +169 -169
- package/esm2015/lib/users/profile.types.js +34 -34
- package/esm2015/lib/users/user.gql.js +60 -60
- package/esm2015/lib/users/user.service.js +79 -79
- package/esm2015/lib/users/user.types.js +5 -5
- package/esm2015/lifeready-core.js +10 -10
- package/esm2015/public-api.js +81 -81
- package/fesm2015/lifeready-core.js +13088 -13088
- package/fesm2015/lifeready-core.js.map +1 -1
- package/lib/_common/ast.d.ts +11 -11
- package/lib/_common/deferred-promise.d.ts +12 -12
- package/lib/_common/exceptions.d.ts +109 -109
- package/lib/_common/queries.gql.d.ts +10 -10
- package/lib/_common/run-outside-angular.d.ts +14 -14
- package/lib/_common/types.d.ts +10 -10
- package/lib/_common/utils.d.ts +3 -3
- package/lib/api/contact-card.gql.d.ts +7 -7
- package/lib/api/contact-card.service.d.ts +52 -52
- package/lib/api/contact-card2.gql.d.ts +34 -34
- package/lib/api/contact-card2.service.d.ts +49 -49
- package/lib/api/file.service.d.ts +18 -18
- package/lib/api/item2.gql.d.ts +96 -96
- package/lib/api/item2.service.d.ts +177 -177
- package/lib/api/key-exchange.gql.d.ts +9 -9
- package/lib/api/key-exchange.service.d.ts +39 -39
- package/lib/api/key-exchange.types.d.ts +196 -196
- package/lib/api/key-exchange2.gql.d.ts +125 -125
- package/lib/api/key-exchange2.service.d.ts +187 -187
- package/lib/api/lock.gql.d.ts +27 -27
- package/lib/api/lock.service.d.ts +25 -25
- package/lib/api/lr-apollo.service.d.ts +15 -15
- package/lib/api/lr-graphql/index.d.ts +5 -5
- package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
- package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -27
- package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
- package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
- package/lib/api/lr-graphql/lr.service.d.ts +9 -9
- package/lib/api/message.service.d.ts +58 -58
- package/lib/api/persist.service.d.ts +31 -31
- package/lib/api/query-processor/common-processors.service.d.ts +36 -36
- package/lib/api/query-processor/index.d.ts +2 -2
- package/lib/api/query-processor/query-processor.service.d.ts +18 -18
- package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
- package/lib/api/shared-contact-card.service.d.ts +33 -33
- package/lib/api/shared-contact-card2.gql.d.ts +36 -36
- package/lib/api/shared-contact-card2.service.d.ts +45 -45
- package/lib/api/time.service.d.ts +16 -16
- package/lib/api/types/graphql.types.d.ts +29 -29
- package/lib/api/types/index.d.ts +2 -2
- package/lib/api/types/lr-graphql.types.d.ts +385 -385
- package/lib/auth/auth.config.d.ts +5 -5
- package/lib/auth/auth.gql.d.ts +15 -15
- package/lib/auth/auth.types.d.ts +66 -66
- package/lib/auth/idle.service.d.ts +40 -40
- package/lib/auth/idle.types.d.ts +10 -10
- package/lib/auth/lbop.service.d.ts +91 -91
- package/lib/auth/life-ready-auth.service.d.ts +59 -59
- package/lib/auth/password.service.d.ts +78 -78
- package/lib/auth/register.service.d.ts +25 -25
- package/lib/auth/two-factor.service.d.ts +15 -15
- package/lib/category/category-meta.service.d.ts +23 -23
- package/lib/category/category.gql.d.ts +45 -45
- package/lib/category/category.service.d.ts +67 -67
- package/lib/category/category.types.d.ts +79 -79
- package/lib/cryptography/cryptography.types.d.ts +83 -83
- package/lib/cryptography/encryption.service.d.ts +41 -41
- package/lib/cryptography/key-factory.service.d.ts +38 -38
- package/lib/cryptography/key-graph.service.d.ts +33 -33
- package/lib/cryptography/key-meta.service.d.ts +44 -44
- package/lib/cryptography/key.service.d.ts +36 -36
- package/lib/cryptography/slip39.service.d.ts +43 -43
- package/lib/cryptography/web-crypto.service.d.ts +5 -5
- package/lib/life-ready.config.d.ts +14 -14
- package/lib/life-ready.module.d.ts +5 -5
- package/lib/plan/plan.gql.d.ts +11 -11
- package/lib/plan/plan.service.d.ts +33 -33
- package/lib/plan/plan.types.d.ts +31 -31
- package/lib/record/record-attachment.service.d.ts +16 -16
- package/lib/record/record.gql.d.ts +14 -14
- package/lib/record/record.service.d.ts +25 -25
- package/lib/record/record.types.d.ts +57 -57
- package/lib/record-type/record-type.service.d.ts +11 -11
- package/lib/record-type/record-type.types.d.ts +50 -50
- package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -7
- package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -63
- package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -32
- package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -5
- package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -17
- package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -18
- package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -8
- package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -30
- package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -54
- package/lib/scenario/scenario-setup.service.d.ts +22 -22
- package/lib/scenario/scenario.gql.d.ts +34 -34
- package/lib/scenario/scenario.service.d.ts +58 -58
- package/lib/scenario/scenario.types.d.ts +217 -217
- package/lib/search/search.gql.d.ts +1 -1
- package/lib/search/search.service.d.ts +25 -25
- package/lib/search/search.types.d.ts +20 -20
- package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
- package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
- package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
- package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -218
- package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -130
- package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
- package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
- package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
- package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
- package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
- package/lib/users/profile-details.service.d.ts +21 -21
- package/lib/users/profile.gql.d.ts +11 -11
- package/lib/users/profile.service.d.ts +35 -35
- package/lib/users/profile.types.d.ts +96 -96
- package/lib/users/user.gql.d.ts +9 -9
- package/lib/users/user.service.d.ts +12 -12
- package/lib/users/user.types.d.ts +23 -23
- package/lifeready-core.d.ts +9 -9
- package/package.json +1 -1
- package/public-api.d.ts +77 -77
|
@@ -1,169 +1,169 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import { Slip39, Slip39Helper } from 'slip39';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
export class SecretShare {
|
|
6
|
-
constructor(assembly = 0, subAssembly = 0, mnemonics = '') {
|
|
7
|
-
this.assembly = assembly;
|
|
8
|
-
this.subAssembly = subAssembly;
|
|
9
|
-
this.mnemonics = mnemonics;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
export class SubAssembly {
|
|
13
|
-
constructor(index, threshold = 0, size = 0) {
|
|
14
|
-
this.index = index;
|
|
15
|
-
this.threshold = threshold;
|
|
16
|
-
this.size = size;
|
|
17
|
-
this.clearShares();
|
|
18
|
-
}
|
|
19
|
-
clearShares() {
|
|
20
|
-
this.shares = Array();
|
|
21
|
-
}
|
|
22
|
-
addShare(share) {
|
|
23
|
-
this.shares.push(share);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export class Assembly {
|
|
27
|
-
constructor(threshold = 0) {
|
|
28
|
-
this.threshold = threshold;
|
|
29
|
-
this.clearSubAssemblies();
|
|
30
|
-
}
|
|
31
|
-
size() {
|
|
32
|
-
return this.subAssemblies.length;
|
|
33
|
-
}
|
|
34
|
-
clearSubAssemblies() {
|
|
35
|
-
this.subAssemblies = new Array();
|
|
36
|
-
}
|
|
37
|
-
addSubAssembly(subAssembly) {
|
|
38
|
-
this.subAssemblies.push(subAssembly);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export class SubQuorum {
|
|
42
|
-
constructor(subAssemblyIndex) {
|
|
43
|
-
this.subAssemblyIndex = subAssemblyIndex;
|
|
44
|
-
this.clearShares();
|
|
45
|
-
}
|
|
46
|
-
clearShares() {
|
|
47
|
-
this.shares = new Array();
|
|
48
|
-
}
|
|
49
|
-
addShare(share) {
|
|
50
|
-
this.shares.push(share);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export class Quorum {
|
|
54
|
-
constructor() {
|
|
55
|
-
this.clearSubQuora();
|
|
56
|
-
}
|
|
57
|
-
clearSubQuora() {
|
|
58
|
-
this.subQuora = new Array();
|
|
59
|
-
}
|
|
60
|
-
addSubQuorum(subQuorum) {
|
|
61
|
-
this.subQuora.push(subQuorum);
|
|
62
|
-
}
|
|
63
|
-
serialiseShares() {
|
|
64
|
-
let shares = [];
|
|
65
|
-
this.subQuora.forEach((subQuorum) => {
|
|
66
|
-
shares = shares.concat(subQuorum.shares);
|
|
67
|
-
});
|
|
68
|
-
return shares;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export class Slip39Service {
|
|
72
|
-
constructor() { }
|
|
73
|
-
generateShares(secret, passphrase, assembly) {
|
|
74
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
-
// Hex-encode secret.
|
|
76
|
-
let ems = btoa(secret);
|
|
77
|
-
ems = Slip39Helper.slip39EncodeHex(ems);
|
|
78
|
-
// Construct group specifications
|
|
79
|
-
const groups = [];
|
|
80
|
-
for (const sa of assembly.subAssemblies) {
|
|
81
|
-
groups.push([sa.threshold, sa.size]);
|
|
82
|
-
}
|
|
83
|
-
// Split!
|
|
84
|
-
const slip = yield Slip39.fromArray(ems, {
|
|
85
|
-
passphrase,
|
|
86
|
-
threshold: assembly.threshold,
|
|
87
|
-
groups,
|
|
88
|
-
title: '',
|
|
89
|
-
});
|
|
90
|
-
// Extract shares
|
|
91
|
-
assembly.subAssemblies.forEach((sa, isa) => {
|
|
92
|
-
// Remove any existing shares
|
|
93
|
-
sa.clearShares();
|
|
94
|
-
for (let im = 0; im < sa.size; im++) {
|
|
95
|
-
// Construct the path to the share, formatted as "r/<subassembly index>/<member index>"
|
|
96
|
-
// with <subassembly index> and <member index> being two-digit, zero-padded integers.
|
|
97
|
-
const path = 'r/' +
|
|
98
|
-
isa.toString().padStart(2, '0') +
|
|
99
|
-
'/' +
|
|
100
|
-
im.toString().padStart(2, '0');
|
|
101
|
-
const mnemonics = slip.fromPath(path).mnemonics[0];
|
|
102
|
-
const share = new SecretShare(isa, im, mnemonics);
|
|
103
|
-
sa.addShare(share);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
// Remove all redundant shares. i.e. keep only enough members and groups to satisfy the thresholds.
|
|
109
|
-
minimalSet(mnemonics) {
|
|
110
|
-
// Decode the mnemonics and sort then into groups.
|
|
111
|
-
let groupThresh = null;
|
|
112
|
-
const groups = new Map();
|
|
113
|
-
for (const mnemonic of mnemonics) {
|
|
114
|
-
const decoded = Slip39Helper.decodeMnemonic(mnemonic);
|
|
115
|
-
if (groupThresh && groupThresh !== decoded.groupThreshold) {
|
|
116
|
-
throw new Error('groupThreshold is different in mnemonics');
|
|
117
|
-
}
|
|
118
|
-
groupThresh = decoded.groupThreshold;
|
|
119
|
-
// Note that Slip39.recoverSecret() will do all the error checking again. So it's not critical
|
|
120
|
-
// that we error check here. So we just optimistically assume it's all good.
|
|
121
|
-
let g = groups.get(decoded.groupIndex);
|
|
122
|
-
if (g == null) {
|
|
123
|
-
g = {
|
|
124
|
-
memberThreshold: decoded.memberThreshold,
|
|
125
|
-
members: [],
|
|
126
|
-
};
|
|
127
|
-
groups.set(decoded.groupIndex, g);
|
|
128
|
-
}
|
|
129
|
-
g.members.push({
|
|
130
|
-
mnemonic,
|
|
131
|
-
decoded,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
// Keep the minimum set of groups that meet threshold.
|
|
135
|
-
const mnemonicsMinSet = [];
|
|
136
|
-
let groupCount = 0;
|
|
137
|
-
for (const g of groups.values()) {
|
|
138
|
-
// Keep only groups that meet threshold
|
|
139
|
-
if (g.members.length < g.memberThreshold) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
// Keep minimum number of approvals needed for group
|
|
143
|
-
g.members.slice(0, g.memberThreshold).forEach((member) => {
|
|
144
|
-
mnemonicsMinSet.push(member.mnemonic);
|
|
145
|
-
});
|
|
146
|
-
++groupCount;
|
|
147
|
-
if (groupCount >= groupThresh) {
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return mnemonicsMinSet;
|
|
152
|
-
}
|
|
153
|
-
recoverSecret(shares, passphrase) {
|
|
154
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
-
shares = this.minimalSet(shares);
|
|
156
|
-
const recovered = yield Slip39.recoverSecret(shares, passphrase);
|
|
157
|
-
const secret = Slip39Helper.slip39DecodeHex(recovered);
|
|
158
|
-
return atob(secret);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
Slip39Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function Slip39Service_Factory() { return new Slip39Service(); }, token: Slip39Service, providedIn: "root" });
|
|
163
|
-
Slip39Service.decorators = [
|
|
164
|
-
{ type: Injectable, args: [{
|
|
165
|
-
providedIn: 'root',
|
|
166
|
-
},] }
|
|
167
|
-
];
|
|
168
|
-
Slip39Service.ctorParameters = () => [];
|
|
169
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpcDM5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiQzovUHJvamVjdHMvbmV3cmVwby9rYy1jbGllbnQvcHJvamVjdHMvY29yZS9zcmMvIiwic291cmNlcyI6WyJsaWIvY3J5cHRvZ3JhcGh5L3NsaXAzOS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDOztBQUU5QyxNQUFNLE9BQU8sV0FBVztJQUN0QixZQUNTLFdBQW1CLENBQUMsRUFDcEIsY0FBc0IsQ0FBQyxFQUN2QixZQUFvQixFQUFFO1FBRnRCLGFBQVEsR0FBUixRQUFRLENBQVk7UUFDcEIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsY0FBUyxHQUFULFNBQVMsQ0FBYTtJQUM1QixDQUFDO0NBQ0w7QUFFRCxNQUFNLE9BQU8sV0FBVztJQUN0QixZQUNTLEtBQWEsRUFDYixZQUFvQixDQUFDLEVBQ3JCLE9BQWUsQ0FBQztRQUZoQixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQ2IsY0FBUyxHQUFULFNBQVMsQ0FBWTtRQUNyQixTQUFJLEdBQUosSUFBSSxDQUFZO1FBRXZCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBSU0sV0FBVztRQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTSxRQUFRLENBQUMsS0FBa0I7UUFDaEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUIsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLFFBQVE7SUFDbkIsWUFBbUIsWUFBb0IsQ0FBQztRQUFyQixjQUFTLEdBQVQsU0FBUyxDQUFZO1FBQ3RDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFJTSxJQUFJ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b3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTbGlwMzksIFNsaXAzOUhlbHBlciB9IGZyb20gJ3NsaXAzOSc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2VjcmV0U2hhcmUge1xyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHVibGljIGFzc2VtYmx5OiBudW1iZXIgPSAwLFxyXG4gICAgcHVibGljIHN1YkFzc2VtYmx5OiBudW1iZXIgPSAwLFxyXG4gICAgcHVibGljIG1uZW1vbmljczogc3RyaW5nID0gJydcclxuICApIHt9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTdWJBc3NlbWJseSB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgaW5kZXg6IG51bWJlcixcclxuICAgIHB1YmxpYyB0aHJlc2hvbGQ6IG51bWJlciA9IDAsXHJcbiAgICBwdWJsaWMgc2l6ZTogbnVtYmVyID0gMFxyXG4gICkge1xyXG4gICAgdGhpcy5jbGVhclNoYXJlcygpO1xyXG4gIH1cclxuXHJcbiAgc2hhcmVzOiBTZWNyZXRTaGFyZVtdO1xyXG5cclxuICBwdWJsaWMgY2xlYXJTaGFyZXMoKSB7XHJcbiAgICB0aGlzLnNoYXJlcyA9IEFycmF5KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkU2hhcmUoc2hhcmU6IFNlY3JldFNoYXJlKSB7XHJcbiAgICB0aGlzLnNoYXJlcy5wdXNoKHNoYXJlKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBBc3NlbWJseSB7XHJcbiAgY29uc3RydWN0b3IocHVibGljIHRocmVzaG9sZDogbnVtYmVyID0gMCkge1xyXG4gICAgdGhpcy5jbGVhclN1YkFzc2VtYmxpZXMoKTtcclxuICB9XHJcblxyXG4gIHN1YkFzc2VtYmxpZXM6IFN1YkFzc2VtYmx5W107XHJcblxyXG4gIHB1YmxpYyBzaXplKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3ViQXNzZW1ibGllcy5sZW5ndGg7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2xlYXJTdWJBc3NlbWJsaWVzKCkge1xyXG4gICAgdGhpcy5zdWJBc3NlbWJsaWVzID0gbmV3IEFycmF5KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkU3ViQXNzZW1ibHkoc3ViQXNzZW1ibHk6IFN1YkFzc2VtYmx5KSB7XHJcbiAgICB0aGlzLnN1YkFzc2VtYmxpZXMucHVzaChzdWJBc3NlbWJseSk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU3ViUXVvcnVtIHtcclxuICBzaGFyZXM6IHN0cmluZ1tdO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgc3ViQXNzZW1ibHlJbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmNsZWFyU2hhcmVzKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2xlYXJTaGFyZXMoKSB7XHJcbiAgICB0aGlzLnNoYXJlcyA9IG5ldyBBcnJheSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZFNoYXJlKHNoYXJlOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuc2hhcmVzLnB1c2goc2hhcmUpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFF1b3J1bSB7XHJcbiAgc3ViUXVvcmE6IFN1YlF1b3J1bVtdO1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHRoaXMuY2xlYXJTdWJRdW9yYSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGNsZWFyU3ViUXVvcmEoKSB7XHJcbiAgICB0aGlzLnN1YlF1b3JhID0gbmV3IEFycmF5KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkU3ViUXVvcnVtKHN1YlF1b3J1bTogU3ViUXVvcnVtKSB7XHJcbiAgICB0aGlzLnN1YlF1b3JhLnB1c2goc3ViUXVvcnVtKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXJpYWxpc2VTaGFyZXMoKSB7XHJcbiAgICBsZXQgc2hhcmVzID0gW107XHJcblxyXG4gICAgdGhpcy5zdWJRdW9yYS5mb3JFYWNoKChzdWJRdW9ydW0pID0+IHtcclxuICAgICAgc2hhcmVzID0gc2hhcmVzLmNvbmNhdChzdWJRdW9ydW0uc2hhcmVzKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzaGFyZXM7XHJcbiAgfVxyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2xpcDM5U2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IoKSB7fVxyXG5cclxuICBwdWJsaWMgYXN5bmMgZ2VuZXJhdGVTaGFyZXMoc2VjcmV0LCBwYXNzcGhyYXNlOiBzdHJpbmcsIGFzc2VtYmx5OiBBc3NlbWJseSkge1xyXG4gICAgLy8gSGV4LWVuY29kZSBzZWNyZXQuXHJcbiAgICBsZXQgZW1zID0gYnRvYShzZWNyZXQpO1xyXG4gICAgZW1zID0gU2xpcDM5SGVscGVyLnNsaXAzOUVuY29kZUhleChlbXMpO1xyXG5cclxuICAgIC8vIENvbnN0cnVjdCBncm91cCBzcGVjaWZpY2F0aW9uc1xyXG4gICAgY29uc3QgZ3JvdXBzID0gW107XHJcblxyXG4gICAgZm9yIChjb25zdCBzYSBvZiBhc3NlbWJseS5zdWJBc3NlbWJsaWVzKSB7XHJcbiAgICAgIGdyb3Vwcy5wdXNoKFtzYS50aHJlc2hvbGQsIHNhLnNpemVdKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTcGxpdCFcclxuICAgIGNvbnN0IHNsaXAgPSBhd2FpdCBTbGlwMzkuZnJvbUFycmF5KGVtcywge1xyXG4gICAgICBwYXNzcGhyYXNlLFxyXG4gICAgICB0aHJlc2hvbGQ6IGFzc2VtYmx5LnRocmVzaG9sZCxcclxuICAgICAgZ3JvdXBzLFxyXG4gICAgICB0aXRsZTogJycsXHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBFeHRyYWN0IHNoYXJlc1xyXG4gICAgYXNzZW1ibHkuc3ViQXNzZW1ibGllcy5mb3JFYWNoKChzYSwgaXNhKSA9PiB7XHJcbiAgICAgIC8vIFJlbW92ZSBhbnkgZXhpc3Rpbmcgc2hhcmVzXHJcbiAgICAgIHNhLmNsZWFyU2hhcmVzKCk7XHJcblxyXG4gICAgICBmb3IgKGxldCBpbSA9IDA7IGltIDwgc2Euc2l6ZTsgaW0rKykge1xyXG4gICAgICAgIC8vIENvbnN0cnVjdCB0aGUgcGF0aCB0byB0aGUgc2hhcmUsIGZvcm1hdHRlZCBhcyBcInIvPHN1YmFzc2VtYmx5IGluZGV4Pi88bWVtYmVyIGluZGV4PlwiXHJcbiAgICAgICAgLy8gd2l0aCA8c3ViYXNzZW1ibHkgaW5kZXg+IGFuZCA8bWVtYmVyIGluZGV4PiBiZWluZyB0d28tZGlnaXQsIHplcm8tcGFkZGVkIGludGVnZXJzLlxyXG4gICAgICAgIGNvbnN0IHBhdGggPVxyXG4gICAgICAgICAgJ3IvJyArXHJcbiAgICAgICAgICBpc2EudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpICtcclxuICAgICAgICAgICcvJyArXHJcbiAgICAgICAgICBpbS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICAgICAgY29uc3QgbW5lbW9uaWNzID0gc2xpcC5mcm9tUGF0aChwYXRoKS5tbmVtb25pY3NbMF07XHJcbiAgICAgICAgY29uc3Qgc2hhcmUgPSBuZXcgU2VjcmV0U2hhcmUoaXNhLCBpbSwgbW5lbW9uaWNzKTtcclxuXHJcbiAgICAgICAgc2EuYWRkU2hhcmUoc2hhcmUpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIFJlbW92ZSBhbGwgcmVkdW5kYW50IHNoYXJlcy4gaS5lLiBrZWVwIG9ubHkgZW5vdWdoIG1lbWJlcnMgYW5kIGdyb3VwcyB0byBzYXRpc2Z5IHRoZSB0aHJlc2hvbGRzLlxyXG4gIHByaXZhdGUgbWluaW1hbFNldChtbmVtb25pY3M6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xyXG4gICAgLy8gRGVjb2RlIHRoZSBtbmVtb25pY3MgYW5kIHNvcnQgdGhlbiBpbnRvIGdyb3Vwcy5cclxuICAgIGxldCBncm91cFRocmVzaCA9IG51bGw7XHJcbiAgICBjb25zdCBncm91cHMgPSBuZXcgTWFwKCk7XHJcbiAgICBmb3IgKGNvbnN0IG1uZW1vbmljIG9mIG1uZW1vbmljcykge1xyXG4gICAgICBjb25zdCBkZWNvZGVkID0gU2xpcDM5SGVscGVyLmRlY29kZU1uZW1vbmljKG1uZW1vbmljKTtcclxuXHJcbiAgICAgIGlmIChncm91cFRocmVzaCAmJiBncm91cFRocmVzaCAhPT0gZGVjb2RlZC5ncm91cFRocmVzaG9sZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ3JvdXBUaHJlc2hvbGQgaXMgZGlmZmVyZW50IGluIG1uZW1vbmljcycpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBncm91cFRocmVzaCA9IGRlY29kZWQuZ3JvdXBUaHJlc2hvbGQ7XHJcblxyXG4gICAgICAvLyBOb3RlIHRoYXQgU2xpcDM5LnJlY292ZXJTZWNyZXQoKSB3aWxsIGRvIGFsbCB0aGUgZXJyb3IgY2hlY2tpbmcgYWdhaW4uIFNvIGl0J3Mgbm90IGNyaXRpY2FsXHJcbiAgICAgIC8vIHRoYXQgd2UgZXJyb3IgY2hlY2sgaGVyZS4gU28gd2UganVzdCBvcHRpbWlzdGljYWxseSBhc3N1bWUgaXQncyBhbGwgZ29vZC5cclxuICAgICAgbGV0IGcgPSBncm91cHMuZ2V0KGRlY29kZWQuZ3JvdXBJbmRleCk7XHJcbiAgICAgIGlmIChnID09IG51bGwpIHtcclxuICAgICAgICBnID0ge1xyXG4gICAgICAgICAgbWVtYmVyVGhyZXNob2xkOiBkZWNvZGVkLm1lbWJlclRocmVzaG9sZCxcclxuICAgICAgICAgIG1lbWJlcnM6IFtdLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZ3JvdXBzLnNldChkZWNvZGVkLmdyb3VwSW5kZXgsIGcpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBnLm1lbWJlcnMucHVzaCh7XHJcbiAgICAgICAgbW5lbW9uaWMsXHJcbiAgICAgICAgZGVjb2RlZCxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gS2VlcCB0aGUgbWluaW11bSBzZXQgb2YgZ3JvdXBzIHRoYXQgbWVldCB0aHJlc2hvbGQuXHJcbiAgICBjb25zdCBtbmVtb25pY3NNaW5TZXQgPSBbXTtcclxuICAgIGxldCBncm91cENvdW50ID0gMDtcclxuICAgIGZvciAoY29uc3QgZyBvZiBncm91cHMudmFsdWVzKCkpIHtcclxuICAgICAgLy8gS2VlcCBvbmx5IGdyb3VwcyB0aGF0IG1lZXQgdGhyZXNob2xkXHJcbiAgICAgIGlmIChnLm1lbWJlcnMubGVuZ3RoIDwgZy5tZW1iZXJUaHJlc2hvbGQpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gS2VlcCBtaW5pbXVtIG51bWJlciBvZiBhcHByb3ZhbHMgbmVlZGVkIGZvciBncm91cFxyXG4gICAgICBnLm1lbWJlcnMuc2xpY2UoMCwgZy5tZW1iZXJUaHJlc2hvbGQpLmZvckVhY2goKG1lbWJlcikgPT4ge1xyXG4gICAgICAgIG1uZW1vbmljc01pblNldC5wdXNoKG1lbWJlci5tbmVtb25pYyk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgKytncm91cENvdW50O1xyXG4gICAgICBpZiAoZ3JvdXBDb3VudCA+PSBncm91cFRocmVzaCkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1uZW1vbmljc01pblNldDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyByZWNvdmVyU2VjcmV0KHNoYXJlczogc3RyaW5nW10sIHBhc3NwaHJhc2U6IHN0cmluZykge1xyXG4gICAgc2hhcmVzID0gdGhpcy5taW5pbWFsU2V0KHNoYXJlcyk7XHJcblxyXG4gICAgY29uc3QgcmVjb3ZlcmVkID0gYXdhaXQgU2xpcDM5LnJlY292ZXJTZWNyZXQoc2hhcmVzLCBwYXNzcGhyYXNlKTtcclxuXHJcbiAgICBjb25zdCBzZWNyZXQgPSBTbGlwMzlIZWxwZXIuc2xpcDM5RGVjb2RlSGV4KHJlY292ZXJlZCk7XHJcblxyXG4gICAgcmV0dXJuIGF0b2Ioc2VjcmV0KTtcclxuICB9XHJcbn1cclxuIl19
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { Slip39, Slip39Helper } from 'slip39';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class SecretShare {
|
|
6
|
+
constructor(assembly = 0, subAssembly = 0, mnemonics = '') {
|
|
7
|
+
this.assembly = assembly;
|
|
8
|
+
this.subAssembly = subAssembly;
|
|
9
|
+
this.mnemonics = mnemonics;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class SubAssembly {
|
|
13
|
+
constructor(index, threshold = 0, size = 0) {
|
|
14
|
+
this.index = index;
|
|
15
|
+
this.threshold = threshold;
|
|
16
|
+
this.size = size;
|
|
17
|
+
this.clearShares();
|
|
18
|
+
}
|
|
19
|
+
clearShares() {
|
|
20
|
+
this.shares = Array();
|
|
21
|
+
}
|
|
22
|
+
addShare(share) {
|
|
23
|
+
this.shares.push(share);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class Assembly {
|
|
27
|
+
constructor(threshold = 0) {
|
|
28
|
+
this.threshold = threshold;
|
|
29
|
+
this.clearSubAssemblies();
|
|
30
|
+
}
|
|
31
|
+
size() {
|
|
32
|
+
return this.subAssemblies.length;
|
|
33
|
+
}
|
|
34
|
+
clearSubAssemblies() {
|
|
35
|
+
this.subAssemblies = new Array();
|
|
36
|
+
}
|
|
37
|
+
addSubAssembly(subAssembly) {
|
|
38
|
+
this.subAssemblies.push(subAssembly);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class SubQuorum {
|
|
42
|
+
constructor(subAssemblyIndex) {
|
|
43
|
+
this.subAssemblyIndex = subAssemblyIndex;
|
|
44
|
+
this.clearShares();
|
|
45
|
+
}
|
|
46
|
+
clearShares() {
|
|
47
|
+
this.shares = new Array();
|
|
48
|
+
}
|
|
49
|
+
addShare(share) {
|
|
50
|
+
this.shares.push(share);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class Quorum {
|
|
54
|
+
constructor() {
|
|
55
|
+
this.clearSubQuora();
|
|
56
|
+
}
|
|
57
|
+
clearSubQuora() {
|
|
58
|
+
this.subQuora = new Array();
|
|
59
|
+
}
|
|
60
|
+
addSubQuorum(subQuorum) {
|
|
61
|
+
this.subQuora.push(subQuorum);
|
|
62
|
+
}
|
|
63
|
+
serialiseShares() {
|
|
64
|
+
let shares = [];
|
|
65
|
+
this.subQuora.forEach((subQuorum) => {
|
|
66
|
+
shares = shares.concat(subQuorum.shares);
|
|
67
|
+
});
|
|
68
|
+
return shares;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export class Slip39Service {
|
|
72
|
+
constructor() { }
|
|
73
|
+
generateShares(secret, passphrase, assembly) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
// Hex-encode secret.
|
|
76
|
+
let ems = btoa(secret);
|
|
77
|
+
ems = Slip39Helper.slip39EncodeHex(ems);
|
|
78
|
+
// Construct group specifications
|
|
79
|
+
const groups = [];
|
|
80
|
+
for (const sa of assembly.subAssemblies) {
|
|
81
|
+
groups.push([sa.threshold, sa.size]);
|
|
82
|
+
}
|
|
83
|
+
// Split!
|
|
84
|
+
const slip = yield Slip39.fromArray(ems, {
|
|
85
|
+
passphrase,
|
|
86
|
+
threshold: assembly.threshold,
|
|
87
|
+
groups,
|
|
88
|
+
title: '',
|
|
89
|
+
});
|
|
90
|
+
// Extract shares
|
|
91
|
+
assembly.subAssemblies.forEach((sa, isa) => {
|
|
92
|
+
// Remove any existing shares
|
|
93
|
+
sa.clearShares();
|
|
94
|
+
for (let im = 0; im < sa.size; im++) {
|
|
95
|
+
// Construct the path to the share, formatted as "r/<subassembly index>/<member index>"
|
|
96
|
+
// with <subassembly index> and <member index> being two-digit, zero-padded integers.
|
|
97
|
+
const path = 'r/' +
|
|
98
|
+
isa.toString().padStart(2, '0') +
|
|
99
|
+
'/' +
|
|
100
|
+
im.toString().padStart(2, '0');
|
|
101
|
+
const mnemonics = slip.fromPath(path).mnemonics[0];
|
|
102
|
+
const share = new SecretShare(isa, im, mnemonics);
|
|
103
|
+
sa.addShare(share);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Remove all redundant shares. i.e. keep only enough members and groups to satisfy the thresholds.
|
|
109
|
+
minimalSet(mnemonics) {
|
|
110
|
+
// Decode the mnemonics and sort then into groups.
|
|
111
|
+
let groupThresh = null;
|
|
112
|
+
const groups = new Map();
|
|
113
|
+
for (const mnemonic of mnemonics) {
|
|
114
|
+
const decoded = Slip39Helper.decodeMnemonic(mnemonic);
|
|
115
|
+
if (groupThresh && groupThresh !== decoded.groupThreshold) {
|
|
116
|
+
throw new Error('groupThreshold is different in mnemonics');
|
|
117
|
+
}
|
|
118
|
+
groupThresh = decoded.groupThreshold;
|
|
119
|
+
// Note that Slip39.recoverSecret() will do all the error checking again. So it's not critical
|
|
120
|
+
// that we error check here. So we just optimistically assume it's all good.
|
|
121
|
+
let g = groups.get(decoded.groupIndex);
|
|
122
|
+
if (g == null) {
|
|
123
|
+
g = {
|
|
124
|
+
memberThreshold: decoded.memberThreshold,
|
|
125
|
+
members: [],
|
|
126
|
+
};
|
|
127
|
+
groups.set(decoded.groupIndex, g);
|
|
128
|
+
}
|
|
129
|
+
g.members.push({
|
|
130
|
+
mnemonic,
|
|
131
|
+
decoded,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Keep the minimum set of groups that meet threshold.
|
|
135
|
+
const mnemonicsMinSet = [];
|
|
136
|
+
let groupCount = 0;
|
|
137
|
+
for (const g of groups.values()) {
|
|
138
|
+
// Keep only groups that meet threshold
|
|
139
|
+
if (g.members.length < g.memberThreshold) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
// Keep minimum number of approvals needed for group
|
|
143
|
+
g.members.slice(0, g.memberThreshold).forEach((member) => {
|
|
144
|
+
mnemonicsMinSet.push(member.mnemonic);
|
|
145
|
+
});
|
|
146
|
+
++groupCount;
|
|
147
|
+
if (groupCount >= groupThresh) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return mnemonicsMinSet;
|
|
152
|
+
}
|
|
153
|
+
recoverSecret(shares, passphrase) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
shares = this.minimalSet(shares);
|
|
156
|
+
const recovered = yield Slip39.recoverSecret(shares, passphrase);
|
|
157
|
+
const secret = Slip39Helper.slip39DecodeHex(recovered);
|
|
158
|
+
return atob(secret);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
Slip39Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function Slip39Service_Factory() { return new Slip39Service(); }, token: Slip39Service, providedIn: "root" });
|
|
163
|
+
Slip39Service.decorators = [
|
|
164
|
+
{ type: Injectable, args: [{
|
|
165
|
+
providedIn: 'root',
|
|
166
|
+
},] }
|
|
167
|
+
];
|
|
168
|
+
Slip39Service.ctorParameters = () => [];
|
|
169
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpcDM5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL29wdC9hdGxhc3NpYW4vcGlwZWxpbmVzL2FnZW50L2J1aWxkL3Byb2plY3RzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2NyeXB0b2dyYXBoeS9zbGlwMzkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7QUFFOUMsTUFBTSxPQUFPLFdBQVc7SUFDdEIsWUFDUyxXQUFtQixDQUFDLEVBQ3BCLGNBQXNCLENBQUMsRUFDdkIsWUFBb0IsRUFBRTtRQUZ0QixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQ3ZCLGNBQVMsR0FBVCxTQUFTLENBQWE7SUFDNUIsQ0FBQztDQUNMO0FBRUQsTUFBTSxPQUFPLFdBQVc7SUFDdEIsWUFDUyxLQUFhLEVBQ2IsWUFBb0IsQ0FBQyxFQUNyQixPQUFlLENBQUM7UUFGaEIsVUFBSyxHQUFMLEtBQUssQ0FBUTtRQUNiLGNBQVMsR0FBVCxTQUFTLENBQVk7UUFDckIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUV2QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUlNLFdBQVc7UUFDaEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRU0sUUFBUSxDQUFDLEtBQWtCO1FBQ2hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQW1CLFlBQW9CLENBQUM7UUFBckIsY0FBUyxHQUFULFNBQVMsQ0FBWTtRQUN0QyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lB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IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNsaXAzOSwgU2xpcDM5SGVscGVyIH0gZnJvbSAnc2xpcDM5JztcblxuZXhwb3J0IGNsYXNzIFNlY3JldFNoYXJlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFzc2VtYmx5OiBudW1iZXIgPSAwLFxuICAgIHB1YmxpYyBzdWJBc3NlbWJseTogbnVtYmVyID0gMCxcbiAgICBwdWJsaWMgbW5lbW9uaWNzOiBzdHJpbmcgPSAnJ1xuICApIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBTdWJBc3NlbWJseSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBpbmRleDogbnVtYmVyLFxuICAgIHB1YmxpYyB0aHJlc2hvbGQ6IG51bWJlciA9IDAsXG4gICAgcHVibGljIHNpemU6IG51bWJlciA9IDBcbiAgKSB7XG4gICAgdGhpcy5jbGVhclNoYXJlcygpO1xuICB9XG5cbiAgc2hhcmVzOiBTZWNyZXRTaGFyZVtdO1xuXG4gIHB1YmxpYyBjbGVhclNoYXJlcygpIHtcbiAgICB0aGlzLnNoYXJlcyA9IEFycmF5KCk7XG4gIH1cblxuICBwdWJsaWMgYWRkU2hhcmUoc2hhcmU6IFNlY3JldFNoYXJlKSB7XG4gICAgdGhpcy5zaGFyZXMucHVzaChzaGFyZSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFzc2VtYmx5IHtcbiAgY29uc3RydWN0b3IocHVibGljIHRocmVzaG9sZDogbnVtYmVyID0gMCkge1xuICAgIHRoaXMuY2xlYXJTdWJBc3NlbWJsaWVzKCk7XG4gIH1cblxuICBzdWJBc3NlbWJsaWVzOiBTdWJBc3NlbWJseVtdO1xuXG4gIHB1YmxpYyBzaXplKCkge1xuICAgIHJldHVybiB0aGlzLnN1YkFzc2VtYmxpZXMubGVuZ3RoO1xuICB9XG5cbiAgcHVibGljIGNsZWFyU3ViQXNzZW1ibGllcygpIHtcbiAgICB0aGlzLnN1YkFzc2VtYmxpZXMgPSBuZXcgQXJyYXkoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRTdWJBc3NlbWJseShzdWJBc3NlbWJseTogU3ViQXNzZW1ibHkpIHtcbiAgICB0aGlzLnN1YkFzc2VtYmxpZXMucHVzaChzdWJBc3NlbWJseSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFN1YlF1b3J1bSB7XG4gIHNoYXJlczogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IocHVibGljIHN1YkFzc2VtYmx5SW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuY2xlYXJTaGFyZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBjbGVhclNoYXJlcygpIHtcbiAgICB0aGlzLnNoYXJlcyA9IG5ldyBBcnJheSgpO1xuICB9XG5cbiAgcHVibGljIGFkZFNoYXJlKHNoYXJlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNoYXJlcy5wdXNoKHNoYXJlKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUXVvcnVtIHtcbiAgc3ViUXVvcmE6IFN1YlF1b3J1bVtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuY2xlYXJTdWJRdW9yYSgpO1xuICB9XG5cbiAgcHVibGljIGNsZWFyU3ViUXVvcmEoKSB7XG4gICAgdGhpcy5zdWJRdW9yYSA9IG5ldyBBcnJheSgpO1xuICB9XG5cbiAgcHVibGljIGFkZFN1YlF1b3J1bShzdWJRdW9ydW06IFN1YlF1b3J1bSkge1xuICAgIHRoaXMuc3ViUXVvcmEucHVzaChzdWJRdW9ydW0pO1xuICB9XG5cbiAgcHVibGljIHNlcmlhbGlzZVNoYXJlcygpIHtcbiAgICBsZXQgc2hhcmVzID0gW107XG5cbiAgICB0aGlzLnN1YlF1b3JhLmZvckVhY2goKHN1YlF1b3J1bSkgPT4ge1xuICAgICAgc2hhcmVzID0gc2hhcmVzLmNvbmNhdChzdWJRdW9ydW0uc2hhcmVzKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBzaGFyZXM7XG4gIH1cbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFNsaXAzOVNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgcHVibGljIGFzeW5jIGdlbmVyYXRlU2hhcmVzKHNlY3JldCwgcGFzc3BocmFzZTogc3RyaW5nLCBhc3NlbWJseTogQXNzZW1ibHkpIHtcbiAgICAvLyBIZXgtZW5jb2RlIHNlY3JldC5cbiAgICBsZXQgZW1zID0gYnRvYShzZWNyZXQpO1xuICAgIGVtcyA9IFNsaXAzOUhlbHBlci5zbGlwMzlFbmNvZGVIZXgoZW1zKTtcblxuICAgIC8vIENvbnN0cnVjdCBncm91cCBzcGVjaWZpY2F0aW9uc1xuICAgIGNvbnN0IGdyb3VwcyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBzYSBvZiBhc3NlbWJseS5zdWJBc3NlbWJsaWVzKSB7XG4gICAgICBncm91cHMucHVzaChbc2EudGhyZXNob2xkLCBzYS5zaXplXSk7XG4gICAgfVxuXG4gICAgLy8gU3BsaXQhXG4gICAgY29uc3Qgc2xpcCA9IGF3YWl0IFNsaXAzOS5mcm9tQXJyYXkoZW1zLCB7XG4gICAgICBwYXNzcGhyYXNlLFxuICAgICAgdGhyZXNob2xkOiBhc3NlbWJseS50aHJlc2hvbGQsXG4gICAgICBncm91cHMsXG4gICAgICB0aXRsZTogJycsXG4gICAgfSk7XG5cbiAgICAvLyBFeHRyYWN0IHNoYXJlc1xuICAgIGFzc2VtYmx5LnN1YkFzc2VtYmxpZXMuZm9yRWFjaCgoc2EsIGlzYSkgPT4ge1xuICAgICAgLy8gUmVtb3ZlIGFueSBleGlzdGluZyBzaGFyZXNcbiAgICAgIHNhLmNsZWFyU2hhcmVzKCk7XG5cbiAgICAgIGZvciAobGV0IGltID0gMDsgaW0gPCBzYS5zaXplOyBpbSsrKSB7XG4gICAgICAgIC8vIENvbnN0cnVjdCB0aGUgcGF0aCB0byB0aGUgc2hhcmUsIGZvcm1hdHRlZCBhcyBcInIvPHN1YmFzc2VtYmx5IGluZGV4Pi88bWVtYmVyIGluZGV4PlwiXG4gICAgICAgIC8vIHdpdGggPHN1YmFzc2VtYmx5IGluZGV4PiBhbmQgPG1lbWJlciBpbmRleD4gYmVpbmcgdHdvLWRpZ2l0LCB6ZXJvLXBhZGRlZCBpbnRlZ2Vycy5cbiAgICAgICAgY29uc3QgcGF0aCA9XG4gICAgICAgICAgJ3IvJyArXG4gICAgICAgICAgaXNhLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKSArXG4gICAgICAgICAgJy8nICtcbiAgICAgICAgICBpbS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICAgIGNvbnN0IG1uZW1vbmljcyA9IHNsaXAuZnJvbVBhdGgocGF0aCkubW5lbW9uaWNzWzBdO1xuICAgICAgICBjb25zdCBzaGFyZSA9IG5ldyBTZWNyZXRTaGFyZShpc2EsIGltLCBtbmVtb25pY3MpO1xuXG4gICAgICAgIHNhLmFkZFNoYXJlKHNoYXJlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJlbW92ZSBhbGwgcmVkdW5kYW50IHNoYXJlcy4gaS5lLiBrZWVwIG9ubHkgZW5vdWdoIG1lbWJlcnMgYW5kIGdyb3VwcyB0byBzYXRpc2Z5IHRoZSB0aHJlc2hvbGRzLlxuICBwcml2YXRlIG1pbmltYWxTZXQobW5lbW9uaWNzOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgICAvLyBEZWNvZGUgdGhlIG1uZW1vbmljcyBhbmQgc29ydCB0aGVuIGludG8gZ3JvdXBzLlxuICAgIGxldCBncm91cFRocmVzaCA9IG51bGw7XG4gICAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3QgbW5lbW9uaWMgb2YgbW5lbW9uaWNzKSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gU2xpcDM5SGVscGVyLmRlY29kZU1uZW1vbmljKG1uZW1vbmljKTtcblxuICAgICAgaWYgKGdyb3VwVGhyZXNoICYmIGdyb3VwVGhyZXNoICE9PSBkZWNvZGVkLmdyb3VwVGhyZXNob2xkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ3JvdXBUaHJlc2hvbGQgaXMgZGlmZmVyZW50IGluIG1uZW1vbmljcycpO1xuICAgICAgfVxuXG4gICAgICBncm91cFRocmVzaCA9IGRlY29kZWQuZ3JvdXBUaHJlc2hvbGQ7XG5cbiAgICAgIC8vIE5vdGUgdGhhdCBTbGlwMzkucmVjb3ZlclNlY3JldCgpIHdpbGwgZG8gYWxsIHRoZSBlcnJvciBjaGVja2luZyBhZ2Fpbi4gU28gaXQncyBub3QgY3JpdGljYWxcbiAgICAgIC8vIHRoYXQgd2UgZXJyb3IgY2hlY2sgaGVyZS4gU28gd2UganVzdCBvcHRpbWlzdGljYWxseSBhc3N1bWUgaXQncyBhbGwgZ29vZC5cbiAgICAgIGxldCBnID0gZ3JvdXBzLmdldChkZWNvZGVkLmdyb3VwSW5kZXgpO1xuICAgICAgaWYgKGcgPT0gbnVsbCkge1xuICAgICAgICBnID0ge1xuICAgICAgICAgIG1lbWJlclRocmVzaG9sZDogZGVjb2RlZC5tZW1iZXJUaHJlc2hvbGQsXG4gICAgICAgICAgbWVtYmVyczogW10sXG4gICAgICAgIH07XG4gICAgICAgIGdyb3Vwcy5zZXQoZGVjb2RlZC5ncm91cEluZGV4LCBnKTtcbiAgICAgIH1cblxuICAgICAgZy5tZW1iZXJzLnB1c2goe1xuICAgICAgICBtbmVtb25pYyxcbiAgICAgICAgZGVjb2RlZCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEtlZXAgdGhlIG1pbmltdW0gc2V0IG9mIGdyb3VwcyB0aGF0IG1lZXQgdGhyZXNob2xkLlxuICAgIGNvbnN0IG1uZW1vbmljc01pblNldCA9IFtdO1xuICAgIGxldCBncm91cENvdW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IGcgb2YgZ3JvdXBzLnZhbHVlcygpKSB7XG4gICAgICAvLyBLZWVwIG9ubHkgZ3JvdXBzIHRoYXQgbWVldCB0aHJlc2hvbGRcbiAgICAgIGlmIChnLm1lbWJlcnMubGVuZ3RoIDwgZy5tZW1iZXJUaHJlc2hvbGQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIEtlZXAgbWluaW11bSBudW1iZXIgb2YgYXBwcm92YWxzIG5lZWRlZCBmb3IgZ3JvdXBcbiAgICAgIGcubWVtYmVycy5zbGljZSgwLCBnLm1lbWJlclRocmVzaG9sZCkuZm9yRWFjaCgobWVtYmVyKSA9PiB7XG4gICAgICAgIG1uZW1vbmljc01pblNldC5wdXNoKG1lbWJlci5tbmVtb25pYyk7XG4gICAgICB9KTtcblxuICAgICAgKytncm91cENvdW50O1xuICAgICAgaWYgKGdyb3VwQ291bnQgPj0gZ3JvdXBUaHJlc2gpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1uZW1vbmljc01pblNldDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZWNvdmVyU2VjcmV0KHNoYXJlczogc3RyaW5nW10sIHBhc3NwaHJhc2U6IHN0cmluZykge1xuICAgIHNoYXJlcyA9IHRoaXMubWluaW1hbFNldChzaGFyZXMpO1xuXG4gICAgY29uc3QgcmVjb3ZlcmVkID0gYXdhaXQgU2xpcDM5LnJlY292ZXJTZWNyZXQoc2hhcmVzLCBwYXNzcGhyYXNlKTtcblxuICAgIGNvbnN0IHNlY3JldCA9IFNsaXAzOUhlbHBlci5zbGlwMzlEZWNvZGVIZXgocmVjb3ZlcmVkKTtcblxuICAgIHJldHVybiBhdG9iKHNlY3JldCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export class WebCryptoService {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.crypto = window.crypto;
|
|
7
|
-
}
|
|
8
|
-
toHex(buffer) {
|
|
9
|
-
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
|
10
|
-
const array = Array.from(new Uint8Array(buffer)); // convert buffer to byte array
|
|
11
|
-
const hex = array.map((b) => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
|
|
12
|
-
return hex;
|
|
13
|
-
}
|
|
14
|
-
stringDigest(algorithm, message) {
|
|
15
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
const encoder = new TextEncoder();
|
|
17
|
-
const data = encoder.encode(message);
|
|
18
|
-
const hash = yield this.crypto.subtle.digest(algorithm, data);
|
|
19
|
-
return this.toHex(hash);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
WebCryptoService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebCryptoService_Factory() { return new WebCryptoService(); }, token: WebCryptoService, providedIn: "root" });
|
|
24
|
-
WebCryptoService.decorators = [
|
|
25
|
-
{ type: Injectable, args: [{
|
|
26
|
-
providedIn: 'root',
|
|
27
|
-
},] }
|
|
28
|
-
];
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class WebCryptoService {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.crypto = window.crypto;
|
|
7
|
+
}
|
|
8
|
+
toHex(buffer) {
|
|
9
|
+
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
|
10
|
+
const array = Array.from(new Uint8Array(buffer)); // convert buffer to byte array
|
|
11
|
+
const hex = array.map((b) => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
|
|
12
|
+
return hex;
|
|
13
|
+
}
|
|
14
|
+
stringDigest(algorithm, message) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const encoder = new TextEncoder();
|
|
17
|
+
const data = encoder.encode(message);
|
|
18
|
+
const hash = yield this.crypto.subtle.digest(algorithm, data);
|
|
19
|
+
return this.toHex(hash);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
WebCryptoService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebCryptoService_Factory() { return new WebCryptoService(); }, token: WebCryptoService, providedIn: "root" });
|
|
24
|
+
WebCryptoService.decorators = [
|
|
25
|
+
{ type: Injectable, args: [{
|
|
26
|
+
providedIn: 'root',
|
|
27
|
+
},] }
|
|
28
|
+
];
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWNyeXB0by5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9vcHQvYXRsYXNzaWFuL3BpcGVsaW5lcy9hZ2VudC9idWlsZC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jcnlwdG9ncmFwaHkvd2ViLWNyeXB0by5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUszQyxNQUFNLE9BQU8sZ0JBQWdCO0lBSDdCO1FBSUUsV0FBTSxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQUM7S0FlaEM7SUFiQyxLQUFLLENBQUMsTUFBbUI7UUFDdkIsNEVBQTRFO1FBQzVFLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtRQUNqRixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyw4QkFBOEI7UUFDdEcsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUssWUFBWSxDQUFDLFNBQWlCLEVBQUUsT0FBZTs7WUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM5RCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUIsQ0FBQztLQUFBOzs7O1lBbEJGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFdlYkNyeXB0b1NlcnZpY2Uge1xuICBjcnlwdG86IENyeXB0byA9IHdpbmRvdy5jcnlwdG87XG5cbiAgdG9IZXgoYnVmZmVyOiBBcnJheUJ1ZmZlcikge1xuICAgIC8vIFJlZjogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1N1YnRsZUNyeXB0by9kaWdlc3RcbiAgICBjb25zdCBhcnJheSA9IEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7IC8vIGNvbnZlcnQgYnVmZmVyIHRvIGJ5dGUgYXJyYXlcbiAgICBjb25zdCBoZXggPSBhcnJheS5tYXAoKGIpID0+IGIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJykpLmpvaW4oJycpOyAvLyBjb252ZXJ0IGJ5dGVzIHRvIGhleCBzdHJpbmdcbiAgICByZXR1cm4gaGV4O1xuICB9XG5cbiAgYXN5bmMgc3RyaW5nRGlnZXN0KGFsZ29yaXRobTogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICBjb25zdCBkYXRhID0gZW5jb2Rlci5lbmNvZGUobWVzc2FnZSk7XG4gICAgY29uc3QgaGFzaCA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5kaWdlc3QoYWxnb3JpdGhtLCBkYXRhKTtcbiAgICByZXR1cm4gdGhpcy50b0hleChoYXNoKTtcbiAgfVxufVxuIl19
|