@baozi.bet/mcp-server 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -0
- package/dist/__tests__/full-test.d.ts +1 -0
- package/dist/__tests__/full-test.js +291 -0
- package/dist/builders/affiliate-transaction.d.ts +41 -0
- package/dist/builders/affiliate-transaction.js +123 -0
- package/dist/builders/bet-transaction.d.ts +70 -0
- package/dist/builders/bet-transaction.js +323 -0
- package/dist/builders/claim-transaction.d.ts +57 -0
- package/dist/builders/claim-transaction.js +196 -0
- package/dist/builders/creator-transaction.d.ts +49 -0
- package/dist/builders/creator-transaction.js +177 -0
- package/dist/builders/dispute-transaction.d.ts +81 -0
- package/dist/builders/dispute-transaction.js +215 -0
- package/dist/builders/index.d.ts +14 -0
- package/dist/builders/index.js +15 -0
- package/dist/builders/market-creation-tx.d.ts +65 -0
- package/dist/builders/market-creation-tx.js +362 -0
- package/dist/builders/market-management-transaction.d.ts +85 -0
- package/dist/builders/market-management-transaction.js +239 -0
- package/dist/builders/race-transaction.d.ts +67 -0
- package/dist/builders/race-transaction.js +242 -0
- package/dist/builders/resolution-transaction.d.ts +108 -0
- package/dist/builders/resolution-transaction.js +250 -0
- package/dist/builders/whitelist-transaction.d.ts +72 -0
- package/dist/builders/whitelist-transaction.js +179 -0
- package/dist/config.d.ts +138 -0
- package/dist/config.js +307 -0
- package/dist/handlers/agent-network.d.ts +81 -0
- package/dist/handlers/agent-network.js +332 -0
- package/dist/handlers/claims.d.ts +47 -0
- package/dist/handlers/claims.js +218 -0
- package/dist/handlers/market-creation.d.ts +154 -0
- package/dist/handlers/market-creation.js +290 -0
- package/dist/handlers/markets.d.ts +41 -0
- package/dist/handlers/markets.js +319 -0
- package/dist/handlers/positions.d.ts +40 -0
- package/dist/handlers/positions.js +244 -0
- package/dist/handlers/quote.d.ts +33 -0
- package/dist/handlers/quote.js +144 -0
- package/dist/handlers/race-markets.d.ts +54 -0
- package/dist/handlers/race-markets.js +308 -0
- package/dist/handlers/resolution.d.ts +43 -0
- package/dist/handlers/resolution.js +194 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +109 -0
- package/dist/resources.d.ts +13 -0
- package/dist/resources.js +336 -0
- package/dist/tools.d.ts +3109 -0
- package/dist/tools.js +1956 -0
- package/dist/validation/bet-rules.d.ts +82 -0
- package/dist/validation/bet-rules.js +276 -0
- package/dist/validation/creation-rules.d.ts +69 -0
- package/dist/validation/creation-rules.js +302 -0
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.js +7 -0
- package/dist/validation/market-rules.d.ts +60 -0
- package/dist/validation/market-rules.js +237 -0
- package/dist/validation/parimutuel-rules.d.ts +117 -0
- package/dist/validation/parimutuel-rules.js +270 -0
- package/package.json +52 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bet Validation Rules
|
|
3
|
+
*
|
|
4
|
+
* Validates bet parameters against protocol constraints:
|
|
5
|
+
* - Amount limits (0.01-100 SOL)
|
|
6
|
+
* - Market state (active, not frozen, not paused)
|
|
7
|
+
* - Whitelist access (for private markets)
|
|
8
|
+
* - Timing constraints (betting freeze)
|
|
9
|
+
*/
|
|
10
|
+
export interface BetValidationParams {
|
|
11
|
+
amountSol: number;
|
|
12
|
+
marketStatus: number;
|
|
13
|
+
closingTime: Date;
|
|
14
|
+
isPaused: boolean;
|
|
15
|
+
accessGate: number;
|
|
16
|
+
userWhitelisted?: boolean;
|
|
17
|
+
layer?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface BetValidation {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
details: {
|
|
24
|
+
amountValid: boolean;
|
|
25
|
+
marketStateValid: boolean;
|
|
26
|
+
timingValid: boolean;
|
|
27
|
+
accessValid: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface ClaimValidationParams {
|
|
31
|
+
marketStatus: number;
|
|
32
|
+
marketOutcome: number;
|
|
33
|
+
positionSide: 'Yes' | 'No';
|
|
34
|
+
positionAmount: number;
|
|
35
|
+
alreadyClaimed: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ClaimValidation {
|
|
38
|
+
valid: boolean;
|
|
39
|
+
error?: string;
|
|
40
|
+
canClaim: boolean;
|
|
41
|
+
isWinner: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate bet parameters before building transaction
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateBet(params: BetValidationParams): BetValidation;
|
|
47
|
+
/**
|
|
48
|
+
* Validate claim parameters before building claim transaction
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateClaim(params: ClaimValidationParams): ClaimValidation;
|
|
51
|
+
/**
|
|
52
|
+
* Calculate quote for a bet (pari-mutuel)
|
|
53
|
+
*/
|
|
54
|
+
export declare function calculateBetQuote(params: {
|
|
55
|
+
betAmountSol: number;
|
|
56
|
+
side: 'Yes' | 'No';
|
|
57
|
+
currentYesPool: number;
|
|
58
|
+
currentNoPool: number;
|
|
59
|
+
platformFeeBps: number;
|
|
60
|
+
}): {
|
|
61
|
+
expectedPayoutSol: number;
|
|
62
|
+
potentialProfitSol: number;
|
|
63
|
+
feeSol: number;
|
|
64
|
+
impliedOdds: number;
|
|
65
|
+
decimalOdds: number;
|
|
66
|
+
newYesPool: number;
|
|
67
|
+
newNoPool: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Estimate claim amount for a winning position
|
|
71
|
+
*/
|
|
72
|
+
export declare function estimateClaimAmount(params: {
|
|
73
|
+
positionAmount: number;
|
|
74
|
+
positionSide: 'Yes' | 'No';
|
|
75
|
+
totalYesPool: number;
|
|
76
|
+
totalNoPool: number;
|
|
77
|
+
platformFeeBps: number;
|
|
78
|
+
}): {
|
|
79
|
+
grossPayout: number;
|
|
80
|
+
fee: number;
|
|
81
|
+
netPayout: number;
|
|
82
|
+
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bet Validation Rules
|
|
3
|
+
*
|
|
4
|
+
* Validates bet parameters against protocol constraints:
|
|
5
|
+
* - Amount limits (0.01-100 SOL)
|
|
6
|
+
* - Market state (active, not frozen, not paused)
|
|
7
|
+
* - Whitelist access (for private markets)
|
|
8
|
+
* - Timing constraints (betting freeze)
|
|
9
|
+
*/
|
|
10
|
+
import { BET_LIMITS, TIMING, MARKET_STATUS, ACCESS_GATE, MARKET_LAYER_NAMES, } from '../config.js';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// BET VALIDATION
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Validate bet parameters before building transaction
|
|
16
|
+
*/
|
|
17
|
+
export function validateBet(params) {
|
|
18
|
+
const warnings = [];
|
|
19
|
+
const details = {
|
|
20
|
+
amountValid: true,
|
|
21
|
+
marketStateValid: true,
|
|
22
|
+
timingValid: true,
|
|
23
|
+
accessValid: true,
|
|
24
|
+
};
|
|
25
|
+
// ==========================================================================
|
|
26
|
+
// Amount Validation
|
|
27
|
+
// ==========================================================================
|
|
28
|
+
if (params.amountSol < BET_LIMITS.MIN_BET_SOL) {
|
|
29
|
+
details.amountValid = false;
|
|
30
|
+
return {
|
|
31
|
+
valid: false,
|
|
32
|
+
error: `Minimum bet is ${BET_LIMITS.MIN_BET_SOL} SOL`,
|
|
33
|
+
warnings,
|
|
34
|
+
details,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (params.amountSol > BET_LIMITS.MAX_BET_SOL) {
|
|
38
|
+
details.amountValid = false;
|
|
39
|
+
return {
|
|
40
|
+
valid: false,
|
|
41
|
+
error: `Maximum bet is ${BET_LIMITS.MAX_BET_SOL} SOL`,
|
|
42
|
+
warnings,
|
|
43
|
+
details,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Amount warnings
|
|
47
|
+
if (params.amountSol > 50) {
|
|
48
|
+
warnings.push('Large bet amount. Ensure you understand the odds before placing.');
|
|
49
|
+
}
|
|
50
|
+
// ==========================================================================
|
|
51
|
+
// Market State Validation
|
|
52
|
+
// ==========================================================================
|
|
53
|
+
if (params.marketStatus !== MARKET_STATUS.ACTIVE) {
|
|
54
|
+
details.marketStateValid = false;
|
|
55
|
+
const statusName = getStatusName(params.marketStatus);
|
|
56
|
+
return {
|
|
57
|
+
valid: false,
|
|
58
|
+
error: `Market is ${statusName}, not accepting bets`,
|
|
59
|
+
warnings,
|
|
60
|
+
details,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (params.isPaused) {
|
|
64
|
+
details.marketStateValid = false;
|
|
65
|
+
return {
|
|
66
|
+
valid: false,
|
|
67
|
+
error: 'Market is paused',
|
|
68
|
+
warnings,
|
|
69
|
+
details,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// ==========================================================================
|
|
73
|
+
// Timing Validation
|
|
74
|
+
// ==========================================================================
|
|
75
|
+
const now = new Date();
|
|
76
|
+
const freezeTime = new Date(params.closingTime.getTime() - TIMING.BETTING_FREEZE_SECONDS * 1000);
|
|
77
|
+
if (now >= params.closingTime) {
|
|
78
|
+
details.timingValid = false;
|
|
79
|
+
return {
|
|
80
|
+
valid: false,
|
|
81
|
+
error: 'Betting has closed',
|
|
82
|
+
warnings,
|
|
83
|
+
details,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (now >= freezeTime) {
|
|
87
|
+
details.timingValid = false;
|
|
88
|
+
const remainingMs = params.closingTime.getTime() - now.getTime();
|
|
89
|
+
const remainingMin = Math.ceil(remainingMs / 60000);
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
error: `Betting is frozen (${remainingMin} minutes until close)`,
|
|
93
|
+
warnings,
|
|
94
|
+
details,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Timing warnings
|
|
98
|
+
const timeToFreezeMs = freezeTime.getTime() - now.getTime();
|
|
99
|
+
const timeToFreezeMin = Math.floor(timeToFreezeMs / 60000);
|
|
100
|
+
if (timeToFreezeMin < 30) {
|
|
101
|
+
warnings.push(`Betting freezes in ${timeToFreezeMin} minutes`);
|
|
102
|
+
}
|
|
103
|
+
// ==========================================================================
|
|
104
|
+
// Access Validation (Whitelist)
|
|
105
|
+
// ==========================================================================
|
|
106
|
+
if (params.accessGate === ACCESS_GATE.WHITELIST) {
|
|
107
|
+
if (params.userWhitelisted !== true) {
|
|
108
|
+
details.accessValid = false;
|
|
109
|
+
return {
|
|
110
|
+
valid: false,
|
|
111
|
+
error: 'You are not whitelisted for this private market',
|
|
112
|
+
warnings,
|
|
113
|
+
details,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Layer-specific warnings
|
|
118
|
+
if (params.layer !== undefined) {
|
|
119
|
+
const layerName = MARKET_LAYER_NAMES[params.layer] || 'Unknown';
|
|
120
|
+
if (params.layer === 1) { // Lab
|
|
121
|
+
warnings.push(`This is a ${layerName} market (community-created). DYOR.`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
valid: true,
|
|
126
|
+
warnings,
|
|
127
|
+
details,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// =============================================================================
|
|
131
|
+
// CLAIM VALIDATION
|
|
132
|
+
// =============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Validate claim parameters before building claim transaction
|
|
135
|
+
*/
|
|
136
|
+
export function validateClaim(params) {
|
|
137
|
+
// Already claimed
|
|
138
|
+
if (params.alreadyClaimed) {
|
|
139
|
+
return {
|
|
140
|
+
valid: false,
|
|
141
|
+
error: 'Position already claimed',
|
|
142
|
+
canClaim: false,
|
|
143
|
+
isWinner: false,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// Market not resolved
|
|
147
|
+
if (params.marketStatus !== MARKET_STATUS.RESOLVED &&
|
|
148
|
+
params.marketStatus !== MARKET_STATUS.CANCELLED) {
|
|
149
|
+
const statusName = getStatusName(params.marketStatus);
|
|
150
|
+
return {
|
|
151
|
+
valid: false,
|
|
152
|
+
error: `Market is ${statusName}, cannot claim yet`,
|
|
153
|
+
canClaim: false,
|
|
154
|
+
isWinner: false,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// Cancelled market - everyone can claim refund
|
|
158
|
+
if (params.marketStatus === MARKET_STATUS.CANCELLED) {
|
|
159
|
+
return {
|
|
160
|
+
valid: true,
|
|
161
|
+
canClaim: true,
|
|
162
|
+
isWinner: false, // Refund, not winning
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// Check if position is on winning side
|
|
166
|
+
const isWinner = (params.positionSide === 'Yes' && params.marketOutcome === 2) ||
|
|
167
|
+
(params.positionSide === 'No' && params.marketOutcome === 3);
|
|
168
|
+
if (!isWinner) {
|
|
169
|
+
return {
|
|
170
|
+
valid: false,
|
|
171
|
+
error: 'Position is on losing side, nothing to claim',
|
|
172
|
+
canClaim: false,
|
|
173
|
+
isWinner: false,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// Nothing to claim if amount is 0
|
|
177
|
+
if (params.positionAmount <= 0) {
|
|
178
|
+
return {
|
|
179
|
+
valid: false,
|
|
180
|
+
error: 'No position amount to claim',
|
|
181
|
+
canClaim: false,
|
|
182
|
+
isWinner: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
valid: true,
|
|
187
|
+
canClaim: true,
|
|
188
|
+
isWinner: true,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// =============================================================================
|
|
192
|
+
// HELPER FUNCTIONS
|
|
193
|
+
// =============================================================================
|
|
194
|
+
function getStatusName(status) {
|
|
195
|
+
switch (status) {
|
|
196
|
+
case MARKET_STATUS.ACTIVE: return 'Active';
|
|
197
|
+
case MARKET_STATUS.CLOSED: return 'Closed';
|
|
198
|
+
case MARKET_STATUS.RESOLVED: return 'Resolved';
|
|
199
|
+
case MARKET_STATUS.CANCELLED: return 'Cancelled';
|
|
200
|
+
case MARKET_STATUS.PAUSED: return 'Paused';
|
|
201
|
+
case MARKET_STATUS.RESOLVED_PENDING: return 'Pending Resolution';
|
|
202
|
+
case MARKET_STATUS.DISPUTED: return 'Disputed';
|
|
203
|
+
default: return 'Unknown';
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Calculate quote for a bet (pari-mutuel)
|
|
208
|
+
*/
|
|
209
|
+
export function calculateBetQuote(params) {
|
|
210
|
+
// Calculate new pools after bet
|
|
211
|
+
const newYesPool = params.side === 'Yes'
|
|
212
|
+
? params.currentYesPool + params.betAmountSol
|
|
213
|
+
: params.currentYesPool;
|
|
214
|
+
const newNoPool = params.side === 'No'
|
|
215
|
+
? params.currentNoPool + params.betAmountSol
|
|
216
|
+
: params.currentNoPool;
|
|
217
|
+
const newTotalPool = newYesPool + newNoPool;
|
|
218
|
+
// Calculate expected payout (pari-mutuel)
|
|
219
|
+
const sidePool = params.side === 'Yes' ? newYesPool : newNoPool;
|
|
220
|
+
const expectedPayoutSol = sidePool > 0
|
|
221
|
+
? (params.betAmountSol / sidePool) * newTotalPool
|
|
222
|
+
: 0;
|
|
223
|
+
// Calculate profit and fee
|
|
224
|
+
const grossProfit = expectedPayoutSol - params.betAmountSol;
|
|
225
|
+
const feeSol = grossProfit > 0
|
|
226
|
+
? (grossProfit * params.platformFeeBps) / 10000
|
|
227
|
+
: 0;
|
|
228
|
+
const potentialProfitSol = grossProfit - feeSol;
|
|
229
|
+
// Calculate odds
|
|
230
|
+
const impliedOdds = newTotalPool > 0
|
|
231
|
+
? (sidePool / newTotalPool) * 100
|
|
232
|
+
: 50;
|
|
233
|
+
const decimalOdds = sidePool > 0
|
|
234
|
+
? newTotalPool / sidePool
|
|
235
|
+
: 2;
|
|
236
|
+
return {
|
|
237
|
+
expectedPayoutSol: round4(expectedPayoutSol),
|
|
238
|
+
potentialProfitSol: round4(potentialProfitSol),
|
|
239
|
+
feeSol: round4(feeSol),
|
|
240
|
+
impliedOdds: round2(impliedOdds),
|
|
241
|
+
decimalOdds: round2(decimalOdds),
|
|
242
|
+
newYesPool: round4(newYesPool),
|
|
243
|
+
newNoPool: round4(newNoPool),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Estimate claim amount for a winning position
|
|
248
|
+
*/
|
|
249
|
+
export function estimateClaimAmount(params) {
|
|
250
|
+
const totalPool = params.totalYesPool + params.totalNoPool;
|
|
251
|
+
const winningPool = params.positionSide === 'Yes'
|
|
252
|
+
? params.totalYesPool
|
|
253
|
+
: params.totalNoPool;
|
|
254
|
+
// Calculate share of winning pool
|
|
255
|
+
const shareOfPool = winningPool > 0
|
|
256
|
+
? params.positionAmount / winningPool
|
|
257
|
+
: 0;
|
|
258
|
+
// Gross payout from total pool
|
|
259
|
+
const grossPayout = shareOfPool * totalPool;
|
|
260
|
+
// Calculate fee on profit only
|
|
261
|
+
const profit = grossPayout - params.positionAmount;
|
|
262
|
+
const fee = profit > 0 ? (profit * params.platformFeeBps) / 10000 : 0;
|
|
263
|
+
return {
|
|
264
|
+
grossPayout: round4(grossPayout),
|
|
265
|
+
fee: round4(fee),
|
|
266
|
+
netPayout: round4(grossPayout - fee),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// Rounding helpers
|
|
270
|
+
function round2(n) {
|
|
271
|
+
return Math.round(n * 100) / 100;
|
|
272
|
+
}
|
|
273
|
+
function round4(n) {
|
|
274
|
+
return Math.round(n * 10000) / 10000;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmV0LXJ1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZhbGlkYXRpb24vYmV0LXJ1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUNMLFVBQVUsRUFDVixNQUFNLEVBQ04sYUFBYSxFQUNiLFdBQVcsRUFDWCxrQkFBa0IsR0FDbkIsTUFBTSxjQUFjLENBQUM7QUEyQ3RCLGdGQUFnRjtBQUNoRixpQkFBaUI7QUFDakIsZ0ZBQWdGO0FBRWhGOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxNQUEyQjtJQUNyRCxNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7SUFDOUIsTUFBTSxPQUFPLEdBQUc7UUFDZCxXQUFXLEVBQUUsSUFBSTtRQUNqQixnQkFBZ0IsRUFBRSxJQUFJO1FBQ3RCLFdBQVcsRUFBRSxJQUFJO1FBQ2pCLFdBQVcsRUFBRSxJQUFJO0tBQ2xCLENBQUM7SUFFRiw2RUFBNkU7SUFDN0Usb0JBQW9CO0lBQ3BCLDZFQUE2RTtJQUM3RSxJQUFJLE1BQU0sQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzlDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzVCLE9BQU87WUFDTCxLQUFLLEVBQUUsS0FBSztZQUNaLEtBQUssRUFBRSxrQkFBa0IsVUFBVSxDQUFDLFdBQVcsTUFBTTtZQUNyRCxRQUFRO1lBQ1IsT0FBTztTQUNSLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBSSxNQUFNLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM5QyxPQUFPLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUM1QixPQUFPO1lBQ0wsS0FBSyxFQUFFLEtBQUs7WUFDWixLQUFLLEVBQUUsa0JBQWtCLFVBQVUsQ0FBQyxXQUFXLE1BQU07WUFDckQsUUFBUTtZQUNSLE9BQU87U0FDUixDQUFDO0lBQ0osQ0FB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LENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWTtRQUNyQixDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztJQUV2QixrQ0FBa0M7SUFDbEMsTUFBTSxXQUFXLEdBQUcsV0FBVyxHQUFHLENBQUM7UUFDakMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEdBQUcsV0FBVztRQUNyQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRU4sK0JBQStCO0lBQy9CLE1BQU0sV0FBVyxHQUFHLFdBQVcsR0FBRyxTQUFTLENBQUM7SUFFNUMsK0JBQStCO0lBQy9CLE1BQU0sTUFBTSxHQUFHLFdBQVcsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO0lBQ25ELE1BQU0sR0FBRyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV0RSxPQUFPO1FBQ0wsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUM7UUFDaEMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDaEIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO0tBQ3JDLENBQUM7QUFDSixDQUFDO0FBRUQsbUJBQW1CO0FBQ25CLFNBQVMsTUFBTSxDQUFDLENBQVM7SUFDdkIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFDLENBQVM7SUFDdkIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDdkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQmV0IFZhbGlkYXRpb24gUnVsZXNcbiAqXG4gKiBWYWxpZGF0ZXMgYmV0IHBhcmFtZXRlcnMgYWdhaW5zdCBwcm90b2NvbCBjb25zdHJhaW50czpcbiAqIC0gQW1vdW50IGxpbWl0cyAoMC4wMS0xMDAgU09MKVxuICogLSBNYXJrZXQgc3RhdGUgKGFjdGl2ZSwgbm90IGZyb3plbiwgbm90IHBhdXNlZClcbiAqIC0gV2hpdGVsaXN0IGFjY2VzcyAoZm9yIHByaXZhdGUgbWFya2V0cylcbiAqIC0gVGltaW5nIGNvbnN0cmFpbnRzIChiZXR0aW5nIGZyZWV6ZSlcbiAqL1xuXG5pbXBvcnQge1xuICBCRVRfTElNSVRTLFxuICBUSU1JTkcsXG4gIE1BUktFVF9TVEFUVVMsXG4gIEFDQ0VTU19HQVRFLFxuICBNQVJLRVRfTEFZRVJfTkFNRVMsXG59IGZyb20gJy4uL2NvbmZpZy5qcyc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBCZXRWYWxpZGF0aW9uUGFyYW1zIHtcbiAgYW1vdW50U29sOiBudW1iZXI7XG4gIG1hcmtldFN0YXR1czogbnVtYmVyO1xuICBjbG9zaW5nVGltZTogRGF0ZTtcbiAgaXNQYXVzZWQ6IGJvb2xlYW47XG4gIGFjY2Vzc0dhdGU6IG51bWJlcjtcbiAgdXNlcldoaXRlbGlzdGVkPzogYm9vbGVhbjtcbiAgbGF5ZXI/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmV0VmFsaWRhdGlvbiB7XG4gIHZhbGlkOiBib29sZWFuO1xuICBlcnJvcj86IHN0cmluZztcbiAgd2FybmluZ3M6IHN0cmluZ1tdO1xuICBkZXRhaWxzOiB7XG4gICAgYW1vdW50VmFsaWQ6IGJvb2xlYW47XG4gICAgbWFya2V0U3RhdGVWYWxpZDogYm9vbGVhbjtcbiAgICB0aW1pbmdWYWxpZDogYm9vbGVhbjtcbiAgICBhY2Nlc3NWYWxpZDogYm9vbGVhbjtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGFpbVZhbGlkYXRpb25QYXJhbXMge1xuICBtYXJrZXRTdGF0dXM6IG51bWJlcjtcbiAgbWFya2V0T3V0Y29tZTogbnVtYmVyO1xuICBwb3NpdGlvblNpZGU6ICdZZXMnIHwgJ05vJztcbiAgcG9zaXRpb25BbW91bnQ6IG51bWJlcjtcbiAgYWxyZWFkeUNsYWltZWQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xhaW1WYWxpZGF0aW9uIHtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIGVycm9yPzogc3RyaW5nO1xuICBjYW5DbGFpbTogYm9vbGVhbjtcbiAgaXNXaW5uZXI6IGJvb2xlYW47XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBCRVQgVkFMSURBVElPTlxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBWYWxpZGF0ZSBiZXQgcGFyYW1ldGVycyBiZWZvcmUgYnVpbGRpbmcgdHJhbnNhY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQmV0KHBhcmFtczogQmV0VmFsaWRhdGlvblBhcmFtcyk6IEJldFZhbGlkYXRpb24ge1xuICBjb25zdCB3YXJuaW5nczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZGV0YWlscyA9IHtcbiAgICBhbW91bnRWYWxpZDogdHJ1ZSxcbiAgICBtYXJrZXRTdGF0ZVZhbGlkOiB0cnVlLFxuICAgIHRpbWluZ1ZhbGlkOiB0cnVlLFxuICAgIGFjY2Vzc1ZhbGlkOiB0cnVlLFxuICB9O1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEFtb3VudCBWYWxpZGF0aW9uXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGlmIChwYXJhbXMuYW1vdW50U29sIDwgQkVUX0xJTUlUUy5NSU5fQkVUX1NPTCkge1xuICAgIGRldGFpbHMuYW1vdW50VmFsaWQgPSBmYWxzZTtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6IGBNaW5pbXVtIGJldCBpcyAke0JFVF9MSU1JVFMuTUlOX0JFVF9TT0x9IFNPTGAsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIGRldGFpbHMsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuYW1vdW50U29sID4gQkVUX0xJTUlUUy5NQVhfQkVUX1NPTCkge1xuICAgIGRldGFpbHMuYW1vdW50VmFsaWQgPSBmYWxzZTtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6IGBNYXhpbXVtIGJldCBpcyAke0JFVF9MSU1JVFMuTUFYX0JFVF9TT0x9IFNPTGAsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIGRldGFpbHMsXG4gICAgfTtcbiAgfVxuXG4gIC8vIEFtb3VudCB3YXJuaW5nc1xuICBpZiAocGFyYW1zLmFtb3VudFNvbCA+IDUwKSB7XG4gICAgd2FybmluZ3MucHVzaCgnTGFyZ2UgYmV0IGFtb3VudC4gRW5zdXJlIHlvdSB1bmRlcnN0YW5kIHRoZSBvZGRzIGJlZm9yZSBwbGFjaW5nLicpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gTWFya2V0IFN0YXRlIFZhbGlkYXRpb25cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgaWYgKHBhcmFtcy5tYXJrZXRTdGF0dXMgIT09IE1BUktFVF9TVEFUVVMuQUNUSVZFKSB7XG4gICAgZGV0YWlscy5tYXJrZXRTdGF0ZVZhbGlkID0gZmFsc2U7XG4gICAgY29uc3Qgc3RhdHVzTmFtZSA9IGdldFN0YXR1c05hbWUocGFyYW1zLm1hcmtldFN0YXR1cyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBgTWFya2V0IGlzICR7c3RhdHVzTmFtZX0sIG5vdCBhY2NlcHRpbmcgYmV0c2AsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIGRldGFpbHMsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuaXNQYXVzZWQpIHtcbiAgICBkZXRhaWxzLm1hcmtldFN0YXRlVmFsaWQgPSBmYWxzZTtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6ICdNYXJrZXQgaXMgcGF1c2VkJyxcbiAgICAgIHdhcm5pbmdzLFxuICAgICAgZGV0YWlscyxcbiAgICB9O1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gVGltaW5nIFZhbGlkYXRpb25cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgY29uc3QgZnJlZXplVGltZSA9IG5ldyBEYXRlKFxuICAgIHBhcmFtcy5jbG9zaW5nVGltZS5nZXRUaW1lKCkgLSBUSU1JTkcuQkVUVElOR19GUkVFWkVfU0VDT05EUyAqIDEwMDBcbiAgKTtcblxuICBpZiAobm93ID49IHBhcmFtcy5jbG9zaW5nVGltZSkge1xuICAgIGRldGFpbHMudGltaW5nVmFsaWQgPSBmYWxzZTtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6ICdCZXR0aW5nIGhhcyBjbG9zZWQnLFxuICAgICAgd2FybmluZ3MsXG4gICAgICBkZXRhaWxzLFxuICAgIH07XG4gIH1cblxuICBpZiAobm93ID49IGZyZWV6ZVRpbWUpIHtcbiAgICBkZXRhaWxzLnRpbWluZ1ZhbGlkID0gZmFsc2U7XG4gICAgY29uc3QgcmVtYWluaW5nTXMgPSBwYXJhbXMuY2xvc2luZ1RpbWUuZ2V0VGltZSgpIC0gbm93LmdldFRpbWUoKTtcbiAgICBjb25zdCByZW1haW5pbmdNaW4gPSBNYXRoLmNlaWwocmVtYWluaW5nTXMgLyA2MDAwMCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBgQmV0dGluZyBpcyBmcm96ZW4gKCR7cmVtYWluaW5nTWlufSBtaW51dGVzIHVudGlsIGNsb3NlKWAsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIGRldGFpbHMsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRpbWluZyB3YXJuaW5nc1xuICBjb25zdCB0aW1lVG9GcmVlemVNcyA9IGZyZWV6ZVRpbWUuZ2V0VGltZSgpIC0gbm93LmdldFRpbWUoKTtcbiAgY29uc3QgdGltZVRvRnJlZXplTWluID0gTWF0aC5mbG9vcih0aW1lVG9GcmVlemVNcyAvIDYwMDAwKTtcbiAgaWYgKHRpbWVUb0ZyZWV6ZU1pbiA8IDMwKSB7XG4gICAgd2FybmluZ3MucHVzaChgQmV0dGluZyBmcmVlemVzIGluICR7dGltZVRvRnJlZXplTWlufSBtaW51dGVzYCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBBY2Nlc3MgVmFsaWRhdGlvbiAoV2hpdGVsaXN0KVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBpZiAocGFyYW1zLmFjY2Vzc0dhdGUgPT09IEFDQ0VTU19HQVRFLldISVRFTElTVCkge1xuICAgIGlmIChwYXJhbXMudXNlcldoaXRlbGlzdGVkICE9PSB0cnVlKSB7XG4gICAgICBkZXRhaWxzLmFjY2Vzc1ZhbGlkID0gZmFsc2U7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiAnWW91IGFyZSBub3Qgd2hpdGVsaXN0ZWQgZm9yIHRoaXMgcHJpdmF0ZSBtYXJrZXQnLFxuICAgICAgICB3YXJuaW5ncyxcbiAgICAgICAgZGV0YWlscyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gTGF5ZXItc3BlY2lmaWMgd2FybmluZ3NcbiAgaWYgKHBhcmFtcy5sYXllciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgbGF5ZXJOYW1lID0gTUFSS0VUX0xBWUVSX05BTUVTW3BhcmFtcy5sYXllcl0gfHwgJ1Vua25vd24nO1xuICAgIGlmIChwYXJhbXMubGF5ZXIgPT09IDEpIHsgLy8gTGFiXG4gICAgICB3YXJuaW5ncy5wdXNoKGBUaGlzIGlzIGEgJHtsYXllck5hbWV9IG1hcmtldCAoY29tbXVuaXR5LWNyZWF0ZWQpLiBEWU9SLmApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmFsaWQ6IHRydWUsXG4gICAgd2FybmluZ3MsXG4gICAgZGV0YWlscyxcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENMQUlNIFZBTElEQVRJT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogVmFsaWRhdGUgY2xhaW0gcGFyYW1ldGVycyBiZWZvcmUgYnVpbGRpbmcgY2xhaW0gdHJhbnNhY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ2xhaW0ocGFyYW1zOiBDbGFpbVZhbGlkYXRpb25QYXJhbXMpOiBDbGFpbVZhbGlkYXRpb24ge1xuICAvLyBBbHJlYWR5IGNsYWltZWRcbiAgaWYgKHBhcmFtcy5hbHJlYWR5Q2xhaW1lZCkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICBlcnJvcjogJ1Bvc2l0aW9uIGFscmVhZHkgY2xhaW1lZCcsXG4gICAgICBjYW5DbGFpbTogZmFsc2UsXG4gICAgICBpc1dpbm5lcjogZmFsc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8vIE1hcmtldCBub3QgcmVzb2x2ZWRcbiAgaWYgKHBhcmFtcy5tYXJrZXRTdGF0dXMgIT09IE1BUktFVF9TVEFUVVMuUkVTT0xWRUQgJiZcbiAgICAgIHBhcmFtcy5tYXJrZXRTdGF0dXMgIT09IE1BUktFVF9TVEFUVVMuQ0FOQ0VMTEVEKSB7XG4gICAgY29uc3Qgc3RhdHVzTmFtZSA9IGdldFN0YXR1c05hbWUocGFyYW1zLm1hcmtldFN0YXR1cyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBgTWFya2V0IGlzICR7c3RhdHVzTmFtZX0sIGNhbm5vdCBjbGFpbSB5ZXRgLFxuICAgICAgY2FuQ2xhaW06IGZhbHNlLFxuICAgICAgaXNXaW5uZXI6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICAvLyBDYW5jZWxsZWQgbWFya2V0IC0gZXZlcnlvbmUgY2FuIGNsYWltIHJlZnVuZFxuICBpZiAocGFyYW1zLm1hcmtldFN0YXR1cyA9PT0gTUFSS0VUX1NUQVRVUy5DQU5DRUxMRUQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICBjYW5DbGFpbTogdHJ1ZSxcbiAgICAgIGlzV2lubmVyOiBmYWxzZSwgLy8gUmVmdW5kLCBub3Qgd2lubmluZ1xuICAgIH07XG4gIH1cblxuICAvLyBDaGVjayBpZiBwb3NpdGlvbiBpcyBvbiB3aW5uaW5nIHNpZGVcbiAgY29uc3QgaXNXaW5uZXIgPSAocGFyYW1zLnBvc2l0aW9uU2lkZSA9PT0gJ1llcycgJiYgcGFyYW1zLm1hcmtldE91dGNvbWUgPT09IDIpIHx8XG4gICAgICAgICAgICAgICAgICAgKHBhcmFtcy5wb3NpdGlvblNpZGUgPT09ICdObycgJiYgcGFyYW1zLm1hcmtldE91dGNvbWUgPT09IDMpO1xuXG4gIGlmICghaXNXaW5uZXIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6ICdQb3NpdGlvbiBpcyBvbiBsb3Npbmcgc2lkZSwgbm90aGluZyB0byBjbGFpbScsXG4gICAgICBjYW5DbGFpbTogZmFsc2UsXG4gICAgICBpc1dpbm5lcjogZmFsc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8vIE5vdGhpbmcgdG8gY2xhaW0gaWYgYW1vdW50IGlzIDBcbiAgaWYgKHBhcmFtcy5wb3NpdGlvbkFtb3VudCA8PSAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiAnTm8gcG9zaXRpb24gYW1vdW50IHRvIGNsYWltJyxcbiAgICAgIGNhbkNsYWltOiBmYWxzZSxcbiAgICAgIGlzV2lubmVyOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHZhbGlkOiB0cnVlLFxuICAgIGNhbkNsYWltOiB0cnVlLFxuICAgIGlzV2lubmVyOiB0cnVlLFxuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gZ2V0U3RhdHVzTmFtZShzdGF0dXM6IG51bWJlcik6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdHVzKSB7XG4gICAgY2FzZSBNQVJLRVRfU1RBVFVTLkFDVElWRTogcmV0dXJuICdBY3RpdmUnO1xuICAgIGNhc2UgTUFSS0VUX1NUQVRVUy5DTE9TRUQ6IHJldHVybiAnQ2xvc2VkJztcbiAgICBjYXNlIE1BUktFVF9TVEFUVVMuUkVTT0xWRUQ6IHJldHVybiAnUmVzb2x2ZWQnO1xuICAgIGNhc2UgTUFSS0VUX1NUQVRVUy5DQU5DRUxMRUQ6IHJldHVybiAnQ2FuY2VsbGVkJztcbiAgICBjYXNlIE1BUktFVF9TVEFUVVMuUEFVU0VEOiByZXR1cm4gJ1BhdXNlZCc7XG4gICAgY2FzZSBNQVJLRVRfU1RBVFVTLlJFU09MVkVEX1BFTkRJTkc6IHJldHVybiAnUGVuZGluZyBSZXNvbHV0aW9uJztcbiAgICBjYXNlIE1BUktFVF9TVEFUVVMuRElTUFVURUQ6IHJldHVybiAnRGlzcHV0ZWQnO1xuICAgIGRlZmF1bHQ6IHJldHVybiAnVW5rbm93bic7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcXVvdGUgZm9yIGEgYmV0IChwYXJpLW11dHVlbClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUJldFF1b3RlKHBhcmFtczoge1xuICBiZXRBbW91bnRTb2w6IG51bWJlcjtcbiAgc2lkZTogJ1llcycgfCAnTm8nO1xuICBjdXJyZW50WWVzUG9vbDogbnVtYmVyO1xuICBjdXJyZW50Tm9Qb29sOiBudW1iZXI7XG4gIHBsYXRmb3JtRmVlQnBzOiBudW1iZXI7XG59KToge1xuICBleHBlY3RlZFBheW91dFNvbDogbnVtYmVyO1xuICBwb3RlbnRpYWxQcm9maXRTb2w6IG51bWJlcjtcbiAgZmVlU29sOiBudW1iZXI7XG4gIGltcGxpZWRPZGRzOiBudW1iZXI7XG4gIGRlY2ltYWxPZGRzOiBudW1iZXI7XG4gIG5ld1llc1Bvb2w6IG51bWJlcjtcbiAgbmV3Tm9Qb29sOiBudW1iZXI7XG59IHtcbiAgLy8gQ2FsY3VsYXRlIG5ldyBwb29scyBhZnRlciBiZXRcbiAgY29uc3QgbmV3WWVzUG9vbCA9IHBhcmFtcy5zaWRlID09PSAnWWVzJ1xuICAgID8gcGFyYW1zLmN1cnJlbnRZZXNQb29sICsgcGFyYW1zLmJldEFtb3VudFNvbFxuICAgIDogcGFyYW1zLmN1cnJlbnRZZXNQb29sO1xuICBjb25zdCBuZXdOb1Bvb2wgPSBwYXJhbXMuc2lkZSA9PT0gJ05vJ1xuICAgID8gcGFyYW1zLmN1cnJlbnROb1Bvb2wgKyBwYXJhbXMuYmV0QW1vdW50U29sXG4gICAgOiBwYXJhbXMuY3VycmVudE5vUG9vbDtcbiAgY29uc3QgbmV3VG90YWxQb29sID0gbmV3WWVzUG9vbCArIG5ld05vUG9vbDtcblxuICAvLyBDYWxjdWxhdGUgZXhwZWN0ZWQgcGF5b3V0IChwYXJpLW11dHVlbClcbiAgY29uc3Qgc2lkZVBvb2wgPSBwYXJhbXMuc2lkZSA9PT0gJ1llcycgPyBuZXdZZXNQb29sIDogbmV3Tm9Qb29sO1xuICBjb25zdCBleHBlY3RlZFBheW91dFNvbCA9IHNpZGVQb29sID4gMFxuICAgID8gKHBhcmFtcy5iZXRBbW91bnRTb2wgLyBzaWRlUG9vbCkgKiBuZXdUb3RhbFBvb2xcbiAgICA6IDA7XG5cbiAgLy8gQ2FsY3VsYXRlIHByb2ZpdCBhbmQgZmVlXG4gIGNvbnN0IGdyb3NzUHJvZml0ID0gZXhwZWN0ZWRQYXlvdXRTb2wgLSBwYXJhbXMuYmV0QW1vdW50U29sO1xuICBjb25zdCBmZWVTb2wgPSBncm9zc1Byb2ZpdCA+IDBcbiAgICA/IChncm9zc1Byb2ZpdCAqIHBhcmFtcy5wbGF0Zm9ybUZlZUJwcykgLyAxMDAwMFxuICAgIDogMDtcbiAgY29uc3QgcG90ZW50aWFsUHJvZml0U29sID0gZ3Jvc3NQcm9maXQgLSBmZWVTb2w7XG5cbiAgLy8gQ2FsY3VsYXRlIG9kZHNcbiAgY29uc3QgaW1wbGllZE9kZHMgPSBuZXdUb3RhbFBvb2wgPiAwXG4gICAgPyAoc2lkZVBvb2wgLyBuZXdUb3RhbFBvb2wpICogMTAwXG4gICAgOiA1MDtcbiAgY29uc3QgZGVjaW1hbE9kZHMgPSBzaWRlUG9vbCA+IDBcbiAgICA/IG5ld1RvdGFsUG9vbCAvIHNpZGVQb29sXG4gICAgOiAyO1xuXG4gIHJldHVybiB7XG4gICAgZXhwZWN0ZWRQYXlvdXRTb2w6IHJvdW5kNChleHBlY3RlZFBheW91dFNvbCksXG4gICAgcG90ZW50aWFsUHJvZml0U29sOiByb3VuZDQocG90ZW50aWFsUHJvZml0U29sKSxcbiAgICBmZWVTb2w6IHJvdW5kNChmZWVTb2wpLFxuICAgIGltcGxpZWRPZGRzOiByb3VuZDIoaW1wbGllZE9kZHMpLFxuICAgIGRlY2ltYWxPZGRzOiByb3VuZDIoZGVjaW1hbE9kZHMpLFxuICAgIG5ld1llc1Bvb2w6IHJvdW5kNChuZXdZZXNQb29sKSxcbiAgICBuZXdOb1Bvb2w6IHJvdW5kNChuZXdOb1Bvb2wpLFxuICB9O1xufVxuXG4vKipcbiAqIEVzdGltYXRlIGNsYWltIGFtb3VudCBmb3IgYSB3aW5uaW5nIHBvc2l0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc3RpbWF0ZUNsYWltQW1vdW50KHBhcmFtczoge1xuICBwb3NpdGlvbkFtb3VudDogbnVtYmVyO1xuICBwb3NpdGlvblNpZGU6ICdZZXMnIHwgJ05vJztcbiAgdG90YWxZZXNQb29sOiBudW1iZXI7XG4gIHRvdGFsTm9Qb29sOiBudW1iZXI7XG4gIHBsYXRmb3JtRmVlQnBzOiBudW1iZXI7XG59KToge1xuICBncm9zc1BheW91dDogbnVtYmVyO1xuICBmZWU6IG51bWJlcjtcbiAgbmV0UGF5b3V0OiBudW1iZXI7XG59IHtcbiAgY29uc3QgdG90YWxQb29sID0gcGFyYW1zLnRvdGFsWWVzUG9vbCArIHBhcmFtcy50b3RhbE5vUG9vbDtcbiAgY29uc3Qgd2lubmluZ1Bvb2wgPSBwYXJhbXMucG9zaXRpb25TaWRlID09PSAnWWVzJ1xuICAgID8gcGFyYW1zLnRvdGFsWWVzUG9vbFxuICAgIDogcGFyYW1zLnRvdGFsTm9Qb29sO1xuXG4gIC8vIENhbGN1bGF0ZSBzaGFyZSBvZiB3aW5uaW5nIHBvb2xcbiAgY29uc3Qgc2hhcmVPZlBvb2wgPSB3aW5uaW5nUG9vbCA+IDBcbiAgICA/IHBhcmFtcy5wb3NpdGlvbkFtb3VudCAvIHdpbm5pbmdQb29sXG4gICAgOiAwO1xuXG4gIC8vIEdyb3NzIHBheW91dCBmcm9tIHRvdGFsIHBvb2xcbiAgY29uc3QgZ3Jvc3NQYXlvdXQgPSBzaGFyZU9mUG9vbCAqIHRvdGFsUG9vbDtcblxuICAvLyBDYWxjdWxhdGUgZmVlIG9uIHByb2ZpdCBvbmx5XG4gIGNvbnN0IHByb2ZpdCA9IGdyb3NzUGF5b3V0IC0gcGFyYW1zLnBvc2l0aW9uQW1vdW50O1xuICBjb25zdCBmZWUgPSBwcm9maXQgPiAwID8gKHByb2ZpdCAqIHBhcmFtcy5wbGF0Zm9ybUZlZUJwcykgLyAxMDAwMCA6IDA7XG5cbiAgcmV0dXJuIHtcbiAgICBncm9zc1BheW91dDogcm91bmQ0KGdyb3NzUGF5b3V0KSxcbiAgICBmZWU6IHJvdW5kNChmZWUpLFxuICAgIG5ldFBheW91dDogcm91bmQ0KGdyb3NzUGF5b3V0IC0gZmVlKSxcbiAgfTtcbn1cblxuLy8gUm91bmRpbmcgaGVscGVyc1xuZnVuY3Rpb24gcm91bmQyKG46IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJvdW5kKG4gKiAxMDApIC8gMTAwO1xufVxuXG5mdW5jdGlvbiByb3VuZDQobjogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgucm91bmQobiAqIDEwMDAwKSAvIDEwMDAwO1xufVxuIl19
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market Creation Validation Rules (v6.2 Compliant)
|
|
3
|
+
*
|
|
4
|
+
* Implements validation for:
|
|
5
|
+
* - Rule A: Event-based markets (12-24h buffer before event)
|
|
6
|
+
* - Rule B: Measurement-period markets (close before measurement starts)
|
|
7
|
+
* - Race market outcome validation
|
|
8
|
+
* - Question and timing constraints
|
|
9
|
+
*/
|
|
10
|
+
export interface CreateMarketParams {
|
|
11
|
+
question: string;
|
|
12
|
+
closingTime: Date;
|
|
13
|
+
resolutionTime: Date;
|
|
14
|
+
layer: 'official' | 'lab' | 'private';
|
|
15
|
+
marketType?: 'event' | 'measurement';
|
|
16
|
+
eventTime?: Date;
|
|
17
|
+
measurementStart?: Date;
|
|
18
|
+
measurementEnd?: Date;
|
|
19
|
+
outcomes?: string[];
|
|
20
|
+
inviteHash?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CreationValidationResult {
|
|
23
|
+
valid: boolean;
|
|
24
|
+
errors: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
suggestions: string[];
|
|
27
|
+
computed: {
|
|
28
|
+
ruleType: 'A' | 'B' | 'unknown';
|
|
29
|
+
bufferHours?: number;
|
|
30
|
+
recommendedClosingTime?: string;
|
|
31
|
+
creationFeeSol: number;
|
|
32
|
+
platformFeeBps: number;
|
|
33
|
+
estimatedRentSol: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validate market creation parameters
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateMarketCreation(params: CreateMarketParams): CreationValidationResult;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate recommended resolution time from closing time
|
|
42
|
+
*/
|
|
43
|
+
export declare function calculateResolutionTime(closingTime: Date, marketType: 'event' | 'measurement', eventTime?: Date): Date;
|
|
44
|
+
/**
|
|
45
|
+
* Calculate recommended closing time for event
|
|
46
|
+
*/
|
|
47
|
+
export declare function calculateRecommendedClosingTime(eventTime: Date, bufferHours?: number): Date;
|
|
48
|
+
/**
|
|
49
|
+
* Get creation fee for layer
|
|
50
|
+
*/
|
|
51
|
+
export declare function getCreationFee(layer: 'official' | 'lab' | 'private'): {
|
|
52
|
+
lamports: number;
|
|
53
|
+
sol: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Validate question format
|
|
57
|
+
*/
|
|
58
|
+
export declare function validateQuestion(question: string): {
|
|
59
|
+
valid: boolean;
|
|
60
|
+
errors: string[];
|
|
61
|
+
suggestions: string[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Validate race outcomes
|
|
65
|
+
*/
|
|
66
|
+
export declare function validateRaceOutcomes(outcomes: string[]): {
|
|
67
|
+
valid: boolean;
|
|
68
|
+
errors: string[];
|
|
69
|
+
};
|