From 34ae25817665a7b0f785bdc529781ee07f9db55c Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 23 Aug 2023 23:15:19 +0100 Subject: [PATCH 1/4] Add Harrogate Borough Council From 903dc0a804f7f90629ef8f6e89fbe79ba74ac261 Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 23 Aug 2023 23:20:32 +0100 Subject: [PATCH 2/4] Add Harrogate Borough Council --- uk_bin_collection/.coverage | Bin 0 -> 53248 bytes .../HarrogateBoroughCouncil.schema | 39 ++++++++++ .../outputs/HarrogateBoroughCouncil.json | 36 ++++++++++ uk_bin_collection/uk_bin_collection/.coverage | Bin 0 -> 53248 bytes .../councils/HarrogateBoroughCouncil.py | 68 ++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 uk_bin_collection/.coverage create mode 100644 uk_bin_collection/tests/council_schemas/HarrogateBoroughCouncil.schema create mode 100644 uk_bin_collection/tests/outputs/HarrogateBoroughCouncil.json create mode 100644 uk_bin_collection/uk_bin_collection/.coverage create mode 100644 uk_bin_collection/uk_bin_collection/councils/HarrogateBoroughCouncil.py diff --git a/uk_bin_collection/.coverage b/uk_bin_collection/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..d98466fb06ac025d21bdea3a533b66a72f580ba4 GIT binary patch literal 53248 zcmeI)PjAy^90zbaE-^_HnGK<+>QJA{Rw~+N-41BmffcAW1QKI|T_!C&ah|l^V!POn zp*>7fU=q@#y@P45V>k8|_7ZmEw$sD`4*UK5*i8ZrLZT93`&v!v*w6F$_k5mzNt5QQ z>sJG{kF&Ur|s6Q_0Bs@?`x}3{l)UW zZC>-%8oxH*oBy*B)_$J<&6PEuPGExo1Rwx`|F^*Kdc$okEZFyc(6T#FI+4Cg%zg9X zms^`Rw#1Fi3s<*T0^;%Zv$X>))IQNeb^Da4r~`-(_ZUnMH? zRcfL*6ZBT7x7l^fxW*M`cv#TB|`au(Mb(-~zx zBxjMl$lRykqPS!oW#mg!<~-&o3%f-AT^8!a63~6jlU{JIal*)MDeQNN>C4YcfQ*C=%j5?uT*>K?EyXC>c~vT`Qr{X zerJR38b7^t+-)r_*$-~#9ff&1-9V=YJGF^Ub8vV{*WvTi`wfqh$xgzfXfP0QKOZuj zTbRb7-aI~L+9ifec%X^6NJx>s*51a!QVgOyh`W=0E$=a@q5(p4L7A+dMLrLelTwE(S^#E zJY*UzPlZaRSyE0UFPbFF9HUvX93#aUs?M5QZEY@2t4@)wvr+6EAG&jH>(nWGXhsCj zOME*vQ3*aW8UoKO1TP={uGBl?`Plg|1-^W&+WO?ww7@xp&IaFC?|)OtLw>N3>xVSy z^UawEnU9P@zM}Tm?#KbnCc837XvoqWY*qll344+f%Wjv9bISubG;xr9tS>zvrxJ$x^X;EGBRre<+z;EHG@>-F+9I2ogbBv z?sFO2cb4;*%Eg7J`5QFo%JD@zVJM?sv0m{qY)YlMp9d#j$4nxWQ7qG-OlgQdQ)XFc zah7MSvi$X3GT~A~*)zkP8)dA-yF2Q+;>>DvNou8oPzg?w2a|WKyD}AiqUa>8r7O$M zi@E`~R%e6n`Bn09ekwOyvfb9%v-U762BVp0Iw>vcp)A8L9#$qg$ulQM{pA`>xb$pi zyq~b$7zaNzSK!Ibv|!gLl&Om6I`tKPfp2?HEc(F)0SG_<0uX=z1Rwwb2tWV=5P-mc zPr$J&w#%>oE8bt0_cz^Pg8&2|009U<00Izz00bZa0SG|g%@k-UhC6)t_PQcd5N!0-Rt-X9kIV1obz zAOHafKmY;|fB*y_009U4_y5gk!y+sQKmY;|fB*y_009U<00Izz zz|jaewqrHT`~OcZ@9EJLic%l|0SG_<0uX=z1Rwwb2tWV=5ST3i$7$Bg`~QzE@9}KK zhG-xF0SG_<0uX=z1Rwwb2tWV=5O`$)*Pg4@-u~S>Vc!3LVtG$qxl9xQ0SG_<0uX=z z1Rwwb2tWV=5P-n!3Cz)-0P^?$trN2s93p}M1Rwwb2tWV=5P$##AOHafK;Y;E`2Byp z{y#cTlmr0?KmY;|fB*y_009U<00I!0MFIZ*f4u&m#g;)#5P$##AOHafKmY;|fB*y_ J0D+?u_!m6bR}=sM literal 0 HcmV?d00001 diff --git a/uk_bin_collection/tests/council_schemas/HarrogateBoroughCouncil.schema b/uk_bin_collection/tests/council_schemas/HarrogateBoroughCouncil.schema new file mode 100644 index 0000000000..9b1fb1fcc4 --- /dev/null +++ b/uk_bin_collection/tests/council_schemas/HarrogateBoroughCouncil.schema @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Welcome7", + "definitions": { + "Welcome7": { + "type": "object", + "additionalProperties": false, + "properties": { + "bins": { + "type": "array", + "items": { + "$ref": "#/definitions/Bin" + } + } + }, + "required": [ + "bins" + ], + "title": "Welcome7" + }, + "Bin": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "collectionDate": { + "type": "string" + } + }, + "required": [ + "collectionDate", + "type" + ], + "title": "Bin" + } + } +} \ No newline at end of file diff --git a/uk_bin_collection/tests/outputs/HarrogateBoroughCouncil.json b/uk_bin_collection/tests/outputs/HarrogateBoroughCouncil.json new file mode 100644 index 0000000000..c78ebd51e2 --- /dev/null +++ b/uk_bin_collection/tests/outputs/HarrogateBoroughCouncil.json @@ -0,0 +1,36 @@ +{ + "bins": [ + { + "type": "Recycling", + "collectionDate": "25/08/2023" + }, + { + "type": "Refuse", + "collectionDate": "02/09/2023" + }, + { + "type": "Recycling", + "collectionDate": "08/09/2023" + }, + { + "type": "Refuse", + "collectionDate": "15/09/2023" + }, + { + "type": "Recycling", + "collectionDate": "22/09/2023" + }, + { + "type": "Refuse", + "collectionDate": "29/09/2023" + }, + { + "type": "Recycling", + "collectionDate": "06/10/2023" + }, + { + "type": "Refuse", + "collectionDate": "13/10/2023" + } + ] +} \ No newline at end of file diff --git a/uk_bin_collection/uk_bin_collection/.coverage b/uk_bin_collection/uk_bin_collection/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..d98466fb06ac025d21bdea3a533b66a72f580ba4 GIT binary patch literal 53248 zcmeI)PjAy^90zbaE-^_HnGK<+>QJA{Rw~+N-41BmffcAW1QKI|T_!C&ah|l^V!POn zp*>7fU=q@#y@P45V>k8|_7ZmEw$sD`4*UK5*i8ZrLZT93`&v!v*w6F$_k5mzNt5QQ z>sJG{kF&Ur|s6Q_0Bs@?`x}3{l)UW zZC>-%8oxH*oBy*B)_$J<&6PEuPGExo1Rwx`|F^*Kdc$okEZFyc(6T#FI+4Cg%zg9X zms^`Rw#1Fi3s<*T0^;%Zv$X>))IQNeb^Da4r~`-(_ZUnMH? zRcfL*6ZBT7x7l^fxW*M`cv#TB|`au(Mb(-~zx zBxjMl$lRykqPS!oW#mg!<~-&o3%f-AT^8!a63~6jlU{JIal*)MDeQNN>C4YcfQ*C=%j5?uT*>K?EyXC>c~vT`Qr{X zerJR38b7^t+-)r_*$-~#9ff&1-9V=YJGF^Ub8vV{*WvTi`wfqh$xgzfXfP0QKOZuj zTbRb7-aI~L+9ifec%X^6NJx>s*51a!QVgOyh`W=0E$=a@q5(p4L7A+dMLrLelTwE(S^#E zJY*UzPlZaRSyE0UFPbFF9HUvX93#aUs?M5QZEY@2t4@)wvr+6EAG&jH>(nWGXhsCj zOME*vQ3*aW8UoKO1TP={uGBl?`Plg|1-^W&+WO?ww7@xp&IaFC?|)OtLw>N3>xVSy z^UawEnU9P@zM}Tm?#KbnCc837XvoqWY*qll344+f%Wjv9bISubG;xr9tS>zvrxJ$x^X;EGBRre<+z;EHG@>-F+9I2ogbBv z?sFO2cb4;*%Eg7J`5QFo%JD@zVJM?sv0m{qY)YlMp9d#j$4nxWQ7qG-OlgQdQ)XFc zah7MSvi$X3GT~A~*)zkP8)dA-yF2Q+;>>DvNou8oPzg?w2a|WKyD}AiqUa>8r7O$M zi@E`~R%e6n`Bn09ekwOyvfb9%v-U762BVp0Iw>vcp)A8L9#$qg$ulQM{pA`>xb$pi zyq~b$7zaNzSK!Ibv|!gLl&Om6I`tKPfp2?HEc(F)0SG_<0uX=z1Rwwb2tWV=5P-mc zPr$J&w#%>oE8bt0_cz^Pg8&2|009U<00Izz00bZa0SG|g%@k-UhC6)t_PQcd5N!0-Rt-X9kIV1obz zAOHafKmY;|fB*y_009U4_y5gk!y+sQKmY;|fB*y_009U<00Izz zz|jaewqrHT`~OcZ@9EJLic%l|0SG_<0uX=z1Rwwb2tWV=5ST3i$7$Bg`~QzE@9}KK zhG-xF0SG_<0uX=z1Rwwb2tWV=5O`$)*Pg4@-u~S>Vc!3LVtG$qxl9xQ0SG_<0uX=z z1Rwwb2tWV=5P-n!3Cz)-0P^?$trN2s93p}M1Rwwb2tWV=5P$##AOHafK;Y;E`2Byp z{y#cTlmr0?KmY;|fB*y_009U<00I!0MFIZ*f4u&m#g;)#5P$##AOHafKmY;|fB*y_ J0D+?u_!m6bR}=sM literal 0 HcmV?d00001 diff --git a/uk_bin_collection/uk_bin_collection/councils/HarrogateBoroughCouncil.py b/uk_bin_collection/uk_bin_collection/councils/HarrogateBoroughCouncil.py new file mode 100644 index 0000000000..2534f6b032 --- /dev/null +++ b/uk_bin_collection/uk_bin_collection/councils/HarrogateBoroughCouncil.py @@ -0,0 +1,68 @@ +from bs4 import BeautifulSoup +from uk_bin_collection.uk_bin_collection.common import * +from uk_bin_collection.uk_bin_collection.get_bin_data import \ + AbstractGetBinDataClass + + +# import the wonderful Beautiful Soup and the URL grabber +class CouncilClass(AbstractGetBinDataClass): + """ + Concrete classes have to implement all abstract operations of the + base class. They can also override some operations with a default + implementation. + """ + + def parse_data(self, page: str, **kwargs) -> dict: + + user_uprn = kwargs.get("uprn") + check_uprn(user_uprn) + + soup = BeautifulSoup(page.text, features="html.parser") + soup.prettify() + + data = {"bins": []} + + headers = { + 'accept-language': 'en-GB,en;q=0.9', + 'cache-control': 'no-cache', + } + + req_data = { + 'uprn': user_uprn, + } + + url = f'https://secure.harrogate.gov.uk/inmyarea/Property/?uprn={user_uprn}' + + requests.packages.urllib3.disable_warnings() + response = requests.post(url, headers=headers) + + soup = BeautifulSoup(response.text, features="html.parser") + soup.prettify() + + collections = [] + + # Find section with bins in + table = soup.find_all("table", {"class": "hbcRounds"})[1] + + # For each bin section, get the text and the list elements + for row in table.find_all('tr'): + bin_type = row.find('th').text + td = row.find('td') + for span in td.find_all('span'): + span.extract() + collectionDate = td.text.strip() + next_collection = datetime.strptime(collectionDate, "%a %d %b %Y") + collections.append((bin_type, next_collection)) + + # Sort the text and list elements by date + ordered_data = sorted(collections, key=lambda x: x[1]) + + # Put the elements into the dictionary + for item in ordered_data: + dict_data = { + "type": item[0], + "collectionDate": item[1].strftime(date_format), + } + data["bins"].append(dict_data) + + return data From 665a49a8b3a7d27f4db3459f6f474b9a53fa49ce Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 23 Aug 2023 23:21:13 +0100 Subject: [PATCH 3/4] Input.json and validate_council_outputs.feature --- .../tests/features/validate_council_outputs.feature | 1 + uk_bin_collection/tests/input.json | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/uk_bin_collection/tests/features/validate_council_outputs.feature b/uk_bin_collection/tests/features/validate_council_outputs.feature index 2daa5c3554..5d16901dcf 100644 --- a/uk_bin_collection/tests/features/validate_council_outputs.feature +++ b/uk_bin_collection/tests/features/validate_council_outputs.feature @@ -37,6 +37,7 @@ Feature: Test each council output matches expected results in /outputs | FenlandDistrictCouncil | | GlasgowCityCouncil | | GuildfordCouncil | + | HarrogateBoroughCouncil | | HighPeakCouncil | | HuntingdonDistrictCouncil | | KingstonUponThamesCouncil | diff --git a/uk_bin_collection/tests/input.json b/uk_bin_collection/tests/input.json index 30d9d46923..3421a3df63 100644 --- a/uk_bin_collection/tests/input.json +++ b/uk_bin_collection/tests/input.json @@ -185,6 +185,13 @@ "wiki_name": "Guildford Council", "wiki_note": "If the bin day is 'today' then the collectionDate will only show today's date if before 7AM, else the date will be in 'previousCollectionDate'. To get the UPRN, you will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN." }, + "HarrogateBoroughCouncil": { + "SKIP_GET_URL": "SKIP_GET_URL", + "uprn": "100050414307", + "url": "https://secure.harrogate.gov.uk/inmyarea", + "wiki_name": "Harrogate Borough Council", + "wiki_note": "Pass the UPRN which can be found at https://secure.harrogate.gov.uk/inmyarea URL doesn't need to be passed." + }, "HighPeakCouncil": { "SKIP_GET_URL": "SKIP_GET_URL", "house_number": "9 Ellison Street, Glossop", From 6b2413800a6938b723ce1fb7f9b64ef84f6a3489 Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 23 Aug 2023 23:21:13 +0100 Subject: [PATCH 4/4] Removed the .coverage files --- uk_bin_collection/.coverage | Bin 53248 -> 0 bytes .../features/validate_council_outputs.feature | 1 + uk_bin_collection/tests/input.json | 7 +++++++ uk_bin_collection/uk_bin_collection/.coverage | Bin 53248 -> 0 bytes 4 files changed, 8 insertions(+) delete mode 100644 uk_bin_collection/.coverage delete mode 100644 uk_bin_collection/uk_bin_collection/.coverage diff --git a/uk_bin_collection/.coverage b/uk_bin_collection/.coverage deleted file mode 100644 index d98466fb06ac025d21bdea3a533b66a72f580ba4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI)PjAy^90zbaE-^_HnGK<+>QJA{Rw~+N-41BmffcAW1QKI|T_!C&ah|l^V!POn zp*>7fU=q@#y@P45V>k8|_7ZmEw$sD`4*UK5*i8ZrLZT93`&v!v*w6F$_k5mzNt5QQ z>sJG{kF&Ur|s6Q_0Bs@?`x}3{l)UW zZC>-%8oxH*oBy*B)_$J<&6PEuPGExo1Rwx`|F^*Kdc$okEZFyc(6T#FI+4Cg%zg9X zms^`Rw#1Fi3s<*T0^;%Zv$X>))IQNeb^Da4r~`-(_ZUnMH? zRcfL*6ZBT7x7l^fxW*M`cv#TB|`au(Mb(-~zx zBxjMl$lRykqPS!oW#mg!<~-&o3%f-AT^8!a63~6jlU{JIal*)MDeQNN>C4YcfQ*C=%j5?uT*>K?EyXC>c~vT`Qr{X zerJR38b7^t+-)r_*$-~#9ff&1-9V=YJGF^Ub8vV{*WvTi`wfqh$xgzfXfP0QKOZuj zTbRb7-aI~L+9ifec%X^6NJx>s*51a!QVgOyh`W=0E$=a@q5(p4L7A+dMLrLelTwE(S^#E zJY*UzPlZaRSyE0UFPbFF9HUvX93#aUs?M5QZEY@2t4@)wvr+6EAG&jH>(nWGXhsCj zOME*vQ3*aW8UoKO1TP={uGBl?`Plg|1-^W&+WO?ww7@xp&IaFC?|)OtLw>N3>xVSy z^UawEnU9P@zM}Tm?#KbnCc837XvoqWY*qll344+f%Wjv9bISubG;xr9tS>zvrxJ$x^X;EGBRre<+z;EHG@>-F+9I2ogbBv z?sFO2cb4;*%Eg7J`5QFo%JD@zVJM?sv0m{qY)YlMp9d#j$4nxWQ7qG-OlgQdQ)XFc zah7MSvi$X3GT~A~*)zkP8)dA-yF2Q+;>>DvNou8oPzg?w2a|WKyD}AiqUa>8r7O$M zi@E`~R%e6n`Bn09ekwOyvfb9%v-U762BVp0Iw>vcp)A8L9#$qg$ulQM{pA`>xb$pi zyq~b$7zaNzSK!Ibv|!gLl&Om6I`tKPfp2?HEc(F)0SG_<0uX=z1Rwwb2tWV=5P-mc zPr$J&w#%>oE8bt0_cz^Pg8&2|009U<00Izz00bZa0SG|g%@k-UhC6)t_PQcd5N!0-Rt-X9kIV1obz zAOHafKmY;|fB*y_009U4_y5gk!y+sQKmY;|fB*y_009U<00Izz zz|jaewqrHT`~OcZ@9EJLic%l|0SG_<0uX=z1Rwwb2tWV=5ST3i$7$Bg`~QzE@9}KK zhG-xF0SG_<0uX=z1Rwwb2tWV=5O`$)*Pg4@-u~S>Vc!3LVtG$qxl9xQ0SG_<0uX=z z1Rwwb2tWV=5P-n!3Cz)-0P^?$trN2s93p}M1Rwwb2tWV=5P$##AOHafK;Y;E`2Byp z{y#cTlmr0?KmY;|fB*y_009U<00I!0MFIZ*f4u&m#g;)#5P$##AOHafKmY;|fB*y_ J0D+?u_!m6bR}=sM diff --git a/uk_bin_collection/tests/features/validate_council_outputs.feature b/uk_bin_collection/tests/features/validate_council_outputs.feature index 2daa5c3554..5d16901dcf 100644 --- a/uk_bin_collection/tests/features/validate_council_outputs.feature +++ b/uk_bin_collection/tests/features/validate_council_outputs.feature @@ -37,6 +37,7 @@ Feature: Test each council output matches expected results in /outputs | FenlandDistrictCouncil | | GlasgowCityCouncil | | GuildfordCouncil | + | HarrogateBoroughCouncil | | HighPeakCouncil | | HuntingdonDistrictCouncil | | KingstonUponThamesCouncil | diff --git a/uk_bin_collection/tests/input.json b/uk_bin_collection/tests/input.json index 30d9d46923..3421a3df63 100644 --- a/uk_bin_collection/tests/input.json +++ b/uk_bin_collection/tests/input.json @@ -185,6 +185,13 @@ "wiki_name": "Guildford Council", "wiki_note": "If the bin day is 'today' then the collectionDate will only show today's date if before 7AM, else the date will be in 'previousCollectionDate'. To get the UPRN, you will need to use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find the UPRN." }, + "HarrogateBoroughCouncil": { + "SKIP_GET_URL": "SKIP_GET_URL", + "uprn": "100050414307", + "url": "https://secure.harrogate.gov.uk/inmyarea", + "wiki_name": "Harrogate Borough Council", + "wiki_note": "Pass the UPRN which can be found at https://secure.harrogate.gov.uk/inmyarea URL doesn't need to be passed." + }, "HighPeakCouncil": { "SKIP_GET_URL": "SKIP_GET_URL", "house_number": "9 Ellison Street, Glossop", diff --git a/uk_bin_collection/uk_bin_collection/.coverage b/uk_bin_collection/uk_bin_collection/.coverage deleted file mode 100644 index d98466fb06ac025d21bdea3a533b66a72f580ba4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI)PjAy^90zbaE-^_HnGK<+>QJA{Rw~+N-41BmffcAW1QKI|T_!C&ah|l^V!POn zp*>7fU=q@#y@P45V>k8|_7ZmEw$sD`4*UK5*i8ZrLZT93`&v!v*w6F$_k5mzNt5QQ z>sJG{kF&Ur|s6Q_0Bs@?`x}3{l)UW zZC>-%8oxH*oBy*B)_$J<&6PEuPGExo1Rwx`|F^*Kdc$okEZFyc(6T#FI+4Cg%zg9X zms^`Rw#1Fi3s<*T0^;%Zv$X>))IQNeb^Da4r~`-(_ZUnMH? zRcfL*6ZBT7x7l^fxW*M`cv#TB|`au(Mb(-~zx zBxjMl$lRykqPS!oW#mg!<~-&o3%f-AT^8!a63~6jlU{JIal*)MDeQNN>C4YcfQ*C=%j5?uT*>K?EyXC>c~vT`Qr{X zerJR38b7^t+-)r_*$-~#9ff&1-9V=YJGF^Ub8vV{*WvTi`wfqh$xgzfXfP0QKOZuj zTbRb7-aI~L+9ifec%X^6NJx>s*51a!QVgOyh`W=0E$=a@q5(p4L7A+dMLrLelTwE(S^#E zJY*UzPlZaRSyE0UFPbFF9HUvX93#aUs?M5QZEY@2t4@)wvr+6EAG&jH>(nWGXhsCj zOME*vQ3*aW8UoKO1TP={uGBl?`Plg|1-^W&+WO?ww7@xp&IaFC?|)OtLw>N3>xVSy z^UawEnU9P@zM}Tm?#KbnCc837XvoqWY*qll344+f%Wjv9bISubG;xr9tS>zvrxJ$x^X;EGBRre<+z;EHG@>-F+9I2ogbBv z?sFO2cb4;*%Eg7J`5QFo%JD@zVJM?sv0m{qY)YlMp9d#j$4nxWQ7qG-OlgQdQ)XFc zah7MSvi$X3GT~A~*)zkP8)dA-yF2Q+;>>DvNou8oPzg?w2a|WKyD}AiqUa>8r7O$M zi@E`~R%e6n`Bn09ekwOyvfb9%v-U762BVp0Iw>vcp)A8L9#$qg$ulQM{pA`>xb$pi zyq~b$7zaNzSK!Ibv|!gLl&Om6I`tKPfp2?HEc(F)0SG_<0uX=z1Rwwb2tWV=5P-mc zPr$J&w#%>oE8bt0_cz^Pg8&2|009U<00Izz00bZa0SG|g%@k-UhC6)t_PQcd5N!0-Rt-X9kIV1obz zAOHafKmY;|fB*y_009U4_y5gk!y+sQKmY;|fB*y_009U<00Izz zz|jaewqrHT`~OcZ@9EJLic%l|0SG_<0uX=z1Rwwb2tWV=5ST3i$7$Bg`~QzE@9}KK zhG-xF0SG_<0uX=z1Rwwb2tWV=5O`$)*Pg4@-u~S>Vc!3LVtG$qxl9xQ0SG_<0uX=z z1Rwwb2tWV=5P-n!3Cz)-0P^?$trN2s93p}M1Rwwb2tWV=5P$##AOHafK;Y;E`2Byp z{y#cTlmr0?KmY;|fB*y_009U<00I!0MFIZ*f4u&m#g;)#5P$##AOHafKmY;|fB*y_ J0D+?u_!m6bR}=sM