@design.estate/dees-wcctools 1.3.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_bundle/bundle.js +197 -34
- package/dist_bundle/bundle.js.map +3 -3
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/wcc-dashboard.d.ts +1 -0
- package/dist_ts_web/elements/wcc-dashboard.js +60 -8
- package/dist_ts_web/elements/wcc-recording-panel.js +6 -2
- package/dist_ts_web/elements/wcc-sidebar.d.ts +3 -1
- package/dist_ts_web/elements/wcc-sidebar.js +133 -18
- package/dist_ts_web/elements/wcctools.helpers.d.ts +13 -0
- package/dist_ts_web/elements/wcctools.helpers.js +26 -1
- package/dist_ts_web/services/ffmpeg.service.d.ts +42 -0
- package/dist_ts_web/services/ffmpeg.service.js +276 -0
- package/dist_ts_web/services/mp4.service.d.ts +32 -0
- package/dist_ts_web/services/mp4.service.js +139 -0
- package/dist_ts_web/services/recorder.service.js +4 -3
- package/dist_watch/bundle.js +202 -35
- package/dist_watch/bundle.js.map +3 -3
- package/package.json +2 -2
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/wcc-dashboard.ts +76 -16
- package/ts_web/elements/wcc-recording-panel.ts +5 -1
- package/ts_web/elements/wcc-sidebar.ts +129 -18
- package/ts_web/elements/wcctools.helpers.ts +31 -0
- package/ts_web/services/recorder.service.ts +4 -2
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import type { TemplateResult } from 'lit';
|
|
2
2
|
export type TTemplateFactory = () => TemplateResult | Promise<TemplateResult>;
|
|
3
|
+
export type TDemoDefinition = TTemplateFactory | TTemplateFactory[];
|
|
3
4
|
export declare const resolveTemplateFactory: (factoryArg: TTemplateFactory) => Promise<TemplateResult>;
|
|
5
|
+
/**
|
|
6
|
+
* Get the number of demos for an element
|
|
7
|
+
*/
|
|
8
|
+
export declare const getDemoCount: (demo: TDemoDefinition) => number;
|
|
9
|
+
/**
|
|
10
|
+
* Get a specific demo by index (0-based internally, displayed as 1-based)
|
|
11
|
+
*/
|
|
12
|
+
export declare const getDemoAtIndex: (demo: TDemoDefinition, index: number) => TTemplateFactory | null;
|
|
13
|
+
/**
|
|
14
|
+
* Check if an element has multiple demos
|
|
15
|
+
*/
|
|
16
|
+
export declare const hasMultipleDemos: (demo: TDemoDefinition) => boolean;
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
export const resolveTemplateFactory = async (factoryArg) => {
|
|
2
2
|
return await Promise.resolve(factoryArg());
|
|
3
3
|
};
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Get the number of demos for an element
|
|
6
|
+
*/
|
|
7
|
+
export const getDemoCount = (demo) => {
|
|
8
|
+
if (Array.isArray(demo)) {
|
|
9
|
+
return demo.length;
|
|
10
|
+
}
|
|
11
|
+
return 1;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Get a specific demo by index (0-based internally, displayed as 1-based)
|
|
15
|
+
*/
|
|
16
|
+
export const getDemoAtIndex = (demo, index) => {
|
|
17
|
+
if (Array.isArray(demo)) {
|
|
18
|
+
return demo[index] ?? null;
|
|
19
|
+
}
|
|
20
|
+
// Single demo - only index 0 is valid
|
|
21
|
+
return index === 0 ? demo : null;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Check if an element has multiple demos
|
|
25
|
+
*/
|
|
26
|
+
export const hasMultipleDemos = (demo) => {
|
|
27
|
+
return Array.isArray(demo) && demo.length > 1;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2NjdG9vbHMuaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy93Y2N0b29scy5oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLEtBQUssRUFDekMsVUFBNEIsRUFDSCxFQUFFO0lBQzNCLE9BQU8sTUFBTSxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7QUFDN0MsQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFxQixFQUFVLEVBQUU7SUFDNUQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDeEIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQztBQUNYLENBQUMsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLENBQUMsSUFBcUIsRUFBRSxLQUFhLEVBQTJCLEVBQUU7SUFDOUYsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDeEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFDRCxzQ0FBc0M7SUFDdEMsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNuQyxDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsSUFBcUIsRUFBVyxFQUFFO0lBQ2pFLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUNoRCxDQUFDLENBQUMifQ==
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FFmpegService - Handles client-side video format conversion using FFmpeg.wasm
|
|
3
|
+
* Uses a custom worker implementation to bypass COEP/CORS issues with the standard library
|
|
4
|
+
*/
|
|
5
|
+
export interface IConversionProgress {
|
|
6
|
+
stage: 'loading' | 'converting' | 'finalizing';
|
|
7
|
+
progress: number;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export interface IConversionOptions {
|
|
11
|
+
inputBlob: Blob;
|
|
12
|
+
outputFormat: 'mp4' | 'webm';
|
|
13
|
+
onProgress?: (progress: IConversionProgress) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare class FFmpegService {
|
|
16
|
+
private worker;
|
|
17
|
+
private core;
|
|
18
|
+
private loadPromise;
|
|
19
|
+
private messageId;
|
|
20
|
+
private pendingMessages;
|
|
21
|
+
private onLog?;
|
|
22
|
+
private onProgress?;
|
|
23
|
+
/**
|
|
24
|
+
* Lazy load FFmpeg.wasm from CDN using custom worker
|
|
25
|
+
*/
|
|
26
|
+
ensureLoaded(onProgress?: (progress: IConversionProgress) => void): Promise<void>;
|
|
27
|
+
private loadFFmpeg;
|
|
28
|
+
private sendMessage;
|
|
29
|
+
/**
|
|
30
|
+
* Convert WebM blob to MP4
|
|
31
|
+
*/
|
|
32
|
+
convertToMp4(options: IConversionOptions): Promise<Blob>;
|
|
33
|
+
/**
|
|
34
|
+
* Check if FFmpeg is currently loaded
|
|
35
|
+
*/
|
|
36
|
+
get isLoaded(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Terminate FFmpeg worker to free resources
|
|
39
|
+
*/
|
|
40
|
+
terminate(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export declare function getFFmpegService(): FFmpegService;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FFmpegService - Handles client-side video format conversion using FFmpeg.wasm
|
|
3
|
+
* Uses a custom worker implementation to bypass COEP/CORS issues with the standard library
|
|
4
|
+
*/
|
|
5
|
+
export class FFmpegService {
|
|
6
|
+
worker = null;
|
|
7
|
+
core = null;
|
|
8
|
+
loadPromise = null;
|
|
9
|
+
messageId = 0;
|
|
10
|
+
pendingMessages = new Map();
|
|
11
|
+
onLog;
|
|
12
|
+
onProgress;
|
|
13
|
+
/**
|
|
14
|
+
* Lazy load FFmpeg.wasm from CDN using custom worker
|
|
15
|
+
*/
|
|
16
|
+
async ensureLoaded(onProgress) {
|
|
17
|
+
if (this.worker && this.core)
|
|
18
|
+
return;
|
|
19
|
+
if (this.loadPromise) {
|
|
20
|
+
await this.loadPromise;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.loadPromise = this.loadFFmpeg(onProgress);
|
|
24
|
+
await this.loadPromise;
|
|
25
|
+
}
|
|
26
|
+
async loadFFmpeg(onProgress) {
|
|
27
|
+
console.log('[FFmpeg] Starting FFmpeg load with custom worker...');
|
|
28
|
+
onProgress?.({
|
|
29
|
+
stage: 'loading',
|
|
30
|
+
progress: 0,
|
|
31
|
+
message: 'Loading FFmpeg library...'
|
|
32
|
+
});
|
|
33
|
+
// Import toBlobURL utility
|
|
34
|
+
const { toBlobURL } = await import('@ffmpeg/util');
|
|
35
|
+
// Use jsdelivr CDN (has proper CORS/CORP headers)
|
|
36
|
+
const coreBaseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.9/dist/umd';
|
|
37
|
+
onProgress?.({
|
|
38
|
+
stage: 'loading',
|
|
39
|
+
progress: 10,
|
|
40
|
+
message: 'Downloading FFmpeg core (~31MB)...'
|
|
41
|
+
});
|
|
42
|
+
console.log('[FFmpeg] Creating blob URLs...');
|
|
43
|
+
const coreURL = await toBlobURL(`${coreBaseURL}/ffmpeg-core.js`, 'text/javascript');
|
|
44
|
+
const wasmURL = await toBlobURL(`${coreBaseURL}/ffmpeg-core.wasm`, 'application/wasm');
|
|
45
|
+
console.log('[FFmpeg] Blob URLs created');
|
|
46
|
+
onProgress?.({
|
|
47
|
+
stage: 'loading',
|
|
48
|
+
progress: 50,
|
|
49
|
+
message: 'Initializing FFmpeg...'
|
|
50
|
+
});
|
|
51
|
+
// Create custom worker code that bypasses @ffmpeg/ffmpeg wrapper issues
|
|
52
|
+
const workerCode = `
|
|
53
|
+
let ffmpeg = null;
|
|
54
|
+
|
|
55
|
+
self.onmessage = async (e) => {
|
|
56
|
+
const { id, type, data } = e.data;
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
switch (type) {
|
|
60
|
+
case 'LOAD': {
|
|
61
|
+
const { coreURL, wasmURL } = data;
|
|
62
|
+
console.log('[FFmpeg Worker] Loading core...');
|
|
63
|
+
importScripts(coreURL);
|
|
64
|
+
|
|
65
|
+
console.log('[FFmpeg Worker] Initializing with WASM...');
|
|
66
|
+
ffmpeg = await self.createFFmpegCore({
|
|
67
|
+
mainScriptUrlOrBlob: coreURL + '#' + btoa(JSON.stringify({ wasmURL }))
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Set up logging
|
|
71
|
+
ffmpeg.setLogger((log) => {
|
|
72
|
+
console.log('[FFmpeg Worker Log]', log);
|
|
73
|
+
self.postMessage({ type: 'LOG', data: log });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Set up progress - progress is an object { ratio: 0-1, time: seconds }
|
|
77
|
+
ffmpeg.setProgress((progress) => {
|
|
78
|
+
const ratio = typeof progress === 'number' ? progress : (progress.ratio || 0);
|
|
79
|
+
console.log('[FFmpeg Worker Progress]', ratio);
|
|
80
|
+
self.postMessage({ type: 'PROGRESS', data: ratio });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
console.log('[FFmpeg Worker] Core initialized successfully');
|
|
84
|
+
console.log('[FFmpeg Worker] Available methods:', Object.keys(ffmpeg).join(', '));
|
|
85
|
+
self.postMessage({ id, type: 'LOAD', data: true });
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
case 'EXEC': {
|
|
90
|
+
const { args, timeout = -1 } = data;
|
|
91
|
+
console.log('[FFmpeg Worker] Executing:', args.join(' '));
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
ffmpeg.setTimeout(timeout);
|
|
95
|
+
ffmpeg.exec(...args);
|
|
96
|
+
const ret = ffmpeg.ret;
|
|
97
|
+
console.log('[FFmpeg Worker] Exec returned:', ret);
|
|
98
|
+
ffmpeg.reset();
|
|
99
|
+
self.postMessage({ id, type: 'EXEC', data: ret });
|
|
100
|
+
} catch (execErr) {
|
|
101
|
+
console.error('[FFmpeg Worker] Exec error:', execErr);
|
|
102
|
+
throw execErr;
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case 'WRITE_FILE': {
|
|
108
|
+
const { path, fileData } = data;
|
|
109
|
+
console.log('[FFmpeg Worker] Writing file:', path, 'size:', fileData.length);
|
|
110
|
+
ffmpeg.FS.writeFile(path, fileData);
|
|
111
|
+
self.postMessage({ id, type: 'WRITE_FILE', data: true });
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case 'READ_FILE': {
|
|
116
|
+
const { path } = data;
|
|
117
|
+
console.log('[FFmpeg Worker] Reading file:', path);
|
|
118
|
+
const fileData = ffmpeg.FS.readFile(path);
|
|
119
|
+
console.log('[FFmpeg Worker] Read file size:', fileData.length);
|
|
120
|
+
self.postMessage({ id, type: 'READ_FILE', data: fileData }, [fileData.buffer]);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
case 'DELETE_FILE': {
|
|
125
|
+
const { path } = data;
|
|
126
|
+
console.log('[FFmpeg Worker] Deleting file:', path);
|
|
127
|
+
ffmpeg.FS.unlink(path);
|
|
128
|
+
self.postMessage({ id, type: 'DELETE_FILE', data: true });
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
default:
|
|
133
|
+
throw new Error('Unknown message type: ' + type);
|
|
134
|
+
}
|
|
135
|
+
} catch (err) {
|
|
136
|
+
console.error('[FFmpeg Worker] Error:', err);
|
|
137
|
+
self.postMessage({ id, type: 'ERROR', data: err.message || String(err) });
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
`;
|
|
141
|
+
// Create worker from blob
|
|
142
|
+
const workerBlob = new Blob([workerCode], { type: 'text/javascript' });
|
|
143
|
+
const workerURL = URL.createObjectURL(workerBlob);
|
|
144
|
+
this.worker = new Worker(workerURL);
|
|
145
|
+
// Set up message handler
|
|
146
|
+
this.worker.onmessage = (e) => {
|
|
147
|
+
const { id, type, data } = e.data;
|
|
148
|
+
if (type === 'LOG') {
|
|
149
|
+
console.log('[FFmpeg Log]', data);
|
|
150
|
+
this.onLog?.(data.message || data);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (type === 'PROGRESS') {
|
|
154
|
+
this.onProgress?.(data);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const pending = this.pendingMessages.get(id);
|
|
158
|
+
if (pending) {
|
|
159
|
+
this.pendingMessages.delete(id);
|
|
160
|
+
if (type === 'ERROR') {
|
|
161
|
+
pending.reject(new Error(data));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
pending.resolve(data);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
this.worker.onerror = (e) => {
|
|
169
|
+
console.error('[FFmpeg] Worker error:', e);
|
|
170
|
+
};
|
|
171
|
+
// Initialize FFmpeg in worker
|
|
172
|
+
console.log('[FFmpeg] Initializing worker...');
|
|
173
|
+
await this.sendMessage('LOAD', { coreURL, wasmURL });
|
|
174
|
+
this.core = true; // Mark as loaded
|
|
175
|
+
console.log('[FFmpeg] Worker initialized successfully');
|
|
176
|
+
onProgress?.({
|
|
177
|
+
stage: 'loading',
|
|
178
|
+
progress: 100,
|
|
179
|
+
message: 'FFmpeg loaded successfully'
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
sendMessage(type, data) {
|
|
183
|
+
return new Promise((resolve, reject) => {
|
|
184
|
+
const id = ++this.messageId;
|
|
185
|
+
this.pendingMessages.set(id, { resolve, reject });
|
|
186
|
+
this.worker.postMessage({ id, type, data });
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Convert WebM blob to MP4
|
|
191
|
+
*/
|
|
192
|
+
async convertToMp4(options) {
|
|
193
|
+
const { inputBlob, onProgress } = options;
|
|
194
|
+
// Check file size limit (2GB)
|
|
195
|
+
const MAX_FILE_SIZE = 2 * 1024 * 1024 * 1024;
|
|
196
|
+
if (inputBlob.size > MAX_FILE_SIZE) {
|
|
197
|
+
throw new Error('File size exceeds 2GB limit for conversion');
|
|
198
|
+
}
|
|
199
|
+
// Set up progress callback
|
|
200
|
+
this.onProgress = (progress) => {
|
|
201
|
+
const percent = Math.round((progress || 0) * 100);
|
|
202
|
+
console.log('[FFmpeg] Conversion progress:', percent + '%');
|
|
203
|
+
onProgress?.({
|
|
204
|
+
stage: 'converting',
|
|
205
|
+
progress: percent,
|
|
206
|
+
message: `Converting video... ${percent}%`
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
await this.ensureLoaded(onProgress);
|
|
210
|
+
onProgress?.({
|
|
211
|
+
stage: 'converting',
|
|
212
|
+
progress: 0,
|
|
213
|
+
message: 'Preparing video for conversion...'
|
|
214
|
+
});
|
|
215
|
+
// Read input blob as Uint8Array
|
|
216
|
+
const inputData = new Uint8Array(await inputBlob.arrayBuffer());
|
|
217
|
+
// Write input file to virtual filesystem
|
|
218
|
+
await this.sendMessage('WRITE_FILE', { path: 'input.webm', fileData: inputData });
|
|
219
|
+
// Execute conversion with optimized settings for web playback
|
|
220
|
+
await this.sendMessage('EXEC', {
|
|
221
|
+
args: [
|
|
222
|
+
'-i', 'input.webm',
|
|
223
|
+
'-c:v', 'libx264',
|
|
224
|
+
'-preset', 'fast',
|
|
225
|
+
'-crf', '23',
|
|
226
|
+
'-c:a', 'aac',
|
|
227
|
+
'-b:a', '128k',
|
|
228
|
+
'-movflags', '+faststart',
|
|
229
|
+
'output.mp4'
|
|
230
|
+
]
|
|
231
|
+
});
|
|
232
|
+
onProgress?.({
|
|
233
|
+
stage: 'finalizing',
|
|
234
|
+
progress: 95,
|
|
235
|
+
message: 'Finalizing video...'
|
|
236
|
+
});
|
|
237
|
+
// Read output file
|
|
238
|
+
const outputData = await this.sendMessage('READ_FILE', { path: 'output.mp4' });
|
|
239
|
+
// Clean up virtual filesystem
|
|
240
|
+
await this.sendMessage('DELETE_FILE', { path: 'input.webm' });
|
|
241
|
+
await this.sendMessage('DELETE_FILE', { path: 'output.mp4' });
|
|
242
|
+
onProgress?.({
|
|
243
|
+
stage: 'finalizing',
|
|
244
|
+
progress: 100,
|
|
245
|
+
message: 'Conversion complete!'
|
|
246
|
+
});
|
|
247
|
+
return new Blob([new Uint8Array(outputData)], { type: 'video/mp4' });
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Check if FFmpeg is currently loaded
|
|
251
|
+
*/
|
|
252
|
+
get isLoaded() {
|
|
253
|
+
return this.worker !== null && this.core !== null;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Terminate FFmpeg worker to free resources
|
|
257
|
+
*/
|
|
258
|
+
async terminate() {
|
|
259
|
+
if (this.worker) {
|
|
260
|
+
this.worker.terminate();
|
|
261
|
+
this.worker = null;
|
|
262
|
+
this.core = null;
|
|
263
|
+
this.loadPromise = null;
|
|
264
|
+
this.pendingMessages.clear();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Singleton instance for caching
|
|
269
|
+
let ffmpegServiceInstance = null;
|
|
270
|
+
export function getFFmpegService() {
|
|
271
|
+
if (!ffmpegServiceInstance) {
|
|
272
|
+
ffmpegServiceInstance = new FFmpegService();
|
|
273
|
+
}
|
|
274
|
+
return ffmpegServiceInstance;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmZtcGVnLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvc2VydmljZXMvZmZtcGVnLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBdUJILE1BQU0sT0FBTyxhQUFhO0lBQ2hCLE1BQU0sR0FBa0IsSUFBSSxDQUFDO0lBQzdCLElBQUksR0FBUSxJQUFJLENBQUM7SUFDakIsV0FBVyxHQUF5QixJQUFJLENBQUM7SUFDekMsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLGVBQWUsR0FBeUQsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNsRixLQUFLLENBQTZCO0lBQ2xDLFVBQVUsQ0FBOEI7SUFFaEQ7O09BRUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLFVBQW9EO1FBQ3JFLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFFckMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUN6QixDQUFDO0lBRU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxVQUFvRDtRQUMzRSxPQUFPLENBQUMsR0FBRyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7UUFFbkUsVUFBVSxFQUFFLENBQUM7WUFDWCxLQUFLLEVBQUUsU0FBUztZQUNoQixRQUFRLEVBQUUsQ0FBQztZQUNYLE9BQU8sRUFBRSwyQkFBMkI7U0FDckMsQ0FBQyxDQUFDO1FBRUgsMkJBQTJCO1FBQzNCLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUVuRCxrREFBa0Q7UUFDbEQsTUFB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
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MP4Service - Handles client-side video format conversion using Mediabunny
|
|
3
|
+
* Uses WebCodecs API for hardware-accelerated encoding (10-50x faster than FFmpeg.wasm)
|
|
4
|
+
* @see https://mediabunny.dev/
|
|
5
|
+
*/
|
|
6
|
+
export interface IConversionProgress {
|
|
7
|
+
stage: 'loading' | 'converting' | 'finalizing';
|
|
8
|
+
progress: number;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export interface IConversionOptions {
|
|
12
|
+
inputBlob: Blob;
|
|
13
|
+
outputFormat: 'mp4' | 'webm';
|
|
14
|
+
onProgress?: (progress: IConversionProgress) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class MP4Service {
|
|
17
|
+
/**
|
|
18
|
+
* Check if WebCodecs is supported in this browser
|
|
19
|
+
*/
|
|
20
|
+
static isSupported(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if H.264 encoding is actually available (not just API presence)
|
|
23
|
+
*/
|
|
24
|
+
static isEncodingSupported(): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Convert WebM blob to MP4 using Mediabunny (hardware accelerated via WebCodecs)
|
|
27
|
+
*/
|
|
28
|
+
convertToMp4(options: IConversionOptions): Promise<Blob>;
|
|
29
|
+
}
|
|
30
|
+
export declare function getMP4Service(): MP4Service;
|
|
31
|
+
export { MP4Service as FFmpegService };
|
|
32
|
+
export { getMP4Service as getFFmpegService };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MP4Service - Handles client-side video format conversion using Mediabunny
|
|
3
|
+
* Uses WebCodecs API for hardware-accelerated encoding (10-50x faster than FFmpeg.wasm)
|
|
4
|
+
* @see https://mediabunny.dev/
|
|
5
|
+
*/
|
|
6
|
+
import { Conversion, Input, Output, ALL_FORMATS, BlobSource, Mp4OutputFormat, BufferTarget, } from 'mediabunny';
|
|
7
|
+
export class MP4Service {
|
|
8
|
+
/**
|
|
9
|
+
* Check if WebCodecs is supported in this browser
|
|
10
|
+
*/
|
|
11
|
+
static isSupported() {
|
|
12
|
+
return (typeof VideoEncoder !== 'undefined' &&
|
|
13
|
+
typeof VideoDecoder !== 'undefined');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if H.264 encoding is actually available (not just API presence)
|
|
17
|
+
*/
|
|
18
|
+
static async isEncodingSupported() {
|
|
19
|
+
if (!this.isSupported())
|
|
20
|
+
return false;
|
|
21
|
+
try {
|
|
22
|
+
const result = await VideoEncoder.isConfigSupported({
|
|
23
|
+
codec: 'avc1.42E01E', // H.264 Baseline
|
|
24
|
+
width: 640,
|
|
25
|
+
height: 480,
|
|
26
|
+
bitrate: 1_000_000,
|
|
27
|
+
framerate: 30,
|
|
28
|
+
});
|
|
29
|
+
return result.supported === true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Convert WebM blob to MP4 using Mediabunny (hardware accelerated via WebCodecs)
|
|
37
|
+
*/
|
|
38
|
+
async convertToMp4(options) {
|
|
39
|
+
const { inputBlob, onProgress } = options;
|
|
40
|
+
if (!MP4Service.isSupported()) {
|
|
41
|
+
throw new Error('WebCodecs API not supported in this browser. Please use a modern browser (Chrome 94+, Edge 94+, Safari 16.4+, Firefox 130+).');
|
|
42
|
+
}
|
|
43
|
+
// Check if encoding is actually available (not just API presence)
|
|
44
|
+
const encodingSupported = await MP4Service.isEncodingSupported();
|
|
45
|
+
if (!encodingSupported) {
|
|
46
|
+
throw new Error('Video encoding is not available in your browser. This may be due to missing hardware encoder support or browser configuration. Try using Chrome with hardware acceleration enabled.');
|
|
47
|
+
}
|
|
48
|
+
onProgress?.({
|
|
49
|
+
stage: 'loading',
|
|
50
|
+
progress: 0,
|
|
51
|
+
message: 'Preparing video for conversion...'
|
|
52
|
+
});
|
|
53
|
+
try {
|
|
54
|
+
// Create input from WebM blob
|
|
55
|
+
const input = new Input({
|
|
56
|
+
source: new BlobSource(inputBlob),
|
|
57
|
+
formats: ALL_FORMATS,
|
|
58
|
+
});
|
|
59
|
+
onProgress?.({
|
|
60
|
+
stage: 'loading',
|
|
61
|
+
progress: 20,
|
|
62
|
+
message: 'Analyzing input video...'
|
|
63
|
+
});
|
|
64
|
+
// Create output for MP4
|
|
65
|
+
const target = new BufferTarget();
|
|
66
|
+
const output = new Output({
|
|
67
|
+
format: new Mp4OutputFormat(),
|
|
68
|
+
target,
|
|
69
|
+
});
|
|
70
|
+
onProgress?.({
|
|
71
|
+
stage: 'converting',
|
|
72
|
+
progress: 30,
|
|
73
|
+
message: 'Starting conversion (hardware accelerated)...'
|
|
74
|
+
});
|
|
75
|
+
// Initialize conversion - let mediabunny auto-detect codecs first
|
|
76
|
+
const conversion = await Conversion.init({
|
|
77
|
+
input,
|
|
78
|
+
output,
|
|
79
|
+
});
|
|
80
|
+
// Debug: log any issues with the conversion
|
|
81
|
+
if (!conversion.isValid) {
|
|
82
|
+
console.error('[MP4Service] Conversion invalid. Discarded tracks:', conversion.discardedTracks);
|
|
83
|
+
conversion.discardedTracks.forEach((track) => {
|
|
84
|
+
console.error('[MP4Service] Track discarded:', track.reason, track);
|
|
85
|
+
});
|
|
86
|
+
throw new Error(`Conversion invalid: tracks discarded due to codec issues. Check browser console for details.`);
|
|
87
|
+
}
|
|
88
|
+
console.log('[MP4Service] Conversion valid, utilized tracks:', conversion.utilizedTracks);
|
|
89
|
+
// Execute conversion with progress tracking
|
|
90
|
+
let lastProgress = 30;
|
|
91
|
+
const progressInterval = setInterval(() => {
|
|
92
|
+
// Increment progress gradually during conversion
|
|
93
|
+
if (lastProgress < 90) {
|
|
94
|
+
lastProgress += 5;
|
|
95
|
+
onProgress?.({
|
|
96
|
+
stage: 'converting',
|
|
97
|
+
progress: lastProgress,
|
|
98
|
+
message: `Converting... ${lastProgress}%`
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}, 500);
|
|
102
|
+
try {
|
|
103
|
+
await conversion.execute();
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
clearInterval(progressInterval);
|
|
107
|
+
}
|
|
108
|
+
onProgress?.({
|
|
109
|
+
stage: 'finalizing',
|
|
110
|
+
progress: 95,
|
|
111
|
+
message: 'Finalizing MP4 file...'
|
|
112
|
+
});
|
|
113
|
+
// Get the output buffer
|
|
114
|
+
const mp4Buffer = target.buffer;
|
|
115
|
+
onProgress?.({
|
|
116
|
+
stage: 'finalizing',
|
|
117
|
+
progress: 100,
|
|
118
|
+
message: 'Conversion complete!'
|
|
119
|
+
});
|
|
120
|
+
return new Blob([mp4Buffer], { type: 'video/mp4' });
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error('[MP4Service] Conversion failed:', error);
|
|
124
|
+
throw new Error(`Video conversion failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Singleton instance
|
|
129
|
+
let mp4ServiceInstance = null;
|
|
130
|
+
export function getMP4Service() {
|
|
131
|
+
if (!mp4ServiceInstance) {
|
|
132
|
+
mp4ServiceInstance = new MP4Service();
|
|
133
|
+
}
|
|
134
|
+
return mp4ServiceInstance;
|
|
135
|
+
}
|
|
136
|
+
// Legacy aliases for compatibility with existing code
|
|
137
|
+
export { MP4Service as FFmpegService };
|
|
138
|
+
export { getMP4Service as getFFmpegService };
|
|
139
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXA0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvc2VydmljZXMvbXA0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFDTCxVQUFVLEVBQ1YsS0FBSyxFQUNMLE1BQU0sRUFDTixXQUFXLEVBQ1gsVUFBVSxFQUNWLGVBQWUsRUFDZixZQUFZLEdBQ2IsTUFBTSxZQUFZLENBQUM7QUFjcEIsTUFBTSxPQUFPLFVBQVU7SUFDckI7O09BRUc7SUFDSCxNQUFNLENBQUMsV0FBVztRQUNoQixPQUFPLENBQ0wsT0FBTyxZQUFZLEtBQUssV0FBVztZQUNuQyxPQUFPLFlBQVksS0FBSyxXQUFXLENBQ3BDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRXRDLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sWUFBWSxDQUFDLGlCQUFpQixDQUFDO2dCQUNsRCxLQUFLLEVBQUUsYUFBYSxFQUFFLGlCQUFpQjtnQkFDdkMsS0FBSyxFQUFFLEdBQUc7Z0JBQ1YsTUFBTSxFQUFFLEdBQUc7Z0JBQ1gsT0FBTyxFQUFFLFNBQVM7Z0JBQ2xCLFNBQVMsRUFBRSxFQUFFO2FBQ2QsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxNQUFNLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQztRQUNuQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUEyQjtRQUM1QyxNQUFNLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUUxQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdB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
|
|
@@ -189,9 +189,10 @@ export class RecorderService {
|
|
|
189
189
|
this.durationInterval = null;
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
handleRecordingComplete() {
|
|
192
|
+
async handleRecordingComplete() {
|
|
193
193
|
// Create blob from recorded chunks
|
|
194
|
-
|
|
194
|
+
const blob = new Blob(this.recordedChunks, { type: 'video/webm' });
|
|
195
|
+
this._recordedBlob = blob;
|
|
195
196
|
// Stop all tracks
|
|
196
197
|
if (this.currentStream) {
|
|
197
198
|
this.currentStream.getTracks().forEach(track => track.stop());
|
|
@@ -303,4 +304,4 @@ export class RecorderService {
|
|
|
303
304
|
}
|
|
304
305
|
}
|
|
305
306
|
}
|
|
306
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9zZXJ2aWNlcy9yZWNvcmRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBZ0JILE1BQU0sT0FBTyxlQUFlO0lBQzFCLGtCQUFrQjtJQUNWLGFBQWEsR0FBeUIsSUFBSSxDQUFDO0lBQzNDLGNBQWMsR0FBVyxFQUFFLENBQUM7SUFDNUIsZ0JBQWdCLEdBQWtCLElBQUksQ0FBQztJQUN2QyxTQUFTLEdBQVcsQ0FBQyxDQUFDO0lBQ3RCLGFBQWEsR0FBZ0IsSUFBSSxDQUFDO0lBQ2xDLFlBQVksR0FBWSxLQUFLLENBQUM7SUFFdEMseUJBQXlCO0lBQ2pCLFlBQVksR0FBd0IsSUFBSSxDQUFDO0lBQ3pDLGFBQWEsR0FBd0IsSUFBSSxDQUFDO0lBQzFDLHVCQUF1QixHQUFrQixJQUFJLENBQUM7SUFDOUMsZ0JBQWdCLEdBQXVCLElBQUksQ0FBQztJQUVwRCwyQkFBMkI7SUFDbkIsYUFBYSxHQUF1QixJQUFJLENBQUM7SUFFakQsa0JBQWtCO0lBQ1YsTUFBTSxHQUFvQixFQUFFLENBQUM7SUFFckMsWUFBWSxNQUF3QjtRQUNsQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRCxpQkFBaUI7SUFDakIsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLFNBQVMsQ0FBQyxNQUF1QjtRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxJQUFJ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
|
|
307
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9zZXJ2aWNlcy9yZWNvcmRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBZ0JILE1BQU0sT0FBTyxlQUFlO0lBQzFCLGtCQUFrQjtJQUNWLGFBQWEsR0FBeUIsSUFBSSxDQUFDO0lBQzNDLGNBQWMsR0FBVyxFQUFFLENBQUM7SUFDNUIsZ0JBQWdCLEdBQWtCLElBQUksQ0FBQztJQUN2QyxTQUFTLEdBQVcsQ0FBQyxDQUFDO0lBQ3RCLGFBQWEsR0FBZ0IsSUFBSSxDQUFDO0lBQ2xDLFlBQVksR0FBWSxLQUFLLENBQUM7SUFFdEMseUJBQXlCO0lBQ2pCLFlBQVksR0FBd0IsSUFBSSxDQUFDO0lBQ3pDLGFBQWEsR0FBd0IsSUFBSSxDQUFDO0lBQzFDLHVCQUF1QixHQUFrQixJQUFJLENBQUM7SUFDOUMsZ0JBQWdCLEdBQXVCLElBQUksQ0FBQztJQUVwRCwyQkFBMkI7SUFDbkIsYUFBYSxHQUF1QixJQUFJLENBQUM7SUFFakQsa0JBQWtCO0lBQ1YsTUFBTSxHQUFvQixFQUFFLENBQUM7SUFFckMsWUFBWSxNQUF3QjtRQUNsQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRCxpQkFBaUI7SUFDakIsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLFNBQVMsQ0FBQyxNQUF1QjtRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVELGtFQUFrRTtJQUVsRSxLQUFLLENBQUMsZUFBZSxDQUFDLG9CQUE2QixLQUFLO1FBQ3RELElBQUksQ0FBQztZQUNILElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDdEIsbURBQW1EO2dCQUNuRCxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxTQUFTLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDaEUsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxRQUFnQjtRQUN6QyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUUzQixJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFFdEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQztnQkFDdkQsS0FBSyxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFO2FBQ3pDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUM7WUFDL0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hELElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQztZQUNqQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUVuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFdkUsSUFBSSxDQUFDLHVCQUF1QixHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO2dCQUNyRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDbkQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO29CQUNyRSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztvQkFDbkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQyxDQUFDO1lBQ0gsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ1QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxDQUFDO0lBQ0gsQ0FBQztJQUVELG1CQUFtQjtRQUNqQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pDLGFBQWEsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDO1FBQ3RDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztJQUM1QixDQUFDO0lBRUQsOERBQThEO0lBRTlELEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBMEI7UUFDN0MsSUFBSSxDQUFDO1lBQ0gseUNBQXlDO1lBQ3pDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBRTNCLGlDQUFpQztZQUNqQyxNQUFNLG1CQUFtQixHQUE4QjtnQkFDckQsS0FBSyxFQUFFO29CQUNMLGNBQWMsRUFBRSxPQUFPLENBQUMsSUFBSSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO2lCQUMzQztnQkFDMUIsS0FBSyxFQUFFLEtBQUs7YUFDYixDQUFDO1lBRUYsOENBQThDO1lBQzlDLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDL0IsbUJBQTJCLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQ3ZELENBQUM7WUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFFdEYsOEVBQThFO1lBQzlFLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUMzRCxJQUFJLENBQUM7b0JBQ0gsSUFBSSxZQUFZLElBQUksTUFBTSxFQUFFLENBQUM7d0JBQzNCLE1BQU0sVUFBVSxHQUFHLE1BQU8sTUFBYyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO3dCQUN6RixNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDO3dCQUNsRCxNQUFPLFVBQWtCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUMvQyxDQUFDO2dCQUNILENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN4RSxDQUFDO1lBQ0gsQ0FBQztZQUVELHNDQUFzQztZQUN0QyxJQUFJLGNBQWMsR0FBRyxXQUFXLENBQUM7WUFDakMsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQzFCLElBQUksQ0FBQztvQkFDSCxNQUFNLFdBQVcsR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDO3dCQUM1RCxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFO3FCQUN0RCxDQUFDLENBQUM7b0JBQ0gsY0FBYyxHQUFHLElBQUksV0FBVyxDQUFDO3dCQUMvQixHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUU7d0JBQy9CLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRTtxQkFDaEMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQUMsT0FBTyxVQUFVLEVBQUUsQ0FBQztvQkFDcEIsT0FBTyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDbkQsQ0FBQztZQUNILENBQUM7WUFFRCwyQkFBMkI7WUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFjLENBQUM7WUFFcEMsdUJBQXVCO1lBQ3ZCLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQUM7Z0JBQ3JFLENBQUMsQ0FBQyx1QkFBdUI7Z0JBQ3pCLENBQUMsQ0FBQyxZQUFZLENBQUM7WUFFakIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxjQUFjLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1lBRXpCLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ3BCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbkMsQ0FBQztZQUNILENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBRWpFLG9EQUFvRDtZQUNwRCxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRTtnQkFDN0MsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ3RCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztvQkFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO2dCQUNoQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDO1lBRUYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7WUFFN0QsdUJBQXVCO1lBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRTtnQkFDOUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pELENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUVULElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQWMsQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRCxhQUFhO1FBQ1gsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ2xFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsdUJBQXVCO1FBQ25DLG1DQUFtQztRQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFbkUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFFMUIsa0JBQWtCO1FBQ2xCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELDBEQUEwRDtJQUUxRCxLQUFLLENBQUMsa0JBQWtCLENBQ3RCLFlBQThCLEVBQzlCLFNBQWlCLEVBQ2pCLE9BQWU7UUFFZixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLHVDQUF1QztZQUN2QyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUM7WUFDL0MsTUFBTSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsV0FBVyxJQUFJLEdBQUcsQ0FBQztZQUNoRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXBDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVCxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDO2dCQUNsRCxPQUFPO1lBQ1QsQ0FBQztZQUVELGlDQUFpQztZQUNqQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRTlDLDBDQUEwQztZQUMxQyxJQUFJLGNBQTJCLENBQUM7WUFFaEMsSUFBSSxDQUFDO2dCQUNILGdEQUFnRDtnQkFDaEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLHdCQUF3QixDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztnQkFDNUQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7Z0JBRW5FLDZEQUE2RDtnQkFDN0QsY0FBYyxHQUFHLElBQUksV0FBVyxDQUFDO29CQUMvQixHQUFHLFlBQVksQ0FBQyxjQUFjLEVBQUU7b0JBQ2hDLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUU7aUJBQ3ZDLENBQUMsQ0FBQztnQkFFSCw2QkFBNkI7Z0JBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRTtvQkFDbkIsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNuQixDQUFDLENBQUM7Z0JBRUYsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDcEgsQ0FBQztZQUFDLE9BQU8sVUFBVSxFQUFFLENBQUM7Z0JBQ3BCLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBQzNFLGNBQWMsR0FBRyxZQUFZLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3JILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxtQkFBbUIsQ0FDekIsS0FBdUIsRUFDdkIsTUFBeUIsRUFDekIsR0FBNkIsRUFDN0IsTUFBbUIsRUFDbkIsU0FBaUIsRUFDakIsT0FBZSxFQUNmLE9BQW1CLEVBQ25CLE9BQTZCLEVBQzdCLE1BQThCO1FBRTlCLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQUM7WUFDckUsQ0FBQyxDQUFDLHVCQUF1QjtZQUN6QixDQUFDLENBQUMsWUFBWSxDQUFDO1FBRWpCLE1BQU0sUUFBUSxHQUFHLElBQUksYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDekQsTUFBTSxNQUFNLEdBQVcsRUFBRSxDQUFDO1FBRTFCLFFBQVEsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMvQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsUUFBUSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUU7WUFDckIsT0FBTyxFQUFFLENBQUM7WUFDVixPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUM7UUFFRixRQUFRLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDdkIsT0FBTyxFQUFFLENBQUM7WUFDVixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUM7UUFFRixxQkFBcUI7UUFDckIsS0FBSyxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFFOUIsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLEVBQUU7WUFDcEIsa0JBQWtCO1lBQ2xCLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFcEIsZ0JBQWdCO1lBQ2hCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUViLHdCQUF3QjtZQUN4QixNQUFNLFNBQVMsR0FBRyxHQUFHLEVBQUU7Z0JBQ3JCLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxPQUFPLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDZCxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztvQkFFdEIsc0VBQXNFO29CQUN0RSxVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNkLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQzs0QkFDbkMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO3dCQUNsQixDQUFDO29CQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDUixPQUFPO2dCQUNULENBQUM7Z0JBRUQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEQscUJBQXFCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbkMsQ0FBQyxDQUFDO1lBRUYsU0FBUyxFQUFFLENBQUM7UUFDZCxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQsb0RBQW9EO0lBRXBELEtBQUs7UUFDSCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUM1QixDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFYixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
|