angular-rich-text-editor
Version:
A lightweight, configurable rich-text editor component for Angular applications.
665 lines (659 loc) • 79.8 kB
JavaScript
import { Component, forwardRef, Input, ViewChild, Inject, Optional, } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, NgControl, } from '@angular/forms';
import { RTE_TOOLBAR_PRESETS, } from './rich-text-editor.constant';
import { RTE_LICENSE_KEY } from './rich-text-editor-license.token';
import { cleanToolbarString } from './utils/toolbar-cleaner';
import { EditorEventManager } from './utils/editor-event-manager';
import { patchRemoveChildIfDetached, safeCleanupFloatingPanels, } from './utils/dom-cleanup';
import { hasRequiredValidator, isTrulyEmpty } from './utils/validation-utils';
import * as i0 from "@angular/core";
import * as i1 from "./rich-text-editor.service";
import * as i2 from "@angular/common";
export class RichTextEditorComponent {
injector;
rteService;
cdr;
ngZone;
globalLicenseKey;
editorContainer;
licenseKey = '';
config = {};
rtePreset = null;
imageToolbarItems = null;
excludedToolbarItems = [];
initialContent = '';
errorMessages = {
required: 'This field is required.',
};
fileUploadHandler = () => { };
enableImageUpload = false;
enableVideoEmbed = false;
readonly = false;
eventManager = null;
editorInstance;
value = '';
ngControl = null;
changeTimer;
isDestroyed = false;
cleanupAttempts = 0;
eventListeners = [];
domCleanupTimer;
onChange = (value) => { };
onTouched = () => { };
constructor(injector, rteService, cdr, ngZone, globalLicenseKey) {
this.injector = injector;
this.rteService = rteService;
this.cdr = cdr;
this.ngZone = ngZone;
this.globalLicenseKey = globalLicenseKey;
}
ngOnInit() {
patchRemoveChildIfDetached();
this.rteService.setCurrentEditor(this);
try {
this.ngControl = this.injector.get(NgControl);
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
catch {
// Safe fallback
}
}
ngAfterViewInit() {
// Run outside Angular zone to prevent change detection issues
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
if (!this.isDestroyed) {
this.initEditor();
}
}, 100);
});
}
initEditor() {
try {
// Clean up any existing instance first
this.cleanupExistingEditor();
const fullConfig = this.prepareConfiguration();
this._applyCustomStyles();
// Create editor instance
this.editorInstance = new RichTextEditor(this.editorContainer.nativeElement, fullConfig);
// Set initial content
if (this.value) {
this.editorInstance.setHTMLCode(this.value);
}
else if (this.initialContent) {
this.value = this.initialContent;
this.editorInstance.setHTMLCode(this.initialContent);
this.ngZone.run(() => {
this.onChange(this.initialContent);
this.onTouched();
});
}
if (this.readonly && this.editorInstance?.setReadOnly) {
this.editorInstance.setReadOnly(true);
}
this.setupEventListeners();
// Update image toolbar if needed
if (this.imageToolbarItems && this.editorInstance) {
this.updateImageToolbar();
}
}
catch (error) {
console.error('[RTE] Failed to initialize editor:', error);
}
}
cleanupExistingEditor() {
if (this.editorInstance) {
try {
// Remove all event listeners first
this.removeAllEventListeners();
// Try to destroy the editor instance
if (typeof this.editorInstance.destroy === 'function') {
this.editorInstance.destroy();
}
}
catch (e) {
console.warn('[RTE] Error during editor cleanup:', e);
}
this.editorInstance = null;
}
}
setupEventListeners() {
if (!this.editorInstance)
return;
this.eventManager = new EditorEventManager(this.editorInstance);
const triggerUpdate = () => {
if (this.changeTimer)
clearTimeout(this.changeTimer);
this.changeTimer = setTimeout(() => {
if (this.isDestroyed || !this.editorInstance)
return;
this.ngZone.run(() => {
try {
const html = this.editorInstance.getHTMLCode() || '';
this.value = html;
this.onChange(html);
this.onTouched();
if (this.ngControl?.control) {
const finalValue = isTrulyEmpty(html) ? '' : html;
this.ngControl.control.setValue(finalValue, { emitEvent: false });
this.ngControl.control.updateValueAndValidity();
}
}
catch (error) {
console.error('[RTE] Error in update handler:', error);
}
});
}, 150);
};
// Change-related events
this.eventManager.attachMany(['change', 'keyup', 'paste', 'input'], triggerUpdate);
// Blur
this.eventManager.attach('blur', () => {
this.ngZone.run(() => {
this.onTouched();
const control = this.ngControl?.control;
if (control) {
control.markAsTouched();
control.updateValueAndValidity();
}
});
});
// Selection change (image toolbar)
this.eventManager.attach('selectionchange', () => {
setTimeout(() => this.checkImageSelection(), 100);
});
}
removeAllEventListeners() {
this.eventManager?.detachAll();
this.eventManager = null;
}
updateImageToolbar() {
if (this.editorInstance && this.imageToolbarItems) {
const hasSlash = this.imageToolbarItems.includes('/');
let imageToolbarString = '';
if (hasSlash) {
imageToolbarString = this.imageToolbarItems.join('');
}
else {
imageToolbarString = `{${this.imageToolbarItems.join(',')}}`;
}
if (this.editorInstance.config) {
this.editorInstance.config.controltoolbar_IMG = imageToolbarString;
}
try {
if (typeof this.editorInstance.setConfig === 'function') {
this.editorInstance.setConfig('controltoolbar_IMG', imageToolbarString);
}
}
catch (e) {
// Some versions might not have setConfig
}
}
}
checkImageSelection() {
if (!this.editorInstance || this.isDestroyed)
return;
try {
const iframe = this.editorContainer.nativeElement.querySelector('iframe');
if (iframe?.contentWindow && iframe.contentDocument) {
const selection = iframe.contentWindow.getSelection();
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const container = range.commonAncestorContainer;
let imgElement = null;
if (container.nodeType === Node.ELEMENT_NODE) {
imgElement = container.querySelector('img');
}
else if (container.parentElement) {
imgElement = container.parentElement.closest('img');
}
if (imgElement && this.imageToolbarItems) {
this.editorInstance.updateToolbar &&
this.editorInstance.updateToolbar();
}
}
}
}
catch (e) {
// Ignore errors during selection check
}
}
writeValue(value) {
const incomingValue = value ?? this.initialContent ?? '';
this.value = incomingValue;
if (this.editorInstance && !this.isDestroyed) {
const current = this.editorInstance.getHTMLCode() || '';
if (this.normalizeHtml(current) !== this.normalizeHtml(incomingValue)) {
try {
this.editorInstance.setHTMLCode(incomingValue);
}
catch (e) {
console.warn('[RTE] Error setting HTML code:', e);
}
}
}
}
normalizeHtml(html) {
return (html || '')
.replace(/\u00A0/g, '')
.replace(/\s+/g, ' ')
.replace(/<br\s*\/?>/gi, '')
.replace(/<p>\s*<\/p>/gi, '')
.trim();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setDisabledState(isDisabled) {
const shouldDisable = isDisabled || this.readonly;
if (this.editorInstance?.setReadOnly && !this.isDestroyed) {
try {
this.editorInstance.setReadOnly(shouldDisable);
}
catch (e) {
console.warn('[RTE] Error setting disabled state:', e);
}
}
}
ngOnDestroy() {
this.isDestroyed = true;
// Clear timers
if (this.changeTimer) {
clearTimeout(this.changeTimer);
}
if (this.domCleanupTimer) {
clearTimeout(this.domCleanupTimer);
}
// Clear service reference
this.rteService.clearCurrentEditor();
// Schedule cleanup outside Angular zone
this.ngZone.runOutsideAngular(() => {
// Immediate cleanup attempt
this.performCleanup();
// Schedule additional cleanup attempts
this.domCleanupTimer = setTimeout(() => {
this.performCleanup();
}, 100);
});
}
performCleanup() {
// Remove event listeners
this.removeAllEventListeners();
// Clean up editor instance
if (this.editorInstance) {
try {
if (typeof this.editorInstance.destroy === 'function') {
this.editorInstance.destroy();
}
}
catch (error) {
// Silently ignore destroy errors
}
this.editorInstance = null;
}
// Clean up floating panels with safe DOM manipulation
safeCleanupFloatingPanels();
}
validate(control) {
const value = control?.value || '';
const isEmpty = isTrulyEmpty(value);
if (hasRequiredValidator(control) && isEmpty) {
return { required: true };
}
return null;
}
fixCharacterCount() {
if (!this.editorInstance || this.isDestroyed)
return;
try {
const html = this.editorInstance.getHTMLCode() || '';
const div = document.createElement('div');
div.innerHTML = html;
const text = div.textContent || '';
const count = text.replace(/\u00A0/g, '').trim().length;
const counter = this.editorContainer.nativeElement.querySelector('.character-count');
if (counter) {
counter.textContent = `characters: ${count}`;
}
}
catch (e) {
// Ignore character count errors
}
}
getCharacterCount() {
try {
const html = this.editorInstance?.getHTMLCode?.() || '';
const div = document.createElement('div');
div.innerHTML = html;
const text = div.textContent || '';
return text.replace(/\u00A0/g, '').trim().length;
}
catch (e) {
return 0;
}
}
get showError() {
const control = this.ngControl?.control;
if (!control)
return false;
const isRequired = hasRequiredValidator(control);
return !!(control.invalid &&
control.touched &&
(isRequired || control.errors?.['required']));
}
get currentErrorMessage() {
const errors = this.ngControl?.control?.errors;
if (!errors)
return null;
const firstKey = Object.keys(errors)[0];
return this.errorMessages[firstKey] || 'Invalid field';
}
getMobileExpandedToolbar() {
const basicMobileTools = [
'paragraphs:dropdown',
'paragraphs:toggle',
'fontname:toggle',
'fontsize:toggle',
'bold',
'italic',
'underline',
'fontname',
'fontsize',
'insertlink',
'insertemoji',
'insertimage',
'insertvideo',
'removeformat',
'code',
'toggleborder',
'fullscreenenter',
'fullscreenexit',
'undo',
'redo',
'togglemore',
'fontname:dropdown',
'fontsize:dropdown',
];
if (this.rtePreset && RTE_TOOLBAR_PRESETS[this.rtePreset]) {
let fullToolbar = RTE_TOOLBAR_PRESETS[this.rtePreset];
for (const tool of basicMobileTools) {
const escapedTool = tool.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const toolPattern = new RegExp(`\\b${escapedTool}\\b`, 'g');
fullToolbar = fullToolbar.replace(toolPattern, '');
}
// 🧼 Clean both desktop/mobile exclusions
fullToolbar = this.excludeToolbarItems(fullToolbar);
return fullToolbar || this.getDefaultMobileExpandedToolbar();
}
return this.getDefaultMobileExpandedToolbar();
}
getDefaultMobileExpandedToolbar() {
return `{strike,subscript,superscript}|{forecolor,backcolor}|
{justifyleft,justifycenter,justifyright,justifyfull}|
{insertorderedlist,insertunorderedlist}|{outdent,indent}|
{inserthorizontalrule,insertblockquote,inserttable}|
{cut,copy,paste,pastetext,pasteword}|
{find,replace}|{selectall,print,spellcheck}|{help}`;
}
prepareConfiguration() {
const baseConfig = { ...this.config };
if (!baseConfig.height) {
baseConfig.height = 300;
}
const enhancedConfig = {
...baseConfig,
license: this.globalLicenseKey || this.licenseKey,
enableObjectResizing: true,
enableImageUpload: this.enableImageUpload,
enableVideoEmbed: this.enableVideoEmbed,
file_upload_handler: (file, callback, optionalIndex, optionalFiles) => {
const wrappedCallback = (url, errorCode) => {
if (!url) {
// 🚨 Upload failed — clean up placeholder
this.rteService.removeLastPlaceholderImage();
console.warn('[RTE] Upload failed. Placeholder removed.');
}
callback(url, errorCode);
};
this.fileUploadHandler(file, wrappedCallback, optionalIndex, optionalFiles);
},
content_changed_callback: () => this.fixCharacterCount(),
showFloatingToolbar: false,
forceDesktopMode: true,
disableMobileMode: true,
toolbarModeViewport: 'always-desktop',
showBottomToolbar: false,
contentCssUrl: '',
toolbarMobile: 'basic',
subtoolbar_more_mobile: this.getMobileExpandedToolbar(),
showControlBoxOnImageSelection: true,
enableImageFloatStyle: true,
contentCSSText: `
/* Custom styles */
body {
overflow-y: hidden;
padding: 0px;
margin: 0px;
}
body, table, p, div {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #414141;
font-size: 14px;
line-height: 1.6;
}
img {
cursor: default;
}
`,
};
if (this.imageToolbarItems && Array.isArray(this.imageToolbarItems)) {
const hasSlash = this.imageToolbarItems.includes('/');
let imageToolbarString = '';
if (hasSlash) {
imageToolbarString = this.imageToolbarItems.join('');
}
else {
imageToolbarString = `{${this.imageToolbarItems.join(',')}}`;
}
enhancedConfig.controltoolbar_IMG = imageToolbarString;
enhancedConfig.imagecontrolbar = imageToolbarString;
enhancedConfig.image_toolbar = imageToolbarString;
}
if (this.rtePreset && RTE_TOOLBAR_PRESETS[this.rtePreset]) {
let fullToolbar = RTE_TOOLBAR_PRESETS[this.rtePreset];
fullToolbar = this.excludeToolbarItems(fullToolbar);
enhancedConfig.toolbar = 'custom';
enhancedConfig.toolbar_custom = fullToolbar;
}
return enhancedConfig;
}
_applyCustomStyles() {
if (!document.getElementById('rte-consistent-toolbar-styles')) {
const styleEl = document.createElement('style');
styleEl.id = 'rte-consistent-toolbar-styles';
styleEl.innerHTML = `
/* Custom mobile styles to fix toolbar */
@media (max-width: 992px) {
.rte-toolbar-desktop,
.rte-toolbar {
display: flex !important;
flex-wrap: wrap !important;
overflow-x: auto !important;
white-space: nowrap !important;
-webkit-overflow-scrolling: touch !important;
max-width: 100% !important;
padding: 4px 0 !important;
}
.rte-toolbar button,
.rte-toolbar .rte-dropdown {
flex-shrink: 0 !important;
min-width: 28px !important;
height: 28px !important;
margin: 2px !important;
}
.rte-toolbar-desktop {
display: flex !important;
}
}
/* Force image toolbar visibility */
.rte-image-controlbox {
display: block !important;
opacity: 1 !important;
visibility: visible !important;
}
/* Prevent orphaned floating panels */
rte-floatpanel {
z-index: 10000;
}
`;
document.head.appendChild(styleEl);
}
}
insertContentAtCursor(content) {
if (this.readonly || this.isDestroyed)
return;
try {
if (!content || typeof content !== 'string' || !content.trim()) {
console.warn('[RTE] Empty or invalid content passed to insertContentAtCursor');
return;
}
const iframe = this.editorContainer.nativeElement.querySelector('iframe');
if (!iframe?.contentWindow || !iframe.contentDocument) {
console.warn('[RTE] iframe not found or inaccessible');
return;
}
const iframeDoc = iframe.contentDocument;
const editableBody = iframeDoc.body;
if (!editableBody?.isContentEditable) {
console.warn('[RTE] iframe body is not editable');
return;
}
editableBody.focus();
const selection = iframe.contentWindow.getSelection();
if (!selection || selection.rangeCount === 0) {
const fallbackRange = iframeDoc.createRange();
fallbackRange.selectNodeContents(editableBody);
fallbackRange.collapse(false);
selection.removeAllRanges();
selection.addRange(fallbackRange);
}
const range = selection.getRangeAt(0);
range.deleteContents();
// ✅ Append a zero-width span to keep cursor inline
const enhancedContent = `${content}<span class="caret-spot">​</span>`;
// ✅ Insert as inline HTML fragment
const fragment = range.createContextualFragment(enhancedContent);
const lastNode = fragment.lastChild;
range.insertNode(fragment);
// ✅ Move caret after the inserted zero-width span
if (lastNode && lastNode.nodeType === Node.ELEMENT_NODE) {
const newRange = iframeDoc.createRange();
newRange.setStartAfter(lastNode);
newRange.setEndAfter(lastNode);
selection.removeAllRanges();
selection.addRange(newRange);
}
// Update Angular model
const html = this.editorInstance.getHTMLCode();
this.value = html;
this.ngZone.run(() => {
this.onChange(html);
this.onTouched();
if (this.ngControl?.control) {
this.ngControl.control.setValue(html, { emitEvent: false });
this.ngControl.control.updateValueAndValidity();
}
});
}
catch (error) {
console.error('[RTE] Failed to inject content into iframe:', error);
}
}
hideAllFloatPanels() {
safeCleanupFloatingPanels();
}
excludeToolbarItems(toolbar) {
if (!toolbar || !this.excludedToolbarItems?.length)
return toolbar;
for (const tool of this.excludedToolbarItems) {
const escapedTool = tool.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const toolPattern = new RegExp(`\\b${escapedTool}\\b`, 'g');
toolbar = toolbar.replace(toolPattern, '');
}
return cleanToolbarString(toolbar);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorComponent, deps: [{ token: i0.Injector }, { token: i1.RichTextEditorService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: RTE_LICENSE_KEY, optional: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RichTextEditorComponent, selector: "lib-rich-text-editor", inputs: { licenseKey: "licenseKey", config: "config", rtePreset: "rtePreset", imageToolbarItems: "imageToolbarItems", excludedToolbarItems: "excludedToolbarItems", initialContent: "initialContent", errorMessages: "errorMessages", fileUploadHandler: "fileUploadHandler", enableImageUpload: "enableImageUpload", enableVideoEmbed: "enableVideoEmbed", readonly: "readonly" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RichTextEditorComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => RichTextEditorComponent),
multi: true,
},
], viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, static: true }], ngImport: i0, template: `
<div #editorContainer [class.invalid]="showError"></div>
<div class="error-message" *ngIf="showError">
{{ currentErrorMessage }}
</div>
`, isInline: true, styles: [":host{display:block;position:relative}.invalid{border:1px solid red}.error-message{color:red;font-size:12px;margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorComponent, decorators: [{
type: Component,
args: [{ selector: 'lib-rich-text-editor', template: `
<div #editorContainer [class.invalid]="showError"></div>
<div class="error-message" *ngIf="showError">
{{ currentErrorMessage }}
</div>
`, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RichTextEditorComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => RichTextEditorComponent),
multi: true,
},
], styles: [":host{display:block;position:relative}.invalid{border:1px solid red}.error-message{color:red;font-size:12px;margin-top:4px}\n"] }]
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1.RichTextEditorService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RTE_LICENSE_KEY]
}] }], propDecorators: { editorContainer: [{
type: ViewChild,
args: ['editorContainer', { static: true }]
}], licenseKey: [{
type: Input
}], config: [{
type: Input
}], rtePreset: [{
type: Input
}], imageToolbarItems: [{
type: Input
}], excludedToolbarItems: [{
type: Input
}], initialContent: [{
type: Input
}], errorMessages: [{
type: Input
}], fileUploadHandler: [{
type: Input
}], enableImageUpload: [{
type: Input
}], enableVideoEmbed: [{
type: Input
}], readonly: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmljaC10ZXh0LWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9yaWNoLXRleHQtZWRpdG9yL3NyYy9saWIvcmljaC10ZXh0LWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxVQUFVLEVBQ1YsS0FBSyxFQUdMLFNBQVMsRUFHVCxNQUFNLEVBQ04sUUFBUSxHQUdULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxpQkFBaUIsRUFDakIsYUFBYSxFQUNiLFNBQVMsR0FJVixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE9BQU8sRUFDTCxtQkFBbUIsR0FHcEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUNMLDBCQUEwQixFQUMxQix5QkFBeUIsR0FDMUIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7QUFvRDlFLE1BQU0sT0FBTyx1QkFBdUI7SUF5Q3hCO0lBQ0E7SUFDQTtJQUNBO0lBQ3FDO0lBMUNDLGVBQWUsQ0FBYztJQUNwRSxVQUFVLEdBQVcsRUFBRSxDQUFDO0lBQ3hCLE1BQU0sR0FBeUIsRUFBRSxDQUFDO0lBQ2xDLFNBQVMsR0FBcUIsSUFBSSxDQUFDO0lBQ25DLGlCQUFpQixHQUFrQyxJQUFJLENBQUM7SUFDeEQsb0JBQW9CLEdBQWEsRUFBRSxDQUFDO0lBQ3BDLGNBQWMsR0FBVyxFQUFFLENBQUM7SUFFNUIsYUFBYSxHQUE4QjtRQUNsRCxRQUFRLEVBQUUseUJBQXlCO0tBQ3BDLENBQUM7SUFHRixpQkFBaUIsR0FLTCxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7SUFFWixpQkFBaUIsR0FBWSxLQUFLLENBQUM7SUFDbkMsZ0JBQWdCLEdBQVksS0FBSyxDQUFDO0lBQ2xDLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFFM0IsWUFBWSxHQUE4QixJQUFJLENBQUM7SUFDL0MsY0FBYyxDQUFNO0lBQ3BCLEtBQUssR0FBVyxFQUFFLENBQUM7SUFDbkIsU0FBUyxHQUFxQixJQUFJLENBQUM7SUFDbkMsV0FBVyxDQUFNO0lBQ2pCLFdBQVcsR0FBWSxLQUFLLENBQUM7SUFDN0IsZUFBZSxHQUFXLENBQUMsQ0FBQztJQUM1QixjQUFjLEdBQTJDLEVBQUUsQ0FBQztJQUM1RCxlQUFlLENBQU07SUFFN0IsUUFBUSxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUUsR0FBRSxDQUFDLENBQUM7SUFDOUIsU0FBUyxHQUFHLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQUVyQixZQUNVLFFBQWtCLEVBQ2xCLFVBQWlDLEVBQ2pDLEdBQXNCLEVBQ3RCLE1BQWMsRUFDdUIsZ0JBQXdCO1FBSjdELGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsZUFBVSxHQUFWLFVBQVUsQ0FBdUI7UUFDakMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUN1QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQVE7SUFDcEUsQ0FBQztJQUVKLFFBQVE7UUFDTiwwQkFBMEIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM5QyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsZ0JBQWdCO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQsZUFBZTtRQUNiLDhEQUE4RDtRQUM5RCxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNqQyxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQ3RCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDcEIsQ0FBQztZQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNWLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLFVBQVU7UUFDaEIsSUFBSSxDQUFDO1lBQ0gsdUNBQXVDO1lBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBRTdCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQy9DLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBRTFCLHlCQUF5QjtZQUN6QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksY0FBYyxDQUN0QyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFDbEMsVUFBVSxDQUNYLENBQUM7WUFFRixzQkFBc0I7WUFDdEIsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzlDLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztnQkFDakMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO29CQUNuQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ25CLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QyxDQUFDO1lBRUQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFFM0IsaUNBQWlDO1lBQ2pDLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUM7Z0JBQ0gsbUNBQW1DO2dCQUNuQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztnQkFFL0IscUNBQXFDO2dCQUNyQyxJQUFJLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ3RELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2hDLENBQUM7WUFDSCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3hELENBQUM7WUFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVPLG1CQUFtQjtRQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWM7WUFBRSxPQUFPO1FBRWpDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFaEUsTUFBTSxhQUFhLEdBQUcsR0FBRyxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLFdBQVc7Z0JBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUVyRCxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pDLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjO29CQUFFLE9BQU87Z0JBRXJELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxDQUFDO3dCQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO3dCQUNyRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQzt3QkFFbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFDcEIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO3dCQUVqQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7NEJBQzVCLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7NEJBQ2xELElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzs0QkFDbEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzt3QkFDbEQsQ0FBQztvQkFDSCxDQUFDO29CQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7d0JBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDekQsQ0FBQztnQkFDSCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNWLENBQUMsQ0FBQztRQUVGLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FDMUIsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsRUFDckMsYUFBYSxDQUNkLENBQUM7UUFFRixPQUFPO1FBQ1AsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtZQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUM7Z0JBQ3hDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUN4QixPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDbkMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1lBQy9DLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyx1QkFBdUI7UUFDN0IsSUFBSSxDQUFDLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztJQUMzQixDQUFDO0lBRU8sa0JBQWtCO1FBQ3hCLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUNsRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RELElBQUksa0JBQWtCLEdBQUcsRUFBRSxDQUFDO1lBRTVCLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2Isa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN2RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sa0JBQWtCLEdBQUcsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDL0QsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7WUFDckUsQ0FBQztZQUVELElBQUksQ0FBQztnQkFDSCxJQUFJLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ3hELElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUMzQixvQkFBb0IsRUFDcEIsa0JBQWtCLENBQ25CLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLHlDQUF5QztZQUMzQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxtQkFBbUI7UUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBRXJELElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRSxJQUFJLE1BQU0sRUFBRSxhQUFhLElBQUksTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNwRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN0RCxJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUMxQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN0QyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsdUJBQXVCLENBQUM7b0JBRWhELElBQUksVUFBVSxHQUFHLElBQUksQ0FBQztvQkFDdEIsSUFBSSxTQUFTLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQzt3QkFDN0MsVUFBVSxHQUFJLFNBQXFCLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMzRCxDQUFDO3lCQUFNLElBQUksU0FBUyxDQUFDLGFBQWEsRUFBRSxDQUFDO3dCQUNuQyxVQUFVLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3RELENBQUM7b0JBRUQsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7d0JBQ3pDLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYTs0QkFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztvQkFDeEMsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsdUNBQXVDO1FBQ3pDLENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUFDLEtBQVU7UUFDbkIsTUFBTSxhQUFhLEdBQUcsS0FBSyxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM3QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUV4RCxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO2dCQUN0RSxJQUFJLENBQUM7b0JBQ0gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ2pELENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sYUFBYSxDQUFDLElBQVk7UUFDaEMsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7YUFDaEIsT0FBTyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7YUFDdEIsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7YUFDcEIsT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7YUFDM0IsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7YUFDNUIsSUFBSSxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsRUFBTztRQUN0QixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsaUJBQWlCLENBQUMsRUFBTztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsZ0JBQWdCLENBQUUsVUFBbUI7UUFDbkMsTUFBTSxhQUFhLEdBQUcsVUFBVSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDbEQsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMxRCxJQUFJLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDakQsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsT0FBTyxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFFeEIsZUFBZTtRQUNmLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELDBCQUEwQjtRQUMxQixJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFckMsd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2pDLDRCQUE0QjtZQUM1QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFdEIsdUNBQXVDO1lBQ3ZDLElBQUksQ0FBQyxlQUFlLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDckMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNWLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGNBQWM7UUFDcEIseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBRS9CLDJCQUEyQjtRQUMzQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUM7Z0JBQ0gsSUFBSSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUN0RCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNoQyxDQUFDO1lBQ0gsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsaUNBQWlDO1lBQ25DLENBQUM7WUFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO1FBRUQsc0RBQXNEO1FBQ3RELHlCQUF5QixFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVELFFBQVEsQ0FBQyxPQUF3QjtRQUMvQixNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUNuQyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFcEMsSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM3QyxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQzVCLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxpQkFBaUI7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBRXJELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ3JELE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFFckIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO1lBRXhELE1BQU0sT0FBTyxHQUNYLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxDQUFDLFdBQVcsR0FBRyxlQUFlLEtBQUssRUFBRSxDQUFDO1lBQy9DLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLGdDQUFnQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDeEQsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUVyQixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztZQUNuQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUNuRCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDWCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztRQUN4QyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRTNCLE1BQU0sVUFBVSxHQUFHLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pELE9BQU8sQ0FBQyxDQUFDLENBQ1AsT0FBTyxDQUFDLE9BQU87WUFDZixPQUFPLENBQUMsT0FBTztZQUNmLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUM3QyxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksbUJBQW1CO1FBQ3JCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQztRQUMvQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3pCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLGVBQWUsQ0FBQztJQUN6RCxDQUFDO0lBRU8sd0JBQXdCO1FBQzlCLE1BQU0sZ0JBQWdCLEdBQUc7WUFDdkIscUJBQXFCO1lBQ3JCLG1CQUFtQjtZQUNuQixpQkFBaUI7WUFDakIsaUJBQWlCO1lBQ2pCLE1BQU07WUFDTixRQUFRO1lBQ1IsV0FBVztZQUNYLFVBQVU7WUFDVixVQUFVO1lBQ1YsWUFBWTtZQUNaLGFBQWE7WUFDYixhQUFhO1lBQ2IsYUFBYTtZQUNiLGNBQWM7WUFDZCxNQUFNO1lBQ04sY0FBYztZQUNkLGlCQUFpQjtZQUNqQixnQkFBZ0I7WUFDaEIsTUFBTTtZQUNOLE1BQU07WUFDTixZQUFZO1lBQ1osbUJBQW1CO1lBQ25CLG1CQUFtQjtTQUNwQixDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksV0FBVyxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUV0RCxLQUFLLE1BQU0sSUFBSSxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2hFLE1BQU0sV0FBVyxHQUFHLElBQUksTUFBTSxDQUFDLE1BQU0sV0FBVyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzVELFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNyRCxDQUFDO1lBRUQsMENBQTBDO1lBQzFDLFdBQVcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFcEQsT0FBTyxXQUFXLElBQUksSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFDL0QsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7SUFDaEQsQ0FBQztJQUVPLCtCQUErQjtRQUNyQyxPQUFPOzs7Ozs2REFLa0QsQ0FBQztJQUM1RCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLE1BQU0sVUFBVSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFdEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN2QixVQUFVLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUMxQixDQUFDO1FBRUQsTUFBTSxjQUFjLEdBQVE7WUFDMUIsR0FBRyxVQUFVO1lBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUNqRCxvQkFBb0IsRUFBRSxJQUFJO1lBQzFCLGlCQUFpQixFQUFFLElBQUksQ0FBQyxpQkFBaUI7WUFDekMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUN2QyxtQkFBbUIsRUFBRSxDQUNuQixJQUFVLEVBQ1YsUUFBMEQsRUFDMUQsYUFBc0IsRUFDdEIsYUFBc0IsRUFDdEIsRUFBRTtnQkFDRixNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQWtCLEVBQUUsU0FBa0IsRUFBRSxFQUFFO29CQUNqRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ1QsMENBQTBDO3dCQUMxQyxJQUFJLENBQUMsVUFBVSxDQUFDLDBCQUEwQixFQUFFLENBQUM7d0JBQzdDLE9BQU8sQ0FBQyxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQztvQkFDNUQsQ0FBQztvQkFDRCxRQUFRLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUMzQixDQUFDLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLGlCQUFpQixDQUNwQixJQUFJLEVBQ0osZUFBZSxFQUNmLGFBQWEsRUFDYixhQUFhLENBQ2QsQ0FBQztZQUNKLENBQUM7WUFDRCx3QkFBd0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDeEQsbUJBQW1CLEVBQUUsS0FBSztZQUMxQixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsbUJBQW1CLEVBQUUsZ0JBQWdCO1lBQ3JDLGlCQUFpQixFQUFFLEtBQUs7WUFDeEIsYUFBYSxFQUFFLEVBQUU7WUFDakIsYUFBYSxFQUFFLE9BQU87WUFDdEIsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixFQUFFO1lBQ3ZELDhCQUE4QixFQUFFLElBQUk7WUFDcEMscUJBQXFCLEVBQUUsSUFBSTtZQUMzQixjQUFjLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWtCZjtTQUNGLENBQUM7UUFFRixJQUFJLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDcEUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0RCxJQUFJLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztZQUU1QixJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLGtCQUFrQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGtCQUFrQixHQUFHLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQy9ELENBQUM7WUFFRCxjQUFjLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7WUFDdkQsY0FBYyxDQUFDLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQztZQUNwRCxjQUFjLENBQUMsYUFBYSxHQUFHLGtCQUFrQixDQUFDO1FBQ3BELENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDMUQsSUFBSSxXQUFXLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXRELFdBQVcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFcEQsY0FBYyxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDbEMsY0FBYyxDQUFDLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDOUMsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsK0JBQStCLENBQUMsRUFBRSxDQUFDO1lBQzlELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDaEQsT0FBTyxDQUFDLEVBQUUsR0FBRywrQkFBK0IsQ0FBQztZQUM3QyxPQUFPLENBQUMsU0FBUyxHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXNDbkIsQ0FBQztZQUNGLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLENBQUM7SUFDSCxDQUFDO0lBRUkscUJBQXFCLENBQUMsT0FBZTtRQUMxQyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBRTlDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQy9ELE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztnQkFDL0UsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3RELE9BQU8sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQztnQkFDdkQsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDO1lBQ3pDLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFFcEMsSUFBSSxDQUFDLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxDQUFDO2dCQUNyQyxPQUFPLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7Z0JBQ2xELE9BQU87WUFDVCxDQUFDO1lBRUQsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRXJCLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQzlDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDL0MsYUFBYSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUIsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUM1QixTQUFTLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3BDLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUV2QixtREFBbUQ7WUFDbkQsTUFBTSxlQUFlLEdBQUcsR0FBRyxPQUFPLHlDQUF5QyxDQUFDO1lBRTVFLG1DQUFtQztZQUNuQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsd0JBQXdCLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDakUsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztZQUVwQyxLQUFLLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRTNCLGtEQUFrRDtZQUNsRCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDeEQsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUN6QyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNqQyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUUvQixTQUFTLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQzVCLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0IsQ0FBQztZQUVELHVCQUF1QjtZQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBRWxCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUVqQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7b0JBQzVCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztvQkFDNUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDbEQsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLDZDQUE2QyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO0lBRVEsa0JBQWtCO1FBQ3ZCLHlCQUF5QixFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVNLG1CQUFtQixDQUFDLE9BQWU7UUFDeEMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxNQUFNO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFFbkUsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUM3QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sV0FBVyxHQUFHLElBQUksTUFBTSxDQUFDLE1BQU0sV0FBVyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDNUQsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFFRCxPQUFPLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7d0dBM3FCVSx1QkFBdUIsc0lBNkNaLGVBQWU7NEZBN0MxQix1QkFBdUIsbWFBYnZCO1lBQ1Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQztnQkFDdEQsS0FBSyxFQUFFLElBQUk7YUFDWjtZQUNEO2dCQUNFLE9BQU8sRUFBRSxhQUFhO2dCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHVCQUF1QixDQUFDO2dCQUN0RCxLQUFLLEVBQUUsSUFBSTthQUNaO1NBQ0YsNEpBakNTOzs7OztHQUtUOzs0RkE4QlUsdUJBQXVCO2tCQXJDbkMsU0FBUzsrQkFDRSxzQkFBc0IsWUFDdEI7Ozs7O0dBS1QsYUFpQlU7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsd0JBQXdCLENBQUM7NEJBQ3RELEtBQUssRUFBRSxJQUFJO3lCQUNaO3dCQUNEOzRCQUNFLE9BQU8sRUFBRSxhQUFhOzRCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSx3QkFBd0IsQ0FBQzs0QkFDdEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7OzBCQStDRSxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGVBQWU7eUNBMUNXLGVBQWU7c0JBQTlELFNBQVM7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNyQyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtOLGlCQUFpQjtzQkFEaEIsS0FBSztnQkFRRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBBZnRlcl