From 1604e303da643e7e8ef4e780e38b510f1cc8eebb Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 2 Mar 2026 19:37:59 +0000 Subject: [PATCH 01/13] first folder --- Sprint-2/debug/address.js | 3 ++- Sprint-2/debug/author.js | 3 ++- Sprint-2/debug/recipe.js | 10 ++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..c1d871fcc 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -12,4 +12,5 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); + +houseNumber: (42, console.log(`My house number is ${address.houseNumber}`)); diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..f3a06f5b3 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -2,6 +2,7 @@ // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem +// the "author" is an object so it needs to be in square brackets to be called const author = { firstName: "Zadie", @@ -11,6 +12,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of [author]) { console.log(value); } diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..55770316e 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -3,6 +3,7 @@ // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line // How can you fix it? +// The recipe is an object so it needs to be in square brackets to be call each element by its key and index. const recipe = { title: "bruschetta", @@ -10,6 +11,11 @@ const recipe = { ingredients: ["olive oil", "tomatoes", "salt", "pepper"], }; -console.log(`${recipe.title} serves ${recipe.serves} +console.log(` ${recipe.title} + serves ${recipe.serves} ingredients: -${recipe}`); + ${recipe.ingredients[0]} + ${recipe.ingredients[1]} + ${recipe.ingredients[2]} + ${recipe.ingredients[3]} + `); From c8a3d01c30158948f30b6164fe46525117c316be Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 5 Mar 2026 16:43:02 +0000 Subject: [PATCH 02/13] Sprint 2 coursework --- Sprint-2/implement/contains.js | 11 +++++++++- Sprint-2/implement/contains.test.js | 33 ++++++++++++++++++++++++++++- Sprint-2/implement/lookup.js | 11 ++++++++-- Sprint-2/implement/lookup.test.js | 10 +++++++-- Sprint-2/implement/package.json | 10 +++++++++ 5 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 Sprint-2/implement/package.json diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..e042e6eda 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,12 @@ -function contains() {} +function contains(inPut, content) { + // if (inPut === undefined || inPut === ) { + // return "fanny pad"; + //} + console.log(inPut.hasOwnProperty(content)); + return inPut.hasOwnProperty(content); +} +console.log(contains({ a: 1, b: 2 }, "a")); +console.log(contains({}, 9)); +//console.log(contains([a, 1, b, 2], "a")); module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..3405eb172 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,16 +20,47 @@ as the object doesn't contains a key of 'c' // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); +test("contains on empty object returns false", () => { + expect(contains({}, "c")).toEqual(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("contains correct object returns true", () => { + expect(contains({ a: 4, b: 3, c: 9 }, "c")).toEqual(true); + expect(contains({ a: 4, b: 3, c: 9 }, "a")).toEqual(true); + expect( + contains( + { ant: "in your pants", bee: "in your bonnet", cats: "pajamas" }, + "bee" + ) + ).toEqual(true); + expect(contains({ aa: "cars", ba: "baracus", cdeez: "nope" }, "ba")).toEqual( + true + ); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("contains incorrect object returns false", () => { + expect(contains({ a: 4, b: 3, c: 9 }, "d")).toEqual(false); + expect(contains({ a: 4, b: 3, c: 9 }, "8")).toEqual(false); + expect( + contains( + { ant: "in your pants", bee: "in your bonnet", cats: "pajamas" }, + "wasp" + ) + ).toEqual(false); + expect( + contains({ aa: "cars", ba: "baracus", cdeez: "nope" }, "Hanable Smith") + ).toEqual(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test("contains incorrect object type returns false", () => { + expect(contains([], "d")).toBe("Invalid Entry please try again"); +}); diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..02065b6ff 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,12 @@ -function createLookup() { - // implementation here +function createLookup(countryAndCurrency) { + const money = new Map(countryAndCurrency); + const cash = Object.fromEntries(money); + console.log(cash); + return cash; } +createLookup([ + ["US", "USD"], + ["CA", "CAD"], +]); module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..ec860860e 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,12 @@ const createLookup = require("./lookup.js"); - -test.todo("creates a country currency code lookup for multiple codes"); +test("contains correct object returns true", () => { + expect( + createLookup([ + ["US", "USD"], + ["CA", "CAD"], + ]) + ).toEqual({ US: "USD", CA: "CAD" }); +}); /* diff --git a/Sprint-2/implement/package.json b/Sprint-2/implement/package.json new file mode 100644 index 000000000..30e709f56 --- /dev/null +++ b/Sprint-2/implement/package.json @@ -0,0 +1,10 @@ +{ + "name": "implement", + "description": "coureswork", + "devDependencies": { + "jest": "^30.2.0" + }, + "scripts": { + "test": "jest" + } +} From 9cbe265b196db16e858e231f21ea58a584473072 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Mar 2026 10:02:49 +0000 Subject: [PATCH 03/13] coursework --- Sprint-2/implement/contains.js | 17 +++++++++-------- Sprint-2/implement/contains.test.js | 2 +- Sprint-2/implement/lookup.js | 1 + Sprint-2/implement/tally.js | 19 ++++++++++++++++++- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index e042e6eda..c24a0ecc9 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,12 +1,13 @@ function contains(inPut, content) { - // if (inPut === undefined || inPut === ) { - // return "fanny pad"; - //} - console.log(inPut.hasOwnProperty(content)); - return inPut.hasOwnProperty(content); + try { + console.log(inPut.hasOwnProperty(content)); + return inPut.hasOwnProperty(content); + } catch (error) { + console.error(error); + } } -console.log(contains({ a: 1, b: 2 }, "a")); -console.log(contains({}, 9)); -//console.log(contains([a, 1, b, 2], "a")); +// console.log(contains({ a: 1, b: 2 }, "a")); +// console.log(contains({}, 9)); +// console.log(contains([a, 1, b, 2], "a")); module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 3405eb172..b3150a765 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -62,5 +62,5 @@ test("contains incorrect object returns false", () => { // When passed to contains // Then it should return false or throw an error test("contains incorrect object type returns false", () => { - expect(contains([], "d")).toBe("Invalid Entry please try again"); + expect(contains([], "d")).toBe(false); }); diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 02065b6ff..80e3da79c 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -2,6 +2,7 @@ function createLookup(countryAndCurrency) { const money = new Map(countryAndCurrency); const cash = Object.fromEntries(money); console.log(cash); + console.log(money); return cash; } createLookup([ diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..3674a50a2 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,20 @@ -function tally() {} +function tally(arr) { + let count = {}; + for (let letters of arr) { + if (count[letters]) { + count[letters]++; + } else { + count[letters] = 1; + } + } + console.log(arr); + return count; +} + +console.log(tally(["a", "a", "b", "c"])); module.exports = tally; +// let chars = arr.reduce( +// (accsess, currentVal, i) => ({ ...arr, [i]: currentVal }), +// {} +// ); From 90a351e89ed0f97602f24adf97602747e05bfaa2 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 8 Mar 2026 13:04:01 +0000 Subject: [PATCH 04/13] coursework on track --- Sprint-2/implement/contains.js | 4 +-- Sprint-2/implement/contains.test.js | 2 ++ Sprint-2/implement/querystring.js | 3 ++- Sprint-2/implement/tally.test.js | 4 ++- Sprint-2/interpret/invert.js | 39 +++++++++++++++++++++-------- Sprint-2/interpret/invert.test.js | 5 ++++ Sprint-2/package-lock.json | 2 ++ 7 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 Sprint-2/interpret/invert.test.js diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index c24a0ecc9..bf2311dcf 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -6,8 +6,8 @@ function contains(inPut, content) { console.error(error); } } -// console.log(contains({ a: 1, b: 2 }, "a")); -// console.log(contains({}, 9)); +console.log(contains({ a: 1, b: 2 }, "a")); +console.log(contains({}, 9)); // console.log(contains([a, 1, b, 2], "a")); module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index b3150a765..9b0fcf2b3 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -63,4 +63,6 @@ test("contains incorrect object returns false", () => { // Then it should return false or throw an error test("contains incorrect object type returns false", () => { expect(contains([], "d")).toBe(false); + expect(contains("h", "d")).toBe(false); + expect(contains(9, "d")).toBe(false); }); diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..8e31efb70 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -12,5 +12,6 @@ function parseQueryString(queryString) { return queryParams; } - +console.log(parseQueryString("y=8&r=y")); +console.log(parseQueryString("equation=x=y+1")); module.exports = parseQueryString; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..0e07579f3 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,7 +23,9 @@ const tally = require("./tally.js"); // Given an empty array // When passed to tally // Then it should return an empty object -test.todo("tally on an empty array returns an empty object"); +test("tally on an empty array returns an empty object", () => { + expect(tally(["a", "b", "a"]).toEqual({ a: 2, b: 1 })); +}); // Given an array with duplicate items // When passed to tally diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..3d5d892ec 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,24 +6,43 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} -function invert(obj) { - const invertedObj = {}; +// function invert(obj) { +// const invertedObj = {}; - for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; - } +// for (const [key, value] of Object.entries(obj)) { +// invertedObj.key = value; +// } - return invertedObj; -} +// return invertedObj; +// } +// console.log(invert({ a: 1, b: 2 })); // a) What is the current return value when invert is called with { a : 1 } +// it only returns { key: 1 }. // b) What is the current return value when invert is called with { a: 1, b: 2 } +// it only returns 2 because the loop continues and rewrights the key // c) What is the target return value when invert is called with {a : 1, b: 2} +// it should return { "1": "a", "2": "b" } + +// d) What does Object.entries return? Why is it needed in this program +// Object.entries returns the key, value pairs for the object it is given. + +// e) Explain why the current return value is different from the target output +// The invertedObj.key = value; is using the literal string "key" as its key instead of the variable key -// c) What does Object.entries return? Why is it needed in this program? +// f) Fix the implementation of invert (and write tests to prove it's fixed!) -// d) Explain why the current return value is different from the target output +function invert(obj) { + const invertedObj = {}; + + for (const [key, value] of Object.entries(obj)) { + invertedObj[value] = key; + } + + return invertedObj; +} +console.log(invert({ a: 1, b: 2 })); -// e) Fix the implementation of invert (and write tests to prove it's fixed!) +module.exports = invert; diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..e0e0d6ab8 --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,5 @@ +const invert = require("../interpret/invert.js"); + +test("test for a number followed by a letter", () => { + expect(invert({ 1: "a", 2: "b", 3: "c" })).toEqual({ a: 1, b: 2, c: 3 }); +}); diff --git a/Sprint-2/package-lock.json b/Sprint-2/package-lock.json index 9b4c725d6..ceda7296e 100644 --- a/Sprint-2/package-lock.json +++ b/Sprint-2/package-lock.json @@ -56,6 +56,7 @@ "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.25.7", @@ -1368,6 +1369,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001663", "electron-to-chromium": "^1.5.28", From 37175258d804215def3916cc01df61b51a0bb6a3 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 12 Mar 2026 18:01:07 +0000 Subject: [PATCH 05/13] almost there --- Sprint-2/implement/querystring.js | 8 +++++-- Sprint-2/implement/querystring.test.js | 4 ++-- Sprint-2/implement/tally.js | 4 ---- Sprint-2/implement/tally.test.js | 30 +++++++++++++++++++++++++- Sprint-2/interpret/invert.test.js | 1 + 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 8e31efb70..00960a80a 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -6,8 +6,12 @@ function parseQueryString(queryString) { const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + const cutOff = pair.indexOf("="); + const key = pair.slice(0, cutOff); + const value = pair.slice(cutOff + 1, pair.length); + queryParams[(key : value)]; + console.log(key); + console.log(value); } return queryParams; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..717ee6901 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,10 +3,10 @@ // Below is one test case for an edge case the implementation doesn't handle well. // Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too. -const parseQueryString = require("./querystring.js") +const parseQueryString = require("./querystring.js"); test("parses querystring values containing =", () => { expect(parseQueryString("equation=x=y+1")).toEqual({ - "equation": "x=y+1", + equation: "x=y+1", }); }); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 3674a50a2..1a8542e52 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -14,7 +14,3 @@ function tally(arr) { console.log(tally(["a", "a", "b", "c"])); module.exports = tally; -// let chars = arr.reduce( -// (accsess, currentVal, i) => ({ ...arr, [i]: currentVal }), -// {} -// ); diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 0e07579f3..55788353a 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -19,17 +19,45 @@ const tally = require("./tally.js"); // Given a function called tally // When passed an array of items // Then it should return an object containing the count for each unique item +test("tally on an empty array returns an empty object", () => { + expect(tally(["a", "b", "a"])).toEqual({ a: 2, b: 1 }); + expect(tally(["ants", "bear", "ants", "antalope"])).toEqual({ + ants: 2, + bear: 1, + antalope: 1, + }); + expect(tally([4, 4, 3, 2, 2, 2, 2, "cat"])).toEqual({ + 4: 2, + 3: 1, + 2: 4, + cat: 1, + }); +}); // Given an empty array // When passed to tally // Then it should return an empty object test("tally on an empty array returns an empty object", () => { - expect(tally(["a", "b", "a"]).toEqual({ a: 2, b: 1 })); + expect(tally([])).toEqual({}); }); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("tally it should return counts for each unique item", () => { + expect(tally(["a", "b", "a"])).toEqual({ a: 2, b: 1 }); + expect(tally(["ants", "bear", "ants", "antalope"])).toEqual({ + ants: 2, + bear: 1, + antalope: 1, + }); + expect(tally([4, 4, 3, 2, 2, 2, 2, "cat"])).toEqual({ + 4: 2, + 3: 1, + 2: 4, + cat: 1, + }); +}); // Given an invalid input like a string // When passed to tally diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index e0e0d6ab8..936a4e50b 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -3,3 +3,4 @@ const invert = require("../interpret/invert.js"); test("test for a number followed by a letter", () => { expect(invert({ 1: "a", 2: "b", 3: "c" })).toEqual({ a: 1, b: 2, c: 3 }); }); +// expect(tally([])).toEqual({}); From f38855d1024e4116e13fdbe82445f11d9e758d5f Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 12 Mar 2026 18:38:04 +0000 Subject: [PATCH 06/13] sprint 2 --- Sprint-2/implement/querystring.js | 4 +++- Sprint-2/implement/querystring.test.js | 12 ++++++++++++ Sprint-2/interpret/invert.js | 1 - Sprint-2/interpret/invert.test.js | 6 +++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 00960a80a..1e55b0f74 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -9,7 +9,7 @@ function parseQueryString(queryString) { const cutOff = pair.indexOf("="); const key = pair.slice(0, cutOff); const value = pair.slice(cutOff + 1, pair.length); - queryParams[(key : value)]; + queryParams[key] = value; console.log(key); console.log(value); } @@ -18,4 +18,6 @@ function parseQueryString(queryString) { } console.log(parseQueryString("y=8&r=y")); console.log(parseQueryString("equation=x=y+1")); +console.log(parseQueryString("=")); + module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 717ee6901..e0d1d22da 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -9,4 +9,16 @@ test("parses querystring values containing =", () => { expect(parseQueryString("equation=x=y+1")).toEqual({ equation: "x=y+1", }); + expect(parseQueryString("FIVE=5")).toEqual({ + FIVE: "5", + }); + expect(parseQueryString("equation=x4=y+1")).toEqual({ + equation: "x4=y+1", + }); +}); + +test("Test for a null/empty string", () => { + expect(parseQueryString("")).toEqual({}); + + // expect(parseQueryString("=")).toEqual({":"}); }); diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 3d5d892ec..485d4d76f 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -43,6 +43,5 @@ function invert(obj) { return invertedObj; } -console.log(invert({ a: 1, b: 2 })); module.exports = invert; diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index 936a4e50b..20fcdf22c 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -1,6 +1,10 @@ const invert = require("../interpret/invert.js"); test("test for a number followed by a letter", () => { - expect(invert({ 1: "a", 2: "b", 3: "c" })).toEqual({ a: 1, b: 2, c: 3 }); + expect(invert({ 1: "a", 2: "b", 3: "c" })).toEqual({ + a: "1", + b: "2", + c: "3", + }); }); // expect(tally([])).toEqual({}); From 614e8cf14df244f2adf758663b990cde3c099b64 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 14 Mar 2026 10:00:31 +0000 Subject: [PATCH 07/13] testing --- Sprint-2/implement/querystring.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index e0d1d22da..218439174 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -20,5 +20,5 @@ test("parses querystring values containing =", () => { test("Test for a null/empty string", () => { expect(parseQueryString("")).toEqual({}); - // expect(parseQueryString("=")).toEqual({":"}); + expect(parseQueryString("=")).toEqual({ "": "" }); }); From 0504c63e9d6faa99daffe738ed2882ae5534b12d Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 15 Mar 2026 22:13:05 +0000 Subject: [PATCH 08/13] changes --- Sprint-2/implement/lookup.js | 8 ++++---- Sprint-2/implement/tally.js | 2 +- Sprint-2/implement/tally.test.js | 11 +++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 80e3da79c..11d56c637 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,8 +1,8 @@ function createLookup(countryAndCurrency) { - const money = new Map(countryAndCurrency); - const cash = Object.fromEntries(money); - console.log(cash); - console.log(money); + // const money = new Map(countryAndCurrency); + const cash = Object.fromEntries(countryAndCurrency); + // console.log(cash); + console.log(countryAndCurrency); return cash; } createLookup([ diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 1a8542e52..59948fd62 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -12,5 +12,5 @@ function tally(arr) { return count; } -console.log(tally(["a", "a", "b", "c"])); +console.log(tally("cheese")); module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 55788353a..a097bd855 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,7 +20,11 @@ const tally = require("./tally.js"); // When passed an array of items // Then it should return an object containing the count for each unique item test("tally on an empty array returns an empty object", () => { - expect(tally(["a", "b", "a"])).toEqual({ a: 2, b: 1 }); + expect(tally(["apples", "bananas", "apples", "orange", "bananas"])).toEqual({ + apples: 2, + bananas: 2, + orange: 1, + }); expect(tally(["ants", "bear", "ants", "antalope"])).toEqual({ ants: 2, bear: 1, @@ -45,7 +49,10 @@ test("tally on an empty array returns an empty object", () => { // When passed to tally // Then it should return counts for each unique item test("tally it should return counts for each unique item", () => { - expect(tally(["a", "b", "a"])).toEqual({ a: 2, b: 1 }); + expect(tally(["armadillos", "boa_constrictor", "armadillos"])).toEqual({ + armadillos: 2, + boa_constrictor: 1, + }); expect(tally(["ants", "bear", "ants", "antalope"])).toEqual({ ants: 2, bear: 1, From 1660c2a779648634fc54b534bf3a09fabce23f1a Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 16 Mar 2026 00:36:58 +0000 Subject: [PATCH 09/13] working on sp2 --- Sprint-2/implement/querystring.js | 10 ++++++--- Sprint-2/implement/querystring.test.js | 1 + Sprint-2/implement/tally.js | 29 +++++++++++++++++--------- Sprint-2/implement/tally.test.js | 6 ++++++ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 1e55b0f74..2e40a29fe 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,6 +1,10 @@ function parseQueryString(queryString) { + // const type = typeof queryString; + // if (type !== "string") { + // return "invalid input"; + // } const queryParams = {}; - if (queryString.length === 0) { + if (queryString.length === 0 || queryString.match(/[^=]\w*/)) { return queryParams; } const keyValuePairs = queryString.split("&"); @@ -16,8 +20,8 @@ function parseQueryString(queryString) { return queryParams; } -console.log(parseQueryString("y=8&r=y")); +console.log(parseQueryString("3=89")); +console.log(parseQueryString("5")); console.log(parseQueryString("equation=x=y+1")); -console.log(parseQueryString("=")); module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 218439174..11a318f82 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -21,4 +21,5 @@ test("Test for a null/empty string", () => { expect(parseQueryString("")).toEqual({}); expect(parseQueryString("=")).toEqual({ "": "" }); + expect(parseQueryString("abc").toEqual({})); }); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 59948fd62..bdec2187a 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,16 +1,25 @@ function tally(arr) { - let count = {}; - for (let letters of arr) { - if (count[letters]) { - count[letters]++; - } else { - count[letters] = 1; + check = arr.constructor === Array; + try { + if (check !== true) { + throw new Error("input requires an array"); + } + + let count = {}; + for (let letters of arr) { + if (count[letters]) { + count[letters]++; + } else { + count[letters] = 1; + } } - } - console.log(arr); - return count; + console.log(arr); + return count; + } catch (e) { + return e.message; + } } -console.log(tally("cheese")); +console.log(tally({ 6: 7 })); module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index a097bd855..a71f28eb7 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -69,3 +69,9 @@ test("tally it should return counts for each unique item", () => { // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("When given an input other than an array", () => { + expect(tally("feet")).toBe("input requires an array"); + expect(tally(67)).toBe("input requires an array"); + expect(tally(true)).toBe("input requires an array"); + expect(tally({ 3: 4 })).toBe("input requires an array"); +}); From fd6e95175ef25a5d988c79fbcdc93482caa88cdb Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 16 Mar 2026 14:24:22 +0000 Subject: [PATCH 10/13] still working on querystrinf --- Sprint-2/implement/querystring.js | 11 ++++------- Sprint-2/implement/querystring.test.js | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 2e40a29fe..be44f7ad6 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,10 +1,6 @@ function parseQueryString(queryString) { - // const type = typeof queryString; - // if (type !== "string") { - // return "invalid input"; - // } const queryParams = {}; - if (queryString.length === 0 || queryString.match(/[^=]\w*/)) { + if (queryString === undefined || queryString.length === 0) { return queryParams; } const keyValuePairs = queryString.split("&"); @@ -20,8 +16,9 @@ function parseQueryString(queryString) { return queryParams; } -console.log(parseQueryString("3=89")); -console.log(parseQueryString("5")); +console.log(parseQueryString("y=8&r=y")); console.log(parseQueryString("equation=x=y+1")); +console.log(parseQueryString("=")); +console.log(parseQueryString("abcdefghijk")); module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 11a318f82..09a4e6e30 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -20,6 +20,6 @@ test("parses querystring values containing =", () => { test("Test for a null/empty string", () => { expect(parseQueryString("")).toEqual({}); - expect(parseQueryString("=")).toEqual({ "": "" }); - expect(parseQueryString("abc").toEqual({})); + expect(parseQueryString("=")).toEqual({}); + expect(parseQueryString("abc").toBe({})); }); From 3f3eb9b7c6a94387ae8ea0905d8ee0d5863011ca Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 16 Mar 2026 14:34:28 +0000 Subject: [PATCH 11/13] author no longer logs the Keys --- Sprint-2/debug/author.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index f3a06f5b3..be6d90aac 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -2,8 +2,7 @@ // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem -// the "author" is an object so it needs to be in square brackets to be called - +// using the key word "Object.velues" and assigning it to a variable passes only the values to the Object const author = { firstName: "Zadie", lastName: "Smith", @@ -11,7 +10,5 @@ const author = { age: 40, alive: true, }; - -for (const value of [author]) { - console.log(value); -} +let details = Object.values(author); +console.log(details); From f4bd70fc8c2593d576766916360b7d8b4bbf43d3 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 17 Mar 2026 16:42:23 +0000 Subject: [PATCH 12/13] recipe updated --- Sprint-2/debug/recipe.js | 6 +- .../QuoteGeneratorApp.html | 15 + .../package.json | 0 .../quote_generator_example.png | Bin .../quote-generator need-review/quotes.js | 509 ++++++++++++++++++ .../quotes.test.js | 0 .../readme.md | 0 .../style.css | 0 .../{index.html => Reading list app.html} | 1 + Sprint-3/reading-list/script.js | 1 - Sprint-3/reading-list/style.css | 13 +- 11 files changed, 538 insertions(+), 7 deletions(-) create mode 100644 Sprint-3/quote-generator need-review/QuoteGeneratorApp.html rename Sprint-3/{quote-generator => quote-generator need-review}/package.json (100%) rename Sprint-3/{quote-generator => quote-generator need-review}/quote_generator_example.png (100%) create mode 100644 Sprint-3/quote-generator need-review/quotes.js rename Sprint-3/{quote-generator => quote-generator need-review}/quotes.test.js (100%) rename Sprint-3/{quote-generator => quote-generator need-review}/readme.md (100%) rename Sprint-3/{quote-generator => quote-generator need-review}/style.css (100%) rename Sprint-3/reading-list/{index.html => Reading list app.html} (88%) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 55770316e..01c9447c6 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -14,8 +14,6 @@ const recipe = { console.log(` ${recipe.title} serves ${recipe.serves} ingredients: - ${recipe.ingredients[0]} - ${recipe.ingredients[1]} - ${recipe.ingredients[2]} - ${recipe.ingredients[3]} + ${recipe.ingredients.join("\n ")} + `); diff --git a/Sprint-3/quote-generator need-review/QuoteGeneratorApp.html b/Sprint-3/quote-generator need-review/QuoteGeneratorApp.html new file mode 100644 index 000000000..ecbd89002 --- /dev/null +++ b/Sprint-3/quote-generator need-review/QuoteGeneratorApp.html @@ -0,0 +1,15 @@ + + + + + + Title here + + + +

hello there

+

+

+ + + diff --git a/Sprint-3/quote-generator/package.json b/Sprint-3/quote-generator need-review/package.json similarity index 100% rename from Sprint-3/quote-generator/package.json rename to Sprint-3/quote-generator need-review/package.json diff --git a/Sprint-3/quote-generator/quote_generator_example.png b/Sprint-3/quote-generator need-review/quote_generator_example.png similarity index 100% rename from Sprint-3/quote-generator/quote_generator_example.png rename to Sprint-3/quote-generator need-review/quote_generator_example.png diff --git a/Sprint-3/quote-generator need-review/quotes.js b/Sprint-3/quote-generator need-review/quotes.js new file mode 100644 index 000000000..d6a3a7364 --- /dev/null +++ b/Sprint-3/quote-generator need-review/quotes.js @@ -0,0 +1,509 @@ +const botton = document + .getElementById("new-quote") + .addEventListener("click", pickNewQuoteToDisplay); + +function pickNewQuoteToDisplay(quote) { + //gets the quote object and brakes it down to the key and value + let quoteAndAuther = pickFromArray(quotes); + let quoteForDisplay = quoteAndAuther.quote; + let authorForDisplay = quoteAndAuther.author; + // prints the values to the page + document.getElementById("quote").innerHTML = quoteForDisplay; + document.getElementById("author").innerHTML = authorForDisplay; +} + +//function randomQuote() + +// DO NOT EDIT BELOW HERE + +// pickFromArray is a function which will return one item, at +// random, from the given array. +// +// Parameters +// ---------- +// choices: an array of items to pick from. +// +// Returns +// ------- +// One item at random from the given array. +// +// Examples of use +// --------------- +// pickFromArray(['a','b','c','d']) // maybe returns 'c' + +// You don't need to change this function +function pickFromArray(choices) { + return choices[Math.floor(Math.random() * choices.length)]; +} + +// A list of quotes you can use in your app. +// DO NOT modify this array, otherwise the tests may break! +const quotes = [ + { + quote: "Life isn't about getting and having, it's about giving and being.", + author: "Kevin Kruse", + }, + { + quote: "Whatever the mind of man can conceive and believe, it can achieve.", + author: "Napoleon Hill", + }, + { + quote: "Strive not to be a success, but rather to be of value.", + author: "Albert Einstein", + }, + { + quote: + "Two roads diverged in a wood, and I—I took the one less traveled by, And that has made all the difference.", + author: "Robert Frost", + }, + { + quote: "I attribute my success to this: I never gave or took any excuse.", + author: "Florence Nightingale", + }, + { + quote: "You miss 100% of the shots you don't take.", + author: "Wayne Gretzky", + }, + { + quote: + "I've missed more than 9000 shots in my career. I've lost almost 300 games. 26 times I've been trusted to take the game winning shot and missed. I've failed over and over and over again in my life. And that is why I succeed.", + author: "Michael Jordan", + }, + { + quote: + "The most difficult thing is the decision to act, the rest is merely tenacity.", + author: "Amelia Earhart", + }, + { + quote: "Every strike brings me closer to the next home run.", + author: "Babe Ruth", + }, + { + quote: "Definiteness of purpose is the starting point of all achievement.", + author: "W. Clement Stone", + }, + { + quote: "We must balance conspicuous consumption with conscious capitalism.", + author: "Kevin Kruse", + }, + { + quote: "Life is what happens to you while you're busy making other plans.", + author: "John Lennon", + }, + { + quote: "We become what we think about.", + author: "Earl Nightingale", + }, + { + quote: + "Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do, so throw off the bowlines, sail away from safe harbor, catch the trade winds in your sails. Explore, Dream, Discover.", + author: "Mark Twain", + }, + { + quote: "Life is 10% what happens to me and 90% of how I react to it.", + author: "Charles Swindoll", + }, + { + quote: + "The most common way people give up their power is by thinking they don't have any.", + author: "Alice Walker", + }, + { + quote: "The mind is everything. What you think you become.", + author: "Buddha", + }, + { + quote: + "The best time to plant a tree was 20 years ago. The second best time is now.", + author: "Chinese Proverb", + }, + { + quote: "An unexamined life is not worth living.", + author: "Socrates", + }, + { + quote: "Eighty percent of success is showing up.", + author: "Woody Allen", + }, + { + quote: + "Your time is limited, so don't waste it living someone else's life.", + author: "Steve Jobs", + }, + { + quote: "Winning isn't everything, but wanting to win is.", + author: "Vince Lombardi", + }, + { + quote: + "I am not a product of my circumstances. I am a product of my decisions.", + author: "Stephen Covey", + }, + { + quote: + "Every child is an artist. The problem is how to remain an artist once he grows up.", + author: "Pablo Picasso", + }, + { + quote: + "You can never cross the ocean until you have the courage to lose sight of the shore.", + author: "Christopher Columbus", + }, + { + quote: + "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel.", + author: "Maya Angelou", + }, + { + quote: "Either you run the day, or the day runs you.", + author: "Jim Rohn", + }, + { + quote: "Whether you think you can or you think you can't, you're right.", + author: "Henry Ford", + }, + { + quote: + "The two most important days in your life are the day you are born and the day you find out why.", + author: "Mark Twain", + }, + { + quote: + "Whatever you can do, or dream you can, begin it. Boldness has genius, power and magic in it.", + author: "Johann Wolfgang von Goethe", + }, + { + quote: "The best revenge is massive success.", + author: "Frank Sinatra", + }, + { + quote: + "People often say that motivation doesn't last. Well, neither does bathing. That's why we recommend it daily.", + author: "Zig Ziglar", + }, + { + quote: "Life shrinks or expands in proportion to one's courage.", + author: "Anais Nin", + }, + { + quote: + "If you hear a voice within you say “you cannot paint,” then by all means paint and that voice will be silenced.", + author: "Vincent Van Gogh", + }, + { + quote: + "There is only one way to avoid criticism: do nothing, say nothing, and be nothing.", + author: "Aristotle", + }, + { + quote: + "Ask and it will be given to you; search, and you will find; knock and the door will be opened for you.", + author: "Jesus", + }, + { + quote: + "The only person you are destined to become is the person you decide to be.", + author: "Ralph Waldo Emerson", + }, + { + quote: + "Go confidently in the direction of your dreams. Live the life you have imagined.", + author: "Henry David Thoreau", + }, + { + quote: + "When I stand before God at the end of my life, I would hope that I would not have a single bit of talent left and could say, I used everything you gave me.", + author: "Erma Bombeck", + }, + { + quote: + "Few things can help an individual more than to place responsibility on him, and to let him know that you trust him.", + author: "Booker T. Washington", + }, + { + quote: + "Certain things catch your eye, but pursue only those that capture the heart.", + author: " Ancient Indian Proverb", + }, + { + quote: "Believe you can and you're halfway there.", + author: "Theodore Roosevelt", + }, + { + quote: "Everything you've ever wanted is on the other side of fear.", + author: "George Addair", + }, + { + quote: + "We can easily forgive a child who is afraid of the dark; the real tragedy of life is when men are afraid of the light.", + author: "Plato", + }, + { + quote: + "Teach thy tongue to say, “I do not know,” and thous shalt progress.", + author: "Maimonides", + }, + { + quote: "Start where you are. Use what you have. Do what you can.", + author: "Arthur Ashe", + }, + { + quote: + "When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy'. They told me I didn't understand the assignment, and I told them they didn't understand life.", + author: "John Lennon", + }, + { + quote: "Fall seven times and stand up eight.", + author: "Japanese Proverb", + }, + { + quote: + "When one door of happiness closes, another opens, but often we look so long at the closed door that we do not see the one that has been opened for us.", + author: "Helen Keller", + }, + { + quote: "Everything has beauty, but not everyone can see.", + author: "Confucius", + }, + { + quote: + "How wonderful it is that nobody need wait a single moment before starting to improve the world.", + author: "Anne Frank", + }, + { + quote: "When I let go of what I am, I become what I might be.", + author: "Lao Tzu", + }, + { + quote: + "Life is not measured by the number of breaths we take, but by the moments that take our breath away.", + author: "Maya Angelou", + }, + { + quote: + "Happiness is not something readymade. It comes from your own actions.", + author: "Dalai Lama", + }, + { + quote: + "If you're offered a seat on a rocket ship, don't ask what seat! Just get on.", + author: "Sheryl Sandberg", + }, + { + quote: + "First, have a definite, clear practical ideal; a goal, an objective. Second, have the necessary means to achieve your ends; wisdom, money, materials, and methods. Third, adjust all your means to that end.", + author: "Aristotle", + }, + { + quote: "If the wind will not serve, take to the oars.", + author: "Latin Proverb", + }, + { + quote: + "You can't fall if you don't climb. But there's no joy in living your whole life on the ground.", + author: "Unknown", + }, + { + quote: + "We must believe that we are gifted for something, and that this thing, at whatever cost, must be attained.", + author: "Marie Curie", + }, + { + quote: + "Too many of us are not living our dreams because we are living our fears.", + author: "Les Brown", + }, + { + quote: + "Challenges are what make life interesting and overcoming them is what makes life meaningful.", + author: "Joshua J. Marine", + }, + { + quote: "If you want to lift yourself up, lift up someone else.", + author: "Booker T. Washington", + }, + { + quote: + "I have been impressed with the urgency of doing. Knowing is not enough; we must apply. Being willing is not enough; we must do.", + author: "Leonardo da Vinci", + }, + { + quote: + "Limitations live only in our minds. But if we use our imaginations, our possibilities become limitless.", + author: "Jamie Paolinetti", + }, + { + quote: + "You take your life in your own hands, and what happens? A terrible thing, no one to blame.", + author: "Erica Jong", + }, + { + quote: + "What's money? A man is a success if he gets up in the morning and goes to bed at night and in between does what he wants to do.", + author: "Bob Dylan", + }, + { + quote: "I didn't fail the test. I just found 100 ways to do it wrong.", + author: "Benjamin Franklin", + }, + { + quote: + "In order to succeed, your desire for success should be greater than your fear of failure.", + author: "Bill Cosby", + }, + { + quote: "A person who never made a mistake never tried anything new.", + author: " Albert Einstein", + }, + { + quote: + "The person who says it cannot be done should not interrupt the person who is doing it.", + author: "Chinese Proverb", + }, + { + quote: "There are no traffic jams along the extra mile.", + author: "Roger Staubach", + }, + { + quote: "It is never too late to be what you might have been.", + author: "George Eliot", + }, + { + quote: "You become what you believe.", + author: "Oprah Winfrey", + }, + { + quote: "I would rather die of passion than of boredom.", + author: "Vincent van Gogh", + }, + { + quote: + "A truly rich man is one whose children run into his arms when his hands are empty.", + author: "Unknown", + }, + { + quote: + "It is not what you do for your children, but what you have taught them to do for themselves, that will make them successful human beings.", + author: "Ann Landers", + }, + { + quote: + "If you want your children to turn out well, spend twice as much time with them, and half as much money.", + author: "Abigail Van Buren", + }, + { + quote: + "Build your own dreams, or someone else will hire you to build theirs.", + author: "Farrah Gray", + }, + { + quote: + "The battles that count aren't the ones for gold medals. The struggles within yourself-the invisible battles inside all of us-that's where it's at.", + author: "Jesse Owens", + }, + { + quote: "Education costs money. But then so does ignorance.", + author: "Sir Claus Moser", + }, + { + quote: + "I have learned over the years that when one's mind is made up, this diminishes fear.", + author: "Rosa Parks", + }, + { + quote: "It does not matter how slowly you go as long as you do not stop.", + author: "Confucius", + }, + { + quote: + "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough.", + author: "Oprah Winfrey", + }, + { + quote: + "Remember that not getting what you want is sometimes a wonderful stroke of luck.", + author: "Dalai Lama", + }, + { + quote: "You can't use up creativity. The more you use, the more you have.", + author: "Maya Angelou", + }, + { + quote: "Dream big and dare to fail.", + author: "Norman Vaughan", + }, + { + quote: + "Our lives begin to end the day we become silent about things that matter.", + author: "Martin Luther King Jr.", + }, + { + quote: "Do what you can, where you are, with what you have.", + author: "Teddy Roosevelt", + }, + { + quote: + "If you do what you've always done, you'll get what you've always gotten.", + author: "Tony Robbins", + }, + { + quote: "Dreaming, after all, is a form of planning.", + author: "Gloria Steinem", + }, + { + quote: + "It's your place in the world; it's your life. Go on and do all you can with it, and make it the life you want to live.", + author: "Mae Jemison", + }, + { + quote: + "You may be disappointed if you fail, but you are doomed if you don't try.", + author: "Beverly Sills", + }, + { + quote: "Remember no one can make you feel inferior without your consent.", + author: "Eleanor Roosevelt", + }, + { + quote: "Life is what we make it, always has been, always will be.", + author: "Grandma Moses", + }, + { + quote: + "The question isn't who is going to let me; it's who is going to stop me.", + author: "Ayn Rand", + }, + { + quote: + "When everything seems to be going against you, remember that the airplane takes off against the wind, not with it.", + author: "Henry Ford", + }, + { + quote: + "It's not the years in your life that count. It's the life in your years.", + author: "Abraham Lincoln", + }, + { + quote: "Change your thoughts and you change your world.", + author: "Norman Vincent Peale", + }, + { + quote: + "Either write something worth reading or do something worth writing.", + author: "Benjamin Franklin", + }, + { + quote: "Nothing is impossible, the word itself says, “I'm possible!”", + author: "-Audrey Hepburn", + }, + { + quote: "The only way to do great work is to love what you do.", + author: "Steve Jobs", + }, + { + quote: "If you can dream it, you can achieve it.", + author: "Zig Ziglar", + }, +]; + +console.log(pickFromArray(quotes)); diff --git a/Sprint-3/quote-generator/quotes.test.js b/Sprint-3/quote-generator need-review/quotes.test.js similarity index 100% rename from Sprint-3/quote-generator/quotes.test.js rename to Sprint-3/quote-generator need-review/quotes.test.js diff --git a/Sprint-3/quote-generator/readme.md b/Sprint-3/quote-generator need-review/readme.md similarity index 100% rename from Sprint-3/quote-generator/readme.md rename to Sprint-3/quote-generator need-review/readme.md diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator need-review/style.css similarity index 100% rename from Sprint-3/quote-generator/style.css rename to Sprint-3/quote-generator need-review/style.css diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/Reading list app.html similarity index 88% rename from Sprint-3/reading-list/index.html rename to Sprint-3/reading-list/Reading list app.html index dbdb0f471..62a835933 100644 --- a/Sprint-3/reading-list/index.html +++ b/Sprint-3/reading-list/Reading list app.html @@ -5,6 +5,7 @@ Title here +
diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list/script.js index 6024d73a0..cba465c4d 100644 --- a/Sprint-3/reading-list/script.js +++ b/Sprint-3/reading-list/script.js @@ -20,4 +20,3 @@ const books = [ bookCoverImage: "https://blackwells.co.uk/jacket/l/9780135957059.jpg", }, ]; - diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list/style.css index 74406e64f..8dd7b2ad7 100644 --- a/Sprint-3/reading-list/style.css +++ b/Sprint-3/reading-list/style.css @@ -8,8 +8,17 @@ html, body { - font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, - "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-family: + "Source Sans Pro", + -apple-system, + system-ui, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + "Helvetica Neue", + Arial, + sans-serif; + background-color: #87ca8a; } .site-footer { From 70d7954efb7196111372502e19a76ff79117e588 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 17 Mar 2026 21:10:17 +0000 Subject: [PATCH 13/13] sprint 3 back to base --- Sprint-3/quote-generator/package.json | 17 ++++ .../quote_generator_example.png | Bin 0 -> 74199 bytes Sprint-3/quote-generator/quotes.test.js | 77 ++++++++++++++++++ Sprint-3/quote-generator/readme.md | 43 ++++++++++ Sprint-3/quote-generator/style.css | 1 + Sprint-3/reading-list/index.html | 15 ++++ Sprint-3/reading-list/script.js | 1 + Sprint-3/reading-list/style.css | 13 +-- 8 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 Sprint-3/quote-generator/package.json create mode 100644 Sprint-3/quote-generator/quote_generator_example.png create mode 100644 Sprint-3/quote-generator/quotes.test.js create mode 100644 Sprint-3/quote-generator/readme.md create mode 100644 Sprint-3/quote-generator/style.css create mode 100644 Sprint-3/reading-list/index.html diff --git a/Sprint-3/quote-generator/package.json b/Sprint-3/quote-generator/package.json new file mode 100644 index 000000000..0f6f98917 --- /dev/null +++ b/Sprint-3/quote-generator/package.json @@ -0,0 +1,17 @@ +{ + "name": "quote-generator", + "version": "1.0.0", + "license": "CC-BY-SA-4.0", + "description": "You must update this package", + "scripts": { + "test": "jest --config=../jest.config.js quote-generator" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git" + }, + "bugs": { + "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" + }, + "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme" +} diff --git a/Sprint-3/quote-generator/quote_generator_example.png b/Sprint-3/quote-generator/quote_generator_example.png new file mode 100644 index 0000000000000000000000000000000000000000..0226264f09ebe03769d58a7112a2ecf03c61480d GIT binary patch literal 74199 zcmeFZ_ghm-+XfmHMMOnWK}DKUM4F<2)QEsI0qMO-@14++APR^`Z&HKw4$=utlp@k= zfDl3t5J>2OgusdK_wK#l>zse!{IJ(`rOaAW*4#7mtoym2Ny6W#DO|a9_YwdAxT2&e zrwIU169Is8hZiqU&Y%c;4=Ep1wlbEYkz&YxOX| zj5L+(-d$9rX$c=GNw{W6b*3mdGKPv?`6G=?M>$`~+_XH^*e#P=8eaTCrMChMZf-dG zJ&gGM8?ImZb%*Qx1PY9gCV=sQ=$WJCz7#Z1iUjBaAj2?IJ2hXgJ0;gPP6<0xC zwIT{YZ4-3KDTp&#Fu7`R(Grj_e^Rk?!0;l0?9Ir@c!-u$XG_>U^J0O0;O4KRqid{Z z0fNga)**mv;IFg(x?i=!3tl?0y+8AkPiMhNSU_jtwQ#xS6bGjp+w3_&O4njf)tMoe zcmBH9flNDg=y#Jk_phm#pICi-e|SF=u<-C>_Y#Kj;ggzkS5wTktxiLpdVYxS?qz9T zH`ac6^+s==U-Q)5DgTk*Cks}e%3-;xLMrQlN*9m^ZFb_93+^zEry^J1fcVEWbzZM!&;@MqJ!`YJ>_)Wmx!Y`J0v2!DnO6 zb!>wB!CT4x9A~$JE?b>rcN?|~waqPl#j%xgQTaRm8qK>vE7L*;?TeqXPIf=)lD*Ct z6c67Y|7^TPwGepi%Fdi?h(nT9htZ|OTMiwkTLWR=R@(FLkqV-&2tTeGa2lrd?X`jzQ@0hWu0^%Qrnr^v;_e6x&Z!MJ%PA`>t8h9d z52c!m;RKA81HBJ2+$4em$RXo_A*G6CKNIQB9*eJi7yW(v%Q?q6z^*&>EF0iMklW)k z9q%||F694w6fx(Y^v=LsK%eUOi}U*DC*C_$o_9Le^xf1A@a%og+|B3I0`DE?xEiSS z)aiV$65EX)e`LEz^Yy{yj@#c}I9<2xVBVGwj&b9-p!8xS<}wFUEZZe3fhww^7ZYsb zzjSk1j;@OZr@s`q&-}||>H0`S^GoUM+sd+6-aH+<${a?_c6xSK^<}}=snyptRQ&RK zSvq#iaBAn5>R*$G)9e_D_n5x}@C`cN--KUS%RoA|x{N#qyVbXjAy8Mzq+Nu>=opBvPQ9C1&2 zQf?}Kda$h+k}EXwYJ_EkMw7cJY%jA^zK*Ra{=u&`D;mEijd9Isf$1|!5M`F!RZSNH(Ss;F)~s$vNM{R%Q<0K zsFPP~h7F#0P)7F*oO&ZtHceS;NO#C*L~R5&Vmi9!CE_qKB4sAnUS0~piz4NgNtJ>@L#u|%93si<{N0(Q3yfD~_RhHqFGKsA2 zA(O!g6dA$)nd-f?ft~CSF(E6fH8=7`vPj0H12Pmc zY&~PxF6Y{VuNsZR(m83bSR)O(=DQlZN+Q!DS-;G2sd2@>wn=dk5px_7oi_LSZg;Y} zGfe&J^zElq@f5Bv15Z#k{+(Xm`)2q?UOUtcZ`2sT#6~4MB)bDMj@)-mX+z~>LMGp4 zbkani^+WkYc%yYX#ec5XKdb#*rLFH$>r{WQrm9}K&d{lLaQ&U|_%uSi*FVEM&ATl! zq+c$rQRIq9+oYxw*jc`g$!QSTT3ubQQcIdBpTecI#7ZGrJ6hXMTF;@_CoS@2Gk#uC z$j+&-EMMg6c2p~jPmcdp)U{UpbbVu!&u4aN=1J(|F4xaiuTfu+0?!!hRAN=$_vU=- z`}V|=G1{4h^ftY}Vb8s!JA;+bIo>Ng=-q^s5(U@OxI~}~QKpR&jk_qv8CTySsr!-) zzBRthdtL`O{ap^47dy97SNF^G(h#<;tgb1b98g7cq= z|LCZ_f$yH~QhuAZ_~M?Zi}TETU(#X9Hc<7x+9#Oy(>0}FqaQOLcEdk++zD^Gf#wR~ zDtir2-iRqxbWs^rN=em(?Fb0-d8;}gmfYhps;%iZaa?MSO5Aw`xp+m^FZ9yZyhtc%S|~SR=%yjnA-7HtJVFkI|(obMMHXe#mS`E@)`H z(NG;G8SqqJWx(E2`Bc&8liK2RFdFwUj&)_u^U!m8#c;sn8DUuRpt)=}_9$f+$)GRz z&}69kvB!M5{Fr=W1jKX$?%Tg0s-l@(la!h$z_)qAwUZVqv?*jTwds1U6;*Z9?2+ko zYoFy*m$ljN^UKMPjCmjNO7mj`+x9Y$ARY9TvR{V7ts?=;D>@xIaXR(7)D^R}uUu7o zQgO965F%xkWxQqt8}jFUMqVl2dZ#RxH%_a?pNbr&?5f?zyVS?C*VBZ*3X>dE9h1jf zksOm_jbc`wiwxELw~VAAf+r^f6Tiw-y?wkBkspzt>ZGPJtH{T6t-vw-<0*}Ai@Rz) z1LY<(O#@@3F$7)&)lzlF`OULETnZdBJzLqrA1M%NM0i5b*`OxfB0)({7Q2n8v*~J> z_oOC$e;vHpwCI}O;mWo5(SlYNHkNRfJE#MU%G$u z-r-Pq+>LYGdE6v5YuLI=+OQ9PZ)sF?;I;TDM1;5z;&~mT2D60$-PyN(3`d+WMjP+6 zj0H}SJVtL-@PwSP4JkxV+ZqGyeJPof*G%|H*w%(FRcg^yii-ciy9k z45XGT2z7nN&qoxG>oxlXxzk*~B|Q&0I)|c8q*G;`Aop&Yk>JfuQBs!zyq4V;76VYn zI857bD0xha_~9gXr>Jw3Xp0++I(W5bN^<_~Dm9olNKN_;L6BMwLViZbLO&e4=RrN7 zgDO+KU-f#;nA&EKx^`8OFOI+etUq$4Mklt3LfWwJ@nO5HT0m*$^!@O?qV?)U%!J^u z8IEq5?uwG1Q0Dr>p!QH3>oZ#p+yh9X>jcFyob3-;4OLP}8(CFC5O#RXf?)xs47D zVKyI6HUZMpi(1Vdg+Iy>DefzE z|35jzDc}E`7QD~)pDbREQup;$->}KLdRVgw3p^8ed|&z!8ylOXhn0=ErrfLl7N?}7 z?%R2Jxrqx3f0$5YW$)_3_NQKpx31n^QupuwY3T3c|L)V;*Z!ZDTs;5VElLLk|6CD#BJf!7@46{P zCI6fie`D`!?W8Yf?`-YjNohk`=e`ggvwsGMGIYn3H;SkE=acd} zBS|Jqcd!5e+a^kKGTOeT8z}0adwSr*ZFFB9?|O?tXB8h|mR6)QsOTMlMoBT~1AzVO zdBuyId)L^`Uu?N?I4X

}p^%sN(ERvMM2%;#`n@$Iv!WPf$}pfGRxRH5X4UIGuqM zTCPn&rxBWeqMOC(|8pn*_ZD*rvLpCEX~i>V$^Vngz4#9DKS|9GFM$7(>xOeWKWXydk;+cPvir4>b_AfO41^F)|0RK*@zo7v9yMX?| z;$L&|4;KHLi@&k>*IfJ!#lPm_{}1c}za?4`6^8)~RTLJ>pU*r0*YH?I6r5V`p90dg zDWvFj!ug|J3{YJte&BV|Upa!lv2Dx4%vFU?J+Y>m;U-o4(s!lb0_0zl`4eIx|2kxUuL;1vUhh9x{OjZYjm7^@6^+?>S5s!r!82J!6n=ocf=}Kk#l~|!kCp2@ zNAH6hT5LAU9yvn>!4%&ppA_GcxA??Da_n%-NaFJglw1A@&y_H`dz-1iC3ZfAOysSR;9IhoF~ zf>r-l8rRx19EAo6@`hZB^T(pfJ_kB*wi~Bc{@b{kITi6;{0)i@_5S`4H27kPCS(su z??f)6%~I&R8tWkzwFas`yjWp5dpw8XoZS8> zM@{IKfjAPTBJsLRlRr&G0}9>H({OgOf^4O2qZfHzM-z^JPw!-q-`1#*{Z`|Ye!RjK ziY>;|&}}3ZIu^A4J%OG-F({-0xCLMG5lk*mJ2m{>E6p*V$=}jW#=SUtEdLGyx%nYX zM0vZsUUB=NUa`_SQO?8!{!E;>U+Tj(_;)pGk`(Q1j!MUrMHj1Lh9aHI<>@|hj#zOct%eYj!v$8mr61Bx9v9Q72B`B^})w{fBGPIO*gmZn1UVj zp~2(3PM3l#OGUEZ6dSq5?R*kk-HnCe(cdceg|;aI`2QV2H?C18f@0I-nDsieiudlO z`&M8AE{3qPxv<>DSrPT}rg9}-hKK+3i(;dsIM!a~#Oc-Xg#EVT|Eq$=ts!xqij#E3 zwcDZX^?=661J~#*{7*;w#Em%MIHQ8#qs_#f_pI?-bFDcQUilnK-7- zUe%G1zv=^Ub5VG8jE#)aBO{1FdpZAog{OvK(054~qw9jzcEP|+XqWM}ZN|v%uRbYN z4@|T1PC?5gc&TtQhAiO{zn&D<*~=pDN=3V6^a2=v-F3!yyWlk=l(<3MPxmZd8t~0r z8a$!~o3(>4|JCH2+!FK2$~c4cnIMS#vZA4@Z=02^35>5@|N2Iw*(Xr5Np{rxpG|3K zWeC`}%y~iGfGx!Up=h(?NA!pLHij=)?{1U&E>iX9EV!(}k96o+CdH05sQJF5B*_H!(5|Ou`s;&g- zQR(Qd<%0f&C*XPG^;PPio1cp1X%1$%H5$d6o0fLPc#L;!dieckFQUqTA0Ni8mj}ox z=UKI13xOA7$azc2tuLE@bXc+fUCZS^6Z30f;EP~pP&kI}!EgLg91!oyA%WrP30};B z@8?^Li)aYPZHyEsxopG2t#*1SThRV{cs=;jrJLT)$!>_1uXJH}zqk}|`4VFbn}J)P zoJ;|gL=tC3DBFl?s<_IIikX0E($|0F^VC0h*xyLtm;_hI$;9y8KHHRbn%)MK{<)91 z=rnoa!09LayeSO`S}_YpOLH6iHxvN?1ihjxLN@E{EROjT;h%TwfKPXwdR~h^@bf;V zBI$AthO&+Ar;8{EjS3Dk{`?a6*UbXvIR4m?5w222{h6nw`o2E6c+?iT+i0wD^h!7I zrp9e0n~A)IWo}NDzl#k02cERTM;hBNcHTae?CFE^`9T8ZO`76uWzBbY)!W`QI~i5| zogdIodBy}Kg#Y*?XA%|)QE0=2>wQUTe%_j$eV!QRtJ1b}Nh{9w@9e8|f6z~>ysyc3 zMQjLPTk{DcCEW=g6YhwmzE8VjD=);~^LMuadtnqym8-V2Qq3v^#NgJUl5!Tpej-$@ z6(uQ3rhiwO1^kbV(&G=8`?-31%a=yhq~F5p?{x@xuJmW#+%VSOh^u_o!M?{Tm|12k zoHEJ^h|+iyS7{l+z~{yCL#b=zB(|S8Sv=U=^AfNc#{0BxT^8GC`S5A>js?v@Mbg&y z2R(5&WVL5XqQOKCif7MFtwNZeze2=kS}FNY!WB%6^#B)gy<5jmHEMYc00716zP4ub zlcqnyf-zg1(XrKbH~(vfx$T>Y1eN7jd_?k{bq=zKIyAy6-z=T)IplXq+Xilo_0pj3 zGbTlw6`h4CuX8-~iFD!G;&K}t_6^Zlc4)TDWbjPB{&R~Dw`dN49PLp+#fDRvaAi`b zYg!H|k%wLFf=2Db;rV^~4I_cXeqiD{+*QfvpmxC;83zJzS3Zo}`o+alab#8`O;n|+ zLuFgfscmzo=lf-G`i=go2E6dbx^j#KGP3x;Zl0mq-dT)qJA1pgRO^j3xjwh*fXUEi zX5;r|b)>3n|4$9~whz=SN#=t>MNWsU+APE>3c-k*DH>FtjaAb)`uNBERPKrt*%|#f z(6SjB(co8k_bs=0S;o3wuO{&DYYAFd?<2bPMF(pWM%w}-Aa!cQ(_Y@>)zVgCJt`ZQ z;jOx(2T;==K7eNkqANBDW)9?2=51~P`Zj0XoeSv~vqwz%e?p({Id%cmF8-lc8Nu7> zXCyPTJvholo6Xb{%GHx7XtO|Gi$f0Sw>@NCYy6HFc#Mx+q(b$$RidIFoEF&U3#Cgq zfP2i2FZJ*TS~v*ghcF}esMdIKZ*2p&Ex$zC4~{NARcroXMYsm6==GR>h}aygi$Fs@ z9WJhLx^}(zF~F?ZygW|7F}-X`S~SXCCaNpj>}V41a%UELz3J`Pr}uV_H%C9B@ez!7 z8?*^O>pXkm{-)qz(xLMbYx-gKjttN2k-8>o%X~(9i0_(w>`j4y#3glbtYUslvnN%E z4o?~JLqalGrOga01YQ~l%)cq%>$r0PV5zGgyMQ|78{Y?U(!QON*Hh|UKE+KJfE%vL zi@g1Hp$r64q!1q}2^_-zFs9W6?Ru)3&apXosI>ELuk!kp86R(##JQmJNBDR*vz zu^GT2K~U;xa=%|W@QE1+nW`+mb50RRc|Ko|&w@IMrM_r0*-8#nQ}-Q=>r2?}bWAIu zt?FUDVAF03JwCgQ3`6&VCf`Afn9-C6@XMapO_StuUs;+%1vs!P0_fthld>rKRMpo! z@+ST?D3i}Qp|E;Gfba5z=R~leR8#9gS&z^lBIJO1>hq!VjZP*}qhp$gy+bLP-TB1r zv>^pw^SsQVX3gfnDy?&|KgL}XW`e!Y2BEDR0t+LuuvoXjOX1>9`Y6pn_K_X6IC72y z1yfSp3Og@8=!TK+)^%s5W@GF|sS}AwMY|UCoQ_a2pJ}IM1$*n5L z8`UV=pc@9;tpp`+lwh15jiY*>DTlNAG1{tqu~+;~A|g;}unobrtZ^G8vOZ9+%h0c% zWj%#Jk>17YY?q5F`kKF=aHlrLFgINt*XlONfb}T$3gZ(uHnXtY5;~B1%d)el0C2!#De;Pv&i$GuMzp z1a4Fp8Ajw{a%t9_AZt%F+vsUH#d|kq1l~ch3Iy4ca=^idi?%8@#Jo6({*f1sJ6vDP zPnFk>*LVYVUTKHtF0Uh$T!tfN9MhjW`3{Uoojz)h(jh+jB)Dabeaid}lK$HGi13vE z)M5ACMBd5L9h}-&UqW?!$OGHs}PI8(f*bSnxoG$>BPd-=75Ex#9|&D$qdaMH4vl^?_LWO{EyOuENRPwO|n z`$Ke!mR}nC7eTG4syyd%169It=CmpMlEa~ZgbmqCejwmr=ca+88 zFuH%%rG1g@CXb%6`IO1f-3^ULU7&`0(-eBAu;*Uy8?v?#4eSJOz6gD)0FB1&U*7M_ znIi5H9wvH8MJsyw!ah)oC|43h%9bz1rFeysrZpC=I~-FMLJG-_{=xn z9Ik~H?#FjL^Omcii8H~rinxRV#e)QHC6|+U&Zaqk6Q8`pc$+mnT~6^T#1){6R5|Kf zT?D^B-;eiA-XvX>O03N`5`%qjAs3K9u%A8DaGf18Ny>oM=D(|6Ks>kbO{y=*C^*90 zrC9AMf#!H&bmZdDnD560HD!-|nLaz9#l zz0>xZvjfuj%%59?T478pHp91jUe0w`=NMBV@g=>8E?CuzK?7Jyvwxr;zZU1y#kVG` z{1Ge0h1SCv@P&QEy=EWhXg=cN(k(X+kNtyYZbuYZuI%R{dYoUWw5x4kkAN@bIdq|| zE^N;{isBh-2Z-II5bw&m%*2zQev@On2N%!M_>{(ufbsD=serXgwYpLw@kE`>1e-j@VmY^FrdEO|?>GuT{Y8r`e+d{JU z_Sr6RN;Y?1p^3h^RlN{xwz{Kf)0Id;3Y@MG6rX?=SMb2J{fhiy>|{NwIKNO_U(qT3Ak_ zsu6Z2-B7y)oe4xV3QOQGYF2DACeDmO;GXS5Gkc-u1oEw@@RSrb<}!(B4-1M>;! zX>Tl`y;#)_lQg-6X_ofueoVzlb08Vhd|S-4PF^T}(Bo)Aob_vV9#RT$7bhF zT#A3|62qwhn%FtP$Q{i~Mgq*3$Wmfk#UzMi5VN;HmB@dhY4W2Hix z*(oSKWPA<~UYv zaZv~dYs^H!aoSCRQwb?XaB_|Du7;=w%1v%uZ4FM2)b!tyrPoRQ>?In!aTS`%@|`W! zr$beM?+idQdgLD9aUg@bgx8Blj;*EK+nrYPx2-Vz%T?MeC(R$2kqg${@6aN=eiOfR z?N;^Jot|qn?Y6n$m~xk=L7zk+pP248hK(=Cu+6t-jCdn~ZnkY^*DAc<4xTq;68C@j zvrZvTO0#*hjNY3$wy;6a;FI=tmH)B*#KO`_XjZ0A(Gr7{x(97$&VF}Fs^Bx%%kRDY zAE5|nLlz&!o0kI>+8C-9)W5)*-=vgMibJ?CWe%Us_#W=7Hb8VUAF znSj+~)$>y|zgO88LDqi6!uq!K+Tf}48S8E`6W;O4Ot$aKZR=iX|)LMxjoB<2P5P27SB-c5#o z+gm}%i#e#KI!Z7zt=mTbM^u@n;ekx-TZ5U4cix}hs%hTi=38GgUY6FPxNCrzySk?L zZ(=gS|$l}4}Ry~vu|yaJ6!aDROr;k$@YvT7OM2MQKc zP{W&^UCL`daHMxK>p9{NiZ|32<5&)BW21;{vOw9I7pI3I+ny!yLU%xnYyiM>G5O9G z3ddI6HaSi=J7dXubd$pODLx-Sp?_C0{HkkG;YbSKou+IDr600sae6$&i3~2#%k2D7 z-VZW#9YSt}7t8lQCJtf9`Cn@;_HO%R>1ikaUNKW%D_8&cENVt7cisoQy)*Tk*Shwy z%P8EwfsZ`>O)S-e)iRnln#jZ3T(SOFgJKT;U+|4HJMz!I%!Sk&j| zyK@)A1g{Hy1`42dzN^E&@vhygKwW7rT*)HO$s<_5ZLPuuF-HWpeQ^_HVbR1>gwZp+nsfV4GM%KmvHg= zHIg#LL{*STH$gLb*=<1WRFRnz`_q=VDjEwl z!Ckej2a;dLMLlCiVlB-F1d1J z^QgsEPoKsUL6C?j4n$X+uXfsSK({m)-g$2IBU$^rOd|L)D$=L&hwv ztly`FLEadadrdz<;Q5(j%ugSI_=G4-DtA) z`B_T!U1vj5(PKWO$Rq+>94D$Kd_v zZ(ewWbt(v0sI{LRsmi89sau4tbe`-alp9q`j)&!G)Putooku;UP0;&BC|eUT>m%&L zj^*z1hSroyeeBVwmpuraW36MaHzPJSvh?A6xs&uX`Yw-)*`zG?!`565JhQ2jwE&yH z|CPl`Y9e)_dNcJZ-8$qGHsY%rDZ2(aE?VAP4dGjpafdR5RRbXFKvWz+^DKS=~XZm~-$J3)34j5f2We&5oAKW6&bC~BV4a1%r zOuHPrAN$`nHvI4Cs>?qZosFW$@JnQJ@;B8r9>`5LBJ+67 zdc~kK#|_QZbt=_Dg4YWOQA;{G4N?~S?`?B@$5(kU##7TDR%G>D9FVU>#SNYV9A($t z8B7?F<#Tg}gvLIqGBcB@5>o&4E&oy{AaQg0;GU)g=dhND5eYdR)0un4zS|i2D3yAK zz={t_FW0l{{ysfOlzd7aS)$u7-QYu=vKP6)M@>6vBN?vDb|{T_EGz6iHwfVUN;>^A zz{})?A{tWUHda=>oYTXn42sD3R+csq+-(=cUO5IZF>%yIGU${0M_^xPAz<*On~-Xmrtb)g9Bp3sqzS;=COsI(a{7uh^&l3Yc0*lz?v zGV?XaQoULVD#*OAE9ZJ`Q}67R)UvGhP%BM|b~v7mG-kF%u#4BNwtm}9k?%44JkeWz zS#q^bVttwkM$k8~!)SMF&cew>enz8VCuVW=n=@}%lj@rWZ#hXsCrJqSH_s5UN66TI zcd|XkXtAa&4{2^MIOa9BO=et&y#9T?pW7$0ba^^j(PlbiTPXdS)AUFbYg=hO|GBwb ziooza>*8KCKNT_hr3ZaH@D$GpTHlQe$-($i5jRQV(A}3b1SiD%7`~?m5=ZGZ#zc{x z%$)?^DZs`LIo~I?VAk}I?^5+ctpTBDTd$^aNbK5DocAG z9`De!1)Z}XN1CZrI)}(*=M2s#vC>I4Ut#UCs3sgEdtV3j%f>)4Iu;=! zuO~^P7WU4{#*`z((=>@$5Xn!zZfesO5#OFot`#5f^P#<`?QCXumM$ zw4WslL~d3&pTx<95frt*y<~^Lcv+{7IO|t=;xbMz_q>)?sR#Qq8g2YAqzH`Kq9-q* z7SB1p?)FcR6cIdrV%?7Pf)- zNRslXnf-XdGa%Fm?Zkw3lX+S-@U(2iV?2QKDS5%lqO_T~>;Jixp{;UI#B|7KZSx+F z@gV~v$L)_M+9kMV)kkz-rRYd+)1eTQnQgaZ$+98oc~4)Xv6)`26WqwK{2Q$ahTHY- z7h2;DBOXd@di2->N`9heY7}u8zd{kxbqpDRsPl9RY1qnfYerLqiZwa9=Cwh&HQ||k z;|}_n3B{S`wb8<9vyeg)@T9nvK`RS>q(YgqACvP>&DD3C6119n6Q?hBx0U;;C${;Ia=vjCt#!eK^awxq;Zb^yEJl*%EG15d_Qn`( zFV?G-M)3NUWjIL5#{~^3rf$HTZL2=0U0+TDC!`1 zW~zI@2j+C`G}nPC!HtLQ`2na#HRmJq=DPGG>WJD6X|4KAA7@fu%!H#f z^XWHMhQp8WI(sp2gf{E=p24 z9Q?hncqfaH!)94+%TPK1SMNCT%Em==#z|}*QFMgi802CtU)HS+qw?tj^$SxJPO_-BfK0OWap`UciEE%U}RlrfdHSf>q54~|5_ZLDL&-eLJNL4&`0aI5i)(_WbC}Z zF|g3N>Rmzlw`N9l!oIy~N!Y@lC1K{;Ek6qO!Re$zKz6f`H`AFX!p@{C79W^s$JU?J z<11Va8|!%M8V(#q9X76aM#}*&%Ke@{{^e>?pYj&Qfmr zCCB@>7?iR8$_24{_cpyTk)<v&*=7+QpVQ-ECtjbo!vXSu|F zGq#r=hhj-)y|OmQir{LjK9M6J&yVbvAP9A&%`z&Yy5gUWI$A4crjJiedOQJk0+lb2 z@g%7;-P_huvAofN=!`=kZez)O#!AYf#Z>)M0S9eB;{J!90=b{hn~LzJ7$oo0_ zomM8W9!JTML>t+P^nQIpPcNL@YI3t?yuArGYQ}Sz&Oj$Omz!xjQ zAzp*bIBq06Er*l)V)@~8W%1w7gkN24Q#im%4=E_1!&)^E?W2}LN>$acn-y}Al-M&p zu2BWuWR(4$Xi^KqOFkTl8{PK{&aX|CV2;-GwTj23q1SFSRgJg2$#pw`IU0_Un~!BR z>z?J?kDko7^h+UG>>!gzAGPaI9C3qmMOxuGYo+i_8y*xvx=8X^g@z8v{QD~sotZ2d zhp)eSp?xA?zX4s+jlfliwJX)BKu)c3aZKuAc_CzyIVf-WRAAZqRK4vdu5e^CMMR|+io)OE zTDSEyR7>1*<)k5$BaZ7efHxZ=_D&9Erp1#OYn^ye1PD(Bu{GbbsS>&Ig<9ZLzwr+4 z=)Etz3^&kj*=Sin17h6x6H+%3NbGLqT)qXHs5xXJJF7}5tSW6rN}nPYqOxPYNNG3dfgO0Xf=*AGb9{l?RYMCTv9 z>g57&s;6dIk4lm^_?*>i98#=YN6=D*N7mhs!r|iHD9^Yw!cxv9yDLg>JofF6-knZ# z*L&aC9FXJ}Et7WoHmv;&<^Tune=YYK^V3J1o&h~Eq`eI?CY7-|aij^Pi71X5P5pii zc3_$%KPFZnCb&}WL-?$Zj)uIQ}k`%lWu44SSd@5wWaJtC5 zer3C9mU~>m)pNNbe`I#g!TU2fd180?-DawYOWech93*T8Jo$lkh1s}Z`MZgx!9ESY zB^Jv>t88s+w)uN(fps>&+tb#S>~bV~N=xTF8rYbtF7|l+$EP~#lPv7ME)B@lhx8pL zWPn({sT!uWxHB;FHJ`Bh%ak9li*3cbd3(B8pf$c`FGz!AgeSeja1rX*)$^;6~sxK07c1Y9R zHLi5d!&#zQ)9d1=YxrCn-UnF83D_|@HFD2ZY~R z*cmY2BkMBkzJ$+gZuk80p};&ON}j(dz6riftqCWfyn8 zLLC~Bht3elKkZ?L-DxB5Sx3E!?bn75p7YnWr5_~$Fx1u1Z7Ni4k$n6N$RzT(W^IUfW?nC8@&I%dUud zf46jh#%I1d@Sw(6u;L_mBFt>U%O^TtOf@34jvW59=JIjQ5~>A$vIRa zO!*bn)n}_Q&2!nS-&;%AX!i65W+pbTO*T{&&Zke7Yv`vq@4vC1qR!iisf(y>#SfH# zcQ)%toMS|BM`l#$kiqY>3wfm4vc`q9`|?s@@}`_wPuvV#V;_WrQdkuUlITBqL* zw7q|p5qnw$TKpq3>i8Sb-*nmt7S8dM!HgKROF8w{tB2RvqJb`-un*0bwYLwT!@C>k zCVT}l->PXtR8}gPwhmpoCXc**Lv3_V8-2kWw9FbP*UO8&O%jt@F&p=8)~fH`NhfD! zESeN_JB8(s);Ga_I6H10`4jN=9-pt`M|U)OE7k=-EtU^4Vo5kkh*N9OT{?GdQyN@G z*&0$UX--FS(VCE~bFIeiu^A3F4qux2<+i_oy{2nsCvLhcEF}#?kaIWhI(x2~d85Gm zX@f(Xa9y-#MFPv=$E2{-HWhe(ohk~MC<)r%sY5%6`M`0}S_`aqK45>fkqL(NEm}~c z-LgzNeQ7teQCfZN=h_2}%4GrP8&a#~T8*)Sp$YZ1tuQ>S4x#Q5)&JO>;$tNmpj(Y1ZE61ZhtkSBjqg_h(qo zr5L$}fIin&f#Tf8S?Ja9QdGvAfd2SN5_9tFA$*8#)B6(mHc7L2_r1WEh2RfF7!aIk zg#j9DhASIO(vud9Kcej5&Dppguq#+W9n`G*q6r5%e`f{Od!kn-Y$M)Ib#B}qf{>C;_f ze&AKbHHuV#)@q7o2D98c$78(rsE40u3C44w6ax0?lCl=sy6H^NH1U*uLC9RUSw~I@ zLJ_=D5PBR)iO6S`V;bq5NM$EBacaV>R*Yu6A)Y511pKd=mcxpA3wup+-oBIQ|uXP(u)S2 z8@d@NiyF%3jMQ6uAlYmdJ+GRY>5*DDfIzRBhOhiM=a}nt+GgJftqv$j-tB~mD^Nsu z?#4Vpgyp^@2n6$GPE~jMxV2Qj*D{YAC;G!k8NQR-7l^Z;lFsK@vwAYVqwK}1`698o zrr9tD<80fr_P-3n2G@&>$TmPj7&eH~sENW7$}YPwV}ton9eh5o{c@>^aerT{S}+-e z^=IBN;I6OOpR{6>DpC&`#J#PpNtRl^Lp*r{#m~=LI?yfGN5yYQ(uRt#-W_`-{jlO# zut>6$)GJWAQZ*ggC}Suu?87Ukjbnf>3n9t_85(BHiY{hKg;kLH#@AZ!K-KHcUvVT zg~j{#{#;{Rf6}ITde5wRyv*}xP$0&ZNORVU_MkjwVbc{+W5bxYNwRIwkh+99ehyH?mEOXpDAf?fXUrW}(+V|Atp6u4P8AJwY*J&S2#h*MBn2nCPa6 zA=VBCN5Io}sNZ^}E$(!z|D;H$$L-_EE~zo0$4<-^d~^mw6XHkuk6U6BZ-~^snGddi zcE#(C3jRRKrvPldsP1j+;O9_tuLnjz!0F5o&kC)OdXU3vI2eX_X5eoB;Hms*@p%-y zmj^Z5kUm1kVJ|XiEpu$N-(tHeGB%Uw077jV;KYk`SdN>uCuU36nhe06Q75Kh6WjP` z#CQ?{cNgpesqv_6`2h~6nf7GxHot4*WZsfE$bt4C?5 zA``^yx3Fa-Tf%yj#7rSyW|GRXw^{NCm^IODP`AFd3$^SlpVJb>xF0x+<2v9rEC^|} zPHBn=*gPE-((L`L101d?v33&XA#K(tHmw3r?Q>XG>x;B021zHlpLYgt6qeXmBj!Gx z{#bQTf?rBc&S~i^vY;-?@KjrLCePm1(fH~W&*H>(VVXT&=*+Wzl7v?qm`9*()hk38@E=f6+6(EZdC|_pYGUExRe?=^CImOr^Vr2DOV?9I)?N<>kHFxg zgz0_+P&?rPbSBZBg!XQ9U(3!VCXGmIevdy#MA0rkuhD&6H6R5w&0fADlb_uSnK4}8-yP?IGcErad1bv`f0 z)Vu}w`rHmiWT5E!qe4x0r{o%`xVgEVB+od=i%(>_c5_pZKeSXM2Y#QnWiN6YXDM3I zm#w%66TV;DIdP^_9Mxrt{hlmDU|dk<->Mz^vK*K5sfx4}rL_GjS-Hxd%2KY}g%M3(oS5Ca!Wvp+9ZFJz1mtRs?N zrP`qTIeB#Ett3ySgQMWB3vPE`l2*2`_qXeW7{PI(n+L-z+R5ICpp^aeyykmky@|dP z0;|5$pnk^q(%QF(ATeJjTp4*eypRz=F|e~*e*ujUqmI7AeD8iTtY&XAsD07JG}cY{ zLHDDMCc99g{|}AKHAC9%fm5pjNQ!vdG$$Kq6cp{5bmQoL--FG}b!ith4vu{?!Ld13 z0-gg7%dj1Tn&KI?cWj&CJTBfkh8o413IivPe|Wi|qba|@hU9k?EQf&SCP+xkZ7mY_ zESzY?E0LP=Xq-uF_3s+<#W$JLPJp^}ng1yX)_+a!Vm2BPZ;t+Q>tCqii3M|r)dstP zvTwO2w9aDe7t)^@42_#q z7e4P_NH$Vgwe@TktB*88-p^)xKGY9F&J^NE;guSX#I~E&KpnK1;Xnnjtx=*sF@ca7_ z+Q!dY(19D%_2e`x?gd>?Zny4_Wne59$O(k}5LUyXNi2IW_0J@44)Gh2zM5GowBj{m+nr z08;Y`cS!Nq8!G*u^;YjM%{#f!8*b_!LAG+m9bBDRy8GZXc5UsXHnPfS>Aa@#=9Zuz zH2p?1CUwg~>{DoMYF=T_kfe#~(lCzumRCmB!X72lc34hhBo02-2~^y7e6(Uz8ndT& zNSGjHjg_XV))MvvOgNvG-7#3BQI5xBPZd+lS(bQL=d_y&Rm2$i@1Vu2+0>qJXF2(U z0^JIINFG@k_VsLEkV9}7qS@ExQdeKVr-#j&$C+f2MwWG#h%beKm?@xJ~lCi0w+0SaZ4@jTz}&F)fQD&@-}*Tkln zEqxc4O*+7HLm2P1h21I8U)ySuW3_5}AlB5l`AEXWs9UKaw-(r?rVl%zr+S_MBPYJ8 zRk?!tlcxhG*S?V-b^iT1F;z(%vCAMoJuu@P;xUZ5A22K>ITjpApVPxZtbS3b(A0Ez z=(gZ;ZDe-6X~}oCxJJ1C_63fNVQPD9QKAqqm(L>aOt3b*b_BQ3)y>MK0=L+bW3Q^l z%I7RgwNn1;GHKw5Nv^1#VhEPTSz~rzJG$7MIna2qkimm|(^w0$s@Z$8y(Syja9$l6 zL;ju63M2w>6d>DniV-ubOtWh}8m%t0d;Gx8qEtnq(bWDv9Rzu7BhW-#qwR&8{wCh)yk zX9nA(RO>*G{6c>9rtkhvvK6tU1orQ^Hy_e-D45h>3s&jbLYVftTP`hP5AI*m_mZ6NBRBiTkv4hxCE%lVCG^^m~d^zDPuYKKV+7IWAc3 znz;4Du(OQH{krG0ayMN4#PuO3f3~H072#eea>sPiyH7SaEKeAY8a+C><{Ou%N87eT zE##+}<92=(5=Zwnu=wnVA4ZwegU{Ml7QumUO4F;&T{5zkZu4O&*&XfLMJx3Ak;YP% zx?1J^QPUVZOop4&n^<~TtzMmrFCw{YX}8pf^(GxQQhOCD3?=_oF^Pu zOPTU%R_g}FpkdNvN`V4$3L11`wLV?{Jy>i+$x+?ZrVMF&`xZKKm| z@m=7g>mI9MzC_We*FUTPR&4E=cGE^A84C-nTT)30ug+D1Tkx*9S=AcW76v-gxSek3 z(j^mQ^cd$ZdsHo8eCx1jUsRIv%!IB$sO>G-RxmmGZC4Mt!~alc#&&I|N?V#r>)`ob zUvgkb>rNSM>sjzK+FrL`BdfmRey!BlL1qoVW&wObWW9;Bl@8r{C`*J}DWwid$_bSS zzVi?4dV+t_Z38o>ahIp^9x_BYz~DyW|0k@)`yqM%ud(5n2^p0e?r1v4i@Ibq;ZwhR z?NKXFW>>qI-d?l(O7noAFIZ}%H7>c)!V0rru*)B&p<{Fzt_c#ZR2&N^!$18K(hYrb zY%6CyM8mRi2zq(d86~lJUR{e>n-^J9s ziZpMB{+tjIbC55V+Ay7bf6!ABDY@FuF?&pZwX(QV&o3?Z!NnIN7m_DhTcs?r`sJ@~ zKDpL2-6d6idyCNT;40*`!K(j!1ixKJrrfQb7V@Whv&A`^e^4Y#op)U;2T`PZ*TwgI z?Ih`PiKmB@`VqHM`Vt_ptTD=jB^3A-4Mk3HDM_hOCj$8VOuE=57r+|l7a>r{B(v^a zglNKGWvEapWOP^2@M~iCRB=FVNC*mb_|-`Dne(9ftll8Gca~>l#(5gFSjl|sdDD)6 zvYAcREu{kW!Sh`)0YZx(XGu%fwd= z(+4XBXs8aT{S4QXN(H%FjIUi28C!IhxK8)Im#rvkm!w@Zec<6T{aNJ=vOjK+5sz#HZ%Fl!}*RYdxEgo555!x>+4WJx-Xiw}u2X zzu}x$_eJdtuewX;H;kM&5PC~|?%}T+Fg&`Ym(x-6+(-Z5v4UWdL}=;K3VQ*E*1Ocx zL$K&B3`H#j$AMR zu6%^ucw3Z5+)m7TeV~6JTiQSPB14uGx%#7h0L7RPQF258$uaT>pSj2!`iv! znMjA!7Hx})fpbOV5XPV>lj{xdrW9l8^)h-yW!{BvO2@azkaMM*GRqDm#~$0FHL=vU z2jf;XntHS($&{1-P~_l7ev&A*)GD~;EgNf_d=cg9R$^W%i=%b`J_c!TjWW2zXfoqX z=pe@q^0^XmxRsg&!&`Shq8)kOs=ZPf4I5AHWjv@U{P9>NnwY6>!9XYSxIXGOp-lF+*8(vxYjN{>>wOsXrB=52$n<4~ z3y0WuT!D0cnY)Tm%2kbeKFX1p3io__ge4-&fEWD-GB9Jh$m03WEXz~&h>c4YDTaJP zjn8ZII}4;)C~3l4-_Gwmufc}z)+O66RX>wyUtUE5b8Wxx2-$nJe{X?S!iG;*+kEjH z@lOe-4>BlXWf8KYXy-J$$s3L;X)UMJC?|jKpgeypvh(XUfN{ zfbc?d*HhZqxMF;OEEFU^o#(dl#_@jRN;Da(u{oE%^Eo@9$csBICBI@R^+Tf|hIWOWG_W?O#CWMj~EU5|cP`LCas?WS(RPCbY2O7UD ztn^>)?p%iVT9tE&ZzBK@_GWY*3sOF|mGKP_#YsuQoPp5(ko%d>iua!zjg3mlzf>Uv z?S&bAI;-!^_Y*U{+zFi-6sY6#{MQ@B>D2^tpMbzK8Xj8B1U;im!g2~O{{?QSoBBlB z-bl7wTA7Ypplk(soDEAXJ}~_+&;)_XLv31JuLozZ{UXc#V)px=L}CU7lhB=SuJ1SS zxu5If@>YPg*yofn{p-dJw2bX{ArWNMPAFGNcyZlsa+(!qy>*Qu^`3=B+<*NqZFVWd ztb`d7LhY6$%*#uLw%dK=Z-X*J97cz)KS>;cajlsQVL!1(Gb;?IPV|6~xcWm{62*$! z-h<%z>?j@T-u)kv~`p0{A`!Ym3Osm1Bc*mRlv9h8i~)|LuZ_;a;f)*~l}c87 zJ6io)&cEGWnnLfhj^NE!T;@iRNtv{L#Y6b+_He^mu}=^1_-gr72o^gFkyP^=gI6uH z`H~v-_qlZL=!X3N>={UIF8v=H5UK}M@?`^uz}b&heA2mDKL9;a{ZpU*8B!*%7*VwI zG9)bvoy6k<6gvi^SqE93vfs`PQ_{@r@{}sUUn(~-By{2cypk_Z+}fE}MY6r|AeZPT z41c~wTYG@yt`blp{6|ex4|)NNvPiQ-Ws)#WxdZpD0p&Y2KSB(Ly4O(BaaUh3hB>~s zZAZjXi_yjWP?3Xjo+RIV^*M~O{IElguDt=t#dvkP- zV7%z3miJ{y5doG1O4E7CDnHioK8T_%%pw@EeU&WsZo{&$fE>V}BV!num^W8H3QI=4 zr#&3?SqP=AACxBo&tg-Vow2m=<8BB;?bt|_A&&s;?pDR_g9c9fGq{n>RvG80O$n6Z zGtRrEXOL2zZ*~2d80Y;nmHjKWX5y=3S961=vfxW}L;LdJG(?UbltDTrOm*LCZGY+9j-{vtxNW+PmJbuELa}dZWp)YdYW+GYIc;K{UCd3Or?< z@%L&kNNfn%w$M5FEe(85E~qTAb$cP7=Wj6?i&@k0-y~wwNB5tlPCXy1*9aK7N4qG^ zr1bwiuFn`=t6hn3UpWhxx4t*l7FcjS!%RfH*bh9ay4yw&EQF?g5B7|*0W%;>doe0Dt|%@|?grOou*RyvB@VG7 z#hyDOKF_xg+UIwQ<+Ec9V>-RGUHCpl~)ouq*8Uz?u(MsmDoQ7kzgBRt{ z!>`mI1KGO}4IQ-V6l%wX_8OUDP@y6oVgxDaBgzK4Porm$0h^qYhjf#|^Ns`FkOU9) z@1EH=j!CSJr8Incu5$3~N3@&oYT9jh<60 zc?vvK#fi5eQ>m)M{KwOhCy9?jAo42y_b4KHNKNaa$3tFO8nU;9Jv1k)JEar0B|{gB zV}&?XS*4BM%FWL^1VQpag4}q%Emeb+plfAid_qkXa;k2qX)E5t_@EMC%JQlAxx0{! z`?&hwk*hg$rtIx%j@iee?dCaW09!xDo2qV9nXlf-39?x>TI|El+&{p|m78=AhHy&= zDAa?k`nue`oXQpbl%$n^D`&X8l4Cms_@6IP^^QW5SCWta8}rHmMhqjk}8ZZ(TsU3n>Z&-5n75&j{fem3co-#A`J6vqd*Zc#IqT)D?FQ%R1Pny27 zv4ub~k-a*TkA54|R23(&KWHyo7lftdyPQBE?mZd!uBk`*GtO(_cAPxERdEvEDn{R6*EEy8())U@k%dtESD$=feV&0qTs#P=^(=`ykutYjg2pH&o<3AjQs@obA zOFb!}$b7@9{5hNr-dcZJnR!?ET5aVHp3YIRdLNb9Z()n7+Is=L(o$n2ree}tcY6nodU|8vsURjj_!ofX5+Zw`~iFzFS>3hr+8vqq`%?<1!$YiU#Hfg82+^4s~B z)Q*q2NOh#SmbBgvl~G+fr<5_|Y+mY1sX5s~{|oW-udHOrjbRots*lSMtFi8Cu2Yt| zi3pU63i1_J%g3v1>}h9qSBPTLaLr)%WD`9m>T(=p(nrukfGe(%WXa4aqOQ*(%^uE$=BovrY zM1KFf-a#aBGMAnqd;XOTg)t+1w001z_hVQc%;iCcuW4u~0Y2oZ;`0H5Hs&zL5q@Wt z;lmlUsAHuFUj2yHY-zIk#m@i}KjK}wu)%~i+Cm;Zm8IRLR!5J5MoTi+mL?h|ehSy# zi?$(o3QzE$E{aZd>qGRYU@FmYlCToZ>-)=(wL495|H(#S%;acdT zw4|cxXqC#r3Tk3m3BU@??aoU!)P&!w;G~bB#~%>~d^@<{1I*IlD7a3({7J4&a;Ai)8D1S2# zxDb)1v`bMQ_omOfQ;ydJrS}OAb!8vOH`T30he>f&HR=%;xY(N-n&;21=l7n&TVK0H z-Y+kWg)Av|3a^a+#SFe0&0E{_7Nnet>V2j1EEFQN?I8kpZCAtbzvwtzSaM)knOXnm zr`1O_fn`QVhYV^W10Nd0$I%1*TD}q{0aC9L_OvFsX$^kDsZm5OQ9Q<0yKszOqyNG) z78PQXgF}L^x?Mr$_pZX&HZ~Q}G6ORPflp|RLvm#-3&c;W@paLartS=8;JS;Pw}_BT z=@>;GC|t&u9whOfPDu_QQ!e)AT_>ll&e(g`py~nyCO}qUwoFBW1@0wiDl0tC!|C+ElTe_pfaC{!B~M zerpgjm#0Ua+OC-ftL3~R5^!IwSP7{&xH)=(Pw-pdqn!>>hj{?-mgXVLw|Jc|#kVz# zNtMVvpl&p4!Wzu*>>BRRaV3+tgIi;}^#hJ;nXlB2p|d)!Dl-3*6+S9(!#SVEp18gx ziubgNu2abjUG$Su&RHhM>!&^}kIs~-vm8h!r zB!d&VZ<~17zL8iNcXh_^U*ayh%IV=niFnce@^O_1->21H1-w|=+RL4&0ZOEqDSuD* z3Qs_|C8<6M_K7gK?~r}^M7y@ch80%Sbu0?wV4ZQ=^ypVv-8I)Yy<>id(Q1Eg3NI8J z1IgZJDjan=lAq9+uFkrW1ez%AUT@e;l6MOXaUJ!PD7b4lGVa@JzRix?m<-V&W0DJn z_)86(mLv_pc_8}JL-(wdzZ?8>==HNgzwNs>LC8DJW%Z{{0iLdFG$&irO|qV&`oTuO z;osFGWFBSTz`=>XsV|o9R|IUZRv7qgzN5IhESWEhbQ74;&$c9oSu=mX6m6ByK7NiU z29AcP2h(_uKR{JQcF3BCJOlzP)2!VBtme8PT`oSaa*b8ZFLZs&g;VIVoTd3`ZBxNh zbXl{NohS|HH6!OA`2u1X*{{8E2r_u#ENZmFJDZB9PBIM~jRNv^1+U}zkp6y+t#4tm zLO9`WU_e=;)^wXOs6W3rz}Vjw6JXt#+A~8{5Telp9<)AhEMP=R$)_zLN7r1FuW)+V zl;1nv-A({IyKx7-pAW>oOg&#woi|+eqvqvVu+E;lT4GDO-NR*HSNC0(5h_MfDv(;G zlTO7%Hov>5i)TSdYR!+-QkPS@KtL>)HbNNP_6QMb?A@DY&BxRk3toD!qoV6i6QRG% zt#GiwxqRr@$JEjedyCPW*u|#ZYq#qoeIE{sesfTcozBI-XnENS!YKxRLZpT`)}BR# zzKtJ6i(8KTRJ#l1hPXA-A<9rt^3tBG>&44NCNyr`KW&vRhcZTfkogM)m|~z_rHS|t zO`Dn;?fkwxs4Cp}qDaQX?SzO#b3kuOBh0-WNjgV1LRw&DcJl4!fy5WlXWR16}bVrE6kMk`+t*iW+m-kZ*v*GY-`HRF_G6lC0?on4u!Klg=+OU*Vc z4GsLK((2^6(q)PWOGX5F`3q*6&_LY*X||-Hb+o)YDkpAMlUknD?)Ov^VI*zmk>{ON z%?pMBxI}_jQcXT50_eLrqzG{JX~4DOJ|_;>OUi%Umy|yp+Fod-qIus66Ns>(GsXXd zzr#$V<#eyohwVK+Pb~Ds#AZTc+@E&|pmoT;h_3}>WKTebw}aJK6JMwNtp1^T;iCU_ z@zUixF^|(s_FIcnMCWiFW$9%L2h5;}tCZDm5xgK>i%X6ZNgdW4_n5o3k(AD<^4RlF z)|Nbj^o8GdA3P`RRnG#Zg$)-CeOiRTin-FwOx*Z~+tu4SlCq!_^SO^5S1u75tn9Vz zo*o#MQ?~S}8uEfb_SYTF9j{To`;^WM_c^3tuqmXAY<`~-5%;J)#E4Wslyy&=Uuq3~nN>2qsody_X*C4r-iCDm?BL`LD+X7vDbX~pDxJ5+RrU{AHC-1hA zZOMMZm&9_V>`qx=`@4Vuj;!Pfi2o?)fgHPHM~BfUGBSJQ?5Jv8X{I`P<{ zLl-t#si{hFr_0!KxAApDSyGYwLbJJT;WMIBBEm?aw}?%n5!+pbz!p!`o#-3*s!A%w zHwvP;^SqX0=;7K7AgkWxE~*})Z9Q0hDDfaHeBB>4vzyGCD?KWF$?uAa0G9H6>V_It z>y~gxO2djYwq7glwG|x;@jnm+A-xMVF+6NS>s0^wMKLeZnj8FRxSk@T{`lwyD(%AWa!~-OLIs zre1T>l`ogG1DA^GDUn(Zp9og%KYw8H7qU)15j8ZIe5fT&+eNR_N-Y$HRa> zdyOVP?P?{sYxQK^)vCy4m3c&@r>Rz8tzH zjB4GHz0v-9{~0CJN>oL(N{gNAM`Y*Fm}Nr_<#+b99+0mh&0Qx?=iskg2v}c!ti$B2 zb1{1*!v+p+Ip@x;2Hhi>qx;9zG?ev$XWnbtwxa$UJFi!lmUE8f7+-&Asy{jkkk%%m z_?wl_S@K5QC?s$10x9ul8INu~hbykR1NNer-;1v?WPzQ8z#jZbx8w=3<&80PEiHb$ zY9)mZ=Y;pDbv#jhPCjE^r}Dm6Y)Xvw`MK)c!eHRAPL9`r_1x*=lz6g=e88w|S>kLd zf-XGi1OGVDv!^-;M``7Qkl}@9l(VvF1oX#vF%}l%$qD$@8<&>sox9k{indTOx$nOu zf-yB0fE!s&cp^X3M6E*beG@gXOVI&9Of@%`Wt??e-8QQeIvc&VyjZDN=0k1R?uyan zeji;47F`TiaDNQU2fH z`;7%JKUUZJ!pc#(O_+d~#kcmOJ5AK4&TLB!dy#N$r~iZqk3dCw;5;NHDosq(?c0j@ zkdu~%x#}xjLaV0fX8$M0vf9Y8y2F z{(#KIAbgBnOSaK^8x3n?LCe5g)%h+Cl8NMvVFQ zYbiRSbhXLVa}x|`exRXQhRg^^(8qbhMytw5%;mpdEnmHNJg=m_Xm@=)7xW2&LEUIu ziB4USpC9`zY!G2}`D*f;SF$9Ve!{w8*2U!G&y^6l(6kKAsd=@%`%dWZl<9 zmC3M~C~+v0J?69f8W1KKs)erWn2hiG)_UASo~DGim7?tmAal`s&kbUH*RrX1?7V<} zhuuwEcEdbhNBLh~zaZ*14qHnBZs za$h)3{<5&gvoyd5UH8W{yWFAJ$q${k(9h*xe~=y7ka(Ul0%LmwRq0f5zCgVS9Tzno zkrUS^DI?C_B3+ld^26S2cl1mMmMZ?rdsrkGpVPpq8eAv2=&nbja5w!uCO&KWZ(lI2 zn}=JuDiv03y?zwI)DIX2mgl93-foiErE6kE1 zIy$d@QRMlZhdSdU6<^Udfrw>Y5z+D4l`qj^8h|`A^hrxv3@%!|L!*&aALT;&qr8uy zoqcxsec#pdXKVXf_$}KXw$=F-v!OIq3+W7!-~PKiYSa3_H(ndf{)Vqm4$y|6q|Lg(-SK%D1>T0-!Hgy3heQ6nq9qTfd9XVq9-wwFS`az4-5u<#)ANCoymXT-Nu{q2*MaWf?oUQ1=N20pCGMo zF}{w=j0v8-2*M2!NMOoYMqtLfAP_Y#sSTDPQ(t9wC3)PX4lb6ezTVNBwEsSo6fCkf z=9YX>bV5284_Vf}aZJEcCp!FXx>wklR6L&jjZFTJ=jQiKW?)b1W#Uzhsj?0ZTJD0M z$-06`-E!J&wem&JsWm%FeM;Y(wc;EaDpVRE-$xx(FOh@`GCP?otTxm$0j(MeWo^P` z{uD(NB%(97amki^xl=%$^l~=oeH{R4qh3>ii~OEJ`q*f?)vs}&5@>_gjf#FB8!L)Hi%r`Q!Jo< z$ZC7touAZLOjS9#@Irj^Y+s<0(HD)CNjVd}@Q-E6lRorJ55AD)P+if*%XM zy{Fi?wW)`x?w!$l0}Ek^(p-a$e8NNW2d!@z!r9W5_(4V-Ce=YW61sdBI7+-+;7=g8dmDTfxAw$hDfaK*qZD2J3&=au+W%f4 zqu%1c*HU^3HU@9r1fGB`4Wa^m{}Zm_Q4Dpg*b9nT$;v2Q^K$S-j@TaI)B3n7_tW@X zy@OfEuD;KF1PG{j_)_)MFdK0JHH! zlCp!)GSefz&#vKF7mPa!4;6c%*FC01|KS=#zo{Bc{YJ~i2Wx&D`Jc zxkJ9D&rbLh&){JFC>ytq3#k9-*4|jDOVBeoQ@*(1`fc+vna7NPMo#Z%l4rtA=qHzz zUyvSIydH#Imdv$CuxI#iJbG`}vc(b$NNOjStv6(2QxCT0<f7Vh{XQGcq`DK)S4x?b~ul2F1Y6Wetj>i$|rTk9T3A0&Q@Hu&>nSGATf-6!U8 zP~5#oRZ5^=I#mNFL=nkIP>v6rRT(HT*x*`XOVytaKEZD3o**>BF9=_ha33tZnJyH3 zmKyNB`T*y7(4qQgZ>*PBHxV=*yJ?eEY@739-5d!^ zc%MQ~C#-GMEh|w`SSo9M^+vwim0QE{#kfKZr~Qg_v60L91q%OVpNQI1xNzw9<$tke zhY$UH{$=3$!@16x0=pxS zlPNqI(O>yaf{wEM&ENBi8rtUQgmh+5D;Pn>8tUcu0cEpf*~42jK!WjA^#jy98(*a7uBhn-~HsQE0S8&jW90!ZiBsaKdSkDuQ|Ohb>NKIWJT4COE<8G!|ub# z^p+Jl*J~W2M>ZwMj$0FjB`x0#q%$SvZRkG1a*AKXhd zf9y|2Y@@{kmMmM51a` zIx4*VmO$uz(hthDMSUdKl)~8Q;0GbL4SKKRPKN0W6f%A}k+Qzu`d=ePp~{f-@11*@ z7TpnE#Ph&Li-h&yrED+W`Oa&VU!&Zs-sKH=O|PgnrrS??jmz@;Vyzn|6vh{(^TN13 z=8R(x#IM{E^S~im-^NG~wZle|b0ah*(+DBSM^cptbu(Sc1cQ{Da3l67z+%I&qW6}I z?LPPKayCMf9ub6LXKc8y$HL*AKSoDu!H4YO9v%w*xzU@N62s3s?UEeimSpJ8tP&z4wnHz2#p}Pmyfksb z+tN||eN=Gj)Fu|1RLYolB*M8N(tJNYCF)nh#nCHjmR4Nd!ry&lcO9b&+}dx^k455_ zzm2N>Fg_cff|9vZBd8ej&(BWhc^LB0q1!7S7<_?mlBV8yzp6N@jjhl56U#585a{Cl zf+8S>?>#UPetGAT{AZfctNQS}cTfAGE-IzpBdZU|qbu_1^ofT=o2n4Qh7mpF^2S}R5z)LLWlGTuo%M6W&xA_W{z+bE5B}bi1Pr@wLG36B{I1@$ zz4;aghh#TD{M*uQAeKm|Ll3rwtNROS!Ip!dQ*f1i_VN6R$x9bi;yq~9Vo8bJ(~?uF zy>=r31sQWMHwT3fXd`vrjSn`*fIDH_mghE>-f&3`1@f6QU#S^;1ZUPBepO16tS!G9 zY-050UNEK1W~vI-AD0JYh5G+SMIZTsGxLIEpuORe&4@8;wCr_nJ%(@0FgP z?^7x@|6!7UB#3Ts{_`QeI_2|*EQQH~ryDOF>y5)kfRL9!NO7%TWldpaWO~8cM+C42 z<;8ycvki&b<$yu%XGB}t(1ukFxdLut`^wU&OS(yFVK@VWFtR8InfuZmI~t0$XlY+* zlVNim6ARGV29qLTPm+-LgTL6cWC#2MH^^dWlOQgK zX7*D^8b=z1&y}yEiq9R7`MmSnDZ4}a$%a)se(kf+GN~`NMp_4%(^^n5m&h@!pU=|; z-g8@xDZqTWy|NXsKC-`Y&3q4*x zN?lrgvw1=2eV_&F=o!xXW}Fnyx|9r(Y$dI}RUq2oP?y?5$CfsdN9ga|P9=aT4T<89 zN%laXHFy8#(!kou~?jTlWK{BlNLK_8s$6O;magH z@7_gdc!;#ShcXcRNw@G38mn*4SVuJM2v30f=+chII$sgV`E~`eX984gNY5w*SFU?R4=dpp6pd^c_U|z7#&zc ziobTPw>L#88HSxpfFJwo1l*$e4L6(GS9>2ZzE87PkbF;eOpl9}W=bUZ+a(M(+W7~x zC6KK=02i6KEPyE{@lR53$~GiYClYtRVQqF))}@G_b#mP*r5nFXE%1h38P;IZidCD* zX~R=>DKlhQj`=^OqcvjW_41lux?)Bre&;PxS)5{t$!bYMn)aqI{d-cIct+G!I%eY@ zNrxGDYqan#L^D9S<&B|ix4T;14dKGyRc?f5&Vz0f-`#Gov7F~X&UItu#(4F|4!8Mh z_gWH>(co{uU`l+ z_t<|qD$eL_2A1c+TsD z){I&0fgxa;m3!e5JlZ6DF}tQ@FyFZ1#scpF*z)!h;ts(ahY z$To4Sd`S(^hLL#W#K#B6cQpPi@_NQ6hg4uS_Gmy(#b*7w;fQ37!yIAz*n>j#Ehi4B zUYEKzOQz^lGf3!j9-$U7qkkD(x*5egHGVYY`DW*J4!u3$g0u|3ietEged{c5P|6S} z`OR6meHY-tiLlN$25UH{1WyToYSIZUiZT;irh3LVr z3wC^!{9%-Z6zJ9yN=b_RKnyS0OmD10uZR|!d0ZRyL9SbtlRD4O@jd*jz3)Lvdr>N4 zFzr>mQ1kX?0{?VU7YhNqd$&bvK-9%}RL)#m$upul&Pwj!3qVsb*1foUO^4N`8Lb>} zbpzME@<{7UEpe1pdi75+6<0YE(HS`t`6&oEY%NtkX_T~7P#Lr7GS+gjDU-~nmf%+_ zsNU{f$AavXhXPqInB&=J&d&7(spteRe0T*{RPNnbbG%5mlplubjAs4J`|%%=GP4s@ zx{|(N60mz$v~G%yYw3KZ)S zucn_0)PdPa2RexQV*fNqlja3i5#C}lf>8yDxCNYioU#*pfzWzw;icOwEWe4>wjSJt zUJL`XO@$tZblL#|=u>dtN7bg<%ch9I69z%qinI4}s2W8>elq3LskimIHDM^4udrSw zk_8FMs38CXpmDs%w~~e`pR!7-l$_CJgl$N}uHYi`E~G@A<$F9*2XZYHZUp$Sg+6(NDZvLQsqrZQFLdRc$M25dR*GwkIEZNz2YworgfK{tI^0CB6|{E^ zKq;_)MgXK@xtnad##+E^Em6-_a&>m_9Vu3*aW<}BjEdSx+k{^+9`*D_@eXaMclOn5 z27EQa=&*0t$ULL}6EXdla{o#~^>jkP*@d+BRTb-%746`@$S z@UXw|eR_=)Zu3Q^8?1fYO3p7M;?;y%Mv}UbtN&Ti3E6}cW2f*Z%t!ugS>OXw{>&`I z@<(49i&OP*RlOujrrKYvDEe&;!93&%&4mcq<;lk5b{n24hA$gIOKmEIM$YVv$MzQQZ4z?AhIqrX!2rDopILr z?EoV{ym}-kNs2GLqpNDL(g>D1Yl=IF3GJA^DxB+E+@a;=)d(y!TBW`ol?~mQmL#^H zGN_H({AJw_0W*#VdOBy{h`QYyxgN~!ggFtClKm@Q$tq{R8~4u+mpCmlRS2KWK4w8v zF#~Zd9@lbX;?2?Y0&wqTL44n!X01`s)yY~N;wBwMQ?(hnT8CYoGr@5LaRwunKjV7l z!-a2cfv#yxpWK;({3C)k{I34rA*rhH;tz*jSM+sbKS3&HPPTSLV%|bLqqnBAOo$nd z%?o#YX20})gv<=hx48=E!cYDStlp|jSHi5Z1<%`jQ#bw3rBT81DX}(S+dA&9B%X?T z$GcO9KN=C2*@9VPg|gl%)BaRPlcv9=H9WqFzjx){&0O?MUKp2HrEHlz`$?b0`yhoax5uKc6=}lIJvh2JNeslG@zFo?Ktn z8%>c^Q0((+twn8G=eu9DA!vAhTdRh|+B4pE#%5JS&gJrQO_`(jJ9{9{yQL`Rw}7op zEG>Ta6FY4H=d#^C4jst)KaQ?6F3I%mHq%VbOpDW4nVDKynWmX(k{i^NX>LqfW3E)D zMlR$oDp2E$Z7$`S3s7!kE~KJ{3sjb-D5$8Ys8ouGh$M)}{_=mn@C_b*&wby|b6w}0 z>m043bY*QNVL9Ym%dPl;6Yhm(7VhQ7yd$s2=R;RT&9bGp0=Y2-Nx((N+ zRQR&-J1>+WuktQf{Qmb0S;-ok`={R*aYX~mKeD7I(ebSZNI$1__$kBadZR0Qk_L=a z#4AZN1?GAsui{2_L{6&ondMP@Mnlu;1MivS+Uf+bFr0kU&wk6ly9dLWHjmZ{vExLGjxW&D2H8%1 z9t_(nAya0BGsg_O4eCuD30@jU)jDzT0o8zYi-+HGVaM6j5EGxEqVMmHTJSOe=m%L# zmxJWTpB0uBZq|6Z@;CTHu}VYVjP)VD&_5h%XFK#%Nn%>|dN8fh!MvONML+IERlDKfh`yZ&>NQ zQ8?&d=*vK!FVD`M_d-=K;4?Z9y}3HC&WF623-g2-Aab)nEBW)26E}>(KL@~SDW#ZJ zyJpdvW5}+HQ*WLPYl^V3@2R8+ULtK6R<}L4ZL=6UI(DS$su830+xP087=voxw1Yqs zOw9e-a6@ekJr<<*YWkI7Ey-rt>x`|LADoCe9$&cT$WBwPaHENuku+sR>XdPG$4Y*G zHTH=679Vo=iPU0I=R4oRLn^B<<5OPF_g@2{zPdx;=Ux+0fRA4)a8GCY*`X7 z$?&P)L=#g%nQRyG!GZ^56K^vH7B}hnvyO@T*MCsMCWEz!9dGBsWiyhWhTDku#10RV zho}Atf3|gv5%_8ZN2CYmce*|bdw-f)z4TqsVDwlcb-V+FF5bTJ`u-I|X>gjZ;&)A4 zUcrcyfFbx*6OZ+HevhNIl=4^RbYEAIkqMCwDeGLK%vi-PZU44=3kIB0_r?ynx#N8O zwY;{qYs4GjU9(TR_pA*L_)P&e!Eci_<1AkPbZH;nso$+H5o80l1D#}Tmcz+{#5pxw&S7Dt!7Er{(`@rkH}EA3O}|^p18?) zY`?rR|HF?oTS;}+;;@OSm<)_QLG5|MG9x^h+Falu(|`Y-gf2Oh^gj6>pCNH6!M|p1 zG3qDY{p#@PqSb9h`;;A48M9TB^(K@(5%v6t(?)(s=+yg7UpSHRd`F_=3)=ZUw79(F z1PwdLB= zYE9@1&0^oj;k z?lGQ7DL!Fw`nBVl6W}Kz?}GhL8WcPRJ+XXErc)iE&nua?%prgOyho$w422P2d$dIs^ZlsP1N7*q+H)Ng&Rv9BXLaaAM;19V_1`}npw^JZ|jz-Y4w}mokh0? zIx$U(x96_xqs1&I5lA_1>C4AwSc8;5lwChKpGv#8Vv!0b3}XfoN60`xYz7- zG8M$tR}tPo|E|TA1=tsR<@N(3vT7KdDUoZj*I{{x=?ia?{%gH#xB^eTlC`#f!DE%V z(6cq;=3a6*+LnN8zDCtri#?#MWQ!=TPxJ8d-K z-}R~gfnIZfgnw8KOuLBt(HENDy%h$Emd;~yzh8%GeY-yaG`Elg5b9vx2lIuhQ1C3( zV?=pv(Lw1sdNubt)3g12#>mdjO9m0#*ymCElIkRNLrs_I2r~bdP48C6CFWZGchCdN4v?IJjS=zDo+-#=k`@ z+-?=nDL(BTysr1mt*T)?+bm@SCl8*VDH@iAti1trUofS76RAdH;bSopI9n ziVo^_Ta?@?a6)2&IXVg7o}{fWpNaL;SU&kamMCjin54KT`Wf}HwdDp7g=r)s5Xpyv~@`4}^<1_WAp3_UZkfQpFP{ z4@}HlavkKv+~PzG(piu+5wu&{4B__Y`zJCkCWz8Yz^vt!3By;-;5R%&1PkOE%1&BK z`m^su`<15Vi0ZEI&AA}n?gTP#qP?Kso1|_YN$AzDY;T62J+-7E4MPRb8Uk1c-nS+k z`dLX5%^nVZ83w#g3CNOqqfRW@e><@V*!_1^)2hoKE0d$m*!}XdL8D2?cUyp$VwEly zXo|k17gqp^Q#;lH70|cItkkL|8FQt}Y1-a!{}~G=k{;XC6#X4e=!$%@p-H>sbAjL6 z2N*JqoOv}O^nK0p2hJ1L_{pD|kcX$6ogcT6&p(!sy7^euzgpwB4N>WuY^wVWDCbjg zU`?bQXhirzN&vWgx(Iy(?~O?GO^YOKGr0Bmhf)Y38{u+^ewTe#(VpRX`j3K^ZT9<8 zB0o4WE8BUqx6Y}X;s}bppmPi-zv~Hu`A1|Zx;=&vL!T-f!rzif{A}zJZ(O8z@xFd{q_HTWIC@-OJJyKU=Umz*3 zu8l@-dV)&M)7Vo!y->B#+tEJf<(srykc`z2`dE5K<1)~BS{m`;$H@krzb$Lqj^`+_ ztu>`dqmSA(an#ZWJYJH|m|)+lX2MJXmf_-Q+t?a?yJ90>Htw5EYD<=YBJ}xGneqj# z9+_#c^=ku<<4&>Z+J4BIJ&@e~Z%IOPwn211?q3!VqM7jf6VLAeb9!4_k^E3xDP5HF|2sUd1?=Xj)lkOl{wB~4+4rO5eS?0N{z`JRc z_PhLD_&rzkZxZ)v-o9z$7n5S6USC{y7(ZBZkXxu}$v~rNtZNTS?lR6JMmqRKHyRO> zHN0KhNwhj@9dO-1xq2%oVXQ8sHsSjEZ-Xv3m%EX8ciR2*_q@&eRdpJ&d#&sA&;IUD zG@03Tw4n7#Ki>$yghnK4Q1u2^@cIfv6B<{=xDDKh?(8gnaY%z@kEMLEnA(!+K^tt+ z5T-6A+EkC(lenfrPbU4-*Q}2kMWDfUT>YkdRy2yM#y39~jY6_ARI9m) z$S|4rDsBxGbI=;9kpOjErU7$*&e3xEDm3vb($FH{J(;bp;D*v^znhv-k>M9pJIRLs z1_j=Y+s9IzGM!OlH9=(+TlwZr@bt%Sw!0Rk8h-+dm7n5HPQn3hVbml3a$eEsQ3EH_ zwvGoGhbG_w%7;J7oTOV>m8?nd_fHv|Xh%4KHuWF++=+J=USg7MgXdeXf~F4m7)1Oy zw(L>C{KIhS@O#o&-;Y6+CJj|=!80n0t0lI{UwO?X+lZeqZnfVA8E`yksr z`v*>>B?@0>EJy~Ho9Cpz8G-kl)c>%5DRH>GX{F=R&{+u6z*0ngs^D6VF~mP;3NJ^W zCR{L1PDDbcK9#*{K5rI*I;7z#{-h6TRW)%rt3leSzHXu2+S8vF{+BMGP&}M?Ln_up zmfjs_J!W{Lh6jVnu&2m^uT8gVrKcz2@%d}1=0Tb|^`gdoHo)z;+J#Ont>Ueth7vYf zE<8Amz2(?v0nfe_4lzIhZzTPmO8i@QsHTDmL4NV^o(Tk1!rq`-b_w96R~V|#1tBfV zhf?1h-?62nzZ&A25H5JS9^C3l!TBt;Iky>4cU(pBD%y>B>Fa82m;7Ga+-vQR>JI+y z1fnldU-GBbmdyu$cm3u5Pa}ECyr=E=4@ds?@0-4(`u=||{ps2SEp3WCaPZ)-UHa)+ z@82@t2DFCy<&N==w+*Pvh>}ZSu%Kq5sjiXC%4wKI6Md*<)^XK}FzS3~KV^t0Xl6T; zXKd*Tr!kNek)K+W{-(CPOJSV8LL6JF=%7_hnn{A_r}uCWGfjS$4Qz3B9IK#a0A)5d zCU9dbRu`k&0qn_{VdQrmD`Yp*$4==V@5|DRu?LUpp2&Q;b@r`V*I(j0>HhT-rWSXQuTx~7RI{yPPy;XC#8pr;OZR8VQ(>fVTvBam?YlBlfFF3?s$_3U zJ`O-2{wgW0FVF=)pr*q8Nl>mU^mr>SD*2O%q&OVT8YQV&i9shl#lZ+w=WVn~31!-U zH#r`M@P`O932Ama(=nHb)8Wd`(eOr4tn#XU3HxGh{`5^s_47`?(aq&0K+nf|ly_^> z5L0+|DjW8&FI5GZLhAx-e3!)*J&6^x4#p?`*+ zI0P8YW39b`rB)sp#4j$hR=w0+pRHSKl*#S*ZP_b3%iN%tGUMC!=Z7cbNXox`!-`4) z(U>)%(?2af?Z=}ZKf;qO#;nP~4NurQ=>dhfruI|yn*|>7w-7fukAQNMzweCN79^X4 z1^_qCQD^dbBIBA!2^u@&g3sz>st?u!l>CDNYkv+BJbBaQwRu0%p=xEp6ra7fxDmZ@ znf_u%TuX118dWO4mfrlf4ssXAM1MWR{!{{6Yol8#FA!i#-Z9&T;~Za*@Z(;4N%+WH z`a<5qGf2c=6!3lOfS@yQZf=-#+@Lv738Bp8^>wI$2;g6a17lTLIj1;#rtLCO=r~IP#d2lDC4O~TglLKAo37b4H zmfj+@UPnXsb!A0(V-z8>CV7^LbmG?X(*9j)x02ON@hKXtH+!*8_3cIPbUSY(Ch)b9 z#FUZlBP~;nFIbw=JAIrCAo~$;n{2y-RS83|14ic;#`hnENuTVM_v?>X&B)6|pNo>l z1|`*})IwTyyA(`crI!%U?80V@LA?*^fI;PeHv@EncqCnqQwtp~FI}3a&hna_vZG=P zBUy#nSt{sIg(d3@5IJaBfPZ7g!}r#7evOy8Vd$m2a^>4+FUZuviL)bbn+-Vg*CXKc z_00Do&o^@nPAM>HOour3I1LDhnSoWsWyPBp(ru~+ims5gm$<=G;R|8}-I zRdJQ$T+2&5SsZ1hID@AC&t@poW1ylMOf;BQ=qlsNI#jmp5wK%z>1okca1N`QKNmhi zq=5>0e{1>M3GME5+&_F^_1!tlrvYVbD@fkkX;g-s`|vJM-rF-w%aV;$^rxWOg^Igz z_ABjkn?s+beH&L_U7`0!Iq>I%cGDXz_|4orMtu>VXw;bm5YOy4lDS=4#pls8p0FKLkZ*HB9R| z-HoufWtO!vuRvh4zoS#}ZlNOf`@c3h7Vm?}NudwE?7977WTY{emswN@HoTksS=Vn# zl>KC-1izNvV68oYy)ON!l63d-Hi&S1Ey+?)SzDEd{}hhXAy_&$8l&$?Xv!VvGz>lR z<9BP8H}GrX?a`aU>LgsAL?wTilqakoUv}or`&OMQE!5-QvIdAJXX3-{P1Pv`ff6VD zsjFEywHTFbgLcyHPd@1eygvX&?+98`TE(mMM_P#}!OwN4Ge&-0gmW*fEaj8pKLA^1 zE4h1^`6|H&^g^5c{0Nb5w(Qrx-051Wm42m%9&1U zWmUOBeKQFq(V5UoDUHsdDt%W-NSq%a+uovIl5TkYOGq^}U0v+ujSIR)!-KQqMeJ@MNVMfa6EH*nrj4S2>1sqjjs#@5f~2J{6)NbMWo$!lRIFyeNOYneA=P zf?<7cKZJGt=HnH6nZXO^L5rf1y+8rEIwp+uJuZ)regH&!jnkVv*>G8aN92?7Nzn5q z{`H{W>#CrGPiDuN8mrwYG&`R`d%0EZZiaK`c+9;oWT7VfR{vW&617GjZ=Rh%C>ciw zR@XwM@n6Jbovs9lM0BjGi!{Hu7e0>1HT4S|(6){DI}OH4Duy+D1^d5(nJs;+xaOe% z+sfFt08fejFk*gdXzl))0*L1f#kfbVdnv-WyCzyTmJhbZ-052yB-CTD}RrnnBCec2N>_@j5_KneZAdJhdH!$hW~y4}>MrJ=u5BTEJr427ahdlOGj7JMo&} zHTzfaa>)tMf4 z3yuTzJEm82((ilQMRqtWxdfh(B$jUewT(1AfJpp#)l z=>cw$6j76j&slkGS(!3tT{A$=Eo83{g0!n4c-$#e2*Jw(E;_@*JMGFFCJDMPM+Oel zn$2m=GkidcBfsW@Q+!W9?kAD60!=BTB=C$)`I2h>O>+x+f#v}Lxd6Mmw9*=~sHd@H zoKL7}JJPm4uRk;`V(q9eE)98E-Rq}0yk|?ok-IPYYYW4iPL(VbV6&#}2hTmj5(3k_ z{9U3ivB$OZJ-JcsCU-))tfTS>6tz(@3VXe2$6pAW zb{@H~mH!B-SIr$SGSolMA*t>O?J4!+yYisuKveir|F307E$_7HeyTnV^%J=D8bI8| zSEewAsz6z4&@L#pInK#wU)J#P+2&pyxR22Jt57-8ybQ~r%4WM(=E6%ll_=-N1RvC- zh)@l@g#7WXt>eBdW5eFYz+q2m=~Dk#TOoUfskm;B>}NYBeW?(A$N2`L<=NyZW%ALQtjr6%0i%8KgAE9QmN#%dEH??_vLxD5#TWgT-az!6U2WrT+?H(m zyS{iNEf#5{T(*#n>Y@vTYawi4q%7HojfOp^2%ggLAGi&d4kRGPlux8FrY=l@R(^ZxX)0;q?#EAbnpJVL325YLzR!p%md%kfxjpg7 zlfOhV_Lx5$=BQP50OdHx2!h#KaDPd!*Oe{l#80=wpK{u&zD9e<8#}z6-q`QHYgW-| z&OgNO2nNWHUr6CTzo7(-*o?qwgxC1#u+}Iy&OP5MM1uW}l*KtVkR<=Yp*OnOhYc_< z&ceW8uv;+9-K{%ApRQU~7XVZ?MFu8c~K>~1( zJa9@9TqKOT>OU;>5kuj7EFM4Okd(i+*R($DW2($7MhPMKKxaY;yAgqyZB!zgFY#`1 z-lsL+HoS3w6K6krqQ}rfJi4G#iDuQVq0I;PnP4ET|M;YqF<0jS>Z8gcY7s6RYQJ!2 zKjIR6@D}VSOwFnRmb7ZS3)}r5u@}wAGm!JwGVx$83CRG)mUM1UFysr|9kf+0{#u}X z5-vn-p*$eP@KWs?rk}U+TDa3{49b;_a3}xQ`QGXRaGdY>e4GMJxQw|7^RW-tyR#j$ zjyV{WqXST%^VbD6i}oME;sG?xY)MkudAQHlz*ycMekzE_R0wS~N9Aq_HQ6So4`A*I zxkq{gBZ2s2V5c=$#_@I^k*Pt6(O_#fBWSI4rg)qS?XB|>nopq#W!(KHXl+hZbH^#Z zM!?!TUW*4OKpH?J?ZrK{mUbsDo=A0hZ5)QW8VHkj*BEZ(AcJfzxbOgddrt3`pk@jO zG?O5ygwe;@Hd#}Px$)6Nj>^hNu-0k;7K;&~lU`Ve)TzMbnMNlXl^O+HS%PV#EDfH$ zceJZB%N`yY>lGVkKlKxwkScPMy-T8Ef%i(jsVcS5)nYEGc11f+&yFdl9qNEODI0Oz+ZRZFI*^Flq8w zdoB!U`#P&qY=x##uYzJ1ckA#f5E9ff39|_d*BEb;eqA#vT&i%vZC1wT6230PkJt^9 z&)hv$DSnxDXf+q$EZWemOjmT#+B!{d4A*c!&Se~HjRM7Ml}e{BG(Q`W>J0m@zs`SJ z9R5rTf&}{^Pra0X-mcW?EFLN6Y<-V*0q)^z0du_^LHqgffA}E{H*Uv^eqDZ@)|7AIiP##{0=LgrLWb11csq3VVUO(6LOYsazKXL!z5XUBus7|Y)L{ohZd_h_dP$qfthCj#?Fq}}q)H;I2$ zCA?`C`altStgE^U^O31GQ90Pmm4#ILuY#VkFN7U}W7ym~EV;TI!C+PK>y55Zb*uOF zqW>_ar9{|dcOKsE@SJMCWbERyZH!LP0vCdfY*4h&Ldprq8w2LE-$ES=IA6-IpC}|C zS}?2qd+n8SilWq$bo(kKi=wS1dEDgoEHMNSF=y42Uh}cQDv?x8H^)z+>#e z_!uEux%D5v*QpWppN5&SA!a#2fP?v>J}G9Y{U&dT5CqEaK@qUNmz1A%Zf@j4GO69t zh4Or;PcsE&BK-N?_ThlGQ%f%B{aMDs|JL$z=$n<7tgH$PSEmS;&)dR-@`RC!c1X_3 z)O+X7&K1MBi zLDKIDhFvFwd6lLyN<$xS|0feA{d4ftu1!UoWiw*!6{PvI{?n|?;Q)D7K3MuIX8*tS zpFVFzne2N)b%md_)>*K18p4WgEx~kE*wjLB{sJ)-k-s@j3T;Rmwx-BQ&nPI3JG0?* z=>y^FC1iX3M2xRLcFTKJrz<+zzfIWcgjxD0e5J8W`b{}sk1EaJX-x_RgLI#nwD;3L zbSa;uo7lbai}dqt0KQ79%two_^b7Wnn#pls z`;2|?b7s6W`uP4Si7F)CP?1tHd)*0}JA#n_26ckVa!Dv&s-_C85}!1X4-}4pA7*0vcu!jC3E{cc)Dw^QJmHcQyXb!ug%tnDxI*|_5!u`P(q&eMN4ywvUI4Im@AepoY@?~J`)OyzIqk;&l%S5LyoKeys}(rTWq!-!itQO zaB?!pDA_B-PbDJ8`%%^fL@G5;PSEfV2 z#Fl#MV@v*JRAKK7`s%PFx1i>8B41xPScP_>BU6}}r5D|#&lBDKC5C*w2#WfNbIw0}>zagKC_JV0&d8I@4#{5l=Zd9M z+4@U$N%nmfb_t(m{3i-XJaGq;cFrF%J3{7$TZV043)iISuw0w%`QiN`vMOj-V9~mh zktM8HJ7rl=xBfdJxCyZeXh^~G?L3xu8u`S+-f zqN|3En!AGT2i#Bcg`lZE^?qBMK_#dJoX>mV_2M>H3IJm&el6a_(}GaThl5|_Z?{J-8^wbYwaRroqF34z&H4? z-!Mf=o#`0)HNpNp;=8_bv!I6d{!~lRXB0hN-^A&7hNVIp@15Xp|8jzM{l>HOpS3^E z&!{yp39v2BAMEO{g_RAPNGv}a#>BX--FNym>45A9F3ZzI%st#y>UBYMiMjUV=jKT! zjV>~_a3M82Xh|ZT>~WcUOX=64C~hsxMXeLtj6r>hhWOlMdPD4IIO7$LYqV2rOg+9i zKsuw8_O0LS?Gb(pD6~AaJxGzxPL+g3l%K&Wz|-p-XeX>1yhAYu;9Iq?##;umrZI>oOR3&F@NlsHKSj;0!NW{y-HguK$T2eGcL=5?G%-Z5X@BJwmw z7hoSfpV-$my=y*Fm)4wiKkR+^XTi=v>5S&!8A<48yEGVJDBOL`7USnL zPsk5kFJIsc<3G)32_CJ;PD8EeAHYFIeYJmSDz3bx+OXs7b21Ca^}cfxX+M}2#Tm{I z==KiTfhO_Hb(bW^qXOkw4F{FX5SueX)}KBJ9WLKXTJt>wV0VB3wegH#qd5pF6@Jj3 z+?#;k!gCX?QEqO0gUqB(CYn(6^QMwej_k|(Vp`WY+$w$->Gq9nARdEmo8;%#8)cQq zE~RhKPc((6-w2>3!?!{5`%$<1zC1V_)r)o^?VV$+vqTQz!R#hi=aDngZ+npo%znq& zRW8;Q<%<~s1Z?SJ^~nD(4q#|@JtB`VuOT?>=Ax4Xr||6K+NbMvWr zl=cP>NJEGSX~A)KgYfiNdFu~A&&IoX;R1mt==!))piV2OL!hmo1KvB&{QtVs-qOg~yY}HXV zt8>n$E9s8Z{ys6-E|2Yti8msKtV7v@{KdJD*)}ERMQ_N{rOv(%mHp9Z#k+>BSmL$^ zB}#rspS27=W8g0CM%UE&R?a;oc(QMdw4Y4tqdD^kjOu@v?brE^3h5OWlvBHY^kX5E zIhn1F1r9*+m$31HEo=YW#wZL-!P%GO%g5;(#L$8cy8YW|UnhXiRMJ>c*x1X2I)R11qF?R@@CCZK81TmU6(f!2Tk+qOaK{Ny1Lb`l_kE*j zXo=6{AgC3)5Q;x0I;!=ly%x`9yp;aBLL4buDhuRj;P)pzmuZ>fdU#Lyml^DLK^^gE z4_-BR>R~e|flHNr`DWyvFq9;SF^?ar43P>K#slavkwDC6a1duK)U33B?$H%pHh8i# zsb8Kpa5}+p_)ew$K?6Km3>isjDKf$0xKWVeaf;+ZxD=2$c21rf#yDfeKTco0fcQ#+ zunI~=RB(h>pu|K;SUFCML*i~^oKQZ}Fh}Q2gW}q#&q~FZx6&j!X|-a>cS*gb`fgJ|8c4?iZ~;>E_O75tQ49i`0Q@O@;nbavX$QKejPDO+uf2M8dqHHY!)M58cTZV@T zG<&n{sh9o7KS3SbIG1=ZPv&T~@a+r7Ee?D?D`6eWwVOKg+cm4kmysVj5Dbn?JRC@| z3Odmm0(MUr4yZ``G!%&UbT}J2ln9?{Ww7#F`2^3A`)jGdd?o~(Hm^{ zg>^>dT(dtB)X*pX`0+IA>2Ik+A?@dgHeQakosFlA@*MYc)oT|3X4tZ}I*_OqQ>{Ci zAE;|_EqC47ZbCJ~En5wRZtP}fg%Wpn-DJupd9-PwsBA+a)bv#qCrnXG(TcE4l%0WP zl)IP{$hn&?dkybts|snrdWAZIdPrsKF%gEEkPdoP>>vP^*}0gL6mj}6%N)|cq30;$ z+J)_d-MIq%MiHb)Ox*8ryi{P5XvRWe>aYdVv_=*`c+jz~Er;XTWw2>O5tH;JkoAFzOA!NQ`gv&XblSD)Ybn{_gGh9ydEn zwu&%fOvGBt_=?vBrJx~!RWp#rwhapI?H@nG+BFA(%NxG>sB8ZI$sgDCy7O5hFePw` zY)EvGvQuvMh9k|#;2muv*MckFo;1+HO17qs{_F@BX8p+omEgzty}$k97^)d%mmeNN zZBW3k3q9=$1x=lnDf+(EI`~PiJBI1czQ+GSsO#K#hF!X2C{YMM^n^UK{E7YK7wMrJ z(Qb8Z()-6+ae4E-rexe3+i4Gzpk4_bJ`d;q%V&;U5)G#x#GH}dU^>Js9_nG`-x3`cbnRGN`owbtp1t!haH_pweTeh_phFZH|mKF5{ zmeVSaZRk~{6_PG+k!OQftSu=q`Yo@F5GezxTow)(r`-XtyWKn|0_j=-iA-V9`$5Ip zY+T&k6)DtD+xsc1B<-aWxd@MtxX{;2gvlwY@bo8oSs`FIlOgi8U~{ZR@+`B_tOu_Y zF9Ks}K#>KrSO6{6Yd^+LMXE(}L(DXACQ4jiGwbI=Ma}pJzvdgA zMgstR<3e1Pt(`Cg< zAD1a;=^f0fP(z#G=<80m?;t_qR=nBfh`css$Z}+2jBF7e)TeuAkHsU!uC%!cili1p z1)o?z^v-(bT zO6BKe&rGi(&M@k#iX0e{;8EoQ1d8S?nEtXYIp7ug|!RO8+zM7{0umi(4N)1*2 z+SlpW2jmT`rOI?f5M_?3lXdiMQ&`W&pHo;R?G!9=+=UxKHncy&rdvv2g~{9S275bX zMdk9Lgc@paVJn?~dA`(K*0(}CUgTN0`7d};-kvJ>xO@L~KfN?3*B`Qo^QC8E^JqG4 zD!~;}M8A^a?&O4e`t0YpxiHB{3RHvD3lh_R7hcOow6km+Es^ zL{ZS+`gf`mR<+6#`XwJX#$aypiK|MLym&#DTV*BtASvu6bnpPBKsdz+XA{H}oMs-T z--t;G7}#W6{RKGhg>hEFb4Jy+4-5N)0XYva;yvIeLe^7Z!Jn2 z!pD3&VwIom+wU8&?1JRXJz7T?W%iZQt)!#C!{FoUO9}3C6LdL1+rkONkB|eL3w~(S zXBnX7B#f{Y`&4*s;b92n-WBqHjeb7{bCb)P*V_pzotEu6Ktk{81v|2Fj(hK6D56ik zKK|hfCa0$rh48eCB>hmMailHROrTY>_7wH*vMy@uSjFs>e*@zlv5!uJ-Q@p0NJIy4 z;De5s&mzaA36*1b#Cpmec9xGs5#li`rO6vgT^{s@tdI9uvhX1Vn}_}4qCC?0ZQh9I z>x0CGDVFT^pbH&ujgUoYW}7c zf!fu6hn$Y?ZIIVdybEUSc|@yNsZmwjzcwpba=U1%JRUP;FB#)rTNz9zL1Uo~`^YP( zi?9TwzhhtCVz@go+NLOI=Xp+NL+2#)j#2RJ+4vcUinfFR6nb#vOjaIMz*01Q&qR{% zJN>AHPE2+F2Q`rQ5$crzlfOCJ(Te+M%8MD^hUB9eRK-gIL<8s^O#Mklkq&|>s*2&D z1kWh}%T}&vN=v8fu`bV^>}t~w45Kp}kB&8~G2=yQ2CHY`mAt?GAZQgi$sB1dY;Cm5 z&gw7a;!^@%`_Ks^HVbAfG%v+V?#C)vDg)r6R#Ckl8R~<(`={qZHMkVrPS#n3ygQUs zBzzme*7Y$EbD&P8>@8E~mI11HL?r3PTAk61pvkO?Z{BvVfK|#07$a|a!%V9dHcYy5 zuq?xFj_N{xw^yY4v-UcJOqd>={xQHFf5)5(u&c6KMsydZjGvj?_s%N^L z4r2@&PcrxBz>qc=tij=dnqZ;}_IGJog3AQDWX)7?7Wm86wCJVwSvQlP>Q$c#d+**y z0oZ-(^8^AlMoV?SpW6?uV-pr^1WK>P^rM{ARCoV>iJKqGO$`1mGRc>I7#=mTa0hAyv(*C{4uMvoK?bOnZ@aC@jAeV*#(2I12s7huXPXi2H}Y}w`6 zjlUpwWBozivjeZdl3|PHw*Z;I0}Mc{P$>kP1=f=_^a+nO6LjoFf>$W+JV99ebp8UpHHe8Wt#fS`ot$>jL%8TIdm zrUv|xrGtMs-sD@&x2Si>F$OP;_=(0A&DGbop(S~tB-}Qh`g?MIXoqP*cUP#7;M4kU zQ#BwTG^UHite>V?U=I%fT-V#)+hxDRd{KG^t7CaaGg&p!pT)7SBc_rNb&C3!>0&F{ zH}Y{Z$X4n!tX(AkPZ*>op6KJX1N_AL;`S@21Vj=R_;(0=qIf_ZOc2rFD7O5OOpnU%!mn;P^kgyBWCJA{K2VoPDqPR@?( z&^W0lp7t0yyC89ey|v(H=+_Kbdi35lsbae`FTsOtifp2%GK5lh0692prrvaLs}G{E zm6`7%Jww2{q(dwDq2F31IOU|fPl=bnk~tfFfYPgTocy%9DBE4=34~5Q_A)EYGOe#k zdu$;okUpn$O|v-ToBBf?--Wz!oQWmJMdZOWaGb|`!L?t~t zQr0@ylx9eI3q=%9nq4~4b~7@;tfQ0?m!$y8WFw;fgoDEEhpl1j#r8e^r~o3ZPtFW% zC9-oSmsMPeS~eSBsvFS~O_%p-}FQSFW{t{iVW z{KafnsZ~@5#uGDsYs#1X^8_SaXu<30j9$hQoT!ODw`x9%;r5{Evg{5+S^QM1ksEWp zU2)#uWyI>@Y->?yswrLvvx!vea=&1jE4;88%OJ1v zSUQ7qmdA~bKDrpZ(n*_gM|u^lKa%ckK`^vNzC~H`xZ`@#mT0JdoB=>s`TODnoXLIU zb?pCO+5-kV=AX2&opWw-==+o%lXMfv$4Qq>_$i@~Q+itS!H!xhl0GdiK~Xh&qj}Av z?_uia_}-9jRI;YN0bWVm0VxdlB{@iz__pjyb>{#to(Kd74e8HE!F>kLd4=n3DlUQK z;>dA9_SZ!Hl>G66SVO7xHB4_;!#sD#NU)bB4sNtX{OP_W1mhc=;i$SI3oq?C;Hl;P zcc_f>+zS&9JxNyj^&m{Qh!=GH7asWg7sdurDfxwSFMi%5Tnn4ORGdW26q#^>sBM9^ z;IP^4g=7y#q`dnI2|PdeFB}Q)GULR&5#4wbDHTu?Y&nuq`_#P?M6X>M71ry$Y9Y*d z@+TqJ(z3K0nI_a^C0aA^ljGfPu*Onc4p;WJK`^*$F+#E>Opn7)v7G6&ae*OuPtp#?R35a^#> z6R{0E-`WKU&7#u9QR4b`GpY%GupH1Y_8Xju?IjbPYgEs zc6K3F*jG6%Fg2K`357VFF-1H$c>Fx_gZ*i>jQ|Zjqp-|KXfw~DIvIf{uRfV3q=c+W zYXo28|12KK6~%;4dQq6YcXvi&s~3EtUEm#;Sd>`D=bCk2yHIzWF1&+cs2!(6{7E&T z&oQdWYAaXz{rs`I?j6-WR7=#3>w1#VJ9e0%Q=n1rsiX!7RJxS>tN#Q|@$?O^xp;O0dRNc+6dwn}X~R@F2U19m9$3%oHq0bN?K0 zshiloPmLglHYe|XG9dVzzc2D^!tptv&qKq|~a(5HuEx<>tG7ME+6V9LXZrGYG zu3gfsVU4&ekfgjut{#8c+ci57s2gX%?<)%&h-za898qu`Xoh<*!x>zSNOBzEG7~R7W z%L7PpsfwwjLW`MkT_c0;BGvd87tQys+uuiS+7x!xBRYGw^+EYw*2zV>Z+uThm!f-^ z*-l(;u(Uhsk3*uQ2Ad3@+)P6dj1;uJ@)7)n_>{|#lv~>%>kY5A4;pRzLGxQ4CPUhr z-bFv|s~`4LvY)?|YTs0p0D3=qlJ)s)^&c}WkS8lWu!|bj_~U%NdS^=*vV^=dD+H@2 zcE;`K*>Z0)AV!Yu)c|~ZhgU8tABKc%G$px&aP86|KYZbq?^U3y7q^ofcZQWhRwNgw zI-Aa1`$_i0rU_5^eN@(}rTQX4p!#!d9G^*5GBhnB>W>h}#@L!<&?;tzb+P^`4^Z1V zzjzxholCd+;fvK$&YtEP{Q5a z{HUGW(dhPar=8A8u|q#^+E4xei&h;gmw)C|JYQbJPS9MQWG!l~S3JDQTtKQ7PhDzv z4*CS^iKQm<|GSdDz1q`CQP=iqakn5#_M?3FCQL?q9=n#FxV4ib$m1VN0iS(AUc3mS zC{wBUnM+VTUee}G4^IF8!aPS-g=Z*yb_f|ftN2;%k3*Aq%hb*9<}O3--n0QHe|@oa z69#FY6R4+AFX^}RWQrQ&Rj1){$VC|M@wuGzijI})+brozKMsS$!Io=^%5&PAzTCaa zl)XPLtn$BSw>!@{leCN;c3k<`B&3F^$_#)9FQWXP^k+X9Q%{F*&tWAMYN&WZ}#v@15* zZ;xpJ!o=@P)$ty~tUftt*QfuLy;9X;J;XtxD6E8AoH>COS!8J{@sPz#Be(7y+DNS( zfUd!$-t`<3a_Erp_xP`mG+Q*$I=(08 ztP;D>#f4BLr&ysJW?Nm#nI%HRYQwmM$|%I38MDLv)>Ys8@VNiD z|G59SANQ~QHIF?W^V#e3e!t$Y*YoiDSXE#as;7wxV-F7DLwPb((s-p_RX~>I|FC7xasPTC_u)fUiUy-3j6auHYhWc@s&KzbW4%vFi^` z4J~VBQ!ZZ7O}+Zb+GM)Q8Z(Xmr{l7u8rTMASFAWUpQh6I${o3X@mRkc@@$9Wrtp4h z;a23KOqXk{fE|&-T23F=zN@o>ioKeV$+Qdf+7O;E_v@1 zGD*Ct_896H z6lOHD6`M$Tp49@r^?sB}?CZC|rW6w2hU$LZ5jv)wQpP6hD#0%7NOL>rhe%k6b;F~& zH9K}3~2IW+#yR8r=YkSN_y1)$?J0}59Yh3(D$P7U%Y*>`Rq!) z=s~O%YU!c>T2>+1mz%ZpR$pV}5TQ2Gy&dP;Z*2`$%T8@v=C-1L#d+vGw-^Z*!^B&5 zeDrU&@&0m|x0(VDoBJ-7RSf!BqF(#Ql=qLdvnHVB(#eKc6k0k@%+}-gig$ME1C^5A z9`a}MXv#vnsn_SCa4Q~lwtZ>a*0GymL(w|>YJa`gZ#}(Xz$t>rW{o)pltqHy<>t-! z+t6zKy^lR7QHx?|MO9S>6;)j73Fw#q{w%z6Ek?I*uJ9+3$|^!7(jO@3rWB*5;2H3? zEZfgReM8(*@6R>R1X|7Slh5Ea3xiS`2Wq%|St*B4)7g1HRR*eDza*WNVN1${8~ng^$vGQp(#k1Z zazZJ64C9Fz*2PEicj|=vLx;gI>2$O(qBY)w)wgl85%4`>-O?sw@yubQi=X$W-DAL&L6tE#3<*7v=7?N{3WAw;k1Ud`c923!CBW-rv*LR zv#k?@5E{mEJztjR`TK7O%ODz+YP4eP&xaKxGbla7&>X(33}yFepP{h`UjXboYYW2* znaRXuoC3Fn2xAvyS%#14fFeoO3f1P~|IwVCpy}~7bHQi-62uYHDWfFBFhZ6j`R<6S zTWwc_f4>4pcHc(OZxOTbO*&vtbUZ$UAG~S}#8mj_oDYDODIUOEG-{3T=5nmpXd)+2 z%vWgPidp4N+6NFQL^5XF9OR4}JG@5;=!xC-N&6@kVv1Icxf0bM_T0ytLs^KQO3*#z zwl$(L;8YU6l5gW*A9yp#QDJn@dRl}@0nn8-YN9xUGW9Ww#AiIGnyu8?D_eN=_{Mse zngo(^dPVwF)aqZ1pva?%2|@PB2sqnyBVj56^JpUfvwmMysy16|)*=V-@0S))vkR%T zsW`&>#$$=|vRSt|*1ONa(>*YbVa}fNO)@;I=gcP|FFlmXYnQ--;n@WHTs4MnA|trb zoI(;5F^-5s`d!P4)vw>o@zjlSbB3{~qlER-IrN%Is>wJqT)oy*Eq*vne`iO-z+@#(I->_*lp z|A(|3(gsd`UlH9^(fT$Nqn|_ckfZu#5>^JyGm6ATRfi2TnthrT1i!u$r(!^}L|DE9 z9!6Q+wR$_7w=CPjs1;Ncce)uVhOb;gYLBJY3eJG$D`Di%yMT{_+TwUEjaewIsU}VZ zfn?OJDQo0C+zT-+C9B8}iBZN(${B@LAWJ%(Ok#9pu+E^pEq7UXB-3Pyd+z;H^{ zpVH#5=+D@I=bccy)udNf2NaGZJz=BuW?(8~IB~Gv>^>8or|Kwlt(l7cNXILB8Zw}@ zT{(f?%gUIv%sRC)eGfT;bEBba2gy7~6XTYAVP!$Fp3&NOx$lRm^?w~O1>J+^g2h;L z=qtVMoU~N)@FP=;QT*XT0CEDUB`!N2d=uDML?SHQ_NccYOx6hF&aQ^u(C zx!|)M>(pgr&}E~XR?;(ph0kiQSS>|9-^H$0OHwGIa`tQe|4P2xsT3A8@%E(ieaSa@ zZCaEe>+x*g)}Dt@MW8v9qvi}+qAS6dugxox7-SG`fwwf2r3##yvaO5yV&8sO_7+K1 zl}>rj9U9I87f7n92A=v}$Q1SOPEXgnK9B4el#0q-nB(EBsJpSi{orVQF#y1#i-ibP z!3!Jq9YoT|-&VrN0{?Kedh>d>g)^!R3n9hTyXI!1pC)>6YRca4l$l8`jI5DTMFEU9 zegrR%*9v)z8TwTrZ+>!CGJxyKFN?=F`7CxEIW;Z1@aEbfe1k^HVubwGSGTt_K)1G$ z(IeJ`^JQy3JrP8Y3TZ8PiLRMOK<8kWM7Z#+BR*2VUROQCe%ay8XvC%P1>RDqZRPww z$Gtgjq9d-pB(s363b2Xyyz=)*s1|v-T(M!smgY5q`e$Tk_u>1EXB+=a93T(vvUA8)gdRj^feGR4+9o$Igtbj3qjBMr-Dfja9T zy<1qIa^(!#J03yD)2We*@>KV%%*Y%{ZzX{Q3J#gV#$`16)~U0P)xZ3jh|fElzzM$1 zWQ$Ttv5byV*e{)F9QvM%7YcCLmwSX``q`p8e+{%>VZwkL2x4bcN&ov*)i3=y)xZdY zU7AH}nv{}Xw8}5fuZ!x`FT!yPe<8i*LdlBWIN{wfi*e8BP_W5tT^uZ_XPS$cJOkQ; z`f%LfxDx`DC2hjPow%E(2g=2j*^NRJbrdYa(}NdQ+7%;LSe9jJY;wimBXw?}Z^50y zRO_>!>yPW9xfQVW*VqRYZrR78+YpxEpdiZKc_guIfAx_szvnzKE44G83NC~>p{_4< z&y=qGcvk&vo&T!W)u8?&^R+x2twKiiIHP?=c#D%UQguZj`<$YeMFH6X=Vv~S1VMU> zK7l@q{sA*y4Ups8!$U+$uP?__|C!tCO^cR+jq~f7!j+GvujcCIz;;*S zZYFMv`tpP0Qt%4%QX-uLq!mr7OXTliPSO5@aNq|tng1Qj99ywMx&fRi>!kBGz5(I- z2OsJmQ45c|(TutH6?gIWmiJTWb1&nIbuau}rcW{iUZ|{?iN~RaQujuM%0DZ?aPq(+ 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 { + page = await JSDOM.fromFile(path.join(__dirname, "index.html"), { + resources: "usable", + runScripts: "dangerously", + }); + + // do this so students can use element.innerText which jsdom does not implement + Object.defineProperty(page.window.HTMLElement.prototype, "innerText", { + get() { + return this.textContent; + }, + set(value) { + this.textContent = value; + }, + }); + + jest + .spyOn(page.window.Math, "random") + .mockReturnValueOnce(0.02) // random number to target Albert Einstein quote [index: 2] + .mockReturnValueOnce(0.25) // random number to target Maya Angelou quote [index: 25] + .mockReturnValueOnce(0.79); // random number to target Rosa Parks quote [index: 80] + + return new Promise((res) => { + page.window.document.addEventListener("load", res); + }); +}); + +afterEach(() => { + page = null; + jest.restoreAllMocks(); +}); + +describe("Quote generator", () => { + test("initially displays quote and author", () => { + const quoteP = page.window.document.querySelector("#quote"); + const authorP = page.window.document.querySelector("#author"); + + expect(quoteP).toHaveTextContent( + "Strive not to be a success, but rather to be of value." + ); + expect(authorP).toHaveTextContent("Albert Einstein"); + }); + test("can change quote to another random quote", () => { + const quoteP = page.window.document.querySelector("#quote"); + const authorP = page.window.document.querySelector("#author"); + const newQuoteBtn = page.window.document.querySelector("#new-quote"); + + expect(quoteP).toHaveTextContent( + "Strive not to be a success, but rather to be of value." + ); + expect(authorP).toHaveTextContent("Albert Einstein"); + expect(newQuoteBtn).toHaveTextContent("New quote"); + + newQuoteBtn.click(); + + expect(quoteP).toHaveTextContent( + "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel." + ); + expect(authorP).toHaveTextContent("Maya Angelou"); + + newQuoteBtn.click(); + + expect(quoteP).toHaveTextContent( + "I have learned over the years that when one's mind is made up, this diminishes fear." + ); + expect(authorP).toHaveTextContent("Rosa Parks"); + }); +}); diff --git a/Sprint-3/quote-generator/readme.md b/Sprint-3/quote-generator/readme.md new file mode 100644 index 000000000..868291958 --- /dev/null +++ b/Sprint-3/quote-generator/readme.md @@ -0,0 +1,43 @@ +# Make a Quote Generator + +In this folder you will find the basic setup of a quote generator. + +You can change any of the files in this project. + +First off, once you've branched off `main`, then update the title element in `index.html` to "Quote generator app" + +## How the Quote Generator should work + +When the page loads it should show a random quote from the `quotes` array on the screen. It should also show who said the quote. + +When you click a button on the screen it should change the quote on the screen. + +It can look however you like but there is an example in this folder at `quote_generator_example.png` + +## Need Help? + +- If you can't work out how to find a random element from the array, either: + - (advanced) try to use `Math.random()` + - OR + - (basic) use the `pickFromArray()` function supplied in the javascript file. + +## Stretch + +Only attempt the stretch once you've attempted the other sections. + +### Add auto-play to your quote generator + +For this task you will return to your quote generator and improve it with "auto-generate" functionality: + +- Add a toggle-switch or checkbox input to your existing quote generator. +- When the switch is ON: + - ... the generator should pick and display a new quote every 60 seconds. (When testing you will probably want to reduce this to every 5 seconds.) + - ... the generator should display "auto-play:ON" somewhere on the page. +- When the switch is OFF + - ... the generator should NOT change quote automatically + +## Hints: + +Use https://rot13.com/ to decipher this hint: + +`Pubbfr bar bs frgGvzrbhg be frgVagreiny.` diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css new file mode 100644 index 000000000..63cedf2d2 --- /dev/null +++ b/Sprint-3/quote-generator/style.css @@ -0,0 +1 @@ +/** Write your CSS in here **/ diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/index.html new file mode 100644 index 000000000..dbdb0f471 --- /dev/null +++ b/Sprint-3/reading-list/index.html @@ -0,0 +1,15 @@ + + + + + + + Title here + + +

+
    +
    + + + diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list/script.js index cba465c4d..6024d73a0 100644 --- a/Sprint-3/reading-list/script.js +++ b/Sprint-3/reading-list/script.js @@ -20,3 +20,4 @@ const books = [ bookCoverImage: "https://blackwells.co.uk/jacket/l/9780135957059.jpg", }, ]; + diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list/style.css index 8dd7b2ad7..74406e64f 100644 --- a/Sprint-3/reading-list/style.css +++ b/Sprint-3/reading-list/style.css @@ -8,17 +8,8 @@ html, body { - font-family: - "Source Sans Pro", - -apple-system, - system-ui, - BlinkMacSystemFont, - "Segoe UI", - Roboto, - "Helvetica Neue", - Arial, - sans-serif; - background-color: #87ca8a; + font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } .site-footer {