From 41b769ab81e8e74ba9acb6b8d25cb6d76309685b Mon Sep 17 00:00:00 2001 From: Enda Phelan Date: Thu, 11 Mar 2021 16:50:24 +0000 Subject: [PATCH] feat(login): add token-based login --- cmd/rhoas/pkged.go | 2 +- docs/commands/rhoas_login.adoc | 1 + locales/cmd/login/active.en.toml | 7 ++ locales/cmd/whoami/active.en.toml | 5 +- pkg/cmd/login/login.go | 126 +++++++++++++++++++----------- pkg/cmd/whoami/whoami.go | 16 +++- 6 files changed, 107 insertions(+), 50 deletions(-) diff --git a/cmd/rhoas/pkged.go b/cmd/rhoas/pkged.go index 86ef4cb043..fd759aa91d 100644 --- a/cmd/rhoas/pkged.go +++ b/cmd/rhoas/pkged.go @@ -9,4 +9,4 @@ import ( "github.com/markbates/pkger/pkging/mem" ) -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffecbd5973a34ab636fc573a7cdbbb6b33085b38e25c189585c032559a18f28b373a4850015622e9944674a2fffb1739304968f2965caeddbae8e8da5642ce8bf5ace159ff77178d7f4c66778fff771744f37001bf7893f84ff843f8e1dd7bde03cfbbc321ef729ee0fee9a10837fb1afdbc7bbcfb339cc4c33f87d37088dcf19fdec41ffe597e9e34ffe34e8ba7939ff3efee3cbc7b3ca9873fee0c371ede3dded1fff83af1ee1eefeefeb8ebbb3f83e19cfebb3b99cccf18c3ab3bf7c2bbc7ffefeecbddfffbe3ae3777d1f0ee71fe733164ffd11dbab3c9f8eef16e3c99ff231acfe62e4243ff1f7031ff87bb7423e44234fc4734fe075c44c8ff87e77ae1f0ee8f3b75d28cd07086dfeba1e8df3f2793f99760827ba0739edd3d8e1708fd71f77538cdfedd1fcee6d983f99fb69e789df80b3cc6ffbb3b6be15edd689c4eecbc5d5227af13ffd4f67f06932ff1c4278f99c39fb388ac1dff8597eefef39ffffc71f783ceeea403f5f8279a782e6b8f4f22fe7f7f38772344fe34a667216df4c7dd2cda0cef1ee5fb3feee2893fbc7b14f8da43ad5ee36b3cf9cbbfe7117940e004fe5f9cf02ffebecf738f82f8288a5f78b156e7e507a90eeefeb88b66fff6f112d1d59a25a4b7afc3e5dda328ff71a78d27778fa2c8f1429dffe3ce40d17874f7c8938d19de3df2f7f587873fee06917ff7c8731cf7c79d9affd3fef7bfa7aecfdd3d727fdc757dfc42ee8fbb5e366a058de8146a1cfdcf89379a91364ff328c683e80d3ddc052fd5a407f101773fc37fb97fe03991bfe7f9fffc71f7bad554ac3df01c2fa64db389fee78fbbc6e94ded7fff7b315ecc86fedde3ffc7fdc1fdc1fd3fb29de1f0e7eddadfaefde16bffc7dd940cf9ffeebe8f8273b73c9301fff9e3ce77e76eba1e53f7e7703ccf5f9a3f417a3c47bcfce92ee8f0f6cb18d22215303cf72e01c393cbc49f256084cb09183cea8f11306ca2a70898bce94dc0dc04cc2f1530540a5c59cafc399f8c86e3c3b2863649858d50ff3061235e4ed8e051df84cd4dd8dc84cd0161c384c187889c3f5d6f1e2d875f86e32ff3498c8e683be5b699287a1053595413b8f709a11f2e9a1d9642b55d29248a7cbdfe1e298407bc470cd5abc4d0fd8328d7538121f312c73f3c88d2e717437f7ab1bf2d8a0a7286fc7848cee422849e412641d8669545485130d0d63769703969b07d4f33e17067094dde578385afca3f81555b786a33f184c102d87a02458dfdb7d9f4c6fad243dc0b1424a47de5025d34178ea5cf404f5940b113b0e702f69e71239842c73639b72171509823184973c756be42b53985f66bf67e475887aec56fbae4bf75bf11cb0bd07b92b5868f862d0539621781863277eca7206daba93aef379431ee571bcf1fda2363e65868ee89bcac45de4b03cd43dfee4edae3eed215cc453bf691ff6cd63c1525c39e84c85c22297f7ffadb80bee7c85862a8caa1afa20548941514d0c26f3c45c00e575aa444bedd098020735a437f1872f47d3f6c2ed2579397bbcb8a61f873b29ad14bbd5fe8a68d7e81e227dd14bf9be27753fc3e44d4a7d7fc8a5a1febe2122a1fcff31fa0f2dd5f4ee52303bea97c3795ef37910387f43dacdbf81b606b0b20985c5f54101ca57fd3bf42819f3b96346ac766e2c572d21e9b0b4f34579e2a27be6a8e707b2f6e72ae258d0722daf8aa39b73bd3258c07c1f7ded3d8b7a48d6f2b2b28ea1cb03a012cb4d75a86e4895d047b4fd1509c2dfabc21ffe869e30beb451e5acce6c7f4a2b451a6177d9cf5fde1827ad1cdfa7ed38b6ef270bf3c4caff915f522d6c59fa3051cfe1c0fe7c7020b0aedce0465e2bf78aecfd71e6b0f8f9cf4e5e141aecbb25c3f4ff8d47f1d287ba87142a6133dd46bbcc8f10ff715c24712eb0ff78294354d275a217c0e34bd099f9bf0f914c2a728193e540e5d02aa893559ceb09a78ff3ea97408abd56a9cf8501591208a02577b8758a2233e07ac3dd4847b2e1521f50759126b62adfef905d30dacfddde4c321dc66cc7cdbe0306e73453302b6be0076177989348382b7702d298689b4f1d526e7db86016c63e3583e2a62333df15e4c359c7a89f296e23cade54fa1ba0aa08a166ea2485034134dcdfa0a7c01716e43311c4b0a81608eb4a681bc31983a82b9d1545dd254230116c377aac17b6277097b4a026c63e9dbfa1bb05f03da8f811c51477eeb75d118a185a61aa1270c02283881d7d2974ebc46d07e0d3c758d1cdb409a6ad68065f0be3a08b4b13e814273531c97277643bf656eb448e160a2bcb9aaf9e626ca1444bb7370f17b5bfad253cd04b6468123c80b10a3b16feb083c4dc8ba34d0fc0db64c8c6793763ce79dd84c606c72c07e5da47df5f01af3051f48e28d1b23630963093962770a855ad0554dceb1d0ccdb4c5e1aa3e6cab18c09e8296dc7023f9d9e32856383732ce90df42781d69a3fb44788bc1fc606eac7cd39b079b9312af51fd0bf1bf85de85bf4c49e934268991b4f6dbe916750ba2f83a063196f5034177e43e903cb4880ddb927cf646d4cc5118ca56f49dc4030dfbcd8e4b2be236facaf262f07ce5bea3f99bbb6b1c1fbde61eb59e137c9da682a99d31b14a4d8b5bc00c468067a87d73df51141550ec1335e6730051cb54b14cf35889b53a89a23add55d6aea7ae9589d808cd962cf1cd95f7c1e606cbef90d690ac70aef37243a4e5b9fb7631e79a281cf7e715ecf90dc9541e00b4dbccee40c4241c2f78007fd3af57f096b7c1f9017493f7d4b475e2c215f3537ed383d331d3cb7713bee22676c8edbb141ce0154d75318fb5fa1202d806570c5b97684e6c211cc19a4fea76c4e9a5a3a87c7fa2777160ce62188e76187d7f2b5b69a892784217cde5de78e20f350ed043096394de5436f6c4c1c6b15f4ade602cb1af0ccde97aea78a9690decf9701277fd3543972c93a1fd90f51478edd453da119bb42f3eb202ac9b8377c2ea1c0f732193360f3b1bac53dca6456fa9e743d5d4b5e682d1d7982cc7bb18188af2e91be39168f7ed85ca4a961e8254a042c7391ca3760750eafe9d80f7dd598746339d95e8f01931f994d2d064b2fe643bf5996253d4b121c6b3d050d223f79d8ea0460ac63794a64976377975e540bd2f7e5eba960994efcb08e20cf3d15cb63e29b155dbb3bc1b2d453f17ee03ba2234f34677e4389bd589e6bcfc66baf577b21b2ec52f3c332ceeef2de96aca4f2017f5342042365e5c5f21b48e5c3331fc2b839065697caca41e93cdf6b0d53384136898edd7d739fc1d21b6dbdcf6463dafe5e5a0619c3f677f2c899ce9e03637386bf29ae45bebd332287547cbed0d2b7b5205fcfda8ba9d6033f46c84f94a9df50d010ef89dd45df82c90b145e032098f85efd7492a739dcf09263f133adc12faae47de16ff28fcee4c2fbd79d42cb5cfa76f13e79639d57122818c8135fc977db179a9c238453187b4765806bf1083494a56f778e7e6fd97b5528eadb77b84ff59b572637d102c475dc7eba7d971ac80f5dbb4bc6066239d15ae9fea7e7fee0790bbcd8dc603dc211068bc6289301c7e6f9e658b5c089078163adf133a321fee6c7d334768083998ed55c79ea7aea084d228fbe055380bf278ed05c68aa3e857127c07210a8e6c25751085baf81afd683a125f35ea4845e4b99b99611b27e794f400bb099bcb47bca12a8757ceea6dad364ae3dcb2b60497d574531f94e89ca12afddb0a708ae658a8d880ba0d55cf856939c63df36c89ab1ef27071b4f2f0d84bfab744cb87f4d95105e0b3c1e576d0aa0a7f481ad0bae6520ed19b7a3eb9efa0af09d2fde8f6fc174e2b7ba2b6f3359b6057feaab21ef44f89bcb2dbdd81cb96a936b5b5de4c7e68cf80f227993bebf6d65ef9fc3fcfd173affe9bbfdf2b95f4ddf1cbb137cffba6ef63927f8d150c8bb1db13b63fb28690d3ed61a5cd0889b2bd704c81b1b546ea9d97817f97875a20378b1b9f4123a6fffad19c2963271facf2f2edecbaf93602098891fa33730c8def1022dac5f76435f7dbe6f444f01c47a5b7f12b8e47e3ccf53dd36fb2dd31b95ec1be7894ae808586e4c37f8bbf02d9804bbe77112688da70088fad2b79feec9efadd717fc374dc5726770cffe7f0e05674ecf255f3e97ec1d85bb74afa95de4a9ebe5d0e2111c7737789c5a431180ad6f48bf9122bc76e873f83707dff1e7e6a68bf545fbf55e6b7513df1abc680d253b1358d7d61a4f734df513289a2b36d79617cbbcd7c23aed4e1ff8772bfdef1f36c7e635c7679ceaca23fcef2e96ad642ce93a13bf55a6a79bdfbb01c30fc1c1ef52365627d5cd533cd4c8f469ac8787be5a116bc5615d7d3dd25469e93714d66e909f8f9e92e9f319ce3aa263d1382d69c3f041499e8258e6615cd2a5f0fb89dc67f15d45f986862adaf80d85ca79751078a2821c01c5ae85bf8585efd6117d3fd5fb4c3ab67ed5d8d23603d17cc318b4a463f034de0b6354ba06cccfc8f64b8bd2b5c37a90c1d33919b16fad67c313c736e09aef18d7416cc662d8d8b7bca705e9bb406347cf384daf37e93aa4d8ae1daf972091a63006cb5cf707a16bad116896ce19c3f2f24253e5586b7527a0b7b386e9990952dcf52d3a71ed3279d67c7330961877f23840d6a60243e2f59a8106d36f593b7cced335cdeed49133efa5fd5b69ffddeaf36f87534f2c9dfffcfba666630f3cb6be9ada9ce173055aa3803edb591cd153a9bd824371497f189935d736b8764cffbf622d0e639add718c1bc1fffccfa5fdebb17fc4b74e2c8f2cd4473c35e05010fabcf028728fdcc317f19e131f045990cef16dc9dc05d3dac4ab451ccaf203c73da44db3995679d6f737bd39b76ecead5f6cbc8efdab7ab362ff7d813cf7a7e5e95fc0972e5f304ffffecc3cfd9b2ffd266efedbc4cd8704f3e4dd5cc27b2e71fc0738cf2b326cdfeb3c2703bef9ce6fbef3df481e9ce63477047ed41e9b1b6016006ffefb36b07e835667e109e1d21b779f816dbc79315a11905634ccf0600a6c8f39b815e411c70e57087a96175e420c23d4e8fb5c76ec4251234652888c896b01aee0b4ae1c0fb0c310dacaac3487c41b37a2d7207762a64e9f2d27be2af37e4399c2d898f91635d03aa29978b1b9f0d5b5840135cc9c44b993bf1175022f0e978efd5a7066106727019e5a839bbb96bf80a28eda96b184e32e1ab63a2f47c7c40ccd2563518b1a2e4ee99319a2643f6ece7c6b70b43f168410faf120f00423716d85a30e636610e9e506c582d1f6456f2889abcaa157e96ced04ed1e1f43517f03bda77f66ef327383b52de406604f0898a1fae2c980c5fbe04de27872840e82b5f9f80854f917f241dcb4e69bd6fc5ffb956437fe839467dadb2574e87b41f8001dba921fe27d3a3419f04d87bee9d0bf9f7438559596e7d09217ed18cc1ccb5b9463eda4d15e75995b2f53ff72ee5f62be74e6b7d6543085ea60c77fb2dd2714404c62e07a19bfc4fe7e493c889240114c813a081cab16e4cf2bec79129b11819ec27b823922b1ad747cc5d82b12c343e3749e535fe84c6b81a927204e5343ce6f299b6f517de908eba58f21441acf101b4bd893f1bb30ac9882716799726e54c5356dcf17c432894501aab971447deab5ba53284845df908ad550d7d267c35eee23767a4ae45ad288e65f92588ba56f77d218d804327f5f7bc787672ca1c52f6124c5506d8edb71d18f7b688fb318e076d13759f6033f4d5ccba171842d03f90de5cdb7f5045812576ea788aeb59e69aa8eb496b90156677a6c9d5228d211e485af9a35bf7168ac680c633901bdbc7fd81a059e60ce30cc0016f1f1519f611ac7ac36376e42ceca06586b020180d57c730bf108043ea94d7c6610f5d95ec30757b8bae3f1d09b1fd3f769a3b37940841afeb68af263adf64514c5075114b9fbb314fedf8107a4c63f3c484409a0aeb674a2155fd6034d6f0aff4de1ff4c9f747ae53f4ce327dd5d841f8493c5c33aff0972e92041c8bd240b4285ffeebd3a3f1df15518423e9968ba29fd7f3b0971b2d69f66c91063b46f1ba5ecb2fcf70a4d9265bb5023bc3181a2ce75f76bb25954531a455fd4c27cb51ef44ad154cad28b94ef58b31e50cd7ad778ceded78e8d396848332848e3fdfd9388df9d3138b6b2822a7a736c1621be35261699bda5f5cac9560476be2ec174e0aa83ad4c252576ad35d254b4611a2f7977c1b08d354f126559308c8730ee04aed54570dc9d82f128f0d51011233535c62f1aa3e60cf709e326e7da006ba53332af1e8d58c77bc9d04edb1ce8cd0e277feb8e504b53cd858f518220cd8976de02a117a3d089d78818cf5b3a72ac4e3a7796dde5f3a9f3a31d4c5efa2379d0ed4f82ddcc431d79b639f56273c3faeef59e65659014115786ca12df92163493ac3abba281ba1397380c3022682e4083a2876fc1e4e5b5570b3a69e4a0fa9cef5d4f09b3c859953c3367d19953bfa1845ea2847944ad3285633ce79dbe83c608a568b6e02408b3e777231557816b77025f4033d8a0f3031648806d4c80d559348249d28e94af0514976760b2a875ad49d60f7962278082febff4ac76270e4177248b0095ce5061fe1591e58577983423e7694ace5921cab8912149555e015b0f7d55c6e7f8e2d1fc7b107149fe9ce80ca377257574352a32317bc5ac8cacbf638e9faa8c83829ca168d42b66571e44cd24929e66d5e0bb9b9f390eaf9fa6864ba876d37b92ce01bf7b84efa56b35675e52bb36d29ccdddf9e208bd096bf30b1c4b97e455ba39966e38f3a6459ea645b21bff413093f67619164ae9233c4b15e6af77a34c32e29b6be986327f3ff9701ac8f4b2544c02d478af4cbbc0e84d5eb715aff4efa7024ccbb54cb19012bc04d1aea2782a90db5654b7e6700ad8a4e3511171f3c02c05ab1941d1e4526091b9484e8f225b684f85b4620c067a789e68b3d3178d84caa29af6a419175c1c180895010f067b9dd88ca148810775396d83b2154b21e6790c5c9c781040551e1360a3a205012a3baea3edb57f7a29822f3305bb164f803006b35ea6d057d18e10857fca52abe3616f0750132a0f60875c3ba8a08719675402478188d7d2a724552ca76c8877f6f318e848cfe9aa8aaa2673d3e5a039a59451d7083c57d297e814fcac6715b41604a043a1564c57fe06c56ee1996e25bd509fd08214fade3604e5eb7694a6a87f3c75b90088cba9cb258aa2e71ca8b2f77ccfd609b1f188bcdc08a65f2b0d132a33cc88e41962f8d94a91cf0c37f81e6e19a60a7ba8f33096c8738351f8bd63be0605c0bb688cf2716aaa11c2881805a6857dcafacdd3ea75cdb7b44503e5861c10a30568940c28113edf435b21cf66544a913225f7d96a268e102c1ac154c5e387167187925451425142effd0aaa26a16bf2623326d19b6a3d705b5dce6bbddeb71339ef2f26e07f0a137902456feeabf57996fadfe04318f1795b76b7ae0158cf8f803c394fb14c002c10b25bf12ca02a5f0ea85e2f4d719bd5974df41402e0bce90da8de80ea2750443f26f2f162118f62edfebcf2081542e858790491abc8967e6f790432e08f298ff06bc5d00d96fe5da4c121384afd2b05d53a6368214c14cfd2d26f9a9b943dcfee4ccb76fd88a8d894c52552e6a98aabb5fc09614ea96283c430aac8724192544cae08b372b8903346eaab92ff3567e7a35175c77d1f8cd186314d64eaf80f9b63b0208dae230c222360e93ca0ea7b422a607118b299896319c4af3868e94b682bdc9e3579a6cfefae099e8f37664949562d702d0cbff4d011bb5392b0c3de5b9cefa0f0ccfef6d7f187d023f403b9c1116f086d72be3384eff3c2a3f0f028095f38e9be5ee7a47aed0c1d53e42e989b7eae33e45eba7f10321d93c383976b5526c772cb749a5516c7bd2d6f0ae64dc1fc349f147ad93f46cd247d5d24bda6769cdffd98343aec0491f85aad02f2be3bbda67626bd7b591ed5847a9d97ebf26717483755f3ef25170e299c2cc5232db91a9b6bdf4209b0bab6ab9a8b7e2c2f7a2505c7f41b7117a559ccc4e6f9950bb411790fa53bcfded149e9766999d6b1b98031a18e9ec271177971f3cd579100acb5a405997215b57bfcc3309154a836c73f6cee9def9bbc6ccfcd4d298e9b20842d13b5633da43e9eaaf9a0851f3767aed50940bc0e41a2e06779d0d30a19fc791b96094ee9f4107d3fa573064b2f7a9ab7edf9439bac912fffa0747f2cb525a5654edfd5b5683fd292f96b4af4c0ed8692d23467bf6b6a33c1ca34f505eddd4fb29e7b94e31eb09bbc6bebacc46c73aca9745c9a9adaf007e382df686b3e84023a2cd8ae479a4ac6411479ba7e199099c23108a18a461d5b1ffb948a33a39d2ca718d5c89cbb8289e733751285bd83dabb99b29eae075dcf4819301fd346539f03479057c35eee63eb0872e4c5cf015b9f80a4fb08cd31e87995fbea6463ec045ad4c5e752f1629f8796b9f05b8492908c85d228a6eba1d133b3c17b722d103045c37974829d396db71f07480f7bc30fee1f05ee91bfff2209529de765f9645bb3240af53d384016af8f03445914f8fbec13298a755ee0b8ead88372d374a295b1077b9bdea0c00d0a7c8a4f7e7adbaf0f04584f9709863a01071c9346877100cf4bf715319aef0f863a13089445c7bd785fe705beda32f1b904d20d0afc9de4c2c140a8250924a1810625caaa0aa52c32499d24944685630575ce72da79aa50152cad05e59ed6085923e6dc874edcdcb8adf5bd2784751023fcef15147de48d8d09b0d633bba7d1400e815f41d5a4991d34b869e3aa72e23f9795f76a0557ef93b60d65eb37a648660142b972af8d7c0463122c40037cf2b5c9299c28effaeebac5eb258cfd1deaaeaa75ecab320630278f8bf209e4b5864aeb397ebd6f04a397c600039b80febbd709b25a335f57939cdaaab40f91631b9397ce446f04a337adb9f7fdb49e856a868e10049e809567fcfc2a0076881cd1e4e85930d0b760a2f755b4f06d320ebd145c54d84b4d25630d7e10be71e27140a0f7b40476f7ad2de0dfc21fe5b14aa3b64803491a019a3b96f17db099bc343aa391d6ca6a7595f68b9cb18652d75a060fd47ae0ab26d21a32ef89da12aaf29b63ad4eec6ff4d230a71bf72bee6fa26b89a28348d9b8aa39838ded7961004238f343483295ba92a69a0bc7d249408d6bd5d2403704c760eac5f282808a465adb8964e72c80658ec89e902039f67c4f99fa8d5aa0350bc137f9fa13a00362790655594cb3961c61909d07601913983c458e6d7250a0fbdc36076cafd1c2b53b0f6c0da730469c163dfdf37ba4fcb39d48f89e26ceeab2e764efd9684d376ee3e99f5a431b0d05b072eceec4da34fd1f3df9073bc7119dd36b6059329fd5938bcdb4de09f5163594505325e427d95e91fbe5d3acb00db0bbbcc7b2db1c6b8e34d58c01c9e0a9917dee62b9c4f67cff3906d3f41cb37a13e91919c0449941a1392a9f4b0cdc0106b3c8b18c09c9d41249dd8e59b1fe1c1488a78cdee3eabb1bbbb631d1bed6821f517d917299b405329ee5d6be2cd93b1644d63ed1da3d5700a823f7c7c83dac0cd22679da75ed5d31502271b49fc3d52e7217648123c3fe98202836d353a20ff2a637607a03a6bf5e01a557fdca9894747209384ac8190e854089ffe2ea7d4e7e14ee1fa5872ff27d4de06b525d382f04aa92f4ed7d215064c0570981927859bae7b32a10d954abc0e8fea637307a930587af696504542109a7c24183484209d6df88be8bf151db5a4f31cef46de2b02818f70bb82e6619ec04bb95faba329e4ca97e57ac0ee38a248bb41b944101b2ba7069867fc7564247085196715f88bcf212ed1a4e05ba339f99c057e47e219fd72dcffaa6b9fd974aeb8f09622ff6751926af5c305d31c7fafe924c5e0784d22dc7faa6c97d5ad9700b693f25a49d15ca2d10c7a6d13fd2322d324d895dbba438666534cc4ee48a22baaab9d054695950163774ccc5a896d2efd99ca9a1dae0bdb18ee0b83b1b925a149d599eb13d08b4889bbb562762513d24eb9bade7deb5a484bf01a5146ae8a9d1f4275b33de13065121737acffa30c265d1e4bc96c9b5e39394f3e72aa5bcdde397bedd5df9761ad15570aa702ce3b44132534557456f2e35088f5cdb5841b5296dd11f15ce5a2de808e1128a782d410205ee5e6be8ffeb09f2428b5681364673d8d0665a43a745d523ef058add09b035ba9f2c131eaf1d3ed32e310677979ada9d7aa232736c46a9560904ceefbb81e66c0ff26ceb3c428e46890df2a831bf14f565a134b26b6fa49f63f18844a489e69c9d89d411b2f2625970ad6e9a9d7d681c0a8cbb24ebba233417f80e7662d3f40473548c862385917b4a9845643130d5eef1d33c92cd08614cfa2f106c37d3b3bb21e3c5f7cb1a94cea0afca2bd77addbdabe3eed253d15b3f96b92e2d56bc5b3459a46db486fe304ca4011495a9c3e54576812a232fa1b289154b250e212a039ed382e50b47601185a37ccff362b8de1541e0cfa13b1f1e0181b4cdd9a4cefc7d9f171eb9fb474ef822f33c777f4e02b3c8fd42a6ad736cf70ffcbd905bd8f02c398eabb6ddef6b7a43803704f869b43c7ad93f060192be2e8200e59a784a36f37e7174c48e5faf899544ceefb3e3d3e15e2b97f93349a41bfcfb7b098693e01fb37f97189cabd477d3130644bda44cc258fde467ae2511622702fdf2a48428574ff5b4ee485482128c79f6636dfc4a082345f1d4e61b864f156adda131ee21edaa4a52592f61ec05db3091c6de64d02ada6697ce987dadda413f03613b569f038f665cbff9d63a240455aacc83823a9fb2407bb1394e99973b16a0a50fe9dc48a634ddcf22442cb040139f08613e8e8645c6e55de898ee47047a5aa17e4df5392b126455c369f6bbfd4a18705d5516a9992087bff95e7bbb245b2413bc7330739cc2394063930aa46adb8cd55a8b260e7949169f545aaf62694a76763266e54630792b94930cabf6f3d0f39aca4b6d8bada15578e684f732f6ea0c5e5316611d79a23963901a7406fcebc1fe1bfc526ba1105aab8cdd78f77e507300ad6fd4ede4e76f97ddb872afabee09d98ba779db4e6b34994996bc546485a767bed0a7a277b7602cbb570b96f044ef49534740a071847f7d8ce9bb28b42d9aab3ab4e6533068e94b3f46237cf706ec3e6acfe879cf1d9941c15b00d58c7cbcaed95df5a99963df9da1ed774d507bcd4b3aa27188ac5fab535a5bba6e2491afc2bcf2140dc5d92285bd7be64148c3da638377041247572477ab32271ab91971cbd442cd184553e284c4dcc526fe3bdb6373545cfbfdb03d87fce9190624ced578c3fd83b139a3359aaace3a5a50931761e75e646bbd674f7a96c4ee1ee2208dff4cb467f26c71ad8949e55b547d6e5dfa8e0535ab481360ad577bd64fc3bfb1f8c56fd4e443c75b5c17d392a69e6d225a57abc0305e714ef6eeeb58e109eb3ab94bf91d6dc74572c1dd6fa3ced1f168adeed457d7888db5e21e7bc5fa6133289a23add0cfb1b562b2a8072c9fc47fbf6f9fd27ed3fbed15758af26f6f933dba437a5e68fbf4eeb7e310c196b2678df06f4f01ad5546bf39991c61cf17f633ea0ae612887ae8a9e1d4119a332ce3993cc2f73f49bf9755f7a1506d60046c6506458440e38a710cfe100d8f99b0589bf34d580f7d5e7c9484c79af4a5765fbfafc935f1e12c2bd60569f8ae67c592ee65f93ef3036613adc28cfb9bdeac58372bd66701abecbe7f88158bf675192b96543b6ac53a26910e1bb2a47b81afa44979af214bda1f16ff170d599f4b28dd0c597f2fd9708a21ab8ba06a5ed3903502d61a6d1bb2806acec08719b2d2399e67c8da1ae3b50d591d60eb73c792d2b88574dd8e1ab6da0d650a6363e65b29eddf7a8681a0a7a2372fa9bd34108d2df1b7cb8691b80a9d871163926709674e3c081cdbf8592c99460a1c338598f9a9331692a262ccde13c2317d365bc360fa1d9f1b6fec4fbdb41d65e75e39b6b1d11adabc6d812549eca4a5cae24211e66c2db68d480556f914d4a46d59f2aa59732c92d8b6073464bf534679355cfab428318fc7e99719f1c7e53d9bbc696a76b68ec7d3742685a4ce741fd9f39dc98b9614f6bc3a0e4874edee841831450539028a5deb35e80d3a45b6fbdcb0c8de45e207be726bd7348081f4ee2b376df7fa61f7f5591e406bdaedc69d0d140c75107b3bc6aafc0ea445a1bb7bd671eb6f14a0923529c62f5402ea67f45c60f3af9a374b226d2e58d9be6c8fb56714b3780c16e7b353e161d7885338e758de8146ede09c69c1f07de7e7e0bcc91906bdddb90f84f9d46b30a329bef729233ebe33a43f14c1d628bb3f69f5870a99b5281b1b32794e8c61ae25c53049ef045a007e2f908f61059d28eb9fc815d677d100f39cbdf70463d756bc4eb687b9f181c999c15f3112a5fb4d8d34dbc5d9cb46c6bf2ed7beed991354e5713b460b10d7f1fcdea088cfa341cbd70d68a583ac2ac01ee3e9be3d2155392222f397de58478e48be17d959ca9248c87c0a06219edc0d1ad3449d1588328d99234ded2e89d380549ec0e322715b79fbc3f79396d6a3ef0c3d7caf5abac4aa962c7319590b06ea1a39846cc19800cbf899965974c9ff483230969f6f69ec137e8fa636c78e85d2c2fa7bd6ba8b9cb1394ecf3fee9bc520eebdb7b87d4167498da5a3dd335d34aae5ef3f6ef83b7417cd7e6a38dd6394d4610c9615e32b7d0f1cfb353b8b25870e5721f768fc163170523637525673db809b1a87d3718eaec4fa952aaa33ef67048f9ab658abbf189f2510e7ff59215afc2fe4ff7d7f88169be829011179d39b71eb66dcfa3c0096ddf80f326fd1de2ec4ff75dcc0754c2a1d8fd4aaa07d78b7818b8cf86322b57ead60ba19b8fe6ef2e134131751ff2c1d5d2f0f3befa39c8bbdd3f7754d5d084c81eda5b067ec934268e49911b0bba16bad9999a3b9d09e9b2bc732f6a8f45a59d5ce6294a89910aaf2027027cde1150ad21843800a989c9ba28272d13a93c64fedc614a9600aacf5c84b183c5043e4da1a232c36530ea26366be4523987688d989c6a244d444a1a5e4c8846bc953cd37d7025296c6b21beb25b2b4ac996bcd592147b2fef8fd7a0a23b7d38ddc1466b594d0130dc2ed44e24d580a479632555d619d54e22f54a49f692ac2fb2938169a513eadda4bb1901d8b45a3e799a51e696a73a3a9e69498e422529dff65c0c9df4881c82652fa8355452cdace594643b549f898f6a5b9a5bfb3c2a013287a043e63089bc78dd1335084e6f80c688922d0e2a22798748ec485a5f0da89072f8de8355d93506b192b60195310a3b7f2fb7489ed4f1eebd720fb48cfc8aada9497c900da567eb550dfea83dea06fbcf4b8516dd057be9b2affbf830118bd0af25b17e9631693c67b6277092d94c5e9e57bc5d2b99e8ef5b93fe6ac30ff349e6bba3725ef50cc569e325534039930466bdf1a04bd41e7605c4c7a6f1cbc8f85fb723933de15a12a8a66f3c31a2169713644156a7d5e7c14eb8fbcf445921fa4da03ff503f0ba25e9002ec6a10b5c63f887539f35f6613add0040f34bd41d41b44fd2c2a28b9ed1f024f714f1781a675f1e13087c409d2e82034bd97b807b93289e89d1c1264c45781a69f4c20dda0e9df492e9c024bd7534fec5c8d9a1aaa68e3374a306ee6da06f7311117646e3412e110cc2494b7b99a4ac7fc3110b34ffa5242ac421ea627c3706abbf63e8361ad34b49a78ec27aee54f34758dfcd89c31d596a8c3741daadf4d6bee67b036636800b45e0bfa4652335601f11cf656415ff417c0d6665a33ad01bf0a2ad2256679f875edc5cce15601ca17d62657c5e958f3f1d03dee657078ea2425b608b236a0bca764dc791a02c25036a2511c20f4ad356587509f035f6d46501d6038cbfb0d0a571d6bbd81090dad2eafc56bd043c6f77ea4e07d25293815d11fc5337e6d784afad2483df6cab39dd599a751245d04e2260f5b9d13a11db94304aec2c259dd3567981bad656ea84772daef7335b2562c4a8bf75b0a4fc3e1f5b96357468ad07960f8a84e3750a8edc047762f598d2734da5b94b4423eec40e7a4e8913617aedde4410f9ff1dcf35e1572bfed81a763aa053dcb29b0daacd2881dc600d33916be4f1834b63ccbec0cd1e80f4fdd1f817024058b980b77e6cc9dc284a2c45e2ccf5393507af7f03d20e3e9290bdfe223606b5bd11ff49bc220feccb5f8a9ff2e98bf9e420b7115507f404c1356b3e65a3c0ff3711039577d36bb4b6aaed291df3213189ba30363de00ab993842f89e681bf66c5071ceba68d8ea049e60865e9c32d280296c91d4b73d67cedc1033108d249969aa2cc2d84cda0d9632da940b29a3ab2c5d94a50fe27770befd5a758f4a696a2046335f359342c4c22b3e7fe716fe2dbe879d1b269fe4b8fa8c15cf245b8b784f240f962702e25cc61ae5d926f2c623561fce408eadbfb9ad9d081f768f48c1639ad2963343e9f9bb8dbd294f20ae1f6486f2124504e45b0396fe968ceec7f53de7d1475e4ca28578187716578d6e984fa6917718aad12639cb1f7706fb28f758ab3d0ac297fb879a5897ebf5f3ac4617641f25c33eabb231f7702fa7784ae0b9ba2cd6eb6225d3df83c8e55ec16ca6954c7f7b9bdecc4637b3d1678187f4c27f88dd8874751112794938857bf4a03c3ac83d2ad6e507a97e39bb1119f059662351ae6574efa228d5f807ae9a44fe7309a49bd9e86f25174eb01b31c6be722843a69f73849daf8c89d9dfa85dc513c2a537eeee94f32aa48d67d4ee05b7e14c6b992ba0d2bf677834ee1423d459c6c9febef7d874f288ec34fdbb51b453ac02df5646ecef29e6c63a76212b445eb996b129e281839918bddad5ca04b17dbc2af1fcb12af24755bf5f483b58ae21cfe1c157578efc4c25e46f6adf4dbc5f44bc7f24f77cb1c78b780f89a7ff8816784c341d66a097f89ac45dd07b48467c961a589424bc84c5539de73ebb78ba29817f472971962e98b2d1331b7d6af73f89a62baab40537b879c14f31732caf90b1ecabcc9f40989e7d219c3a42c032e3d0c653d7e1708b3e2765a0d69e8d0914e40de8511bf7b7e82972c7c6124694d91b5aaba8dd788a8656730e1bdab811cb9cab9ac93b99cda9fe29bea3df83ecd9996f20f15544f4582fd95debedccbba2adbcfc2c990f592fd6d769fdc7e60aaae88d94c0dcc94c2fdbecf3b6e91e37df7c554e8a3af3997d73c092c8f8fba7f44f6cd3f28865124ea1352067075a6886f104b08c258cbba99f3bf262f9275e2be6ab4968f832a990b0726c9d73d93ca02a8f355547f8cc825e297b6fea37bce02416f43d150bde556d200bdf5d05ded85cecad16407cae9595180a38650f96da6298f72d29f4edee048afa74189759e569a67d13af0d0fe326efabe1d28bd17d9add4f32744505a521d63f6c2e650ac8b06491e1ff9def43349b9ee2b492ff675786a515356228ea916b7547c02a9d27920dee30bbbf17eb53a07611a4ac010fc344fa8ecf1a3de792fc83c821123f41fad157d3250d7b7eefbb289526932ba7b1ecc768e1ab6602e3e66c2098891f9b09abaa519cd79466e34a212461b0ba80d79cedf1896cfeaca4b2d95d7604790163f3cd6f769779266cd617debb08923b4f191e20cdbac5f33e37937befb9847fa1aa00cd44a67e1d122f5075ffe8b3b92f69903d7f757c7fb59a025b659cea1ca957249c85ef7f2121db5661398914963ba586533ad1136a38159ade20fe0de27f32e5fd038b0b147bbc04c4af9f5963ae4a381daf3177413f4ffdc34accfd62f17483f87f47297116c4afaa3890177863ae933daa75e9d9d35d404a98abcdc7df7bccbda327de4b276368cf4c02d484b015b67790f02c98bc983b64666be4b75e5362b19df1b7696659c018f7a794f446e2a1a5232f5296207a7a2943f2550132bf06344c5647be6a2e5878e30ad8fa140a1d52400e58eb0d0d271cec847ba6d9a915e1aa99ea9c3231ef92966d138eedcead2ae3315ddb8c913e5d87fef34e7867062732f6e5ede260cd3918a04d7521359faaee494a144448e590679b648ddb91d2f3ad5aa08db7c25bd978f2f93cd5d938e684b8a85f8b8e9cb9bcf0a220c5789ffc673aeee2994bd78186aa15e643608c12c2968e1cab2b69aa59736d8363a698bd10a897879265443a47c65924ffa1fb9ddeafca75a4fd98142a17c87a32b6f9f38babbd4dae0d87aec74f7d013824fc420a9f1b1cbac1a1ff6a45e72359aa8b3d5e020ec9d29174c98bc0a14aaaeaf7c12132e01b1cbac1a1df534a9c03872a79ab33b52f8d4aab56cdcacf1e8743397ff46138547eef2970a89b46cffd3538b40f561ce042decb637c12acd88efa3b042baaf97407873c867d57402bc2bb5ce4493dc00b9d797a8fac43ea99609cbe47ea43333eea7d35a20b3cb0c5fd4b6b4743b1433c809066d530ef4ef3cd579100acb574e40ca5c58208ac2a17082a14f2629caf7bb85ad9fcf7f227df1f19430ab1e6ae6dcc1dbbfbe6aae6681f87ed8e678771f0025a480e8106853619efaec5de45a1d808928c2b420243fb6a54f3f2a6eb4c3302bb896b99a332cf2cebc73238df6ace8e78ad2a397b99a7f239e5402dde5bf330a42c16d8ca3854593df3fdc438bfce93f5e9195885df81dee693111ddee0db4d31bb9062f6913cace53e2f01e1c41aff0164ac951eadf791b19201dfb8586f10ee779514e781b86a66d64cc12da401ed51deb698494f0173196362aeb4ef032e196b220550eb258cfdfdefc6000829896b491c56467db5398544f9a3ca3210d35032525d995172148b033d6f87cb463b2c9cfbd7ae4877b24d5552a47d3915e0a5734fff367fed10a079e574f9abf12cfe7545f48219f33745f4a688de3e2f677c5e3e8e6d31efef120aa8c44b1fa0805eb0dc2519f04d01bd29a0bfa3843847f9dce55fccf33dc86f954a6191a3f0b8b259e0413c9c1f5fe4addb5369b2542df2b5c03d97e6225cd273b08f47ef10075e3a8e2a8eb9d4124dda53caf3aab5c9a9e80f29a7740f9ee63051fed713e45daafaad3d2e5a76612cd3401bd128028db3027e58e5ac054c0af9654d9d87d153743410ebeb9aad054facf5df238de660648171784c5757b21753ff68fe026bf30b02767e213fc12d60e7a668ff577f46d9adff40559bf67891fc0551bc7ec08e7c41860232e05bc0ce4dd9fe3da5c419eaf638a58faa0ed849299e2ad5b8ad678faadd7cda5e0933b5f750e0ced6fb4f09dc31d978af14b8c37b6af7b47c808c968b054b8ccdb9139b090d02d191a7aea70e89bba795b14eb1fda67b5108ee09da3d3e01b632732d8305e3f0b163191c14b560affa9daf6b16abef58d2028add67609178f60d3095d01b77a7e49d2363e95b1257911a5d31371664d22a3c3f7e0d1ca1b9a0a9c384821c51b59a54d96294caf387f6082450e0493a374bf31e4091978fcca118c7bfc1aafba0902fd211641e8ef7c7f357e71c101881fbff0a4573e1b778796b3e8b33c684d775e25ad2d85465939e9f922fe55bfa3ba51e48df71f8fc5504c5a4ef3e2728e6dc9c8ac02515ca74440b5ed3f3081a5784458bd9313434fb25c12fbf3095fbe673b841a1ff5225075ff60f41408bd9658a0e0b35e1fa6e865a25f27967d16132e29b9fe1067d7e2ba9700ae231375b28a7aa6891e909031252ce0ab52c408f9fb99644eaba92c20e6a1af23d2810afe9843caae498b08d0faa2d5c495675a8ceeebe71ee717054d4631ead9730f6826dd23a1a2d4308a3421877a22de70823f1ea048e553b88c0d2621dc0ee04aedd2914cec911dc56dd609bd6ea25754cc973fb6b9da6854fb23abd1ccd8e26eb18a635a6ab89bfd83e58ebd92e8158617f5aaff998484d67f44c49c9682dd562e11842b6c688bcd2bd2abce7b49aab64fc643e154e97fcdc033b0ca1adccf616ce497fb75f09199eabca22432559fddbfc0c7ae508abe835f00493c3c8dbad2aeea3d6694dd8fdfb58e5a02299fba40ef4576eed9a063090de7de5a6ed5e3fecbe3ecb03684dbbddb8b38182a10e626fb667fe9faa48125da7e666676f8b5688725a045e872c4dc6139a02186459f59545b428b2df2d485341c0fdc6ea6593d418bc47e4fdec6ca635cb8b455c1c8caad54ea1c0d32e9aaeb847154873778e25646b1b68209a6f8e606e3cbefaccf608ca3e699e22962378edf5e4a9e00cde9bf6b1ed588c808565cc2972e22a44e668124447b8cb69938f770d8ab75cfe1b1ebee1e18fd37ce945bf3216269d5c24dd43e26aa770944b8f35e9b1267fb9971e44497e3887a39c132f5ae1988ef82c17e08354cb6a673df0bc28c975b9b27656b96936d74a92f2bd4d6f38f8260d0e5fd422065e2f818016e56c8e0a5c87889e3f4d751bac2391a293586fb709e62d14fe2b60d098be5f0bb0de5deaebda058d97809174c344e9f59e65659090e2ca3328f853187d54d162794cc8705b06c2fa20b0d612c14d4d5deb73cd3ed6f3bd58e6811004580f05961638637de98b06f2a2ca42c64b4f35171e49113713ade5232722e4dba227906297a2ab9a09e8d1147247682e34c28086dba2a56f6b24700d5056b410623c9ae1a2d2fe5cbb18ef065806efc5e66cd8536650f09837b61e0c46e1f78ef91a38e351569077676d8262015e3a6e12a4d862d93cb47f42b24d49cf532fa8620e462b86c1cc10507c86db2da1d524eda0ba9634555e014b2a1403c6f8cadf005b2b6251769648f158d26fdb363630e1792f5e65f40a18b7b8562d2d981a7a2a6a397617f942533a0773b67b7ce8a9a339109a1cb0fd70d85308762daead69eaaf053a0165f03c0af2f6b58014af6e8110b64c8cb5431891a2bae44eb367136297509b33d76a6eda916239d67a0a483163147a24e5bf9980fe24f05afa12b4cc37eaf95c634c3b762d69fc4325e4d9e38c505ced9202db5054e6782f187e4def618abf179e6062bcbbefbced5b138cade8ddaa588fae25854e4cce68b11d3997be254d1d818e516bf9535f0de85eb70ce48d01be7f01632d1cb9b691be4700b63e05714ecc0f0527309fd77d4dc5cf75d3df705b5270cb55e58ddfa0540f5e52ab3a136f5045088ebb3ad853fcb7dde3599b4ec1e6b02d0f8b0562c9f9d5bba4f82d62f6942eee038f0f79957b40c8e14d2f5ebfa7982fb96b6ddb4c6063671f2272ee9a66af5fb0870c78e3bbf64cfa24e3caf7225bffa862ade68e6d28b82fd3d667efb1d938b6c9b90d7247776c371a2d8e4e6404de576a2be49541c2f7075c3de8e067a9ecccf6df6304f1ed48db5dd331950b03d158be77bc5e4b9fe27df7446349d7b7385efafecce620c80b4f9067a097ca26329799d6f227ae654c981d94146e67727a49e4e7ceb792455fa8cf0150510c6293daa1b6bf3791322064fd999d11f0b0a14c4144bf3f303611a01426b98ca7858947ae056260535bdfd63709cf3d845961b8f26fd466466c9ae47df8bfbda850ac7e678c55fb62bc4151394bd664fb21184b4fad2a142e63d990e07b9615ef4fc7f49cddc78d23c82b4064713df0440539028a873d658edbb9b682f78eb6b15f67ccbe1a923ba1361312e5531a0396d766e80841c0feb6287dcbc778ed50022c831b9042e412e7daddbd765e53451c4cdf4be7909e87f43c25c0ea4e3d5a7c400496be722c1f95be418239c3fa0ae815cf5349dee4ef6892a2eb0b279647c32b8ec9ca8b602cb09e82650a104c5aa8406d6eb4afeb8d87bf7b2d831b5a6bf4bda7c750c0df731fb9963ff1bf4ec4d7af4fd177122d636e80ad2f980db0de168d9563d5feb9f55dc372aaf717e76974ccd73991934cc7d15af97e92733e26ef2d167c0779810c69e9d3351aa77705eb57fd41b3df368d7e9f246f3cd53d51c1776de3b7d00cf4b908c4f2c26ff022b0d0d86d75ee8dcdd34a7b931e868964e2fb04992df77b43266bf63ddafaa665b66863022c1ef52db4f104b4001c89e23af07da176eb821f8dad05b5dba6efa3fe127eea89543704637d09990e43e47383c8bce29a6c1c2144d0c218858d25956fe49bc4185c4dfdf587cd45ed48e940d50c3d6110385677a4a9e694152089dc5697f35aaf11d1931afac46f75575ea295e64fedd45de48ccd71c62a6b7595bce00bfdce1dfc1eec148d27c567988e8df5d1bc904bfa1dc2e32f7e73fba2821895d54edf64de5f274171de7be7509021c0ea0e204774e4c8b18c9fe7cd81ed636c8e5c5b674577888c7873acf5cc899b6f6eb2b377f91d5253daa8bcff8a7954ec054b24227f93fabe65bce131ed19f76bfa9df252ff42610e67c914ea2b28dd19ad2c238ad18004d7e1bb7e604d751883e5cefd286015273fff14e3b474de1189bf76532ab68fcf06fbbe82589e41551649a421d5d1b04ca5f832c73d4476408667bf55cca358dc08ebcaa62af77db599f84da6cf5517331bd3e851ad603f60df5b4acb562a7ce389ddd01b77329dab38a7b45f765738c7d6b94c977ca3678445aaca3f7a7bf781c84bbc16bd7211a3d7f4ef78feeda856fecec65887c27b0096e4df828fc0332a4521f78be7a365f08e60e07d8c7d6b3d1b9e361ea3631a7bc744e69debaa788c07ef021ecbbe77a6df8bec0e088027b8b8dcc7957c5993c5313e09dae65dd19ddca3203e8ae2175e14ebbcfc20496779b37e136a339ee3c5ac2a663ad1ea70aa7d4d6fdeac9b37eb53d8aff14dbfbe3b6bb2b80c7b44ad7e4a58e741217424ac9317c5da05d9236a6716e43927aaf33389a19b37ebef220d8eb9b3643ee57bb842382756c796beddc9e012144dee035d5ab8ef14f26ebbb5f06f0789cfaa6a09f7f1dc774cc9fbc7a173fbc6414d5ab83d857bd4dd445575f40648511e3f74addaac6072e4291ccf791898ba1a15cc29645e15f0e295fed6dd634e288c73076214cc7622abc1d9cbcd94784fbf6df5bfad3ee336c742d0a8fb0f9f476593c2cec2b92ac2dc0c9682b13983ad51014ee2e7af9248f59348b6435f39d2e217a8d9bf0971db67fabeddd4ecdb87f5dd1f5672cfafac64e33e2ea162dff3f207a8d8f79753b1c980ff828a5d232a7655c0d82713413715fbef21090e28d8a2be84fb48d844168ff3759dc5fd7c8f9eea9e68469922f9b5165802983996bfb1a9cd3381827c4c81ce6ca8696c50875bebc4fe5a1ccf31b65f8e0f614ceccbccb6dd5c31b68562dcc1d421312ea9cf612d954a41e4394c0154d102f4a88dd58be5650a3a8ab934db79304e397e006dc58565b160cca77d5acc53b1c264450e501573444e5ec64b6d8be5c358c6ccb70d0ed8da0b196ba1f267a6c4f794d01128eb439a8be5d800d131d0f812c75a6fa89fe639e821e37b3f5262d75a97c691bdcf6abe919c11160340fddbfc5253a71b28d4e838f262f774df9ee7bc139b098c4d0ed8af4be2cb40c6c4b500a7a9d91c685e518f16e677adf23a38c29af7c42ea2b17bd202580697c5c195ce142d81e3aae6cc6b48a3fd0c26d43747db31f0548a7ffb9f6b28f0b3e1cf65e40d5dcf9b2cc64754f9adb6592232cf7d582ac80559e2c8b06fb92037b5fef6313ff031dfbaf35756f0cbbd5d243b44e43fa0a0a32c5c303b848cf846107753f67f3ff97048edcf54632555fff61400c9d42dc732de08495683a8f9d9df3bd9dfcf2d6ebf623cc2ab62b18b59b1122256cb7332b474cc83201b4b8b160ec9d4cf41a67e9e0621f834dd9dfc7fa6de79090d636245e1678c2b7996a58b583a6a370ad50f4971fa8c082e5b1b4d4dc7d3ddb42305e4291ccd9927d4032f36730a836d953b238cab9877a37660de189ac98b54d585a2c9792d936bc727f931f685e52f7dbbbb22b67712265bf41f8025a94248c38c445745a47220a461f62ba8362516fe58b12e9d85f66c4ca020e3f527217cdfa2a7c81d1b4b186933ada14bd05a45edc65334b49a73d8d0c68d58c6fb95fc92be8fae392bdc1f97f7b21ba319183467f83c81166a0ef1b96f19ef0a9bc430c48bcd114d8369cebc84c23172a6627334ec2988be1fc3d30e6e3f83429a2e53f09308600ad5010da3c2e33395d05743f947afaa287f2d306d83842a4311206fec272e2328d45412262d7a31ca4810017e1fbedf85306bfa37be30169a56c04200d37d0831540731402cd5be34f6bd7247e0e750c84355296d41f71b14bb7d0c673ba5907343c5eb752e9d423564debeb3f8efeb11a3ff8848e8b70d5089424328b53900b7c9fe9c71e6a4a5ff0cf0b8463981e369e78b85e655dd11e253a5848ef4ddc510bdca3561a937bd418792118ed033a55620f38df19e8143df90adbd7469f5d28563adfbb83db075ba4745392e9014a504c6cd599e6ea230d2cbd3fb2255696334c267a568a61ae6a1a13114f5c8b5ba23c0c2af091d86a8a02c3dca26a6a5a99754ae67597e89247d23f4627ac7d3be69c8235e3b79056c9d9eff312f135946d23ccefd16a667a518d6583e73034205b2cff7baf36d22b223a50fa9f4c36e3fd332423f6621bf9404740a55b3e3d8dd491ae67b78ec6841bf6355b275bd4ccd7ee54abd5573a1efd90dbbad9e2354e53435a8e0dfd5bf56cbe07c1cdf689acac173e75ad28af8f82be4533fef979aabf6a492f5e83bcaa6aaad141b2a7bf77c07b8349d947c2757783fe81e91ffa6f3c232d0d6d1816fe96eca8f8066b02403f177f9f85dccd624ad523c287e5fa44c2eef0da926559b89fc2e865417bf51dbdf4f56e9b9b826e77d1bbb580e6c51ff94be932ae2be9f31f72c8d6850f8163ebff38c1742b00be949db6b50fc2ebfa555ad77cfbd6f330a219a0ea6a29f2cce22a5ba927652cc76efd19fd42c5b894196d0e29730ca2b5ffbb6c10db2f52032e3dcef5a716eb42a387b9f6b99a5ef1995f33cef15da0c894e42e740299d9a42aae79ca2139c305796ae49e6a6d2a2849d8aeaec67a77092bb4baba8131d79379d3696136835391a6e9ea6149270fbd04f29bc2af1c7f6f9a9051d215c4291546b4fa0c0dd6b0d1dc1b143f4e7824ebdf262f24de35ccbdc68d12ad0e292f97fee09267e37a79df2dda629a44b3f36135fd4a7a4c2fcbbd7ed69deb64a72a272bd1c0145249ea774bf9ff7c9dc298894a9dfa8941b276338b0f38d3b05cbed4db166e7227f1fabb05f8a5f02767743e7656e7c559e57dce39dfbb04d4570c2d9a7a926aa19f99697ea7aa12376a77e3c60f366e7f7595afa4d03f97bbe83ec1dd5ba4892e10f56f4334bb99e923a42224941e1da0d059fcf39796fec91945a8fa6d1e2fb8c281ea7e9f6fa6a727d17d09fdecfe1d13241accd5f0cebaa91f881fa590ea0df841bbb1c28c1267a4a4c45def4e6ffb9f97f3e9d7d975dfc8f7503d14e2fe10d12eadc49a5390fcaa8a3915f97e4cca623fe98ec8a5f2ba66edea0bfa9b438db29c49c35574bc0489d2cd15e6598c5117d4c524621f6aa12f8ec37eab0795c3f6123f1c68da3e35444d7ee4e2a0ccb13e21420c69c82410e8376a220d75e1a9d91de189563e952ee235f9597c4b8937282ed3346ee0044a2446ff1770d82464c62cea644b98e9b6fd9b8536e335b59c11d6e1e927cb2680453e25083b6b929706d4b94ef4ae6fd163104650a3f061730c99d44555c3445a395afca09e5d97e0ada3d0c009ce045ed22103779d8ea4cbf454a9fb4a93228458483833cc38060e8111001a65e2c2fa045d648706c7d4a9255ecd717adf134677172f75ad3e0a0a8573805d162370e8f8cefa76fe9c88b25e4abe6a66d1ba4f292ff75120cc4eed28b77e7ea5ab5c01a348d3ee5380eb7e2f082410ac41b21e5bb16cd08d8fa02502eac3ea92065171d042937468739acd0d2ef8de8bc5a4a024585f269d9af47e7e7b5f4a5a79a89af22941a5729171ed93bc25b38b4157c3e49728d4f2b4ce1757f716c10b66d1d41958ec5c7e74295963411c9dc14aa7e9d708f8b95bf2a8d4ee9ef1bc2d3a6864b9f9e75c267be15633adea91ea61ebdc79cdbd297bee54fe8b9a68e0ec73238d70688acabc0affca7422c691ef7ba65946a72a03379d172c776299eb264cc250eed821168df392c9f894d7a26d8994fef5e9163af22a0201f4fd1d1ece2779f335e152cbdd8983a31e1fbdb714a1e31d0e44e536b8dd76a34ec9cb8a6bd2dc3d13bd678972f8bc4babef9b6c14181db35e007e78c8d186ee605c38ddc8ee46c4c6dabf9e6889df9b6f18618ed4ebc2bcc10473894fea2718abca3c220f58dfe3de342ac74e81f3038a57a0c33b696c7f817c7bcfbedde361c56d5cff86bf3c82afa1183fcb3b4f49fd96f7b6b3eecf0b288b49646f5f77bbb5640aa871d70666767beca307ec29c8a3c29ec5de668b0c55952ca1fa832c0ef70fae7dfa55dfe936a6775fb80f1393df3a9b38670011d774c519eb65e817bee590aa13508d87b8ace4532f6430ec43d6398006bbddad33ff9ade82020351c7abbce2f6de44fb14c62390b7b64572d005673e35a58d622a6fb80294bbca5773838badfac6f897cdf5367c451e716df9dfaea1aa55cbddb8ed882beb7b5aefe1ea72d33307f9dec37c86718247542979d35071db4071db3b90306bfb7ec6c287d4319d762387584e05d8ea86f679ce9ad792c3299b147b6f4b7b89eaac753decb43f2f14595e9d98d9bb397fee41abc445be8d81fa2e131433b6bf32e437bedb176ffc8f35f24b15ee7855aedacfce9da2f2cba7186a1bd7eff9037cd265a69c1dadbf46668bf19da3f9de98c5dfc8f35b4d34e2f529c52924e32b41f9451870ded7cfda22c4674c45732b47f2a317533b4ff4da5c5b986f634ebe16a86f6345b61afa11da8e60c7c98a13dcff238d3d09ecee3630ced4841181cc0182bed18ec1c1b77ede5a8f13c55e2f3c21a9520ab116f1beffd295457812776975e4311a1a8ffa464a13471db5569b13e527c312bd95ecb0a579cb0e7d72e129267cc54cff998a1307b9e148a6c3cad8d8df1f66a3547df7a9cf4bad147ed7e67f5fad59b3bd66005228e03eab368a80e07beea6f8ed039712d5892b8759128bc29a888bca3853baa0b4b5647d57797f9d9db0be4b2bbc10c72183cbe81de6ea27ba58168af91ea69deb6d0a8c2288701f09b6be9b3612fdf9b03d1ef070c5b99fc4b8d0259146a37db976351afdb11ddbba0ba431c5fb478ac9fff5b7476d6f8d05e541b8d0e44f866fb522613677d0d88f16e096330f5621eed2b1ab2af00268b527b73559241430c76f84ea6e7b95a4e150b9c561a000bd96d465a54254ca3e5b2e86ccb1cb523a5395411476451cb984295caca13f63a3562325268730039f6db3e52fd222974be57683b6b672f9174fe4c7576c651d950cca048c79a913ffbe508ca5d999ebe071418e41843dce2434825fef48733ef67048f9a3a58abfdc60ee9e1e2b412347dbb9a9319fff95661f466ecb8193bae0e5fd8d5ff687307edf622060fae7e26cf044feee49955482b0d1eefe399a023fe189e0936d7534455def466f0b8498c73afee71934746a670b57aa5791ffbfd913be3b8aee9038129b0bdacdebe9f26f846f81dddd025f13572bc97a7edf479cca0206dc1ba6a08ab8dd64b527ba90a02e6f14b51397e696ab9962992df633005a299a4717a204608aadd0d334d70ae6a4ebd48111c6bcd03fb95bdb77a7eed60f232509b9b74afb5889bbb562762f093d58dc992f3d298b04a130a4bca64310aeba92bd0243e3f46c84f6a2f0d54a89f47fec6ce1723cd20757fb27a51244eee65c0c9df48bda82652fa83555e6ff5b43db9b68945a07bf25c48727cad5ce7227f5e8180859a2cbe7235a7ff2480be53337a7cfcedab26b6fb1dce895fe7ce9b121a0997187d25723661e8c403fe352ec76e0d2d7e76faba7c52734b8bdc530209f5a37360240c63463e6e7697dd7c4dc7e7924d94212b40be6a4cf6c6e90852ec5a3e9f1210ec87be07df4320edc7405014cd8e1504c22d3e3ea1adf65b9603ba25b4dda0e7df439124d7fe636127eef23290f3a1f601c96c97f4b19311df92d96e90f3379514e7c24dc2e157a23aaff212139e3352fe9aa8da58959a536a708567218eb9ba16e4e5592997e15eaff5ccb58d8faa2b34f5c44ea55aeb25278defdab0f115f7a5a9cd19ac846ddd0d8680ac547f067532ef774b5ffa311a51aeb8700a842080aa29006b954238acda87a46de51a60d8b7cfeb4e206b027a397f20b03a81331ee139c68e6dce18d760a8b5ba44b56e379408439e22afa3130f5e808a369eba0e8796392230f279daef7335c28947d3ae0e7be6e979daa5a0af0eed67bfdbafa4ccbdabca22853029bfe5a07056bc1d1a7bda175db31ea39427e566d5e682d0e7b7cc0df5ee6d9541df4db32b7af07f3a16f8e9f41472b628b53d3d9b8eb59e5551db7b495a3f2a85d9cdec1ee6fc933464ba8a069fcee3690e13e57f3d413e02cda93ca8aa4385c7fbd720dba13b58f4bc966b55917b7126b71b3b27c5d489057e7f37967918efe3732375af7653415469b9a7ffc0174cc67f6796cf1077ea33b50f08e3fe399c0de7fff27e0efde1781eb954733b500f6ba7f999a053fc17cff779e151787894842f9cf450af7352fde12cd0f90b8b63dd4bf70f42063a393c78b956e54328b74ca759e542d8dbf286386f88f3d3e991bb02e063e1e74eff17a1d9aff1fc51f7e731b175d8fd29f135a92229e5dd34fb64c46761d192e4aa09f53a2fd7e5cf2eba6e48f4ef2f41ce84a5631d7982c975b6b2afaf055319e5fc76b6f7dea070dabebb95397998eabf6abc03d2b6730654d47bc03690bfc7b37789f143555e00ee2418fe8a21f17606639a819a41d4a0ec8d1bbc9fde7f2ffc0582b9a094d024887a016c2ff0d4e6c613fda517778e7856a70aa03486958c08ae4a324a2360990bad45cf651bc3c2f1688b8945da100f68abbb8442ce2a9379283bd3edac5c42e3aaa93acaca24589d6dafe6f65c6e0c2f3786976b30bc2444ae3c97c7f541def98daf3613626a890aac472ac2f78e518fd27b919606d9dad3630912746e0dbe7c5e57849184fd569531af1da2fa4defdd9498c28e31c3bca352e09e6fd27b933c82b6550f4e602fd9730e2e118db037616280ef996f4953cf3691f68c9e8f309a64a53f2835f356b20293d1e9b9dba264de6b32daf34d4c69a8975e6c54b1b8145837e653afb143134e930e0a14c9e919fe4b34d97bf4a38a521f5f1963c845ca5ed0f77698dc4be5189137c5fd2cb3a4a4152ff7245c9c770eb74b35e0bebb5b65e5d1d184039aa02285d032e51f3dadc0e2b2938080bf8d9cdb50f46ee3291a8ab3456fd0c5cfec4fdad9b337298b04be4345e6883c022e5f9f7c1d14bdfb7572ae1e97260b4d41e33cf693dea08a2144b75d95b071a47af5d148a1effb5d2a87f675042c9d27fb5bfa06949950fab1cc613d7f5f42d02fa0bc7ed73928d178378e32e50c8a4c39e730a674aa19bed2f9df5f68fc87ce99563867e730d3a825269add7256b44cd0e9e537de3dd72cb1cb64fa7f29e92e1bafe2318620ad65f0f9bff3f217279436ab9cc7890975a7dcad37c792de80b59e01ab4bb164b358fa8d7c4b27acfcd2048a06fe16e0b5a677a338fed34a209cfbbd4d93dfd85ce8f7a9f89d2d7d83d26ffdd96b99c9fe73c7577429d131362b13ddb65995523d733f13d01643d7b967b59444c9daf82a5a80ad9243259d85ce912629fe8535bc860b6beece17471c55accdbb42228547eefe9113bec8bcc8dd8b1c771ef5d0058b3c5f3324f281bf17f2d02436d1ea78a37d4d6f0eaa9b83ea139897e94dbfb61b8af472f15cbb03818f07a5d091c0c77aad8a01edfd818fe7e6da6d053ed648e0a3f8f905d1cdddf4779107079d4a9c6377f9d4a9c19883f21a9d6237f45be6466bce432ff63736630ff1d526e7dba9a3092bc03ab71bf397297934d58b0110f62c893523b15caac17b631d2b54b321714099a3022d716adc298d738ff3a5643035693c5fd61f5146c5dce084fb6734a56fbead937a73056371a6d07949ed25ab4f96a7f6a4ca3d1b5745dca0fdca8c224f5166c04cd7335288d2981a479da4d81fa3b16fe899b1369d4341d1f53512e7c88cc7db75f30aa0c31b9b8bfc5d4ff56c7c7dcafe91efad0209c8170d5f8b0af1856ccc1546eeeaf4b17dfb5cd8d3925197bd9fc4f8ed5f5b6244617bd326b181658aedb4ed4ff6dbc1f16cd3d332a70c891bac1a9bd6e097ccf952b12e690ddd6602c4d7624ce04f18cb22cc0c56e66eed59d15cb882b4f48be5097ad48096d1130fb64058d6efd11addc76bf5a9dda9272a33c71e55adb904453329ee5b3b52bebaaabcf4844100c6fa12f6278116937561b5aef919a9cb374621b456d1d6dd2dd56bf36273ed5be686802f9eb5e1e4389bb75d028a3d603779601b2953ccced900b13c83aa2cb2dfb331a7d4b5a9cca20090c4302e602cf7e9df0de471cd0498e686d6b1cda9c361f96e86d45986f73c65f5d211ed133fdb59684d52031183d89283d6b56a246dd757cd9adf589d712fb56bb1bbacc2891b47873537d6e67cf028f7f9da23fff028d6bed4244e166bf5fb53a95cc45a4daedd57a4ab7c3ef0f850ab09522d6d9a4db44a67dbdff4061e6fe0f1d72b8beca65f193cd25e2e011e25f178d2dc312174103b1229541160fd5eec48067c1de8f8b9c4d00d3afe5da4c121e8e863d57bee5e8f7456c4aa11b446c4afeb0be1d2b1f8e9c7b0ac28894be30c1834a5f1695e4caa6e548de7da696f1d2f46b4a21383416c2c04ce303f591146a76590994f96a6ade13dc8e7abacc83b5b6c5fb0fa6aebac824e73e309f29bcbe2b5986f3fef7b0b3263951a60d8aea245217e2addbf8fa986d53ab867c5d8a7745c04ca5d5aad9ec431be90076b2ed33667abd482d8e7e447917b941ebedcf33256524f6647a4fe98dfa1e6728d7b10eea587ac693ad18a6fd981a63795faa652ffe28f28bde5d754a7490f17f1c33c9ce486f96bfc13d2058b2993015fcb0b73a39fb8a9d297950207d46881a8344b18e545f91cdbe068c13ddddf1b2e2a34373e0bb534e3e6cc67219abe5a0fc8df5a68056c5e2616d8bc8f9205b610feda776c8006b1197bb1b9719bdda52b980b5395bf3282b052c84e711cac9058022c9000db98d0907af927b02416cecd08fe36972fc43519ff888263aa1669f3f16c6055098e9f4ed5fa64b2eea66add84ec3b852cb9e55755b5700f17c9af16c50f50b584cba95a64c03755eba66afd1e52e088aa855511e2886e8e72de55e24cae74ce170876de5cd57c731352f39bf1a67a6996405aff9b38e8536ee676bc5e3a564e12e4c566082a22b54be43f2d1d3956562265aca9a4fef6e1f7aacdc4db135c5018ffcab1f50dcd3024632fbf734cb2f2b277420bbf330ce1b1f1aa7ce88d8d8963adb231672a275d6b927d90afb59fb8761755a8b7ac8ccba0589f361bebe555c7f1d09b47c72d7559bb547edfdf7f980a794142d9fbfb9b0a7953216f1f8f431f8ff4a65f578d64bd5c42951464f9b02a49997aa447f1fe517cf852971e04b12e0af279aae4055963c980cfaa53722fe7aaa4c0d50451e6c4fb4aa21edc34f3046453ad64ead9dbf4a64adea4c1917bbaad4e4ac8116999fb4c758a65aecf1ca23d4bda55cb0469e937941914fc31b04869fe85d6d47918e571c2948ca2165115abc9fb6a4813ce84665ac111ab460bc0aaebe531a8d2d27f5e2f81e023f08c16fd41b35fa16a11cb5dd1694bfa79e69541c2f7075cfd72e3199384bf2914a4e6b0a54cbdd81c558c67036c63430910cc9aa7a284c6519e35868bc747e64760344c3c347147ff3e556dac7ae07c6ec86335a68eea8fbf901bf2fdb5f07e6d81a99bfe78fb62fcd52f46d5edff189db2a2e78b045a72d20714c4bbbf1c232419f0ad1ede4dcffcbda5c6e9baa7b7e5b9adc8b5a1bf935c1bd6862f125ae8081032849010b9388cdc07eb5af47d153ade387b6600853982e36d7285b49fac1d21a3c9b9bf9b6f8e6092526decf9201fa739cacd88f93c9967f91bb0cc51fede60ab3236d521870363022ce36785be99f2b08bae4accb7d4b44bb9e3e9582205117d753cbad75af38736d291631b4b382e78d4cf1d175b8f9e6df47d15cd6013845045a3a269d524efa99160590fbf5b5d057edc9cb9581f7e66bab14dc9f988975f457330582330eeca3f0ee2027e4af4f0d86f4041e63cb19b38b6620e46ebe2ba44f96f4f8169eaaf84cc484d9ff568906a05f7fe2e29c7c5f39546ee8f917b44ed264d3e9e845dfa8534173712f69b96fddff3bda437fc8aca34e9e032cc16cc227b5d1af54a3fff7bab48e311df68d46f3af36f20030ea9c6543d698fa97ac5e81e32f3ac6b498263ada7e099a4d5fb5b79363a64cf55aa392ac92559684c75a3ff6d621589a7257b9a9c6b1bf1b05791924e0221bb53927b347ebd6f0493406b70293f7544b8b3edae48f8b3bf3e53aedcafaf89a61a13c7d64347ec226f9cf240d3fea020cd86d44bbea165b1e45853d74b5f30f173a1270c66a4ac941a86706cce81ad4f1d12c9d04c1ccbe080adb32acb4fe376cf2bbd1bcfd91b67b93f21e1ac6e2913c7d291afa2b7d2b8ca734130ae7a4ee2a16526aef51a38421852de4a33c9ca2cedd9371837e7a09705c7ce80258d7d35dc35ab737bf7ebdc35269111ac2cd482aadf5d56653b1bc7343d2703c10cbdd898b020dc73f963b3f7682d0339b64ef8ab292f29e1da5c79b12cb85617ed94de8ad10caae6d8b108e5081943cab5c9d4f13eb09a892384f28f9e36ab783fe5556f19786e1b306614102a58427286081cc2676be432def66fc1a474469c98e69fbdf6089dc99c71769f795e0f9fcf363d9b33ade1ffd01325c4674b4f06e39d7313ef04522fa0d85549f9a8675dea5915113e5567a6e54f7d35201caf453e494d256e9bac845503cd5989328970766fbb805809adc690d2779cd6f7168c3ab7cf416c86a085ded917867aa4bf0458cdd1b0a748c0ee5c2af2663677e791775895626d72156a1bc0490f27181fe5ba2ccbf2a900ae56e3c47a958f9bbfafcbe2bbd4a88ff294b0899e627acc9bde30dc0dc3fd1afd8dddee2b8037fae63fd124888e3866699354c0d46a1f2660aa5db1ef1230b5fd24123701731330ffed028689812b8b993f67b3c9bf7e0efde8e7d09bff6bea06c32fe1fc98a968cf339938128f17de3b26888eb959ebd205ddac64c07fc1cd5a276ed6ca70becf258a6e26a3df5f22ecbbb1b9e5e87ba3f9dce78c81652a4d4d0d3968adfed9082675573543f0b586916c1daa68e1261821ad646d6c70436b4d1d9b7627d2d4300196236b71c8f92d65f32daa2f7d4b5ab90249b59db73965e5d85d8e54c98ad7525b5442bfd5455e2cc5b0859e8c464d7c6dd492f2df470b473436da1beddf571107d5c13f75dba9b7c5eed457d7e87b30a9b785103956878cd789e5d1b04fdb0315099a6acc1cdbd87cefe92b10f16f6dcb9c7badaed4b649de0b62ef0eb4afeb916b3b8123ac434f7c95b5b112b7add739b0f895df1acd09f1a46afeb0056309c75d04c79de83bb1fc3ce1ffd55d8cecd5e6c6db7011889b1b4d0561db9aa3614fa9ecd7e6e5a923c80b2d52422f4661db0aa740ed22f8c6457e4be7414ffbe7f7863c2df5f1f579677c6c4d024f75e6b0c7cf40a2d1f5118275f1d953d6c2e6e5080a5d497bab21ff6db5c4cfa4eff8de90f1fafcb31115fefdb65ab2f53eeaf0a4a2677853836e6ad061a1f79fff1f0000ffff010000ffffe0efdcaf1b6e0200`))) +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffecbd5973a3c8b636fc574ef8f6f4ae6610b670c47b61541602cb546962c82fded841820ab01249a734a237ce7fff2207260934b86557756f5decd85d5642ce8bf5ace159ffef2e9afe982dee1effdf5d102dc315fce2cde23fe10fe18777ef790f3cef8ec7bccb7982fba78722dcec6bf4f3eef1eecf70168fff1ccfc33172a77f7a337ffc67f979d2fc8f3b2d9ecf7e2ebfbbcbf0eef1ac1efeb833dc787cf77847fff175e6dd3ddeddfd7137747f06e325fdeffe6cb6bc600cafeed20bef1effbfbb2f77fff78fbbc1d245e3bbc7e5cfd598fda33f7617b3e9dde3dd74b6fcaf68ba58ba088dfdff82abe57fb96b37422e44e3ff8aa6ff055711f2ffcb73bd707cf7c79d3a6b4768bcc0eff550f4ef9fb3d9f24b30c33dd0392fee1ea72b84feb8fb3a9e67ff3d1c2f96d983f99ff69e789df92b3cc6ff7777d1c2bdbad1349dd865bba4ce5e67feb9edff0c665fe2994f1e33c73f1711593bfe0b2fddfdeffffeef1f773fe8ecce3a508f7fa299e7b2f6f824e2fff7c74b3742e44f537a16d2467fdc2da2ddf8ee51beffe32e9ef9e3bb47816f3c349a0dbec193bffc7b199107044ee0ffc509ffe2ef873cf728888fa2f885171b4d5e7e909ae0ee8fbb68f16f1f2f115dad45427afb3a5edf3d8af21f77da7476f7288a1c2f34f93fee0c144d27778f3cd998f1dd237fdf7c78f8e36e14f9778f3cc7717fdca9f97fdafffef7dcf5b9bb47ee8fbbbe8f5fc8fd7137c846ada0099d4283a3ff9c79930569f3b48c623c88c1d8c35df052437a101f70f70bfc97fb079e13f97b9effdf3fee5ef79a8a8d079ee3c5b46936d1fffde3ae757e53fbdfff5e4d578bb17ff7f8ff717f707f70ff976c6738fe79bbf6b76b7ffcdaff71372743fe7f77df27c1a55b9ec980fffde3ce77976eba1e73f7e778bacc5f9a3f417abc44bcfce9aee8f0ea650c69910a189e7b9780e1c965e22f1230c2f5040c1ef5e7081836d173044cdef426606e02e6970a182a053e58cafcb99c4dc6d3e3b2863649858dd0fc3461235e4fd8e051df84cd4dd8dc84cd1161c384c1a7889c3f5d6f19adc75fc6d32fcb598c4e683be5b699287a105359d410b8f709a11f2e5a1c97428d4329248a7cb3f91e2984075c23869a5562e8fe41949ba9c0907989e31f1e44e9f717437f7ab1bf2f8a0a7286fc784ccee422849e412641d8669545485130d0d63769703d69b07f4f33e17067096dde578395afca3f81d558796a3bf184d10ad87a02458dfddb6c7b537ded21ee050a12d2be72812e9a2bc7d21760a0aca0d80bd873017bcfb415cca1639b9cdb9238282c118ca4a5632b5fa1da9e43fb357bbf236c43d7e2777df26fdd6fc5f20a0c9e64ade5a37147418ed847a0a52c1dfb2948db6aaacefb2d658afbd5a6cb87eec45838165a7a222f6b91f7d242cbd0b7fbb3eeb4bf760573d58d7de43f9b0d4f45c9782021329748cadf9ffe36a2ef39319618aa72e8ab680512650305b4f25b4f11b0c38d1629916ff70220c89cd6d21fc61c7ddf0f9b8bf4cdece5eeba6218fe9c6d16f452d70bddb4d12f50fca49be27753fc6e8adfa788faf49a7fa0d6c7bab886cac7f3fc27a87cf7d753f9c8806f2adf4de5fb9bc88163fa1ed66dfc1db0b515104c6e282a084ed2bfe95fa1c02f1d4b9a746333f16239e94ecd95279a1b4f95135f3527b8bd17b739d792a62311ed7cd55cdabdf91ac6a3e0fbe069ea5bd2ceb7950d14750e58bd0016da6b1d43f2c43e8283a7682c2e5643de907f0cb4e995f5220fad16cb537a51da28d38b3ecffafe7045bde8667dbfe9453779582f0fd36bfe817a11ebe2cfc90a8e7f4ec7cb5381058576178232f15f3c37e41b8f8d87474efaf2f0203765596e5e267c9abf0e943d343821d3891e9a0d5ee4f887fb0ae12389cd877b41ca9aa613ad103e479ade84cf4df8fc16c2a728193e550e5d03aa890d59ceb09a78ff3ea9740cab351a9cf8501591208a02d7788758a223be04ac3d34847b2e1521cd0759121b62a3f9fb0ba61b58fba7c98763b8cd58f8b6c161dce68a66046c7d05ec3ef2126901056fe55a520c1369e7ab6dceb70d03d8c6ceb17c54c4667ae2bd986a38f712e52dc5795ac79f4375134015addc4491a068269a9af515f802e2dc966238961402c19c686d03795330770473a7a9baa4a946022c86ef5483f7c4fe1a0e9404d8c6dab7f53760bf06b41f0339a28efcceebaa35412b4d35424f1805507002afa3af9d788ba0fd1a78ea1639b68134d56c00cbe07d751468537d0685f6ae382e4fec877ec7dc6991c2c144797355f3cd4d9439880ee7e0e2f776f4b5a79a09ec4c02479057204653dfd611789a917569a1e51bec9818cf26dd78c93bb199c0d8e480fdba4afb1ae035e60b3e90c49bb626c61ac61272c4fe1c0a8da0af9a9c63a185b79bbdb426ed8d6319333050ba8e057e3a03650ea706e758d21b18ce02adb37ce84e10793f8c0d348cdb4b60f3726b52ea3fa07f37f0bbd0b7e8893d2785d032779eda7e23cfa0745f4641cf32dea068aefc963204969100bb774f9ec9da988a23186bdf92b89160be79b1c9657d47de54dfcc5e8e9cb7d47fb2746d6387f7bdc7d6b3c26f92b5d15432a7372848b16b790188d1020c8eaf7bea2382aa1c8267bcce600e386a97289e6b10b7e75035275aa7bfd6d4eddab17a0119b3c59e39b1bff83cc0d87cf35bd21c4e15de6f49749cb6beecc63cf244039ffde2bc9e21b92ba3c017da789dc919848284ef010f864deaff12b6f83e202f927efa968ebc5842be6aeeba717a667a786ed36edc47ced49c7663839c03a86ee730f6bf42415a01cbe08a73ed09ed9523980b48fd4fd99c34b5740e4ff54fee2c182d43102fc31eafe56b6db5134f0843f87cb8ce3d41e6a1da0b602c739aca87ded49839d626185aed159635e099bd2f5d4f15ad21bd9f2f234efea6a972e492753eb11fa28e1cbb8f06423b7685f6d7515492716ff85c42811f643266c4e663f58b7b94c9acf43de97aba96bcd23a3af20499f76203115f5d227d732c1efdb0b94853c3d04b940858e62a956fc0ea1d5fd3a91ffaaa31ebc772b2bf1e23263f329b5a0cd65ecc877ebb2c4b06962438d6760e5a447ef2b0d30bc054c7f294c82ec7eeafbda811a4efcbd753c1329df8611d415e7a2a96c7c4372bba767f8665a9a7e2fdc07744479e682efc96127bb1bcd49e8dd7c1a0f14264d9b5e687659cdde7bd3d5949e503fea6840846cac68be53790ca87673e84717b0aac3e9595a3d279bed75aa670866c121dbbffe63e83b537d97b9fc9c6b4ffbdb40c3286fdefe489339d3d07a6e6027f535c8b7c7b17440ea9f87ca1b56f6b41be9e8d17536d067e8c909f2873bfa5a031de13bb8fbe05b31728bc064030f1bdfae9244f4bb8e325c7e2175a8b5f55c9fbc2dfe41fbdd995f7af3f8796b9f6ede27df2a63aaf2450309027be92efb62fb4394708e730f64eca00d7e21168296bdfee9dfcdeb2f7aa50d4f7eff090ea37af4c6ea215889bb8fd7cff2eb5901fba769f8c0dc472a275d2fd4fcffdd1f31678b1b9c37a84238c56ad4926034ecdf3cdb11a81138f02c7dae2672663fccd8fe769ec0007331dabbdf1d4eddc11da441e7d0be6007f4f1ca1bdd2547d0ee35e80e52050cd95afa210765e035f6d06634be6bd4809bd8eb2702d2364fdf29e805660377be90e9435509bf8dccdb5a7d9527b9637c09286ae8a62f29d1295355ebbf140115ccb145b111740abbdf2ad3639c7be6d903563df4f0eb69e5e5a087f57e99870ff9a2a21bc16783caeda16c04019025b175ccb40da336e47d73df515e03b5fbc1fdf82f9cceff437de6eb6ee0afedc5743de89f037975b7bb13971d536d7b5fac88fcd05f11f44f22e7d7fd7cadebf84f9fbaf74fed377fbe573bf99bf39762ff8fe75db1e724ef0a3a590773b627fc1f651d25a7cacb5b8a015b737ae09903735a8dc52b3f1aef2f1ea4407f06273ed2574defe5b3b841d65e60c9f5f5cbc975f67c14830133f466f6094bde3055a58bfec87befa7cdf8a9e0288f5b6e12c70c9fd785ea6ba6df65ba6372ad937ce1395d011b0dc98eff077e15b300b0ecfe32cd05a4f0110f5b56f3fdd93df3baf2ff86f9a8ae5cee89efdff120ace929e4bbe7c2ed93b0a77e95e53fbc853b7ebb1c52338edeff038b59622005bdf917e234578edd1e7f06f0ebee3cfed5d1feb8bf6ebbdd6e927be357ad15a4a7626b0aeadb59e969aea275034376cae1d2f9679af8375da833ef0ef56faef1f36c7e6b5c4679ceaca13fcdf7d2c5bc958d275267eab4c4f37bff703861f82a3dfa56cac4eaa9ba778a895e9d3580f0f7db522d68ac3bafa76a2a9d2da6f29acdd283f1f0325d3e7339c7542c7a2715ad28ee183923c05b1ccc3b8a44be1f713b9cfe2bb8af20d8d55b4f35b0a95f3ea28f0440539028a5d0b7f0b0bdfad13fa7eaaf799746cc3aab1a56d46a2f986316849c7e069bc17c6a8740d989f91ed9716a56b87f52083a7733262dfda2ec6678e6dc4b5df31aea3d88cc5b0b16ff9400bd27781d6819e719e5e6fd27548b15d37deae4122cd610cd6b9ee0f42d7da22d02e9d3386e5e595a6cab1d6e9cfc0e0600dd33313a4b8eb5b74e6da65f2acfde6602c31ede57180ac4d0586c4ebb5002da6dfb276f89ca76b9adda91367de4bfbb7d2fefbd5e7df0ee79e583afff9f74dcdc61e786c7d35b5bdc0e70a7426017db6b73aa1a7527b0587e292fe30311bae6d70dd98fe7fc55a1cc73487e398b682fff37faeed5f8ffd13be75627964a13ee2b901878230e48547917be41ebe88f79cf820c88274896f4be6ae98d6267e58c4a12c3f70dc43da349b699567bdbee9cdb975736efd62e375ec7fa8372bf6df17c8737f5e9efe157ce9f215f3f4ef2fccd3bff9d26fe2e63f4ddc7c4a304fdecd35bce712c77f82f3bc22c3f6bdce7332e09beffce63bff1bc983f39ce68ec04fba537307cc02e0cd7fdf07d66fd0eaad3c215c7bd3fe33b08d372f461b02d28a86191ecc81ed3107b7823ce2d8e10a41cff2ca4b8861841a7d9fcb8e5d286ac4480a9131732dc0159cd695e3017618425b5994e69078d356f41ae44eccd4e9b3e7c45765de6f2973181b0bdfa2065a4734132f3657beba9530a08699932877f2b7a25ee0c5e1dab15f0bce0ce2ec24c0536b714bd7f25750d451d732d670da47e34eefe5e49898a1b9642cea50c3c5397d324394ecc7ed856f8d4ef6c78210423f1e059e6024aead70d461cc0c2283dca05830dabee82d25715539f42a9dadbda03be06328ea6f60f0f4dfd9bbccdc606d0bb901d8130266a8be7a3260f13e78b3389e9da083606d3e3f0255fe857c1037adf9a635ffc77e25d98dff24e599f6760d1dfa5e103e4187aee487789f0e4d067cd3a16f3af4df4f3a9cab4acb4b68c9ab6e0c168ee5adcab176d2a4565de6b6ebd4bf9cfb97982f9df9ad3515cca13a3af09fecf70905109318b841c62f51df2f89075112288239504781633582fc79853d4f6233223050784f302724b6958eaf187b456278689cce73ea0b5d681d30f704c4696ac8f91d65f72d6aae1d61bbf6318448e31962630d07327e1786157330edad53ce8daab8a6fdf9825826b1284035778ea8cfbd4e7f0e05a9e81b52b11aea5afa623cc87dc4ce40895c4b9ad0fc4b126bb1f6ed5e1a039b40e6efeb1ef8f08c35b4f8358ca418aaed69372efa718fed711603dc2dfa26cb7ee0a7996b39348eb06320bfa5bcf9b69e004be2caed14d1b5b60b4dd591d63177c0eacd4fad530a457a82bcf255b3e1b78e8d154d612c276090f70f3b93c013cc058619c0223e3eea334ce398d5f6ce4dc859d9016b4b2000b0da6f6e211e81c027b58dcf0ca23edb8ff0c115aeee743af696a7f47ddae8621e10a181bfada2fcd8687c1145f1411445eefe2285ffefc003d2e01f1e24a20450575b3ad18a2feb91a63785ffa6f0ff4e9f747ae53f4de327dd5d851f8493c5e33aff1972e92841c8bd240b4285ffeebd3a3f1df1873084fc66a2e9a6f4ffe324c4d95a7f9a25438cd1be6d94b2cbf2df2b344996ed428df0c60c8a3ad7afd764b3a8a6348abea885f96a331894a2a994b51729dfb1663da29af5a1f19cbdaf1b1b4bd092165090a6f5fd9388df833138b6b2812a7a736c1621be37261699bda7f5cac95e0476be2ec17ce4aaa3bd4c252576ad2dd254b4631a2f7977c1b08d354f126559308c8730ee05aed54770da9f83e924f0d51011233535c6af5a93f602f709e336e7da006ba50b32af018d58c77bc9d04ed71ce9ed1e277feb4f504753cd958f5182202d8976de01a117a3d089b78818cf3b3a72ac5e3a7796dde5f3a9f3a31bcc5e861379d41fce82c3cc431d79b639f76273c7fa1e0c9e65659414115786ca12df92563493ac3abba285fa3397380c302268af408ba2876fc1ece575d0087a69e4a0fa9cefdd4009b3c859953cb364d19973bfa5845ea2847944ad3287533ce783be83d604a568b6e02408b3e70f231537816bf7025f400bd8a2f3031648806dcc80d55bb58259d28d94af0514976760b2a875ad4dd60f79622f8082fe3ff4acf6670e4177248b0095ce5061fe1591e58577983423e7694ece5921cab895214955de005b0f7d55c6e7f8ead1fc3588b8247fce7486d1bb923aba5a15999883625646d6df29c74f55c64141ce5034ea15b32b8fa26612494fb36af0ddcdcf1c87d74f53c33554fbe93d49e780df3dc1f7d2b5da0b2f697c34d25c2cdde5ea04bd096bf30b1c4bd7e455ba39966e38f3a6459ea745b21bff493093f6761d164ae9333c4b15e6af77a34c32e29b6be98632ff7ef2e13c90e965a99804a8f15e997681d19bbcee2b5ee9dfcf0598966b99622125780da24345f15c20b7afa8eecde11cb049c7a322e2e681590a563b82a2c9a5c02273919c1f45b6d29e0a69c5180c0cf03cd1eea02f1a09954535d5a419175c1c180895010f067bbdd88ca14881077539ed83b20d4b21e6790c5c9c781440559e1260a3a215012a07aea3fdb57f7a29822f3305bb164f803006b35ea6d057d18e10857fce52abe3f1e00050132a0f60875c37a8a08799665402278188d7d1e724552ca76c880ff6f314e848cfe9a68aaa2673d3e5a039a59451b7083c57d297e814fc6c1715b41604a043a1514c57fe06c57ee1997e25bdd090d08214fade3704e5eb7692a668783a75b90088cba9cb258aa2e71ca8b2f77ccfd609b1f188bcdc0ae65f2b0d132a33cc88e41962f8d94b91cf0c37f81eee19a60a7ba8f33096c873a349f8bd67be0605c0bb6a4df2716aaa11c2881805e6857dcafacdd3ea75cdb7b4550be5861c10a31568950c28113edf635b21cf66544a913227f7d96a278e10ac5ac15cc5e387167187925451425142effd06aa26a16bf2623326d19b6a33703b7dceebbcde771339ef2f26e07f0e137906456fe9abcd6596fadfe24318f1795b76b73e02b05e1e0179769e629900582064b7e2454055be1e50fdb834c57d565f36d1730880f3a637a07a03aabf8122fa39918f578b78141bf7979547a81042a7ca23885c45b6f47bcb2390017f4e79845f2b866eb0f49f220d8ec151ea5f29a8d619430b61a27896d67edbdca5ec79766f5eb6eb4744c5a62c2e91b24c555cade3cf08734a151b24865145960b92a46272459895c3859c3152df94fcaf393b1f8daa3bedfb608c368c692253c77fd81c830569741d611099004be70155df1352018bc390cd4c1ccb207ec551475f435be16ad6e4993e7fb826783ede942525598dc0b530fcd24347eccf49c20e7b6f71bea3c233f5ed3fc61f428fd00fe40627bc21b4c9e5ce107ec80b8fc2c3a3247ce1a4fb6693939a8d0b744c91bb626efaa5ce907be9fe41c8744c0e0f5e6e54991ccb2dd36956591c6b5bde14cc9b82f9db7c52e865ff1c3593f47595f49ac6697ef753d2e8b81344e21b8d0ac8fbeef49ac685f4ee6579d4109a4d5e6ecabfbb40baa99aff2cb9704ce164291e69c9d5d8dcfa164a80d5b75dd55c0d637935282938a6df8afb28cd622636cfaf5ca04dc87b28dd79f68e5e4ab74bcbb44ecd158c0975f41c4efbc88bdb6fbe8a04606d252dc894aba83be01fc689a442b53dfd6173ef7cdfec657f6e6e4a71dc0621ec98a81beb21f5f154cd07adfcb8bd70ad5e00e26d0812053fcb838156c8e0cfdbb04c704aa787e8fb299d33587bd1d3b26b2f1fba648d7cf907a5fb63a92d292d73faaebe45fb91d6cc5f53a207eeb69494a639fb5d53db0956a6a92fa8763fc97ad628c70360b779d7d65989d9f65453e9b83435b5e18fa605bfd1de7c08057458b05d4f34958c8328f274fd32203387531042154d7ab63ef5291567463b594e316a9039f70513cf67ee240a7b07b57733653d5d0fba9e9132623ea69da63e078e206fc683dcc7d613e4c88b9f03b63e0149f711da5330f02af7d5c9c6d80bb4a88fcfa5e2c53e0f2d73e577082521190ba5514cd743a3676687f7e4a340c01c8d97d11976e6b45d3d0e901e6ac30fee1f05ee91bfff22095293e765f96c5bb3240acd1a1c208b9f80039a9c2064e69806d7b8171f3851a88c3d904581bfcfbea6e9442b630f6a9bdea0c00d0afc169ffcf4b67f3c10603d5d2718ea0c1c704a1a1dc7013c2fdd57c468be3f18ea5220d0e41a7c160c2570b22c4bf75ca565e2f712483728f04f920b4703a1d6249084061a9428ab2a94b2c8247592501a158e15d425cb69e7a94255b0b416947b5a23648b98731f3a717be776b6f79e1036418cf07f6fa0e8236f6acc80b55dd8038d067208fc06aa26cdeca0c14d3b579513ffb9acbc572bb8fa90b46d297bbf3145320b10ca957b6de223189360011ae093af4d4ee14479d70fd72ddeae61ec1f507755ade350953180397b5c944f20af35545acfe9eb7d2b98bcb44618d804f4bf07bd20ab35f37533cba9ad4afb1039b6317be9cdf4563079d3dab5efa7f52c5433748420f004ac3ce3e73701b043e4882647cf8281be05337da8a2956f9371e8a5e0a2c25e6a2a196bf083f08d138f030283a735b0fb6f5d01ff16fe288f559a74451a48d20ad0d2b18cefa3ddeca5d59b4cb44e56ababb45fe48cb594a6d63178a036035f3591d692794fd4d65095df1c6b73667f93979639dfb95f717f335d4b141d44cace55cd056cedcf0b0310c2991f4292a9d49734d55c39964e026a5cab9106ba213805732f96570454b4d2da4e243b67052c7342f68404c9b1e707cadc6f3502ad5d08bec9d79f001d10cb0ba8ca629ab5e408a3ec3c00cb98c1e429726c938302dde7ae39627b8d56aedd7b606b388731e2b4e8e9bfbf47ca7f771309dfd3c4d95cf79cd49e8dce7ce7b69efe5b6b6993b100368edd9f59bbb6ff6320ff60e738a2737a0d2c4be6b37a72b199d63ba1dea296126aaa84fc24db2b72bf7c9a15b603769ff758769b632d91a69a3120193c0db2cf7d2c97d89ed79f63304fcf31ab37919e91114c940514da93f2b9c4c01d60308b1ccb98914c2d91d4ed5814ebcf418178cae83daebebbb16b1b33ed6b23f81135572997495720e359efedcb9abd634564ed13adddf3010075e2fe98b8c79541da244fbb6ebc2b064a248ef64bb8da45ee8a2c7064d89f1304c5667a4ef441def4064c6fc0f4d72ba0f4aa7f3026259d5c038e127286632150e2bfb8e690931f85fb47e9e18b7cdf10f886d4142e0b81aa247d7b5f081419f087844049bc2cddf35915886caa5560b4bee90d8cde64c1f16b5a19015548c2a970d020925082f537a2ef627cd4b5b6738c337d9b382c0ac6fd02ae8b59063bc16ea5be3e184fa654bf1b568771439245ba2dcaa000595db834c3bf672ba1238428cbb82f445e7989f6114e05ba33bf3381afc8fd423eaf5b9ef54d73fb0f95d69f13c45eeceb3a4c5eb960fac01cebfb6b32791d114ab71ceb9b26f7dbca865b48fb3921edac506e8138368dfe91d66991694aecda27c5312ba3610e225714d155cd95a64aeb82b2b8a3632e46b5947ecfe64c0dd506ef4d7504a7fdc598d4a2e82df28ced51a045dcd2b57a118bea2159df6c3d6bd79212fe069452a8a5a746d39f6ccd784f184585cce99af56184cba2c9791d93ebc66729e7cf554a7977c0af7dbbbff1ed34a2abe054e158c6698b64a68aae8ade5c6a109eb8b6b1816a5bdaa33f2a9cb546d013c23514f15a82040adcbdd6d2ffc713e495166d026d8a96b0a52db4964e8baa47de0b14fb33606b743f59263c5e3b7ca65d620ceeaf35b53ff74465e1d88c52ad12085cde770b2dd91ee4d9d679841c8d121be551637e29eacb426964576da49f63f18844a489e6929d89d411b2f1625970ad7e9a9d7d6c1c0a8cfb24ebba27b457f80ef662d3f40473528c86238591074a9845643130d51df0f33c92cd08614cfa2f106cb7d3b3bb23e3c5f7cb1a95cea0afca1bd77a3dbcabd3feda53d1db3096b93e2d567c583459a46db496fe304ea4111495b9c3e54576812a232fa1b289154b250e212a039ed382e52b47601185937ccff362b8de0782c09f6377393e0102699b8b499df9fb212f3c72f78f9cf045e679eefe92046691fb854c5b97d8ee1ff87b21b7b0e159721c576dbbaf6b7a43803704f8db6879f4b27f0e02247d5d0501ca0df19c6ce67a7174c28edf6c889544ceefb3e3d3e17e542ef3ef24916ef0ef9f2518ce827fccfe5d6270ae52df4d4f1811f592320963f5935fb89644889d08f4cb9312a25c3dd5d3ba2351094a30e6d9cfb5f12b218c14c553db6f183e55a875c7c65843da5595a4b25dc3d80bf661228dbdc9a055b4cf2e9d31fb5a8da37e06c276ac3e071ecdb87ef3ad6d4808aa54990705753e6581f662739a322ff72c404b1fd2b9914c69ba9f4588586081263e11c27c1c8d8b8ccb87d031dd8f080cb442fd9aea735624c8aa86d3ec77fb9530e0baaa2c5233410e7ff3bdf60e49b6482678ef68e638857380c6261548d5f619abb50e4d1cf2922c3ea9b45ec5d294ecec64cccaad60f65628271956ede7b1e7359597ba165b43abf0cc19ef65ecd519bca62cc23af24473c12035e88df8d7a3fdb7f8b5d64121b43619bbf1e1fda0e6005adfa8dfcbcfdf21bb71e55e57dd13b2174fcbae9dd66832932c79a9c80a4fcf7ca14f45efefc15876af562ce189de93b68e8040e308fffa18d37751685b3457f568cda760d4d1d77e8c26f8ee8dd87dd49ed173cd1d5940c15b01d58c7cbcaed95df5a999a3eeced0f68726a85af3928e681c22ebd7ea95d696ae1b49e4ab30af3c456371b14a616fcd3c086958776af08e40e2e88ae46e55e644233723ee995aa819a3684a9c9198bbd8c47f677b6c4e8a6b5f0fdb73c89f9e6140e25c8d37dc3f989a0b5aa3a9eaaca31535791176ee55b6d6357b32b02476f7100769fc67a23d93678b6b4d4c2adfa2ea73ebd277aca859459a016bbba9593f0dffc6e217bf51930f1d6f715d4c4b9a7bb689685dad02c378c539a9ddd7a9c213d6757297f23bda8d8be48287df469da3e3d13afdb9af6e111b6bc53df68af5c3165034275aa19f536bc564d100583e89ff7edf3ea5fda6f7db2bea14e5dfde6635ba437a5e68fbf4ee77e310c18e52b346f8b7a780d62aa3df9c4c8eb0e70bfb19f505730d443df4d470ee08ed0596f14c1ee1fb9fa4dfcbaafb50a8363001b6b2802242a0f581710cfe188d4f99b0589bcb4d580f435e7c9484c786f4a571dfbc6fc80df1e1222bd61569f83ece8a25ddcbf27de607cc265a8519eb9bdeac58372bd6ef0256d97dff142b16edeb3a562ca971d28a754a221d376449f7025f4993f25e4396541f16ff170d59bf9750ba19b2fe59b2e11c43561f41d5fc4843d604585bb46fc802aab9009f66c84ae77899216b6f8c1f6dc8ea015b5f3a9694c62da4eb76d2b0d56d2973181b0bdf4a69ffb60b0c043d15bd7949e3a585686c89bf5f368cc455e83c8c18933c4b3873e251e0d8c6cf62c93452e09829c4cc4f9db190141563f69e104ee9b3d91a06f3eff8dc78537feea5ed283bf7c6b18d9dd6d2965d0bac4962272d5516178a30676bb16f442ab0caa7a0266dcb9257cd866391c4b61ad090fd4e19e5d570edd3a2c43c1ea75f66c49f96f76cf6a6a9d9d93a1d4fd39b15923ad37d64cff7662f5a52d8f3ea3820d1b5fb3362c41415e4082876add76030ea15d9ee73c3227b17891ff8ca6d5dd30006d2fbafdcbc3b1886fdd7677904ad79bf1ff7765030d451ec1d18abf23b901685eed7ace3dedf2840256b528c5fa804d4cfe8b9c0e65f356f9644da5eb1b27dd91e6bcf2866f1182ccee7a0c2c3a111a770ceb1bc03adc6d139d382e175e7e7e8bcc9190683c3b98f84e5dc6b31a329bef729233ebe33a43f14c1ce24bb3f69f5870a99b52a1b1b32794e8c61ae25c53049ef045a01be16c8c7b0824e94f54fe40aebbb688079cede7b86b16b2f5e27dbc3dcf8c0e4cce8af1889d2fda6469afde2ec6523e35f976bdf6ae6045579da8dd10ac44d3cbf3728e2f368d0f275235ae920ab0a50633caddb1352952322327fed4d75e488e47b919da52c8984cca76010e2c9dda0314dd4598128d39839d1d4fe9a380d48e5093c2e12b795b73f7e3f69693dfaced0c3f7aaa34bac6ac93a97918d60a46e9143c8168c19b08c9f69994597fc8f240363f9f996c63ee1f7686a7bea58282dac5fb3d67de44ccd697afe71df2c06b1f6dee2f6059d2535964e0ecf74d1a896bfffb4e1efd85d3487a9e1b4c628a9c318ac2bc657fa1e38f66b76164b0e1dae42eed1f82d62e0a46c6ea4ace6be0137350ea7e39c7c10eb57aaa82ebc9f113c69da62adfe627c96409cff178568f1bf90fff7fd215a6ca2e70444e44d6fc6ad9b71ebf701b0ecc67f92798bf67625feafd306ae5352e974a45605edc3bb0d5c64c49f13a9f56b05d3cdc0f54f930fe799b888fa67e9e8e3f2b0f33ecab9d8077d7faca90b8139b0bd14f64c7d52088d3c3301763f74ad2d3373b457da737be358468d4aaf9555ed2c46899a09a12aaf0077d61c5ea1204d3104a880c9b9292a2817ad3369fcd4614c910ae6c0da4ebc84c1033544aead31c26233e5203a65e65bb582798f989d682c4a444d145a4a8e4cb8963cd57c732d2065692c87b15e224bcb5ab8d692157224eb8fdfafa730723fddc84d615647093dd120dc4e24de84a570642953d515d64925fe4245fa85a622bc9f8263a105e5d36abc140bd9b158347a9e59ea91a6b6779a6ace89492e22d5f95f469cfc8d14886c236538da54c4a21d9c653456db848fa92ecd2dfd9d15069d41d123f01943d83c6e8c9e812234c767404b148116173dc3a473222e2c85d74e3c7a6945afe99a845ac7d800cb988318bd95dfa74b6c7ff258bf16d9477a4636d5a6bc4c06d0b6f2ab8586d6100c4643e365c04d1aa3a1f2dd54f9ff198dc0e45590dffa489fb29834de13fb6b68a12c4e2fdf2b96cef574aacffa98b3c2fcd378ae796d4adeb198ad3c65aa680632618cb6be350a06a3ded1b898f4de38781f0bf7e57a66bc0f84aa285a2c8f6b84a4c5c51055680c79f1516c3ef2d217497e901a0ffc43f322887a450ab00f83a80dfe416cca99ff329b68852678a4e90da2de20eaefa28292dbfe29f014f7741568da141f8e73489c218d8e42d37b897b902b9388dec9214146fc21d0f43713483768fa4f920be7c0d2eddc137b1f464d0d55b4f35b2518b7706d83fb9c880b32371a89700c6612cadb5c4da563fe1c8839247d292156218fd3936138b55f7b9fc1b04e1a5a4d3cf633d7f2679aba457e6c2e986a4bd461ba0ed5efa635f733589b3134005aaf057d23a9199b80780e079b6028fa2b606b0bad9dd680df0415e9128b3cfcbaf162e670ab00e50b6b93abe274acf978e81e0f32383c7792125b04591b50de5332ee3c0d0161281bd1280e10fad696b243a8cf81afb623a88e309ce5fd1685ab8eb5ddc184865697d7e2351820e3fb3052f0be92149c8ae88fe219ff68784afad2483df6cab39dd599a751247d04e2360f3bbd33a11db94304aec2c2593d3467983bad63eea847723e1c720db2562c4a8bf73b0a4fc3e1f5a56357468ad07960f8a8ce7750681cc047762f598d2734a92d4a5a211f0ea07352f4489b2bd76ef36080cf78ee79af0ab9dff7c0d331358281e514586d3669c40e6380e99d0adf270c1a7b9e65768668f487a7d647209c48c122e6c2833973e730a128b117cbcbd42494de3d7c0fc87806cacab7f808d8da5ef407fda63088bf702d7eeebf0be66fe7d0425c05d41f11d384d56eb816cfc37c1c44ce559fcdfe9a9aab74e477cc04c6e6e4c89877c06a278e10be27da863d1b549cb33e1a777a812798a117a78c34600e3b24f5ade6cc993b6206a291240b4d9545189b49b7c55246db7221657493a58bb2f441fc0eceb75fabee51294d0dc468e1ab6652885878c5e7efd2c2bfc5f7b073c3e4931c579fb1e299646b11d744f260792220ce65ac519e6d226f3a61f5e10ce4d8fa9bdb3988f061f788143ca6296d3933949ebfdba84d790271f328339497282220df1ab0f6f764f4306ed69c471f79318916e261dc5b7d6874c372368fbce3508d36c959feb80bd847b9c746e35110bedc3f34c4a6dc6c5e6635ba22fb2819f645958db9877b392b20c4734d596c36c54aa6bf0791cbbd82d94c2b99fe6a9bdecc4637b3d1ef020fe985ff14bb11e9ea2a24f292700ef7e8517974947b546cca0f52f37a762332e08bcc46a2dcc8e8de45516af00f5c3589fcef25906e66a37f945c38c36ec418fbcaa10c997ece1176be3226667fa376154f08d7deb47f50ceab90369e51bb17dc860bad636e804aff9ee1d1b8578c50671927f57dd7d874f288ec34fdbb55b4536c02df5626ecef29e6c63a76212b44deb896b12be281a3991883c687950962fbf8a1c4f3a7aac89f54fd7e21ed60b9863c87072f57568efc9d4ac8dfd4be9b78bf8a78ff4ceef9628f57f11e124fff092df094683ace402ff10d89bba2f7908cf82235b0284978098ba726cffdeee2e9a604fe13a5c445ba60ca46cf6cf4a9ddff2c9aaea8d216dce296053fc5c2b1bc42c6b2af327f02617af68570ee0801cb8c433b4fdd86e33dfa9c94815a7b366650907760406ddcdfa2a7c89d1a6b1851666f686da26eeb291a5bed256c69d3562c73ae6a26ef6436a7faa7f88e7e8fb26767be81c45711d163bde470adf733ef8ab6f2f2b3643e64bd585fe7f51f9b1ba8a2375202f32033bd6cb3cfdba67bdc7ef3553929eacc17f6cd014b22e31f9ed33fb14dcb1396493887d6889c1d68a105c613c032d630eea77eeec88be59f78ad98af26a1e1cba442c2c6b175ce65f380aa3cd5541de1330b06a5ecbdb9dff282b358d06b2a16bcabda4016bebb09bca9b9aaad16407cae9595180a38a5064bed31ccfb9614fa767f06457d3e8ecbacf234d3be8dd78687719bf7d570edc5e83ecdee2719baa282d210eb1f369732056458b2c8f0ffcef7219a4d4f715ac9ff7328c3d28a1a3114f5c8b5fa136095ce13c9067798dddf8bf53950fb0852d6808771227dc7678d9e7349fe41e410899f20fde89bf99a863dbff75d944a93c995f358f663b4f2553381717b3112ccc48fcd8455d528ce6b4eb371a5109230585dc06bcef6f84c367f5652d9ecaf7b82bc82b1f9e6b7fbeb3c1336eb0bef5d04c99da70c0f9066dde2795f9ac95d7b2ee15fa82a403391a95f87c40b54dd3ffa6cee4b1a65cf7f38beffb09a027b659c9a1ca957245c84ef7f2121db5e61398914963ba786533ad1336a38159ade20fe0de2ff66cafb27161728f6780d88dfbcb0c65c95703a5d63ee8a7e9ee6a79598fbc5e2e906f1ff8952e222885f5571202ff0c65c2735aa75e9d9f35d404a98abcda7df7bcabda327de4b2f6368cf4c02d484b017b67794f02c98bd980764665be4775e5362b183f177696659c018f7e794f446e2a1a5232f52d6207a7a2943f24d0132bf06344c5647be6aae5878e306d8fa1c0a3d52400e58db1d0d271c1d847ba6d9a915e1aa99ea9c32311f9296ed138e1dcead2ae3315ddb8c913e5d87e1f3417867062732f6e5fde260ed2518a15d7521359faaee494a144448e590679b648dbb9132f0ad46a04df7c25bd978f2f93c35d9389684b868d8884e9cb9bcf0a220c5789ffc673aeee2994bd78186aa15e643608c12c28e8e1cab2f69aad9706d8363a6985a0834c843c932229d13e32c92ffd0fd4eef57e53ad27e4c0a950b643d19dbfce5c5d5de661f0d873e8e9ffa0a7048f885143e3738748343ffd18ace67b254177bbc061c92a513e9925781439554d5ef834364c037387483437f4f2971091caae4adced4be342aad5a352b3f7b1a0ee5fcd1c7e150f9bde7c0a17e1a3df7d7e0501dac38c2855ccb637c16acd88ffa3b062baaf97447c73c864357401bc2bb5ce4493dc20b9d797a4fac43ea99609cbe27ea43333eeaba1ad1051ed8e2fea5b5a3a1d8231e4048b36a9877a7fde6ab4800d6563a7186d262410456950b04150a7931ced71aae5636ff5afee4fb13634821d6d2b58da563f7df5cd59cd471d81e787618072fa085e41068516893f1ee5aec5d148a4d20c9b8222430b4af56352f6fbace3423b09fb8963929f3ccb27e2c83f3adf6e284d7aa92b397792a9f530ed4e2bd358f43ca6281ad8c4395d533af27c6f9759eacdf9e8155f83bd0dbfc66448737f87653ccaea4987d260f6bb9cf6b4038b1c17f02196ba547eb7d64ac64c0372ed61b84fbbb4a8acb405c35336ba6e016d2806a94b73d66d273c05cc698982bed75c025634da4006abb86b15fff6e0c809092b896c46165d457db7348943faa2c03310d2523d595192547b138d0f37eb86c74c0c259bf7645ba937daa9222edcbb9002f9d7bfab7e56b8f00cd0f4e97ff309ec5bfae885e3163fea688de14d1dbe7e582cfcbe7b12de6fd5d43019578e91314d02b96bb2403be29a03705f4ef28212e513e0ff917f37c0ff25ba55258e4283cad6c1678108fe7c71779eb6a2a4d96aa45be16b8e7d25c846b7a0eea78f48e71e0a5e3a8e2984b2dd1a43da53caf5a9b9c8afe98724af7e0690913e57f3c413ea4aadfdbe3a26517c6320db4118d22d0b828e08755ce5ac1a4905fd6d679183d452703b1be6ed95af0c45aff3dd2680e46161887c7f4e14af66aee9fcc5f606d7e41c0ce2fe427b805ecdc14edffe8cf28bbf59fa86ad31eaf92bf208a1f1fb0235f91a1800cf816b07353b6ff9e52e202757b9ad2475507eca4144f956adcdeb327d56e3e6daf8499da7b2c7067effde704ee986cbc1f14b8c37b6affbc7c808c968b054b4ccda5139b090d02d191a76ee70e89bba795b1ceb1fda67b5108ee09ba033e01b6b2702d8305e3f0b163191c14b5a056fdced7358bd5772c6905c5fe33b0483cfb0e984ae84dfb73f2ce89b1f62d89ab488dae981b0b32e9149e9fbe068ed05ed1d46142418ea85a4daa6c314ae5e54377021228f0249d9ba5798fa0c8cb27e6508ce3df61d57d54c817e909320fa7f5f1fcd539070446e0febf42d15cf91d5ede9bcfea8231e1759db996343555d9a4e7a7e44bf996fe4ea907d2771c3f7f154131e9bb2f098ab934a722704985321dd182d7f43c82d607c2a2d5e2141a5afc92e0975f98ca7df339dca0d07fa892832ffba720a0d5e23a45878586f0f16e864625f27967d16132e29b9fe1067dfe5652e11cc463eef6504e55d122d3134624a49c156a598101bf702d89d47525851dd434e47b54205ed3097954c931611b9f545bb892acea589dddba71d638382aea314fb66b187bc13e691d8d96218451218c7bd19e73849178f502c76a1c456069b10e60f702d7ee150ae7e4086eaf6eb04d6bf5923aa6e4b9fa5aa769e193ac4e2f47b3a3c93a86698de96ae22fb60fd67671482056d89fce6b3e2652d3193d5352325a4bb558388690ad3122af74af0aef39afe62a193f994f85d3253ff7c00e43682b8bdac239e9eff62b21c373555964a824ab7f9b9f41af1c6115bd069e60721879bb55c57dd426ad095bbf8f550e2a92b94fea407fe5b6ae690003e9fd576ede1d0cc3feebb33c82d6bcdf8f7b3b2818ea28f61635f3ffad8a24d1756aef0ef6b6688528a745e075c8d2643ca12d805196555f59448b22fbc382341504dc6fac5e36498dc17b44decfce665ab3bc58c4c5c1a85aed150a3c1da2e98a7b5481340fe75842b6b68146a2f9e608e6cee3abcfec80a0ecb3e629623982d75e4f9e0acee0dab48f7dc762042c2c63ce91131f42648e66417482bb9c36f97cd7a078cbe5bfe1e11b1efe3ccd975ef40fc6c2a493aba47b3c488d7338caef1f1bf223d7fcd214ef1f644116a5cb3c8057ac704c477c090e6ef26223ab9d25361f6451e41f2a29ca71cb4c606553ade428af6d7a83c1376170fc9e1621f0760d04b42a277354c03a44d4fc79aada601589d49cc46abb4d206fa1ee5f0182c6f4fd5a80d5ee525f1f5dcf780d1847374c94c1e059564609a9adbc80823f87d167d52c96a7840bb76320ac0e026b2b11d8d4d6b521d71e6235df8b651e084180d55060698133d5d7be68202faaac63bcf65473e5910c7133d13a3e7222c2bd2d7a02a97529baaa998001cd207784f64a230468b82d5afbb646e2d60025450b2186a3192c2aedcf47d7e2dd01cbe0bdd85c8c07ca020a1e73c63683d124fcde335f03673ac9eaf11eac4d50acbf4bc74d62143b2c9987f64f38b629e779ea0455ccd164c3209819020acf70bb35b4daa41d54b792a6ca1b6049855ac0185ef93b606b4528cace12a91d4bfaeddac60e263cefc59b8c5d01c316d76aa4f552434f451dc7ee235f684b9740ceee800f3d75b204429b03b61f8e070a81aec5b5354dfdb5c026a08c9e2741debe1190dad51d10c28e89a1760823525397dc69f66c42cc126a7be15aed5d37522cc7dace01a9658c428f64fcb713309c055e475f838ef9461d9f5b0c69a7ae254d7fa8843b7b9af189ab7d525f1b8aca12ef0583afe93d4ce1f7ca134c0c77ebce5bdd9a606845ef56c57af42d29746272468bedc8b9f42d69ee08748c5ac79ffb6a40f7ba63206f0af0fd0b1869e1c4b58df43d02b0f53988735e7e283881f9bc1d6a2a7eae9ffe86db927a5bae2aeffc16657af09246d59978832a4270dad7414deddfee80676d7a0593c3be3c2cd68725e757ef93dab7889953fab80f3c3ee455ee01e18637bd78fb9e5abee4ae756d3381ad837d88c8b96b9b8361c11c32e28defda33e9938c2bdf8b6cfda38ab55a3ab6a1e0be4c5b5fbcc764e3d826e7b6c81d3d30dd68b4363a9111785fa9a9905746093f1c71cda0879fa5b233db7f8ff1c37723ed704da7fdb52b98c56094a8676d175896309324fe3ee5f22f9577163e5720862a5a115610618960b4c9ea7650b9ae234d952392b448c831db9ca6869cdf5176dfa2e6daa135e6575e6c4e5cb5cd11befe814cbf1f423807d3deda57e59fc06aec7d9f59bd888e3e87d3fed013e4f79e898d17a395dfe2779ed05cfab6be289e89117dff2eff56483b286c512acfe979c9e7cc8842b1cc62a49d4d564b027f5f0bdf54c6dce10c94896b8118d8d49ce80b665490e32bad4dbfad2eadfb8ec0d45c682a8ad9beac40c65292e912a26bf7679a8aef1040ccb4f386d7977e63da0baa1fb557e99cf67ea3ac2e34b805bf8f7ec38bc4a3fb63acda17c1c07bf8ae7adb8e206faae4e45004c89bea73a01e92a10e4505c1097ad63ac61b1415d48d94114c3253b5a4a93c0f3bfd39d605d2365eb2a17a80fa8cefc7c6b1f5d0df1f0321616dbfb92d85fdad2c1bc9b9b575e488fd9e63f9a84b826c6af591916bf717e97bc91cb2f3c0ce5307eb3d280196c111bd694aeabd176ba5dbc0dae26f032a9ea7926e34cddf312275dda5080afdbaeff835c604f27a17d2daa73ac73433c1daafc1f78eb1c1f2c213fb125447b2168335fe4ef882390742c87d7bf336af2dedbf0949a96dd07a159629ff186ed69ea884f0adb12aeb7f7ce8f17f719e0599c9f633c8f7939e735a17bf683627f72ef4e251006359a46be4a77705cb49a367be2ec977436defb4afdb9d47ee9ac18dad2dfa3ed06328601dcc47aee5cffcaf33f1f5eb53f49d0438993b60eb2b66b66d7645b266ffbda78ba4416f3b470811b44cc3b58d1dd669fa537d0d4d338175b5f9a9f9bd58fb9cae05659662efa3ee4368a19d2710862916e0467535fc4da332afb026a2f1e6aae6120c94653a9654be117d8d9aa3cdd1642bff186099a62c4890de400981da0b8085682da6963ef33bfd8d976884fc588be977422bcfbf54e73ecd6f01cf79cd185657e5e8f7c0999ad3822b94b935427c76a9599c7c43e5c4b5e7459dbc70e6f5eff81b45e67ad07783ccfb5ba414e75d3b87820c41a0dd5ff784f602aa7ae808cbcbe640f73101567feec558e74dbf0d042f448e65fc3cd8bbc21d4ad9c79cacff45c53c0ef782050ad2bf21837704038fa966dcd9776ae75bc61bb08d5d610e17c914edf0ce44651981fbc2f808acbb0ce367ee184e5a17e4cc478eb5f4bd28e58ce16f16328643befece1eb887e8b7729d9d3d159fbd80e122e2024a7ccb6064e3fbba761a480cd650ddae7d7abf19d66c10ddc52be0f4925ef136ab98c7617da091d80fbd697f48eb0ce935eb4a9f2b9e5de27a67ae2f9fe12156cb8a736c9dcbf5eda2dc61fd52fd1463bbc4cf6b1cddd3a05cdad70f9babdf07559ee2b30138540ac81ea67f2767a0b1ea56c8a1c2d99f02abafefe56916bf0dd919c23a1cec4cce1acf70d41ed68fa9fcbde946fbdfc8fdf3ef23f05cf74e73c26c40e9fd8d7d6bbb180fca7de89bfff311c1b26816cc56a7e839689b7705cb728f82f8288a5f78516cf2f283245de41cfc9b30c5f11c2f664546d3895647a7d535bd39076fcec1dfc21f806ffac77b0767abeb9071349ae744c91e154227a26479516c5c918ca371617da34b82647f273174f30efe53a4c129f7a0cca7f4191f101d8bd5bbb56ff732532f144dee135d84b8ef0060783f387013e2df8ef2c85595661ee2b91f98e6ebc7c1a050c5381a81a93603dc9e46af51f71d3537a337406a1cf9a16b35160513254f4d0b39ad055383a3828a4de6552c458b2181a9caaff4b7fe31c846c77960eea8850ec4b48df7f4db5efffb6a396e732aa28fba53f1793c091b877b902080992a8e9fff90bcb49f44b21dfbca9116bf40cdfe9bf0e0fd4edfb79b9a7dfbb0befbc34aeef9072bd9b88f6ba8d8f7bcfc092af6fdf5546c32e0bfa06237888a2dfefe22e8a662ff3324c111055bd4d7b08ed34e64f14d5fb7591cd5f7e8a9e989669429925f1b8125808563f93b9bfa0f1228c8a714e8cc3e99c65af5b8ad4eec9bc5f19c224fe6f810c6c4d7c5fcd8ed0d23af28c671cc1d123394fa4db652a9b2469e1216d058076ad3f762799d828e626ad27e5a91538ec7407b7176596c1db3bf9f1743562cd85991525545c49173c1f152d762e94596b1f06d8303b6f642c65a28a49a29f1032574044aa291a6b6393640740c345ec7b1b63bea2f780e06c8f83e8c94d8b5b6a57164efb3da6f240567dacbfb6bf16b4d9defa0d0a0e310e415c47bd162fbf6bce49dd84c606c72c07e5d0fa9ef64e65a80d3d46c0ed47f35a03e00d72aaf83236c794fec231a0b29ad806570595c61e94cd118065735175e4b9ad413c218249e90b663e0a9144ff821b6f2c5f8e73af2c6aee7cd56d313aafc5edb2caf9be73e2db3e68aa47b64d8b7d49a9b5a7ffb981ff998efddf90f56f0cbbd5d25d946e43fa13ea62c5c31d9868cf8c6b77753f6ff7ef2e198da9fa9c64aaafed5d453c9d42dc732de08e7588ba8f9d9df7bd9dfcfa5b84ed5db0da365de146b872c8a8525b15a9e73cba5631e05d9583ab40e4ba67e8e32f5f33c08c1a7ec01e4ff33f5ce4b88ed38adb1bf60d4d38b2cfdc6d251b7552826496afd67bc7ad9da686a3a9efeae1b29204f89692f3ca11978b1993342ecabdc19ff5ec5bc5b8d23f3c6d04ccec275a168725ec7e4baf1597e8cba3487b56ff737c4f64e42d68bfe03b026451d5b2c445945a41023a4690b1ba8b625166258b12ebd95f66ccca020e3f527e188dfa2a7c89d1a6b18690bada54bd0da44ddd65334b6da4bd8d2a6ad58a62185bfa2ef936bcec2a6e2f25ef663b400a3f6029f27d041ed313ef79dba30bae32154ce6158378163e44cc5e6643c50107d3f86a73ddc7e018534fda8e02711c01caaa3602c2e56647ca612fa6a28ff1814f906cd866b1b9c973402d33648fa0224a1da7ee232be474d950560eba217a38c5312e0f7e1fb5d487ba07fe30b63a161e02c8c31dd87702fbcbd34f65ab923f04b2834329f126581e87f83627f88e16caf947266a878bd2e65a7a886ccfb7716ff7d3b616c2a113e77b8ff122389506a73046e93fdb9e0cc496bff19e0714d723eccf3ce571a265c714768c830e1c7a4ef2e86ed57ae094b651a8c7a348c73829e295305996f8cf70c1cfb86eceda54b8bc1ae1c6b9b861ed23d2aca7181a47c25306e2ff270428585539fdf1729f21ba3093e2b4533154dfd68d3142f518f5cab3f012c5d90b08b880acad2cd6c625a9a7b49e57a96e59798879c17fba6e19178ede40d20a90b680da7bc4c6419496fbcf45b989e9562d860f9cc8d08b34a9deff5e0db446447cac652e987dd7fa663847eccc29629a7ea1caa66cfb1fbb33484f3f8d8d18a7ec7aa64eb769d9afdca858fabe642df73205f0fbfbf648e5095d354ab6288f8d76a199c8fe31b4dc73a7aee5c4bda101f7f857c1ae6fd5273557d1831f92e974c55e5145b268f6bbe035c9a9e4bbe931bbc1f748fc8bfe9bcb00cb47574e45b7ad0a72fa0052cc940fc5d3e7d17b335498b3e8f8adf172993cb35f25ba745b089fc2eec6de91bb5fffd6485b38b6b72d9b7b18fe5c01e9352e93ba922eefb0573f7440539028ac7a3c2b7f0f99d67bc900e92bdf7700d8adfe5b7b448f8e1b9f76dc6c84452c9a08a7ea621da793ad67300541483d864cc5107f7e84f6a96adc4206b68f1eb422accd2b70d6e94ad079119977ed78a73a345d6d9fb5ccb2c7dcfa89ce779afd0664c74123a079a4ad216523de71c9de08cb9b2f457323795d678ec5514bbbf38dd8edc5d5a949ee8c887e9c9b19c40abcdd1f0707fe65a06bbfb58568f8ae9c87bf863fffc34829e10aea1488adf2750e0eeb5968ee0d421fa7341a7de7831f9a671ae65eeb468136871c9fcbff40413bf9bd3cef96ed394dcb51f9b892fea7352b0ffddebf6b4ec5a253951b95e8e802212cf53badfcf7532770e2265eeb72ae5c6d9180e1c7ce3cec172b529ebec5ce4efd354d24f297e09d8fd1d9d97b9f3557959718f0feec33eb5c31967bf942ec574bdd011fb733f1eb179b3f3fb2cadfdb681fc9aef207b47b52e9264f883d550cd52d8e7a42c13beef82c9755b0a3e9f4bf2ded82329a41e4dc5c0f719513c4ee90bf4cdece35d407f7a3fc727ab2eb1367f31acab41e2079a173980fe2654e3e5400936d173622af2a637ffcfcdfff3dbd977d9c5ff5c3710edf41ade20a1c99d55e9f4a88c3a19f9754d0a723ae2cfc9aef8b562eae60dfa874a8b8b9d42cc59f3610918a99325aa5586591cd1e724651462af2a814fbd5187cde3e31336126fda3a39ce942be6c0b03c234e0162cc2918e43068270a72e3a5d59be8ad4939962ee592f255794d8c3b29c75a9d31b282970626fb7c68a3a0159398b33951aee3f65b36ee942bce5636f080eb88249fac5ac19c38d4a06dee0ad4e512e50f9379bf430c4199c28fc1054c72275105602919ad7c554e286df953d01d6000e0042f392fcdfc5ba40c499b2a8352a48430a2cf3020187a044480b917cb2b689135121c5b9f936415fbf5456b3d2d599cdcbdd6363828ea154e41b43a8cc323e3fbe95b3af26209f9aab9ebda062964e57f9d0523b1bff6e2c3b9ba5623b0466d634829a3c3bd38bc609402f15648e9c3453302b6be02945b6c480a72d94507013b93841f4ca67c7f83099d574749082fcfb43f07f6ebc9f9791d7deda966e2ab08a5c655ca2d48f68ef0408e6d654ef82c3a9322a7d18b6383b06beb08aa6dc67b61beb9aab4a68948e6ae5044ed8c7b5c2ca45669744a7fdf11de3b95f28cc024e5882ac5984e0f8ab1a927ef31e776f4b56ff9337aaea9a3c3b10cceb50122eb2af01bffa9104b9ac7bdee19a5da1ce8cd5eb4dcb15d8aa72c19738943bb6004aa3b87e533b14bcf043bf3e9dd2b7216560414e4e3293a9a5dfcee4bc6ab82b5171b732726fc89074ec913069adc696a6df15a4dc6bd33d774b067387ac71a1fc8211aebfae6db060705eed0801f5c323662b859160c37723792b33175adf69b23f696fbc61b62b43bf3ae30431ce16af98bc629f28e0a83d437faf78c5bb2d2a17fc4e094ea31ccd85a1ee35f1cf3e1b77bdf7058558ee4afcd232b90480cf2cfd2da7f66bfd596d038e08812696992eaeff77ee9858c8fa9de999d9df92ac3f819732af2aeb07799932c2953003c54b752297fa0ca007f502221ff2e797befaa7356778f189fd3339f3a6b60dc5e9ee198e20e39caa4907072d1f7149d8b64ecc71c88356398016bbba9e99ffc5674109092188343e79736f1e75826b19c851ad9d50880d5deb91696b588e93e60ce126fe91d0e4eee37eb5b22dff7d41971d2b9c5531ebe94fb78df115bd0f7f6d6d5af71da3203f3d759bd413ec320a913baecac39eaa03dea98cd1d30f8bd656743e91b4af9391917e57b1c51df2e38d37bf3586532a346b60cf778e7aac753decb63f2f14595e9d98ddb8b97e1ec234a96eca1637f8cc6a70cedaccdbb0ced8dc7c6fd23cf7f91c46693171a8d8bf2a71bbfb086c90586f6e6fd43de349b68a505abb6e9cdd07e33b4ff76a63376f13fd7d04e3bbd4aad4f493acbd07e54461d37b4f3cdabb218d1117f90a1fdb712533743fb3f545a5c6a684fb31e3eccd09e662bd41ada816a2ec0a719daf32c8f0b0dede93c3ec7d08e1484c1018cb1d28ec1cea971375e4e1acf53253e2f545209b25af1bef1de9f43751378627fedb514118afa4f46144b12b75d95d63e24b52cb30af88dac10c8197bfed14557f28c99ea399f321466cf93ba9bada7adb133de5eadf6e4db80935e77faa43bec6d5ebf7a4bc71a6d40c471407d160dd5e1c057fdcd117a67ae054b12b7ae12853707159177b4104a759dceeaa8fafe3a3f7bb5402ebb1bcc2087c1e31b181c26ba571a886a8d544fcbae85261546390c80df5c4b5f8c07f9de1c897e3f62d8cae45f6a14c8a250fbd9be9c8a7add8fe83e04d53de2f8a2b578fdfcbf45e7608d8fed45b5d1e848846fb62f94758c127c67731e11e3dd1ac660eec53caa2bc252574f9445a9bdb92ac9a021063b7c27d3f35c2da78a44e19506c042769b9116a909d368b92c3adb3227dd48698f55c41159d431e650a5b2f28cbd4e8d983c8cdb1154cd11e4d86f358606b348209def15dacfda29eeb95ffd4c7576c649d950cca048c75a24462f46501ecaf4f43da075401abdfa1452893ffdf1c2fb19c193a60ed6aaded8213d5c9d5682a66f577332e33fdf0ab6de8c1d3763c787c31776f53fdbdc41bbbd8ac1836b5ec833c1933bd9b88c67a2d2e0f13e9e093ae2cfe19960733d4754e54d6f068f9bc4b8f4ea9e367964640a1f56ff35efa3de1f79308e8f357d203007b697aad0533f4df08df03bfaa14be26be4b896a7edfc792ca020edc1ba6a08ab4db66b187bc1becacd1263d3f8a5a81cbf34b75ccb14c9ef319803d14cd2383d102304d5fe8e9926385735e75ea4088eb5e581fdcade5b3dbf6e307b19a9ed5dbad75ac42d5dab1731f8497d9f79725e1a135669426149992c46613b77593d283f46c84f1a2f2d44e0df9b836114f91b3b5f8c3483d4f952cdb9af8624f9c74b949711277f23754adb48198e3679fddaf3f6e4a34d2c02dd93e74292e36be53a17f9f30a042cd464f1956b38c327010c9d8631e0e36f5f35b13bec714efcba74de94d048b8c4182a91b30b43271ef1af7139766b6cf18bf3d7e53735b774c83d2590503f3987c37a49fd7c4da797924d94212b40be6acc6ae3740429762d9f4f0908eaa1efd1f71048fb391014458b530581708bcf4f686bfc2dcb01dd12da6ed0f39fa148926bffb9b01377791dc8f9d0f88464b66bfad8c9886fc96c37c8f937951497c24dc2e157a23aaff212139e3315a565c1b12ab56465d07916e298ab6b415e4e9c7219d67aad17ae6d7c565da1b947f90c0ed45a2f396b7c1f0d1b5f715f9ada5ec04ad8d6df610868522f62067532ef77475ffb319a50aeb8700e842080aa29006b934238acda87a46de51a60d857e77527903501839c3f1058bdc0994ef01c63c736178c6b30d43a7da25a775b4a84214f91d7d189472f40453b4fdd86638b94c6df69cff3e1906b104e3c9a7675dc334fcfd321057d75683ffbdd7e0da0e004ae2a8b14c2a4fc96a3c259f10e68ec695f74cd068c52deb5a49dafb657843ebf63d2d2cff44e4c800542dfda72156976450ffe4fc7023f9d8142ce16a5b6a767d3b1b68b2a6a7b2f49eb47a530bb9dddc39c7f92864c57d1e0d3793c2d61a2fc8f27c827a03995075575a8f078ff1a643b76078b9ed772ad2a722f2ee47663e7a4983ab1c2efefc7320fe33a3e3752f7ea30154495d635fd07be6032fe3bb37c86b8739f697c4218f7cff162bcfc97f773ec8fa7cbc8a59adb917a5807cd2f049de2bf787ec80b8fc2c3a3247ce1a4876693939a0f1781ce5f581ceb5eba7f1032d0c9e1c1cb8d2a1f42b9653acd2a17426dcb1be2bc21cedf4e8f3c14009f0b3f0ffabf0acd7e83e74fba3f4f89ade3ee4f896f48154929efa6d92723be088b96245743683679b929ffeea2eb8644fff912e442583ad59127985c6f2ffbfaa3602aa39cdfcff6ae0d0aa7edfb7b9993c7a9feabc63b226d7b1740457d006c03f9359ebd6b8c1faaf20a7067c1f0570c89f73318d30cd40ca206656fdce8fdf4feb5f01708e68a52429320ea15b0bdc053db3b4ff4d75edc3be1599d2b80d218563222b82ac9288d8065aeb40e3d975d0c0ba7933d261669473ca09dfe1a0a39ab4ce6a1eccdf7b372098daba6ea282b9360f5f6bd9afb73b931bcdc185e3e82e1252172e5b93cae4ff2ceef7cb59d10534b54603d5211be778c7a94de8bb434c8de9e9e4a90a0736bf1e5f3ba218c24ecb7aa8c79ed18d56f7aefe6c414768a19e61d95026bbe49ef4df208ba56333883bda4e61c5c231aa136616284ef996f4973cf3691f68c9e4f309a64a53f2835f35eb20293d1e9b9dba364ae3519d57c13531aeab5171b552c2e05d68de5dc6b1dd084d3a4830245727a86ff124d768d7e5451eae32b630cb94ad90bfade1e937ba91c23f2a6b89f659694b4e2654dc2c565e770bf5403eebbbf57561e9d4c38a0092a52082d53fe31d00a2c2e070908f8dbc8b92d45efb79ea2b1b8580d467dfc4c7dd24ecddea42c12f80e159923f208b87c7df27550f4fed7d9a57a5c9a2c3407adcbd84f06a32a8610dd7655c2c691ead5272385bed7bb548eedeb04583a4ff6b7f40d2833a10c6399c37a7e5d42d02fa0bc7ed73928d178b74e32e58c8a4c399730a6f4aa19bed2f9df5f69fcc7ce995638679730d3a825269ac37256b44cd0f9e537de3dd72cb1cb64fa7f29e92e1bafe2318620ad63f0f97fe7e52fce286d56398f3313eaceb95b6f8e25bd016bbb00569f62c976b1f41bf996ce58f9a519140dfc2dc06b4def4671fce79540b8f47b9b26bfb1b9d0ef53f13b5bfa06a5dffa8bd73293fd978eafe852a2636c5726baedb32aa57a663d13d01e43d7a567b59444c9daf82a5a81bd9243259d85ce912629fe8535fc0817d6d25dae4e38aa589b7785440a8fdcfd23277c917991bb1739ee32eaa12b1679fec890c807fe5ec84393d844abe38dea9ade1c543707d56f605ea637fda3dd50a497abe7da1d097c3c2a854e043e361b550c68ef0f7cbc34d76e2ff0b141021fc5df5f10dddc4dff147970d4a9c439769f4f9d1a8c3928afd129f643bf63eeb4f632f4627f6733f6105f6d73be9d3a9ab002ac7387317f99924753bd180061cf92583312cba51abc37d5b142b5181307943929d012a7c69dd2386b9c2f2583a949e3f9b2fe88322ae60627dc3fa3297df36d9dd49b2b188b3385ce4b1a2f597db23cb52755eed9b82ae206ed576614798a320366ba9e914294c6d438ea24c5fe188d7d4bcf8cb5e91c0a8aaeaf913847663cdeaf9b57001dded45ce5ef7a6a66e31b52f68f7c6f154840be68f85a54882f6463ae307257a78fd5ed73614f4b465df67e12e357bfb6c488c2f6a64b6203cb14db69db9fecb7a3e3d9a7a7654e191237583536adc5af99f3a5625dd21abaed0488afc598c09f3096459819acccc3dab3a2b9720569ed17cb130ca8012da3271eed81b0acdf9335ba4fd7ea53fb734f54168e3da95a73098a6652dcb76ea47c755579ed09a3004cf5351cce022d26ebc26a5df30b52976f8a42686da2bdbb5baad7e6c5e6d6b7cc1d015f3c6bc3c971366fbb041407c06ef3c03652a69883b301627901555964bf67634ea96b539945012089615cc1581ed2bf1bc8e3da0930cd1dad639b5387c3f2dd0ca9b30cef79caeaa523da277eb6b7d2daa4062206b12507ad6b3548daaeaf9a0dbfb5b9e05e6a1fc5eeb209676e1c1dd7dc589bcbc1a33ce41b8ffcc3a3d8f8d29038596c34efcfa572111b0db9715f91aef2fb81c7874643901a69d36ca2553a5b7dd31b78bc81c75faf2cb29bfec1e091f6720df078cf09c7b1230d54bc7f6c708f8de697fb87fba6f82070f2d9d89148a18a00ebf7624732e04ba063936b36e45460880f4df141e684ca3045dcb2990b2c36d3ca38c5daa637e478130627ae691139fa58f35eba1fc7392b62cd085a13e2d6f58570ed58fcfc73485694c4a561060c99d2f0342f264537aac6f3d1596f3d2f46b4a01343416c2c04cd3037591145a75590994b9666ade13dc8e7ab6cc83b3b6c5fb0f66aebac804e7be709f29bcbc2b5986b3fef7b0f31638d1a60d4aea255217c2addbfcf2986d539ba67c5d0a7745c1992cbf7b2103631edaf5dc15c0dd4f66e18cb26d6ce49a114b3e806a46d3435a4dc9664acacddc0bbbac63e8b637cd98f9673a66d2ed6d60571c8c98f22f7283d7cb9e765acff9e4dbc485d3d7f8772ce0dee41b8971eb2a6e9442bbe93479adeb4f59bb6fe8b3fd0f4967fa4a64e7ab88a8be7e12c0fcf5fa3b690ae58a7990cf8a31c3c37668b9b9a7e5d297044451788bab486515eefcfb10d8ed6f2d3fdda4854a1bdf35914a719b7173e8bfef4d56640fed6411b60f33231eee67d948cbb85c8daa16303348acdd88bcd9ddba62a93a9ca5f19f758291aa8380e56a32c011648806dcc68b4befc1358128b1467dc81bbebd7f89a4d7f44c129558bb4f97ca2b1aadcc9df4ed5facd64dd4dd5ba09d9770a5972cb3f54d5c23d5c25755b143f41d512aea76a9101df54ad9baaf5f7900227542dac8a101f777b9253ba123f75a5dfbfc0ddf3e6aae69b9b9072e28c92d54b1310d2d2e2c45295d23e77e3eddab172fe212f36435011045ee215eae8c8b1b2ea2b534d25a5bd8fbf576d275e4ddc4261fc1bc7d6773479918cbdfcce2949f8cbde092dfcce3084a7c6abf2a13735668eb5c9c69ca99c74ad496243bed67ee2da7d54a1deb20a31a362e9db6cacd7571da7636f199db6d465ed3287d6fda7a99057e4aabdbfbfa9903715f2f6f138f6f1486ffac7aa91ac976ba892822c9fe35b971ec5fb47f1e14b537a10c4a6289cef5b2752e88a84b464c0179540b997735552e01a822873e27da5731d37cd3c01d9542b9debb54d6faae44d1a9cb8a7fbeaa4841c9156d0cf54a758e686ccd93ab0a443b54c90d67e4b5940c19f028b54fd5f696d9d87511e824c792e1a1155b1dabcaf8634974d68a7c521b16ab402ac705f1ede2aadfde7ed1a083e02cf68351cb58715aa16b1dc151dc2a49f675e1925fc70c435af379e29c9259c43416a8f3bcadc8bcd49c57876c03676945bc16c782a4a6888e64563b8be23373b029371e2a1993bf9f7b96a63d50397d34e9e2a5f75527ffc85b493ef2fb3f76b6b57ddf4c7db17e3af7e31aa6effe7e894153d5f43cf9438e9136aeddd5f8f6c920cf8566aefa667febda5c6f9baa7b7e7b9ad48e3a1bf93341ed6862f06c9e908109e859070c4388c3708eb5af47d153ade347b6604852582d37dde86b49fac1de1b9c969c5db6f8e60922a70ecf9201fa739c9cd88f93c9967f91bb0cc49fede60afe836d521c72363062ce36785be9952bc8bae4accb7d4b44b69e9e9582205117d753ab9d73acb872ed291631b6b382d78d42f1d571aac681b435f450bd8062154d1a4685a35c97b1a2410d7c3ef5637811fb7172ed6879f996e6c53de3fe2e557d1128cb6084cfbf28fa3b8809f133d3cf65b5090394fec278ead98a3c9b6b82e51fedb53609afa2be14952d3673d1a005b41eb7fc8f771f554a889fb63e29e50bb4993cfe777977e2183c68ddffda665ffe77c2fe90dff40659a74701dd20c6691fd5886f64a3fff7b0b54e311df18da6f3af3df40061c538da97ad29d52f58a314964e659d79204c7dacec133c9d8f7f7727874c89eab54735492a7b2d298ea46ff6d621589a7d580da9c6b1bf1785091ed4e0221fb7392d7347dbd6f05b3406b7129f5754468b9edbe48a8b9bf3e531adeafaf89a61a33c7d64347ec236f9a524cd3fea0202dc6d44bbea315b7e45853b76b5f30f173a1278c16a462951a86706a2e81adcf1d12c9d04e1ccbe080adb302ce4fd3eec02bbd1bcfd99b66794521a1c3ee2833c7d291afa2b7d2b8ca734130ae7a4ee2a16526aef51a384218524a4c33c92a38d5ec1bcdd3c9826317c092a6be1a1e9ad5b9dafdba748d496404ab38b5a2ea779f15f0cec6314fcfc94830432f36662c08f7526adaec3d5ac7408ead136a6c4a794a683c375e2c0baed5470755bd62b480aa39752cc26642c690d27832757c08ac76e208a1fc63a02d2ade4f29db3b069edb0e4c19bb840ad6909c210287f0d99ab88c12fe5b302b9d1127a6b96daf03c294b26474e0179ed7e3e7b34bcfe6426bf93ff44409f1d9d293d1f4e0dcc40781d42b28f6555299ea5997065645844fd599e9f8735f0d087d6c91aa525389db26ab8ed5424b56fd4c2274e0fb2e20569dab35a6cc20e7f5bd07a32eed73149b21e8a077f685a11ee92f01567b321e2812b07bd78abc592cdd65e41d57a5589b5c85da0770d2c319c647b929cbb27c2e806b3438b159e5e3e6ef9bb2f82e35eab33c256ca2e7981ef3a6370c77c370bf467f63b7fb03c01b7df39f681644271cb3b4492a601a8d4f1330d5aed8770998467d4de79b80b90998ff7401c3c4c0078b993f178bd9bf7e8efde8e7d85bfe6bee06e32fe1f294a9a8e6994c1c89a76bfa9d1244a7dcac4de98a6e5632e0bfe0666d12376b6538dfef258a6e26a3bfbf44a8bbb1b9e5e87babfd3ce48c91652a6d4d0d39686dfebb15cc9aae6a86e06b0323d92654d1ca4d3042dac8dad4e0c6d6963a36ed5ea4a961022c47d6e290f33bcaee5bd45cfb96b47105926abbec72cac6b1fb1c29c0156fa5aea8847ea78fbc588a61073d19ad86f8da6a24e5bf4f568e68ecb437dabfaf220eaaa3ffd66da7d915fb735fdda2efc1acd91542e4583d325e279627e3216d0f542468aab1706c63f77da06f40c4bf752d73e975fa52d726792f88bd3bd0be6e27aeed048eb00d3df155d6fe7fe539e5fa84fb9644851b96a778649780cfb4740f4b8b30f22b4bca0bca49ca0bcc0c008ffc3882b04522a867efee56955c65901995eb56e5e91e95e1135e92931aec84d5de0843cb824823cb52cf4ca78ce4dc9c0c9ff08c8228f7a09ca42c83cc140f2fc3a8604fed0067cb02143b5c5c31dc070d93f464f7c892a460c3e2a84a4f48f818a55720eb25262c220c2d33938c824c3db34c7252b2cacb407a606604385b82c247db3913899d555e060d6f82139e90a22775b41934da0cc25fe8d502000000ffff010000ffffc709cddfc56f0200`))) diff --git a/docs/commands/rhoas_login.adoc b/docs/commands/rhoas_login.adoc index 4a701f1919..963bef5bee 100644 --- a/docs/commands/rhoas_login.adoc +++ b/docs/commands/rhoas_login.adoc @@ -36,6 +36,7 @@ $ rhoas login --print-sso-url --mas-auth-url string The URL of the MAS-SSO Authentication server. (default "https://keycloak-edge-redhat-rhoam-user-sso.apps.mas-sso-stage.1gzl.s1.devshift.org/auth/realms/mas-sso-staging") --print-sso-url Prints the console login URL, which you can use to log in to RHOAS from a different web browser. This is useful if you need to log in with different credentials than the credentials you used in your default web browser. --scope stringArray Override the default OpenID scope. To specify multiple scopes, use a separate --scope for each scope. (default [openid]) + -t, --token string Allows you to log in using an offline token, which can be obtained at https://cloud.redhat.com/openshift/token. .... === Options inherited from parent commands diff --git a/locales/cmd/login/active.en.toml b/locales/cmd/login/active.en.toml index 6030c760b1..41ad9f98dc 100644 --- a/locales/cmd/login/active.en.toml +++ b/locales/cmd/login/active.en.toml @@ -44,6 +44,9 @@ one = "The URL of the SSO Authentication server." description = 'Description for the --auth-url flag' one = "The URL of the MAS-SSO Authentication server." +[login.flag.token] +one = "Allows you to log in using an offline token, which can be obtained at https://cloud.redhat.com/openshift/token." + [login.flag.printSsoUrl] description = 'Description for the --print-sso-url' one = "Prints the console login URL, which you can use to log in to RHOAS from a different web browser. This is useful if you need to log in with different credentials than the credentials you used in your default web browser." @@ -80,6 +83,10 @@ one = 'Redirected to callback URL: {{.URL}}' description = 'Log in success message' one = 'You are now logged in as "{{.Username}}"' +[login.log.info.loginSuccessNoUsername] +description = 'Log in success message' +one = 'You are now logged in' + [login.log.info.openSSOUrl] description = 'Info message for opening auth URL instructions' one = 'Open the following URL in your browser to log in:' diff --git a/locales/cmd/whoami/active.en.toml b/locales/cmd/whoami/active.en.toml index 9b07c4b4f6..339445faeb 100644 --- a/locales/cmd/whoami/active.en.toml +++ b/locales/cmd/whoami/active.en.toml @@ -19,4 +19,7 @@ description = 'Examples of how to use the command' one = ''' # print current username $ rhoas whoami -''' \ No newline at end of file +''' + +[whoami.log.info.tokenHasNoUsername] +one = 'Token has no username' \ No newline at end of file diff --git a/pkg/cmd/login/login.go b/pkg/cmd/login/login.go index fa0d2a9692..f8c005f6e4 100644 --- a/pkg/cmd/login/login.go +++ b/pkg/cmd/login/login.go @@ -8,7 +8,6 @@ import ( "fmt" "net/http" "net/url" - "os" "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/auth/login" "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/auth/token" @@ -25,11 +24,12 @@ import ( ) const ( - devURL = "http://localhost:8000" - productionURL = "https://api.openshift.com" - stagingURL = "https://api.stage.openshift.com" - integrationURL = "https://api-integration.6943.hive-integration.openshiftapps.com" - defaultClientID = "rhoas-cli-prod" + devURL = "http://localhost:8000" + productionURL = "https://api.openshift.com" + stagingURL = "https://api.stage.openshift.com" + integrationURL = "https://api-integration.6943.hive-integration.openshiftapps.com" + defaultClientID = "rhoas-cli-prod" + defaultOfflineTokenClientID = "cloud-services" ) // When the value of the `--url` option is one of the keys of this map it will be replaced by the @@ -48,9 +48,10 @@ var urlAliases = map[string]string{ } type Options struct { - Config config.IConfig - Logger func() (logging.Logger, error) - IO *iostreams.IOStreams + Config config.IConfig + Logger func() (logging.Logger, error) + Connection factory.ConnectionFunc + IO *iostreams.IOStreams url string authURL string @@ -59,14 +60,16 @@ type Options struct { scopes []string insecureSkipTLSVerify bool printURL bool + offlineToken string } // NewLoginCmd gets the command that's log the user in func NewLoginCmd(f *factory.Factory) *cobra.Command { opts := &Options{ - Config: f.Config, - Logger: f.Logger, - IO: f.IOStreams, + Config: f.Config, + Connection: f.Connection, + Logger: f.Logger, + IO: f.IOStreams, } cmd := &cobra.Command{ @@ -75,6 +78,9 @@ func NewLoginCmd(f *factory.Factory) *cobra.Command { Long: localizer.MustLocalizeFromID("login.cmd.longDescription"), Example: localizer.MustLocalizeFromID("login.cmd.example"), RunE: func(cmd *cobra.Command, _ []string) error { + if opts.offlineToken != "" && opts.clientID == defaultClientID { + opts.clientID = defaultOfflineTokenClientID + } return runLogin(opts) }, } @@ -86,6 +92,7 @@ func NewLoginCmd(f *factory.Factory) *cobra.Command { cmd.Flags().StringVar(&opts.masAuthURL, "mas-auth-url", connection.DefaultMasAuthURL, localizer.MustLocalizeFromID("login.flag.masAuthUrl")) cmd.Flags().BoolVar(&opts.printURL, "print-sso-url", false, localizer.MustLocalizeFromID("login.flag.printSsoUrl")) cmd.Flags().StringArrayVar(&opts.scopes, "scope", connection.DefaultScopes, localizer.MustLocalizeFromID("login.flag.scope")) + cmd.Flags().StringVarP(&opts.offlineToken, "token", "t", "", localizer.MustLocalizeFromID("login.flag.token")) return cmd } @@ -117,44 +124,51 @@ func runLogin(opts *Options) (err error) { })) } - tr := createTransport(opts.insecureSkipTLSVerify) - httpClient := &http.Client{Transport: tr} - - loginExec := &login.AuthorizationCodeGrant{ - HTTPClient: httpClient, - Scopes: opts.scopes, - Logger: logger, - IO: opts.IO, - Config: opts.Config, - ClientID: opts.clientID, - PrintURL: opts.printURL, + if opts.offlineToken == "" { + tr := createTransport(opts.insecureSkipTLSVerify) + httpClient := &http.Client{Transport: tr} + + loginExec := &login.AuthorizationCodeGrant{ + HTTPClient: httpClient, + Scopes: opts.scopes, + Logger: logger, + IO: opts.IO, + Config: opts.Config, + ClientID: opts.clientID, + PrintURL: opts.printURL, + } + + ssoCfg := &login.SSOConfig{ + AuthURL: opts.authURL, + RedirectPath: "sso-redhat-callback", + } + + masSsoCfg := &login.SSOConfig{ + AuthURL: opts.masAuthURL, + RedirectPath: "mas-sso-callback", + } + + if err = loginExec.Execute(context.Background(), ssoCfg, masSsoCfg); err != nil { + return err + } } - ssoCfg := &login.SSOConfig{ - AuthURL: opts.authURL, - RedirectPath: "sso-redhat-callback", - } - - masSsoCfg := &login.SSOConfig{ - AuthURL: opts.masAuthURL, - RedirectPath: "mas-sso-callback", - } - - if err = loginExec.Execute(context.Background(), ssoCfg, masSsoCfg); err != nil { - return err + if opts.offlineToken != "" { + if err = loginWithOfflineToken(opts); err != nil { + return err + } } cfg, err := opts.Config.Load() if err != nil { - logger.Error(err) - os.Exit(1) + return err } + cfg.APIUrl = gatewayURL.String() cfg.Insecure = opts.insecureSkipTLSVerify cfg.ClientID = opts.clientID cfg.AuthURL = opts.authURL cfg.MasAuthURL = opts.masAuthURL - cfg.APIUrl = gatewayURL.String() cfg.Scopes = opts.scopes if err = opts.Config.Save(cfg); err != nil { @@ -163,19 +177,39 @@ func runLogin(opts *Options) (err error) { username, ok := token.GetUsername(cfg.AccessToken) if !ok { - username = "unknown" + logger.Info("\n", localizer.MustLocalizeFromID("login.log.info.loginSuccessNoUsername")) + } else { + logger.Info("\n", localizer.MustLocalize(&localizer.Config{ + MessageID: "login.log.info.loginSuccess", + TemplateData: map[string]interface{}{ + "Username": username, + }, + })) } - logger.Info("\n", localizer.MustLocalize(&localizer.Config{ - MessageID: "login.log.info.loginSuccess", - TemplateData: map[string]interface{}{ - "Username": username, - }, - })) - return nil } +func loginWithOfflineToken(opts *Options) (err error) { + cfg, err := opts.Config.Load() + if err != nil { + return err + } + cfg.Insecure = opts.insecureSkipTLSVerify + cfg.ClientID = opts.clientID + cfg.AuthURL = opts.authURL + cfg.MasAuthURL = opts.masAuthURL + cfg.Scopes = opts.scopes + cfg.RefreshToken = opts.offlineToken + + if err = opts.Config.Save(cfg); err != nil { + return err + } + + _, err = opts.Connection(connection.DefaultConfigSkipMasAuth) + return err +} + func createTransport(insecure bool) *http.Transport { // #nosec 402 return &http.Transport{ diff --git a/pkg/cmd/whoami/whoami.go b/pkg/cmd/whoami/whoami.go index 2aa758f214..b8d9a197c8 100644 --- a/pkg/cmd/whoami/whoami.go +++ b/pkg/cmd/whoami/whoami.go @@ -9,6 +9,7 @@ import ( "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/cmd/factory" "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/connection" "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/iostreams" + "github.com/bf2fc6cc711aee1a0c2a/cli/pkg/logging" "github.com/spf13/cobra" ) @@ -17,6 +18,7 @@ type Options struct { Config config.IConfig Connection factory.ConnectionFunc IO *iostreams.IOStreams + Logger func() (logging.Logger, error) } func NewWhoAmICmd(f *factory.Factory) *cobra.Command { @@ -24,6 +26,7 @@ func NewWhoAmICmd(f *factory.Factory) *cobra.Command { Config: f.Config, Connection: f.Connection, IO: f.IOStreams, + Logger: f.Logger, } cmd := &cobra.Command{ @@ -45,6 +48,11 @@ func runCmd(opts *Options) (err error) { return err } + logger, err := opts.Logger() + if err != nil { + return err + } + _, err = opts.Connection(connection.DefaultConfigSkipMasAuth) if err != nil { return err @@ -54,9 +62,13 @@ func runCmd(opts *Options) (err error) { tknClaims, _ := token.MapClaims(accessTkn) - userName, _ := tknClaims["preferred_username"] + userName, ok := tknClaims["preferred_username"] - fmt.Fprintln(opts.IO.Out, userName) + if ok { + fmt.Fprintln(opts.IO.Out, userName) + } else { + logger.Info(localizer.MustLocalizeFromID("whoami.log.info.tokenHasNoUsername")) + } return nil }