@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.
Files changed (60) hide show
  1. package/README.md +294 -0
  2. package/dist/__tests__/full-test.d.ts +1 -0
  3. package/dist/__tests__/full-test.js +291 -0
  4. package/dist/builders/affiliate-transaction.d.ts +41 -0
  5. package/dist/builders/affiliate-transaction.js +123 -0
  6. package/dist/builders/bet-transaction.d.ts +70 -0
  7. package/dist/builders/bet-transaction.js +323 -0
  8. package/dist/builders/claim-transaction.d.ts +57 -0
  9. package/dist/builders/claim-transaction.js +196 -0
  10. package/dist/builders/creator-transaction.d.ts +49 -0
  11. package/dist/builders/creator-transaction.js +177 -0
  12. package/dist/builders/dispute-transaction.d.ts +81 -0
  13. package/dist/builders/dispute-transaction.js +215 -0
  14. package/dist/builders/index.d.ts +14 -0
  15. package/dist/builders/index.js +15 -0
  16. package/dist/builders/market-creation-tx.d.ts +65 -0
  17. package/dist/builders/market-creation-tx.js +362 -0
  18. package/dist/builders/market-management-transaction.d.ts +85 -0
  19. package/dist/builders/market-management-transaction.js +239 -0
  20. package/dist/builders/race-transaction.d.ts +67 -0
  21. package/dist/builders/race-transaction.js +242 -0
  22. package/dist/builders/resolution-transaction.d.ts +108 -0
  23. package/dist/builders/resolution-transaction.js +250 -0
  24. package/dist/builders/whitelist-transaction.d.ts +72 -0
  25. package/dist/builders/whitelist-transaction.js +179 -0
  26. package/dist/config.d.ts +138 -0
  27. package/dist/config.js +307 -0
  28. package/dist/handlers/agent-network.d.ts +81 -0
  29. package/dist/handlers/agent-network.js +332 -0
  30. package/dist/handlers/claims.d.ts +47 -0
  31. package/dist/handlers/claims.js +218 -0
  32. package/dist/handlers/market-creation.d.ts +154 -0
  33. package/dist/handlers/market-creation.js +290 -0
  34. package/dist/handlers/markets.d.ts +41 -0
  35. package/dist/handlers/markets.js +319 -0
  36. package/dist/handlers/positions.d.ts +40 -0
  37. package/dist/handlers/positions.js +244 -0
  38. package/dist/handlers/quote.d.ts +33 -0
  39. package/dist/handlers/quote.js +144 -0
  40. package/dist/handlers/race-markets.d.ts +54 -0
  41. package/dist/handlers/race-markets.js +308 -0
  42. package/dist/handlers/resolution.d.ts +43 -0
  43. package/dist/handlers/resolution.js +194 -0
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.js +109 -0
  46. package/dist/resources.d.ts +13 -0
  47. package/dist/resources.js +336 -0
  48. package/dist/tools.d.ts +3109 -0
  49. package/dist/tools.js +1956 -0
  50. package/dist/validation/bet-rules.d.ts +82 -0
  51. package/dist/validation/bet-rules.js +276 -0
  52. package/dist/validation/creation-rules.d.ts +69 -0
  53. package/dist/validation/creation-rules.js +302 -0
  54. package/dist/validation/index.d.ts +6 -0
  55. package/dist/validation/index.js +7 -0
  56. package/dist/validation/market-rules.d.ts +60 -0
  57. package/dist/validation/market-rules.js +237 -0
  58. package/dist/validation/parimutuel-rules.d.ts +117 -0
  59. package/dist/validation/parimutuel-rules.js +270 -0
  60. package/package.json +52 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Market Validation Rules (v6.2)
3
+ *
4
+ * Implements timing validation for market creation based on:
5
+ * - Rule A: Event-Based Markets (single point in time)
6
+ * - Rule B: Measurement-Period Markets (outcome over time range)
7
+ */
8
+ import { TIMING } from '../config.js';
9
+ // =============================================================================
10
+ // MAIN VALIDATION FUNCTION
11
+ // =============================================================================
12
+ /**
13
+ * Validate market timing parameters against v6.2 rules
14
+ *
15
+ * Rule A (Event-Based):
16
+ * - Betting closes BEFORE the event occurs
17
+ * - Minimum 12h buffer between close and event
18
+ * - Recommended 18-24h buffer for safety
19
+ *
20
+ * Rule B (Measurement-Period):
21
+ * - Betting must close BEFORE measurement starts
22
+ * - Measurement period should be well-defined
23
+ * - Prefer 2-7 day measurement periods for UX
24
+ */
25
+ export function validateMarketTiming(params) {
26
+ const errors = [];
27
+ const warnings = [];
28
+ const suggestions = [];
29
+ const timing = {};
30
+ // Common validation: question length
31
+ if (params.question.length > 200) {
32
+ errors.push(`Question too long: ${params.question.length} chars (max 200)`);
33
+ }
34
+ if (params.question.length < 10) {
35
+ warnings.push(`Question may be too short: ${params.question.length} chars`);
36
+ }
37
+ // Common validation: closing time in future
38
+ const now = new Date();
39
+ if (params.closingTime <= now) {
40
+ errors.push('Closing time must be in the future');
41
+ }
42
+ // Common validation: closing time not too far
43
+ const maxClosingTime = new Date(now.getTime() + TIMING.MAX_MARKET_DURATION_DAYS * 24 * 60 * 60 * 1000);
44
+ if (params.closingTime > maxClosingTime) {
45
+ errors.push(`Closing time too far in future (max ${TIMING.MAX_MARKET_DURATION_DAYS} days)`);
46
+ }
47
+ // ==========================================================================
48
+ // Rule A: Event-Based Markets
49
+ // ==========================================================================
50
+ if (params.marketType === 'event') {
51
+ if (!params.eventTime) {
52
+ errors.push('Event-based markets require event_time');
53
+ return { valid: false, ruleType: 'A', errors, warnings, suggestions };
54
+ }
55
+ // Event time must be after closing time
56
+ if (params.eventTime <= params.closingTime) {
57
+ errors.push('Event time must be after closing time');
58
+ }
59
+ // Calculate buffer
60
+ const bufferMs = params.eventTime.getTime() - params.closingTime.getTime();
61
+ const bufferHours = bufferMs / (1000 * 60 * 60);
62
+ timing.bufferHours = Math.round(bufferHours * 10) / 10;
63
+ // Minimum buffer check (12 hours)
64
+ if (bufferHours < TIMING.MIN_EVENT_BUFFER_HOURS) {
65
+ errors.push(`Buffer too short: ${timing.bufferHours}h. ` +
66
+ `Minimum ${TIMING.MIN_EVENT_BUFFER_HOURS}h required between betting close and event.`);
67
+ }
68
+ else if (bufferHours < 18) {
69
+ warnings.push(`Buffer is ${timing.bufferHours}h. ` +
70
+ `Recommend ${TIMING.RECOMMENDED_EVENT_BUFFER_HOURS}h for safety margin.`);
71
+ }
72
+ // Suggest optimal closing time
73
+ const recommendedClose = new Date(params.eventTime.getTime() - TIMING.RECOMMENDED_EVENT_BUFFER_HOURS * 60 * 60 * 1000);
74
+ timing.recommendedClose = recommendedClose;
75
+ if (recommendedClose > now && params.closingTime > recommendedClose) {
76
+ suggestions.push(`Consider closing betting at ${recommendedClose.toISOString()} ` +
77
+ `(${TIMING.RECOMMENDED_EVENT_BUFFER_HOURS}h before event)`);
78
+ }
79
+ // Check for common mistakes
80
+ if (params.question.toLowerCase().includes('will') && !params.question.includes('?')) {
81
+ suggestions.push('Consider ending your question with a question mark for clarity');
82
+ }
83
+ return {
84
+ valid: errors.length === 0,
85
+ ruleType: 'A',
86
+ errors,
87
+ warnings,
88
+ suggestions,
89
+ timing,
90
+ };
91
+ }
92
+ // ==========================================================================
93
+ // Rule B: Measurement-Period Markets
94
+ // ==========================================================================
95
+ if (params.marketType === 'measurement') {
96
+ if (!params.measurementStart) {
97
+ errors.push('Measurement-period markets require measurement_start');
98
+ return { valid: false, ruleType: 'B', errors, warnings, suggestions };
99
+ }
100
+ // CRITICAL: Betting must close BEFORE measurement starts
101
+ if (params.closingTime >= params.measurementStart) {
102
+ const overlapMs = params.closingTime.getTime() - params.measurementStart.getTime();
103
+ const overlapHours = overlapMs / (1000 * 60 * 60);
104
+ errors.push(`INVALID: Betting closes ${Math.round(overlapHours * 10) / 10}h AFTER measurement starts. ` +
105
+ `This allows information advantage! ` +
106
+ `Betting must close BEFORE measurement period begins.`);
107
+ }
108
+ // Calculate buffer before measurement
109
+ const bufferMs = params.measurementStart.getTime() - params.closingTime.getTime();
110
+ const bufferHours = bufferMs / (1000 * 60 * 60);
111
+ timing.bufferHours = Math.round(bufferHours * 10) / 10;
112
+ if (bufferHours < 1 && bufferHours > 0) {
113
+ warnings.push(`Very tight buffer (${timing.bufferHours}h) between betting close and measurement start. ` +
114
+ `Consider adding more time for late bettors.`);
115
+ }
116
+ // Measurement end validation
117
+ if (params.measurementEnd) {
118
+ if (params.measurementEnd <= params.measurementStart) {
119
+ errors.push('Measurement end must be after measurement start');
120
+ }
121
+ const periodMs = params.measurementEnd.getTime() - params.measurementStart.getTime();
122
+ const periodDays = periodMs / (1000 * 60 * 60 * 24);
123
+ timing.measurementDays = Math.round(periodDays * 10) / 10;
124
+ // UX guidance for measurement periods
125
+ if (periodDays > 30) {
126
+ warnings.push(`Very long measurement period: ${timing.measurementDays} days. ` +
127
+ `Consider shorter periods (2-7 days) for better user experience.`);
128
+ }
129
+ else if (periodDays > 7) {
130
+ warnings.push(`Long measurement period: ${timing.measurementDays} days. ` +
131
+ `Prefer 2-7 days for optimal engagement.`);
132
+ }
133
+ else if (periodDays < 1) {
134
+ suggestions.push(`Short measurement period (${Math.round(periodDays * 24)}h). ` +
135
+ `Ensure resolution can be determined within this timeframe.`);
136
+ }
137
+ }
138
+ // Suggest optimal closing time
139
+ const recommendedClose = new Date(params.measurementStart.getTime() - 2 * 60 * 60 * 1000 // 2 hours before measurement
140
+ );
141
+ timing.recommendedClose = recommendedClose;
142
+ if (recommendedClose > now && params.closingTime > recommendedClose) {
143
+ suggestions.push(`Consider closing betting at ${recommendedClose.toISOString()} ` +
144
+ `(2h before measurement period starts)`);
145
+ }
146
+ return {
147
+ valid: errors.length === 0,
148
+ ruleType: 'B',
149
+ errors,
150
+ warnings,
151
+ suggestions,
152
+ timing,
153
+ };
154
+ }
155
+ // Unknown market type
156
+ errors.push(`Unknown market type: ${params.marketType}`);
157
+ return { valid: false, ruleType: 'A', errors, warnings, suggestions };
158
+ }
159
+ // =============================================================================
160
+ // HELPER FUNCTIONS
161
+ // =============================================================================
162
+ /**
163
+ * Generate timing suggestions based on market parameters
164
+ */
165
+ export function generateTimingSuggestions(params) {
166
+ const suggestions = [];
167
+ const now = new Date();
168
+ if (params.marketType === 'event' && params.eventTime) {
169
+ // Suggest closing time for event-based markets
170
+ const optimalClose = new Date(params.eventTime.getTime() - TIMING.RECOMMENDED_EVENT_BUFFER_HOURS * 60 * 60 * 1000);
171
+ if (optimalClose > now) {
172
+ suggestions.push(`Optimal betting close: ${optimalClose.toISOString()}`);
173
+ }
174
+ // Suggest question format
175
+ if (!params.question.includes('?')) {
176
+ suggestions.push('End your question with "?" for clarity');
177
+ }
178
+ }
179
+ if (params.marketType === 'measurement' && params.measurementStart) {
180
+ // Suggest closing time for measurement markets
181
+ const optimalClose = new Date(params.measurementStart.getTime() - 2 * 60 * 60 * 1000);
182
+ if (optimalClose > now) {
183
+ suggestions.push(`Optimal betting close: ${optimalClose.toISOString()}`);
184
+ }
185
+ }
186
+ return suggestions;
187
+ }
188
+ /**
189
+ * Check if a market question follows best practices
190
+ */
191
+ export function validateQuestionFormat(question) {
192
+ const issues = [];
193
+ // Length checks
194
+ if (question.length < 10) {
195
+ issues.push('Question too short (min 10 chars)');
196
+ }
197
+ if (question.length > 200) {
198
+ issues.push('Question too long (max 200 chars)');
199
+ }
200
+ // Format checks
201
+ if (!question.trim()) {
202
+ issues.push('Question cannot be empty');
203
+ }
204
+ // Best practice checks
205
+ if (!question.includes('?') && !question.toLowerCase().startsWith('will ')) {
206
+ issues.push('Consider phrasing as a yes/no question');
207
+ }
208
+ // Check for ambiguous language
209
+ const ambiguousTerms = ['maybe', 'probably', 'might', 'could possibly'];
210
+ for (const term of ambiguousTerms) {
211
+ if (question.toLowerCase().includes(term)) {
212
+ issues.push(`Avoid ambiguous term: "${term}"`);
213
+ }
214
+ }
215
+ return {
216
+ valid: issues.length === 0,
217
+ issues,
218
+ };
219
+ }
220
+ /**
221
+ * Calculate recommended times for a market
222
+ */
223
+ export function calculateRecommendedTimes(eventOrMeasurementStart, marketType) {
224
+ const buffer = marketType === 'event'
225
+ ? TIMING.RECOMMENDED_EVENT_BUFFER_HOURS * 60 * 60 * 1000
226
+ : 2 * 60 * 60 * 1000; // 2 hours for measurement
227
+ const minBuffer = marketType === 'event'
228
+ ? TIMING.MIN_EVENT_BUFFER_HOURS * 60 * 60 * 1000
229
+ : 1 * 60 * 60 * 1000; // 1 hour for measurement
230
+ const maxBuffer = 48 * 60 * 60 * 1000; // 48 hours max
231
+ return {
232
+ recommendedClose: new Date(eventOrMeasurementStart.getTime() - buffer),
233
+ latestClose: new Date(eventOrMeasurementStart.getTime() - minBuffer),
234
+ earliestClose: new Date(eventOrMeasurementStart.getTime() - maxBuffer),
235
+ };
236
+ }
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2V0LXJ1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZhbGlkYXRpb24vbWFya2V0LXJ1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUE0QnRDLGdGQUFnRjtBQUNoRiwyQkFBMkI7QUFDM0IsZ0ZBQWdGO0FBRWhGOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxNQUEwQjtJQUM3RCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFDNUIsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBQzlCLE1BQU0sV0FBVyxHQUFhLEVBQUUsQ0FBQztJQUNqQyxNQUFNLE1BQU0sR0FBK0IsRUFBRSxDQUFDO0lBRTlDLHFDQUFxQztJQUNyQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxrQkFBa0IsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLFFBQVEsQ0FBQyxJQUFJLENBQUMsOEJBQThCLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxRQUFRLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDdkIsSUFBSSxNQUFNLENBQUMsV0FBVyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsOENBQThDO0lBQzlDLE1BQU0sY0FBYyxHQUFHLElBQUksSUFBSSxDQUFDLEdB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Q0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUN2Qyx1QkFBNkIsRUFDN0IsVUFBbUM7SUFNbkMsTUFBTSxNQUFNLEdBQUcsVUFBVSxLQUFLLE9BQU87UUFDbkMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyw4QkFBOEIsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUk7UUFDeEQsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLDBCQUEwQjtJQUVsRCxNQUFNLFNBQVMsR0FBRyxVQUFVLEtBQUssT0FBTztRQUN0QyxDQUFDLENBQUMsTUFBTSxDQUFDLHNCQUFzQixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSTtRQUNoRCxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMseUJBQXlCO0lBRWpELE1BQU0sU0FBUyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLGVBQWU7SUFFdEQsT0FBTztRQUNMLGdCQUFnQixFQUFFLElBQUksSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUN0RSxXQUFXLEVBQUUsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQ3BFLGFBQWEsRUFBRSxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsR0FBRyxTQUFTLENBQUM7S0FDdkUsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1hcmtldCBWYWxpZGF0aW9uIFJ1bGVzICh2Ni4yKVxuICpcbiAqIEltcGxlbWVudHMgdGltaW5nIHZhbGlkYXRpb24gZm9yIG1hcmtldCBjcmVhdGlvbiBiYXNlZCBvbjpcbiAqIC0gUnVsZSBBOiBFdmVudC1CYXNlZCBNYXJrZXRzIChzaW5nbGUgcG9pbnQgaW4gdGltZSlcbiAqIC0gUnVsZSBCOiBNZWFzdXJlbWVudC1QZXJpb2QgTWFya2V0cyAob3V0Y29tZSBvdmVyIHRpbWUgcmFuZ2UpXG4gKi9cblxuaW1wb3J0IHsgVElNSU5HIH0gZnJvbSAnLi4vY29uZmlnLmpzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRZUEVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgaW50ZXJmYWNlIE1hcmtldFRpbWluZ1BhcmFtcyB7XG4gIHF1ZXN0aW9uOiBzdHJpbmc7XG4gIGNsb3NpbmdUaW1lOiBEYXRlO1xuICBtYXJrZXRUeXBlOiAnZXZlbnQnIHwgJ21lYXN1cmVtZW50JztcbiAgZXZlbnRUaW1lPzogRGF0ZTtcbiAgbWVhc3VyZW1lbnRTdGFydD86IERhdGU7XG4gIG1lYXN1cmVtZW50RW5kPzogRGF0ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNYXJrZXRWYWxpZGF0aW9uIHtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIHJ1bGVUeXBlOiAnQScgfCAnQic7XG4gIGVycm9yczogc3RyaW5nW107XG4gIHdhcm5pbmdzOiBzdHJpbmdbXTtcbiAgc3VnZ2VzdGlvbnM6IHN0cmluZ1tdO1xuICB0aW1pbmc/OiB7XG4gICAgYnVmZmVySG91cnM/OiBudW1iZXI7XG4gICAgcmVjb21tZW5kZWRDbG9zZT86IERhdGU7XG4gICAgbWVhc3VyZW1lbnREYXlzPzogbnVtYmVyO1xuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gTUFJTiBWQUxJREFUSU9OIEZVTkNUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFZhbGlkYXRlIG1hcmtldCB0aW1pbmcgcGFyYW1ldGVycyBhZ2FpbnN0IHY2LjIgcnVsZXNcbiAqXG4gKiBSdWxlIEEgKEV2ZW50LUJhc2VkKTpcbiAqIC0gQmV0dGluZyBjbG9zZXMgQkVGT1JFIHRoZSBldmVudCBvY2N1cnNcbiAqIC0gTWluaW11bSAxMmggYnVmZmVyIGJldHdlZW4gY2xvc2UgYW5kIGV2ZW50XG4gKiAtIFJlY29tbWVuZGVkIDE4LTI0aCBidWZmZXIgZm9yIHNhZmV0eVxuICpcbiAqIFJ1bGUgQiAoTWVhc3VyZW1lbnQtUGVyaW9kKTpcbiAqIC0gQmV0dGluZyBtdXN0IGNsb3NlIEJFRk9SRSBtZWFzdXJlbWVudCBzdGFydHNcbiAqIC0gTWVhc3VyZW1lbnQgcGVyaW9kIHNob3VsZCBiZSB3ZWxsLWRlZmluZWRcbiAqIC0gUHJlZmVyIDItNyBkYXkgbWVhc3VyZW1lbnQgcGVyaW9kcyBmb3IgVVhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTWFya2V0VGltaW5nKHBhcmFtczogTWFya2V0VGltaW5nUGFyYW1zKTogTWFya2V0VmFsaWRhdGlvbiB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHN1Z2dlc3Rpb25zOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCB0aW1pbmc6IE1hcmtldFZhbGlkYXRpb25bJ3RpbWluZyddID0ge307XG5cbiAgLy8gQ29tbW9uIHZhbGlkYXRpb246IHF1ZXN0aW9uIGxlbmd0aFxuICBpZiAocGFyYW1zLnF1ZXN0aW9uLmxlbmd0aCA+IDIwMCkge1xuICAgIGVycm9ycy5wdXNoKGBRdWVzdGlvbiB0b28gbG9uZzogJHtwYXJhbXMucXVlc3Rpb24ubGVuZ3RofSBjaGFycyAobWF4IDIwMClgKTtcbiAgfVxuICBpZiAocGFyYW1zLnF1ZXN0aW9uLmxlbmd0aCA8IDEwKSB7XG4gICAgd2FybmluZ3MucHVzaChgUXVlc3Rpb24gbWF5IGJlIHRvbyBzaG9ydDogJHtwYXJhbXMucXVlc3Rpb24ubGVuZ3RofSBjaGFyc2ApO1xuICB9XG5cbiAgLy8gQ29tbW9uIHZhbGlkYXRpb246IGNsb3NpbmcgdGltZSBpbiBmdXR1cmVcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgaWYgKHBhcmFtcy5jbG9zaW5nVGltZSA8PSBub3cpIHtcbiAgICBlcnJvcnMucHVzaCgnQ2xvc2luZyB0aW1lIG11c3QgYmUgaW4gdGhlIGZ1dHVyZScpO1xuICB9XG5cbiAgLy8gQ29tbW9uIHZhbGlkYXRpb246IGNsb3NpbmcgdGltZSBub3QgdG9vIGZhclxuICBjb25zdCBtYXhDbG9zaW5nVGltZSA9IG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyBUSU1JTkcuTUFYX01BUktFVF9EVVJBVElPTl9EQVlTICogMjQgKiA2MCAqIDYwICogMTAwMCk7XG4gIGlmIChwYXJhbXMuY2xvc2luZ1RpbWUgPiBtYXhDbG9zaW5nVGltZSkge1xuICAgIGVycm9ycy5wdXNoKGBDbG9zaW5nIHRpbWUgdG9vIGZhciBpbiBmdXR1cmUgKG1heCAke1RJTUlORy5NQVhfTUFSS0VUX0RVUkFUSU9OX0RBWVN9IGRheXMpYCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBSdWxlIEE6IEV2ZW50LUJhc2VkIE1hcmtldHNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgaWYgKHBhcmFtcy5tYXJrZXRUeXBlID09PSAnZXZlbnQnKSB7XG4gICAgaWYgKCFwYXJhbXMuZXZlbnRUaW1lKSB7XG4gICAgICBlcnJvcnMucHVzaCgnRXZlbnQtYmFzZWQgbWFya2V0cyByZXF1aXJlIGV2ZW50X3RpbWUnKTtcbiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgcnVsZVR5cGU6ICdBJywgZXJyb3JzLCB3YXJuaW5ncywgc3VnZ2VzdGlvbnMgfTtcbiAgICB9XG5cbiAgICAvLyBFdmVudCB0aW1lIG11c3QgYmUgYWZ0ZXIgY2xvc2luZyB0aW1lXG4gICAgaWYgKHBhcmFtcy5ldmVudFRpbWUgPD0gcGFyYW1zLmNsb3NpbmdUaW1lKSB7XG4gICAgICBlcnJvcnMucHVzaCgnRXZlbnQgdGltZSBtdXN0IGJlIGFmdGVyIGNsb3NpbmcgdGltZScpO1xuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZSBidWZmZXJcbiAgICBjb25zdCBidWZmZXJNcyA9IHBhcmFtcy5ldmVudFRpbWUuZ2V0VGltZSgpIC0gcGFyYW1zLmNsb3NpbmdUaW1lLmdldFRpbWUoKTtcbiAgICBjb25zdCBidWZmZXJIb3VycyA9IGJ1ZmZlck1zIC8gKDEwMDAgKiA2MCAqIDYwKTtcbiAgICB0aW1pbmcuYnVmZmVySG91cnMgPSBNYXRoLnJvdW5kKGJ1ZmZlckhvdXJzICogMTApIC8gMTA7XG5cbiAgICAvLyBNaW5pbXVtIGJ1ZmZlciBjaGVjayAoMTIgaG91cnMpXG4gICAgaWYgKGJ1ZmZlckhvdXJzIDwgVElNSU5HLk1JTl9FVkVOVF9CVUZGRVJfSE9VUlMpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBgQnVmZmVyIHRvbyBzaG9ydDogJHt0aW1pbmcuYnVmZmVySG91cnN9aC4gYCArXG4gICAgICAgIGBNaW5pbXVtICR7VElNSU5HLk1JTl9FVkVOVF9CVUZGRVJfSE9VUlN9aCByZXF1aXJlZCBiZXR3ZWVuIGJldHRpbmcgY2xvc2UgYW5kIGV2ZW50LmBcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChidWZmZXJIb3VycyA8IDE4KSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICBgQnVmZmVyIGlzICR7dGltaW5nLmJ1ZmZlckhvdXJzfWguIGAgK1xuICAgICAgICBgUmVjb21tZW5kICR7VElNSU5HLlJFQ09NTUVOREVEX0VWRU5UX0JVRkZFUl9IT1VSU31oIGZvciBzYWZldHkgbWFyZ2luLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gU3VnZ2VzdCBvcHRpbWFsIGNsb3NpbmcgdGltZVxuICAgIGNvbnN0IHJlY29tbWVuZGVkQ2xvc2UgPSBuZXcgRGF0ZShcbiAgICAgIHBhcmFtcy5ldmVudFRpbWUuZ2V0VGltZSgpIC0gVElNSU5HLlJFQ09NTUVOREVEX0VWRU5UX0JVRkZFUl9IT1VSUyAqIDYwICogNjAgKiAxMDAwXG4gICAgKTtcbiAgICB0aW1pbmcucmVjb21tZW5kZWRDbG9zZSA9IHJlY29tbWVuZGVkQ2xvc2U7XG5cbiAgICBpZiAocmVjb21tZW5kZWRDbG9zZSA+IG5vdyAmJiBwYXJhbXMuY2xvc2luZ1RpbWUgPiByZWNvbW1lbmRlZENsb3NlKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFxuICAgICAgICBgQ29uc2lkZXIgY2xvc2luZyBiZXR0aW5nIGF0ICR7cmVjb21tZW5kZWRDbG9zZS50b0lTT1N0cmluZygpfSBgICtcbiAgICAgICAgYCgke1RJTUlORy5SRUNPTU1FTkRFRF9FVkVOVF9CVUZGRVJfSE9VUlN9aCBiZWZvcmUgZXZlbnQpYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgY29tbW9uIG1pc3Rha2VzXG4gICAgaWYgKHBhcmFtcy5xdWVzdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCd3aWxsJykgJiYgIXBhcmFtcy5xdWVzdGlvbi5pbmNsdWRlcygnPycpKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKCdDb25zaWRlciBlbmRpbmcgeW91ciBxdWVzdGlvbiB3aXRoIGEgcXVlc3Rpb24gbWFyayBmb3IgY2xhcml0eScpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICAgIHJ1bGVUeXBlOiAnQScsXG4gICAgICBlcnJvcnMsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIHN1Z2dlc3Rpb25zLFxuICAgICAgdGltaW5nLFxuICAgIH07XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBSdWxlIEI6IE1lYXN1cmVtZW50LVBlcmlvZCBNYXJrZXRzXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGlmIChwYXJhbXMubWFya2V0VHlwZSA9PT0gJ21lYXN1cmVtZW50Jykge1xuICAgIGlmICghcGFyYW1zLm1lYXN1cmVtZW50U3RhcnQpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdNZWFzdXJlbWVudC1wZXJpb2QgbWFya2V0cyByZXF1aXJlIG1lYXN1cmVtZW50X3N0YXJ0Jyk7XG4gICAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIHJ1bGVUeXBlOiAnQicsIGVycm9ycywgd2FybmluZ3MsIHN1Z2dlc3Rpb25zIH07XG4gICAgfVxuXG4gICAgLy8gQ1JJVElDQUw6IEJldHRpbmcgbXVzdCBjbG9zZSBCRUZPUkUgbWVhc3VyZW1lbnQgc3RhcnRzXG4gICAgaWYgKHBhcmFtcy5jbG9zaW5nVGltZSA+PSBwYXJhbXMubWVhc3VyZW1lbnRTdGFydCkge1xuICAgICAgY29uc3Qgb3ZlcmxhcE1zID0gcGFyYW1zLmNsb3NpbmdUaW1lLmdldFRpbWUoKSAtIHBhcmFtcy5tZWFzdXJlbWVudFN0YXJ0LmdldFRpbWUoKTtcbiAgICAgIGNvbnN0IG92ZXJsYXBIb3VycyA9IG92ZXJsYXBNcyAvICgxMDAwICogNjAgKiA2MCk7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgYElOVkFMSUQ6IEJldHRpbmcgY2xvc2VzICR7TWF0aC5yb3VuZChvdmVybGFwSG91cnMgKiAxMCkgLyAxMH1oIEFGVEVSIG1lYXN1cmVtZW50IHN0YXJ0cy4gYCArXG4gICAgICAgIGBUaGlzIGFsbG93cyBpbmZvcm1hdGlvbiBhZHZhbnRhZ2UhIGAgK1xuICAgICAgICBgQmV0dGluZyBtdXN0IGNsb3NlIEJFRk9SRSBtZWFzdXJlbWVudCBwZXJpb2QgYmVnaW5zLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQ2FsY3VsYXRlIGJ1ZmZlciBiZWZvcmUgbWVhc3VyZW1lbnRcbiAgICBjb25zdCBidWZmZXJNcyA9IHBhcmFtcy5tZWFzdXJlbWVudFN0YXJ0LmdldFRpbWUoKSAtIHBhcmFtcy5jbG9zaW5nVGltZS5nZXRUaW1lKCk7XG4gICAgY29uc3QgYnVmZmVySG91cnMgPSBidWZmZXJNcyAvICgxMDAwICogNjAgKiA2MCk7XG4gICAgdGltaW5nLmJ1ZmZlckhvdXJzID0gTWF0aC5yb3VuZChidWZmZXJIb3VycyAqIDEwKSAvIDEwO1xuXG4gICAgaWYgKGJ1ZmZlckhvdXJzIDwgMSAmJiBidWZmZXJIb3VycyA+IDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXG4gICAgICAgIGBWZXJ5IHRpZ2h0IGJ1ZmZlciAoJHt0aW1pbmcuYnVmZmVySG91cnN9aCkgYmV0d2VlbiBiZXR0aW5nIGNsb3NlIGFuZCBtZWFzdXJlbWVudCBzdGFydC4gYCArXG4gICAgICAgIGBDb25zaWRlciBhZGRpbmcgbW9yZSB0aW1lIGZvciBsYXRlIGJldHRvcnMuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBNZWFzdXJlbWVudCBlbmQgdmFsaWRhdGlvblxuICAgIGlmIChwYXJhbXMubWVhc3VyZW1lbnRFbmQpIHtcbiAgICAgIGlmIChwYXJhbXMubWVhc3VyZW1lbnRFbmQgPD0gcGFyYW1zLm1lYXN1cmVtZW50U3RhcnQpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ01lYXN1cmVtZW50IGVuZCBtdXN0IGJlIGFmdGVyIG1lYXN1cmVtZW50IHN0YXJ0Jyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBlcmlvZE1zID0gcGFyYW1zLm1lYXN1cmVtZW50RW5kLmdldFRpbWUoKSAtIHBhcmFtcy5tZWFzdXJlbWVudFN0YXJ0LmdldFRpbWUoKTtcbiAgICAgIGNvbnN0IHBlcmlvZERheXMgPSBwZXJpb2RNcyAvICgxMDAwICogNjAgKiA2MCAqIDI0KTtcbiAgICAgIHRpbWluZy5tZWFzdXJlbWVudERheXMgPSBNYXRoLnJvdW5kKHBlcmlvZERheXMgKiAxMCkgLyAxMDtcblxuICAgICAgLy8gVVggZ3VpZGFuY2UgZm9yIG1lYXN1cmVtZW50IHBlcmlvZHNcbiAgICAgIGlmIChwZXJpb2REYXlzID4gMzApIHtcbiAgICAgICAgd2FybmluZ3MucHVzaChcbiAgICAgICAgICBgVmVyeSBsb25nIG1lYXN1cmVtZW50IHBlcmlvZDogJHt0aW1pbmcubWVhc3VyZW1lbnREYXlzfSBkYXlzLiBgICtcbiAgICAgICAgICBgQ29uc2lkZXIgc2hvcnRlciBwZXJpb2RzICgyLTcgZGF5cykgZm9yIGJldHRlciB1c2VyIGV4cGVyaWVuY2UuYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChwZXJpb2REYXlzID4gNykge1xuICAgICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICAgIGBMb25nIG1lYXN1cmVtZW50IHBlcmlvZDogJHt0aW1pbmcubWVhc3VyZW1lbnREYXlzfSBkYXlzLiBgICtcbiAgICAgICAgICBgUHJlZmVyIDItNyBkYXlzIGZvciBvcHRpbWFsIGVuZ2FnZW1lbnQuYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChwZXJpb2REYXlzIDwgMSkge1xuICAgICAgICBzdWdnZXN0aW9ucy5wdXNoKFxuICAgICAgICAgIGBTaG9ydCBtZWFzdXJlbWVudCBwZXJpb2QgKCR7TWF0aC5yb3VuZChwZXJpb2REYXlzICogMjQpfWgpLiBgICtcbiAgICAgICAgICBgRW5zdXJlIHJlc29sdXRpb24gY2FuIGJlIGRldGVybWluZWQgd2l0aGluIHRoaXMgdGltZWZyYW1lLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdWdnZXN0IG9wdGltYWwgY2xvc2luZyB0aW1lXG4gICAgY29uc3QgcmVjb21tZW5kZWRDbG9zZSA9IG5ldyBEYXRlKFxuICAgICAgcGFyYW1zLm1lYXN1cmVtZW50U3RhcnQuZ2V0VGltZSgpIC0gMiAqIDYwICogNjAgKiAxMDAwIC8vIDIgaG91cnMgYmVmb3JlIG1lYXN1cmVtZW50XG4gICAgKTtcbiAgICB0aW1pbmcucmVjb21tZW5kZWRDbG9zZSA9IHJlY29tbWVuZGVkQ2xvc2U7XG5cbiAgICBpZiAocmVjb21tZW5kZWRDbG9zZSA+IG5vdyAmJiBwYXJhbXMuY2xvc2luZ1RpbWUgPiByZWNvbW1lbmRlZENsb3NlKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFxuICAgICAgICBgQ29uc2lkZXIgY2xvc2luZyBiZXR0aW5nIGF0ICR7cmVjb21tZW5kZWRDbG9zZS50b0lTT1N0cmluZygpfSBgICtcbiAgICAgICAgYCgyaCBiZWZvcmUgbWVhc3VyZW1lbnQgcGVyaW9kIHN0YXJ0cylgXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICAgIHJ1bGVUeXBlOiAnQicsXG4gICAgICBlcnJvcnMsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIHN1Z2dlc3Rpb25zLFxuICAgICAgdGltaW5nLFxuICAgIH07XG4gIH1cblxuICAvLyBVbmtub3duIG1hcmtldCB0eXBlXG4gIGVycm9ycy5wdXNoKGBVbmtub3duIG1hcmtldCB0eXBlOiAke3BhcmFtcy5tYXJrZXRUeXBlfWApO1xuICByZXR1cm4geyB2YWxpZDogZmFsc2UsIHJ1bGVUeXBlOiAnQScsIGVycm9ycywgd2FybmluZ3MsIHN1Z2dlc3Rpb25zIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEdlbmVyYXRlIHRpbWluZyBzdWdnZXN0aW9ucyBiYXNlZCBvbiBtYXJrZXQgcGFyYW1ldGVyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVUaW1pbmdTdWdnZXN0aW9ucyhwYXJhbXM6IE1hcmtldFRpbWluZ1BhcmFtcyk6IHN0cmluZ1tdIHtcbiAgY29uc3Qgc3VnZ2VzdGlvbnM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgaWYgKHBhcmFtcy5tYXJrZXRUeXBlID09PSAnZXZlbnQnICYmIHBhcmFtcy5ldmVudFRpbWUpIHtcbiAgICAvLyBTdWdnZXN0IGNsb3NpbmcgdGltZSBmb3IgZXZlbnQtYmFzZWQgbWFya2V0c1xuICAgIGNvbnN0IG9wdGltYWxDbG9zZSA9IG5ldyBEYXRlKFxuICAgICAgcGFyYW1zLmV2ZW50VGltZS5nZXRUaW1lKCkgLSBUSU1JTkcuUkVDT01NRU5ERURfRVZFTlRfQlVGRkVSX0hPVVJTICogNjAgKiA2MCAqIDEwMDBcbiAgICApO1xuXG4gICAgaWYgKG9wdGltYWxDbG9zZSA+IG5vdykge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChgT3B0aW1hbCBiZXR0aW5nIGNsb3NlOiAke29wdGltYWxDbG9zZS50b0lTT1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIC8vIFN1Z2dlc3QgcXVlc3Rpb24gZm9ybWF0XG4gICAgaWYgKCFwYXJhbXMucXVlc3Rpb24uaW5jbHVkZXMoJz8nKSkge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaCgnRW5kIHlvdXIgcXVlc3Rpb24gd2l0aCBcIj9cIiBmb3IgY2xhcml0eScpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwYXJhbXMubWFya2V0VHlwZSA9PT0gJ21lYXN1cmVtZW50JyAmJiBwYXJhbXMubWVhc3VyZW1lbnRTdGFydCkge1xuICAgIC8vIFN1Z2dlc3QgY2xvc2luZyB0aW1lIGZvciBtZWFzdXJlbWVudCBtYXJrZXRzXG4gICAgY29uc3Qgb3B0aW1hbENsb3NlID0gbmV3IERhdGUoXG4gICAgICBwYXJhbXMubWVhc3VyZW1lbnRTdGFydC5nZXRUaW1lKCkgLSAyICogNjAgKiA2MCAqIDEwMDBcbiAgICApO1xuXG4gICAgaWYgKG9wdGltYWxDbG9zZSA+IG5vdykge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChgT3B0aW1hbCBiZXR0aW5nIGNsb3NlOiAke29wdGltYWxDbG9zZS50b0lTT1N0cmluZygpfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdWdnZXN0aW9ucztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIG1hcmtldCBxdWVzdGlvbiBmb2xsb3dzIGJlc3QgcHJhY3RpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVF1ZXN0aW9uRm9ybWF0KHF1ZXN0aW9uOiBzdHJpbmcpOiB7XG4gIHZhbGlkOiBib29sZWFuO1xuICBpc3N1ZXM6IHN0cmluZ1tdO1xufSB7XG4gIGNvbnN0IGlzc3Vlczogc3RyaW5nW10gPSBbXTtcblxuICAvLyBMZW5ndGggY2hlY2tzXG4gIGlmIChxdWVzdGlvbi5sZW5ndGggPCAxMCkge1xuICAgIGlzc3Vlcy5wdXNoKCdRdWVzdGlvbiB0b28gc2hvcnQgKG1pbiAxMCBjaGFycyknKTtcbiAgfVxuICBpZiAocXVlc3Rpb24ubGVuZ3RoID4gMjAwKSB7XG4gICAgaXNzdWVzLnB1c2goJ1F1ZXN0aW9uIHRvbyBsb25nIChtYXggMjAwIGNoYXJzKScpO1xuICB9XG5cbiAgLy8gRm9ybWF0IGNoZWNrc1xuICBpZiAoIXF1ZXN0aW9uLnRyaW0oKSkge1xuICAgIGlzc3Vlcy5wdXNoKCdRdWVzdGlvbiBjYW5ub3QgYmUgZW1wdHknKTtcbiAgfVxuXG4gIC8vIEJlc3QgcHJhY3RpY2UgY2hlY2tzXG4gIGlmICghcXVlc3Rpb24uaW5jbHVkZXMoJz8nKSAmJiAhcXVlc3Rpb24udG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCd3aWxsICcpKSB7XG4gICAgaXNzdWVzLnB1c2goJ0NvbnNpZGVyIHBocmFzaW5nIGFzIGEgeWVzL25vIHF1ZXN0aW9uJyk7XG4gIH1cblxuICAvLyBDaGVjayBmb3IgYW1iaWd1b3VzIGxhbmd1YWdlXG4gIGNvbnN0IGFtYmlndW91c1Rlcm1zID0gWydtYXliZScsICdwcm9iYWJseScsICdtaWdodCcsICdjb3VsZCBwb3NzaWJseSddO1xuICBmb3IgKGNvbnN0IHRlcm0gb2YgYW1iaWd1b3VzVGVybXMpIHtcbiAgICBpZiAocXVlc3Rpb24udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSkge1xuICAgICAgaXNzdWVzLnB1c2goYEF2b2lkIGFtYmlndW91cyB0ZXJtOiBcIiR7dGVybX1cImApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmFsaWQ6IGlzc3Vlcy5sZW5ndGggPT09IDAsXG4gICAgaXNzdWVzLFxuICB9O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSByZWNvbW1lbmRlZCB0aW1lcyBmb3IgYSBtYXJrZXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJlY29tbWVuZGVkVGltZXMoXG4gIGV2ZW50T3JNZWFzdXJlbWVudFN0YXJ0OiBEYXRlLFxuICBtYXJrZXRUeXBlOiAnZXZlbnQnIHwgJ21lYXN1cmVtZW50J1xuKToge1xuICByZWNvbW1lbmRlZENsb3NlOiBEYXRlO1xuICBsYXRlc3RDbG9zZTogRGF0ZTtcbiAgZWFybGllc3RDbG9zZTogRGF0ZTtcbn0ge1xuICBjb25zdCBidWZmZXIgPSBtYXJrZXRUeXBlID09PSAnZXZlbnQnXG4gICAgPyBUSU1JTkcuUkVDT01NRU5ERURfRVZFTlRfQlVGRkVSX0hPVVJTICogNjAgKiA2MCAqIDEwMDBcbiAgICA6IDIgKiA2MCAqIDYwICogMTAwMDsgLy8gMiBob3VycyBmb3IgbWVhc3VyZW1lbnRcblxuICBjb25zdCBtaW5CdWZmZXIgPSBtYXJrZXRUeXBlID09PSAnZXZlbnQnXG4gICAgPyBUSU1JTkcuTUlOX0VWRU5UX0JVRkZFUl9IT1VSUyAqIDYwICogNjAgKiAxMDAwXG4gICAgOiAxICogNjAgKiA2MCAqIDEwMDA7IC8vIDEgaG91ciBmb3IgbWVhc3VyZW1lbnRcblxuICBjb25zdCBtYXhCdWZmZXIgPSA0OCAqIDYwICogNjAgKiAxMDAwOyAvLyA0OCBob3VycyBtYXhcblxuICByZXR1cm4ge1xuICAgIHJlY29tbWVuZGVkQ2xvc2U6IG5ldyBEYXRlKGV2ZW50T3JNZWFzdXJlbWVudFN0YXJ0LmdldFRpbWUoKSAtIGJ1ZmZlciksXG4gICAgbGF0ZXN0Q2xvc2U6IG5ldyBEYXRlKGV2ZW50T3JNZWFzdXJlbWVudFN0YXJ0LmdldFRpbWUoKSAtIG1pbkJ1ZmZlciksXG4gICAgZWFybGllc3RDbG9zZTogbmV3IERhdGUoZXZlbnRPck1lYXN1cmVtZW50U3RhcnQuZ2V0VGltZSgpIC0gbWF4QnVmZmVyKSxcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,117 @@
1
+ /**
2
+ * BAOZI PARIMUTUEL MARKET RULES v6.2
3
+ *
4
+ * STRICT ENFORCEMENT - All Lab markets MUST comply with these rules.
5
+ * AI agents creating markets through MCP MUST validate against these rules.
6
+ * Markets that don't comply will be BLOCKED from creation.
7
+ */
8
+ export declare const PARIMUTUEL_RULES: {
9
+ version: string;
10
+ /**
11
+ * RULE A: Event-Based Markets
12
+ *
13
+ * For markets about specific events (sports, elections, announcements):
14
+ * - Betting must close AT LEAST 12 hours BEFORE the event
15
+ * - Recommended buffer: 18-24 hours
16
+ * - Event time must be explicitly specified
17
+ *
18
+ * RATIONALE: Prevents late-breaking information from giving unfair advantage
19
+ *
20
+ * Examples:
21
+ * ✅ "Will Team A win vs Team B?" + event_time = game_start
22
+ * ✅ "Will Company X announce earnings above $1B?" + event_time = announcement
23
+ * ❌ "Will it rain tomorrow?" (no clear event time)
24
+ */
25
+ RULE_A: {
26
+ name: string;
27
+ minBufferHours: number;
28
+ recommendedBufferHours: number;
29
+ requirement: string;
30
+ rationale: string;
31
+ };
32
+ /**
33
+ * RULE B: Measurement-Period Markets
34
+ *
35
+ * For markets about measured values (prices, temperatures, metrics):
36
+ * - Betting must close BEFORE the measurement period starts
37
+ * - measurement_start must be explicitly specified
38
+ * - Recommended: betting closes 1-2 hours before measurement
39
+ *
40
+ * RATIONALE: Prevents anyone from betting with foreknowledge of measurements
41
+ *
42
+ * Examples:
43
+ * ✅ "Will BTC be above $100k at 00:00 UTC Feb 1?" + measurement_start = Feb 1 00:00
44
+ * ✅ "Will Tokyo have snowfall on Feb 4?" + measurement_start = Feb 4 00:00
45
+ * ❌ "Will BTC close above $100k on Feb 2?" + betting_closes = Feb 2 23:59 (VIOLATION!)
46
+ */
47
+ RULE_B: {
48
+ name: string;
49
+ requirement: string;
50
+ rationale: string;
51
+ recommendedBufferHours: number;
52
+ };
53
+ /**
54
+ * MANDATORY: Verifiable Data Source
55
+ *
56
+ * Every market question MUST specify or clearly imply a verifiable data source.
57
+ * This ensures objective resolution and prevents disputes.
58
+ *
59
+ * Examples:
60
+ * ✅ "Will BTC be above $100k? (Source: CoinGecko)"
61
+ * ✅ "Will it snow in Tokyo? (JMA official record)"
62
+ * ✅ "Will Real Madrid win?" (Implied: official UEFA result)
63
+ * ❌ "Will the economy improve?" (No verifiable source)
64
+ * ❌ "Will Claude be the best AI?" (Subjective, no source)
65
+ */
66
+ DATA_SOURCE: {
67
+ name: string;
68
+ requirement: string;
69
+ rationale: string;
70
+ };
71
+ /**
72
+ * MANDATORY: Clear YES/NO Criteria
73
+ *
74
+ * The market question must have clear, unambiguous YES/NO criteria.
75
+ * There should be no room for interpretation in the resolution.
76
+ *
77
+ * Examples:
78
+ * ✅ "Will BTC be above $100,000 at 00:00 UTC Feb 1, 2026?"
79
+ * ✅ "Will Team A score 3+ goals?"
80
+ * ❌ "Will BTC perform well?" (Subjective)
81
+ * ❌ "Will the game be exciting?" (Subjective)
82
+ */
83
+ CLEAR_CRITERIA: {
84
+ name: string;
85
+ requirement: string;
86
+ rationale: string;
87
+ };
88
+ };
89
+ export interface ParimutuelValidationResult {
90
+ valid: boolean;
91
+ blocked: boolean;
92
+ errors: string[];
93
+ warnings: string[];
94
+ ruleViolations: {
95
+ rule: string;
96
+ description: string;
97
+ severity: 'CRITICAL' | 'ERROR' | 'WARNING';
98
+ }[];
99
+ rulesChecked: string[];
100
+ }
101
+ /**
102
+ * Validate market against parimutuel rules
103
+ * Returns BLOCKED=true if market violates mandatory rules
104
+ */
105
+ export declare function validateParimutuelRules(params: {
106
+ question: string;
107
+ closingTime: Date;
108
+ marketType?: 'event' | 'measurement';
109
+ eventTime?: Date;
110
+ measurementStart?: Date;
111
+ layer: 'official' | 'lab' | 'private';
112
+ }): ParimutuelValidationResult;
113
+ export declare const PARIMUTUEL_RULES_DOCUMENTATION = "\n# BAOZI PARIMUTUEL MARKET RULES v6.2\n\n## MANDATORY FOR ALL LAB MARKETS\n\n### Rule A: Event-Based Markets\nMarkets about specific events (sports, elections, announcements):\n- Betting MUST close AT LEAST 12 hours BEFORE the event\n- You MUST specify event_time parameter\n- Recommended buffer: 18-24 hours\n\nExample:\n- Question: \"Will Team A win vs Team B?\"\n- Event time: Game start (e.g., 2026-02-15T20:00:00Z)\n- Closing time: At least 12h before (e.g., 2026-02-15T08:00:00Z)\n\n### Rule B: Measurement-Period Markets\nMarkets about measured values (prices, temperatures, metrics):\n- Betting MUST close BEFORE the measurement period starts\n- You MUST specify measurement_start parameter\n- Recommended: betting closes 1-2 hours before measurement\n\nExample:\n- Question: \"Will BTC be above $100k at 00:00 UTC Feb 1?\"\n- Measurement start: 2026-02-01T00:00:00Z\n- Closing time: BEFORE measurement (e.g., 2026-01-31T22:00:00Z)\n\n### Data Source Requirement\n- Include verifiable data source in question\n- Examples: \"(Source: CoinGecko)\", \"(Official: UEFA)\", \"(NWS Los Angeles)\"\n\n### Clear Criteria\n- Question must have unambiguous YES/NO resolution\n- Include specific thresholds: \"$100,000\", \"3+ goals\", etc.\n\n## VIOLATIONS WILL BLOCK MARKET CREATION\n\nIf you try to create a market that violates these rules, the MCP will:\n1. Return blocked: true\n2. List specific rule violations\n3. Refuse to build the transaction\n\n## CLASSIFICATION REQUIRED\n\nEvery Lab market MUST be classified as either:\n1. Event-based (provide event_time) - Rule A applies\n2. Measurement-based (provide measurement_start) - Rule B applies\n\nUnclassified markets will be BLOCKED.\n";
114
+ /**
115
+ * Get rules summary for AI agents
116
+ */
117
+ export declare function getParimutuelRulesSummary(): string;