From 8278abef75caca0fdc89fc0499e0514abe583c1a Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Thu, 30 Apr 2026 14:57:23 -0600 Subject: [PATCH 1/9] Linting/formatting --- test/jasmine/tests/shapes_test.js | 2044 +++++++++++++++-------------- 1 file changed, 1075 insertions(+), 969 deletions(-) diff --git a/test/jasmine/tests/shapes_test.js b/test/jasmine/tests/shapes_test.js index a0a398d5f4f..60284c2a54f 100644 --- a/test/jasmine/tests/shapes_test.js +++ b/test/jasmine/tests/shapes_test.js @@ -19,11 +19,11 @@ var assertElemTopsAligned = customAssertions.assertElemTopsAligned; var assertElemInside = customAssertions.assertElemInside; // Reusable vars -var shapeTypes = [{type: 'rect'}, {type: 'circle'}, {type: 'line'}]; +var shapeTypes = [{ type: 'rect' }, { type: 'circle' }, { type: 'line' }]; var resizeDirections = ['n', 's', 'w', 'e', 'nw', 'se', 'ne', 'sw']; var resizeTypes = [ - {resizeType: 'shrink', resizeDisplayName: 'shrunken'}, - {resizeType: 'enlarge', resizeDisplayName: 'enlarged'} + { resizeType: 'shrink', resizeDisplayName: 'shrunken' }, + { resizeType: 'enlarge', resizeDisplayName: 'enlarged' } ]; var dxToShrinkWidth = { n: 0, s: 0, w: 10, e: -10, nw: 10, se: -10, ne: -10, sw: 10 }; var dyToShrinkHeight = { n: 10, s: -10, w: 0, e: 0, nw: 10, se: -10, ne: 10, sw: -10 }; @@ -38,15 +38,19 @@ function getMoveLineDragElement(index) { function getResizeLineOverStartPointElement(index) { index = index || 0; - return d3SelectAll('.shapelayer g[drag-helper][data-index="' + index + '"] circle[data-line-point="start-point"]').node(); + return d3SelectAll( + '.shapelayer g[drag-helper][data-index="' + index + '"] circle[data-line-point="start-point"]' + ).node(); } function getResizeLineOverEndPointElement(index) { index = index || 0; - return d3SelectAll('.shapelayer g[drag-helper][data-index="' + index + '"] circle[data-line-point="end-point"]').node(); + return d3SelectAll( + '.shapelayer g[drag-helper][data-index="' + index + '"] circle[data-line-point="end-point"]' + ).node(); } -describe('Test shapes defaults:', function() { +describe('Test shapes defaults:', function () { 'use strict'; function _supply(layoutIn, layoutOut) { @@ -58,8 +62,8 @@ describe('Test shapes defaults:', function() { return layoutOut.shapes; } - it('should skip non-array containers', function() { - [null, undefined, {}, 'str', 0, false, true].forEach(function(cont) { + it('should skip non-array containers', function () { + [null, undefined, {}, 'str', 0, false, true].forEach(function (cont) { var msg = '- ' + JSON.stringify(cont); var layoutIn = { shapes: cont }; var out = _supply(layoutIn); @@ -69,28 +73,30 @@ describe('Test shapes defaults:', function() { }); }); - it('should make non-object item visible: false', function() { + it('should make non-object item visible: false', function () { var shapes = [null, undefined, [], 'str', 0, false, true]; var layoutIn = { shapes: shapes }; var out = _supply(layoutIn); expect(layoutIn.shapes).toEqual(shapes); - out.forEach(function(item, i) { - expect(item).toEqual(jasmine.objectContaining({ - visible: false, - _index: i - })); + out.forEach(function (item, i) { + expect(item).toEqual( + jasmine.objectContaining({ + visible: false, + _index: i + }) + ); }); }); - it('should provide the right defaults on all axis types', function() { + it('should provide the right defaults on all axis types', function () { var fullLayout = { - xaxis: {type: 'linear', range: [0, 20], _shapeIndices: []}, - yaxis: {type: 'log', range: [1, 5], _shapeIndices: []}, - xaxis2: {type: 'date', range: ['2006-06-05', '2006-06-09'], _shapeIndices: []}, - yaxis2: {type: 'category', range: [-0.5, 7.5], _shapeIndices: []}, - _subplots: {xaxis: ['x', 'x2'], yaxis: ['y', 'y2']} + xaxis: { type: 'linear', range: [0, 20], _shapeIndices: [] }, + yaxis: { type: 'log', range: [1, 5], _shapeIndices: [] }, + xaxis2: { type: 'date', range: ['2006-06-05', '2006-06-09'], _shapeIndices: [] }, + yaxis2: { type: 'category', range: [-0.5, 7.5], _shapeIndices: [] }, + _subplots: { xaxis: ['x', 'x2'], yaxis: ['y', 'y2'] } }; Axes.setConvert(fullLayout.xaxis); @@ -98,8 +104,8 @@ describe('Test shapes defaults:', function() { Axes.setConvert(fullLayout.xaxis2); Axes.setConvert(fullLayout.yaxis2); - var shape1In = {type: 'rect'}; - var shape2In = {type: 'circle', xref: 'x2', yref: 'y2'}; + var shape1In = { type: 'rect' }; + var shape2In = { type: 'circle', xref: 'x2', yref: 'y2' }; var layoutIn = { shapes: [shape1In, shape2In] @@ -127,29 +133,31 @@ describe('Test shapes defaults:', function() { expect(shape2Out.y1).toBeWithin(5.5, 0.001); }); - it('should not coerce line.color and line.dash when line.width is zero', function() { + it('should not coerce line.color and line.dash when line.width is zero', function () { var fullLayout = { - xaxis: {type: 'linear', range: [0, 1], _shapeIndices: []}, - yaxis: {type: 'log', range: [0, 1], _shapeIndices: []}, - _subplots: {xaxis: ['x'], yaxis: ['y']} + xaxis: { type: 'linear', range: [0, 1], _shapeIndices: [] }, + yaxis: { type: 'log', range: [0, 1], _shapeIndices: [] }, + _subplots: { xaxis: ['x'], yaxis: ['y'] } }; Axes.setConvert(fullLayout.xaxis); Axes.setConvert(fullLayout.yaxis); var layoutIn = { - shapes: [{ - type: 'line', - xref: 'xaxis', - yref: 'yaxis', - x0: 0, - x1: 1, - y0: 1, - y1: 10, - line: { - width: 0 + shapes: [ + { + type: 'line', + xref: 'xaxis', + yref: 'yaxis', + x0: 0, + x1: 1, + y0: 1, + y1: 10, + line: { + width: 0 + } } - }] + ] }; var shapes = _supply(layoutIn, fullLayout); @@ -176,8 +184,7 @@ function isShapeInUpperLayer(shape) { } function isShapeInLowerLayer(shape) { - return (shape.xref === 'paper' && shape.yref === 'paper') && - !isShapeInUpperLayer(shape); + return shape.xref === 'paper' && shape.yref === 'paper' && !isShapeInUpperLayer(shape); } function isShapeInSubplot(shape) { @@ -212,13 +219,13 @@ function countShapePathsInSubplots() { return d3SelectAll('.layer-subplot > .shapelayer > .shape-group > path').size(); } -describe('Test shapes:', function() { +describe('Test shapes:', function () { 'use strict'; var mock = require('../../image/mocks/shapes.json'); var gd; - beforeEach(function(done) { + beforeEach(function (done) { gd = createGraphDiv(); var mockData = Lib.extendDeep([], mock.data); @@ -229,81 +236,69 @@ describe('Test shapes:', function() { afterEach(destroyGraphDiv); - describe('*shapeLowerLayer*', function() { - it('has one node', function() { + describe('*shapeLowerLayer*', function () { + it('has one node', function () { expect(countShapeLowerLayerNodes()).toEqual(1); }); - it('has as many *path* nodes as shapes in the lower layer', function() { - expect(countShapePathsInLowerLayer()) - .toEqual(countShapesInLowerLayer(gd)); + it('has as many *path* nodes as shapes in the lower layer', function () { + expect(countShapePathsInLowerLayer()).toEqual(countShapesInLowerLayer(gd)); }); - it('should be able to get relayout', function(done) { - Plotly.relayout(gd, {height: 200, width: 400}) - .then(function() { - expect(countShapeLowerLayerNodes()).toEqual(1); - expect(countShapePathsInLowerLayer()) - .toEqual(countShapesInLowerLayer(gd)); - }) - .then(done, done.fail); + it('should be able to get relayout', function (done) { + Plotly.relayout(gd, { height: 200, width: 400 }) + .then(function () { + expect(countShapeLowerLayerNodes()).toEqual(1); + expect(countShapePathsInLowerLayer()).toEqual(countShapesInLowerLayer(gd)); + }) + .then(done, done.fail); }); }); - describe('*shapeUpperLayer*', function() { - it('has one node', function() { + describe('*shapeUpperLayer*', function () { + it('has one node', function () { expect(countShapeUpperLayerNodes()).toEqual(1); }); - it('has as many *path* nodes as shapes in the upper layer', function() { - expect(countShapePathsInUpperLayer()) - .toEqual(countShapesInUpperLayer(gd)); + it('has as many *path* nodes as shapes in the upper layer', function () { + expect(countShapePathsInUpperLayer()).toEqual(countShapesInUpperLayer(gd)); }); - it('should be able to get relayout', function(done) { - Plotly.relayout(gd, {height: 200, width: 400}) - .then(function() { - expect(countShapeUpperLayerNodes()).toEqual(1); - expect(countShapePathsInUpperLayer()) - .toEqual(countShapesInUpperLayer(gd)); - }) - .then(done, done.fail); + it('should be able to get relayout', function (done) { + Plotly.relayout(gd, { height: 200, width: 400 }) + .then(function () { + expect(countShapeUpperLayerNodes()).toEqual(1); + expect(countShapePathsInUpperLayer()).toEqual(countShapesInUpperLayer(gd)); + }) + .then(done, done.fail); }); }); - describe('each *subplot*', function() { - it('has one *shapelayer*', function() { - expect(countShapeLayerNodesInSubplots()) - .toEqual(countSubplots(gd)); + describe('each *subplot*', function () { + it('has one *shapelayer*', function () { + expect(countShapeLayerNodesInSubplots()).toEqual(countSubplots(gd)); }); - it('has as many *path* nodes as shapes in the subplot', function() { - expect(countShapePathsInSubplots()) - .toEqual(countShapesInSubplots(gd)); + it('has as many *path* nodes as shapes in the subplot', function () { + expect(countShapePathsInSubplots()).toEqual(countShapesInSubplots(gd)); }); - it('should be able to get relayout', function(done) { - Plotly.relayout(gd, {height: 200, width: 400}) - .then(function() { - expect(countShapeLayerNodesInSubplots()) - .toEqual(countSubplots(gd)); - expect(countShapePathsInSubplots()) - .toEqual(countShapesInSubplots(gd)); - }) - .then(done, done.fail); + it('should be able to get relayout', function (done) { + Plotly.relayout(gd, { height: 200, width: 400 }) + .then(function () { + expect(countShapeLayerNodesInSubplots()).toEqual(countSubplots(gd)); + expect(countShapePathsInSubplots()).toEqual(countShapesInSubplots(gd)); + }) + .then(done, done.fail); }); }); function countShapes(gd) { - return gd.layout.shapes ? - gd.layout.shapes.length : - 0; + return gd.layout.shapes ? gd.layout.shapes.length : 0; } function getLastShape(gd) { - return gd.layout.shapes ? - gd.layout.shapes[gd.layout.shapes.length - 1] : - null; + return gd.layout.shapes ? gd.layout.shapes[gd.layout.shapes.length - 1] : null; } Lib.seedPseudoRandom(); @@ -317,106 +312,103 @@ describe('Test shapes:', function() { }; } - describe('Plotly.relayout', function() { - it('should be able to add a shape', function(done) { + describe('Plotly.relayout', function () { + it('should be able to add a shape', function (done) { var pathCount = countShapePathsInUpperLayer(); var index = countShapes(gd); var shape = getRandomShape(); Plotly.relayout(gd, 'shapes[' + index + ']', shape) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount + 1); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 1); + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount + 1); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 1); - // add a shape not at the end of the array - return Plotly.relayout(gd, 'shapes[0]', getRandomShape()); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount + 2); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 2); - }) - .then(done, done.fail); + // add a shape not at the end of the array + return Plotly.relayout(gd, 'shapes[0]', getRandomShape()); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount + 2); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 2); + }) + .then(done, done.fail); }); - it('should be able to remove a shape', function(done) { + it('should be able to remove a shape', function (done) { var pathCount = countShapePathsInUpperLayer(); var index = countShapes(gd); var shape = getRandomShape(); Plotly.relayout(gd, 'shapes[' + index + ']', shape) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount + 1); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 1); + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount + 1); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 1); - return Plotly.relayout(gd, 'shapes[' + index + ']', 'remove'); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount); - expect(countShapes(gd)).toEqual(index); + return Plotly.relayout(gd, 'shapes[' + index + ']', 'remove'); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount); + expect(countShapes(gd)).toEqual(index); - return Plotly.relayout(gd, 'shapes[2].visible', false); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount - 1); - expect(countShapes(gd)).toEqual(index); + return Plotly.relayout(gd, 'shapes[2].visible', false); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount - 1); + expect(countShapes(gd)).toEqual(index); - return Plotly.relayout(gd, 'shapes[1]', null); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(pathCount - 2); - expect(countShapes(gd)).toEqual(index - 1); - }) - .then(done, done.fail); + return Plotly.relayout(gd, 'shapes[1]', null); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(pathCount - 2); + expect(countShapes(gd)).toEqual(index - 1); + }) + .then(done, done.fail); }); - it('should be able to remove all shapes', function(done) { + it('should be able to remove all shapes', function (done) { Plotly.relayout(gd, { shapes: null }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(0); - expect(countShapePathsInLowerLayer()).toEqual(0); - expect(countShapePathsInSubplots()).toEqual(0); - }) - .then(function() { - return Plotly.relayout(gd, {'shapes[0]': getRandomShape()}); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(1); - expect(countShapePathsInLowerLayer()).toEqual(0); - expect(countShapePathsInSubplots()).toEqual(0); - expect(gd.layout.shapes.length).toBe(1); + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(0); + expect(countShapePathsInLowerLayer()).toEqual(0); + expect(countShapePathsInSubplots()).toEqual(0); + }) + .then(function () { + return Plotly.relayout(gd, { 'shapes[0]': getRandomShape() }); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(1); + expect(countShapePathsInLowerLayer()).toEqual(0); + expect(countShapePathsInSubplots()).toEqual(0); + expect(gd.layout.shapes.length).toBe(1); - return Plotly.relayout(gd, {'shapes[0]': null}); - }) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(0); - expect(countShapePathsInLowerLayer()).toEqual(0); - expect(countShapePathsInSubplots()).toEqual(0); - expect(gd.layout.shapes).toBeUndefined(); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { 'shapes[0]': null }); + }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(0); + expect(countShapePathsInLowerLayer()).toEqual(0); + expect(countShapePathsInSubplots()).toEqual(0); + expect(gd.layout.shapes).toBeUndefined(); + }) + .then(done, done.fail); }); - it('can replace the shapes array', function(done) { + it('can replace the shapes array', function (done) { spyOn(Lib, 'warn'); - Plotly.relayout(gd, { shapes: [ - getRandomShape(), - getRandomShape() - ]}) - .then(function() { - expect(countShapePathsInUpperLayer()).toEqual(2); - expect(countShapePathsInLowerLayer()).toEqual(0); - expect(countShapePathsInSubplots()).toEqual(0); - expect(gd.layout.shapes.length).toBe(2); - expect(Lib.warn).not.toHaveBeenCalled(); - }) - .then(done, done.fail); + Plotly.relayout(gd, { shapes: [getRandomShape(), getRandomShape()] }) + .then(function () { + expect(countShapePathsInUpperLayer()).toEqual(2); + expect(countShapePathsInLowerLayer()).toEqual(0); + expect(countShapePathsInSubplots()).toEqual(0); + expect(gd.layout.shapes.length).toBe(2); + expect(Lib.warn).not.toHaveBeenCalled(); + }) + .then(done, done.fail); }); - it('should be able to update a shape layer', function(done) { + it('should be able to update a shape layer', function (done) { var index = countShapes(gd); var astr = 'shapes[' + index + ']'; var shape = getRandomShape(); @@ -426,62 +418,62 @@ describe('Test shapes:', function() { shape.xref = 'paper'; shape.yref = 'paper'; - Plotly.relayout(gd, astr, shape).then(function() { - expect(countShapePathsInLowerLayer()) - .toEqual(shapesInLowerLayer); - expect(countShapePathsInUpperLayer()) - .toEqual(shapesInUpperLayer + 1); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 1); - }) - .then(function() { - shape.layer = 'below'; - return Plotly.relayout(gd, astr + '.layer', shape.layer); - }) - .then(function() { - expect(countShapePathsInLowerLayer()) - .toEqual(shapesInLowerLayer + 1); - expect(countShapePathsInUpperLayer()) - .toEqual(shapesInUpperLayer); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 1); - }) - .then(function() { - shape.layer = 'above'; - return Plotly.relayout(gd, astr + '.layer', shape.layer); - }) - .then(function() { - expect(countShapePathsInLowerLayer()) - .toEqual(shapesInLowerLayer); - expect(countShapePathsInUpperLayer()) - .toEqual(shapesInUpperLayer + 1); - expect(getLastShape(gd)).toEqual(shape); - expect(countShapes(gd)).toEqual(index + 1); - }) - .then(done, done.fail); + Plotly.relayout(gd, astr, shape) + .then(function () { + expect(countShapePathsInLowerLayer()).toEqual(shapesInLowerLayer); + expect(countShapePathsInUpperLayer()).toEqual(shapesInUpperLayer + 1); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 1); + }) + .then(function () { + shape.layer = 'below'; + return Plotly.relayout(gd, astr + '.layer', shape.layer); + }) + .then(function () { + expect(countShapePathsInLowerLayer()).toEqual(shapesInLowerLayer + 1); + expect(countShapePathsInUpperLayer()).toEqual(shapesInUpperLayer); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 1); + }) + .then(function () { + shape.layer = 'above'; + return Plotly.relayout(gd, astr + '.layer', shape.layer); + }) + .then(function () { + expect(countShapePathsInLowerLayer()).toEqual(shapesInLowerLayer); + expect(countShapePathsInUpperLayer()).toEqual(shapesInUpperLayer + 1); + expect(getLastShape(gd)).toEqual(shape); + expect(countShapes(gd)).toEqual(index + 1); + }) + .then(done, done.fail); }); }); }); -describe('shapes axis reference changes', function() { +describe('shapes axis reference changes', function () { 'use strict'; var gd; - beforeEach(function(done) { + beforeEach(function (done) { gd = createGraphDiv(); - Plotly.newPlot(gd, [ - {y: [1, 2, 3]}, - {y: [1, 2, 3], yaxis: 'y2'} - ], { - yaxis: {domain: [0, 0.4]}, - yaxis2: {domain: [0.6, 1]}, - shapes: [{ - xref: 'x', yref: 'paper', type: 'rect', - x0: 0.8, x1: 1.2, y0: 0, y1: 1, - fillcolor: '#eee', layer: 'below' - }] + Plotly.newPlot(gd, [{ y: [1, 2, 3] }, { y: [1, 2, 3], yaxis: 'y2' }], { + yaxis: { domain: [0, 0.4] }, + yaxis2: { domain: [0.6, 1] }, + shapes: [ + { + xref: 'x', + yref: 'paper', + type: 'rect', + x0: 0.8, + x1: 1.2, + y0: 0, + y1: 1, + fillcolor: '#eee', + layer: 'below' + } + ] }).then(done); }); @@ -493,7 +485,7 @@ describe('shapes axis reference changes', function() { return s; } - it('draws the right number of objects and updates clip-path correctly', function(done) { + it('draws the right number of objects and updates clip-path correctly', function (done) { expect(getShape(0).attr('clip-path') || '').toMatch(/x\)$/); Plotly.relayout(gd, { @@ -501,70 +493,88 @@ describe('shapes axis reference changes', function() { 'shapes[0].x0': 0.2, 'shapes[0].x1': 0.6 }) - .then(function() { - expect(getShape(0).attr('clip-path')).toBe(null); + .then(function () { + expect(getShape(0).attr('clip-path')).toBe(null); - return Plotly.relayout(gd, { - 'shapes[0].yref': 'y2', - 'shapes[0].y0': 1.8, - 'shapes[0].y1': 2.2, - }); - }) - .then(function() { - expect(getShape(0).attr('clip-path') || '').toMatch(/^[^x]+y2\)$/); + return Plotly.relayout(gd, { + 'shapes[0].yref': 'y2', + 'shapes[0].y0': 1.8, + 'shapes[0].y1': 2.2 + }); + }) + .then(function () { + expect(getShape(0).attr('clip-path') || '').toMatch(/^[^x]+y2\)$/); - return Plotly.relayout(gd, { - 'shapes[0].xref': 'x', - 'shapes[0].x0': 1.5, - 'shapes[0].x1': 20 - }); - }) - .then(function() { - expect(getShape(0).attr('clip-path') || '').toMatch(/xy2\)$/); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { + 'shapes[0].xref': 'x', + 'shapes[0].x0': 1.5, + 'shapes[0].x1': 20 + }); + }) + .then(function () { + expect(getShape(0).attr('clip-path') || '').toMatch(/xy2\)$/); + }) + .then(done, done.fail); }); }); -describe('shapes edge cases', function() { +describe('shapes edge cases', function () { 'use strict'; var gd; - beforeEach(function() { gd = createGraphDiv(); }); + beforeEach(function () { + gd = createGraphDiv(); + }); afterEach(destroyGraphDiv); - it('falls back on shapeLowerLayer for below missing subplots', function(done) { - Plotly.newPlot(gd, [ - {x: [1, 3], y: [1, 3]}, - {x: [1, 3], y: [1, 3], xaxis: 'x2', yaxis: 'y2'} - ], { - xaxis: {domain: [0, 0.5]}, - yaxis: {domain: [0, 0.5]}, - xaxis2: {domain: [0.5, 1], anchor: 'y2'}, - yaxis2: {domain: [0.5, 1], anchor: 'x2'}, - shapes: [{ - x0: 1, x1: 2, y0: 1, y1: 2, type: 'circle', - layer: 'below', - xref: 'x', - yref: 'y2' - }, { - x0: 1, x1: 2, y0: 1, y1: 2, type: 'circle', - layer: 'below', - xref: 'x2', - yref: 'y' - }] - }).then(function() { - expect(countShapePathsInLowerLayer()).toBe(2); - expect(countShapePathsInUpperLayer()).toBe(0); - expect(countShapePathsInSubplots()).toBe(0); - }) - .then(done, done.fail); + it('falls back on shapeLowerLayer for below missing subplots', function (done) { + Plotly.newPlot( + gd, + [ + { x: [1, 3], y: [1, 3] }, + { x: [1, 3], y: [1, 3], xaxis: 'x2', yaxis: 'y2' } + ], + { + xaxis: { domain: [0, 0.5] }, + yaxis: { domain: [0, 0.5] }, + xaxis2: { domain: [0.5, 1], anchor: 'y2' }, + yaxis2: { domain: [0.5, 1], anchor: 'x2' }, + shapes: [ + { + x0: 1, + x1: 2, + y0: 1, + y1: 2, + type: 'circle', + layer: 'below', + xref: 'x', + yref: 'y2' + }, + { + x0: 1, + x1: 2, + y0: 1, + y1: 2, + type: 'circle', + layer: 'below', + xref: 'x2', + yref: 'y' + } + ] + } + ) + .then(function () { + expect(countShapePathsInLowerLayer()).toBe(2); + expect(countShapePathsInUpperLayer()).toBe(0); + expect(countShapePathsInSubplots()).toBe(0); + }) + .then(done, done.fail); }); }); -describe('shapes autosize', function() { +describe('shapes autosize', function () { var gd; afterEach(destroyGraphDiv); @@ -576,94 +586,104 @@ describe('shapes autosize', function() { expect(fullLayout.yaxis.range).toBeCloseToArray(y, PREC, msg + ' - yaxis'); } - it('should adapt to relayout calls', function(done) { + it('should adapt to relayout calls', function (done) { gd = createGraphDiv(); var mock = { data: [{}], layout: { - shapes: [{ - type: 'line', - x0: 0, - y0: 0, - x1: 1, - y1: 1 - }, { - type: 'line', - x0: 0, - y0: 0, - x1: 2, - y1: 2 - }] + shapes: [ + { + type: 'line', + x0: 0, + y0: 0, + x1: 1, + y1: 1 + }, + { + type: 'line', + x0: 0, + y0: 0, + x1: 2, + y1: 2 + } + ] } }; - Plotly.newPlot(gd, mock).then(function() { - assertRanges('base', [0, 2], [0, 2]); - return Plotly.relayout(gd, { 'shapes[1].visible': false }); - }) - .then(function() { - assertRanges('shapes[1] not visible', [0, 1], [0, 1]); + Plotly.newPlot(gd, mock) + .then(function () { + assertRanges('base', [0, 2], [0, 2]); + return Plotly.relayout(gd, { 'shapes[1].visible': false }); + }) + .then(function () { + assertRanges('shapes[1] not visible', [0, 1], [0, 1]); - return Plotly.relayout(gd, { 'shapes[1].visible': true }); - }) - .then(function() { - assertRanges('back to base', [0, 2], [0, 2]); + return Plotly.relayout(gd, { 'shapes[1].visible': true }); + }) + .then(function () { + assertRanges('back to base', [0, 2], [0, 2]); - return Plotly.relayout(gd, { 'shapes[0].x1': 3 }); - }) - .then(function() { - assertRanges('stretched shapes[0]', [0, 3], [0, 2]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { 'shapes[0].x1': 3 }); + }) + .then(function () { + assertRanges('stretched shapes[0]', [0, 3], [0, 2]); + }) + .then(done, done.fail); }); - it('should propagate axis autorange changes when axis ranges are set', function(done) { + it('should propagate axis autorange changes when axis ranges are set', function (done) { gd = createGraphDiv(); - Plotly.newPlot(gd, [{y: [1, 2]}], { - xaxis: {range: [0, 2]}, - yaxis: {range: [0, 2]}, - shapes: [{ - x0: 2, y0: 2, - x1: 3, y1: 3 - }] - }) - .then(function() { - assertRanges('set rng / narrow shape', [0, 2], [0, 2]); - return Plotly.relayout(gd, 'shapes[0].x1', 10); - }) - .then(function() { - assertRanges('set rng / large shape', [0, 2], [0, 2]); - return Plotly.relayout(gd, { - 'xaxis.autorange': true, - 'yaxis.autorange': true - }); - }) - .then(function() { - assertRanges('auto rng / large shape', [-0.61, 10], [0.86, 3]); - return Plotly.relayout(gd, 'shapes[0].x1', 3); - }) - .then(function() { - assertRanges('auto rng / small shape', [-0.18, 3], [0.86, 3]); + Plotly.newPlot(gd, [{ y: [1, 2] }], { + xaxis: { range: [0, 2] }, + yaxis: { range: [0, 2] }, + shapes: [ + { + x0: 2, + y0: 2, + x1: 3, + y1: 3 + } + ] }) - .then(done, done.fail); + .then(function () { + assertRanges('set rng / narrow shape', [0, 2], [0, 2]); + return Plotly.relayout(gd, 'shapes[0].x1', 10); + }) + .then(function () { + assertRanges('set rng / large shape', [0, 2], [0, 2]); + return Plotly.relayout(gd, { + 'xaxis.autorange': true, + 'yaxis.autorange': true + }); + }) + .then(function () { + assertRanges('auto rng / large shape', [-0.61, 10], [0.86, 3]); + return Plotly.relayout(gd, 'shapes[0].x1', 3); + }) + .then(function () { + assertRanges('auto rng / small shape', [-0.18, 3], [0.86, 3]); + }) + .then(done, done.fail); }); }); -describe('Test shapes: a plot with shapes and an overlaid axis', function() { +describe('Test shapes: a plot with shapes and an overlaid axis', function () { 'use strict'; var gd, data, layout; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); - data = [{ - y: [1934.5, 1932.3, 1930.3], - x: ['1947-01-01', '1947-04-01', '1948-07-01'], - type: 'scatter' - }]; + data = [ + { + y: [1934.5, 1932.3, 1930.3], + x: ['1947-01-01', '1947-04-01', '1948-07-01'], + type: 'scatter' + } + ]; layout = { yaxis: { @@ -676,47 +696,51 @@ describe('Test shapes: a plot with shapes and an overlaid axis', function() { side: 'right', overlaying: 'y' }, - shapes: [{ - fillcolor: '#ccc', - type: 'rect', - x0: '1947-01-01', - x1: '1947-04-01', - xref: 'x', - y0: 0, - y1: 1, - yref: 'paper', - layer: 'below' - }, { - type: 'path', - xref: 'x', - yref: 'y2', - path: 'M1947-01-01_12:00,2V4H1947-03-01Z' - }, { - type: 'rect', - xref: 'x', - yref: 'y2', - x0: '1947-02-01', - x1: '1947-03-01', - y0: 3, - y1: 5, - layer: 'below' - }, { - type: 'circle', - xref: 'x', - yref: 'y', - x0: '1947-01-15', - x1: '1947-02-15', - y0: 1931, - y1: 1934 - }] + shapes: [ + { + fillcolor: '#ccc', + type: 'rect', + x0: '1947-01-01', + x1: '1947-04-01', + xref: 'x', + y0: 0, + y1: 1, + yref: 'paper', + layer: 'below' + }, + { + type: 'path', + xref: 'x', + yref: 'y2', + path: 'M1947-01-01_12:00,2V4H1947-03-01Z' + }, + { + type: 'rect', + xref: 'x', + yref: 'y2', + x0: '1947-02-01', + x1: '1947-03-01', + y0: 3, + y1: 5, + layer: 'below' + }, + { + type: 'circle', + xref: 'x', + yref: 'y', + x0: '1947-01-15', + x1: '1947-02-15', + y0: 1931, + y1: 1934 + } + ] }; }); afterEach(destroyGraphDiv); - it('should not throw an exception', function(done) { - Plotly.newPlot(gd, data, layout) - .then(done, done.fail); + it('should not throw an exception', function (done) { + Plotly.newPlot(gd, data, layout).then(done, done.fail); }); }); @@ -735,94 +759,102 @@ function assertShapeFullyVisible(shapeElem) { assertElemInside(shapeElem, gridLayer, 'shape element fully visible'); } -describe('A path shape sized relative to data', function() { +describe('A path shape sized relative to data', function () { 'use strict'; var gd, data, layout; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); - data = [{ - x: [1, 5], - y: [1, 5], - type: 'scatter' - }]; + data = [ + { + x: [1, 5], + y: [1, 5], + type: 'scatter' + } + ]; layout = { title: { text: 'Path shape sized relative to data' }, width: 400, height: 400, - shapes: [{ - type: 'path', - xref: 'x', - yref: 'y', - xsizemode: 'data', - ysizemode: 'data', - path: 'M10,0 L2,10 L1,0 Z', - - // Hint: set those too intentionally - xanchor: '3', - yanchor: '0', - x0: 1, - x1: 3, - y0: 1, - y1: 3 - }] + shapes: [ + { + type: 'path', + xref: 'x', + yref: 'y', + xsizemode: 'data', + ysizemode: 'data', + path: 'M10,0 L2,10 L1,0 Z', + + // Hint: set those too intentionally + xanchor: '3', + yanchor: '0', + x0: 1, + x1: 3, + y0: 1, + y1: 3 + } + ] }; }); afterEach(destroyGraphDiv); - it('is expanding an auto-ranging axes', function() { + it('is expanding an auto-ranging axes', function () { Plotly.newPlot(gd, data, layout); assertShapeFullyVisible(getFirstShapeNode()); }); }); -describe('A fixed size path shape', function() { +describe('A fixed size path shape', function () { 'use strict'; var gd, data, layout; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); - data = [{ - x: [1, 5], - y: [1, 5], - type: 'scatter' - }]; + data = [ + { + x: [1, 5], + y: [1, 5], + type: 'scatter' + } + ]; layout = { title: { text: 'Fixed size path shape' }, width: 400, height: 400, - shapes: [{ - type: 'path', - xref: 'x', - yref: 'y', - xsizemode: 'pixel', - ysizemode: 'pixel', - path: 'M0,0 L30,0 L15,20 Z', - xanchor: '3', - yanchor: '0', - - // Hint: set those too intentionally - x0: 1, - x1: 3, - y0: 1, - y1: 3 - }] + shapes: [ + { + type: 'path', + xref: 'x', + yref: 'y', + xsizemode: 'pixel', + ysizemode: 'pixel', + path: 'M0,0 L30,0 L15,20 Z', + xanchor: '3', + yanchor: '0', + + // Hint: set those too intentionally + x0: 1, + x1: 3, + y0: 1, + y1: 3 + } + ] }; }); afterEach(destroyGraphDiv); - it('is defined in pixel', function() { + it('is defined in pixel', function () { Plotly.newPlot(gd, data, layout); assertShapeSize(getFirstShapeNode(), 30, 20); }); - it('is expanding auto-ranging axes', function() { + it('is expanding auto-ranging axes', function () { layout.shapes[0].xanchor = 10; layout.shapes[0].yanchor = 10; @@ -831,15 +863,14 @@ describe('A fixed size path shape', function() { assertShapeFullyVisible(getFirstShapeNode()); }); - it('is being rendered correctly when linked to a date axis', function() { - data = [{ - x: ['2018-01-01 00:00:00', - '2018-02-01 00:00:00', - '2018-03-01 00:00:00', - '2018-04-01 00:00:00'], - y: [3, 4, 2, 5], - type: 'scatter' - }]; + it('is being rendered correctly when linked to a date axis', function () { + data = [ + { + x: ['2018-01-01 00:00:00', '2018-02-01 00:00:00', '2018-03-01 00:00:00', '2018-04-01 00:00:00'], + y: [3, 4, 2, 5], + type: 'scatter' + } + ]; layout.shapes[0].xanchor = '2018-07-01 00:00:00'; layout.shapes[0].yanchor = 10; @@ -850,108 +881,114 @@ describe('A fixed size path shape', function() { assertShapeSize(shapeNode, 30, 20); }); - it('keeps its dimensions when plot is being resized', function(done) { + it('keeps its dimensions when plot is being resized', function (done) { Plotly.newPlot(gd, data, layout); assertShapeSize(getFirstShapeNode(), 30, 20); - Plotly.relayout(gd, {height: 200, width: 600}) - .then(function() { - assertShapeSize(getFirstShapeNode(), 30, 20); - }) - .then(done, done.fail); + Plotly.relayout(gd, { height: 200, width: 600 }) + .then(function () { + assertShapeSize(getFirstShapeNode(), 30, 20); + }) + .then(done, done.fail); }); - it('is draggable', function(done) { - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - drag({node: getFirstShapeNode(), dpos: [50, 50]}).then(function() { - assertShapeSize(getFirstShapeNode(), 30, 20); - }) - .then(done, done.fail); - }); + it('is draggable', function (done) { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + drag({ node: getFirstShapeNode(), dpos: [50, 50] }) + .then(function () { + assertShapeSize(getFirstShapeNode(), 30, 20); + }) + .then(done, done.fail); + }); }); - it('being sized relative to data horizontally is getting narrower ' + - 'when being dragged to expand the x-axis', - function(done) { - layout.shapes[0].xsizemode = 'data'; - layout.shapes[0].path = 'M0,0 L2,0 L1,20 Z'; + it( + 'being sized relative to data horizontally is getting narrower ' + 'when being dragged to expand the x-axis', + function (done) { + layout.shapes[0].xsizemode = 'data'; + layout.shapes[0].path = 'M0,0 L2,0 L1,20 Z'; - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { var shapeNodeBeforeDrag = getFirstShapeNode(); var widthBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect().width; - drag({node: shapeNodeBeforeDrag, dpos: [300, 50]}).then(function() { - var shapeNodeAfterDrag = getFirstShapeNode(); - var bbox = shapeNodeAfterDrag.getBoundingClientRect(); - expect(bbox.height).toBe(20); - expect(bbox.width).toBeLessThan(widthBeforeDrag); - assertShapeFullyVisible(shapeNodeAfterDrag); - }) - .then(done, done.fail); + drag({ node: shapeNodeBeforeDrag, dpos: [300, 50] }) + .then(function () { + var shapeNodeAfterDrag = getFirstShapeNode(); + var bbox = shapeNodeAfterDrag.getBoundingClientRect(); + expect(bbox.height).toBe(20); + expect(bbox.width).toBeLessThan(widthBeforeDrag); + assertShapeFullyVisible(shapeNodeAfterDrag); + }) + .then(done, done.fail); }); - }); + } + ); - it('being sized relative to data vertically is getting lower ' + - 'when being dragged to expand the y-axis', - function(done) { - layout.shapes[0].ysizemode = 'data'; - layout.shapes[0].path = 'M0,0 L30,0 L15,2 Z'; + it( + 'being sized relative to data vertically is getting lower ' + 'when being dragged to expand the y-axis', + function (done) { + layout.shapes[0].ysizemode = 'data'; + layout.shapes[0].path = 'M0,0 L30,0 L15,2 Z'; - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { var shapeNodeBeforeDrag = getFirstShapeNode(); var heightBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect().height; - drag({node: shapeNodeBeforeDrag, dpos: [50, 300]}).then(function() { - var shapeNodeAfterDrag = getFirstShapeNode(); - var bbox = shapeNodeAfterDrag.getBoundingClientRect(); - expect(bbox.width).toBe(30); - expect(bbox.height).toBeLessThan(heightBeforeDrag); - assertShapeFullyVisible(shapeNodeAfterDrag); - }) - .then(done, done.fail); + drag({ node: shapeNodeBeforeDrag, dpos: [50, 300] }) + .then(function () { + var shapeNodeAfterDrag = getFirstShapeNode(); + var bbox = shapeNodeAfterDrag.getBoundingClientRect(); + expect(bbox.width).toBe(30); + expect(bbox.height).toBeLessThan(heightBeforeDrag); + assertShapeFullyVisible(shapeNodeAfterDrag); + }) + .then(done, done.fail); }); - }); + } + ); }); -describe('A fixed size shape', function() { +describe('A fixed size shape', function () { 'use strict'; var gd, data, layout; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); - data = [{ - x: [1, 5], - y: [1, 5], - type: 'scatter' - }]; + data = [ + { + x: [1, 5], + y: [1, 5], + type: 'scatter' + } + ]; layout = { title: { text: 'Fixed size shape' }, width: 400, height: 400, - shapes: [{ - type: 'rect', - xref: 'x', - yref: 'y', - xsizemode: 'pixel', - ysizemode: 'pixel', - xanchor: '3', - yanchor: '0', - x0: 3, - x1: 28, - y0: 0, - y1: -25 - }] + shapes: [ + { + type: 'rect', + xref: 'x', + yref: 'y', + xsizemode: 'pixel', + ysizemode: 'pixel', + xanchor: '3', + yanchor: '0', + x0: 3, + x1: 28, + y0: 0, + y1: -25 + } + ] }; }); afterEach(destroyGraphDiv); - it('can be positioned relative to data', function() { + it('can be positioned relative to data', function () { Plotly.newPlot(gd, data, layout); var shapeNode = getFirstShapeNode(); @@ -964,7 +1001,7 @@ describe('A fixed size shape', function() { assertElemRightTo(shapeNode, gridLine, 'Shape right to third grid line'); }); - it('can be positioned relative to the plotting area', function() { + it('can be positioned relative to the plotting area', function () { layout.shapes[0].xref = 'paper'; layout.shapes[0].yref = 'paper'; layout.shapes[0].xanchor = '1'; @@ -976,7 +1013,7 @@ describe('A fixed size shape', function() { assertElemRightTo(shapeNode, d3SelectAll('.cartesianlayer').node(), 'Shape right to plotting area'); }); - it('can be sized by pixel horizontally and relative to data vertically', function() { + it('can be sized by pixel horizontally and relative to data vertically', function () { layout.shapes[0].ysizemode = 'data'; layout.shapes[0].y0 = 1; layout.shapes[0].y1 = 5; @@ -988,7 +1025,7 @@ describe('A fixed size shape', function() { expect(bBox.width).toBe(25); }); - it('can be sized relative to data vertically and by pixel horizontally', function() { + it('can be sized relative to data vertically and by pixel horizontally', function () { layout.shapes[0].xsizemode = 'data'; layout.shapes[0].x0 = 1; layout.shapes[0].x1 = 5; @@ -1000,15 +1037,14 @@ describe('A fixed size shape', function() { expect(bBox.height).toBe(25); }); - it('is being rendered correctly when linked to a date axis', function() { - data = [{ - x: ['2018-01-01 00:00:00', - '2018-02-01 00:00:00', - '2018-03-01 00:00:00', - '2018-04-01 00:00:00'], - y: [3, 4, 2, 5], - type: 'scatter' - }]; + it('is being rendered correctly when linked to a date axis', function () { + data = [ + { + x: ['2018-01-01 00:00:00', '2018-02-01 00:00:00', '2018-03-01 00:00:00', '2018-04-01 00:00:00'], + y: [3, 4, 2, 5], + type: 'scatter' + } + ]; layout.shapes[0].xanchor = '2018-07-01 00:00:00'; layout.shapes[0].yanchor = 10; @@ -1019,82 +1055,84 @@ describe('A fixed size shape', function() { assertShapeSize(shapeNode, 25, 25); }); - it('keeps its dimensions when plot is being resized', function(done) { + it('keeps its dimensions when plot is being resized', function (done) { layout.shapes[0].yanchor = 3; // Ensure visible for debugging Plotly.newPlot(gd, data, layout); var shapeNode = getFirstShapeNode(); assertShapeSize(shapeNode, 25, 25); - Plotly.relayout(gd, {height: 200, width: 600}) - .then(function() { - var reRenderedShapeNode = getFirstShapeNode(); - assertShapeSize(reRenderedShapeNode, 25, 25); - }) - .then(done, done.fail); + Plotly.relayout(gd, { height: 200, width: 600 }) + .then(function () { + var reRenderedShapeNode = getFirstShapeNode(); + assertShapeSize(reRenderedShapeNode, 25, 25); + }) + .then(done, done.fail); }); - it('is draggable', function(done) { - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - drag({node: getFirstShapeNode(), dpos: [50, 50]}).then(function() { - assertShapeSize(getFirstShapeNode(), 25, 25); - }) - .then(done, done.fail); - }); + it('is draggable', function (done) { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + drag({ node: getFirstShapeNode(), dpos: [50, 50] }) + .then(function () { + assertShapeSize(getFirstShapeNode(), 25, 25); + }) + .then(done, done.fail); + }); }); - it('being sized relative to data horizontally is getting narrower ' + - 'when being dragged to expand the x-axis', - function(done) { - layout.shapes[0].xsizemode = 'data'; - layout.shapes[0].x0 = 1; - layout.shapes[0].x1 = 2; + it( + 'being sized relative to data horizontally is getting narrower ' + 'when being dragged to expand the x-axis', + function (done) { + layout.shapes[0].xsizemode = 'data'; + layout.shapes[0].x0 = 1; + layout.shapes[0].x1 = 2; - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { var shapeNodeBeforeDrag = getFirstShapeNode(); var widthBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect().width; - drag({node: shapeNodeBeforeDrag, dpos: [300, 50]}).then(function() { - var shapeNodeAfterDrag = getFirstShapeNode(); - var bbox = shapeNodeAfterDrag.getBoundingClientRect(); - expect(bbox.height).toBe(25); - expect(bbox.width).toBeLessThan(widthBeforeDrag); - assertShapeFullyVisible(shapeNodeAfterDrag); - }) - .then(done, done.fail); + drag({ node: shapeNodeBeforeDrag, dpos: [300, 50] }) + .then(function () { + var shapeNodeAfterDrag = getFirstShapeNode(); + var bbox = shapeNodeAfterDrag.getBoundingClientRect(); + expect(bbox.height).toBe(25); + expect(bbox.width).toBeLessThan(widthBeforeDrag); + assertShapeFullyVisible(shapeNodeAfterDrag); + }) + .then(done, done.fail); }); - }); + } + ); - it('being sized relative to data vertically is getting lower ' + - 'when being dragged to expand the y-axis', - function(done) { - layout.shapes[0].ysizemode = 'data'; - layout.shapes[0].y0 = 1; - layout.shapes[0].y1 = 2; + it( + 'being sized relative to data vertically is getting lower ' + 'when being dragged to expand the y-axis', + function (done) { + layout.shapes[0].ysizemode = 'data'; + layout.shapes[0].y0 = 1; + layout.shapes[0].y1 = 2; - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { var shapeNodeBeforeDrag = getFirstShapeNode(); var heightBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect().height; - drag({node: shapeNodeBeforeDrag, dpos: [50, 300]}).then(function() { - var shapeNodeAfterDrag = getFirstShapeNode(); - var bbox = shapeNodeAfterDrag.getBoundingClientRect(); - expect(bbox.width).toBe(25); - expect(bbox.height).toBeLessThan(heightBeforeDrag); - assertShapeFullyVisible(shapeNodeAfterDrag); - }) - .then(done, done.fail); + drag({ node: shapeNodeBeforeDrag, dpos: [50, 300] }) + .then(function () { + var shapeNodeAfterDrag = getFirstShapeNode(); + var bbox = shapeNodeAfterDrag.getBoundingClientRect(); + expect(bbox.width).toBe(25); + expect(bbox.height).toBeLessThan(heightBeforeDrag); + assertShapeFullyVisible(shapeNodeAfterDrag); + }) + .then(done, done.fail); }); - }); + } + ); // Helper to combine two arrays of objects function combinations(arr1, arr2) { var combinations = []; - arr1.forEach(function(elemArr1) { - arr2.forEach(function(elemArr2) { + arr1.forEach(function (elemArr1) { + arr2.forEach(function (elemArr2) { combinations.push(Lib.extendFlat({}, elemArr1, elemArr2)); }); }); @@ -1103,53 +1141,55 @@ describe('A fixed size shape', function() { // Only rect and circle because (i) path isn't yet resizable // and (ii) line has a different resize behavior. - var shapeAndResizeTypes = combinations([{type: 'rect'}, {type: 'circle'}], resizeTypes); - shapeAndResizeTypes.forEach(function(testCase) { - describe('of type ' + testCase.type + ' can be ' + testCase.resizeDisplayName, function() { - resizeDirections.forEach(function(direction) { - it('over direction ' + direction, function(done) { + var shapeAndResizeTypes = combinations([{ type: 'rect' }, { type: 'circle' }], resizeTypes); + shapeAndResizeTypes.forEach(function (testCase) { + describe('of type ' + testCase.type + ' can be ' + testCase.resizeDisplayName, function () { + resizeDirections.forEach(function (direction) { + it('over direction ' + direction, function (done) { layout.shapes[0].type = testCase.type; - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - var shapeNodeBeforeDrag = getFirstShapeNode(); - var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + var shapeNodeBeforeDrag = getFirstShapeNode(); + var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); - var shallShrink = testCase.resizeType === 'shrink'; - var dx = shallShrink ? dxToShrinkWidth[direction] : dxToEnlargeWidth[direction]; - var dy = shallShrink ? dyToShrinkHeight[direction] : dyToEnlargeHeight[direction]; + var shallShrink = testCase.resizeType === 'shrink'; + var dx = shallShrink ? dxToShrinkWidth[direction] : dxToEnlargeWidth[direction]; + var dy = shallShrink ? dyToShrinkHeight[direction] : dyToEnlargeHeight[direction]; - drag({node: shapeNodeBeforeDrag, dpos: [dx, dy], edge: direction}) - .then(function() { + drag({ node: shapeNodeBeforeDrag, dpos: [dx, dy], edge: direction }) + .then(function () { var shapeNodeAfterDrag = getFirstShapeNode(); var bBoxAfterDrag = shapeNodeAfterDrag.getBoundingClientRect(); var resizeFactor = shallShrink ? -1 : 1; - expect(bBoxAfterDrag.height).toBeCloseTo(bBoxBeforeDrag.height + resizeFactor * Math.abs(dy)); - expect(bBoxAfterDrag.width).toBeCloseTo(bBoxBeforeDrag.width + resizeFactor * Math.abs(dx)); + expect(bBoxAfterDrag.height).toBeCloseTo( + bBoxBeforeDrag.height + resizeFactor * Math.abs(dy) + ); + expect(bBoxAfterDrag.width).toBeCloseTo( + bBoxBeforeDrag.width + resizeFactor * Math.abs(dx) + ); assertShapeFullyVisible(shapeNodeAfterDrag); }) .then(done, done.fail); - }); + }); }); }); }); }); - describe('of type line', function() { - beforeEach(function() { + describe('of type line', function () { + beforeEach(function () { layout.shapes[0].type = 'line'; layout.shapes[0].yanchor = 3; }); - it('can be moved by dragging the middle', function(done) { - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - var shapeNodeBeforeDrag = getFirstShapeNode(); - var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); + it('can be moved by dragging the middle', function (done) { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + var shapeNodeBeforeDrag = getFirstShapeNode(); + var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); - var dragSensitiveElement = getMoveLineDragElement(0); - drag({node: dragSensitiveElement, dpos: [10, -10]}) - .then(function() { + var dragSensitiveElement = getMoveLineDragElement(0); + drag({ node: dragSensitiveElement, dpos: [10, -10] }) + .then(function () { var shapeNodeAfterDrag = getFirstShapeNode(); var bBoxAfterDrag = shapeNodeAfterDrag.getBoundingClientRect(); @@ -1158,18 +1198,17 @@ describe('A fixed size shape', function() { expect(bBoxAfterDrag.top).toBe(bBoxBeforeDrag.top - 10); }) .then(done, done.fail); - }); + }); }); - it('can be resized by dragging the start point', function(done) { - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - var shapeNodeBeforeDrag = getFirstShapeNode(); - var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); + it('can be resized by dragging the start point', function (done) { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + var shapeNodeBeforeDrag = getFirstShapeNode(); + var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); - var dragSensitiveElement = getResizeLineOverStartPointElement(); - drag({node: dragSensitiveElement, dpos: [50, -10]}) - .then(function() { + var dragSensitiveElement = getResizeLineOverStartPointElement(); + drag({ node: dragSensitiveElement, dpos: [50, -10] }) + .then(function () { var shapeNodeAfterDrag = getFirstShapeNode(); var bBoxAfterDrag = shapeNodeAfterDrag.getBoundingClientRect(); @@ -1180,18 +1219,17 @@ describe('A fixed size shape', function() { expect(bBoxAfterDrag.left).toBe(bBoxBeforeDrag.left + 25, 'left'); }) .then(done, done.fail); - }); + }); }); - it('can be resized by dragging the end point', function(done) { - Plotly.newPlot(gd, data, layout, {editable: true}) - .then(function() { - var shapeNodeBeforeDrag = getFirstShapeNode(); - var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); + it('can be resized by dragging the end point', function (done) { + Plotly.newPlot(gd, data, layout, { editable: true }).then(function () { + var shapeNodeBeforeDrag = getFirstShapeNode(); + var bBoxBeforeDrag = shapeNodeBeforeDrag.getBoundingClientRect(); - var dragSensitiveElement = getResizeLineOverEndPointElement(); - drag({node: dragSensitiveElement, dpos: [50, -10]}) - .then(function() { + var dragSensitiveElement = getResizeLineOverEndPointElement(); + drag({ node: dragSensitiveElement, dpos: [50, -10] }) + .then(function () { var shapeNodeAfterDrag = getFirstShapeNode(); var bBoxAfterDrag = shapeNodeAfterDrag.getBoundingClientRect(); @@ -1202,105 +1240,133 @@ describe('A fixed size shape', function() { expect(bBoxAfterDrag.left).toBe(bBoxBeforeDrag.left, 'left'); }) .then(done, done.fail); - }); + }); }); }); - describe('is expanding an auto-ranging x-axis', function() { + describe('is expanding an auto-ranging x-axis', function () { var sizeVariants = [ - {x0: 5, x1: 25}, - {x0: 5, x1: -25}, - {x0: -5, x1: 25}, - {x0: -5, x1: -25} + { x0: 5, x1: 25 }, + { x0: 5, x1: -25 }, + { x0: -5, x1: 25 }, + { x0: -5, x1: -25 } ]; var shapeVariants = combinations(shapeTypes, sizeVariants); - describe('to the left', function() { - shapeVariants.forEach(function(testCase) { - it('and is fully visible when being a ' + testCase.type + - ' with x0,x1=[' + testCase.x0 + ',' + testCase.x1 + ']', - function() { - layout.shapes[0].type = testCase.type; - layout.shapes[0].xanchor = -1; - layout.shapes[0].x0 = testCase.x0; - layout.shapes[0].x1 = testCase.x1; - Plotly.newPlot(gd, data, layout); - - expect(gd.layout.xaxis.range[0]).toBeLessThanOrEqual(-1); - assertShapeFullyVisible(getFirstShapeNode()); - }); + describe('to the left', function () { + shapeVariants.forEach(function (testCase) { + it( + 'and is fully visible when being a ' + + testCase.type + + ' with x0,x1=[' + + testCase.x0 + + ',' + + testCase.x1 + + ']', + function () { + layout.shapes[0].type = testCase.type; + layout.shapes[0].xanchor = -1; + layout.shapes[0].x0 = testCase.x0; + layout.shapes[0].x1 = testCase.x1; + Plotly.newPlot(gd, data, layout); + + expect(gd.layout.xaxis.range[0]).toBeLessThanOrEqual(-1); + assertShapeFullyVisible(getFirstShapeNode()); + } + ); }); }); - describe('to the right', function() { - shapeVariants.forEach(function(testCase) { - it('and is fully visible when being a ' + testCase.type + - ' with x0,x1=[' + testCase.x0 + ',' + testCase.x1 + ']', - function() { - layout.shapes[0].type = testCase.type; - layout.shapes[0].xanchor = 10; - layout.shapes[0].x0 = testCase.x0; - layout.shapes[0].x1 = testCase.x1; - Plotly.newPlot(gd, data, layout); - - expect(gd.layout.xaxis.range[1]).toBeGreaterThanOrEqual(10); - assertShapeFullyVisible(getFirstShapeNode()); - }); + describe('to the right', function () { + shapeVariants.forEach(function (testCase) { + it( + 'and is fully visible when being a ' + + testCase.type + + ' with x0,x1=[' + + testCase.x0 + + ',' + + testCase.x1 + + ']', + function () { + layout.shapes[0].type = testCase.type; + layout.shapes[0].xanchor = 10; + layout.shapes[0].x0 = testCase.x0; + layout.shapes[0].x1 = testCase.x1; + Plotly.newPlot(gd, data, layout); + + expect(gd.layout.xaxis.range[1]).toBeGreaterThanOrEqual(10); + assertShapeFullyVisible(getFirstShapeNode()); + } + ); }); }); }); - describe('is expanding an auto-ranging y-axis', function() { + describe('is expanding an auto-ranging y-axis', function () { var sizeVariants = [ - {y0: 5, y1: 25}, - {y0: 5, y1: -25}, - {y0: -5, y1: 25}, - {y0: -5, y1: -25} + { y0: 5, y1: 25 }, + { y0: 5, y1: -25 }, + { y0: -5, y1: 25 }, + { y0: -5, y1: -25 } ]; var shapeVariants = combinations(shapeTypes, sizeVariants); - describe('to the bottom', function() { - shapeVariants.forEach(function(testCase) { - it('and is fully visible when being a ' + testCase.type + - ' with y0,y1=[' + testCase.y0 + ',' + testCase.y1 + ']', - function() { - layout.shapes[0].type = testCase.type; - layout.shapes[0].yanchor = -1; - layout.shapes[0].y0 = testCase.y0; - layout.shapes[0].y1 = testCase.y1; - Plotly.newPlot(gd, data, layout); - - expect(gd.layout.yaxis.range[0]).toBeLessThanOrEqual(-1); - assertShapeFullyVisible(getFirstShapeNode()); - }); + describe('to the bottom', function () { + shapeVariants.forEach(function (testCase) { + it( + 'and is fully visible when being a ' + + testCase.type + + ' with y0,y1=[' + + testCase.y0 + + ',' + + testCase.y1 + + ']', + function () { + layout.shapes[0].type = testCase.type; + layout.shapes[0].yanchor = -1; + layout.shapes[0].y0 = testCase.y0; + layout.shapes[0].y1 = testCase.y1; + Plotly.newPlot(gd, data, layout); + + expect(gd.layout.yaxis.range[0]).toBeLessThanOrEqual(-1); + assertShapeFullyVisible(getFirstShapeNode()); + } + ); }); }); - describe('to the top', function() { - shapeVariants.forEach(function(testCase) { - it('and is fully visible when being a ' + testCase.type + - ' with y0,y1=[' + testCase.y0 + ',' + testCase.y1 + ']', - function() { - layout.shapes[0].type = testCase.type; - layout.shapes[0].yanchor = 10; - layout.shapes[0].y0 = testCase.y0; - layout.shapes[0].y1 = testCase.y1; - Plotly.newPlot(gd, data, layout); - - expect(gd.layout.yaxis.range[1]).toBeGreaterThanOrEqual(10); - assertShapeFullyVisible(getFirstShapeNode()); - }); + describe('to the top', function () { + shapeVariants.forEach(function (testCase) { + it( + 'and is fully visible when being a ' + + testCase.type + + ' with y0,y1=[' + + testCase.y0 + + ',' + + testCase.y1 + + ']', + function () { + layout.shapes[0].type = testCase.type; + layout.shapes[0].yanchor = 10; + layout.shapes[0].y0 = testCase.y0; + layout.shapes[0].y1 = testCase.y1; + Plotly.newPlot(gd, data, layout); + + expect(gd.layout.yaxis.range[1]).toBeGreaterThanOrEqual(10); + assertShapeFullyVisible(getFirstShapeNode()); + } + ); }); }); }); }); -describe('Test shapes', function() { +describe('Test shapes', function () { 'use strict'; var gd, data, layout, config; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); data = [{}]; layout = {}; @@ -1336,32 +1402,30 @@ describe('Test shapes', function() { } ]; - testCases.forEach(function(testCase) { - it('' + testCase.title + ' should be draggable', function(done) { - setupLayout(testCase, [{type: 'line'}, {type: 'rect'}, {type: 'circle'}, {type: 'path'}]); + testCases.forEach(function (testCase) { + it('' + testCase.title + ' should be draggable', function (done) { + setupLayout(testCase, [{ type: 'line' }, { type: 'rect' }, { type: 'circle' }, { type: 'path' }]); testDragEachShape(done); }); }); - testCases.forEach(function(testCase) { - resizeDirections.forEach(function(direction) { - var testTitle = testCase.title + - ' should be resizeable over direction ' + - direction; - it('' + testTitle, function(done) { + testCases.forEach(function (testCase) { + resizeDirections.forEach(function (direction) { + var testTitle = testCase.title + ' should be resizeable over direction ' + direction; + it('' + testTitle, function (done) { // Exclude line because it has a different resize behavior - setupLayout(testCase, [{type: 'rect'}, {type: 'circle'}, {type: 'path'}]); + setupLayout(testCase, [{ type: 'rect' }, { type: 'circle' }, { type: 'path' }]); testResizeEachShape(direction, done); }); }); }); - testCases.forEach(function(testCase) { - ['start', 'end'].forEach(function(linePoint) { - var testTitle = 'Line shape ' + testCase.title + - ' should be resizable by dragging the ' + linePoint + ' point'; - it('' + testTitle, function(done) { - setupLayout(testCase, [{type: 'line'}]); + testCases.forEach(function (testCase) { + ['start', 'end'].forEach(function (linePoint) { + var testTitle = + 'Line shape ' + testCase.title + ' should be resizable by dragging the ' + linePoint + ' point'; + it('' + testTitle, function (done) { + setupLayout(testCase, [{ type: 'line' }]); testLineResize(linePoint, done); }); }); @@ -1379,22 +1443,22 @@ describe('Test shapes', function() { var y0 = yrange[0]; var y1 = yrange[1]; - if(testCase.xaxis && testCase.xaxis.type === 'log') { + if (testCase.xaxis && testCase.xaxis.type === 'log') { x0 = Math.pow(10, x0); x1 = Math.pow(10, x1); } - if(testCase.yaxis && testCase.yaxis.type === 'log') { + if (testCase.yaxis && testCase.yaxis.type === 'log') { y0 = Math.pow(10, y0); y1 = Math.pow(10, y1); } - if(testCase.xaxis && testCase.xaxis.type === 'category') { + if (testCase.xaxis && testCase.xaxis.type === 'category') { x0 = 0; x1 = 1; } - if(testCase.yaxis && testCase.yaxis.type === 'category') { + if (testCase.yaxis && testCase.yaxis.type === 'category') { y0 = 0; y1 = 1; } @@ -1403,11 +1467,11 @@ describe('Test shapes', function() { var x1y1 = x1 + ',' + y1; var x1y0 = x1 + ',' + y0; - layoutShapes.forEach(function(s) { + layoutShapes.forEach(function (s) { s.xref = xref; s.yref = yref; - if(s.type === 'path') { + if (s.type === 'path') { s.path = 'M' + x0y0 + 'L' + x1y1 + 'L' + x1y0 + 'Z'; } else { s.x0 = x0; @@ -1425,20 +1489,18 @@ describe('Test shapes', function() { var layoutShapes = gd.layout.shapes; - expect(layoutShapes.length).toBe(4); // line, rect, circle and path + expect(layoutShapes.length).toBe(4); // line, rect, circle and path - layoutShapes.forEach(function(layoutShape, index) { + layoutShapes.forEach(function (layoutShape, index) { var dx = 100; var dy = 100; - promise = promise.then(function() { - var node = layoutShape.type === 'line' ? - getMoveLineDragElement(index) : - getShapeNode(index); + promise = promise.then(function () { + var node = layoutShape.type === 'line' ? getMoveLineDragElement(index) : getShapeNode(index); expect(node).not.toBe(null); - return (layoutShape.path) ? - testPathDrag(dx, dy, layoutShape, node) : - testShapeDrag(dx, dy, layoutShape, node); + return layoutShape.path + ? testPathDrag(dx, dy, layoutShape, node) + : testShapeDrag(dx, dy, layoutShape, node); }); }); @@ -1454,20 +1516,20 @@ describe('Test shapes', function() { // Hint: line has different resize behavior. expect(layoutShapes.length).toBe(3); - layoutShapes.forEach(function(layoutShape, index) { - if(layoutShape.path) return; + layoutShapes.forEach(function (layoutShape, index) { + if (layoutShape.path) return; var dx = dxToShrinkWidth[direction]; var dy = dyToShrinkHeight[direction]; - promise = promise.then(function() { + promise = promise.then(function () { var node = getShapeNode(index); expect(node).not.toBe(null); return testShapeResize(direction, dx, dy, layoutShape, node); }); - promise = promise.then(function() { + promise = promise.then(function () { var node = getShapeNode(index); expect(node).not.toBe(null); @@ -1479,26 +1541,28 @@ describe('Test shapes', function() { } function getShapeNode(index) { - return d3SelectAll('.shapelayer .shape-group path').filter(function() { - return +this.getAttribute('data-index') === index; - }).node(); + return d3SelectAll('.shapelayer .shape-group path') + .filter(function () { + return +this.getAttribute('data-index') === index; + }) + .node(); } function testShapeDrag(dx, dy, layoutShape, node) { var xa = Axes.getFromId(gd, layoutShape.xref); var ya = Axes.getFromId(gd, layoutShape.yref); - var x2p = function(v, shift) { + var x2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, xa, shift); return dataToPixel(v); }; - var y2p = function(v, shift) { + var y2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, ya, shift, true); return dataToPixel(v); }; var initialCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); - return drag({node: node, dpos: [dx, dy]}).then(function() { + return drag({ node: node, dpos: [dx, dy] }).then(function () { var finalCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); expect(finalCoordinates.x0 - initialCoordinates.x0).toBeCloseTo(dx); @@ -1528,22 +1592,20 @@ describe('Test shapes', function() { expect(initialCoordinates.length).toBe(6); - return drag({node: node, dpos: [dx, dy]}).then(function() { + return drag({ node: node, dpos: [dx, dy] }).then(function () { var finalPath = layoutShape.path; var finalCoordinates = getPathCoordinates(finalPath, x2p, y2p); expect(finalCoordinates.length).toBe(initialCoordinates.length); - for(var i = 0; i < initialCoordinates.length; i++) { + for (var i = 0; i < initialCoordinates.length; i++) { var initialCoordinate = initialCoordinates[i]; var finalCoordinate = finalCoordinates[i]; - if(initialCoordinate.x) { - expect(finalCoordinate.x - initialCoordinate.x) - .toBeCloseTo(dx); + if (initialCoordinate.x) { + expect(finalCoordinate.x - initialCoordinate.x).toBeCloseTo(dx); } else { - expect(finalCoordinate.y - initialCoordinate.y) - .toBeCloseTo(dy); + expect(finalCoordinate.y - initialCoordinate.y).toBeCloseTo(dy); } } }); @@ -1552,46 +1614,46 @@ describe('Test shapes', function() { function testShapeResize(direction, dx, dy, layoutShape, node) { var xa = Axes.getFromId(gd, layoutShape.xref); var ya = Axes.getFromId(gd, layoutShape.yref); - var x2p = function(v, shift) { + var x2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, xa, shift, false); return dataToPixel(v); }; - var y2p = function(v, shift) { + var y2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, ya, shift, true); return dataToPixel(v); }; var initialCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); - return drag({node: node, dpos: [dx, dy], edge: direction}).then(function() { + return drag({ node: node, dpos: [dx, dy], edge: direction }).then(function () { var finalCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); var keyN, keyS, keyW, keyE; - if(initialCoordinates.y0 < initialCoordinates.y1) { - keyN = 'y0'; keyS = 'y1'; + if (initialCoordinates.y0 < initialCoordinates.y1) { + keyN = 'y0'; + keyS = 'y1'; } else { - keyN = 'y1'; keyS = 'y0'; + keyN = 'y1'; + keyS = 'y0'; } - if(initialCoordinates.x0 < initialCoordinates.x1) { - keyW = 'x0'; keyE = 'x1'; + if (initialCoordinates.x0 < initialCoordinates.x1) { + keyW = 'x0'; + keyE = 'x1'; } else { - keyW = 'x1'; keyE = 'x0'; + keyW = 'x1'; + keyE = 'x0'; } - if(~direction.indexOf('n')) { - expect(finalCoordinates[keyN] - initialCoordinates[keyN]) - .toBeCloseTo(dy); - } else if(~direction.indexOf('s')) { - expect(finalCoordinates[keyS] - initialCoordinates[keyS]) - .toBeCloseTo(dy); + if (~direction.indexOf('n')) { + expect(finalCoordinates[keyN] - initialCoordinates[keyN]).toBeCloseTo(dy); + } else if (~direction.indexOf('s')) { + expect(finalCoordinates[keyS] - initialCoordinates[keyS]).toBeCloseTo(dy); } - if(~direction.indexOf('w')) { - expect(finalCoordinates[keyW] - initialCoordinates[keyW]) - .toBeCloseTo(dx); - } else if(~direction.indexOf('e')) { - expect(finalCoordinates[keyE] - initialCoordinates[keyE]) - .toBeCloseTo(dx); + if (~direction.indexOf('w')) { + expect(finalCoordinates[keyW] - initialCoordinates[keyW]).toBeCloseTo(dx); + } else if (~direction.indexOf('e')) { + expect(finalCoordinates[keyE] - initialCoordinates[keyE]).toBeCloseTo(dx); } }); } @@ -1602,25 +1664,24 @@ describe('Test shapes', function() { var xa = Axes.getFromId(gd, layoutShape.xref); var ya = Axes.getFromId(gd, layoutShape.yref); - var x2p = function(v, shift) { + var x2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, xa, shift); return dataToPixel(v); }; - var y2p = function(v, shift) { + var y2p = function (v, shift) { var dataToPixel = helpers.getDataToPixel(gd, ya, shift, true); return dataToPixel(v); }; - promise = promise.then(function() { - var dragHandle = pointToMove === 'start' ? - getResizeLineOverStartPointElement() : - getResizeLineOverEndPointElement(); + promise = promise.then(function () { + var dragHandle = + pointToMove === 'start' ? getResizeLineOverStartPointElement() : getResizeLineOverEndPointElement(); var initialCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); - return drag({node: dragHandle, dpos: [10, 10]}).then(function() { + return drag({ node: dragHandle, dpos: [10, 10] }).then(function () { var finalCoordinates = getShapeCoordinates(layoutShape, x2p, y2p); - if(pointToMove === 'start') { + if (pointToMove === 'start') { expect(finalCoordinates.x0 - initialCoordinates.x0).toBeCloseTo(10); expect(finalCoordinates.y0 - initialCoordinates.y0).toBeCloseTo(10); } else { @@ -1636,7 +1697,7 @@ describe('Test shapes', function() { function getPathCoordinates(pathString, x2p, y2p) { var coordinates = []; - pathString.match(constants.segmentRE).forEach(function(segment) { + pathString.match(constants.segmentRE).forEach(function (segment) { var paramNumber = 0; var segmentType = segment.charAt(0); var xParams = constants.paramIsX[segmentType]; @@ -1644,13 +1705,13 @@ describe('Test shapes', function() { var nParams = constants.numParams[segmentType]; var params = segment.slice(1).match(constants.paramRE); - if(params) { - params.forEach(function(param) { - if(paramNumber >= nParams) return; + if (params) { + params.forEach(function (param) { + if (paramNumber >= nParams) return; - if(xParams[paramNumber]) { + if (xParams[paramNumber]) { coordinates.push({ x: x2p(param) }); - } else if(yParams[paramNumber]) { + } else if (yParams[paramNumber]) { coordinates.push({ y: y2p(param) }); } @@ -1663,12 +1724,14 @@ describe('Test shapes', function() { } }); -describe('Test multi-axis shapes', function() { +describe('Test multi-axis shapes', function () { 'use strict'; var gd; - beforeEach(function() { gd = createGraphDiv(); }); + beforeEach(function () { + gd = createGraphDiv(); + }); afterEach(destroyGraphDiv); function getShapesWithIndex(index) { @@ -1680,254 +1743,297 @@ describe('Test multi-axis shapes', function() { return node ? node.getBoundingClientRect() : null; } - it('renders all shape types with array xref and yref values', function(done) { - Plotly.newPlot(gd, [ - {x: [1, 2], y: [1, 2]}, - {x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2'} - ], { - xaxis: {domain: [0, 0.45]}, - yaxis: {domain: [0, 0.45]}, - xaxis2: {domain: [0.55, 1], anchor: 'y2'}, - yaxis2: {domain: [0.55, 1], anchor: 'x2'}, - shapes: [ - {type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5}, - {type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2'} - ] - }).then(function() { - expect(getShapesWithIndex(0).size()).toBe(1); - expect(getShapesWithIndex(1).size()).toBe(1); - expect(getShapesWithIndex(2).size()).toBe(1); - expect(getShapesWithIndex(3).size()).toBe(1); - }) - .then(done, done.fail); + it('renders all shape types with array xref and yref values', function (done) { + Plotly.newPlot( + gd, + [ + { x: [1, 2], y: [1, 2] }, + { x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2' } + ], + { + xaxis: { domain: [0, 0.45] }, + yaxis: { domain: [0, 0.45] }, + xaxis2: { domain: [0.55, 1], anchor: 'y2' }, + yaxis2: { domain: [0.55, 1], anchor: 'x2' }, + shapes: [ + { type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5 }, + { type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2' } + ] + } + ) + .then(function () { + expect(getShapesWithIndex(0).size()).toBe(1); + expect(getShapesWithIndex(1).size()).toBe(1); + expect(getShapesWithIndex(2).size()).toBe(1); + expect(getShapesWithIndex(3).size()).toBe(1); + }) + .then(done, done.fail); }); - it('positions shapes correctly with side-by-side subplots', function(done) { - Plotly.newPlot(gd, [ - {x: [1, 2], y: [1, 2]}, - {x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2'} - ], { - width: 800, height: 400, - xaxis: {domain: [0, 0.45]}, - yaxis: {domain: [0, 0.45]}, - xaxis2: {domain: [0.55, 1], anchor: 'y2'}, - yaxis2: {domain: [0.55, 1], anchor: 'x2'}, - shapes: [ - {type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5}, - {type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2'} - ] - }).then(function() { - var xa = gd._fullLayout.xaxis; - var xa2 = gd._fullLayout.xaxis2; - var ya = gd._fullLayout.yaxis; - var ya2 = gd._fullLayout.yaxis2; - - var lineBBox = getBoundingBox(0); - expect(lineBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(lineBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); - expect(lineBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(lineBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); - - var rectBBox = getBoundingBox(1); - expect(rectBBox.left).toBeCloseTo(xa.l2p(1.5) + xa._offset); - expect(rectBBox.right).toBeCloseTo(xa2.l2p(1.5) + xa2._offset); - expect(rectBBox.bottom).toBeCloseTo(ya.l2p(1.5) + ya._offset); - expect(rectBBox.top).toBeCloseTo(ya2.l2p(1.5) + ya2._offset); - - var circleBBox = getBoundingBox(2); - expect(circleBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(circleBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); - expect(circleBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(circleBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); - - var pathBBox = getBoundingBox(3); - expect(pathBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(pathBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); - expect(pathBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(pathBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); - }) - .then(done, done.fail); + it('positions shapes correctly with side-by-side subplots', function (done) { + Plotly.newPlot( + gd, + [ + { x: [1, 2], y: [1, 2] }, + { x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2' } + ], + { + width: 800, + height: 400, + xaxis: { domain: [0, 0.45] }, + yaxis: { domain: [0, 0.45] }, + xaxis2: { domain: [0.55, 1], anchor: 'y2' }, + yaxis2: { domain: [0.55, 1], anchor: 'x2' }, + shapes: [ + { type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5 }, + { type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2' } + ] + } + ) + .then(function () { + var xa = gd._fullLayout.xaxis; + var xa2 = gd._fullLayout.xaxis2; + var ya = gd._fullLayout.yaxis; + var ya2 = gd._fullLayout.yaxis2; + + var lineBBox = getBoundingBox(0); + expect(lineBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(lineBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); + expect(lineBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(lineBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); + + var rectBBox = getBoundingBox(1); + expect(rectBBox.left).toBeCloseTo(xa.l2p(1.5) + xa._offset); + expect(rectBBox.right).toBeCloseTo(xa2.l2p(1.5) + xa2._offset); + expect(rectBBox.bottom).toBeCloseTo(ya.l2p(1.5) + ya._offset); + expect(rectBBox.top).toBeCloseTo(ya2.l2p(1.5) + ya2._offset); + + var circleBBox = getBoundingBox(2); + expect(circleBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(circleBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); + expect(circleBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(circleBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); + + var pathBBox = getBoundingBox(3); + expect(pathBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(pathBBox.right).toBeCloseTo(xa2.l2p(2) + xa2._offset); + expect(pathBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(pathBBox.top).toBeCloseTo(ya2.l2p(2) + ya2._offset); + }) + .then(done, done.fail); }); - it('positions shapes correctly with overlaid axes', function(done) { - Plotly.newPlot(gd, [ - {x: [1, 2], y: [1, 2]}, - {x: [1, 2], y: [50, 100], yaxis: 'y2'} - ], { - width: 600, height: 400, - yaxis: {range: [0, 10]}, - yaxis2: {overlaying: 'y', side: 'right', range: [0, 100]}, - shapes: [ - {type: 'line', xref: 'x', yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 20}, - {type: 'rect', xref: 'x', yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 50}, - {type: 'circle', xref: 'x', yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 65}, - {type: 'path', xref: 'x', yref: ['y', 'y2'], path: 'M1,1L2,90'}] - }).then(function() { - var xa = gd._fullLayout.xaxis; - var ya = gd._fullLayout.yaxis; - var ya2 = gd._fullLayout.yaxis2; - - var lineBBox = getBoundingBox(0); - expect(lineBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(lineBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); - expect(lineBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(lineBBox.top).toBeCloseTo(ya2.l2p(20) + ya2._offset); - - var rectBBox = getBoundingBox(1); - expect(rectBBox.left).toBeCloseTo(xa.l2p(1.5) + xa._offset); - expect(rectBBox.right).toBeCloseTo(xa.l2p(1.5) + xa._offset); - expect(rectBBox.bottom).toBeCloseTo(ya.l2p(1.5) + ya._offset); - expect(rectBBox.top).toBeCloseTo(ya2.l2p(50) + ya2._offset); - - var circleBBox = getBoundingBox(2); - expect(circleBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(circleBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); - expect(circleBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(circleBBox.top).toBeCloseTo(ya2.l2p(65) + ya2._offset); - - var pathBBox = getBoundingBox(3); - expect(pathBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); - expect(pathBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); - expect(pathBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); - expect(pathBBox.top).toBeCloseTo(ya2.l2p(90) + ya2._offset); - }) - .then(done, done.fail); + it('positions shapes correctly with overlaid axes', function (done) { + Plotly.newPlot( + gd, + [ + { x: [1, 2], y: [1, 2] }, + { x: [1, 2], y: [50, 100], yaxis: 'y2' } + ], + { + width: 600, + height: 400, + yaxis: { range: [0, 10] }, + yaxis2: { overlaying: 'y', side: 'right', range: [0, 100] }, + shapes: [ + { type: 'line', xref: 'x', yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 20 }, + { type: 'rect', xref: 'x', yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 50 }, + { type: 'circle', xref: 'x', yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 65 }, + { type: 'path', xref: 'x', yref: ['y', 'y2'], path: 'M1,1L2,90' } + ] + } + ) + .then(function () { + var xa = gd._fullLayout.xaxis; + var ya = gd._fullLayout.yaxis; + var ya2 = gd._fullLayout.yaxis2; + + var lineBBox = getBoundingBox(0); + expect(lineBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(lineBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); + expect(lineBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(lineBBox.top).toBeCloseTo(ya2.l2p(20) + ya2._offset); + + var rectBBox = getBoundingBox(1); + expect(rectBBox.left).toBeCloseTo(xa.l2p(1.5) + xa._offset); + expect(rectBBox.right).toBeCloseTo(xa.l2p(1.5) + xa._offset); + expect(rectBBox.bottom).toBeCloseTo(ya.l2p(1.5) + ya._offset); + expect(rectBBox.top).toBeCloseTo(ya2.l2p(50) + ya2._offset); + + var circleBBox = getBoundingBox(2); + expect(circleBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(circleBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); + expect(circleBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(circleBBox.top).toBeCloseTo(ya2.l2p(65) + ya2._offset); + + var pathBBox = getBoundingBox(3); + expect(pathBBox.left).toBeCloseTo(xa.l2p(1) + xa._offset); + expect(pathBBox.right).toBeCloseTo(xa.l2p(2) + xa._offset); + expect(pathBBox.bottom).toBeCloseTo(ya.l2p(1) + ya._offset); + expect(pathBBox.top).toBeCloseTo(ya2.l2p(90) + ya2._offset); + }) + .then(done, done.fail); }); - it('adjusts shape position when one referenced axis is zoomed', function(done) { - Plotly.newPlot(gd, [ - {x: [0, 4], y: [0, 4]}, - {x: [0, 4], y: [0, 4], xaxis: 'x2', yaxis: 'y2'} - ], { - width: 800, height: 400, - xaxis: {domain: [0, 0.45], range: [0, 4]}, - yaxis: {range: [0, 4]}, - xaxis2: {domain: [0.55, 1], anchor: 'y2', range: [0, 4]}, - yaxis2: {anchor: 'x2', range: [0, 4]}, - shapes: [ - {type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5}, - {type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2'} - ] - }).then(function() { - return Plotly.relayout(gd, 'xaxis.range', [0, 2]); - }).then(function() { - var xa = gd._fullLayout.xaxis; - var xa2 = gd._fullLayout.xaxis2; + it('adjusts shape position when one referenced axis is zoomed', function (done) { + Plotly.newPlot( + gd, + [ + { x: [0, 4], y: [0, 4] }, + { x: [0, 4], y: [0, 4], xaxis: 'x2', yaxis: 'y2' } + ], + { + width: 800, + height: 400, + xaxis: { domain: [0, 0.45], range: [0, 4] }, + yaxis: { range: [0, 4] }, + xaxis2: { domain: [0.55, 1], anchor: 'y2', range: [0, 4] }, + yaxis2: { anchor: 'x2', range: [0, 4] }, + shapes: [ + { type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5 }, + { type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2' } + ] + } + ) + .then(function () { + return Plotly.relayout(gd, 'xaxis.range', [0, 2]); + }) + .then(function () { + var xa = gd._fullLayout.xaxis; + var xa2 = gd._fullLayout.xaxis2; - var lineExpectedLeft = xa.l2p(1) + xa._offset; - var lineExpectedRight = xa2.l2p(2) + xa2._offset; - var lineBBox = getBoundingBox(0); + var lineExpectedLeft = xa.l2p(1) + xa._offset; + var lineExpectedRight = xa2.l2p(2) + xa2._offset; + var lineBBox = getBoundingBox(0); - expect(lineBBox.left).toBeCloseTo(lineExpectedLeft); - expect(lineBBox.right).toBeCloseTo(lineExpectedRight); + expect(lineBBox.left).toBeCloseTo(lineExpectedLeft); + expect(lineBBox.right).toBeCloseTo(lineExpectedRight); - var rectExpectedLeft = xa.l2p(1.5) + xa._offset; - var rectExpectedRight = xa2.l2p(1.5) + xa2._offset; - var rectBBox = getBoundingBox(1); + var rectExpectedLeft = xa.l2p(1.5) + xa._offset; + var rectExpectedRight = xa2.l2p(1.5) + xa2._offset; + var rectBBox = getBoundingBox(1); - expect(rectBBox.left).toBeCloseTo(rectExpectedLeft); - expect(rectBBox.right).toBeCloseTo(rectExpectedRight); + expect(rectBBox.left).toBeCloseTo(rectExpectedLeft); + expect(rectBBox.right).toBeCloseTo(rectExpectedRight); - var circleExpectedLeft = xa.l2p(1) + xa._offset; - var circleExpectedRight = xa2.l2p(2) + xa2._offset; - var circleBBox = getBoundingBox(2); + var circleExpectedLeft = xa.l2p(1) + xa._offset; + var circleExpectedRight = xa2.l2p(2) + xa2._offset; + var circleBBox = getBoundingBox(2); - expect(circleBBox.left).toBeCloseTo(circleExpectedLeft); - expect(circleBBox.right).toBeCloseTo(circleExpectedRight); + expect(circleBBox.left).toBeCloseTo(circleExpectedLeft); + expect(circleBBox.right).toBeCloseTo(circleExpectedRight); - var pathExpectedLeft = xa.l2p(1) + xa._offset; - var pathExpectedRight = xa2.l2p(2) + xa2._offset; - var pathBBox = getBoundingBox(3); + var pathExpectedLeft = xa.l2p(1) + xa._offset; + var pathExpectedRight = xa2.l2p(2) + xa2._offset; + var pathBBox = getBoundingBox(3); - expect(pathBBox.left).toBeCloseTo(pathExpectedLeft); - expect(pathBBox.right).toBeCloseTo(pathExpectedRight); - }) - .then(done, done.fail); + expect(pathBBox.left).toBeCloseTo(pathExpectedLeft); + expect(pathBBox.right).toBeCloseTo(pathExpectedRight); + }) + .then(done, done.fail); }); - it('updates shape positions when axis range changes via relayout', function(done) { - Plotly.newPlot(gd, [ - {x: [0, 4], y: [0, 4]}, - {x: [0, 4], y: [0, 4], xaxis: 'x2', yaxis: 'y2'} - ], { - width: 800, height: 400, - xaxis: {domain: [0, 0.45], range: [0, 4]}, - yaxis: {range: [0, 4]}, - xaxis2: {domain: [0.55, 1], anchor: 'y2', range: [0, 4]}, - yaxis2: {anchor: 'x2', range: [0, 4]}, - shapes: [ - {type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5}, - {type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2}, - {type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2'} - ] - }).then(function() { - return Plotly.relayout(gd, 'yaxis.range', [1, 5]); - }).then(function() { - var ya = gd._fullLayout.yaxis; - var ya2 = gd._fullLayout.yaxis2; + it('updates shape positions when axis range changes via relayout', function (done) { + Plotly.newPlot( + gd, + [ + { x: [0, 4], y: [0, 4] }, + { x: [0, 4], y: [0, 4], xaxis: 'x2', yaxis: 'y2' } + ], + { + width: 800, + height: 400, + xaxis: { domain: [0, 0.45], range: [0, 4] }, + yaxis: { range: [0, 4] }, + xaxis2: { domain: [0.55, 1], anchor: 'y2', range: [0, 4] }, + yaxis2: { anchor: 'x2', range: [0, 4] }, + shapes: [ + { type: 'line', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'rect', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1.5, x1: 1.5, y0: 1.5, y1: 1.5 }, + { type: 'circle', xref: ['x', 'x2'], yref: ['y', 'y2'], x0: 1, x1: 2, y0: 1, y1: 2 }, + { type: 'path', xref: ['x', 'x2'], yref: ['y', 'y2'], path: 'M1,1L2,2' } + ] + } + ) + .then(function () { + return Plotly.relayout(gd, 'yaxis.range', [1, 5]); + }) + .then(function () { + var ya = gd._fullLayout.yaxis; + var ya2 = gd._fullLayout.yaxis2; - var lineExpectedBottom = ya.l2p(1) + ya._offset; - var lineExpectedTop = ya2.l2p(2) + ya2._offset; - var lineBBox = getBoundingBox(0); + var lineExpectedBottom = ya.l2p(1) + ya._offset; + var lineExpectedTop = ya2.l2p(2) + ya2._offset; + var lineBBox = getBoundingBox(0); - expect(lineBBox.bottom).toBeCloseTo(lineExpectedBottom); - expect(lineBBox.top).toBeCloseTo(lineExpectedTop); + expect(lineBBox.bottom).toBeCloseTo(lineExpectedBottom); + expect(lineBBox.top).toBeCloseTo(lineExpectedTop); - var rectExpectedBottom = ya.l2p(1.5) + ya._offset; - var rectExpectedTop = ya2.l2p(1.5) + ya2._offset; - var rectBBox = getBoundingBox(1); + var rectExpectedBottom = ya.l2p(1.5) + ya._offset; + var rectExpectedTop = ya2.l2p(1.5) + ya2._offset; + var rectBBox = getBoundingBox(1); - expect(rectBBox.bottom).toBeCloseTo(rectExpectedBottom); - expect(rectBBox.top).toBeCloseTo(rectExpectedTop); + expect(rectBBox.bottom).toBeCloseTo(rectExpectedBottom); + expect(rectBBox.top).toBeCloseTo(rectExpectedTop); - var circleExpectedBottom = ya.l2p(1) + ya._offset; - var circleExpectedTop = ya2.l2p(2) + ya2._offset; - var circleBBox = getBoundingBox(2); + var circleExpectedBottom = ya.l2p(1) + ya._offset; + var circleExpectedTop = ya2.l2p(2) + ya2._offset; + var circleBBox = getBoundingBox(2); - expect(circleBBox.bottom).toBeCloseTo(circleExpectedBottom); - expect(circleBBox.top).toBeCloseTo(circleExpectedTop); + expect(circleBBox.bottom).toBeCloseTo(circleExpectedBottom); + expect(circleBBox.top).toBeCloseTo(circleExpectedTop); - var pathExpectedBottom = ya.l2p(1) + ya._offset; - var pathExpectedTop = ya2.l2p(2) + ya2._offset; - var pathBBox = getBoundingBox(3); + var pathExpectedBottom = ya.l2p(1) + ya._offset; + var pathExpectedTop = ya2.l2p(2) + ya2._offset; + var pathBBox = getBoundingBox(3); - expect(pathBBox.bottom).toBeCloseTo(pathExpectedBottom); - expect(pathBBox.top).toBeCloseTo(pathExpectedTop); - }) - .then(done, done.fail); + expect(pathBBox.bottom).toBeCloseTo(pathExpectedBottom); + expect(pathBBox.top).toBeCloseTo(pathExpectedTop); + }) + .then(done, done.fail); }); - it('handles autorange', function(done) { - Plotly.newPlot(gd, [ - {x: [1, 2], y: [1, 2]}, - {x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2'} - ], { - xaxis: {domain: [0, 0.45]}, - yaxis: {domain: [0, 0.45]}, - xaxis2: {domain: [0.55, 1], anchor: 'y2'}, - yaxis2: {domain: [0.55, 1], anchor: 'x2'}, - shapes: [{ - type: 'rect', - xref: ['x', 'x2'], yref: ['y', 'y2'], - x0: 0, x1: 5, y0: 0, y1: 5 - }] - }).then(function() { - expect(gd._fullLayout.xaxis.range[0]).toBeCloseTo(-0.01); - expect(gd._fullLayout.xaxis.range[1]).toBeCloseTo(2.14); - expect(gd._fullLayout.yaxis.range[0]).toBeCloseTo(-0.02); - expect(gd._fullLayout.yaxis.range[1]).toBeCloseTo(2.18); - expect(gd._fullLayout.xaxis2.range[0]).toBeCloseTo(0.72); - expect(gd._fullLayout.xaxis2.range[1]).toBeCloseTo(5.02); - expect(gd._fullLayout.yaxis2.range[0]).toBeCloseTo(0.64); - expect(gd._fullLayout.yaxis2.range[1]).toBeCloseTo(5.04); - }) - .then(done, done.fail); + it('handles autorange', function (done) { + Plotly.newPlot( + gd, + [ + { x: [1, 2], y: [1, 2] }, + { x: [1, 2], y: [1, 2], xaxis: 'x2', yaxis: 'y2' } + ], + { + xaxis: { domain: [0, 0.45] }, + yaxis: { domain: [0, 0.45] }, + xaxis2: { domain: [0.55, 1], anchor: 'y2' }, + yaxis2: { domain: [0.55, 1], anchor: 'x2' }, + shapes: [ + { + type: 'rect', + xref: ['x', 'x2'], + yref: ['y', 'y2'], + x0: 0, + x1: 5, + y0: 0, + y1: 5 + } + ] + } + ) + .then(function () { + expect(gd._fullLayout.xaxis.range[0]).toBeCloseTo(-0.01); + expect(gd._fullLayout.xaxis.range[1]).toBeCloseTo(2.14); + expect(gd._fullLayout.yaxis.range[0]).toBeCloseTo(-0.02); + expect(gd._fullLayout.yaxis.range[1]).toBeCloseTo(2.18); + expect(gd._fullLayout.xaxis2.range[0]).toBeCloseTo(0.72); + expect(gd._fullLayout.xaxis2.range[1]).toBeCloseTo(5.02); + expect(gd._fullLayout.yaxis2.range[0]).toBeCloseTo(0.64); + expect(gd._fullLayout.yaxis2.range[1]).toBeCloseTo(5.04); + }) + .then(done, done.fail); }); }); From 51e1de92929a8b956c72d6f74e0ac388934b93cd Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 1 May 2026 14:29:17 -0600 Subject: [PATCH 2/9] fix: Handle 'pixel' size mode for shape labels --- src/components/shapes/display_labels.js | 34 +++++++++++++++++-------- src/components/shapes/helpers.js | 1 + 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/components/shapes/display_labels.js b/src/components/shapes/display_labels.js index a300e3736a5..8845c335342 100644 --- a/src/components/shapes/display_labels.js +++ b/src/components/shapes/display_labels.js @@ -104,16 +104,30 @@ module.exports = function drawLabel(gd, index, options, shapeGroup) { const xRefType1 = Axes.getRefType(isArrayXref ? options.xref[1] : options.xref); const yRefType0 = Axes.getRefType(isArrayYref ? options.yref[0] : options.yref); const yRefType1 = Axes.getRefType(isArrayYref ? options.yref[1] : options.yref); - const x2p = function(v, shift, xa, xRefType) { - return helpers.getDataToPixel(gd, xa, shift, false, xRefType)(v); - }; - const y2p = function(v, shift, ya, yRefType) { - return helpers.getDataToPixel(gd, ya, shift, true, yRefType)(v); - }; - shapex0 = x2p(options.x0, options.x0shift, xa0, xRefType0); - shapex1 = x2p(options.x1, options.x1shift, xa1, xRefType1); - shapey0 = y2p(options.y0, options.y0shift, ya0, yRefType0); - shapey1 = y2p(options.y1, options.y1shift, ya1, yRefType1); + const x2p = (v, shift, xa, xRefType) => helpers.getDataToPixel(gd, xa, shift, false, xRefType)(v); + const y2p = (v, shift, ya, yRefType) => helpers.getDataToPixel(gd, ya, shift, true, yRefType)(v); + // When using pixel offset mode it's necessary to add the anchor position for the + // correct final value + if (options.xsizemode === 'pixel') { + const xAnchorPos = x2p(options.xanchor, undefined, xa0, xRefType0); + const xShift0 = helpers.getPixelShift(xa0, options.x0shift); + const xShift1 = helpers.getPixelShift(xa0, options.x1shift); + shapex0 = xAnchorPos + options.x0 + xShift0; + shapex1 = xAnchorPos + options.x1 + xShift1; + } else { + shapex0 = x2p(options.x0, options.x0shift, xa0, xRefType0); + shapex1 = x2p(options.x1, options.x1shift, xa1, xRefType1); + } + if (options.ysizemode === 'pixel') { + const yAnchorPos = y2p(options.yanchor, undefined, ya0, yRefType0); + const yShift0 = helpers.getPixelShift(ya0, options.y0shift); + const yShift1 = helpers.getPixelShift(ya0, options.y1shift); + shapey0 = yAnchorPos - options.y0 + yShift0; + shapey1 = yAnchorPos - options.y1 + yShift1; + } else { + shapey0 = y2p(options.y0, options.y0shift, ya0, yRefType0); + shapey1 = y2p(options.y1, options.y1shift, ya1, yRefType1); + } } // Handle `auto` angle diff --git a/src/components/shapes/helpers.js b/src/components/shapes/helpers.js index d27e7264d1f..8b11c2ebd11 100644 --- a/src/components/shapes/helpers.js +++ b/src/components/shapes/helpers.js @@ -352,6 +352,7 @@ function convertPath(options, x2p, y2p) { }); } +exports.getPixelShift = getPixelShift; function getPixelShift(axis, shift) { shift = shift || 0; var shiftPixels = 0; From a2a7e70a10ed687f79e002145f1d42ed0c0753f0 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 1 May 2026 14:30:17 -0600 Subject: [PATCH 3/9] Add test --- test/jasmine/tests/shapes_test.js | 133 ++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/test/jasmine/tests/shapes_test.js b/test/jasmine/tests/shapes_test.js index 60284c2a54f..683d3bb3e59 100644 --- a/test/jasmine/tests/shapes_test.js +++ b/test/jasmine/tests/shapes_test.js @@ -2037,3 +2037,136 @@ describe('Test multi-axis shapes', function () { .then(done, done.fail); }); }); + +describe('Shape labels with pixel sizemode', () => { + let gd; + beforeEach(() => { + gd = createGraphDiv(); + }); + afterEach(destroyGraphDiv); + + const getLabelNodes = () => d3SelectAll('.shape-label-text'); + const data = [ + { + type: 'scatter', + x: [1, 2], + y: [1, 2] + } + ]; + + it('positions labels inside shapes with xsizemode/ysizemode pixel', (done) => { + Plotly.newPlot(gd, data, { + width: 600, + height: 400, + shapes: [ + { + type: 'circle', + label: { text: 'Circle Label' }, + xref: 'x', + yref: 'y', + xsizemode: 'pixel', + ysizemode: 'pixel', + xanchor: 1.5, + yanchor: 1.5, + x0: -30, + x1: 30, + y0: -30, + y1: 30 + }, + { + type: 'rect', + label: { text: 'Rect Label' }, + xref: 'x', + yref: 'y', + xsizemode: 'pixel', + ysizemode: 'pixel', + xanchor: 1.5, + yanchor: 1.5, + x0: -40, + x1: 40, + y0: -25, + y1: 25 + } + ] + }) + .then(() => { + const labels = getLabelNodes(); + expect(labels.size()).toBe(2); + + const shapeNodes = d3SelectAll('.shapelayer .shape-group path'); + expect(shapeNodes.size()).toBe(2); + + // Each label should be positioned within or near its shape + labels.each(function (_, i) { + const labelBB = this.getBoundingClientRect(); + const shapeBB = shapeNodes[0][i].getBoundingClientRect(); + // Label center should be inside the shape bounding box + const labelCenterX = labelBB.left + labelBB.width / 2; + const labelCenterY = labelBB.top + labelBB.height / 2; + + expect(labelCenterX).toBeGreaterThan(shapeBB.left); + expect(labelCenterX).toBeLessThan(shapeBB.right); + expect(labelCenterY).toBeGreaterThan(shapeBB.top); + expect(labelCenterY).toBeLessThan(shapeBB.bottom); + }); + }) + .then(done, done.fail); + }); + + it('positions labels inside shapes with paper ref and pixel sizemode', (done) => { + Plotly.newPlot(gd, data, { + width: 600, + height: 400, + shapes: [ + { + type: 'circle', + label: { text: 'Circle Label' }, + xref: 'x', + xsizemode: 'pixel', + xanchor: 1.5, + x0: -25, + x1: 25, + yref: 'paper', + ysizemode: 'pixel', + yanchor: 0.5, + y0: -25, + y1: 25 + }, + { + type: 'rect', + label: { text: 'Rect Label' }, + xref: 'x', + xsizemode: 'pixel', + xanchor: 1.5, + x0: -30, + x1: 30, + yref: 'paper', + ysizemode: 'pixel', + yanchor: 0.5, + y0: -20, + y1: 20 + } + ] + }) + .then(() => { + const labels = getLabelNodes(); + expect(labels.size()).toBe(2); + + const shapeNodes = d3SelectAll('.shapelayer .shape-group path'); + + labels.each(function (_, i) { + const labelBB = this.getBoundingClientRect(); + const shapeBB = shapeNodes[0][i].getBoundingClientRect(); + // Label center should be inside the shape bounding box + const labelCenterX = labelBB.left + labelBB.width / 2; + const labelCenterY = labelBB.top + labelBB.height / 2; + + expect(labelCenterX).toBeGreaterThan(shapeBB.left); + expect(labelCenterX).toBeLessThan(shapeBB.right); + expect(labelCenterY).toBeGreaterThan(shapeBB.top); + expect(labelCenterY).toBeLessThan(shapeBB.bottom); + }); + }) + .then(done, done.fail); + }); +}); From 48ff5122d9654618851e6ed6b0324d657295ea9e Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 1 May 2026 14:39:18 -0600 Subject: [PATCH 4/9] Add mock and baseline image --- .../baselines/shape_label_pixel_sizemode.png | Bin 0 -> 17076 bytes .../mocks/shape_label_pixel_sizemode.json | 52 ++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 test/image/baselines/shape_label_pixel_sizemode.png create mode 100644 test/image/mocks/shape_label_pixel_sizemode.json diff --git a/test/image/baselines/shape_label_pixel_sizemode.png b/test/image/baselines/shape_label_pixel_sizemode.png new file mode 100644 index 0000000000000000000000000000000000000000..6b0c58c14f89fa3f89fa093d4fc6b9507a57e982 GIT binary patch literal 17076 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 YEr5wdh_@H~8440jHEq?r%XfnRALUQ19smFU literal 0 HcmV?d00001 diff --git a/test/image/mocks/shape_label_pixel_sizemode.json b/test/image/mocks/shape_label_pixel_sizemode.json new file mode 100644 index 00000000000..bece18ba1f3 --- /dev/null +++ b/test/image/mocks/shape_label_pixel_sizemode.json @@ -0,0 +1,52 @@ +{ + "data": [{ "type": "scatter", "x": [1, 2], "y": [1, 2] }], + "layout": { + "margin": { "t": 92 }, + "shapes": [ + { + "label": { + "text": "Circle", + "textangle": 0, + "textposition": "middle center", + "xanchor": "center", + "yanchor": "middle" + }, + "showlegend": false, + "type": "circle", + "x0": -25, + "x1": 25, + "xanchor": 1, + "xref": "x", + "xsizemode": "pixel", + "y0": 25, + "y1": 75, + "yanchor": 1, + "yref": "paper", + "ysizemode": "pixel" + }, + { + "label": { + "text": "Rect", + "textangle": 0, + "textposition": "middle center", + "xanchor": "center", + "yanchor": "middle" + }, + "showlegend": false, + "type": "rectangle", + "x0": -25, + "x1": 25, + "xanchor": 2, + "xref": "x", + "xsizemode": "pixel", + "y0": 25, + "y1": 75, + "yanchor": 1, + "yref": "paper", + "ysizemode": "pixel" + } + ], + "width": 500, + "height": 500 + } +} From b277856579c8428805ab2307b9501e1650b33f45 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 1 May 2026 14:44:59 -0600 Subject: [PATCH 5/9] Add draftlog --- draftlogs/7790_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/7790_fix.md diff --git a/draftlogs/7790_fix.md b/draftlogs/7790_fix.md new file mode 100644 index 00000000000..9c1c6f47ee4 --- /dev/null +++ b/draftlogs/7790_fix.md @@ -0,0 +1 @@ +- Handle 'pixel' size mode for shape labels [[#7790](https://github.com/plotly/plotly.js/pull/7790)] From 5616f2410ea29b2b1a717226b96ab5c8c236b8c3 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 1 May 2026 16:13:34 -0600 Subject: [PATCH 6/9] Use valid type value --- test/image/mocks/shape_label_pixel_sizemode.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/image/mocks/shape_label_pixel_sizemode.json b/test/image/mocks/shape_label_pixel_sizemode.json index bece18ba1f3..066bbd2bd72 100644 --- a/test/image/mocks/shape_label_pixel_sizemode.json +++ b/test/image/mocks/shape_label_pixel_sizemode.json @@ -33,7 +33,7 @@ "yanchor": "middle" }, "showlegend": false, - "type": "rectangle", + "type": "rect", "x0": -25, "x1": 25, "xanchor": 2, From bb3f31d4767ff750accd2cb482ba0616a8e5921f Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 8 May 2026 06:51:42 -0600 Subject: [PATCH 7/9] Add comments --- src/components/shapes/display_labels.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/shapes/display_labels.js b/src/components/shapes/display_labels.js index 8845c335342..ee2234000f1 100644 --- a/src/components/shapes/display_labels.js +++ b/src/components/shapes/display_labels.js @@ -110,6 +110,8 @@ module.exports = function drawLabel(gd, index, options, shapeGroup) { // correct final value if (options.xsizemode === 'pixel') { const xAnchorPos = x2p(options.xanchor, undefined, xa0, xRefType0); + // Use xa0 for both shifts because in pixel mode x0/x1 are offsets from the + // anchor, which is always on xa0 (pixel mode with array xref is unsupported) const xShift0 = helpers.getPixelShift(xa0, options.x0shift); const xShift1 = helpers.getPixelShift(xa0, options.x1shift); shapex0 = xAnchorPos + options.x0 + xShift0; @@ -120,6 +122,7 @@ module.exports = function drawLabel(gd, index, options, shapeGroup) { } if (options.ysizemode === 'pixel') { const yAnchorPos = y2p(options.yanchor, undefined, ya0, yRefType0); + // Both shifts use ya0 for the same reason as above const yShift0 = helpers.getPixelShift(ya0, options.y0shift); const yShift1 = helpers.getPixelShift(ya0, options.y1shift); shapey0 = yAnchorPos - options.y0 + yShift0; From 324e2d3277f0ffaf6e875133ba7efaa673177b90 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 8 May 2026 11:24:13 -0600 Subject: [PATCH 8/9] Revert new mock, baseline image --- .../baselines/shape_label_pixel_sizemode.png | Bin 17076 -> 0 bytes .../mocks/shape_label_pixel_sizemode.json | 52 ------------------ 2 files changed, 52 deletions(-) delete mode 100644 test/image/baselines/shape_label_pixel_sizemode.png delete mode 100644 test/image/mocks/shape_label_pixel_sizemode.json diff --git a/test/image/baselines/shape_label_pixel_sizemode.png b/test/image/baselines/shape_label_pixel_sizemode.png deleted file mode 100644 index 6b0c58c14f89fa3f89fa093d4fc6b9507a57e982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17076 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 YEr5wdh_@H~8440jHEq?r%XfnRALUQ19smFU diff --git a/test/image/mocks/shape_label_pixel_sizemode.json b/test/image/mocks/shape_label_pixel_sizemode.json deleted file mode 100644 index 066bbd2bd72..00000000000 --- a/test/image/mocks/shape_label_pixel_sizemode.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "data": [{ "type": "scatter", "x": [1, 2], "y": [1, 2] }], - "layout": { - "margin": { "t": 92 }, - "shapes": [ - { - "label": { - "text": "Circle", - "textangle": 0, - "textposition": "middle center", - "xanchor": "center", - "yanchor": "middle" - }, - "showlegend": false, - "type": "circle", - "x0": -25, - "x1": 25, - "xanchor": 1, - "xref": "x", - "xsizemode": "pixel", - "y0": 25, - "y1": 75, - "yanchor": 1, - "yref": "paper", - "ysizemode": "pixel" - }, - { - "label": { - "text": "Rect", - "textangle": 0, - "textposition": "middle center", - "xanchor": "center", - "yanchor": "middle" - }, - "showlegend": false, - "type": "rect", - "x0": -25, - "x1": 25, - "xanchor": 2, - "xref": "x", - "xsizemode": "pixel", - "y0": 25, - "y1": 75, - "yanchor": 1, - "yref": "paper", - "ysizemode": "pixel" - } - ], - "width": 500, - "height": 500 - } -} From 5d4dae8954f088e7d79598ad12c5619f62954e6d Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 8 May 2026 11:25:54 -0600 Subject: [PATCH 9/9] Update existing mock, baseline image --- test/image/baselines/text_on_shapes_basic.png | Bin 83386 -> 87449 bytes test/image/mocks/text_on_shapes_basic.json | 16 ++++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/test/image/baselines/text_on_shapes_basic.png b/test/image/baselines/text_on_shapes_basic.png index b5aa71b6a21df0af8ef383446ab84a7fdbaf19b4..6eb40a229445fa36dbdbf0b648d4639ba96ae4e1 100644 GIT binary patch literal 87449 zcmZr&by$?m*M@b0C6q4d5|k2=uBAaF47#L2y1Tm(C6q=56{Mv@xeCzgd0z z_g&Zi;mh;xGc#w-oO7T1+_T{-O0w6nZepRJpj?-ilX{GTa%~L-1@#by4*pWWg29f0 zf`=k6CH~Y6bu$e!wO943y`iD_dY4i*8~dxrckaAkVf;uW|Kl*$BmGD^<>;oha$cE* zcSPbJ(^OYB&&TI8Hk|OWW~S zeEdThDh2=X|Z5(@cvbWK{|Xq)c<~1 zSRe!g*b#?wg>Oav_r3ISGH{5;%?J(cZx>;Hu>X9d2vITDz8zXiKh_^1{qKwM{EGw-e$iLRyAq!S?fM4*21Q^+W8c#*{ACLXB z6@ekYU0ymL11n31`fWe`$FymikaOPUl$#+$es_&FQ}3VCUQY0X9@Y{JpZwmS6J@yi z-y7*q4+n3?{~7Nb`TOw%;lQK6M-GF6SureVtI+)R48zxc+lqe=?H~od9CP<${2yB& zbqDo_!k>?6)qvx~CfGhcru)N8C*pAHzh*{628@LkqD4yZr&o2z!KeOmB47MCzf01{ zqI`Dk@*X{(6O)>iMD6@1xk@f=_Gd^cqN0XL? z6S)~a&!6NxEN+b?or<9nvf3E^d^Ba-F!6J5X=^D~tX$OlRO5Ji=Cjt9=PrE$h;i1! zTEp%nPF%^@;h;ZV5q?QHK>WvHqOAo3BK#2@FBm?9d5wN}#GoK2SM-|OOzUKSC2i&W zwOM*GuISINZ821q2dllMTT>NNA=fE35gESakKW2m)a=w-#)=#z6ZX7}kJqW2vZ?94 zA$D$8vsuzTE#SWPMv3@O3x>Hs)*F7!0sex47WD$9-XVXHU8}6)d=EVvYd z+U@HtrBw42Uh9&^Kn(5vbdjwt*1|Hi&stSWm6huG8sB1sw)rim%0HK;ikq`cV1CnRvNy;O z^R3r)?ByXLB^8YV&hbT-#(P+^?-BaDckjld`DWMh_rk-&1vWo_3jgbj!r2H1>X82l zw<3UL7?Y=XP3ta%_%vZMkGsx!BM2JtWn-{Cy}W9L(rIWat6$!?8GI+t5k3uGZJe9x z5RpaH5xenG@$X6E`PV_qkVnm5f}R%DTWlUbeyYr3iJ+FtdUCn*m>aT z^Pu8);6k21fkyBH7a_ky!Rx~B!ylB#;j^3nio=8D`ttjjObn%kaXhm>rRFkrg=}^8 zpXck>rb%I-{&)B<( z+)m=@-+}Yjkqc9WR2OC=BWSg4mFv!Ix%CvU<#{k?|FZWe5;8Po15kM z3^G!t%p1v+*?^vp;H=#Zm^wXfxY|m5arvmq!DQpx+t7_wNnDZT z{}~(4UydR3aybgDzAhCVhipC{5lz8Ye$X%GyEEINKke8rqE_$aZYG_gQQ#O4x`Sr3Btr+%*G}i^y*+N^taeJjg^; ze}{8;RR+E@RZ$qJ?YokozKKi+vefP^qCe-a3H=y;BFS!gA=VJ{v;NGpvvA|XKXJkD z9rZt_Q&~oHS}Y$c)ZbYfEzq4}KRzxt?j%UzvrXqR^QiOqG5F~W>bO&XR^YrdJF~^i z>ILHY7R}YqP-J#(4R5$OnsWIuqOJ{c!X^lhck}o1cV_FR(wZ?|PfW;?-!q2Ql(2iE zIlc5tXTL@DKb{oE1SW8Jor0G?>jWIM^2OFj#9HJ&*9L6ub($ZF?`CoPWLE+!I}CC* zcXf%-nZsW{JKnL?_x_Qf>$VVlwA+k3C4fjZ!X{y}+y24y;FVo3{#1Hus+DBu4QFQ| zm(8^!v*Sm1As#Lw16=<;LCEl0i^sALsV0pGr0w8pS4`opss`TW&>cksn{KCaO}#kX zC@eQ>zp*j-CC|XZ_FHza_dzdTpU3RSC(K4?Yj0y+NSqSuso2(U-@dIB*05DRb-rzt zBwmzz3-yk&(CiJLe=;x)OB1FexNf znw-X_3AqaL9RS2I3y=k$&_NG(nlq*PkH_yHOng$!+XQP?_KhgbWEeP0!zSf$+CFG0 zpYuMR@o_Czn0z0gOwwN6RSzv=`ZvU+g}iu}*@3<0B`_=E)fz!;wOw)Fc6Pc8w(;ag8UV1GF=P2cYU~b-jd8GiK6MO4bkhS{X(?zR{^xR!4hYq?d<TefGAjd60! z@x8h@E;s*1&oE1=e&n(>Dd0~KjWd;OZ_rb;nxK zH+gXAMCj-m2?zb=jZEe18}k7qrP7D8#N1BxzIQ*3V*Y(A_y>J!=-|M2K7P9Fc+Ypv-0QEl5QUOnFn z=L%z*l`ms@+((Z(PSX`#2X8EJ^rIK-v8hVY#=|~v{>K~7kTYoc0Afy-vZI=HMSL#? z$vQ}d6M?v*Yi!G|)Ape=&SSbqU$5bggBjW4iX6tJh;D(w%aC!Vs>Dd%_wbwSR=Vf5 zJtFRB^pcgM4H6WB6}UQU&I0gblj1?yog=i3hq(PGwwmvze2M_hasL8w#izh;9+ z_$#QjJy8}J=}O|XEj8;e2S7UXNNUWN?Wm==!e(X?^ZU0E&mU^Y%zeuIFZV{11gSL4 z5fAFph(;PT+7ohvYCZAWp}4Tn#gBB9{5+5mq%cvPpZpt$00dG`8boRnj;bs#KT*TC zPimY_bI&+zW381`fAf#TsSH>6N8s>ZqXUR+$2Hil+sU%w@-%PdKG)Rj6KrSk)H8tj zH){|29Lblkzi?Mq0*v#BA@l4nj1BS`i~*Uj4cgklPPzpz;C2!>ApgU zT_GLb^Jv11p)z;<4H9io!cfx~elK+C`E%Sqxd7x}q>*{WY0ec{Q21P&9-Zwp)L8Tl zQblyA-fMqJx&0}xpag^vQTnqFO24pa3xP`e-$|La3Dj81$HC9SeYUF*)6_W%%`-FB zQu7%0h->ILMFdO_-f3Pk6s4^H!jeRqkZSwCt!z1PQl>y{uL(&af)W7aaa2Yd+x~Cr>^8!rE zs$XAwoknz;+UMuO!{@~3967!l!yjLQDyHK$o(dz87w2CfvV#FN4HVPALvq}0u$tF~ zTp)TSUZ)lw51_TC zywAv~9Q1-TKN+@{(*?ZP1OVy#P?K`(k~r1N!y)Ag0OT~j55C_5J8zE_6tEds@K=bQ zhpkEe;hOu=U|%mX>p)_Sj{0uW^{N;ErAdq2wACDgseTIsAz}A@W1;WwUT%VNv*aev zb7YNShDdc(8lO~`{Od@)kb-;T|DI+Sm>Ob!s$nfV(rU8ILJ58ekc;m5@sP5ZHOP=1 zjT0DZCIB9}G+*Z%*ECBr*%&LVxTW}JJc^uq^C$43B6R1(e_>xFzJg03D}m-hj7Bn4 za!cOV!#fREK0>E!Z$JB9UCQj2Q}UM1JqHoAG$;s~2heog$!bdCt5?SAdhYMN&$cQ+ z(fH*ey%6iK8Plt1K%IVL6#rUK!>42Wz&bPr^+8k@hLwf)q>>abK^QBFXHwYyn6Lb|^Rm2wI*lPm z#XCS6W}lVgQFf4{h<>GAmIz3-Y9AjnX;(SCulq5oJ(?wnk*86dt?RYddbC;EKN(8n zW4_cLTQTQz)(et>HK=cnx;Y!hlevsG>yBqj+i85KtBTY=s5D;gTwV5?M9)<_=TSKi zKMGM11#nX6>iocQLQ?ggnW;krHSHI~3s#0hPEma@jGydGl;&RSwbSsL573%j+y2f>FWh(QVe-6(%9rP=X2E7RzqlW) z3RJkb!fF1tFfHUSUQ2)$gno>;k~{($8e0H3%0d3R89t+7D9-$GimRP+X?m_W?u-|2 z&~mK68i|FvVZH$8O@X9i)%%9$sExvQe8Mcl+TQ+DOPKRtF#1Rt&I1CCVW1yl<6WOv zjm~g}E8zb#PUen?KIbPT3zO*peG}a);nXZ?=|C3)03LW;#urcmMb)W1`R8=$@zfyC zA3~)v{Xn$hq#dY^`nMm#O`&Cgw)_fQaa-Q}_Ma#E_qoRNggVL6<4J>Emi?CWzTiLQ zffNbq4;g5aJV+e;7N6Mvc97qv8%Bfr1VWX6Ayr4p*Lb8zm{`mPpomf7!aG=h-{_mSXKF3^pv@iWJ<%K-F?k_Izj~Dpc zAvcF3{<$o)Ng2-mA4?I@fl(s|l0It_`+H-W|HVB1HWz?OfPZ{vE9s5zuR)*b`8$sO zHM0(4FmP4V`z~O@7ZUJ`zaAj};jaPcGm+8yM>DY?M)JcxT>oQ99X$Ram~Zp@yqk49 ze{>3pBOOWtxMnEr+Ardbhz(WuH$h5Ef?1ZY&rV{iaLfn@UqA3ak!Ks%zh3SyLANUxite%}&-1xUoC$m76zMm>@L`dc+5=R;Eu;wi!5N>_ zb)7K*wQMD;vgpY>x+2-fG$Tp1_yZHaec?6X2M@d3o_i%SN6nJf_X;!Xkbf_t0j4^> zCKn2@yo2m~n(J(FhVSKs$B%Ur5bbIKbI?~0VDL0g_M|l6cy*zMAzwi%umK@Bh>4N0 zrAOqu%x~DSp9I|Gd?jyGIvb&1nW(Ju*)rmax_D4 zP)*lU*wz+zIDCu#&BHIpfQe7DE-8gnK$LnQq19Cy%0u~GXZU~mxeI@x|bI9*_`ELd)HHk>()*UyE} zHlMx}ZnGQM#D97y7w~HVnfDQ3-0zr&J9Bf?-iMD^RX@EdrAFp3kg<7$7J>+IHt>tr zaGa7jbk~)T34i7>a^lhnaN{|?s(X0(R~I|JQ)}Pe&Ny!6q}bde&^=8r)cVpDe4w&3 z<2v`{j_N0V*CQ~IDNy*WIoLwQpMm<{Dfb*C^~BWF&Cwr!G9Cf|YKt(xdMXQ*nzw~6 zE-vPKo$R~xiyT*?vL)uQ7F0G}x3X=xaA6=x^WO$(cr)k-FryPWiYZ7c-`7$>2gls1goH{>BpkxfyOOaS9WLUVF9+HX=71{65LSirjRMuC$?SY3xtiPk=!Y4tAS> z#8~Z3sp#jjM!Fah@VJ13XeKL*1kpzdD3JmZf;Q=(VlNX9L?<8J2e_uSpmzU34Zsas zNG2x3=d`n+?ntXSJBIb#he8bvX=WA_NQU>(Yj2QBl|KFiB=+Q2|7+LzekgF(4Odki zoM%%IrMt2rbFSi>`vxOSU%kG+Pnz~PjYYBn)|bH5kPg+sib^DNZhcSaD?oC#j5L(I zRvLOKGYGFjxduQg>BKkto-ffT;Wq$#d9PalXi0koLR!CA`EyOEVIm6W?nJ3s%~{Rq zdfsR2sd6P2X7a%T-I{5i_*UnQ(OxCd6JrEqU3bwwl2f<3EblFFVK8+o2yE>T)gLkZ zMA>8{VWXg?56KNwY>U|Tq1zT;gPI|GQ{vV&5TZd zv7EWbNfTr=&n^LJLDt29wy~}OWYBa?$^>QvF>7Mds&fHwAP(dnps}f57xT|pWiPdV z;@eqvUhXD6iKbpKk*vm?cTqgumoeq?u9)RR0^ry9$DD#3d==3XM7anGHq6I&YIa1C zR8*vhS>K#en&1Qoz*a3;WBHmxt>)#HV|`(o$6LQq&kgU zqk9RARXn>WO?AoDvk^X^%&ak^N_1Hq6{xpglKE8m7_i38y%*V$93{wH0qRLxbzSEK zx}I1{fx(gR*SIrs{`k9kR4hI!LF%8LcCHV9G4 zlxvjr^dk4!*%_$ba7NgCLK{)OSWN&Xz zDJ(}+%`sh<(OID|xkd1#5rc-m@r?&;hOM~LQB(rkX5Wn@D|I=U6WMZmp>o4gC_q5% zLHb+R)B2diGv>^jX9OB0#^LxJZFBR0m^Wra^rdao^5gY9BH43&_<_7#ZZV=MwL$sS zW82!jw)*QK<)(e9Rjsm!@6}lpCmAQD=Vo!=`&r#zH33L!PNCv7FXZM! zgXNFbzDlXrC)W#oj?~;z&Wkf(LK?2$&STP4?MLZkhKpfH0@Ai(&EL^V1T06{EGNr8 zmS*;Yc3FlcFX)~H(8^7@E(DVbR=DVmBfAkPSI3})aV3u$x?}PC9KJ$nLQ9l}l2*%= zC=lrGTS?+~igtlgs+*quDaP@U>#TdbJ6=|t@oEIJpM@8bY#8ry^`p?2ygiIq2G4yl zoEaI`6E#;|$0|j!0^v_}Uw%B>t~=H{rj|incBG=se9Op;$ttfoanwFupx;oh3hJf(F9VgvQ(t(Jt-jmrb~Xi`D>m~)fK3R_#yv%7n*)pQjLv9X{R z8Y!eX4VoDnIvZZ5M*6b9*rqUJ2&gqH@%tl3Vy(8DLvdXtcnpM>`#z|19_nGuphzg1 z8^}^Qzv})OBXpNUKHdz!G?Ek_f@iZ|d1e^hzLM7BSa}|wyHqx$FT5<+abNSVoSJk8iYxRvmyu)Y%j9$?8nXj?&h4SvZ$jkhu(gQ#Bpxz zdzZ`)1HCV&1sqp3x)a%>k41Jo*ba?d+n>Z(K5;!g{LU8j`i2U@JJRi{TM-Z<^rwqA zH5NL_`pW_J^OYKj9_y?8Z-Eu ztRxNHU&mqT#8QyBS+>~nHg^X{%MQJOZ^r4R)=zpN~j9D0av?&ch~LQ zagZPuntDmtG@eD0a=N(RzzdP@5(LfaB@xB?ARrH@Hafq4>ab7=+IXP*Mx_ z3%6mG123b`&&RdgOj} zVg}UHJ{*OW-yP3901wN7I*t{6f#lfk)uu+NyQ`6SE;SbdbSJol1;$rxoj_FF-idDs z-Bi%WTRoXFp|Rg|i{Cwt$`0R+1${Mg`8mA9egOn!Gm{TU5F9#zTu^FyKwYHcb4Yjz zZ_Ptu15jFttzR(4Txbk@XP&*yQaheY4{$E2e`SN(ms=1t1R-MSYp`X>nscOkp*llh&1s+1eehE`R#7B zpNQCRCaCLi5utA~Tb={m?G;D*O=X=A5tG*MGPqoL= z*j9cgm~1|QZ7z?0RZXL$5M~YEW8z37dzK!kF)Dv6)J`H9cc{Rix2N}usyfu+fu9|B zkcmV$%fqC$IVNgrSPeKW#m?UcTbZ6q517(Kya&3KK^0N1G;)P?r_J$iATQN=V&3plKUGgAGHW$sT&hc9v|8Wf%^;4q{GoG`O}5gu{%}x% zBb~s2DiT-gNL}B1#4bsawmm+G6{!YEv%JOmFn<;2VR7<708^(zjNsb`zw&oKROPPd z$?{8%mx2L2n!|gSoxLW-N8ivNJn*F^*#%7`%?6)~sAO%nSeV>HZfP8Lj(Sj7l+&dW z-dOG*dJNr(5X0uVuKNA@7g$wkV<`Wx0IeP8%Pt=EwrhTNO~^~XR~sQwYp|Ey7%GTzqWT zxZ?hx@49e=Ts1M&zf_4pKjxWu;`+3n><{UAIA$iy(4$_1eP8tCOh4p^NEgYjY`Yc; z#nM4q;D#bt0bh%tFL)BBnw?+zvvIuX(VqkZbn>X&FVLwP?5%p3eY=m&o~gT*C?|Q5 zJZwG|PZTr(n9q$qO5JUTXl6+S*Xl?hki-w15l@ANJ{c78uuF#siLqC$BEoa`9J2=r zCZ3Q#Bf#zCB{^uu6`O7iFu-R{-v_9=?D@zi@`)+X?^4+q$O=@T46G3%xm`lQ9ei^; zO+1c!%%kA_uj7Uxfx_pUl9`yYf7K0J||m`JRwj>HcCLx!vMypC3scF?l%o zX8imLkV4#JTmK_$E!=_^V6zPxC$_x}bx){5?`NfX5E$1ZiZu&=NEOVCM=ffsY$j&E zz*uCQHdtgJ`8FC2n=Dkq$PV0deJ)2Se1#vNmp-4aimOgT7S~f)aPUdnp`0XY2L3B0M3}??iV(C zh$)>aAR$UEWt`kr16wf#^g6c?kN$D*YwmWuf_ZTr?|Qw5(d}%guQXYb9JELCH3>@} zIvLU9WkHXo*fH16q~Bqk$ip?KOS4iU*|vQ=;`f%?DQr^A2U36t2@p{w3(cY0g?e@Q zfV69)eRW%@W9Q}ov2kOW6iFkD8O)_&G)cYt3{gblw$-n>&V(Iyf0 zjqP^N-NyLWw>3@|`}-flnRn0=JqhYwL{q(orwKaaL<;vyNqBeEEll0{z;r=7hoQM> z|K$n{5cM&)B!#0i^E78eiU!q3=&%~7Fl9J`FNm9@KJ4@x=>or`y$4%XgvUmCs&Got znqn>=VyvS%>4=>D*f4`3DrQ_#xOT0Ea-s<*J0C>74_UU$CvEe)Z`!~zlMKM64<;?q z86t+X8i)-gn}5t`4_LHdPt0<&)CJ>W3pxWqOE>*zw}rWy4kLFOpzgZZ(7!72+^HL@ zUAb%_R4!vqcWXix>j?3u*;3(UyjUK=1Uv_6L#tPDq1Pf>#&D6`CB7195MI9Wv)nu4loo5Rf%`b-gvxk#XW3I4+ z!#VCiq+i2ZOH5_e`pHojImyivIrV2-A3LZ4^@i@bK;qjmJQ3l>8q<|5qZDkDU`F>+`mowd`)qxWXIzm25?35cA=Z}E(nBT~WJznw+%jlrU%sEwP9$R^Fp9yp0fp*y1EdzF>OE4iU>|5T-6(+DNYzi<8|2TXtxS0?8tI60lkv+)D;=o^(wV;>$h7o9ev@cClx?XhsUg_PZz|~OUSFl z;hQ!M7d)j83Y_C;x--k(^JbvV)73}~O{dAb@p_s)t^`AaZ;)J$lVj)FhTHgV?L4_;O?^@CVa#&qSB-$|=+iS+ z(5Wr~G>XR6<;C^9`wcX{Hw66TJOm7ypcRp3#A8dx{V|c8_2Zbw8gp|V8|;#e?e?b- zR<_w;$>K3EAvIm^SEfi+Efyio&0)||Mhc`AVlW-m-FGmi>{?#7hvM3Qc#tsg?0#8* zI_}u}UF}?sjqk4=IYm4U?;f2s9V`OgS9yxhVvvz9W`*DAv0KQSu`4Sin~1I?Me`V8 z7y{Q>Q+JaSC@p7BEaK>0vcA~Q*i1~hw6JYBD0i-2Hax)9)MJ}vdKEeYXw&pIzeWyD zEis3MZMr^jKkp7TBDEvogW07s73)ZK*BNPv=74X?i^EYda0cE}9hi3zd zZSFCT>?+!C_V(Ol(ZFAm-)$|HE0Un6j597%l^gh)f_lkVZban|IW~1;HBGn8Un36U z*?z+$!LJ~pQS_KOi0JwG^_Tko_OQ}h^S1-xUHoWS_zVyTJ%YA!k8R!-Q#@`CYpB5< z2bEM3t$|^GV^`a-w)sbg1()}!Q}sgI16Y%d(GCXIU8vJ5d5s`k!8KZ-ryiPpYkJtp zdRK=Ae8m!v9qIeB{ns&eZm&uMWxkgMpZ;YJ#JZJ<1=8OANqE+0C7O!BCh-}?AJ8;qD_e3jp*?^5Dk~#h-~svewN@EqDU$@5qnQ)X zg99NW&%V`e9bl#Udb1zpDp7Th$3~5flxxb}$3w^eDTKP!=?gjk*_FU+sn?LK>uy?` z<|SpHBH~ybNi0^VD}>0=tZ}h!K9$VTr{2d&B)gxbddntEPbr1Bm#oE*9f1}iGmh&f zQ1H8al*j~{+BUzWOWGiYeD2+r_2|3Z@Rvrj@j=9CW)#;<(mge*@Nn$W5bj}LJLcoX z>Dr4{O{0`^>jGGCT=3<>*byE$shW%AU%hRCCb}p@3a9VUo!zuz{rBbsyVTxM;&^3`rWu2vj`;}K zGq?RcSH*M)+xWTnfon8v6n(@T)H<_FQUg&Dh0VWpw@;j(k@=dhZ0!oXA3bw~cl_mP%+;vwvX( zbdDGvhL)RCyhq2vWt%(Xf{Nu-$lft=h+f;$jzrF9*^ej6&n^OGH00(8q~E zBfRojC7|nLQKcM;3R-zf3gg4J4J8|eXGuK51^xyG;w%jteL`t2NtF-u1kJgCY}qIm zlj$49q`V#nj+Xtk*4{7-Ad<`RMPgUHk5DqFAwG0Z7V2Uf&>D8$e839Z@ww(N1cNlk z2c_H|Wy^QOQLzuc03A%P4JHjQR#&rPnSi-2s@#?W_K8nXEOMIFR44OsF11qqIjbMN_? zCR@LN_m^5=Zg)>e> zAH|3Q>GigXOV6X^pFT_S%fz`FhZd0tF95`&@MuogZw|{QB0GuUG8k9^@RU{NaWre~ zWL2BzYT1U#9OPBKM6ujLm1UZN%^)E?zpY*Bl<2%O+6%512;`oyX_rSWWVbd`^|Et{ zmE}CdZ<&vEV>i4x5qs+k=m?GGD$~@gf6ANg=5*N65djri7!yQ8z33fvhX_~ZsxW#y zPNk-qT?Bo+GgLdD7q)|A9M0L^C2H6LGg66GMdx#Aax0RsS27?1#J7F=gE3rVYP6W#9lt=y$wEGI=K zl<5~|8`0TZ(mPxTpzj>^^^ME5wZVk<2OP1w7blVjFq+I!;&9DZW}%Fx$??o zVYz1%lP7{jnm&^nY3R4%aK(bPhN0&D>XXKW`_U6+CQAsNJ>5p2AU)(n@!yU31){=oA|-=ieVnc2NBi}^zznYMmPmXqPGU8mp^B$X&j#}O7-=!q+T z38iXLp^rO=rxk~B^0HA5H&**c(rpZzeEb#L(Zv1yZ%T06M`JjMu(4bU2dOv2z~vzK zu&(h3$)Lw*)D#`=P8(4q*`fDd)&}Sp&KTb9=OK41efO-jy}A{JxG`8?NTmRB-L}mA~impoVBKSikt zMYS})WrVM_b_8TY7Kl-ktL+~6a!#KCxmy$^G3>kDLY25Kk!5~!Z2fK&gi2R-3{< zcAVl9hk??{Dj)kXH=YM|IV3-JJq#f37}&1lC#}BC%I2lb%_RkmtvmJ>5+0h+gGqar z*-oZ>lRyHsyyskb&gKFs!uI)TlkbY1x4k|p%5Cj2 zu0dM$F9C@P9u$wro?X_iZM~H?Rh)dPs!lY}7~L^dR#-q`Qhe9UE_@_e{H~fH@Bn9W z7+rFMlNY|P_RJ$F{2 zjN=Z=UoBJc)_6oJO*1u2hZEv`&hb&95~p469pZ%R7Gn>-((Vt0qX?0oM#-MJA2uR~ z)6HzLF7RIPPUKGb63bd82b#1v$N;IkQLDmOV=KZ~{WmA+_o(O4Hs_T^67n%=)s4NM z%1Y5@U`G9m?mjqqeljEs`6=%lIWc0^I>nTmRPrQ-%|@2yrWr=kJ)x2}6VkbfMcB%> zE#4E5PDWqVHp$@7n3_Cjui;Pq_O`(xO#&rD(D{uvr}hzTb1(n{J5HKH?)LLtosz>f z64_kN3657;+`n`&>d>$Y8FN#=b&OV6u7*zWtL0C{bqU4q?%LIX3qLwC`qSdYaSTss ze{z47qJxWDkV6}1xew~$`0zHj_-d1}n@wzqCQ!`jiATxc=F*U2N{c(rbSHTeJROyp z_YJ;F%s~M4 z>@yO{MN>D=Ux3-b+F+mRX~XE`4m@*qD-=br8XO&N(t4FfGsoD5HaH(W%9z92D(baG zTOjHdn4-*m*77W6sh(qtuB9YHLd-nFo6?8|QS#1?V{4GJ{KQ%%qrS*E<>HXEkvNu= zNDJ0f7XCPTk9=eJy$C=X2QSX%y~@K|S0~H5eNKA>$8u~_6%51>Ma#mcp^sykF6MQ} z21yX#(1XF{nxk`G??p z5^wS-iA-Imr&wk2<1_d3P>5gSU20sM$e+NA#bDb z#1jkvdU;7WdWxU0X;Vo2k=Y(({ zH}9n1#=w8o81hyA?3YU{RP=h=iB1hK{XZVj{zYRDw=bB^+Me24Wn7lVqThCixi4#1 ztaMC>^FHBTSbZ06puR>5tBY(6cy z1vF8XyZ|&z5U}VD=8xDjZGKp9-F(>?7>z+1sETg(K60yUQZ@eb)RnG9rHpf3ex7Q+ zMx&kUa^rnK05vDXN!?7Tu;QAI0oM*qD{mKPV36577xuFMv2PzW;qrlna##d3O_nK8 z*(5K{j``B1VO=;SVc;Wv-1g0O6 zd(q<|%Ic;^B|GJ#ZX?|3-u%eN!ko8bXzdOcWDGR=j@|E6`9c`8kU2jd*2t(OxmNHb zHzws~xDk*V)PJ#>7zD+c*)#&&n7=N~mT!;CBu}{gp?<5Dt%?tQRELJtgKZ6Fh-^qK zcH3LDzDZBAT$}Eo_d^LX5vmBDbGF%mnh=DyM`$(b3Nf(Onnm0Ut(~>yZ+5xoLsMMB zjtVZecCysPn)faGsMJny@kEB^&mKgL)1W6*N{XJHcONy!KUS-C>x}zKWvi}dFKsT; zcS|vSk&PHAHty?Om#_4XT+4sWokpA{ev>2tsrH{Nx3<)9dvo7{;QgGHlZ$p8iGTJ( zzj5j5PfJTn*T<}bET#+byYM^k`R!k~j8L>PU`9CH$y|D@n93v}wmn*z54O?sVWDtL-SsDB* zy{xnqBLRK>G;)w_``qph6_FWJL`pQ(S@d44xZ1>i==j%`&qpi|goEOzvXrocNUOT^h(leSrXT^tkdYs&K1r97lqL+*}41L9kchX~bBjVCuZaDML~0D8#aL6JCgG>CWQBeZBl=7MRr!?@+2l|-Cu4jWQC3vsir)(Y7Kd+Fl}O! z_We$>0|si{^MnU#`5N}kx=t%y#38C!V@l8ia&A*HO|jxz2_kFHrYhM-5Go1sKjL-YCItnr)m^f;nJZO0?hZJ^Di`QpE7dvzBv%aTO z1O$T@&v4b79$=u2zSp!6+Ijc*sMYM6mFwe@NFhW@TN)uY&W|u2v-uF>$dwq~k9~`x zXUE1AJdPFK4R41Gd`?(I9 zR1{N{4ogfeyw=hZAAw}$4H`wBqtdBVJWpW@Eu|m7OT6TQUcDnisX3TR{RrqCM)!Jg z-$T=Jl5|~OXZ1+qOSnPg=jEzp7x`YHh)#JaZOi}hGe7h%K`*`ITyHoJMz2y*shM`i zRK1+VL_I^bi-Z6DyR@kfK}^9t2r-UH>&hUtLcJL~W=bKKe6)}9N9(MdQ=kK9$!&IS zK2zV?20tG}B2HAxkm+7si`6XHj7*o1rxQ8-?|!U48sZ zI7WBw6BU#N{y6Vs&bVKTgEtvoA$!}u+nxUvf!!@SnlWpjfaIzp#EJ*^`6eoFY#%** zzf8<__`BIIMO%&hX`SsI<+^@ZNULPS4Yrl&SQgWyRBGFg;d!5T^1L_0nW;;gS#M2c z5kpcAWJ|1P@HN2YSzYBY2IjzRpt&(X>TbB0FeWAi`ux5Ctyu_hp4SOhxrO#8cKr;) zCq4=#oMxNl!FloQT*mUs59}4cBbDCIVNx=(_;(%=WW#E=t2b~gPmmYnk@wm==aRc{ zVrfd;7&Hp?8$>@ZRZ0=6UjiLf^#T7~pxPyA<5F`g2lv=K^KTYR^G(|YE=($Fmz@FW zE*aOVS%!BxF{j@2NaQdsXXcO?+alZTmgJWxxF+ZZD4PszXHD3g_jTH7ymrOUz;8() zwf_zg>O=*|i`+oVI8G&NfhybAtuRsVUGrp_+Odag6nTwaP>={hs_XPZG5Ky|2f1I0 zNb!YxRZJf-xSKz(DQVaQew2hF+(AA&Iq7JBL&ry%aqfK~IHMba^}6ZNJ#CWN50CH{ zo4@Qi7zjP?0>V*)Lsp}`1)&#%{n_KOaj?fkw%W&R5KY1`?29{hUhxWjwBfS!G{m&j zsHyBt;ciZT@_%H#bySpL+x1NhFu(vqh%`e93L>F&cL;(g4$_U%Al==KgtQ1KAW{<2 zH8i6l-6bL&(%^TF_j7;m`>b~@|8}jJxwy{bJoetdO>GO;-H%#P(jUa zd_7#kr9S4E9QxCkB^=Y*a8K9`Ica5qO{-$K45`Brcue?1)lx&D+0Zql(Qe~9)1XcN zpU&I-8?7&rvoQWD`((io8f(bY-^(NMAn@-|4C^wB;XVOogmR!7YpSe&LAn{@YVQTf zb$C!Z;-ucNFxmxn@WJ+0_wDEMda{fV^Hj=)-Ia<2JVvrGOpw~hdxK+z_E8_!pZ9s` zoo?DVaN~HlT!<_568V$x9u0^(JAZ68kYA6MX@KsDFY1j}7>chr{s|&rsx)k3z2``Z zR?dBPnbvImuz|*6oK#Jt+4yvLxk%8Y9jj~fpl-%tu-v;~+q`)I`58csD#*C5_I%|` zJj9Q*ZNQsTrNB`CCUsCGn^tM)ly*e7-g+^|c5{l_^IeQJ6t?+u+Z*AEt8p@DJ+_GG^p`gMzc5&4n)cSct>#1a`Nl2*02Ga|(tFf4|* zl)Cl1LF*7E&!vd$-DXU;r%EU%kTq%WT`|*`{haW$B+lmc2Hq>4@9cH*EK3CY$eBGk z87!6!`je=@c&xa`IJV~)>o%8Rmopm4)X208Yo?Abb%F6OZXx;iNd+ z&noVRJ}RcPXdVTE(#lDSRDz;NMaqPbCn?5yKSCL~@BZ{4TN_x!4L>{in6bE1rbZ9TRG@5lKHRhO?(jW&m=4f=%LWVs%MHVeAe$u_{zW;&a zuG__(ri%*ktpW9!nUw@dGuih-<1F~<-E=#XNj4lY1morYgyM&j%er;1Oy<9Y(t{AP zdd>wKS<^Ddvi;Tg6a8kfo?Am2)sFs})ob)r)=YAxf5Br*AQLFd&zk~$-SBYPEZ#>{ zj*WM`L2=YhS10nUgAGS)eC4K*X9xUPJ(bI}L4v||IFQ=orP+8?)vYOpG|%dKwv0o& zGOYrf^eJP)O=l_yut~b_)FKZzPJ#>&QtzDp;M|+XuGOir(pdkZnJqjIY4CdcYArJ% z0vmmd$qn~qgbSm*YP)+@fW`jXU($~?%9v_A}($5SHBX4 zo^trHKqz=y$>nUI0Tx-bh+hPoTsu1;(7_gpRm3tLFfNG(FU2%7W zSbUbktVz`IHEbW;`0p;jK^11Amu!y-$~(0GXbTAN`Q6_OE-~*^VZS`R_!fHxLM_+6 z%9DM*J9E-d6Ht%n55H=d@z>9^YpCJ0d}W>B68^gtOvu-i?Qdda;)%_GTXI$~nvZUl z@^&i$)TjJV!Ys22t`iri=Cj&EBk5ghN@A{sx|{-MX(^?g>ah?evkrpWv9h;ABzbtV zv#N%JCsDx~QVAGYR7(oRDE4C>gt&2AYwO<@`YL9~sI)f)u6jFlRL46FVP!I~deSiX z0_%gXWB@A@5%heO%d}G5WmUx^lHCbP*)UGo^}P5YZM`uwD^`%O9FF&=`VxA}VN@Fk z9L}RZ3vxsIwydKn`zaDA%6~jukK|xXV1l?`&#R*P9Em#UgI@EIhQ1nE@@S`twus=O zCpUTa$!J^R360}^?D9#k2n;*tpU$r$g@4|0KLG@X%pQESTWFm-)hO^~V-Hh^2Qh3l zam~C-*FZP_zoB=|TM?lGo4BSto=^jjyF=L#ZFGfvr&F)*bi5gKlLH@Z<&VDR%N65N z-Jri%eA4Xcyy6uXOxnYMBel6&x5(s0U5JorSU>AH^Bjk3%KY_mw?skL?w;U03bn0B zuWC>7J4)xkvoy8ZE+_|RyLj^Okb@3xOA%!b3^Fbvz2tce1y^cO?Q4pm_-O>2 z$2lw=65yn3ygwBl0WLV|$+3P-$!{TvUqIFx?hFCo5792VkQEb2oWVdB#fx5x5CS`#*SSY#zcm%t=r95^F*4N~c)vOSU!qEhzE1VEh3g(0Q zNAwMSY~^g8ZzbL_F4qHEk|P)WKgDVt8Bd#FO4YF$=BiD@3SoQ27Rzcf%4yu!6*MCm z#sAO7miqro&5!;`&4@IHAO=f1-GB=8Vfuo=y2Z289M|kB78K(+`9N>j4uNUbg*h{h zfEv+Gjx`S2=v+4Wk-_r*Ec>nkc+6lG5@o*#25>xG9J!3m$Zt@&-0a*pwwp4GUm91B9k$!wJ8!RUhvN^ z#|A7pQKfR>#`saq@UMHx>>Rg6N5<_mtBjw$o6N}bm|68wt#en8-k!BjOO6mZMC5aN zH96)0>?K?hLgN%q!{6D=%_eCrgF+mp={uN?>Ltyog_A)x5m1BgxA0pw$OI=X0;A2y z(Fh)HWJG`a&}W+a9>2bJcoqZA!RcXuztKdLTelw*UP;2|kx~t+qFF)J-QtItW)=!o zi6dB<-EJ_hDnx#Rk3TaH#29$Q6fu3BVr zhVqWbir+)+rs$k9u7riGlMvmJP|~W~=Rv%}XUXMIc z4jx9CUxsU8ImOm-LA#*E<)cE;D&=Dml;o9OsOonlR#qn2%KELXyTonA<-fLiN1>Lu zZI*R4+}XX(Ji9!%kAj4>zJ4Q1C731f^*rA5{dpD`sA;@J4+)6-3ooV@cCbSpYri>n zy46hLyI}gH)%WZxQfTBCZm^J@R_fP?SiJEq^YX#uxMS5Lm+U(7XxMGotUxfkr`egXX|*<4x8R`({j+PU zt9h?6o(KJJge2!kY`jeO5EqMACx$pwMz?HU$(M)^Qj%#c-}55;voYHHH8d^yo;m&B zho3oYQ?_S}Q?|;cn(U{hsf6vHyU-MC$m{q2c?yIHvn;G}@>$}lQnMB-ghH%{M_hYk z*)3hhI&uSGmO&a;&VQv2`FzwHWpCj$v`AU+08uJG_`yOfvA+h5Uy80OHY5r$o#pGN zcv#LJ;&9BCUp-XLC$m1)+X&135YiLLu?8ZdW~RufSv68A8{#ksu0^sC|6Rrqi)Ecg z52_nWYTnAt5<5i=p$Cktu)QmmzD05wU;BoN*F7I?>!GW}*eGdeyM(fUQQ!jCzybs3wfl3gP(bS9B zi*nL119BROi?WZ6M%U*aO2`MvbeKmHNj!>dvdXcBqi>xr<@p@-5VsjHryn!>pLXn- zbp~%;pw9GeKo$V^C8IvK5E4jestTQi)^n*>se#$!8>)d)*HhseS*Y0oE&tEeYcGEU zVr70rJn;I$r#RtOxqqhAGl&`KWzTfD`=aro4QV|^YHCydtv*;guo?a zxpUzicvX>wUWn=^HZVx4!LeIicx3&>t5YK|xKq4D&KszSA9I zyL3xg3e zNdwC?m4O=OuLA8p43{7JDVoU!FwT!UkbM64Cg{;^Yz0f1+&pv~Cg7pM*c4AEfAXIo~vsG|vj+!u1)C z60}s^@9Y3s-Kn9vQ-4Ip3S(gYNIn%F_lf`5(`U3H-|gu8mt;fnnm=OF&nrxg(&ai( z?1oPi$_e@}NwZ=WU;cis&9V5}%qUU=jlC(r#LHC#|GN8Slb6k%A&ix9=~OcReU~A< z>CK?j1-3TVzq4`~3a7<}Fjn>#Y}f{1hiAyD+-Y>$Vs`r$goB^|+xHW^O$oGiGvof3 z0!AXVW*YQY?1EELZ%TwS^MGi)!ndO z>DIa!?OMqTl}i(nUx>;|SNtuyyb5g05trw-xn2yV@6Am6RIB*oF#K7R8XO zjmpy+##*WE!L}s}c~z3Ab_239>775w(b0(s?^8lVQ)t^$%o~86&+5C~h1rp3ja$mF zdzi;>;_HSLd8M;AuUED*=$yx^R8_^fq$&w^HeVp$dbgdvbrt7~PYGh#$wq3U{14-@ zgio*jUQbvqb_a)Hq2(Ed?>hg4-68LM=J2p;YA|_wFtf@2{H?_d9mTi@M;PpYdOkoF z9$GI80$`ZALd9J{f-_hEmlZ$3LeSyc+n$B<-*dF1#ETo;{LpT8 zpy>EkLUiNKBr1-cWKgizCY_^)cpJGiIa0njttJhJ{UYeZrsi56q&4V@*tBqWa5(1o zES7}80OzbMnhTRG3+@wVR_lDNL~M{)#e4K4h!OgBt>!A$sfMPy#=690Xu zKMK;bd;`U@xgrQbK<6@ehNd4C~jJ(7x_nK_ySq zq$jCFT&mhb)w!)s_iD*@k1hml$$t8hdD;|xD*FSLkgyc#yJb(w`>=!lqdl^0_E!9{ zy4~dBglc_yiW|RTzAzWw0~`TX_Vj6$gCkroV*F`LT-Prx4%e@?@O|bgTBq+k5uMew zQ*nM{SQ`xU%*u5RwLrj&~QLOod{JIkU> zxM(td?t|tc`s-`lh4Sgn-@-dKE#9xHem~`A@DvvVdSt!~;o@{(AX%A{)wrQSsVHiZ zqzt5Nqcq+XBJVgQpo%EUhg1E;aqA3e#(vMa`4(tZ`{MFN2kxLDKZ*dXn!$NG`n^=4|+|yNl&D^lM`eQUp3s1I>1sS7#Atm+D34BpO?FPF2c5dC}^wV5;6kmA1z;NWzLhkO(UXcjb7o00Km+gPwzOqun z$&3`DEwj;wu%^gNdDcviEth+rwKpdkNgUlY{1B@*>fN(lZmy0j{L=H$?nAp>ub6p0 zm2v4iQ(2Y^{f*?H*W8rWFf;P6w6F>Ba~t!@!TbyY1g^~eTx8zB>rWSUfOp7MtqHaCr(j@9DEApRM&|_z~(tKsPWczjK%VsN} zhP_--1=SXoCdPTdn~(hJS$vTFXQFFt?9&BDn%y`i`n#;I$9ci0nhXdCtIcoVuV@+A z7)2o}Fb?QO8TLA=1>@cxLg{_%Oy zV|K#sBMr7}miGN@S*LFC-kZ4rv3c;{T+qlLg?kbTa78SOtc65J0@-xGAIeTe;7N#Y zK@14>-i{rd{MqnH-KXJ4&HuJApzY3kgak$Z$HQRfn^*bYUBFTLI?+i;HJQ3_=RIQq zBBJS&6SQl(t4QAQ2K~gbdhTC_Li_1Onm@nFcIkU>SIWIF4lwAQu#{fci8vOKmSn4I zWMbG5-2AcPyYT2dyETuY_b|v^RNBv{)tF(0VWfyrZ}g0~FOP!4`k=)0^Bo*f7AJ(> zEO{r{Cx%I{I5lLi&f|~XjTYRr=jv9|wdS^{DLf6e=P`*+*JGUbriO**OaT3_n)sf` zLh;|d7JhsDagyb?%kntq0rS57KZi1HC1|2HWf9hUy@&(?W6jg<` zdJT^Ucl+!7o|P^SxgKzo#Y4OKf&ed_PWNT`Eodw2<_QnPM;}&k>U= z#Y%++PNPJm{OqW6mlb>{kdRoAcUdCO2D+3Zi>R1uNN5F27bRbI-VE5R79WLRl+%C- zk?^CmhF}+eSt@+=QOY{!#NhzJxV9Sbvo%>h1{*?S8X&|DCSFq6~EPRt(@y zjPK(|^h~V{t4~!Mqoy?`jLjpS-8JQ8)*ccQ;(amvn?t|nlrfF&_rt0N5p#scdX9(4 zCUJ;fven|3qvtjzJ^A(>mkZ@q!*nQv99X3as-uf~!riRgJv4L=h@o30YyCnm#~m&l zWUKAxb6<)_39hpiY_87y{Y+^$PbRG3kWt`?ihZtl3w#KYE^PTnbUU7|d5KC;v)DDvfXtbq3BGGYdPl?WE6A zo(?anpQiFNuxS{-XRD9KWVjMZ-QM=%ptKMFQqS{!6M#^m`~5|HZ)Hb z?$oCRJ=j{>B{ogTVUIc7*@Et{3zt3rTmHiu37Be`-0-Q)=eaDboAJtaFne3q_J*A&1P094@DzgE&s5y$mRSRP~{aV=9u_ zW2W<|&+Jr6vOFjC_rD0}oD++oe)@whR#g`&fd`Z~W3gCx!RqiRZ3$2=D!D%{&W|X8 zEeEn;ost{6f;7=nUhEpqaibVWno3_M@8ncdFep}i+@I{~WZrub(eOylEz(h$ruSt+ z<(pRNT3Xeflei0+_K`_ps#4_pe#+oL(t1pjLSJ;e+Z!hwo-rDBLXB^ zu#Ps~zCweBDvS@enzIlBRi1f?k@B`6Kk}gpk{Hh2-y2FNB&+N(KK;wix=Z;Y^!%?9 z{T_JN&bgk>hG2%yqg0;y8SKq=~mrN73q zSe1Y&p{X=(lfC$Hcjn&)c5sZMjnY;r+P8^58*-(V)oD?m$YHnbD)xULN`2UU#`+MW z`oX^oQt};3>gX#5$(&FAKEe^B)(y3$Nfgbo1U5@4T5PJadly_>)OrW?igOq+QstML zyoOCcrln2uknr2PUNX3*?r(^Rc|aIfsWqy^eiLYjz2&I}&=rRDdA)g;!MnVWjmGs{ z*NRO(lqK^cyi{6G2Y)HP1VdNj+J6rtYdmKD z2+vwrd^h;~@-;ug5=&ixseGeIE#oz}MxO)Q6!ZjNNjbjU+k zU8J)Dmi3!j(E#?DXW;+%ai&_ggnly9IFr4%t2wTm#1@F>`0Hzd!@!NuyQw1GjjUWw zu@<_Dq|pwij*tvFm}w?1@>x{+tta?Jq-kd5?a=QGCE&tJ(eZ|(Y7AI4i~)x>f*#xq z#m&bFb4@SjzELmTP*3M|>#fRlmCE$ve)3*MP+L3l(+T6SnhYl)przWE1|g3(g)V+b{l+E%{|-gjsMfyte)Jkw`$WS^POAQ@KS zZG_&@2Z=~agZwF!W!Cx)-tTrgeM2LHFPFQcl&S?Gj>SrBp*X~1a+3Yf{o@Yr5h^3Q zLKF5g+KM?0ID_TusL}l!61cu?0cUGBR{*d&4|d|oJ^Sl1W0>`5T`$Jv!rWd0`f+LrX#s|+Wo&VCO z_|68khYs?{;RbiiHoB5{tYGr`INET?i)RV9$}FFkd`@k=l=ybu^v%`Ra}J(a#fSfUarK!ZP%nP*xnGKt@ECc z2?y+?Ul&5y9HG&CR3Exi9VaV0fP`wv-p+QLiQ#=2aO}fHA$v9eNf?KL8frbK45kom znHi;=UpnIVI|DS@V}>8r4TSGo_%Ni)TZu1k{Ux;1yszJ6iJr9rh%=#OS}#$!NBqqB z`y@7!boXUS+Ee~MOEsos7`bD-&)RX059Cl!J;nYsp~)VV%sxXs9g*d8y%1CZ?}t>n zVD_LwzNb#98W2p*?~2usm$(fpMEQ>p#X2v)5QUthxX-wr6KL+at(RLrX_=ck{z3b>5I;fEx`I3u5JN>@OMQ&XMCK>HfyU;srnS4S*?1QEZ6BDy*%_c zzOiqoLoOl$kGC620%F82bi^)niRDCtOhgEtcinjAYwBh1UbCuWt>v|O8Pr~RyQ|MG z5RS2oWIGX2$peJBut5{K=9!PVSk=~aB+49!rUfk*J53|@IUN$gXF!XMQ*eZC&x*6C z81YlboxGQdkRd;kC?}PkA3My)6Rujyiq;>53r!6>BQy>m6Y$TnZmEIm<@V>J_ zhrIWd_GEzcJSK(_Bz*T`dG=RnfRt#vbY$Q8{1 zvb`K6Yf(SIpzd3_zr|XQJO-=%1}km;D+>^~h`OoM1(=uW2E3vU{FbFMDJRC!0T6gRw@I=2`U{qVEWDdf3_(Rc_xi2yz)!1@^|LVWEWunTB*qywrps1I?enDx9& zJhBH5vu>NeAI7O-ko^aosJ6(jqSE6;v@_av{BX|V>{%9xHrj`R!)qYi#WYs+r|Q^m z!(Rcx34tem=%rxE=2#MG=A@*cfT@c$iohrPcY}lDX|>_anVLzy4A7125SdskqY492 zw&tznn0rEUw4zF|Gr;>aOkM=+3R)boUDJvPfl=aF=(2wr>|Bw>E}WxRgse!cQ{-ZA zb}91$U=Qf34v#o_E%-VGu{dzhFQ={W34fP?*g1s=7Iq7wsl>KNEQs_Yoqkgd-PFCd zA^v1GFvE06(eCB?9rPn?eH94B|GaOnurV4C%YOVlzD#dcE%e%~jQQ~}kdghmf};>) zAPRS=`-*8^TyA{-HNDPOiDm!s+R&VkpLVr9A>n3I^3dZ#DjPUNd;0L#mXMs-n`;1C zr|Vw<(jf(>Ns<$s13rMbK8{T2VLeRab;hr z_L(W*p8z&Fy%+za2SBxJKln+6`wM_r>2P0By$6g$_vokit;lAYOD2F(<@Z?l!a~k< z2g9u0b-3{fk!v3s#*$$!smymPq8oU%RwynGc)B;qO&Mid05AhplPKhrq%2}J&<`Bj zblZuCc(QNSe*>gMwo|;^C5VQ5)cj$;b&GC&*)60x+lhrLV70+1XZoUpUzf0G$xx%? zF$VCs?iOXX2&k*!-gT7!-37SXFAd8ZLjD#eNKN-~c8Um!CvahY27fp-O8o4b9noxt72@@xy$jK!*%A6OxI`p zNKXp_|4z=Ta$f}|rhd$?BGbNT8UGaSA%f2`M3KMyA-^@JuZa{_ezr#Yr&eV%MpxfC z>y}Abr{2j$Iy>#gKV3?t`GKkCs0>f?^Xmx4Q{s^f7TaIL7};jxn;o?zDT4ZL@tMe2 zUo1sz5;ZgUz2X?$V(z?$!y|VOZ%}yL72?D*3RcCgB?XlhZ&Y#09U7eEz35>@>q!F_V*w0Ujz_gERd zpgAJ{Fq?IX)9)b7NAC6pvtJ3x4RS6O97Ro;dnyfIbjQI$`TkqjVx?BD=WLakwIDf=HZwQA0VY{+`nLNU?nF> z3&Cwl9*K6x2_1tgN4bT|a`i7%et&mU6Iivq&Ed4$CvWurYRfePP%*E%z&tk0g_ddo zxHQ7$h>P$-eh-a|NdeQa)_ZxfOtC0ku z)SK1e&Jo*7Wo`OzriZwaz%G^s-mn!E0CGBSrwXCD}du&vnc= z5|D2;2Z@%I;dl%rx2rNFxx=|wNU1Y3N~ zBv8Si6G9Mtj-lswyD3@iVyeA@a9INBMb?*8Q38G)hK%yWXe`L9Vh)bW#CM5YbyW`q z$Jpfrc()~(!LHGwA=$^22Agpy%RO^!36LlFTyzn?C`lUu(?s5hQvzTx5|fav zTPLZ$`i*%})wv{aqXm6JA#FD0)-^QXnGcnQR zlEmbxnU<=ZXuwU0G8*6Ti|M5AOwKu%a|yJ9sGgLA*<0L#X(dNGXhpSvF${%!5572s z5=_wJ6tGQlQj9O`b^tt{vf!`cfR`#i7036`hE-0OfV}PlI@ul-JYnd;SQcKHz{-FP z{95pgDt8}Sk!a@;Mb%%LlNUiT5*MR4I~_z~BPf?%mKP#>aL_exq_qD6W{DtGxu=Xa z=1YBp`BHB&^-m0%FMNH1x#XhqNj%sW81^Lr+ruf#VuxK19xNe8=CBRWF?I5#&+0KU zMC2dY8ntZJHxs2#OD8uSTkUn5vmZzn>e;|)95?HVr#r`P3;Am%$6bi_17|&05IwMe zBVV2XzNiImoeKD7xJg~x;9_U5Bep4C2gx%pf&QIc2}Wrr9M5S4j{v-T-~f2dnr5jV z=6EcA-0}HYoLEGFw{qi|fhn+KRqxLoFqp&p{aamUZ=FbT3)O4o3gq81cmYT*BTZ3G z36stGbFV>Uf-~?j#Txs#J;eOL_O$a5OO|ep5fAUdAFj}|#C`B|+Ecx6%>nx=x{LRZ zL}<4w~Kko+yOdWUi zqXdm<(93cQan}|*zZicEA&QnUkTq19i1NefK3`;dQe~#-1F9trhj=|Se90@e*=GNZ;8O%Kp4&&?P60(ry>oF^&_QTN4vpeqoOhX(R|y)N>)W}!Ox?nw8(C%JQO)wbf# z6P$M+iuRej*@%DpN9uW+sG{9*vRIN?aHFLDw zhGd;|!F_7cGWv~H=38^dsq^G=VpB6!Z`nLc+DItO|A1(y_sPz7u@g%@j;@D4F4R@} z>L|r@O(P(FoGcp)P1{KVpx(B!@CGLud@oq1&Fk1U9zkwjGGsG(gZ4WM-3UMA(pf8Q zbCL~IkvLc+mn5K?(if!QImqtoq{a_t{m>sEF0O& zkwiM}b&aZOKRD66Wcc&+Kr_%9Ms1KGNDtYM@4j(x_0`)QM~pVIDl{d7YXyskgQEx2 z*@{HMPyLXjz__y6AaQWDJU!y}1QX5upBf4SjF&Iw-L!MCFil@}lscSu3;L^}p3Nx* z65lvzJ^bch#gKtQRocq)(5FPU>}j7K?_1h+<$b8L(TMiDuub;6(n-E*Eb)l7vHFL}j8R=Kax+@iK<(JX>B+V2j5k_pBgE8zvG zM~1lUtny1$uQndbFS?7%GY{>-L2HcXeMDe{yX8gRhWqAry^$_at_V@R`x9Och;n;~Sbs%U?4!Nn+S^Z1_%la&o>zMTy(@ zoEr++>Q%>ORLxlNXx2%4yrXmeStVdgXJ=MRwJ{^7()%)gnXul*gzxo3P!_S|Ff4?} zE#6-XU!KzK&&7&{rTVe2vPlF^H&oSJ0w1Iyk2LKVKp2nkg7&VDTUUFa=+I&335WkI zr%2aD#BCoHQUzbpsOUas8Oi_FJYZ1%Q1Ch+4t9YVg>-PsshsO$N*-n;K>JbLhoaIa zAIzZan7e6?|M>>WpxdIGy^4}rd3IJ6r{3zy>cVYbjb7Zf(Dj9JlW31dR21De+urPJ*`7IPW>$Ku0b~25t_H{-Y5Mlo3 z9{?KwLp)@SrV;;8x(%EdyendQ<5ke&w$EV9N!M8hxbE^ua0d}Em{-kE9O50-Kke9k z^GDzA;K)nJdznYS`ej6n;3Ktt>zn&)VEuP5u`Q6#5WOoWPx zDuq;?siu|t`0ZW>*VwEF!Lv74aTg~6w04c6&6%OzGYupSIw_kKbIt#e8vgUiK*9Gi z(RuI}qa%v;k4NB~_84~#CFglgJ2x98&$*MhQ&v8c49)rui7+&5pC~Kuo z636}$K)QYKDiezpRg(RB%RO5RbU6!993>HixW(&$U*E#>pz=RVssH?5Ntm)*c3)!h zX#$ATtoj0>-ZhOyN(;>rJ+bIc5%@DN1ywQ*dGnO_)KDuxO+sN7HeHWZz88U|!nO|D z(N2B#1xQh5D!4vU7_{LGOpI@j(iiul-4h}VZs(u}Uw;~)W4L@_18`QE zI``trLLAz;5R*qjZlP|+MUSYIVd4{Dnc@R0>Ia~&MXNW97mG;1hm76JidB=J*8V>w zK|!6Mw7I3SPx;hMHLd%|`eBriut%M!Um|bsU5PB+dn9LO05iWMJchXar zar*K#&mjZno*UsV4yah#@XC=X&>ix?$^{`PHiN+@H4{OxO_)WwLCvp8Nsc>Rgkc7Z z+mrcWw#YYd=<=sNUH$JaU=!kY%o4bAuIW!K0$kLob0CH@1pfv~v;itDg|gY}*o1#Q zGi(A!@2EdVwt=LxOjbj!=QD?G;L&lw^Kff^1&!+%7|~>|LAyrU=L!RglHCjBfHrK_sf#51aj1d|2DYz0 z5RoOG=9)aDZTt_I`=4W&^);B`Rj#av8jLZmBLKtph35x*otYCoGxM&u^ABxhJEp58X)N?mIrpw|>8*Zxm@SYLx_6Gt@7 zfP#y)d}VpQ?AbjweUV_!G?O$7zW~r)o}JA7c$c%xAJnuAGja>OT?KsJv} zk0FYuQ4?bw+!9-QfJyZ&ee3f2zurLb4ahQUOUQ5IYYK!?$_Bb}*|h)VY(o`4->qUw zkH@o$8`#e4uwt~t;lrC~RYL>4s!Bm5${PjRu3R`(bju9pUq1O{rCS=USCwp_#zBeW z`M{!Dzv*ot_^5KC{2SoBs&gF??S&hhkzm4x;rUU?#1pp3d=z)8fjgF~p+?g12px6i#Nss=(CJlI_9jI^N1$P~>Tgg` z(cXqD!Cd0syM?`S0h>C{BY2Ae)0kV~XE7e1R7%bxA22F9ut%KMxqVln3uWhVE*+uKa!vrQ*ZB_YMrR zqsL&AI*rL5HaMgMMynG6r*G&2d_Z8f%{f3>R=0glB7ZQ+ZkTuh)F%i!l5pbZh%UVV zpf~W!M9!6XKKpZo;|)Stan?jPyvFxpgD7=AvHYNHdn6$mbw{b zk%XPM^D!W;{_h`^A~?rm7VG23E~^K51q~dW+c-oiskyWgp}gSW1#TJhN0NV1O^4-> zy>2;v?D3f9UX}(y8B}SH7r}GX!#DQEu}qG24%JgX^M>n22Al0>QeXpyoTB@m#Pqfk zirnRd86g3Btnyjs%wb?X7p2;Jm6h?zA!ya9;qze=YXO794zv)sEbD-vf%YAG;KtVI zDVrt5YKP7i9kncDmhx@DlQjV)A3oC(KY#4^=r4#8gfY*HGqCwHeqx}C^rSXX=J14Fe-5&YQ)k$g0p{f6#O0z$U0vk_iDx!x&a~8GMZB}QO*?saI;H; zvtPE0ee%`)G-JoD`|-id=XtxC<;2A+{hyXT-q?QY#%|TqZ4dCLKm0Gt;p&agBMDeI z(2Z_&HYa~@>2x^fE9P$ooxz5?eQOx*=!!?5W1Q^$;4*QV4rXw&H$zk=QBPc6i2|Bl zT+W|Zyqg~7%R}j!LOz{V@YWB{0LjsIp|yo_>jhaD!eQ5dxCg&t3wmJDThgj#L9XTK zq6w_@3&IjMB3%)$t8(+gtjWC)TESQSy%h3!=cXRUTx|Xj%ViZ&rV*D;{?8xBHhQ<~?@L|x)ebTl)V+F+ z`RHT+N^h76x8Kb*=$eIt_ZIJ#g#-p^Jw*H-`Mt83po3|N^4W<^!;4gy5u&6`!rDo4 zU23X$kD&@^}?eVI22B6cN_cr%t2mzVUd{=o2Cw>@HFCq4lM{qj5nq<7rUWWXy zl3M$jah11y*GFL|(v5stI23hC(ity;UAb1>^Zh|DT&&REdp0!0$P?hlAHJ=jrm56Ff~H|{YIm)I=Mv=@P{QDSysqTk%d->93A0j z2Z{;eBn&D` zn^KNgaH?cXb|n!CKAWPu7VaswL2F>Bi(7!_+DlOS|Go0SbPNxJ^AEbeDBR%~e)0fE zsDLFjz=_uq)7v-1--{W_Een+sG+hhUY4BL+$wZUI1a65eM@sG@CG@|%+E^aB*bVq= z3sSwWyx8~LJ4PMmo4vx}kFpG#+&^PfuQr|OLPKEdt#seiq?hn(Y!P&>8a8SbEzjw4 zCBh>i40}PtL3tKOV_luYT=XbU%E2nZJVA2Y^Dlo&#L4tP!sZ7Ja?rv6eu5ZZrcW_F z_KWR7?mai2iG1`1GU||iyR#{$Rf?=5I6(}l-HjF-qA8dMirOv@)VrcbaO3SqWK%}E z5;nenMWrC(|J^6ftxU_>`1zs&t0~;?HF+0 zOa;C1L%AI>#m*#VM`;~%0FN;SDu_LBa)g(VI-g*Dw4&9cQYRasgX=`sL;G8$lVE)?2kUC8Gw|�MhJgR!;P}@+K`vjS2&Cb13D97fx5qaaHb4d#sv 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%0DY&0p8 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 R4gQBn>4J*fOBp@y{{wyg|7`#O literal 83386 zcmZr&Wmr|))2BpIy1N?$q#Hy!6zOh|?vh3kNol1;K)Sn;u7e^6=?4i5ep1sQl!#(bXx4h|bm z;jz?nZ}^?L`{@*#=lcg6`QfB`C}Qr9S-#=_M3EP8NAkxcd~E*%n}GhQI?ktv&u>U? z-q6a%sY;@>%0n{LKc&FM$KC9mc63|LsqhaZH#e(^3yJIwzvpfDgADs@{p1t7WeBE^ zLyDKgl}AvZMy3DzM}}&)cFlIXz33m${`kNKGq{W+yMFyawd#LI-hIU>Nqz75{Y!Zt z=Kncf4o4ooHCO%?;^C_HKgW|GJ(J7|{@7f)di@Vg|E#Y~8;9VleNnSjSU#2VKj^p7 zKw!zPXBo9GDMhgm`DfhkwKAUoR!O=<;}75BHvF?S1JBK0ajU( zXq(j_c91+mh7xso=70HDPY;k+f2DJjAK#IV*Uy{qANFpN1LS!yIF{I*!JJ| zHo?IB96ZhQ24~ga-A7DciD%9mE|E6I29WZ_uMIcQTCe+~v z!6j*belS)I8(%GP+j0p^?E4_NW&B?Y2r~iXX9P-4wcb6Rq>gJ<{!=?r^#Srh9G#*P zzgRb&C22(S2N%VHfaS#&Wk&V?8ulKqKlcwIe7+BipZrn~=P&wo6FpotSx_=^i;b%266>1R&q{T=}jI{jL* zF8&vdVlglV?9qY9?ga3c0zKyWYr7XP@~-_Er*ePq4`7bF2g20tuivSNF#f{Vi2h48 zvw2ZhYwzfpO8};yJ8~OoR{WP(G!T4@U<73+paAk!SUjo%=KV)|#S$dvJ?`E!0Q1*B zW;|v3`?%kISSCm9mk#WJh!LQV=w`oa`(NV~vdvLfCje7nqXrw#G-ogJ$Lx2Xg7Nx4 zC}fA@0jE1W5dIMQ5Bu(RrbZKY`W|U310et82G#QRzh-9>4XG+t!K4gOPw`2V>VH#r zH-jHuKhzH)7=O&Kt04U}^>3BS=pNKNd)oXpu?y5OmUKh)#*2IUbrZ~^YJe3<=Hwf?4a z3>DZr#AMT_@qdmTf!SRlRzoji=>Ib8P0Rpin>X)I3eAlcGyX63!^XGvTQyg!Q3J;B zzw{rQ0E%(Ch}B*&=R5E8H&Jnai6J`^5Udd>OBGtmhST5n{})()3uuPhD=sxv1PWQ| z@`V42&kJUlyl%seZsH~FP%JY3yGLP|W@X&qSlo}7JY|aW`mcU;l)yC0?ujnUZd@?N zwJQC43v(f`gSBivoCfSI`x?b!=-)fcHisQ7?(`$pyXWhutMmURVV@FU-~!^i$h*g0 z^l_(&f9_$-12*16ym-eJ#+>YV6pO&$dUYq@={SG@2Nd44zcj0kKF;AE8>NtK4dcJH z|GZEAFT&Ju`Yr!p^Hvlv+yfeH;q`0QY``ow0}K7O0v$Vm?)ZB~SYH1oJ421y@3(jW z8zckB&+7{opA*YpC%a=7r@#6iH6En~1YoTWvimK&%>kst`G4M9!5j;F^6dM+ckQl; zFa`O&nqd+^pW#WuP{2QyCqs(5{P*YCb1?om+Eg$79s!U(%o$vg^=m${_rQ3u^Kp=$ z+TWYhY3(IQ^ag7dNS4{KwvGQT{`ycb|^n^!o!OJcn5}`Bk3(+TA@l zY6vr`I}L1j4i;PUhrjv%m)-Ek>7S<$2Gj|`SO42^-G7z`R&$V}*55LP84pt`?|H}n zuCK6Yh;Uv%4~WOeDN7#8^j`w#$0$%%#fJF-^|vO|&HQWMe=8m={>f0u7BP~zcf5C2 zxGwgGQva=-v)G%7ZW@vh{2iaK|KjhjADfLxAKH)b$I>?9{r=IoKR$G44(7)j6RDZ> zsr=*VKZbKIN>UqVteFJb^8XCS9X}v2=`Owd_lf+?DR)j_Ya$_mMt_GKf3m299pH>O zx}@QfGnD)P@g@$bNgQTaZ>)dJd&TYkqx=8x=RP)Yuo0;@7_6R9$NmrIzyXrYjmx{l z?HBn|w|~*#jsuhXJ1o{_-7KUk?SE$dO=2A^p3;9e>=`dPgV#^^U+!&6!Q?JQi#eJMqMy!Mx z<;DdD5?rvuG08MmyuBbjF9i^C^4Mg#JK|v1DNrQfFd-|^b@iPba&T+rMXLXM5d@#V z!p28xCY9%xeJ*~b6!jEM9!CVOcMi^k5a35j^>>vC?+A7x|7(t~Xr# zIER?mO4-2oXI}NBJb3Syv8<=rALa#h>R1;KH#BHXI~zTxNPQx_il)vHa0B1 zCNn$eA&R~FoeyO5A^FzkKLg*{qepU!U*)KxfjKTKuc0%23QQUJHz&I@0`uN0(cYK4 z_2yHSDbXijeXh)ai=WTPLGegUe8DY^luC;kUh@%dqe4tK3%8enENwINsAEh5VG6pgB?OC6M+0Kv3 z%H_9gy~jVtS1z{8x%dR8ZE~w#ULEue@!SHEd$@sgIDA3-&~h+Q@b>CRNqU&AyoD#= zw0Yr`e{osUi=UeoJ~A9^1vhHuh_@QdS1d`=f1%!h1Zg|# zddHgE_jvQrKxDrIQRd@N(FRw`@yMV(9NaG~U|$+_<0&LI@XDOMY4c-G#*Ushp zQ@Nhj(|NM2+pCRG*$lQTcCt~lJAxiiJJ0)U^blwpJWYHnN9kjc?g7^ARPm1$gEBkr zWg0i-c+cx{*3Y_D-dt?!bD%y{6I=?bnm+@<4ri4QutJh0z$Z7Qpss$e@f|pkoeCLw zaqq9PL?aH>5Rvw0pQxNW;28#%3V?lmd=m(rvR=^Ug6+aa0>)IT8G9jAcYOq-#nV|g zwZ?W(0JOStgntG<$AIUPLIPvbb$kydmAEKa*E(YvL9emfEs{#m*`zSxmz&8@2?{F1 zLdwMC|IzV+E;*qQr zgHDmTYR)&ZB++Sig7?A`^I{#GsZkEF7?f(oW$FO+ndvalk&jUmgW)Fv1Ttwqpdgyi0(}I zVGfwAqUyyAUc>29f%)*rsenGE&tW48(aW2>N$c;nwt-%b8xl_KyrHskr7h>{X+3-y z>PCj+*;R^B-5wdQuj6DML;yqPUwzc4SEmHWetW3$5>-SX*y zyMQ~J5@r9Q@PbBRRsc8#JpS}{!jncC3WKGch;RHVo016phdAolLBh$NF55Bffa(<` zR`t_HA_<(T0X~M?Ww~4M`gnYWH|ty(d!4I!r|Mb3%+&zd&xZ&}+V^{~WY4=sHlvM*`+R0wBVWHWSeNlvSbtIsxt*OjureSe06swMu{Uql6`fN8T z;~W;yNoQ-HrvYlogwwE*Q?R^+4By&#xQ}<6k-WXY)xw`^q;#2P_oXd)tG;GIXe0^t zx4n^n$F49y=`!O8JcB2EjEB3j&M*{mJSuXl`JjR_nwXnbCrG*SN$yQ$tba*&;gp=< z=^>x9iRta2b{p=|Ft1uTRE!H28spk<1j8dDO=TcRah&D3UDJdIplUCo#{#6+!7@*XRM6*K3_8p1C&0zN#1=Jq>X@C;=ZZg>`7P9nNfmS}Dy$8OfsoB>6p6aDFh)nk%0 zjtM8*+bF!WlA7o3dDkkckhqa%NSg@%tn(K$slel}atmG~(frfQFKVZw{6!!wZZ3AG zT{nQc)m^{69#9K-#zPGHoXB=(289_U8%%WR8#X^$q~IF*);)bZU0@J+eL~19?a@%5 z<-1kb6Z%H_+c1G$X{{D^j52rO99O_W@k)B2GgX(2~Uqb<43C|7Zo{T^VpTyTnB9rR~Z4zglG@?Mise}BYomY1Z(O0v+1SS_!Z z$zYX2gaiL3P1MU6?9B zQ=;I*`%fTCUA2DGsn`=>HoMW?DUT5_^qlbY#oDY;ljUE=QxkQ0{bVlanU)T!txZo) zuD~7!M?>&-@O?_1S%DEMWxKt+`39r1yVRtKCs?nPf2C1}VKrXO{A5BKs|y5kYt%1A ztPIVRr7t$3F2C9_`#Nz_nf88D2MxHoU0-Uk<#KuF0pD!g5?{N6e}n}U)dK%@ntvu*fq zrX--)w;p_`9OqAa!d_+ic;S_BA<;?Tl-_PT=bFQWKB24LHW2O!x9nV=LL^o!mB}1^ zA0du71zyhZE`MqGH{8ayhZRReNaz}>eY(xt0on&;!4%nITKb_-H zXUA=}aj-x-DH`U@)=Kw`$x-L)zp3!?%LEPV+N z-=IaOWuv~wm?NW)YgPHdj}VVjl+DsxAbQoIevS~=%7+v8qeVUAm>`!DEC&qJff&&c zt3-x{9x^F9L*WN@fDO;XQ>4HZ?#b5Web+oK-XXXxVI5nXfxZr9>#Y-WE*% zc3c&fBE(CIVPkKre74%9dp@k1WntgG{=qIJt!#{P1MkP$kHsR+zSq`y#KtZ^&4R@4 z>w*~)=+aS+xOYkI)^`j?|KBgb79 zd;$+GxlcoqR`WD71{CkyjVGgIr#Fx$Co69u+39}wxg8$0)V-{cQqaxlLulKro9X@h zG*^0RvJ7Up8FF6@wH!$UAt%X8vU3mke)j+RZQ7$qqLk2k{!&Va|xhq zls{2U``(n`t618@AFVk_Mo5P>&HI|2-zMKnWpVw<`m4b$4bAoBQOoh{cqLMzS~AB5 znuh#H3SNe{M<|Qz>PDY2NAH zgKknfalUsVvz_N9!&d??kFo|dA_I_ykbpP7LX&3k#9NPNFNHd#leeZ?Rl#ZqZi+#) z{l_ooYCoM0+y?Nvs(~1Q)Dm>Pb2QqF1J4~-A_qhtIw2M+9)1P_m==vTAKKjkkBd^4 zZZ@XeOv|_fWGS|((6F92nwzl9JK_tzNUt#ccv0Q2n0-1lXe04VkC6Xu7uX>5;{lLB zaJg|RJz67=VB^@xPc<9ljayVhY2W-9`F0=lOyQw*F!>{!u~`FJSddMP`W-QNM}`7c z-ieV&&m5~AUY_UAsuFryOYc_%pYJU{!@fSmUacH)&m4zH&8LsTt9!9CR0axVNY$s{2hc~T{s%tx+=7&^05NOI)061v?`+YfsTaFrO zU_kHKklV(Gjzxe-o-Zlo(cw-a5)UM9O1y9K-uG>2BlZE_S)@C*`l7$1%;g|;r8kkU*J5hLoZcyd{Nk z*FZ*2XCare_>DW+Ge^MHrk}DDlUGIO!;8VH+BEr~G3Mj&dFfTvzBVxDO^BPw=5i_6>e)|p#_ zJ&bvOV*z_j+tRa*@Jy$khJdiD585erGtuO89Jfu`#hiHRP8A~ z(efg7Qt2vxG$(2exdWu-B|5*R>*X$nikh;L%3ji(JBX%epYl?lH8ZlRB9eQ<;dnWc z3;AAf$#{MQZHe}^ZDI6m7SdL95ajR;4xL%IJ>kNwZ*$6y8t$e&LWch}fRJ9|Z7xlM z*!M~=5x&3R_2MgMpEvu;;J#9I4xMo#D)zC=@ZImc9|^}PQXI7tP8Hzo90B2`z?{IxkqrUwVPDdjpX*lFIV7J`M^i0EdU{>ObiBy?O;8|O+nlE z-K#lw>+u3LEG^H=4{T~;C(p?}zCSfpWOi8(drA42NBM~JYTNJpkfsI9rZ1U+sU#ZP6e15QVQNB5JSwat>nlqr$Z3@KJ)%YR;YS zNW-=%Lc!k{36)!E@nuJy!qwBW{#i%=SfAA@wc-))D@)Cyqcps+wK|Ho3Xl z!wsg20*V@rmj*j3c=a6!=?hrV+`lBLkHf;mdRov*C${_kW7S-cF3Tm6itQb#02 zp;6r4jW4(L7tqY3rtCk;6va|Wv=P%E1L&EW!>Qc|n!eiJC=!jb9zW|Dhx%wB1nCPy z#T#t%y*L6OPLVL#y~d498k+nTstLD-%!{dni*M5hfdvl-A{m1-l}&Pd=(Nbc2_r0X zVLl=Pz%X2;pCzvd^*(oJRg+&|Oty1^X%RIJ(qpWDMShQhS?lywqgXe3KmazlJU~Y- z7syJ}>?+_Sx>+6u75BgRES#&ZN~+_kK?P)>oGR)l<<^hsR_HtZ>Dj*1~bU!dy zs^Ws&2Qg~7HcA1IVk-|dv;} z7zm@6bpKDNmfwrHK@Uw6$VPNq$5lL_RU2LP-j$c$$c=)YdQJp5#wL#xMP zEL+M2NKRh;q+SD?h#9v@!8sm$QWai&&r*KBxZQdzHsCn->?rG&eBwAM<9jJ(;1vGY z%r09TCR6Yf-B^1kbL~GO;1N~&^V3kD$b8kBOo|e7?LD&gU z2EeaBmbhBNvWy#{nDs&O%9QHz`EFWy*m4N~AXLjkBkD98ubU_gM@5f@<5+IO@KjO8 z_0c$ZbT(qz0i+wbSOR(Wis0Y?pD1$)EYj4@+e}#o2wwX==HvLMTJn?+kdO5p8`p+a zN6hCE;bemJ^-W(9uzy4op-F9nPTMgghJ`4nMid%q;&v_7E9tDwnSsNA5&_q6Q3pc{ z>+D#xA4+tn!j59Vch~|I*;n=u9snBLV_T3xSn@4EVnWCjPQlk_w{|kwFjKQ^ z>95Lsf`@`HXy$s6?k_BKHT7*k6| z>HE4{o(Di;9mstSpD)Qg;Apb>Vp3!JN;`I&HDG&7&uMtJmE3(y$}~_@l*40+l;*5Z^O|qNc?j%}FfD*f0+|TLdNe5Rq zMD5ytr*50`shCBp4r_`!R&(Ih3KcIg@s4kVPfn!`F?PUF+Cr2RCh06m(%(svPI5!~ z_G@CfP{+N!I^9OmjS>+nmdY6*EDEiSSsWy2ag7ilW;!-<8{zBmPa0$Mj6dl!X?UR| zLZPXA^2B!0*St3h72E{ik|HPs$a6fSBKgks*3tac$oJTSjY7EkwmQ)i1mi5+Bax*- z1rTp=XLOm=ot=6`%-8+R#LBV3v$YH~v(He_*-qXdzxn{FxI*itu~J!Nk)h^OrFq0d zi;bNj<9x)vZ%B)BQJQ))!i~Tw^J?MUm2iMkuSgkFLCO5063OsJwINPBfR_T_8xNgH1q?B=i6P-?591fZ!^uO%U`v@nYD` z6mYPXb?B2H!x{h|J>*ucRebNpY++=5rKPB1U!N&kpPys8(A5(AhQ;!@+Dw&YMVy(R zA1G)o=Pe!`y+1-|S`0y#&cw``0SZXZtiBQpyW2e4l^fq)_k0{`6Gsfxig5eIcGWs! zoq~gL$jYZhpmP?ICDqbd4I5=MN+oBWGmiSRk5YisV{-lO=cLTM$v}35mhNnv(Y)&r zhbi`u-rl_@bOxB-6hOHQaG#%v5L*3CA0QfC(}dxHF-3J-QLB+Z#AqhdYq^8?5iLPt zTAU#?+Rh*ugxtZC-0%tuds> z@*7CLQm0mD;&pf*o*NBmbcF0)?)s@<=f62j8$-^cFr9OHkKW)J<%SaO%5!!@G9&-E zk9CMz>WBNDs>m*W*b`}i&f1F+&8#<5IHDTN&?nKPnk82k+7y#cll3a{bw($ztl{dt z5zc{JlnltmuqF%6R-~5Gli!Mx;yX?_A;lJzi8m6hG#7Ct`ohlb06PmMu{p|_wxNe+ zW#&pP0C>E9Na0|c_AIn3bWNYiu2v7l?ik~{mvmbkHSgtO0i~t>1eVe)JBube8IeET zb3db>Y33K;RG}Ugt3=dk+LFtwicgPobQY%;r$&D~?l18EO0{cg`yP%YXD!!<9<>H5 zm~!C-1R0^2bAk;zTVZT}kkjUJbfVpz0=+dWIp~}Sef3KHX4lET*v6|z)A#3?8So>J z?Sp#6ybV*U0ft^FyD@81q9BV@yUM4^S#0wK1aZ;?Axd*VGuo!6vTkkRs# zuJS~E9YaF)6i#sc1DevY&_=pBU(LwjUZWI_WCtZs=u;pr!0fWm!*&k2&@^r+)K-*5 zV6jA`F=}0ZyM1_gFoP42`#@^uo5yj4rGXAsPEu7TA4+E;QJBLZ_sN{!id~^nN0P=D zCryfLueOC!>&Ok<-~}H+$EpFw;M|2WaiId%R9%7O8hZoLEdR{J+`Bqq&U@~HhlLj- z37?;(S8du2xdr4#^P|y-U+9qzOWbw3$v*PQru#3LH@z8uGNYVjgmZ)yrQ`oz4`U`f zu;uvsT;;<45)gLD5shpB1!6pd8qrx>$JQ$w6%`zdeI_F%<=pE>g|M>9O00yq_|bb% zVv6zgybqKeNbB|<2YI|=@KD_w2%7dmjz^vaW2&;ymg3p#I-o$1tCoj!r??td;~##u zN?PjWj0z_h6v}ui>W696^J?A?(%RFSc&`F?Ol;_6$RrC605Sp+lfDLoG~05i3IF_r zTdXj(H8pyYk!`9TI3{)fUa<5vlofd#pB{N+*$x#Gd7Z~q=|$fbND*u_3G!^Fgb$&Y zs=+lQTjPn|Gf#wywf~yC~e8|V1_}v zn4K7xPB-e5!5qs&Z<@_ml9$X>-n{$tu1*G{6O)Wj#KZIb86GO-vsk?9kTC0h6E7em zCe4@M`!V2FTm$Xxda7G(f%CzRCudL4c2nS6glm(Dg6Eber#sqQN<&Db-LI0d*5A>O z%_AXmRhh60SvWtwm8J7NwSx@Rs$BBg=4pSayz!^)P7){?J#)Gh#jHQgvGnV4Bs-48 z;<&N$mTZS!Z1=p11CMu%qozHw5nKnz;&f|6V=uU35IWjuNUV6D!2~*Q}*R#*wihJm@9Zgy**wAo39tR;SB}Rq||@B z4YM-%9&OBAg_6=`5EY1$loTH`rijhV|KapE7Vy1nq4|@Ut19;KT80S?6l0%kMQF2r zvVkj1Hu=SZ@!sn6QSG-ebOxk`_=tS~xhN zZA^i07v{V~19bv|B!;gH_j0|x6%nMl=+I^FEhWK~aH>W_dRk!>6&ksFG!#T2Ob-@t z$w~oN<~yDW2_QG??3WpMjb|AmuKsXwdA8{DiqMJ|*G-0*6cxD_ha$X#-@0uv!+IN5 z3w^_y$mCJ1SAtt{z;?JO9DaE`WpPTLCBo|KnraY z?8D;y{%dj-v(ILcoQ}2ttaPFPSQKph#$>#7-Bye)%t3q5-U((r=6X6)=Ik>Oq`*)m zE%Q(lEn!4CEki`pP+KtFiAa?G;xtLFs%;cn=Ae5E=6$I7qe)A1b<*nY92*aVeiWeaK23o$ES^xT zbL)~YZF`2Y87iDSN+VzWvY4q?UsQyx-umlaGo)-Vs!OT25#Mt{wcYfx;?S?SOvZ)U zI<91WT9b;+gXO}$m=2>?yj{uT)sP_LJEI;@s(LD&>Y3I?Gvz&MCH`1sgY=n({n6D{ znfJ>_heATCQX5TZvYo@J8tL9oMATdiH&`ozRDp~pHpQ5G--ol!S7W_Oq=Z%5LmG$pE8vP1J!I`ZE_=GFHb z$^_r{udkuUjW5Qn$H?6#zrBW*Hs9aywcf1u+|`yN+j_cK18oLtZ07~dYe<|6H$sSv zedsd%me!D$t|s2tCTxAuE`{_;W3J>Iihtws)N3~uz3xVI`H>?LHRn0ih_WtHGR_74 zQDH3Vye)eW?evlZ8Ox|exzTN_upJ9k#YPXPHs|j<&bp6}n0196Fpw2Ggi1O}Qo14+ zKgy@{J#m__5o<1iH6u?_cT8)ZJjY&e>>eeG?5p|C8Y%ns?H&ka-o6f`VWcH^ZyQ_{^FOIF zWFKLe6h1OZdhXb~TZcY)eyk#LZmoS*gn&niaI+izFnSt~{qnGe**k-H$KbGKB=D(n}`vY1+y@=!OAX0WFKI7R^R4m4M0%g0%@xLUm1~n$Xb*n8lu2X?8 zXlv7%t}_lq9p3AM%qNB-S^hvtpT3j&nL{(y#*7x|{|mj$vXE-DM_qq({Iyw@_>1ys zFw+LJIMeQy-HC3a+OD9Hp$vtCjapVQzd!N_w-<+l%|er(bJ<3TxZPxcM@#9 za!fijq&fHg_~zH#P_~@Mq)sj8R?Z@%;xE0OHL4a6qtZTvb7_~e#<=8DY@yyiq6FGr zZ3Gb5WePGp^}Gpj5;3c~xX;}Cii+C zs)pcVHTgqIu| zbV8m$&9-kn&507|tUx>UfuYB;?BH1$2HWKry;?B=rBf@D-3x?0)bg? zjmqahn}lKKgnAby=SQyv5ADj2WS=TOU#&7pL;$D?qmDNiNa8s!20TX`t;-W6)flNg z-|3$O!6Sxj^P7ISDGRw73>`S^se%S(E0oPJI?z+b4M>&&&O4dW`a_K~@?Pyu9Kw zWl#W^~o!mjV)0g+k*SjFXKev8wn*M zpXM9OyacQ{DfHPGuY6miUMYD0WiuT9RwTCwluH^E%i33zcN+1Sb1T(CPyVS0=S7L`3-oa+KJDab`|>~p z323&Xf3@;tP`~3M2zl*3O@_(niN;lv=X!nv7NPg4tQ0j#B9z~$0_^tH`eZ|IP-E!k zSB;8ZeF3STLw4NLpyn3kfA|B|)ib#i}Q8?j@|S zUZH{NPS(*E!)yApb;|Ad$xxSfK&pHkPpxlQZM#r>t&*}_r>$f9D*OAxRva2bLVM1m z%%6K-g}M^yjcB7Hw-Y5EGvj3%#HxtZ0JY{P`pgVrRQtZp{@l6ZWV^UmKJ1%_mcap* zf3?4s$p9T$WkB?MOW-WH{V=IKQ5d;k8INHLd%>n%iqPw8J(F^5U^_pDW8h0g1NRZcgN|HK_n8;z zCx4>;cqHKjNu%Z=yaoX04vp(q$w(8rXU5>ImijPfmMYIw*Y->Ubra}w@vg|$V6DRU z%df=8dq!4tZ_-u?#Fy-~i}#ofKACngigy%6>)7{=U)i2+)?BQm9UAf$s%<=61bU-G zW&7S_qRaA;*!W1>!L(iZy5o1>#)3z?l3_)Yg$-sST>6A|VC_g7mV%e6ujwZ}N z(a61?RC`oJnO;`PnLM@K8JC|L-Ksi1Gl6G2q6vl$GZe-nd#*FB^Ly94RAK_f#QEmQ z8v-y4-TH_RqQ%Vm%|ai&11=2cBlwu_$^_LK44K7Q9<>2I>eBoND*RLQI$dH3vhHjU)x9vM%F}txy zhcU?`F#XKzc1ncPtUCwKYW!-82X2DFuEqEVa84Bq(~gy^b&tu?LFZ}$UwT&GRE`5B zQaroUXco-%BazHhas%mb3=-T~)bggSqR%Q>xJ=hu-Dl%jH^g3ZK5`g9qpvbU_lNGT zgX3|vaAGyL?I-1J2ZQ?KD_@E7dnQiRBJ3zraY60k9P{r*#k#X6abE8z;%*Ki`5G+f zx`}zAfMUfjY@E02M%PHA@{?B-)rlNe8oJCJg&-|QdWpKsD4*Et!mfZmE57b5yl&kj z)QT|gkai2Vuz{`FZ;}~TF2+fG=^|~Hw$ps`@L{f(2S+V!K%@P#In||3Dq3`xrbx*K ztV?>Ihq@-Rz94bYb)HZWHJxGAZ4Ogl_MtN5u~ZdM&m8*AviGoUw{9r}LDyOirJ6lh5A5wS#7O53H zTMSiF>wY(s?YH!bs270uar0N>O6Ob)er6=B z91!LAh9N6mB--W`Ucs&brqHNUQ7}AzhWiX@59o{T)Vn!|4HSjpVDVQY&#goQEDjiT z+Ap?>d4)$A^bF2ru*9B^x-9}Zcr{92iFX~)lO9+_YS4%!xEQoJUCOab2~>$`dS3!v zx>108O!PguD8L;%iItswhGWhNPigu3A>3uRH^BALPLC^C12kalZzB+~L@St$SPa4+ zP>_aGc;GprAcO27#{lrXm;vycgIJ_0(|KTa6mDI5F4ff z98tW%^2!ZBZ6*A1V?6Vyir=nB*+Rl<^TpQt38Trv=@a`$WU-ImLs1W09E>>Yw)4nc zx^Z%hRg?(YG`OyJBCc()rF@qiHpG~MlTm?Mg(e0m@xc-{sm1zlEMU#A4_3S2OWwxA zl5n<8)kx-hqj}ZDoojwHart_GpZioTW$tzX>y_WDyozm@VY)a#a>Pcoh z1@DtVdS}*rAjwO{nmZD_NYrCdk^IpLRR^0xz+3x^Rfr9nnX$* zvuuQE?b;=+U{Y?Ajv!pMJ(`(fZHSJ0uu>eRJ?BT{FZo#UpZh|+fzCEe z)DWFSM%4&!m)V+z+o?kCi@gDtqg)N8I?u}jwQ>>sDOgXzRytf{qwTP}28LiUU(P7` zI&NYmsSvov*{i<%ZF^lAwyLG}hV(AU6J~}IH@}T4l>?hrplp)j#0g$5E7tLFa8LTC zBWe9E`A3ZON7C-rVuF&oY-XX;WKf{7<5q~<>sSz>U1%ei_@H@4$>(6g%i0hwr}eb?iQB85*??YDr9n0&&^#ldkkh@KyT5LQ{>^GUB>cecMAW?{4|*);hhM`{yK%+trUpc7jn=6g?k))E zAfn1n#nu&>p+`D{;m~O074@sbly;P43`YgzisY)&Q^-O)Mk-*rYR-PXlVH(uS4hCv zY!Suq)_t#|m8@eH;q7+Syth*?&da6y>h!PuG;zy~=&tX=C`guBm$QJPcJD0fI1a;%utR zL{3IMMAP-f1UNrgE8Ch(hw9XuLr={r`~U-xBop6(!`J|hG|jNi^clPXd>{6iLuior z;c0#N;kWHug0UIDb~^!Wlzyl_EP(Ygr>%JGCZ%B6(WkD%LJ{PJI03QLJ5gYuyBi<<;52l7Q?v zBfTtbpUX<`h+vu8gj+|`Lc4lT5m%UcwK$6T63sr)RU$r|KPD(@^Ta$_>&g?gC6PFD zBmgvFnkk(4>B5Ri)&Jrc6=a7d{8k8|&7+ZHHrJZ_9{ke$(U)^kyD+@Xc57|7C}yWQ z^vp23Njp8~8nr+Ug2Ar!>D&@>pfZc{CFkYmM4r)sZ-4)T4I-Mw$o7toH$6mAKV0Sl zDyQyW_U@)+;0KBvm49tl3%ftXBq793NdAb~hPg+dRP?Kn@6;O+3zc_pF?>CUlaX(b z!J!^k-N>CSor(dI8X7Ch$emZCl^R`b3K~r)**jJM9PA;txS1RK08Fe!ox!_!Y+zPc zX-EK~-cF26jvfN;?cuSjAO|8Bv(rojrC_Tz_8VsImr)S9hiX)70&O?FDkBq3@OAIG ztR~)c7HyQ|O>r@+_Lype83&(+f^}=hXI+x*z}#A5*EE8}C<{Qj-^%T)k9x~r*4iYX&>#n-{5rm-T;?-2)T$9SVtrm1qKoO&LXJU z4{{)F{0;qhVARaS@M)a(YoM77*>dHsq%`VkFWSr8wcXQ*|2oV>TEH|hs8mh!U3lnB zYj-LPzCg&k(d;{!IdQ-fFV*&6BB4$Ovj6wJTab&)_JE<$_qqonUb8>qT>6A_UMhdN z#;%*o@<*~zL_6Jkzc^J)75~yTVxy4-(hc+nQ8f5!{k(4ppSc&koGbKXdfn7{RA?g% zoAgc{VmD&)mZwK*t-&bQ$LHRR&nQ1<+FC0LZ_g||KfeYmxmFa z-$K8K+Q4q9OhxEwTAcC8A4_L1CDB_Bem6S!MmD~jvytDEbgB|VMwN-n)h@)rs2Y>X zPvo**`yq39&VOSHa2f6t2*~NcEjNYdWl_G4l2&o&6XgLDR+Y3VNsNIg;99*>dIz3O zhnGK0#^I98-dST0p>0=S43}AswXDR5ytXDao$IJPICpF21i!l!y=P5eH}@ zTQjWD$>K4;yntkK!)Q?ay$FQbJbt}tr#Ll*;NW1k;zoGkSK%xx^sT(iPCu`vrfz|d zDrrgt<4SiO_1<3R#^wj$2E&44K*E$Q?>1Bv!PpUdOzx%aoI0Vg#UcjWZfjugs}CjE zQM%!}&j^y8z-|bFOCykRmVmw%XYYA+^#kG@`y+O2VHp(d*n5q_ax?gEL~&pxWJS3Z z-gc^8UvZ&zfyeNRsde~W4?Dj%)v?g(7K`Db{>ZFMo_@$1>XKPk1XPc&0(8IbZrDDa zTCBJCv+D7Qscz9{y~xHy6TZ$Cb*4J=hI)(piDQqQ5G(*UGFBwIj(xXFiP$d_^ECzW zoI;Br#2gKaA(-Y8@`s&pGdV-s}7Kxh|i* zH*2lA<{bAJzwtIrr}pNGj(c-B=1HbfFrL8GTk=77BiE?w^P?dc8W9&E#mtAH(3LLq zH&;Ir2KPH2KYsS*`fe{_!L5aRn3tO+{B|(5axtxI|EOoEyY!vfl;PyFNx8AV_K#D> zM&ahVDD}AG$>*=bDr*>@I*yo*6e-x3S?g%&Y1x&U6^@=&j!Ora1Sr|gU`T7YIh*>C z8YtRZ=a5Y3~!Q;BGm#o427- z%_!P`7>E9l(}yZK?-CK)#2qQtik_-+ei47s>^l%i(?a*$(?(Y>CrEc-Mm9qai|iKP zS4<{JztJw1r*Ax1p#L*wXi;m3@sAb9J&&lL;f1nM1>Wdjx4^--kSbYw^=F)i*VL|gXz@;W_CYFWK_)?1iHQ64f-OXADHas64m^4Jc9t9|~ zr~kv9b$NP4L*rz3dVlbCGwoO;i!v~m-8)#>%i2etJBW8yjX=ix9on? zw~Xxco^p`n-%0KTPy?@rdkni%G^qvE?+eDSzg?Sr5ie*%)E|eBBX(zuXPigxKVTps zbofC186G6+%BYw`G>s=lBo-x_Va9rlvhu{zzGvnj4|}(|U8+?QwMkX zG#vw~VgbllD}dVklZpgWf&k5Jmh2gSd1EDd04KTxy12uq6Fv@6k8Q#nn_tr)Q`qF* z$I9_x4=i|iMbUxpn^{m(v!beP)Nz+tDCiLcAGDKNXE3#$Z1t>YP*9hbI>(%^)&Y~+Ez&@PI9wIs`(9FN;x3voisAG|i-La%yjf{Q z=z{&-JJNe?#3}Tt?Aa)1z$bbef<_wLu}Rp^l`JHr^H|7hux*B6g3z8*kosnN=BaN$Ohp2~G z2^43HR+$}-k^IEdSf`pz5s>z! zdM)&bWi&B23_qzeE@SX$D?Gkz^F+7Y4|s9^e*909NRj-?)X=48PnY|~74Ln32WgcGVl1w?kvysYOL7vz5`3G-Eb4Wby>fEF^8#l%f=5 zCCi1Ql=40Evu9UTdTZq@nW@DwIpUh{Z8$+LxapDl+y`88V@i8BD$@nFXJS!%<)=3g(f& z!5TFgcq}I@Rbk@2wy8U5ja z97dqLE?<^+%f682F>=^vfqtX{Rt(BU#pLGzONo z+~fAPy0?#a+d&5Tfm1sAgS>WUr#dgJD5J@&6>C21Qvb%#g4%}zb%Tc2pN}kCOJ(x} zm#)=4{XEVOZ)Tc|>j$qMPUZdb=GMToAMv`H zl>G`+ED9FxR&5eXf-&UaBv@Zk<%9@2Z7mj5$sM8;>k<1udG)0238~W9)55&iFiczc zi<}Fax+|~;r;bj0mk?(G^t5t{Ts}gITs^a;Itlib*vyO9i8LFlP;d^;k0&Plf(wNgw}@E9JAI;jh{^(|7nO)H+snZQ9%u+d#GrBO_h6S z=x$>p1?rC9ug_mA7YsJTdD^-vSHlIqE|exfG1nx{(d7O2*&4Cdf9I^7KmpUcIPAE_xB$RsL{ zl+B%Qz8yFZC!cT;qw>NW9dYs=QS!2#R_b6;DBZeh-%-DI>=o)CQ5>>3Px1M7(3^>o z^w1_rqicsAu-#T4;TKKM>vNkn>AaD0Pyb+d)O`5Tx>7EEd>h@%WM}2Fwf5TT;chJf zrX2dkDGmwI#2n^HP8-_c(Y*jIwCbikR<;5v%o@x#YF|v>XKA@gIP8MV?R8>eX>MjZ z(`S3jm9H{7R%2caW6CNDi;T)bOHlQy%QtZ==N|*&DtcaYRry6^mqpH zaqOGbGxb|w=e-}#8K5#?Q znDTI5)B-D_)+u}O+~VrxPc^Jhn=EM`F;vhpY#P2~Kl0D_+9ZURnIzl8vA==~AJ$_H zU3lsQ_e4a9QmDgNXc8g<1V;a;(VN9aIBV2 zc{=2f_F&T4d+8+GTWFPP&5|i^qaJlfjiNR2bi3r_Y9MTd$atveOhZ1TxX)wG(h`e+9=8^@@2O@S*$169aDs};k*sk!7L8HAH^)*fO*K7>=18% zE#G5DFkzVa+z8});@sg}Mht0^`SuDnwKEWoG~a$Anq%U-B-C;NE2N(eB_*=z6icNn zmn=jj#Nj1%7+}JCIE#l?<>K^MY$aAr%9EZ{9$ny`Gtdp*4J(*C?gthv`e>ayO#aa!2iycCpz=g-4foQB@Yj!%og?7w-ytr22!> zLw`yB@Hl0+%kfAkl=Vj04F$pmi>HgY0QQUH<4(Fr+;dd9kAO}C2Ii?#g>y^~QqnYB zFPbYN%0H&F}-KUQ+oxW?cYKkur2Ct|aW$?$9)-*7USoy4gRv)@<`L zxPY^lXw7L^1kG|=*LfHHW>qu!g1Xy!^r8Ommxg?Y zaeXsL$5PuP8zet+*aEL_bvgNOl??F@I3)-y3O|u87dOAwGM=BR+4Xf@$=lc;4;?b@ zMORx)y3A^IDo|o`SheA{(Xm2`Yz;r~12CIAO@3%uLZ{Og8}ClO(_sVgBdX?Wb!PAS zG)+}HY?+R8qNp2c;E-wDdFh}Lpyk(plt^?y*p}wCi>+w&j_!6Y6#vB%q>AS zQ33fhbmKoWm%&VFWZjI()&!Fd`np68@v}IwY?CXhTy(_)U6+4obUvV$AB(8HC-Z1qd$&b1~GO1o?QbKvyNTAFo;@)JVxuoLXY#Kb6T^uYSb~ zm=~B!qrUZa)|tNQjICUb=-NNS0VfKj#7TQ&rt5+c3fsz<{M3YS!+&C_US*m)G+}&N zj>f=$YfbJw?{{}QNu{!4icHkC@RggmHf>l*qYl%agHr|Pmz3W6G?_ppxtE+n(QkBw zKT?Y9K6Xf#a&E04Y}ekw&I!N#*5}TuJ~w?AwdUO%^Be7-E7-IdOXVOQ7?iu7JJgJ= zmCeF1%@t9b9!Rn$Y$#?oX|8KsQ~s3s)n~u$u2>YC-!A36mvD4JKVUSW2Or~JEgn$w;|V~#k(sW+XC6T57QXI=+`&o=QKzXG z0C8M!((n>sj(Z>ZkW1*{}YjwG54PBmwYZ>~TOI`i=<;Jd^ zq9vs7cE0il)i!I9z-%JUx62R~Mu$56?A?Pa4@Kjn_dVFoI%lctzH}54pm37{Ojqtsv6CmmA`<=K@O~C1$w{#(D;rO8i~vwh>Gy( zlL_$Qc2_!t$m9low@7yr{=hjYf{9C|m8nelfY~j|uNXD;7Y)7IVp``t2I=38<#WDn zi)9s=9fVv8pqqDQ;dqOp`ST_E-$`;GdoYSTC7U?4@uY2|rur zp`q#gIx~CSd9s!6`_9~x=_vLiBmWa8E@aOxNJNq{VQ?m%~}rbc?k$;Rlm$8 zOZ&rkZ_^)~ukV+PBW zT0K13rH8kj$N)Z+T>Y{nIvJtqrB6l>?q;qcP9R-X6eM6y8Ua$awI~ z3YUYBbw(+Pzp6x?M+MXD!o_%H3NT9TQuj94D9}t<(Lvy|hn?1$*Vwh(w2LbObE#9? zZKMXc`(gU`7yGO7fOcWl^h3|{t6#cgK8qVYIe}e&o#Rz2;?7}BdJ+Zc9JdgXN`zt7 zcD$pn?s}J|KzRT|OX&8bqM;4^Z{P>SP==e94Z#pb_@s9Df%w_{UfohZeBd<3YfBI< z?bXPLDIuwxiF--64*XG0JdckWO>ss#0Kch-eG~1V_PN@}G&5=VO7!RcsV&L!=5&5N zQHhcv2N=}-7J8?MN#GcHa`=k9{CTVB^-V=h z9c6vq;r*X&r5i)A=*m~5dZo2QxP}TArpbG)e_Hdr)(5{dF*t&hIJdL=uIonlyZu3@ zp~du5g17T>?t+&=B2HEY*(Qj?+wU-@T+}D#{JLNDA1y%9+T7-Sn+XJx zx&r12cH1q?LySYPJh0Nc)0NgBXkW(}=d#V3oCskbVW4HY5Xp50blM@VkH;QRzZ?+1 zwAPyuN1Y*xOv{6&iEizxti$R|CA`Oy84>QkX%2=}?26gMqMxVh*BS3U!D(e0)uaDl z$4ygzw(nPTcyVpqCmff_$ZLb=@(3DXp(`4qX3k^yoUrMZ! z6dWYCNcr+>zAdx*!V=%G7dz?9czV}fAPMv8?YIem}8JDpEO}$8t zD;R6H`fmz4vSJ0Df>#;kQ>bIIq;FsVG*0uqG+6DS4eaR?M)psT z{rl{)86kPnUpI(6)iULS0T-aQ((&-@pQ9a!77DzVeBK}*n;^KQ1gLdQ{>Uq&hN*Sd zI1fIl8Ykk@T18XoJ5Gs<-;pjG;}^&iw-r$IFp5t@lVc%^RY4T7Bqju6Lx!>mp#hDY z4LEmF$yKmsGu2`v1EP>rXxyltes@T)7R*584Tfd*ULN-xxPW2N^AMZ?YkjsQUnWr- zdm3ZkG9LF@HLy=hcvV!+xw+Cy6d~#a@yPH+3MA?%aHU1jnIDSgl-XcnAD7VkMbJOJ zi{>ul!c{ObgS}nZ=3ca8Zq;#pDuEwO7fyMqlj5L#_ZMUo_AK0@XgiM(Bf=XR{IZNm77ZcOaZKR zTQQk0<#)e62eC)e9k;Pzc10(a;U5B|Gt2rhBYXHbsoS4p6DAxPvUp zb|6OZRf})WY@g>$4@B>)!5|Bd!7oh;0>W}sbhCAqC}@#2r5vXivVUxaAXCxfVK zlL5~IDu<~1`d=lxSw_;%qk8V}nHV3f_bk;mq(7n_hkwK~zdcCc{c0C5;<@vKsr`;c zDgmtb)Wv$xP$eB<$N}sUX&K=^g7iSnTrTAtP$eF!Y*9vcid|imR$kn&IP3(dEw(uf zEv9x2ndoT7^)Ai$Xw}uk`-p^~(5B+k{>~tK54*%Az#`LM&GnyNz?JGHh)P$J@e)2p zJVJkgoQM^=*V6-RVCM&(JcCEmi^#5!mb#jnds)WH0880$*Xr~37T}I*efq)lGn7kW z-WR>w<=V?1)I0z;ZojD0Y2{A&wMcDl?LqVJX^Cbo)cC=iLQg25tDUI{PG^o3K|kI- z5qsSC+5vb0f=)MpnXx4{B+#DNZSu|9TMuBT#W~l<0@Ju5-s0k(JKyw3TsoMgSWu`! zrEg13N;VEht6qG-#pX4^9~8@?zZ}l$cI1jxy*<*S1V9)Wf^`RQb2s-{mB|~*2S^X2 zL~m&Q5Eq^*~asCP9@t1HjU61V1TH)8arPRr2a=S^S{Ni$eFYMvSS`d9# zrZ(-c9lSQd#=xC*KYMfoR^6Iwrm|>& zh4H@d(r+P}0y-WvBuPmE;Kcv8rNKoPO zV5wrxO`!iOf+?%@6+%AbGA)f@iAiDC1q_&Vsw*!Q-%Hbehs~SGv7=*13BqWa0-9f2 z7uDXyz~?&bUpLV&F+(FDEi$iwn;;|hlJ@E{T8+q0>(0g+Zq##IN5!^01w?mOk#fgw z{5^zbENvqo<*P>Y3+(ZY<|UOO@4*YWh1ZF=2Pji%Ou?VWM2e=F#)sn|oIj8ZprBR1 zlMQ+-cTcvckH;okR*EOVW#A)lgWSZ!un$^k|Q2 z!*nj{M-(6l{^0RMh@FgsR2u*eVyks4b3T-+Jat&GLFQ}Yxq1P#25;Y^ey^REjVMag zsI34u5x9$z6D|2;+;I+PfHh#Cyxyg*lqrAc^aijE+4sMvO%?N$ zi1MYm=j&f2UqcZ?8!Xpy0C{x&T167XCaf4-2dwJxtbwx-MwGb*yG4o+d*(ht`A9{n z4SOXxmgwR&i@y>?ox;V(Fds#BQz&vH;d0H6%^p6Lol|p_STzoxKgQVeZ4u?L@1>1g ze7^zlHd3No(TrgL1Qt#LH04JMwP^(c30~iRU2SSMP+;0j|C7DidJ54m%+yvDyZo^Z z0;z3x1ZLiwu#20%z567Zd|9#fC>;3q*h2Qv|2_+vc+TB(*;G64! zd~>2t8QP}>7;dg7O9?E}hBAp;&$Cjo&gzpKU*%FZS!*OLG_O@W*P^X-h)a-l(O6sA z7h-B0`cU|mrnB1-Vk}RSWcDW?YRvhpR${^)+*tyiZ$bz&eP%7zf%|0VG|?&9^HzJt zDfD32SEuq1Sjn|(lLI~857hiExyg9)oJCfst6Je{yumltw7VGZx@ucs!#Kb0wE%MvDL zv!3M+@wQvMkB`r-3@&vNonO?%MvQo^@nF9v^3#9h{H0d$l!<2aqsO2W4hIq7jlhE^ zoW~YJE6ZW!w6u47V#f6*<)#2v#_K41#NR6BBV&({P;6`TJ8aieQVhOJnY%K; zr`2cY_8uGoJCcm*1nF z2>BJ>n*QENWOm1N4a;4;Oa;WS`YzpN>R&QF4F=&`up=@^i&XzY!>~@^ON>_Fe$TI( zAjF0+Fvmso1sLIwDT|bgwP5e32>>OZ%=@pBpXQCiIZGD2H>j`nfFedw0Dpg4Zmj z9RZ$7DSj)S9QG=vqqwfKht5X6!?73$M_wwRmB4%xqQ-a9l*tm!6OJsb^p>i_gVc6(#7z4O7b;UHl=C z+16l?PIBw+Dc3cqs72~CyFZi}hXibYWi0$ZUIy43(Y_Nb(h>MfEh2XK`;`P6gZ-Bg zC5;#Lq3LQ8J=27HVMa}D)7JQlkJ^YYJWIuSQS~s5n8{#fy)btrEMb1Ov4^d0KrnHYq~(yewrp=75=& zrYQ6hi~c)=+ouJd58b2zM`Sa8bqWOU^nZ0H9V}kMd>x7MwQlCtl1zQg7 zalquGVBh5FgTUmh&8b=fU#K$QCGX&@U5eqPy+*Le-Nn6wL+n6P7?r&d;N| zga-B7#XZ>+5HBS}%3loiHYWYbbT4Wz%vg*o?f~io07jF)fc1a3xK)S&z7n*nc8NQl)_=i6e@(c5Z}#V z{}H~$te&|-i#XYr|KSB>CdX5I=?1>na0+3v{cZSJ&b&L8rD>hUfcJONVAnXi8x$kke_}iS~C{X*MiH-LAe%>)K?OH=v5F^W9KpuI9MKAN%>pjH1 z$8&nv^NFR1FqBRJAv>?{ejM()-nF)rU8B#%xx>}KohP3h@34Bu;wJb)=K1Seh&e~3 zxERNh9uJW73geyKmF})WDd;`HH{laX4?fC5s4Bysc z+^!2-?&DN(vRb*TN!AjqCL`_KEt(0ky^7HQ{nqDxx*9{NW{2Z{nu(xG5&^aM$S5Nj z$DZCEg7S?jszo#Zp+t@|HP6f}~!2P(da{uI` z$&oXnW1MuB#bH$~Q{CcpZ>1-(t?orVs?Ga{Qq{Of_Ko_jKxYj-H{wcj2-hw7*3>4! zFf2nKJHci+$o6+HpcPYeP&vutQi}>oM^KToFF=6_5K|CcxoN%7ohm z=Bv8_&VG@`kC?&=-|{&-k$&Vvj?Qbkm>p`Q0U1D&`4;MZh!)^u+$->)4!wNrRo>Js z$jzvvU~$rJ?N|qhgf%q2P9{Kr>sSITiSQZ3TwQAhA&pzqSvdYOc2uSzU6f0mNUC$B zTeqt@euQrJj*tUznFV?hjlrE1ez}0&g*$Dt6~L}^Hr^pl0=;xq_SEl5qSb`NFSeWl zd;QPcO)`;8{L;3FoWoW^r9cd?14AtYTpI{<0Zfs9`G9`MWl(=(`?RO}CZ#n#fKj;_?6!q=yLv(u6F{SR$Q~5UX;b=JdN)VYrdG_zSUyRV zLG@X|r{&@tLYnV{f>mWbJ&jY}HFDxiO`wNZs#+9pw9l4iV*)@0&&yrZ#(&X# z^T<1~<#%qb_6jF#3pPTe?t){GbOq7Kvt40!vqPvTNJ~!(K6*xK{Vu9%-34pj7M_(*WFnA& zn3&g)ARI-LD{=|=-1m8fI>T%)i+eb6^zTTaY{vlf9`8U{q~|i-{e-9FY_$*aYmn8D z+83H(`xrH4tLBPC5b8m3`M5FKi(dqSTMz_3WPWD?=xm8?R+1!MRlI>y_%}Vlf1&!| zzy~fUuxdlaox+#Tg=<6z8XhKLPZpC>Y9&jDMA<&&xKTr6LT0g>tm2SNby1uE47U&% z4&)OEbo(=kmzL}@6{G_=FZ4U-p$3)LZ`!kwh*y5EJ|A6vLAjh>6DQ@W-IG#wch)di zTdmGrf;N=)TTE}PdP)LL(7@b_cK79$Mrgfo!$Fyx#WJhJ+rf-8AShC)tI9g8M97wR1nCR*LC0o@WcZ?3FqmD> z0zBL7MO)2Q<ZwJQa`N*W0fT>n^L_#G7O7S-v$# zAUDx~P8{gSy#e9pJ%IxGz&~ehF#YBzi{`DWqeESMpvuqAWV`x_JIL)BP7Sm&jsZxl z9I*sjmpt}sZI=l%4s#+Y-h}saHgZjyji8?BF_90(DM09R(}yn=m9!GTVohTJ(F}xILgiD#@7Pkp|c*x`r3~ zLf%A;IZam0<94)*MnCix-dC>%C}>yucf9=rOHGj8eC%y$CvH z0HjyaUf{X;h~sQZ{C@*pY8?z(bsq>A%z6uuzp3gU#=gxP`g4OER%}riv%D>P$#1=S z%lXd~A+9jWAgpb6ZiSIbb)GC7tsI=&d;Gvs&EB23WDo z)2zY5ooV(w`lyl3559BfP&^^z)Jo>PyjJ)YA16T8ZGD2R@%`&!{-@{*`TnyqO^I-i z28isBWemD_8V!Y>GDA2d98G7@;6olA3wEKEK0707>wV zNEH>pC^zhh9O?3YVyuh@(Uzt7NKK*gr1>HKp z6K)6p$^gS-M+M8#1Hlo3m%okSHnBf4plX0oERe@!4_FmlX4te7NDWU`--f{|N`0h*7}=l-6rY$O3+wVX zpaO+g(YpAL>b2#qIHd*Lo6uCxd#LfuWA0MF2qW}G7FNu7ulT)EsEkF@cWu?Ch7Bv@ zK>5w%u4XpHrG{3s@ABj)bNly5jJX;K@D#(27+rk8 za~A>SI-5pP$CUEo^%;nJs4KVmD|+4gmjW546cSe&i|cS!;-`6~EaihbJvwUY>k5+p z-P-q`2GN#Nc(6Z=av;w3g>O`UkY4*CI9Ld?qQ)_V z^VMm1Xr3)^&Jx=uMSmga1je}!TUD2(d9D$A6ovW9XTMrPJA_GIQ0A^qkGHK$0FZW* z$2?*B*-I63DzIZWlEz*$mqpuwWi08OCX?E>C+%d%I>&eSi|oRqi*+Q{0A9soyjql- z$UOoFbzfv*Mf%rTWwS}dU;%Wzq7D9f9Ugkx04Iy}Z5};pktgg|S$0wO0lP9>o4ubg z7XGBO(6JgEOL3-DxL^ZM=7n}V{*<06R*+)z;&#EBmo`h%udQV*r}f9WLBXX3R9(xv zQSrMBd-Bh+W#49B!n7yy9`Q~?1q5N2iD%;ig$Y5a zIHFrZUzR}i9(M4WD*^tzgONHH(+X(ZdxTYsco4YW?T$>fu7KmjLle<6ynX9Kc_^o8 z9L_iT>F#6Cr-80#3TJ(;284w{AFyui^Lbph$F+d19)$4oKmGnDGhqJ(Ax~?17!@=8 z`?FyX@vK+Jf%OD9F7~+Hp8DL9f?_()F1n_vpsbme2NG0)t~N-(el7YfO&K)z>!dXK zM?F^U)o82W+KI)|@K#!wN1E3+1(6P?5PxYYBRn;pE<4kdcQs<&Ah%**egeYW;`p;Z z<_AA(%O{uIC(H@f*&*STPc5hQitPR6VQZ%4PTX5^iI z^*5eBVFn=4*c5_9wU`omwn6Qk3HuhFK-2&C2vPa~>?(SmBGeM6t4b-U)FRZ;kK^-2 z%Z*U_?_7loOu7t?{5du+YjDuNClz#of!oFCwmwc`0dwnI6aZV&O0Yfi&x)wL0()Ry zX6C>}{As+S$rdXa3D61PPV*dP^Z^>=m6Tf??QTn@k;l>o*g24(LSh+Fm)F%WIPqjRc>s7i=yo^>>yjE46cCow?J6$$mFP*?=xvd*PYm@ z2MbBcigb2^{lce-1D=c!vEV>iP1B(#^T`1XL)c@lqu)lpwczgf;DU{X;eHIYAq>`I zu;TDG#SPjF9_9fy>6NX8%gWy}vJZMv9f>1bKTUEyM#`}6jtJ9wf$YUAl}-f&RCvdI zGVQFuCbLIlZ6A6ne<M2xpxN~d=__pfJ?7QxQIu&^A!R*HF4kwO()rNY|AXXWR2;~ia zvDimuywnOP%d?@ya@aR6^%k7(eF}>SqbU@zub20mt=e7UFK8Pr#T~j!Po39etu$nsa?;(kO1O)~_IXlVp>L~bl$ZNf*vGQVUIP8UnqztZ`0 z6B3RQXt`?udM?kjewv~D#x1f2;m?hlSmp^VrL;n96)yS=wJVirmv~)M&*vGxYa#OI zDBBX|NF~#vXT5`9HFLCP;$P%Cu@jsJ2nSGw-i19#SxcIX&rmULmwOJSL9hb8QN4fM zPBv+q9GzE6?AM|1o->h|=DD(Cemc;lI7hyA&Z*7HJ~L|+D@s6knKn7V8_eXo6pof6Dbvo&EXW`YkbjHcXiS#s1>=!wB`bICK50xtbp2LNv{RPGT!Eb zx$Q-U*eMS`%E^-xRSQ2JvzUa!yYxL(r0hHN0)m`-n9G3inYsq+m|{vEk0Tt%2~|}*txd^x3(FeLJ0xQn2E?r!1ZtXzzjMwJL(goqC!)Ec>gAdUk-6wix{urQMi$6+V+#mJBK*5p?qi&hI7w z7;`@)Z}SFg4x$Pr#t-hMz(krpE{1wkxi?Q@F^=r&oqejsYe&tEz<9LlIdISa!5wP9 znW}rVAN>b}8S3U}B|jw>x?m}(i)<<*39qyduD$g>vO%UkEpzp8AfxzyHJIU4aaU&2 zq!9HfLDXD*J>;+PQFKwI7b>{$);WE2$oVk8H8kc@B=R4fJd%1{43`k*%VnB#P;*KR zj?Q{yL#kL0mq&&^oMbOjVKSTO?Mj3gradap5&nDZ24fq&qnPcP8pL2OWz=rPoVVl_ zvr(8N&%*Qz6{;!|>JNX9q2au*Nh;dWxENDIJxE_g%_ySHM4+rBO7g8tfH9D!v4~kN z-{3!C9W>I5GNYUV1L{%4kWm3IfOynSPN>6Nz4af<6+s$h1<#JE* zs&q&Z$2RnW`8@V=zPodi(Oh4O1>F-_Rx;!Q%qBBIzH>sMRS1VAk40HypF9n=5FTot z2tqB_Ds3jLRG*u325W_UOf>PJghQeM4Ch=n&}^hF%fAK>a-6%#d?me|x${%Wh^YbN z0jW(b408ZemOHz6vf&Jp&-57#Me>y?D0}V|?di^|oBOC=9BmL{I8D_zY#tI6 zr2^!T0NU>Dic3Y!*6JzUO)rPLP*Ub6SdvYU*$(&vI2X2)2RbR3@MU?GD)?r_{R;_t z{GxGpoaTdBC|^@K>Vwl!&_#I%RnLxLaRK!O86y!i7nam27)e5eTkx5b@uE12lfHxn z&;xk+IxD4J+56hEAmiuktP4#UsVi4~0(0zY-&ClJ2SfRK*A%US&FhfzzJJ02Yf@o8 z?q^>)xhC^y+pc@0=A{dmj{Pjx{>@Uw&Vp>+bkCZym^zR5{)oY_mdKcA8S^B3E$qw? z)?9Viw`%{zvx7D6FJ6n1>v^WIKV-^~nhQ@Ob^Yo7DiibIS!|8_Rsp_kgK z?Tbh*HL0ib(pl5VW7=YMyhDZ0^%1~8-ujHt*wQa8trc1|5h zF5K~IiV0vyGyaVB`qLe{XhaNuj?{i@O8`L#j}GOm-pD@aI6}SzVg={bJ4YMd@wmah zfWnQuPfA%v%hHx|vEa4Jp6euFsUuJUs8c^5qXjxjapY(-904~*5yO%jgCXU!9;T)z z7TF%y4Yx3i36bCqk~zdpgHbyR(G$-J0t6C&6(!`^40 z_+{-c(@_tcA+JvhMD3 z>5~z)%*wWBK@%?Qm_4sp*Flf2%RqasH{UEvbX3XQ3Z4qS>p1=Gkt>|mLqC`bS_fu> zBozFs626Xe?^}-KeQy5L!^R=ZMv`|9m>Q&u6WP!bA)8T;jsK_5!P-~9Ezn73&0Ov+ zsqW<2efkfkiEnF_sIn!Wog$O*lP@wYdhyB<3;BpAyM zQ760_B^+&ppxbS6MV3B{eW0IakPaJPSqq~E_E2JuPNI|Aa|nl{R2jQ$FCzQtnYf36 zN+(5tyFjPYOGzrcxIi0wrGgPl+MDTWd+cCLx6pA7<`|0XhFysj?mO{?IAceY?gl~A zpl0n8w5VOR94R~D7<;f+-77Mc#bl~aIqrTw+wuq4#{MSg1K;a&Vd$%I6lvJwEEltu zLI?^6u%3U=8ia_}UlPlDOBIl+1hV-7a5a#-X*A5E6tp+AXNb+nDnjA7pK4X}QkmVZ zSj_6%J0qK{J-W{@&Nj3Gu{7rw5?Gg*MhXKxJO7q1s4;5k!uYTkn)5|(gCxh-W(+A5 zwxpN?RRuZerM!-7BdG{8f7q&TujxJU>DpUpfoXkwdat>L-_`fm7JRCiBhdd#(%VNQ8*W3 z$8GmrbGM9ddSB#lE=(66q#3PD0{h9%z5R7{0_s^o<8!Rp+$W%B#pRx#YSqHPBgFK> zd>dc-+0?B2l5jEqs!9!i_ZK5q>Hm_IW<3C00pjBR^VEdbXpbPl@qXLP2`O*k zYQ&~wyE`X;uVKA|d2e}xW%+0DNiqay^LHi47NtO4_*}xfM6G)5C-kddVrxM2Y4@_)0)as4xFZ?qO?dGbI9ur!|s7q0tYFAa@$F`#ak9K5oR35#XB7i=T>J0&Itouj7iE_s zXr&x{0!|vI&ZABZZXrTnI95{_qNeNy=~G^r>q!Y&Rbo~(=(5HgD6&^qgTr(64DC=p zv4fX!5B384CY)S*c_dCxa~zj;wlP;DM~LCypAUB0$^{t326_?D{feZ!oV#C8*nE#0 z5V~*0qC9}?v(Aq}@5{>&ZaskEIF$78>r9600eHznX0L!fBv}sB8op@{c(Mw#e#zmi z<-)WDuGVGcffN6;_(OjEJK|wUezvqv{8& z+~i}}Rwg_)$6uL~s=c-ZaB9pS-t@6p-Phfb?KMH_kUK*7r>uYVCjI+U1?ZI1D`Nf) z*#jTw&Wt)SQuVn36sZL@LWElk`-wk&lQg>3VMusiRdJ|-rUQ5};&CsC2?$v`P(QElE<^_){ZUVHcjUrJ($89%LZqJmpTS5J#;R{4Ra!LK z1(ko#&|fLf=9S@MYcOp)+@m-Xw%Lwmn|x;`I;YwUsAp=~>RT9ATR=Mg{;DuLl!<9L z**qM-0ch+PI90zaO|93uIY+@6tEN3K)n4Dsj|&e-15y7a_ugk3)IqIl5s4@Ldo6*H z+PJo_c@OkbW=|sl4NfmU&X-fS=21cYMRwa|$ai~ns%mTGh$M1r%DP0MbMXd5_FAEO z9Qcw#2Qx`(TMFA1G?iMMz&;wOf?fyz9u7lyrzo29lMDp4F915e2JeYHtU`?*&l{i- zH;gD`-vah*I}o;s2^#aj1Q247MJ+4PsXLZiPSt}=0|OAcfjKv~q`CB6?rL<47?{S~ zzbgqht^g{<$Cq}CT~)n=ClHw}gQ(De%0r0u_P=f+z(Tm=mqwd0c4u?@CHVB2R1~Wt zsJnukb6sIKA&R}dcHg^bq5SfAixiq#7P=OIin%7Unb@}@Z{7tW?x8pe%09{S< zCY_9buPrn^0mg+I-=7$3#rw05Ik%^KBLx>fk?*hGSLa@afN}Vpz|g(^c6&9SgT!%k zA8LZ&1nO}#t}S$$SbMufId>+VTQ;h*4^8H!7X>)?Bho>``WI_3732o>eS-rmYMFu@ zruKH$iCiKeBnkfb|8rHc9s-GLXt3gP7rfwpH$AxyLC|?1g=P zg!U|W0~CQalU!PSe>`&Lg7HIoV0z)Nkfj{_7rkROYIW}+yFhwkV7qwWbJh}tJ#!v+ zoWkG%$|qdv3gkaOrLD|K-UMC-&SXGLyzki=Mca096IbBLkbArI_?FpWU45|vSl&2q zz)1+R!g)~0LJ+ZNEJe?As6|~1?6F~UTD>gykAkg4wuH?5 z`=O3_taxWBkumqbWw!tOsJ*9#Tm_L{1C@@mW(4cfVAQ4Kz_7-OEQi3_#=#^H^xNW{ z*buqzjGV!)g+ZehOl(~bvma^L%FfFBF-D{g+9f?h69%QCzOie*>%!Ig}MNt}$E&|=mS z_-lXf@ssw!n!>Ol*)~hi8oU)g^x$pwQH0uSN%lFK-?Ir-1n7#6Y_eXbFyHNW=Hu{FN1tyEnZE z%Ct@vF@3-QG1eX9_>?b-@_%n&@MZtKIY=elGR7#bkuHCSqPx7DqKCe#i-aDb@3!t0`J<=5B)1{`81T*)p1)-d915185E*4s?YC zdOOICYyyf3BjYsng<7*<>n@-?F5#u^+{I|cA{Y>}?XQ3(!y}P#2fSdz<1}<+o$@$& z+C-q70FLZBiO$glVkj>_GfZUu7jwxy=FM*O=`%XkOmCc*!s>MNkC+P<&hdL=}Z5=6Q~ zQlvpjL?jiZK|;E_OF$$ROnQ1ZWy@4eqQzA+f%ImT1Yz5DFF z_F8k!HCGE1iQc6!XcenlXkP10)ycuEgtE|l5HeOb%%Blku;P9@;x3SadE3xT$}t_Z zVuVZi?R;ig1iZw--X`IDWL*Pve3^X|K_3d&D5oJdsqpf|LoharkuEM0Lp3Ug6>uW9 zt4Xs`Z#ybtC{7)Nmn#K3F)||s{x}^aIWts;ZVdrd5?4&^9x`)HF@$+zY9B@unh-`e zKa!uqIY9JTpId!L9%-BpnEquIWa9ACs1<<{L)?F{&otb;5iWs%OSYT9pSEU|cdcF~ zbCs_B@s%-=cyZ&faOp;~1oYTQk#FsEbBC-t2CmRaCYnvdnat8VK&FLvpzt_UNpN7W z!I4#Eae1pT>D66(B3AShAVk6D~|(cO=v58WDf zQx``28uZHRF4#r(?p+DJ+kNj-Ix^{vHIPDm zF~zBmO)Ww@fpO%h!y!{==6-$0Ezn+x>V^g71^JpFZBUzOjv0eA7nVUY{ZWzM6Jc)| zNCx}vpU$2g`I*qPl?y1!u(K7ok#6#I)O77$y?zC*<6NXaacnT;l^z&?XIK&Pv`qk` zp(Ub+J6br`LF4Dm0o*xLW6C6zpp*O(qv2xh>G5tq_6L`Z)og7(O}eWI&qTgorqesF z2_S4v={^LF8p(|ggdut2WjAq!)WdfB@##)NU_t$nxi$;n92(3#rag&9{DMC7@RG^F z@KM9}z22Y3vQ52o43z>9Tg2z_iaL%*`zt>$E?hyH;4zOuA{x(>#dVoS{yy$lzu2zg zHh~v18CNjOn_aA@@lUT^yedbg-i-Xxw`UTdlzai3oHNMa1+}>6Gd!P9nLB3?&T!K> zi<^_Jn!N5g_$=*j)Sn%FJj2_}g&M{2BjQQiqrY%a*ozDgR17~%_;}2Ovz|2%rjkE{ zU{AU1NIemRnDN~cZN9aaWIrjCe1tSePIcjh z@DfOZ>uz1KBi?wwt#XrBpc(9q7H21O+@^ivCb<{au5kQ_3m4sF7uG;Vmd?pDCxouU zeQ=XeAucM`z=o9AM%9(Lv*K`cmk;Lb71lgeD<8cJcS=+e64Vq#KQNS>7(4jWoW+sY55`gWW62D zswxMbIt(J!H(4@>GjM0@&tUfG#WaJ3=Idl`T}4?5`nBIUcvD%zf5RrxpP@rr8a^x> z%f7f5X-McMHglA7>oT9ZBkA^mYr=UZ-eBJTo5L^TQ}O+9#-o#y0$M$ylOKfP(dih4 zGKCFry$m~uKhXcgmYGhn_Jc0)PP``q?~D6f8&5zgzl)d~j`|xS&>%)ZMkdU)urQ&S z)iyL)yS`CJQ%5rz=(2N!>TZtduB>-o zX9-Xzh?*Ka_)wOFbWUbIEUhRqr!Qa(pqBTi^@d8BG?Z$G#KK^U-y6z+eHH`0OmahGcoN6RR5FZVvWl%GN7a!VtKQ1C6I` zUo2-5;$uI?$4>8$yEbNB+{|uw?n8PPXNo3_wFK8Q-IB9v7j`)dTote1lefLbzZ&K; zHgxBa#>WaT=*@QP?q{>hUqyr!tG=$|yYL-<`ePhagA>7l)OBtt9W!V76spyR!flSj zDQv&3K$=$ZgDGNNthT7|B|dixr8Ar#eP(nCb0H)5vvu^(JsR~OU&HUx98qhsz#s9< z9fmoab=`bV;8EPe9FNp@`@NU>#EI|DxDX{OpwOn$+=j0+)~1b;=M)I`XG)ctn8k=A zY_10xrD?{aJry>Ij;uvzA7s0D`9w9k5;G3xErl7|UIO=XrLs+$K&Uq2LU z!f2p}E_(`fQ`;*<@@Z-4iC6>_3*)0ufJ;1wFv>o=d{e7MWaC+Oh>`FZO{k;mghdX) z><6eopDm8?#yhx}s)I}pMk7B5sp<7<)-c%wwuI{p-NM&HTOEy#s) zK6F?r^O$Wf&UEnwjd*`%N+|p^W14`BeKHt57dlp}kVn$57wEfR#zFw=%HrMS@e;W+ ztWbrEvqv)r_X<7Y^5XY&1>80c&_AKai-mE;P}YFoyeO(~8fksIw6TU|qI-dQmVz+Z@mWMFl{xKsHr^0S-uGB&> z%=IlRT=^G;`>u-$a^BeB7!TTp>Wc4)9u0C!+)rpo8tCJnE~S%sR+0ZH$eGkLbWxLa z462;DpT63FFHKcD(A`h9DQ=xwW7=|PQ0GsJi*C{-;+frsLO?5<{0m9JAMn(;3July zy&I2rE&;iPyq-yd#5{l7C^Jccd_x1X5;IF8hZhUAt=HZdU?grt+=ZG1**CW^aTjrZ zaE$8?E1hF;;?#INd{3*ajCeqN441b^Y3t72vFsp+8+A@DIj#I1Ylu{J?$+5Sno}O% zlhwxwd9F7IHCFs+YP~LN_99wcC};`^LAf3Z7*zoy{}cWd*`evpk8d})-~U?!Qpp)) zqYjad0XPa)SL@|DzAdd}b+EU{J`lvdc+~*LviyCc5Glxhfe$1n&JP5Hl8N5~q?1Fl zn@z1IJ>9X3jR_h|_#ZtLEdE&}4Z+kBwr4SE+Q<~82 zb2o<9zxE+=4EQ^HGRW8tJoW9aXkSQ(I}AgpNRgR21UR889YpnTebLPekL+2UEn`nI8&sbaHb; zVIh>GQGfrUGisp;cb4Oa$fxMOtkk*VAqDR7D@L76?!+uy%@mn>PX(pjtj<%m5WZxW zCR7lffBb-JbO(y@_qrj{2?X4RV`Gi`mF^H#yAhN3SG5#;#ni zZFMpls-bZzGBX5bf8{R_S`X6vM<1XM#x&eN59PDM)$nU5`dCTx{L%xfxO?R;rG+U- zHQ~wtJ1Py?cAmj9Z{mRd;Hm<2Gph1LboP(3gN?K99fR(F#owwl=ot_QFR0H{3!*7n zc0p`Mu9l;WKcfm;&Eb3BHdy_Xc#l~YCCA^ZEBrpOq^;1ld8$&n^7wElq3dB%+K;l* z?q80S6)V3-TQSgrDXP( zdZj{U_l^GO4WH)TROtjV_2I*sR9FlDo%A+c574PT9nrNtXZ-4QY69qJh`vjqchqAf z1(^n{Ob<*vDbMkh2A5Tbt331@RuX(+=>rW_uKx|v;*$2~>E(k7O$F~tm|7~nIoL|I zyFC>?zmCvTXtzyNhpBpn!j{C3cQJqUkj;VE*kgYHzJ6Cd(!Vw(7LR5}8TI%iX!e46 z`e$-=r{RM~F8{PxncJbpeGzdY-<1J`bKr5g6kbEdJa(5V?pMbHc|4H|AWVX#(+kJI z{0?ZVX9TcSx1i4;fys^yg8A1KDDi12^U9G<60o?O$*1^Ie9#V^H{sXI@}@LLDkt-? z${v7Y&gySp*;mjeE%y7J zIwd|Z17Er@Bpo%JpzauUAq@WKofON#dblJqrP}vRPnVx|KR$Jo|9R(bG=5qXGUlpp z6yMXWq|qwfC2fvh2mi?uwX6Z615*juywFDQ9nfsc#{`tH`uBq*ZmOFdu0J3vf< zNjH}P)WO{hLA179FsLW`N%4aT0rAiQzg9xIRwNb84somtA>KMM>nTr2PA zG8xE_5>HW_@g>UjL#3@o2MBNic790dmX=eze--WVcp46a)70o%n)w~#vEmsMpq_2N zE*lEe*;Kmu&>0_Qr!9LQk{Y?I`)qp6hW{AO z(a7o1Oe(Vhon^C&aPTj3P0wFprLD+p6AGJ(`!}nS@N!lM4R)4eB+2MYMzyViwL}=t zjo7G}Z&Z%y%jQ;!vn+u~Is(9f>Tj7m-8fm>kazI2DE00Oi#4V&&R+QRj!h1*$!%m* z)_QS)v{bQ7MAmS&QaFOg2IY+HFp`K)j}($Ju0<(m(NJnPvK35 zgE<74Krcn6$@+t@3W($1MvAa6r~926@tU1z0oLkC`n-OUai9%X^~)sy!5GndM{#DY zYczn0ynZX{1vf zTlgRFF<0~42eduTU7c>O^BdO0eZ9)HwRD z5mPS)!!RlQulb{fu7hk1?y%1N(P9uOwxyo9eLT`DWiPQW$uBQ{50vLNBp5kQY~MR3 z#Kz1XeTvhf*tA)G6GF(N4sc8(jZsfqQqD+yh!5e8Yu%LqjmJLxGvNKI3H~^yQ)Iy# zh_d}`^X%lKks+d*?LuIt49zj52Qk{ZcFp?N3S3-lIwXx~mws$foMXo~_AAUKcnwRg zeV)hAR4h_au)%U`J9KVj_0Jow{`Vm3DAgSn_~6k|Ij(ESc|cwFGru5=UwcxlDZkcK z(BVa%T28#4>Gi?lyxjGHbfo>dy0iO-(ImfC6*7r1Xo~CS=Nbpl#_GJlAwXti4?t=2`K#bkLE$IeGLQbYD#3h7z@mN)Yk!S!&hTHSJX z1ij~v%OXaC%|YAFQieQHxC5xzpCuBPhEdqnJN&4kk<|M9FNFm@fKY_g#Hd>@(r3yCkoQW>b;`?~4tju{$5BjM{^db)bxq>$=#i!{sFMOeQ% zrX~iclzhWB;4Z28cDS(2?LCLIUE#1H%~~k}Zw(ATxv*Wt8Ac!`Bc#2L@4c$gckGQ= z95F&jH)-My%6F?b>$3OqxgkIBi&|Bz`B^(k)j#Bcq#(o9_I!U}=o1x|MIpnjhmR-j z4G#+`I|$e@6#Pqbr4r=^IR`S0hC|5Be&S-LWQK1Rnrn2qVM=QX|D7iGRJ0UHbB||y zntYSwn88SOvs*L94va_R{DbGo{HlJHaljXi;{y6)%gXWVzA;V{*E3c6O!i<@y&apa zmOnCriHNj2aYeigY@8Bwnb0OJMTd{_CLAMuf-D`@N15`NoslyzuZ#OlOouhFa$QJ4 z1dk^(fl2og=lspWUWBQ?>z`i~--Wae1U>FDN4XfEM;RtCc|t6|-+NEmom#+Jv$RU> zf+{*OuBBX=i;QbmEEuO}Vo~ayANt9Gbg?$r*%|%bnx9V#j<_#o|7Z-0+jL`KZ2T^Y>|yihy!N5N;OO3E=()VAz}|2L|P($I9 zm4}M0p8OC)HJG|ulrmO`!FH5ReEFp+kytwu`UQ$pETh!be{QI_vi?)|EI)%vb~#m) zECGQ*+GR9+Bkklc-6**(qmaSiWnp_iYw1M(#?q@M0DXZY!C*wsO zQNPGIpoII-_D5{h2xnQBr`y+MPp;eXMhSBsKrLd=Ke|zac@8W0##{67sP3O)xl#m; zpb`w@d5@acPcHnaTN6Cvn3=;kx(}9d;caOh?_X!DKlX9S3EtIgY)I~kBt5O(hrWj} zv#VtGBRB)`9Me-@$vJTA(9ZWTM=eo@h#Qi@3A6Jm&8MteLK@o~B;3Vz^*z7Fe9Fp1 z<)~J5#}c$mUk{mGxO9ZO5&t6Gt4!(lj6op&Q=@ZEM^o4V)3pK~0&6g=FH>S)a4Z1; zXYIWq<&pFo2$l)m}hV!yd{p5SHiO5^W%@#1gze>bfs z24*0=mUXZox%)s51#L-`*SL&9QUWqV7%3GN-k8zSo-5v^>>qN%u{Vjc@?Q$O@_dyE zFSYOt>iiY|PEjRP>TQ3X&w5_!ChDY1qt5BcAKXx@c8@+16>AMOU<<(X5h98{yzncB zKp5ewFXlHg(Iq4cb-RIHht!VLn$)SEq$T^{LV;*Ee{*`9Tg_7ZbsOT88pm>s@+RQ!;&1w$5dBKs2)J3%s4GVp3?)LnIAobF(*g$N zJuvC23>ha8E!jW-nLWk3LMCf+gR8WZAoidW=}rqmuA$5 zKJ&|-<7?XYvH03^h9C?KDBa2$1!6^t+4yP)VfmmA$4|_$#3JOsG=sFFD8@eMvw2;| z+W;)X!c7+I}Ikqy0}$~#d{4d(kJF$EJXjTjuu({qB2YmJwLHo$+A`NbF^=3 z7JGVfMA34K)bdx`$}V}#1%9j13fXYd!Pc)BPBWz?w9&IV9E3b(X7YrahVQx3&NX5r zvdVp3al1-AbJA2bK=ZS8B2+#|y-1tf>Nrn^&I*T-En~3)!|9Hx^Y1sjGM_juQ(yIn zy7_vKl=8}LNi_VlBwz#*DiRMy-nc8NDYx5nO%e;$(_?(6(}2mFE!PZ}&_FUo!yvvj zlV92@Qj4{l_GV~00dHHVq&aaDB?bQa+Iaa3J&CW;7n@&YsTMZeDY>&7AuqUzi@sf@ z_Un)LGyibcDLiwxL2ZUF3|Hyb%D9rsJo+>K$gcL;;dbY1as|$X#wU5>ECbNyDEUe$ zH>AS+Tj>;?Ju#wxSH}E?_=JV zz;gAWA@%C>H*&a!GR3keN2mDy_}@tvQ#8$x3b}F;fV;W%+h%^;(8r&KTxj0=(yfXZ zuP^K3*O~9#eH*onjwTr(?6E-c&6y8rDLiY6#D0urKDCI~c3%ov(c853xU}#1q6`Lt zENHY*g$2)7vLw8J+Z$tCnIZX7CyCL3=csewOLqVftoEoxo{Ly8!a zh?A#TbmgvrkC5qnire>rW+5!B9rxzCm**_GBN@hmfVLQ}W~P!`NF>R=6m&OIzdqqv zZN1YFy#YgR88rp5d&Q?ImZ*3~A_C%~t*kj0XAgx+`+a^x-Z z`l{g$2DYpD-nrp70W2@1+llW!kfag!tl)hcoO63rxMT)X4yWh)7E_K#&yf8?0!%{q z!SO@kESg{9@i23xT1P(>R=&-Y5^}bCc`Y-C|7B#P>x^Flr_S=I{hK^o#T+L>f`Bc0 zfBtpI*9@WiB_5Fw^u4;7Gz;?SYuk!5i0sVvx-yB^?^0>vUcz9SYmd3zJ*rpY+Fm*G zNUWSlUt72vh~)!Dw9h`cZm5x&5UX74lMivSqWrim+GaIL(26HY(prwT+%I4c6h(2ZG&O={RHLTeNfzV#mc zU3^6=Y0~XPuw)&ILE}U{3Ou-m;TY76(xQ)XlHv!ni5C7lkuez3BG+(wmc&#(%#W+> zvD2a4xlQr1B#VSwgfAr#-Fq+e&obrl->Xx_**?kq)}KBrojI*F*#3L=!PoOu=lBkP zTMT&?9pfTzNDjx0VDybF-lx{g#~*#$*DkIS^Vq$+Ynmm*{@fo2exA^vaDE7d8o$ul z|554Lb=BXj|L|VVSHhm{`wXkNK7#)Qil-5hodPWKm1w7+@7* z34R0a6|vrp12?MDy|Qd!&PxS$HA|!#5(;*#JnZaUdc)Mx(DaUv9Y3W;5THsohyE3N zlQbYD;fB7>=L8lN>Pr{k?EUj&c-x>qO}xD-A6+$JXyn_Q#NRGpY4}CSMHW5=KDwk( zmMa6tmruy_P7|LfX@m7}d*p+eJ~c(6k~`Edm)zMp>V%KH%xa-R%FKLQg=C)-;YBrCb-*-UT|L$3rRJ_$z^jzolsv(-zcs9p1NQEzTuv zR!G0O7+;%_m(6i=f|8G6?gwR&@F_R@!`!+2V*p33fwMVuR+VxJ;j0g&r~e`&H?qsL=!dnGQw`!hw&ms?B>D z=;?>vy2sI>=n3wi2hxn?yKhZ6TODjnQ|g+})Yt6&9O+Kw8|)~)tjnQY(Ya;Vd;&dO zW0BP2KdUT_KiX~(j~44uSY^*-NS!lQP+4ebLeq=htF#>HTKWiWF;hjscw`fwV_06` zwsGmzRv!|_nCN2pJeQ0jx~nQ_=2s7;#q8EhB$?a(%A&$YfOXVr30Vu%9r-BfzhEPA z1b#ZP&~M(p#V`5;Wu#SNcwegM*o?;tRm`Xug_ySs?>Ag;F#1pyl9g1F&(*DQ%s-4I zShwik){>>Gb6sCB01PL5sVlBKaZ09orq-q4em_X_3_zt4k?OTkGYYVzOuOW{Mw>~2 zgUQ7kM-oOxMi+~IgSN(cccuU3;^x!!bkIs#;H*Hto+eQ_4icJgk>-7bJv1KQ2t`2_ zkIxJMLrq=IWkMV#6z+xZh1}ea@?(=r7hYQZ{E{bN(1c+u-T?|Z>ti~P)NgW4qGP;E z=vbM*hd~lu77Z>I*o7dbZLgahPU8D*3j~h3fPzc7KMtA~lTvP2484_`%PJGI@w(dB z6x_%Yv}zoetlPq_?1PkuV$8e|45GA+!|zm?!Q4?+*{jlmsG7PhKU%LsoezB$gZGIJ z-%k0ZG?dmooNozE<-SM>4r1;%mzeIw+WYcdq}ZA(+ezt}3ZiYhUM4Qe9dlvuuzCf`M~~tcBdZxm2$I2qqj#L z#MgCTN}Q7Hf~-a}a|IYQbBscMWqM>9Q(YB1}k{)EY7x@kTuoI@s*erHj?&eevclZ;b4)|`x$ zIFrh31cWpxPC*)((&rbGLj9qb|McuKjjg!X{>{%Q*7i3g3cUv!HHx%Ha$lNM9mn$utJXSOT-U8G zk(HC9(0LDuY7fEaea6#dJ#0c8augfUfK0ZAWiAe5pno)S%}Bb^`;StVt12pJF@#m6 zGz(1ZuC+?}T)`x~D~?Gi|AyBOguDwRH|*ymbCeDsactvc-e7bG-EHc#WGD0waz4{) z=f(CHPF7!dO>)Fqz<27RVVYA*y~l1!x$sW=WkrlAtm}_AO50P9V_&{i2s)vc4YOB} zLQ6;bqklztJ+ZWZPN2#si`*#YICH&Mm4@NeY~EB!%q^SI)!xnUxNZ3yC+H%kuPC!} z%J82??K#)=56qwj5zM_7U;OW#BQuQt>uuNKqsG18;SG;)CHQtT9r> zW#aG8-oSUqy(@WnLhkLeP)SlE)e(3Yor=E{?^EIITp=ePfP?_VzQsq$670S51&&4l z2ZKE{t!RNyuncpFzIeAmo)O{Q^O(5b^Zc_p;9pxXWK6+-$mQmMmk@CNuKMX6mC_Y$ zrRes)U-A{3#&P`b(oshd4GiB?{R6Mz=?nh}(2d7qXggI2{2VDrFy?vENszeQ@O6ka zSeC8ke-9;vho-e%mK=fL`&`nLNL6oM2BYW?;1`9COI@T?R5l1wTR18vcd23K(~5in z3-TOV)Oe`>%-r}7i-PxmpIeH4=*dj@8)nJl7YWbAg4}Ygo(;aBqV}%h!h6gAKI>c9 z8~v>B^%MX9*CLO2mrqN51ypjjmR^iPb+EsGlPh^~72zfXvREKAE}6(zF20qm|E zN=lzZdl$B*W{z^I^=zXL@OUrDTZFUMrDmM@RsOwYZqvR-GiI<5$3_QZ2b}oPRG!*- z6H}+kzafLmBMBVZ^+*W`4NbaY9rRP6cb>lB@yEt#xas!+kz;zL^Pwd`61Kv$6P!?y z)9yLA&3cC9lHD|>V(x_fiLpqD_TsxEQc)b|2GMhb&a)&1}>CcS^3>5mhH2|Lwri(n-9 z8!@XU?FXNo2_;vJ-3y=lNlk}sU*KU?9_a;xmuQG?^pd9Eu3Y6%WyO(~s=?kS) zk&(l_RWtBXsVddjfySeyo9lD~vi!WS(e906cEK_6R|6rPVT>^yWtP$D({`#@G3k!4 zM3Opv-#;eZ3EYoKZz?|e-^Y1^1s~_Nl$OgA;eeGHEsMkt!%;0}%cblIX}uPj=+Ugv zLapIjr@xIwp@%8Opwail^8?F{lHl|cNPSCJSj5*Yi8stAe0Wpk9kn26AeaG=-6Ir@h&DRH!-Fc)X)f zH}@284f-`4TW&4yu(96`h4?X~2wgkpO0}H|jli@|S*OmmNcQ&acQw{mqUO;L18~qx z0ddzgv>|%q)7+YRL3k6FCibQL3!(ru_#hJJL+M*Wn?@4Sjft_ol&k35SSne?;pP;N zL*w2iWpkzjg`jN;pPh;lHeug3jt}%ePPonbnAuELDJk)GF+haAhZ-ClRL^_BbZ`(c z>b)^lvk#I&O~|a&wBD2jlVR@NK|i?TAL_=uR$6FWwwW11?Wpb;eBnwN(19W*!EBWf zShA5Y^P}^Tp(%mp@812dmJ|H7owm99?E50ul|@|FzE=quCzm%75EIAbFH=hRPH8?? z)`GI69J11>Dx1mp{Ibr6`48EWCHxwfKF4(2I{BrR%xjD_h}1OXcQJ}QAc3E5dOiCT zSj;wyUgS#!ROXu#K9`eBFqFlx`2z>uYz^c7dwm#=Tv>2(@bQe_dw@1$F(ezz0;(YM zDEaw8gaI{wTN33dB(AjAMtGH^vWtEr)x=KutXU8H6Sir7V&*WZSguo_x*2SKCU#j& zGuw;HFR4UL!8hUcJgx0`naMtg(Q|TBeuu)5u-p82);OOC6!3jlfXsi(J9ENvDx<&3 zVix@YiVu>(E9Fos)X^4sh+wMoO36s#e-=Z5tIVrR&JMFS$WP{&ryhH)^LxQ-nd0Ko z{QRg`cU-B{ZFQ7W37>+;K=Nr=2ml7zwNrA`9<6cXx%U}XD0gA6D!XWPv7#~+;mfc} zh*zGFpkgG(pZMtiS;0QpdPSTwrNZ&lWz6UBS1B|ch{~Xcq0*SN_?&wN67rJH&buFG zVpn6aDs0^?SZJ;}SFD&fjTPz0Jxr1gC*`#6OA%HMY=r#%W?WVetbY!Xkn{Jby^ZO~ z0ejxTWs6?nv?Og_n)|VVMm|O$wXUfe~y3-{-!lU}P(o!@hDq6jyD?hB0o7@*H zAGp}JS+hdDYZ`8Gj$0W0r-_VJ`R!KIDM;eT&j9j%@WEsP-kNQp9upTkJG=Vt#}($U z5TVG1tPk|lO+a_$I$Qp~}iQoMng&?(%o37}~q+ zkMf1A$W9~0i~fL*f6RW%Be>Hfu?TQd=~)yL=XxeQ{9sK52cPXu2HtpzUR!SA#I5*vvLgzn*?O?+22q)M4!|Q+mEf=hdd8 z#BN4lJ(QSb4IF7Jl~YA(s7%{m(rj+{KvJkoIFPMGVdl6=f9_Vj1HR~R2LFm+^d!!4 zM7k<9kG?TBMY}*@9<<9%zHpT9{{14$@3=iWe#t-WJ#{f}^2#j}_UDo%NP4lRa(7*n zGoWAN)O5@(%|i5m($OM3C2ovL=2)BSfBh=U>)1a(#MY`z#-PRkgzvo<~3CRdIxfgW=KNB58mAVr0f+&!e&&cCF7sNnb>og z{6_22Jk!brBx{rm`wIiuN?)WQ)cjFG9s5zKe}Sp(JbNILIx$N6%X_?OC_T3#A6#bA zeQnbXJ@ame$>k;Q#e;L_oeO{2i+F*-O-+^<&i4qtt7EDw#42KjG=9gW!}~E~c=}r3 z1gcZ7i!GAI;z#&-?)@}TypZ8+aQqO8y716Y-bg6QZ*sUmXnFB`l?U@dHmwiV5OA? zI74I*tAlNZ7BM#_w;o(%UWD#r7Q#0~d&21-H+mN*KK45qao6I}QAC$FS*Nz+#gGk$ zb2pk7GVG4V4wBxSHSZkkq)T}##j*(*OnY-tdItv;CKabxKAibmH{%E$Z*}sp{$( z&&#sqAxoMPkFn`alxefu zCG50(GoFNZIZv;y3h@lhWIa!ag9{11%mQ!Tt58BA$F-oP&iQgLoyVr)6OWX6$R%d1 zd2hfpw690zF%YZ;#Xlni~Kcif`zY+9O8;^2&#E|cl0xEzO$cixienq zl`ig81r_Zi2xGtNyW@Pu`3}TH8B`6T&0c^FK2syLi%%gVK#B7Wg_Cg$aG>0qw|Cg} zYAd#PbjqHD>Ws3O`VsuH0XV-9IgZdKBI5zt6=b@44=Z6dOm2ZS4JF{KY7R8IAg zB@QfRTw0Z2rbr}d(m4TpC9^Bn)ftmtZ2~AmDiknh`&|b8GzBVUT0cok{UNmWo!H7? zyPM_rUp`JZkoHZ~Qh9+(mh^-ubNmpLXj9hgrm8{=Qj&K{OiuXAKNp_wFr0)8^o7k} zXF_~ac*t=8H*S#ms3NbH|a= zVKw0vj11chaykrBr;?((m5I9zD@Qn;`qf(cY{!x zrxI|Etzuu8%tIZw8GF^dN8AKQ+a<`?j$^5EkP3ph6p~O7NKo=~8lohQ>pS$5szvrq zi`bcr`p>BhJYA%t+I`T|?4a1QHQN{Hxc6+WySKbQp{6a zeyjw@)s`OoC9H15Vk}k-HudIjG?> z+Z5h&i+F`7t*{W)ULm|)mzy&IKZHAeK7X6zZqU=pPx?X;MH|GBA!t6(^k>%aHMKEC zSB~{i**>-GIb%}FB_cWfSgI5=S5+VSC{hFokXG^FOKn!e| zq2+ixiiPGt{^h#|zy8AlR#Lq{IMC-2a3fhMJ&&ftp=3cDiGp01%&6A}#)4=St40XY zpXi@`ZmQ06`HQHN%lWTA^f)l4>jhwJ z0odd6&2dqf>&HBA*W!YE-AURSzHPOio2UK_$Inr^4Zf1WYXwTLT! zs}^)xR?K;rVI9kE{+Ybn!-6ej){yeE1GTBtG_DgYisO6**_mDYqq7W z^xo@6Pk&0G$Rv(YgH3%rP)?ny*i*dlhcbXt&9y#-Z}<>+lUmMp7?B`Tb`!g&6xae& zs9OsQ(izqbO0{EZ1;Zh`e&&ckm@Nxywh z4#`ixb$V*zXCkCdr{5{xJdPUaSOKw{!mV}s8aS80d= zuNACV4rru2Rm%T+EkC({={;7WhIbD;K8H7;)3E{JFE*y@ruPduLO!L4RpPf0QY>Dq z5;eANOGIt1MetRdT1%(uUyF>mFBE-=MiAcac7#@^f|f2ZYY1;l!ZV?Et_U^ObY46Q z)@1h`CuNbYdBJhK?s!fG8@F=9TQ0%{fP?k_WXU*GyFE9ZL%+5yS}<`GXe(xO%eUG= zpk{I=8a3d=g{c z2Fn@0kPfsWp-Iei>aDd)sr0ZAx^ZdYu88-Pdw^JLIpy>E*f#zE$FEu)3NpGshO%B1 zjj__m)x68JUijQE{DU<_9)~+)TSXx~PLK*WH+L977GLe#_o7D7M!wT470VTig-<=! z#%(p6JSS9hRWrZdbU*qgcWs!3GNE;5D?NjJV>suf;eOxcItljN)AGm&fpXvL*RL%X zz352cxc*Zkm7YKmUBYZQ#I9-;X}{s2dMUdqpA){;crwNtf6=x) z5Q-lOe(?OG`Ymyx+=w|wf=flw{?wOLcq5KVVAxNA+pKkgPru^PVt-)X2Aei#eN8zv zRXHnVvg+42vf)$uN$#X=vB}j27u=0ZriF=d3KzS=s^(8pYr!*@;={C#dWDorm?RIu zRZ-W%Qh^=tlD&!0l!Hmw+9_xm(Gjfw;EjNbbWv=<_aysCdh!`7(bvRy#(Zb0`gfK- z|KO&#nItj98i54slaAS#n{eVwU*1RzaJK`uWj_`ya-r z`>x!k6(vZ#VREl*BHR;6zz7j{3=j+X&1IE${Ekk}@ z3Fx6O0p7y6n+DYv54uXsPj8qKS$^FJfAN#>FR+M^I6|mQ_6##h!nl+ybR?CiVUbtw z2f>`Ps0CLZcT>?DRfGi(^P)=|#eC@iDozy#`OP!?$j_F?N6oGcw$mbG?+Qr=8V(!w ztMB}fLAS(WSoLUGMef&IkC(yFh;;JF3#kt6bA z@u55FhJzMi{b80=|AoVRzH*!l{*SB0brG}J^_8=b1Swll6B54CQc@L1vWLGv<46)z z_#2hmhsLE8_MAEuv2VRV+G&HQ|M7FQ)o7#hj|bslVPznq5?)clSs>H34=BxQheFxr zFF7$JEawDY{V6_9S!aXSfynzG2zUtC42yz}M%fd2jWgIm)Axbou|>$tY3*HrmBxNI z_WwUJb1JRk@NeXR57ev#nT5SX`ol`DhkQ$)Q-_xurdmlG2Ya}t8(g*DNRmtP!*#N6Bugx-?Vxz0QYXq`USryWmx#_1TZJ{0vvo==b>g z$-19@(V+|_5g=`}!OIPdYtlTlcPp*Nu6?9191wT;N6&&#Canm1SBg!F?o~QquID+_ zncSI_XfY4)t|`BrzE-?H(ZV zU#%r91$s30!~$+dirFJp&613Q39Fd80bs6$0?a>-rp!J=ZhAlvOw&f|AuFew;p2b& zzkTr#p)W>Q$e7oue{bCLT3gCef4{os=M`IjZZelHgGS7KK76N7gkTL}F5$+s9 ztMRfd#0pA1Tai3RPeuQ8b4(ZUv)4~>o~f4>eF3Cst@BmvA1s__RR#F;1b6+Hc+y72 zn3>ycK}Z1Xa#U0wLL2@4DGNik2mO0bn_+Ih@kNFNVIt$hF_(^S-qw>zvjykhiSd-@s=?7*}%F!c;K~}GWEr4&Ltk}TNAP=zzbc& z^j3eE_n>VciH!YWC&=K}q~|u}a`)udfg?jI1E4=>klTJm>zS?!m)IFcGGG0xUZ1>D zJ+HQ!&$bfTYZptjybxAs5@uyZh=*ZcqBMs_xFW;IURNueSlEuPt3xq*?$?O3&0JLi zl_iGCr@q85S?n~pW>rxx5eF2~`!CnKtd6$Zq6>ND;E0M9OuY4!3B*vy_P&+=$NR#q z$1NAXN#4BK*ln2wrM5W%fCSh2*$TC5po%R$v3O7r!QWWyyyo(N#aj58r0?->hdO{6 z)&bmiJ0gCIdtIyST^y&*D6q=LP*>fks7GRHro2i%`1FN*5}lCq6Hd~Kr>@^OD2mF$ zzrTdQtQ^Bgya$hni6X%jH-Gz0$3C7&|qI+iz*u}znS@UNwfa&-Kd%np1WVy!5!JAr;>`H1 zbtrG`tp*1RS3o(G&iCug3nfCmT3##Y-rey4vq~5$=by`rnjh)^x9^eX(|*Ah8|Kcw42LSFFGt7h**7TYMCDtmEUh!E^MxJ9sZNnF- zE_&G&&uJy$@!*R@yN3Gl9$iKWj6Y!7Do`uR_jY=0odAyfz#Kl211i>n1mtb z!R?;Aph3_9mW-2Q_C72c zIZ}IKo$K3Zqq*hTqCIxq>}0dyh88Qt0XH2$Y2&yb&)8(OU$kB6OU0LpTLkvO5)5)a zKtE`^yL@ng{YEnaUx=E73%fP)^Kl z2d9DvnS4~(W$)iSe-KYQa_wJ;WFU7DhQ262dfmkcFVYpM?)p@j7^N|C?89fQZPgy< zrmtyzCDV6reqFG5j88`uU=Mv`(B1uh9EhEtiZuhvjS#KdM=e2*a`)Z-*7JSSc0hs? zvZ!`ocy3JAi~CFCFZ>U$|GlT@SehaQKrrsN4t$MUybDlw;d>2%j^}zkfliFz{Q}@5 zKJo7+f1^*271z$-`kh3=JlF>cwCl{^LrDZTj8g)l*SVf^|Lq-RhcY0%$X>qr1~Ude zfPPjBZc|{TJh;+KLJ*D+?)#cm2&=WzuGP$qFh91Pu_^yi!IX~=0)gF=L>=ZSlEh%4 zR*m<+X5^mzA6ai56m{Fa{}Zb$0wQ1Z^ZDcVn{nozamIT#-g{l=d7Q7~I4{?YpMLdz^C%`Z*8TQEY2(2o z8Uc$aNUsLhp}A-b1dzXzPtad?=$;HW0D?5 zocqtAn@2tpOMVB)VMbxlkj!hv9E3e;eN?vTQqcwsOcvuyFa-Jn)G_cX^ zwHY1&50Nisi$ez$1dyfre`khyg(`ZLe#edm;0S}pth%^4TrVDM4d+KLmQ!d-QXv+o zazNKTxW~~U(Ddr(XDSCPO^I~hrShAMO+ct``2>EUIem)!pIFP+ie^2xjTm%uUNqO% zS+kbzTLzqhF)F12f!*h|!JOSv64kW0%d7L5i!x7w|1GVfnSlAAbK?$!NA=*^NVihGN zF|uMXG}Q;N5|4A2Xl(+Y)TfKGL+~@u`>ABrpjXt@Uo9UIo@4jCM)U6*Sx=7KD?l7r z$l!4DuX}(;RII)w-GvsqlYbyyM;n5fG?Nf8Qq##WqRHwk`^ho>$6)H{etRiOp@*H9 z+NGE#Ksx7e57`!8_&T<8k63XEG~m=*OD+#0yJl&=@g=sf;%GUEbuaSh`@`J(Sj+zN zow{aH7gCa_(uGhkeA>ut)%0l&e1C&+g+HU8xIT3qtZ(NFM1$nLb;;-@&eEXkt0RD0 z*Hhf!eGiB=eQ0|k*dHDbI9}Q&3dTlMbpRYOQRF+k{WfU6`l7E4|* z=?E07BICKEjUb1A3IdIOet97h{<7ATgb@<%~WoFEO+j5I5$zxvHNx80MmchkM0_VP0W-* z5$#1h%Bk^jIP)-nz>@*k@xC;HoS3fS-+;#0pna1t*q>yC+yjR|%GLw&8#}B?GFCs* zS6^8WWk?MFi?0+AVBcj1hv5?(nae*(RlyYUiacY5Odg~rgCU5N}O#~>-y6zsG?GND-#%=_j_jU+I@6i-_*sS+P=Dq~I#+!dtzfe%HvM#JYAAudwiJEzQ8>kgG zvYHy7KjKJ7O^z8i`9h0Ytii=qWCUUb2F^J#7V=+=0a(KkUR8@P$P?Hz8Ftu7@lr@K z#dW@NL&mt)eU>a)Y!DsHhWpoNdja}_!B?9dOwEa7s*2Sw9=-t}iteM^O5MN-l(kE* zF+=sjg{<3Im%%k#rzb#(h=V4EBj79K_@UyJ#5nZ%m;ZU-XpX1y)r^{B z{_9V7+k~r%(Z!Y7X=Z6@tE#f<=$OzFaa3Vv=Gm|cLk)mEyDO`lZ`0JuES`YBpxSB` z8!T=)2n7O_2-kpHZ?W&Qc&NgJNnqD#!vvDB<|aWb-tD>wYS3at&4br7;6$7fX>T+R zW~yE}6=cVhPhD21TcNN6FM~ptmGtwI8}cNfjDz(t0u7$quU3|O#vPJ1v$7<-gh$-w zK&Ryg0uj;b@poBmzec`~kfpg7cI1-75|A5M`=(zb@UuEhJ{o*&I==dH$;~)@m?&`*V9nAQ)56euY30@JAps_&y>8jEo!im93kRo*6A3`O0yG zWUdXTbs~BYSGggf*w>_ zl5g;R#0)K(kC&etZk?>)VAzBn8ug{}=9n@^d?MFUyGcliFd#Qp-e-Kn$GIr^zzE$n zq3#aOq9ag&b~L5Qy|CHZZ+PQIY1J(Fk^1g`Y7x-Mk1_n)p@sYd@f@$*Cwa{?x}_`F z<}V!~(#b*MN{b8&{T@ZsHn<4Y95DMAK6qG(9?%Xg|K4SPGrnRv*{-!-OwpiT~ zBHSRz4MC#w6nZKc)gfi{$wl5%AMmKy??iRguE$w<{$1@HEnNIv5`BoMeQ7?giLM_l zT;Ssgm(q4=X(M+B>8qZvk4U#qL8(PVTnyi!(oehfA2baSVy_@e2Q{%F1>k?JovvN` zU1D$cUF`!aZSKg;cOxpIMJ)gpq`JMhcQBW)Lj3-YmO^mNIjaxAJ7O)dGmE^UqN6JS zWAM!ktn6j-0+c)SilG+`N9d42!}4tKI3)yyQ~e6bR%ov7R(Vh*evH<5%mzmm^Jw2E z(>Dn}T|yy|L*@V zc|-$j%oV)ySPsTdoXb>^7DUsYwB`J6f$k0rhwf5d8Ux+nYO>p&uJe*V2IQoj=tGwI zgVlbh<;9GFD#7nJKiA{;;eR(qyIC_OxO=a>!GJq+LGslYr$M8)OXVRO$08_zUjeUt z1T@>^*EYz>^ndg}0f;#v0M2b#KQwWe$>#Fs3|wPcAuUfDNAKCH=BV~0tV396&ATJO z0*$}EP4_C2m|-BHf%N{JFN&LvL%AWd;509G`DjzM4Wa~v;skT%cuKX5|(d+v$L{2Z=LCXKA}3=uoIaq2oce3Pseab zU_dv$4M+($_7V6BXl;Z7t3kklZTkl0RytG&ap_lobR$d^v>vcXEeXFy1kVD`((;2L z&!Quh(YuJf3ZFx(x)rSWZAbyA^&qG(dHSDU4-CGSk;eN{nhS_RE-T_878|6U;k7UD zR04}Y_q?_F7b%^?Yqa@bX!XT%jQ6zD@}*2aaw_qAPwS6wW~C^`gDcNT+9x5EbIYG1r(&TJE=*tz$`cDsC^-HX;f|IXaDB&-8YjZ zfBUv@YsxBXfM~m<>w&fdRDO9Amiu(33 zYE@BGXp8|hEAHI5$J~b)y_evkzNSSjTyfbe1kb$ zZb24JKB*DF^-&=;p?yo{@>JJ?bGcHesZX^9nOM}1UHK~pDdR0;49O5vlb^Z;LsS@7 zcYQ$bI^#+12fFAFrh2_3i)rWF^X)iEjqoUAX^j!U$y>%gM!`(J%+X1B)>ra|&Xw#oQ<3_7lFtM6k| z`9)N`KRn=O-{8W8D+hKyay=Ph2+Zg710%lyboOD3teEb~3`lI((hIZf0Ie-8E<29e zH-I-kJ!y}u^=6VL2xRGvv1A`icWVRb9;@h$UX|;`mah~`sS4S@?||#Hs3=SEWoqf9 zX`SRzwEE)}wB!ydlbE(`F(iv29dzK|YS_RjAapf^VuOS@L2K*hIW?mf`y54vgmw=aoWxTo`Jl4-a3nyZ`@b0enN~SQ0Xg7DZ@27c!F@=nJOx7s- zPEv}$p<5$J7KrnbS-l+XtIvV!!$rV(_lciAH=w)?E#mmdD1sTgnFXvd1kAQ)wd@vA zI2y3Z?4BheIE?f2;1PMvtz`q$=t^i(57E5}Q5WB@&t<-WJe}C@0mbqs#)-sVG{XNv z=HGd_aJOUycp2a!L~;f(LRIi`Aa8|n&7Uub;PUVdIFT%+O|*5SAH8J<3iZ8IN<1l` zTfSZxP{e(ntBcQQ_!4+(SRbOBYz5_6<=HMR18O)HzA5fYHy-gBE1#(7tU58Uktg8- zPm|YHRoS;4aRpfw88m*?lu(;TLW29?0=JYzx-Q27_=#?bFR1PAD{mEN1Y?{8#Hc)V6JHHX{3+GDm zl=SP$hM?7gJ|=C?Tckr(qoZ2y%U&3HB0XODRy3VBYx;p)wZN#is`P#Yau_ANVSE`MI`zGw^sdv^;gb&ib zuHwCI)qQg6{x9z?5QY`zNc-l1rqd)7TOi#OZ7Z06)glf8=O2n}pe;CY&4pGjo(uT2 zU}ev1h2IQM1czBeF*wD_!3}Nzu+=OSe(TKtv;ZGYYED=HdcjBAbs#Z>SB2MEQy=F2 zLZ<}}*9)ZsFwTcWN7g}-z4h}8 zCPkfD=m~Eq$COobD$o%M8zzE-#5z4%fhl5*y@fNs3qcCnS*l*=?W7r=Yq9MF~#8 z?6+%%NQ9W%nZ5gU!+2G|D(p!Xb!SViL7n4xp*n^6w=w{UO7O;^-w2-f5-tL-P^`=e zQ1HbMJD#dP*6>Auz$Z}kH~^D^qh}qcJ-hmECdpf+Hc{yWE>t+K|0>I&5i)zz8}9(9 zyNuQ~NvSC^ZcA=mgn7_)fRJu_z9*yz{uLCHYT5zE-RQOLkF`e&3roTb_X zMJ{NwmM-2CnUd&AQjarz0*aspI$gx)o_wJ zVWiCoQe5{-ndb;llWo)AtS}_pr}fG#-QhP*?+T<~wTbE5CktpiXKH-kS@^v9*M(88 zOQ#5li|$iKP627t*q&poxHIqu)`aQ`_Hn4)VK2J);ngeWU>=g?#@{^ZFGKZ`d2C+_ z@_c8#>xT$Djmaig(SxR?C|l7WJa`DuJQ(|IkNL%lG&$1|I%PmsRmg~AM3%?$p&LAe zepxW{s9dq*eE-$Kb_a#Un7#XOY6-Lr5-;y|w03dD^HWp%u%DmMz0WFVqqFpue`qeg zN19tS3o4!hu_sXe$nsRn?_&rsWW0rq3LZNH3(jRd0G5hlk9f}gXag< z4E6q4N*OeKUU4r{g;rkd7fi#Q@0Xn4Kud&ZL@Y}Sv6xKdoNT0>m1Wu~_@#HnOAJO+ zuvh&eq&>~E=1XxY=}UiG=WyOH<03RqElg{Ndy~8Jq1}~UQOd)T$0eXRyvMdc^jWNu zheYM(1{~+|A}LmbblDkyF>Uo9!cr0hVvI6MFhS8ov8n@Wl*X{?Dy?SQpw`~Sssv?_ zuc@FA1Xfnk;OgFtCiEqtFDF!3w>+TIq#}E7n15-O`$iaL$4;OMSnxeTMy0(4FNzY1 zFaz#PzKXwSQ4(o{W16ms4zdty_Zd4bV(%VTU<+y78L0q|m20rC4{!btmGZTzEdsK; z$tveV?92t`zB_5;EHmEdbsBl>Hj*~k3t_Xb5jV#$>NC}p*l}lwA+auE!Xc86B>K9e z>H&P=Vzz0?t@80TEjFb5_{s!>f+`3Lvxr7G*`H`XU2evNgqKXqaFd529;{?auxxC7 z`z6FC0_{z&A-Z4Jez@cm{CyF)TPaVQdPTCu1`{y@E2Oqm{fzF17pK{b+~&{P=B3h& ziuKE%FZzYtq$?3vRaQ~S8L@4?RumwYKOC4J1Q{36u2!=baeIDp5<{eiO;)iTUeT3$ zeR2%^>KLcAc`|{+I{6?`?fZNK@9m2pFBL6+1EXtsj3O1bG$3ZhZ1SBhJo)t^`7|;l z7t?k{Lix9kc82RZPWGmI12lduDqK^Q;nhY2x@w9e;fJ)RMiEk&>UVbWGE;8ZB*&!Y zA#6By^J(R#CE^~3MtRbK?F)Uoxch40kt@EPX7nBQ2hC2;`nO`O@mbkvZFiYmkk{Io zMco^0Jl-dPl!(S*&b>%AY;<^D@7_&H_&S7N;bVq+GlP4{_3_aWkOdV!Pk4)Jj32A% z`s$qMDT}eL&0|V?E3JNkx|GSP>&Yjp3$5nD=3U}3v6-e0(^|FBWG|-Ynj!`3_&;j` z&7c#881LyY;p-|RQW4$3P@t*G1!OyIX~*>m#rbPirIv{phc^WhJ`lnz!fjzD;aUgD zU<}NOTS63yZJBSY!qv~1*~;&e@zBod;`z>GRX2i^GiFr|K8SK>>B;}0M0Nrx&Nb`R zX~JN-UnJM1m?K&pkSSQMyr3j1w_vgN`|y--Tc{0pKRZ{Gp=av`?1si~{w*axwV?WL zlT;RYtjmMbCsz8gt5{(cH!(K*L+GW*?Ih%>m3S+#$t3{e;`|AYPRK{v7t!1 zPrHn_xvybJVrD|pLz@S)g3BdGly_ChyG5F`b>QfGhRapEYCJm3w9&q3aL)>a4HcU? zv>s>oK6tdYo4~Txuc5z~8f@JuxV#%;-8Ii4&pPiW^bwxBBKN5!TpLUSvYh+oZ|z_3 z0Dp#FQpzrC5C$I5Vg9hkE9TFICd)q$UN+CzcJ}VxxJseg@|G8Elbjb}$3F3sTTqq- z-oB>&EOXL$e1;U$1d0-I%fv{xk%NF0uh8fRJHwvM-!8~qwr@0NBrBaa)wi$&bT8rB z(XjVW=JSJKdw9|f-J=$y8o^apkGjMO7-^UmX(#qxN7beZAWG9_h>%xRbUyN`(yM5d)nK>ebzh1=H zOHcCE^$dMoXY}mphbDzav@qx z1UCTvo}_?^Qc$+w1w4#!iOSF|UXBk(9M|<`S-~Q03F3P^Jf|b6OR(EAIGTzx>`Az} z#L%s)#Qlt)-T}XOTtLPi8i}q>GN=sUa;$? ziRR|mWFZFb5r^Di*S*abtdeUTO8(@5MFO{Je)lm zD3pU=lV}}&ljsK{u0uBVU!RaxNemoLi;Igxy=`vBAV*-zo##0cbikDC-G+06}Do9)8u@DNM4B% zH>TcU$i@v=s3Y`TDI|goRJiBT@o^wQ09rQwCA+5lY7+U)mDQdaik`5)1ePZJt-FF` zVjX@df-^MI{`KYxfn~HKL$80+j=Yc^9AH%_-hE;0iR7XDiI%3E8ggBe{A<_JpPlyD zI2<**pRYpUv%inmO-x&Lkts;fD;sqV54jl1&0^zmxy76?32X2wGd;w3Rjbf{vIRY- zSmBw^VPNI?PKHB?fp#Uod2`L|H{$HK$|T?l)>FV@%2ZRjiQYG82~IsG!xfuTFJ`lp z?H9Lz>EHZmQ{wH#^v8FXsZ`1|%Wa3rMu$ELg$iOh5m->->r5tJyi-COre3XGeZ#5O zW^h=D1nu_eY zg6LYN>jZm(kWIxYG9e|JdBUfrrv*A~6e>NASSD!w>(Bg9!hVV590!C$Vvvm;na!n*!Sck**9u0eSv>$Bh zN5JNL?SkcWmH?(98Ds%lwg8y3+45Y5*x?*==D1C%=^0P=##L5a}YI(J;75s7!kp7C?L${(y%47L_}f4$h2ubg?aj{I^UlDO{?_| z9g2FLo+6B65IF60X?$(%NARfO?7)pXsM#6%lWl1(1kJ9 zwzvF=OBD$tyh({Z*(W`^sZ?~Q7*5i|igSZtZJ+qg{pkWV2k!fy3$G)dw;o{P&jaQw zEz9C4E5@ir=&hT4f7J0dPrL%kKe~YYGc}Nz$}1{{=WYLGCvaW6=oY}U z;|FIxp}@VI;Ff+8Y`Vpq5W#f8an$>b)j41&CfpWzt_5sed|xq_z2`zedvHc|NW8=5 zmKT1o#DwRCo2QrKZn+5Qsc<5H*ss{&nI`D z)3L)FG;XtwDNn`bqA9VjxRrvXPMc(9ytT@grPIAfTp9AH^Jwy@9T+`EmE|uy-|Jz% zvJ54qTKD=sKQOClIga4RWACjF=_MbDFjz=C^VgNJa+H;z&0%{((>%>-2TGcq<~l=j zl2!{sefMmsV=9@0OXaXPHL!UX$pSYmMuv2+5x&3`r^IRvZP-Tt2_)V>DicyKGN_hIcBW)Ao0=vX#pfeVk%3Y7_KF0o5bt2Pm^24R5nfU z;f9C@dZWm91W5*e;wtzYat%kG3TxPq9mA{NosTKyaE=m;sRZ?OCrZ1<3vlMhe(i9H zch5|UuWYPskMw*(Y}+WAyj&B3=?K_W{idekJJlt1M)a-a;OhtCg2LO#l|m=jlq!|v z3)BevfsV+&r1g?5ivx%E>Ja&a6^0S}GDusdcrbA4EY*lito`i!X&e#NxkKeyA2AWH zt<@tv!SF7e-8%H=Dq|#7J4ljQjwg)6y1jJbvSyiCd@ETMCJ-%K_^7kQX@2TxScPsj zajWGsNnd`xd9g}7afx0PzVNFt*XibfAQRFoh*BWMMq5%zR))WcekoKA??44G8|Hho zl2C_(S_k9Rht;+4Qk%C!a5CK~5cXCc*_Gl4Z$uTCks~)a$W7rx#V@*N z?u5L3APBd768yKMIIXLg{?IjCG2B%{7vE-_KSYTv;#8EH1s!~k!SpVVOq;Zi*n5xe zv25(UYTMC^@0tNwg4*F)LW}Tg_{1L?GNZY#C&7zG{bw)Odxk5?x~X;9xex=x1uR2? zdrHohpY$)9TL?|leDBfl(5a75@;wzHk5?G&vF8CfQk>w*Zp`eR~p-S9Xc^z0}LK>?Xi1!LC&0waP?x_C5ViY_t=TCeu`R0PEbXgN9aXB-B z3$ZN`AjA=$q>E~-Gx3Zw(mz=(V?%I8jDs$7fzlDXR`(wZ&!PGUGtFw7+ME!ydQ1DB zn1iHdIs|=WZ+X^07%iLCIQ@5cH8yGyinI~DD%Lh9r>PP#Mxws4lrR6F`_T~Cu}n7R z!AAx*{4pQxwLf&2YeXLX8TBZ6^^>$n$ZKQ7VZ3OtXuP1;+wXL>u-0SiWl_Q7a4@Dk zBWa$W6_qdj0XVD9tbBQBse=UMADf(e zsdn<;11~Rv&I4lIHdj>X(VD&5#=N=M?9SV>`5L9REZfX74hyQ2w7m*`sxiwPQ&?(C ze7LKb4|5CJ$C3|hSVAt6RcNu3y!x1U9Tudw3k`YcT#R4#D2P?Z3)!@b6*(lg2Mmb4 zjThz3^3weJC(bXEjF@3pZ`g6FJzz@ZT2&!!?8n2k?Xi9_OXqkYV+pY$LU3mX98_8a zOD6XR>Xb{`se$=b)6J!_Ewm=lW2^f1YMUHVl=?Zt;4JG*o(C#x7QDFjjo@37#Rm`q_Wr zb;bb5Nx*=Vd(oHI-d${Z{FU5gmwUS0(&_Uw1qsRG0rSTy$9RIwng#6CNe}dFlhBO1 zrH(KO{1#53dXDAnw_ke%3v~892{)gAc}~@z*iKR8zy%D^+R|TJs2@^Whu!3<{k!GW z`L&Dy+{b&&z`#m;ay>^wwKfW2__2hjNW9mv#avQ-U1@a44bSb7T@&wst*7HO#q68E z%AEFb)oGtRANll&f4j&q6Pe}vf}a_@DF72=+-iCP2^@MsWcZb&*bht$mx(Uv^~4g} zp78mzN;<-=1wIE1{T3Eg`NE~JP`I0Z2_sG~M*`Q2+c8m`cI}ZOm6KJ|2ER&Q==Hv} z?z(4keZ?Yd*>^mi*ZvQHvTb)V>qVoX0|9XW+jB-bBbVzy1Zi5^H6;}ArfEnk=E}N~ zQzf3@i*usUa?cEKhDJ=HbQZBuCfm#-dm;I1mPi@T#3qnJU#;=v+x8uJ8m=9kgC1CL9VL7`_;|bOH zSGR}f3t^r|n_o09sY4H5>-n1${VJK>sNNu=LDm#y>zmk2;_hx4Lfi`Y)AkO_;Fhwo zGWGP#;`gX5@(KJr#ptI2-wKkk$=Oy+`(*&Roj?b<7V?WOyjs#Ht_=;xn(0UT`jRl)3sUlWE`cnO@74PYWd*X{|}=tg2U}*Vjx{Rb#V6jJG1{? zmpBC|d^h{)b%B?)`FRT%!s-E*Cf0=wi8cGfo55!2aHZEAm=@#Q@YJ=szQFfvHYdeG zV4@E!USN5WGG@2b2HM-I(zBE8WwFlV4?TfHAxdF?dke~q>~Vh{B*w=&UwHS`hMP^3 z31QSzxcMcED%tu0mu6<5Q>@GX1q_~EDv0(>MA%l{>Vq% z(rXR9L9~cE2UTIM5UC6)(k@@+z4dNr=nQ!w)9c~NS}`T`M>3nF|u z4GNVDQ7v?r@3)r=r|qv^e4o(1H*@P1;H-D>+(6)G*W4NyZ#=Y;BBm8xm}-q@6wHB! z?dK#OiD!rq3ljLXqW$3b_aLM5^?c;`H!q$qI(fR8S|Go)O-6RY25hSB)~`m{I5pL@ zdHz1ZIB{voLwdr$m`N0A%Lbz+6l5q`pCIC7%%Piq&zj4)8USE}!d+<)yRqm`IeG%7 zs8bNHw|~jV(c43SiJ`5b#DR{Z=*Xc_xbs{JJ9ucr?~*hrzlR2MzdwOdIA< z55Nicl;vQd5EqpjAk^zbDP!!NK9DwQ?WQ7BtKLtp6=)UI2O#n($h!?_gvzKWxIu&a zr;Kfj@x)1W^fcFrHItt9igxKWGeQy;`jHK^6cq-JpKO-9YHIhFojfredM)1pEn%In z%u|=)m~JBFH&C^{PAL&+`06i~qWFJoCU7~N>|kR+Bu$L7xG$Sf_M<`m(y%jo&qO5{ z18Kz|Z)SGDf5Ha~)l=65gmXPG%sT6s^oF5yK~E)k5pDQ^S`s_e^PHJ;Krj-;Xrng) zgl-DF=I;Fu!QOOh-Pk9{P&kYWU`(xN7EgvAfS$uVr__$%rIQuOixiFL0{~cUV0aMj z8n{j$bm0Q6gNwUFgDg5H5X-_Js4+Pn%FqRD?yO%7*+@g2nG>d(4ShEzUkeA!HBLjN zD~ROT7gfp;>O zI0A@_n*iAHHblH?j1y2ium`iKO7QAMw|;{IuPKOSs1ASWLTl-!nvr2^*LX=;mk$O#SUE zsHt_G9hgY|_3R#rU-lS&RkBSdI3S&X{i+rU<#Sy_+lmH4zJ^ROQkhq1@h4h8QPB?f3>y{CZ*p}iMWOjmzJgb!BsHt$k9^%m~H*t+^ zFnv_10REY3aGT+6=c_fC;?C)t&f*1`LQn|c{@Alb=ZucrJ1_7!s8A(>TT$Kp0QhY1 zki#RUuLg-%!$4$%Qf5d8miI?NfZOYq2nzCwNQP3|!!-~0>;=0qPLD_Y>Zy)`w0(=Z zjuYi46*vl`50tcAsR40GB85RVBA^< zU`p{Sx9VR|1X`Y^%H9JIYZ!DO-Usa>0l@&@nO4ki4f_5CQ6@uaE#JX5o-404Nd?&= z4ax5e;_f|=d&F*}Ao?9pF!vI}%|$bN;;0|?QBJ4ad)fuKT+?JhkIjF~U2_5U*QNgl z1cprj^m(&3+>HptIl`F0Z$a)vN9$LC%(b{Z3rCqp@0?F1GRsHV(JQcl7sQjAzjZOrCtwy=E*Ez5s}Oe~E0K#RTNl$l;FD&h!d-+`ybW`}@EFS20`%lU z&Jg|j!PA?|PY)7uc*buM)7z7=Yw%^#k`2PJR!LN~jWUyvLSwxnnj=i>*8P!1T9GjD z_L=rkOTv{sdOkd7f303S2lmHNbTy^*`~;u)f)xiaFtN3NVHb>Vx~z%@Q!D;V=LHa^ z>1H$HvefEnS3Id!AgTo3M*(ig;Q*J7(Kq8&*k2|EYF$9#5Jtv_D3$3|wacjLS;SGt zRmp{spI;k$-I%*Q?dGBJ?`gm&ioZ|V9%)Y%06hB9!rU?H&76y^Sj`vd$$f_;n9{Q{BaH+=f!5k-W3?=^OO ze6sxy)bhEP>b1quOJPZ+`fNB>VlXCmIJbU)@OPmj@lRy5ZBT?^S3`zf zS=0EXDwMeQ+K0qXTfiW?R~vZB7Zbw%ZjcTnF@N@BPH2X?uKm$dRMh+4m7Dk@dv*?g zn@v5Ns_5vWfG5}y6VMChgYa}b8-e@;{y_YR3Mc_H>YEBYekUdd0fyR%3>&-3nSR?%d2^)k>r1ivR{z_d zOTatb4z{^Dn9~vK9|H1srevS#@a_vkQ?FT%)MHzw;q{()-yXLMjEI=?I8Bqy<#c#uo-zR{muj+DIyJU<`U5VolZg&4< zg1^>>uwAZJ!oKhJ+YHZ-KH!tDQ$7%T<}g*=3t40#UQ-HKkq1Us0hhK~3X<9$`+*Y2 zi2wIPF~1{w3}2~YH0c8^2Iws-ONns?{!!+?4-R4qx=9uf4K7C=zsx%zxA*OaR0gm3CwVL~gfxCm z$`fIOCl8o<&6MiCvqmhm(sesSip)_0Ye~3U4<~S}lGXnisml7dSlHeu+M?D!YN7vc zt+1pqpCLr$#QVK*tk&_8i!T~-{k~O@wN+$<$$4)nJG5NRsR&jR`3sWyV{L? zOjJ@fEUuqK3-J^;u)FgmHT!G3nFHpYg9V|!o~kQ-xus00&u9sKBS z$QVLajx2*$#ki`m^X=`g1F@R)98UK32U>wwr`FdJA3l;vQ`rFwZW)a8Wcme@UdXQ% zq>FoerW18;0o;|f?mH{@63Aij#SGZ`ZoUi`2Q?x?)%HY{HF2Z{ajcB6pDHNaDun+<}nF4BHLZWLgrbM!XvetHfd&21|| zKM?p;%#Vo-60GpxiZ^!T!@53k3(3olT(o z`l}%AZq_q{U-%wK<1H*=mcwaK$ok9h?TEILL-|3B1DyKLL=3AIh<|?tQBPon zQZJ$z3fihGq@MoFAJ&c51|<+T2p}C8Ytqh2?i2V5SJdL{WG2jm3O>8+>W5;=TMINJ@zTd1MJ;^;`DfXp^*It zmneSonZH5T=P$4Q91A3fFJ%1&6mcBHzy>w@U!_JBb$}0`VBrhoA|u-wdQ=Be=7sw~BBdj@0>mZ9WB@#Ci$MM!$TCwF zRXQJd`%k#yl!AdtL|2A82y;R*Up8Xy?;PiCa^o{vS^By7cqEwo;O%bY3$dCm#T5O$!ZIR;KH%E2T*RCN33vxE-3 zsY6MhgN|FB{zZ)|oGg!}U8OAh?i|mETHnK-=g%GmzPp{|WYou}ya%MVjdn{5uIocg z@5zWj%Wpd{oIL8-tiVlm1xP(Z`sTq*D4`Va!=1JbF#Pq6P=1Gqi?i-|$Rs-9wp&`= z{qj^?DT4n?dpz?N%gOQzaTLx8|4P66a-0aY9jmTE+i$R$@{qxi3p6Vh3OJao7efu6 zO?~*AyiH>h%*=iI1DP%*?&HOiiwwFv2gLMU4J^O(B5tXqG_G@j@|c~{r-G%J*Qi10 zOL~DXIJ-es!zR&v9JrlO6pOrQH!v=vZ9jn~6q8~&2ORgWTcll<6pI`b8I^PtY`B35 znu+l(o+&=|1)%3$zyF1Q)YW#0ci92W&$jUQ4+l^zJ&w4%#NRBi9eb@rQ<+f-@j=sA zb~HNJ7}#%%NV;U6=6(`Vm*aZ&+2Ufk5quJ_ht_H$Dh|Oes#h$^v3%UHat%xSOYot- zW$T4>1TTi9Aa25$h--5oWBfN&IwFYq!YL?L?9k@y0HAT-L`R0aV5S)i zG~g5a11_#9V8xFXIBPAyyV&5Jzj4-m9ADU`%bApbc~WijSZkCG6crS)wpM%R)M35ODf5{2%8=+oahv;(%uA!4F!;?$}@F2(!7KVJfs zjtDEKLjsKGd-KK^_B*CYjiMNNo0%%>cqYbYM+6f9hy_xCo7J(>n>!UiQYcz23YZI+ z(!4Ze>2cYqxzUdW)0&e2fhdKbV4(iX0?TovlfYR6?EwYXowhJ>cy)BMp>yjE@R-q| z5I7)jdWRd=yPIhtzfj5Vb{WtzrXgZJ+@Md{+p-P!hlm5Tlj)s(lkeZyS{4pQV#fNp zHH?b5#f_eH%`I@CRx_*f|ZG+90PmZXfXKr|qqQiyb$_O(=c ztd}B=bd1eHqVWN7lueWF-p7a()?t{xYeCm_vl^R6DpW#0XoY@r$*+z297rdq;s=Zq z?Kc8};P2`(hnGTlvSHT!1zh62N~6T+tBOCt_}d{o^9tEy(VX$M%qMPH^l~`9zB(G_ zRI^TBEW-T8%1>D`pm_qTF13|3ddlRgjUtklUd9S&tIa&XO0jDCIzdJ@&>8h(DU*t! zT8ngmjv10YI#`0qzW!J0ocdBG{1Cn9hC!acnyBB`rV)3K9{nuycMQjT+qcnd>%hDNN`MlX~33&k4%E--ju3P5!@HP0DlxKw;_Z> zYW_^<9dFa0w-ufgt#CU|m~6Q72$QIf4=0U-2o55&F7;+B1&@Thz$)`c7vj7(_*grS z$+5S^)&?`53V+zQc}XR~V#1>1T0jVU;3VIozFTuc(4%_2gC#*=G8i%FAs^xkPW+Y3 zj0)I0A@~&Sr$}L@-~kkWJ3^m?`BOenj|cj&OsC2ItoxZ56)3d;KUx`6_!IVR4w)&# zlqzN&=Dj3hB=AZ#wUWf>XJh*`VhIi;(tzDkFw<;~=P(G)`S$LP8@ooMC(DdLVy_oY zoU|oVey*Czw5EYk2)_SbF{1Hn#Ikrc&2u=syJMej;XHg)Sa;YH=AO+X@iY(BffKsR zK2J8)7H~kSI_Qd#iuV!UwP>y;K<1KZcQ&8WctsRc$xcoOIqAI*x?z2#i|wCHxE zJHCsG>Bf_STWUlh#&l)nZf{o9`M7Sgd!L{m?JLEB0N&DzQ&RKi9lzPOyif8LBNG|! zHbdD;o?6SQIVP=d?m*5$EF2)#yWU;}J~5kk$tR=0)Jf|6>-XN`vat2QP0VGJ$CjF~ z6}m2vNcPN$O3-V^@S3&d5lD{(f?bfS$;VM+V7{E$BaPjVs9Hh)Hdne+l-Pg>ac2(} zUoJJs}FXbMcn4O~<5wONc|B45~VRmR{1k91797F~W8SaeyfP=DuMT zJAE&;P#=C&jo*4Vk3ukLX(5lNHrm~=nP;h298Hux+RM!p+R|+?Uy_^HS4aAZtbMB~?#yFJV1djvD=Zp;` z-F#AXnSzgY=jVq8m<INm#7XsGk=X%ly&U?Z-pM5@|!g&5kgd zyq_?y%m7;n`vYL6n*}+INl9h{$Jj(-R;MeS9a%LqD}{tpeO1c!N}h5GNI?W?6`x#B`r)m+_v`Wf*|}^aY@Hjr54#$$Leh3`Idqxf@IaTq%-dU~ zB#mE{O*ovuC4!y((C*~%n@8?2T`8z?JZkAnrdkjhs?|&&TI>ZH$=}R zEBoy+scMk{TV{_>{IPw^&6A|%PUPTizeVzre(4NpHTRC7a>#@ zE@kzFvOu-HCym^TpA@6k85z1c;=Drbz!Um#qkKXB@$2$9XH^E(CS zX_rqx%2%tP(Fv-oLdInok`+8Xev zh{ovKn+jakR!iX~03}u{$?AtK3s$j5CvDhNLCEdw2C116V&o}u z#HtkkPmZq`hx2yY=OmfD7BBL_(*n$?pxDalB2{b5?(HNA$*}M~RfkO2pRu?7EB^i! zRA9%$03lfrIz;fHf9vT|zNYn2Ovo#Ck;gxyfhnFJ_&Hr^(*Jz?m~wP=?(jRs;J$vV zx3nMvJ@0E5G3!1GyKb@0X8KoCn*0akS8vyT#*hu)a$N90@%QSjgeTD5Z;j&;$fZroub`@ZpLUudhDB>`VxmAB5j$jK{v*64 zihP{lM4g#FByq2gtE_%|Fsgl@L!K>^=(Klh*1BJC2|*rRL|fYAf06C>BjCV$Bl>XU zE%6U2pGH2{71cV8H+~(7sVt|WBg$n`aCC>CrQffaqClJ}=Wwg8NgGcRjZbc1Q-ZRO zac-7z)}J&lGM8j+Kd~a7WI9x;ci$eenz%KoVNoS*g^3sNkz;b=Bi_HNbG%2M;(3fd z2S|rD0P5tD#Z~`bU0(tYb@#rHrmxXvq*6pvvbLy1Oh!`_%GM^?B74ZbM9D;|S6Q;J zsib5HW63TmEfQI>WEaLR*|*lGxDxd&}`eLa4M_HPt|RYVX=p^-YMt$RTp|jdWPDB?ig~xKf~_Y?I344WYQN zjJ=^~a=8fBvLgj!1+O%}D@!hND#Qu6g%S$VL$K4=rS*j#atH=G1?^&kb7nmq4aJ0y zUZJAa(1CNOXENAJJjh?iebgSAecG`twpq*ek(7>e+YA4vKvEG^`LTUv+ZGupBvU*p z_Xlqjuf^|rcZVpaSLTCZ(^V?O`^BNrB497fQ*W-D6JfT~_G|NX+D`?mP$11R+fOHlUqN^MTW$?;5>k?=&1xJo_6f z`Ryq#&`%O$RZ~b%ta&2J-ckK2jIHKa%kOC0t}>l8Z*)BC`xpbBf}v8Fmbqnq-H%w6 zf-evkTUEU4y6!VLeow1-T9B@m*fg@baS6dwxHF}z^o73gosXQ9&Y4&}hmtWhEq`34 zTunmjR)2+45zV?yC^fjlc+Ykbo!pXC<;ZkbbDtt-LTTT`+T*>-TLPXhEccID~W$|-^x@{8D2@o{b@U(FndXp^lD7|@ja@dtsz%``4WKjP~ z5?}OlPmN8TdJoom^QpU&^;wMU_c@j@Vt9Bd$)+!Xi3-ofE~q`VySFLN^Af|LF4|*i zq<>QP-a2n`RBE^R*Rc-&)c}^T7B?xstXbe1?ARN?yUrMRao4UTa9TxB_u-~G{8jGT zdte(967@48nn^+9kWN$r@jTs-C;M#&5}y^H5}^!*#GwdUNQ=Rlk${sM0hI%~T=LPR zxm>lenYOr9T@g3buw&{<$|6j{0uqP=v#jf(N&LR;di(yd-6aw-+UXZIN3z73%QcnEd3=Cj_NBUOmkPe zj+8%aKj=BCGts8ImXk7&AX4llJRFkE8^W9X74{m=;{z5F7H`rXq#FQ(+@YG)PZUae zue{R9yWg*FHBcm}Y=~>ibGAqR_`*w`ozYMkg`46q!GU!{Iv?_{O9<+UNdNE2n#+__ zrI(s0`qsuy+BaA~DjY5rp9exC`U0=JO1E5y&%fHJEEC?8+^PY}BVz^HOh?4Yu|DoK%^?Sk*><-_xSbV@GM{QH%skzoW znGNo&HOU7ISG}W7!fAr}`}_8rwn!F>c&MNZsOgnG#n#_2I(Ro;-KSzmXK;opP!H1W zh6(45Ew#3mL=y#AHEg^?GAZpV%Wgb*@}v*RS{&?kBA1jfGf7cvQy=olMA;JB)~^Ow zjLYTB4I=a)8SW(}HMtRzrE#trFW=kwk9M01$y|d|Em=H;rA0RB?DJjb^=TPpSz48` z9GXqJlI;h9;o^uzcR63piwgDL%C55@;9%kK%OGNB3WtP&X-z^X>S9*-3(2}i5vt&a zgT+LTZX>}O)G5*+x7Sm^I@F@$j8AX$wwC?GRUNWyGVim_vF}yu(%$?vQ4!-* zl>d2XklAQBq-GpAO{C{%Y=h^TH3^FV14PR51oJR^J0nqukPS!UXll^I)J7%VoX(o_VE{NVcH|nqzmAf{_jPZ_6;vn zC@XmyE9@wPLehsnoPm=z{rIi9Z}sm1St?(#yHptz`RxYKL2%s<@mR5P(@srF5q2=&vzY@^U3&g&Wn9@VjKC^%8`lN4NGw; zgsu4b_0eah`Pr#nX)duVStyR@JQ`*RQe4#{vH}Te#yMgh{V=g}9=irA3-=Qn>H)ri z9YkDOl`-umBftu5e@n7{95`{fnwq%|nm}ijYxg$F16?Jul69Ai=NfC%igFc@84D~4 zy6P0<$ntw(=+o*MhsVt@ISUh>A)P&VJyvM>cIxZc>YVgQH7J6Hbm5kCoryUvSEBC2 zvrU6y#2!(ee`9)1!jws*Jb=;}v8RRy7-)<;%cgz-N17zNBc>m5@g18+tXh2!ttW=` zAfw9X!RGx%xWeHL+tfQFByA%cq9hJd6VAVa(a7S4c6bgJvz$omQ>4kN36SF{{tL#%DFVr#6#-@cEPE@ha9 z2JY3aS3g^}>8cLTpgd=33-Ik+MKnPpJU+oriVYllwM^WZSskJ}6nu=ZVp`_p#>rx$kHm2{TLDpVnhtg zhag*519Z6AQ4ZMSa&hT2)wLl-RZ)J14<184ro=7?IJQUA2Ljki0aOjfKeBlC+sM0 z>-0fKWvvKVMh^4uAewimYj_rkN5T9yG17Qd!Y_v!8;&T%-%pLAI9qw)&Ea<(8P_Lm zdZ`?R6)}{iNc#b&n_bR8^fI6Wl0FfT#_Ldz@CTt$4Z z^2K3xHOZhHTLtmf{ra9_=C$RZ25F-|EsmK3l%WRbF-P)CC$B?^81#XOhozQ$&~7i& zNB(FJsOOuLgzODN?{;#tcEhg7AA*Y)ZJ zJOZZ+j|1%QemeD4{?yBKV0&AjD#@99&tWXsYW$TM0P8B8 z$CC^<3UBaoZ|$yNcl|PPB4>V15+Nd7dJ{Kh=$DYu^oc7&bU-e^UOXE%;nEjwnZLg# ziPskxvx-AADQbDZQ#tobV{^U3)(e>7Nj6Xe`ZDmjwmb#Q6`cgPL=C8ein<6 zk;>uHmQDRAO=0aG7hS4=azxrYuS|6~`$|;sA0GSl`IH4fBgqPF5fp8%s3x}ZK~RE2 zYKo$kNLS4Qc!RCKA2cxtWwsDM;`If+xdw|GX26V^xe_Wlx8^*6l3YQu%htJ;HS;-2p!mb`M}=@%*Wnq6hp2~NYJZB>OefL2S$(6o#+_XF-} zaQ4Q=o8{VLDsI!q7$}GZld@NLUsyX)%M+INX|C2$BFjRRuy8}NFW&bC*EKYGnthLt zh@Sg)>cO5JPZEGR$!mqdmoRRi!QNq3Yn5;~=~BTiTDtP$*e#@DV{+W`ZRgp-^KHV3 z#OdkE>cr{ArX4!MwB5>6)wR+7nFZt_0H0fC!|eDa3%-*Z?pOYDXZDd)at6p(qIQmu zr`&`D3jmCkI>kMlydz^{ynyrUy1{dFyL_-=qBgn#vZF!U@w~mpD8RRRN?Z4Pu_kmu z50iekTY4z}59Pfq-WNUce)lj=J^KPr@@V%G2LGYkS7Wt2XQAT9KVXgR_mjJ#G5PDb z)+H{Gv9$Sla{NN#E=`2`p}kt=NKZY7Tw;6t7R*W7#0DUAhyI16$G*hOFc4llfAV?I zi_P@rBlnSj+}gqE)1vkT=w-e*^UMQSwl9Y2SiTfK$G`NS(RcvX3i7yf(x1Kc6p09m z!HYW)9+(>S%QsN>MjGVk3t~KX*Mp&9aeCIIdo-DSx0lGG{L_-Wtn&>mF z7E?C;Vg^8wtIA)8oH1Po-R6u8lzZic&;p6+ zVwJ(+;AX4_A!b}GsuR`yeCE=CMj!C@m;g}Uz{kU?_Eq@TOPUlh{idnBjH4If*X5$h z^j3vBKR!X~-$+*FhYANgimKoHr~9EN^9{wE3&t7+*6y7L{NGV)Aon1iLuRh=w_y zCE-#*lNeC#tqS73;~LAohK>t|2P28&qx~+4JAF7>eO&AWMz$plBgHriYlmN0F^YQFrZtZJ7*hkB5;D7_L7FTcg((8jP3}aEYjF*tM!5^LfjFnM^WXyeSX8nE{xp?htJ5%Gb zve{F6v)+crpahw+(#FapUMt>QAXBVP%I*=)?A+SA)z(SzhxPh9l2S|rjcXn@r49Ri zj34A=>O>M25)tWR<-i>nMWw9?8Zc-eSl7^D#4Q>5PG(w$m1qFD4ry$>CvZO%YuU2v zoY(4c8($460=#?R)x+X7k9oCto!S-mS~lfoz!HXd^0@)lgkbzJ$K#a+f!s8OpZm+< z-fG01X9fa0t#;n&14(C=4JDWzIMJfvsj(3zXp9KC#bgVAH{x4*pqDoZUDq4{ok60; z${ZZ*?D`>@wq(_Q)6YO^Xe{By8#QfG%*stLfK09wlm@~wft@jbh45;e8urIv*K}X3 z+oa*6CY*j4&qW<}ysDo_0J4f@Q_#||f-ma=Ne8AMyyqGjfxcVIv_kXI>9-vp{riCv zwzDeAsf{Hw2jelUGX-u8449iJN8ryW zz%ee)$+Q*&pNO~wNym|KJ78k);0X$&Z8ULOm@1%opbsK>6&OL4{;{9v&c|=aRHT_7 z-cz?gpR4O5$LG+B-Z8|=cw=eR!*Ic`Z^mS+coxgUGBfooi0`4P0aSAVjkW)P;nKZ6 zTwwxSDy{G$KWJO4>o0r!=?fuA11tE7?jW&1$ro>F2QJ;q;1W|$*5a=_k&{!TwP9IH zJqF)v)50@hFTw-Kj8(+7E>;;#={t!zN0T}Oj6Y0P*5>C^>9<8S{e%?+>2w%kW^gTK zwEaTYpG6dZm`(K(`V;>ec}N3YPiy}2kXA9KFX**>lZQ%iG79G`D;P?ooiX6%kcTuc zs>b@KU?{T14r2!f!DCTQ>8(4_{7as~f&rb_RR_UZfEQl)wi0H1cbBvq%$y>)e3!e}g-(!WS@@74 zsitv=3+}HM$oEwR*`c&EZR?l&{`95Ah9>{s;oJDh&n>Dk>h+?w%JKpj$kD68_Zskf zarCcJ7yjq53jQY%TFA!e6W!}x{!dh8{Bb7d?C(iTf7y{fMQ7|6Y6SHuT2d&S!*a=a2OAXkGOi+A(mp7#gWnFL8J;JrJ%5we0wa($&EL z<^Q->crWNPU)z{{iI7(E-`gsKvob}+QeB7GRagJ}XZ#w}vhH_Y>^0cU82B#-7#y9W zsAW~vxOezUFg7j;>(K`rl$>20&B}(oz|<4`ua5HqWrGN-ob2B~*4-H`zPvj_CyGI% zn(BFGC43)qh%u0M;7)(wx_gE5D;OB&=il8ZFJxd~_#c{zRxor*TAF`I9QKB97!-~x K%O)Muz4d=H;*$6P diff --git a/test/image/mocks/text_on_shapes_basic.json b/test/image/mocks/text_on_shapes_basic.json index f65a7e6f4bb..b7ae146522d 100644 --- a/test/image/mocks/text_on_shapes_basic.json +++ b/test/image/mocks/text_on_shapes_basic.json @@ -154,6 +154,22 @@ "y0": 0.2, "y1": 0.0, "line": { "color": "#339", "width": 3 } + }, + { + "label": { "text": "Circle" }, + "showlegend": true, + "legendgroup": "g1", + "type": "circle", + "x0": -25, + "x1": 25, + "xanchor": 1, + "xref": "x", + "xsizemode": "pixel", + "y0": 25, + "y1": 75, + "yanchor": 1, + "yref": "paper", + "ysizemode": "pixel" } ], "newshape": {