rovided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type null $last_used Null. * @type null $last_ip Null. * } * @param string $new_password The generated application password in plain text. * @param array $args { * Arguments used to create the application password. * * @type string $name The name of the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * } */ do_action( 'wp_create_application_password', $user_id, $new_item, $new_password, $args ); return array( $new_password, $new_item ); } /** * Gets a user's application passwords. * * @since 5.6.0 * * @param int $user_id User ID. * @return array { * The list of application passwords. * * @type array ...$0 { * @type string $uuid The unique identifier for the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. * @type string|null $last_ip The IP address the application password was last used by. * } * } */ public static function get_user_application_passwords( $user_id ) { $passwords = get_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, true ); if ( ! is_array( $passwords ) ) { return array(); } $save = false; foreach ( $passwords as $i => $password ) { if ( ! isset( $password['uuid'] ) ) { $passwords[ $i ]['uuid'] = wp_generate_uuid4(); $save = true; } } if ( $save ) { static::set_user_application_passwords( $user_id, $passwords ); } return $passwords; } /** * Gets a user's application password with the given UUID. * * @since 5.6.0 * * @param int $user_id User ID. * @param string $uuid The password's UUID. * @return array|null { * The application password if found, null otherwise. * * @type string $uuid The unique identifier for the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. * @type string|null $last_ip The IP address the application password was last used by. * } */ public static function get_user_application_password( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $password ) { if ( $password['uuid'] === $uuid ) { return $password; } } return null; } /** * Checks if an application password with the given name exists for this user. * * @since 5.7.0 * * @param int $user_id User ID. * @param string $name Application name. * @return bool Whether the provided application name exists. */ public static function application_name_exists_for_user( $user_id, $name ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $password ) { if ( strtolower( $password['name'] ) === strtolower( $name ) ) { return true; } } return false; } /** * Updates an application password. * * @since 5.6.0 * @since 6.8.0 The actual password should now be hashed using wp_fast_hash(). * * @param int $user_id User ID. * @param string $uuid The password's UUID. * @param array $update { * Information about the application password to update. * * @type string $uuid The unique identifier for the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. * @type string|null $last_ip The IP address the application password was last used by. * } * @return true|WP_Error True if successful, otherwise a WP_Error instance is returned on error. */ public static function update_application_password( $user_id, $uuid, $update = array() ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as &$item ) { if ( $item['uuid'] !== $uuid ) { continue; } if ( ! empty( $update['name'] ) ) { $update['name'] = sanitize_text_field( $update['name'] ); } $save = false; if ( ! empty( $update['name'] ) && $item['name'] !== $update['name'] ) { $item['name'] = $update['name']; $save = true; } if ( $save ) { $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); } } /** * Fires when an application password is updated. * * @since 5.6.0 * @since 6.8.0 The password is now hashed using wp_fast_hash() instead of phpass. * Existing passwords may still be hashed using phpass. * * @param int $user_id The user ID. * @param array $item { * The updated application password details. * * @type string $uuid The unique identifier for the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. * @type string|null $last_ip The IP address the application password was last used by. * } * @param array $update The information to update. */ do_action( 'wp_update_application_password', $user_id, $item, $update ); return true; } return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } /** * Records that an application password has been used. * * @since 5.6.0 * * @param int $user_id User ID. * @param string $uuid The password's UUID. * @return true|WP_Error True if the usage was recorded, a WP_Error if an error occurs. */ public static function record_application_password_usage( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as &$password ) { if ( $password['uuid'] !== $uuid ) { continue; } // Only record activity once a day. if ( $password['last_used'] + DAY_IN_SECONDS > time() ) { return true; } $password['last_used'] = time(); $password['last_ip'] = $_SERVER['REMOTE_ADDR']; $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); } return true; } // Specified application password not found! return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } /** * Deletes an application password. * * @since 5.6.0 * * @param int $user_id User ID. * @param string $uuid The password's UUID. * @return true|WP_Error Whether the password was successfully found and deleted, a WP_Error otherwise. */ public static function delete_application_password( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $key => $item ) { if ( $item['uuid'] === $uuid ) { unset( $passwords[ $key ] ); $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not delete application password.' ) ); } /** * Fires when an application password is deleted. * * @since 5.6.0 * * @param int $user_id The user ID. * @param array $item The data about the application password. */ do_action( 'wp_delete_application_password', $user_id, $item ); return true; } } return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } /** * Deletes all application passwords for the given user. * * @since 5.6.0 * * @param int $user_id User ID. * @return int|WP_Error The number of passwords that were deleted or a WP_Error on failure. */ public static function delete_all_application_passwords( $user_id ) { $passwords = static::get_user_application_passwords( $user_id ); if ( $passwords ) { $saved = static::set_user_application_passwords( $user_id, array() ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not delete application passwords.' ) ); } foreach ( $passwords as $item ) { /** This action is documented in wp-includes/class-wp-application-passwords.php */ do_action( 'wp_delete_application_password', $user_id, $item ); } return count( $passwords ); } return 0; } /** * Sets a user's application passwords. * * @since 5.6.0 * * @param int $user_id User ID. * @param array $passwords { * The list of application passwords. * * @type array ...$0 { * @type string $uuid The unique identifier for the application password. * @type string $app_id A UUID provided by the application to uniquely identify it. * @type string $name The name of the application password. * @type string $password A one-way hash of the password. * @type int $created Unix timestamp of when the password was created. * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. * @type string|null $last_ip The IP address the application password was last used by. * } * } * @return int|bool User meta ID if the key didn't exist (ie. this is the first time that an application password * has been saved for the user), true on successful update, false on failure or if the value passed * is the same as the one that is already in the database. */ protected static function set_user_application_passwords( $user_id, $passwords ) { return update_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, $passwords ); } /** * Sanitizes and then splits a password into smaller chunks. * * @since 5.6.0 * * @param string $raw_password The raw application password. * @return string The chunked password. */ public static function chunk_password( #[\SensitiveParameter] $raw_password ) { $raw_password = preg_replace( '/[^a-z\d]/i', '', $raw_password ); return trim( chunk_split( $raw_password, 4, ' ' ) ); } /** * Hashes a plaintext application password. * * @since 6.8.0 * * @param string $password Plaintext password. * @return string Hashed password. */ public static function hash_password( #[\SensitiveParameter] string $password ): string { return wp_fast_hash( $password ); } /** * Checks a plaintext application password against a hashed password. * * @since 6.8.0 * * @param string $password Plaintext password. * @param string $hash Hash of the password to check against. * @return bool Whether the password matches the hashed password. */ public static function check_password( #[\SensitiveParameter] string $password, string $hash ): bool { if ( ! str_starts_with( $hash, '$generic$' ) ) { /* * If the hash doesn't start with `$generic$`, it is a hash created with `wp_hash_password()`. * This is the case for application passwords created before 6.8.0. */ return wp_check_password( $password, $hash ); } return wp_verify_fast_hash( $password, $hash ); } } ۖF(l5M^KUnْlw˗#>$ q^0p^:s'S?|ɉL\ `U3ǺD"22232"232g9[KbϏZoUgQ+O"^En7%ѣ-GO<ˆG2$K%?j|qفs?>jN8rks:ص<%--) wZvJ/Ws5݋)GX?GnO jhٽՖ + baHknLLmbiD6QҬiW&+/H֠2'~:yzt~<|kX$'C@:Pzs,;_ualo 0y%aR1T%v߭x}RZ%SύE+aLt ma2pܙ{;=>wc (Y.d YUQcKr]~ˑ].ٳ ECAE΂-moV1VhyGJpk ?sߝY^$[Obx; Bzg" u Zu`].j_@e\ĭI%ړNZ-Z_ a}%S@WTb-dp.|stZ&%i݆@<$# rwZMȠKrnfOi[%[bW_%4iQ+ 1iA^x@} INt<ӵ͝P7>ƃruM=P;RnΊӊtkfN)7קewBk췯$Scgݟﴖ?ar{ٷr7oot3nX3BE^2w}Z.,~.xl/>릟tKv|uq@~+<-cO(b+kE{,Or ]mJC2l!M(4xrߵĉgGwbUK>%yD>=xsC"2|ic`yǷ/ _Ni,avDA Ǚ}˹#P"G$ `+OQ'TS|>~y&nt e9}|z+ }C׏\4S[]0>̓XsMQا " eU()^A9*d/; );~Gq5՝/9ۖ3,u9q;JN;ܳ[7̚Y\< P/` 5z- K}d(T'hn;|:~ʰ hc44gi6vc5EE(>Z"D.7-9(MĐ _rva u`S8A@-\6HQ`.՝ՊQ])Y\5E lz}pc-O:¿yA0ؗzP_&7*!+`{i/nT@wI ]<^`%T$^ qV-S-jOUW<>yF&J]ܨڞRV0mnCilSwIp%-iMIaCab.\R& =UCل4hB%'{P1M0UK+ ؏P·d7::gF{ n!MDq"4J!降򸛜/`rs@+auJ9~I0(Nd|ĤEbC 0(@CTQԆ8(a~j귷iJν[6-WAq`r0 6?3QŁyrj72̝'!o_Qs5ɕyJw O/Es8Apl%W.렂̥۩.|η.DNoO7Mv^cޮ_Ӕ۽B q: &>#Nu/⸾%7Ehj*VA6tcgsPI #qbe^hVF ]jL.䤦 #NgFt[逫k )hkj674Lqf! Myv "e/bgq^BDԻ'ܖ Zs[D4'܎0AMI9jTSule@p1wXYKfjUAh0ą 'ue6Qx&{̍ܩQF!fJI%jF7լU&"jCB[EܸZ!L.67Zަ=K(Vc ʯ<,r!@A[xz,iP-IuKݡ"8:[lχ0y6TcZEͱ(mjm߬XN{_rUo/lĈ7(ٹRn籞cG)GmɉF5~HߪLؽNs& EnFOS# k5kEj <| !bqjdtlY 1) lXO-OsW trW_/_KwMv`| _{2sC.{#D7TkQ胑R`~j6D1Wp/"ds$YQ`A7YQWۛVBd-ImTWMujV¤ptaCkS9Tqsa`ݓgB=..LsEZA[݅&* _n cnIƼYg0JsSJEKf%&\1}'d TOt۵eX&Ѽ>don&@l}~WP!b^ 0?Foس D`hP^u3fXUi]S[fJC!($P:RW#hnѣ]"oSAԅcS诉 AJono+PO1'5wdl28cGq@݃x+'l0lAN#T{rEno,y^R84 `V1QGi;KH`wo!@Ba@E(,o[KIKֆsv\ demEF? @W 0Yn-phBY&wn`(v4)bNm7GY`:Ý$گ02`PN6}b%;J*@Afÿ6¡h̠N6bF^e>6 F8HwM:!@Tv^%P0`*{ȏ`$ARm/]3ct0 und462:Ъ8oӁzVjrm Ƈ..8XF(1 aq.R0WK 'ejG @-^o.;mHO퍶j6(OpüAGZ^Ls;&G_mn */.ƒ墶Sήx,hw2 &v35\|K54rɖ."3ifB(8OnڒŮ>+w[mXs_5]ZRUYSnh:`0P<|56|a{y:U)(9 2|*!#'Í,NKaztԱ] -pTmj0l lO_+kp՛]_ܪZWBu{%ƶs5&ȧ{Ei#ڈ7R7%kTW J̕Ń+(&Y;=HX.ޥ.؛лdKiwXpc)|2o!ޕH;>rUk,^.k;]k5 -nXj[`6E)ww/MYmYm/)4.bT=mD---w+{MFjnHjR@SinSRci^ܬOjm̻nuVFXk1U%T:eP^j~bڤ iNhj(o4ީ2^I ~^weV e+y "c)_ [cYzWq< Owoصîv!7/zE+G]t#Z], e$Ɋ}&p9t Zz֜ ]8r7Z%:o<05[2˟zBYuw! Fmrs_"hp;u:Q]SQ^L.mbt}5+J {﹖UXduPӧ.PzE0M.Șco:%>>{*S~' cu+( 1л\%Șw# yvOdkc%3S]gcu-'LOK~72+t 2: '潝kc\ '{ GpgJTlnKҁɔߕy0/2Oz!kt:>ݠx Z{րߦue?ϼVkC3aG X\/&jP78 s4@RR#C5׮`%%g\L蛡w^ʝnQYzP"f#L8<{XCTfȆ\KL%*9'BQO鑽56:TB,ocͥϓ< Vf;xq )߾{~w"gjsfKؚozE_⢗QX:0ѩYQ )OreIX*t6Hoz-dBeYYK=]r a;)(.ݸv_xY HùfIY/=4TfKd%gQX$TtvOZ~Z;-,FZ=}JgEb$ Y0]#d ɆQ5*nAif\ s)Sܛgl)gz[:1GH#Jty?/^u3!D,UBqn`֕d!u%#_<N掃[PZr+̂PV@V,܃!Z3OiME~qJ4vg[",r8)GGHg(tOhBWpy[^Niu\?+ڠbEfq`HU^ BV2fƮv%x(wKSu@R?)p߸2*7ih,nmZIi!\7o$G*bm6ii@fh׽G{[6;,;A"nH&bR0mxSZdd"^.EoG2*S?U ǡU9MJ hK5ο'@t":Qg)*۝8~;WK% ӽ#kF=y?H_ţ5*Khe].Q)z.).nL%Cx@I!ނnw޺4o|],,zY;A]/?~*F:+))ς43m+q2FIJ$6S~!0s:E?bk$`i zVh rs%& f5]C㍵V+37tgJIH0G'̋M* MYCc*YyD]C3z]m9^%`{EWzEPW(^}l\%2J 2MNH.w˨D ?IP9I](#]<+-dato(X+gCKui2,YðB`hK>Fd‴fd$AYf"eTyQR^% 'Bg",_θRr[.ؚ0{d#;+AeJ|WLGҐF @ k''r?8Bf:kqz%u&Q}"/h1OE}VB~ CE2ϮRHݔ0q&5=f{/ꓮBVԸ{E >H)T*PyԠ>,KXgľ#mB!u-Z_0Ԙ akkϬ=?Ih!+*SؒizV2gtAޥre\V/5o͆ŚPZͪvլ5kt^Y.Y]UoUŪxrJ*tscItCy4Kx;l\aOKT1W zhPf_\e./L 5]h^M^b{3~۾MRm~+Xnv4?l ڽZ2}íe6}kM)|Em>!k2!["߭߭vI`8Wi*8֚M 0=V-#~Szf7߫CtЦն:5تh܆jv]kWbeuaUu/ ѕco/CBu9߫JT}Gj}{cfyAýTwP}k>L`/)ՃTz+Sߋ~JuVTefJ{]Ate!z*C{C#|i7ՐE? ls B4 ?^:ŹZh1qxcpQPBAn_'`̷Ť>-xAzdV(s^Z =j |fy nIﲈErIL4U"؞tRSwR[``ܐ̑7h{&_Z_ٳ迮e~ m ṇ``ucظ}!}6bkM$cD?1] (\bggk S 1dc?XV#<P*BrJϼjKCP5$z4]#c$%MK[rdL]JNO'Lrpz#?MtH|5p^+3!+ XDi Nl08oU%=K)'X<}9[_c9o+dObwS8Q+hfΤ;$w9B Po ck3MhZS5i>Rk! 1JMVX#|xX\{S,vK ݅ʦgIG"ER?̵!, L꧓'W'ryb//OwyU"A2:p-\ C* 6U&DR:$8#*N(Q7?*GP<G'Y՝%lhdudzc5=# l,K^b|9@hQly1f?w ka4up`*`!^rl rp,t{Ib}iܡ"$fy $ sP򦘍c%1j -JRpWNzbvF&7;OlB<{LuZY0J,L=Œ%}Cxh$/:xl/@i_j`$nx.h.};7Ě^j Fb rqKV1^O#~Kf3|8-iI罣F:C~7~.}w(B[]P$3(Z<9 m㜃2 ?VVPN?dVY :qiǓ ;ÿ&AHuTy9+Uo|—@påUo=C*W?b9cϮ2&=~42tkr<Ur@z+l(^({YdS,Z+wF4yW&Oԍ@,=sF.Q}rIyOQdWH / gDx2~GtD^T{  =eo|'5=ş<ea4P"Dxjp긭7tS]?ܞ[(:ϔ=[SڣePo)~/L@5 aYLaҺj#No>膩 CR#] \CL.sU?,o{`JP1NwEΈ4\H|lh\Sx|񗽏Gfflaz+3L  xlIr̫z0ƪ12_:h̴uWwƇ/{Ÿ`c zI$se_ΆG/G& /(B$0}?}`x80&4!4iu_t]5iYF? "EWRi}'Y&m*GFʷxNcj8WI}%R.P"v2Vkڃ \dCE5ϫßLMAԾgH1At6G ! )'} < 8P.t0>:qC }|?)/h5`=@Ԣ!^zIeHXz07D:P5hz0.#S1u"#gPJҫnpMRMwKzt㙢Q/-$ZAl`BGTPQ B%₉?6nGe H@EU (~?j/s^\Mn)'z&XBX=$0+bB(Z͂JKK+E7rd #1]Rdd,޲| v%@L'%Hb{됇+/[1bWs#~zNkaK_fr3}]~3!Z6P )7[f3hy5- _7 !O="?؞\/f"Om2gqV~a[Nﰡ|,޸ikfu8%aC@sRhZվ Dڞ=mZ'!F#8@M>B,Ko 6r*VQ@|YIܚϭBX?X>AMޤ貕op=Or}.=KѲegZkK9WHզ0೙ϱbO~PlM`r.s`r.pχ' ̴{zt̒--|~ȞZ[.˜}šsN= hG܈} C &}/Pig ]赕q2޷.qEg+t"F_rH3u"drh̘q<۽;aqh(/*뚠&l Gfag=Fp0@|Xfaokl564F Svh^EKh;tG`5A^ :ZX*Fg-IJ@9qIj%Q-UxqF{jgt\ )Q2tdDHS8 x+O3w9.-ĕҊ*J pa~놆\Y В,f!h,|X}g!*Ne ̈́.1;G+kKZE=C{G]}V:Sz0aaiy/s|w:x i "!q\vOꁯ(;N#'#O :}s.p0bRvXt%.XkiS|+U 6{;߈>ly[>Q~ Dq`vYoo҇߾Y ,&15a qE l\## [eC*<%غhmM%^֘klg} 9@u]ny @ #0Y+zYIPJ_)W~c; O\xP )<ɯdvvu׿vVTA:_nmi͍Lh)nfGo7VP?>p ,K7XF+n's w\0%oM~nP[ 5Z9nM[x!'K Iis T~K ϧx\0oAST!Uӫϩ誦S F]!DOڭ7"a~hyzڑG%m+>1 8xa8VY:>(\NJ%"cKP 9KO/-r&/(-~"Z޹u)"'*Xpt\Bu^fI c7!e@qsRh2t(!3(qʙq]Y$Slz8-דpHoCݎw,]R,QaWY.aLXKjoq(9R#°sǏ>š1=V6>.=F?'z(Tԑ0'}%ӱH3%  MQKe=Z\4y ~w*.ׄ]*r0EA{-%>N!\=k(RQ,\΢vT| ?KD?Q.k}#A0  ƸTy"AwJ:!rH{bq ]C#@33#zBkR-{A{SN1'QnqOISF>@*0Zboy_&dxI&7bkD LlU.El*Cw6+ ]DK?9K]Q|\ ˘KtY_p_aEX:ܣ:o%^OCW+oS~k-[wKs'Eq(QH>!t<. ) ':YKl#,[Q@ml )a= {z:v|Z( tM$zk|%x=MfWX _E5,DG?[,(K^<]0ʔ5C[a0ȯP6%s:" VP4 O;sfii+xQ4ߦfj&ac-JfC1:V1v]R09cm]d)W"Va0s=.0d@z3n:fzT‘ |:† оxM-s+ E&0Ău'ΠP=Y1䧔$~|tqrj{ c"XAWe D{s/:TbDS+$tq7-[ރbUS4|pC d6&,Ч*Q8 X9v$Un:*/ Gl_vcfR j˲m] ɐ s y_{e\s8kP`# cdmNk,6T*sC-?HTВm(bCLԛf#<03/[`GAQxOJϥ:z&e5Bӻoʉ*;`@ɀɣ CP`>2W0ݾ'y&Ϙ mޣ↾=tt zLJ&(@$E`,b|G?zWKD:]T='}݂HiN |=F(ʵ+) F!oEhlBSt㔜k\kGFu\+j՞`ݰ^my䔘 A'g94x+`97x%;(9S,`^XyҡƐKusḥ -0;SaF7C\f/*W?u?3cqԝC⻿&>8B z#vݲY` &;%S+{kp`E bm}VA^}j@cyR:(3f$QTF˲BysŃIz(/Bf͖آ`.݃UQ֫[$Hu.0McPgp;B2x*PG JovQсD\zN+$"K-иPW$`' D,NE/0NQ49a977-e$ju?},܈ц+@! h:SWVtQ+onjo_ iwsws|E%ՁϋINI':5,lJtoSeu^^A]G"0f ٮZ&>?&m6o# 5؀Ч*P tAС c(*.vXMV}et5WQBhϖLQ,!@#G׏{0.867l@31iI!gʁg/G%~[tE=! :zcƏC':Uxq?GG/m[T.PˉNtut"@lo'>8 Y/Ɍk$99"lZkP<,u(=@UL|ڃaQ/JM̬p%XK鯥xh`c)neYYM>Q}vmޣGIB9"@G-{i=l&VK$>iZGkI&g--)jZ[6r6V:[ Z cr\ QYq*.\ׯ.o\dU>P_G0bQMlbxaMurPdy}JgrzK=:& /pyO/p 8u03?vF( * a*vBKh [HS3qyRl#M4kբ.kgQL-T$ws@>4oV(]!}>dOSb[H8zlkҴZKEFNRŇU.p9z ?zfߤ /$p:5;ڝkrn 0YRS%6gj#G8zG;*. P л0 t l @D%H&I/#,@ 9ѦÃܞĪM?\<@8wAsk:CiOxX;~O@hKT2{%zcoؗ<[e/zLJ꧁CסxV=%L'0];:c|Mdy$PN AYxȉ0PA2GX37:0OIG tupxK[?,5 $7<U(Z_t'>O7;^B}