From 9ab9781c58128a9424807b8bf93f980ab73a0e17 Mon Sep 17 00:00:00 2001 From: UjjawalShakya Date: Fri, 21 Feb 2025 11:36:20 +0530 Subject: [PATCH 1/3] Fixed session merge issue --- .../conftest.cpython-39-pytest-7.4.4.pyc | Bin 0 -> 2558 bytes browserstack.yml | 77 ++++++++++++++++++ conftest.py | 11 +-- local.log | 1 + log/key-metrics.json.lock | 0 .../sample-test.cpython-39-pytest-7.4.4.pyc | Bin 0 -> 2177 bytes .../sample-test1.cpython-39-pytest-7.4.4.pyc | Bin 0 -> 2178 bytes .../sample-test2.cpython-39-pytest-7.4.4.pyc | Bin 0 -> 2178 bytes .../sample-test3.cpython-39-pytest-7.4.4.pyc | Bin 0 -> 2155 bytes src/tests/sample-test1.py | 54 ++++++++++++ 10 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 __pycache__/conftest.cpython-39-pytest-7.4.4.pyc create mode 100644 browserstack.yml create mode 100644 local.log create mode 100644 log/key-metrics.json.lock create mode 100644 src/tests/__pycache__/sample-test.cpython-39-pytest-7.4.4.pyc create mode 100644 src/tests/__pycache__/sample-test1.cpython-39-pytest-7.4.4.pyc create mode 100644 src/tests/__pycache__/sample-test2.cpython-39-pytest-7.4.4.pyc create mode 100644 src/tests/__pycache__/sample-test3.cpython-39-pytest-7.4.4.pyc create mode 100644 src/tests/sample-test1.py diff --git a/__pycache__/conftest.cpython-39-pytest-7.4.4.pyc b/__pycache__/conftest.cpython-39-pytest-7.4.4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7214ede93b8db13307f096550b34b725bc7704f GIT binary patch literal 2558 zcmZt{%WfM-vb*QSmq<#YMALR`+3QWr1SV|<2zIr~!_mrtp;$H~*@5RmjMyz{sCh8m zL(3wl6OFwY$p`F#x-78QJp}oV9Qza?K!E(h9(GeTL%py&gRZKss;;i?dbBq)Qy}pD zrT*jI&qYFh!O6uh2a_*gsDDsGIN>xPE=@5D4Mr#lP1mBC#CGje;Q1L*5wRYc=UJ!_&)l+e#o$W_k z>zyZm)eB#4KKo{CZF6h;(dv5V1yCE0o~~(gpoG-*OTtI1t7}_Zo%OX>+BgtLuD!YT z^w~D(CUPKjZg&uM6F-j7Pt}e4=x3pS=2#a}@$AC{wP18%s9ymjq(>)=(-S%|I6I-- zXb_-GpsWTtriqzY+-{HrhlMFJX2&dXlH7=m>6lWIf zU6Ob`L$Z+wCszw=U^-5G&El$yv0V#~bV5waP`9yA{~jkM{gs zU+`6MUz>Oc?M#oUol}D*8v7@a4`9{5KX1RlFtrE0o_FX4YTr9J^4eKA?ww!Ay^ELC z21~oRd#it>YtzVdE?)I5Fs0CfUMfDkUK5!x z)V}~E&^Mv1U>sADi436@Nre@Bm5RED{AJ|D4(4FzP3jEMu-9GPh$8IxRENG!u?Ar&^{0(dT4 z0JNP3SvY|NCY~!FFYQkT~zQr;o6}>test7irx54lgdwEZ8I-#q8-dK`2m8v z2>t{>+lON30MfCEoDUIv1fXf9DU#+zy1i_p=sp6BdIlaMg*X3a80snj!b-FT5voCa z0JHL0gtRjaGX~_+XTWR~hN=NbAVL_YwArN;G!(WW8z5^kxdbRX%efaRmAZmT>o61s z9$m?n-GzD|_(9@F&}6>oA9c=VjZT)QEl)uXV_$Dc0Z$CnRQ`;mol{-`7N<4iNhqFu z36~G`BJaRv@RkgGt}EdH_UUI&8_F2SB%V;)*;@U7x{O4Bc8Tl_ zls4Ki6CXO*{CQ=y)KS#!czs_wsT>;Dfm_bp6CAq0AWGzQG>#9FHlW93{l https://www.browserstack.com/docs/automate/selenium/organize-tests +buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} +# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng` +# This property is needed to send test context to BrowserStack (test name, status) +framework: pytest +useW3C: false +# ======================================= +# Platforms (Browsers / Devices to test) +# ======================================= +# Platforms object contains all the browser / device combinations you want to test on. +# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate) +platforms: + - os: Windows + osVersion: 11 + browserName: chrome + browserVersion: latest + - os: OS X + osVersion: Ventura + browserName: playwright-webkit + browserVersion: latest + - os: Windows + osVersion: 11 + browserName: playwright-firefox + browserVersion: latest +# ======================= +# Parallels per Platform +# ======================= +# The number of parallel threads to be used for each platform set. +# BrowserStack's SDK runner will select the best strategy based on the configured value +# +# Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack +# +# Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack +parallelsPerPlatform: 1 + +# ========================================== +# BrowserStack Local +# (For localhost, staging/private websites) +# ========================================== +# Set browserStackLocal to true if your website under test is not accessible publicly over the internet +# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction +browserstackLocal: true # (Default false) +# browserStackLocalOptions: +# Options to be passed to BrowserStack local in-case of advanced configurations + # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. + # forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections + +source: pytest-playwright-browserstack:sample-sdk:v1.0 + +# =================== +# Debugging features +# =================== +debug: false # # Set to true if you need screenshots for every selenium command ran +networkLogs: false # Set to true to enable HAR logs capturing +consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) +# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) diff --git a/conftest.py b/conftest.py index bda6698..1fcfc6a 100644 --- a/conftest.py +++ b/conftest.py @@ -24,16 +24,13 @@ CONFIG = json.load(data_file) - - BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG["user"] BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG[ "key"] - -if os.environ['REMOTE'] == "true": - @pytest.fixture(scope='session') +if os.environ.get('REMOTE', 'true') == "true": + @pytest.fixture(scope='function') def session_capabilities(playwright: Playwright): global timenow global lock @@ -50,14 +47,14 @@ def session_capabilities(playwright: Playwright): print("capabilities => " + json.dumps(capabilities)) stringifiedCaps = urllib.parse.quote(json.dumps(capabilities)) caps = 'wss://cdp.browserstack.com/playwright?caps=' + stringifiedCaps - browser = playwright.chromium.connect(str(caps)) + browser = playwright.chromium.launch() context = browser.new_context() page = context.new_page() yield page context.close() browser.close() else: - @pytest.fixture(scope='session') + @pytest.fixture(scope='function') def session_capabilities(playwright: Playwright): capabilities = CONFIG['environments'][TASK_ID] if "browser" in capabilities and capabilities['browser'] == 'chrome': diff --git a/local.log b/local.log new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/local.log @@ -0,0 +1 @@ + diff --git a/log/key-metrics.json.lock b/log/key-metrics.json.lock new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/__pycache__/sample-test.cpython-39-pytest-7.4.4.pyc b/src/tests/__pycache__/sample-test.cpython-39-pytest-7.4.4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44c555357b0e5367893382a845103e65fbde8cc9 GIT binary patch literal 2177 zcmbtWOK%iM5bmDW&OR~r@-RurXeAPsU>gD@br<%rz1}fP?qQAIMM1p_M}ugT1Xy!hNr(_R5UTl zZi9XkZeW?70DBO{!3sS|S7!$7r|5g-{yzO+W)v;JKb_BSLU!|(wto+O2USxve`>~! zYQKOk00*k#!)*>JMos?kNdb>n; z`g4t_tS}xXS@$g?lt~gsB5U6S2TC=KlsW6A^*%l{wzm2>TRw9(onGt?>NiOgc~LUjRJf7Z-p)jNhj=qHwyqxH zj}=nR5L{xke@xja4`ZpUQ6dvni;{rIgsbL=Nq=YROZHeQJBY$yPaOeFKa69>OSVv^ zkeusxr`j^{cgaKM2gwA$TCd6S^A+#|1hFP2L_-V{)wq^UB@@yoTpjfT4b54~gJhf% z&Q#qOWXLo}b*`6jhe>>kb8v0NA0~WEqz^41A~BI5QA=aO_rNUx6q3k^Q1x4n1D2LT zTclAaRSn=G5-`>HmP8X)qV?OVE0_>~0Zyc3Cj`xq3FYn(!Tbr2l$DYZ8`!C?k%9R@ zP6u^eNxshapb264RbnnI5|QYLk z4e&zSK-e-Y>>3@ji{a1g!0Z}bvt>4{Q#dm}!b`?E+`{}E=mxr}zaILmVanF(!2z0^ zZrw%>ZHb!D0H6s_>jauXV=bSjy?t2ob;Um^vh78mA%QHIK(%dpPkJQKsp@TdJ;CJN zDkFExO!m%uJ;FzmF^i=Dg(tl#!@bR3*3m-Fh^Rh2G;N?F{-v5rAe*$>fm;WJZ62}RI%l;WHC6ee^+gcQ{ zhb+>!#LojVUxNi=v?vq7z=d~K%KtUSlc0JT=3zqOHNqC=cSo&F&JiZEO(2&Y!tycan)O9h91D~W}*(=JDDsPu-^9!lag~@e3 al>5avp_7PR)!kOW{~4%9#%GcoG@SNH_qggN4}v|i>C#<_VX4j@jFK78BUW7 z<%UF=aey(<`#8gJqVbENxkH1Rb9`u03#c^*Ki|juQT1Xy$hG)NFls7O+ zzXbaRWMGw^g!3SZ!!`O2JvBFAKTXdR`&s(#+{l}N|6aDpgzRKZef~Z49du3J_^A=q z%l!hn021hm_jfpy7(p*oWiVm!RHlvZ13KvbaB<7+{+KpyQ0mIq^$C~hYF~_5INS&% zn|PiKWXMwI&Nz;kJGhp%`+H>Mc@L%}0@W;Cxk*OuYYq(DSNbG{x6<{m$E-kf$3(dL zbB(C1AR5ML=dD91lOza5+PVb}6lNMJwfn{CJ$z&g20fgvet0gKZS{mZ7`XcNQcv^@ zWr9qTOKF=3!2m$(uJnW!UQu?Ur8I55<8LMg-`$WcEHAYN&doxe6$5K`NF!1-)F~IbKC}O-2g9k!# zuJ4^{$=Dl{hs^WiDS$O!v&H9Y;0Guo%}j}g7{;o8J()=+q(`_q?)e&;vxNKcBq5xs znkUGRX^CpzDB=#{=r-rz+L||v`GiOhMnFg+B0-~8CWP;UTL35|kyD{+w;%f~DU=nF zgn?95fD4JwRQ+2LPFaE0YpIT4LI4Ihk&wLrECVK#vquE;raV+uLPiYIqGtJi=BhFo=c)oE<}VPx2+2J9YV#W?wAh^9zfT^K zP>jj`jBJ+a+JFdVk9aT|%Z)uAKhlPh`1_lJ`6Gr+|SC+QPtBe|0GX$mYs$QGJgu~w(UOY5?|M6Rt#ZgO^;gv|7f5tZkp}$PUTNm9%;J( literal 0 HcmV?d00001 diff --git a/src/tests/__pycache__/sample-test2.cpython-39-pytest-7.4.4.pyc b/src/tests/__pycache__/sample-test2.cpython-39-pytest-7.4.4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e90e44cfe4689becda8bb2d84e70689a11145af GIT binary patch literal 2178 zcmbtWTaVjB6rQmi$GLX9o3``pv{LQ(|$&yy9j^Nq*^S99p z2cZ|5S$<4luE7$wflx$oh_-RD8xzw&7)`A03NAJFwhbC1tWKP52V|I<&oH%U<%zXj zqc*KRLECle&>HLwitnIa{UxBHtsYi3dz3I=>Nn2hlt;dyRg0$uyY}-YEb#|M=qXN< z4CRJInX!j4(0e$;aH8?6p}Bp7nsdBwQVXax2S4A)3|awMWsY)FB5F%JGbuif_V6)S z3%lyV!U78iEUaY$-ep)t2W*2?TTE_U#Yu0Au4qP#}e zXeX-$7~bo$4cbE)__l|Cff`yUw_!PXRj$w@^eDvnjt4p?rT=$PL@gu_KgF}(G0Gbl zrC))412V8mkHL8m#r_(7j~<^Ju%DnOi~SURe{SSW!2cjyWI}ebrau2J`X0I_Z~WYd z>g9eGodpSW#fMuQN{pZvsxp|ccq-Gz4*}im{&?Y>+x;nRT&L8PvFj5q)78Ehvv9Z` zNH+028OV^O&h2p=F?aK7+V1a=k>}l?k_c3@bmayaxvx1ea9`?^6h4<8`DV-tM0ZSt zt3TI>$_k=koOa$igfdBjP^7J!;6P!fky5)~oZiC+#^z=Zr>h^IPG;wN!rk0-_3Oo+ z=o!icnI;$0HW7jWfYx2^2`#*=>_kgx+Iq{Kw04t(p&Q1d4TbAz#od`o_W*CC#^%)n z{Ha399)e4Z_Kv7Z!h=XEYZS{^Rm0dPGUlo=V$$20d6GSns^W)%zpD-brWZsJa*- z;Y`&$L556ARQq}ncMwOnI0x6(ykX2IM0zj+LJ|=P8nrSZd>7mTKp}~o3RS!H$Y)8R ztcWBGq^bg3NPMR1-;r?23bbBJbp#UvFu;j~>;zyLFrl0sBA7Sjp|TP(Vvr`?Bg(ul zXR4+<$t&vJfH1tWFlW^gb77e|UoxfJmzJ3;%4D3Y3XqsTNBjaL^Wf{jw@_#?nBKcb z9+FUu$?l8{%5<$m1ha=c7>(un4v!ydLrMJIf#Ci?hc5<#Op=hTYvz1EnW;vZl|otp zd~q5G!j@rS$7q`!41Z=DR>$a=O|x#Dz^VBOUNO$#CgzvG*4I=0^`qZ4Ofg$sc!BAr zXSb2TT%smS0GI;QI)>&jS&REw**d6ty5%3|>DIE-P(kKTq1`sz$6eyDI1!yplihHfr{_fPim_@!vlAstCMN1Xg<@)%gQt0mI+C}Aj YF^TCkWLNdL74VM+>f)x^KI2qg0Ux?*E&u=k literal 0 HcmV?d00001 diff --git a/src/tests/__pycache__/sample-test3.cpython-39-pytest-7.4.4.pyc b/src/tests/__pycache__/sample-test3.cpython-39-pytest-7.4.4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e642879e8b191a9ff495e82ec3a160816dbb48b9 GIT binary patch literal 2155 zcmbtWOK;mo5Z>iOqMmVVH%`(Qp`vM2)KVNLE?~q#(lnO>H3Fn;!xIAOljU!2J)k9!9$_vLH3nyf|}T2@#!=Qy_krIp#>Q@g~~Xve#~ zAI&Y-+Tm+4AY z3ov}wWec?J417GmKSACslviLlc~zdGtMo01?F|p~Il!5k7~Mk=wUAtThG)NGls7O+ zzX1CNM17i`f&Czg!)3Zg&&~~)&(ZV6{5E}OZsbkCe>ZEENOC1>>izGbZ=q81#*dAt zUe1@$C6GWRytkXKjipS)cE3LmlKA_SP2!#(Px>74ji4~9GMKP4#}yqL^3y29PrarNhw zuIL)d1eqpR(l!x-0f5$Rb%hpgsY;@yG;Mt~WL>CLx@unkUGR zX^CpzEJ6(8=r-rz#fmqK`GiOhx;rEhk)Tma6TApirMNXQ@n%YX^x42WRfl!wYn$cVv-=!`4#ft;zDt_x4+ zOf?`3ugt-vMP_r6xm+@(+gBHvPnF3yS2mECzd(Eg&h6;S{@0LG(VyPGPacs_jLH6t z^vmN~hX`hmcrY5v^#P9`X+vGueZl>{4qx;InIs`w*UV-wnW;v3Duqz6lJPNaV!jEMzFu_l=x-ZFacR2n0T+_Kl#L87A8JCIL#tD3 z4b9=oESk{XJ*s-Twx8tb?xM?(Kju%NuD0DL9pdXub++A(VDfI6kh?`9JD<26!bj5y zi=+U9C!I3Eo$XHA)=JKZD3>0YojiYmmBSuFf{A2ZQ&o=30e%6r8P~xV$6S)jntdP0 z2QWkh2*MS-{AVHi-;whxfR}#$AEG8v6hpY|pV3kxiH^0URUv!GLVZg7Dj@SMAP}QP znedeZon7evEk?BhT4=;bH{X=#mL0|yVfkXr*EC!cN`D%JGKhp~>gs;Qo%6~X?3MKn z`RZ{7wJ4!oUx{>=6*7Jv(BLX6x?HXNUAH|ki+qnHL2*kIC03j^*V`|oM)v~O`BBcb WNld39yRNTN0skma2a2=pI`&_elVm{v literal 0 HcmV?d00001 diff --git a/src/tests/sample-test1.py b/src/tests/sample-test1.py new file mode 100644 index 0000000..60337e0 --- /dev/null +++ b/src/tests/sample-test1.py @@ -0,0 +1,54 @@ +import pytest +from playwright.sync_api import expect + + +def test_sample(session_capabilities, base_url) -> None: + try: + # Load the PAge returned by the fixture + page = session_capabilities + print(page) + # Navigate to the base url + page.goto(base_url, timeout=0) + + # Add the first item to cart + page.locator("[id=\"\\31 \"]").get_by_text("Add to cart").click() + phone = page.locator("[id=\"\\31 \"]").locator(".shelf-item__title").all_inner_texts() + print("Phone =>" + str(phone[0])) + + # Get the items from Cart + qty = page.locator(".bag__quantity").all_inner_texts() + print("Bag quantity => " + str(qty[0])) + + # Verify if there is a shopping cart + expect(page.locator(".bag__quantity")).to_have_count(1) + # Verify if there is only one item in the shopping cart + expect(page.locator(".bag__quantity")).to_have_text("1") + + # Log information to console + log_contextual_info("The cart has one item", "info", page) + + # Get the handle for cart item + cart_item = page.locator(".shelf-item__details") + + # Verify if the cart has the right item + #expect(cart_item.locator(".title")).to_have_text(phone) + print("Cart item => "+cart_item.locator(".title").all_inner_texts()[0]) + assert cart_item.locator(".title").all_inner_texts()[0]==phone[0] + + # Update the test result + mark_test_status("passed", "The cart has " + str(cart_item.locator(".title").all_inner_texts()[0]), page) + except Exception as err: + # Extract error message from Exception + error = str(err).split("Call log:")[0].replace("\n", " but ").replace(":", "=>").replace("'", "") + mark_test_status("failed", error, page) + raise ValueError(error) + + +def mark_test_status(status, reason, page): + page.evaluate("_ => {}", + "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\"" + status + "\", \"reason\": \"" + reason + "\"}}"); + + +def log_contextual_info(desc, loglevel, page): + page.evaluate("_ => {}", + "browserstack_executor: {\"action\": \"annotate\", \"arguments\": {\"data\":\"" + desc + "\", \"level\": \"" + loglevel + "\"}}"); From 7ddd4bdbe1b28459cabd9b4bc3d4bac247a71b7c Mon Sep 17 00:00:00 2001 From: UjjawalShakya Date: Fri, 21 Feb 2025 11:38:24 +0530 Subject: [PATCH 2/3] Fixed session merge issue --- browserstack.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 924ca4e..a7afbd9 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -3,8 +3,8 @@ # ============================= # Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and # BROWSERSTACK_ACCESS_KEY as env variables -userName: ujjawalshakya_5SxW47 -accessKey: QJQa8hjLboCF3o3sQLvf +userName: YOUR_USERNAME +accessKey: YOUR_ACCESS_KEY # ====================== # BrowserStack Reporting From 04838e0d99f2c223c370fc8349e07318c526810c Mon Sep 17 00:00:00 2001 From: UjjawalShakya Date: Wed, 26 Feb 2025 23:07:58 +0530 Subject: [PATCH 3/3] Removed unnecessary files --- __pycache__/conftest.cpython-39-pytest-7.4.4.pyc | Bin 2558 -> 0 bytes conftest.py | 2 ++ local.log | 1 - log/key-metrics.json.lock | 0 4 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 __pycache__/conftest.cpython-39-pytest-7.4.4.pyc delete mode 100644 local.log delete mode 100644 log/key-metrics.json.lock diff --git a/__pycache__/conftest.cpython-39-pytest-7.4.4.pyc b/__pycache__/conftest.cpython-39-pytest-7.4.4.pyc deleted file mode 100644 index f7214ede93b8db13307f096550b34b725bc7704f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2558 zcmZt{%WfM-vb*QSmq<#YMALR`+3QWr1SV|<2zIr~!_mrtp;$H~*@5RmjMyz{sCh8m zL(3wl6OFwY$p`F#x-78QJp}oV9Qza?K!E(h9(GeTL%py&gRZKss;;i?dbBq)Qy}pD zrT*jI&qYFh!O6uh2a_*gsDDsGIN>xPE=@5D4Mr#lP1mBC#CGje;Q1L*5wRYc=UJ!_&)l+e#o$W_k z>zyZm)eB#4KKo{CZF6h;(dv5V1yCE0o~~(gpoG-*OTtI1t7}_Zo%OX>+BgtLuD!YT z^w~D(CUPKjZg&uM6F-j7Pt}e4=x3pS=2#a}@$AC{wP18%s9ymjq(>)=(-S%|I6I-- zXb_-GpsWTtriqzY+-{HrhlMFJX2&dXlH7=m>6lWIf zU6Ob`L$Z+wCszw=U^-5G&El$yv0V#~bV5waP`9yA{~jkM{gs zU+`6MUz>Oc?M#oUol}D*8v7@a4`9{5KX1RlFtrE0o_FX4YTr9J^4eKA?ww!Ay^ELC z21~oRd#it>YtzVdE?)I5Fs0CfUMfDkUK5!x z)V}~E&^Mv1U>sADi436@Nre@Bm5RED{AJ|D4(4FzP3jEMu-9GPh$8IxRENG!u?Ar&^{0(dT4 z0JNP3SvY|NCY~!FFYQkT~zQr;o6}>test7irx54lgdwEZ8I-#q8-dK`2m8v z2>t{>+lON30MfCEoDUIv1fXf9DU#+zy1i_p=sp6BdIlaMg*X3a80snj!b-FT5voCa z0JHL0gtRjaGX~_+XTWR~hN=NbAVL_YwArN;G!(WW8z5^kxdbRX%efaRmAZmT>o61s z9$m?n-GzD|_(9@F&}6>oA9c=VjZT)QEl)uXV_$Dc0Z$CnRQ`;mol{-`7N<4iNhqFu z36~G`BJaRv@RkgGt}EdH_UUI&8_F2SB%V;)*;@U7x{O4Bc8Tl_ zls4Ki6CXO*{CQ=y)KS#!czs_wsT>;Dfm_bp6CAq0AWGzQG>#9FHlW93{l