From 5d39e59dd5afe7fd16492f1fa0249ebe0e892f5d Mon Sep 17 00:00:00 2001 From: Paul Kaplan Date: Tue, 24 Sep 2019 14:34:02 -0400 Subject: [PATCH] Use a feature flag to contain new Scratch Desktop updates --- .../extension-landing/extension-landing.jsx | 12 +- .../install-scratch-link.jsx | 9 +- .../install-scratch/install-scratch.jsx | 146 +++++++++ .../install-scratch/install-scratch.scss | 95 ++++++ .../install-scratch/install-util.js | 13 + src/components/os-chooser/os-chooser.jsx | 25 +- src/l10n.json | 10 +- src/lib/detect-os.js | 18 ++ src/lib/feature-flags.js | 10 + .../extension-landing => lib}/os-enum.js | 4 +- src/views/download/download.jsx | 299 ++++++++++-------- src/views/download/download.scss | 13 + src/views/download/l10n.json | 19 +- src/views/ev3/ev3.jsx | 2 +- src/views/microbit/microbit.jsx | 2 +- static/images/badges/google-play-badge.png | Bin 0 -> 16087 bytes static/images/badges/mac-store-badge.svg | 46 +++ static/images/badges/windows-store-badge.svg | 82 +++++ static/svgs/download/mac-badge.svg | 46 +++ static/svgs/download/ms-badge.svg | 82 +++++ 20 files changed, 768 insertions(+), 165 deletions(-) create mode 100644 src/components/install-scratch/install-scratch.jsx create mode 100644 src/components/install-scratch/install-scratch.scss create mode 100644 src/components/install-scratch/install-util.js create mode 100644 src/lib/detect-os.js create mode 100644 src/lib/feature-flags.js rename src/{components/extension-landing => lib}/os-enum.js (51%) create mode 100644 static/images/badges/google-play-badge.png create mode 100755 static/images/badges/mac-store-badge.svg create mode 100755 static/images/badges/windows-store-badge.svg create mode 100755 static/svgs/download/mac-badge.svg create mode 100755 static/svgs/download/ms-badge.svg diff --git a/src/components/extension-landing/extension-landing.jsx b/src/components/extension-landing/extension-landing.jsx index 44cb3fb01..c883d294f 100644 --- a/src/components/extension-landing/extension-landing.jsx +++ b/src/components/extension-landing/extension-landing.jsx @@ -1,7 +1,7 @@ const bindAll = require('lodash.bindall'); const React = require('react'); -const OS_ENUM = require('./os-enum.js'); +const detectOS = require('../../lib/detect-os.js').default; class ExtensionLanding extends React.Component { constructor (props) { @@ -10,16 +10,8 @@ class ExtensionLanding extends React.Component { 'onSetOS' ]); - // @todo use bowser for browser detection - let detectedOS = OS_ENUM.WINDOWS; - if (window.navigator && window.navigator.platform) { - if (window.navigator.platform === 'MacIntel') { - detectedOS = OS_ENUM.MACOS; - } - } - this.state = { - OS: detectedOS + OS: detectOS() }; } diff --git a/src/components/extension-landing/install-scratch-link.jsx b/src/components/extension-landing/install-scratch-link.jsx index b8186fbcf..507cdbeb7 100644 --- a/src/components/extension-landing/install-scratch-link.jsx +++ b/src/components/extension-landing/install-scratch-link.jsx @@ -2,13 +2,14 @@ const PropTypes = require('prop-types'); const FormattedMessage = require('react-intl').FormattedMessage; const React = require('react'); -const OS_ENUM = require('./os-enum.js'); +const OS_ENUM = require('../../lib/os-enum.js'); const FlexRow = require('../../components/flex-row/flex-row.jsx'); const Steps = require('../../components/steps/steps.jsx'); const Step = require('../../components/steps/step.jsx'); require('./extension-landing.scss'); +// Assumes this will only be called with an OS that needs Scratch Link const InstallScratchLink = ({ currentOS }) => ( @@ -37,20 +38,20 @@ const InstallScratchLink = ({ - + - + diff --git a/src/components/install-scratch/install-scratch.jsx b/src/components/install-scratch/install-scratch.jsx new file mode 100644 index 000000000..eff760cff --- /dev/null +++ b/src/components/install-scratch/install-scratch.jsx @@ -0,0 +1,146 @@ +const PropTypes = require('prop-types'); +const FormattedMessage = require('react-intl').FormattedMessage; +const React = require('react'); + +const OS_ENUM = require('../../lib/os-enum.js'); +const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js'); + +const {isDownloaded, isFromGooglePlay} = require('./install-util.js'); + +const FlexRow = require('../../components/flex-row/flex-row.jsx'); +const Steps = require('../../components/steps/steps.jsx'); +const Step = require('../../components/steps/step.jsx'); + +require('./install-scratch.scss'); + +const InstallScratch = ({ + currentOS +}) => ( +
+ +

+ {CHROME_APP_RELEASED ? ( + + ) : ( + + {isDownloaded(currentOS) && ( + + )} + {isFromGooglePlay(currentOS) && ( + + )} + + )} +

+ +
+ + + + {isDownloaded(currentOS) && ( + + )} + {isFromGooglePlay(currentOS) && ( + + )} + + +
+ {currentOS === OS_ENUM.WINDOWS && ( + + + + )} + {currentOS === OS_ENUM.MACOS && ( + + + + )} + {isFromGooglePlay(currentOS) && ( + + + + + )} + {isDownloaded(currentOS) && ( + + + + + + + + + )} +
+
+ +
+ {isDownloaded(currentOS) && ( + + + {currentOS === OS_ENUM.WINDOWS ? + : + + } + + +
+ +
+
+ )} +
+
+
+); + +InstallScratch.propTypes = { + currentOS: PropTypes.string +}; + +module.exports = InstallScratch; diff --git a/src/components/install-scratch/install-scratch.scss b/src/components/install-scratch/install-scratch.scss new file mode 100644 index 000000000..953b93d5a --- /dev/null +++ b/src/components/install-scratch/install-scratch.scss @@ -0,0 +1,95 @@ +@import "../../colors"; +@import "../../frameless"; + +#view { + padding: 0; +} + +.install-scratch { + padding: 2rem 0; + + .inner { + align-items: flex-start; + } + + .downloads-container { + text-align: center; + + .horizontal-divider { + display: block; + margin: 20px; + } + + .horizontal-divider:before, + .horizontal-divider:after { + display: inline-block; + position: relative; + background-color: $ui-dark-gray; + width: 50%; + height: 1px; + vertical-align: middle; + content: ""; + } + + .horizontal-divider:before { + right: .5em; + margin-left: -50%; + } + + .horizontal-divider:after { + left: .5em; + margin-right: -50%; + } + } + + .step-image { + height: 14rem; + } + + .title { + margin-bottom: 2rem; + font-size: 2rem; + } + + .legacy-link { + display: flex; + } + + .download-button { + display: inline-block; + margin: .5em 0; + border: 0; + border-radius: 8px; + background-color: $ui-blue; + cursor: pointer; + padding: 1rem 2rem; + color: $ui-white; + font-size: 1rem; + } + + .macos-badge img { + height: 50px; + } + + .ms-badge img { + height: 50px; + } + + .play-badge img { + height: 50px; + } + + .download-image { + width: 100%; + max-width: $cols6; + + img { + max-width: 100%; + max-height: 100%; + } + } + + .blue { + background-color: $ui-blue-10percent; + } +} diff --git a/src/components/install-scratch/install-util.js b/src/components/install-scratch/install-util.js new file mode 100644 index 000000000..20f667c21 --- /dev/null +++ b/src/components/install-scratch/install-util.js @@ -0,0 +1,13 @@ +const OS_ENUM = require('../../lib/os-enum.js'); + +module.exports = {}; + +module.exports.isDownloaded = os => { + if (os === OS_ENUM.WINDOWS || os === OS_ENUM.MACOS) return true; + return false; +}; + +module.exports.isFromGooglePlay = os => { + if (os === OS_ENUM.ANDROID || os === OS_ENUM.CHROMEOS) return true; + return false; +}; diff --git a/src/components/os-chooser/os-chooser.jsx b/src/components/os-chooser/os-chooser.jsx index 977c207ea..5d77d19e2 100644 --- a/src/components/os-chooser/os-chooser.jsx +++ b/src/components/os-chooser/os-chooser.jsx @@ -4,11 +4,12 @@ const FormattedMessage = require('react-intl').FormattedMessage; const PropTypes = require('prop-types'); const React = require('react'); +const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js'); const FlexRow = require('../../components/flex-row/flex-row.jsx'); const Button = require('../../components/forms/button.jsx'); -const OS_ENUM = require('../../components/extension-landing/os-enum.js'); +const OS_ENUM = require('../../lib/os-enum.js'); require('./os-chooser.scss'); @@ -34,6 +35,28 @@ const OSChooser = props => ( macOS + {CHROME_APP_RELEASED && ( + + + + + )} ); diff --git a/src/l10n.json b/src/l10n.json index 9b9032b7a..a72a5de67 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -133,10 +133,16 @@ "oschooser.choose": "Choose your OS:", + "installScratch.or": "or", + "installScratch.directDownload": "Direct download", + "installScratch.desktopHeaderTitle": "Install Scratch Desktop", + "installScratch.appHeaderTitle": "Install Scratch for {operatingsystem}", + "installScratch.downloadScratchDesktop": "Download Scratch Desktop", + "installScratch.downloadScratchAppGeneric": "Download Scratch for {operatingsystem}", + "installScratch.getScratchAppPlay": "Get Scratch on the Google Play Store", + "installScratchLink.installHeaderTitle": "Install Scratch Link", "installScratchLink.downloadAndInstall": "Download and install Scratch Link.", - "installScratchLink.or": "or", - "installScratchLink.directDownload": "Direct download", "installScratchLink.startScratchLink": "Start Scratch Link and make sure it is running. It should appear in your toolbar.", "parents.FaqAgeRangeA": "While Scratch is primarily designed for 8 to 16 year olds, it is also used by people of all ages, including younger children with their parents.", diff --git a/src/lib/detect-os.js b/src/lib/detect-os.js new file mode 100644 index 000000000..fa94c3229 --- /dev/null +++ b/src/lib/detect-os.js @@ -0,0 +1,18 @@ +import bowser from 'bowser'; +import OS_ENUM from './os-enum.js'; +import {CHROME_APP_RELEASED} from './feature-flags.js'; + +/** + * Helper function to the current Operating System. + * @returns {OS_ENUM} Returns the OS value, defaults to WINDOWS + */ +export default function () { + // matching OS strings from https://github.com/lancedikson/bowser/blob/master/src/constants.js + if (bowser.osname === 'macOS') return OS_ENUM.MACOS; + if (CHROME_APP_RELEASED) { + if (bowser.osname === 'Chrome OS') return OS_ENUM.CHROMEOS; + if (bowser.osname === 'Android') return OS_ENUM.ANDROID; + } + // if (bowser.osname === 'iOS') return OS_ENUM.IOS; // @todo + return OS_ENUM.WINDOWS; +} diff --git a/src/lib/feature-flags.js b/src/lib/feature-flags.js new file mode 100644 index 000000000..2965c1e9c --- /dev/null +++ b/src/lib/feature-flags.js @@ -0,0 +1,10 @@ +const isStaging = () => process.env.SCRATCH_ENV === 'staging'; + +const flagInUrl = flag => { + const url = (window.location && window.location.search) || ''; + return url.indexOf(`${flag}=true`) !== -1; +}; + +module.exports = { + CHROME_APP_RELEASED: isStaging() && flagInUrl('CHROME_APP_RELEASED') +}; diff --git a/src/components/extension-landing/os-enum.js b/src/lib/os-enum.js similarity index 51% rename from src/components/extension-landing/os-enum.js rename to src/lib/os-enum.js index b8cde494e..24d41c018 100644 --- a/src/components/extension-landing/os-enum.js +++ b/src/lib/os-enum.js @@ -1,6 +1,8 @@ const OS_ENUM = { WINDOWS: 'Windows', - MACOS: 'macOS' + MACOS: 'macOS', + CHROMEOS: 'ChromeOS', + ANDROID: 'Android' }; module.exports = OS_ENUM; diff --git a/src/views/download/download.jsx b/src/views/download/download.jsx index 2c935f04b..b0f77a4a8 100644 --- a/src/views/download/download.jsx +++ b/src/views/download/download.jsx @@ -5,13 +5,14 @@ const React = require('react'); const FlexRow = require('../../components/flex-row/flex-row.jsx'); const bindAll = require('lodash.bindall'); -const Steps = require('../../components/steps/steps.jsx'); -const Step = require('../../components/steps/step.jsx'); const Page = require('../../components/page/www/page.jsx'); const render = require('../../lib/render.jsx'); -const OS_ENUM = require('../../components/extension-landing/os-enum.js'); +const detectOS = require('../../lib/detect-os.js').default; +const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js'); const OSChooser = require('../../components/os-chooser/os-chooser.jsx'); +const InstallScratch = require('../../components/install-scratch/install-scratch.jsx'); +const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js'); require('./download.scss'); require('../../components/forms/button.scss'); @@ -22,15 +23,9 @@ class Download extends React.Component { bindAll(this, [ 'onSetOS' ]); - let detectedOS = OS_ENUM.WINDOWS; - if (window.navigator && window.navigator.platform) { - if (window.navigator.platform === 'MacIntel') { - detectedOS = OS_ENUM.MACOS; - } - } this.state = { - OS: detectedOS + OS: detectOS() }; } @@ -55,10 +50,16 @@ class Download extends React.Component { src="/images/download/icon.png" width="40" /> - + - + @@ -80,6 +81,24 @@ class Download extends React.Component { /> macOS 10.13+ + {CHROME_APP_RELEASED && ( + + + + ChromeOS + + + + Android 5.0+ + + + )} @@ -95,89 +114,150 @@ class Download extends React.Component { currentOS={this.state.OS} handleSetOS={this.onSetOS} /> -
- -

- -

- -
- - - - -
+ + {isDownloaded(this.state.OS) && ( +
+ +

+ +

+

+ +

+ + - - -
- - - {this.state.OS === OS_ENUM.WINDOWS ? - : - - } - - -
- +

-
- - -
+
+ + + +

+ + + + +

+
+ + +
+ )}

+ {isDownloaded(this.state.OS) && ( + +

+ +

+

+ +

+
+ )} + {isFromGooglePlay(this.state.OS) && ( + +

+ +

+

+ +

+
+ )}

- -

-

- -

-

- + {isFromGooglePlay(this.state.OS) ? + : + + }

-

- -

-

- -

-

- -

-

- -

+ {isDownloaded(this.state.OS) && (CHROME_APP_RELEASED ? ( + +

+ +

+

+ +

+
+ ) : ( + +

+ +

+

+ +

+
+ ))} + {isFromGooglePlay(this.state.OS) && ( + +

+ +

+

+ +

+
+ )} + {!CHROME_APP_RELEASED && ( + +

+ +

+

+ +

+
+ )}

@@ -186,64 +266,7 @@ class Download extends React.Component {

-
- -

- -

-

- -

- -
- - - -

- - - - -

-
-
- - - -

- - - - -

-
-
-
-
+
); diff --git a/src/views/download/download.scss b/src/views/download/download.scss index e53275950..3e2b4064c 100644 --- a/src/views/download/download.scss +++ b/src/views/download/download.scss @@ -27,6 +27,18 @@ font-size: 1rem; } + .macos-badge img { + height: 50px; + } + + .ms-badge img { + height: 50px; + } + + .play-badge img { + height: 50px; + } + .download-header { background-color: $ui-blue; padding: 4rem 0; @@ -80,6 +92,7 @@ .download-requirements { justify-content: space-between; + line-height: 2rem; } .download-requirements span { diff --git a/src/views/download/l10n.json b/src/views/download/l10n.json index e475c8a75..c1559b070 100644 --- a/src/views/download/l10n.json +++ b/src/views/download/l10n.json @@ -1,11 +1,10 @@ { "download.title": "Scratch Desktop", "download.intro": "You can install the Scratch Desktop editor to work on projects without an internet connection. This version will work on Windows and MacOS.", + "download.appTitle": "Download Scratch", + "download.appIntro": "You can install Scratch for free to work on projects without an internet connection.", "download.requirements": "Requirements", "download.imgAltDownloadIllustration" : "Scratch 3.0 Desktop screenshot", - "download.installHeaderTitle": "Install Scratch Desktop", - "download.downloadScratchDesktop": "Download Scratch Desktop", - "download.downloadButton": "Download", "download.troubleshootingTitle": "FAQ", "download.startScratchDesktop": "Start Scratch Desktop", "download.howDoIInstall": "How do I install Scratch Desktop?", @@ -14,17 +13,23 @@ "download.supportChromeOS" : "When will you have Scratch Desktop for Chromebooks?", "download.supportChromeOSAnswer": "Scratch Desktop for Chromebooks is not yet available. We are working on it and expect to release later in 2019.", "download.olderVersionsTitle" : "Older Versions", - "download.olderVersions": "Looking for the Scratch 2.0 Offline Editor or Scratch 1.4?", - "download.scratch1-4Desktop" : "Scratch 1.4 Desktop", - "download.scratch2Desktop" : "Scratch 2.0 Desktop", + "download.olderVersions": "Looking for earlier Scratch Offline Editors?", + "download.scratch1-4Desktop" : "Scratch 1.4", + "download.scratch2Desktop" : "Scratch 2.0 Offline Editor", "download.cannotAccessMacStore" : "What if I can't access the Mac App Store?", "download.cannotAccessWindowsStore" : "What if I can't access the Microsoft Store?", "download.macMoveToApplications" : "Open the .dmg file. Move Scratch Desktop into Applications.", "download.winMoveToApplications" : "Run the .exe file.", "download.canIUseScratchLink" : "Can I use Scratch Link to connect to extensions?", "download.canIUseScratchLinkAnswer" : "Yes. However, you will need an Internet connection to use Scratch Link.", + "download.canIUseExtensions" : "Can I connect to hardware extensions?", + "download.canIUseExtensionsAnswer" : "Yes. With the Scratch app you can connect to extensions, and you do not need Scratch Link.", "download.desktopAndBrowser": "Can I use Scratch Desktop and also have Scratch open in the browser?", + "download.appAndBrowser": "Can I use the Scratch app and also have Scratch open in the browser?", "download.yesAnswer" : "Yes.", "download.canIShare": "Can I share from Scratch Desktop?", - "download.canIShareAnswer": "This isn’t supported currently. For now, you can save a project from Scratch Desktop, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch Desktop." + "download.canIShareAnswer": "This isn’t supported currently. For now, you can save a project from Scratch Desktop, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch Desktop.", + "download.canIShareApp": "Can I share from Scratch for {operatingsystem}?", + "download.canIShareAnswerPlayStore": "Yes. Click the 3-dots menu on a project in the lobby and select Share from the options. In addition to sharing by email you can sign in to your Scratch account and share the project on the Scratch Community.", + "download.canIShareAnswerDownloaded": "This isn’t supported currently. For now, you can save a project from Scratch for {operatingsystem}, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch for {operatingsystem}." } diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index a03b55a14..6666490e9 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -23,7 +23,7 @@ const ProjectCard = require('../../components/extension-landing/project-card.jsx const Steps = require('../../components/steps/steps.jsx'); const Step = require('../../components/steps/step.jsx'); -const OS_ENUM = require('../../components/extension-landing/os-enum.js'); +const OS_ENUM = require('../../lib/os-enum.js'); require('../../components/extension-landing/extension-landing.scss'); require('./ev3.scss'); diff --git a/src/views/microbit/microbit.jsx b/src/views/microbit/microbit.jsx index 1b36c4ba3..ac274423b 100644 --- a/src/views/microbit/microbit.jsx +++ b/src/views/microbit/microbit.jsx @@ -22,7 +22,7 @@ const Button = require('../../components/forms/button.jsx'); const Steps = require('../../components/steps/steps.jsx'); const Step = require('../../components/steps/step.jsx'); -const OS_ENUM = require('../../components/extension-landing/os-enum.js'); +const OS_ENUM = require('../../lib/os-enum.js'); require('../../components/extension-landing/extension-landing.scss'); require('./microbit.scss'); diff --git a/static/images/badges/google-play-badge.png b/static/images/badges/google-play-badge.png new file mode 100644 index 0000000000000000000000000000000000000000..27392d21753e7e06361a69aa19cbb771bbbb288e GIT binary patch literal 16087 zcmbWe1z6Nw*Ec#M(kTjvNDHXM(A^;*DcwDEH_|BrqJSVRAl;30NOwy!(jeV^_IN+f zbKdV&bs1g6~xn~KvLLd()EL1d{HRNP@jqPlh3{C8eOqtwm>;W|d!Y|}*Z)j{~ z>P%r|YGz?8K($xjOhsW~B0#0iAqSPS7c(`tkn(giRrZuuG4`}F<}slX5~SdF=LG}U zm^vF$xZ7CUI`O&-Q2ia37raM&%uGe`m&DmhfJy{0A%%vVB88ZpqbUUk6DOlF3p)n| z7Y`E)CmTBt4+8}&l!coa%FWEe#>m3S%MRsbWu^GnKPoVrqX~@nt+?dB<^q2SP?=pH?(JFVS*x-^q0`Y_&;>^E{@iJCpR%> zHnldjF|~De0<dY|$A8O|iaB`M#1k~5ClwESQ|7m(PIfMi#-WvOhf{@xi*;(5;f{6ilZ2$Fh zX)!THM?08>HTc5m?Q2mAX$dh-79LJcMph=4zwFA%@k-k|IUCvAvcMRP*f}^ESzzoe#zw}*CM@iR|9)QF&e#Q^2mgNF4GAF-9$jg15f%63o%wfODyu0%`wH|jOrr_( z->yIK(OEZsvPo%gW4f*6pu0L!EzmVJFI0L78?DQ_+_qzLs8S_L>iJz)r^h;i@te`C z^h<^+t&5eqICpwMu;_|7!{Y}D_hiw6Ru@?63K7(L+@D329x&&lDLK(Z!gvr6sizUpd}>o^710>?Cf0e@$r#+ zuYOVIq;-0V{vZ*|(Kq+QX+B=Zv1j6u5gMS*sM+1!U3yLKy`ooRJD(DEoxCPo;kepM z6wjb}7#I)`(C}SL>Mx-ZaKQFc#kyw){ClI0-V?&gnwl16T17_E(qTN4tGc?nziRBr zy#&dDl zxu7EKskvIAhLQ*1^_F#VfAn-`w#@s=_0Mb#b2=XwAPDcF&B5=E+S|+RGK1CthjPP=Ce2iWr%4Q%y_j!@J!dbQw+AnVHn~Ljq?JuWAzry+bA}AHV2FkkHJ6 zb%cUvj13HgdF%kY56%|e?WJyPOCl$Jd8OV&ESMD5hJ~27yl4Fg{$o8goZD_BL!xlr z)-5P42l?-gML&PzgXaUkJlX!&s0FTj3z1w4?$o~<-Y_>-GF?|bG+!G`*~Vc;vbC|v zLNY)IY$XU#+y}eTyBQt*(8--S@}W7?kCo_xc3=CO%aa6ia>TUnX-C8q;En8Kej|~z z?U?>Gc8l`c|L~sE%}3BJBO}w_7tef$0wpwG>rXgp+$aB*PWyNKjK#a#GyI(J@bJ3_ z#F*?yYXi!0%Q0s#Dui@;IO^T@K5`3KO%}eoXP^b7_}r`ZUrTkIXlW7tSsK$}^aBr) z{rJ%%2FzwExiMPsoD|blpZ;xzm%gInCv~7+37p2A5hcO;VMy2rZXGp!eSLp!08cu za#r%L{48p@cKG(@N~|l295)Xg87X~ma8S|M*tpx8vtZ%0H4s(R&WUP!szlw^3~aje zqC9ubSi-O|!NRR_j=Y3UToI?lUB$F@dU0{FqPlwg)*c2Jzgw)l| zEtLD?n=KY=J3EC9vrY1wOyA4fSB#9lruE zPWZJBf@_7BoV^QoTso&m7|BjPO4Uiytbno1ygYQfrVCo8#^bmBsRG(3W`{>dz>$&8 zd90_LUmp#%mRnywO{5NJHKmCudI($ccj zZExXwYV+^kMh%x+1<<4c^gCg3Wq8^#+!H1BQd%9vb z=cDo2aNp@W!bKgQ$2di^0b*={0k6``3ih>e`e>GD`E@7T7g>Q~2{ys;Ay2ZjXuk>1b7<~s_kEBVu4Pm#} z7x?RE$HxZ1KWo&x?$r7jaV8m7Oz*ec$6ac}WDe>vL4x!r^AOa`IfiEokByB5=A`*( zIq|h`%jo%Bn0kTe!BSFVJgT)6#GuwMzk*`=_&Z%OOu~rRc|3*4K?!d%v8Yl=!CD6H^7P z5Vj*HhTC4D zO*%(=IL!HS;tg%n7f0)_gHT2AqHhHx&11TjMI0Q;9P65!$$>{);A4Y^(LB3F%j9oSz>oe`Pbn@f$H%b*(q7(sKEsAN1)D zR2F;SxI{m=b@*2p|F`CnhdBz&WJEC0Ze@8~s`u6DuB419{?GSH+Eyc9Rg!zG;EzvE8Uf{~J?MNo_Dk#G0IZ_bvMM9j{CKYn zunXKMN?&;*3`aUTXlu)oAMEJH&W`FJGZRzitCEI{%cJ)8cKq}%qq3z|RC3vKAK)cJ z4Ur<92Q|EZYV2Sg`uQ)&BtOw1W$O>}{UUnr55G5YYZ7z&ovkkRTGMug6Wx1TJ+Fg~ z_eO)MsbmbAoO|KnpYi?H zRvV)rn0M(^RaLcrb%QVTS^^$K91j-C&Uz|Ws7S49L|;m8`&DVn>QK_&{+woJ@NBt6 zzmXuk`WB1ru8F3?E#&)m;I51;?OwkQEtV*!X&gPco`1L3h~LP*y1JS#L@oVrx9Mv4 zJ%vlhWA%;lZVF18BP;^*OG!Mo{%(ELEE(iXQ90+Y=y$xt7@}C!%lnJ{ekaX)t&7)( zufO`-o0uYQb(zx5@e%@t-$m}rA6`TmCewAae&9~!X%W!+ExXEspA2_qW+rwluTV}5 zt%s?--x0~4vn8mrDe984Jk2Txk4LQd{Ca4f4W-dYb9)?qA3b6NN<5JM)3(NVeK4iBkWMQp z1kadN{u??jv?VBg?YKuK8FT3ko3?7Z?72smXd^dECi#&XQ=95z-_RkSTNL^0ONE3V zb~Kc5W$!@1v?j~d*o(F=Beet;X<-6g$z`{niwn)=ZucCJ<7OQ@DO@{k5+GWk%kU!sUg@ zb*ZP-KR(*MMD;oyi`Fi|M^w+p2O+k z6Hd>S&#(70$#0}I%|B0OQ~q?vQWhhq@S&BL8yF6gLB1liz+vm|Q!ZvB#xUCJW^ph1 z>i=MG^7o;7UK6c))+_h!SHscAqemCvdL}F*n#v<%ofbAEq7fan0_-H7mH}O_)gPsv zuBr_f(q0z?L0qxPJ0uo=5QpEv4N0AvqcZO<-XSZbG78cp5D8X7y)T`iSed-mz!M6= z4{zZ$C+fZ@>JZ8J#WX1eg`uE!rIBM2`2^W$kK0PL#bpb7dng=ErSu4X;BMc?So5v4 zR8cbtHjv0sNduuoF-R6Bc-3!?&XMxvd{iS>nx;Rw(W|m4`&Bdf(XLid2iM)R28CO) zu1U1bh8miWaJb>>)pUhf;4=3NH4&&+7)xXrutZcFGTg)G+pKoy88V(^R$sMLJgOJ8s2-0!$EnM@x4v9Rs{K=ryCvY&Aqh~K8K4C za>~1COyzog8cLu-2xWHk1PSvCa(hcFE9xy+h8V#})a=gW$pu@|fJURIi#YQf-(Ew^ z@s0<7>U+4fhfU(qARqJQEKSh&GzX-}&ZUQ32x4vYC1PsbyiToO-xLDYeSnLd~C0qKeU+0VFk6CWcd5d z*7mltIi;eKlK*m7)ayzI5OiP6(^AqjMi7`obVUcG-aQu`&4>j{Gfvlgf1%r=8{V?3 z6CA#~_OSk5bS%jCC9yCEQuv78o$bnnv){^Wx!wBeN z$MkOxP#~9d$ zkz3k^p>gztJW0^eKRPJX%P;A{6Tusvn zP?4_K`Ns@7WV*F@x-p-0A&{xChxt|S0ZIj?C);QmdEpy zdp9$vw)~&d#6K~MBlxtBmE#^C+*E7oypmVTkp<*kT*9KS1OYpXKj(vnO4{7HWR{Y* z$o(Xzu8u@q*X423;g=G6)TAFy>%RxM7Jq)GehuvC}a9Y%*REmKMk z1NQzxttuJiy@<&oT*%C=0o5zDLO=Qsr5X$n$@^kTO8C{b^B;8UT@80;s+L`wVVZ=m z)QiPUO`pU1zv3%#IUTM@>%7~ks*^9Pp51W=2^dv&5P_&;j02Kf^jP(>E+MaH-^S{C z&DPBL$Ymk~=DqAyN-h{=Y=x}VOe+`1pcw$FHr%YNtlm;FkhOuV=iso9nVJ|Yqozjv z$8CQCo05tOyDfWkocGy$VjI>-JgFrR7q4x8LyyS^_gkR%za0!=_V##!X}F8mYg}V$XDZs- z;bS=pIjhy^l$R{PXh(@GKYnK(hxoaDN3B2NL-+v=243Jyv3KjXndY3wBCUT(4ljA@ zEvJPR04bQj2r(@6x^VPb=UWt!mPYp*q09;hKte{kN6KvvdCF<+*R?#NW2XebhvQ14 zA~su}+oQDQ)p&jR^Yu!p>YGh#Wp)uf`)Sj7e^bplV2_AAOi4$l(Aq##QPFQ;-SBtn+7+o>bR%R` zNqNzR7F=L#t+#NW8S)RHD3>JoA%nEr_Al(63## zgId~%Rp=OkX!nfCD1}Qx6dOW{d1B<|LuWrl#lKXK>Ndyzs$d6E^_TZ>`=fkQBzXQF z|0~MrvY9S(>&?EzuN&U*f?r4FGYB+-<|$wfg27=}7}!Ngx&RsbM2_YaA@N+V;jW;s zY%`&crQjF$)yIc`G!I0fFd_pmXOCE<%RV>qBFfiLg){*t4WvuA_ES0Z&;@O*sX(l3 zg&YF_BbXer0Rx~Pk0`?-3tfuDV1tKzgf|S^j?bZx5^9XA=*E^+DbVySp6_IjX2f8Gtb6-&qfGD1h0IQ6HIXMgbpB9jPOMTe?{YG{5WtY zY(v_)ZVKo*I^j*#6FY&fmZJrVUEjIzn^2UoQAuhzHx6eKHbY-VVWI5N(1n*EFc%TL zr2}^g>9?08(rA?81k1=I1~Q=}&-=0H@L+A&Z-j+|ivCdPTt$|^v!?3z_nALt6wu{b z@i{$fhuZU|fHDS}AS*o|0>C^~)yMhy`NQMmL2GNUeSX}iu1q`QFgOd={rY)9_$o*Q z`G?F31rmNc^SU(4l}uqOJ)-QaWFW=TcKE6 zTU)dZ4Ov;HZ&4E6&v;aQn)NrI$(@!dTcuH;Ju=7Y{wmR0hT%WK#ATjd%3)91*2?{$ zrRUSO70d@~syVUjs)phA;O^^5{S9dw6boeN)i$$naZrLmqcVfBY&ksSdsyw?Pu%cX zRTE@s8FcF&$;ruqjd6I_(mife2+T82(HNUF)LwWUO2EX9mVApG&UEs-h=|x-@0x@u zDJ?B^@yi38(EAzmMw_EqPi`7bO-(^8zzLxkw*J)Jt4d5Xe^pcMbWAcEeOIn#L z)z49+cam`9z$@58671U_Lcy~fUHd(pgvGol6@y%Z<|gbF(^yemfgvFw-?vTPnzAMg z4-Z39*9|$7Dn?O6voQ)LJ_x)!RkRy;WQOn|34fW~w+I2*37miVhM^k>y-r+5=H=pVlE}keUM|&kINc%UJ(~p;c4s~k}^K3M)@fAD{X1qx)IyM zVI)4P_2_!leq7=8a$hGs35dD@6g2a%#zsexz+Ov7m!Ha>C$f`v`I}A$*)3XD1uS#F zB&7X2FvQ?3p?1tU@G;TojF$218o6aSK_~qtull=116wTci|hJEoL;^^Y2NI04E$|O zObfD5g&%~-hHWP%8G&eh<)yPb;3v^X-^GO^_=za1RB^$G@dqvzoMl{|U|+i>INf#& zP^s+Dgz@AHz>tph^td)mXMQ+DCien(OnrfXDnYoZ;#b2Rz3TcaVZ3v_FDpPlvgw znZa$_!aX%~!g9iSzPg%|L8lhawO(M=g_cG-U~Ch)9cpfCOXkJ{cs-_+eh9Sek1HR* zR);4ivoG1y3chSvWD_H-@oh+=4lWzS4F zdb-G%O980cZY?6$Jpg~70Pg(6pk`L}oh1VyW|0D0FbF9dkF~~`h7@z*`tL|pi;@g) z8zAOd$XIK(k-bY6OGoWLro=Ki*iBds-e*V|hJ3;rIiw5@Ny)}Rus#};m>n6l{Bd%? z%y+LWf#;d!M`uX$Y}}5Tc=@z-Vl}I|we@#Dk#3sjA2POv2~LJ(pLJre`@zNJ#!ARv zPwcw+E2grBleU=Wdhncy4oIV)$G?Vbs#I$~l9Ib}mDll_3u^Xy5W{bjpIwWru(l#$D=ne$Q z0=(9w9-ZbjSS=(3hlAP99qE;8V*$f%d|$dG?*r0(q`TvimJ*+&DwwR)o09OpRT&R0 zPD+}y=j9=f66S!;jy?fGQeYWxI4+>G?@C*E043C`3`!(oBez6B@n`1s@6vNsFjto+$g?pC|R>A0`cCdp=8D z&*{(M3^9xq$ToT`BomDctPf4Jvwlr8?m?G>0WmFXwn49Cv|5%~$*y8L_EaKf);MVA z<;qn{IRkOX6Sp6qci)sdW^Hg?+KpIqz7kso9(0&G zQF;Kkms?N}xVRVEwd@bXsqF`FT6=C%gb`~nIFx9ssf7S!2I4ogt~?W0oGuz-xa7>7k}mwuI^>c znh@KUc}JEaZ#K976K=$IwSxxg%4#-`oWVwL6PtfaioQt@ODJov)u>Uec$)Kpa; zluQ-$(TOAtpp;A{*?&bhV@)Wv7|SjkOpHmpQz19z`5u;mRxw?uf4}1ArgMH1-FM^K z0f06Qr3y%gCYW<@aNtR>tnDXIpqX1(DA_3FSI$WmqZ%4NAfZ?n8wkISslACZY?t-( zNr&kkro;BJhCLqI-x1c@KHuMX<2Rl(E@v7U2hZ*yHeYG^HkD*n8xn%D&!2YOD(7RY z&X-FggM**f;Ll5nV?9$T9slV81cc+dIr$6#=4ltHp#|Vo>~_*~e-zWzP1!m*#$gA? zEQ}=&!aI;e@Qgx8syaj%3E#+&Lx@9^c2X=XEP5^$?3S^3g8N3`IYj4l4p-zg5HxZv zl6o0>+-}S)!Rty}{C(q{c7;~MmPOQSL)_v0HwIUsi9Y?M#|$WI-15rrWmFpiIlCMH z5?c2x);KReKe05Io2-65^)%2+SN9oli1ax@Zr`dXVAPZ3iwHxXC|*z{|D9UFW3nhz z(yk}P?-yVd7Fze_c3ihT7yr1v)6!R`jX@8f@B@%aI&12>>buMp!x0nn&Afq=g(oe! z{wUo)6puv5fG7hQjm;uc6RH)D=BSp6&(kG~V=n%n4cFc~pO_`kn}D*;i)Ee=806C? z9<-EO&$LJMgE+kIG0;j$U?_>$ZKX#XMDKF0zQw$NRq*T#`MT$_ApI!S-p0#FMKugD zWMzf7n6QGH(t#YR!=yf^m6-J=KEUwncTc79+g)$LG)m9rNCNY=cJacaa$?I=-wWxv z+grltStfkr$Jh{k=X=+__l9md-NoL}{0P)^a&r2a!wa;>Le(^3a_Q5?(|Z0S>g!0g z)Zh6ox%nVQCG3*m_LZYQV7!RrZLneJ%P)3`Mdu%~^6^^HG|HfF+dg?Y)HnbeV<+g{ zbcP)h08>+-7k_@Kg(7+8Fy{20=CjdtTpZzQ)z*n8NDjd^rx?;zXcYlpgWss=$Sl{8 z7LR#EU+mf=5CfD!_oP#+zJ!t0X>flWdz63eBSebxy8mkDz&-Yf7SPvS zCyDhBX5o%7sS8{)g}!)+w3659_F!!TRLED^%i_5E zi{y}+VkDo#v`4TA8s1@mV_I~7FDjDT42W|36u<*)_E0|5qEXRY)%S%stQlgrg*U>cGDe{OE2t<+-&Xep_g0k!D z0)bBcAplcOTp7kHz%9K5^|eBVb(n~VLt4vC`v6MCzk3J{I84=a`2n3Fab;CiN26Y$ zsD9OYw+ZWW6}#*#V(x{|EFI$p;rlD%xteDIq_7o==nF+QQjGNZcT8GStmp9N`+Yu~ zKf-;g3h4}2G@r5-p;m~8^LV6owFP6UmZ+<$a=@2!SI5$3cS3;XIi zx1E@nKz~-d3jNxn*bWi~5!#V;{k{y}gH*RnskJ>SC19*BlW)lb-lA)446+o|N(Y|DXCYoc=M_GrFa ze8D+0xXZmxB2BTw#w5G>gCcr3Wo-z9($*sw0Kav1vLiu{klTV-ZmFEjk90qvz zEP3d;z>C8K{VnqzJJiohH}ZsMd>!F1uf)1Xb9mh+V5(&q&RRC=P{+>26}Vg*ft}>h zsK*WB5)6JXbI;5&%B?UV)bhj%R3C|ps1wjCC1)A}E&&v|IO-Og!Q+RNEmDna zej^_OjC%~y_noW|%DpZiENIpCd!fw8U_+hWi?m3#k-0#$ zFbkByLG)Z;L<8NJIB+Bw{xS1p)R!JZs*WQ+KpeM>44o4ru(K=Ln36kRFwLN+y{>z! zJvRjM9&64nZ=LbB0=+$s1e0sw`zAEw{592vm1dGnSPAGHt)KCD19A@H{ROWxj?fl% zc|I=%vi$(*#Lt^${W|BoE%I_T&z<*4QYD|YD8{x4!11O3(0cg0{RqL*JZ!Gb3C`5@ zWt7B?KqjCbsCEJ~w7!Y*>vd2|u?GPZKfP>btvP?~oPN(qy7CgN)hSM1$Xi%HYTZ5& z#X~mz;K}*Cj#j>Qzp*bmZz!6JBxR$@oHgM$lVCR#U_Tx2ldehLb-&Od2~C?UwrM%s z*`xG4e|^Cz*RIeNI=G~8@>IE6RIrO51EN$8LFB$m=Kk5H-C$X?dfCmw!UaT z(2ACb`ql^j8ZZr~i6$&j&zHGRJtfVAz+04YMe6_H(?F5z|TNTXu7}nd@ z_c=a3eptw3hYDmzCs1nK^-Y!={%OBLLhf-Ga_92V1s2yFGVu!lf-qq%_ z(_X;rqu#{jXlym~;vWuO=Z#v*RuKG&*%j4UYpfg-cVC8S;$H3vSV-H);Yl&Gl9l$kzdj@KhUWO!o%?zG+aK0Fj*pMO6&EwXy(@uNCVBc)>FryjqygAh z4oSyg{<)a2#|;xR_)!yHBv7P>PgpmEb7BGo=~YMuB}TuCKmOG8a9j;*8B(vB2e=u8P2prd?kbB5)`upVQ)vN-b|Tn=qNwfS*?I$+sg81(g_9T-tLgILVy;o zET>TG_O!O?_o}dC&wg(~a&VmUhs;cZ22??A*4Cb4iwBgZ{9nh$F)^`7}aq(C}iABtx0YFUy9 zppXdM*q-~|RH*8WIcx=0jMtD9sYbbcM*-3w^R}SMH*4s2 zD>v3uJK@+pyZVB+>G*^8kN0Ebdra||05)rA&~ZW2m7@Y%CD6&p$QXjt+=mlM~lQ=dbEISBke|u z=@u3>7Ffoc^c>Nh>bAguxOA4rfcx#x{EEi5*=$1dLbU?h5`X6@*mEc7!G%|DNy%#f zQvj3z+c?`lE+K|9i4nelEwGTb@|>8~s7xbvsz|G(>hn7@NG2+YaE;>8pE0JnI-Bij zQC(0FLmvg~$wIW{UEoZ6de=gWX?gOr4-VJ-EoEtyJH@cUUd`7L$c3x$5pQw?zIkJ4 zaNMd|6s}W3Dad%n(qN;7v*anesy=I>i5rHT2=vgjw~F68>3e9L#Pb;RXwt4tR&AM` z#$nrmp7HC9k>K7U?JpH4I2_N+)mY6+v8T=TMg zdb(K_<4kK=4$4?d<`fWmfn-2S(k0|4R94NCiLSsTyy)c8FQYnGR8{rM)}r4C5DWDK zlB(folU$GNGJMe4h(ggx<@O?kd#s{q|=Ty5*)dyw^opQ1%ax~{2RK%KK>>$;b73J?D9$sap(ANu zQI4bmnNQLt6N;hj=~{H@S#;^(TM!+cDMq!RBz7^lHUAP^~&Wd@VQNQZGFJ7Z!04s5a=ukj7oBe(28y_wH<3)~1@zX%e= zhI%f|SKB-V*ckxq=55pVApkUObs#0hK?Upa^z;OvcC6xOb7SMo>;+8FB?JobiEYgy zwXD#W3rR29p`g-B42WOci@I9tJZi|U%K})y`;6Qf>NW>bWRc-YgMitM!z`tkj40P7L&p-nu z|08cl(j49gygD{EMOz|_BMM(Z852O!0_v@fX`swwvIX{tE*Vt9kISVtvz!Ap(*U~s zW56h63lIyAtM9;6=I+TA36%LruGw?5W8?NFCM8jRpaS?OjkNT9ytsZ20ebN7W*#dK zrm+_zr=VR9p~g{}{Mz(hXrZRl->pgy561;tUq3{qOm|5yztN#7sH}WcpjPx&z8ReC zSB+KtN*!ON^vMmY)4^dQ=Hp|IMO_J&Y>qE^M3Q2W!gbo7K0K|+=Gn+k@krE;{{3M3 z*twlAU8>M#$7i&6i(1OqPzdap)N(HX@!J*AHg;`;IQ%jay}M2)Wz zougU-I>t4#Y=^wIR#u?(G$sSet_$+l-hxXQu)@Sy9!*O#lTKWAKg(PTuPqBNyFQH? zJ9_3kMFLWE_^)A#+h0?WzI>^ncAjzb7mpNF$_-ufqcMF?+~q){SXL3LTHhoz#-W6H899-LaL`HM0;}n) zc#e(WKtefp^C`N~odGkaGkI&uYr&t11gLo%Q+_K6!j7fVukAufO;$`dPSya9P|g5y z78eU&P`(o~>EyoAUTw)zxBEJ~qXvUz$>^0l|Dw?9SlfHrW(>}GfR)sFWt?4j0r@Gs z=$BW`pbs!4o|wp61_`gc)hG6(f&41BX&-@{z_Jek6CeEAih8_t^ zDcjP|LgS7NRn(K}5phi4e}a|iP4749PsTsy0=Ys_$XdVs6oHZU+qz=fpkn&%%Z%81 z>s8-`CC4AJFV=vp-~nniv)HNYF3iZWXOkFq+Ei>`R~{SzByv|-3UrTfe^kz%xAGob zU7v#6(|9j^rg>otk**|CNVQGf@c!IWpptWCkWE-u{w(9IO&b4o?8Xr|r$EUWdvf6O z`Qv=igkbJZZL8ky2sWFm?%H5O+7-`h>!JSXCw69m;nxGxW0~>Tp`zR@UL;qj3h;~F zz+a>9bfV&7NV^TDVA84~Ers=r%XMnv?&mRX_d49>?VXmH;`^I6 zLOm}M1ix+dY@e+CF*5)0@G`?<`iz#as$;txpO8kn*BqBJjB$EOg%_04wTOhEqjb;B z5|NjFO<&9FN^3pi#1z)ka2L5&9OHW^-lYi9zTzDju1d2sL8D~Jvtj$RWB5oEa`LRf z>A8DWpu>lN(7^~H=0Y?L9Jb7k#!RBl*>@K7>_~f?J`H2D{$KR}1XLUuW3UCuvVv33 z<%5m#i;MwS_&X1#Q_0VH5=E{9>ql~1!p6yDiDQ8+JnJ8YgmB%r%FOJKU?S+;V8r*+ z%52d@qU*yHf&xw$%r4|V-+8AbSO`(lP_IOaJ;Mn-T-$Z#Rn~i;&NwVPY3pS~YT3~e z!_yCu+)AIWU|XA35In`4Yw)Nv@}3KcRubUQZO+qJb2ywn&Y8*U^?O3nuDn5p{s~XMM&g{%wUsajv&fJq@IPd4%1-q# z?s=yhl0Mt&nr+;1FI$Jmj|@MgjQKdzq<#ptHZ%k%$j!o?6{YeK8%Kwy4k+Afb%Qr7GJ^TCKw!O#l+6!D8%%9XF$sR zGMUmr_fB1~#|EoC*H(&W`qbt_2e&_LtU$O6AJRe)B^ds}turJc_HHmF(J*MgLlHub zmE7XpCHPaw?N8eX<&1Fjrykip$2|bXg2?PYwi)q*^J9b|F@XI3Ojo?-=$8#vXrigf z3;qJyrC*exe0B&)mX~g+quVb@$5c9KT^NCXZzwaQ?Urb1DO;jwLOWePQ5I}?`K;G6 z2Awhi_)w7EbK1;&_nZgl`}o8}q;`y$UatH$M!!$9(5jKK=vx3`f>ZY2dS>NQgWZTW zvzA7buDeUiKjbfeCNn=?nrpD=?z0Ft zHR4@HDSe_e`4F?XR27nF(sN~mAI%67fvQmZ{Nq6g3KlyAh)hWDli+|W8yY3g%lUNL zr&pZ#i2mh{qJwBI@06Dj%8z8xDA7T34MNM*jqCO{xWV!%`I{+aV;(z=jDH9os|C+r zq);(Fcuz}9tJEIe_JZZ+%Zgx?4US(P2dMX*yTkBAD<4YWgM;K{Zg8vuj^NqT)9h?* zL;6-Tim;{R5$+53`_y*IL*=S=rEio$vH&|522h73XJ5I2rt4himqUNyCPB&{-OC5E z3Da-1{t~^2rWtAV`y~C|(j0MF#K`^8|KxQH$-l+lnkxWt(?q=B0VZJtpWO`T>=(ij z60=Ds1D^(cvIgzrAGn{PA#=)MA|oZW4SoN6_2iQd;er?e8nP(j+LqjGtwUx>eLWw& zzM_^^;+IZD+elFE3kHUW4KJ`EDJ>dG`y-jJy$>H$zy>lD5qDTVC0Dv1{C+$oi>v>Xm{n`XqmRf<5vdswp z<yzV6V=Z@D}m(Z=l&rL*!*0iGz zI{UL{&s6<|DQMF4D$Vh+1rQw5(19CL29t%Fy_;g8IMVz>^($jC-=@LZ>_EpcbLidv zGq*XBv0B7!s%X`4B4$Ym35lN`@J2S_@k!L}$)ftB;dHTRuR3sr0$1P|FPH?up-FIu z(G#xm@tK*IA!maSmQzO%a*f+DgIsI?e2^1J2ns#f2 zD;$<37e7AZv&AjR`7DM#@y`PUU`I+VC-OmW8(?dh%Ms}lxMpXR67~3%no3-Jyd6C~ zeK)31b5+%2a6P6Av|S!sa{-n`(Gaa!MjamMTo5kmm zpUk&=e&G6DIJg`32HdGCW7^x=YHRYoS~|K|I*Pna1^49?ad8j~be3r_^x94nhCcuu zhZ>~@B0q=U)=o~U9dv)Du68#>8OAd=0sW0$4n5J&h2E0|{Jn2AqW$mNc@jgg#P@5$ z_ajax`&0O)ynCL<>pZg}M)ZVH(mX~iDN69NyU}*Oj*sBtM-Y-+?f-a@P!t}5Ann=O z*g&hSsoC56^T*3MBSW7<8a2`W%a<>4h}&0eu>Nx`a9dGbxk&`EeX^FIrP!C0jBFPR fsQ>tuapn0PWb2aei^0>sch99I + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/badges/windows-store-badge.svg b/static/images/badges/windows-store-badge.svg new file mode 100755 index 000000000..21c139edd --- /dev/null +++ b/static/images/badges/windows-store-badge.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/svgs/download/mac-badge.svg b/static/svgs/download/mac-badge.svg new file mode 100755 index 000000000..072b425a1 --- /dev/null +++ b/static/svgs/download/mac-badge.svg @@ -0,0 +1,46 @@ + + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/svgs/download/ms-badge.svg b/static/svgs/download/ms-badge.svg new file mode 100755 index 000000000..21c139edd --- /dev/null +++ b/static/svgs/download/ms-badge.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +