webdriverio-automation
Version:
WebdriverIO-Automation android ios project
530 lines (484 loc) • 85.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
require("source-map-support/register");
var _chai = _interopRequireDefault(require("chai"));
var _path = _interopRequireDefault(require("path"));
var _chaiAsPromised = _interopRequireDefault(require("chai-as-promised"));
var _sinon = _interopRequireDefault(require("sinon"));
var _ = require("../../..");
var _find = require("../../../lib/basedriver/commands/find");
var _appiumSupport = require("appium-support");
const should = _chai.default.should();
_chai.default.use(_chaiAsPromised.default);
class TestDriver extends _.BaseDriver {
async getWindowSize() {}
async getScreenshot() {}
}
const CUSTOM_FIND_MODULE = _path.default.resolve(__dirname, '..', '..', '..', '..', 'test', 'basedriver', 'fixtures', 'custom-element-finder');
const BAD_CUSTOM_FIND_MODULE = _path.default.resolve(__dirname, '..', '..', '..', '..', 'test', 'basedriver', 'fixtures', 'custom-element-finder-bad');
const TINY_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N0NDMDM4MDM4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6N0NDMDM4MDQ4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3Q0MwMzgwMTg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3Q0MwMzgwMjg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpdvJjQAAAAlSURBVHjaJInBEQAACIKw/Xe2Ul5wYBtwmJqkk4+zfvUQVoABAEg0EfrZwc0hAAAAAElFTkSuQmCC';
const TINY_PNG_DIMS = [4, 4];
describe('finding elements by image', function () {
describe('findElement', function () {
it('should use a different special method to find element by image', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'findByImage').returns(true);
_sinon.default.stub(d, 'findElOrElsWithProcessing').returns(false);
await d.findElement(_find.IMAGE_STRATEGY, 'foo').should.eventually.be.true;
await d.findElements(_find.IMAGE_STRATEGY, 'foo').should.eventually.be.true;
});
it('should not be able to find image element from any other element', async function () {
const d = new TestDriver();
await d.findElementFromElement(_find.IMAGE_STRATEGY, 'foo', 'elId').should.eventually.be.rejectedWith(/Locator Strategy.+is not supported/);
await d.findElementsFromElement(_find.IMAGE_STRATEGY, 'foo', 'elId').should.eventually.be.rejectedWith(/Locator Strategy.+is not supported/);
});
});
describe('findByImage', function () {
const rect = {
x: 10,
y: 20,
width: 30,
height: 40
};
const size = {
width: 100,
height: 200
};
const screenshot = 'iVBORfoo';
const template = 'iVBORbar';
function basicStub(driver) {
const sizeStub = _sinon.default.stub(driver, 'getWindowSize').returns(size);
const screenStub = _sinon.default.stub(driver, 'getScreenshotForImageFind').returns(screenshot);
const compareStub = _sinon.default.stub(driver, 'compareImages').returns({
rect
});
return {
sizeStub,
screenStub,
compareStub
};
}
function basicImgElVerify(imgElProto, driver) {
const imgElId = imgElProto.ELEMENT;
driver._imgElCache.has(imgElId).should.be.true;
const imgEl = driver._imgElCache.get(imgElId);
(imgEl instanceof _.ImageElement).should.be.true;
imgEl.rect.should.eql(rect);
return imgEl;
}
it('should find an image element happypath', async function () {
const d = new TestDriver();
basicStub(d);
const imgElProto = await d.findByImage(template, {
multiple: false
});
basicImgElVerify(imgElProto, d);
});
it('should find image elements happypath', async function () {
const d = new TestDriver();
basicStub(d);
const els = await d.findByImage(template, {
multiple: true
});
els.should.have.length(1);
basicImgElVerify(els[0], d);
});
it('should fail if driver does not support getWindowSize', async function () {
const d = new _.BaseDriver();
await d.findByImage(template, {
multiple: false
}).should.eventually.be.rejectedWith(/driver does not support/);
});
it('should fix template size if requested', async function () {
const d = new TestDriver();
const newTemplate = 'iVBORbaz';
const {
compareStub
} = basicStub(d);
await d.settings.update({
fixImageTemplateSize: true
});
_sinon.default.stub(d, 'ensureTemplateSize').returns(newTemplate);
const imgElProto = await d.findByImage(template, {
multiple: false
});
const imgEl = basicImgElVerify(imgElProto, d);
imgEl.template.should.eql(newTemplate);
compareStub.args[0][2].should.eql(newTemplate);
});
it('should fix template size scale if requested', async function () {
const d = new TestDriver();
const newTemplate = 'iVBORbaz';
const {
compareStub
} = basicStub(d);
await d.settings.update({
fixImageTemplateScale: true
});
_sinon.default.stub(d, 'fixImageTemplateScale').returns(newTemplate);
const imgElProto = await d.findByImage(template, {
multiple: false
});
const imgEl = basicImgElVerify(imgElProto, d);
imgEl.template.should.eql(newTemplate);
compareStub.args[0][2].should.eql(newTemplate);
});
it('should not fix template size scale if it is not requested', async function () {
const d = new TestDriver();
const newTemplate = 'iVBORbaz';
basicStub(d);
await d.settings.update({});
_sinon.default.stub(d, 'fixImageTemplateScale').returns(newTemplate);
d.fixImageTemplateScale.callCount.should.eql(0);
});
it('should throw an error if template match fails', async function () {
const d = new TestDriver();
const {
compareStub
} = basicStub(d);
compareStub.throws(new Error('Cannot find any occurrences'));
await d.findByImage(template, {
multiple: false
}).should.eventually.be.rejectedWith(/element could not be located/);
});
it('should return empty array for multiple elements if template match fails', async function () {
const d = new TestDriver();
const {
compareStub
} = basicStub(d);
compareStub.throws(new Error('Cannot find any occurrences'));
await d.findByImage(template, {
multiple: true
}).should.eventually.eql([]);
});
it('should respect implicit wait', async function () {
const d = new TestDriver();
d.setImplicitWait(10);
const {
compareStub
} = basicStub(d);
compareStub.onCall(0).throws(new Error('Cannot find any occurrences'));
const imgElProto = await d.findByImage(template, {
multiple: false
});
basicImgElVerify(imgElProto, d);
compareStub.callCount.should.eql(2);
});
it('should not add element to cache and return it directly when checking staleness', async function () {
const d = new TestDriver();
basicStub(d);
const imgEl = await d.findByImage(template, {
multiple: false,
shouldCheckStaleness: true
});
(imgEl instanceof _.ImageElement).should.be.true;
d._imgElCache.has(imgEl.id).should.be.false;
imgEl.rect.should.eql(rect);
});
});
describe('fixImageTemplateScale', function () {
it('should not fix template size scale if no scale value', async function () {
const newTemplate = 'iVBORbaz';
await _find.helpers.fixImageTemplateScale(newTemplate, {
fixImageTemplateScale: true
}).should.eventually.eql(newTemplate);
});
it('should not fix template size scale if it is null', async function () {
const newTemplate = 'iVBORbaz';
await _find.helpers.fixImageTemplateScale(newTemplate, null).should.eventually.eql(newTemplate);
});
it('should not fix template size scale if it is not number', async function () {
const newTemplate = 'iVBORbaz';
await _find.helpers.fixImageTemplateScale(newTemplate, 'wrong-scale').should.eventually.eql(newTemplate);
});
it('should fix template size scale', async function () {
const actual = 'iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAWElEQVR4AU3BQRWAQAhAwa/PGBsEgrC16AFBKEIPXW7OXO+Rmey9iQjMjHFzrLUwM7qbqmLcHKpKRFBVuDvj4agq3B1VRUQYT2bS3QwRQVUZF/CaGRHB3wc1vSZbHO5+BgAAAABJRU5ErkJggg==';
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
fixImageTemplateScale: true,
xScale: 1.5,
yScale: 1.5
}).should.eventually.eql(actual);
});
it('should not fix template size scale because of fixImageTemplateScale is false', async function () {
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
fixImageTemplateScale: false,
xScale: 1.5,
yScale: 1.5
}).should.eventually.eql(TINY_PNG);
});
it('should fix template size scale with default scale', async function () {
const actual = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwUlEQVR4AaXBPUsrQQCG0SeX+cBdkTjwTpG1NPgLpjY/fW1stt4UYmm2cJqwMCsaw70uJJ3CBc9Z/P3Cl+12S9u2tG1L27bEGLm/v2ez2bDZbJDEd/7wS4YT7z3X19fc3Nxwd3dHXdd47xnHkefnZ8ZxpKoq6rqmqiqMMcwMJ1VV0TQN0zThnOPj44O6rsk503UdkmiahqZpWK1WGGOYGU7quqZpGqy1SCLnTM6Z19dXcs5IYpomrLVI4uLigpnhpKoqVqsVkjgcDjw9PdF1HTlnuq5DEs45JHE4HDgznByPR97e3pimiVIK4zhyPB7x3hNCIITA5eUl3nsWiwVnhpNSCsMwsNvtGIaB/X5PKQVJpJSQxHq9RhLOOc4MJ9M0sdvt2G639H3PTBIxRiQhCUnEGLHWcmY4KaUwDAN93/P4+MhyuSSlhCRSSkjCOYe1FmstZ6bve2YvLy/s93tmy+USSUhCEpIIIfAd8/DwwOz9/Z1SCpJIKSGJ9XqNJJxz/MS0bcvs6uoKScQYkYQkJBFjxFrLT0zbtsxub29JKSGJlBKScM5hrcVay09MzplZjJHPz0+894QQCCHwP/7wS/8A4e6nAg+R8LwAAAAASUVORK5CYII=';
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
defaultImageTemplateScale: 4.0
}).should.eventually.eql(actual);
});
it('should fix template size scale with default scale and image scale', async function () {
const actual = 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACaUlEQVR4AbXBMWvrWBSF0c9BsFPtW91UR1U6+///FKlKKt8qqnyqnMozggkI8xgMj6x1uv+L/6zryrIsrOvKsiys68qyLFwuF87nM5fLhfP5zOVy4Xw+84wXftkLv2ziQBK26b0TEVQVu4jANrvM5Hq9spOEJCQhCUlI4mjiQBK26b1TVewkYRvb7DKTMQaZiW1s01rDNraRxNHEgSRaa1QVO0m01jjKTDKTXe+d3jtVxU4SjyYOJGGbnSRs03snM8lMMpPb7UZmkplEBFXFThK2eTRxIAnbSMI2VcX39zdjDMYYZCaZyRiDMQZVxU4StqkqHk0cSEISf5KZ7DKTMQbLsrCTRGuN3jtVxaOJg6qiqqgqqoqqoqoYY5CZ7GwTEdzvd97f34kIeu/YRhKPJg6qiswkM7ndbmQmmUlmkpnsbBMR2CYimOeZ3ju2kcSjiYOqIjP5+vpi2za2bWPbNo5aa7TW2PXe6b3Te6e1hiQeTRxUFbfbjW3bGGNwvV4ZY2Ab27TWsI1tbGMb27TWsI0kHk0cVBWZybZtXK9XPj8/+fj4YJ5nIoLWGraJCOZ5RhKSkIQkJPFo4qCqyEy2bWOMwefnJ+u6cjqdsM3ONvM8cz6feca0ris/rtcrmcnONhHB/X7n/f2diKD3jm0k8axpWRZ+ZCaZyc42EYFtIoJ5num9YxtJPGta15U/sY1tdm9vb/Te6b1jG0k8a1qWhR+2sU1rjdYatrGNbWxjm9YaknjWtK4rPyKCiKC1hm0igojg9fUVSUhCEpJ41rQsC0e22dkmIrhcLvyNF/7H6XTib73wy174Zf8AJEsePtlPj10AAAAASUVORK5CYII=';
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
defaultImageTemplateScale: 4.0,
fixImageTemplateScale: true,
xScale: 1.5,
yScale: 1.5
}).should.eventually.eql(actual);
});
it('should not fix template size scale with default scale and image scale', async function () {
const actual = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwUlEQVR4AaXBPUsrQQCG0SeX+cBdkTjwTpG1NPgLpjY/fW1stt4UYmm2cJqwMCsaw70uJJ3CBc9Z/P3Cl+12S9u2tG1L27bEGLm/v2ez2bDZbJDEd/7wS4YT7z3X19fc3Nxwd3dHXdd47xnHkefnZ8ZxpKoq6rqmqiqMMcwMJ1VV0TQN0zThnOPj44O6rsk503UdkmiahqZpWK1WGGOYGU7quqZpGqy1SCLnTM6Z19dXcs5IYpomrLVI4uLigpnhpKoqVqsVkjgcDjw9PdF1HTlnuq5DEs45JHE4HDgznByPR97e3pimiVIK4zhyPB7x3hNCIITA5eUl3nsWiwVnhpNSCsMwsNvtGIaB/X5PKQVJpJSQxHq9RhLOOc4MJ9M0sdvt2G639H3PTBIxRiQhCUnEGLHWcmY4KaUwDAN93/P4+MhyuSSlhCRSSkjCOYe1FmstZ6bve2YvLy/s93tmy+USSUhCEpIIIfAd8/DwwOz9/Z1SCpJIKSGJ9XqNJJxz/MS0bcvs6uoKScQYkYQkJBFjxFrLT0zbtsxub29JKSGJlBKScM5hrcVay09MzplZjJHPz0+894QQCCHwP/7wS/8A4e6nAg+R8LwAAAAASUVORK5CYII=';
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
defaultImageTemplateScale: 4.0,
fixImageTemplateScale: false,
xScale: 1.5,
yScale: 1.5
}).should.eventually.eql(actual);
});
it('should not fix template size scale because of ignoreDefaultImageTemplateScale', async function () {
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
defaultImageTemplateScale: 4.0,
ignoreDefaultImageTemplateScale: true
}).should.eventually.eql(TINY_PNG);
});
it('should ignore defaultImageTemplateScale to fix template size scale because of ignoreDefaultImageTemplateScale', async function () {
const actual = 'iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAWElEQVR4AU3BQRWAQAhAwa/PGBsEgrC16AFBKEIPXW7OXO+Rmey9iQjMjHFzrLUwM7qbqmLcHKpKRFBVuDvj4agq3B1VRUQYT2bS3QwRQVUZF/CaGRHB3wc1vSZbHO5+BgAAAABJRU5ErkJggg==';
await _find.helpers.fixImageTemplateScale(TINY_PNG, {
defaultImageTemplateScale: 4.0,
ignoreDefaultImageTemplateScale: true,
fixImageTemplateScale: true,
xScale: 1.5,
yScale: 1.5
}).should.eventually.eql(actual);
});
});
describe('ensureTemplateSize', function () {
it('should not resize the template if it is smaller than the screen', async function () {
const screen = TINY_PNG_DIMS.map(n => n * 2);
const d = new TestDriver();
await d.ensureTemplateSize(TINY_PNG, ...screen).should.eventually.eql(TINY_PNG);
});
it('should not resize the template if it is the same size as the screen', async function () {
const d = new TestDriver();
await d.ensureTemplateSize(TINY_PNG, ...TINY_PNG_DIMS).should.eventually.eql(TINY_PNG);
});
it('should resize the template if it is bigger than the screen', async function () {
const d = new TestDriver();
const screen = TINY_PNG_DIMS.map(n => n / 2);
const newTemplate = await d.ensureTemplateSize(TINY_PNG, ...screen);
newTemplate.should.not.eql(TINY_PNG);
newTemplate.length.should.be.below(TINY_PNG.length);
});
});
describe('getScreenshotForImageFind', function () {
it('should fail if driver does not support getScreenshot', async function () {
const d = new _.BaseDriver();
await d.getScreenshotForImageFind().should.eventually.be.rejectedWith(/driver does not support/);
});
it('should not adjust or verify screenshot if asked not to by settings', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG);
d.settings.update({
fixImageFindScreenshotDims: false
});
const screen = TINY_PNG_DIMS.map(n => n + 1);
const {
b64Screenshot,
scale
} = await d.getScreenshotForImageFind(...screen);
b64Screenshot.should.eql(TINY_PNG);
should.equal(scale, undefined);
});
it('should return screenshot without adjustment if it matches screen size', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG);
const {
b64Screenshot,
scale
} = await d.getScreenshotForImageFind(...TINY_PNG_DIMS);
b64Screenshot.should.eql(TINY_PNG);
should.equal(scale, undefined);
});
it('should return scaled screenshot with same aspect ratio if matching screen aspect ratio', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG);
const screen = TINY_PNG_DIMS.map(n => n * 1.5);
const {
b64Screenshot,
scale
} = await d.getScreenshotForImageFind(...screen);
b64Screenshot.should.not.eql(TINY_PNG);
const screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot);
screenshotObj.bitmap.width.should.eql(screen[0]);
screenshotObj.bitmap.height.should.eql(screen[1]);
scale.should.eql({
xScale: 1.5,
yScale: 1.5
});
});
it('should return scaled screenshot with different aspect ratio if not matching screen aspect ratio', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG);
let screen = [TINY_PNG_DIMS[0] * 2, TINY_PNG_DIMS[1] * 3];
let expectedScale = {
xScale: 2.67,
yScale: 4
};
const {
b64Screenshot,
scale
} = await d.getScreenshotForImageFind(...screen);
b64Screenshot.should.not.eql(TINY_PNG);
let screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot);
screenshotObj.bitmap.width.should.eql(screen[0]);
screenshotObj.bitmap.height.should.eql(screen[1]);
scale.xScale.toFixed(2).should.eql(expectedScale.xScale.toString());
scale.yScale.should.eql(expectedScale.yScale);
screen = [TINY_PNG_DIMS[0] * 3, TINY_PNG_DIMS[1] * 2];
expectedScale = {
xScale: 4,
yScale: 2.67
};
const {
b64Screenshot: newScreen,
scale: newScale
} = await d.getScreenshotForImageFind(...screen);
newScreen.should.not.eql(TINY_PNG);
screenshotObj = await _appiumSupport.imageUtil.getJimpImage(newScreen);
screenshotObj.bitmap.width.should.eql(screen[0]);
screenshotObj.bitmap.height.should.eql(screen[1]);
newScale.xScale.should.eql(expectedScale.xScale);
newScale.yScale.toFixed(2).should.eql(expectedScale.yScale.toString());
});
it('should return scaled screenshot with different aspect ratio if not matching screen aspect ratio with fixImageTemplateScale', async function () {
const d = new TestDriver();
_sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG);
let screen = [TINY_PNG_DIMS[0] * 2, TINY_PNG_DIMS[1] * 3];
let expectedScale = {
xScale: 2.67,
yScale: 4
};
const {
b64Screenshot,
scale
} = await d.getScreenshotForImageFind(...screen);
b64Screenshot.should.not.eql(TINY_PNG);
let screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot);
screenshotObj.bitmap.width.should.eql(screen[0]);
screenshotObj.bitmap.height.should.eql(screen[1]);
scale.xScale.toFixed(2).should.eql(expectedScale.xScale.toString());
scale.yScale.should.eql(expectedScale.yScale);
await _find.helpers.fixImageTemplateScale(b64Screenshot, {
fixImageTemplateScale: true,
scale
}).should.eventually.eql('iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMCAYAAABfnvydAAAAJ0lEQVR4AYXBAQEAIACDMKR/p0fTBrKdbZcPCRIkSJAgQYIECRIkPAzBA1TpeNwZAAAAAElFTkSuQmCC');
screen = [TINY_PNG_DIMS[0] * 3, TINY_PNG_DIMS[1] * 2];
expectedScale = {
xScale: 4,
yScale: 2.67
};
const {
b64Screenshot: newScreen,
scale: newScale
} = await d.getScreenshotForImageFind(...screen);
newScreen.should.not.eql(TINY_PNG);
screenshotObj = await _appiumSupport.imageUtil.getJimpImage(newScreen);
screenshotObj.bitmap.width.should.eql(screen[0]);
screenshotObj.bitmap.height.should.eql(screen[1]);
newScale.xScale.should.eql(expectedScale.xScale);
newScale.yScale.toFixed(2).should.eql(expectedScale.yScale.toString());
await _find.helpers.fixImageTemplateScale(newScreen, {
fixImageTemplateScale: true,
scale
}).should.eventually.eql('iVBORw0KGgoAAAANSUhEUgAAAAwAAAAICAYAAADN5B7xAAAAI0lEQVR4AZXBAQEAMAyDMI5/T5W2ayB5245AIokkkkgiiST6+W4DTLyo5PUAAAAASUVORK5CYII=');
});
});
});
describe('custom element finding plugins', function () {
it('should find a single element using a custom finder', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.eql('bar');
});
it('should not require selector prefix if only one find plugin is registered', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'foo').should.eventually.eql('bar');
});
it('should find multiple elements using a custom finder', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElements(_find.CUSTOM_STRATEGY, 'f:foos').should.eventually.eql(['baz1', 'baz2']);
});
it('should give a hint to the plugin about whether multiple are requested', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foos').should.eventually.eql('bar1');
});
it('should be able to use multiple find modules', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE,
g: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.eql('bar');
await d.findElement(_find.CUSTOM_STRATEGY, 'g:foo').should.eventually.eql('bar');
});
it('should throw an error if customFindModules is not set', async function () {
const d = new _.BaseDriver();
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/customFindModules/);
});
it('should throw an error if customFindModules is the wrong shape', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = CUSTOM_FIND_MODULE;
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/customFindModules/);
});
it('should throw an error if customFindModules is size > 1 and no selector prefix is used', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE,
g: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'foo').should.eventually.be.rejectedWith(/multiple element finding/i);
});
it('should throw an error in attempt to use unregistered plugin', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE,
g: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'z:foo').should.eventually.be.rejectedWith(/was not registered/);
});
it('should throw an error if plugin cannot be loaded', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: './foo.js'
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/could not load/i);
});
it('should throw an error if plugin is not the right shape', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: BAD_CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/constructed correctly/i);
});
it('should pass on an error thrown by the finder itself', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:error').should.eventually.be.rejectedWith(/plugin error/i);
});
it('should throw no such element error if element not found', async function () {
const d = new _.BaseDriver();
d.opts.customFindModules = {
f: CUSTOM_FIND_MODULE
};
await d.findElement(_find.CUSTOM_STRATEGY, 'f:nope').should.eventually.be.rejectedWith(/could not be located/);
});
});require('source-map-support').install();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvYmFzZWRyaXZlci9jb21tYW5kcy9maW5kLXNwZWNzLmpzIl0sIm5hbWVzIjpbInNob3VsZCIsImNoYWkiLCJ1c2UiLCJjaGFpQXNQcm9taXNlZCIsIlRlc3REcml2ZXIiLCJCYXNlRHJpdmVyIiwiZ2V0V2luZG93U2l6ZSIsImdldFNjcmVlbnNob3QiLCJDVVNUT01fRklORF9NT0RVTEUiLCJwYXRoIiwicmVzb2x2ZSIsIl9fZGlybmFtZSIsIkJBRF9DVVNUT01fRklORF9NT0RVTEUiLCJUSU5ZX1BORyIsIlRJTllfUE5HX0RJTVMiLCJkZXNjcmliZSIsIml0IiwiZCIsInNpbm9uIiwic3R1YiIsInJldHVybnMiLCJmaW5kRWxlbWVudCIsIklNQUdFX1NUUkFURUdZIiwiZXZlbnR1YWxseSIsImJlIiwidHJ1ZSIsImZpbmRFbGVtZW50cyIsImZpbmRFbGVtZW50RnJvbUVsZW1lbnQiLCJyZWplY3RlZFdpdGgiLCJmaW5kRWxlbWVudHNGcm9tRWxlbWVudCIsInJlY3QiLCJ4IiwieSIsIndpZHRoIiwiaGVpZ2h0Iiwic2l6ZSIsInNjcmVlbnNob3QiLCJ0ZW1wbGF0ZSIsImJhc2ljU3R1YiIsImRyaXZlciIsInNpemVTdHViIiwic2NyZWVuU3R1YiIsImNvbXBhcmVTdHViIiwiYmFzaWNJbWdFbFZlcmlmeSIsImltZ0VsUHJvdG8iLCJpbWdFbElkIiwiRUxFTUVOVCIsIl9pbWdFbENhY2hlIiwiaGFzIiwiaW1nRWwiLCJnZXQiLCJJbWFnZUVsZW1lbnQiLCJlcWwiLCJmaW5kQnlJbWFnZSIsIm11bHRpcGxlIiwiZWxzIiwiaGF2ZSIsImxlbmd0aCIsIm5ld1RlbXBsYXRlIiwic2V0dGluZ3MiLCJ1cGRhdGUiLCJmaXhJbWFnZVRlbXBsYXRlU2l6ZSIsImFyZ3MiLCJmaXhJbWFnZVRlbXBsYXRlU2NhbGUiLCJjYWxsQ291bnQiLCJ0aHJvd3MiLCJFcnJvciIsInNldEltcGxpY2l0V2FpdCIsIm9uQ2FsbCIsInNob3VsZENoZWNrU3RhbGVuZXNzIiwiaWQiLCJmYWxzZSIsImhlbHBlcnMiLCJhY3R1YWwiLCJ4U2NhbGUiLCJ5U2NhbGUiLCJkZWZhdWx0SW1hZ2VUZW1wbGF0ZVNjYWxlIiwiaWdub3JlRGVmYXVsdEltYWdlVGVtcGxhdGVTY2FsZSIsInNjcmVlbiIsIm1hcCIsIm4iLCJlbnN1cmVUZW1wbGF0ZVNpemUiLCJub3QiLCJiZWxvdyIsImdldFNjcmVlbnNob3RGb3JJbWFnZUZpbmQiLCJmaXhJbWFnZUZpbmRTY3JlZW5zaG90RGltcyIsImI2NFNjcmVlbnNob3QiLCJzY2FsZSIsImVxdWFsIiwidW5kZWZpbmVkIiwic2NyZWVuc2hvdE9iaiIsImltYWdlVXRpbCIsImdldEppbXBJbWFnZSIsImJpdG1hcCIsImV4cGVjdGVkU2NhbGUiLCJ0b0ZpeGVkIiwidG9TdHJpbmciLCJuZXdTY3JlZW4iLCJuZXdTY2FsZSIsIm9wdHMiLCJjdXN0b21GaW5kTW9kdWxlcyIsImYiLCJDVVNUT01fU1RSQVRFR1kiLCJnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQSxNQUFNQSxNQUFNLEdBQUdDLGNBQUtELE1BQUwsRUFBZjs7QUFDQUMsY0FBS0MsR0FBTCxDQUFTQyx1QkFBVDs7QUFHQSxNQUFNQyxVQUFOLFNBQXlCQyxZQUF6QixDQUFvQztBQUNsQyxRQUFNQyxhQUFOLEdBQXVCLENBQUU7O0FBQ3pCLFFBQU1DLGFBQU4sR0FBdUIsQ0FBRTs7QUFGUzs7QUFLcEMsTUFBTUMsa0JBQWtCLEdBQUdDLGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQyxJQUFwQyxFQUEwQyxJQUExQyxFQUN6QixNQUR5QixFQUNqQixZQURpQixFQUNILFVBREcsRUFDUyx1QkFEVCxDQUEzQjs7QUFFQSxNQUFNQyxzQkFBc0IsR0FBR0gsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLElBQXhCLEVBQThCLElBQTlCLEVBQW9DLElBQXBDLEVBQTBDLElBQTFDLEVBQzdCLE1BRDZCLEVBQ3JCLFlBRHFCLEVBQ1AsVUFETyxFQUNLLDJCQURMLENBQS9COztBQUdBLE1BQU1FLFFBQVEsR0FBRyxzdkNBQWpCO0FBQ0EsTUFBTUMsYUFBYSxHQUFHLENBQUMsQ0FBRCxFQUFJLENBQUosQ0FBdEI7QUFFQUMsUUFBUSxDQUFDLDJCQUFELEVBQThCLFlBQVk7QUFDaERBLEVBQUFBLFFBQVEsQ0FBQyxhQUFELEVBQWdCLFlBQVk7QUFDbENDLElBQUFBLEVBQUUsQ0FBQyxnRUFBRCxFQUFtRSxrQkFBa0I7QUFDckYsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjs7QUFDQWMscUJBQU1DLElBQU4sQ0FBV0YsQ0FBWCxFQUFjLGFBQWQsRUFBNkJHLE9BQTdCLENBQXFDLElBQXJDOztBQUNBRixxQkFBTUMsSUFBTixDQUFXRixDQUFYLEVBQWMsMkJBQWQsRUFBMkNHLE9BQTNDLENBQW1ELEtBQW5EOztBQUNBLFlBQU1ILENBQUMsQ0FBQ0ksV0FBRixDQUFjQyxvQkFBZCxFQUE4QixLQUE5QixFQUFxQ3RCLE1BQXJDLENBQTRDdUIsVUFBNUMsQ0FBdURDLEVBQXZELENBQTBEQyxJQUFoRTtBQUNBLFlBQU1SLENBQUMsQ0FBQ1MsWUFBRixDQUFlSixvQkFBZixFQUErQixLQUEvQixFQUFzQ3RCLE1BQXRDLENBQTZDdUIsVUFBN0MsQ0FBd0RDLEVBQXhELENBQTJEQyxJQUFqRTtBQUNELEtBTkMsQ0FBRjtBQU9BVCxJQUFBQSxFQUFFLENBQUMsaUVBQUQsRUFBb0Usa0JBQWtCO0FBQ3RGLFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7QUFDQSxZQUFNYSxDQUFDLENBQUNVLHNCQUFGLENBQXlCTCxvQkFBekIsRUFBeUMsS0FBekMsRUFBZ0QsTUFBaEQsRUFDSHRCLE1BREcsQ0FDSXVCLFVBREosQ0FDZUMsRUFEZixDQUNrQkksWUFEbEIsQ0FDK0Isb0NBRC9CLENBQU47QUFFQSxZQUFNWCxDQUFDLENBQUNZLHVCQUFGLENBQTBCUCxvQkFBMUIsRUFBMEMsS0FBMUMsRUFBaUQsTUFBakQsRUFDSHRCLE1BREcsQ0FDSXVCLFVBREosQ0FDZUMsRUFEZixDQUNrQkksWUFEbEIsQ0FDK0Isb0NBRC9CLENBQU47QUFFRCxLQU5DLENBQUY7QUFPRCxHQWZPLENBQVI7QUFpQkFiLEVBQUFBLFFBQVEsQ0FBQyxhQUFELEVBQWdCLFlBQVk7QUFDbEMsVUFBTWUsSUFBSSxHQUFHO0FBQUNDLE1BQUFBLENBQUMsRUFBRSxFQUFKO0FBQVFDLE1BQUFBLENBQUMsRUFBRSxFQUFYO0FBQWVDLE1BQUFBLEtBQUssRUFBRSxFQUF0QjtBQUEwQkMsTUFBQUEsTUFBTSxFQUFFO0FBQWxDLEtBQWI7QUFDQSxVQUFNQyxJQUFJLEdBQUc7QUFBQ0YsTUFBQUEsS0FBSyxFQUFFLEdBQVI7QUFBYUMsTUFBQUEsTUFBTSxFQUFFO0FBQXJCLEtBQWI7QUFDQSxVQUFNRSxVQUFVLEdBQUcsVUFBbkI7QUFDQSxVQUFNQyxRQUFRLEdBQUcsVUFBakI7O0FBRUEsYUFBU0MsU0FBVCxDQUFvQkMsTUFBcEIsRUFBNEI7QUFDMUIsWUFBTUMsUUFBUSxHQUFHdEIsZUFBTUMsSUFBTixDQUFXb0IsTUFBWCxFQUFtQixlQUFuQixFQUFvQ25CLE9BQXBDLENBQTRDZSxJQUE1QyxDQUFqQjs7QUFDQSxZQUFNTSxVQUFVLEdBQUd2QixlQUFNQyxJQUFOLENBQVdvQixNQUFYLEVBQW1CLDJCQUFuQixFQUFnRG5CLE9BQWhELENBQXdEZ0IsVUFBeEQsQ0FBbkI7O0FBQ0EsWUFBTU0sV0FBVyxHQUFHeEIsZUFBTUMsSUFBTixDQUFXb0IsTUFBWCxFQUFtQixlQUFuQixFQUFvQ25CLE9BQXBDLENBQTRDO0FBQUNVLFFBQUFBO0FBQUQsT0FBNUMsQ0FBcEI7O0FBQ0EsYUFBTztBQUFDVSxRQUFBQSxRQUFEO0FBQVdDLFFBQUFBLFVBQVg7QUFBdUJDLFFBQUFBO0FBQXZCLE9BQVA7QUFDRDs7QUFFRCxhQUFTQyxnQkFBVCxDQUEyQkMsVUFBM0IsRUFBdUNMLE1BQXZDLEVBQStDO0FBQzdDLFlBQU1NLE9BQU8sR0FBR0QsVUFBVSxDQUFDRSxPQUEzQjtBQUNBUCxNQUFBQSxNQUFNLENBQUNRLFdBQVAsQ0FBbUJDLEdBQW5CLENBQXVCSCxPQUF2QixFQUFnQzdDLE1BQWhDLENBQXVDd0IsRUFBdkMsQ0FBMENDLElBQTFDOztBQUNBLFlBQU13QixLQUFLLEdBQUdWLE1BQU0sQ0FBQ1EsV0FBUCxDQUFtQkcsR0FBbkIsQ0FBdUJMLE9BQXZCLENBQWQ7O0FBQ0EsT0FBQ0ksS0FBSyxZQUFZRSxjQUFsQixFQUFnQ25ELE1BQWhDLENBQXVDd0IsRUFBdkMsQ0FBMENDLElBQTFDO0FBQ0F3QixNQUFBQSxLQUFLLENBQUNuQixJQUFOLENBQVc5QixNQUFYLENBQWtCb0QsR0FBbEIsQ0FBc0J0QixJQUF0QjtBQUNBLGFBQU9tQixLQUFQO0FBQ0Q7O0FBRURqQyxJQUFBQSxFQUFFLENBQUMsd0NBQUQsRUFBMkMsa0JBQWtCO0FBQzdELFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7QUFDQWtDLE1BQUFBLFNBQVMsQ0FBQ3JCLENBQUQsQ0FBVDtBQUNBLFlBQU0yQixVQUFVLEdBQUcsTUFBTTNCLENBQUMsQ0FBQ29DLFdBQUYsQ0FBY2hCLFFBQWQsRUFBd0I7QUFBQ2lCLFFBQUFBLFFBQVEsRUFBRTtBQUFYLE9BQXhCLENBQXpCO0FBQ0FYLE1BQUFBLGdCQUFnQixDQUFDQyxVQUFELEVBQWEzQixDQUFiLENBQWhCO0FBQ0QsS0FMQyxDQUFGO0FBTUFELElBQUFBLEVBQUUsQ0FBQyxzQ0FBRCxFQUF5QyxrQkFBa0I7QUFDM0QsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBa0MsTUFBQUEsU0FBUyxDQUFDckIsQ0FBRCxDQUFUO0FBQ0EsWUFBTXNDLEdBQUcsR0FBRyxNQUFNdEMsQ0FBQyxDQUFDb0MsV0FBRixDQUFjaEIsUUFBZCxFQUF3QjtBQUFDaUIsUUFBQUEsUUFBUSxFQUFFO0FBQVgsT0FBeEIsQ0FBbEI7QUFDQUMsTUFBQUEsR0FBRyxDQUFDdkQsTUFBSixDQUFXd0QsSUFBWCxDQUFnQkMsTUFBaEIsQ0FBdUIsQ0FBdkI7QUFDQWQsTUFBQUEsZ0JBQWdCLENBQUNZLEdBQUcsQ0FBQyxDQUFELENBQUosRUFBU3RDLENBQVQsQ0FBaEI7QUFDRCxLQU5DLENBQUY7QUFPQUQsSUFBQUEsRUFBRSxDQUFDLHNEQUFELEVBQXlELGtCQUFrQjtBQUMzRSxZQUFNQyxDQUFDLEdBQUcsSUFBSVosWUFBSixFQUFWO0FBQ0EsWUFBTVksQ0FBQyxDQUFDb0MsV0FBRixDQUFjaEIsUUFBZCxFQUF3QjtBQUFDaUIsUUFBQUEsUUFBUSxFQUFFO0FBQVgsT0FBeEIsRUFDSHRELE1BREcsQ0FDSXVCLFVBREosQ0FDZUMsRUFEZixDQUNrQkksWUFEbEIsQ0FDK0IseUJBRC9CLENBQU47QUFFRCxLQUpDLENBQUY7QUFLQVosSUFBQUEsRUFBRSxDQUFDLHVDQUFELEVBQTBDLGtCQUFrQjtBQUM1RCxZQUFNQyxDQUFDLEdBQUcsSUFBSWIsVUFBSixFQUFWO0FBQ0EsWUFBTXNELFdBQVcsR0FBRyxVQUFwQjtBQUNBLFlBQU07QUFBQ2hCLFFBQUFBO0FBQUQsVUFBZ0JKLFNBQVMsQ0FBQ3JCLENBQUQsQ0FBL0I7QUFDQSxZQUFNQSxDQUFDLENBQUMwQyxRQUFGLENBQVdDLE1BQVgsQ0FBa0I7QUFBQ0MsUUFBQUEsb0JBQW9CLEVBQUU7QUFBdkIsT0FBbEIsQ0FBTjs7QUFDQTNDLHFCQUFNQyxJQUFOLENBQVdGLENBQVgsRUFBYyxvQkFBZCxFQUFvQ0csT0FBcEMsQ0FBNENzQyxXQUE1Qzs7QUFDQSxZQUFNZCxVQUFVLEdBQUcsTUFBTTNCLENBQUMsQ0FBQ29DLFdBQUYsQ0FBY2hCLFFBQWQsRUFBd0I7QUFBQ2lCLFFBQUFBLFFBQVEsRUFBRTtBQUFYLE9BQXhCLENBQXpCO0FBQ0EsWUFBTUwsS0FBSyxHQUFHTixnQkFBZ0IsQ0FBQ0MsVUFBRCxFQUFhM0IsQ0FBYixDQUE5QjtBQUNBZ0MsTUFBQUEsS0FBSyxDQUFDWixRQUFOLENBQWVyQyxNQUFmLENBQXNCb0QsR0FBdEIsQ0FBMEJNLFdBQTFCO0FBQ0FoQixNQUFBQSxXQUFXLENBQUNvQixJQUFaLENBQWlCLENBQWpCLEVBQW9CLENBQXBCLEVBQXVCOUQsTUFBdkIsQ0FBOEJvRCxHQUE5QixDQUFrQ00sV0FBbEM7QUFDRCxLQVZDLENBQUY7QUFZQTFDLElBQUFBLEVBQUUsQ0FBQyw2Q0FBRCxFQUFnRCxrQkFBa0I7QUFDbEUsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBLFlBQU1zRCxXQUFXLEdBQUcsVUFBcEI7QUFDQSxZQUFNO0FBQUNoQixRQUFBQTtBQUFELFVBQWdCSixTQUFTLENBQUNyQixDQUFELENBQS9CO0FBQ0EsWUFBTUEsQ0FBQyxDQUFDMEMsUUFBRixDQUFXQyxNQUFYLENBQWtCO0FBQUNHLFFBQUFBLHFCQUFxQixFQUFFO0FBQXhCLE9BQWxCLENBQU47O0FBQ0E3QyxxQkFBTUMsSUFBTixDQUFXRixDQUFYLEVBQWMsdUJBQWQsRUFBdUNHLE9BQXZDLENBQStDc0MsV0FBL0M7O0FBQ0EsWUFBTWQsVUFBVSxHQUFHLE1BQU0zQixDQUFDLENBQUNvQyxXQUFGLENBQWNoQixRQUFkLEVBQXdCO0FBQUNpQixRQUFBQSxRQUFRLEVBQUU7QUFBWCxPQUF4QixDQUF6QjtBQUNBLFlBQU1MLEtBQUssR0FBR04sZ0JBQWdCLENBQUNDLFVBQUQsRUFBYTNCLENBQWIsQ0FBOUI7QUFDQWdDLE1BQUFBLEtBQUssQ0FBQ1osUUFBTixDQUFlckMsTUFBZixDQUFzQm9ELEdBQXRCLENBQTBCTSxXQUExQjtBQUNBaEIsTUFBQUEsV0FBVyxDQUFDb0IsSUFBWixDQUFpQixDQUFqQixFQUFvQixDQUFwQixFQUF1QjlELE1BQXZCLENBQThCb0QsR0FBOUIsQ0FBa0NNLFdBQWxDO0FBQ0QsS0FWQyxDQUFGO0FBV0ExQyxJQUFBQSxFQUFFLENBQUMsMkRBQUQsRUFBOEQsa0JBQWtCO0FBQ2hGLFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7QUFDQSxZQUFNc0QsV0FBVyxHQUFHLFVBQXBCO0FBQ0FwQixNQUFBQSxTQUFTLENBQUNyQixDQUFELENBQVQ7QUFDQSxZQUFNQSxDQUFDLENBQUMwQyxRQUFGLENBQVdDLE1BQVgsQ0FBa0IsRUFBbEIsQ0FBTjs7QUFDQTFDLHFCQUFNQyxJQUFOLENBQVdGLENBQVgsRUFBYyx1QkFBZCxFQUF1Q0csT0FBdkMsQ0FBK0NzQyxXQUEvQzs7QUFDQXpDLE1BQUFBLENBQUMsQ0FBQzhDLHFCQUFGLENBQXdCQyxTQUF4QixDQUFrQ2hFLE1BQWxDLENBQXlDb0QsR0FBekMsQ0FBNkMsQ0FBN0M7QUFDRCxLQVBDLENBQUY7QUFTQXBDLElBQUFBLEVBQUUsQ0FBQywrQ0FBRCxFQUFrRCxrQkFBa0I7QUFDcEUsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBLFlBQU07QUFBQ3NDLFFBQUFBO0FBQUQsVUFBZ0JKLFNBQVMsQ0FBQ3JCLENBQUQsQ0FBL0I7QUFDQXlCLE1BQUFBLFdBQVcsQ0FBQ3VCLE1BQVosQ0FBbUIsSUFBSUMsS0FBSixDQUFVLDZCQUFWLENBQW5CO0FBQ0EsWUFBTWpELENBQUMsQ0FBQ29DLFdBQUYsQ0FBY2hCLFFBQWQsRUFBd0I7QUFBQ2lCLFFBQUFBLFFBQVEsRUFBRTtBQUFYLE9BQXhCLEVBQ0h0RCxNQURHLENBQ0l1QixVQURKLENBQ2VDLEVBRGYsQ0FDa0JJLFlBRGxCLENBQytCLDhCQUQvQixDQUFOO0FBRUQsS0FOQyxDQUFGO0FBT0FaLElBQUFBLEVBQUUsQ0FBQyx5RUFBRCxFQUE0RSxrQkFBa0I7QUFDOUYsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBLFlBQU07QUFBQ3NDLFFBQUFBO0FBQUQsVUFBZ0JKLFNBQVMsQ0FBQ3JCLENBQUQsQ0FBL0I7QUFDQXlCLE1BQUFBLFdBQVcsQ0FBQ3VCLE1BQVosQ0FBbUIsSUFBSUMsS0FBSixDQUFVLDZCQUFWLENBQW5CO0FBQ0EsWUFBTWpELENBQUMsQ0FBQ29DLFdBQUYsQ0FBY2hCLFFBQWQsRUFBd0I7QUFBQ2lCLFFBQUFBLFFBQVEsRUFBRTtBQUFYLE9BQXhCLEVBQTBDdEQsTUFBMUMsQ0FBaUR1QixVQUFqRCxDQUE0RDZCLEdBQTVELENBQWdFLEVBQWhFLENBQU47QUFDRCxLQUxDLENBQUY7QUFNQXBDLElBQUFBLEVBQUUsQ0FBQyw4QkFBRCxFQUFpQyxrQkFBa0I7QUFDbkQsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBYSxNQUFBQSxDQUFDLENBQUNrRCxlQUFGLENBQWtCLEVBQWxCO0FBQ0EsWUFBTTtBQUFDekIsUUFBQUE7QUFBRCxVQUFnQkosU0FBUyxDQUFDckIsQ0FBRCxDQUEvQjtBQUNBeUIsTUFBQUEsV0FBVyxDQUFDMEIsTUFBWixDQUFtQixDQUFuQixFQUFzQkgsTUFBdEIsQ0FBNkIsSUFBSUMsS0FBSixDQUFVLDZCQUFWLENBQTdCO0FBQ0EsWUFBTXRCLFVBQVUsR0FBRyxNQUFNM0IsQ0FBQyxDQUFDb0MsV0FBRixDQUFjaEIsUUFBZCxFQUF3QjtBQUFDaUIsUUFBQUEsUUFBUSxFQUFFO0FBQVgsT0FBeEIsQ0FBekI7QUFDQVgsTUFBQUEsZ0JBQWdCLENBQUNDLFVBQUQsRUFBYTNCLENBQWIsQ0FBaEI7QUFDQXlCLE1BQUFBLFdBQVcsQ0FBQ3NCLFNBQVosQ0FBc0JoRSxNQUF0QixDQUE2Qm9ELEdBQTdCLENBQWlDLENBQWpDO0FBQ0QsS0FSQyxDQUFGO0FBU0FwQyxJQUFBQSxFQUFFLENBQUMsZ0ZBQUQsRUFBbUYsa0JBQWtCO0FBQ3JHLFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7QUFDQWtDLE1BQUFBLFNBQVMsQ0FBQ3JCLENBQUQsQ0FBVDtBQUNBLFlBQU1nQyxLQUFLLEdBQUcsTUFBTWhDLENBQUMsQ0FBQ29DLFdBQUYsQ0FBY2hCLFFBQWQsRUFBd0I7QUFBQ2lCLFFBQUFBLFFBQVEsRUFBRSxLQUFYO0FBQWtCZSxRQUFBQSxvQkFBb0IsRUFBRTtBQUF4QyxPQUF4QixDQUFwQjtBQUNBLE9BQUNwQixLQUFLLFlBQVlFLGNBQWxCLEVBQWdDbkQsTUFBaEMsQ0FBdUN3QixFQUF2QyxDQUEwQ0MsSUFBMUM7QUFDQVIsTUFBQUEsQ0FBQyxDQUFDOEIsV0FBRixDQUFjQyxHQUFkLENBQWtCQyxLQUFLLENBQUNxQixFQUF4QixFQUE0QnRFLE1BQTVCLENBQW1Dd0IsRUFBbkMsQ0FBc0MrQyxLQUF0QztBQUNBdEIsTUFBQUEsS0FBSyxDQUFDbkIsSUFBTixDQUFXOUIsTUFBWCxDQUFrQm9ELEdBQWxCLENBQXNCdEIsSUFBdEI7QUFDRCxLQVBDLENBQUY7QUFRRCxHQXRHTyxDQUFSO0FBd0dBZixFQUFBQSxRQUFRLENBQUMsdUJBQUQsRUFBMEIsWUFBWTtBQUM1Q0MsSUFBQUEsRUFBRSxDQUFDLHNEQUFELEVBQXlELGtCQUFrQjtBQUMzRSxZQUFNMEMsV0FBVyxHQUFHLFVBQXBCO0FBQ0EsWUFBTWMsY0FBUVQscUJBQVIsQ0FBOEJMLFdBQTlCLEVBQTJDO0FBQUNLLFFBQUFBLHFCQUFxQixFQUFFO0FBQXhCLE9BQTNDLEVBQ0gvRCxNQURHLENBQ0l1QixVQURKLENBQ2U2QixHQURmLENBQ21CTSxXQURuQixDQUFOO0FBRUQsS0FKQyxDQUFGO0FBTUExQyxJQUFBQSxFQUFFLENBQUMsa0RBQUQsRUFBcUQsa0JBQWtCO0FBQ3ZFLFlBQU0wQyxXQUFXLEdBQUcsVUFBcEI7QUFDQSxZQUFNYyxjQUFRVCxxQkFBUixDQUE4QkwsV0FBOUIsRUFBMkMsSUFBM0MsRUFDSDFELE1BREcsQ0FDSXVCLFVBREosQ0FDZTZCLEdBRGYsQ0FDbUJNLFdBRG5CLENBQU47QUFFRCxLQUpDLENBQUY7QUFNQTFDLElBQUFBLEVBQUUsQ0FBQyx3REFBRCxFQUEyRCxrQkFBa0I7QUFDN0UsWUFBTTBDLFdBQVcsR0FBRyxVQUFwQjtBQUNBLFlBQU1jLGNBQVFULHFCQUFSLENBQThCTCxXQUE5QixFQUEyQyxhQUEzQyxFQUNIMUQsTUFERyxDQUNJdUIsVUFESixDQUNlNkIsR0FEZixDQUNtQk0sV0FEbkIsQ0FBTjtBQUVELEtBSkMsQ0FBRjtBQU1BMUMsSUFBQUEsRUFBRSxDQUFDLGdDQUFELEVBQW1DLGtCQUFrQjtBQUNyRCxZQUFNeUQsTUFBTSxHQUFHLHNNQUFmO0FBQ0EsWUFBTUQsY0FBUVQscUJBQVIsQ0FBOEJsRCxRQUE5QixFQUF3QztBQUM1Q2tELFFBQUFBLHFCQUFxQixFQUFFLElBRHFCO0FBQ2ZXLFFBQUFBLE1BQU0sRUFBRSxHQURPO0FBQ0ZDLFFBQUFBLE1BQU0sRUFBRTtBQUROLE9BQXhDLEVBRUgzRSxNQUZHLENBRUl1QixVQUZKLENBRWU2QixHQUZmLENBRW1CcUIsTUFGbkIsQ0FBTjtBQUdELEtBTEMsQ0FBRjtBQU9BekQsSUFBQUEsRUFBRSxDQUFDLDhFQUFELEVBQWlGLGtCQUFrQjtBQUNuRyxZQUFNd0QsY0FBUVQscUJBQVIsQ0FBOEJsRCxRQUE5QixFQUF3QztBQUM1Q2tELFFBQUFBLHFCQUFxQixFQUFFLEtBRHFCO0FBQ2RXLFFBQUFBLE1BQU0sRUFBRSxHQURNO0FBQ0RDLFFBQUFBLE1BQU0sRUFBRTtBQURQLE9BQXhDLEVBRUgzRSxNQUZHLENBRUl1QixVQUZKLENBRWU2QixHQUZmLENBRW1CdkMsUUFGbkIsQ0FBTjtBQUdELEtBSkMsQ0FBRjtBQU1BRyxJQUFBQSxFQUFFLENBQUMsbURBQUQsRUFBc0Qsa0JBQWtCO0FBQ3hFLFlBQU15RCxNQUFNLEdBQUcsc3FCQUFmO0FBQ0EsWUFBTUQsY0FBUVQscUJBQVIsQ0FBOEJsRCxRQUE5QixFQUF3QztBQUM1QytELFFBQUFBLHlCQUF5QixFQUFFO0FBRGlCLE9BQXhDLEVBRUg1RSxNQUZHLENBRUl1QixVQUZKLENBRWU2QixHQUZmLENBRW1CcUIsTUFGbkIsQ0FBTjtBQUdELEtBTEMsQ0FBRjtBQU9BekQsSUFBQUEsRUFBRSxDQUFDLG1FQUFELEVBQXNFLGtCQUFrQjtBQUN4RixZQUFNeUQsTUFBTSxHQUFHLHM0QkFBZjtBQUNBLFlBQU1ELGNBQVFULHFCQUFSLENBQThCbEQsUUFBOUIsRUFBd0M7QUFDNUMrRCxRQUFBQSx5QkFBeUIsRUFBRSxHQURpQjtBQUU1Q2IsUUFBQUEscUJBQXFCLEVBQUUsSUFGcUI7QUFHNUNXLFFBQUFBLE1BQU0sRUFBRSxHQUhvQztBQUcvQkMsUUFBQUEsTUFBTSxFQUFFO0FBSHVCLE9BQXhDLEVBSUgzRSxNQUpHLENBSUl1QixVQUpKLENBSWU2QixHQUpmLENBSW1CcUIsTUFKbkIsQ0FBTjtBQUtELEtBUEMsQ0FBRjtBQVNBekQsSUFBQUEsRUFBRSxDQUFDLHVFQUFELEVBQTBFLGtCQUFrQjtBQUM1RixZQUFNeUQsTUFBTSxHQUFHLHNxQkFBZjtBQUNBLFlBQU1ELGNBQVFULHFCQUFSLENBQThCbEQsUUFBOUIsRUFBd0M7QUFDNUMrRCxRQUFBQSx5QkFBeUIsRUFBRSxHQURpQjtBQUU1Q2IsUUFBQUEscUJBQXFCLEVBQUUsS0FGcUI7QUFHNUNXLFFBQUFBLE1BQU0sRUFBRSxHQUhvQztBQUcvQkMsUUFBQUEsTUFBTSxFQUFFO0FBSHVCLE9BQXhDLEVBSUgzRSxNQUpHLENBSUl1QixVQUpKLENBSWU2QixHQUpmLENBSW1CcUIsTUFKbkIsQ0FBTjtBQUtELEtBUEMsQ0FBRjtBQVNBekQsSUFBQUEsRUFBRSxDQUFDLCtFQUFELEVBQWtGLGtCQUFrQjtBQUNwRyxZQUFNd0QsY0FBUVQscUJBQVIsQ0FBOEJsRCxRQUE5QixFQUF3QztBQUM1QytELFFBQUFBLHlCQUF5QixFQUFFLEdBRGlCO0FBRTVDQyxRQUFBQSwrQkFBK0IsRUFBRTtBQUZXLE9BQXhDLEVBR0g3RSxNQUhHLENBR0l1QixVQUhKLENBR2U2QixHQUhmLENBR21CdkMsUUFIbkIsQ0FBTjtBQUlELEtBTEMsQ0FBRjtBQU9BRyxJQUFBQSxFQUFFLENBQUMsK0dBQUQsRUFBa0gsa0JBQWtCO0FBQ3BJLFlBQU15RCxNQUFNLEdBQUcsc01BQWY7QUFDQSxZQUFNRCxjQUFRVCxxQkFBUixDQUE4QmxELFFBQTlCLEVBQXdDO0FBQzVDK0QsUUFBQUEseUJBQXlCLEVBQUUsR0FEaUI7QUFFNUNDLFFBQUFBLCtCQUErQixFQUFFLElBRlc7QUFHNUNkLFFBQUFBLHFCQUFxQixFQUFFLElBSHFCO0FBSTVDVyxRQUFBQSxNQUFNLEVBQUUsR0FKb0M7QUFJL0JDLFFBQUFBLE1BQU0sRUFBRTtBQUp1QixPQUF4QyxFQUtIM0UsTUFMRyxDQUtJdUIsVUFMSixDQUtlNkIsR0FMZixDQUttQnFCLE1BTG5CLENBQU47QUFNRCxLQVJDLENBQUY7QUFTRCxHQXpFTyxDQUFSO0FBMkVBMUQsRUFBQUEsUUFBUSxDQUFDLG9CQUFELEVBQXVCLFlBQVk7QUFDekNDLElBQUFBLEVBQUUsQ0FBQyxpRUFBRCxFQUFvRSxrQkFBa0I7QUFDdEYsWUFBTThELE1BQU0sR0FBR2hFLGFBQWEsQ0FBQ2lFLEdBQWQsQ0FBa0JDLENBQUMsSUFBSUEsQ0FBQyxHQUFHLENBQTNCLENBQWY7QUFDQSxZQUFNL0QsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBLFlBQU1hLENBQUMsQ0FBQ2dFLGtCQUFGLENBQXFCcEUsUUFBckIsRUFBK0IsR0FBR2lFLE1BQWxDLEVBQ0g5RSxNQURHLENBQ0l1QixVQURKLENBQ2U2QixHQURmLENBQ21CdkMsUUFEbkIsQ0FBTjtBQUVELEtBTEMsQ0FBRjtBQU1BRyxJQUFBQSxFQUFFLENBQUMscUVBQUQsRUFBd0Usa0JBQWtCO0FBQzFGLFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7QUFDQSxZQUFNYSxDQUFDLENBQUNnRSxrQkFBRixDQUFxQnBFLFFBQXJCLEVBQStCLEdBQUdDLGFBQWxDLEVBQ0hkLE1BREcsQ0FDSXVCLFVBREosQ0FDZTZCLEdBRGYsQ0FDbUJ2QyxRQURuQixDQUFOO0FBRUQsS0FKQyxDQUFGO0FBS0FHLElBQUFBLEVBQUUsQ0FBQyw0REFBRCxFQUErRCxrQkFBa0I7QUFDakYsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjtBQUNBLFlBQU0wRSxNQUFNLEdBQUdoRSxhQUFhLENBQUNpRSxHQUFkLENBQWtCQyxDQUFDLElBQUlBLENBQUMsR0FBRyxDQUEzQixDQUFmO0FBQ0EsWUFBTXRCLFdBQVcsR0FBRyxNQUFNekMsQ0FBQyxDQUFDZ0Usa0JBQUYsQ0FBcUJwRSxRQUFyQixFQUErQixHQUFHaUUsTUFBbEMsQ0FBMUI7QUFDQXBCLE1BQUFBLFdBQVcsQ0FBQzFELE1BQVosQ0FBbUJrRixHQUFuQixDQUF1QjlCLEdBQXZCLENBQTJCdkMsUUFBM0I7QUFDQTZDLE1BQUFBLFdBQVcsQ0FBQ0QsTUFBWixDQUFtQnpELE1BQW5CLENBQTBCd0IsRUFBMUIsQ0FBNkIyRCxLQUE3QixDQUFtQ3RFLFFBQVEsQ0FBQzRDLE1BQTVDO0FBQ0QsS0FOQyxDQUFGO0FBT0QsR0FuQk8sQ0FBUjtBQXFCQTFDLEVBQUFBLFFBQVEsQ0FBQywyQkFBRCxFQUE4QixZQUFZO0FBQ2hEQyxJQUFBQSxFQUFFLENBQUMsc0RBQUQsRUFBeUQsa0JBQWtCO0FBQzNFLFlBQU1DLENBQUMsR0FBRyxJQUFJWixZQUFKLEVBQVY7QUFDQSxZQUFNWSxDQUFDLENBQUNtRSx5QkFBRixHQUNIcEYsTUFERyxDQUNJdUIsVUFESixDQUNlQyxFQURmLENBQ2tCSSxZQURsQixDQUMrQix5QkFEL0IsQ0FBTjtBQUVELEtBSkMsQ0FBRjtBQUtBWixJQUFBQSxFQUFFLENBQUMsb0VBQUQsRUFBdUUsa0JBQWtCO0FBQ3pGLFlBQU1DLENBQUMsR0FBRyxJQUFJYixVQUFKLEVBQVY7O0FBQ0FjLHFCQUFNQyxJQUFOLENBQVdGLENBQVgsRUFBYyxlQUFkLEVBQStCRyxPQUEvQixDQUF1Q1AsUUFBdkM7O0FBQ0FJLE1BQUFBLENBQUMsQ0FBQzBDLFFBQUYsQ0FBV0MsTUFBWCxDQUFrQjtBQUFDeUIsUUFBQUEsMEJBQTBCLEVBQUU7QUFBN0IsT0FBbEI7QUFDQSxZQUFNUCxNQUFNLEdBQUdoRSxhQUFhLENBQUNpRSxHQUFkLENBQWtCQyxDQUFDLElBQUlBLENBQUMsR0FBRyxDQUEzQixDQUFmO0FBQ0EsWUFBTTtBQUFDTSxRQUFBQSxhQUFEO0FBQWdCQyxRQUFBQTtBQUFoQixVQUF5QixNQUFNdEUsQ0FBQyxDQUFDbUUseUJBQUYsQ0FBNEIsR0FBR04sTUFBL0IsQ0FBckM7QUFDQVEsTUFBQUEsYUFBYSxDQUFDdEYsTUFBZCxDQUFxQm9ELEdBQXJCLENBQXlCdkMsUUFBekI7QUFDQWIsTUFBQUEsTUFBTSxDQUFDd0YsS0FBUCxDQUFhRCxLQUFiLEVBQW9CRSxTQUFwQjtBQUNELEtBUkMsQ0FBRjtBQVNBekUsSUFBQUEsRUFBRSxDQUFDLHVFQUFELEVBQTBFLGtCQUFrQjtBQUM1RixZQUFNQyxDQUFDLEdBQUcsSUFBSWIsVUFBSixFQUFWOztBQUNBYyxxQkFBTUMsSUFBTixDQUFXRixDQUFYLEVBQWMsZUFBZCxFQUErQkcsT0FBL0IsQ0FBdUNQLFFBQXZDOztBQUNBLFlBQU07QUFBQ3lFLFFBQUFBLGFBQUQ7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCLE1BQU10RSxDQUFDLENBQUNtRSx5QkFBRixDQUE0QixHQUFHdEUsYUFBL0IsQ0FBckM7QUFDQXdFLE1BQUFBLGFBQWEsQ0FBQ3RGLE1BQWQsQ0FBcUJvRCxHQUFyQixDQUF5QnZDLFFBQXpCO0FBQ0FiLE1BQUFBLE1BQU0sQ0FBQ3dGLEtBQVAsQ0FBYUQsS0FBYixFQUFvQkUsU0FBcEI7QUFDRCxLQU5DLENBQUY7QUFPQXpFLElBQUFBLEVBQUUsQ0FBQyx3RkFBRCxFQUEyRixrQkFBa0I7QUFDN0csWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjs7QUFDQWMscUJBQU1DLElBQU4sQ0FBV0YsQ0FBWCxFQUFjLGVBQWQsRUFBK0JHLE9BQS9CLENBQXVDUCxRQUF2Qzs7QUFDQSxZQUFNaUUsTUFBTSxHQUFHaEUsYUFBYSxDQUFDaUUsR0FBZCxDQUFrQkMsQ0FBQyxJQUFJQSxDQUFDLEdBQUcsR0FBM0IsQ0FBZjtBQUNBLFlBQU07QUFBQ00sUUFBQUEsYUFBRDtBQUFnQkMsUUFBQUE7QUFBaEIsVUFBeUIsTUFBTXRFLENBQUMsQ0FBQ21FLHlCQUFGLENBQTRCLEdBQUdOLE1BQS9CLENBQXJDO0FBQ0FRLE1BQUFBLGFBQWEsQ0FBQ3RGLE1BQWQsQ0FBcUJrRixHQUFyQixDQUF5QjlCLEdBQXpCLENBQTZCdkMsUUFBN0I7QUFDQSxZQUFNNkUsYUFBYSxHQUFHLE1BQU1DLHlCQUFVQyxZQUFWLENBQXVCTixhQUF2QixDQUE1QjtBQUNBSSxNQUFBQSxhQUFhLENBQUNHLE1BQWQsQ0FBcUI1RCxLQUFyQixDQUEyQmpDLE1BQTNCLENBQWtDb0QsR0FBbEMsQ0FBc0MwQixNQUFNLENBQUMsQ0FBRCxDQUE1QztBQUNBWSxNQUFBQSxhQUFhLENBQUNHLE1BQWQsQ0FBcUIzRCxNQUFyQixDQUE0QmxDLE1BQTVCLENBQW1Db0QsR0FBbkMsQ0FBdUMwQixNQUFNLENBQUMsQ0FBRCxDQUE3QztBQUNBUyxNQUFBQSxLQUFLLENBQUN2RixNQUFOLENBQWFvRCxHQUFiLENBQWlCO0FBQUVzQixRQUFBQSxNQUFNLEVBQUUsR0FBVjtBQUFlQyxRQUFBQSxNQUFNLEVBQUU7QUFBdkIsT0FBakI7QUFDRCxLQVZDLENBQUY7QUFXQTNELElBQUFBLEVBQUUsQ0FBQyxpR0FBRCxFQUFvRyxrQkFBa0I7QUFDdEgsWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjs7QUFDQWMscUJBQU1DLElBQU4sQ0FBV0YsQ0FBWCxFQUFjLGVBQWQsRUFBK0JHLE9BQS9CLENBQXVDUCxRQUF2Qzs7QUFHQSxVQUFJaUUsTUFBTSxHQUFHLENBQUNoRSxhQUFhLENBQUMsQ0FBRCxDQUFiLEdBQW1CLENBQXBCLEVBQXVCQSxhQUFhLENBQUMsQ0FBRCxDQUFiLEdBQW1CLENBQTFDLENBQWI7QUFDQSxVQUFJZ0YsYUFBYSxHQUFHO0FBQUVwQixRQUFBQSxNQUFNLEVBQUUsSUFBVjtBQUFnQkMsUUFBQUEsTUFBTSxFQUFFO0FBQXhCLE9BQXBCO0FBRUEsWUFBTTtBQUFDVyxRQUFBQSxhQUFEO0FBQWdCQyxRQUFBQTtBQUFoQixVQUF5QixNQUFNdEUsQ0FBQyxDQUFDbUUseUJBQUYsQ0FBNEIsR0FBR04sTUFBL0IsQ0FBckM7QUFDQVEsTUFBQUEsYUFBYSxDQUFDdEYsTUFBZCxDQUFxQmtGLEdBQXJCLENBQXlCOUIsR0FBekIsQ0FBNkJ2QyxRQUE3QjtBQUNBLFVBQUk2RSxhQUFhLEdBQUcsTUFBTUMseUJBQVVDLFlBQVYsQ0FBdUJOLGFBQXZCLENBQTFCO0FBQ0FJLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjVELEtBQXJCLENBQTJCakMsTUFBM0IsQ0FBa0NvRCxHQUFsQyxDQUFzQzBCLE1BQU0sQ0FBQyxDQUFELENBQTVDO0FBQ0FZLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjNELE1BQXJCLENBQTRCbEMsTUFBNUIsQ0FBbUNvRCxHQUFuQyxDQUF1QzBCLE1BQU0sQ0FBQyxDQUFELENBQTdDO0FBQ0FTLE1BQUFBLEtBQUssQ0FBQ2IsTUFBTixDQUFhcUIsT0FBYixDQUFxQixDQUFyQixFQUF3Qi9GLE1BQXhCLENBQStCb0QsR0FBL0IsQ0FBbUMwQyxhQUFhLENBQUNwQixNQUFkLENBQXFCc0IsUUFBckIsRUFBbkM7QUFDQVQsTUFBQUEsS0FBSyxDQUFDWixNQUFOLENBQWEzRSxNQUFiLENBQW9Cb0QsR0FBcEIsQ0FBd0IwQyxhQUFhLENBQUNuQixNQUF0QztBQUdBRyxNQUFBQSxNQUFNLEdBQUcsQ0FBQ2hFLGFBQWEsQ0FBQyxDQUFELENBQWIsR0FBbUIsQ0FBcEIsRUFBdUJBLGFBQWEsQ0FBQyxDQUFELENBQWIsR0FBbUIsQ0FBMUMsQ0FBVDtBQUNBZ0YsTUFBQUEsYUFBYSxHQUFHO0FBQUVwQixRQUFBQSxNQUFNLEVBQUUsQ0FBVjtBQUFhQyxRQUFBQSxNQUFNLEVBQUU7QUFBckIsT0FBaEI7QUFFQSxZQUFNO0FBQUNXLFFBQUFBLGFBQWEsRUFBRVcsU0FBaEI7QUFBMkJWLFFBQUFBLEtBQUssRUFBRVc7QUFBbEMsVUFBOEMsTUFBTWpGLENBQUMsQ0FBQ21FLHlCQUFGLENBQTRCLEdBQUdOLE1BQS9CLENBQTFEO0FBQ0FtQixNQUFBQSxTQUFTLENBQUNqRyxNQUFWLENBQWlCa0YsR0FBakIsQ0FBcUI5QixHQUFyQixDQUF5QnZDLFFBQXpCO0FBQ0E2RSxNQUFBQSxhQUFhLEdBQUcsTUFBTUMseUJBQVVDLFlBQVYsQ0FBdUJLLFNBQXZCLENBQXRCO0FBQ0FQLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjVELEtBQXJCLENBQTJCakMsTUFBM0IsQ0FBa0NvRCxHQUFsQyxDQUFzQzBCLE1BQU0sQ0FBQyxDQUFELENBQTVDO0FBQ0FZLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjNELE1BQXJCLENBQTRCbEMsTUFBNUIsQ0FBbUNvRCxHQUFuQyxDQUF1QzBCLE1BQU0sQ0FBQyxDQUFELENBQTdDO0FBQ0FvQixNQUFBQSxRQUFRLENBQUN4QixNQUFULENBQWdCMUUsTUFBaEIsQ0FBdUJvRCxHQUF2QixDQUEyQjBDLGFBQWEsQ0FBQ3BCLE1BQXpDO0FBQ0F3QixNQUFBQSxRQUFRLENBQUN2QixNQUFULENBQWdCb0IsT0FBaEIsQ0FBd0IsQ0FBeEIsRUFBMkIvRixNQUEzQixDQUFrQ29ELEdBQWxDLENBQXNDMEMsYUFBYSxDQUFDbkIsTUFBZCxDQUFxQnFCLFFBQXJCLEVBQXRDO0FBQ0QsS0EzQkMsQ0FBRjtBQTZCQWhGLElBQUFBLEVBQUUsQ0FBQyw0SEFBRCxFQUErSCxrQkFBa0I7QUFDakosWUFBTUMsQ0FBQyxHQUFHLElBQUliLFVBQUosRUFBVjs7QUFDQWMscUJBQU1DLElBQU4sQ0FBV0YsQ0FBWCxFQUFjLGVBQWQsRUFBK0JHLE9BQS9CLENBQXVDUCxRQUF2Qzs7QUFHQSxVQUFJaUUsTUFBTSxHQUFHLENBQUNoRSxhQUFhLENBQUMsQ0FBRCxDQUFiLEdBQW1CLENBQXBCLEVBQXVCQSxhQUFhLENBQUMsQ0FBRCxDQUFiLEdBQW1CLENBQTFDLENBQWI7QUFDQSxVQUFJZ0YsYUFBYSxHQUFHO0FBQUVwQixRQUFBQSxNQUFNLEVBQUUsSUFBVjtBQUFnQkMsUUFBQUEsTUFBTSxFQUFFO0FBQXhCLE9BQXBCO0FBRUEsWUFBTTtBQUFDVyxRQUFBQSxhQUFEO0FBQWdCQyxRQUFBQTtBQUFoQixVQUF5QixNQUFNdEUsQ0FBQyxDQUFDbUUseUJBQUYsQ0FBNEIsR0FBR04sTUFBL0IsQ0FBckM7QUFDQVEsTUFBQUEsYUFBYSxDQUFDdEYsTUFBZCxDQUFxQmtGLEdBQXJCLENBQXlCOUIsR0FBekIsQ0FBNkJ2QyxRQUE3QjtBQUNBLFVBQUk2RSxhQUFhLEdBQUcsTUFBTUMseUJBQVVDLFlBQVYsQ0FBdUJOLGFBQXZCLENBQTFCO0FBQ0FJLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjVELEtBQXJCLENBQTJCakMsTUFBM0IsQ0FBa0NvRCxHQUFsQyxDQUFzQzBCLE1BQU0sQ0FBQyxDQUFELENBQTVDO0FBQ0FZLE1BQUFBLGFBQWEsQ0FBQ0csTUFBZCxDQUFxQjNELE1BQXJCLENBQTRCbEMsTUFBNUIsQ0FBbUNvRCxHQUFuQyxDQUF1QzBCLE1BQU0sQ0FBQyxDQUFELENBQTdDO0FBQ0FTLE1BQUFBLEtBQUssQ0FBQ2IsTUFBTixDQUFhcUIsT0FBYixDQUFxQixDQUFyQixFQUF3Qi9GLE1BQXhCLENBQStCb0QsR0FBL0IsQ0FBbUMwQyxhQUFhLENBQUNwQixNQUFkLENBQXFCc0IsUUFBckIsRUFBbkM7QUFDQVQsTUFBQUEsS0FBSyxDQUFDWixNQUFOLENBQWEzRSxNQUFiLENBQW9Cb0QsR0FBcEIsQ0FBd0IwQyxhQUFhLENBQUNuQixNQUF0QztBQUVBLFlBQU1ILGNBQVFULHFCQUFSLENBQThCdUIsYUFBOUIsRUFBNkM7QUFBQ3ZCLFFBQUFBLHFCQUFxQixFQUFFLElBQXhCO0FBQThCd0IsUUFBQUE7QUFBOUIsT0FBN0MsRUFDSHZGLE1BREcsQ0FDSXVCLFVBREosQ0FDZTZCLEdBRGYsQ0FDbUIsa0lBRG5CLENBQU47QUFJQTBCLE1BQUFBLE1BQU0sR0FBRyxDQUFDaEUsYUFBYSxDQUFDLENBQUQsQ0FBYixHQUFtQixDQUFwQixFQUF1QkEsYUFBYSxDQUFDLENBQUQsQ0FBYixHQUFtQixDQUExQyxDQUFUO0FBQ0FnRixNQUFBQSxhQUFhLEdBQUc7QUFBRXBCLFFBQUFBLE1BQU0sRUFBRSxDQUFWO0FBQWFDLFFBQUFBLE1BQU0sRUFBRTtBQUFyQixPQUFoQjtBQUVBLFlBQU07QUFBQ1csUUFBQUEsYUFBYSxFQUFFVyxTQUFoQjtBQUEyQlYsUUFBQUEsS0FBSyxFQUFFVztBQUFsQyxVQUE4QyxNQUFNakYsQ0FBQyxDQUFDbUUseUJBQUYsQ0FBNEIsR0FBR04sTUFBL0IsQ0FBMUQ7QUFDQW1CLE1BQUFBLFNBQVMsQ0FBQ2pHLE1BQVYsQ0FBaUJrRixHQUFqQixDQUFxQjlCLEdBQXJCLENBQXlCdkMsUUFBekI7QUFDQTZFLE1BQUFBLGFBQWEsR0FBRyxNQUFNQyx5QkFBVUMsWUFBVixDQUF1QkssU0FBdkIsQ0FBdEI7QUFDQVAsTUFBQUEsYUFBYSxDQUFDRyxNQUFkLENBQXFCNUQsS0FBckIsQ0FBMkJqQyxNQUEzQixDQUFrQ29ELEdBQWxDLENBQXNDMEIsTUFBTSxDQUFDLENBQUQsQ0FBNUM7QUFDQVksTUFBQUEsYUFBYSxDQUFDRyxNQUFkLENBQXFCM0QsTUFBckIsQ0FBNEJsQyxNQUE1QixDQUFtQ29ELEdBQW5DLENBQXVDMEIsTUFBTSxDQUFDLENBQUQsQ0FBN0M7QUFDQW9CLE1BQUFBLFFBQVEsQ0FBQ3hCLE1BQVQsQ0FBZ0IxRSxNQUFoQixDQUF1Qm9ELEdBQXZCLENBQTJCMEMsYUFBYSxDQUFDcEIsTUFBekM7QUFDQXdCLE1BQUFBLFFBQVEsQ0FBQ3ZCLE1BQVQsQ0FBZ0JvQixPQUFoQixDQUF3QixDQUF4QixFQUEyQi9GLE1BQTNCLENBQWtDb0QsR0FBbEMsQ0FBc0MwQyxhQUFhLENBQUNuQixNQUFkLENBQXFCcUIsUUFBckIsRUFBdEM7QUFFQSxZQUFNeEIsY0FBUVQscUJBQVIsQ0FBOEJrQyxTQUE5QixFQUF5QztBQUFDbEMsUUFBQUEscUJBQXFCLEVBQUUsSUFBeEI7QUFBOEJ3QixRQUFBQTtBQUE5QixPQUF6QyxFQUNIdkYsTUFERyxDQUNJdUIsVUFESixDQUNlNkIsR0FEZixDQUNtQiw4SEFEbkIsQ0FBTjtBQUVELEtBakNDLENBQUY7QUFtQ0QsR0FqR08sQ0FBUjtBQWtHRCxDQTVUTyxDQUFSO0FBOFRBckMsUUFBUSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFFckRDLEVBQUFBLEVBQUUsQ0FBQyxvREFBRCxFQUF1RCxrQkFBa0I7QUFDekUsVUFBTUMsQ0FBQyxHQUFHLElBQUlaLFlBQUosRUFBVjtBQUNBWSxJQUFBQSxDQUFDLENBQUNrRixJQUFGLENBQU9DLGlCQUFQLEdBQTJCO0FBQUNDLE1BQUFBLENBQUMsRUFBRTdGO0FBQUosS0FBM0I7QUFDQSxVQUFNUyxDQUFDLENBQUNJLFdBQUYsQ0FBY2lGLHFCQUFkLEVBQStCLE9BQS9CLEVBQXdDdEcsTUFBeEMsQ0FBK0N1QixVQUEvQyxDQUEwRDZCLEdBQTFELENBQThELEtBQTlELENBQU47QUFDRCxHQUpDLENBQUY7QUFLQXBDLEVBQUFBLEVBQUUsQ0FBQywwRUFBRCxFQUE2RSxrQkFBa0I7QUFDL0YsVUFBTUMsQ0FBQyxHQUFHLElBQUlaLFlBQUosRUFBVjtBQUNBWSxJQUFBQSxDQUFDLENBQUNrRixJQUFGLENBQU9DLGlCQUFQLEdBQTJCO0FBQUNDLE1BQUFBLENBQUMsRUFBRTdGO0FBQUosS0FBM0I7QUFDQSxVQUFNUyxDQUFDLENBQUNJLFdBQUYsQ0FBY2lGLHFCQUFkLEVBQStCLEtBQS9CLEVBQXNDdEcsTUFBdEMsQ0FBNkN1QixVQUE3QyxDQUF3RDZCLEdBQXhELENBQTRELEtBQTVELENBQU47QUFDRCxHQUpDLENBQUY7QUFLQXBDLEVBQUFBLEVBQUUsQ0FBQyxxREFBRCxFQUF3RCxrQkFBa0I7QUFDMUUsVUFBTUMsQ0FBQyxHQUFHLElBQUlaLFlBQUosRUFBVjtBQUNBWSxJQUFBQSxDQUFDLENBQUNrRixJQUFGLENBQU9DLGlCQUFQLEdBQTJCO0FBQUNDLE1BQUFBLENBQUMsRUFBRTdGO0FBQUosS0FBM0I7QUFDQSxVQUFNUyxDQUFDLENBQUNTLFlBQUYsQ0FBZTRFLHFCQUFmLEVBQWdDLFFBQWhDLEVBQTBDdEcsTUFBMUMsQ0FBaUR1QixVQUFqRCxDQUE0RDZCLEdBQTVELENBQWdFLENBQUMsTUFBRCxFQUFTLE1BQVQsQ0FBaEUsQ0FBTjtBQUNELEdBSkMsQ0FBRjtBQUtBcEMsRUFBQUEsRUFBRSxDQUFDLHVFQUFELEVBQTBFLGtCQUFrQjtBQUM1RixVQUFNQyxDQUFDLEdBQUcsSUFBSVosWUFBSixFQUFWO0FBQ0FZLElBQUFBLENBQUMsQ0FBQ2tGLElBQUYsQ0FBT0MsaUJBQVAsR0FBMkI7QUFBQ0MsTUFBQUEsQ0FBQyxFQUFFN0Y7QUFBSixLQUEzQjtBQUNBLFVBQU1TLENBQUMsQ0FBQ0ksV0FBRixDQUFjaUYscUJBQWQsRUFBK0IsUUFBL0IsRUFBeUN0RyxNQUF6QyxDQUFnRHVCLFVBQWhELENBQTJENkIsR0FBM0QsQ0FBK0QsTUFBL0QsQ0FBTjtBQUNELEdBSkMsQ0FBRjtBQUtBcEMsRUFBQUEsRUFBRSxDQUFDLDZDQUFELEVBQWdELGtCQUFrQjtBQUNsRSxVQUFNQyxDQUFDLEdBQUcsSUFBSVosWUFBSixFQUFWO0FBQ0FZLElBQUFBLENBQUMsQ