From 28a771b0734c22894d1c01ed90b2731bf6250449 Mon Sep 17 00:00:00 2001 From: Marco Pasqualetti Date: Wed, 17 Nov 2021 19:00:27 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20Quoted=20=E2=80=93=20clone=20throw=20an?= =?UTF-8?q?=20error=20(#141)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add missing `quoted.test.js` file (fixtures were already present) --- lib/nodes/Quoted.js | 9 +- test/quoted.test.js | 57 ++ test/snapshots/quoted.test.js.md | 1445 ++++++++++++++++++++++++++++ test/snapshots/quoted.test.js.snap | Bin 0 -> 2692 bytes 4 files changed, 1509 insertions(+), 2 deletions(-) create mode 100644 test/quoted.test.js create mode 100644 test/snapshots/quoted.test.js.md create mode 100644 test/snapshots/quoted.test.js.snap diff --git a/lib/nodes/Quoted.js b/lib/nodes/Quoted.js index dbee524..f2a42c2 100644 --- a/lib/nodes/Quoted.js +++ b/lib/nodes/Quoted.js @@ -18,8 +18,13 @@ class Quoted extends Node { constructor(options) { super(options); this.type = 'quoted'; - this.contents = unquote(options.value); - [this.quote] = options.value; + /** + * When cloning the node via {@link Node.clone()} there are no constructor params + */ + if (options && options.value) { + this.contents = unquote(options.value); + [this.quote] = options.value; + } } static fromTokens(tokens, parser) { diff --git a/test/quoted.test.js b/test/quoted.test.js new file mode 100644 index 0000000..1dc810a --- /dev/null +++ b/test/quoted.test.js @@ -0,0 +1,57 @@ +/* + Copyright © 2018 Andrew Powell + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of this Source Code Form. +*/ +const test = require('ava'); + +const { nodeToString, parse } = require('../lib'); + +const { snapshot, throws } = require('./fixtures/quoted'); + +for (const fixture of snapshot) { + test(fixture, (t) => { + const root = parse(fixture); + const nodes = root.nodes.map((node) => { + delete node.parent; // eslint-disable-line no-param-reassign + return node; + }); + const string = nodeToString(root); + + t.is(string, fixture); + t.is(fixture, root.toString()); + t.snapshot(root.first.toString()); + t.snapshot(string); + t.snapshot(nodes); + + root.clone(); + }); + + test(`${fixture} be should cloned`, (t) => { + const root = parse(fixture); + const nodes = root.nodes.map((node) => { + delete node.parent; // eslint-disable-line no-param-reassign + return node; + }); + const string = nodeToString(root); + + const cloned = root.clone(); + + t.is(string, fixture); + t.is(fixture, root.toString()); + t.snapshot(cloned.first.toString()); + t.snapshot(string); + t.snapshot(nodes); + }); +} + +for (const fixture of throws) { + test(fixture, (t) => { + t.throws(() => parse(fixture)); + }); +} diff --git a/test/snapshots/quoted.test.js.md b/test/snapshots/quoted.test.js.md new file mode 100644 index 0000000..4b3f561 --- /dev/null +++ b/test/snapshots/quoted.test.js.md @@ -0,0 +1,1445 @@ +# Snapshot report for `test/quoted.test.js` + +The actual snapshot is saved in `quoted.test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "" + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "word'word" + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## "word\"word" + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## '' + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word"word' + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word\'word' + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## word1"string"word2 + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] + +## should clone "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "" + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## should clone "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "word'word" + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "word\"word" + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## should clone '' + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone 'word"word' + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone 'word\'word' + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone word1"string"word2 + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] + +## "string" be should cloned + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "" be should cloned + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## "string" be should cloned + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "word'word" be should cloned + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## "word\"word" be should cloned + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## '' be should cloned + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word"word' be should cloned + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word\'word' be should cloned + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## word1"string"word2 be should cloned + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] diff --git a/test/snapshots/quoted.test.js.snap b/test/snapshots/quoted.test.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..0fa332483ff2f1ee362e247437eb15f808210c5f GIT binary patch literal 2692 zcmYL}c{~&TAIBZJ7jld+XF2AoIbzODi8RKnnj9UJE0oc9j@(C%Uqd1`hTKOD@pY9P zVa_t--iA4Ilu)6sdVC+>-}|rE=%DV+HIO30zC-=bcrjkqarLrHw9f=pYq;P+M~^?f$YUtsZYy@$SU=m}5l&YH@f{vh))Id-sGS8b!b z+D`uPte>5pmfY@F$ptZEC_3OPWn!DKFEC(}r`8x>li+W8vAZKpv-wM$dd;1TyB?$0 zIbD+q)g}}tdJhO+^x#1wpI>eN?0bEJl`9?^zW<=3Q%VK>S%rycfO)2`S%|NFTckS&s%Iq7kdeJ z?LX-6z#im%TuBpFPV}KS_b#)8UfudN(|`4?G14D5#&C|gxBHEx28~B`;8tO9CL!q2 zkAO-Q->aeHBNWy$Ax232}G2jKUhMivkAR&zY0jKv={H z_k!=f`DL;3soHofFvp1exZ2%l5vrsag@-pXFHH{D1=|<3we9wattuy4FQ_p}s<|<5 z^XJGH#kvFz6hj|>V`zB=p@5$|aG75hz2W@Xb?==nH!T(@DNg_8y~;l=M9J47pa{(o z(V0z%(9-i`Tczp4KLnihcZzbVOVVoaU#F4q=njPb*lOIp?ERl7+?LlXU)loio$Kpm zCx{ksTjrPq?>4~F(RYJNyFiuklQx*z)S4&50fyTjLwkON6*);}to3C6v^)^|Riu{n z?qomiE=11P7ju1=mT2J3HPG)8y1w-Gy)DqFTfe`j`b2dNvn7F2AezC+FYfxvn<9b0 zV2|CEzuN>_f6+8rx)b?S}+U>-xfIq)_Mfg(3Vgn431| zL4~mWG(D5ERAbTg4&apUI3bt7y@fCER6@F=B1tuRAnEM(IVP*T%9x@0 zD0S2Fj8I;(tRctju%KO2pPLVmxFI&uNG#MyMA$u_(7IjrQbWCb9DMM`gUPUS;m2l% zH2`O7Ed?351l!aNwKucthZu7InuVJiIO>xTR#p2J*CzR;YV(-pP;1o?&x$Jk0muRw z;aGlZdBxnQIJJ)INFz5yVzYH;uh6jLZ!}|gl~)T{%Qk`^Pe@$>V)r<70=uYo0(==i zxFIvbVBwcK))^S5Zt;8+gQV5rnhR%~QC4;(ouBz3h8?^Ked}u} z?V$?tB&1utZgX<4YYTxby>Odyi%86868kS=xQr>hjsvMF6&Mv@O=0)5iMBC78=kK# zZ^iUxeCmnVYh>xRL4dtPn#$7RBno%AvcgbN7%Tv`K`!t}NtYNJ7e3ZW*LND-S{tE8 zry@t(6RaCRqQJ{`Y_a^(0FJJRMfsWGD(=Kk}I{G}v9 zPlaJ_B9$xa^AOL?MSCd2z4Qzvmkk|M_DpP1{15x$3WSJ{uWc@rJ=6h_9oyqEtcJT+ zmO556CkXt;V=lM+q5^ReFTaw;k;&IwRf33znGoN*4~kTiKed@7?MgtpBp2_6s?`o>J2`4Qx>;($A7)a`kzRuU2@>1k`N?9Dszs;Gt|TBSW29kQ&Sz$hxTSZ(xd3GtYyVY7&Q0Oy(#Rvu)l$9bs+E1-bS2yBnwS*ZR&Woxc;To(Mkwgt=@25$sj67s;xa-r8R`e0F<%W>9SnJ&KNZj^V9Dj&17$j&{%*M zW`j66mct^Sf^V4knP*8$X7Y!0Hm333`D z*UTmt6ZxZtYPmt2e-G{gg`)YRNR%l4D8Y0t5NC;DJyIGgPHJzp$r!pR$RE?@)Ul|#%Qh<28T>*o6dPX9)fpi-((zoXxQ t8Up^$^E)%D$VKhnJ^thQ1G~QI#`e2odf4DMX#hABcxE%Yk(JKE@(&bX2n7HD literal 0 HcmV?d00001