diff options
| author | trisusilo48 <tri.susilo@altama.co.id> | 2024-07-10 15:58:51 +0700 |
|---|---|---|
| committer | trisusilo48 <tri.susilo@altama.co.id> | 2024-07-10 15:58:51 +0700 |
| commit | 2e3c726bc8217f3960cfecec44b81303b03de72b (patch) | |
| tree | 1b85ced7f61f3e4c3f1f27b577b37aa161615065 | |
| parent | 2b3bd9c0a454dbad69ce29cee877bfb1fca5dfa6 (diff) | |
| parent | a99bf6480eea556e53b85e6db45f3b8c2361e693 (diff) | |
Merge branch 'release' into development
# Conflicts:
# src/pages/shop/product/variant/[slug].jsx
248 files changed, 14335 insertions, 3140 deletions
@@ -37,4 +37,9 @@ next-env.d.ts package-lock.json -.vscode
\ No newline at end of file +.vscode + +sw.js +workbox-* + +.unlighthouse
\ No newline at end of file diff --git a/next.config.js b/next.config.js index 8e1ceda3..12aa2f3e 100644 --- a/next.config.js +++ b/next.config.js @@ -1,9 +1,9 @@ /** @type {import('next').NextConfig} */ const withPWA = require('next-pwa')({ dest: 'public', - register: true, - disable: process.env.NODE_ENV === 'development', - skipWaiting: true + register: true, + disable: process.env.NODE_ENV === 'development', + skipWaiting: true }) const nextConfig = { @@ -30,6 +30,26 @@ const nextConfig = { hostname: 'erp.indoteknik.com' } ] + }, + async rewrites() { + return [ + { + source: '/solr/:path*', + destination: 'http://34.101.189.218:8983/solr/:path*' // Proxy to Solr + } + ] + }, + async headers() { + return [ + { + source: '/solr/:path*', + headers: [ + { key: 'Access-Control-Allow-Origin', value: '*' }, + { key: 'Access-Control-Allow-Methods', value: 'GET, POST, OPTIONS, PUT, DELETE' }, + { key: 'Access-Control-Allow-Headers', value: '*' } + ] + } + ] } } diff --git a/package.json b/package.json index 33f6dd38..28fbc5d8 100644 --- a/package.json +++ b/package.json @@ -26,15 +26,19 @@ "cookies-next": "^2.1.1", "flowbite": "^1.6.4", "framer-motion": "^7.10.3", + "http-proxy-middleware": "^3.0.0", "lodash-contrib": "^4.1200.1", "lucide-react": "^0.279.0", "midtrans-client": "^1.3.1", - "next": "13.0.0", + "moment": "^2.29.4", + "next": "^13.5.6", "next-auth": "^4.22.3", "next-progress": "^2.2.0", "next-pwa": "^5.6.0", "next-seo": "^5.15.0", + "node-fetch": "^3.3.2", "nodemailer": "^6.8.0", + "primereact": "^10.6.6", "react": "18.2.0", "react-dom": "18.2.0", "react-google-recaptcha": "^2.1.0", @@ -44,11 +48,17 @@ "react-lazy-load": "^4.0.1", "react-lazy-load-image-component": "^1.5.5", "react-loading-skeleton": "^3.3.1", + "react-multi-select-component": "^4.3.4", "react-query": "^3.39.3", - "react-select": "^5.7.0", + "react-select": "^5.8.0", + "react-web-share": "^2.0.2", + "sharp": "^0.33.2", + "snakecase-keys": "^5.5.0", + "striptags": "^3.2.0", "swiper": "^8.4.4", "tw-merge": "^0.0.1-alpha.3", "usehooks-ts": "^2.9.1", + "xlsx": "^0.18.5", "xmlbuilder": "^15.1.1", "yup": "^0.32.11", "zod": "^3.22.4", @@ -61,6 +71,7 @@ "@types/react": "^18.2.31", "@types/react-dom": "^18.2.14", "@types/react-google-recaptcha": "^2.1.7", + "@types/react-lazy-load-image-component": "^1.6.3", "autoprefixer": "^10.4.14", "eslint": "8.26.0", "eslint-config-next": "13.0.0", diff --git a/public/images/BG-FLASH-SALE-IDUL-FITRI.jpg b/public/images/BG-FLASH-SALE-IDUL-FITRI.jpg Binary files differnew file mode 100644 index 00000000..6f699ae7 --- /dev/null +++ b/public/images/BG-FLASH-SALE-IDUL-FITRI.jpg diff --git a/public/images/GAMBAR-BG-FLASH-SALE.jpg b/public/images/BG-FLASH-SALE.jpg Binary files differindex db26136a..db26136a 100644 --- a/public/images/GAMBAR-BG-FLASH-SALE.jpg +++ b/public/images/BG-FLASH-SALE.jpg diff --git a/public/images/TKDN.png b/public/images/TKDN.png Binary files differnew file mode 100644 index 00000000..dba43d15 --- /dev/null +++ b/public/images/TKDN.png diff --git a/public/images/empty_cart.svg b/public/images/empty_cart.svg new file mode 100644 index 00000000..76e4db1a --- /dev/null +++ b/public/images/empty_cart.svg @@ -0,0 +1,3601 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#EBEBEB;} + .st1{fill:#DBDBDB;} + .st2{display:none;} + .st3{display:inline;fill:#DBDBDB;} + .st4{fill:#263238;} + .st5{fill:none;} + .st6{fill:#FFFFFF;} + .st7{fill:#CC0000;} + .st8{fill:#EA0000;} + .st9{fill:none;stroke:#FFFFFF;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} + .st10{fill:#E2AC00;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;} + .st11{enable-background:new ;} + .st12{fill:#4C4C4C;} + .st13{font-family:'Gilroy-Black';} + .st14{font-size:16.8015px;} + .st15{fill:none;stroke:#263238;stroke-width:2;stroke-miterlimit:10;} + .st16{opacity:0.2;enable-background:new ;} + .st17{opacity:0.1;enable-background:new ;} + .st18{opacity:0.1;} + .st19{fill:#455A64;} + .st20{fill:#37474F;} + .st21{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;} + .st22{fill:#F7A9A0;} + .st23{fill:#FFC727;} + .st24{fill:none;stroke:#263238;stroke-miterlimit:10;} + .st25{fill:#AD6359;} + .st26{opacity:0.4;} + .st27{fill:#000102;} + .st28{opacity:0.1;fill:#000102;enable-background:new ;} + .st29{opacity:0.4;fill:#000102;enable-background:new ;} + .st30{fill:#C7C7C7;} + .st31{fill:#FF9ABB;} +</style> +<g id="Background_Complete"> + <g> + <g id="IaQ7Yo_4_"> + <g> + <g> + <path class="st0" d="M139.9,316c-1.5,1.5-3.3,2.2-5.3,2.6c-0.9,0.2-1.8,0.3-2.6,0.5h-4.6c-1.5-0.3-3.1-0.4-4.6-0.8 + c-6.1-1.2-11.6-3.9-16.7-7.4c-11.9-8-21.8-18-29.8-30c-3.4-5.1-6-10.5-7.3-16.5c-0.3-1.6-0.5-3.2-0.8-4.7v-4.4 + c0.3-1.4,0.5-2.9,1-4.3c0.5-1.3,1.2-2.5,1.9-3.8c0.4,0.3,0.6,0.5,0.7,0.6c6.3,6.3,12.6,12.6,18.9,18.9c0.4,0.4,0.5,0.7,0.3,1.2 + c-1,3.4-0.3,6.5,2,9.2c5.3,6.1,11,11.8,17.1,17.1c2.7,2.4,5.8,3,9.2,2c0.4-0.1,0.7-0.2,1.1,0.2c6.4,6.4,12.8,12.8,19.2,19.2 + C139.7,315.7,139.8,315.9,139.9,316z"/> + <path class="st0" d="M151,305c-2.2,2.2-4.4,4.4-6.7,6.7c-0.2,0.2-0.4,0.3-0.5,0.4c-6.5-6.5-12.9-12.9-19.4-19.3 + c0.5-0.4,1-0.9,1.5-1.4c1.9-1.9,3.8-3.8,5.7-5.7c1.6-1.6,3.3-1.6,4.9,0c4.8,4.8,9.6,9.6,14.4,14.4 + C152.6,301.7,152.6,303.4,151,305z"/> + <path class="st0" d="M101.9,255.6c-2.5,2.4-5,4.7-7.5,7.1c-6.2-6.2-12.6-12.6-19.1-19.1c0.1-0.1,0.2-0.3,0.4-0.4 + c2.3-2.3,4.5-4.5,6.8-6.8c1.5-1.5,3.2-1.5,4.7,0c4.9,4.9,9.7,9.7,14.6,14.6C103.3,252.4,103.3,254.1,101.9,255.6z"/> + </g> + </g> + </g> + </g> + <g> + <path class="st1" d="M444.7,205.7l5.5-8.9l-2.7-1.7c-0.8-0.5-1.2-1.4-1.2-2.3c0-0.5,0.1-1,0-1.6c0-0.9,0.5-1.8,1.3-2.3l2.8-1.5 + l-4.9-9.2l-2.8,1.5c-0.8,0.4-1.8,0.4-2.6-0.2c-0.4-0.3-0.9-0.6-1.3-0.8c-0.8-0.5-1.3-1.3-1.3-2.3l0.1-3.2l-10.4-0.3l-0.1,3.2 + c0,0.9-0.6,1.8-1.5,2.2c-0.2,0.1-0.5,0.2-0.7,0.3s-0.4,0.2-0.7,0.4c-0.8,0.5-1.8,0.5-2.6,0l-2.7-1.7l-5.5,8.9l2.7,1.7 + c0.8,0.5,1.2,1.4,1.2,2.3c0,0.5-0.1,1-0.1,1.6c0,0.9-0.5,1.8-1.3,2.3l-2.8,1.5l4.9,9.2l2.8-1.5c0.8-0.4,1.8-0.4,2.6,0.2 + c0.4,0.3,0.9,0.6,1.3,0.8c0.8,0.5,1.3,1.3,1.3,2.3l-0.1,3.2l10.4,0.3l0.1-3.2c0-0.9,0.6-1.8,1.5-2.2c0.2-0.1,0.5-0.2,0.7-0.3 + s0.4-0.2,0.7-0.4c0.8-0.5,1.8-0.5,2.6,0L444.7,205.7z M435.9,199.1c-4.2,2.2-9.3,0.7-11.6-3.5c-2.2-4.2-0.7-9.4,3.5-11.6 + c4.2-2.2,9.4-0.7,11.6,3.5S440.1,196.9,435.9,199.1z"/> + <path class="st1" d="M75.4,315.9l-3.7-6.3l-1.9,1.1c-0.6,0.3-1.3,0.3-1.8-0.1c-0.3-0.2-0.6-0.4-0.9-0.5c-0.6-0.3-1-0.9-1-1.5v-2.2 + h-7.3v2.2c0,0.7-0.4,1.2-1,1.5c-0.3,0.2-0.6,0.3-0.9,0.5c-0.6,0.4-1.3,0.4-1.8,0.1l-1.9-1.1l-3.7,6.3l1.9,1.1 + c0.6,0.3,0.9,1,0.9,1.6c0,0.2,0,0.4,0,0.5c0,0.2,0,0.4,0,0.5c0,0.7-0.3,1.3-0.8,1.6l-2,1.1l3.7,6.3l1.9-1.1 + c0.6-0.3,1.3-0.3,1.8,0.1c0.3,0.2,0.6,0.4,0.9,0.5c0.6,0.3,1,0.9,1,1.5v2.2h7.3v-2.2c0-0.7,0.4-1.2,1-1.5c0.3-0.2,0.6-0.3,0.9-0.5 + c0.6-0.4,1.3-0.4,1.8-0.1l1.9,1.1l3.7-6.3l-1.9-1.1c-0.6-0.3-0.9-1-0.8-1.6c0-0.2,0-0.4,0-0.5c0-0.2,0-0.4,0-0.5 + c0-0.7,0.3-1.3,0.9-1.6L75.4,315.9z M68.4,319.2c0,3.3-2.7,6-6,6s-6-2.7-6-6s2.7-6,6-6C65.7,313.2,68.4,315.8,68.4,319.2z"/> + <g> + <g> + <path class="st0" d="M345.6,33.2c-15.7,0-28.5,12.8-28.5,28.5s12.8,28.5,28.5,28.5s28.5-12.8,28.5-28.5 + C374,46,361.3,33.2,345.6,33.2z M345.6,75c-7.4,0-13.3-6-13.3-13.3c0-7.4,6-13.3,13.3-13.3c7.4,0,13.3,6,13.3,13.3 + C358.9,69.1,352.9,75,345.6,75z"/> + <polygon class="st0" points="351,34.4 340.1,34.4 340.7,26.6 350.4,26.6 "/> + <polygon class="st0" points="330.2,38.1 322.4,45.8 317.4,39.9 324.3,33 "/> + <polygon class="st0" points="318,55.4 318,66.4 310.3,65.8 310.3,56.1 "/> + <polygon class="st0" points="321.7,76.3 329.5,84 323.6,89.1 316.7,82.2 "/> + <polygon class="st0" points="339.1,88.4 350,88.4 349.4,96.2 339.7,96.2 "/> + <polygon class="st0" points="359.9,84.7 367.7,77 372.7,82.9 365.9,89.8 "/> + <polygon class="st0" points="372.1,67.4 372.1,56.4 379.8,57 379.8,66.8 "/> + <polygon class="st0" points="368.4,46.5 360.6,38.8 366.6,33.7 373.4,40.6 "/> + </g> + </g> + </g> +</g> +<g id="Background_Simple" class="st2"> + <path class="st3" d="M442.6,278.9c0,0.7-0.5,1.2-1.2,1.2s-1.2-0.5-1.2-1.2s0.5-1.2,1.2-1.2S442.6,278.3,442.6,278.9z M437.9,152 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,152,437.9,152z M434.3,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,148.4,434.3,148.4z M434.3,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S434.9,213.1,434.3,213.1z M437.9,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,252.6,437.9,252.6z + M437.9,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C439.1,138.2,438.5,137.6,437.9,137.6z M434.3,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,155.6,434.3,155.6z M437.9,173.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,173.6,437.9,173.6z M437.9,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C439.1,231.6,438.5,231,437.9,231z M437.9,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,159.2,437.9,159.2z + M434.3,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,170,434.3,170z M437.9,274.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,274.1,437.9,274.1z M437.9,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C439.1,181.3,438.5,180.7,437.9,180.7z M437.9,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S438.5,266.9,437.9,266.9z M434.3,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,191.5,434.3,191.5z + M437.9,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,223.8,437.9,223.8z M434.3,205.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,205.9,434.3,205.9z M437.9,187.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,187.9,437.9,187.9z M437.9,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S438.5,238.2,437.9,238.2z M434.3,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,162.8,434.3,162.8z + M437.9,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,245.4,437.9,245.4z M434.3,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C435.5,177.7,434.9,177.1,434.3,177.1z M437.9,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,209.5,437.9,209.5z M437.9,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,166.4,437.9,166.4z M434.3,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S434.9,198.7,434.3,198.7z M434.3,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C435.5,134.6,434.9,134,434.3,134z + M434.3,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,141.2,434.3,141.2z M434.3,184.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,184.3,434.3,184.3z M437.9,195.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,195.1,437.9,195.1z M437.9,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S438.5,216.7,437.9,216.7z M437.9,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,259.8,437.9,259.8z + M437.9,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C439.1,145.4,438.5,144.8,437.9,144.8z M437.9,202.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S438.5,202.3,437.9,202.3z M441.5,256.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C442.6,256.7,442.1,256.2,441.5,256.2z M441.5,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C442.6,192,442.1,191.5,441.5,191.5z M441.5,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S442.1,220.2,441.5,220.2z M441.5,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,263.4,441.5,263.4z + M441.5,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,234.6,441.5,234.6z M441.5,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C442.6,177.7,442.1,177.1,441.5,177.1z M441.5,198.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,198.7,441.5,198.7z M441.5,270.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C442.6,271.1,442.1,270.5,441.5,270.5z M441.5,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C442.6,242.3,442.1,241.8,441.5,241.8z M441.5,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C442.6,206.4,442.1,205.9,441.5,205.9z M441.5,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C442.6,213.6,442.1,213.1,441.5,213.1z M441.5,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,249,441.5,249z + M441.5,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,184.3,441.5,184.3z M441.5,162.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,162.8,441.5,162.8z M441.5,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C442.6,170.5,442.1,170,441.5,170z M441.5,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C442.6,228,442.1,227.4,441.5,227.4z M445,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S445.7,281.3,445,281.3z M445,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C446.2,181.3,445.7,180.7,445,180.7z + M441.5,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C442.6,148.9,442.1,148.4,441.5,148.4z M445,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,245.4,445,245.4z M445,216.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,216.7,445,216.7z M445,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S445.7,187.9,445,187.9z M445,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,195.1,445,195.1z M445,274.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,274.1,445,274.1z M445,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,238.2,445,238.2z M445,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S445.7,252.6,445,252.6z M441.5,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,155.6,441.5,155.6z + M445,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,266.9,445,266.9z M445,259.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,259.8,445,259.8z M445,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S445.7,209.5,445,209.5z M445,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,202.3,445,202.3z M445,223.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,223.8,445,223.8z M441.5,141.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S442.1,141.2,441.5,141.2z M441.5,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C442.6,134.6,442.1,134,441.5,134z M445,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C446.2,231.6,445.7,231,445,231z M445,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C446.2,138.2,445.7,137.6,445,137.6z M445,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C446.2,145.4,445.7,144.8,445,144.8z M445,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,173.6,445,173.6z + M445,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,159.2,445,159.2z M445,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S445.7,166.4,445,166.4z M445,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S445.7,152,445,152z M448.6,277.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,277.7,448.6,277.7z M448.6,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,284.9,448.6,284.9z M448.6,270.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C449.8,271.1,449.3,270.5,448.6,270.5z M434.3,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S434.9,234.6,434.3,234.6z M434.3,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S434.9,263.4,434.3,263.4z M434.3,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,256.2,434.3,256.2z + M434.3,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,220.2,434.3,220.2z M434.3,249 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,249,434.3,249z M434.3,241.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S434.9,241.8,434.3,241.8z M434.3,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C435.5,271.1,434.9,270.5,434.3,270.5z M434.3,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C435.5,228,434.9,227.4,434.3,227.4z M430.7,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,145.4,431.3,144.8,430.7,144.8z M430.7,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,195.6,431.3,195.1,430.7,195.1z M427.1,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S427.7,141.2,427.1,141.2z M430.7,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,209.5,430.7,209.5z + M430.7,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,159.2,430.7,159.2z M427.1,162.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S427.7,162.8,427.1,162.8z M427.1,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C428.3,170.5,427.7,170,427.1,170z M430.7,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S431.3,223.8,430.7,223.8z M430.7,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S431.3,245.4,430.7,245.4z M430.7,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,187.9,430.7,187.9z + M430.7,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C431.9,202.8,431.3,202.3,430.7,202.3z M427.1,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S427.7,155.6,427.1,155.6z M430.7,152c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,152,430.7,152z M430.7,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,231.6,431.3,231,430.7,231z M430.7,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,266.9,430.7,266.9z + M430.7,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C431.9,181.3,431.3,180.7,430.7,180.7z M430.7,259.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S431.3,259.8,430.7,259.8z M427.1,134c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C428.3,134.6,427.7,134,427.1,134z M431.3,132.7l-1.4-0.2c0.2,0.2,0.5,0.3,0.8,0.3 + C430.9,132.8,431.1,132.8,431.3,132.7z M430.7,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,174.1,431.3,173.6,430.7,173.6z M430.7,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,238.7,431.3,238.2,430.7,238.2z M430.7,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,138.2,431.3,137.6,430.7,137.6z M427.1,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,148.9,427.7,148.4,427.1,148.4z M430.7,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,217.2,431.3,216.7,430.7,216.7z M430.7,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S431.3,166.4,430.7,166.4z M430.7,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C431.9,253.1,431.3,252.6,430.7,252.6z M427.1,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S427.7,198.7,427.1,198.7z M427.1,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,213.6,427.7,213.1,427.1,213.1z M427.1,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,206.4,427.7,205.9,427.1,205.9z M427.1,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S427.7,184.3,427.1,184.3z M427.1,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,242.3,427.7,241.8,427.1,241.8z M427.1,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S427.7,249,427.1,249z + M427.1,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C428.3,177.7,427.7,177.1,427.1,177.1z M427.1,263.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S427.7,263.4,427.1,263.4z M427.1,234.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S427.7,234.6,427.1,234.6z M427.1,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,192,427.7,191.5,427.1,191.5z M427.1,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,256.7,427.7,256.2,427.1,256.2z M427.1,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S427.7,220.2,427.1,220.2z M427.1,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C428.3,228,427.7,227.4,427.1,227.4z M448.6,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S449.3,263.4,448.6,263.4z M448.6,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,234.6,448.6,234.6z + M448.6,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C449.8,242.3,449.3,241.8,448.6,241.8z M448.6,256.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C449.8,256.7,449.3,256.2,448.6,256.2z M448.6,249c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,249,448.6,249z M423.5,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S424.2,202.3,423.5,202.3z M423.5,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,252.6,423.5,252.6z + M423.5,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,259.8,423.5,259.8z M423.5,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,245.4,423.5,245.4z M423.5,180.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C424.7,181.3,424.2,180.7,423.5,180.7z M423.5,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S424.2,195.1,423.5,195.1z M423.5,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S424.2,209.5,423.5,209.5z M423.5,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,152,423.5,152z M423.5,223.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,223.8,423.5,223.8z M423.5,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,166.4,423.5,166.4z M423.5,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S424.2,187.9,423.5,187.9z M423.5,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C424.7,231.6,424.2,231,423.5,231z + M423.5,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C424.7,138.2,424.2,137.6,423.5,137.6z M423.5,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,173.6,423.5,173.6z M423.5,159.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,159.2,423.5,159.2z M423.5,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C424.7,145.4,424.2,144.8,423.5,144.8z M423.5,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S424.2,216.7,423.5,216.7z M423.5,132.8c0.6,0,1-0.4,1.1-0.9l-2.3-0.3C422.3,132.3,422.8,132.8,423.5,132.8z M423.5,238.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S424.2,238.2,423.5,238.2z M419.9,220.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,220.2,419.9,220.2z M419.9,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S420.6,184.3,419.9,184.3z M419.9,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C421.1,228,420.6,227.4,419.9,227.4z M419.9,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S420.6,256.2,419.9,256.2z M419.9,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,141.2,419.9,141.2z + M419.9,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,241.8,419.9,241.8z M419.9,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,148.4,419.9,148.4z M419.9,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,191.5,419.9,191.5z M419.9,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S420.6,162.8,419.9,162.8z M419.9,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,170,419.9,170z M419.9,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C421.1,177.7,420.6,177.1,419.9,177.1z M419.9,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,155.6,419.9,155.6z M419.9,213.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,213.1,419.9,213.1z M419.9,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S420.6,234.6,419.9,234.6z M419.9,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C421.1,134.6,420.6,134,419.9,134z + M419.9,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,249,419.9,249z M419.9,198.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S420.6,198.7,419.9,198.7z M419.9,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S420.6,205.9,419.9,205.9z M448.6,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,213.6,449.3,213.1,448.6,213.1z M448.6,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,228,449.3,227.4,448.6,227.4z M448.6,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S449.3,220.2,448.6,220.2z M448.6,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,206.4,449.3,205.9,448.6,205.9z M448.6,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,192,449.3,191.5,448.6,191.5z M448.6,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,177.7,449.3,177.1,448.6,177.1z M448.6,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S449.3,198.7,448.6,198.7z M448.6,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,184.3,448.6,184.3z + M416.3,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,216.7,416.3,216.7z M416.3,231c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C417.5,231.6,417,231,416.3,231z M416.3,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S417,202.3,416.3,202.3z M416.3,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S417,159.2,416.3,159.2z M416.3,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,252.6,416.3,252.6z + M416.3,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C417.5,181.3,417,180.7,416.3,180.7z M416.3,166.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,166.4,416.3,166.4z M416.3,209.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,209.5,416.3,209.5z M416.3,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S417,195.1,416.3,195.1z M416.3,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,187.9,416.3,187.9z + M416.3,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,223.8,416.3,223.8z M416.3,152c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,152,416.3,152z M416.3,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C417.5,138.2,417,137.6,416.3,137.6z M416.3,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,173.6,416.3,173.6z + M416.3,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,245.4,416.3,245.4z M415.4,130.9 + c-0.2,0.2-0.3,0.5-0.3,0.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.2-0.1-0.4-0.2-0.6L415.4,130.9z M416.3,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C417.5,145.4,417,144.8,416.3,144.8z M416.3,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S417,238.2,416.3,238.2z M448.6,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,148.9,449.3,148.4,448.6,148.4z M448.6,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C449.8,170.5,449.3,170,448.6,170z M452.2,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C453.4,289,452.9,288.5,452.2,288.5z M448.6,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S449.3,155.6,448.6,155.6z M448.6,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,162.8,448.6,162.8z + M448.6,134.6l-0.9-0.1c-0.1,0.2-0.3,0.4-0.3,0.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.2,0-0.3-0.1-0.5L448.6,134.6z + M452.2,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,274.1,452.2,274.1z M452.2,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,281.3,452.2,281.3z M448.6,141.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S449.3,141.2,448.6,141.2z M452.2,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S452.9,245.4,452.2,245.4z M452.2,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,266.9,452.2,266.9z + M452.2,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,253.1,452.9,252.6,452.2,252.6z M452.2,259.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,259.8,452.2,259.8z M452.2,216.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,217.2,452.9,216.7,452.2,216.7z M452.2,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S452.9,209.5,452.2,209.5z M452.2,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S452.9,223.8,452.2,223.8z M452.2,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,231.6,452.9,231,452.2,231z + M452.2,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,238.7,452.9,238.2,452.2,238.2z M409.1,130.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,130.4,409.1,130.4z M409.1,231c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C410.3,231.6,409.8,231,409.1,231z M409.1,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C410.3,138.2,409.8,137.6,409.1,137.6z M409.1,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C410.3,174.1,409.8,173.6,409.1,173.6z M412.7,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S413.4,198.7,412.7,198.7z M412.7,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S413.4,155.6,412.7,155.6z + M409.1,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,159.2,409.1,159.2z M409.1,223.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,223.8,409.1,223.8z M412.7,213.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C413.9,213.6,413.4,213.1,412.7,213.1z M412.7,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C413.9,177.7,413.4,177.1,412.7,177.1z M412.7,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S413.4,249,412.7,249z M409.1,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,152,409.1,152z M412.7,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C413.9,148.9,413.4,148.4,412.7,148.4z M412.7,191.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C413.9,192,413.4,191.5,412.7,191.5z M412.7,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S413.4,162.8,412.7,162.8z M412.7,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S413.4,184.3,412.7,184.3z M409.1,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,166.4,409.1,166.4z + M412.7,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C413.9,242.3,413.4,241.8,412.7,241.8z M412.7,220.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S413.4,220.2,412.7,220.2z M409.1,180.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C410.3,181.3,409.8,180.7,409.1,180.7z M409.1,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C410.3,202.8,409.8,202.3,409.1,202.3z M412.7,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C413.9,170.5,413.4,170,412.7,170z M409.1,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C410.3,217.2,409.8,216.7,409.1,216.7z M409.1,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S409.8,209.5,409.1,209.5z M412.7,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C413.9,206.4,413.4,205.9,412.7,205.9z M409.1,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C410.3,195.6,409.8,195.1,409.1,195.1z M409.1,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C410.3,145.4,409.8,144.8,409.1,144.8z M412.7,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C413.9,228,413.4,227.4,412.7,227.4z M412.7,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S413.4,234.6,412.7,234.6z M409.1,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,187.9,409.1,187.9z + M412.7,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S413.4,141.2,412.7,141.2z M412.7,134 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C413.9,134.6,413.4,134,412.7,134z M401.9,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,238.2,401.9,238.2z M405.5,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S406.2,234.6,405.5,234.6z M401.9,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,223.8,401.9,223.8z + M405.5,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,220.2,405.5,220.2z M398.4,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,148.9,399,148.4,398.4,148.4z M405.5,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,170,405.5,170z M401.9,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C403.1,145.4,402.6,144.8,401.9,144.8z M401.9,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S402.6,202.3,401.9,202.3z M398.4,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S399,155.6,398.4,155.6z + M401.9,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,173.6,401.9,173.6z M405.5,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,155.6,405.5,155.6z M401.9,152c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,152,401.9,152z M398.4,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S399,234.6,398.4,234.6z M399.1,129l-0.7-0.1l-0.9-0.1c0.2,0.3,0.5,0.4,0.9,0.4C398.6,129.3,398.9,129.1,399.1,129z M398.4,227.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,228,399,227.4,398.4,227.4z M398.4,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S399,162.8,398.4,162.8z M401.9,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S402.6,166.4,401.9,166.4z M401.9,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,130.4,401.9,130.4z + M405.5,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,213.1,405.5,213.1z M398.4,205.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,206.4,399,205.9,398.4,205.9z M398.4,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,170.5,399,170,398.4,170z M405.5,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S406.2,141.2,405.5,141.2z M405.5,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C406.7,177.7,406.2,177.1,405.5,177.1z M401.9,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S402.6,195.1,401.9,195.1z M401.9,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,216.7,401.9,216.7z + M405.5,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,198.7,405.5,198.7z M405.5,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,148.4,405.5,148.4z M405.5,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,162.8,405.5,162.8z M398.4,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S399,184.3,398.4,184.3z M409.1,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S409.8,245.4,409.1,245.4z + M401.9,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C403.1,231.6,402.6,231,401.9,231z M405.5,191.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,191.5,405.5,191.5z M398.4,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,192,399,191.5,398.4,191.5z M398.4,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S399,220.2,398.4,220.2z M409.1,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C410.3,238.7,409.8,238.2,409.1,238.2z M401.9,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S402.6,187.9,401.9,187.9z M405.5,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C406.7,228,406.2,227.4,405.5,227.4z M401.9,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C403.1,181.3,402.6,180.7,401.9,180.7z M405.5,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S406.2,241.8,405.5,241.8z M398.4,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S399,141.2,398.4,141.2z + M405.5,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S406.2,205.9,405.5,205.9z M401.9,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,209.5,401.9,209.5z M405.5,134c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C406.7,134.6,406.2,134,405.5,134z M398.4,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C399.5,213.6,399,213.1,398.4,213.1z M398.4,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S399,198.7,398.4,198.7z M401.9,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S402.6,159.2,401.9,159.2z + M398.4,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,134.6,399,134,398.4,134z M398.4,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C399.5,177.7,399,177.1,398.4,177.1z M401.9,137.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C403.1,138.2,402.6,137.6,401.9,137.6z M405.5,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S406.2,184.3,405.5,184.3z M463,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S463.7,292.1,463,292.1z M463,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C464.2,271.1,463.7,270.5,463,270.5z + M463,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,284.9,463,284.9z M463,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,277.7,463,277.7z M391.2,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C392.4,213.6,391.8,213.1,391.2,213.1z M391.2,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S391.8,155.6,391.2,155.6z M384,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C385.2,134.6,384.6,134,384,134z + M387.6,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C388.8,195.6,388.2,195.1,387.6,195.1z M394.8,195.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,195.1,394.8,195.1z M394.8,231c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C396,231.6,395.4,231,394.8,231z M384,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S384.6,205.9,384,205.9z M391.2,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C392.4,206.4,391.8,205.9,391.2,205.9z M387.6,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S388.2,209.5,387.6,209.5z M384,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,162.8,384,162.8z + M391.2,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S391.8,184.3,391.2,184.3z M394.8,202.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,202.3,394.8,202.3z M384,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,148.4,384,148.4z M384,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S384.6,155.6,384,155.6z M384,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,184.3,384,184.3z M391.2,227.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C392.4,228,391.8,227.4,391.2,227.4z M394.8,216.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,216.7,394.8,216.7z M391.2,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C392.4,170.5,391.8,170,391.2,170z M387.6,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C388.8,138.2,388.2,137.6,387.6,137.6z M394.8,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S395.4,159.2,394.8,159.2z M387.6,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C388.8,181.3,388.2,180.7,387.6,180.7z M394.8,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S395.4,223.8,394.8,223.8z M394.8,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,130.4,394.8,130.4z + M394.8,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,209.5,394.8,209.5z M394.8,187.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,187.9,394.8,187.9z M387.6,216.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C388.8,217.2,388.2,216.7,387.6,216.7z M391.2,129.3c0.6,0,1.1-0.5,1.2-1l-1.2-0.1h-0.3L390,128 + v0.1C390,128.7,390.5,129.3,391.2,129.3z M384,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S384.6,141.2,384,141.2z M384,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,220.2,384,220.2z M394.8,137.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C396,138.2,395.4,137.6,394.8,137.6z M387.6,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C388.8,145.4,388.2,144.8,387.6,144.8z M387.6,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S388.2,223.8,387.6,223.8z M387.6,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S388.2,152,387.6,152z M394.8,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,166.4,394.8,166.4z M394.8,152 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,152,394.8,152z M391.2,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C392.4,192,391.8,191.5,391.2,191.5z M387.6,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S388.2,166.4,387.6,166.4z M391.2,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S391.8,162.8,391.2,162.8z M394.8,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.4,173.6,394.8,173.6z + M384,127.3l-0.8-0.1c-0.2,0.2-0.4,0.5-0.4,0.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.3-0.1-0.5-0.2-0.7L384,127.3z + M391.2,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S391.8,220.2,391.2,220.2z M391.2,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C392.4,177.7,391.8,177.1,391.2,177.1z M384,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,191.5,384,191.5z M387.6,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S388.2,130.4,387.6,130.4z M391.2,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C392.4,134.6,391.8,134,391.2,134z + M394.8,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C396,181.3,395.4,180.7,394.8,180.7z M387.6,159.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S388.2,159.2,387.6,159.2z M391.2,198.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S391.8,198.7,391.2,198.7z M391.2,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C392.4,148.9,391.8,148.4,391.2,148.4z M394.8,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C396,145.4,395.4,144.8,394.8,144.8z M391.2,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S391.8,141.2,391.2,141.2z M384,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,198.7,384,198.7z M384,170 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S384.6,170,384,170z M384,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S384.6,213.1,384,213.1z M387.6,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C388.8,202.8,388.2,202.3,387.6,202.3z M387.6,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C388.8,174.1,388.2,173.6,387.6,173.6z M384,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C385.2,177.7,384.6,177.1,384,177.1z M387.6,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S388.2,187.9,387.6,187.9z M463.5,136.3l-0.5-0.1l-0.7-0.1c0.2,0.1,0.4,0.2,0.7,0.2C463.2,136.4,463.3,136.4,463.5,136.3z + M463,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,299.3,463,299.3z M380.4,130.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,130.4,380.4,130.4z M380.4,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S381.1,152,380.4,152z M376.8,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,205.9,376.8,205.9z + M376.8,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C378,177.7,377.5,177.1,376.8,177.1z M380.4,195.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,195.1,380.4,195.1z M376.8,126.9c-0.7,0-1.2,0.5-1.2,1.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,126.9,376.8,126.9z M380.4,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S381.1,159.2,380.4,159.2z M380.4,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S381.1,209.5,380.4,209.5z M380.4,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,173.6,380.4,173.6z + M380.4,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,187.9,380.4,187.9z M380.4,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C381.6,145.4,381.1,144.8,380.4,144.8z M376.8,213.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,213.1,376.8,213.1z M380.4,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,166.4,380.4,166.4z M376.8,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S377.5,162.8,376.8,162.8z M376.8,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,155.6,376.8,155.6z + M376.8,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C378,134.6,377.5,134,376.8,134z M376.8,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,148.4,376.8,148.4z M380.4,216.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,216.7,380.4,216.7z M380.4,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C381.6,138.2,381.1,137.6,380.4,137.6z M380.4,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C381.6,181.3,381.1,180.7,380.4,180.7z M376.8,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S377.5,141.2,376.8,141.2z M376.8,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,198.7,376.8,198.7z + M380.4,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S381.1,202.3,380.4,202.3z M376.8,191.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,191.5,376.8,191.5z M376.8,184.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S377.5,184.3,376.8,184.3z M376.8,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S377.5,170,376.8,170z M452.2,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,195.6,452.9,195.1,452.2,195.1z + M459.4,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,288.5,459.4,288.5z M459.4,274.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,274.1,459.4,274.1z M459.4,259.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,259.8,459.4,259.8z M459.4,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S460.1,166.4,459.4,166.4z M459.4,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,173.6,459.4,173.6z + M455.8,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,148.4,455.8,148.4z M459.4,231 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C460.6,231.6,460.1,231,459.4,231z M459.4,223.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,223.8,459.4,223.8z M455.8,136.4c0.5,0,1-0.4,1.1-0.8l-1.1-0.1l-1.2-0.1 + C454.7,135.9,455.2,136.4,455.8,136.4z M455.8,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S456.5,284.9,455.8,284.9z M459.4,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C460.6,138.2,460.1,137.6,459.4,137.6z M455.8,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S456.5,198.7,455.8,198.7z M459.4,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C460.6,181.3,460.1,180.7,459.4,180.7z M455.8,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C457,271.1,456.5,270.5,455.8,270.5z M452.2,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,152,452.2,152z + M455.8,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,162.8,455.8,162.8z M455.8,234.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,234.6,455.8,234.6z M459.4,295.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,295.7,459.4,295.7z M455.8,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S456.5,241.8,455.8,241.8z M455.8,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,213.1,455.8,213.1z + M455.8,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,205.9,455.8,205.9z M459.4,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,245.4,459.4,245.4z M455.8,249c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,249,455.8,249z M455.8,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S456.5,191.5,455.8,191.5z M455.8,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,220.2,455.8,220.2z + M455.8,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C457,228,456.5,227.4,455.8,227.4z M459.4,266.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,266.9,459.4,266.9z M459.4,252.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,252.6,459.4,252.6z M459.4,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S460.1,209.5,459.4,209.5z M452.2,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C453.4,202.8,452.9,202.3,452.2,202.3z M455.8,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,170,455.8,170z + M459.4,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,195.1,459.4,195.1z M459.4,238.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,238.2,459.4,238.2z M455.8,292.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,292.1,455.8,292.1z M452.2,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C453.4,145.4,452.9,144.8,452.2,144.8z M459.4,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C460.6,145.4,460.1,144.8,459.4,144.8z M452.2,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C453.4,174.1,452.9,173.6,452.2,173.6z M459.4,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,152,459.4,152z + M459.4,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,216.7,459.4,216.7z M455.8,184.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,184.3,455.8,184.3z M455.8,177.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C457,177.7,456.5,177.1,455.8,177.1z M455.8,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S456.5,263.4,455.8,263.4z M459.4,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S460.1,187.9,459.4,187.9z M452.2,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,159.2,452.2,159.2z + M455.8,277.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,277.7,455.8,277.7z M452.2,137.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,138.2,452.9,137.6,452.2,137.6z M455.8,256.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,256.2,455.8,256.2z M452.2,180.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C453.4,181.3,452.9,180.7,452.2,180.7z M459.4,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S460.1,159.2,459.4,159.2z M452.2,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S452.9,187.9,452.2,187.9z M455.8,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S456.5,141.2,455.8,141.2z + M459.4,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,202.3,459.4,202.3z M459.4,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S460.1,281.3,459.4,281.3z M452.2,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S452.9,166.4,452.2,166.4z M455.8,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S456.5,155.6,455.8,155.6z M369.6,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C370.8,170.5,370.3,170,369.6,170z + M369.6,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C370.8,177.7,370.3,177.1,369.6,177.1z M373.2,195.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C374.4,195.6,373.9,195.1,373.2,195.1z M369.6,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S370.3,155.6,369.6,155.6z M369.6,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S370.3,162.8,369.6,162.8z M373.2,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C374.4,181.3,373.9,180.7,373.2,180.7z M373.2,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C374.4,202.8,373.9,202.3,373.2,202.3z M369.6,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C370.8,206.4,370.3,205.9,369.6,205.9z M373.2,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C374.4,138.2,373.9,137.6,373.2,137.6z M369.6,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C370.8,148.9,370.3,148.4,369.6,148.4z M373.2,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C374.4,145.4,373.9,144.8,373.2,144.8z M373.2,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C374.4,174.1,373.9,173.6,373.2,173.6z M369.6,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S370.3,184.3,369.6,184.3z M373.2,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S373.9,159.2,373.2,159.2z + M373.2,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S373.9,130.4,373.2,130.4z M369.6,126.9 + c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S370.3,126.9,369.6,126.9z M369.6,198.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S370.3,198.7,369.6,198.7z M373.2,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S373.9,152,373.2,152z M373.2,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S373.9,209.5,373.2,209.5z M369.6,134 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C370.8,134.6,370.3,134,369.6,134z M373.2,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S373.9,166.4,373.2,166.4z M369.6,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C370.8,192,370.3,191.5,369.6,191.5z M369.6,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S370.3,141.2,369.6,141.2z M373.2,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S373.9,187.9,373.2,187.9z + M351.7,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S352.3,187.9,351.7,187.9z M355.2,162.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S355.9,162.8,355.2,162.8z M348.1,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S348.7,162.8,348.1,162.8z M351.7,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C352.9,174.1,352.3,173.6,351.7,173.6z M358.8,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S359.5,195.1,358.8,195.1z M362.4,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S363.1,126.9,362.4,126.9z + M351.7,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S352.3,130.4,351.7,130.4z M351.7,166.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S352.3,166.4,351.7,166.4z M366,137.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C367.2,138.2,366.7,137.6,366,137.6z M366,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S366.7,187.9,366,187.9z M366,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S366.7,166.4,366,166.4z M358.8,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C360,138.2,359.5,137.6,358.8,137.6z + M358.8,125.7c0.6,0,1.1-0.5,1.2-1.1l-2.3-0.3c0,0.1,0,0.1,0,0.2C357.6,125.1,358.2,125.7,358.8,125.7z M348.1,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C349.3,148.9,348.7,148.4,348.1,148.4z M348.1,134c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C349.3,134.6,348.7,134,348.1,134z M362.4,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S363.1,198.7,362.4,198.7z M366,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S366.7,152,366,152z + M366,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S366.7,202.3,366,202.3z M366,159.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S366.7,159.2,366,159.2z M366,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S366.7,173.6,366,173.6z M351.7,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S352.3,159.2,351.7,159.2z + M351.7,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C352.9,138.2,352.3,137.6,351.7,137.6z M366,195.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S366.7,195.1,366,195.1z M366,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C367.2,145.4,366.7,144.8,366,144.8z M366,125.7c0.3,0,0.6-0.1,0.8-0.3l-1.8-0.2 + C365.3,125.4,365.6,125.7,366,125.7z M366,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C367.2,181.3,366.7,180.7,366,180.7z M362.4,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S363.1,148.4,362.4,148.4z M362.4,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C363.6,177.7,363.1,177.1,362.4,177.1z M348.1,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S348.7,141.2,348.1,141.2z M348.1,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S348.7,126.9,348.1,126.9z + M362.4,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C363.6,134.6,363.1,134,362.4,134z M358.8,166.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S359.5,166.4,358.8,166.4z M362.4,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S363.1,170,362.4,170z M358.8,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S359.5,159.2,358.8,159.2z M351.7,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C352.9,181.3,352.3,180.7,351.7,180.7z M366,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S366.7,130.4,366,130.4z + M351,123.5c-0.3,0.2-0.5,0.6-0.5,1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.3-0.1-0.6-0.3-0.8L351,123.5z M358.8,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S359.5,173.6,358.8,173.6z M362.4,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S363.1,162.8,362.4,162.8z M362.4,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S363.1,184.3,362.4,184.3z M362.4,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S363.1,155.6,362.4,155.6z + M358.8,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S359.5,130.4,358.8,130.4z M355.2,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C356.4,148.9,355.9,148.4,355.2,148.4z M358.8,187.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S359.5,187.9,358.8,187.9z M358.8,180.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C360,181.3,359.5,180.7,358.8,180.7z M355.2,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S355.9,184.3,355.2,184.3z M355.2,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S355.9,126.9,355.2,126.9z M358.8,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S359.5,152,358.8,152z M355.2,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S355.9,141.2,355.2,141.2z M358.8,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C360,145.4,359.5,144.8,358.8,144.8z M362.4,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S363.1,141.2,362.4,141.2z M355.2,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C356.4,134.6,355.9,134,355.2,134z M362.4,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S363.1,191.5,362.4,191.5z + M355.2,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C356.4,170.5,355.9,170,355.2,170z M355.2,191.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C356.4,192,355.9,191.5,355.2,191.5z M355.2,177.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C356.4,177.7,355.9,177.1,355.2,177.1z M351.7,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S352.3,152,351.7,152z M348.1,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S348.7,155.6,348.1,155.6z M355.2,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S355.9,155.6,355.2,155.6z + M351.7,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C352.9,145.4,352.3,144.8,351.7,144.8z M337.3,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C338.5,145.4,337.9,144.8,337.3,144.8z M337.3,123.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S337.9,123.3,337.3,123.3z M344.5,180.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C345.7,181.3,345.1,180.7,344.5,180.7z M348.1,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C349.3,177.7,348.7,177.1,348.1,177.1z M340.9,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S341.5,141.2,340.9,141.2z M337.3,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S337.9,130.4,337.3,130.4z + M348.1,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S348.7,184.3,348.1,184.3z M344.5,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S345.1,173.6,344.5,173.6z M340.9,177.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C342.1,177.7,341.5,177.1,340.9,177.1z M340.9,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C342.1,134.6,341.5,134,340.9,134z M344.5,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S345.1,166.4,344.5,166.4z M344.5,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S345.1,159.2,344.5,159.2z + M344.5,123.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S345.1,123.3,344.5,123.3z M337.3,137.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C338.5,138.2,337.9,137.6,337.3,137.6z M340.9,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S341.5,170,340.9,170z M340.9,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S341.5,126.9,340.9,126.9z M340.9,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S341.5,155.6,340.9,155.6z M344.5,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C345.7,145.4,345.1,144.8,344.5,144.8z M344.5,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S345.1,152,344.5,152z + M340.9,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S341.5,148.4,340.9,148.4z M340.9,162.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S341.5,162.8,340.9,162.8z M344.5,130.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S345.1,130.4,344.5,130.4z M348.1,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C349.3,170.5,348.7,170,348.1,170z M344.5,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C345.7,138.2,345.1,137.6,344.5,137.6z M326.5,162.8c-0.7,0-1.2,0.5-1.2,1.2c0,0.1,0,0.1,0.1,0.2l0.9,0.9c0.1,0,0.2,0.1,0.3,0.1 + c0.7,0,1.2-0.5,1.2-1.2S327.2,162.8,326.5,162.8z M322.9,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C324.1,145.4,323.6,144.8,322.9,144.8z M322.9,159.2c-0.7,0-1.2,0.5-1.2,1.2v0.1l1,1.1h0.1c0.7,0,1.2-0.5,1.2-1.2 + S323.6,159.2,322.9,159.2z M330.1,166.4c-0.7,0-1.2,0.5-1.2,1.2c0,0.1,0,0.2,0.1,0.4l0.8,0.8c0.1,0,0.3,0.1,0.4,0.1 + c0.7,0,1.2-0.5,1.2-1.2S330.8,166.4,330.1,166.4z M333.7,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S334.4,126.9,333.7,126.9z M330.1,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S330.8,152,330.1,152z M333.7,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C334.9,148.9,334.4,148.4,333.7,148.4z M330.1,130.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S330.8,130.4,330.1,130.4z M326.5,155.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S327.2,155.6,326.5,155.6z M333.7,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C334.9,134.6,334.4,134,333.7,134z M319.3,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S320,126.9,319.3,126.9z M337.3,173.6c-0.7,0-1.2,0.5-1.2,1.2c0,0.3,0.1,0.6,0.3,0.8l0.1,0.1c0.2,0.2,0.5,0.3,0.8,0.3 + c0.7,0,1.2-0.5,1.2-1.2C338.5,174.1,337.9,173.6,337.3,173.6z M322.9,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C324.1,138.2,323.6,137.6,322.9,137.6z M330.1,144.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C331.3,145.4,330.8,144.8,330.1,144.8z M330.1,123.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C331.3,123.8,330.8,123.3,330.1,123.3z M322.9,123.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S323.6,123.3,322.9,123.3z M326.5,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S327.2,148.4,326.5,148.4z + M337.3,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S337.9,152,337.3,152z M322.9,130.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S323.6,130.4,322.9,130.4z M333.7,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S334.4,162.8,333.7,162.8z M330.1,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S330.8,159.2,330.1,159.2z + M333.7,170c-0.7,0-1.2,0.5-1.2,1.2c0,0.2,0,0.3,0.1,0.5l0.6,0.6c0.2,0.1,0.3,0.1,0.5,0.1c0.7,0,1.2-0.5,1.2-1.2 + C334.9,170.5,334.4,170,333.7,170z M326.5,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S327.2,141.2,326.5,141.2z + M326.5,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S327.2,126.9,326.5,126.9z M322.9,152 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S323.6,152,322.9,152z M337.3,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S337.9,166.4,337.3,166.4z M333.7,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S334.4,141.2,333.7,141.2z M333.7,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S334.4,155.6,333.7,155.6z + M326.5,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C327.7,134.6,327.2,134,326.5,134z M325.4,120.6 + c0,0.1-0.1,0.2-0.1,0.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2l0,0l-1.2-0.1L325.4,120.6z M319.3,119.9l-0.5-0.1 + c-0.4,0.2-0.6,0.6-0.6,1.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.4-0.2-0.7-0.4-0.9L319.3,119.9z M337.3,159.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S337.9,159.2,337.3,159.2z M330.1,137.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C331.3,138.2,330.8,137.6,330.1,137.6z M333.7,122.1c0.4,0,0.7-0.2,0.9-0.4l-0.9-0.1l-1-0.1 + C332.8,121.8,333.2,122.1,333.7,122.1z M315.7,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C316.9,138.2,316.4,137.6,315.7,137.6z M290.6,119.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C291.8,120.2,291.3,119.7,290.6,119.7z M308.6,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S309.2,130.4,308.6,130.4z M312.1,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C313.3,134.6,312.8,134,312.1,134z + M319.3,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S320,148.4,319.3,148.4z M315.7,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C316.9,145.4,316.4,144.8,315.7,144.8z M301.4,123.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S302,123.3,301.4,123.3z M294.2,123.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C295.4,123.8,294.8,123.3,294.2,123.3z M319.3,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S320,141.2,319.3,141.2z M293.1,116.9c0,0.1-0.1,0.3-0.1,0.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2v-0.1 + L293.1,116.9z M312.1,126.9c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S312.8,126.9,312.1,126.9z M301.4,130.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S302,130.4,301.4,130.4z M297.8,126.9c-0.7,0-1.2,0.5-1.2,1.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S298.4,126.9,297.8,126.9z M319.3,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C320.5,134.6,320,134,319.3,134z M315.7,152c-0.6,0-1.1,0.5-1.2,1.1l1.2,1.3c0.6,0,1.2-0.6,1.2-1.2 + C316.9,152.5,316.4,152,315.7,152z M312.1,148.4c-0.6,0-1.1,0.5-1.2,1l0.2,0.2l1,1l0.1,0.1c0.6-0.1,1.1-0.6,1.1-1.2 + C313.3,148.9,312.8,148.4,312.1,148.4z M294.2,130.4c-0.5,0-0.9,0.3-1.1,0.7l1.6,1.6c0.4-0.2,0.7-0.6,0.7-1.1 + C295.4,131,294.8,130.4,294.2,130.4z M305,134c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C306.2,134.6,305.6,134,305,134z M312.1,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S312.8,141.2,312.1,141.2z + M297.8,119.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S298.4,119.7,297.8,119.7z M305,126.9 + c-0.7,0-1.2,0.5-1.2,1.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S305.6,126.9,305,126.9z M308.6,123.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C309.7,123.8,309.2,123.3,308.6,123.3z M305,141.2c-0.6,0-1,0.4-1.1,0.9l0.3,0.3l0.8,0.9l0.3,0.3 + c0.5-0.1,0.9-0.6,0.9-1.1C306.2,141.8,305.6,141.2,305,141.2z M297.8,134c-0.5,0-0.9,0.3-1.1,0.7l0.5,0.5l0.6,0.7l0.4,0.4 + c0.5-0.2,0.8-0.6,0.8-1.1C299,134.6,298.4,134,297.8,134z M308.6,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C309.7,138.2,309.2,137.6,308.6,137.6z M290.6,126.9c-0.5,0-0.8,0.3-1,0.6l0.6,0.6l0.5,0.5l0.5,0.6c0.4-0.2,0.6-0.6,0.6-1 + C291.8,127.4,291.3,126.9,290.6,126.9z M301.4,137.6c-0.5,0-1,0.3-1.1,0.8l1.5,1.5c0.5-0.1,0.8-0.6,0.8-1.1 + C302.6,138.2,302,137.6,301.4,137.6z M308.6,144.8c-0.6,0-1,0.4-1.1,1l1.3,1.4c0.6-0.1,1-0.6,1-1.2 + C309.7,145.4,309.2,144.8,308.6,144.8z M287,123.3c-0.4,0-0.8,0.2-1,0.6l1.6,1.6c0.4-0.2,0.6-0.6,0.6-1 + C288.2,123.8,287.7,123.3,287,123.3z M287.6,116.3l-1-0.1c-0.5,0.2-0.8,0.6-0.8,1.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C288.2,116.8,288,116.5,287.6,116.3z M283.4,119.7c-0.4,0-0.7,0.2-1,0.5l0.7,0.7l0.3,0.3l0.7,0.7c0.3-0.2,0.5-0.6,0.5-1 + C284.6,120.2,284.1,119.7,283.4,119.7z M315.7,130.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S316.4,130.4,315.7,130.4z M305,119.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S305.6,119.7,305,119.7z + M319.3,155.6c-0.7,0-1.2,0.5-1.2,1.2l1.2,1.2l0,0c0.7,0,1.2-0.5,1.2-1.2S320,155.6,319.3,155.6z M279.8,116.1 + c-0.4,0-0.7,0.2-0.9,0.4l1.6,1.7c0.3-0.2,0.5-0.5,0.5-0.9C281,116.6,280.5,116.1,279.8,116.1z M315.7,123.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C316.9,123.8,316.4,123.3,315.7,123.3z M301.4,118.5c0.4,0,0.8-0.2,1-0.5l-2.1-0.2 + C300.4,118.2,300.9,118.5,301.4,118.5z M312.1,119.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C313.3,120.2,312.8,119.7,312.1,119.7z M560,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C561.2,181.3,560.6,180.7,560,180.7z M560,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,173.6,560,173.6z + M560,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,166.4,560,166.4z M560,159.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,159.2,560,159.2z M560,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S560.6,152,560,152z M560,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.3,0,0.6-0.1,0.8-0.3l0.3-1.4 + C560.8,238.5,560.5,238.2,560,238.2z M562.4,228.6c0,0.4,0.2,0.8,0.5,1l0.2-1l0.2-1.1C562.8,227.6,562.4,228,562.4,228.6z + M563.6,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.3,0,0.6-0.1,0.8-0.3l0.2-0.9l0.1-0.5C564.5,220.5,564.1,220.2,563.6,220.2 + z M563.6,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,213.1,563.6,213.1z M563.6,205.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,205.9,563.6,205.9z M563.6,198.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,198.7,563.6,198.7z M563.6,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S564.2,191.5,563.6,191.5z M563.6,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,184.3,563.6,184.3z + M563.6,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C564.8,177.7,564.2,177.1,563.6,177.1z M563.6,170 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,170,563.6,170z M563.6,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,162.8,563.6,162.8z M563.6,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S564.2,155.6,563.6,155.6z M563.6,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S564.2,148.4,563.6,148.4z + M566,210.7c0,0.4,0.2,0.8,0.6,1l0.4-2.2C566.4,209.6,566,210.1,566,210.7z M567.2,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S567.8,195.1,567.2,195.1z M567.2,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S567.8,187.9,567.2,187.9z M567.2,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C568.4,181.3,567.8,180.7,567.2,180.7z M567.2,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S567.8,173.6,567.2,173.6z M567.2,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S567.8,166.4,567.2,166.4z + M567.2,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S567.8,159.2,567.2,159.2z M567.2,152 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S567.8,152,567.2,152z M567.2,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2c0.4,0,0.7-0.2,0.9-0.4l0.2-1.1C568.1,202.6,567.7,202.3,567.2,202.3z M569.6,192.7c0,0.5,0.3,0.8,0.6,1l0.2-1 + l0.2-1.2C570,191.6,569.6,192.1,569.6,192.7z M570.8,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.4,0,0.8-0.2,1-0.5l0.1-0.7 + l0.1-0.2C571.8,184.7,571.3,184.3,570.8,184.3z M570.8,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C572,177.7,571.4,177.1,570.8,177.1z M570.8,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S571.4,170,570.8,170z + M570.8,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S571.4,162.8,570.8,162.8z M570.8,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S571.4,155.6,570.8,155.6z M571.5,148.7l-0.7-0.1l-0.5-0.1 + c-0.4,0.2-0.7,0.6-0.7,1.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C572,149.2,571.8,148.9,571.5,148.7z M573.2,174.7 + c0,0.5,0.3,0.9,0.7,1.1l0.5-2.3C573.7,173.6,573.2,174.1,573.2,174.7z M574.4,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S575,159.2,574.4,159.2z M574.4,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S575,152,574.4,152z + M574.4,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.5,0,0.8-0.3,1-0.6l0.1-0.6C575.5,166.9,575,166.4,574.4,166.4z + M576.7,156.8c0,0.5,0.3,0.9,0.7,1.1l0.2-1.1l0.2-1.2C577.3,155.6,576.7,156.1,576.7,156.8z M579.1,149.5l-1.2-0.1l-1.1-0.1 + c0,0.1-0.1,0.2-0.1,0.3c0,0.7,0.5,1.2,1.2,1.2S579.1,150.3,579.1,149.5C579.1,149.6,579.1,149.6,579.1,149.5z M549.2,292.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.2,0,0.4-0.1,0.6-0.2l0.2-1l0.1-0.7C549.9,292.3,549.6,292.1,549.2,292.1z M549.2,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,284.9,549.2,284.9z M549.2,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,277.7,549.2,277.7z M549.2,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C550.4,271.1,549.9,270.5,549.2,270.5z M549.2,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S549.9,263.4,549.2,263.4z M549.2,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,256.2,549.2,256.2z + M549.2,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,249,549.2,249z M549.2,241.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,241.8,549.2,241.8z M549.2,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S549.9,234.6,549.2,234.6z M549.2,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C550.4,228,549.9,227.4,549.2,227.4z M549.2,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S549.9,220.2,549.2,220.2z M549.2,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,213.1,549.2,213.1z + M549.2,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,205.9,549.2,205.9z M549.2,198.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,198.7,549.2,198.7z M549.2,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,191.5,549.2,191.5z M549.2,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S549.9,184.3,549.2,184.3z M549.2,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C550.4,177.7,549.9,177.1,549.2,177.1z M549.2,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,170,549.2,170z + M549.2,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,162.8,549.2,162.8z M549.2,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,155.6,549.2,155.6z M549.2,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S549.9,148.4,549.2,148.4z M551.6,282.5c0,0.4,0.2,0.7,0.4,0.9l0.4-2 + C551.9,281.5,551.6,282,551.6,282.5z M552.8,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S553.5,266.9,552.8,266.9z M552.8,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,259.8,552.8,259.8z + M552.8,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,252.6,552.8,252.6z M552.8,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,245.4,552.8,245.4z M552.8,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,238.2,552.8,238.2z M552.8,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C554,231.6,553.5,231,552.8,231z M552.8,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,223.8,552.8,223.8z + M552.8,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,216.7,552.8,216.7z M552.8,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,209.5,552.8,209.5z M552.8,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,202.3,552.8,202.3z M552.8,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S553.5,195.1,552.8,195.1z M552.8,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,187.9,552.8,187.9z + M552.8,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C554,181.3,553.5,180.7,552.8,180.7z M552.8,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,173.6,552.8,173.6z M552.8,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,166.4,552.8,166.4z M552.8,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S553.5,159.2,552.8,159.2z M552.8,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S553.5,152,552.8,152z M552.8,274.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.2,0,0.5-0.1,0.6-0.2l0.3-1.6C553.6,274.3,553.2,274.1,552.8,274.1z M552.8,147.2 + c0.4,0,0.8-0.2,1-0.6l-2.1-0.2C551.8,146.9,552.3,147.2,552.8,147.2z M555.2,264.5c0,0.4,0.2,0.7,0.5,0.9l0.2-0.9l0.2-1.1 + C555.6,263.6,555.2,264,555.2,264.5z M556.4,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.3,0,0.5-0.1,0.7-0.3l0.2-0.9l0.1-0.6 + C557.2,256.4,556.8,256.2,556.4,256.2z M556.4,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S557.1,249,556.4,249z + M556.4,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C557.6,242.3,557.1,241.8,556.4,241.8z M556.4,234.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S557.1,234.6,556.4,234.6z M556.4,227.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C557.6,228,557.1,227.4,556.4,227.4z M556.4,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S557.1,220.2,556.4,220.2z M556.4,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C557.6,213.6,557.1,213.1,556.4,213.1z M556.4,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C557.6,206.4,557.1,205.9,556.4,205.9z M556.4,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S557.1,198.7,556.4,198.7z M556.4,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C557.6,192,557.1,191.5,556.4,191.5z M556.4,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S557.1,184.3,556.4,184.3z M556.4,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C557.6,177.7,557.1,177.1,556.4,177.1z M556.4,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C557.6,170.5,557.1,170,556.4,170z M556.4,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S557.1,162.8,556.4,162.8z + M556.4,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S557.1,155.6,556.4,155.6z M556.4,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C557.6,148.9,557.1,148.4,556.4,148.4z M558.8,246.6 + c0,0.4,0.2,0.7,0.5,0.9l0.4-2.1C559.2,245.6,558.8,246,558.8,246.6z M560,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C561.2,231.6,560.6,231,560,231z M560,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S560.6,223.8,560,223.8z M560,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,216.7,560,216.7z M560,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,209.5,560,209.5z M560,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,202.3,560,202.3z M560,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S560.6,195.1,560,195.1z M560,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S560.6,187.9,560,187.9z M538.4,338.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,338.8,538.4,338.8z M538.4,331.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,331.6,538.4,331.6z M538.4,324.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,324.4,538.4,324.4z M538.4,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,317.8,539.1,317.2,538.4,317.2z M538.4,310c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,310,538.4,310z + M538.4,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C539.6,303.4,539.1,302.9,538.4,302.9z M538.4,295.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,295.7,538.4,295.7z M538.4,288.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C539.6,289,539.1,288.5,538.4,288.5z M538.4,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S539.1,281.3,538.4,281.3z M538.4,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,274.1,538.4,274.1z M538.4,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,266.9,538.4,266.9z + M538.4,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,259.8,538.4,259.8z M538.4,252.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C539.6,253.1,539.1,252.6,538.4,252.6z M538.4,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,245.4,538.4,245.4z M538.4,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C539.6,238.7,539.1,238.2,538.4,238.2z M538.4,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C539.6,231.6,539.1,231,538.4,231z M538.4,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,223.8,538.4,223.8z M538.4,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,217.2,539.1,216.7,538.4,216.7z M538.4,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,209.5,538.4,209.5z M538.4,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,202.8,539.1,202.3,538.4,202.3z M538.4,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,195.6,539.1,195.1,538.4,195.1z M538.4,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,187.9,538.4,187.9z M538.4,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,181.3,539.1,180.7,538.4,180.7z M538.4,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C539.6,174.1,539.1,173.6,538.4,173.6z M538.4,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S539.1,166.4,538.4,166.4z M538.4,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,159.2,538.4,159.2z + M538.4,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S539.1,152,538.4,152z M539,145l-0.8-0.1c-0.5,0.1-1,0.6-1,1.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C539.6,145.5,539.4,145.2,539,145z M537.2,347.2c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.3,0,0.4-0.1 + l0.4-2c-0.2-0.2-0.5-0.3-0.8-0.3C537.8,346,537.2,346.5,537.2,347.2z M540.8,336.4c0,0.3,0.1,0.5,0.3,0.7l0.1-0.7l0.2-1 + C541.1,335.5,540.8,335.9,540.8,336.4z M540.8,329.2c0,0.7,0.5,1.2,1.2,1.2c0.2,0,0.3,0,0.5-0.1l0.2-1.1l0.2-0.8 + c-0.2-0.2-0.5-0.4-0.9-0.4C541.4,328,540.8,328.5,540.8,329.2z M542,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S542.7,320.8,542,320.8z M542,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C543.2,314.2,542.7,313.6,542,313.6z + M542,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,306.5,542,306.5z M542,299.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,299.3,542,299.3z M542,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S542.7,292.1,542,292.1z M542,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,284.9,542,284.9z M542,277.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,277.7,542,277.7z M542,270.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C543.2,271.1,542.7,270.5,542,270.5z M542,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S542.7,263.4,542,263.4z M542,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S542.7,256.2,542,256.2z M542,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,249,542,249z M542,241.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,241.8,542,241.8z M542,234.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,234.6,542,234.6z M542,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C543.2,228,542.7,227.4,542,227.4z M542,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,220.2,542,220.2z + M542,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,213.1,542,213.1z M542,205.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,205.9,542,205.9z M542,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S542.7,198.7,542,198.7z M542,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,191.5,542,191.5z M542,184.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,184.3,542,184.3z M542,177.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C543.2,177.7,542.7,177.1,542,177.1z M542,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S542.7,170,542,170z M542,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,162.8,542,162.8z + M542,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,155.6,542,155.6z M542,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S542.7,148.4,542,148.4z M544.4,318.4c0,0.3,0.1,0.6,0.3,0.8l0.4-1.9 + C544.7,317.5,544.4,317.9,544.4,318.4z M545.6,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S546.3,302.9,545.6,302.9z M545.6,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,295.7,545.6,295.7z + M545.6,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,288.5,545.6,288.5z M545.6,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,281.3,545.6,281.3z M545.6,274.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,274.1,545.6,274.1z M545.6,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S546.3,266.9,545.6,266.9z M545.6,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,259.8,545.6,259.8z + M545.6,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,252.6,545.6,252.6z M545.6,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,245.4,545.6,245.4z M545.6,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,238.2,545.6,238.2z M545.6,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C546.8,231.6,546.3,231,545.6,231z M545.6,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,223.8,545.6,223.8z + M545.6,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,216.7,545.6,216.7z M545.6,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,209.5,545.6,209.5z M545.6,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,202.3,545.6,202.3z M545.6,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S546.3,195.1,545.6,195.1z M545.6,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,187.9,545.6,187.9z + M545.6,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C546.8,181.3,546.3,180.7,545.6,180.7z M545.6,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,173.6,545.6,173.6z M545.6,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,166.4,545.6,166.4z M545.6,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S546.3,159.2,545.6,159.2z M545.6,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S546.3,152,545.6,152z M544.4,311.2 + c0,0.7,0.5,1.2,1.2,1.2c0.2,0,0.4,0,0.5-0.1l0.4-1.8c-0.2-0.3-0.5-0.4-0.9-0.4C545,310,544.4,310.6,544.4,311.2z M544.5,145.6 + c0,0.1-0.1,0.3-0.1,0.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.1,0-0.1,0-0.2L544.5,145.6z M548,300.5c0,0.3,0.1,0.6,0.4,0.9 + l0.2-0.9l0.2-1.1C548.3,299.5,548,300,548,300.5z M527.7,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C528.9,177.7,528.3,177.1,527.7,177.1z M527.7,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,170,527.7,170z + M527.7,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,162.8,527.7,162.8z M527.7,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,155.6,527.7,155.6z M527.7,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,148.4,527.7,148.4z M531.3,367.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,367.5,531.3,367.5z M531.3,360.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,360.9,531.9,360.3,531.3,360.3z M531.3,353.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,353.1,531.3,353.1z M531.3,346c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,346.5,531.9,346,531.3,346z + M531.3,338.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,338.8,531.3,338.8z M531.3,331.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,331.6,531.3,331.6z M531.3,324.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,324.4,531.3,324.4z M531.3,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,317.8,531.9,317.2,531.3,317.2z M531.3,310c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,310,531.3,310z + M531.3,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,303.4,531.9,302.9,531.3,302.9z M531.3,295.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,295.7,531.3,295.7z M531.3,288.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,289,531.9,288.5,531.3,288.5z M531.3,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S531.9,281.3,531.3,281.3z M531.3,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,274.1,531.3,274.1z M531.3,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,266.9,531.3,266.9z + M531.3,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,259.8,531.3,259.8z M531.3,252.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,253.1,531.9,252.6,531.3,252.6z M531.3,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,245.4,531.3,245.4z M531.3,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,238.7,531.9,238.2,531.3,238.2z M531.3,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C532.4,231.6,531.9,231,531.3,231z M531.3,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,223.8,531.3,223.8z M531.3,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,217.2,531.9,216.7,531.3,216.7z M531.3,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,209.5,531.3,209.5z M531.3,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,202.8,531.9,202.3,531.3,202.3z M531.3,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,195.6,531.9,195.1,531.3,195.1z M531.3,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,187.9,531.3,187.9z M531.3,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,181.3,531.9,180.7,531.3,180.7z M531.3,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C532.4,174.1,531.9,173.6,531.3,173.6z M531.3,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S531.9,166.4,531.3,166.4z M531.3,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,159.2,531.3,159.2z + M531.3,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S531.9,152,531.3,152z M531.3,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C532.4,145.4,531.9,144.8,531.3,144.8z M531.3,374.7c-0.2,0-0.4,0.1-0.6,0.2l1.6,1.6 + c0.1-0.2,0.2-0.4,0.2-0.6C532.4,375.2,531.9,374.7,531.3,374.7z M533.6,372.3c0,0.2,0.1,0.4,0.2,0.6l0.1-0.6l0.2-1 + C533.9,371.6,533.6,371.9,533.6,372.3z M533.6,365.1c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.2,0,0.3-0.1l0.2-1.1l0.2-0.9 + c-0.2-0.2-0.5-0.3-0.8-0.3C534.2,363.9,533.6,364.5,533.6,365.1z M534.8,356.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S535.5,356.7,534.8,356.7z M534.8,349.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,349.6,534.8,349.6z M534.8,342.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,342.4,534.8,342.4z + M534.8,335.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,335.2,534.8,335.2z M534.8,328 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,328,534.8,328z M534.8,320.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,320.8,534.8,320.8z M534.8,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C536,314.2,535.5,313.6,534.8,313.6z M534.8,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,306.5,534.8,306.5z M534.8,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,299.3,534.8,299.3z + M534.8,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,292.1,534.8,292.1z M534.8,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,284.9,534.8,284.9z M534.8,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,277.7,534.8,277.7z M534.8,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C536,271.1,535.5,270.5,534.8,270.5z M534.8,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,263.4,534.8,263.4z M534.8,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,256.2,534.8,256.2z + M534.8,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,249,534.8,249z M534.8,241.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,241.8,534.8,241.8z M534.8,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,234.6,534.8,234.6z M534.8,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C536,228,535.5,227.4,534.8,227.4z + M534.8,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,220.2,534.8,220.2z M534.8,213.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,213.1,534.8,213.1z M534.8,205.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,205.9,534.8,205.9z M534.8,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,198.7,534.8,198.7z M534.8,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,191.5,534.8,191.5z + M534.8,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,184.3,534.8,184.3z M534.8,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C536,177.7,535.5,177.1,534.8,177.1z M534.8,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,170,534.8,170z M534.8,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S535.5,162.8,534.8,162.8z M534.8,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,155.6,534.8,155.6z + M534.8,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S535.5,148.4,534.8,148.4z M537.2,354.3 + c0,0.3,0.1,0.5,0.2,0.7l0.3-1.7C537.5,353.6,537.2,353.9,537.2,354.3z M513.3,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S514,205.9,513.3,205.9z M513.3,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,198.7,513.3,198.7z M513.3,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,191.5,513.3,191.5z + M513.3,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,184.3,513.3,184.3z M513.3,177.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C514.5,177.7,514,177.1,513.3,177.1z M513.3,170c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,170,513.3,170z M513.3,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,162.8,513.3,162.8z M513.3,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,155.6,513.3,155.6z + M513.3,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,148.4,513.3,148.4z M513.3,142l-1.1-0.1 + c-0.1,0.2-0.1,0.3-0.1,0.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.1,0-0.2,0-0.3L513.3,142z M516.9,353.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,353.1,516.9,353.1z M516.9,346c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,346.5,517.5,346,516.9,346z M516.9,338.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S517.5,338.8,516.9,338.8z M516.9,331.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S517.5,331.6,516.9,331.6z M516.9,324.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,324.4,516.9,324.4z + M516.9,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,317.8,517.5,317.2,516.9,317.2z M516.9,310 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,310,516.9,310z M516.9,302.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,303.4,517.5,302.9,516.9,302.9z M516.9,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S517.5,295.7,516.9,295.7z M516.9,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C518.1,289,517.5,288.5,516.9,288.5z M516.9,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S517.5,281.3,516.9,281.3z M516.9,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,274.1,516.9,274.1z + M516.9,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,266.9,516.9,266.9z M516.9,259.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,259.8,516.9,259.8z M516.9,252.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,253.1,517.5,252.6,516.9,252.6z M516.9,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S517.5,245.4,516.9,245.4z M516.9,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C518.1,238.7,517.5,238.2,516.9,238.2z M516.9,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C518.1,231.6,517.5,231,516.9,231z M516.9,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,223.8,516.9,223.8z + M516.9,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,217.2,517.5,216.7,516.9,216.7z M516.9,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,209.5,516.9,209.5z M516.9,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,202.8,517.5,202.3,516.9,202.3z M516.9,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C518.1,195.6,517.5,195.1,516.9,195.1z M516.9,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S517.5,187.9,516.9,187.9z M516.9,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C518.1,181.3,517.5,180.7,516.9,180.7z M516.9,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C518.1,174.1,517.5,173.6,516.9,173.6z M516.9,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S517.5,166.4,516.9,166.4z M516.9,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,159.2,516.9,159.2z + M516.9,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S517.5,152,516.9,152z M516.9,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C518.1,145.4,517.5,144.8,516.9,144.8z M516.9,360.3c-0.1,0-0.2,0-0.3,0.1l1.4,1.5 + c0-0.1,0.1-0.2,0.1-0.3C518.1,360.9,517.5,360.3,516.9,360.3z M520.5,143.6c0.5,0,0.8-0.3,1-0.6l-1-0.1l-1.1-0.1 + C519.5,143.2,519.9,143.6,520.5,143.6z M520.5,363.9c-0.1,0-0.3,0-0.4,0.1l0.4,0.4l0.7,0.7l0.4,0.4c0-0.1,0.1-0.3,0.1-0.4 + C521.7,364.5,521.1,363.9,520.5,363.9z M520.5,356.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,356.7,520.5,356.7z M520.5,349.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,349.6,520.5,349.6z + M520.5,342.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,342.4,520.5,342.4z M520.5,335.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,335.2,520.5,335.2z M520.5,328c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,328,520.5,328z M520.5,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,320.8,520.5,320.8z M520.5,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C521.7,314.2,521.1,313.6,520.5,313.6z M520.5,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,306.5,520.5,306.5z M520.5,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,299.3,520.5,299.3z + M520.5,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,292.1,520.5,292.1z M520.5,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,284.9,520.5,284.9z M520.5,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,277.7,520.5,277.7z M520.5,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C521.7,271.1,521.1,270.5,520.5,270.5z M520.5,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,263.4,520.5,263.4z M520.5,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,256.2,520.5,256.2z + M520.5,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,249,520.5,249z M520.5,241.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,241.8,520.5,241.8z M520.5,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,234.6,520.5,234.6z M520.5,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C521.7,228,521.1,227.4,520.5,227.4z M520.5,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,220.2,520.5,220.2z M520.5,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,213.1,520.5,213.1z + M520.5,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,205.9,520.5,205.9z M520.5,198.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,198.7,520.5,198.7z M520.5,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,191.5,520.5,191.5z M520.5,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,184.3,520.5,184.3z M520.5,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C521.7,177.7,521.1,177.1,520.5,177.1z M520.5,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,170,520.5,170z + M506.1,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C507.3,271.1,506.8,270.5,506.1,270.5z M506.1,263.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,263.4,506.1,263.4z M506.1,256.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C507.3,256.7,506.8,256.2,506.1,256.2z M506.1,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S506.8,249,506.1,249z M506.1,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,242.3,506.8,241.8,506.1,241.8z M506.1,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,234.6,506.1,234.6z M506.1,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,228,506.8,227.4,506.1,227.4z M506.1,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,220.2,506.1,220.2z M506.1,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,213.6,506.8,213.1,506.1,213.1z M506.1,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,206.4,506.8,205.9,506.1,205.9z M506.1,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,198.7,506.1,198.7z M506.1,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,192,506.8,191.5,506.1,191.5z M506.1,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,184.3,506.1,184.3z M506.1,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,177.7,506.8,177.1,506.1,177.1z M506.1,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C507.3,170.5,506.8,170,506.1,170z M506.1,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,162.8,506.1,162.8z + M506.1,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,155.6,506.1,155.6z M506.1,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C507.3,148.9,506.8,148.4,506.1,148.4z M506.1,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,141.2,506.1,141.2z M509.7,346c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,346.5,510.4,346,509.7,346z M509.7,338.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S510.4,338.8,509.7,338.8z M509.7,331.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S510.4,331.6,509.7,331.6z M509.7,324.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,324.4,509.7,324.4z + M509.7,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,317.8,510.4,317.2,509.7,317.2z M509.7,310 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,310,509.7,310z M509.7,302.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,303.4,510.4,302.9,509.7,302.9z M509.7,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S510.4,295.7,509.7,295.7z M509.7,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C510.9,289,510.4,288.5,509.7,288.5z M509.7,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S510.4,281.3,509.7,281.3z M509.7,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,274.1,509.7,274.1z + M509.7,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,266.9,509.7,266.9z M509.7,259.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,259.8,509.7,259.8z M509.7,252.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,253.1,510.4,252.6,509.7,252.6z M509.7,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S510.4,245.4,509.7,245.4z M509.7,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C510.9,238.7,510.4,238.2,509.7,238.2z M509.7,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C510.9,231.6,510.4,231,509.7,231z M509.7,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,223.8,509.7,223.8z + M509.7,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,217.2,510.4,216.7,509.7,216.7z M509.7,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,209.5,509.7,209.5z M509.7,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,202.8,510.4,202.3,509.7,202.3z M509.7,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C510.9,195.6,510.4,195.1,509.7,195.1z M509.7,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S510.4,187.9,509.7,187.9z M509.7,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C510.9,181.3,510.4,180.7,509.7,180.7z M509.7,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C510.9,174.1,510.4,173.6,509.7,173.6z M509.7,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S510.4,166.4,509.7,166.4z M509.7,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,159.2,509.7,159.2z + M509.7,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S510.4,152,509.7,152z M509.7,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C510.9,145.4,510.4,144.8,509.7,144.8z M509.7,353.1h-0.1l1.3,1.3c0-0.1,0-0.1,0-0.2 + C510.9,353.7,510.4,353.1,509.7,353.1z M513.3,356.7c-0.1,0-0.1,0-0.2,0l0.2,0.2l0.9,0.9l0.3,0.3c0-0.1,0-0.2,0-0.3 + C514.5,357.3,514,356.7,513.3,356.7z M513.3,349.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,349.6,513.3,349.6z + M513.3,342.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,342.4,513.3,342.4z M513.3,335.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,335.2,513.3,335.2z M513.3,328c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,328,513.3,328z M513.3,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,320.8,513.3,320.8z M513.3,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C514.5,314.2,514,313.6,513.3,313.6z + M513.3,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,306.5,513.3,306.5z M513.3,299.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,299.3,513.3,299.3z M513.3,292.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,292.1,513.3,292.1z M513.3,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,284.9,513.3,284.9z M513.3,277.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,277.7,513.3,277.7z + M513.3,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C514.5,271.1,514,270.5,513.3,270.5z M513.3,263.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,263.4,513.3,263.4z M513.3,256.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,256.2,513.3,256.2z M513.3,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,249,513.3,249z M513.3,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,241.8,513.3,241.8z M513.3,234.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S514,234.6,513.3,234.6z M513.3,227.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C514.5,228,514,227.4,513.3,227.4z M513.3,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S514,220.2,513.3,220.2z M513.3,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S514,213.1,513.3,213.1z M499,342.4l1.1,1.1C500.1,342.9,499.6,342.5,499,342.4z M498.9,335.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,335.2,498.9,335.2z M498.9,328c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S499.6,328,498.9,328z M498.9,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,320.8,498.9,320.8z + M498.9,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C500.1,314.2,499.6,313.6,498.9,313.6z M498.9,306.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,306.5,498.9,306.5z M498.9,299.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,299.3,498.9,299.3z M498.9,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S499.6,292.1,498.9,292.1z M498.9,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,284.9,498.9,284.9z + M498.9,277.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,277.7,498.9,277.7z M498.9,270.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C500.1,271.1,499.6,270.5,498.9,270.5z M498.9,263.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,263.4,498.9,263.4z M498.9,256.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,256.2,498.9,256.2z M498.9,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S499.6,249,498.9,249z M498.9,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,241.8,498.9,241.8z + M498.9,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,234.6,498.9,234.6z M498.9,227.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C500.1,228,499.6,227.4,498.9,227.4z M498.9,220.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,220.2,498.9,220.2z M498.9,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S499.6,213.1,498.9,213.1z M498.9,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,205.9,498.9,205.9z + M498.9,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,198.7,498.9,198.7z M498.9,191.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,191.5,498.9,191.5z M498.9,184.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,184.3,498.9,184.3z M498.9,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C500.1,177.7,499.6,177.1,498.9,177.1z M498.9,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,170,498.9,170z + M498.9,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,162.8,498.9,162.8z M498.9,155.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,155.6,498.9,155.6z M498.9,148.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S499.6,148.4,498.9,148.4z M498.9,141.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S499.6,141.2,498.9,141.2z M502.5,338.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,338.8,502.5,338.8z + M502.5,331.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,331.6,502.5,331.6z M502.5,324.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,324.4,502.5,324.4z M502.5,317.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C503.7,317.8,503.2,317.2,502.5,317.2z M502.5,310c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S503.2,310,502.5,310z M502.5,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S503.2,302.9,502.5,302.9z M502.5,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,295.7,502.5,295.7z + M502.5,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,288.5,502.5,288.5z M502.5,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,281.3,502.5,281.3z M502.5,274.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,274.1,502.5,274.1z M502.5,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S503.2,266.9,502.5,266.9z M502.5,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,259.8,502.5,259.8z + M502.5,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,252.6,502.5,252.6z M502.5,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,245.4,502.5,245.4z M502.5,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,238.2,502.5,238.2z M502.5,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C503.7,231.6,503.2,231,502.5,231z M502.5,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,223.8,502.5,223.8z + M502.5,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,216.7,502.5,216.7z M502.5,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,209.5,502.5,209.5z M502.5,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,202.3,502.5,202.3z M502.5,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S503.2,195.1,502.5,195.1z M502.5,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,187.9,502.5,187.9z + M502.5,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C503.7,181.3,503.2,180.7,502.5,180.7z M502.5,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,173.6,502.5,173.6z M502.5,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,166.4,502.5,166.4z M502.5,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S503.2,159.2,502.5,159.2z M502.5,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S503.2,152,502.5,152z M502.5,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C503.7,145.4,503.2,144.8,502.5,144.8z M502.5,346l1.2,1.2l0,0 + C503.7,346.5,503.2,346,502.5,346z M506.1,349.6L506.1,349.6L506.1,349.6l1.1,1.2l0.1,0.1v-0.1 + C507.3,350.1,506.8,349.6,506.1,349.6z M506.1,342.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,342.4,506.1,342.4z M506.1,335.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,335.2,506.1,335.2z + M506.1,328c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C507.3,328.5,506.8,328,506.1,328z M506.1,320.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,320.8,506.1,320.8z M506.1,313.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C507.3,314.2,506.8,313.6,506.1,313.6z M506.1,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C507.3,307,506.8,306.5,506.1,306.5z M506.1,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S506.8,299.3,506.1,299.3z M506.1,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,292.1,506.1,292.1z + M506.1,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,284.9,506.1,284.9z M506.1,277.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S506.8,277.7,506.1,277.7z M492.1,335.3l0.8,0.8 + C492.8,335.7,492.5,335.4,492.1,335.3z M491.7,328c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,328.5,492.4,328,491.7,328z M491.7,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,320.8,491.7,320.8z + M491.7,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C492.9,314.2,492.4,313.6,491.7,313.6z M491.7,306.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C492.9,307,492.4,306.5,491.7,306.5z M491.7,299.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,299.3,491.7,299.3z M491.7,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S492.4,292.1,491.7,292.1z M491.7,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,284.9,491.7,284.9z + M491.7,277.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,277.7,491.7,277.7z M491.7,270.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C492.9,271.1,492.4,270.5,491.7,270.5z M491.7,263.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,263.4,491.7,263.4z M491.7,256.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C492.9,256.7,492.4,256.2,491.7,256.2z M491.7,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S492.4,249,491.7,249z M491.7,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,242.3,492.4,241.8,491.7,241.8z M491.7,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S492.4,234.6,491.7,234.6z M491.7,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,228,492.4,227.4,491.7,227.4z M491.7,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S492.4,220.2,491.7,220.2z M491.7,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,213.6,492.4,213.1,491.7,213.1z M491.7,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,206.4,492.4,205.9,491.7,205.9z M491.7,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S492.4,198.7,491.7,198.7z M491.7,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,192,492.4,191.5,491.7,191.5z M491.7,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S492.4,184.3,491.7,184.3z M491.7,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,177.7,492.4,177.1,491.7,177.1z M491.7,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C492.9,170.5,492.4,170,491.7,170z M491.7,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,162.8,491.7,162.8z + M491.7,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,155.6,491.7,155.6z M491.7,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C492.9,148.9,492.4,148.4,491.7,148.4z M491.7,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S492.4,141.2,491.7,141.2z M495.5,140l-0.7-0.1c0.2,0.1,0.3,0.1,0.5,0.1 + C495.4,140,495.4,140,495.5,140z M495.3,331.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,331.6,495.3,331.6z + M495.3,324.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,324.4,495.3,324.4z M495.3,317.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C496.5,317.8,496,317.2,495.3,317.2z M495.3,310c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,310,495.3,310z M495.3,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S496,302.9,495.3,302.9z M495.3,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,295.7,495.3,295.7z + M495.3,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,288.5,495.3,288.5z M495.3,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,281.3,495.3,281.3z M495.3,274.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,274.1,495.3,274.1z M495.3,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S496,266.9,495.3,266.9z M495.3,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,259.8,495.3,259.8z + M495.3,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,252.6,495.3,252.6z M495.3,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,245.4,495.3,245.4z M495.3,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,238.2,495.3,238.2z M495.3,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C496.5,231.6,496,231,495.3,231z M495.3,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,223.8,495.3,223.8z + M495.3,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,216.7,495.3,216.7z M495.3,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,209.5,495.3,209.5z M495.3,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,202.3,495.3,202.3z M495.3,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S496,195.1,495.3,195.1z M495.3,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,187.9,495.3,187.9z + M495.3,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C496.5,181.3,496,180.7,495.3,180.7z M495.3,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,173.6,495.3,173.6z M495.3,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,166.4,495.3,166.4z M495.3,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S496,159.2,495.3,159.2z M495.3,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S496,152,495.3,152z M495.3,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C496.5,145.4,496,144.8,495.3,144.8z M495.6,338.8l0.9,0.9 + C496.4,339.3,496,338.9,495.6,338.8z M481,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,245.4,481,245.4z + M481,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,238.2,481,238.2z M481,231c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C482.2,231.6,481.6,231,481,231z M481,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S481.6,223.8,481,223.8z M481,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S481.6,216.7,481,216.7z M481,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,209.5,481,209.5z M481,202.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,202.3,481,202.3z M481,195.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,195.1,481,195.1z M481,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S481.6,187.9,481,187.9z M481,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C482.2,181.3,481.6,180.7,481,180.7z + M481,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,173.6,481,173.6z M481,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,166.4,481,166.4z M481,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S481.6,159.2,481,159.2z M481,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,152,481,152z M481,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C482.2,145.4,481.6,144.8,481,144.8z M480,138.2c-0.1,0.2-0.2,0.4-0.2,0.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.1,0-0.2-0.1-0.4L480,138.2z M484.6,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S485.2,320.8,484.6,320.8z M484.6,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,314.2,485.2,313.6,484.6,313.6z M484.6,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,307,485.2,306.5,484.6,306.5z M484.6,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S485.2,299.3,484.6,299.3z M484.6,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,292.1,484.6,292.1z + M484.6,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,284.9,484.6,284.9z M484.6,277.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,277.7,484.6,277.7z M484.6,270.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C485.8,271.1,485.2,270.5,484.6,270.5z M484.6,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S485.2,263.4,484.6,263.4z M484.6,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,256.7,485.2,256.2,484.6,256.2z M484.6,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,249,484.6,249z + M484.6,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C485.8,242.3,485.2,241.8,484.6,241.8z M484.6,234.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,234.6,484.6,234.6z M484.6,227.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C485.8,228,485.2,227.4,484.6,227.4z M484.6,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S485.2,220.2,484.6,220.2z M484.6,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,213.6,485.2,213.1,484.6,213.1z M484.6,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,206.4,485.2,205.9,484.6,205.9z M484.6,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S485.2,198.7,484.6,198.7z M484.6,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,192,485.2,191.5,484.6,191.5z M484.6,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S485.2,184.3,484.6,184.3z M484.6,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,177.7,485.2,177.1,484.6,177.1z M484.6,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C485.8,170.5,485.2,170,484.6,170z M484.6,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,162.8,484.6,162.8z + M484.6,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,155.6,484.6,155.6z M484.6,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C485.8,148.9,485.2,148.4,484.6,148.4z M484.6,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S485.2,141.2,484.6,141.2z M488.1,324.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,324.4,488.1,324.4z M488.1,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,317.8,488.8,317.2,488.1,317.2z M488.1,310c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,310,488.1,310z + M488.1,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C489.3,303.4,488.8,302.9,488.1,302.9z M488.1,295.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,295.7,488.1,295.7z M488.1,288.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C489.3,289,488.8,288.5,488.1,288.5z M488.1,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S488.8,281.3,488.1,281.3z M488.1,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S488.8,274.1,488.1,274.1z M488.1,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,266.9,488.1,266.9z + M488.1,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,259.8,488.1,259.8z M488.1,252.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C489.3,253.1,488.8,252.6,488.1,252.6z M488.1,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,245.4,488.1,245.4z M488.1,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C489.3,238.7,488.8,238.2,488.1,238.2z M488.1,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C489.3,231.6,488.8,231,488.1,231z M488.1,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S488.8,223.8,488.1,223.8z M488.1,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,217.2,488.8,216.7,488.1,216.7z M488.1,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S488.8,209.5,488.1,209.5z M488.1,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,202.8,488.8,202.3,488.1,202.3z M488.1,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,195.6,488.8,195.1,488.1,195.1z M488.1,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S488.8,187.9,488.1,187.9z M488.1,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,181.3,488.8,180.7,488.1,180.7z M488.1,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C489.3,174.1,488.8,173.6,488.1,173.6z M488.1,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S488.8,166.4,488.1,166.4z M488.1,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,159.2,488.1,159.2z + M488.1,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S488.8,152,488.1,152z M488.1,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C489.3,145.4,488.8,144.8,488.1,144.8z M488.1,140c0.5,0,0.9-0.3,1.1-0.7L487,139 + C487.1,139.6,487.6,140,488.1,140z M488.6,331.7l0.6,0.7C489.1,332.1,488.9,331.8,488.6,331.7z M470.2,256.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C471.4,256.7,470.8,256.2,470.2,256.2z M470.2,249c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,249,470.2,249z M470.2,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,242.3,470.8,241.8,470.2,241.8z M470.2,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S470.8,234.6,470.2,234.6z M470.2,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,228,470.8,227.4,470.2,227.4z M470.2,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S470.8,220.2,470.2,220.2z M470.2,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,213.6,470.8,213.1,470.2,213.1z M470.2,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,206.4,470.8,205.9,470.2,205.9z M470.2,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S470.8,198.7,470.2,198.7z M470.2,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,192,470.8,191.5,470.2,191.5z M470.2,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S470.8,184.3,470.2,184.3z M470.2,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,177.7,470.8,177.1,470.2,177.1z M470.2,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,170.5,470.8,170,470.2,170z M470.2,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,162.8,470.2,162.8z + M470.2,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,155.6,470.2,155.6z M470.2,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C471.4,148.9,470.8,148.4,470.2,148.4z M470.2,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,141.2,470.2,141.2z M473.8,310c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,310,473.8,310z M473.8,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S474.4,302.9,473.8,302.9z M473.8,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,295.7,473.8,295.7z + M473.8,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,288.5,473.8,288.5z M473.8,281.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,281.3,473.8,281.3z M473.8,274.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,274.1,473.8,274.1z M473.8,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S474.4,266.9,473.8,266.9z M473.8,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,259.8,473.8,259.8z + M473.8,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,252.6,473.8,252.6z M473.8,245.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,245.4,473.8,245.4z M473.8,238.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,238.2,473.8,238.2z M473.8,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C475,231.6,474.4,231,473.8,231z M473.8,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,223.8,473.8,223.8z + M473.8,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,216.7,473.8,216.7z M473.8,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,209.5,473.8,209.5z M473.8,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,202.3,473.8,202.3z M473.8,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S474.4,195.1,473.8,195.1z M473.8,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,187.9,473.8,187.9z + M473.8,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C475,181.3,474.4,180.7,473.8,180.7z M473.8,173.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,173.6,473.8,173.6z M473.8,166.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,166.4,473.8,166.4z M473.8,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S474.4,159.2,473.8,159.2z M473.8,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S474.4,152,473.8,152z M473.8,144.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C475,145.4,474.4,144.8,473.8,144.8z M473.8,137.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C475,138.2,474.4,137.6,473.8,137.6z M477.4,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C478.6,314.2,478,313.6,477.4,313.6z M477.4,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S478,306.5,477.4,306.5z M477.4,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,299.3,477.4,299.3z + M477.4,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,292.1,477.4,292.1z M477.4,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,284.9,477.4,284.9z M477.4,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,277.7,477.4,277.7z M477.4,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C478.6,271.1,478,270.5,477.4,270.5z M477.4,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,263.4,477.4,263.4z + M477.4,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,256.2,477.4,256.2z M477.4,249c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,249,477.4,249z M477.4,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S478,241.8,477.4,241.8z M477.4,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,234.6,477.4,234.6z + M477.4,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C478.6,228,478,227.4,477.4,227.4z M477.4,220.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,220.2,477.4,220.2z M477.4,213.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,213.1,477.4,213.1z M477.4,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S478,205.9,477.4,205.9z M477.4,198.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,198.7,477.4,198.7z + M477.4,191.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,191.5,477.4,191.5z M477.4,184.3 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,184.3,477.4,184.3z M477.4,177.1c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C478.6,177.7,478,177.1,477.4,177.1z M477.4,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S478,170,477.4,170z M477.4,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,162.8,477.4,162.8z + M477.4,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,155.6,477.4,155.6z M477.4,148.4 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,148.4,477.4,148.4z M477.4,141.2c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S478,141.2,477.4,141.2z M481,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C482.2,317.8,481.6,317.2,481,317.2z M481,310c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,310,481,310z + M481,302.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,302.9,481,302.9z M481,295.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,295.7,481,295.7z M481,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S481.6,288.5,481,288.5z M481,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,281.3,481,281.3z M481,274.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,274.1,481,274.1z M481,266.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,266.9,481,266.9z M481,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S481.6,259.8,481,259.8z M481,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S481.6,252.6,481,252.6z M463,249 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,249,463,249z M463,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S463.7,256.2,463,256.2z M463,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S463.7,263.4,463,263.4z M463,241.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,241.8,463,241.8z M463,234.6 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,234.6,463,234.6z M463,227.4c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C464.2,228,463.7,227.4,463,227.4z M463,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S463.7,220.2,463,220.2z M463,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S463.7,213.1,463,213.1z M463,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,205.9,463,205.9z M463,198.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,198.7,463,198.7z M463,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,191.5,463,191.5z M463,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S463.7,184.3,463,184.3z M463,177.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C464.2,177.7,463.7,177.1,463,177.1z + M463,170c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,170,463,170z M463,162.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,162.8,463,162.8z M463,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S463.7,155.6,463,155.6z M463,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,148.4,463,148.4z M463,141.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S463.7,141.2,463,141.2z M466.6,302.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C467.8,303.4,467.3,302.9,466.6,302.9z M466.6,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S467.3,295.7,466.6,295.7z M466.6,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C467.8,289,467.3,288.5,466.6,288.5z M466.6,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S467.3,281.3,466.6,281.3z M466.6,274.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,274.1,466.6,274.1z + M466.6,266.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,266.9,466.6,266.9z M466.6,259.8 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,259.8,466.6,259.8z M466.6,252.6c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C467.8,253.1,467.3,252.6,466.6,252.6z M466.6,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S467.3,245.4,466.6,245.4z M466.6,238.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C467.8,238.7,467.3,238.2,466.6,238.2z M466.6,231c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C467.8,231.6,467.3,231,466.6,231z M466.6,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,223.8,466.6,223.8z + M466.6,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C467.8,217.2,467.3,216.7,466.6,216.7z M466.6,209.5 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,209.5,466.6,209.5z M466.6,202.3c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C467.8,202.8,467.3,202.3,466.6,202.3z M466.6,195.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C467.8,195.6,467.3,195.1,466.6,195.1z M466.6,187.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S467.3,187.9,466.6,187.9z M466.6,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C467.8,181.3,467.3,180.7,466.6,180.7z M466.6,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C467.8,174.1,467.3,173.6,466.6,173.6z M466.6,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S467.3,166.4,466.6,166.4z M466.6,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,159.2,466.6,159.2z + M466.6,152c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S467.3,152,466.6,152z M466.6,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C467.8,145.4,467.3,144.8,466.6,144.8z M466.6,137.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C467.8,138.2,467.3,137.6,466.6,137.6z M470.2,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C471.4,307,470.8,306.5,470.2,306.5z M470.2,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S470.8,299.3,470.2,299.3z M470.2,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,292.1,470.2,292.1z + M470.2,284.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,284.9,470.2,284.9z M470.2,277.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S470.8,277.7,470.2,277.7z M470.2,270.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C471.4,271.1,470.8,270.5,470.2,270.5z M470.2,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S470.8,263.4,470.2,263.4z M520.5,162.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,162.8,520.5,162.8z M524.1,360.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C525.3,360.9,524.7,360.3,524.1,360.3z M520.5,148.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S521.1,148.4,520.5,148.4z M520.5,155.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S521.1,155.6,520.5,155.6z + M524.1,353.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,353.1,524.1,353.1z M524.1,346 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,346,524.1,346z M524.1,338.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,338.8,524.1,338.8z M524.1,331.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S524.7,331.6,524.1,331.6z M524.1,324.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,324.4,524.1,324.4z + M524.1,317.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C525.3,317.8,524.7,317.2,524.1,317.2z M524.1,310 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,310,524.1,310z M524.1,302.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,302.9,524.1,302.9z M524.1,295.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S524.7,295.7,524.1,295.7z M524.1,288.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,288.5,524.1,288.5z + M524.1,281.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,281.3,524.1,281.3z M524.1,274.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,274.1,524.1,274.1z M524.1,266.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,266.9,524.1,266.9z M524.1,259.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S524.7,259.8,524.1,259.8z M524.1,252.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,252.6,524.1,252.6z + M524.1,245.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,245.4,524.1,245.4z M524.1,238.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,238.2,524.1,238.2z M524.1,231c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C525.3,231.6,524.7,231,524.1,231z M524.1,223.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2S524.7,223.8,524.1,223.8z M524.1,216.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S524.7,216.7,524.1,216.7z M524.1,209.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,209.5,524.1,209.5z + M524.1,202.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,202.3,524.1,202.3z M524.1,195.1 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,195.1,524.1,195.1z M524.1,187.9c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,187.9,524.1,187.9z M524.1,180.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C525.3,181.3,524.7,180.7,524.1,180.7z M524.1,173.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S524.7,173.6,524.1,173.6z M524.1,166.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,166.4,524.1,166.4z + M524.1,159.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,159.2,524.1,159.2z M524.1,152 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S524.7,152,524.1,152z M524.1,144.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2C525.3,145.4,524.7,144.8,524.1,144.8z M524.1,367.5c-0.2,0-0.3,0-0.5,0.1l1.5,1.6 + c0.1-0.1,0.1-0.3,0.1-0.5C525.3,368.1,524.7,367.5,524.1,367.5z M527.7,371.1c-0.2,0-0.4,0-0.5,0.1l0.5,0.5l0.5,0.5l0.5,0.5 + c0.1-0.2,0.1-0.4,0.1-0.5C528.9,371.6,528.3,371.1,527.7,371.1z M527.7,363.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2C528.9,364.5,528.3,363.9,527.7,363.9z M527.7,356.7c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,356.7,527.7,356.7z M527.7,349.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,349.6,527.7,349.6z + M527.7,342.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,342.4,527.7,342.4z M527.7,335.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,335.2,527.7,335.2z M527.7,328c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,328,527.7,328z M527.7,320.8c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,320.8,527.7,320.8z M527.7,313.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C528.9,314.2,528.3,313.6,527.7,313.6z M527.7,306.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,306.5,527.7,306.5z M527.7,299.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,299.3,527.7,299.3z + M527.7,292.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,292.1,527.7,292.1z M527.7,284.9 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,284.9,527.7,284.9z M527.7,277.7c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,277.7,527.7,277.7z M527.7,270.5c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C528.9,271.1,528.3,270.5,527.7,270.5z M527.7,263.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,263.4,527.7,263.4z M527.7,256.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,256.2,527.7,256.2z + M527.7,249c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,249,527.7,249z M527.7,241.8c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,241.8,527.7,241.8z M527.7,234.6c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,234.6,527.7,234.6z M527.7,227.4c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C528.9,228,528.3,227.4,527.7,227.4z M527.7,220.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,220.2,527.7,220.2z M527.7,213.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,213.1,527.7,213.1z + M527.7,205.9c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,205.9,527.7,205.9z M527.7,198.7 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,198.7,527.7,198.7z M527.7,191.5c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S528.3,191.5,527.7,191.5z M527.7,184.3c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + S528.3,184.3,527.7,184.3z M332.8,398.7c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.1,0,0.2,0l0.3-2.3c-0.1-0.1-0.3-0.1-0.5-0.1 + C333.4,397.5,332.8,398.1,332.8,398.7z M336.4,373.6c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.1,0,0.1,0l0.2-1.2l0.2-1.1 + c-0.1-0.1-0.3-0.1-0.5-0.1C337,372.4,336.4,372.9,336.4,373.6z M329.2,431.1c0,0.4,0.2,0.7,0.4,0.9l0.1-0.9l0.2-1.1 + C329.5,430.2,329.2,430.6,329.2,431.1z M332.8,405.9c0,0.3,0.1,0.7,0.4,0.9l0.3-1.9C333.1,405.1,332.8,405.5,332.8,405.9z + M329.2,423.9c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.1,0,0.2,0l0.2-1.2l0.1-1.1c-0.1-0.1-0.3-0.1-0.5-0.1 + C329.8,422.7,329.2,423.2,329.2,423.9z M329.2,409.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S329.2,408.8,329.2,409.5z M329.2,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,416,329.2,416.7z + M336.4,380.8c0,0.3,0.1,0.6,0.4,0.9l0.1-0.9l0.1-1C336.7,379.9,336.4,380.3,336.4,380.8z M332.8,377.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S332.8,376.5,332.8,377.2z M332.8,391.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S332.8,390.9,332.8,391.5z M332.8,384.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S332.8,383.7,332.8,384.4z + M325.6,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,426.8,325.6,427.5z M325.6,398.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,398.1,325.6,398.7z M325.6,434.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,434,325.6,434.7z M325.6,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S325.6,405.3,325.6,405.9z M329.2,395.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,394.5,329.2,395.1z + M325.6,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,441.2,325.6,441.8z M328,377.2c0-0.1,0-0.2-0.1-0.3 + l-2.1,1.1c0.2,0.3,0.5,0.5,0.9,0.5C327.5,378.4,328,377.8,328,377.2z M329.2,380.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S329.2,380.1,329.2,380.8z M325.6,391.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S325.6,390.9,325.6,391.5z M325.6,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,412.4,325.6,413.1z + M325.6,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,419.6,325.6,420.3z M329.2,388c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,387.3,329.2,388z M329.2,402.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S329.2,401.7,329.2,402.3z M325.6,384.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,383.7,325.6,384.4z + M325.6,449c0,0.7,0.5,1.2,1.2,1.2c0.1,0,0.1,0,0.2,0l0.3-2.2c-0.2-0.1-0.3-0.1-0.5-0.1C326.2,447.8,325.6,448.4,325.6,449z + M325.6,456.2c0,0.4,0.2,0.7,0.4,0.9l0.3-2C325.9,455.3,325.6,455.7,325.6,456.2z M322.1,409.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,408.8,322.1,409.5z M322.1,481.3c0,0.4,0.2,0.7,0.4,0.9l0.1-0.9l0.2-1.1 + C322.4,480.4,322.1,480.9,322.1,481.3z M322.1,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S322.1,451.9,322.1,452.6z M322.1,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,416,322.1,416.7z + M322.1,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,437.6,322.1,438.2z M322.1,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,459.1,322.1,459.8z M322.1,431.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,430.4,322.1,431.1z M322.1,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S322.1,423.2,322.1,423.9z M322.1,402.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,401.7,322.1,402.3z + M322.1,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,466.3,322.1,467z M322.1,474.2c0,0.7,0.5,1.2,1.2,1.2 + c0.1,0,0.1,0,0.2,0l0.2-1.2l0.1-1.1c-0.2-0.1-0.3-0.1-0.5-0.1C322.6,473,322.1,473.5,322.1,474.2z M322.1,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,444.8,322.1,445.4z M322.1,395.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,394.5,322.1,395.1z M318.5,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S318.5,455.5,318.5,456.2z M318.5,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C319,404.7,318.5,405.3,318.5,405.9z M318.5,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S318.5,412.4,318.5,413.1z M318.5,398.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.5,398.1,318.5,398.7z + M322.1,388c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322.1,387.3,322.1,388z M318.5,463.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C319,462.2,318.5,462.7,318.5,463.4z M318.5,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C319,476.6,318.5,477.1,318.5,477.8z M318.5,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S318.5,448.4,318.5,449z M318.5,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.5,426.8,318.5,427.5z + M318.5,391.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C319,390.4,318.5,390.9,318.5,391.5z M318.5,420.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C319,419.1,318.5,419.6,318.5,420.3z M318.5,492.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.5,491.5,318.5,492.1z M318.5,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C319,483.7,318.5,484.3,318.5,484.9z M318.5,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S318.5,469.9,318.5,470.6z M318.5,384.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C319,383.2,318.5,383.7,318.5,384.4z M322.1,380.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S322.1,380.1,322.1,380.8z M318.5,506.5c0,0.2,0.1,0.5,0.2,0.6l0.3,0.1l0.3-1.8C318.8,505.6,318.5,506,318.5,506.5z M318.5,441.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C319,440.6,318.5,441.2,318.5,441.8z M318.5,499.3c0,0.7,0.5,1.2,1.2,1.2 + c0.1,0,0.2,0,0.3-0.1l0.3-2.2c-0.2-0.1-0.4-0.2-0.6-0.2C319,498.1,318.5,498.6,318.5,499.3z M318.5,434.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.5,434,318.5,434.7z M314.9,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S314.9,473.5,314.9,474.2z M314.9,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,437.6,314.9,438.2z + M314.9,395.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,394.5,314.9,395.1z M314.9,481.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,480.7,314.9,481.3z M311.3,492.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,491.5,311.3,492.1z M314.9,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S314.9,430.4,314.9,431.1z M314.9,388c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,387.3,314.9,388z M314.9,467 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,466.3,314.9,467z M314.9,416.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,416,314.9,416.7z M314.9,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S314.9,451.9,314.9,452.6z M314.9,488.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,487.9,314.9,488.5z + M311.3,499.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,498.6,311.3,499.3z M314.9,423.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,423.2,314.9,423.9z M314.9,409.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,408.8,314.9,409.5z M311.3,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.3,484.3,311.3,484.9z M314.9,502.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,502.2,314.9,502.9z + M314.9,402.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,401.7,314.9,402.3z M314.9,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,444.8,314.9,445.4z M314.9,495.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.9,495.1,314.9,495.7z M314.9,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S314.9,459.1,314.9,459.8z M307.7,488.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,487.9,307.7,488.5z + M307.7,495.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,495.1,307.7,495.7z M307.7,502.9c0,0.2,0,0.3,0.1,0.5 + l1.1,0.4l0.5,0.2c0.4-0.2,0.7-0.6,0.7-1c0-0.7-0.5-1.2-1.2-1.2C308.2,501.7,307.7,502.2,307.7,502.9z M311.3,434.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,434,311.3,434.7z M311.3,391.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,390.9,311.3,391.5z M313.7,384.4v-0.1l-1.9,1c0.2,0.2,0.5,0.3,0.8,0.3 + C313.1,385.6,313.7,385,313.7,384.4z M311.3,398.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.3,398.1,311.3,398.7z M311.3,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,462.7,311.3,463.4z + M311.3,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,448.4,311.3,449z M311.3,441.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,441.2,311.3,441.8z M311.3,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.3,419.6,311.3,420.3z M311.3,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,477.1,311.3,477.8z + M311.3,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,455.5,311.3,456.2z M311.3,413.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,412.4,311.3,413.1z M311.3,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,469.9,311.3,470.6z M311.3,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.3,426.8,311.3,427.5z M311.3,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.3,405.3,311.3,405.9z + M304.1,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304.1,448.4,304.1,449z M307.7,402.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.2,401.1,307.7,401.7,307.7,402.3z M307.7,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S307.7,473.5,307.7,474.2z M307.7,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S307.7,430.4,307.7,431.1z M304.1,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.6,462.2,304.1,462.7,304.1,463.4z M304.1,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.6,419.1,304.1,419.6,304.1,420.3z M304.1,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S304.1,455.5,304.1,456.2z M307.7,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,416,307.7,416.7z + M307.7,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,466.3,307.7,467z M304.1,441.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C304.6,440.6,304.1,441.2,304.1,441.8z M307.7,395.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S307.7,394.5,307.7,395.1z M304.1,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S304.1,412.4,304.1,413.1z M304.1,398.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304.1,398.1,304.1,398.7z + M307.7,481.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.2,480.1,307.7,480.7,307.7,481.3z M307.7,409.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,408.8,307.7,409.5z M304.1,427.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304.1,426.8,304.1,427.5z M304.1,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.6,483.7,304.1,484.3,304.1,484.9z M307.7,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C308.2,458.6,307.7,459.1,307.7,459.8z M304.1,492.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S304.1,491.5,304.1,492.1z M304.1,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304.1,469.9,304.1,470.6z + M307.7,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,437.6,307.7,438.2z M308,387.2 + c-0.2,0.2-0.3,0.5-0.3,0.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2h-0.1L308,387.2z M304.1,477.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C304.6,476.6,304.1,477.1,304.1,477.8z M304.1,434.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304.1,434,304.1,434.7z M307.7,452.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.7,451.9,307.7,452.6z M304.1,499.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.6,498.1,304.1,498.6,304.1,499.3z M307.7,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C308.2,444.2,307.7,444.8,307.7,445.4z M307.7,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C308.2,422.7,307.7,423.2,307.7,423.9z M304.1,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.6,404.7,304.1,405.3,304.1,405.9z M300.5,395.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S300.5,394.5,300.5,395.1z M296.9,492.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S296.9,491.5,296.9,492.1z + M300.5,409.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,408.8,300.5,409.5z M300.5,402.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C301,401.1,300.5,401.7,300.5,402.3z M300.5,438.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,437.6,300.5,438.2z M300.5,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S300.5,430.4,300.5,431.1z M300.5,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,416,300.5,416.7z + M300.5,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C301,422.7,300.5,423.2,300.5,423.9z M300.5,488.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,487.9,300.5,488.5z M300.5,445.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C301,444.2,300.5,444.8,300.5,445.4z M300.5,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S300.5,473.5,300.5,474.2z M300.5,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S300.5,466.3,300.5,467z M300.5,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,451.9,300.5,452.6z + M300.5,495.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S300.5,495.1,300.5,495.7z M300.5,481.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C301,480.1,300.5,480.7,300.5,481.3z M300.5,459.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C301,458.6,300.5,459.1,300.5,459.8z M304.1,391.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C304.6,390.4,304.1,390.9,304.1,391.5z M289.7,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S289.7,405.3,289.7,405.9z M289.7,398.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,398.1,289.7,398.7z + M289.7,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,434,289.7,434.7z M289.7,441.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,441.2,289.7,441.8z M289.7,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S289.7,426.8,289.7,427.5z M289.7,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,419.6,289.7,420.3z + M289.7,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,412.4,289.7,413.1z M296.9,427.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S296.9,426.8,296.9,427.5z M293.3,416.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,415.5,293.3,416,293.3,416.7z M289.7,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S289.7,448.4,289.7,449z M296.9,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,483.7,296.9,484.3,296.9,484.9z M293.3,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,465.8,293.3,466.3,293.3,467z M296.9,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S296.9,412.4,296.9,413.1z M289.7,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,469.9,289.7,470.6z + M289.7,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,477.1,289.7,477.8z M296.9,434.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S296.9,434,296.9,434.7z M293.3,474.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,473,293.3,473.5,293.3,474.2z M293.3,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C293.9,458.6,293.3,459.1,293.3,459.8z M293.3,495.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,494.5,293.3,495.1,293.3,495.7z M293.3,402.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,401.1,293.3,401.7,293.3,402.3z M296.9,398.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S296.9,398.1,296.9,398.7z M293.3,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,429.9,293.3,430.4,293.3,431.1z M289.7,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S289.7,484.3,289.7,484.9z M293.3,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,451.4,293.3,451.9,293.3,452.6z M289.7,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S289.7,455.5,289.7,456.2z M293.3,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.9,422.7,293.3,423.2,293.3,423.9z M296.9,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,404.7,296.9,405.3,296.9,405.9z M299.3,391.7l-1.7,0.9c0.2,0.1,0.4,0.1,0.6,0.1C298.7,392.7,299.2,392.3,299.3,391.7z + M293.3,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,437,293.3,437.6,293.3,438.2z M293.3,488.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,487.3,293.3,487.9,293.3,488.5z M293.3,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,444.2,293.3,444.8,293.3,445.4z M289.7,492.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S289.7,491.5,289.7,492.1z M293.3,409.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,408.3,293.3,408.8,293.3,409.5z M296.9,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C297.4,476.6,296.9,477.1,296.9,477.8z M289.7,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S289.7,462.7,289.7,463.4z M296.9,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S296.9,455.5,296.9,456.2z + M296.9,499.3c0,0.1,0,0.3,0.1,0.4l1.8,0.6c0.3-0.2,0.5-0.6,0.5-1c0-0.7-0.5-1.2-1.2-1.2C297.4,498.1,296.9,498.6,296.9,499.3z + M296.9,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S296.9,448.4,296.9,449z M296.9,441.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C297.4,440.6,296.9,441.2,296.9,441.8z M293.4,394.7c0,0.1-0.1,0.3-0.1,0.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.6-0.4-1-0.9-1.1l-0.3,0.2L293.4,394.7z M293.3,481.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C293.9,480.1,293.3,480.7,293.3,481.3z M296.9,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C297.4,462.2,296.9,462.7,296.9,463.4z M296.9,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S296.9,469.9,296.9,470.6z M296.9,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,419.1,296.9,419.6,296.9,420.3z M282.5,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,433.5,282.5,434,282.5,434.7z M275.4,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.4,469.9,275.4,470.6z M275.4,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,448.4,275.4,449z M282.5,449 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,447.8,282.5,448.4,282.5,449z M275.4,477.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,477.1,275.4,477.8z M286.1,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S286.1,430.4,286.1,431.1z M279,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,473.5,279,474.2z M286.1,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,459.1,286.1,459.8z M286.1,481.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,480.7,286.1,481.3z M286.1,495.7c0,0.1,0,0.2,0,0.3l1.1,0.4l0.8,0.3 + c0.3-0.2,0.4-0.5,0.4-0.9c0-0.7-0.5-1.2-1.2-1.2S286.1,495.1,286.1,495.7z M279,488.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S279,487.9,279,488.5z M275.4,405.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.4,405.3,275.4,405.9z M286.1,409.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,408.8,286.1,409.5z + M279,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,430.4,279,431.1z M275.4,492.1v0.1l2,0.7 + c0.2-0.2,0.3-0.5,0.3-0.8c0-0.7-0.5-1.2-1.2-1.2S275.4,491.5,275.4,492.1z M279,409.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S279,408.8,279,409.5z M286.1,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S286.1,444.8,286.1,445.4z M282.5,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,462.2,282.5,462.7,282.5,463.4z M286.1,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S286.1,416,286.1,416.7z M279,402.2v0.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.4-0.3-0.8-0.6-1l-0.6,0.3L279,402.2z + M282.5,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,476.6,282.5,477.1,282.5,477.8z M279,438.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,437.6,279,438.2z M286.1,452.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,451.9,286.1,452.6z M275.4,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.4,426.8,275.4,427.5z M286.1,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,466.3,286.1,467z + M275.4,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,419.6,275.4,420.3z M282.5,456.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,455,282.5,455.5,282.5,456.2z M279,459.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,459.1,279,459.8z M282.5,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,440.6,282.5,441.2,282.5,441.8z M279,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,416,279,416.7z + M275.4,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,412.4,275.4,413.1z M275.4,456.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,455.5,275.4,456.2z M282.5,484.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,483.7,282.5,484.3,282.5,484.9z M275.4,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S275.4,441.2,275.4,441.8z M282.5,492.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,490.9,282.5,491.5,282.5,492.1z M275.4,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.4,462.7,275.4,463.4z M286.1,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,437.6,286.1,438.2z + M275.4,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.4,434,275.4,434.7z M282.5,405.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,404.7,282.5,405.3,282.5,405.9z M282.5,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C283.1,411.9,282.5,412.4,282.5,413.1z M279,481.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S279,480.7,279,481.3z M284.8,399.2l-1.4,0.7c0.1,0,0.2,0,0.3,0C284.2,399.9,284.7,399.6,284.8,399.2z M286.1,474.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,473.5,286.1,474.2z M279,445.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,444.8,279,445.4z M279,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S279,451.9,279,452.6z M279,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,423.2,279,423.9z M282.5,427.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283.1,426.3,282.5,426.8,282.5,427.5z M286.1,488.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,487.9,286.1,488.5z M286.1,402.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,401.7,286.1,402.3z M282.5,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,419.1,282.5,419.6,282.5,420.3z M282.5,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283.1,469.4,282.5,469.9,282.5,470.6z M275.4,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.4,484.3,275.4,484.9z M286.1,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,423.2,286.1,423.9z + M279,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S279,466.3,279,467z M250.2,459.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C250.8,458.6,250.2,459.1,250.2,459.8z M250.2,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C250.8,473,250.2,473.5,250.2,474.2z M250.2,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.8,465.8,250.2,466.3,250.2,467z M250.2,481.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.8,480.1,250.2,480.7,250.2,481.3z M253.8,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,455,253.8,455.5,253.8,456.2z M253.8,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,476.6,253.8,477.1,253.8,477.8z M253.8,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,426.3,253.8,426.8,253.8,427.5z M253.8,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,462.2,253.8,462.7,253.8,463.4z M257.4,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S257.4,416,257.4,416.7z M253.8,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C254.3,447.8,253.8,448.4,253.8,449z + M253.8,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C254.3,440.6,253.8,441.2,253.8,441.8z M253.8,484.8l2.2,0.7 + c0.1-0.2,0.2-0.4,0.2-0.6c0-0.7-0.5-1.2-1.2-1.2C254.4,483.7,253.9,484.2,253.8,484.8z M252.6,416.7c0-0.3-0.1-0.5-0.3-0.7 + l-0.9,0.5l-0.4,0.2l-0.7,0.4c0.1,0.5,0.6,0.8,1.1,0.8C252.1,417.9,252.6,417.4,252.6,416.7z M257.4,423.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S257.4,423.2,257.4,423.9z M253.8,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,419.1,253.8,419.6,253.8,420.3z M253.8,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,433.5,253.8,434,253.8,434.7z M253.8,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,469.4,253.8,469.9,253.8,470.6z M268.2,420.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S268.2,419.6,268.2,420.3z M261,484.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,484.3,261,484.9z M261,441.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,441.2,261,441.8z M271.8,488.5c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,487.9,271.8,488.5z M264.6,488.5L264.6,488.5l1.2,0.4l0.9,0.3c0.2-0.2,0.3-0.4,0.3-0.7 + c0-0.7-0.5-1.2-1.2-1.2S264.6,487.9,264.6,488.5z M271.8,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S271.8,444.8,271.8,445.4z M257.4,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S257.4,451.9,257.4,452.6z + M271.8,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,423.2,271.8,423.9z M257.4,467c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S257.4,466.3,257.4,467z M257.4,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S257.4,459.1,257.4,459.8z M264.6,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,437.6,264.6,438.2z + M264.6,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,430.4,264.6,431.1z M261,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,469.9,261,470.6z M264.6,481.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.6,480.7,264.6,481.3z M271.8,409.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,408.8,271.8,409.5z + M268.2,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,477.1,268.2,477.8z M268.2,434.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,434,268.2,434.7z M261,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S261,448.4,261,449z M264.6,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.6,459.1,264.6,459.8z M264.6,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,466.3,264.6,467z + M269.6,407.1c0.2-0.1,0.5-0.2,0.6-0.3L269.6,407.1z M257.4,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S257.4,437.6,257.4,438.2z M257.4,481.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S257.4,480.7,257.4,481.3z + M261,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,477.1,261,477.8z M271.8,416.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,416,271.8,416.7z M267,409.5c0-0.4-0.1-0.7-0.4-0.9l-0.8,0.4l-0.9,0.5l-0.3,0.1 + c0.1,0.6,0.6,1.1,1.2,1.1C266.4,410.7,267,410.2,267,409.5z M271.8,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S271.8,430.4,271.8,431.1z M271.8,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,473.5,271.8,474.2z + M271.8,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,437.6,271.8,438.2z M271.8,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,459.1,271.8,459.8z M268.2,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,469.9,268.2,470.6z M261,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S261,434,261,434.7z M257.4,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S257.4,430.4,257.4,431.1z M268.2,463.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,462.7,268.2,463.4z M261,456.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,455.5,261,456.2z M264.6,423.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.6,423.2,264.6,423.9z M271.8,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,466.3,271.8,467z + M264.6,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,473.5,264.6,474.2z M268.2,449c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,448.4,268.2,449z M257.4,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S257.4,473.5,257.4,474.2z M261,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,462.7,261,463.4z M261,420.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,419.6,261,420.3z M268.2,484.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,484.3,268.2,484.9z M261,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S261,426.8,261,427.5z M271.8,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,451.9,271.8,452.6z + M264.6,416.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,416,264.6,416.7z M268.2,456.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,455.5,268.2,456.2z M257.4,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S257.4,444.8,257.4,445.4z M261,413.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S261,412.4,261,413.1z M271.8,481.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.8,480.7,271.8,481.3z M268.2,413.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,412.4,268.2,413.1z M264.6,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.6,451.9,264.6,452.6z M264.6,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.6,444.8,264.6,445.4z + M268.2,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,441.2,268.2,441.8z M268.2,427.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.2,426.8,268.2,427.5z M232.3,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.3,469.9,232.3,470.6z M232.3,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.3,462.7,232.3,463.4z M235.8,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,466.3,235.8,467z + M235.8,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,437.6,235.8,438.2z M235.8,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,444.8,235.8,445.4z M235.8,452.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,451.9,235.8,452.6z M235.8,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,459.1,235.8,459.8z M235.8,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,473.5,235.8,474.2z + M235.8,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,430.4,235.8,431.1z M250.2,423.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C250.8,422.7,250.2,423.2,250.2,423.9z M250.2,438.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C250.8,437,250.2,437.6,250.2,438.2z M243,423.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.6,422.7,243,423.2,243,423.9z M239.4,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C240,476.6,239.4,477.1,239.4,477.8z M243,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.6,451.4,243,451.9,243,452.6z M239.4,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,462.2,239.4,462.7,239.4,463.4z M243,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.6,437,243,437.6,243,438.2z M239.4,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,455,239.4,455.5,239.4,456.2z M239.4,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,447.8,239.4,448.4,239.4,449z M243,474.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.6,473,243,473.5,243,474.2z M246.6,477.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,477.1,246.6,477.8z + M246.6,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,434,246.6,434.7z M246.6,449c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,448.4,246.6,449z M246.6,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S246.6,462.7,246.6,463.4z M246.6,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,441.2,246.6,441.8z + M243,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.6,429.9,243,430.4,243,431.1z M250.2,452.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C250.8,451.4,250.2,451.9,250.2,452.6z M246.6,420.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,419.6,246.6,420.3z M246.6,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S246.6,469.9,246.6,470.6z M250.2,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.8,444.2,250.2,444.8,250.2,445.4z M243,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.6,444.2,243,444.8,243,445.4z M239.4,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,440.6,239.4,441.2,239.4,441.8z M239.4,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,426.3,239.4,426.8,239.4,427.5z M246.6,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S246.6,426.8,246.6,427.5z M243.1,481.2l0.6,0.2l0.6,0.2l1,0.4c0.1-0.2,0.2-0.4,0.2-0.6c0-0.7-0.5-1.2-1.2-1.2 + C243.6,480.1,243.2,480.6,243.1,481.2z M239.4,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C240,433.5,239.4,434,239.4,434.7z M250.2,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.8,429.9,250.2,430.4,250.2,431.1z M243,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.6,458.6,243,459.1,243,459.8z M238.2,423.9c0-0.2-0.1-0.4-0.1-0.5l-1,0.5H237l-1,0.5c0.2,0.4,0.6,0.6,1,0.6 + C237.7,425.1,238.2,424.5,238.2,423.9z M246.6,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S246.6,455.5,246.6,456.2z M243,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.6,465.8,243,466.3,243,467z + M239.4,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C240,469.4,239.4,469.9,239.4,470.6z M180.7,453.1l-1.1,0.6 + l-0.2,0.1c0.1,0,0.1,0,0.2,0C180.1,453.8,180.5,453.5,180.7,453.1z M207.1,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S207.1,459.1,207.1,459.8z M217.9,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.9,455.5,217.9,456.2z M207.1,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S207.1,451.9,207.1,452.6z + M217.9,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.9,448.4,217.9,449z M203.5,456.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C204.1,455,203.5,455.5,203.5,456.2z M195.1,445.6l-1.1,0.6l-0.5,0.3c0.2,0.1,0.3,0.1,0.5,0.1 + C194.5,446.6,195,446.2,195.1,445.6z M210.7,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S210.7,462.7,210.7,463.4z M182,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S182,455.5,182,456.2z M192.7,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.3,458.6,192.7,459.1,192.7,459.8z M185.6,452.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.6,451.9,185.6,452.6z M214.3,438.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S214.3,437.6,214.3,438.2z M189.4,462.7l2.2,0.7c0,0,0,0,0-0.1c0-0.7-0.5-1.2-1.2-1.2 + C189.9,462.2,189.6,462.4,189.4,462.7z M214.3,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S214.3,451.9,214.3,452.6z M200.1,466.4l1,0.4l0.7,0.2l0.5,0.2c0-0.1,0-0.1,0-0.2c0-0.7-0.5-1.2-1.2-1.2 + C200.7,465.8,200.3,466,200.1,466.4z M210.7,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S210.7,448.4,210.7,449z + M199.9,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S199.9,459.1,199.9,459.8z M189.2,448.7 + c0,0.1-0.1,0.2-0.1,0.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.5-0.3-1-0.8-1.1L189.2,448.7z M214.3,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C214.8,458.6,214.3,459.1,214.3,459.8z M203.5,463.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C204.1,462.2,203.5,462.7,203.5,463.4z M217.9,463.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.4,462.2,217.9,462.7,217.9,463.4z M179.6,458.6 + c-0.4,0-0.7,0.2-0.9,0.4l0.9,0.3l1.2,0.4C180.7,459.1,180.2,458.6,179.6,458.6z M217.9,441.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.4,440.6,217.9,441.2,217.9,441.8z M192.7,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C193.3,451.4,192.7,451.9,192.7,452.6z M203.8,441.1c-0.1,0.2-0.2,0.4-0.2,0.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2c0-0.6-0.5-1.2-1.2-1.2L203.8,441.1z M174.8,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.4-0.2-0.8-0.6-1 + L174.8,456.2L174.8,456.2z M189.2,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.2,455.5,189.2,456.2z + M210.7,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S210.7,455.5,210.7,456.2z M214.3,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C214.8,444.2,214.3,444.8,214.3,445.4z M207.1,445.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S207.1,444.8,207.1,445.4z M207.1,467c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S207.1,466.3,207.1,467z M196.3,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,455.5,196.3,456.2z M203.5,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C204.1,447.8,203.5,448.4,203.5,449z + M199.9,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S199.9,451.9,199.9,452.6z M214.3,467c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S214.3,466.3,214.3,467z M199.9,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S199.9,444.8,199.9,445.4z M210.7,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S210.7,441.2,210.7,441.8z + M196.3,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,462.7,196.3,463.4z M185.6,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186.1,458.6,185.6,459.1,185.6,459.8z M209.5,438.2L209.5,438.2h-0.1 + l-1.1,0.5l-0.7,0.4c0.2,0.1,0.4,0.3,0.7,0.3C209,439.4,209.5,438.9,209.5,438.2z M196.3,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S196.3,448.4,196.3,449z M210.8,470.1l2.2,0.8c0-0.1,0.1-0.2,0.1-0.3c0-0.7-0.5-1.2-1.2-1.2 + C211.4,469.4,211,469.7,210.8,470.1z M217.9,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.9,434,217.9,434.7z + M225.1,449c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225.1,448.4,225.1,449z M232.3,434.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.3,434,232.3,434.7z M232.3,456.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.3,455.5,232.3,456.2z M225.1,470.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225.1,469.9,225.1,470.6z + M225.1,463.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.6,462.2,225.1,462.7,225.1,463.4z M232.3,449 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.3,448.4,232.3,449z M217.9,470.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.9,469.9,217.9,470.6z M221.5,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.5,437.6,221.5,438.2z M225.1,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C225.6,440.6,225.1,441.2,225.1,441.8z M221.5,452.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.5,451.9,221.5,452.6z M228.7,431.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.7,430.4,228.7,431.1z + M221.5,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.5,444.8,221.5,445.4z M225.1,456.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225.1,455.5,225.1,456.2z M228.7,452.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.7,451.9,228.7,452.6z M232.3,441.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.3,441.2,232.3,441.8z M221.5,459.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.5,459.1,221.5,459.8z + M225.1,434.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225.1,434,225.1,434.7z M221.5,467c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.5,466.3,221.5,467z M232.3,477.5l2.2,0.8c0.1-0.1,0.1-0.3,0.1-0.5c0-0.7-0.5-1.2-1.2-1.2 + C232.9,476.6,232.5,476.9,232.3,477.5z M223.9,431.1c0-0.1,0-0.2-0.1-0.3l-0.6,0.3l-0.6,0.3l-0.9,0.5c0.2,0.3,0.5,0.4,0.9,0.4 + C223.3,432.3,223.9,431.7,223.9,431.1z M228.7,467c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.7,466.3,228.7,467z + M228.7,438.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.7,437.6,228.7,438.2z M228.7,459.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.2,458.6,228.7,459.1,228.7,459.8z M221.6,473.8l1.1,0.4h0.1l1.1,0.4 + c0-0.1,0.1-0.2,0.1-0.4c0-0.7-0.5-1.2-1.2-1.2C222.2,473,221.7,473.3,221.6,473.8z M228.7,474.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.7,473.5,228.7,474.2z M232.3,427.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.3,426.8,232.3,427.5z M228.7,445.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C229.2,444.2,228.7,444.8,228.7,445.4z M397.8,339.8l1.8-0.3c0.1-0.2,0.1-0.3,0.1-0.5c0-0.7-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2 + C397.4,339.3,397.6,339.6,397.8,339.8z M395,334.1c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2S395.7,334.1,395,334.1z + M390.2,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C390.8,337.7,390.2,338.2,390.2,338.9z M390.2,331.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C390.8,330.5,390.2,331.1,390.2,331.7z M383,338.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C383.6,337.7,383,338.2,383,338.9z M386.8,341.9l1.7-0.3c-0.2-0.1-0.4-0.3-0.7-0.3 + C387.4,341.3,387,341.5,386.8,341.9z M383,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C383.6,330.5,383,331.1,383,331.7z M386.6,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C387.2,334.1,386.6,334.6,386.6,335.3z M385.4,324.5c0-0.1,0-0.1,0-0.2l-1.2-1c-0.6,0-1.1,0.5-1.1,1.2s0.5,1.2,1.2,1.2 + C384.9,325.7,385.4,325.2,385.4,324.5z M381.7,321.4L380,320c-0.3,0.2-0.5,0.6-0.5,1c0,0.7,0.5,1.2,1.2,1.2 + C381.1,322.1,381.6,321.8,381.7,321.4z M386.6,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C387.2,326.9,386.6,327.5,386.6,328.1z M375.9,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C376.4,337.7,375.9,338.2,375.9,338.9z M379.4,342.5c0,0.3,0.1,0.5,0.3,0.7l2.1-0.4c0-0.1,0.1-0.2,0.1-0.3c0-0.7-0.5-1.2-1.2-1.2 + C380,341.3,379.4,341.8,379.4,342.5z M375.9,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S375.9,331.1,375.9,331.7z M379.4,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C380,334.1,379.4,334.6,379.4,335.3z M375.9,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S375.9,323.9,375.9,324.5z M379.4,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C380,326.9,379.4,327.5,379.4,328.1z M377,318.5c0.3,0,0.6-0.1,0.8-0.3l-1.8-1.5c-0.1,0.2-0.2,0.4-0.2,0.6 + C375.9,318,376.4,318.5,377,318.5z M369,345.2l1.3-0.3c-0.1-0.1-0.3-0.1-0.5-0.1C369.5,344.9,369.2,345,369,345.2z M368.7,338.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C369.2,337.7,368.7,338.2,368.7,338.9z M372.3,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S372.3,341.8,372.3,342.5z M368.7,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S368.7,331.1,368.7,331.7z M372.3,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C372.8,334.1,372.3,334.6,372.3,335.3z M368.7,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S368.7,323.9,368.7,324.5z M372.3,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S372.3,327.5,372.3,328.1z + M368.7,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C369.2,316.1,368.7,316.7,368.7,317.3z M372.3,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C372.8,319.7,372.3,320.3,372.3,320.9z M373.5,314.9c0.1,0,0.2,0,0.2,0 + l-1.4-1.1l0,0C372.3,314.4,372.8,314.9,373.5,314.9z M361.5,346.1c0,0.2,0.1,0.4,0.2,0.6l2.2-0.4v-0.1c0-0.7-0.5-1.2-1.2-1.2 + C362,344.9,361.5,345.4,361.5,346.1z M361.5,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C362,337.7,361.5,338.2,361.5,338.9z M365.1,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S365.1,341.8,365.1,342.5z M361.5,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S361.5,331.1,361.5,331.7z + M365.1,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C365.6,334.1,365.1,334.6,365.1,335.3z M361.5,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S361.5,323.9,361.5,324.5z M365.1,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S365.1,327.5,365.1,328.1z M361.5,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C362,316.1,361.5,316.7,361.5,317.3z M365.1,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C365.6,319.7,365.1,320.3,365.1,320.9z M361.5,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S361.5,309.5,361.5,310.2z M365.1,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C365.6,312.6,365.1,313.1,365.1,313.8z M354.3,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S354.3,345.4,354.3,346.1z M354.3,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C354.8,337.7,354.3,338.2,354.3,338.9z M357.9,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S357.9,341.8,357.9,342.5z M354.3,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S354.3,331.1,354.3,331.7z + M357.9,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C358.4,334.1,357.9,334.6,357.9,335.3z M354.3,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S354.3,323.9,354.3,324.5z M357.9,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S357.9,327.5,357.9,328.1z M354.3,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C354.8,316.1,354.3,316.7,354.3,317.3z M357.9,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C358.4,319.7,357.9,320.3,357.9,320.9z M354.3,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S354.3,309.5,354.3,310.2z M357.9,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C358.4,312.6,357.9,313.1,357.9,313.8z M354.3,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S354.3,302.3,354.3,303z + M357.9,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S357.9,305.9,357.9,306.6z M347.1,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C347.7,344.9,347.1,345.4,347.1,346.1z M347.1,338.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C347.7,337.7,347.1,338.2,347.1,338.9z M350.7,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S350.7,341.8,350.7,342.5z M347.1,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C347.7,330.5,347.1,331.1,347.1,331.7z M350.7,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C351.2,334.1,350.7,334.6,350.7,335.3z M347.1,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C347.7,323.3,347.1,323.9,347.1,324.5z M350.7,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S350.7,327.5,350.7,328.1z M347.1,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C347.7,316.1,347.1,316.7,347.1,317.3z M350.7,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C351.2,319.7,350.7,320.3,350.7,320.9z M347.1,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C347.7,309,347.1,309.5,347.1,310.2z M350.7,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C351.2,312.6,350.7,313.1,350.7,313.8z M347.1,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C347.7,301.8,347.1,302.3,347.1,303z M350.7,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S350.7,305.9,350.7,306.6z M349.5,295.8c0-0.2,0-0.3-0.1-0.4l-0.9-0.7c-0.1,0-0.1,0-0.2,0c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2 + C349,297,349.5,296.5,349.5,295.8z M345.9,292.5l-1.7-1.3c-0.4,0.2-0.7,0.6-0.7,1.1c0,0.7,0.5,1.2,1.2,1.2 + C345.3,293.4,345.7,293,345.9,292.5z M350.7,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C351.2,298.2,350.7,298.7,350.7,299.4z M339.9,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,344.9,339.9,345.4,339.9,346.1z M343.5,349.7c0,0.1,0,0.3,0.1,0.4l2.3-0.4c0-0.6-0.5-1.1-1.2-1.1 + C344.1,348.5,343.5,349,343.5,349.7z M339.9,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,337.7,339.9,338.2,339.9,338.9z M343.5,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,341.3,343.5,341.8,343.5,342.5z M339.9,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,330.5,339.9,331.1,339.9,331.7z M343.5,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,334.1,343.5,334.6,343.5,335.3z M339.9,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,323.3,339.9,323.9,339.9,324.5z M343.5,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,326.9,343.5,327.5,343.5,328.1z M339.9,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,316.1,339.9,316.7,339.9,317.3z M343.5,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,319.7,343.5,320.3,343.5,320.9z M339.9,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,309,339.9,309.5,339.9,310.2z M343.5,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,312.6,343.5,313.1,343.5,313.8z M339.9,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,301.8,339.9,302.3,339.9,303z M343.5,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,305.4,343.5,305.9,343.5,306.6z M339.9,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C340.5,294.6,339.9,295.1,339.9,295.8z M343.5,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C344.1,298.2,343.5,298.7,343.5,299.4z M342,289.4l-1.8-1.5c-0.1,0.2-0.2,0.4-0.2,0.7c0,0.7,0.5,1.2,1.2,1.2 + C341.5,289.8,341.8,289.6,342,289.4z M332.7,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,344.9,332.7,345.4,332.7,346.1z M336.3,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,348.5,336.3,349,336.3,349.7z M332.7,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,337.7,332.7,338.2,332.7,338.9z M336.3,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,341.3,336.3,341.8,336.3,342.5z M332.7,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,330.5,332.7,331.1,332.7,331.7z M336.3,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,334.1,336.3,334.6,336.3,335.3z M332.7,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,323.3,332.7,323.9,332.7,324.5z M336.3,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,326.9,336.3,327.5,336.3,328.1z M332.7,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,316.1,332.7,316.7,332.7,317.3z M336.3,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,319.7,336.3,320.3,336.3,320.9z M332.7,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,309,332.7,309.5,332.7,310.2z M336.3,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,312.6,336.3,313.1,336.3,313.8z M332.7,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,301.8,332.7,302.3,332.7,303z M336.3,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,305.4,336.3,305.9,336.3,306.6z M332.7,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,294.6,332.7,295.1,332.7,295.8z M336.3,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,298.2,336.3,298.7,336.3,299.4z M332.7,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C333.3,287.4,332.7,287.9,332.7,288.6z M336.3,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C336.9,291,336.3,291.5,336.3,292.2z M337.5,286.2c0.1,0,0.3,0,0.4-0.1l-1.6-1.3c0,0.1,0,0.1,0,0.2 + C336.3,285.7,336.9,286.2,337.5,286.2z M333.4,282.5l-0.4-0.3C333.1,282.3,333.3,282.4,333.4,282.5z M325.6,353.3 + c0,0.1,0,0.1,0,0.2l2.3-0.4c-0.1-0.5-0.6-0.9-1.1-0.9C326.1,352.1,325.6,352.6,325.6,353.3z M325.6,346.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,345.4,325.6,346.1z M329.2,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S329.2,349,329.2,349.7z M325.6,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C326.1,337.7,325.6,338.2,325.6,338.9z M329.2,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S329.2,341.8,329.2,342.5z M325.6,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,331.1,325.6,331.7z + M329.2,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C329.7,334.1,329.2,334.6,329.2,335.3z M325.6,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,323.9,325.6,324.5z M329.2,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,327.5,329.2,328.1z M325.6,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C326.1,316.1,325.6,316.7,325.6,317.3z M329.2,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C329.7,319.7,329.2,320.3,329.2,320.9z M325.6,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S325.6,309.5,325.6,310.2z M329.2,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C329.7,312.6,329.2,313.1,329.2,313.8z M325.6,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,302.3,325.6,303z + M329.2,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,305.9,329.2,306.6z M325.6,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C326.1,294.6,325.6,295.1,325.6,295.8z M329.2,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C329.7,298.2,329.2,298.7,329.2,299.4z M325.6,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S325.6,287.9,325.6,288.6z M329.2,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,291.5,329.2,292.2z M325.6,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C326.1,280.2,325.6,280.8,325.6,281.4z M329.2,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S329.2,284.4,329.2,285z + M318.4,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C318.9,352.1,318.4,352.6,318.4,353.3z M318.4,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.4,345.4,318.4,346.1z M322,349.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322,349,322,349.7z M318.4,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C318.9,337.7,318.4,338.2,318.4,338.9z M322,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322,341.8,322,342.5z + M318.4,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.4,331.1,318.4,331.7z M322,335.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C322.5,334.1,322,334.6,322,335.3z M318.4,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S318.4,323.9,318.4,324.5z M322,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S322,327.5,322,328.1z M318.4,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C318.9,316.1,318.4,316.7,318.4,317.3z + M322,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C322.5,319.7,322,320.3,322,320.9z M318.4,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.4,309.5,318.4,310.2z M322,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C322.5,312.6,322,313.1,322,313.8z M318.4,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S318.4,302.3,318.4,303z M322,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322,305.9,322,306.6 + z M318.4,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C318.9,294.6,318.4,295.1,318.4,295.8z M322,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C322.5,298.2,322,298.7,322,299.4z M318.4,288.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.4,287.9,318.4,288.6z M322,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S322,291.5,322,292.2z M318.4,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C318.9,280.2,318.4,280.8,318.4,281.4z + M322,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S322,284.4,322,285z M318.4,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S318.4,273.6,318.4,274.2z M322,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C322.5,276.6,322,277.2,322,277.8z M311.2,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C311.7,352.1,311.2,352.6,311.2,353.3z M311.2,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.2,345.4,311.2,346.1z M314.8,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.8,349,314.8,349.7z + M311.2,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C311.7,337.7,311.2,338.2,311.2,338.9z M314.8,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.8,341.8,314.8,342.5z M311.2,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.2,331.1,311.2,331.7z M314.8,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C315.3,334.1,314.8,334.6,314.8,335.3z M311.2,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.2,323.9,311.2,324.5z M314.8,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.8,327.5,314.8,328.1z + M311.2,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C311.7,316.1,311.2,316.7,311.2,317.3z M314.8,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C315.3,319.7,314.8,320.3,314.8,320.9z M311.2,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.2,309.5,311.2,310.2z M314.8,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C315.3,312.6,314.8,313.1,314.8,313.8z M311.2,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S311.2,302.3,311.2,303z M314.8,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S314.8,305.9,314.8,306.6z M311.2,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C311.7,294.6,311.2,295.1,311.2,295.8z M314.8,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C315.3,298.2,314.8,298.7,314.8,299.4z M311.2,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S311.2,287.9,311.2,288.6z M314.8,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.8,291.5,314.8,292.2z + M311.2,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C311.7,280.2,311.2,280.8,311.2,281.4z M314.8,285 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S314.8,284.4,314.8,285z M311.2,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S311.2,273.6,311.2,274.2z M314.8,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C315.3,276.6,314.8,277.2,314.8,277.8z M313.6,267.1c0-0.3-0.1-0.6-0.3-0.8l-0.2-0.2c-0.2-0.1-0.4-0.2-0.6-0.2 + c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2C313.1,268.3,313.6,267.7,313.6,267.1z M308.4,262.3c-0.5,0.2-0.8,0.6-0.8,1.1 + c0,0.7,0.5,1.2,1.2,1.2c0.6,0,1.1-0.5,1.2-1.1L308.4,262.3z M314.8,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C315.3,269.5,314.8,270,314.8,270.6z M304,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.5,352.1,304,352.6,304,353.3z M307.6,356.9l2.3-0.4c-0.2-0.4-0.6-0.8-1.1-0.8C308.1,355.7,307.6,356.2,307.6,356.9z + M304,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304,345.4,304,346.1z M307.6,349.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.6,349,307.6,349.7z M304,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.5,337.7,304,338.2,304,338.9z M307.6,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.6,341.8,307.6,342.5z + M304,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304,331.1,304,331.7z M307.6,335.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.1,334.1,307.6,334.6,307.6,335.3z M304,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S304,323.9,304,324.5z M307.6,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S307.6,327.5,307.6,328.1z M304,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C304.5,316.1,304,316.7,304,317.3z + M307.6,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.1,319.7,307.6,320.3,307.6,320.9z M304,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304,309.5,304,310.2z M307.6,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.1,312.6,307.6,313.1,307.6,313.8z M304,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S304,302.3,304,303z M307.6,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S307.6,305.9,307.6,306.6z M304,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C304.5,294.6,304,295.1,304,295.8z + M307.6,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.1,298.2,307.6,298.7,307.6,299.4z M304,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304,287.9,304,288.6z M307.6,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.6,291.5,307.6,292.2z M304,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C304.5,280.2,304,280.8,304,281.4z M307.6,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S307.6,284.4,307.6,285z + M304,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S304,273.6,304,274.2z M307.6,277.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C308.1,276.6,307.6,277.2,307.6,277.8z M304,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S304,266.4,304,267.1z M307.6,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C308.1,269.5,307.6,270,307.6,270.6z M306.2,260.5l-1.8-1.5c-0.2,0.2-0.3,0.5-0.3,0.8c0,0.7,0.5,1.2,1.2,1.2 + C305.6,261.1,306,260.9,306.2,260.5z M301.5,358l0.8-0.1c0.4-0.2,0.6-0.6,0.6-1c0-0.7-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2 + C300.4,357.5,300.9,357.9,301.5,358z M296.8,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,352.1,296.8,352.6,296.8,353.3z M296.8,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,344.9,296.8,345.4,296.8,346.1z M300.4,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,348.5,300.4,349,300.4,349.7z M296.8,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,337.7,296.8,338.2,296.8,338.9z M300.4,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,341.3,300.4,341.8,300.4,342.5z M296.8,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,330.5,296.8,331.1,296.8,331.7z M300.4,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,334.1,300.4,334.6,300.4,335.3z M296.8,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,323.3,296.8,323.9,296.8,324.5z M300.4,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,326.9,300.4,327.5,300.4,328.1z M296.8,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,316.1,296.8,316.7,296.8,317.3z M300.4,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,319.7,300.4,320.3,300.4,320.9z M296.8,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,309,296.8,309.5,296.8,310.2z M300.4,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,312.6,300.4,313.1,300.4,313.8z M296.8,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,301.8,296.8,302.3,296.8,303z M300.4,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,305.4,300.4,305.9,300.4,306.6z M296.8,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,294.6,296.8,295.1,296.8,295.8z M300.4,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,298.2,300.4,298.7,300.4,299.4z M296.8,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,287.4,296.8,287.9,296.8,288.6z M300.4,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,291,300.4,291.5,300.4,292.2z M296.8,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,280.2,296.8,280.8,296.8,281.4z M300.4,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,283.8,300.4,284.4,300.4,285z M296.8,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,273,296.8,273.6,296.8,274.2z M300.4,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,276.6,300.4,277.2,300.4,277.8z M296.8,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,265.9,296.8,266.4,296.8,267.1z M300.4,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,269.5,300.4,270,300.4,270.6z M296.8,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C297.4,258.7,296.8,259.2,296.8,259.9z M300.4,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C301,262.3,300.4,262.8,300.4,263.5z M301.6,257.5c0.2,0,0.4-0.1,0.6-0.2l-1.7-1.4c0,0.1-0.1,0.2-0.1,0.3 + C300.4,256.9,301,257.5,301.6,257.5z M297.9,253.9l-0.9-0.8C297.1,253.5,297.4,253.8,297.9,253.9z M289.7,360.2l2.2-0.4 + c-0.2-0.3-0.6-0.6-1-0.6C290.3,359.3,289.8,359.7,289.7,360.2z M289.6,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C290.2,352.1,289.6,352.6,289.6,353.3z M293.2,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,355.7,293.2,356.2,293.2,356.9z M289.6,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,344.9,289.6,345.4,289.6,346.1z M293.2,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,348.5,293.2,349,293.2,349.7z M289.6,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,337.7,289.6,338.2,289.6,338.9z M293.2,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,341.3,293.2,341.8,293.2,342.5z M289.6,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,330.5,289.6,331.1,289.6,331.7z M293.2,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,334.1,293.2,334.6,293.2,335.3z M289.6,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,323.3,289.6,323.9,289.6,324.5z M293.2,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,326.9,293.2,327.5,293.2,328.1z M289.6,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,316.1,289.6,316.7,289.6,317.3z M293.2,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,319.7,293.2,320.3,293.2,320.9z M289.6,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,309,289.6,309.5,289.6,310.2z M293.2,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,312.6,293.2,313.1,293.2,313.8z M289.6,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,301.8,289.6,302.3,289.6,303z M293.2,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,305.4,293.2,305.9,293.2,306.6z M289.6,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,294.6,289.6,295.1,289.6,295.8z M293.2,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,298.2,293.2,298.7,293.2,299.4z M289.6,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,287.4,289.6,287.9,289.6,288.6z M293.2,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,291,293.2,291.5,293.2,292.2z M289.6,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,280.2,289.6,280.8,289.6,281.4z M293.2,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,283.8,293.2,284.4,293.2,285z M289.6,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,273,289.6,273.6,289.6,274.2z M293.2,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,276.6,293.2,277.2,293.2,277.8z M289.6,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,265.9,289.6,266.4,289.6,267.1z M293.2,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,269.5,293.2,270,293.2,270.6z M289.6,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,258.7,289.6,259.2,289.6,259.9z M293.2,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C293.8,262.3,293.2,262.8,293.2,263.5z M289.6,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C290.2,251.5,289.6,252,289.6,252.7z M293.2,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C293.8,255.1,293.2,255.6,293.2,256.3z M283.1,361.5l1.5-0.3c0.2-0.2,0.3-0.5,0.3-0.8c0-0.7-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2 + C282.5,360.9,282.7,361.3,283.1,361.5z M282.5,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283,352.1,282.5,352.6,282.5,353.3z M286.1,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C286.6,355.7,286.1,356.2,286.1,356.9z M282.5,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S282.5,345.4,282.5,346.1z M286.1,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,349,286.1,349.7z + M282.5,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283,337.7,282.5,338.2,282.5,338.9z M286.1,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,341.8,286.1,342.5z M282.5,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S282.5,331.1,282.5,331.7z M286.1,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C286.6,334.1,286.1,334.6,286.1,335.3z M282.5,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S282.5,323.9,282.5,324.5z M286.1,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,327.5,286.1,328.1z + M282.5,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283,316.1,282.5,316.7,282.5,317.3z M286.1,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C286.6,319.7,286.1,320.3,286.1,320.9z M282.5,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S282.5,309.5,282.5,310.2z M286.1,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C286.6,312.6,286.1,313.1,286.1,313.8z M282.5,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S282.5,302.3,282.5,303z M286.1,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S286.1,305.9,286.1,306.6z M282.5,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283,294.6,282.5,295.1,282.5,295.8z M286.1,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C286.6,298.2,286.1,298.7,286.1,299.4z M282.5,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S282.5,287.9,282.5,288.6z M286.1,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,291.5,286.1,292.2z + M282.5,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C283,280.2,282.5,280.8,282.5,281.4z M286.1,285 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S286.1,284.4,286.1,285z M282.5,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S282.5,273.6,282.5,274.2z M286.1,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C286.6,276.6,286.1,277.2,286.1,277.8z M282.5,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S282.5,266.4,282.5,267.1z M286.1,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C286.6,269.5,286.1,270,286.1,270.6z M282.5,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C283,258.7,282.5,259.2,282.5,259.9z M286.1,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S286.1,262.8,286.1,263.5z M282.5,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S282.5,252,282.5,252.7z + M286.1,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C286.6,255.1,286.1,255.6,286.1,256.3z M282.5,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S282.5,244.8,282.5,245.5z M286.1,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C286.6,247.9,286.1,248.4,286.1,249.1z M275.3,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C275.8,359.3,275.3,359.8,275.3,360.4z M275.3,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C275.8,352.1,275.3,352.6,275.3,353.3z M278.9,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C279.4,355.7,278.9,356.2,278.9,356.9z M275.3,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.3,345.4,275.3,346.1z M278.9,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S278.9,349,278.9,349.7z + M275.3,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C275.8,337.7,275.3,338.2,275.3,338.9z M278.9,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S278.9,341.8,278.9,342.5z M275.3,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.3,331.1,275.3,331.7z M278.9,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C279.4,334.1,278.9,334.6,278.9,335.3z M275.3,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.3,323.9,275.3,324.5z M278.9,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S278.9,327.5,278.9,328.1z + M275.3,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C275.8,316.1,275.3,316.7,275.3,317.3z M278.9,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C279.4,319.7,278.9,320.3,278.9,320.9z M275.3,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.3,309.5,275.3,310.2z M278.9,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C279.4,312.6,278.9,313.1,278.9,313.8z M275.3,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S275.3,302.3,275.3,303z M278.9,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S278.9,305.9,278.9,306.6z M275.3,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C275.8,294.6,275.3,295.1,275.3,295.8z M278.9,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C279.4,298.2,278.9,298.7,278.9,299.4z M275.3,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.3,287.9,275.3,288.6z M278.9,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S278.9,291.5,278.9,292.2z + M275.3,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C275.8,280.2,275.3,280.8,275.3,281.4z M278.9,285 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S278.9,284.4,278.9,285z M275.3,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.3,273.6,275.3,274.2z M278.9,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C279.4,276.6,278.9,277.2,278.9,277.8z M275.3,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S275.3,266.4,275.3,267.1z M278.9,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C279.4,269.5,278.9,270,278.9,270.6z M275.3,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C275.8,258.7,275.3,259.2,275.3,259.9z M278.9,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S278.9,262.8,278.9,263.5z M275.3,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.3,252,275.3,252.7z + M278.9,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C279.4,255.1,278.9,255.6,278.9,256.3z M275.3,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S275.3,244.8,275.3,245.5z M278.9,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C279.4,247.9,278.9,248.4,278.9,249.1z M275.3,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S275.3,237.7,275.3,238.3z M274.1,234.7L274.1,234.7l-1.4-1.2c-0.6,0.1-1,0.6-1,1.2c0,0.7,0.5,1.2,1.2,1.2 + C273.5,235.9,274.1,235.4,274.1,234.7z M278.9,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S278.9,241.3,278.9,241.9z M268.1,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C268.6,359.3,268.1,359.8,268.1,360.4z M271.8,363.6l2-0.4c-0.2-0.2-0.5-0.4-0.9-0.4C272.4,362.8,271.9,363.2,271.8,363.6z + M268.1,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C268.6,352.1,268.1,352.6,268.1,353.3z M271.7,356.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,355.7,271.7,356.2,271.7,356.9z M268.1,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,345.4,268.1,346.1z M271.7,349.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.7,349,271.7,349.7z M268.1,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C268.6,337.7,268.1,338.2,268.1,338.9z M271.7,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S271.7,341.8,271.7,342.5z M268.1,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,331.1,268.1,331.7z + M271.7,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,334.1,271.7,334.6,271.7,335.3z M268.1,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,323.9,268.1,324.5z M271.7,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.7,327.5,271.7,328.1z M268.1,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C268.6,316.1,268.1,316.7,268.1,317.3z M271.7,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C272.2,319.7,271.7,320.3,271.7,320.9z M268.1,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S268.1,309.5,268.1,310.2z M271.7,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C272.2,312.6,271.7,313.1,271.7,313.8z M268.1,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,302.3,268.1,303z + M271.7,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.7,305.9,271.7,306.6z M268.1,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C268.6,294.6,268.1,295.1,268.1,295.8z M271.7,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,298.2,271.7,298.7,271.7,299.4z M268.1,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,287.9,268.1,288.6z M271.7,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.7,291.5,271.7,292.2z M268.1,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C268.6,280.2,268.1,280.8,268.1,281.4z M271.7,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S271.7,284.4,271.7,285z + M268.1,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,273.6,268.1,274.2z M271.7,277.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,276.6,271.7,277.2,271.7,277.8z M268.1,267.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,266.4,268.1,267.1z M271.7,270.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,269.5,271.7,270,271.7,270.6z M268.1,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C268.6,258.7,268.1,259.2,268.1,259.9z M271.7,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S271.7,262.8,271.7,263.5z M268.1,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,252,268.1,252.7z + M271.7,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C272.2,255.1,271.7,255.6,271.7,256.3z M268.1,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S268.1,244.8,268.1,245.5z M271.7,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C272.2,247.9,271.7,248.4,271.7,249.1z M268.1,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S268.1,237.7,268.1,238.3z M271.7,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S271.7,241.3,271.7,241.9z M270.3,231.7l-1.8-1.5c-0.3,0.2-0.4,0.5-0.4,0.9c0,0.7,0.5,1.2,1.2,1.2 + C269.7,232.3,270.1,232.1,270.3,231.7z M264.9,364.9l1.8-0.3c0.1-0.2,0.1-0.3,0.1-0.5c0-0.7-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2 + C264.5,364.4,264.7,364.7,264.9,364.9z M260.9,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C261.4,359.3,260.9,359.8,260.9,360.4z M260.9,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C261.4,352.1,260.9,352.6,260.9,353.3z M264.5,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C265,355.7,264.5,356.2,264.5,356.9z M260.9,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S260.9,345.4,260.9,346.1z M264.5,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.5,349,264.5,349.7z + M260.9,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C261.4,337.7,260.9,338.2,260.9,338.9z M264.5,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.5,341.8,264.5,342.5z M260.9,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,331.1,260.9,331.7z M264.5,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C265,334.1,264.5,334.6,264.5,335.3z M260.9,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S260.9,323.9,260.9,324.5z M264.5,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.5,327.5,264.5,328.1z + M260.9,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C261.4,316.1,260.9,316.7,260.9,317.3z M264.5,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C265,319.7,264.5,320.3,264.5,320.9z M260.9,310.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,309.5,260.9,310.2z M264.5,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C265,312.6,264.5,313.1,264.5,313.8z M260.9,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,302.3,260.9,303z + M264.5,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.5,305.9,264.5,306.6z M260.9,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C261.4,294.6,260.9,295.1,260.9,295.8z M264.5,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C265,298.2,264.5,298.7,264.5,299.4z M260.9,288.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,287.9,260.9,288.6z M264.5,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.5,291.5,264.5,292.2z M260.9,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C261.4,280.2,260.9,280.8,260.9,281.4z M264.5,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S264.5,284.4,264.5,285z + M260.9,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,273.6,260.9,274.2z M264.5,277.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C265,276.6,264.5,277.2,264.5,277.8z M260.9,267.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,266.4,260.9,267.1z M264.5,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C265,269.5,264.5,270,264.5,270.6z M260.9,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C261.4,258.7,260.9,259.2,260.9,259.9z M264.5,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.5,262.8,264.5,263.5z M260.9,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,252,260.9,252.7z + M264.5,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C265,255.1,264.5,255.6,264.5,256.3z M260.9,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S260.9,244.8,260.9,245.5z M264.5,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C265,247.9,264.5,248.4,264.5,249.1z M260.9,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S260.9,237.7,260.9,238.3z M264.5,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.5,241.3,264.5,241.9z M260.9,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C261.4,229.9,260.9,230.5,260.9,231.1z M264.5,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S264.5,234.1,264.5,234.7z M265.7,228.7c0.3,0,0.5-0.1,0.7-0.2l-1.8-1.4c-0.1,0.1-0.1,0.3-0.1,0.5 + C264.5,228.2,265,228.7,265.7,228.7z M262.1,225.2C262.1,225.2,262.2,225.1,262.1,225.2l-1.2-1C261,224.7,261.5,225.2,262.1,225.2z + M253.9,367l1.7-0.3c-0.2-0.1-0.4-0.3-0.7-0.3C254.5,366.4,254.1,366.7,253.9,367z M253.7,360.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C254.3,359.3,253.7,359.8,253.7,360.4z M257.3,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C257.9,362.8,257.3,363.4,257.3,364z M253.7,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,352.1,253.7,352.6,253.7,353.3z M257.3,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,355.7,257.3,356.2,257.3,356.9z M253.7,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,344.9,253.7,345.4,253.7,346.1z M257.3,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,348.5,257.3,349,257.3,349.7z M253.7,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,337.7,253.7,338.2,253.7,338.9z M257.3,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,341.3,257.3,341.8,257.3,342.5z M253.7,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,330.5,253.7,331.1,253.7,331.7z M257.3,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,334.1,257.3,334.6,257.3,335.3z M253.7,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,323.3,253.7,323.9,253.7,324.5z M257.3,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,326.9,257.3,327.5,257.3,328.1z M253.7,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,316.1,253.7,316.7,253.7,317.3z M257.3,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,319.7,257.3,320.3,257.3,320.9z M253.7,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,309,253.7,309.5,253.7,310.2z M257.3,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,312.6,257.3,313.1,257.3,313.8z M253.7,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,301.8,253.7,302.3,253.7,303z M257.3,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,305.4,257.3,305.9,257.3,306.6z M253.7,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,294.6,253.7,295.1,253.7,295.8z M257.3,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,298.2,257.3,298.7,257.3,299.4z M253.7,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,287.4,253.7,287.9,253.7,288.6z M257.3,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,291,257.3,291.5,257.3,292.2z M253.7,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,280.2,253.7,280.8,253.7,281.4z M257.3,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,283.8,257.3,284.4,257.3,285z M253.7,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,273,253.7,273.6,253.7,274.2z M257.3,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,276.6,257.3,277.2,257.3,277.8z M253.7,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,265.9,253.7,266.4,253.7,267.1z M257.3,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,269.5,257.3,270,257.3,270.6z M253.7,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,258.7,253.7,259.2,253.7,259.9z M257.3,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,262.3,257.3,262.8,257.3,263.5z M253.7,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,251.5,253.7,252,253.7,252.7z M257.3,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C257.9,255.1,257.3,255.6,257.3,256.3z M253.7,245.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,244.3,253.7,244.8,253.7,245.5z M257.3,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,247.9,257.3,248.4,257.3,249.1z M253.7,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,237.1,253.7,237.7,253.7,238.3z M257.3,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,240.7,257.3,241.3,257.3,241.9z M253.7,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,229.9,253.7,230.5,253.7,231.1z M257.3,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,233.5,257.3,234.1,257.3,234.7z M253.7,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C254.3,222.8,253.7,223.3,253.7,224z M257.3,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C257.9,226.4,257.3,226.9,257.3,227.5z M246.5,367.6c0,0.3,0.1,0.5,0.3,0.7l2.1-0.4c0-0.1,0.1-0.2,0.1-0.3c0-0.7-0.5-1.2-1.2-1.2 + C247.1,366.4,246.5,367,246.5,367.6z M246.5,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,359.3,246.5,359.8,246.5,360.4z M250.1,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,362.8,250.1,363.4,250.1,364z M246.5,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,352.1,246.5,352.6,246.5,353.3z M250.1,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,355.7,250.1,356.2,250.1,356.9z M246.5,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,344.9,246.5,345.4,246.5,346.1z M250.1,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,348.5,250.1,349,250.1,349.7z M246.5,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,337.7,246.5,338.2,246.5,338.9z M250.1,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,341.3,250.1,341.8,250.1,342.5z M246.5,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,330.5,246.5,331.1,246.5,331.7z M250.1,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,334.1,250.1,334.6,250.1,335.3z M246.5,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,323.3,246.5,323.9,246.5,324.5z M250.1,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,326.9,250.1,327.5,250.1,328.1z M246.5,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,316.1,246.5,316.7,246.5,317.3z M250.1,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,319.7,250.1,320.3,250.1,320.9z M246.5,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,309,246.5,309.5,246.5,310.2z M250.1,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,312.6,250.1,313.1,250.1,313.8z M246.5,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,301.8,246.5,302.3,246.5,303z M250.1,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,305.4,250.1,305.9,250.1,306.6z M246.5,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,294.6,246.5,295.1,246.5,295.8z M250.1,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,298.2,250.1,298.7,250.1,299.4z M246.5,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,287.4,246.5,287.9,246.5,288.6z M250.1,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,291,250.1,291.5,250.1,292.2z M246.5,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,280.2,246.5,280.8,246.5,281.4z M250.1,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,283.8,250.1,284.4,250.1,285z M246.5,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,273,246.5,273.6,246.5,274.2z M250.1,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,276.6,250.1,277.2,250.1,277.8z M246.5,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,265.9,246.5,266.4,246.5,267.1z M250.1,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,269.5,250.1,270,250.1,270.6z M246.5,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,258.7,246.5,259.2,246.5,259.9z M250.1,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,262.3,250.1,262.8,250.1,263.5z M246.5,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,251.5,246.5,252,246.5,252.7z M250.1,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C250.7,255.1,250.1,255.6,250.1,256.3z M246.5,245.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,244.3,246.5,244.8,246.5,245.5z M250.1,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,247.9,250.1,248.4,250.1,249.1z M246.5,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,237.1,246.5,237.7,246.5,238.3z M250.1,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,240.7,250.1,241.3,250.1,241.9z M246.5,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,229.9,246.5,230.5,246.5,231.1z M250.1,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,233.5,250.1,234.1,250.1,234.7z M246.5,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,222.8,246.5,223.3,246.5,224z M250.1,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,226.4,250.1,226.9,250.1,227.5z M246.5,216.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C247.1,215.6,246.5,216.1,246.5,216.8z M250.1,220.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C250.7,219.2,250.1,219.7,250.1,220.4z M239.4,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S239.4,367,239.4,367.6z M237,370c-0.3,0-0.6,0.1-0.8,0.3l1.3-0.2C237.3,370.1,237.1,370,237,370z M239.4,360.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C239.9,359.3,239.4,359.8,239.4,360.4z M243,364c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,363.4,243,364z M239.4,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C239.9,352.1,239.4,352.6,239.4,353.3z M243,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.5,355.7,243,356.2,243,356.9z M239.4,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,345.4,239.4,346.1z + M243,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,349,243,349.7z M239.4,338.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C239.9,337.7,239.4,338.2,239.4,338.9z M243,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S243,341.8,243,342.5z M239.4,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S239.4,331.1,239.4,331.7z M243,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.5,334.1,243,334.6,243,335.3z + M239.4,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,323.9,239.4,324.5z M243,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,327.5,243,328.1z M239.4,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C239.9,316.1,239.4,316.7,239.4,317.3z M243,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.5,319.7,243,320.3,243,320.9z M239.4,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,309.5,239.4,310.2z + M243,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.5,312.6,243,313.1,243,313.8z M239.4,303 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,302.3,239.4,303z M243,306.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,305.9,243,306.6z M239.4,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C239.9,294.6,239.4,295.1,239.4,295.8z M243,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.5,298.2,243,298.7,243,299.4z M239.4,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,287.9,239.4,288.6z + M243,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,291.5,243,292.2z M239.4,281.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C239.9,280.2,239.4,280.8,239.4,281.4z M243,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S243,284.4,243,285z M239.4,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S239.4,273.6,239.4,274.2z M243,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.5,276.6,243,277.2,243,277.8z + M239.4,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,266.4,239.4,267.1z M243,270.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.5,269.5,243,270,243,270.6z M239.4,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C239.9,258.7,239.4,259.2,239.4,259.9z M243,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S243,262.8,243,263.5z M239.4,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,252,239.4,252.7z M243,256.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C243.5,255.1,243,255.6,243,256.3z M239.4,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,244.8,239.4,245.5z M243,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C243.5,247.9,243,248.4,243,249.1z M239.4,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S239.4,237.7,239.4,238.3z M243,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S243,241.3,243,241.9z M239.4,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C239.9,229.9,239.4,230.5,239.4,231.1z + M243,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,234.1,243,234.7z M239.4,224c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,223.3,239.4,224z M243,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C243.5,226.4,243,226.9,243,227.5z M239.4,216.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S239.4,216.1,239.4,216.8z + M243,220.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S243,219.7,243,220.4z M239.4,209.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C239.9,208.4,239.4,208.9,239.4,209.6z M238.2,206c0-0.1,0-0.2,0-0.2l-1.2-1 + c-0.6,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2C237.6,207.2,238.2,206.7,238.2,206z M243,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S243,212.5,243,213.2z M232.2,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.2,367,232.2,367.6z M232.2,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,359.3,232.2,359.8,232.2,360.4z M235.8,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,363.4,235.8,364z + M232.2,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C232.7,352.1,232.2,352.6,232.2,353.3z M235.8,356.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,355.7,235.8,356.2,235.8,356.9z M232.2,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,345.4,232.2,346.1z M235.8,349.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,349,235.8,349.7z M232.2,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,337.7,232.2,338.2,232.2,338.9z M235.8,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,341.8,235.8,342.5z M232.2,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,331.1,232.2,331.7z + M235.8,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,334.1,235.8,334.6,235.8,335.3z M232.2,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,323.9,232.2,324.5z M235.8,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,327.5,235.8,328.1z M232.2,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,316.1,232.2,316.7,232.2,317.3z M235.8,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C236.3,319.7,235.8,320.3,235.8,320.9z M232.2,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S232.2,309.5,232.2,310.2z M235.8,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C236.3,312.6,235.8,313.1,235.8,313.8z M232.2,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,302.3,232.2,303z + M235.8,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,305.9,235.8,306.6z M232.2,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C232.7,294.6,232.2,295.1,232.2,295.8z M235.8,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,298.2,235.8,298.7,235.8,299.4z M232.2,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,287.9,232.2,288.6z M235.8,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,291.5,235.8,292.2z M232.2,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,280.2,232.2,280.8,232.2,281.4z M235.8,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,284.4,235.8,285z + M232.2,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,273.6,232.2,274.2z M235.8,277.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,276.6,235.8,277.2,235.8,277.8z M232.2,267.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,266.4,232.2,267.1z M235.8,270.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,269.5,235.8,270,235.8,270.6z M232.2,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C232.7,258.7,232.2,259.2,232.2,259.9z M235.8,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,262.8,235.8,263.5z M232.2,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,252,232.2,252.7z + M235.8,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C236.3,255.1,235.8,255.6,235.8,256.3z M232.2,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,244.8,232.2,245.5z M235.8,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,247.9,235.8,248.4,235.8,249.1z M232.2,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S232.2,237.7,232.2,238.3z M235.8,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,241.3,235.8,241.9z M232.2,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,229.9,232.2,230.5,232.2,231.1z M235.8,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,234.1,235.8,234.7z M232.2,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,223.3,232.2,224z + M235.8,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C236.3,226.4,235.8,226.9,235.8,227.5z M232.2,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S232.2,216.1,232.2,216.8z M235.8,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S235.8,219.7,235.8,220.4z M232.2,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C232.7,208.4,232.2,208.9,232.2,209.6z M235.8,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S235.8,212.5,235.8,213.2z M234.5,202.8l-1.8-1.4c-0.3,0.2-0.6,0.6-0.6,1c0,0.7,0.5,1.2,1.2,1.2 + C233.9,203.6,234.3,203.3,234.5,202.8z M225,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,367,225,367.6z + M228.6,371.2c0,0.2,0.1,0.4,0.2,0.6l2.2-0.4v-0.1c0-0.7-0.5-1.2-1.2-1.2C229.1,370,228.6,370.6,228.6,371.2z M225,360.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.5,359.3,225,359.8,225,360.4z M228.6,364c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,363.4,228.6,364z M225,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C225.5,352.1,225,352.6,225,353.3z M228.6,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C229.1,355.7,228.6,356.2,228.6,356.9z M225,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,345.4,225,346.1z + M228.6,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,349,228.6,349.7z M225,338.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.5,337.7,225,338.2,225,338.9z M228.6,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S228.6,341.8,228.6,342.5z M225,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S225,331.1,225,331.7z M228.6,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.1,334.1,228.6,334.6,228.6,335.3z + M225,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,323.9,225,324.5z M228.6,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,327.5,228.6,328.1z M225,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C225.5,316.1,225,316.7,225,317.3z M228.6,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C229.1,319.7,228.6,320.3,228.6,320.9z M225,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,309.5,225,310.2z + M228.6,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.1,312.6,228.6,313.1,228.6,313.8z M225,303 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,302.3,225,303z M228.6,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S228.6,305.9,228.6,306.6z M225,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C225.5,294.6,225,295.1,225,295.8z M228.6,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C229.1,298.2,228.6,298.7,228.6,299.4z M225,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,287.9,225,288.6z + M228.6,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,291.5,228.6,292.2z M225,281.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.5,280.2,225,280.8,225,281.4z M228.6,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S228.6,284.4,228.6,285z M225,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,273.6,225,274.2 + z M228.6,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.1,276.6,228.6,277.2,228.6,277.8z M225,267.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,266.4,225,267.1z M228.6,270.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.1,269.5,228.6,270,228.6,270.6z M225,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C225.5,258.7,225,259.2,225,259.9z M228.6,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S228.6,262.8,228.6,263.5z M225,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,252,225,252.7z M228.6,256.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C229.1,255.1,228.6,255.6,228.6,256.3z M225,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,244.8,225,245.5z M228.6,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C229.1,247.9,228.6,248.4,228.6,249.1z M225,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S225,237.7,225,238.3z M228.6,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S228.6,241.3,228.6,241.9z M225,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.5,229.9,225,230.5,225,231.1z + M228.6,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,234.1,228.6,234.7z M225,224c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,223.3,225,224z M228.6,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C229.1,226.4,228.6,226.9,228.6,227.5z M225,216.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S225,216.1,225,216.8z + M228.6,220.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,219.7,228.6,220.4z M225,209.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C225.5,208.4,225,208.9,225,209.6z M228.6,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S228.6,212.5,228.6,213.2z M225,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S225,201.7,225,202.4z M228.6,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S228.6,205.3,228.6,206z M229.8,200 + c0.3,0,0.6-0.1,0.8-0.3l-1.8-1.5c-0.1,0.2-0.2,0.4-0.2,0.6C228.6,199.5,229.1,200,229.8,200z M226.2,196.4c0.1,0,0.2,0,0.3-0.1 + l-1.4-1.2l0,0C225,195.9,225.5,196.4,226.2,196.4z M217.8,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.8,367,217.8,367.6z M221.4,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,370.6,221.4,371.2z + M217.8,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.3,359.3,217.8,359.8,217.8,360.4z M221.4,364 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,363.4,221.4,364z M217.8,353.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.3,352.1,217.8,352.6,217.8,353.3z M221.4,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C221.9,355.7,221.4,356.2,221.4,356.9z M217.8,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.8,345.4,217.8,346.1z M221.4,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,349,221.4,349.7z + M217.8,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.3,337.7,217.8,338.2,217.8,338.9z M221.4,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,341.8,221.4,342.5z M217.8,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,331.1,217.8,331.7z M221.4,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C221.9,334.1,221.4,334.6,221.4,335.3z M217.8,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.8,323.9,217.8,324.5z M221.4,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,327.5,221.4,328.1z + M217.8,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.3,316.1,217.8,316.7,217.8,317.3z M221.4,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C221.9,319.7,221.4,320.3,221.4,320.9z M217.8,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,309.5,217.8,310.2z M221.4,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C221.9,312.6,221.4,313.1,221.4,313.8z M217.8,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S217.8,302.3,217.8,303z M221.4,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,305.9,221.4,306.6z M217.8,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C218.3,294.6,217.8,295.1,217.8,295.8z M221.4,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C221.9,298.2,221.4,298.7,221.4,299.4z M217.8,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.8,287.9,217.8,288.6z M221.4,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,291.5,221.4,292.2z + M217.8,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C218.3,280.2,217.8,280.8,217.8,281.4z M221.4,285 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,284.4,221.4,285z M217.8,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,273.6,217.8,274.2z M221.4,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C221.9,276.6,221.4,277.2,221.4,277.8z M217.8,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S217.8,266.4,217.8,267.1z M221.4,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C221.9,269.5,221.4,270,221.4,270.6z M217.8,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C218.3,258.7,217.8,259.2,217.8,259.9z M221.4,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,262.8,221.4,263.5z M217.8,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,252,217.8,252.7z + M221.4,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C221.9,255.1,221.4,255.6,221.4,256.3z M217.8,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,244.8,217.8,245.5z M221.4,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C221.9,247.9,221.4,248.4,221.4,249.1z M217.8,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S217.8,237.7,217.8,238.3z M221.4,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,241.3,221.4,241.9z M217.8,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C218.3,229.9,217.8,230.5,217.8,231.1z M221.4,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,234.1,221.4,234.7z M217.8,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,223.3,217.8,224z + M221.4,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C221.9,226.4,221.4,226.9,221.4,227.5z M217.8,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,216.1,217.8,216.8z M221.4,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,219.7,221.4,220.4z M217.8,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C218.3,208.4,217.8,208.9,217.8,209.6z M221.4,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,212.5,221.4,213.2z M217.8,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,201.7,217.8,202.4z + M221.4,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S221.4,205.3,221.4,206z M217.8,195.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S217.8,194.6,217.8,195.2z M221.4,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S221.4,198.2,221.4,198.8z M210.6,374.8c0,0.1,0,0.3,0.1,0.4l2.3-0.4c0-0.6-0.5-1.1-1.2-1.1C211.2,373.6,210.6,374.2,210.6,374.8z + M210.6,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C211.2,366.4,210.6,367,210.6,367.6z M214.2,371.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C214.8,370,214.2,370.6,214.2,371.2z M210.6,360.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C211.2,359.3,210.6,359.8,210.6,360.4z M214.2,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C214.8,362.8,214.2,363.4,214.2,364z M210.6,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,352.1,210.6,352.6,210.6,353.3z M214.2,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,355.7,214.2,356.2,214.2,356.9z M210.6,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,344.9,210.6,345.4,210.6,346.1z M214.2,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,348.5,214.2,349,214.2,349.7z M210.6,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,337.7,210.6,338.2,210.6,338.9z M214.2,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,341.3,214.2,341.8,214.2,342.5z M210.6,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,330.5,210.6,331.1,210.6,331.7z M214.2,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,334.1,214.2,334.6,214.2,335.3z M210.6,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,323.3,210.6,323.9,210.6,324.5z M214.2,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,326.9,214.2,327.5,214.2,328.1z M210.6,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,316.1,210.6,316.7,210.6,317.3z M214.2,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,319.7,214.2,320.3,214.2,320.9z M210.6,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,309,210.6,309.5,210.6,310.2z M214.2,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,312.6,214.2,313.1,214.2,313.8z M210.6,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,301.8,210.6,302.3,210.6,303z M214.2,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,305.4,214.2,305.9,214.2,306.6z M210.6,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,294.6,210.6,295.1,210.6,295.8z M214.2,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,298.2,214.2,298.7,214.2,299.4z M210.6,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,287.4,210.6,287.9,210.6,288.6z M214.2,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,291,214.2,291.5,214.2,292.2z M210.6,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,280.2,210.6,280.8,210.6,281.4z M214.2,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,283.8,214.2,284.4,214.2,285z M210.6,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,273,210.6,273.6,210.6,274.2z M214.2,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,276.6,214.2,277.2,214.2,277.8z M210.6,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,265.9,210.6,266.4,210.6,267.1z M214.2,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,269.5,214.2,270,214.2,270.6z M210.6,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,258.7,210.6,259.2,210.6,259.9z M214.2,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,262.3,214.2,262.8,214.2,263.5z M210.6,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,251.5,210.6,252,210.6,252.7z M214.2,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C214.8,255.1,214.2,255.6,214.2,256.3z M210.6,245.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,244.3,210.6,244.8,210.6,245.5z M214.2,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,247.9,214.2,248.4,214.2,249.1z M210.6,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,237.1,210.6,237.7,210.6,238.3z M214.2,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,240.7,214.2,241.3,214.2,241.9z M210.6,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,229.9,210.6,230.5,210.6,231.1z M214.2,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,233.5,214.2,234.1,214.2,234.7z M210.6,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,222.8,210.6,223.3,210.6,224z M214.2,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,226.4,214.2,226.9,214.2,227.5z M210.6,216.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,215.6,210.6,216.1,210.6,216.8z M214.2,220.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,219.2,214.2,219.7,214.2,220.4z M210.6,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,208.4,210.6,208.9,210.6,209.6z M214.2,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,212,214.2,212.5,214.2,213.2z M210.6,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,201.2,210.6,201.7,210.6,202.4z M214.2,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,204.8,214.2,205.3,214.2,206z M210.6,195.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,194,210.6,194.6,210.6,195.2z M214.2,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,197.6,214.2,198.2,214.2,198.8z M210.6,188c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C211.2,186.8,210.6,187.4,210.6,188z M214.2,191.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C214.8,190.4,214.2,191,214.2,191.6z M203.4,374.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,373.6,203.4,374.2,203.4,374.8z M203.4,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,366.4,203.4,367,203.4,367.6z M207,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,370,207,370.6,207,371.2z M203.4,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,359.3,203.4,359.8,203.4,360.4z M207,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,362.8,207,363.4,207,364z M203.4,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,352.1,203.4,352.6,203.4,353.3z M207,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,355.7,207,356.2,207,356.9z M203.4,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,344.9,203.4,345.4,203.4,346.1z M207,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,348.5,207,349,207,349.7z M203.4,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,337.7,203.4,338.2,203.4,338.9z M207,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,341.3,207,341.8,207,342.5z M203.4,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,330.5,203.4,331.1,203.4,331.7z M207,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,334.1,207,334.6,207,335.3z M203.4,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,323.3,203.4,323.9,203.4,324.5z M207,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,326.9,207,327.5,207,328.1z M203.4,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,316.1,203.4,316.7,203.4,317.3z M207,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,319.7,207,320.3,207,320.9z M203.4,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,309,203.4,309.5,203.4,310.2z M207,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,312.6,207,313.1,207,313.8z M203.4,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,301.8,203.4,302.3,203.4,303z M207,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,305.4,207,305.9,207,306.6z M203.4,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,294.6,203.4,295.1,203.4,295.8z M207,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,298.2,207,298.7,207,299.4z M203.4,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,287.4,203.4,287.9,203.4,288.6z M207,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,291,207,291.5,207,292.2z M203.4,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,280.2,203.4,280.8,203.4,281.4z M207,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,283.8,207,284.4,207,285z M203.4,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,273,203.4,273.6,203.4,274.2z M207,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,276.6,207,277.2,207,277.8z M203.4,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,265.9,203.4,266.4,203.4,267.1z M207,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,269.5,207,270,207,270.6z M203.4,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,258.7,203.4,259.2,203.4,259.9z M207,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,262.3,207,262.8,207,263.5z M203.4,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,251.5,203.4,252,203.4,252.7z M207,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C207.6,255.1,207,255.6,207,256.3z M203.4,245.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,244.3,203.4,244.8,203.4,245.5z M207,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,247.9,207,248.4,207,249.1z M203.4,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,237.1,203.4,237.7,203.4,238.3z M207,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,240.7,207,241.3,207,241.9z M203.4,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,229.9,203.4,230.5,203.4,231.1z M207,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,233.5,207,234.1,207,234.7z M203.4,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,222.8,203.4,223.3,203.4,224z M207,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,226.4,207,226.9,207,227.5z M203.4,216.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,215.6,203.4,216.1,203.4,216.8z M207,220.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,219.2,207,219.7,207,220.4z M203.4,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,208.4,203.4,208.9,203.4,209.6z M207,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,212,207,212.5,207,213.2z M203.4,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,201.2,203.4,201.7,203.4,202.4z M207,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,204.8,207,205.3,207,206z M203.4,195.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,194,203.4,194.6,203.4,195.2z M207,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,197.6,207,198.2,207,198.8z M203.4,188c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,186.8,203.4,187.4,203.4,188z M207,191.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,190.4,207,191,207,191.6z M203.4,180.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C204,179.7,203.4,180.2,203.4,180.9z M202.2,177.3c0-0.2,0-0.3-0.1-0.5l-0.9-0.7c-0.1,0-0.2,0-0.2,0c-0.7,0-1.2,0.5-1.2,1.2 + s0.5,1.2,1.2,1.2S202.2,177.9,202.2,177.3z M207,184.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C207.6,183.2,207,183.8,207,184.4z M196.3,374.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C196.8,373.6,196.3,374.2,196.3,374.8z M196.3,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,367,196.3,367.6z M199.8,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,370,199.8,370.6,199.8,371.2z + M196.3,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C196.8,359.3,196.3,359.8,196.3,360.4z M199.8,364 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,362.8,199.8,363.4,199.8,364z M196.3,353.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C196.8,352.1,196.3,352.6,196.3,353.3z M199.8,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C200.4,355.7,199.8,356.2,199.8,356.9z M196.3,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,345.4,196.3,346.1z M199.8,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,348.5,199.8,349,199.8,349.7z M196.3,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C196.8,337.7,196.3,338.2,196.3,338.9z M199.8,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,341.3,199.8,341.8,199.8,342.5z M196.3,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,331.1,196.3,331.7z M199.8,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,334.1,199.8,334.6,199.8,335.3z M196.3,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,323.9,196.3,324.5z M199.8,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,326.9,199.8,327.5,199.8,328.1z M196.3,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C196.8,316.1,196.3,316.7,196.3,317.3z M199.8,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,319.7,199.8,320.3,199.8,320.9z M196.3,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,309.5,196.3,310.2z M199.8,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,312.6,199.8,313.1,199.8,313.8z M196.3,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,302.3,196.3,303z + M199.8,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,305.4,199.8,305.9,199.8,306.6z M196.3,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C196.8,294.6,196.3,295.1,196.3,295.8z M199.8,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,298.2,199.8,298.7,199.8,299.4z M196.3,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,287.9,196.3,288.6z M199.8,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,291,199.8,291.5,199.8,292.2z M196.3,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C196.8,280.2,196.3,280.8,196.3,281.4z M199.8,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,283.8,199.8,284.4,199.8,285z M196.3,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,273.6,196.3,274.2z M199.8,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,276.6,199.8,277.2,199.8,277.8z M196.3,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,266.4,196.3,267.1z M199.8,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,269.5,199.8,270,199.8,270.6z M196.3,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C196.8,258.7,196.3,259.2,196.3,259.9z M199.8,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,262.3,199.8,262.8,199.8,263.5z M196.3,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,252,196.3,252.7z M199.8,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C200.4,255.1,199.8,255.6,199.8,256.3z M196.3,245.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,244.8,196.3,245.5z M199.8,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,247.9,199.8,248.4,199.8,249.1z M196.3,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,237.7,196.3,238.3z M199.8,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,240.7,199.8,241.3,199.8,241.9z M196.3,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C196.8,229.9,196.3,230.5,196.3,231.1z M199.8,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,233.5,199.8,234.1,199.8,234.7z M196.3,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,223.3,196.3,224z + M199.8,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,226.4,199.8,226.9,199.8,227.5z M196.3,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,216.1,196.3,216.8z M199.8,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,219.2,199.8,219.7,199.8,220.4z M196.3,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C196.8,208.4,196.3,208.9,196.3,209.6z M199.8,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,212,199.8,212.5,199.8,213.2z M196.3,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,201.7,196.3,202.4z M199.8,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,204.8,199.8,205.3,199.8,206z + M196.3,195.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,194.6,196.3,195.2z M199.8,198.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C200.4,197.6,199.8,198.2,199.8,198.8z M196.3,188c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S196.3,187.4,196.3,188z M199.8,191.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,190.4,199.8,191,199.8,191.6z M196.3,180.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S196.3,180.2,196.3,180.9z M199.8,184.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C200.4,183.2,199.8,183.8,199.8,184.4z M198.6,173.9l-1.7-1.3c-0.4,0.2-0.7,0.6-0.7,1.1c0,0.7,0.5,1.2,1.2,1.2 + C198,174.9,198.5,174.5,198.6,173.9z M194.8,170.9l-1.8-1.5c-0.1,0.2-0.3,0.4-0.3,0.7c0,0.7,0.5,1.2,1.2,1.2 + C194.2,171.3,194.5,171.1,194.8,170.9z M189.1,374.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C189.6,373.6,189.1,374.2,189.1,374.8z M192.7,378.4c0,0.1,0,0.1,0,0.2l2.3-0.4c-0.1-0.5-0.6-0.9-1.1-0.9 + C193.2,377.2,192.7,377.7,192.7,378.4z M189.1,367.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,367,189.1,367.6z M192.7,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,370.6,192.7,371.2z + M189.1,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C189.6,359.3,189.1,359.8,189.1,360.4z M192.7,364 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,363.4,192.7,364z M189.1,353.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C189.6,352.1,189.1,352.6,189.1,353.3z M192.7,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C193.2,355.7,192.7,356.2,192.7,356.9z M189.1,346.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,345.4,189.1,346.1z M192.7,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,349,192.7,349.7z + M189.1,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C189.6,337.7,189.1,338.2,189.1,338.9z M192.7,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,341.8,192.7,342.5z M189.1,331.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,331.1,189.1,331.7z M192.7,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C193.2,334.1,192.7,334.6,192.7,335.3z M189.1,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,323.9,189.1,324.5z M192.7,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,327.5,192.7,328.1z + M189.1,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C189.6,316.1,189.1,316.7,189.1,317.3z M192.7,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.2,319.7,192.7,320.3,192.7,320.9z M189.1,310.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,309.5,189.1,310.2z M192.7,313.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.2,312.6,192.7,313.1,192.7,313.8z M189.1,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S189.1,302.3,189.1,303z M192.7,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,305.9,192.7,306.6z M189.1,295.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C189.6,294.6,189.1,295.1,189.1,295.8z M192.7,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C193.2,298.2,192.7,298.7,192.7,299.4z M189.1,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,287.9,189.1,288.6z M192.7,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,291.5,192.7,292.2z + M189.1,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C189.6,280.2,189.1,280.8,189.1,281.4z M192.7,285 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,284.4,192.7,285z M189.1,274.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,273.6,189.1,274.2z M192.7,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C193.2,276.6,192.7,277.2,192.7,277.8z M189.1,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,266.4,189.1,267.1z M192.7,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C193.2,269.5,192.7,270,192.7,270.6z M189.1,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C189.6,258.7,189.1,259.2,189.1,259.9z M192.7,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,262.8,192.7,263.5z M189.1,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,252,189.1,252.7z + M192.7,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C193.2,255.1,192.7,255.6,192.7,256.3z M189.1,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,244.8,189.1,245.5z M192.7,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.2,247.9,192.7,248.4,192.7,249.1z M189.1,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S189.1,237.7,189.1,238.3z M192.7,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,241.3,192.7,241.9z M189.1,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C189.6,229.9,189.1,230.5,189.1,231.1z M192.7,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,234.1,192.7,234.7z M189.1,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,223.3,189.1,224z + M192.7,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.2,226.4,192.7,226.9,192.7,227.5z M189.1,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,216.1,189.1,216.8z M192.7,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,219.7,192.7,220.4z M189.1,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C189.6,208.4,189.1,208.9,189.1,209.6z M192.7,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,212.5,192.7,213.2z M189.1,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,201.7,189.1,202.4z + M192.7,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,205.3,192.7,206z M189.1,195.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,194.6,189.1,195.2z M192.7,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S192.7,198.2,192.7,198.8z M189.1,188c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,187.4,189.1,188z + M192.7,191.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C193.2,190.4,192.7,191,192.7,191.6z M189.1,180.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S189.1,180.2,189.1,180.9z M192.7,184.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,183.8,192.7,184.4z M189.1,173.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S189.1,173,189.1,173.7z M192.7,177.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S192.7,176.6,192.7,177.3z + M190.3,167.7c0.2,0,0.3,0,0.4-0.1l-1.6-1.3c0,0.1,0,0.1,0,0.2C189.1,167.1,189.6,167.7,190.3,167.7z M181.9,374.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C182.4,373.6,181.9,374.2,181.9,374.8z M185.5,378.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,377.2,185.5,377.7,185.5,378.4z M181.9,367.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,367,181.9,367.6z M185.5,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,370.6,185.5,371.2z M181.9,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,359.3,181.9,359.8,181.9,360.4z M185.5,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,363.4,185.5,364z + M181.9,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C182.4,352.1,181.9,352.6,181.9,353.3z M185.5,356.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,355.7,185.5,356.2,185.5,356.9z M181.9,346.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,345.4,181.9,346.1z M185.5,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,349,185.5,349.7z M181.9,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,337.7,181.9,338.2,181.9,338.9z M185.5,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,341.8,185.5,342.5z M181.9,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,331.1,181.9,331.7z + M185.5,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,334.1,185.5,334.6,185.5,335.3z M181.9,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,323.9,181.9,324.5z M185.5,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,327.5,185.5,328.1z M181.9,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,316.1,181.9,316.7,181.9,317.3z M185.5,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C186,319.7,185.5,320.3,185.5,320.9z M181.9,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S181.9,309.5,181.9,310.2z M185.5,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C186,312.6,185.5,313.1,185.5,313.8z M181.9,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,302.3,181.9,303z + M185.5,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,305.9,185.5,306.6z M181.9,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C182.4,294.6,181.9,295.1,181.9,295.8z M185.5,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,298.2,185.5,298.7,185.5,299.4z M181.9,288.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,287.9,181.9,288.6z M185.5,292.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,291.5,185.5,292.2z M181.9,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,280.2,181.9,280.8,181.9,281.4z M185.5,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,284.4,185.5,285z + M181.9,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,273.6,181.9,274.2z M185.5,277.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,276.6,185.5,277.2,185.5,277.8z M181.9,267.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,266.4,181.9,267.1z M185.5,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C186,269.5,185.5,270,185.5,270.6z M181.9,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,258.7,181.9,259.2,181.9,259.9z M185.5,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,262.8,185.5,263.5z M181.9,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,252,181.9,252.7z + M185.5,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C186,255.1,185.5,255.6,185.5,256.3z M181.9,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,244.8,181.9,245.5z M185.5,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,247.9,185.5,248.4,185.5,249.1z M181.9,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S181.9,237.7,181.9,238.3z M185.5,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,241.3,185.5,241.9z M181.9,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,229.9,181.9,230.5,181.9,231.1z M185.5,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,234.1,185.5,234.7z M181.9,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,223.3,181.9,224z + M185.5,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,226.4,185.5,226.9,185.5,227.5z M181.9,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,216.1,181.9,216.8z M185.5,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,219.7,185.5,220.4z M181.9,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C182.4,208.4,181.9,208.9,181.9,209.6z M185.5,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,212.5,185.5,213.2z M181.9,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,201.7,181.9,202.4z + M185.5,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,205.3,185.5,206z M181.9,195.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,194.6,181.9,195.2z M185.5,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S185.5,198.2,185.5,198.8z M181.9,188c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,187.4,181.9,188z + M185.5,191.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,190.4,185.5,191,185.5,191.6z M181.9,180.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,180.2,181.9,180.9z M185.5,184.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,183.8,185.5,184.4z M181.9,173.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S181.9,173,181.9,173.7z M185.5,177.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S185.5,176.6,185.5,177.3z + M181.9,166.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S181.9,165.8,181.9,166.5z M185.5,170.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C186,168.9,185.5,169.4,185.5,170.1z M186.2,164l-0.5-0.4 + C185.9,163.8,186,163.9,186.2,164z M174.7,382l2.3-0.4c-0.2-0.4-0.6-0.8-1.1-0.8C175.2,380.8,174.7,381.3,174.7,382z M174.7,374.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C175.2,373.6,174.7,374.2,174.7,374.8z M178.3,378.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,377.2,178.3,377.7,178.3,378.4z M174.7,367.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,367,174.7,367.6z M178.3,371.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,370.6,178.3,371.2z M174.7,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,359.3,174.7,359.8,174.7,360.4z M178.3,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,363.4,178.3,364z + M174.7,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C175.2,352.1,174.7,352.6,174.7,353.3z M178.3,356.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,355.7,178.3,356.2,178.3,356.9z M174.7,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,345.4,174.7,346.1z M178.3,349.7c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,349,178.3,349.7z M174.7,338.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,337.7,174.7,338.2,174.7,338.9z M178.3,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,341.8,178.3,342.5z M174.7,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,331.1,174.7,331.7z + M178.3,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,334.1,178.3,334.6,178.3,335.3z M174.7,324.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,323.9,174.7,324.5z M178.3,328.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,327.5,178.3,328.1z M174.7,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,316.1,174.7,316.7,174.7,317.3z M178.3,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C178.8,319.7,178.3,320.3,178.3,320.9z M174.7,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S174.7,309.5,174.7,310.2z M178.3,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C178.8,312.6,178.3,313.1,178.3,313.8z M174.7,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,302.3,174.7,303z + M178.3,306.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,305.9,178.3,306.6z M174.7,295.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C175.2,294.6,174.7,295.1,174.7,295.8z M178.3,299.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,298.2,178.3,298.7,178.3,299.4z M174.7,288.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,287.9,174.7,288.6z M178.3,292.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,291.5,178.3,292.2z M174.7,281.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,280.2,174.7,280.8,174.7,281.4z M178.3,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,284.4,178.3,285z + M174.7,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,273.6,174.7,274.2z M178.3,277.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,276.6,178.3,277.2,178.3,277.8z M174.7,267.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,266.4,174.7,267.1z M178.3,270.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,269.5,178.3,270,178.3,270.6z M174.7,259.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C175.2,258.7,174.7,259.2,174.7,259.9z M178.3,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,262.8,178.3,263.5z M174.7,252.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,252,174.7,252.7z + M178.3,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2C178.8,255.1,178.3,255.6,178.3,256.3z M174.7,245.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,244.8,174.7,245.5z M178.3,249.1c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,247.9,178.3,248.4,178.3,249.1z M174.7,238.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S174.7,237.7,174.7,238.3z M178.3,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,241.3,178.3,241.9z M174.7,231.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,229.9,174.7,230.5,174.7,231.1z M178.3,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,234.1,178.3,234.7z M174.7,224c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,223.3,174.7,224z + M178.3,227.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,226.4,178.3,226.9,178.3,227.5z M174.7,216.8 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,216.1,174.7,216.8z M178.3,220.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,219.7,178.3,220.4z M174.7,209.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C175.2,208.4,174.7,208.9,174.7,209.6z M178.3,213.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,212.5,178.3,213.2z M174.7,202.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,201.7,174.7,202.4z + M173.5,198.8c0-0.7-0.5-1.2-1.2-1.2c-0.1,0-0.1,0-0.2,0l-0.2,2.3c0.1,0,0.2,0.1,0.3,0.1C173,200,173.5,199.5,173.5,198.8z + M178.3,206c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,205.3,178.3,206z M174.7,195.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,194.6,174.7,195.2z M173.5,191.6c0-0.6-0.4-1-0.9-1.1l-0.2,2.3 + C173,192.7,173.5,192.2,173.5,191.6z M178.3,198.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S178.3,198.2,178.3,198.8z M174.7,188c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,187.4,174.7,188z + M173.5,184.4c0-0.4-0.2-0.7-0.4-0.9l-0.1,1.9C173.3,185.2,173.5,184.9,173.5,184.4z M178.3,191.6c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C178.8,190.4,178.3,191,178.3,191.6z M174.7,180.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S174.7,180.2,174.7,180.9z M173.5,177.3C173.5,177.3,173.5,177.2,173.5,177.3L173.5,177.3L173.5,177.3z + M178.3,184.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,183.8,178.3,184.4z M174.7,173.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S174.7,173,174.7,173.7z M178.3,177.3c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,176.6,178.3,177.3z M174.7,166.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S174.7,165.8,174.7,166.5z M178.3,170.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C178.8,168.9,178.3,169.4,178.3,170.1z M174.7,159.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S174.7,158.6,174.7,159.3z M178.3,162.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S178.3,162.2,178.3,162.9z + M168.5,383.2l0.8-0.1c0.4-0.2,0.6-0.6,0.6-1c0-0.7-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2C167.5,382.6,168,383.1,168.5,383.2z + M167.5,374.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,373.6,167.5,374.2,167.5,374.8z M171.1,378.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C171.6,377.2,171.1,377.7,171.1,378.4z M167.5,367.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,366.4,167.5,367,167.5,367.6z M171.1,371.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,370.6,171.1,371.2z M167.5,360.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,359.3,167.5,359.8,167.5,360.4z M171.1,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,363.4,171.1,364z + M167.5,353.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,352.1,167.5,352.6,167.5,353.3z M171.1,356.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C171.6,355.7,171.1,356.2,171.1,356.9z M167.5,346.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,344.9,167.5,345.4,167.5,346.1z M171.1,349.7 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,349,171.1,349.7z M167.5,338.9c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,337.7,167.5,338.2,167.5,338.9z M171.1,342.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S171.1,341.8,171.1,342.5z M167.5,331.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,330.5,167.5,331.1,167.5,331.7z M171.1,335.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,334.1,171.1,334.6,171.1,335.3z M167.5,324.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,323.3,167.5,323.9,167.5,324.5z M171.1,328.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S171.1,327.5,171.1,328.1z M167.5,317.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,316.1,167.5,316.7,167.5,317.3z M171.1,320.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,319.7,171.1,320.3,171.1,320.9z M167.5,310.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,309,167.5,309.5,167.5,310.2z M166.3,306.6c0-0.7-0.5-1.2-1.2-1.2c-0.1,0-0.1,0-0.2,0l-0.2,2.3c0.1,0,0.2,0.1,0.3,0.1 + C165.8,307.8,166.3,307.2,166.3,306.6z M171.1,313.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,312.6,171.1,313.1,171.1,313.8z M167.5,303c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,301.8,167.5,302.3,167.5,303z M166.3,299.4c0-0.6-0.4-1-0.9-1.1l-0.2,2.3C165.9,300.5,166.3,300,166.3,299.4z M171.1,306.6 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,305.9,171.1,306.6z M167.5,295.8c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,294.6,167.5,295.1,167.5,295.8z M166.3,292.2c0-0.4-0.2-0.7-0.4-0.9l-0.1,1.9 + C166.1,293,166.3,292.6,166.3,292.2z M171.1,299.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,298.2,171.1,298.7,171.1,299.4z M167.5,288.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,287.4,167.5,287.9,167.5,288.6z M166.3,285L166.3,285L166.3,285C166.3,285.1,166.3,285,166.3,285z M171.1,292.2 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,291.5,171.1,292.2z M167.5,281.4c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C168.1,280.2,167.5,280.8,167.5,281.4z M171.1,285c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S171.1,284.4,171.1,285z M167.5,274.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,273,167.5,273.6,167.5,274.2z M171.1,277.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,276.6,171.1,277.2,171.1,277.8z M167.5,267.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.1,265.9,167.5,266.4,167.5,267.1z M171.1,270.6c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C171.6,269.5,171.1,270,171.1,270.6z M168.1,258.9l-0.1,1.9c0.2,0.2,0.5,0.3,0.8,0.3c0.7,0,1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C168.5,258.7,168.2,258.8,168.1,258.9z M171.1,263.5c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + S171.1,262.8,171.1,263.5z M169.9,252.7c0-0.7-0.5-1.2-1.2-1.2c-0.1,0-0.1,0-0.2,0l-0.2,2.3c0.1,0,0.2,0.1,0.3,0.1 + C169.4,253.9,169.9,253.4,169.9,252.7z M171.1,256.3c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2 + C171.6,255.1,171.1,255.6,171.1,256.3z M169.9,245.5c0-0.6-0.4-1-0.9-1.1l-0.2,2.3C169.5,246.6,169.9,246.1,169.9,245.5z + M171.1,249.1c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C171.6,247.9,171.1,248.4,171.1,249.1z M169.9,238.3 + c0-0.4-0.2-0.7-0.4-0.9l-0.1,1.9C169.7,239.1,169.9,238.7,169.9,238.3z M171.1,241.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2S171.1,241.3,171.1,241.9z M169.9,231.1L169.9,231.1L169.9,231.1C169.9,231.2,169.9,231.2,169.9,231.1z + M171.1,234.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,234.1,171.1,234.7z M171.1,227.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C171.6,226.4,171.1,226.9,171.1,227.5z M171.1,220.4 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,219.7,171.1,220.4z M171.1,213.2c0,0.7,0.5,1.2,1.2,1.2 + s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2S171.1,212.5,171.1,213.2z M171.5,206.9c0.2,0.2,0.5,0.3,0.8,0.3c0.7,0,1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2c-0.3,0-0.5,0.1-0.7,0.2L171.5,206.9z M161.5,383.2c0.7,0,1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2s-1.2,0.5-1.2,1.2 + S160.9,383.2,161.5,383.2z M160.3,374.8c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C160.9,373.6,160.3,374.2,160.3,374.8z M163.9,378.4c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C164.5,377.2,163.9,377.7,163.9,378.4z M160.9,366.7l-0.1,1.9c0.2,0.2,0.5,0.3,0.8,0.3c0.7,0,1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C161.3,366.4,161.1,366.5,160.9,366.7z M163.9,371.2c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C164.5,370,163.9,370.6,163.9,371.2z M162.7,360.4c0-0.7-0.5-1.2-1.2-1.2c-0.1,0-0.1,0-0.2,0l-0.2,2.3c0.1,0,0.2,0.1,0.3,0.1 + C162.2,361.6,162.7,361.1,162.7,360.4z M163.9,364c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2 + C164.5,362.8,163.9,363.4,163.9,364z M162.7,353.3c0-0.6-0.4-1-0.9-1.1l-0.2,2.3C162.3,354.4,162.7,353.9,162.7,353.3z + M163.9,356.9c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C164.5,355.7,163.9,356.2,163.9,356.9z M162.7,346.1 + c0-0.4-0.2-0.7-0.4-0.9l-0.1,1.9C162.5,346.8,162.7,346.5,162.7,346.1z M163.9,349.7c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + s-0.5-1.2-1.2-1.2C164.5,348.5,163.9,349,163.9,349.7z M162.7,338.9L162.7,338.9L162.7,338.9L162.7,338.9z M163.9,342.5 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C164.5,341.3,163.9,341.8,163.9,342.5z M163.9,335.3 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C164.5,334.1,163.9,334.6,163.9,335.3z M163.9,328.1 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C164.5,326.9,163.9,327.5,163.9,328.1z M163.9,320.9 + c0,0.7,0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2C164.5,319.7,163.9,320.3,163.9,320.9z M164.3,314.6 + c0.2,0.2,0.5,0.3,0.8,0.3c0.7,0,1.2-0.5,1.2-1.2s-0.5-1.2-1.2-1.2c-0.3,0-0.5,0.1-0.7,0.2L164.3,314.6z"/> +</g> +<g id="Floor"> + <g> + <polygon class="st4" points="49.2,459 99.4,458.8 149.6,458.7 250,458.5 350.4,458.7 400.6,458.8 450.8,459 400.6,459.2 + 350.4,459.3 250,459.5 149.6,459.3 99.4,459.2 "/> + </g> +</g> +<g id="Device"> + <g> + <g> + <path class="st4" d="M334.5,76.1h-169c-9.4,0-17.1,7.8-17.1,17.4v348c0,9.6,7.7,17.4,17.1,17.4h169.1c9.4,0,17.1-7.8,17.1-17.4 + v-348C351.6,83.9,344,76.1,334.5,76.1z M340.9,430.8c0,9.2-6.9,16.6-15.3,16.6H174.4c-8.5,0-15.3-7.4-15.3-16.6v-324 + c0-18.7,6.9-19.6,15.3-19.6h30.3c1.8,0,3.2,2,3.2,4.5v1.1c0,5.8,3.2,5.8,7.1,5.8h70c3.9,0,7.1,0,7.1-5.8v-1.1 + c0-2.5,1.4-4.5,3.2-4.5h30.3c8.5,0,15.3,2.5,15.3,19.6V430.8z"/> + <line class="st5" x1="159" y1="410.3" x2="158.5" y2="410.3"/> + <g> + <path class="st6" d="M340.9,106.8v324.1c0,9.2-6.9,16.6-15.3,16.6H174.4c-8.5,0-15.3-7.4-15.3-16.6V106.8 + c0-18.7,6.9-19.6,15.3-19.6h30.3c1.8,0,3.2,2,3.2,4.5v1.1c0,5.8,3.2,5.8,7.1,5.8h70c3.9,0,7.1,0,7.1-5.8v-1.1 + c0-2.5,1.4-4.5,3.2-4.5h30.3C334.1,87.2,340.9,89.7,340.9,106.8z"/> + <g> + <path class="st7" d="M340.9,106.8v32.5H159v-32.5c0-18.7,6.9-19.6,15.3-19.6h30.3c1.8,0,3.2,2,3.2,4.5v1.1 + c0,5.8,3.2,5.8,7.1,5.8H285c3.9,0,7.1,0,7.1-5.8v-1.1c0-2.5,1.4-4.5,3.2-4.5h30.3C334.1,87.2,340.9,89.7,340.9,106.8z"/> + <g> + <g id="u5Zjqx_00000083070283198486713530000017039902837453840309_"> + <g> + <path class="st6" d="M199.4,94.5c-0.1,0.1-0.2,0.2-0.3,0.3c-0.1,0.1-0.1,0.1-0.2,0.2c-0.8-0.8-1.7-1.2-2.8-1.2 + s-2,0.4-2.8,1.2c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1-0.1-0.2-0.2-0.3-0.3l0,0l0,0l0,0c0.1-0.1,0.2-0.2,0.4-0.3 + c0.3-0.2,0.6-0.4,0.9-0.5c0.4-0.2,0.7-0.3,1.1-0.4c0.2,0,0.4-0.1,0.6-0.1c0.1,0,0.5,0,0.5,0c0.1,0,0.3,0,0.4,0 + c0.4,0,0.7,0.1,1,0.2c0.2,0.1,0.5,0.2,0.7,0.3c0.2,0.1,0.5,0.3,0.7,0.5C199.2,94.3,199.3,94.4,199.4,94.5L199.4,94.5z"/> + <path class="st6" d="M194.3,95.8c-0.2-0.2-0.3-0.3-0.5-0.5c0.5-0.5,1.1-0.8,1.9-0.9c1.1-0.1,2,0.2,2.8,0.9 + c-0.2,0.2-0.3,0.3-0.5,0.5c-0.5-0.5-1.2-0.8-1.9-0.8C195.4,95.1,194.8,95.3,194.3,95.8z"/> + <path class="st6" d="M197.6,96.3c-0.2,0.2-0.3,0.3-0.5,0.5c-0.3-0.3-0.6-0.4-1-0.4s-0.7,0.1-1,0.4c-0.2-0.2-0.3-0.3-0.5-0.5 + C195.5,95.5,196.8,95.5,197.6,96.3z"/> + </g> + <path class="st6" d="M196.6,97.2c0,0.2-0.2,0.4-0.4,0.4s-0.4-0.2-0.4-0.4c0-0.2,0.2-0.4,0.4-0.4 + C196.4,96.8,196.6,97,196.6,97.2z"/> + </g> + <g> + <path class="st6" d="M170.9,95.4c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2s-0.5,1.2-1.2,1.2S170.9,96,170.9,95.4z"/> + <path class="st6" d="M174.7,95.4c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2s-0.5,1.2-1.2,1.2S174.7,96,174.7,95.4z"/> + <path class="st6" d="M178.5,95.4c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2s-0.5,1.2-1.2,1.2S178.5,96,178.5,95.4z"/> + <path class="st6" d="M182.3,95.4c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2s-0.5,1.2-1.2,1.2S182.3,96,182.3,95.4z"/> + <path class="st6" d="M186.1,95.4c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2s-0.5,1.2-1.2,1.2S186.1,96,186.1,95.4z"/> + </g> + <g> + <path class="st6" d="M327.3,98h-9.8v-4.5h9.8V98z M318,97.5h8.8V94H318V97.5z"/> + <rect x="318.3" y="94.2" class="st6" width="6.3" height="3"/> + <rect x="327.3" y="94.5" class="st6" width="0.9" height="2.4"/> + </g> + </g> + <g> + <g> + <rect x="320.1" y="124.3" class="st6" width="8.2" height="1"/> + <rect x="320.1" y="127.5" class="st6" width="8.2" height="1"/> + <rect x="320.1" y="130.6" class="st6" width="8.2" height="1"/> + <circle class="st6" cx="322" cy="124.8" r="1.4"/> + <path class="st6" d="M327.6,128c0,0.8-0.6,1.4-1.4,1.4s-1.4-0.6-1.4-1.4c0-0.8,0.6-1.4,1.4-1.4 + C326.9,126.5,327.6,127.2,327.6,128z"/> + <circle class="st6" cx="323.3" cy="131.1" r="1.4"/> + </g> + <path class="st6" d="M177.3,128.3c-0.9,1.6-3,3-3,3s-2.1-1.4-2.9-3c-1-1.8-0.4-3.6,1-3.6c1.6,0,2,2,2,2s0.4-2,2-2 + C177.7,124.6,178.3,126.5,177.3,128.3z"/> + <g> + <path class="st6" d="M238.4,128c0-1.6,1.4-2.9,3-3c0.7,0,1.4,0.2,1.9,0.6c0.2,0.2,0.2,0.5,0.1,0.7c-0.2,0.2-0.5,0.2-0.7,0.1 + c-0.4-0.3-0.8-0.5-1.3-0.5c-0.6,0-1.1,0.2-1.5,0.6s-0.6,0.9-0.6,1.4c0,0.6,0.2,1.1,0.6,1.4c0.4,0.4,0.9,0.6,1.5,0.6 + c0.5,0,1-0.2,1.3-0.5c0.2-0.1,0.5-0.1,0.7,0.1c0.1,0.2,0.1,0.5-0.1,0.7c-0.5,0.4-1.2,0.6-1.9,0.6 + C239.8,130.9,238.4,129.6,238.4,128z"/> + <path class="st6" d="M248.6,129.6h-2l-0.4,1.1c-0.1,0.2-0.2,0.3-0.4,0.3c-0.1,0-0.1,0-0.2,0c-0.2-0.1-0.4-0.4-0.3-0.6 + l1.8-4.8c0.1-0.2,0.3-0.3,0.4-0.3c0.2,0,0.4,0.1,0.4,0.3l1.8,4.8c0.1,0.2,0,0.5-0.3,0.6c0,0-0.1,0-0.2,0 + c-0.2,0-0.4-0.1-0.4-0.3L248.6,129.6z M248.3,128.7l-0.7-1.8l-0.7,1.8H248.3z"/> + <path class="st6" d="M255.6,130.2c0.1,0.2,0,0.5-0.3,0.6c0,0-0.1,0-0.2,0l0,0c-0.1,0-0.2,0-0.3-0.1s-0.2-0.2-0.3-0.3 + c-0.1-0.2-0.2-0.5-0.2-1c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.2c-0.2-0.1-0.4-0.2-0.5-0.2h-1v1.8c0,0.2-0.2,0.5-0.5,0.5 + s-0.5-0.2-0.5-0.5v-4.8c0-0.3,0.2-0.5,0.5-0.5l0,0h1.5c1,0,1.8,0.8,1.8,1.8c0,0.5-0.2,1-0.6,1.3c0.1,0.1,0.2,0.2,0.3,0.3 + c0.2,0.2,0.3,0.5,0.3,0.9c0,0.2,0,0.4,0,0.5C255.5,130,255.6,130.1,255.6,130.2z M254.5,126.9c0-0.5-0.4-0.9-0.8-0.9h-1v1.7 + h1C254.1,127.8,254.5,127.4,254.5,126.9z"/> + <path class="st6" d="M261.1,126.1h-1.3v4.4c0,0.3-0.2,0.5-0.5,0.5c-0.2,0-0.5-0.2-0.5-0.5v-4.4h-1.3c-0.3,0-0.5-0.2-0.5-0.5 + s0.2-0.5,0.5-0.5h3.5c0.2,0,0.5,0.2,0.5,0.5C261.6,125.9,261.4,126.1,261.1,126.1z"/> + </g> + </g> + </g> + <path class="st6" d="M259.6,91.3h-19.1c-0.7,0-1.2-0.5-1.2-1.2l0,0c0-0.7,0.5-1.2,1.2-1.2h19.1c0.7,0,1.2,0.5,1.2,1.2l0,0 + C260.7,90.8,260.2,91.3,259.6,91.3z"/> + </g> + </g> + <g> + <path class="st8" d="M238.4,432.6c0,2.2-1.8,3.9-3.9,3.9s-3.9-1.8-3.9-3.9c0-2.2,1.8-3.9,3.9-3.9S238.4,430.5,238.4,432.6z"/> + <circle class="st1" cx="250" cy="432.6" r="2.5"/> + <path class="st1" d="M268,432.6c0,1.4-1.1,2.5-2.5,2.5s-2.5-1.1-2.5-2.5s1.1-2.5,2.5-2.5S268,431.2,268,432.6z"/> + </g> + <g> + <rect x="216.3" y="165.9" class="st7" width="67.5" height="67.5"/> + <g> + <path class="st9" d="M236.5,188.2"/> + <path class="st6" d="M263.8,208.1h-22.6c-0.4,0-0.8-0.3-0.9-0.7l-6.5-19.7h-5.3c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1h6 + c0.4,0,0.8,0.3,0.9,0.7l6.5,19.7h21.9c0.5,0,1,0.4,1,1C264.8,207.7,264.3,208.1,263.8,208.1z"/> + <path class="st6" d="M261.6,215.6c-1.7,0-3.2-1.4-3.2-3.2c0-1.7,1.4-3.2,3.2-3.2c1.7,0,3.2,1.4,3.2,3.2 + C264.8,214.2,263.3,215.6,261.6,215.6z M261.6,211.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C262.8,211.8,262.2,211.2,261.6,211.2z"/> + <path class="st6" d="M242.9,215.6c-1.7,0-3.2-1.4-3.2-3.2c0-1.7,1.4-3.2,3.2-3.2c1.7,0,3.2,1.4,3.2,3.2 + C246.1,214.2,244.7,215.6,242.9,215.6z M242.9,211.2c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2s1.2-0.5,1.2-1.2 + C244.1,211.8,243.6,211.2,242.9,211.2z"/> + <polygon class="st6" points="269.2,189.3 264.2,205 242.8,205 237.8,189.3 254.5,189.3 "/> + </g> + <g> + <circle class="st10" cx="283.1" cy="167" r="12.1"/> + </g> + </g> + <g> + <rect x="212.8" y="362.2" class="st8" width="74.5" height="18"/> + <g> + <path class="st6" d="M223.6,371h-0.9v1.7c0,0.2-0.2,0.4-0.4,0.4s-0.4-0.2-0.4-0.4v-4.5c0-0.2,0.2-0.4,0.4-0.4l0,0h1.4 + c0.9,0,1.6,0.7,1.6,1.6C225.3,370.3,224.6,371,223.6,371z M222.7,370.2h0.9c0.4,0,0.8-0.4,0.8-0.8s-0.4-0.8-0.8-0.8h-0.9V370.2z + "/> + <path class="st6" d="M228.6,369.7c0,0.2-0.2,0.4-0.4,0.4s-0.3,0-0.5,0.1c-0.1,0.1-0.3,0.2-0.4,0.4c-0.2,0.2-0.3,0.5-0.3,0.6v1.5 + c0,0.2-0.2,0.4-0.4,0.4s-0.4-0.2-0.4-0.4v-3c0-0.2,0.2-0.4,0.4-0.4s0.4,0.2,0.4,0.4v0.1c0-0.1,0.1-0.1,0.2-0.2 + c0.3-0.2,0.6-0.3,1-0.3C228.4,369.3,228.6,369.5,228.6,369.7z"/> + <path class="st6" d="M229.8,372.5c-0.3-0.3-0.5-0.8-0.5-1.3s0.2-1,0.5-1.3c0.3-0.4,0.8-0.6,1.3-0.6s1,0.2,1.3,0.6 + s0.5,0.8,0.5,1.3s-0.2,1-0.5,1.3c-0.3,0.4-0.8,0.6-1.3,0.6C230.5,373.1,230.1,372.9,229.8,372.5z M230.1,371.2 + c0,0.3,0.1,0.6,0.3,0.8c0.2,0.2,0.4,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.5,0.3-0.8s-0.1-0.6-0.3-0.8 + c-0.2-0.2-0.4-0.3-0.7-0.3s-0.5,0.1-0.7,0.3C230.2,370.6,230.1,370.9,230.1,371.2z"/> + <path class="st6" d="M233.9,371.2c0-1.1,0.9-1.9,1.9-1.9c0.5,0,0.9,0.2,1.2,0.4c0.2,0.1,0.2,0.4,0.1,0.6 + c-0.2,0.2-0.4,0.2-0.6,0.1c-0.2-0.1-0.4-0.2-0.7-0.2c-0.6,0-1.1,0.5-1.1,1.1s0.5,1.1,1.1,1.1c0.3,0,0.5-0.1,0.7-0.2 + s0.4-0.1,0.6,0.1c0.1,0.2,0.1,0.4-0.1,0.6c-0.3,0.2-0.8,0.4-1.2,0.4C234.8,373.1,233.9,372.3,233.9,371.2z"/> + <path class="st6" d="M238.2,371.2c0-1,0.8-1.9,1.9-1.9c1,0,1.8,0.7,1.8,1.8l0,0v0.1c0,0.2-0.2,0.3-0.4,0.3H239 + c0,0.2,0.1,0.4,0.3,0.5c0.2,0.2,0.5,0.3,0.7,0.3c0.3,0,0.6,0,0.8-0.2s0.5-0.1,0.6,0s0.2,0.3,0,0.5c-0.4,0.3-0.8,0.5-1.4,0.5 + C239,373.1,238.2,372.2,238.2,371.2z M239,370.8h2.2c-0.1-0.3-0.5-0.8-1.1-0.8C239.4,370,239.1,370.5,239,370.8z"/> + <path class="st6" d="M242.8,371.2c0-1,0.8-1.9,1.9-1.9c1,0,1.8,0.7,1.8,1.8l0,0v0.1c0,0.2-0.2,0.3-0.4,0.3h-2.4 + c0,0.2,0.1,0.4,0.3,0.5c0.2,0.2,0.5,0.3,0.7,0.3c0.3,0,0.6,0,0.8-0.2s0.5-0.1,0.6,0s0.2,0.3,0,0.5c-0.4,0.3-0.8,0.5-1.4,0.5 + C243.6,373.1,242.8,372.2,242.8,371.2z M243.7,370.8h2.2c-0.1-0.3-0.5-0.8-1.1-0.8C244,370,243.7,370.5,243.7,370.8z"/> + <path class="st6" d="M251.2,372.7c0,0.2-0.2,0.4-0.4,0.4s-0.4-0.1-0.4-0.3c-0.3,0.2-0.7,0.3-1,0.3c-1,0-1.9-0.9-1.9-1.9 + s0.8-1.9,1.9-1.9c0.4,0,0.7,0.1,1,0.3v-1.4c0-0.2,0.2-0.4,0.4-0.4s0.4,0.2,0.4,0.4v3l0,0V372.7z M249.4,370.1 + c-0.3,0-0.5,0.1-0.7,0.3c-0.2,0.2-0.3,0.5-0.3,0.8s0.1,0.6,0.3,0.8c0.2,0.2,0.4,0.3,0.7,0.3s0.5-0.1,0.7-0.3 + c0.2-0.2,0.3-0.5,0.3-0.8s-0.1-0.6-0.3-0.8S249.7,370.1,249.4,370.1z"/> + <path class="st6" d="M256.8,369.7c0,0.2-0.2,0.4-0.4,0.4h-0.2v2.1c0.2,0,0.4,0.2,0.4,0.4c0,0.2-0.2,0.4-0.4,0.4 + c-0.5,0-0.9-0.4-0.9-0.9V370h-0.2c-0.2,0-0.4-0.2-0.4-0.4c0-0.2,0.2-0.4,0.4-0.4h0.2v-1.1c0-0.2,0.2-0.4,0.4-0.4 + s0.4,0.2,0.4,0.4v1.1h0.2C256.6,369.3,256.8,369.5,256.8,369.7z"/> + <path class="st6" d="M258.4,372.5c-0.3-0.3-0.5-0.8-0.5-1.3s0.2-1,0.5-1.3c0.3-0.4,0.8-0.6,1.3-0.6s1,0.2,1.3,0.6 + s0.5,0.8,0.5,1.3s-0.2,1-0.5,1.3c-0.3,0.4-0.8,0.6-1.3,0.6C259.2,373.1,258.7,372.9,258.4,372.5z M258.7,371.2 + c0,0.3,0.1,0.6,0.3,0.8c0.2,0.2,0.4,0.3,0.7,0.3c0.3,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.5,0.3-0.8s-0.1-0.6-0.3-0.8 + c-0.2-0.2-0.4-0.3-0.7-0.3c-0.3,0-0.5,0.1-0.7,0.3S258.7,370.9,258.7,371.2z"/> + <path class="st6" d="M265.1,374.1v-2.9l0,0v-1.5c0-0.2,0.2-0.4,0.4-0.4c0.2,0,0.4,0.1,0.4,0.3c0.3-0.2,0.7-0.3,1-0.3 + c1,0,1.9,0.9,1.9,1.9s-0.8,1.9-1.9,1.9c-0.4,0-0.8-0.1-1-0.3v1.3c0,0.2-0.2,0.4-0.4,0.4C265.3,374.5,265.1,374.3,265.1,374.1z + M266,371.2c0,0.3,0.1,0.6,0.3,0.8c0.2,0.2,0.4,0.3,0.7,0.3c0.3,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.5,0.3-0.8s-0.1-0.6-0.3-0.8 + c-0.2-0.2-0.5-0.3-0.7-0.3c-0.3,0-0.5,0.1-0.7,0.3C266.1,370.6,266,370.9,266,371.2z"/> + <path class="st6" d="M273.4,371.2v1.5c0,0.2-0.2,0.4-0.4,0.4c-0.2,0-0.4-0.1-0.4-0.3c-0.3,0.2-0.6,0.3-1,0.3 + c-0.5,0-1-0.2-1.3-0.6s-0.5-0.8-0.5-1.3s0.2-1,0.5-1.3c0.3-0.4,0.8-0.6,1.3-0.6c0.4,0,0.7,0.1,1,0.3c0-0.2,0.2-0.3,0.4-0.3 + c0.2,0,0.4,0.2,0.4,0.4V371.2z M272.6,371.2c0-0.3-0.1-0.6-0.3-0.8c-0.2-0.2-0.4-0.3-0.7-0.3c-0.3,0-0.5,0.1-0.7,0.3 + c-0.2,0.2-0.3,0.5-0.3,0.8s0.1,0.6,0.3,0.8c0.2,0.2,0.4,0.3,0.7,0.3c0.3,0,0.5-0.1,0.7-0.3C272.5,371.8,272.6,371.5,272.6,371.2 + z"/> + <path class="st6" d="M278,369.7v1.8v1.1c0,1-0.8,1.8-1.8,1.8c-0.3,0-0.6-0.1-0.8-0.2c-0.2-0.1-0.3-0.3-0.2-0.5 + c0.1-0.2,0.4-0.3,0.5-0.2c0.1,0.1,0.3,0.1,0.4,0.1c0.5,0,0.8-0.3,1-0.7c-0.2,0.1-0.5,0.2-0.7,0.2c-0.9,0-1.6-0.7-1.6-1.6v-1.8 + c0-0.2,0.2-0.4,0.4-0.4c0.2,0,0.4,0.2,0.4,0.4v1.8c0,0.4,0.4,0.8,0.8,0.8s0.8-0.3,0.8-0.8v-1.8c0-0.2,0.2-0.4,0.4-0.4 + C277.9,369.3,278,369.5,278,369.7z"/> + </g> + </g> + </g> + <g class="st11"> + <path class="st12" d="M194.7,265.4h0.2c0.4,0,0.8,0.2,1.2,0.7c0.2,0.2,0.3,0.6,0.3,1.1c0.1,0.6,0.3,1.4,0.4,2.4 + c1.2-0.5,3.2-1.3,5.9-2.6c0.2-0.1,0.4-0.1,0.6-0.1c0.6,0,1.1,0.3,1.5,1c0.1,0.2,0.1,0.4,0.1,0.6c0,0.7-0.4,1.2-1.2,1.6 + c-2.1,0.9-3.1,1.4-3.2,1.5c0.5,0.8,1.5,2.8,3,6c0.2,0.3,0.3,0.7,0.3,0.9c0,0.6-0.3,1.1-1,1.4c-0.2,0.1-0.4,0.1-0.5,0.1h-0.1 + c-0.7,0-1.3-0.5-1.6-1.4c-1-2.2-1.9-3.9-2.5-5c-0.2-0.3-0.4-0.6-0.5-0.7l-0.4,0.1c0,1,0,2.6,0,4.8c0,0.7-0.1,1.2-0.3,1.4 + c-0.3,0.4-0.8,0.7-1.3,0.7c-0.6,0-1.1-0.3-1.4-0.9c-0.1-0.2-0.1-0.4-0.1-0.6v-1.2c0-4.8-0.1-7.8-0.5-8.9c-0.1-0.6-0.2-1-0.2-1.1 + c0-0.6,0.2-1.1,0.7-1.5C194.2,265.5,194.4,265.4,194.7,265.4z"/> + <path class="st12" d="M208.6,269.6h0.2c0.5,0,0.9,0.3,1.1,0.9c0,0.1,0,0.2,0,0.3c0,0.5-0.2,0.8-0.7,1c0,0-0.4,0.1-1.3,0.1 + c-0.3,0-0.6,0.1-0.8,0.1l-0.1,0.9h0.5c0.4,0,0.9,0,1.5,0c0.5,0,0.9,0.3,1.1,0.8c0,0.1,0,0.2,0,0.3v0.1c0,0.4-0.2,0.8-0.7,1 + c-0.2,0.1-1,0.1-2.4,0.1h-0.2c0,0.3,0,0.5,0,0.6v0.1c0,0.9,0.1,1.4,0.3,1.6c0.2,0.1,0.5,0.2,0.8,0.2h0.2c0.5,0,1-0.1,1.5-0.3 + c0.2-0.1,0.4-0.1,0.5-0.1c0.5,0,0.8,0.2,1,0.7c0,0.1,0.1,0.2,0.1,0.4c0,0.6-0.3,0.9-1,1.2c-0.6,0.3-1.4,0.4-2.2,0.4h0 + c-1.5,0-2.5-0.5-3-1.6c-0.3-0.6-0.4-1.4-0.4-2.4c0.1-3.2,0.2-4.9,0.3-4.9c0.2-0.4,0.3-0.6,0.5-0.7c0.1-0.1,0.3-0.2,0.6-0.3 + C206.9,269.7,207.7,269.6,208.6,269.6z"/> + <path class="st12" d="M214.2,269.6c0.9,0,1.8,0.2,2.8,0.7c1.1,0.6,1.6,1.3,1.6,2.2v0c0,0.9-0.6,1.7-1.9,2.6 + c0.6,0.5,1.1,1.1,1.5,1.7c0.4,0.6,0.9,1.2,1.5,1.9c0.1,0.1,0.1,0.3,0.1,0.4v0.1c0,0.3-0.2,0.5-0.5,0.7c-0.2,0.1-0.4,0.1-0.6,0.1h0 + c-0.5,0-0.9-0.2-1.1-0.7c-0.4-0.5-0.9-1.1-1.6-2c-0.3-0.3-0.6-0.7-1-1c-0.1,0-0.1-0.1-0.1-0.1c-0.1,0.1-0.3,0.1-0.6,0.2 + c0.1,0.7,0.2,1.5,0.3,2.3c0,0.1,0,0.1,0,0.2c0,0.3-0.2,0.6-0.6,0.8c-0.2,0.1-0.4,0.1-0.5,0.1c-0.4,0-0.8-0.2-1-0.6 + c0,0-0.2-0.9-0.4-2.6c-0.2-2.2-0.5-3.9-0.8-4.8c-0.1-0.4-0.2-0.6-0.2-0.8V271c0-0.4,0.2-0.6,0.7-0.8c0.1,0,0.3-0.1,0.6-0.2 + C213.1,269.8,213.6,269.6,214.2,269.6z M213.6,271.6c0.2,0.8,0.4,1.7,0.5,2.9v0h0c0.3-0.2,0.8-0.4,1.3-0.8c0.7-0.5,1-0.9,1-1.1 + c0-0.3-0.3-0.5-1-0.8c-0.5-0.2-0.9-0.2-1.2-0.3h-0.2C213.9,271.5,213.8,271.5,213.6,271.6z"/> + <path class="st12" d="M224,269.5h0.1c0.8,0,1.5,0.4,2.2,1.2c0.5,0.6,0.8,1.1,1,1.7c0.2,0.3,0.3,0.9,0.6,1.7 + c0.2,0.8,0.4,1.7,0.5,2.8c0.1,0.9,0.2,1.5,0.2,1.8v0c0,0.4-0.2,0.7-0.6,1c-0.1,0.1-0.3,0.1-0.4,0.1c-0.4,0-0.8-0.2-1-0.6 + c-0.1,0-0.1-0.6-0.2-1.8l-0.1-0.8c-1.7,0.1-2.7,0.1-3.2,0.2c-0.2,0-0.6,0.1-1,0.2c0.1,0.3,0.2,0.7,0.4,1.2c0,0.1,0,0.1,0,0.3v0.1 + c0,0.4-0.2,0.8-0.7,1c-0.1,0-0.2,0.1-0.3,0.1h0c-0.5,0-0.9-0.3-1.1-0.8c-0.3-0.8-0.4-1.3-0.4-1.4c-0.3-0.1-0.6-0.3-0.7-0.5 + c-0.1-0.2-0.2-0.4-0.2-0.5v-0.1c0-0.3,0.2-0.6,0.6-0.9c0.1,0,0.2-0.1,0.2-0.1c0-0.5,0.2-1.2,0.5-2.2c0.3-0.9,0.8-1.7,1.4-2.4 + C222.4,269.9,223.2,269.5,224,269.5z M221.9,274.8L221.9,274.8c1-0.2,1.8-0.3,2.3-0.3c0.2,0,0.7,0,1.5-0.1c0,0,0,0,0,0 + c-0.2-0.7-0.4-1.3-0.6-1.7c-0.4-0.7-0.8-1.1-1.1-1.1c-0.3,0-0.7,0.3-1.1,0.8c-0.2,0.3-0.5,0.7-0.7,1.3 + C222,274.3,221.9,274.7,221.9,274.8z"/> + <path class="st12" d="M235.1,269.6L235.1,269.6c0.5,0,0.8,0.2,1,0.6c0.1,0.1,0.2,0.6,0.3,1.4c0.1,0.5,0.2,1.5,0.4,3.1 + c0.2,2,0.2,3.2,0.2,3.8c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.5,0.1h-0.1c-0.5,0-0.9-0.3-1.2-0.8c-1.3-1.7-2.3-3.2-3-4.4 + c-0.3-0.5-0.5-0.7-0.5-0.7h0c0.1,1.4,0.2,3,0.2,5c0,0.5-0.2,0.8-0.7,1.1c-0.1,0-0.2,0.1-0.4,0.1h-0.1c-0.5,0-0.8-0.2-1-0.7 + c0-0.1-0.1-0.3-0.1-0.4c0-1.4,0-3-0.1-4.7c-0.1-0.8-0.2-1.6-0.3-2.4c0-0.1,0-0.1,0-0.2c0-0.5,0.2-0.8,0.5-1.1 + c0.2-0.4,0.6-0.6,1-0.6c0.5,0,1.1,0.4,1.8,1.3c0.4,0.5,0.9,1.1,1.4,1.9c0.1,0.2,0.6,0.9,1.3,2h0v0c0-0.4-0.1-1.4-0.4-3 + c-0.1-0.6-0.2-1-0.2-1.2v0c0-0.5,0.2-0.8,0.7-1C234.9,269.6,235,269.6,235.1,269.6z"/> + <path class="st12" d="M241.6,269.6h0.1c0.3,0,0.6,0.2,0.9,0.5c0.1,0.2,0.2,0.4,0.2,0.6c0.2,2,0.4,3.3,0.4,4c0,0.2,0,0.4,0,0.6 + c0,1.7-0.5,3-1.5,3.8c-0.5,0.4-1.1,0.6-1.7,0.6c-0.8,0-1.4-0.4-2-1.1c-0.2-0.3-0.4-0.7-0.6-1.3c-0.2-0.7-0.3-1.3-0.3-1.9 + c0-0.6,0.1-1,0.3-1.3c0.2-0.3,0.5-0.5,0.9-0.5h0.1c0.4,0,0.7,0.2,1,0.6c0.1,0.2,0.1,0.3,0.1,0.5v0c0,0.1,0,0.2-0.1,0.5v0.1 + c0,0.7,0.2,1.3,0.5,1.9c0.1,0.1,0.2,0.2,0.2,0.2c0.2,0,0.4-0.2,0.7-0.6c0.2-0.5,0.3-0.9,0.3-1.4v-0.1c0-0.5-0.1-1.7-0.3-3.6 + c-0.1-0.6-0.1-0.9-0.1-1.1c0-0.4,0.2-0.8,0.7-1C241.3,269.7,241.5,269.6,241.6,269.6z M241.3,266.3c0.5,0,0.8,0.2,1,0.7 + c0,0.1,0.1,0.3,0.1,0.4v0c0,0.5-0.3,0.9-0.9,1.1c-0.1,0-0.2,0-0.2,0h-0.1c-0.4,0-0.8-0.2-1-0.7c0-0.2-0.1-0.3-0.1-0.4 + c0-0.5,0.2-0.8,0.7-1C241.1,266.4,241.2,266.3,241.3,266.3z"/> + <path class="st12" d="M247.2,269.5h0.1c0.8,0,1.5,0.4,2.2,1.2c0.5,0.6,0.8,1.1,1,1.7c0.2,0.3,0.3,0.9,0.6,1.7 + c0.2,0.8,0.4,1.7,0.5,2.8c0.1,0.9,0.2,1.5,0.2,1.8v0c0,0.4-0.2,0.7-0.6,1c-0.1,0.1-0.3,0.1-0.4,0.1c-0.4,0-0.8-0.2-1-0.6 + c-0.1,0-0.1-0.6-0.2-1.8l-0.1-0.8c-1.7,0.1-2.7,0.1-3.2,0.2c-0.2,0-0.6,0.1-1,0.2c0.1,0.3,0.2,0.7,0.4,1.2c0,0.1,0,0.1,0,0.3v0.1 + c0,0.4-0.2,0.8-0.7,1c-0.1,0-0.2,0.1-0.3,0.1h0c-0.5,0-0.9-0.3-1.1-0.8c-0.3-0.8-0.4-1.3-0.4-1.4c-0.3-0.1-0.6-0.3-0.7-0.5 + c-0.1-0.2-0.2-0.4-0.2-0.5v-0.1c0-0.3,0.2-0.6,0.6-0.9c0.1,0,0.2-0.1,0.2-0.1c0-0.5,0.2-1.2,0.5-2.2c0.3-0.9,0.8-1.7,1.4-2.4 + C245.7,269.9,246.5,269.5,247.2,269.5z M245.2,274.8L245.2,274.8c1-0.2,1.8-0.3,2.3-0.3c0.2,0,0.7,0,1.5-0.1c0,0,0,0,0,0 + c-0.2-0.7-0.4-1.3-0.6-1.7c-0.4-0.7-0.8-1.1-1.1-1.1c-0.3,0-0.7,0.3-1.1,0.8c-0.2,0.3-0.5,0.7-0.7,1.3 + C245.3,274.3,245.2,274.7,245.2,274.8z"/> + <path class="st12" d="M258.4,269.6L258.4,269.6c0.5,0,0.8,0.2,1,0.6c0.1,0.1,0.2,0.6,0.3,1.4c0.1,0.5,0.2,1.5,0.4,3.1 + c0.2,2,0.2,3.2,0.2,3.8c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.5,0.1H259c-0.5,0-0.9-0.3-1.2-0.8c-1.3-1.7-2.3-3.2-3-4.4 + c-0.3-0.5-0.5-0.7-0.5-0.7h0c0.1,1.4,0.2,3,0.2,5c0,0.5-0.2,0.8-0.7,1.1c-0.1,0-0.2,0.1-0.4,0.1h-0.1c-0.5,0-0.8-0.2-1-0.7 + c0-0.1-0.1-0.3-0.1-0.4c0-1.4,0-3-0.1-4.7c-0.1-0.8-0.2-1.6-0.3-2.4c0-0.1,0-0.1,0-0.2c0-0.5,0.2-0.8,0.5-1.1 + c0.2-0.4,0.6-0.6,1-0.6c0.5,0,1.1,0.4,1.8,1.3c0.4,0.5,0.9,1.1,1.4,1.9c0.1,0.2,0.6,0.9,1.3,2h0v0c0-0.4-0.1-1.4-0.4-3 + c-0.1-0.6-0.2-1-0.2-1.2v0c0-0.5,0.2-0.8,0.7-1C258.2,269.6,258.3,269.6,258.4,269.6z"/> + <path class="st12" d="M265,269.4L265,269.4c0.8,0,1.5,0.2,2,0.6c0.3,0.2,0.4,0.5,0.4,0.9c0,0.4-0.2,0.8-0.7,1 + c-0.1,0-0.3,0.1-0.4,0.1h0c-0.2,0-0.5-0.1-0.8-0.3c-0.1,0-0.3-0.1-0.4-0.1H265c-0.6,0-1.2,0.6-1.8,1.7c-0.2,0.4-0.2,0.7-0.2,0.8 + c1.1-0.5,2-0.7,2.7-0.7h0.1c0.9,0,1.6,0.3,2.2,0.9c0.4,0.4,0.5,0.9,0.5,1.4c0,0.8-0.5,1.6-1.4,2.5c-1,1-2,1.5-3,1.5H264 + c-0.9,0-1.7-0.4-2.4-1.2c-0.4-0.5-0.6-1-0.8-1.5c-0.3-0.3-0.5-0.6-0.5-0.9c0-0.2,0.1-0.5,0.3-0.7c0-1.4,0.4-2.6,1.1-3.8 + C262.6,270.1,263.7,269.4,265,269.4z M263,276.6c0.1,0.2,0.2,0.4,0.4,0.6c0.2,0.2,0.5,0.3,0.7,0.3c0.4,0,0.9-0.3,1.6-0.9 + c0.3-0.4,0.5-0.6,0.6-0.8c-0.1-0.1-0.3-0.1-0.5-0.1C265.2,275.7,264.3,276,263,276.6L263,276.6z"/> + <path class="st12" d="M275.1,265.4h0.2c0.4,0,0.8,0.2,1.2,0.7c0.2,0.2,0.3,0.6,0.3,1.1c0.1,0.6,0.3,1.4,0.4,2.4 + c1.2-0.5,3.2-1.3,5.9-2.6c0.2-0.1,0.4-0.1,0.6-0.1c0.6,0,1.1,0.3,1.5,1c0.1,0.2,0.1,0.4,0.1,0.6c0,0.7-0.4,1.2-1.2,1.6 + c-2.1,0.9-3.1,1.4-3.2,1.5c0.5,0.8,1.5,2.8,3,6c0.2,0.3,0.3,0.7,0.3,0.9c0,0.6-0.3,1.1-1,1.4c-0.2,0.1-0.4,0.1-0.5,0.1h-0.1 + c-0.7,0-1.3-0.5-1.6-1.4c-1-2.2-1.9-3.9-2.5-5c-0.2-0.3-0.4-0.6-0.5-0.7l-0.4,0.1c0,1,0,2.6,0,4.8c0,0.7-0.1,1.2-0.3,1.4 + c-0.3,0.4-0.8,0.7-1.3,0.7c-0.6,0-1.1-0.3-1.4-0.9c-0.1-0.2-0.1-0.4-0.1-0.6v-1.2c0-4.8-0.2-7.8-0.5-8.9c-0.1-0.6-0.2-1-0.2-1.1 + c0-0.6,0.2-1.1,0.7-1.5C274.6,265.5,274.9,265.4,275.1,265.4z"/> + <path class="st12" d="M289.2,269.5h0.1c0.8,0,1.5,0.4,2.2,1.2c0.5,0.6,0.8,1.1,1,1.7c0.2,0.3,0.3,0.9,0.6,1.7 + c0.2,0.8,0.4,1.7,0.5,2.8c0.1,0.9,0.2,1.5,0.2,1.8v0c0,0.4-0.2,0.7-0.6,1c-0.1,0.1-0.3,0.1-0.4,0.1c-0.4,0-0.8-0.2-1-0.6 + c-0.1,0-0.1-0.6-0.2-1.8l-0.1-0.8c-1.7,0.1-2.7,0.1-3.2,0.2c-0.2,0-0.6,0.1-1,0.2c0.1,0.3,0.2,0.7,0.4,1.2c0,0.1,0,0.1,0,0.3v0.1 + c0,0.4-0.2,0.8-0.7,1c-0.1,0-0.2,0.1-0.3,0.1h0c-0.5,0-0.9-0.3-1.1-0.8c-0.3-0.8-0.4-1.3-0.4-1.4c-0.3-0.1-0.6-0.3-0.7-0.5 + c-0.1-0.2-0.2-0.4-0.2-0.5v-0.1c0-0.3,0.2-0.6,0.6-0.9c0.1,0,0.2-0.1,0.2-0.1c0-0.5,0.2-1.2,0.5-2.2c0.3-0.9,0.8-1.7,1.4-2.4 + C287.6,269.9,288.4,269.5,289.2,269.5z M287.1,274.8L287.1,274.8c1-0.2,1.8-0.3,2.3-0.3c0.2,0,0.7,0,1.5-0.1c0,0,0,0,0,0 + c-0.2-0.7-0.4-1.3-0.6-1.7c-0.4-0.7-0.8-1.1-1.1-1.1c-0.3,0-0.7,0.3-1.1,0.8c-0.2,0.3-0.5,0.7-0.7,1.3 + C287.2,274.3,287.1,274.7,287.1,274.8z"/> + <path class="st12" d="M301.5,269.6h0.1c0.4,0,0.7,0.2,1,0.7c0.1,0.3,0.2,0.9,0.2,1.7c0,0.6,0.1,2.2,0.1,4.7c0.1,1.1,0.1,1.8,0.1,2 + v0.1c0,0.3-0.2,0.6-0.5,0.9c-0.2,0.1-0.4,0.2-0.6,0.2c-0.5,0-0.9-0.3-1.1-0.8c0,0-0.1-1-0.2-3c0-0.6,0-1.4,0-2.4l-1.3,1.4 + c-0.2,0.2-0.5,0.2-0.7,0.2c-0.3,0-0.6-0.1-0.8-0.4c-0.1,0-0.4-0.3-0.9-0.8c0,0-0.1-0.1-0.4-0.3l-0.4-0.4h0 + c0.2,0.9,0.3,2.7,0.5,5.2c0,0.4-0.2,0.8-0.6,1c-0.2,0.1-0.3,0.1-0.5,0.1h0c-0.4,0-0.8-0.2-1-0.7c-0.1-0.1-0.1-0.4-0.1-0.9 + c-0.2-2.7-0.4-4.6-0.6-5.7c-0.1-0.4-0.2-0.8-0.2-1v-0.1c0-0.1,0-0.3,0.1-0.5v0c0-0.6,0.3-1,0.9-1.2c0.1,0,0.2,0,0.2,0 + c0.4,0,1,0.3,1.6,0.9c0.5,0.4,1.1,1,2.1,1.8h0c0.7-0.8,1.3-1.5,1.6-2c0.1-0.2,0.2-0.3,0.3-0.3c0.1-0.3,0.3-0.5,0.6-0.6 + C301.4,269.7,301.5,269.6,301.5,269.6z"/> + <path class="st12" d="M308.7,269.6c0.5,0,0.9,0.3,1.1,0.8c0,0.1,0,0.3,0,0.4v0.2c0,0.8,0.2,2.5,0.5,5c0,0.2,0,0.4,0,0.6 + c0,1.3-0.6,2.2-1.7,2.8c-0.6,0.4-1.3,0.6-1.9,0.6c-0.7,0-1.4-0.2-2.2-0.7c-0.5-0.3-0.8-0.8-0.9-1.3c-0.1-0.2-0.2-1.1-0.2-2.5 + c0-1.7-0.1-3.2-0.3-4.4c0-0.1,0-0.2,0-0.3c0-0.5,0.2-0.8,0.7-1c0.1,0,0.2-0.1,0.3-0.1h0.1c0.4,0,0.7,0.2,0.9,0.6 + c0.1,0.1,0.1,0.3,0.2,0.7c0.2,1.1,0.3,2.8,0.3,5.2c0,0.8,0,1.2,0.1,1.2c0.3,0.2,0.6,0.3,0.9,0.3h0c0.3,0,0.7-0.2,1.2-0.6 + c0.1-0.1,0.2-0.3,0.2-0.6v-0.1c0-0.1-0.1-1.3-0.4-3.5c-0.1-0.9-0.1-1.6-0.1-2.2c0-0.4,0.2-0.8,0.6-1 + C308.3,269.6,308.5,269.6,308.7,269.6z"/> + </g> + <g class="st11"> + <path class="st12" d="M201.2,294.2h0.1c0.4,0,0.7,0.2,1,0.7c0.1,0.3,0.2,0.9,0.2,1.7c0,0.6,0.1,2.2,0.1,4.7c0.1,1.1,0.1,1.8,0.1,2 + v0.1c0,0.3-0.2,0.6-0.5,0.9c-0.2,0.1-0.4,0.2-0.6,0.2c-0.5,0-0.9-0.3-1.1-0.8c0,0-0.1-1-0.2-3c0-0.6,0-1.4,0-2.4l-1.3,1.4 + c-0.2,0.2-0.5,0.2-0.7,0.2c-0.3,0-0.6-0.1-0.8-0.4c-0.1,0-0.4-0.3-0.9-0.8c0,0-0.1-0.1-0.4-0.3l-0.4-0.4h0 + c0.2,0.9,0.3,2.7,0.5,5.2c0,0.4-0.2,0.8-0.6,1c-0.2,0.1-0.3,0.1-0.5,0.1h-0.1c-0.4,0-0.8-0.2-1-0.7c-0.1-0.1-0.1-0.4-0.1-0.9 + c-0.2-2.7-0.4-4.6-0.6-5.7c-0.1-0.4-0.2-0.8-0.2-1v-0.1c0-0.1,0-0.3,0.1-0.5v0c0-0.6,0.3-1,0.9-1.2c0.1,0,0.2,0,0.2,0 + c0.4,0,1,0.3,1.6,0.9c0.5,0.4,1.1,1,2.1,1.8h0c0.7-0.8,1.3-1.5,1.6-2c0.1-0.2,0.2-0.3,0.3-0.3c0.1-0.3,0.3-0.5,0.6-0.6 + C201.1,294.3,201.2,294.2,201.2,294.2z"/> + <path class="st12" d="M206.9,294.1h0.1c0.8,0,1.5,0.4,2.2,1.2c0.5,0.6,0.8,1.1,1,1.7c0.2,0.3,0.3,0.9,0.6,1.7 + c0.2,0.8,0.4,1.7,0.5,2.8c0.1,0.9,0.2,1.5,0.2,1.8v0c0,0.4-0.2,0.7-0.6,1c-0.1,0.1-0.3,0.1-0.4,0.1c-0.4,0-0.8-0.2-1-0.6 + c-0.1,0-0.1-0.6-0.2-1.8l-0.1-0.8c-1.7,0.1-2.7,0.1-3.2,0.2c-0.2,0-0.6,0.1-1,0.2c0.1,0.3,0.2,0.7,0.4,1.2c0,0.1,0,0.1,0,0.3v0.1 + c0,0.4-0.2,0.8-0.7,1c-0.1,0-0.2,0.1-0.3,0.1h0c-0.5,0-0.9-0.3-1.1-0.8c-0.3-0.8-0.4-1.3-0.4-1.4c-0.3-0.1-0.6-0.3-0.7-0.5 + c-0.1-0.2-0.2-0.4-0.2-0.5v-0.1c0-0.3,0.2-0.6,0.6-0.9c0.1,0,0.2-0.1,0.2-0.1c0-0.5,0.2-1.2,0.5-2.2c0.3-0.9,0.8-1.7,1.4-2.4 + C205.3,294.5,206.1,294.1,206.9,294.1z M204.8,299.4L204.8,299.4c1-0.2,1.8-0.3,2.3-0.3c0.2,0,0.7,0,1.5-0.1c0,0,0,0,0,0 + c-0.2-0.7-0.4-1.3-0.6-1.7c-0.4-0.7-0.8-1.1-1.1-1.1c-0.3,0-0.7,0.3-1.1,0.8c-0.2,0.3-0.5,0.7-0.7,1.3 + C204.9,298.9,204.8,299.3,204.8,299.4z"/> + <path class="st12" d="M215.7,294L215.7,294c0.9,0,1.8,0.3,2.8,0.8c0.6,0.3,0.8,0.7,0.8,1v0.1c0,0.4-0.2,0.6-0.6,0.9 + c-0.2,0.1-0.3,0.1-0.5,0.1c-0.3,0-0.6-0.1-0.9-0.4c-0.6-0.3-1.1-0.5-1.6-0.5c-0.4,0-0.8,0.2-1.1,0.5c-0.2,0.2-0.3,0.4-0.3,0.6v0 + c0,0.4,0.8,1,2.4,1.6c1.2,0.5,2,1,2.2,1.5c0.2,0.3,0.3,0.6,0.3,0.9c0,0.9-0.6,1.7-1.8,2.4c-0.5,0.3-1,0.5-1.5,0.6 + c-0.6,0.2-1.1,0.3-1.6,0.3h-0.1c-1.1,0-1.9-0.4-2.6-1.3c-0.2-0.3-0.4-0.7-0.5-1.1c-0.1-0.2-0.1-0.3-0.1-0.4v-0.1 + c0-0.3,0.2-0.6,0.6-0.8c0.2-0.1,0.4-0.1,0.5-0.1c0.5,0,0.8,0.2,1,0.6c0.1,0.4,0.3,0.7,0.4,0.9c0.2,0.2,0.5,0.3,0.8,0.3 + c0.3,0,0.8-0.1,1.4-0.3c0.3-0.1,0.7-0.4,1.1-0.7c0.1-0.2,0.2-0.3,0.2-0.4c-0.1-0.1-0.2-0.2-0.5-0.4c-0.4-0.2-1-0.4-1.8-0.8 + c-1.7-0.8-2.6-1.7-2.6-2.9c0-0.8,0.4-1.5,1.2-2.2c0.6-0.4,1.2-0.7,1.7-0.8C215.2,294.1,215.5,294,215.7,294z"/> + <path class="st12" d="M220.4,291.8c0.5,0,0.8,0.3,1,0.8c0,0.1,0.1,0.2,0.1,0.3v0.1c0,0.3-0.2,0.6-0.6,0.9 + c-0.2,0.1-0.4,0.1-0.5,0.1h-0.1c-0.5,0-0.8-0.3-1-0.8c0-0.2-0.1-0.3-0.1-0.4c0-0.4,0.2-0.8,0.7-1 + C220.1,291.8,220.3,291.8,220.4,291.8z M221.1,294.6c0.5,0,0.8,0.3,1,0.8c0.1,0.6,0.2,1.4,0.4,2.5c0.1,1,0.2,2.5,0.4,4.6 + c0,0.2,0.1,0.5,0.1,0.9c0,0.4-0.2,0.7-0.6,0.9c-0.2,0.1-0.4,0.1-0.5,0.1c-0.5,0-0.8-0.2-1-0.7c0,0-0.1-0.5-0.1-1.4 + c-0.2-2.4-0.3-4.2-0.5-5.4c-0.1-0.7-0.2-1.1-0.2-1.2c0-0.5,0.3-0.8,0.8-1.1C220.8,294.6,220.9,294.6,221.1,294.6z"/> + <path class="st12" d="M228.5,294.2c0.3,0,0.6,0.1,0.9,0.4c0.2,0.3,0.4,0.6,0.4,1c0.1,0.4,0.3,1.2,0.4,2.5c0.1,0.9,0.2,2.5,0.3,4.6 + v0.3c0,0.6-0.3,0.9-0.8,1.1c-0.1,0-0.2,0-0.3,0c-0.5,0-0.8-0.3-1.1-0.8c0,0-0.1-0.6-0.1-1.9l-0.1-1.9c-0.5,0-1,0-1.3,0h0 + c-0.4,0-0.8,0-1.2,0c0.1,1.8,0.2,3,0.2,3.7c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.4,0.1h-0.1c-0.5,0-0.8-0.2-1-0.7 + c0,0-0.1-0.5-0.1-1.4c-0.1-2.3-0.2-3.8-0.4-4.6c-0.1-0.4-0.2-1.2-0.3-2.2c0-0.1,0-0.1,0-0.1c0-0.4,0.2-0.7,0.5-0.9 + c0.2-0.1,0.4-0.2,0.6-0.2c0.4,0,0.8,0.2,1,0.7c0,0.1,0.2,0.9,0.4,2.4l0.1,0l1.3,0c0.5,0,0.9,0,1.1-0.1c-0.1-0.7-0.2-1.1-0.3-1.4 + c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.5,0.3-0.8,0.8-1.1C228.3,294.2,228.4,294.2,228.5,294.2z"/> + <path class="st12" d="M236.7,294.1h0.1c0.3,0,0.6,0.2,0.9,0.5c0.1,0.2,0.2,0.4,0.2,0.8c0.1,0.4,0.2,1,0.3,1.8 + c0.9-0.4,2.3-1,4.2-1.9c0.1,0,0.3-0.1,0.4-0.1c0.5,0,0.8,0.2,1,0.7c0.1,0.2,0.1,0.3,0.1,0.4c0,0.5-0.3,0.9-0.9,1.1 + c-1.5,0.7-2.2,1-2.3,1.1c0.4,0.6,1.1,2,2.1,4.3c0.1,0.2,0.2,0.5,0.2,0.7c0,0.4-0.2,0.8-0.7,1c-0.1,0-0.3,0.1-0.4,0.1h-0.1 + c-0.5,0-0.9-0.3-1.1-1c-0.7-1.6-1.3-2.8-1.8-3.6c-0.2-0.2-0.3-0.4-0.3-0.5l-0.3,0.1c0,0.7,0,1.8,0,3.4c0,0.5-0.1,0.8-0.2,1 + c-0.2,0.3-0.5,0.5-0.9,0.5c-0.4,0-0.8-0.2-1-0.7c-0.1-0.1-0.1-0.3-0.1-0.5v-0.8c0-3.4-0.1-5.5-0.3-6.3c-0.1-0.4-0.1-0.7-0.1-0.8 + c0-0.4,0.2-0.8,0.5-1C236.3,294.1,236.5,294.1,236.7,294.1z"/> + <path class="st12" d="M248.1,294.2L248.1,294.2c0.9,0,1.7,0.3,2.4,0.8c0.4,0.4,0.7,0.7,0.9,1c0.6,1,0.9,2.1,0.9,3.2 + c0,1.3-0.3,2.4-1,3.5c-0.8,1.2-1.8,1.8-3.1,1.8c-1.2,0-2.3-0.7-3.2-2.2c-0.2-0.4-0.4-0.8-0.7-1.5c-0.3-0.9-0.4-1.7-0.4-2.4v0 + c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1v-0.1c0-0.9,0.3-1.9,0.8-2.7c0.3-0.4,0.6-0.7,1.1-0.7h0.1l0.7-0.3 + C247,294.3,247.6,294.2,248.1,294.2z M246.1,298.4c0,0.9,0.2,1.8,0.7,2.7c0.2,0.4,0.5,0.7,0.8,1c0.2,0.2,0.4,0.3,0.6,0.3h0.1 + c0.5,0,0.9-0.4,1.3-1.2c0.3-0.7,0.4-1.3,0.4-2v0c0-1-0.3-1.8-0.8-2.4c-0.3-0.3-0.7-0.5-1.1-0.5c-0.6,0-1.2,0.2-1.7,0.7 + c-0.1,0-0.1,0.1-0.2,0.2C246.1,297.6,246.1,298,246.1,298.4z"/> + <path class="st12" d="M256.4,294L256.4,294c0.9,0,1.8,0.3,2.8,0.8c0.6,0.3,0.8,0.7,0.8,1v0.1c0,0.4-0.2,0.6-0.6,0.9 + c-0.2,0.1-0.3,0.1-0.5,0.1c-0.3,0-0.6-0.1-0.9-0.4c-0.6-0.3-1.1-0.5-1.6-0.5c-0.4,0-0.8,0.2-1.1,0.5c-0.2,0.2-0.3,0.4-0.3,0.6v0 + c0,0.4,0.8,1,2.4,1.6c1.2,0.5,2,1,2.2,1.5c0.2,0.3,0.3,0.6,0.3,0.9c0,0.9-0.6,1.7-1.8,2.4c-0.5,0.3-1,0.5-1.5,0.6 + c-0.6,0.2-1.1,0.3-1.6,0.3H255c-1.1,0-1.9-0.4-2.6-1.3c-0.2-0.3-0.4-0.7-0.5-1.1c-0.1-0.2-0.1-0.3-0.1-0.4v-0.1 + c0-0.3,0.2-0.6,0.6-0.8c0.2-0.1,0.4-0.1,0.5-0.1c0.5,0,0.8,0.2,1,0.6c0.1,0.4,0.3,0.7,0.4,0.9c0.2,0.2,0.5,0.3,0.8,0.3 + c0.3,0,0.8-0.1,1.4-0.3c0.3-0.1,0.7-0.4,1.1-0.7c0.1-0.2,0.2-0.3,0.2-0.4c-0.1-0.1-0.2-0.2-0.5-0.4c-0.4-0.2-1-0.4-1.8-0.8 + c-1.7-0.8-2.6-1.7-2.6-2.9c0-0.8,0.4-1.5,1.2-2.2c0.6-0.4,1.2-0.7,1.7-0.8C256,294.1,256.2,294,256.4,294z"/> + <path class="st12" d="M264.3,294.2L264.3,294.2c0.9,0,1.7,0.3,2.4,0.8c0.4,0.4,0.7,0.7,0.9,1c0.6,1,0.9,2.1,0.9,3.2 + c0,1.3-0.3,2.4-1,3.5c-0.8,1.2-1.8,1.8-3.1,1.8c-1.3,0-2.3-0.7-3.2-2.2c-0.2-0.4-0.4-0.8-0.7-1.5c-0.3-0.9-0.4-1.7-0.4-2.4v0 + c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1v-0.1c0-0.9,0.3-1.9,0.8-2.7c0.3-0.4,0.6-0.7,1.1-0.7h0l0.7-0.3 + C263.3,294.3,263.8,294.2,264.3,294.2z M262.3,298.4c0,0.9,0.2,1.8,0.7,2.7c0.2,0.4,0.5,0.7,0.8,1c0.2,0.2,0.4,0.3,0.6,0.3h0.1 + c0.5,0,0.9-0.4,1.3-1.2c0.3-0.7,0.4-1.3,0.4-2v0c0-1-0.3-1.8-0.8-2.4c-0.3-0.3-0.7-0.5-1.1-0.5c-0.6,0-1.2,0.2-1.7,0.7 + c-0.1,0-0.1,0.1-0.2,0.2C262.4,297.6,262.3,298,262.3,298.4z"/> + <path class="st12" d="M275,294.2L275,294.2c0.5,0,0.8,0.2,1,0.6c0.1,0.1,0.2,0.6,0.3,1.4c0.1,0.5,0.2,1.5,0.4,3.1 + c0.2,2,0.2,3.2,0.2,3.8c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.5,0.1h-0.1c-0.5,0-0.9-0.3-1.2-0.8c-1.3-1.7-2.3-3.2-3-4.4 + c-0.3-0.5-0.5-0.7-0.5-0.7h0c0.1,1.4,0.2,3,0.2,5c0,0.5-0.2,0.8-0.7,1.1c-0.1,0-0.2,0.1-0.4,0.1H270c-0.5,0-0.8-0.2-1-0.7 + c0-0.1-0.1-0.3-0.1-0.4c0-1.4,0-3-0.1-4.7c-0.1-0.8-0.2-1.6-0.3-2.4c0-0.1,0-0.1,0-0.2c0-0.5,0.2-0.8,0.5-1.1 + c0.2-0.4,0.6-0.6,1-0.6c0.5,0,1.1,0.4,1.8,1.3c0.4,0.5,0.9,1.1,1.4,1.9c0.1,0.2,0.6,0.9,1.3,2h0v0c0-0.4-0.1-1.4-0.4-3 + c-0.1-0.6-0.2-1-0.2-1.2v0c0-0.5,0.2-0.8,0.7-1C274.8,294.2,274.9,294.2,275,294.2z"/> + <path class="st12" d="M281.6,294L281.6,294c0.8,0,1.5,0.2,2,0.6c0.3,0.2,0.4,0.5,0.4,0.9c0,0.4-0.2,0.8-0.7,1 + c-0.1,0-0.3,0.1-0.4,0.1h0c-0.2,0-0.5-0.1-0.8-0.3c-0.1,0-0.3-0.1-0.4-0.1h-0.1c-0.6,0-1.2,0.6-1.8,1.7c-0.2,0.4-0.2,0.7-0.2,0.8 + c1.1-0.5,2-0.7,2.7-0.7h0.1c0.9,0,1.6,0.3,2.2,0.9c0.4,0.4,0.5,0.9,0.5,1.4c0,0.8-0.5,1.6-1.4,2.5c-1,1-2,1.5-3,1.5h-0.1 + c-0.9,0-1.7-0.4-2.4-1.2c-0.4-0.5-0.6-1-0.8-1.5c-0.3-0.3-0.5-0.6-0.5-0.9c0-0.2,0.1-0.5,0.3-0.7c0-1.4,0.4-2.6,1.1-3.8 + C279.2,294.7,280.3,294,281.6,294z M279.7,301.2c0.1,0.2,0.2,0.4,0.4,0.6c0.2,0.2,0.5,0.3,0.7,0.3c0.4,0,0.9-0.3,1.6-0.9 + c0.3-0.4,0.5-0.6,0.6-0.8c-0.1-0.1-0.3-0.1-0.5-0.1C281.9,300.3,281,300.6,279.7,301.2L279.7,301.2z"/> + <path class="st12" d="M296.8,294.2L296.8,294.2c0.5,0,0.8,0.2,1,0.6c0.1,0.1,0.2,0.6,0.3,1.4c0.1,0.5,0.2,1.5,0.4,3.1 + c0.2,2,0.2,3.2,0.2,3.8c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.5,0.1h-0.1c-0.5,0-0.9-0.3-1.2-0.8c-1.3-1.7-2.3-3.2-3-4.4 + c-0.3-0.5-0.5-0.7-0.5-0.7h0c0.1,1.4,0.2,3,0.2,5c0,0.5-0.2,0.8-0.7,1.1c-0.1,0-0.2,0.1-0.4,0.1h-0.1c-0.5,0-0.8-0.2-1-0.7 + c0-0.1-0.1-0.3-0.1-0.4c0-1.4,0-3-0.1-4.7c-0.1-0.8-0.2-1.6-0.3-2.4c0-0.1,0-0.1,0-0.2c0-0.5,0.2-0.8,0.5-1.1 + c0.2-0.4,0.6-0.6,1-0.6c0.5,0,1.1,0.4,1.8,1.3c0.4,0.5,0.9,1.1,1.4,1.9c0.1,0.2,0.6,0.9,1.3,2h0v0c0-0.4-0.1-1.4-0.4-3 + c-0.1-0.6-0.2-1-0.2-1.2v0c0-0.5,0.2-0.8,0.7-1C296.6,294.2,296.7,294.2,296.8,294.2z"/> + <path class="st12" d="M299.9,291.8c0.5,0,0.8,0.3,1,0.8c0,0.1,0.1,0.2,0.1,0.3v0.1c0,0.3-0.2,0.6-0.6,0.9 + c-0.2,0.1-0.4,0.1-0.5,0.1h-0.1c-0.5,0-0.8-0.3-1-0.8c0-0.2,0-0.3,0-0.4c0-0.4,0.2-0.8,0.7-1C299.6,291.8,299.7,291.8,299.9,291.8 + z M300.5,294.6c0.5,0,0.8,0.3,1,0.8c0.1,0.6,0.2,1.4,0.4,2.5c0.1,1,0.2,2.5,0.4,4.6c0,0.2,0.1,0.5,0.1,0.9c0,0.4-0.2,0.7-0.6,0.9 + c-0.2,0.1-0.4,0.1-0.5,0.1c-0.5,0-0.8-0.2-1-0.7c0,0-0.1-0.5-0.1-1.4c-0.2-2.4-0.3-4.2-0.5-5.4c-0.1-0.7-0.2-1.1-0.2-1.2 + c0-0.5,0.3-0.8,0.8-1.1C300.3,294.6,300.4,294.6,300.5,294.6z"/> + <path class="st12" d="M308,294.2c0.3,0,0.6,0.1,0.9,0.4c0.2,0.3,0.4,0.6,0.4,1c0.1,0.4,0.3,1.2,0.4,2.5c0.1,0.9,0.2,2.5,0.3,4.6 + v0.3c0,0.6-0.3,0.9-0.8,1.1c-0.1,0-0.2,0-0.3,0c-0.5,0-0.8-0.3-1.1-0.8c0,0-0.1-0.6-0.1-1.9l-0.1-1.9c-0.5,0-1,0-1.3,0h0 + c-0.4,0-0.8,0-1.2,0c0.1,1.8,0.2,3,0.2,3.7c0,0.4-0.2,0.8-0.7,1c-0.2,0.1-0.3,0.1-0.4,0.1h0c-0.5,0-0.8-0.2-1-0.7 + c0,0-0.1-0.5-0.1-1.4c-0.1-2.3-0.2-3.8-0.4-4.6c-0.1-0.4-0.2-1.2-0.3-2.2c0-0.1,0-0.1,0-0.1c0-0.4,0.2-0.7,0.5-0.9 + c0.2-0.1,0.4-0.2,0.6-0.2c0.4,0,0.8,0.2,1,0.7c0,0.1,0.2,0.9,0.4,2.4l0.1,0l1.3,0c0.5,0,0.9,0,1.1-0.1c-0.1-0.7-0.2-1.1-0.3-1.4 + c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.5,0.3-0.8,0.8-1.1C307.7,294.2,307.8,294.2,308,294.2z"/> + </g> + <text transform="matrix(1 0 0 1 278.0344 173.1807)" class="st6 st13 st14">X</text> +</g> +<g id="Shopping_bags"> + <g> + <g> + <path class="st15" d="M94.2,349.6c0,0,3.4-41.9,21.9-42.2c16.6-0.3,7.7,42.4,7.7,42.4"/> + <g> + <g> + <g> + <polygon class="st8" points="83.8,339.9 154.9,339.6 165.3,460 82.9,464.1 "/> + </g> + <g> + <polygon class="st8" points="82.9,464.1 57.8,459.4 73.9,338.4 78.5,341.7 83.8,339.9 "/> + <polygon class="st16" points="82.9,464.1 57.8,459.4 73.9,338.4 78.5,341.7 83.8,339.9 "/> + <polygon class="st17" points="70.1,449.1 57.8,459.4 73.9,338.4 78.5,341.7 "/> + </g> + <g class="st18"> + <path d="M82.4,461.4c-1.9-2.2-3.8-4.3-5.8-6.3s-3.9-4-6-6l-0.3-0.3L70,449c-1.9,1.3-3.7,2.7-5.5,4.1c-1.8,1.4-3.6,2.8-5.4,4.4 + c2-1.1,3.9-2.3,5.8-3.5s3.8-2.5,5.6-3.8l-0.6-0.1c2,2,4,3.9,6.1,5.8C78.2,457.8,80.3,459.7,82.4,461.4z"/> + <path d="M70.3,450c0.9-9,1.7-18,2.5-27s1.4-18,2.2-27.1c0.6-9,1.3-18.1,1.9-27.1l0.9-13.6c0.2-4.5,0.5-9,0.7-13.6 + c-0.5,4.5-0.9,9-1.3,13.5L76,368.7c-0.8,9-1.4,18-2.2,27.1c-0.6,9-1.3,18.1-1.9,27.1C71.3,431.9,70.8,440.9,70.3,450z"/> + </g> + </g> + </g> + <path class="st15" d="M136.7,349.6c0,0-3.4-41.9-21.9-42.2c-16.6-0.3-7.7,42.4-7.7,42.4"/> + </g> + <g> + <g> + <g> + <g> + <polygon class="st19" points="112.3,372.3 195.3,372.1 203.2,464.3 111.7,467.5 "/> + </g> + <g> + <polygon class="st20" points="111.7,467.5 92.4,463.9 104.7,371.1 108.3,373.7 112.3,372.3 "/> + <polygon class="st16" points="111.7,467.5 92.4,463.9 104.7,371.1 108.3,373.7 112.3,372.3 "/> + <polygon class="st17" points="101.8,456 92.4,463.9 104.7,371.1 108.3,373.7 "/> + </g> + <g class="st18"> + <path d="M111.3,465.4c-1.4-1.7-2.9-3.3-4.4-4.8c-1.5-1.6-3-3.1-4.6-4.6l-0.2-0.2l-0.2,0.2c-1.4,1-2.8,2-4.2,3.1 + c-1.4,1.1-2.8,2.2-4.1,3.3c1.5-0.8,3-1.7,4.4-2.7c1.5-0.9,2.9-1.9,4.3-2.9h-0.4c1.5,1.5,3.1,3,4.7,4.4 + C108,462.7,109.6,464.1,111.3,465.4z"/> + <path d="M102,456.6c0.7-6.9,1.3-13.8,1.9-20.7c0.6-6.9,1.1-13.8,1.7-20.7c0.5-6.9,1-13.8,1.5-20.8l0.7-10.4 + c0.2-3.5,0.4-6.9,0.6-10.4c-0.4,3.4-0.7,6.9-1,10.3l-0.9,10.4c-0.6,6.9-1.1,13.8-1.7,20.7c-0.5,6.9-1,13.8-1.5,20.8 + C102.8,442.8,102.3,449.7,102,456.6z"/> + </g> + </g> + </g> + <path class="st21" d="M133.4,376.6c0,0,4,34.7,24,33.6c21.3-1.1,13.9-33.2,13.9-33.2"/> + </g> + </g> +</g> +<g id="Character_2"> + <g> + <g> + <path class="st4" d="M371,106.4c-6.4,0.6-10.2,8.3-12.2,15c-2,6.8-1.7,12.4-6.7,15.6c0,0,3.3,7.5,18.4,9.9 + c12.5,2,19.8-0.1,19.8-0.1s2.7-7.6,3.3-15.4c0.7-8.5-0.8-17.4-6.2-21.9C378.3,102.2,371,106.4,371,106.4z"/> + <path class="st4" d="M371,106.4c-1.6,0.2-3,0.8-4.3,1.7c-1.3,0.8-2.4,1.9-3.3,3.1c-1.9,2.4-3.1,5.3-4.1,8.3c-1,2.9-1.8,6-2.8,9 + c-0.5,1.5-1.1,3-1.9,4.4s-2,2.6-3.4,3.2c1.4-0.8,2.4-2,3-3.4c0.7-1.4,1.2-2.9,1.6-4.4c0.8-3,1.5-6.1,2.6-9.1c1-3,2.3-6,4.4-8.4 + c1-1.2,2.3-2.3,3.7-3.1C367.9,107,369.4,106.4,371,106.4z"/> + <path class="st4" d="M383.5,107.1c3.3,1.4,5.9,4.2,7.7,7.4c1.8,3.2,2.8,6.9,3.1,10.6c0.3,3.7-0.1,7.5-0.8,11.1 + c-0.7,3.6-1.5,7.2-2.5,10.7l1-5.4c0.3-1.8,0.6-3.6,0.9-5.4c0.5-3.6,0.9-7.3,0.6-10.9c-0.2-3.6-1.1-7.2-2.8-10.3 + c-0.8-1.6-1.8-3.1-3-4.4C386.4,109.1,385,107.9,383.5,107.1z"/> + </g> + <g> + <g> + <g> + <g> + <path class="st22" d="M443.5,459.3c-2.3,0.7-70.2-0.7-72.7-2.4c-1-0.6,4.9-64.9,4.9-64.9l43,0.8l-4.9,43c0,0,25,11.9,27.6,14 + C443.9,451.9,445.8,458.6,443.5,459.3z"/> + <path class="st8" d="M443.5,459.3c-2.3,0.7-70.2-0.7-72.7-2.4c-0.3-0.2-0.4-6.7,0.7-15.2c12.3,2.1,56.2,8.8,59.7,6.8 + c2.4-1.4,0.3-3.6-1.7-5.1c5.6,2.8,10.8,5.5,11.9,6.4C443.9,451.9,445.8,458.6,443.5,459.3z"/> + <path class="st17" d="M408.9,459c-18.1-0.5-36.8-1.3-38.1-2.1c-0.4-0.3,0.3-10.5,1.3-22.8L408.9,459z"/> + </g> + <g> + <path class="st20" d="M415.1,425.5l-42.3-0.6c0,0,8.4-101.2,8-103.2c-0.4-2.5-30.4-120-30.4-120h40.3 + c0,0,31.8,109.6,32.9,120.1C425.5,338.9,415.1,425.5,415.1,425.5z"/> + <g> + <path class="st4" d="M376.6,415.4c2.5-0.2,5-0.1,7.5-0.2c2.5,0,5,0,7.5,0c5,0,10,0.1,15,0.3c1.4,0,2.7,0.1,4.1,0.1 + c1.5,0.1,2.9,0.3,4.4,0.4c0.1,0,0.1,0.2,0,0.2c-1.2,0-2.5,0.2-3.7,0.2c-1.3,0-2.6,0-3.8,0c-2.5,0-5,0-7.5,0 + c-5,0-10-0.1-15-0.3c-2.8-0.1-5.7-0.2-8.5-0.4C376.4,415.6,376.4,415.4,376.6,415.4z"/> + <path class="st4" d="M359.3,211.2c3.6,12.8,6.9,25.7,10.1,38.5c3.2,12.9,6.5,25.8,9.7,38.7c1.6,6.4,3.2,12.9,4.8,19.3 + c1.6,6.3,3.4,12.6,3.8,19.1c0.4,6.6-0.4,13.2-1,19.8c-0.6,6.6-1.1,13.2-1.7,19.8c-1.2,13.2-2.3,26.4-3.7,39.6 + c-0.2,1.6-0.4,3.3-0.5,4.9c0,0.1-0.2,0.1-0.2,0c0.9-13.2,1.8-26.4,2.8-39.6c0.5-6.6,1.1-13.2,1.6-19.8 + c0.5-6.6,1.3-13.2,1.5-19.8c0.2-6.7-1-13.1-2.6-19.5c-1.6-6.3-3.2-12.6-4.7-18.9c-3.2-12.9-6.5-25.8-9.7-38.7 + c-3.6-14.4-7.2-28.9-10.3-43.4C359.1,211.1,359.3,211.1,359.3,211.2z"/> + </g> + <path class="st4" d="M350.4,201.7c0,0,12.9,50.4,21.9,85.9l17.2-85.9L350.4,201.7L350.4,201.7z"/> + </g> + </g> + <g> + <g> + <g> + <path class="st22" d="M394.1,459.4c-2.3,0.7-70.2-0.7-72.7-2.4c-1-0.6,2.6-64.9,2.6-64.9l42.5,0.8l-2.1,43 + c0,0,25,11.9,27.6,14C394.5,452,396.4,458.7,394.1,459.4z"/> + <path class="st8" d="M394.1,459.4c-2.3,0.7-70.2-0.7-72.7-2.4c-0.3-0.2-0.2-6.5,0-15.2c12.3,2.1,56.9,8.8,60.3,6.8 + c2.4-1.4,0.3-3.6-1.7-5.1c5.6,2.8,10.8,5.5,11.9,6.4C394.5,452,396.4,458.7,394.1,459.4z"/> + </g> + </g> + <g> + <path class="st20" d="M390.7,201.7c0,0-1.2,19.3-5.8,34.5c-0.4,1.3-0.8,2.5-1.2,3.7c0,0-4.6,1.6-11.7,5.8 + c0,0-2.9,73.8-2.9,78.3c0.2,17.1-4.2,100.6-4.2,100.6l-42.6-0.4c0,0,4.4-94.4,4.4-100.7c0-6.1,2.9-44.4,5.5-77.6 + c0,0-3.8-10.6-3.4-16c1-13,6.8-28.3,6.8-28.3L390.7,201.7z"/> + <g> + <path class="st4" d="M377.1,230.9c0.1-1.1,0.2-2.1,0.3-3.2c0.2-2,0.5-3.9,0.7-5.9c0.5-4.5,1.1-8.9,1.8-13.4 + c0-0.1,0.2-0.1,0.2,0c-0.1,1.8-0.2,3.6-0.3,5.3c-0.1,1.8-0.2,3.6-0.4,5.3c-0.3,3.5-0.6,7-1,10.5c-0.2,1.3-0.8,3.8,1.1,4.1 + c1.5,0.2,2.6-1.3,3-2.6c0.5-1.6,0.6-3.3,0.8-4.9c0.2-1.8,0.4-3.6,0.5-5.3c0.3-3.9,0.7-7.8,1.1-11.6c0-0.1,0.2-0.1,0.2,0 + c0.1,4,0.1,7.9-0.2,11.9c-0.1,1.9-0.3,3.8-0.5,5.7c-0.2,1.8-0.3,3.6-1,5.3c-0.5,1.3-1.6,2.5-3,2.7h-0.1l0.1,0.1 + c0,0.6,0.1,1.3,0,1.9c0,0.6-0.1,1.2-0.2,1.9c-0.1,0.6-0.2,1.3-0.4,1.9c-0.1,0.3-0.2,0.6-0.3,0.9c-0.1,0.3-0.3,0.5-0.5,0.8 + c-0.1,0.1-0.2,0.1-0.2-0.1l0,0c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1l0,0c0-0.2,0-0.4,0-0.5c0-0.3,0.1-0.6,0.1-0.9 + c0.1-0.6,0.2-1.2,0.4-1.8c0.1-0.6,0.2-1.2,0.3-1.8c0.1-0.6,0.3-1.2,0.4-1.8c0,0,0,0,0-0.1c-1.1,0.1-2.3-0.5-2.8-1.5 + C376.9,232.6,377,231.7,377.1,230.9z"/> + <path class="st4" d="M368.6,247.2c1.2-1,2.7-1.8,4-2.6c1.5-0.9,3-1.7,4.6-2.4c3.1-1.3,6.3-2.3,9.4-3.3c0.1,0,0.2,0.1,0.1,0.2 + c-3.1,1.2-6,2.9-9,4.3c-1.5,0.7-2.9,1.4-4.4,2.1c-1.5,0.7-3,1.4-4.5,2C368.6,247.4,368.5,247.3,368.6,247.2z"/> + <path class="st4" d="M344.5,220.3c2.2,0,4.3-0.3,6.4-0.9c1-0.2,1.9-0.6,2.9-0.9c0.9-0.3,1.9-0.7,2.6-1.3 + c1.5-1.3,2.1-3.2,2.8-5c0.7-2,1.2-4,1.7-6.1c0-0.1,0.2-0.1,0.2,0c0.1,2.3-0.3,4.7-0.9,6.9c-0.5,1.9-1.2,4-2.8,5.4 + c-1.6,1.4-3.8,1.9-5.9,2.2c-2.3,0.3-4.7,0.2-7-0.1C344.4,220.5,344.4,220.3,344.5,220.3z"/> + <path class="st4" d="M324.3,416c2.5-0.2,5-0.1,7.5-0.2c2.5,0,5,0,7.5,0c5,0,10,0.1,15,0.3c1.4,0,2.7,0.1,4.1,0.1 + c1.5,0.1,2.9,0.3,4.4,0.4c0.1,0,0.1,0.2,0,0.2c-1.2,0-2.5,0.2-3.7,0.2c-1.3,0-2.6,0-3.8,0c-2.5,0-5,0-7.5,0 + c-5,0-10-0.1-15-0.3c-2.8-0.1-5.7-0.2-8.5-0.4C324.1,416.2,324.1,416,324.3,416z"/> + <path class="st4" d="M329.5,410.4L329.5,410.4c-0.3,0-0.5-0.3-0.5-0.5l9.6-165.2c-0.1-0.7-2.8-9.9-3.1-14.7 + c-0.3-5,4.9-24.4,5.1-25.2c0.1-0.3,0.4-0.4,0.6-0.4c0.3,0.1,0.4,0.4,0.4,0.6c-0.1,0.2-5.3,20.1-5.1,24.9 + c0.2,4.9,3.1,14.5,3.1,14.6L330,409.8C330,410.2,329.7,410.4,329.5,410.4z"/> + </g> + </g> + </g> + </g> + </g> + <g> + <g> + <g> + <path class="st22" d="M378.3,156.4c2.3,10.1,12.5,52.4,21,54.8c8.6,2.4,16.9-3.2,17.2-10.3c0.3-7.7-22.7-38.4-28.3-45 + C382.8,149.6,376.1,146.5,378.3,156.4z"/> + </g> + <g> + <path class="st8" d="M382.8,181.5l24.6-4.3c0,0-16.8-21.7-23.5-26.7c-7.6-5.6-8.8-0.5-7.6,8.4 + C377.5,167.7,382.8,181.5,382.8,181.5z"/> + <path class="st6" d="M377.5,158.4c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8c-0.8,0.3-1.5,0.7-2.2,1.2 + C378.6,157.2,378,157.7,377.5,158.4z M392,173.4c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8c-0.3-0.8-0.7-1.5-1.2-2.2 + C393.2,174.5,392.7,173.9,392,173.4z M389.5,162.4c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C391.2,162.3,390.4,162.3,389.5,162.4z M380.9,175.4c0.4-0.8,0.5-1.6,0.7-2.4c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C380.9,173.7,380.8,174.5,380.9,175.4z M403.9,176c0.4-0.8,0.5-1.6,0.7-2.4c-0.2-0.2-0.4-0.4-0.5-0.7c0,0.2-0.1,0.4-0.1,0.5 + C403.8,174.3,403.7,175.1,403.9,176z"/> + <g> + <g> + <path class="st4" d="M403.1,173.3c-0.9,0-8.6,1.3-10.2,1.6c-1.7,0.3-8.5,1.5-10.2,1.9c-0.1,0-0.1,0.1,0,0.1 + c1.7-0.1,8.6-1.3,10.3-1.6c1.7-0.3,9.3-1.7,10.1-1.9C403.2,173.4,403.2,173.3,403.1,173.3z"/> + </g> + </g> + <path class="st17" d="M376.3,158.8c1.2,8.9,6.5,22.7,6.5,22.7l17.5-3.1l-22.7-30C375.7,149.5,375.5,153.5,376.3,158.8z"/> + </g> + </g> + <g> + <path class="st8" d="M334.4,203.9h57.7l-2.6-15.4c0,0,4.5-6,4.1-12.6c-0.3-7-13.8-25.5-14.9-26.6c-4.4-4.2-11.5-4.5-15.1-1.5 + C344.9,163.6,334.4,203.9,334.4,203.9z"/> + <path class="st23" d="M392,173.4c0.3,0.8,0.7,1.5,1.2,2.2c0.2,0.2,0.3,0.4,0.5,0.6c0-0.1,0-0.1,0-0.2c0-0.3-0.1-0.7-0.1-1 + C393.1,174.4,392.6,173.8,392,173.4z"/> + <path class="st23" d="M385.9,203.9h0.2c0.3-0.7,0.4-1.3,0.5-2c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C385.9,202.5,385.8,203.2,385.9,203.9z"/> + <path class="st23" d="M381.6,172.9c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4c-0.1,0.8-0.2,1.7,0,2.5 + C381.3,174.6,381.5,173.7,381.6,172.9z"/> + <path class="st23" d="M380,186.2c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C381.7,186.1,380.9,186.1,380,186.2z"/> + <path class="st23" d="M377.5,158.4c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8c-0.8,0.3-1.5,0.7-2.2,1.2 + C378.6,157.2,378,157.7,377.5,158.4z"/> + <path class="st23" d="M372.1,146.1c0.1,0.1,0.1,0.1,0.2,0.2c0-0.1,0-0.1-0.1-0.2H372.1z"/> + <path class="st23" d="M370.3,193.9c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8c-0.3-0.8-0.7-1.5-1.2-2.2 + C371.6,195.1,371,194.4,370.3,193.9z"/> + <path class="st23" d="M366.7,178.4c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8c-0.8,0.3-1.5,0.7-2.2,1.2 + C367.8,177.2,367.2,177.7,366.7,178.4z"/> + <path class="st23" d="M365.6,162.9c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C367.3,162.8,366.5,162.7,365.6,162.9z"/> + <path class="st23" d="M359.7,151.7c0.8,0.4,1.5,0.5,2.3,0.6s1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C361.4,151.6,360.6,151.5,359.7,151.7C359.8,151.7,359.8,151.7,359.7,151.7z"/> + <path class="st23" d="M356,185.3c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C357.7,185.3,356.9,185.2,356,185.3z"/> + <path class="st23" d="M354.4,169.8c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8c-0.3-0.8-0.7-1.5-1.2-2.2 + C355.6,171,355.1,170.3,354.4,169.8z"/> + <path class="st23" d="M354.1,199.6c-0.1,0.8-0.2,1.7,0,2.5c0.4-0.8,0.5-1.6,0.7-2.4c0.1-0.8,0.2-1.7,0-2.5 + C354.4,198,354.2,198.8,354.1,199.6z"/> + <path class="st23" d="M341.3,189.8c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8c-0.8,0.3-1.5,0.8-2.2,1.2 + C342.5,188.5,341.8,189.1,341.3,189.8z"/> + <path class="st23" d="M338,201.8c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C339.7,201.7,338.9,201.6,338,201.8z"/> + <g> + <g> + <path class="st4" d="M369.1,185.3c2.8,0.1,5.5,0.3,8.3,0.8c1.4,0.3,2.7,0.6,4,1c0.7,0.2,1.3,0.4,2,0.5 + c0.7,0.2,1.4,0.3,2.1,0.3c0.1,0,0.1,0.1,0,0.1c-0.7,0.1-1.3,0.2-2,0.1c-0.7,0-1.3-0.1-2-0.2c-1.4-0.3-2.7-0.6-4.1-0.9 + c-2.8-0.6-5.6-1.1-8.4-1.5C368.9,185.5,368.9,185.3,369.1,185.3z"/> + <path class="st4" d="M362.6,188.7c2.2-0.5,4.5-0.8,6.7-1c1.1-0.1,2.3-0.1,3.4-0.1c0.5,0,1.1,0,1.6,0.1c0.6,0,1.2,0.2,1.8,0.2 + c0.1,0,0.1,0.1,0,0.1c-0.6,0-1.1,0.1-1.7,0.1s-1.1,0.1-1.7,0.1c-1.1,0.1-2.3,0.2-3.4,0.2c-2.3,0.1-4.5,0.3-6.8,0.5 + C362.5,188.9,362.5,188.7,362.6,188.7z"/> + </g> + </g> + <path class="st6" d="M354,202.1c0.4-0.8,0.5-1.6,0.7-2.4c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C354,200.4,353.9,201.3,354,202.1z M385.9,203.9h0.2c0.3-0.7,0.4-1.3,0.5-2c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C385.9,202.5,385.8,203.2,385.9,203.9z M380.9,175.4c0.4-0.8,0.5-1.6,0.7-2.4c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C380.9,173.7,380.8,174.5,380.9,175.4z M365.6,162.9c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C367.3,162.8,366.5,162.7,365.6,162.9z M380,186.2c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C381.7,186.1,380.9,186.1,380,186.2z M338,201.8c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C339.7,201.7,338.9,201.6,338,201.8z M356,185.3c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C357.7,185.3,356.9,185.2,356,185.3z M359.7,151.7c0.8,0.4,1.5,0.5,2.3,0.6s1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C361.4,151.6,360.6,151.5,359.7,151.7C359.8,151.7,359.8,151.7,359.7,151.7z M372.1,146.1c0.1,0.1,0.1,0.1,0.2,0.2 + c0-0.1,0-0.1-0.1-0.2H372.1z M392,173.4c0.3,0.8,0.7,1.5,1.2,2.2c0.2,0.2,0.3,0.4,0.5,0.6c0-0.1,0-0.1,0-0.2 + c0-0.3-0.1-0.7-0.1-1C393.1,174.4,392.6,173.8,392,173.4z M354.4,169.8c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8 + c-0.3-0.8-0.7-1.5-1.2-2.2C355.6,171,355.1,170.3,354.4,169.8z M370.3,193.9c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8 + c-0.3-0.8-0.7-1.5-1.2-2.2C371.6,195.1,371,194.4,370.3,193.9z M377.5,158.4c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8 + c-0.8,0.3-1.5,0.7-2.2,1.2C378.6,157.2,378,157.7,377.5,158.4z M366.7,178.4c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8 + c-0.8,0.3-1.5,0.7-2.2,1.2C367.8,177.2,367.2,177.7,366.7,178.4z M341.3,189.8c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8 + c-0.8,0.3-1.5,0.8-2.2,1.2C342.5,188.5,341.8,189.1,341.3,189.8z"/> + </g> + <g> + <path class="st22" d="M358.6,151c-7.1,7.5-37.2,42.4-34.1,51.5c2.9,8.5,15.5,6.5,20.4,1.4c7.1-7.4,17.2-36.6,19.6-44.9 + C366.7,151,365.6,143.7,358.6,151z"/> + <g> + <path class="st23" d="M358.5,179.8l-24.1-6.5c0,0,18.6-20.2,25.8-24.5c8.1-4.9,8.8,0.3,6.8,9 + C365,166.5,358.5,179.8,358.5,179.8z"/> + <path class="st23" d="M334.4,173.3l24.1,6.5c0,0,6.5-13.3,8.5-22s1.3-13.9-6.8-9c-0.4,0.3-0.9,0.6-1.3,0.9 + c-0.2,0.1-0.4,0.3-0.6,0.4l0,0c-2.6,2-6.1,5.1-9.5,8.5c-0.1,0.1-0.1,0.1-0.2,0.2c-2.7,2.6-5.4,5.4-7.7,7.8 + c-0.3,0.3-0.7,0.7-1,1C336.7,170.9,334.4,173.3,334.4,173.3z"/> + <path class="st8" d="M334.4,173.3l24.1,6.5c0,0,6.5-13.3,8.5-22s1.3-13.9-6.8-9c-0.4,0.3-0.9,0.6-1.3,0.9 + c-0.2,0.1-0.4,0.3-0.6,0.4l0,0c-2.6,2-6.1,5.1-9.5,8.5c-0.1,0.1-0.1,0.1-0.2,0.2c-2.7,2.6-5.4,5.4-7.7,7.8 + c-0.3,0.3-0.7,0.7-1,1C336.7,170.9,334.4,173.3,334.4,173.3z"/> + <path class="st6" d="M337.4,173.3c0.8-0.3,1.5-0.7,2.2-1.2s1.3-1.1,1.8-1.8c-0.8,0.3-1.5,0.7-2.2,1.2 + C338.5,172.1,337.9,172.6,337.4,173.3z M354.4,169.8c0.3,0.8,0.7,1.5,1.2,2.2s1.1,1.3,1.8,1.8c-0.3-0.8-0.7-1.5-1.2-2.2 + C355.6,171,355.1,170.3,354.4,169.8z M359.6,151.7c0.8,0.4,1.6,0.5,2.4,0.7c0.8,0.1,1.7,0.2,2.5,0c-0.8-0.4-1.6-0.5-2.4-0.7 + C361.3,151.6,360.5,151.5,359.6,151.7z M350.8,163.7c0.4-0.8,0.5-1.6,0.7-2.4c0.1-0.8,0.2-1.7,0-2.5c-0.4,0.8-0.5,1.6-0.7,2.4 + C350.8,162,350.7,162.8,350.8,163.7z"/> + <g> + <g> + <path class="st4" d="M339,170c0.9,0.1,8.4,2,10,2.5s8.3,2.2,10,2.8c0.1,0,0.1,0.1,0,0.1c-1.7-0.3-8.5-2.1-10.1-2.5 + c-1.7-0.4-9.1-2.5-9.9-2.8C338.9,170,338.9,170,339,170z"/> + </g> + </g> + <g> + <g> + <path class="st4" d="M356.2,179.2c0.8,0.2,1.6,0.3,2.4,0.5l-0.2,0.1l3.4-8l3.4-8c-0.8,2.8-1.8,5.5-3,8.2 + c-0.5,1.3-1.2,2.7-1.7,4c-0.6,1.3-1.2,2.6-1.9,3.9l-0.1,0.1h-0.1C357.7,179.7,356.9,179.5,356.2,179.2z"/> + </g> + <g> + <path class="st4" d="M365.5,165.8c-0.1,0.6-0.4,1-0.7,1.5c-0.2,0.2-0.3,0.4-0.6,0.6c-0.2,0.2-0.4,0.3-0.7,0.5 + c0.2-0.5,0.5-0.9,0.8-1.4C364.7,166.6,365.1,166.2,365.5,165.8z"/> + </g> + </g> + </g> + </g> + <g> + <g> + <path class="st22" d="M367,150c0.4,1,6.4,7.3,11.2,6.4c1.6-0.3,0.4-8.9,0.4-8.9l0.1-0.7l0.8-9.2l-11.4-5.4l-1.6-0.7 + c0,0-0.1,2.5-0.1,5.7c0,0.1,0,0.3,0,0.4c0,0.2,0,0.3,0,0.5c0,0.5,0,1,0,1.4s0,0.7,0,1.1c0,0.4,0,0.8,0,1.1 + C366.4,145.7,366.8,149.6,367,150z"/> + <path class="st4" d="M366.5,131.6c0,0-0.1,2.5-0.1,5.7c0,0.2,0,0.3,0,0.5s0,0.3,0,0.5c0,0.5,0,1,0,1.4s0,0.7,0,1.1 + c0,0.4,0,0.8,0,1.1c0,1.3,0.1,2.7,0.2,3.9c3.5,0.2,8.8-0.2,12.6-4l0.4-4.2l-11.4-5.4L366.5,131.6z"/> + </g> + <g> + <path class="st22" d="M359.9,121.1c-6,15.1,2.3,20.4,5.6,21.7c3,1.2,13.1,4.8,20.7-9.5c7.6-14.4,2.5-21.9-4.1-25 + C375.5,105.2,366,106,359.9,121.1z"/> + <g> + <path class="st4" d="M375.8,109.6c0,0-1.4,2.1-1.2,4c0.4,4,4.9,4.5,5.8,6.4c0.9,1.7-0.5,4.2,0.3,5.9c1,2.3,2.6,1.5,2.5,2.7 + c-0.1,1.3-0.7,5.3,0.7,6.3c1.3,1,17-21.7-3-27.7c0,0-2.4-2.2-7.3-1.4c-7,1.2-10.7,8.6-10.7,8.6s1.3,0.2,2.2-0.2 + c1.2-0.5,1.9-1,2.8-1.3c1.4-0.5,1.9,0.4,3.3-0.1C373.4,112.3,375.8,109.6,375.8,109.6z"/> + <path class="st4" d="M376.3,108.9c-0.6,0.9-1.2,1.8-1.6,2.8s-0.7,2.1-0.6,3.1c0.2,1,0.9,1.9,1.7,2.5c0.8,0.7,1.8,1.1,2.7,1.9 + c0.4,0.4,0.8,0.9,1,1.5s0.1,1.2,0.1,1.7c-0.1,1.1-0.3,2.2,0.1,3.1c0.4,1,1.2,1.7,2.3,2c1,0.3,2.2,0.4,3,1.2 + c-0.9-0.7-2-0.7-3.1-1s-2.1-1.1-2.5-2.1c-0.5-1.1-0.4-2.3-0.3-3.3c0.1-0.5,0.1-1.1-0.1-1.5c-0.1-0.5-0.5-0.9-0.9-1.2 + c-0.8-0.7-1.8-1.2-2.6-1.9c-0.4-0.4-0.8-0.8-1.1-1.3c-0.3-0.5-0.6-1-0.6-1.6c-0.1-1.2,0.3-2.3,0.8-3.2 + C375,110.6,375.6,109.7,376.3,108.9z"/> + <path class="st4" d="M375.6,109.6c-0.5,0.9-1.2,1.7-1.9,2.4c-0.7,0.7-1.7,1.3-2.7,1.5c-0.5,0.1-1.1,0.1-1.5,0.1 + c-0.5,0-1,0.1-1.3,0.3c-0.4,0.3-0.8,0.7-1.3,0.9c-0.5,0.2-1,0.3-1.5,0.3c0.5-0.1,1-0.2,1.4-0.5c0.4-0.2,0.7-0.6,1.1-1 + c0.5-0.4,1-0.5,1.5-0.5s1,0,1.5-0.1c0.9-0.2,1.8-0.7,2.6-1.3C374.2,111.1,374.9,110.4,375.6,109.6z"/> + </g> + <g> + <g> + <path class="st22" d="M382.7,132.1c0,0,4.9-3.8,6.7-1.9c1.8,1.9-2.8,8.1-5.7,8.3c-2.9,0.2-3.1-2.5-3.1-2.5L382.7,132.1z"/> + <path class="st4" d="M388,131.9C388.1,131.9,388.1,132,388,131.9c-2,0.3-3.5,1.6-4.7,3.2c0.7-0.5,1.6-0.7,2.3,0.3 + c0,0,0,0.1-0.1,0.1c-0.7-0.4-1.3-0.4-1.9,0c-0.5,0.3-0.9,0.8-1.3,1.2c-0.1,0.1-0.4,0-0.3-0.2l0,0 + C382.7,134.1,385.5,131.4,388,131.9z"/> + </g> + </g> + <g> + <path class="st4" d="M364.8,118.7c0.4,0.1,0.7,0.1,1.1,0.2s0.8,0.1,1.2-0.1c0.2-0.1,0.3-0.5,0.2-0.7c-0.2-0.5-0.7-0.7-1.2-0.8 + c-0.6-0.1-1,0-1.5,0.3S364.3,118.6,364.8,118.7z"/> + <path class="st4" d="M375,123.2c-0.3-0.2-0.6-0.4-1-0.6s-0.7-0.4-0.9-0.8c-0.1-0.2,0-0.6,0.2-0.7c0.5-0.3,1-0.1,1.5,0.2 + c0.5,0.3,0.8,0.6,1,1.2C376,123,375.4,123.4,375,123.2z"/> + <g> + <g> + <path class="st4" d="M371.3,126.1C371.3,126.1,371.4,126.2,371.3,126.1c-0.4,1.1-0.8,2.4,0,3.1v0.1 + C370.2,128.6,370.7,127,371.3,126.1z"/> + <path class="st4" d="M372.6,125.3c1.7,0.5,0.5,4-1.1,3.5C370,128.3,371.2,124.9,372.6,125.3z"/> + </g> + <path class="st4" d="M373.3,125.7c0.2,0.3,0.4,0.7,0.8,0.9c0.4,0.2,0.8-0.1,1.2-0.3c0,0,0.1,0,0,0.1 + c-0.2,0.7-0.7,1.2-1.4,1.1c-0.7-0.1-0.9-0.9-0.9-1.6C373,125.8,373.2,125.6,373.3,125.7z"/> + </g> + <g> + <g> + <path class="st4" d="M365.4,123.2c0,0-0.1,0-0.1,0.1c-0.3,1.1-0.9,2.3-2,2.3v0.1C364.5,125.9,365.2,124.3,365.4,123.2z"/> + <path class="st4" d="M364.8,121.8c-1.7-0.7-3,2.7-1.4,3.3C364.9,125.8,366.2,122.4,364.8,121.8z"/> + </g> + <path class="st4" d="M364,121.8c-0.3,0.1-0.7,0.3-1.1,0.2c-0.4-0.1-0.5-0.6-0.6-1c0,0,0,0-0.1,0c-0.3,0.6-0.3,1.4,0.3,1.8 + c0.5,0.3,1.2-0.1,1.6-0.7C364.2,121.9,364.2,121.7,364,121.8z"/> + </g> + <path class="st4" d="M368,134.4c-0.3,0.2-0.7,0.4-1.1,0.4c-0.4-0.1-0.8-0.4-1.1-0.6h-0.1c0.2,0.5,0.7,0.9,1.2,1 + C367.5,135.2,367.9,134.9,368,134.4C368.1,134.4,368.1,134.4,368,134.4z"/> + <g> + <path class="st4" d="M365,129c0,0-0.8,1.5-1.1,2.2c0,0.1,0.1,0.2,0.4,0.3l0,0c1.2,0.7,2.7,0.7,3.9-0.1c0.1-0.1,0-0.2-0.1-0.1 + c-1.2,0.4-2.4,0.2-3.6-0.2c0-0.2,1.4-2.5,1.3-2.6c-0.4-0.2-1.3-0.2-1.8-0.2c1.6-3.2,3.6-6.1,5.1-9.3c0.1-0.1-0.1-0.2-0.2-0.1 + c-2.4,2.9-4.2,6.5-5.9,9.7C362.9,129,364.6,129,365,129z"/> + </g> + </g> + </g> + </g> + <g> + <g> + <g> + <path class="st22" d="M417.2,172.9c0.4-6.9,0.3-16.7-1.7-19.2c-2.1-2.6-10-11.3-12.5-12.7s-13.4-8.2-15.9-7.4 + c-1.9,0.7-0.8,5.7,4.4,8.9c4.6,2.9,6.8,5.2,8.1,6.1c1.3,0.9,3.9,6.3,2.5,8.1c-0.8,1.1-4.6,1.9-6.6,0.4c-2-1.4-1.7-5.9-3.8-8.5 + c-2.1-2.6-6.6-3.2-7.1-2s0.9,2,2.3,6.5c1,2.9-0.2,9.2,2.3,14.4c1.2,2.6,3,9.2,3,9.2L417.2,172.9z"/> + <path class="st4" d="M389.8,146.4c-0.7-0.3-1.5-0.7-2-1.4c-0.2-0.3-0.3-0.6-0.3-1c0-0.2,0-0.4,0.1-0.6 + c0.1-0.2,0.2-0.4,0.3-0.5c0.1,0,0-0.1,0-0.1c-0.1,0.1-0.2,0.1-0.3,0.2c-0.1,0.1-0.1,0.1-0.2,0.2c-0.1,0.2-0.2,0.3-0.2,0.5 + c-0.1,0.4,0,0.8,0.2,1.2C387.9,145.9,388.8,146.3,389.8,146.4C389.8,146.5,389.8,146.4,389.8,146.4z"/> + <g> + <path class="st22" d="M415.5,153.7c-1.5-3.8-5.8-10.9-10.8-14.1c-3.4-2.1-17.3,1.6-17.4,4.1s2.1,2.9,5.3,3.2 + c1.2,0.1,7.8-0.9,8.6,0.6c1.1,2.2,1.8,8.9,1.8,8.9L415.5,153.7z"/> + <path class="st4" d="M387.8,142.8c2.1-2.3,5.8-3,9.4-3.4c0.1,0,0.1,0.1,0,0.1C396.3,139.6,390.3,141,387.8,142.8 + C387.8,142.9,387.8,142.8,387.8,142.8z"/> + </g> + <g> + <path class="st22" d="M415.5,153.7c-1.5-3.8-5.8-10.9-10.8-14.1c-3.4-2.1-14.9,3.8-15.1,6.3c-0.1,2.5,3,3.3,6.6,2.8 + c1.2-0.2,5.4-2.1,6.2-0.6c1.1,2.2,3.9,7.5,3.9,7.5L415.5,153.7z"/> + <path class="st4" d="M404.8,152.3c-0.2-0.6-0.3-0.8-0.6-1.4c-0.3-0.6-0.5-1.2-0.8-1.8c-0.3-0.5-0.5-1-0.9-1.4 + s-0.9-0.5-1.5-0.6c-1.2-0.1-2.4,0.4-3.6,0.8c-1.3,0.4-3.8,1-5.5,0.5c-0.5-0.1-1-0.3-1.3-0.7c-0.3-0.2-0.6-0.5-0.7-0.8 + c-0.5-1.5,0.7-2.8,1.9-3.7c2.2-1.6,5-2.6,7.6-3.3c0.6-0.2,1.3-0.3,2-0.5s1.5-0.3,2.3-0.2c1.2,0.2,3,1.9,3.6,2.4 + c0,0,0.1,0,0.1-0.1c-0.7-0.6-2.3-2.5-4.3-2.8c-0.7-0.1-1.5,0.1-2.2,0.3c-0.8,0.2-1.5,0.4-2.3,0.6c-1.5,0.4-2.9,0.9-4.3,1.5 + c-1.3,0.6-2.7,1.3-3.7,2.3c-0.9,0.9-1.4,2.3-0.9,3.5c0.4,1,1.5,1.5,2,1.6c0.5,0.2,1,0.3,1.6,0.3s2.7-0.2,3.6-0.3 + c1.2-0.2,2.3-0.8,3.5-0.9c0.6-0.1,1.2,0.1,1.6,0.4c0.4,0.3,0.7,0.9,1,1.3c0.6,1,1.1,1.7,1.6,2.8 + C404.8,152.6,404.9,152.6,404.8,152.3z"/> + </g> + <g> + <path class="st22" d="M416.5,157c-0.5-1.8-0.5-8.6-1.4-10.9c-0.9-2.3-5.3-10.4-8.1-10.6c-3.5-0.3-1.1,6.6,0.2,9.5 + c1.3,2.9,0.2,7.1,0.2,7.1L416.5,157z"/> + <path class="st4" d="M405.5,140.2c0.5,0.9,0.9,1.9,1.3,2.9c0.4,0.9,0.8,1.8,1,2.8s0.2,2,0.1,2.9c0,0.5-0.1,1-0.2,1.4 + c-0.1,0.5-0.2,1-0.3,1.6c0,0.1-0.1,0-0.1,0c0.1-0.9,0.2-1.9,0.2-2.9s-0.1-2-0.3-3C406.8,144,405.9,142.1,405.5,140.2 + C405.4,140.1,405.5,140.1,405.5,140.2z"/> + <path class="st4" d="M407.2,152.7c-0.1,1.7-0.9,3.2-1.8,4.6c-0.5,0.7-1,1.4-1.5,2c-0.6,0.6-1.2,1.2-1.8,1.7 + c-1.2,1.1-2.3,2.2-3.3,3.5c-0.9,1.3-1.6,2.8-2.2,4.3c0.2-1.6,0.7-3.3,1.6-4.7c0.8-1.5,2-2.7,3.2-3.8c1.3-1.1,2.3-2.2,3.3-3.5 + C405.6,155.6,406.6,154.3,407.2,152.7z"/> + </g> + </g> + </g> + <g> + <g> + <path class="st22" d="M403.9,210.5c-6.5-2.3-8.5-14.3-12.1-35.4c-0.6-3.7,21.1-21.2,22.8-17.6c2.2,4.6,5.6,28.3,5.2,34.5 + C419,204.2,411.4,213.2,403.9,210.5z"/> + </g> + </g> + <g> + <path class="st4" d="M391.8,175.1l1.6,8.6c0.6,2.8,1.1,5.7,1.8,8.5c0.6,2.8,1.3,5.6,2.1,8.4c0.4,1.4,0.9,2.8,1.5,4.1 + s1.2,2.6,2.3,3.7c-1.2-0.9-1.9-2.2-2.6-3.5c-0.6-1.3-1.2-2.7-1.7-4.1c-1-2.8-1.7-5.6-2.3-8.4c-0.6-2.8-1.2-5.7-1.6-8.6 + C392.4,180.9,392,178,391.8,175.1z"/> + </g> + </g> + <g> + <g> + <path class="st20" d="M382.3,152.2l-9.2,28.5c-0.4,0.8,0,1.6,0.9,1.6l15,1c0.8,0.1,1.8-0.6,2.2-1.4l9.2-28.5 + c0.4-0.8,0-1.6-0.9-1.6l-15-1C383.6,150.7,382.6,151.3,382.3,152.2z"/> + <path class="st19" d="M384.1,152.3l-9.2,28.5c-0.4,0.8,0,1.6,0.9,1.6l15,1c0.8,0.1,1.8-0.6,2.2-1.4l9.2-28.5 + c0.4-0.8,0-1.6-0.9-1.6l-15-1C385.4,150.8,384.4,151.4,384.1,152.3z"/> + <path class="st4" d="M388.1,153.9c-0.1,0.7-0.7,1.2-1.4,1.2c-0.7-0.1-1.2-0.7-1.2-1.4c0.1-0.7,0.7-1.2,1.4-1.2 + C387.6,152.5,388.1,153.2,388.1,153.9z"/> + </g> + <g> + <path class="st22" d="M327.6,208.6c4.3,2.3,14.2,1.7,33.4-11.4c3-2-6.3-27.9-9.5-25.8c-4.1,2.7-19.3,13.9-20.4,14.9 + C322.6,194.4,323,206.1,327.6,208.6z"/> + <g> + <path class="st22" d="M343.9,178.9c0,0,6-8.4,10.6-11.9c6.1-4.6,13.2-6.1,16.3-6.6c6.3-0.9,22.3,1.2,22.5,5.9 + c0.2,4.3-16,1.3-16,1.3s17,0.3,16.3,5.5s-19.3,0.6-19.3,0.6s17.5,0.7,15.9,5.9c-1.2,3.9-18.3,0.8-18.3,0.8s15,0.7,14,4.8 + c-1.2,4.5-17.1,2.6-17.1,2.6c-4.5,10-10.9,12.8-15.6,14.3C351.8,202.5,343.9,178.9,343.9,178.9z"/> + <g> + <path class="st4" d="M371.3,167.1c2,0,4-0.1,6,0.1c2,0.1,4,0.4,6,0.7c4.8,0.8,7.8,2.1,7.6,2c-4.4-1.4-11.6-2-13.6-2.2 + C375.3,167.6,373.3,167.3,371.3,167.1C371.2,167.2,371.3,167.1,371.3,167.1z"/> + <path class="st4" d="M370.6,174.3c2.6,0.1,5.1,0,7.7,0.2c2.5,0.2,4.9,0.6,7.5,0.9c0.2,0,0.1,0.1-0.1,0.1 + c-2.5-0.3-4.9-0.3-7.4-0.5C375.7,174.8,373.2,174.5,370.6,174.3L370.6,174.3z"/> + <path class="st4" d="M369,180.4c3.9-0.1,7.8,0.5,11.7,1.2c0.2,0,0.1,0.1-0.1,0.1c-3.9-0.5-6.9-0.9-11.6-1.2 + C368.9,180.5,368.9,180.4,369,180.4z"/> + </g> + </g> + <g> + <path class="st4" d="M347.6,174.1c-2.4,1.9-4.9,3.7-7.4,5.5l-3.8,2.7c-1.3,0.9-2.5,1.8-3.7,2.7c1.1-1.1,2.3-2,3.5-3 + s2.5-1.9,3.7-2.8C342.5,177.5,345,175.7,347.6,174.1z"/> + </g> + </g> + </g> + </g> + </g> +</g> +<g id="Character_1"> + <g> + <g> + <ellipse class="st1" cx="132.9" cy="141.3" rx="84.3" ry="84.3"/> + <g> + <path class="st24" d="M88.8,68.3c13.7-9.6,30.3-15.2,48.3-15.2c16.8,0,32.5,4.9,45.6,13.4c8.4,5.4,15.8,12.3,21.7,20.3 + c10.5,14,16.7,31.4,16.7,50.3c0,46.4-37.6,84.1-84.1,84.1c-21,0-40.3-7.7-55-20.5"/> + <path class="st24" d="M56.4,160.4c-2.1-7.4-3.3-15.2-3.3-23.3c0-20.2,7.1-38.8,19-53.3"/> + <path class="st24" d="M72.5,190.8c-4.8-5.7-8.8-12.1-11.9-19"/> + </g> + </g> + <g> + <g> + <g> + <path class="st25" d="M146.8,131.1c10.3,31.4,18.2,63.4,34.5,70.7c15.5,7,60.9-26.9,69.8-39.2c3-4.2-27.3-30-32.2-27.4 + c-9.2,5-27.3,22.7-29.8,21.7c-2.6-1-15-21.5-31.8-41C147.2,104.2,139.7,109.3,146.8,131.1z"/> + <g> + <g> + <path class="st25" d="M241,169.5c4.8-0.7,22.8-8.5,28.6-11c10-4.2,18.6-15,16.4-19.4c-2-4-11,6.5-11,6.5s14.9-11.2,12.2-17.2 + c-2-4.5-8.6,0.6-8.6,0.6s6.7-6.9,3.1-10.3c-2.9-2.8-17,8.5-17,8.5s13-12.4,7-15.8c-4-2.2-9.8,6.9-18,10.2 + c-0.7,0.3-7.9,2.6-15,4.9c-7.4,2.4-25.8,25.8-25.8,25.8L241,169.5z"/> + <path class="st4" d="M264.5,127.1c-4.7,3.4-8.3,4.7-11.6,6c-0.1,0,0,0.3,0.1,0.3c5.9-1.4,7.6-2.2,11.8-6.1 + C265,127.1,264.7,126.9,264.5,127.1z"/> + <path class="st4" d="M278.3,129c-7.9,6.9-12.5,9.1-22.4,12.4c-0.1,0-0.1,0.3,0.1,0.3c9.9-2.4,15.6-4.3,22.6-12.2 + C278.9,129.1,278.6,128.7,278.3,129z"/> + <path class="st4" d="M282.1,138.7c-7.3,6.2-11.6,7.9-20.7,10.3c-0.1,0-0.1,0.3,0.1,0.3c9.2-1.5,14.4-2.8,20.9-10.1 + C282.7,138.8,282.4,138.4,282.1,138.7z"/> + </g> + <g> + <path class="st25" d="M213,152.3c0,0,2.5-20.3,10.5-28.3c4-4,23.6-16.3,26.6-12.4c3.8,5-5.6,14.4-10.8,18.3 + c0,0,8.8,11.6,3.5,19.8C237.5,157.8,213,152.3,213,152.3z"/> + <path class="st4" d="M250.6,113.3c0.2,7.1-7,11.9-11.7,16.1c-0.4,0.3-0.2,0.7,0.1,1c3.4,5.1,6.6,13.3,4.2,19.3 + c-0.1,0.2,0.2,0.3,0.3,0.1c3.4-6.1,0.9-14.4-3.1-19.7C245.3,125.7,252.2,120.6,250.6,113.3 + C250.7,113.2,250.6,113.2,250.6,113.3z"/> + </g> + </g> + </g> + <g> + <g> + <path class="st8" d="M210.7,139.1l26.1,39.1c0,0-40,32-55.1,25.3c-15.1-6.6-31.8-52-36.8-80.7c-3.4-19.9,6.5-15.1,15.9-4 + s28.3,36.3,29.7,36.2C191.7,154.9,210.7,139.1,210.7,139.1z"/> + </g> + <g class="st26"> + <path class="st27" d="M210.7,139.1l26.1,39.1c0,0-40,32-55.1,25.3c-15.1-6.6-31.8-52-36.8-80.7c-3.4-19.9,6.5-15.1,15.9-4 + s28.3,36.3,29.7,36.2C191.7,154.9,210.7,139.1,210.7,139.1z"/> + </g> + <path class="st4" d="M225.5,182.1c-3.8-5.4-18.6-28.2-21.5-33.4c-0.2-0.4,0-0.6,0.2-0.2c11.8,16,18,27.9,21.5,33.5 + C225.8,182.1,225.6,182.2,225.5,182.1z"/> + <path class="st28" d="M191.7,204.5c-3.5,1.1-7.5,1.4-10.2,0.4c-5.4-2-9.7-10.6-9.7-10.6c-11.8-16-23-49.1-26.9-71.5 + c-1.9-11.1,0.3-14.5,4.3-13.4l0,0c0.5,0.3,1,0.6,1.5,1C162.1,133.8,182,181.9,191.7,204.5z"/> + </g> + </g> + <g> + <path class="st0" d="M168.5,217.7c-2.3,1.1-4.6,2-7,2.9c-8.3,3-17.1,4.7-26.3,5c-0.8,0-1.5,0-2.3,0c-23.8,0-45.3-9.9-60.6-25.7 + c10-30.9,28.1-73.3,53.4-92.4c0.9-0.7,1.9-1.2,2.9-1.7c7.3-3.2,17.1-0.7,21.8,2.5c0.4,0.3,1,1,1.7,1.9c3.2,4.6,8.4,16,9.9,26.2 + C163.4,146.2,167.6,196.3,168.5,217.7z"/> + <path class="st23" d="M135.2,225.5c-0.8,0-1.5,0-2.3,0c-23.8,0-45.3-9.9-60.6-25.7c-0.3-0.3-0.7-0.7-1-1 + c5.6-15.6,19.5-51.8,33.6-70c16.5-21.4,23.5-23.7,23.5-23.7s0,0.2,0.1,0.6c1,6.4,9.3,57.8,9.5,60 + C138.4,167.6,136.1,208.8,135.2,225.5z"/> + <path class="st8" d="M135.2,225.5c-0.8,0-1.5,0-2.3,0c-23.8,0-45.3-9.9-60.6-25.7c-0.3-0.3-0.7-0.7-1-1 + c5.6-15.6,19.5-51.8,33.6-70c16.5-21.4,23.5-23.7,23.5-23.7s0,0.2,0.1,0.6c1,6.4,9.3,57.8,9.5,60 + C138.4,167.6,136.1,208.8,135.2,225.5z"/> + <path class="st29" d="M135.2,225.5c-0.8,0-1.5,0-2.3,0c-23.8,0-45.3-9.9-60.6-25.7c-0.3-0.3-0.7-0.7-1-1 + c5.6-15.6,19.5-51.8,33.6-70c16.5-21.4,23.5-23.7,23.5-23.7s0,0.2,0.1,0.6c1,6.4,9.3,57.8,9.5,60 + C138.4,167.6,136.1,208.8,135.2,225.5z"/> + <path class="st8" d="M170.6,216.7c-0.7,0.4-1.4,0.7-2.1,1c-2.3,1.1-4.6,2-7,2.9c-1.1-17.6-3.3-54.1-3.4-56.5 + c-0.1-3-5.2-46.7-6.1-53.9c-0.1-0.6-0.1-1-0.1-1s7.8,13.3,10,24.5c1.4,7.1,4.6,45.1,5.1,48.6 + C167.5,184.8,169.4,204.4,170.6,216.7z"/> + <path class="st29" d="M170.6,216.7c-0.7,0.4-1.4,0.7-2.1,1c-2.3,1.1-4.6,2-7,2.9c-1.1-17.6-3.3-54.1-3.4-56.5 + c-0.1-3-5.2-46.7-6.1-53.9c-0.1-0.6-0.1-1-0.1-1s7.8,13.3,10,24.5c1.4,7.1,4.6,45.1,5.1,48.6 + C167.4,184.8,169.4,204.4,170.6,216.7z"/> + </g> + <g> + <g> + <path class="st8" d="M115.1,113.2c-30.9,29-60.3,82.7-53.8,95.8c7.2,14.6,48.7-25.4,47.4-27.6c-1-1.8,4.5-22.1,13.3-50.4 + C130.9,102.3,122.8,106,115.1,113.2z"/> + </g> + <g class="st26"> + <path class="st27" d="M115.1,113.2c-30.9,29-60.3,82.7-53.8,95.8c7.2,14.6,48.7-25.4,47.4-27.6c-1-1.8,4.5-22.1,13.3-50.4 + C130.9,102.3,122.8,106,115.1,113.2z"/> + </g> + <g> + <g> + <path class="st25" d="M61.2,208.2c5.9,9.1,22.7,11.4,64.5,21.3c5.8,1.4,26.4-36.9,20.3-38.6c-7.7-2.2-38-9.2-40.3-9.5 + C86.5,179.4,57.2,202,61.2,208.2z"/> + <g> + <path class="st25" d="M137.6,188.6c0,0,17.7,3.4,26.5,8c11.7,6.2,19.3,16.4,22.2,20.9c6.1,9.3,14.3,36.1,7,39.8 + c-6.6,3.4-13.7-24.4-13.7-24.4s11.9,27.2,3.2,29.8c-8.7,2.6-15.1-30.1-15.1-30.1s11.6,28.2,2.2,29.4 + c-7.1,1-14.5-28.4-14.5-28.4s9.8,24.3,2.5,25.6c-8,1.4-16.6-25.2-16.6-25.2c-19,0.2-28.1-7.5-34-13.8 + C106,218.7,137.6,188.6,137.6,188.6z"/> + <g> + <path class="st4" d="M176.2,223.3c1.5,3.1,3.1,6.3,4.3,9.6s2.3,6.6,3.3,9.9c2.2,8.2,2.4,13.8,2.3,13.4 + c-1-8-5.3-19.8-6.5-23.1S177.3,226.5,176.2,223.3C176.1,223.2,176.2,223.2,176.2,223.3z"/> + <path class="st4" d="M164.4,227.5c1.8,4.1,3.6,8.1,5.2,12.3c1.6,4.2,2.7,8.2,4,12.5c0.1,0.3-0.1,0.3-0.2-0.1 + c-1.4-4.2-3.1-8-4.6-12.1c-1.5-4.2-2.8-8.4-4.5-12.5C164.2,227.5,164.3,227.4,164.4,227.5z"/> + <path class="st4" d="M153.5,229.3c3,6.1,4.9,12.8,6.5,19.4c0.1,0.3-0.2,0.2-0.3-0.1c-2.1-6.5-3.6-11.6-6.5-19.2 + C153.3,229.3,153.5,229.2,153.5,229.3z"/> + </g> + </g> + </g> + <g> + <g> + <path class="st8" d="M145.6,187.2c0,0-32.1,43.5-32.6,43.5s-48.2-12-52-22.5c-3.8-10.5,27.7-28.3,44.7-26.9 + C122.6,182.7,145.6,187.2,145.6,187.2z"/> + <path class="st29" d="M145.6,187.2c0,0-32.1,43.5-32.6,43.5s-48.2-12-52-22.5c-3.8-10.5,27.7-28.3,44.7-26.9 + C122.6,182.8,145.6,187.2,145.6,187.2z"/> + <path class="st4" d="M130.2,186.7c-1.3,1.4-11.3,15.8-13.4,18.9c-2.1,3.2-10.8,16-12.7,19.4c-0.1,0.2,0.1,0.3,0.2,0.2 + c2.5-3,11.3-15.9,13.5-19.1c2.2-3.2,11.7-17.5,12.6-19.3C130.5,186.7,130.3,186.6,130.2,186.7z"/> + </g> + <g> + <path class="st4" d="M86.8,185.1c3.4-1.6,12.9-5.3,22-3.6c0.1,0,0.1,0.1,0,0.1c-7.5-0.4-18.5,2.3-21.9,3.6 + C86.8,185.2,86.7,185.1,86.8,185.1z"/> + <g> + <g> + <path class="st4" d="M143.6,189.9l1.9-2.7l0.1,0.1c-3.1-0.6-6.2-1.2-9.4-1.7c-3.1-0.6-6.3-1.1-9.4-1.6s-6.3-1-9.4-1.4 + s-6.3-0.8-9.4-1.1l-0.6-0.1l0.1-0.5c1.5-6.6,3-13.3,4.9-19.8c0.9-3.3,1.9-6.5,3-9.8c1.1-3.2,2.2-6.4,3.4-9.6 + c-1,3.2-2.1,6.5-3,9.7c-0.9,3.3-1.9,6.5-2.7,9.8c-1.7,6.6-3.3,13.2-4.7,19.8l-0.4-0.6c6.3,0.6,12.6,1.6,18.9,2.7 + c3.1,0.6,6.2,1.2,9.4,1.8c3.1,0.6,6.2,1.4,9.3,2.1h0.1l-0.1,0.1L143.6,189.9z"/> + </g> + <g> + <path class="st4" d="M114.1,156.4l1.1-2.3c0.4-0.8,0.8-1.5,1.2-2.2c0.8-1.5,1.7-2.9,2.6-4.3c-0.6,1.6-1.4,3.1-2.2,4.5 + c-0.4,0.7-0.8,1.5-1.3,2.2C115.1,155,114.7,155.7,114.1,156.4z"/> + </g> + </g> + <g> + <path class="st4" d="M66.6,213.7c3.7,1.7,7.6,3.3,11.4,4.9c3.8,1.6,7.7,3,11.5,4.4c3.9,1.4,7.8,2.7,11.7,3.9 + c3.9,1.3,7.9,2.3,11.9,3.5l-0.4,0.1c0.5-0.5,0.9-1.1,1.4-1.6s1-1,1.5-1.5c-0.4,0.6-0.8,1.2-1.2,1.8 + c-0.4,0.6-0.8,1.2-1.2,1.8l-0.1,0.2h-0.2c-2-0.3-4-0.9-6-1.5c-2-0.5-4-1.1-6-1.7c-3.9-1.2-7.8-2.6-11.7-4 + c-3.9-1.4-7.7-3-11.5-4.7C74,217.4,70.2,215.6,66.6,213.7z"/> + </g> + </g> + </g> + </g> + </g> + <g> + <g> + <g> + <g> + <path class="st25" d="M146.4,124.1c-5.8,0.4-14.1-9.8-16.7-17.3c-0.2-0.5,5-19.2,5.6-23.1c0.1-0.8,23,9.8,23,9.8 + s-3.7,7.6-4.7,14.3C153.4,108.3,152,123.7,146.4,124.1z"/> + </g> + <path class="st4" d="M158.3,93.4L158.3,93.4c-0.1,0.1-0.3,0.6-0.6,1.3c-0.5,1.2-1.4,3.2-2.2,5.5s-1.6,4.9-2,7.4 + c0,0.2,0,0.4-0.1,0.5v0.1c0,0.3-0.1,0.7-0.2,1.2c-0.7,0-1.5-0.1-2.4-0.3c-13-2.5-14.7-19.2-14.9-25.5c0.1,0,0.3,0.1,0.4,0.1 + c0.6,0.2,1.4,0.5,2.4,0.9c0.2,0.1,0.5,0.2,0.7,0.3c1.5,0.6,3.4,1.4,5.3,2.2c0.6,0.3,1.2,0.5,1.9,0.8c1.4,0.6,2.7,1.2,4,1.8 + c0.5,0.3,1.1,0.5,1.6,0.7c0.6,0.2,1.1,0.5,1.6,0.7c0.3,0.1,0.5,0.2,0.7,0.3c0.1,0.1,0.2,0.1,0.3,0.2c0.7,0.3,1.4,0.6,1.9,0.9 + c0.4,0.2,0.7,0.3,0.9,0.4C158,93.3,158.1,93.4,158.3,93.4C158.2,93.4,158.2,93.4,158.3,93.4L158.3,93.4z"/> + </g> + <g> + <g> + <path class="st19" d="M160.4,78.4c-0.5,5.5,3,10.4,7.8,10.8c4.8,0.5,9.2-3.6,9.7-9.2c0.5-5.5-3-10.4-7.8-10.8 + C165.3,68.8,161,72.9,160.4,78.4z"/> + <path class="st30" d="M157.6,78.5c-0.6,6.1,3.3,11.5,8.7,12s10.2-4.1,10.8-10.2s-3.3-11.5-8.7-12 + C163,67.8,158.1,72.4,157.6,78.5z"/> + </g> + <g> + <path class="st25" d="M137.9,56.5c-4.3,7.9-4.7,33.2,0.2,39.8c7.1,9.6,21.2,13.2,30,4.1c8.5-8.8,8.5-41.8,2.8-48 + C162.5,43.1,144.2,44.8,137.9,56.5z"/> + </g> + <g> + <g> + <path class="st4" d="M158.7,75.6c0-0.1-0.1,0.1-0.1,0.1c0,1.7-0.3,3.7-1.9,4.1v0.1C158.6,79.8,158.9,77.2,158.7,75.6z"/> + <path class="st4" d="M157.3,73.8c-2.7-0.3-3.2,5.1-0.7,5.5C159.1,79.5,159.5,74.1,157.3,73.8z"/> + </g> + <g> + <path class="st4" d="M168.5,76.7c0-0.1,0.1,0.1,0.1,0.2c-0.2,1.7-0.1,3.7,1.4,4.4v0.1C168.1,80.9,168,78.3,168.5,76.7z"/> + <path class="st4" d="M170.2,75.1c2.7,0,2.5,5.5,0,5.5C167.6,80.6,167.9,75.1,170.2,75.1z"/> + </g> + <path class="st4" d="M155.2,72.4c0.8,0,1.5-0.2,2.2-0.3c0.9-0.1,1.6-0.2,2.2-0.8c0.4-0.3,0.4-1,0.1-1.4 + c-0.7-0.9-1.8-1-2.8-0.8c-1.1,0.1-2,0.5-2.7,1.3C153.5,71.1,154.2,72.4,155.2,72.4z"/> + <path class="st4" d="M172.3,73.5c-0.7-0.2-1.4-0.5-2.1-0.7c-0.8-0.3-1.5-0.4-2-1.2c-0.3-0.4-0.2-1.1,0.2-1.4 + c0.8-0.7,1.9-0.6,2.9-0.3c1.1,0.3,1.8,0.9,2.4,1.8C174.3,72.6,173.3,73.8,172.3,73.5z"/> + <path class="st4" d="M154.5,91.1c0.4,0.4,0.7,1,1.3,1.2c0.6,0.1,1.3-0.1,1.9-0.2c0.1,0,0.1,0.1,0.1,0.1 + c-0.5,0.6-1.5,0.9-2.3,0.6c-0.7-0.2-1-0.9-1.1-1.7C154.4,91,154.5,91,154.5,91.1z"/> + <g> + <g> + <path class="st4" d="M157,86.3c0.8,1.6,2,2.6,3.5,3.1c0.7,0.2,1.4,0.3,2.1,0.4c0.1,0,0.3,0,0.4,0c0.1,0,0.2,0,0.4,0 + s0.3-0.2,0.4-0.3l0,0c0-0.1,0-0.1,0-0.2l0,0v-0.1c0.2-1.3,0.3-3.3,0.3-3.3c0.4,0.3,2.7,1.7,2.8,1c0.4-5.7,0.8-12,0-17.7 + c0-0.2-0.3-0.2-0.3,0c-0.6,5.4-0.2,10.9-0.7,16.4c-0.7-0.4-1.9-1.1-2.6-1.2c-0.2,0-0.2,3.9-0.3,4.4c0,0,0,0,0,0.1 + c-2.2,0-3.8-0.9-5.7-2.6C157,86,156.9,86.1,157,86.3z"/> + </g> + </g> + <g> + <path class="st4" d="M161.8,88.9c0,0-1.4,1.4-3,1.8c-0.6,0.1-1.2,0.1-1.9-0.1c-1.3-0.5-1.2-1.8-0.8-2.8 + c0.3-0.8,0.8-1.5,0.8-1.5S158.7,88.3,161.8,88.9z"/> + <path class="st31" d="M158.8,90.7c-0.6,0.1-1.2,0.1-1.9-0.1c-1.3-0.5-1.2-1.8-0.8-2.8C157.6,88.1,158.9,89.3,158.8,90.7z"/> + </g> + </g> + <path class="st4" d="M133.8,78c3.7,1.2,7.2-4.3,8.2-6.6c1-2.3,0.5-12.9,2.4-16.4s5.9-5.3,9-4.3s9.1,5.5,11.4,5.4 + c2.3-0.1,1.6-4.8,3.2-4.7c3.5,0.1,5.9,7.9,6.4,11.7c0,0,2.1-15.8-15.8-18.1c-16.3-2-21.9,9.1-23.5,14 + C132,68.3,133.8,78,133.8,78z"/> + <g> + <path class="st25" d="M139.3,77.4c0,0-4.1-8.9-8.1-7.6c-3.9,1.3-1.8,13.5,2.1,15.9c3.9,2.3,6.2-1.3,6.2-1.3L139.3,77.4z"/> + <path class="st4" d="M132,73.3C131.9,73.3,131.9,73.4,132,73.3c2.7,1.8,3.8,4.8,4.4,7.9c-0.7-1.3-1.8-2.1-3.4-1.3 + c-0.1,0,0,0.2,0.1,0.2c1.3,0,2.1,0.3,2.7,1.4c0.5,0.8,0.7,1.7,1,2.6c0.1,0.3,0.6,0.2,0.5-0.1c0,0,0,0,0-0.1 + C137.9,80.2,136,74.4,132,73.3z"/> + </g> + <g> + <g> + <polygon class="st30" points="154,93.7 146.1,92.1 138.8,86.1 139.7,84.9 146.7,90.7 154.3,92.3 "/> + <path class="st20" d="M153,92.7c0.3-2.3,6.3-2.7,5.9,0.7C158.5,96.9,152.7,95,153,92.7z"/> + </g> + <path class="st30" d="M135.5,71.2c0,0-0.2-11.8,3.6-18.2c4.2-7.1,19.1-12.5,29.6-4.2c0,0-16.2-4.7-25,4.9 + c-3.7,4.1-4.3,17.9-4.3,17.9L135.5,71.2z"/> + <path class="st30" d="M146.7,78.2c-0.2,6.2-4.8,11-10.2,10.8s-9.6-5.4-9.4-11.5c0.2-6.2,4.8-11,10.2-10.8 + C142.8,66.9,147,72,146.7,78.2z"/> + <path class="st19" d="M143.9,77.7c-0.2,5.5-4.3,9.9-9.2,9.7c-4.9-0.2-8.6-4.8-8.4-10.4c0.2-5.5,4.3-9.9,9.2-9.7 + C140.4,67.6,144.1,72.2,143.9,77.7z"/> + </g> + </g> + </g> + <g> + <g> + <path class="st0" d="M153.4,109.8l-7.9,13.4l-15.1-20.7l-5.9,5.1c0,0,13.1,31.3,13.4,30l7.7-11.4l7.2,9.8l2.5-21.6 + L153.4,109.8z"/> + <path class="st4" d="M154.7,125.3c0.3-3.6,0.7-7.2,0.8-10.8c0-0.1-0.2-0.2-0.2-0.1c-1.2,3.3-2.3,17-2.8,20.3l0,0 + c-0.3-0.4-6.8-8.7-6.8-8.6c-1.6,1.8-7.2,10.1-7.6,10.9c-2.1-5-10.1-23.1-12.7-27.9c-0.1-0.1-0.3-0.1-0.2,0.1 + c1.7,5.2,12.3,29.6,12.5,29.5c0.1,0.1,7.1-10.1,8.1-12.1c1,1.8,7.4,11,7.5,10.4C153.9,133.5,154.4,128.9,154.7,125.3z"/> + </g> + </g> + </g> + </g> + </g> +</g> +<g id="Speech_bubbles"> + <g> + <g> + <path class="st6" d="M238.7,64.2c-1.5,14.1-14.1,24.4-28.3,22.9c-5.7-0.6-10.8-3-14.7-6.6l-12.9,1.9l6.4-11.1 + c-1.6-3.8-2.2-8-1.8-12.4c1.5-14.1,14.1-24.4,28.3-22.9C229.9,37.4,240.2,50.1,238.7,64.2z"/> + <path class="st4" d="M238.7,64.2c-0.5,4.7-2.3,9.3-5.2,13c-0.7,1-1.5,1.8-2.3,2.7c-0.9,0.8-1.7,1.6-2.7,2.3 + c-1.9,1.4-4,2.6-6.2,3.5s-4.6,1.4-6.9,1.7c-1.2,0.1-2.4,0.2-3.6,0.1c-1.2,0-2.4-0.2-3.6-0.4c-4.7-0.9-9.2-3.1-12.7-6.3l0.3,0.1 + l-12.9,2L182,83l0.5-0.8l6.4-11.1v0.4c-3.1-7.3-2.4-16.1,1.6-22.9c2-3.4,4.8-6.4,8.1-8.6c3.3-2.2,7.1-3.6,11-4.1 + s7.9-0.2,11.6,1.1c3.7,1.3,7.1,3.4,9.9,6.1C236.7,48.3,239.5,56.4,238.7,64.2z M238.7,64.2c0.8-7.8-2.1-15.8-7.8-21.1 + c-2.8-2.7-6.2-4.7-9.9-5.9s-7.6-1.4-11.4-0.9c-3.8,0.6-7.5,2-10.6,4.2s-5.8,5.1-7.7,8.4s-3,7.1-3.3,10.9 + c-0.2,3.8,0.4,7.7,1.8,11.2l0.1,0.2l-0.1,0.2l-6.5,11.1l-0.5-0.7l12.9-1.8h0.2l0.1,0.1c3.4,3.2,7.7,5.4,12.3,6.3 + c1.2,0.2,2.3,0.4,3.5,0.4c1.2,0.1,2.3,0,3.5,0c2.3-0.2,4.7-0.6,6.9-1.5c2.2-0.8,4.3-1.9,6.2-3.3c1-0.7,1.8-1.5,2.7-2.3 + c0.8-0.9,1.7-1.7,2.3-2.7C236.4,73.5,238.1,68.9,238.7,64.2z"/> + </g> + <polygon class="st8" points="210.1,76.2 199.1,65.1 202.8,61.4 209.2,67.9 222.6,47 226.9,49.8 "/> + </g> + <g> + <g> + <path class="st6" d="M452.2,99.9c-1.5,14.1-14.1,24.4-28.3,22.9c-5.7-0.6-10.8-3-14.7-6.6l-12.9,1.9l6.4-11.1 + c-1.6-3.8-2.2-8-1.8-12.4c1.5-14.1,14.1-24.4,28.3-22.9C443.4,73.1,453.7,85.8,452.2,99.9z"/> + <path class="st4" d="M452.2,99.9c-0.5,4.7-2.3,9.3-5.2,13c-0.7,1-1.5,1.8-2.3,2.7c-0.9,0.8-1.7,1.6-2.7,2.3 + c-1.9,1.4-4,2.6-6.2,3.5s-4.6,1.4-6.9,1.7c-1.2,0.1-2.4,0.2-3.6,0.1c-1.2,0-2.4-0.2-3.6-0.4c-4.7-0.9-9.2-3.1-12.7-6.3l0.3,0.1 + l-12.9,2l-0.9,0.1l0.5-0.8l6.4-11.1v0.4c-3.1-7.3-2.4-16.1,1.6-22.9c2-3.4,4.8-6.4,8.1-8.6c3.3-2.2,7.1-3.6,11-4.1 + s7.9-0.2,11.6,1.1c3.7,1.3,7.1,3.4,9.9,6.1C450.2,84.1,453,92.2,452.2,99.9z M452.2,99.9c0.8-7.8-2.1-15.8-7.8-21.1 + c-2.8-2.7-6.2-4.7-9.9-5.9c-3.7-1.2-7.6-1.4-11.4-0.9c-3.8,0.6-7.5,2-10.6,4.2s-5.8,5.1-7.7,8.4c-1.9,3.3-3,7.1-3.3,10.9 + c-0.2,3.8,0.4,7.7,1.8,11.2l0.1,0.2l-0.1,0.2l-6.5,11.1l-0.5-0.7l12.9-1.8h0.2l0.1,0.1c3.4,3.2,7.7,5.4,12.3,6.3 + c1.1,0.2,2.3,0.4,3.5,0.4c1.2,0.1,2.3,0,3.5,0c2.3-0.2,4.7-0.6,6.9-1.5c2.2-0.8,4.3-1.9,6.2-3.3c1-0.7,1.8-1.5,2.7-2.3 + c0.8-0.9,1.7-1.7,2.3-2.7C449.9,109.2,451.6,104.6,452.2,99.9z"/> + </g> + <g> + <path class="st8" d="M428,100.8v2.7c0,1.2-0.9,2-2,2s-2-0.9-2-2v-4.3c0,0,0,0,0-0.1c0,0,0,0,0-0.1c0-1.1,1-2,2-2 + c2.6,0,4.7-2.1,4.7-4.7s-2.1-4.7-4.7-4.7c-1.7,0-3.2,0.9-4,2.3c-0.6,1-1.8,1.3-2.8,0.7c-1-0.6-1.3-1.8-0.7-2.8 + c1.5-2.6,4.3-4.3,7.5-4.3c4.8,0,8.8,3.9,8.8,8.7C434.8,96.5,431.9,99.9,428,100.8z M428,110v0.7c0,1.2-0.9,2-2,2s-2-0.9-2-2V110 + c0-1.1,1-2,2-2C427.2,107.9,428,108.8,428,110z"/> + </g> + </g> +</g> +</svg> diff --git a/public/images/footer/payment-method-new.png b/public/images/footer/payment-method-new.png Binary files differnew file mode 100644 index 00000000..5bc85bdf --- /dev/null +++ b/public/images/footer/payment-method-new.png diff --git a/public/images/footer/payment-method-new_old.png b/public/images/footer/payment-method-new_old.png Binary files differnew file mode 100644 index 00000000..066bc9f1 --- /dev/null +++ b/public/images/footer/payment-method-new_old.png diff --git a/public/images/footer/payment-method.png b/public/images/footer/payment-method.png Binary files differnew file mode 100644 index 00000000..258a2992 --- /dev/null +++ b/public/images/footer/payment-method.png diff --git a/public/images/footer/secures.png b/public/images/footer/secures.png Binary files differnew file mode 100644 index 00000000..b9ab4c44 --- /dev/null +++ b/public/images/footer/secures.png diff --git a/public/images/footer/shippings.png b/public/images/footer/shippings.png Binary files differnew file mode 100644 index 00000000..59c28ee3 --- /dev/null +++ b/public/images/footer/shippings.png diff --git a/public/images/remove.png b/public/images/remove.png Binary files differnew file mode 100644 index 00000000..2b4c3568 --- /dev/null +++ b/public/images/remove.png diff --git a/public/images/sni-logo.png b/public/images/sni-logo.png Binary files differnew file mode 100644 index 00000000..a5ade90c --- /dev/null +++ b/public/images/sni-logo.png diff --git a/public/robots.txt b/public/robots.txt index 205ec9f3..7ae1495b 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -22,8 +22,9 @@ Allow: /my/* Allow: /shop/search/* User-agent: * -Disallow: sentral.indoteknik.com/* -Disallow: erp.indoteknik.com/* +Disallow: /sentral.indoteknik.com/ +Disallow: /erp.indoteknik.com/ +Disallow: /development.indoteknik.com/ Sitemap: https://indoteknik.com/sitemap/products.xml Sitemap: https://indoteknik.com/sitemap/brands.xml diff --git a/src-migrate/common/components/skeleton/PageContentSkeleton.tsx b/src-migrate/common/components/skeleton/PageContentSkeleton.tsx deleted file mode 100644 index bf85cff1..00000000 --- a/src-migrate/common/components/skeleton/PageContentSkeleton.tsx +++ /dev/null @@ -1,19 +0,0 @@ -const PageContentSkeleton = () => { - return ( - <div className="animate-pulse grid gap-y-4"> - <div className="w-full h-10 bg-gray-300 rounded" /> - <div className="h-2" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-8/12 h-4 bg-gray-300 rounded" /> - <div className="h-2" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-full h-4 bg-gray-300 rounded" /> - <div className="w-1/2 h-4 bg-gray-300 rounded" /> - </div> - ) -} - -export default PageContentSkeleton
\ No newline at end of file diff --git a/src-migrate/common/components/elements/Seo.tsx b/src-migrate/components/seo.tsx index 2245663a..1e78ed4d 100644 --- a/src-migrate/common/components/elements/Seo.tsx +++ b/src-migrate/components/seo.tsx @@ -3,7 +3,7 @@ import React from 'react' import { NextSeo } from "next-seo" import { MetaTag, NextSeoProps } from 'next-seo/lib/types'; -const Seo = (props: NextSeoProps) => { +export const Seo = (props: NextSeoProps) => { const router = useRouter() const additionalMetaTags: MetaTag[] = [ @@ -29,6 +29,4 @@ const Seo = (props: NextSeoProps) => { additionalMetaTags={additionalMetaTags} /> ) -} - -export default Seo
\ No newline at end of file +}
\ No newline at end of file diff --git a/src-migrate/components/ui/image.tsx b/src-migrate/components/ui/image.tsx new file mode 100644 index 00000000..de0ad1da --- /dev/null +++ b/src-migrate/components/ui/image.tsx @@ -0,0 +1,34 @@ +import NextImage, { ImageProps as NextImageProps } from 'next/image'; +import { useState } from 'react'; + +import clsxm from '~/libs/clsxm'; + +type ImageProps = { + rounded?: string; +} & NextImageProps; + +const Image = (props: ImageProps) => { + const { alt, src, className, rounded, ...rest } = props; + const [isLoading, setLoading] = useState(true); + + return ( + <NextImage + className={clsxm( + 'duration-500 ease-in-out', + isLoading + ? 'scale-[1.02] blur-xl grayscale' + : 'scale-100 blur-0 grayscale-0', + rounded, + className + )} + src={src} + alt={alt} + loading='lazy' + quality={100} + onLoadingComplete={() => setLoading(false)} + unoptimized + {...rest} + /> + ); +}; +export default Image;
\ No newline at end of file diff --git a/src-migrate/common/components/elements/Modal.tsx b/src-migrate/components/ui/modal.tsx index 9c5c73ce..34e1d1c3 100644 --- a/src-migrate/common/components/elements/Modal.tsx +++ b/src-migrate/components/ui/modal.tsx @@ -1,13 +1,12 @@ -import { XMarkIcon } from "@heroicons/react/24/outline"; -import { AnimatePresence, motion } from "framer-motion" -import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import ReactDOM from "react-dom"; +import { useRouter } from "next/router"; +import { AnimatePresence, motion } from "framer-motion" import { useWindowSize } from "usehooks-ts"; -import clsxm from "~/common/libs/clsxm"; - +import { XMarkIcon } from "@heroicons/react/24/outline"; +import clsxm from "~/libs/clsxm"; -type Props = { +export interface ModalProps { children: React.ReactNode active: boolean title?: string @@ -16,14 +15,14 @@ type Props = { mode?: "mobile" | "desktop" } -const Modal = ({ +export const Modal = ({ children, active = false, title, close, className, mode -}: Props) => { +}: ModalProps) => { const router = useRouter() const { width } = useWindowSize() const [rendered, setRendered] = useState<boolean>(false) @@ -37,7 +36,7 @@ const Modal = ({ const modalClassNames = clsxm( "fixed bg-white max-h-[80vh] overflow-auto p-4 pt-0 z-[60] border-gray_r-6", { - "left-1/2 -translate-x-1/2 translate-y-1/2 bottom-1/2 w-11/12 md:w-1/4 lg:w-1/3 border rounded-xl": mode === 'desktop', + "left-1/2 -translate-x-1/2 translate-y-1/2 bottom-1/2 w-11/12 md:w-[500px] border rounded-xl": mode === 'desktop', "left-0 w-full border-t bottom-0 rounded-t-xl": mode === 'mobile' }, className @@ -72,8 +71,8 @@ const Modal = ({ {title} </div> {close && ( - <button className="rounded-full h-10 w-10 flex justify-center bg-white" type='button' onClick={close}> - <XMarkIcon className='w-5 stroke-2' /> + <button className="rounded-full h-10 w-10 flex justify-center items-center bg-white" type='button' onClick={close}> + <XMarkIcon className='w-5 h-5 ' /> </button> )} </div> @@ -85,6 +84,4 @@ const Modal = ({ </AnimatePresence>, document.querySelector('body')! ) -} - -export default Modal
\ No newline at end of file +}
\ No newline at end of file diff --git a/src-migrate/common/components/elements/ReCaptcha.tsx b/src-migrate/components/ui/re-captcha.tsx index 1bc31d90..e31aa1e3 100644 --- a/src-migrate/common/components/elements/ReCaptcha.tsx +++ b/src-migrate/components/ui/re-captcha.tsx @@ -2,16 +2,14 @@ import ReCAPTCHA, { ReCAPTCHAProps } from "react-google-recaptcha" const GOOGLE_RECAPTCHA_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE || '' -type Props = Omit<ReCAPTCHAProps, 'sitekey'> & { +export interface ReCaptchaProps extends Omit<ReCAPTCHAProps, 'sitekey'> { sitekey?: string; } -const ReCaptcha = (props: Props) => { +export const ReCaptcha = (props: ReCaptchaProps) => { const { sitekey, ...rest } = props return ( <ReCAPTCHA sitekey={sitekey || GOOGLE_RECAPTCHA_KEY} {...rest} /> ) } - -export default ReCaptcha
\ No newline at end of file diff --git a/src-migrate/components/ui/smooth-render.tsx b/src-migrate/components/ui/smooth-render.tsx new file mode 100644 index 00000000..5de3b28d --- /dev/null +++ b/src-migrate/components/ui/smooth-render.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import clsxm from '~/libs/clsxm' + +type Props = { + children: React.ReactNode, + isLoaded: boolean, + height: string, + duration?: string + delay?: string +} & React.HTMLProps<HTMLDivElement> + +const SmoothRender = (props: Props) => { + const { + children, + isLoaded, + height, + duration = 0, + delay = 0, + style, + className, + ...rest + } = props + + return ( + <div + className={clsxm('overflow-y-hidden transition-all', className)} + style={{ + opacity: isLoaded ? 1 : 0, + height: isLoaded ? height : 0, + transitionDuration: duration || '', + transitionDelay: delay || '', + ...style + }} + {...rest} + > + {isLoaded && children} + </div> + ) +} + +export default SmoothRender
\ No newline at end of file diff --git a/src-migrate/common/constants/menu.ts b/src-migrate/constants/menu.ts index 853da507..d1adebca 100644 --- a/src-migrate/common/constants/menu.ts +++ b/src-migrate/constants/menu.ts @@ -1,20 +1,20 @@ -import { SecondaryNavItemProps } from '../types/nav' +import { SecondaryNavItemProps } from '~/types/nav'; export const SECONDARY_MENU_ITEMS: SecondaryNavItemProps[] = [ { label: 'Semua Brand', - href: '/shop/brands' + href: '/shop/brands', }, { label: 'Ready Stock', - href: '/shop/search?orderBy=stock' + href: '/shop/search?orderBy=stock', }, { label: 'Blog Indoteknik', - href: 'https://blog.indoteknik.com/' + href: 'https://blog.indoteknik.com/', }, { label: 'Indoteknik TV', - href: '/video' - } -] + href: '/video', + }, +]; diff --git a/src-migrate/constants/promotion.ts b/src-migrate/constants/promotion.ts new file mode 100644 index 00000000..e6dfcc9b --- /dev/null +++ b/src-migrate/constants/promotion.ts @@ -0,0 +1,17 @@ +export const PROMO_CATEGORY = { + bundling: { + name: 'Bundling', + alias: 'Silat', + description: 'Kombinasi Kilat (SiLat)', + }, + discount_loading: { + name: 'Discount Loading', + alias: 'Barong', + description: 'Barang Borong (BaRong)', + }, + merchandise: { + name: 'Merchandise', + alias: 'Angklung', + description: 'Menang Langsung (Angklung)', + }, +}; diff --git a/src-migrate/constants/utm-source.ts b/src-migrate/constants/utm-source.ts new file mode 100644 index 00000000..95c03ed2 --- /dev/null +++ b/src-migrate/constants/utm-source.ts @@ -0,0 +1,8 @@ +export const UTM_SOURCE = { + '/': 'web.home', + '/shop/product/[slug]': 'web.other-product', + '/shop/search': 'web.search', + '/shop/brands/[slug]': 'web.brand', + '/shop/category/[slug]': 'web.category', + '/shop/cart': 'web.cart', +}; diff --git a/src-migrate/hooks/useUtmSource.ts b/src-migrate/hooks/useUtmSource.ts new file mode 100644 index 00000000..a72fae36 --- /dev/null +++ b/src-migrate/hooks/useUtmSource.ts @@ -0,0 +1,20 @@ +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { UTM_SOURCE } from '~/constants/utm-source'; + +const useUtmSource = () => { + const router = useRouter(); + const [source, setSource] = useState<string>(); + + useEffect(() => { + console.log(router.pathname); + + if (router.pathname) { + setSource(UTM_SOURCE[router.pathname as keyof typeof UTM_SOURCE]); + } + }, [router.pathname]); + + return source; +}; + +export default useUtmSource; diff --git a/src-migrate/common/libs/auth.ts b/src-migrate/libs/auth.ts index fb4e836a..86ce26e1 100644 --- a/src-migrate/common/libs/auth.ts +++ b/src-migrate/libs/auth.ts @@ -1,5 +1,5 @@ import { deleteCookie, getCookie, setCookie } from 'cookies-next'; -import { AuthProps } from '../types/auth'; +import { AuthProps } from '~/types/auth'; const COOKIE_KEY = 'auth'; diff --git a/src-migrate/common/libs/clsxm.ts b/src-migrate/libs/clsxm.ts index 0fc10317..0fc10317 100644 --- a/src-migrate/common/libs/clsxm.ts +++ b/src-migrate/libs/clsxm.ts diff --git a/src-migrate/libs/formatCurrency.ts b/src-migrate/libs/formatCurrency.ts new file mode 100644 index 00000000..d683acf3 --- /dev/null +++ b/src-migrate/libs/formatCurrency.ts @@ -0,0 +1,5 @@ +const formatCurrency = (value: number) => { + return Math.round(value).toLocaleString('id-ID'); +}; + +export default formatCurrency; diff --git a/src-migrate/libs/formatNumber.ts b/src-migrate/libs/formatNumber.ts new file mode 100644 index 00000000..da243418 --- /dev/null +++ b/src-migrate/libs/formatNumber.ts @@ -0,0 +1,8 @@ +export const formatToShortText = (number: number) => { + if (number > 1000) { + return `${Math.floor(number / 1000)}rb+`; + } else if (number > 100) { + return `${Math.floor(number / 100) * 100}+`; + } + return number.toString(); +}; diff --git a/src-migrate/common/libs/odooApi.ts b/src-migrate/libs/odooApi.ts index 2dbc18d3..9482542b 100644 --- a/src-migrate/common/libs/odooApi.ts +++ b/src-migrate/libs/odooApi.ts @@ -1,7 +1,7 @@ import axios, { AxiosRequestConfig, Method } from 'axios'; import { getCookie, setCookie } from 'cookies-next'; import { getAuth } from './auth'; -import { AuthApiProps, AuthProps } from '../types/auth'; +import { AuthApiProps } from '~/types/auth'; const ODOO_HOST = process.env.NEXT_PUBLIC_ODOO_API_HOST as string; diff --git a/src-migrate/libs/slug.ts b/src-migrate/libs/slug.ts new file mode 100644 index 00000000..5ab3b3dd --- /dev/null +++ b/src-migrate/libs/slug.ts @@ -0,0 +1,34 @@ +import { toTitleCase } from './toTitleCase'; + +export const createSlug = ( + prefix: string, + name: string, + id: string, + withHost = false +) => { + const cleanName = name + .trim() + .replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-') + .toLowerCase(); + + let slug = `${cleanName}-${id}`; + const splitSlug = slug.split('-'); + const filterSlug = splitSlug.filter((x) => x !== ''); + + slug = `${prefix}${filterSlug.join('-')}`; + + if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug; + + return slug; +}; + +export const getIdFromSlug = (slug: string) => { + let id = slug.split('-'); + return id[id.length - 1]; +}; + +export const getNameFromSlug = (slug: string) => { + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +}; diff --git a/src-migrate/libs/toTitleCase.ts b/src-migrate/libs/toTitleCase.ts new file mode 100644 index 00000000..dad66813 --- /dev/null +++ b/src-migrate/libs/toTitleCase.ts @@ -0,0 +1,5 @@ +export const toTitleCase = (val: string) => { + return val.replace(/\w\S*/g, function (txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); +}; diff --git a/src-migrate/libs/whatsappUrl.ts b/src-migrate/libs/whatsappUrl.ts new file mode 100644 index 00000000..a3fcf8ad --- /dev/null +++ b/src-migrate/libs/whatsappUrl.ts @@ -0,0 +1,48 @@ +import { getAuth } from './auth'; + +const TEMPLATES = { + default: 'Bisa tolong bantu kebutuhan saya?', + product: + 'Saya mencari barang berikut:\n\n{{url}}\n\n```Brand: {{manufacture}}\nName: {{productName}}```', +}; + +interface WhatsappUrlProps { + template: keyof typeof TEMPLATES; + payload: any; + greeting?: boolean; + needLogin?: boolean; + fallbackUrl?: string; +} + +export const whatsappUrl = ({ + template, + payload, + greeting = true, + needLogin = true, + fallbackUrl, +}: WhatsappUrlProps) => { + const auth = getAuth(); + + let greetingText = ''; + + if (needLogin && !auth) { + return fallbackUrl + ? `/login?next=${encodeURIComponent(fallbackUrl)}` + : '/login'; + } + + let result = TEMPLATES[template].replace( + /{{(.*?)}}/g, + (match, key) => payload[key] || '' + ); + + if (greeting && typeof auth === 'object') { + greetingText = `Halo Indoteknik.com, Saya ${auth.name} `; + if (auth.parentName) greetingText += `dari ${auth.parentName}`; + greetingText += '.\n\n'; + + result = greetingText + result; + } + + return `https://wa.me/6281717181922?text=${encodeURIComponent(result)}`; +}; diff --git a/src-migrate/modules/account-activation/components/FormEmail.tsx b/src-migrate/modules/account-activation/components/FormEmail.tsx index ec300ba4..f7925481 100644 --- a/src-migrate/modules/account-activation/components/FormEmail.tsx +++ b/src-migrate/modules/account-activation/components/FormEmail.tsx @@ -3,9 +3,9 @@ import Link from "next/link" import { useRouter } from "next/router" import { ChangeEvent, useEffect, useState } from "react" import { useMutation } from "react-query" -import Modal from "~/common/components/elements/Modal" -import { useRegisterStore } from "~/common/stores/useRegisterStore" -import { ActivationReqProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { useRegisterStore } from "~/modules/register/stores/useRegisterStore" +import { ActivationReqProps } from "~/types/auth" import { activationReq } from "~/services/auth" const FormEmail = () => { diff --git a/src-migrate/modules/account-activation/components/FormOTP.tsx b/src-migrate/modules/account-activation/components/FormOTP.tsx index 6815a088..cf4da2db 100644 --- a/src-migrate/modules/account-activation/components/FormOTP.tsx +++ b/src-migrate/modules/account-activation/components/FormOTP.tsx @@ -3,9 +3,9 @@ import { useRouter } from "next/router" import { useEffect, useState } from "react" import { useMutation } from "react-query" import { useCountdown } from "usehooks-ts" -import Modal from '~/common/components/elements/Modal' -import { setAuth } from "~/common/libs/auth" -import { ActivationOtpProps, ActivationReqProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { setAuth } from "~/libs/auth" +import { ActivationOtpProps, ActivationReqProps } from "~/types/auth" import { activationReq, activationUserOTP } from "~/services/auth" const FormOTP = () => { diff --git a/src-migrate/modules/account-activation/components/FormToken.tsx b/src-migrate/modules/account-activation/components/FormToken.tsx index b68b244f..2835ec0e 100644 --- a/src-migrate/modules/account-activation/components/FormToken.tsx +++ b/src-migrate/modules/account-activation/components/FormToken.tsx @@ -4,10 +4,10 @@ import { useEffect, useState } from "react" import Link from "next/link" import { useMutation } from "react-query" -import Modal from "~/common/components/elements/Modal" -import { ActivationTokenProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { ActivationTokenProps } from "~/types/auth" import { activationUserToken } from "~/services/auth" -import { setAuth } from "~/common/libs/auth" +import { setAuth } from "~/libs/auth" const FormToken = () => { const router = useRouter() diff --git a/src-migrate/modules/account-activation/index.tsx b/src-migrate/modules/account-activation/index.tsx index 97c96953..c6e2c683 100644 --- a/src-migrate/modules/account-activation/index.tsx +++ b/src-migrate/modules/account-activation/index.tsx @@ -1,4 +1,3 @@ -import { useRouter } from "next/router" import FormToken from "./components/FormToken" import FormEmail from "./components/FormEmail" import FormOTP from "./components/FormOTP" diff --git a/src-migrate/modules/cart/components/CartSummaryMobile.tsx b/src-migrate/modules/cart/components/CartSummaryMobile.tsx new file mode 100644 index 00000000..d9f72e0e --- /dev/null +++ b/src-migrate/modules/cart/components/CartSummaryMobile.tsx @@ -0,0 +1,111 @@ +import style from '../styles/summary.module.css'; + +import React, { useState } from 'react'; +import formatCurrency from '~/libs/formatCurrency'; +import clsxm from '~/libs/clsxm'; +import { Button, Skeleton } from '@chakra-ui/react'; +import _ from 'lodash'; +import { ChevronDownIcon } from '@heroicons/react/24/outline'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import useDevice from '@/core/hooks/useDevice'; + +type Props = { + total?: number; + discount?: number; + subtotal?: number; + tax?: number; + shipping?: number; + grandTotal?: number; + isLoaded: boolean; +}; + +const CartSummaryMobile = ({ + total, + discount, + subtotal, + tax, + shipping, + grandTotal, + isLoaded = false, +}: Props) => { + const [showPopup, setShowPopup] = useState(false); + return ( + <> + <BottomPopup + className=' !h-[35%]' + title='Ringkasan Pensanan' + active={showPopup} + close={() => setShowPopup(false)} + > + <div className='mt-4'> + <div className='flex flex-col gap-y-3'> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Belanja</span> + <span className={style.value}> + Rp {formatCurrency(subtotal || 0)} + </span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Diskon</span> + <span className={clsxm(style.value, style.discount)}> + - Rp {formatCurrency(discount || 0)} + </span> + </Skeleton> + + <div className={style.divider} /> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Subtotal</span> + <span className={style.value}> + Rp {formatCurrency(total || 0)} + </span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Tax 11%</span> + <span className={style.value}>Rp {formatCurrency(tax || 0)}</span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Biaya Kirim</span> + <span className={style.value}> + Rp {formatCurrency(shipping || 0)} + </span> + </Skeleton> + + <div className={style.divider} /> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={clsxm(style.label, style.grandTotal)}> + Grand Total + </span> + <span className={style.value}> + Rp {formatCurrency(grandTotal || 0)} + </span> + </Skeleton> + </div> + </div> + </BottomPopup> + <div className='flex flex-col gap-y-3'> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={clsxm(style.label, style.grandTotal)}> + Grand Total + </span> + <button + onClick={() => setShowPopup(true)} + className='bg-gray-300 w-6 h-6 items-center justify-center cursor-pointer hover:bg-red-400 md:hidden ' + > + <ChevronDownIcon className='h-6 w-6 text-white' /> + </button> + </Skeleton> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.value}> + Rp {formatCurrency(grandTotal || 0)} + </span> + </Skeleton> + </div> + </> + ); +}; + +export default CartSummaryMobile; diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx new file mode 100644 index 00000000..6ded6373 --- /dev/null +++ b/src-migrate/modules/cart/components/Item.tsx @@ -0,0 +1,156 @@ +import style from '../styles/item.module.css' + +import { Skeleton, SkeletonProps, Tooltip } from '@chakra-ui/react' +import { InfoIcon } from 'lucide-react' +import Image from 'next/image' +import Link from 'next/link' + +import { PROMO_CATEGORY } from '~/constants/promotion' +import formatCurrency from '~/libs/formatCurrency' +import { createSlug } from '~/libs/slug' +import { CartItem as CartItemProps } from '~/types/cart' + +import CartItemAction from './ItemAction' +import CartItemPromo from './ItemPromo' +import CartItemSelect from './ItemSelect' + +type Props = { + item: CartItemProps + editable?: boolean +} + +const CartItem = ({ item, editable = true }: Props) => { + return ( + <div className={style.wrapper}> + {item.cart_type === 'promotion' && ( + <div className={style.header}> + {item.promotion_type?.value && ( + <Tooltip label={PROMO_CATEGORY[item.promotion_type?.value].description} placement="top" bgColor='red.600' p={2} rounded={6}> + <div className={style.badgeType}> + Paket {PROMO_CATEGORY[item.promotion_type?.value].alias} + <InfoIcon size={14} /> + </div> + </Tooltip> + )} + <div className='w-2' /> + <div> + Selamat! Pembelian anda lebih hemat {' '} + <span className={style.savingAmt}> + Rp{formatCurrency((item.package_price || 0) * item.quantity - item.subtotal)} + </span> + </div> + </div> + )} + + <div className={style.mainProdWrapper}> + {editable && <CartItemSelect item={item} />} + <div className='w-4' /> + + <CartItem.Image item={item} /> + + <div className={style.details}> + <CartItem.Name item={item} /> + + <div className='mt-2 flex justify-between w-full'> + <div className='flex flex-col gap-y-1'> + {item.cart_type === 'promotion' && ( + <div className={style.discPriceSection}> + <span className={style.priceBefore}> + Rp {formatCurrency((item.package_price || 0))} + </span> + <span className={style.price}> + Rp {formatCurrency(item.price.price)} + </span> + </div> + )} + + {item.cart_type === 'product' && ( + <div className={style.discPriceSection}> + {item.price.discount_percentage > 0 && ( + <span className={style.priceBefore}> + Rp {formatCurrency((item.price.price || 0))} + </span> + )} + + <div className={style.price}> + {item.price.price_discount > 0 && `Rp ${formatCurrency(item.price.price_discount)}`} + {item.price.price_discount === 0 && '-'} + </div> + </div> + )} + + <div>{item.cart_type === 'product' && item.code}</div> + <div>{Math.round(item.weight * 10) / 10} Kg</div> + </div> + + {editable && <CartItemAction item={item} />} + {!editable && <div className={style.quantity}>{item.quantity}</div>} + </div> + </div> + + </div> + + <div className="flex flex-col"> + {item.products?.map((product) => <CartItemPromo key={product.id} product={product} />)} + {item.free_products?.map((product) => <CartItemPromo key={product.id} product={product} />)} + </div> + </div> + ) +} + +CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { + const image = item?.image || item?.parent?.image + + return ( + <> + {item.cart_type === 'promotion' && ( + <div className={style.image}> + {image && <Image src={image} alt={item.name} width={128} height={128} />} + {!image && <div className={style.noImage}>No Image</div>} + </div> + )} + + {item.cart_type === 'product' && ( + <Link + href={createSlug('/shop/product/', item.parent.name, item.parent.id.toString())} + className={style.image} + > + {image && <Image src={image} alt={item.name} width={128} height={128} />} + {!image && <div className={style.noImage}>No Image</div>} + </Link> + )} + </> + ) +} + +CartItem.Name = function CartItemName({ item }: { item: CartItemProps }) { + return ( + <> + {item.cart_type === 'promotion' && ( + <div className={style.name}>{item.name}</div> + )} + + {item.cart_type === 'product' && ( + <Link + href={createSlug('/shop/product/', item.parent.name, item.parent.id.toString())} + className={style.name} + > + {item.name} + </Link> + )} + </> + ) +} + +CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: number }) { + return Array.from({ length: props.count }).map((_, index) => ( + <Skeleton key={index} + height='100px' + width='100%' + rounded='md' + {...props} + /> + )) +} + +export default CartItem
\ No newline at end of file diff --git a/src-migrate/modules/cart/components/ItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx new file mode 100644 index 00000000..e73d507b --- /dev/null +++ b/src-migrate/modules/cart/components/ItemAction.tsx @@ -0,0 +1,111 @@ +import style from '../styles/item-action.module.css' + +import React, { useEffect, useState } from 'react' + +import { Spinner, Tooltip } from '@chakra-ui/react' +import { MinusIcon, PlusIcon, Trash2Icon } from 'lucide-react' + +import { CartItem } from '~/types/cart' +import { getAuth } from '~/libs/auth' +import { deleteUserCart, upsertUserCart } from '~/services/cart' + +import { useDebounce } from 'usehooks-ts' +import { useCartStore } from '../stores/useCartStore' + + +type Props = { + item: CartItem +} + +const CartItemAction = ({ item }: Props) => { + const auth = getAuth() + + const [isLoadDelete, setIsLoadDelete] = useState<boolean>(false) + const [isLoadQuantity, setIsLoadQuantity] = useState<boolean>(false) + + const [quantity, setQuantity] = useState<number>(item.quantity) + + const { loadCart } = useCartStore() + + const limitQty = item.limit_qty?.transaction || 0 + + const handleDelete = async () => { + if (typeof auth !== 'object') return + + setIsLoadDelete(true) + await deleteUserCart(auth.id, [item.cart_id]) + await loadCart(auth.id) + setIsLoadDelete(false) + } + + const decreaseQty = () => { setQuantity((quantity) => quantity -= 1) } + const increaseQty = () => { setQuantity((quantity) => quantity += 1) } + const debounceQty = useDebounce(quantity, 1000) + useEffect(() => { + if (isNaN(debounceQty)) setQuantity(1) + if (limitQty > 0 && debounceQty > limitQty) setQuantity(limitQty) + }, [debounceQty, limitQty]) + + useEffect(() => { + const updateCart = async () => { + if (typeof auth !== 'object' || isNaN(debounceQty)) return + + setIsLoadQuantity(true) + await upsertUserCart({ + userId: auth.id, + type: item.cart_type, + id: item.id, + qty: debounceQty, + selected: item.selected, + }) + await loadCart(auth.id) + setIsLoadQuantity(false) + } + updateCart() + //eslint-disable-next-line react-hooks/exhaustive-deps + }, [debounceQty]) + + return ( + <div className={style.actionSection}> + <button className={style.deleteButton} onClick={handleDelete} disabled={isLoadDelete}> + {isLoadDelete && <Spinner size='xs' />} + {!isLoadDelete && <Trash2Icon size={16} />} + </button> + + <div className={style.quantitySection}> + {isLoadQuantity && ( + <div className={style.quantityLoading}> + <Spinner size='sm' /> + </div> + )} + + <button + className={style.quantityControl} + onClick={decreaseQty} + disabled={quantity <= 1} + > + <MinusIcon size={16} /> + </button> + + <input + type='number' + className={style.quantity.toString()} + onChange={(e) => setQuantity(parseInt(e.target.value))} + value={quantity} + /> + + <Tooltip label={limitQty > 0 ? `Max. ${limitQty}` : ''}> + <button + className={style.quantityControl} + onClick={increaseQty} + disabled={limitQty > 0 && quantity >= limitQty} + > + <PlusIcon size={16} /> + </button> + </Tooltip> + </div> + </div> + ) +} + +export default CartItemAction
\ No newline at end of file diff --git a/src-migrate/modules/cart/components/ItemPromo.tsx b/src-migrate/modules/cart/components/ItemPromo.tsx new file mode 100644 index 00000000..878e17ac --- /dev/null +++ b/src-migrate/modules/cart/components/ItemPromo.tsx @@ -0,0 +1,44 @@ +import style from '../styles/item-promo.module.css' + +import Image from 'next/image' +import Link from 'next/link' +import { createSlug } from '~/libs/slug' + +import { CartProduct } from '~/types/cart' + +type Props = { + product: CartProduct +} + +const CartItemPromo = ({ product }: Props) => { + return ( + <div key={product.id} className={style.wrapper}> + <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className={style.imageWrapper}> + {product?.image && <Image src={product.image} alt={product.name} width={128} height={128} className={style.image} />} + </Link> + + <div className={style.details}> + <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className={style.name}> + {product.display_name} + </Link> + + <div className='flex w-full'> + <div className="flex flex-col"> + <div className={style.code}>{product.code}</div> + <div> + <span className={style.weightLabel}>Berat Barang: </span> + <span>{product.package_weight} Kg</span> + </div> + </div> + + <div className={style.quantity}> + {product.qty} + </div> + </div> + </div> + + </div> + ) +} + +export default CartItemPromo
\ No newline at end of file diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx new file mode 100644 index 00000000..b904a1de --- /dev/null +++ b/src-migrate/modules/cart/components/ItemSelect.tsx @@ -0,0 +1,54 @@ +import { Checkbox, Spinner } from '@chakra-ui/react' +import React, { useState } from 'react' + +import { getAuth } from '~/libs/auth' +import { CartItem } from '~/types/cart' +import { upsertUserCart } from '~/services/cart' + +import { useCartStore } from '../stores/useCartStore' + +type Props = { + item: CartItem +} + +const CartItemSelect = ({ item }: Props) => { + const auth = getAuth() + const { loadCart } = useCartStore() + + const [isLoad, setIsLoad] = useState<boolean>(false) + + const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => { + if (typeof auth !== 'object') return + + setIsLoad(true) + await upsertUserCart({ + userId: auth.id, + type: item.cart_type, + id: item.id, + qty: item.quantity, + selected: e.target.checked + }) + await loadCart(auth.id) + setIsLoad(false) + } + + return ( + <div className='w-6 my-auto'> + {isLoad && ( + <Spinner className='my-auto' size='sm' /> + )} + + {!isLoad && ( + <Checkbox + borderColor='gray.600' + colorScheme='red' + size='lg' + isChecked={item.selected} + onChange={handleChange} + /> + )} + </div> + ) +} + +export default CartItemSelect
\ No newline at end of file diff --git a/src-migrate/modules/cart/components/Summary.tsx b/src-migrate/modules/cart/components/Summary.tsx new file mode 100644 index 00000000..2e55c8df --- /dev/null +++ b/src-migrate/modules/cart/components/Summary.tsx @@ -0,0 +1,75 @@ +import style from '../styles/summary.module.css' + +import React from 'react' +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' +import { Skeleton } from '@chakra-ui/react' +import _ from 'lodash' + +type Props = { + total?: number + discount?: number + subtotal?: number + tax?: number + shipping?: number + grandTotal?: number + isLoaded: boolean +} + +const CartSummary = ({ + total, + discount, + subtotal, + tax, + shipping, + grandTotal, + isLoaded = false, +}: Props) => { + return ( + <> + <div className='text-h-sm font-medium'>Ringkasan Pesanan</div> + + <div className="h-6" /> + + <div className='flex flex-col gap-y-3'> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Belanja</span> + <span className={style.value}>Rp {formatCurrency(subtotal || 0)}</span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Diskon</span> + <span className={clsxm(style.value, style.discount)}>- Rp {formatCurrency(discount || 0)}</span> + </Skeleton> + + <div className={style.divider} /> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Subtotal</span> + <span className={style.value}>Rp {formatCurrency(total || 0)}</span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Tax 11%</span> + <span className={style.value}>Rp {formatCurrency(tax || 0)}</span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Biaya Kirim</span> + <span className={style.value}>Rp {formatCurrency(shipping || 0)}</span> + </Skeleton> + + <div className={style.divider} /> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={clsxm(style.label, style.grandTotal)}> + Grand Total + </span> + <span className={style.value}>Rp {formatCurrency(grandTotal || 0)}</span> + </Skeleton> + </div> + </> + ) +} + +export default CartSummary
\ No newline at end of file diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts new file mode 100644 index 00000000..3d9a0aed --- /dev/null +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -0,0 +1,64 @@ +import { create } from 'zustand'; +import { CartProps } from '~/types/cart'; +import { getUserCart } from '~/services/cart'; + +type State = { + cart: CartProps | null; + isLoadCart: boolean; + summary: { + subtotal: number; + discount: number; + total: number; + tax: number; + grandTotal: number; + }; +}; + +type Action = { + loadCart: (userId: number) => Promise<void>; +}; + +export const useCartStore = create<State & Action>((set, get) => ({ + cart: null, + isLoadCart: false, + summary: { + subtotal: 0, + discount: 0, + total: 0, + tax: 0, + grandTotal: 0, + }, + loadCart: async (userId) => { + if (get().isLoadCart === true) return; + + set({ isLoadCart: true }); + const cart: CartProps = (await getUserCart(userId)) as CartProps; + set({ cart }); + set({ isLoadCart: false }); + + const summary = computeSummary(cart); + set({ summary }); + }, +})); + +const computeSummary = (cart: CartProps) => { + let subtotal = 0; + let discount = 0; + for (const item of cart.products) { + if (!item.selected) continue; + + let price = 0; + if (item.cart_type === 'promotion') + price = (item?.package_price || 0) * item.quantity; + else if (item.cart_type === 'product') + price = item.price.price * item.quantity; + + subtotal += price; + discount += price - item.price.price_discount * item.quantity; + } + let total = subtotal - discount; + let tax = Math.round(total * 0.11); + let grandTotal = total + tax; + + return { subtotal, discount, total, tax, grandTotal }; +}; diff --git a/src-migrate/modules/cart/styles/item-action.module.css b/src-migrate/modules/cart/styles/item-action.module.css new file mode 100644 index 00000000..e4db7fa5 --- /dev/null +++ b/src-migrate/modules/cart/styles/item-action.module.css @@ -0,0 +1,32 @@ +.actionSection { + @apply flex ml-auto h-fit my-auto; +} + +.deleteButton { + @apply bg-red-100 disabled:bg-gray-100 + text-red-700 disabled:text-gray-500 + hover:bg-red-200 + disabled:cursor-not-allowed + transition-all + p-2.5 rounded; +} + +.quantitySection { + @apply relative flex border border-gray-300 rounded ml-4 items-center text-red-700; +} + +.quantityLoading { + @apply absolute flex items-center justify-center text-white rounded w-full h-full bg-gray-900/50 z-10; +} + +.quantityControl { + @apply h-full w-8 flex items-center justify-center hover:bg-gray-100 + disabled:text-gray-500 + disabled:bg-transparent + disabled:cursor-not-allowed + transition; +} + +.quantity { + @apply text-gray-900 font-medium max-w-[28px] outline-none text-center; +} diff --git a/src-migrate/modules/cart/styles/item-promo.module.css b/src-migrate/modules/cart/styles/item-promo.module.css new file mode 100644 index 00000000..15bf8146 --- /dev/null +++ b/src-migrate/modules/cart/styles/item-promo.module.css @@ -0,0 +1,31 @@ +.wrapper { + @apply md:ml-16 ml-8 mt-4 flex; +} + +.imageWrapper { + @apply md:h-24 md:w-24 md:min-w-[96px] + h-20 w-20 min-w-[80px] + border border-gray-300 rounded + p-2.5; +} + +.image { + @apply w-full h-full object-contain; +} + +.details { + @apply ml-4 w-full flex flex-col gap-y-1; +} + +.name { + @apply font-medium; +} + +.code, +.weightLabel { + @apply text-gray-600; +} + +.quantity { + @apply w-12 min-w-[42px] py-2.5 bg-gray-100 border border-gray-300 h-fit my-auto rounded-md ml-auto font-medium text-center; +} diff --git a/src-migrate/modules/cart/styles/item.module.css b/src-migrate/modules/cart/styles/item.module.css new file mode 100644 index 00000000..dfbbf5e8 --- /dev/null +++ b/src-migrate/modules/cart/styles/item.module.css @@ -0,0 +1,60 @@ +.wrapper { + @apply border-b border-gray-300 pb-8; +} + +.header { + @apply mb-4 flex items-center text-caption-1 leading-6; +} + +.badgeType { + @apply min-w-fit p-2 flex items-center gap-x-1.5 rounded-md border border-danger-500 text-danger-500; +} + +.mainProdWrapper { + @apply flex; +} + +.image { + @apply md:h-32 md:w-32 md:min-w-[128px] + w-24 h-24 min-w-[96px] rounded flex p-2 border border-gray-300; +} + +.noImage { + @apply m-auto font-semibold text-gray-400; +} + +.details { + @apply ml-4 flex flex-col gap-y-1 w-full; +} + +.name { + @apply font-medium; +} + +.spacing2 { + @apply h-2; +} + +.discPriceSection { + @apply flex flex-col md:flex-row gap-x-2.5; +} + +.priceBefore { + @apply line-through text-gray-500; +} + +.price { + @apply text-red-600 font-medium; +} + +.savingAmt { + @apply text-success-600; +} + +.weightLabel { + @apply text-gray-500; +} + +.quantity { + @apply py-2.5 bg-red-100 border border-red-300 text-red-800 h-fit my-auto rounded-md ml-auto font-medium w-12 text-center; +} diff --git a/src-migrate/modules/cart/styles/summary.module.css b/src-migrate/modules/cart/styles/summary.module.css new file mode 100644 index 00000000..48ccec28 --- /dev/null +++ b/src-migrate/modules/cart/styles/summary.module.css @@ -0,0 +1,21 @@ +.line { + @apply flex justify-between; +} + +.label, +.value { + @apply text-gray-700; +} + +.value, +.grandTotal { + @apply font-medium; +} + +.discount { + @apply text-red-700; +} + +.divider { + @apply my-0.5 h-0.5 bg-gray-200; +} diff --git a/src-migrate/modules/footer-banner/index.tsx b/src-migrate/modules/footer-banner/index.tsx new file mode 100644 index 00000000..b214493d --- /dev/null +++ b/src-migrate/modules/footer-banner/index.tsx @@ -0,0 +1,32 @@ +import Link from "next/link" +import React, { useMemo } from "react"; +import { useQuery } from "react-query" +import Image from "~/components/ui/image" +import { getBanner } from "~/services/banner" +import { getRandomInt } from '@/utils/getRandomInt' + +const FooterBanner = () => { + const fetchFooterBanner = useQuery({ + queryKey: 'footerBanner', + queryFn: () => getBanner({ type: 'bottom-search-promotion' }) + }) + // ubah dari static menjadid dynamic dengan menggunakan random index + const length = useMemo(() => fetchFooterBanner.data?.length, [fetchFooterBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchFooterBanner?.data?.[randomIndex] || false; + + return banner && ( + <> + {banner.url && ( + <Link href={banner.url}> + <Image src={banner.image} alt={banner.name} width={924} height={150} className='object-cover object-center rounded-lg' /> + </Link> + )} + + {!banner.url && ( + <Image src={banner.image} alt={banner.name} width={924} height={150} className='object-cover object-center rounded-lg' /> + )} + </> + ) +} +export default FooterBanner
\ No newline at end of file diff --git a/src-migrate/modules/header/components/HeaderDesktop.tsx b/src-migrate/modules/header/components/HeaderDesktop.tsx index 3860bded..131fa7da 100644 --- a/src-migrate/modules/header/components/HeaderDesktop.tsx +++ b/src-migrate/modules/header/components/HeaderDesktop.tsx @@ -8,7 +8,7 @@ import Link from 'next/link' import SearchBar from "./SearchBar"; // Constants -import { SECONDARY_MENU_ITEMS } from "~/common/constants/menu"; +import { SECONDARY_MENU_ITEMS } from "~/constants/menu"; const LOGO_WIDTH = 210; const LOGO_HEIGHT = LOGO_WIDTH / 3; @@ -54,7 +54,7 @@ const HeaderDesktop = () => { <Image src='/images/socials/Whatsapp-2.png' alt='Whatsapp' width={48} height={48} /> <div> <div className='font-semibold'>Whatsapp</div> - 0812 8080 622 (Chat) + 0817 1718 1922 (Chat) </div> </a> </div> diff --git a/src-migrate/modules/page-content/index.tsx b/src-migrate/modules/page-content/index.tsx index 608079f8..547b1957 100644 --- a/src-migrate/modules/page-content/index.tsx +++ b/src-migrate/modules/page-content/index.tsx @@ -1,7 +1,6 @@ import { useMemo } from "react" import { useQuery } from "react-query" -import PageContentSkeleton from "~/common/components/skeleton/PageContentSkeleton" -import { PageContentProps } from "~/common/types/pageContent" +import { PageContentProps } from "~/types/pageContent" import { getPageContent } from "~/services/pageContent" type Props = { @@ -26,4 +25,20 @@ const PageContent = ({ path }: Props) => { ) } +const PageContentSkeleton = () => ( + <div className="animate-pulse grid gap-y-4"> + <div className="w-full h-10 bg-gray-300 rounded" /> + <div className="h-2" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-8/12 h-4 bg-gray-300 rounded" /> + <div className="h-2" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-full h-4 bg-gray-300 rounded" /> + <div className="w-1/2 h-4 bg-gray-300 rounded" /> + </div> +) + export default PageContent
\ No newline at end of file diff --git a/src-migrate/modules/popup-information/index.tsx b/src-migrate/modules/popup-information/index.tsx index 78e9dcf2..0d36f8e9 100644 --- a/src-migrate/modules/popup-information/index.tsx +++ b/src-migrate/modules/popup-information/index.tsx @@ -1,9 +1,9 @@ import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; -import Modal from '~/common/components/elements/Modal'; -import { getAuth } from '~/common/libs/auth'; + +import { Modal } from "~/components/ui/modal"; +import { getAuth } from '~/libs/auth'; import PageContent from '../page-content'; -import Link from 'next/link'; const PagePopupInformation = () => { const router = useRouter(); @@ -12,25 +12,18 @@ const PagePopupInformation = () => { const [active, setActive] = useState<boolean>(false); useEffect(() => { - if (isHomePage && !auth) { - setActive(true); - } + if (isHomePage && !auth) setActive(true); }, [isHomePage, auth]); return ( <div className='group'> <Modal active={active} - className='!w-fit !bg-transparent !border-none' + className='!w-fit !bg-transparent !border-none overflow-hidden' close={() => setActive(false)} mode='desktop' > - <div> - <Link href={'/register'}> - <PageContent path='/onbording-popup' /> - </Link> - <Link href={'/register'} className='btn-yellow w-full mt-2'> - Daftar Sekarang - </Link> + <div className='w-[350px] md:w-[530px]' onClick={() => setActive(false)}> + <PageContent path='/onbording-popup' /> </div> </Modal> </div> diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx new file mode 100644 index 00000000..0febfadb --- /dev/null +++ b/src-migrate/modules/product-card/components/ProductCard.tsx @@ -0,0 +1,144 @@ +import style from '../styles/product-card.module.css' +import ImageNext from 'next/image'; +import clsx from 'clsx' +import Link from 'next/link' +import React, { useEffect, useMemo, useState } from 'react' +import Image from '~/components/ui/image' +import useUtmSource from '~/hooks/useUtmSource' +import clsxm from '~/libs/clsxm' +import formatCurrency from '~/libs/formatCurrency' +import { formatToShortText } from '~/libs/formatNumber' +import { createSlug } from '~/libs/slug' +import { IProduct } from '~/types/product' + +type Props = { + product: IProduct + layout?: 'vertical' | 'horizontal' +} + +const ProductCard = ({ product, layout = 'vertical' }: Props) => { + const utmSource = useUtmSource() + + + const URL = { + product: createSlug('/shop/product/', product.name, product.id.toString()) + `?utm_source=${utmSource}`, + manufacture: createSlug('/shop/brands/', product.manufacture.name, product.manufacture.id.toString()), + } + + const image = useMemo(() => { + if (product.image) return product.image + '?ratio=square' + return '/images/noimage.jpeg' + }, [product.image]) + + return ( + <div className={clsxm(style['wrapper'], { + [style['wrapper-v']]: layout === 'vertical', + [style['wrapper-h']]: layout === 'horizontal', + })} + > + <div className={clsxm('relative', { + [style['image-v']]: layout === 'vertical', + [style['image-h']]: layout === 'horizontal', + })}> + <Link href={URL.product}> + + <div className="relative"> + <Image + src={image} + alt={product.name} + width={128} + height={128} + className='object-contain object-center h-full w-full' + /> + <div className="absolute top-0 right-0 flex mt-2"> + <div className="gambarB "> + {product.isSni && ( + <ImageNext + src="/images/sni-logo.png" + alt="SNI Logo" + className="w-3 h-4 object-contain object-top sm:h-4" + width={50} + height={50} + /> + )} + </div> + <div className="gambarC "> + {product.isTkdn && ( + <ImageNext + src="/images/TKDN.png" + alt="TKDN" + className="w-5 h-4 object-contain object-top ml-1 mr-1 sm:h-6" + width={50} + height={50} + /> + )} + </div> + </div> + </div> + + {product.variant_total > 1 && ( + <div className={style['variant-badge']}>{product.variant_total} Varian</div> + )} + </Link> + </div> + + <div className={clsxm({ + [style['content-v']]: layout === 'vertical', + [style['content-h']]: layout === 'horizontal', + })}> + <Link + href={URL.manufacture} + className={style['brand']} + > + {product.manufacture.name} + </Link> + + <div className='h-0.5' /> + + <Link + href={URL.product} + className={clsxm(style['name'], { + [style['name-v']]: layout === 'vertical', + [style['name-h']]: layout === 'horizontal', + })} + > + {product.name} + </Link> + <div className='h-1.5' /> + + <div className={style['price']}> + Rp {formatCurrency(product.lowest_price.price)} + </div> + + <div className='h-1.5' /> + + <div className={style['price-inc']}> + Inc PPN: + Rp {formatCurrency(Math.round(product.lowest_price.price * 1.11))} + </div> + + <div className='h-1' /> + + <div className='flex items-center gap-x-2.5'> + {product.stock_total > 0 && ( + <div className={style['ready-stock']}> + Ready Stock + </div> + )} + {product.qty_sold > 0 && ( + <div className={style['sold']}> + {formatToShortText(product.qty_sold)} Terjual + </div> + )} + </div> + + </div> + </div> + ) +} + +const classPrefix = ({ layout }: Props) => { + +} + +export default ProductCard
\ No newline at end of file diff --git a/src-migrate/modules/product-card/index.tsx b/src-migrate/modules/product-card/index.tsx new file mode 100644 index 00000000..c87167bc --- /dev/null +++ b/src-migrate/modules/product-card/index.tsx @@ -0,0 +1,3 @@ +import ProductCard from "./components/ProductCard"; + +export default ProductCard
\ No newline at end of file diff --git a/src-migrate/modules/product-card/styles/product-card.module.css b/src-migrate/modules/product-card/styles/product-card.module.css new file mode 100644 index 00000000..653bf2ca --- /dev/null +++ b/src-migrate/modules/product-card/styles/product-card.module.css @@ -0,0 +1,54 @@ +.wrapper { + @apply w-full flex; +} +.wrapper-v { + @apply flex-col border border-gray-300 rounded-md h-[350px]; +} +.wrapper-h { + @apply flex-row gap-x-2 pt-4; +} + +.image-v { + @apply w-full h-48 px-4 border-b border-gray-300; +} +.image-h { + @apply w-4/12 h-24 px-1; +} + +.content-v { + @apply w-full p-2; +} +.content-h { + @apply w-8/12; +} + +.brand { + @apply text-danger-500 font-medium block; +} + +.name { + @apply text-gray-700 font-medium line-clamp-3; +} +.name-v { + @apply min-h-[64px]; +} +.name-h { + @apply min-h-[32px]; +} + +.price { + @apply text-danger-500 font-medium; +} + +.ready-stock { + @apply bg-danger-500 text-white text-[11px] px-2 py-1 rounded-md whitespace-nowrap; +} + +.price-inc, +.sold { + @apply text-gray-600 text-[11px]; +} + +.variant-badge { + @apply bg-gray-500/20 backdrop-blur-md absolute rounded-md bottom-2 left-2 px-2 py-1 text-caption-2; +} diff --git a/src-migrate/modules/product-detail/components/AddToCart.tsx b/src-migrate/modules/product-detail/components/AddToCart.tsx new file mode 100644 index 00000000..097db98a --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToCart.tsx @@ -0,0 +1,78 @@ +import { Button, useToast } from '@chakra-ui/react' +import { useRouter } from 'next/router' + +import { getAuth } from '~/libs/auth' +import { upsertUserCart } from '~/services/cart' + +type Props = { + variantId: number | null, + quantity?: number; + source?: 'buy' | 'add_to_cart'; +} + +const AddToCart = ({ + variantId, + quantity = 1, + source = 'add_to_cart' +}: Props) => { + const auth = getAuth() + const router = useRouter() + const toast = useToast({ + position: 'top', + isClosable: true + }) + + const handleClick = async () => { + if (typeof auth !== 'object') { + const currentUrl = encodeURIComponent(router.asPath) + router.push(`/login?next=${currentUrl}`) + return; + } + + if ( + !variantId || + isNaN(quantity) || + typeof auth !== 'object' + ) return; + + toast.promise( + upsertUserCart({ + userId: auth.id, + type: 'product', + id: variantId, + qty: quantity, + selected: true, + source: source, + qtyAppend: true + }), + { + loading: { title: 'Menambahkan ke keranjang', description: 'Mohon tunggu...' }, + success: { title: 'Menambahkan ke keranjang', description: 'Berhasil menambahkan ke keranjang belanja' }, + error: { title: 'Menambahkan ke keranjang', description: 'Gagal menambahkan ke keranjang belanja' }, + } + ) + + if (source === 'buy') { + router.push('/shop/checkout?source=buy') + } + } + + const btnConfig = { + 'add_to_cart': { + colorScheme: 'yellow', + text: 'Keranjang' + }, + 'buy': { + colorScheme: 'red', + text: 'Beli' + } + } + + return ( + <Button onClick={handleClick} colorScheme={btnConfig[source].colorScheme} className='w-full'> + {btnConfig[source].text} + </Button> + ) +} + +export default AddToCart
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/AddToWishlist.tsx b/src-migrate/modules/product-detail/components/AddToWishlist.tsx new file mode 100644 index 00000000..697b2d5c --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToWishlist.tsx @@ -0,0 +1,61 @@ +import { Button, useToast } from '@chakra-ui/react' +import { HeartIcon } from 'lucide-react' +import React from 'react' +import { useQuery } from 'react-query' +import { getAuth } from '~/libs/auth' +import clsxm from '~/libs/clsxm' +import { getUserWishlist, upsertUserWishlist } from '~/services/wishlist' + +type Props = { + productId: number +} + +const AddToWishlist = ({ productId }: Props) => { + const auth = getAuth() + const toast = useToast({ + position: 'top', + isClosable: true + }) + + const searchParams = { product_id: productId.toString() } + const query = useQuery({ + queryKey: ['wishlist', searchParams, auth], + queryFn: () => { + if (typeof auth !== 'object') return null; + return getUserWishlist(auth.id, searchParams) + }, + refetchOnWindowFocus: false + }) + + const isAdded = query.data?.product_total ? query.data.product_total > 0 : false; + + const toggleWishlist = async () => { + if (typeof auth !== 'object') return; + await upsertUserWishlist(auth.id, productId) + await query.refetch() + } + + const handleClick = async () => { + toast.promise(toggleWishlist(), { + loading: { title: 'Update Wishlist', description: 'Mohon tunggu...' }, + success: { title: 'Update Wishlist', description: 'Berhasil update wishlist' }, + error: { title: 'Update Wishlist', description: 'Gagal update wishlist' }, + }) + } + + return ( + <Button + variant='link' + colorScheme='gray' + onClick={handleClick} + leftIcon={<HeartIcon size={18} className={clsxm('transition-colors', { + 'text-danger-500 fill-danger-500': isAdded, + 'fill-transparent': !isAdded + })} />} + > + Wishlist + </Button> + ) +} + +export default AddToWishlist
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Breadcrumb.tsx b/src-migrate/modules/product-detail/components/Breadcrumb.tsx new file mode 100644 index 00000000..f41859a9 --- /dev/null +++ b/src-migrate/modules/product-detail/components/Breadcrumb.tsx @@ -0,0 +1,41 @@ +import React, { Fragment } from 'react' +import { useQuery } from 'react-query' +import { getProductCategoryBreadcrumb } from '~/services/product' +import Link from 'next/link' +import { createSlug } from '~/libs/slug' + +type Props = { + id: number, + name: string +} + +const Breadcrumb = ({ id, name }: Props) => { + const query = useQuery({ + queryKey: ['product-category-breadcrumb'], + queryFn: () => getProductCategoryBreadcrumb(id), + refetchOnWindowFocus: false + }) + + const breadcrumbs = query.data || [] + + return ( + <div className='line-clamp-2 md:line-clamp-1 leading-7 text-caption-1'> + <Link href='/' className='text-danger-500'>Home</Link> + <span className='mx-2'>/</span> + {breadcrumbs.map((category, index) => ( + <Fragment key={index}> + <Link + href={createSlug('/shop/category/', category.name, category.id.toString())} + className='text-danger-500' + > + {category.name} + </Link> + <span className='mx-2'>/</span> + </Fragment> + ))} + <span>{name}</span> + </div> + ) +} + +export default Breadcrumb
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx new file mode 100644 index 00000000..30ca0d34 --- /dev/null +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -0,0 +1,133 @@ +import style from '../styles/image.module.css'; +import ImageNext from 'next/image'; +import React, { useEffect, useMemo, useState } from 'react' +import { InfoIcon } from 'lucide-react' +import { Tooltip } from '@chakra-ui/react' + +import { IProductDetail } from '~/types/product' +import ImageUI from '~/components/ui/image' +import moment from 'moment'; + +type Props = { + product: IProductDetail +} + +const Image = ({ product }: Props) => { + const flashSale = product.flash_sale + const [count, setCount] = useState(flashSale?.remaining_time || 0); + + + + useEffect(() => { + let interval: NodeJS.Timeout; + + if (flashSale?.remaining_time && flashSale.remaining_time > 0) { + setCount(flashSale.remaining_time); + + interval = setInterval(() => { + setCount((prevCount) => prevCount - 1); + }, 1000); + } + + return () => { + clearInterval(interval); + }; + }, [flashSale?.remaining_time]); + + const duration = moment.duration(count, 'seconds') + + const image = useMemo(() => { + if (product.image) return product.image + '?ratio=square' + return '/images/noimage.jpeg' + }, [product.image]) + + return ( + <div className={style['wrapper']}> + {/* <div className="relative"> */} + <ImageUI + src={image} + alt={product.name} + width={256} + height={256} + className={style['image']} + loading='eager' + priority + /> + <div className="absolute top-4 right-10 flex "> + <div className="gambarB "> + {product.isSni && ( + <ImageNext + src="/images/sni-logo.png" + alt="SNI Logo" + className="w-12 h-8 object-contain object-top sm:h-6" + width={50} + height={50} + /> + )} + </div> + <div className="gambarC "> + {product.isTkdn && ( + <ImageNext + src="/images/TKDN.png" + alt="TKDN" + className="w-16 h-8 object-contain object-top ml-1 mr-1 sm:h-6" + width={50} + height={50} + /> + )} + </div> + </div> + {/* </div> */} + + + + <div className={style['absolute-info']}> + <Tooltip + placement='bottom-end' + label='Gambar atau foto berperan sebagai ilustrasi produk. Kadang tidak sesuai dengan kondisi terbaru dengan berbagai perubahan dan perbaikan. Hubungi admin kami untuk informasi yang lebih baik perihal gambar.' + > + <div className="text-gray-600"> + <InfoIcon size={20} /> + </div> + </Tooltip> + </div> + + {flashSale.remaining_time > 0 && ( + <div className='absolute bottom-0 w-full h-14'> + <div className="relative w-full h-full"> + <ImageUI + src='/images/BG-FLASH-SALE.jpg' + alt='Flash Sale Indoteknik' + width={200} + height={100} + className={style['flashsale-bg']} + /> + + <div className={style['flashsale']}> + <div className='flex items-center gap-x-3'> + <div className={style['disc-badge']}>{Math.floor(product.lowest_price.discount_percentage)}%</div> + <div className={style['flashsale-text']}> + <ImageUI + src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' + alt='Icon Flash Sale' + width={20} + height={20} + /> + {product.flash_sale.tag} + </div> + </div> + <div className={style['countdown']}> + <span>{duration.hours().toString().padStart(2, '0')}</span> + <span>{duration.minutes().toString().padStart(2, '0')}</span> + <span>{duration.seconds().toString().padStart(2, '0')}</span> + </div> + </div> + + </div> + </div> + )} + </div> + ) +} + +export default Image
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx new file mode 100644 index 00000000..52eb6b88 --- /dev/null +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -0,0 +1,56 @@ +import style from '../styles/information.module.css' + +import React from 'react' +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { useQuery } from 'react-query' + +import { IProductDetail } from '~/types/product' +import { IProductVariantSLA } from '~/types/productVariant' +import { createSlug } from '~/libs/slug' +import { getVariantSLA } from '~/services/productVariant' +import { formatToShortText } from '~/libs/formatNumber' + +const Skeleton = dynamic(() => import('@chakra-ui/react').then((mod) => mod.Skeleton)) + +type Props = { + product: IProductDetail +} + +const Information = ({ product }: Props) => { + const querySLA = useQuery<IProductVariantSLA>({ + queryKey: ['variant-sla', product.variants[0].id], + queryFn: () => getVariantSLA(product.variants[0].id), + enabled: product.variant_total === 1 + }) + + const sla = querySLA?.data + + return ( + <div className={style['wrapper']}> + <div className={style['row']}> + <div className={style['label']}>SKU Number</div> + <div className={style['value']}>SKU-{product.id}</div> + </div> + <div className={style['row']}> + <div className={style['label']}>Manufacture</div> + <div className={style['value']}> + {!!product.manufacture.name ? ( + <Link + href={createSlug('/shop/brands/', product.manufacture.name, product.manufacture.id.toString())} + className='text-danger-500 hover:underline' + > + {product.manufacture.name} + </Link> + ) : '-'} + </div> + </div> + <div className={style['row']}> + <div className={style['label']}>Terjual</div> + <div className={style['value']}>{product.qty_sold > 0 ? formatToShortText(product.qty_sold) : '-'}</div> + </div> + </div> + ) +} + +export default Information
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx new file mode 100644 index 00000000..81271f6e --- /dev/null +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -0,0 +1,115 @@ +import style from '../styles/price-action.module.css'; + +import React, { useEffect } from 'react'; +import formatCurrency from '~/libs/formatCurrency'; +import { IProductDetail } from '~/types/product'; +import { useProductDetail } from '../stores/useProductDetail'; +import AddToCart from './AddToCart'; +import Link from 'next/link'; +import { getAuth } from '~/libs/auth'; + +type Props = { + product: IProductDetail; +}; + +const PriceAction = ({ product }: Props) => { + const { + activePrice, + setActive, + activeVariantId, + quantityInput, + setQuantityInput, + askAdminUrl, + isApproval, + setIsApproval, + } = useProductDetail(); + + useEffect(() => { + setActive(product.variants[0]) + if(product.variants.length > 2 && product.variants[0].price.price === 0){ + const variants = product.variants + for (let i = 0; i < variants.length; i++) { + if(variants[i].price.price > 0){ + setActive(variants[i]) + break; + } + } + } + + }, [product, setActive]); + + + + return ( + <div + className='block md:sticky top-[150px] bg-white py-0 md:py-6 z-10' + id='price-section' + > + {!!activePrice && activePrice.price > 0 && ( + <> + <div className='flex items-end gap-x-2'> + {activePrice.discount_percentage > 0 && ( + <> + <div className={style['disc-badge']}> + {Math.floor(activePrice.discount_percentage)}% + </div> + <div className={style['disc-price']}> + Rp {formatCurrency(activePrice.price || 0)} + </div> + </> + )} + <div className={style['main-price']}> + Rp {formatCurrency(activePrice.price_discount || 0)} + </div> + </div> + <div className='h-1' /> + <div className={style['secondary-text']}> + Termasuk PPN: Rp{' '} + {formatCurrency(Math.round(activePrice.price_discount * 1.11))} + </div> + </> + )} + + {!!activePrice && activePrice.price === 0 && ( + <span> + Hubungi kami untuk dapatkan harga terbaik,{' '} + <Link + href={askAdminUrl} + target='_blank' + className={style['contact-us']} + > + klik disini + </Link> + </span> + )} + + <div className='h-4' /> + + <div className={style['action-wrapper']}> + <label htmlFor='quantity' className='hidden'> + Quantity + </label> + <input + type='number' + id='quantity' + value={quantityInput} + onChange={(e) => setQuantityInput(e.target.value)} + className={style['quantity-input']} + /> + <AddToCart + variantId={activeVariantId} + quantity={Number(quantityInput)} + /> + {!isApproval && ( + <AddToCart + source='buy' + variantId={activeVariantId} + quantity={Number(quantityInput)} + /> + )} + </div> + </div> + ); +}; + +export default PriceAction; diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx new file mode 100644 index 00000000..fad35a7d --- /dev/null +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -0,0 +1,191 @@ +import style from '../styles/product-detail.module.css' + +import Link from 'next/link' +import { useRouter } from 'next/router' +import { useEffect } from 'react' + +import { Button } from '@chakra-ui/react' +import { MessageCircleIcon, Share2Icon } from 'lucide-react' +import { LazyLoadComponent } from 'react-lazy-load-image-component' +import { RWebShare } from 'react-web-share' + +import useDevice from '@/core/hooks/useDevice' +import { whatsappUrl } from '~/libs/whatsappUrl' +import ProductPromoSection from '~/modules/product-promo/components/Section' +import { IProductDetail } from '~/types/product' +import { useProductDetail } from '../stores/useProductDetail' +import AddToWishlist from './AddToWishlist' +import Breadcrumb from './Breadcrumb' +import ProductImage from './Image' +import Information from './Information' +import PriceAction from './PriceAction' +import SimilarBottom from './SimilarBottom' +import SimilarSide from './SimilarSide' +import VariantList from './VariantList' +import { getAuth } from '~/libs/auth' + +import { gtagProductDetail } from '@/core/utils/googleTag' + +type Props = { + product: IProductDetail +} + +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST + +const ProductDetail = ({ product }: Props) => { + const { isDesktop, isMobile } = useDevice() + const router = useRouter() + const auth = getAuth() + const { setAskAdminUrl, askAdminUrl, activeVariantId, setIsApproval, isApproval } = useProductDetail() + + useEffect(() => { + gtagProductDetail(product); + },[product]) + + useEffect(() => { + const createdAskUrl = whatsappUrl({ + template: 'product', + payload: { + manufacture: product.manufacture.name, + productName: product.name, + url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath + }, + fallbackUrl: router.asPath + }) + + setAskAdminUrl(createdAskUrl) + }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) + + useEffect(() => { + if (typeof auth === 'object') { + setIsApproval(auth?.feature?.soApproval); + } + }, []); + + return ( + <> + <div className='md:flex md:flex-wrap'> + <div className="w-full mb-4 md:mb-0 px-4 md:px-0"> + <Breadcrumb id={product.id} name={product.name} /> + </div> + <div className='md:w-9/12 md:flex md:flex-col md:pr-4 md:pt-6'> + <div className='md:flex md:flex-wrap'> + <div className="md:w-4/12"> + <ProductImage product={product} /> + </div> + + <div className='md:w-8/12 px-4 md:pl-6'> + <div className='h-6 md:h-0' /> + + <h1 className={style['title']}> + {product.name} + </h1> + + <div className='h-6 md:h-8' /> + + <Information product={product} /> + + <div className='h-6' /> + + <div className="flex gap-x-5"> + <Button + as={Link} + href={askAdminUrl} + variant='link' + target='_blank' + colorScheme='gray' + leftIcon={<MessageCircleIcon size={18} />} + > + Ask Admin + </Button> + + <AddToWishlist productId={product.id} /> + + <RWebShare + data={{ + text: 'Check out this product', + title: `${product.name} - Indoteknik.com`, + url: SELF_HOST + router.asPath + }} + > + <Button + variant='link' + colorScheme='gray' + leftIcon={<Share2Icon size={18} />} + > + Share + </Button> + </RWebShare> + </div> + + </div> + </div> + + <div className='h-full'> + {isMobile && ( + <div className='px-4 pt-6'> + <PriceAction product={product} /> + </div> + )} + + <div className='h-4 md:h-10' /> + {!!activeVariantId && !isApproval && <ProductPromoSection productId={activeVariantId} />} + + <div className={style['section-card']}> + <h2 className={style['heading']}> + Variant ({product.variant_total}) + </h2> + <div className='h-4' /> + <VariantList variants={product.variants} /> + </div> + + <div className='h-0 md:h-6' /> + + <div className={style['section-card']}> + <h2 className={style['heading']}> + Informasi Produk + </h2> + <div className='h-4' /> + <div + className={style['description']} + dangerouslySetInnerHTML={{ __html: !product.description || product.description == '<p><br></p>' ? 'Belum ada deskripsi' : product.description }} + /> + </div> + </div> + </div> + + {isDesktop && ( + <div className="md:w-3/12"> + <PriceAction product={product} /> + + <div className='h-6' /> + + <div className={style['heading']}> + Produk Serupa + </div> + + <div className='h-4' /> + + <SimilarSide product={product} /> + </div> + )} + + <div className='md:w-full pt-4 md:py-10 px-4 md:px-0'> + <div className={style['heading']}> + Kamu Mungkin Juga Suka + </div> + + <div className='h-6' /> + + <LazyLoadComponent> + <SimilarBottom product={product} /> + </LazyLoadComponent> + </div> + + <div className='h-6 md:h-0' /> + </div> + </> + ) +} + +export default ProductDetail
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarBottom.tsx b/src-migrate/modules/product-detail/components/SimilarBottom.tsx new file mode 100644 index 00000000..40d4dd82 --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarBottom.tsx @@ -0,0 +1,29 @@ +import { Skeleton } from '@chakra-ui/react' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import ProductSlider from '~/modules/product-slider' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarBottom = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id } + }) + + const products = productSimilar.data?.products || [] + + return ( + <Skeleton + isLoaded={!productSimilar.isLoading} + rounded='lg' + className='h-[350px]' + > + <ProductSlider products={products} productLayout='vertical' /> + </Skeleton> + ); +} + +export default SimilarBottom
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarSide.tsx b/src-migrate/modules/product-detail/components/SimilarSide.tsx new file mode 100644 index 00000000..d70a314d --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarSide.tsx @@ -0,0 +1,36 @@ +import { Skeleton } from '@chakra-ui/react' + +import ProductCard from '~/modules/product-card' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarSide = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id, manufactureId: product.manufacture.id }, + }) + + const products = productSimilar.data?.products || [] + + return ( + <Skeleton + isLoaded={!productSimilar.isLoading} + className="h-[500px] overflow-auto grid grid-cols-1 gap-y-4 divide-y divide-gray-300 border border-gray-300 rounded-lg" + rounded='lg' + > + {products.map((product) => ( + <ProductCard + key={product.id} + product={product} + layout='horizontal' + /> + ))} + </Skeleton> + ) +} + +export default SimilarSide
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx new file mode 100644 index 00000000..3d5b9b74 --- /dev/null +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -0,0 +1,117 @@ +import style from '../styles/variant-list.module.css' + +import React from 'react' +import { Button, Skeleton } from '@chakra-ui/react' + +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' +import { IProductVariantDetail, IProductVariantSLA } from '~/types/productVariant' +import { useProductDetail } from '../stores/useProductDetail' +import { LazyLoadComponent } from 'react-lazy-load-image-component'; +import { getVariantSLA } from '~/services/productVariant' +import { useQuery } from 'react-query' +import useDevice from '@/core/hooks/useDevice' + +type Props = { + variants: IProductVariantDetail[] +} + +const VariantList = ({ variants }: Props) => { + return ( + <div className='overflow-auto'> + <div className={style['wrapper']}> + <div className={style['header']}> + <div className="w-2/12">Part Number</div> + <div className="w-2/12">Variant</div> + <div className="w-1/12">Stock</div> + <div className="w-2/12">Masa Persiapan</div> + <div className="w-1/12">Berat</div> + <div className="w-3/12">Harga</div> + <div className='w-1/12 sticky right-0 bg-gray-200'></div> + </div> + {variants.map((variant) => ( + <LazyLoadComponent key={variant.id}> + <Row variant={variant} /> + </LazyLoadComponent> + ))} + </div> + </div> + ) +} + +const Row = ({ variant }: { variant: IProductVariantDetail }) => { + const { isMobile } = useDevice() + + const { activeVariantId, setActive } = useProductDetail() + const querySLA = useQuery<IProductVariantSLA>({ + queryKey: ['variant-sla', variant.id], + queryFn: () => getVariantSLA(variant.id), + refetchOnWindowFocus: false, + }) + + const sla = querySLA?.data + + const handleSelect = (variant: IProductVariantDetail) => { + const priceSectionEl = document.getElementById('price-section') + if (isMobile && priceSectionEl) { + window.scrollTo({ + top: priceSectionEl.offsetTop - 120, + behavior: 'smooth' + }) + } + setActive(variant) + } + + return ( + <div className={style['row']}> + <div className='w-2/12'>{variant.code}</div> + <div className='w-2/12'>{variant.attributes.join(', ') || '-'}</div> + <div className='w-1/12'> + <Skeleton isLoaded={querySLA.isSuccess} h='21px' w={16}> + {sla?.qty !== undefined && ( + <div className={clsxm('text-center rounded-md', { + [style['stock-empty']]: sla.qty == 0, + [style['stock-ready']]: sla.qty > 0, + })} + > + {sla.qty > 0 && sla.qty} + {sla.qty == 0 && '-'} + </div> + )} + </Skeleton> + </div> + <div className='w-2/12'> + <Skeleton isLoaded={querySLA.isSuccess} h='21px' w={16}> + {sla?.sla_date} + </Skeleton> + </div> + <div className='w-1/12'> + {variant.weight > 0 ? `${variant.weight} Kg` : '-'} + </div> + <div className='w-3/12'> + {variant.price.discount_percentage > 0 && ( + <div className='flex items-center gap-x-1'> + <div className={style['disc-badge']}>{Math.floor(variant.price.discount_percentage)}%</div> + <div className={style['disc-price']}>Rp {formatCurrency(variant.price.price)}</div> + </div> + )} + {variant.price.price_discount > 0 && `Rp ${formatCurrency(variant.price.price_discount)}`} + {variant.price.price_discount === 0 && '-'} + </div> + <div className='w-1/12 sticky right-0 bg-white md:bg-transparent'> + <Button + onClick={() => handleSelect(variant)} + size='sm' + w='100%' + className={clsxm(style['select-btn'], { + [style['select-btn--active']]: variant.id === activeVariantId + })} + > + Pilih + </Button> + </div> + </div> + ) +} + +export default VariantList
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/index.ts b/src-migrate/modules/product-detail/index.ts new file mode 100644 index 00000000..246bc06a --- /dev/null +++ b/src-migrate/modules/product-detail/index.ts @@ -0,0 +1,3 @@ +import ProductDetail from './components/ProductDetail'; + +export default ProductDetail; diff --git a/src-migrate/modules/product-detail/stores/useProductDetail.ts b/src-migrate/modules/product-detail/stores/useProductDetail.ts new file mode 100644 index 00000000..2da8835d --- /dev/null +++ b/src-migrate/modules/product-detail/stores/useProductDetail.ts @@ -0,0 +1,37 @@ +import { create } from 'zustand'; +import { IProductVariantDetail } from '~/types/productVariant'; + +type State = { + activeVariantId: number | null; + activePrice: IProductVariantDetail['price'] | null; + quantityInput: string; + askAdminUrl: string; + isApproval : boolean; +}; + +type Action = { + setActive: (variant: IProductVariantDetail) => void; + setQuantityInput: (value: string) => void; + setAskAdminUrl: (url: string) => void; + setIsApproval : (value : boolean) => void; +}; + +export const useProductDetail = create<State & Action>((set, get) => ({ + activeVariantId: null, + activePrice: null, + quantityInput: '1', + askAdminUrl: '', + isApproval : false, + setActive: (variant) => { + set({ activeVariantId: variant.id, activePrice: variant.price }); + }, + setQuantityInput: (value: string) => { + set({ quantityInput: value }); + }, + setAskAdminUrl: (url: string) => { + set({ askAdminUrl: url }); + }, + setIsApproval : (value : boolean) => { + set({ isApproval : value }) + } +})); diff --git a/src-migrate/modules/product-detail/styles/image.module.css b/src-migrate/modules/product-detail/styles/image.module.css new file mode 100644 index 00000000..e472fe8d --- /dev/null +++ b/src-migrate/modules/product-detail/styles/image.module.css @@ -0,0 +1,35 @@ +.wrapper { + @apply h-[250px] md:h-[340px] flex items-center justify-center border border-gray-200 rounded-lg p-4 relative; +} + +.image { + @apply object-contain object-center h-full w-full; +} + +.absolute-info { + @apply absolute hidden md:block top-4 right-4; +} + +.disc-badge { + @apply bg-warning-500 py-1 px-3 w-fit font-semibold rounded-full; +} + +.countdown { + @apply flex gap-x-1; +} + +.countdown span { + @apply py-0.5 w-8 bg-warning-500 rounded-md text-center; +} + +.flashsale-text { + @apply flex items-center gap-x-2 text-white font-medium text-caption-1; +} + +.flashsale-bg { + @apply absolute top-0 w-full h-full object-cover object-center z-10; +} + +.flashsale { + @apply absolute top-0 w-full h-full z-20 flex items-center justify-between px-3; +} diff --git a/src-migrate/modules/product-detail/styles/information.module.css b/src-migrate/modules/product-detail/styles/information.module.css new file mode 100644 index 00000000..c9b29020 --- /dev/null +++ b/src-migrate/modules/product-detail/styles/information.module.css @@ -0,0 +1,19 @@ +.wrapper { + @apply grid grid-cols-1; +} + +.row { + @apply flex p-3 rounded; +} + +.row:nth-child(odd) { + @apply bg-gray-100; +} + +.label { + @apply w-1/2 md:w-1/3 font-medium text-gray-500; +} + +.value { + @apply w-1/2 md:w-3/4 text-gray-950; +} diff --git a/src-migrate/modules/product-detail/styles/price-action.module.css b/src-migrate/modules/product-detail/styles/price-action.module.css new file mode 100644 index 00000000..651de958 --- /dev/null +++ b/src-migrate/modules/product-detail/styles/price-action.module.css @@ -0,0 +1,24 @@ +.secondary-text { + @apply font-medium text-gray-500; +} +.main-price { + @apply font-medium text-danger-500 text-title-md; +} +.action-wrapper { + @apply flex gap-x-2.5; +} +.quantity-input { + @apply px-2 rounded text-center border border-gray-300 w-14 h-10 focus:outline-none; +} + +.contact-us { + @apply text-danger-500 font-medium underline; +} + +.disc-badge { + @apply bg-danger-500 px-2 py-1.5 rounded text-white text-caption-2; +} + +.disc-price { + @apply line-through text-gray-600 text-caption-2; +} diff --git a/src-migrate/modules/product-detail/styles/product-detail.module.css b/src-migrate/modules/product-detail/styles/product-detail.module.css new file mode 100644 index 00000000..c668167c --- /dev/null +++ b/src-migrate/modules/product-detail/styles/product-detail.module.css @@ -0,0 +1,15 @@ +.title { + @apply font-medium text-h-lg leading-8 md:text-title-md md:leading-10; +} + +.section-card { + @apply p-4 md:p-6 md:bg-gray-50 rounded-xl; +} + +.heading { + @apply text-h-md md:text-h-lg font-medium; +} + +.description { + @apply leading-relaxed text-gray-700; +} diff --git a/src-migrate/modules/product-detail/styles/variant-list.module.css b/src-migrate/modules/product-detail/styles/variant-list.module.css new file mode 100644 index 00000000..6d46df84 --- /dev/null +++ b/src-migrate/modules/product-detail/styles/variant-list.module.css @@ -0,0 +1,35 @@ +.wrapper { + @apply grid grid-cols-1 w-[200%] md:w-full; +} + +.header { + @apply flex py-2.5 pl-4 font-medium bg-gray-200 rounded-md; +} + +.row { + @apply flex items-center py-2.5 pl-4 text-gray-800; +} + +.select-btn { + @apply !bg-gray-200 hover:!bg-danger-500 hover:!text-white; +} + +.select-btn--active { + @apply !text-white !bg-danger-500 hover:!text-white; +} + +.stock-empty { + @apply bg-red-50 border border-red-500 text-red-800; +} + +.stock-ready { + @apply bg-green-50 border border-green-500 text-green-800; +} + +.disc-badge { + @apply bg-danger-500 p-1 rounded text-white text-caption-2; +} + +.disc-price { + @apply text-caption-2 line-through text-gray-600; +} diff --git a/src-migrate/modules/product-promo/components/AddToCart.tsx b/src-migrate/modules/product-promo/components/AddToCart.tsx new file mode 100644 index 00000000..87017c14 --- /dev/null +++ b/src-migrate/modules/product-promo/components/AddToCart.tsx @@ -0,0 +1,100 @@ +import { Button, Spinner, useToast } from '@chakra-ui/react' +import { CheckIcon, PlusIcon } from 'lucide-react' +import { useRouter } from 'next/router' +import { useEffect, useState } from 'react' + +import { getAuth } from '~/libs/auth' +import { upsertUserCart } from '~/services/cart' +import { IPromotion } from '~/types/promotion' + +import DesktopView from '../../../../src/core/components/views/DesktopView'; +import MobileView from '../../../../src/core/components/views/MobileView'; + +type Props = { + promotion: IPromotion +} + +type Status = 'idle' | 'loading' | 'success' + +const ProductPromoAddToCart = ({ promotion }: Props) => { + const auth = getAuth() + const toast = useToast() + const router = useRouter() + + const [status, setStatus] = useState<Status>('idle') + + const handleButton = async () => { + if (typeof auth !== 'object') { + const currentUrl = encodeURIComponent(router.asPath) + router.push(`/login?next=${currentUrl}`) + return + } + if (status === 'success') return + + setStatus('loading') + await upsertUserCart({ + userId: auth.id, + type: 'promotion', + id: promotion.id, + qty: 1, + selected: true, + source: 'add_to_cart', + qtyAppend: true + }) + setStatus('idle') + + toast({ + title: 'Tambah ke keranjang', + description: 'Berhasil menambahkan barang ke keranjang belanja', + status: 'success', + duration: 3000, + isClosable: true, + position: 'top', + }) + } + + useEffect(() => { + if (status === 'success') setTimeout(() => { setStatus('idle') }, 3000) + }, [status]) + + return ( + <div> + <MobileView> + <Button + colorScheme='yellow' + px={2} + w='36px' + gap={1} + isDisabled={status === 'loading'} + onClick={handleButton} + > + {status === 'success' && <CheckIcon size={16} />} + {status === 'loading' && <Spinner size='xs' mr={1.5} />} + {status === 'idle' && <PlusIcon size={16} />} + + {status === 'success' && <span>Berhasil</span>} + {/* {status !== 'success' && <span>Keranjang</span>} */} + </Button> + </MobileView> + <DesktopView> + <Button + colorScheme='yellow' + px={2} + w='110px' + gap={1} + isDisabled={status === 'loading'} + onClick={handleButton} + > + {status === 'success' && <CheckIcon size={16} />} + {status === 'loading' && <Spinner size='xs' mr={1.5} />} + {status === 'idle' && <PlusIcon size={16} />} + + {status === 'success' && <span>Berhasil</span>} + {status !== 'success' && <span>Keranjang</span>} + </Button> + </DesktopView> + </div> + ) +} + +export default ProductPromoAddToCart
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx new file mode 100644 index 00000000..56e29e38 --- /dev/null +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -0,0 +1,206 @@ +import style from "../styles/card.module.css" + +import React, { useEffect, useMemo, useState } from 'react' +import { InfoIcon, PlusIcon } from "lucide-react" +import { Skeleton, Tooltip } from '@chakra-ui/react' +import { motion } from "framer-motion" + +import { PROMO_CATEGORY } from "~/constants/promotion" +import { getVariantById } from "~/services/productVariant" + +import { IProductVariantPromo, IPromotion } from '~/types/promotion' +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' + +import ProductPromoItem from './Item' +import ProductPromoAddToCart from "./AddToCart" +import ProductPromoCardCountdown from "./CardCountdown" + +import MobileView from '../../../../src/core/components/views/MobileView'; +import DesktopView from '../../../../src/core/components/views/DesktopView'; + +type Props = { + promotion: IPromotion + +} + +const ProductPromoCard = ({ promotion}: Props) => { + const [products, setProducts] = useState<IProductVariantPromo[]>([]) + const [freeProducts, setFreeProducts] = useState<IProductVariantPromo[]>([]) + const [error, setError] = useState<string | null>(null) + + useEffect(() => { + const getProducts = async () => { + try { + const datas = [] + for (const product of promotion.products) { + const res = await getVariantById(product.product_id) + res.data.qty = product.qty + datas.push(res.data) + } + setProducts(datas) + } catch (err) { + setError('Failed to fetch product variants.') + console.error(err) + } + } + + getProducts() + }, [promotion.products]) + + useEffect(() => { + const getFreeProducts = async () => { + try { + const datas = [] + for (const product of promotion.free_products) { + const res = await getVariantById(product.product_id) + res.data.qty = product.qty + datas.push(res.data) + } + setFreeProducts(datas) + } catch (err) { + setError('Failed to fetch free product variants.') + console.error(err) + } + } + + getFreeProducts() + }, [promotion.free_products]) + + const priceTotal = useMemo(() => { + let total = 0; + [...products, ...freeProducts].forEach((product) => { + total += product.price.price_discount * product.qty + }) + return total + }, [products, freeProducts]) + + const allProducts = [...products, ...freeProducts] + + + + return ( + <div> + <MobileView> + <div className={style.card}> + <ProductPromoCardCountdown promotion={promotion} /> + + <div className='px-4 mt-4 text-caption-1'> + <div className="flex justify-between items-center"> + <div className={style.title}>{promotion.name}</div> + + <Tooltip label={PROMO_CATEGORY[promotion.type.value].description} placement="top" bgColor='red.600' p={1} rounded={6}> + {/* <div className={style.badgeType} > */} + {/* Paket {PROMO_CATEGORY[promotion.type.value].alias} */} + <InfoIcon className={style.badgeType} size={25} /> + {/* </div> */} + </Tooltip> + </div> + + <Skeleton className={clsxm(style.productSection, { 'justify-center': allProducts.length === 2 })} isLoaded={allProducts.length > 0}> + {allProducts.map((product, index) => ( + <React.Fragment key={product.id}> + <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.6 }}> + <ProductPromoItem + variant={product} + isFree={index + 1 > products.length && promotion.type.value === 'merchandise'} + // isFree={index + 1 > products.length } + /> + </motion.div> + <motion.div initial={{ y: 30, opacity: 0 }} animate={{ y: 0, opacity: 1 }} transition={{ duration: 0.5, delay: 0.1 }}> + {index + 1 < allProducts.length && ( + <div className="h-fit p-1 rounded-full border border-danger-500 text-danger-500 mt-[38px]"> + <PlusIcon size={14} strokeWidth='2px' /> + </div> + )} + </motion.div> + </React.Fragment> + ))} + </Skeleton> + + <div className={style.priceSection}> + <div className={style.priceCol}> + <Skeleton className={style.priceRow} isLoaded={priceTotal > 0}> + <span className={style.basePrice}>Rp{formatCurrency(priceTotal)}</span> + <span className="text-[11px]">Hemat <span className={style.savingAmt}>Rp {formatCurrency(priceTotal - promotion.price)}</span></span> + </Skeleton> + + <div className={style.priceRow}> + <span className={style.price}>Rp{formatCurrency(promotion.price)}</span> + <span className={style.totalItems}>(Total {promotion.total_qty} barang)</span> + </div> + + </div> + <div> + <ProductPromoAddToCart promotion={promotion} /> + </div> + + </div> + </div> + </div> + </MobileView> + <DesktopView> + <div className={style.card}> + <ProductPromoCardCountdown promotion={promotion} /> + + <div className='px-4 mt-4 text-caption-1'> + <div className="flex justify-between items-center"> + <div className={style.title}>{promotion.name}</div> + + <Tooltip label={PROMO_CATEGORY[promotion.type.value].description} placement="top" bgColor='red.600' p={2} rounded={6}> + <div className={style.badgeType}> + Paket {PROMO_CATEGORY[promotion.type.value].alias} + <InfoIcon size={16} /> + </div> + </Tooltip> + </div> + + <Skeleton className={clsxm(style.productSection, { 'justify-center': allProducts.length === 2 })} isLoaded={allProducts.length > 0}> + {allProducts.map((product, index) => ( + <React.Fragment key={product.id}> + <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.6 }}> + <ProductPromoItem + variant={product} + isFree={index + 1 > products.length && promotion.type.value === 'merchandise'} + // isFree={index + 1 > products.length } + /> + </motion.div> + <motion.div initial={{ y: 30, opacity: 0 }} animate={{ y: 0, opacity: 1 }} transition={{ duration: 0.5, delay: 0.1 }}> + {index + 1 < allProducts.length && ( + <div className="h-fit p-1 rounded-full border border-danger-500 text-danger-500 mt-[38px]"> + <PlusIcon size={14} strokeWidth='2px' /> + </div> + )} + </motion.div> + </React.Fragment> + ))} + </Skeleton> + + <div className={style.priceSection}> + <div className={style.priceCol}> + <Skeleton className={style.priceRow} isLoaded={priceTotal > 0}> + <span className={style.basePrice}>Rp{formatCurrency(priceTotal)}</span> + <span>Hemat <span className={style.savingAmt}>Rp {formatCurrency(priceTotal - promotion.price)}</span></span> + </Skeleton> + + <div className={style.priceRow}> + <span className={style.price}>Rp{formatCurrency(promotion.price)}</span> + <span className={style.totalItems}>(Total {promotion.total_qty} barang)</span> + </div> + </div> + <div> + <ProductPromoAddToCart promotion={promotion} /> + </div> + + </div> + </div> + </div> + </DesktopView> + </div> + // shouldRender && ( + + // ) + ) +} + +export default ProductPromoCard diff --git a/src-migrate/modules/product-promo/components/CardCountdown.tsx b/src-migrate/modules/product-promo/components/CardCountdown.tsx new file mode 100644 index 00000000..b61ad115 --- /dev/null +++ b/src-migrate/modules/product-promo/components/CardCountdown.tsx @@ -0,0 +1,67 @@ +import style from '../styles/card-countdown.module.css' + +import React, { useEffect, useState } from 'react' +import { useQuery } from 'react-query' +import { ClockIcon } from 'lucide-react' +import { Skeleton } from '@chakra-ui/react' +import moment from 'moment' + +import clsxm from '~/libs/clsxm' +import { IPromotion } from '~/types/promotion' +import { getPromotionProgram } from '~/services/promotionProgram' + +type Props = { + promotion: IPromotion +} + +const ProductPromoCardCountdown = ({ promotion }: Props) => { + const query = useQuery(['promotion-program', promotion.program_id], async () => { + return await getPromotionProgram(promotion.program_id) + }) + + const program = query.data?.data || null + + const [count, setCount] = useState(program?.time_left || 0); + + useEffect(() => { + let interval: NodeJS.Timeout; + + if (program?.time_left && program?.time_left > 0) { + setCount(program?.time_left); + + interval = setInterval(() => { + setCount((prevCount) => prevCount - 1); + }, 1000); + } + + return () => { + clearInterval(interval); + }; + }, [program?.time_left]); + + const duration = moment.duration(count, 'seconds') + + const countdownClass = { + 'text-white': true, + 'bg-[#312782]': promotion.type.value === 'bundling', + 'bg-[#329E44]': promotion.type.value === 'discount_loading', + 'bg-[#FAD147]': promotion.type.value === 'merchandise', + 'text-gray-700': promotion.type.value === 'merchandise', + } + + return ( + <Skeleton isLoaded={query.isFetched} className={clsxm(style.countdownSection, countdownClass)}> + <span> + <ClockIcon size={20} /> + </span> + <span>Berakhir dalam</span> + <div className={style.countdown}> + <span>{duration.hours().toString().padStart(2, '0')}</span> + <span>{duration.minutes().toString().padStart(2, '0')}</span> + <span>{duration.seconds().toString().padStart(2, '0')}</span> + </div> + </Skeleton> + ) +} + +export default ProductPromoCardCountdown
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/CategoryTab.tsx b/src-migrate/modules/product-promo/components/CategoryTab.tsx new file mode 100644 index 00000000..c8e698c2 --- /dev/null +++ b/src-migrate/modules/product-promo/components/CategoryTab.tsx @@ -0,0 +1,34 @@ +import React from 'react' +import style from '../styles/category-tab.module.css' +import { useModalStore } from '../stores/useModalStore' +import clsxm from '~/libs/clsxm' +import { ICategoryPromo } from '~/types/promotion' + +const TABS: ICategoryPromo[] = [ + { value: 'bundling', label: 'Bundling' }, + { value: 'discount_loading', label: 'Discount Loading' }, + { value: 'merchandise', label: 'Free Merchant' }, +] + +const ProductPromoCategoryTab = () => { + const { activeTab, changeTab } = useModalStore() + return ( + <div className={style.tabs}> + {TABS.map((tab) => ( + <button + key={tab.value} + type='button' + className={clsxm({ + [style.tab]: true, + [style.tabActive]: activeTab === tab.value + })} + onClick={() => changeTab(tab.value)} + > + {tab.label} + </button> + ))} + </div> + ) +} + +export default ProductPromoCategoryTab
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/Item.tsx b/src-migrate/modules/product-promo/components/Item.tsx new file mode 100644 index 00000000..b396160f --- /dev/null +++ b/src-migrate/modules/product-promo/components/Item.tsx @@ -0,0 +1,34 @@ +import style from '../styles/item.module.css' + +import { Tooltip } from '@chakra-ui/react' + +import Image from '~/components/ui/image' +import { IProductVariantPromo } from '~/types/promotion' + +type Props = { + variant: IProductVariantPromo, + isFree?: boolean +} + +const ProductPromoItem = ({ + variant, + isFree = false +}: Props) => { + return ( + <div className={style.item}> + <div className={style.image}> + <Image src={variant.image || '/images/noimage.jpeg'} alt={variant.display_name} width={120} height={120} quality={100} /> + <div className={style.quantity}> + {variant.qty} pcs {isFree ? '(free)' : ''} + </div> + </div> + <Tooltip label={variant.display_name} placement='top' fontSize='sm'> + <div className={style.name}> + {variant.name} + </div> + </Tooltip> + </div> + ) +} + +export default ProductPromoItem
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/Modal.tsx b/src-migrate/modules/product-promo/components/Modal.tsx new file mode 100644 index 00000000..0de672c2 --- /dev/null +++ b/src-migrate/modules/product-promo/components/Modal.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import { Modal } from "~/components/ui/modal" +import { useModalStore } from '../stores/useModalStore' +import ProductPromoCategoryTab from './CategoryTab' +import ProductPromoModalContent from './ModalContent' + +const ProductPromoModal = () => { + const { active, closeModal } = useModalStore() + + return ( + <Modal + active={active} + close={closeModal} + title='Promo Tersedia' + > + <ProductPromoCategoryTab /> + + <div className='h-4' /> + + <ProductPromoModalContent /> + </Modal> + ) +} + +export default ProductPromoModal
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/ModalContent.tsx b/src-migrate/modules/product-promo/components/ModalContent.tsx new file mode 100644 index 00000000..ab5129f8 --- /dev/null +++ b/src-migrate/modules/product-promo/components/ModalContent.tsx @@ -0,0 +1,37 @@ +import { useQuery } from "react-query" +import { Skeleton } from "@chakra-ui/react" + +import { getVariantPromoByCategory } from "~/services/productVariant" + +import { useModalStore } from "../stores/useModalStore" +import ProductPromoCard from "./Card" + +const ProductPromoModalContent = () => { + const { activeTab, variantId } = useModalStore() + + const promotionsQuery = useQuery( + `variant-promo:${variantId}:${activeTab}`, + async () => { + if (!variantId) return + + return getVariantPromoByCategory(variantId, activeTab) + }, + ) + + const promotions = promotionsQuery.data + + return ( + <Skeleton isLoaded={!promotionsQuery.isLoading} className='min-h-[70vh] max-h-[70vh]'> + <div className="grid grid-cols-1 gap-y-6 pb-6"> + {promotions?.data.map((promo) => ( + <ProductPromoCard key={promo.id} promotion={promo} /> + ))} + {promotions?.data.length === 0 && ( + <div className="py-10 rounded-lg h-fit text-center text-body-1 font-semibold text-gray-800 bg-gray-200">Belum ada promo pada kategori ini</div> + )} + </div> + </Skeleton> + ) +} + +export default ProductPromoModalContent
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/Section.tsx b/src-migrate/modules/product-promo/components/Section.tsx new file mode 100644 index 00000000..4e8a7dd5 --- /dev/null +++ b/src-migrate/modules/product-promo/components/Section.tsx @@ -0,0 +1,61 @@ +import style from "../styles/section.module.css" + +import { Button, Skeleton } from '@chakra-ui/react' +import { useQuery } from 'react-query' + +import SmoothRender from "~/components/ui/smooth-render" +import clsxm from "~/libs/clsxm" +import { IPromotion } from '~/types/promotion' +import { useModalStore } from "../stores/useModalStore" +import ProductPromoCard from './Card' +import ProductPromoModal from "./Modal" + +type Props = { + productId: number; +} + +const ProductPromoSection = ({ productId }: Props) => { + const promotionsQuery = useQuery({ + queryKey: [`promotions.highlight`, productId], + queryFn: async () => await fetch(`/api/product-variant/${productId}/promotion/highlight`).then((res) => res.json()) as { data: IPromotion[] } + }) + + const promotions = promotionsQuery.data + + const { openModal } = useModalStore() + + return ( + <SmoothRender + isLoaded={(promotions?.data && promotions?.data.length > 0) || false} + height='450px' + duration='700ms' + > + <ProductPromoModal /> + + {promotions?.data && promotions?.data.length > 0 && ( + <div className={style.titleWrapper}> + <span className={style.title}>Promo Tersedia</span> + <Button colorScheme="yellow" type='button' onClick={() => openModal(productId)}> + Lihat Semua + </Button> + </div> + )} + + <Skeleton + isLoaded={promotionsQuery.isSuccess} + className={clsxm( + "flex gap-x-4 overflow-x-auto px-4 md:px-0", { + "min-h-[340px]": promotions?.data && promotions?.data.length > 0 + })} + > + {promotions?.data.map((promotion) => ( + <div key={promotion.id} className="min-w-[400px] max-w-[400px]"> + <ProductPromoCard promotion={promotion} /> + </div> + ))} + </Skeleton> + </SmoothRender> + ) +} + +export default ProductPromoSection
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/stores/useModalStore.ts b/src-migrate/modules/product-promo/stores/useModalStore.ts new file mode 100644 index 00000000..464bb598 --- /dev/null +++ b/src-migrate/modules/product-promo/stores/useModalStore.ts @@ -0,0 +1,28 @@ +import { create } from 'zustand'; +import { CategoryPromo } from '~/types/promotion'; + +type State = { + active: boolean; + variantId?: number; + activeTab: CategoryPromo; +}; + +type Action = { + openModal: (variantId: number) => void; + closeModal: () => void; + changeTab: (tab: State['activeTab']) => void; +}; + +const defaultState: Omit<State, 'activeTab'> = { + active: false, + variantId: undefined, +}; + +export const useModalStore = create<State & Action>((set) => ({ + ...defaultState, + activeTab: 'bundling', + openModal: (variantId: number) => set({ active: true, variantId }), + closeModal: () => set(defaultState), + // TABS + changeTab: (tab) => set({ activeTab: tab }), +})); diff --git a/src-migrate/modules/product-promo/styles/card-countdown.module.css b/src-migrate/modules/product-promo/styles/card-countdown.module.css new file mode 100644 index 00000000..dae8945f --- /dev/null +++ b/src-migrate/modules/product-promo/styles/card-countdown.module.css @@ -0,0 +1,14 @@ +.countdownSection { + @apply w-fit p-2.5 pr-6 + rounded-r-full + font-medium + flex items-center gap-x-2.5; +} + +.countdown { + @apply flex gap-x-1; +} + +.countdown span { + @apply py-0.5 w-8 bg-red-600 text-gray_r-4 rounded-md text-center; +}
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/styles/card.module.css b/src-migrate/modules/product-promo/styles/card.module.css new file mode 100644 index 00000000..faa3b370 --- /dev/null +++ b/src-migrate/modules/product-promo/styles/card.module.css @@ -0,0 +1,58 @@ +.card { + @apply border border-gray_r-7 + rounded-lg + h-fit + py-3; +} + +.title { + @apply font-semibold text-h-md; +} + +.badgeType { + @apply p-2 flex gap-x-1.5 rounded-md border border-danger-500 text-danger-500; +} + +.productSection { + @apply flex gap-x-2 overflow-x-auto overflow-y-hidden mt-4 min-h-[160px]; +} + +.priceSection { + @apply flex items-center justify-between mt-4; +} + +.priceCol { + @apply flex flex-col gap-y-1; +} + +.priceRow { + @apply flex gap-x-2 items-center; +} + +.basePrice { + @apply line-through; +} + +.savingAmt { + @apply text-success-600 font-medium; +} + +.price { + @apply text-body-1 text-danger-600 font-medium; +} + +.totalItems { + @apply text-gray_r-9; +} + +@media only screen and (max-width: 384px) { + .basePrice { + @apply text-[13px]; + } + .price{ + @apply text-[15px]; + } + .totalItems{ + @apply text-[11px]; + } + }
\ No newline at end of file diff --git a/src-migrate/modules/product-promo/styles/category-tab.module.css b/src-migrate/modules/product-promo/styles/category-tab.module.css new file mode 100644 index 00000000..cab2cb1b --- /dev/null +++ b/src-migrate/modules/product-promo/styles/category-tab.module.css @@ -0,0 +1,12 @@ +.tabs { + @apply flex gap-x-4; +} + +.tab { + @apply py-1.5 duration-300; + transition-property: background-color; +} + +.tabActive { + @apply cursor-default border-b-2 border-danger-500 font-medium; +} diff --git a/src-migrate/modules/product-promo/styles/item.module.css b/src-migrate/modules/product-promo/styles/item.module.css new file mode 100644 index 00000000..b6a8b2ef --- /dev/null +++ b/src-migrate/modules/product-promo/styles/item.module.css @@ -0,0 +1,19 @@ +.item { + @apply w-[100px] h-[100px]; +} + +.image { + @apply w-full h-[100px] relative border border-gray_r-6 p-2.5 rounded-lg mb-3; +} + +.fillDesc { + @apply mt-2 text-danger-600; +} + +.quantity { + @apply backdrop-blur-lg border border-danger-300 text-danger-600 font-semibold px-2 py-1 text-caption-2 flex items-center justify-center rounded absolute bottom-2.5; +} + +.name { + @apply mt-1 line-clamp-2 leading-5 font-medium; +} diff --git a/src-migrate/modules/product-promo/styles/section.module.css b/src-migrate/modules/product-promo/styles/section.module.css new file mode 100644 index 00000000..d830f5d4 --- /dev/null +++ b/src-migrate/modules/product-promo/styles/section.module.css @@ -0,0 +1,7 @@ +.titleWrapper { + @apply w-full mb-4 h-20 bg-[#C70817] rounded-none md:rounded-lg flex items-center justify-between px-4 py-1; +} + +.title { + @apply font-semibold text-xl text-white; +} diff --git a/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx b/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx new file mode 100644 index 00000000..f2c49472 --- /dev/null +++ b/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx @@ -0,0 +1,15 @@ +import { useQuery } from 'react-query' +import { GetProductSimilarProps, getProductSimilar } from '~/services/product' + +type Props = GetProductSimilarProps + +const useProductSimilar = (props: Props) => { + const similarQuery = useQuery({ + queryKey: ['product-similar', props], + queryFn: () => getProductSimilar(props), + }) + + return similarQuery +} + +export default useProductSimilar
\ No newline at end of file diff --git a/src-migrate/modules/product-slider/components/ProductSlider.tsx b/src-migrate/modules/product-slider/components/ProductSlider.tsx new file mode 100644 index 00000000..05f8c322 --- /dev/null +++ b/src-migrate/modules/product-slider/components/ProductSlider.tsx @@ -0,0 +1,42 @@ +import 'swiper/css' + +import React from 'react' +import { Swiper, SwiperSlide } from 'swiper/react' +import { FreeMode } from 'swiper' + +import ProductCard from '~/modules/product-card' +import { IProduct } from '~/types/product' +import useDevice from '@/core/hooks/useDevice' + +type Props = { + products: IProduct[], + productLayout?: 'vertical' | 'horizontal', +} + +const ProductSlider = ({ products, productLayout }: Props) => { + const { isDesktop } = useDevice() + + return ( + <div> + <Swiper + slidesPerView={isDesktop ? 6.7 : 2.2} + spaceBetween={isDesktop ? 16 : 12} + prefix='product-slider' + modules={[FreeMode]} + freeMode={{ enabled: true, sticky: false }} + className='!pb-0.5' + > + {products.map((product) => ( + <SwiperSlide key={product.id}> + <ProductCard + product={product} + layout={productLayout} + /> + </SwiperSlide> + ))} + </Swiper> + </div > + ) +} + +export default ProductSlider
\ No newline at end of file diff --git a/src-migrate/modules/product-slider/index.ts b/src-migrate/modules/product-slider/index.ts new file mode 100644 index 00000000..1593a543 --- /dev/null +++ b/src-migrate/modules/product-slider/index.ts @@ -0,0 +1,3 @@ +import ProductSlider from './components/ProductSlider'; + +export default ProductSlider; diff --git a/src-migrate/modules/register/components/Form.tsx b/src-migrate/modules/register/components/Form.tsx index e9dc4906..4baaf380 100644 --- a/src-migrate/modules/register/components/Form.tsx +++ b/src-migrate/modules/register/components/Form.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, useMemo } from "react"; import { useMutation } from "react-query"; -import { useRegisterStore } from "~/common/stores/useRegisterStore"; -import { RegisterProps } from "~/common/types/auth"; +import { useRegisterStore } from "../stores/useRegisterStore"; +import { RegisterProps } from "~/types/auth"; import { registerUser } from "~/services/auth"; import TermCondition from "./TermCondition"; import FormCaptcha from "./FormCaptcha"; diff --git a/src-migrate/modules/register/components/FormCaptcha.tsx b/src-migrate/modules/register/components/FormCaptcha.tsx index 967be017..fbea2b10 100644 --- a/src-migrate/modules/register/components/FormCaptcha.tsx +++ b/src-migrate/modules/register/components/FormCaptcha.tsx @@ -1,5 +1,5 @@ -import ReCaptcha from '~/common/components/elements/ReCaptcha' -import { useRegisterStore } from '~/common/stores/useRegisterStore' +import { ReCaptcha } from '~/components/ui/re-captcha' +import { useRegisterStore } from "../stores/useRegisterStore"; const FormCaptcha = () => { const { updateValidCaptcha } = useRegisterStore() diff --git a/src-migrate/modules/register/components/TermCondition.tsx b/src-migrate/modules/register/components/TermCondition.tsx index 6b95ba19..b7729deb 100644 --- a/src-migrate/modules/register/components/TermCondition.tsx +++ b/src-migrate/modules/register/components/TermCondition.tsx @@ -1,7 +1,7 @@ import { Checkbox } from '@chakra-ui/react' import React from 'react' -import Modal from '~/common/components/elements/Modal' -import { useRegisterStore } from '~/common/stores/useRegisterStore' +import { Modal } from '~/components/ui/modal' +import { useRegisterStore } from "../stores/useRegisterStore"; import PageContent from '~/modules/page-content' const TermCondition = () => { diff --git a/src-migrate/common/stores/useRegisterStore.ts b/src-migrate/modules/register/stores/useRegisterStore.ts index 90ce8a2b..d8abf52b 100644 --- a/src-migrate/common/stores/useRegisterStore.ts +++ b/src-migrate/modules/register/stores/useRegisterStore.ts @@ -1,6 +1,6 @@ import { create } from 'zustand'; -import { RegisterProps } from '../types/auth'; -import { registerSchema } from '../validations/auth'; +import { RegisterProps } from '~/types/auth'; +import { registerSchema } from '~/validations/auth'; import { ZodError } from 'zod'; type State = { diff --git a/src-migrate/modules/side-banner/index.tsx b/src-migrate/modules/side-banner/index.tsx new file mode 100644 index 00000000..6214edfb --- /dev/null +++ b/src-migrate/modules/side-banner/index.tsx @@ -0,0 +1,30 @@ +import React, { useMemo } from "react"; +import Link from "next/link"; +import { useQuery } from "react-query"; +import Image from "~/components/ui/image"; +import { getBanner } from "~/services/banner"; +import { getRandomInt } from '@/utils/getRandomInt'; + +const SideBanner = () => { + const fetchSideBanner = useQuery({ + queryKey: 'sideBanner', + queryFn: () => getBanner({ type: 'side-banner-search' }) + }); + // ubah dari static menjadid dynamic dengan menggunakan random index + const length = useMemo(() => fetchSideBanner.data?.length, [fetchSideBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchSideBanner?.data?.[randomIndex] || false; + + return banner && ( + <> + {banner.url ? ( + <Link href={banner.url}> + <Image src={banner.image} alt={banner.name} width={315} height={450} className='object-cover object-center rounded-lg' /> + </Link> + ) : ( + <Image src={banner.image} alt={banner.name} width={315} height={450} className='object-cover object-center rounded-lg' /> + )} + </> + ); +} +export default SideBanner; diff --git a/src-migrate/pages/_app.tsx b/src-migrate/pages/_app.tsx index 2dc82559..36640c04 100644 --- a/src-migrate/pages/_app.tsx +++ b/src-migrate/pages/_app.tsx @@ -1,5 +1,5 @@ -import '~/common/styles/fonts/Inter/inter.css' -import '~/common/styles/globals.css' +import '~/styles/fonts/Inter/inter.css' +import '~/styles/globals.css' import type { AppProps } from "next/app" export default function MyApp({ Component, pageProps }: AppProps) { diff --git a/src-migrate/pages/api/product-variant/[id].tsx b/src-migrate/pages/api/product-variant/[id].tsx new file mode 100644 index 00000000..955fde6a --- /dev/null +++ b/src-migrate/pages/api/product-variant/[id].tsx @@ -0,0 +1,53 @@ +import moment from "moment"; +import { NextApiRequest, NextApiResponse } from "next"; +import { SolrResponse } from "~/types/solr"; + +const SOLR_HOST = process.env.SOLR_HOST as string + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const variantId = req.query.id as string + let price_tier = 'tier1' + + let auth = req.cookies.auth ? JSON.parse(req.cookies.auth) : null + if (auth?.pricelist) price_tier = auth.pricelist + + if (req.method === 'GET') { + const queryParams = new URLSearchParams({ q: `id:${variantId}` }) + const response = await fetch(`${SOLR_HOST}/solr/variants/select?${queryParams.toString()}`) + const data: SolrResponse<any[]> = await response.json() + + if (data.response.numFound === 0) { + res.status(404).json({ error: 'Variant not found' }) + return + } + + const variant = await map(data.response.docs[0], price_tier) + + res.status(200).json({ data: variant }) + } +} + +const map = async (variant: any, price_tier: string) => { + const data: any = {} + const price = variant[`price_${price_tier}_v2_f`] || 0 + + data.id = parseInt(variant.id) + data.parent_id = variant.template_id_i + data.display_name = variant.display_name_s + data.image = variant.image_s + data.name = variant.name_s + data.default_code = variant.default_code_s + data.price = { discount_percentage: 0, price, price_discount: price } + + return data +} + +const checkIsFlashsale = (variant: any) => { + const endDateStr = variant.flashsale_end_date_s || null + if (!endDateStr) return false + + const now = moment() + const endDate = moment(endDateStr, 'YYYY-MM-DD HH:mm:ss') + + return variant.flashsale_id_i > 0 && now.isSameOrBefore(endDate) +}
\ No newline at end of file diff --git a/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx b/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx new file mode 100644 index 00000000..8da0d9a3 --- /dev/null +++ b/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx @@ -0,0 +1,49 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import { SolrResponse } from "~/types/solr"; + +const SOLR_HOST = process.env.SOLR_HOST as string + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const productId = req.query.id as string + const category = req.query.category as string + + if (req.method === 'GET') { + const queryParams = new URLSearchParams({ q: `product_ids:${productId}` }) + queryParams.append('fq', `type_value_s:${category}`) + queryParams.append('fq', `active_b:true`) + + const response = await fetch(`${SOLR_HOST}/solr/promotion_program_lines/select?${queryParams.toString()}`) + const data: SolrResponse<any[]> = await response.json() + + const promotions = await map(data.response.docs) + res.status(200).json({ data: promotions }) + } +} + +const map = async (promotions: any[]) => { + const result = [] + + for (const promotion of promotions) { + const data: any = {} + + data.id = promotion.id + data.program_id = promotion.program_id_i + data.name = promotion.name_s + data.type = { + value: promotion.type_value_s, + label: promotion.type_label_s, + } + data.limit = promotion.package_limit_i + data.limit_user = promotion.package_limit_user_i + data.limit_trx = promotion.package_limit_trx_i + data.price = promotion.price_f + data.total_qty = promotion.total_qty_i + + data.products = JSON.parse(promotion.products_s) + data.free_products = JSON.parse(promotion.free_products_s) + + result.push(data) + } + + return result +}
\ No newline at end of file diff --git a/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx b/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx new file mode 100644 index 00000000..c4acacf1 --- /dev/null +++ b/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx @@ -0,0 +1,58 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import { SolrResponse } from "~/types/solr"; + +const SOLR_HOST = process.env.SOLR_HOST as string + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const productId = req.query.id as string + + if (req.method === 'GET') { + const types = ['bundling', 'discount_loading', 'merchandise'] + const queryParams = new URLSearchParams({ + q: `product_ids:${productId}`, + rows: '1' + }) + + let programs: any[] = [] + + for (const type of types) { + queryParams.set('fq', `type_value_s:${type}`) + queryParams.append('fq', `active_b:true`) + + const response = await fetch(`${SOLR_HOST}/solr/promotion_program_lines/select?${queryParams.toString()}`) + const data: SolrResponse<any[]> = await response.json() + programs.push(...data.response.docs) + } + + programs = await extractPrograms(programs) + res.status(200).json({ data: programs }) + } +} + +const extractPrograms = async (programs: any[]) => { + const result = [] + + for (const program of programs) { + const data: any = {} + + data.id = program.id + data.program_id = program.program_id_i + data.name = program.name_s + data.type = { + value: program.type_value_s, + label: program.type_label_s, + } + data.limit = program.package_limit_i + data.limit_user = program.package_limit_user_i + data.limit_trx = program.package_limit_trx_i + data.price = program.price_f + data.total_qty = program.total_qty_i + + data.products = JSON.parse(program.products_s) + data.free_products = JSON.parse(program.free_products_s) + + result.push(data) + } + + return result +}
\ No newline at end of file diff --git a/src-migrate/pages/api/promotion-program/[id].tsx b/src-migrate/pages/api/promotion-program/[id].tsx new file mode 100644 index 00000000..c509b802 --- /dev/null +++ b/src-migrate/pages/api/promotion-program/[id].tsx @@ -0,0 +1,42 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import { SolrResponse } from "~/types/solr"; + +const SOLR_HOST = process.env.SOLR_HOST as string + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const id = req.query.id as string + + if (req.method === 'GET') { + const queryParams = new URLSearchParams({ q: `id:${id}` }) + const response = await fetch(`${SOLR_HOST}/solr/promotion_programs/select?${queryParams.toString()}`) + const data: SolrResponse<any[]> = await response.json() + + if (data.response.numFound === 0) { + res.status(404).json({ error: 'Program not found' }) + return + } + + const program = await map(data.response.docs[0]) + + res.status(200).json({ data: program }) + } +} + +const map = async (program: any) => { + const data: any = {} + + data.id = program.id + data.name = program.name_s + data.start_time = program.start_time_s + data.end_time = program.end_time_s + data.applies_to = program.applies_to_s + data.time_left = (new Date(data.end_time).getTime() - new Date().getTime()) / 1000 + + // const duration = moment.duration(data.time_left, 'seconds') + // const days = duration.days() + // const hours = duration.hours() + // const minutes = duration.minutes() + // const seconds = duration.seconds() + + return data +}
\ No newline at end of file diff --git a/src-migrate/pages/register.tsx b/src-migrate/pages/register.tsx index 1246c6f5..136eaa3b 100644 --- a/src-migrate/pages/register.tsx +++ b/src-migrate/pages/register.tsx @@ -1,7 +1,7 @@ import BasicLayout from "@/core/components/layouts/BasicLayout" import { useWindowSize } from "usehooks-ts" -import Seo from "~/common/components/elements/Seo" +import { Seo } from "~/components/seo" import Register from "~/modules/register" const RegisterPage = () => { diff --git a/src-migrate/pages/shop/cart/cart.module.css b/src-migrate/pages/shop/cart/cart.module.css new file mode 100644 index 00000000..806104be --- /dev/null +++ b/src-migrate/pages/shop/cart/cart.module.css @@ -0,0 +1,35 @@ +.title { + @apply text-h-lg font-semibold; +} + +.content { + @apply flex flex-wrap ; +} + +.item-wrapper { + @apply w-full md:w-3/4 min-h-screen; +} + +.item-skeleton { + @apply grid grid-cols-1 gap-y-4; +} + +.items { + @apply flex flex-col gap-y-6 border-t border-gray-300 pt-6; +} + +.summary-wrapper { + @apply w-full md:w-1/4 md:pl-6 mt-6 md:mt-0 bottom-0 md:sticky sticky bg-white; +} + +.summary { + @apply border border-gray-300 p-4 rounded-md sticky top-[180px]; +} + +.summary-buttons { + @apply grid grid-cols-2 gap-x-3 mt-6; +} + +.summary-buttons-step-approval { + @apply grid grid-cols-1 gap-y-3 mt-6; +} diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx new file mode 100644 index 00000000..d89707d2 --- /dev/null +++ b/src-migrate/pages/shop/cart/index.tsx @@ -0,0 +1,156 @@ +import style from './cart.module.css'; + +import React, { useEffect, useMemo } from 'react'; +import Link from 'next/link'; +import { Button, Tooltip } from '@chakra-ui/react'; + +import { getAuth } from '~/libs/auth'; +import { useCartStore } from '~/modules/cart/stores/useCartStore'; + +import CartItem from '~/modules/cart/components/Item'; +import CartSummary from '~/modules/cart/components/Summary'; +import clsxm from '~/libs/clsxm'; +import useDevice from '@/core/hooks/useDevice'; +import CartSummaryMobile from '~/modules/cart/components/CartSummaryMobile'; +import Image from '~/components/ui/image'; + +const CartPage = () => { + const auth = getAuth(); + const [isStepApproval, setIsStepApproval] = React.useState(false); + + const { loadCart, cart, summary } = useCartStore(); + + const useDivvice = useDevice(); + + useEffect(() => { + if (typeof auth === 'object' && !cart) { + loadCart(auth.id); + setIsStepApproval(auth?.feature?.soApproval); + } + }, [auth, loadCart, cart]); + + const hasSelectedPromo = useMemo(() => { + if (!cart) return false; + for (const item of cart.products) { + if (item.cart_type === 'promotion' && item.selected) return true; + } + return false; + }, [cart]); + + const hasSelected = useMemo(() => { + if (!cart) return false; + for (const item of cart.products) { + if (item.selected) return true; + } + return false; + }, [cart]); + + const hasSelectNoPrice = useMemo(() => { + if (!cart) return false; + for (const item of cart.products) { + if (item.selected && item.price.price_discount == 0) return true; + } + return false; + }, [cart]); + + return ( + <> + <div className={style['title']}>Keranjang Belanja</div> + + <div className='h-6' /> + + <div className={style['content']}> + <div className={style['item-wrapper']}> + <div className={style['item-skeleton']}> + {!cart && <CartItem.Skeleton count={5} height='120px' />} + </div> + + <div className={style['items']}> + {cart?.products.map((item) => ( + <CartItem key={item.id} item={item} /> + ))} + + {cart?.products?.length === 0 && ( + <div className='flex flex-col items-center'> + <Image + src='/images/empty_cart.svg' + alt='Empty Cart' + width={450} + height={450} + /> + <div className='text-title-sm md:text-title-lg text-center font-semibold'> + Keranjangnya masih kosong nih + </div> + <div className='text-body-2 md:text-body-1 text-center mt-3'> + Yuk, tambahin barang-barang yang kamu mau ke keranjang + sekarang! + <br /> + Ada banyak potongan belanjanya pakai kode voucher + </div> + <Link + href='/' + className='btn-solid-red rounded-full text-body-1 mt-6' + > + Mulai Belanja + </Link> + </div> + )} + </div> + </div> + <div + className={`${style['summary-wrapper']} ${ + useDivvice.isMobile && cart?.product_total === 0 ? 'hidden' : '' + }`} + > + <div className={style['summary']}> + {useDivvice.isMobile && ( + <CartSummaryMobile {...summary} isLoaded={!!cart} /> + )} + {!useDivvice.isMobile && ( + <CartSummary {...summary} isLoaded={!!cart} /> + )} + + <div className={isStepApproval ? style['summary-buttons-step-approval'] : style['summary-buttons'] }> + <Tooltip + label={ + hasSelectedPromo && + 'Barang promo tidak dapat dibuat quotation' + } + > + <Button + colorScheme='yellow' + w='full' + isDisabled={hasSelectedPromo || !hasSelected} + as={Link} + href='/shop/quotation' + > + Quotation + </Button> + </Tooltip> + {!isStepApproval && ( + <Tooltip + label={clsxm({ + 'Tidak ada item yang dipilih': !hasSelected, + 'Terdapat item yang tidak ada harga': hasSelectNoPrice, + })} + > + <Button + colorScheme='red' + w='full' + isDisabled={!hasSelected || hasSelectNoPrice} + as={Link} + href='/shop/checkout' + > + Checkout + </Button> + </Tooltip> + )} + </div> + </div> + </div> + </div> + </> + ); +}; + +export default CartPage; diff --git a/src-migrate/pages/shop/product/[slug].tsx b/src-migrate/pages/shop/product/[slug].tsx new file mode 100644 index 00000000..fc72a6b0 --- /dev/null +++ b/src-migrate/pages/shop/product/[slug].tsx @@ -0,0 +1,83 @@ +import { GetServerSideProps, NextPage } from 'next' +import React, { useEffect } from 'react' +import dynamic from 'next/dynamic' +import cookie from 'cookie' + +import { getProductById } from '~/services/product' +import { getIdFromSlug } from '~/libs/slug' +import { IProductDetail } from '~/types/product' + +import { Seo } from '~/components/seo' +import { useRouter } from 'next/router' +import { useProductContext } from '@/contexts/ProductContext' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout'), { ssr: false }) +const ProductDetail = dynamic(() => import('~/modules/product-detail'), { ssr: false }) + +type PageProps = { + product: IProductDetail +} + +export const getServerSideProps: GetServerSideProps<PageProps> = (async (context) => { + const { slug } = context.query + const cookieString = context.req.headers.cookie; + const cookies = cookieString ? cookie.parse(cookieString) : {}; + const auth = cookies?.auth ? JSON.parse(cookies.auth) : {}; + const tier = auth?.pricelist || '' + + const productId = getIdFromSlug(slug as string) + + const product = await getProductById(productId, tier) + + if (!product) return { notFound: true } + + return { + props: { product } + } +}) + +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST + +const ProductDetailPage: NextPage<PageProps> = ({ product }) => { + const router = useRouter(); + + const { setProduct } = useProductContext(); + + useEffect(() => { + if (product) setProduct(product); + }, [product, setProduct]); + + return ( + <BasicLayout> + <Seo + title={`${product.name} - Indoteknik.com`} + description='Temukan pilihan produk B2B Industri & Alat Teknik untuk Perusahaan, UMKM & Pemerintah dengan lengkap, mudah dan transparan.' + openGraph={{ + url: SELF_HOST + router.asPath, + images: [ + { + url: product?.image, + width: 800, + height: 800, + alt: product?.name, + }, + ], + type: 'product', + }} + additionalMetaTags={[ + { + name: 'keywords', + content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}`, + } + ]} + canonical={SELF_HOST + router.asPath} + /> + + <div className='md:container pt-4 md:pt-6'> + <ProductDetail product={product} /> + </div> + </BasicLayout> + ) +} + +export default ProductDetailPage
\ No newline at end of file diff --git a/src-migrate/services/auth.ts b/src-migrate/services/auth.ts index a5d02754..35ba290a 100644 --- a/src-migrate/services/auth.ts +++ b/src-migrate/services/auth.ts @@ -1,4 +1,4 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; import { RegisterResApiProps, RegisterProps, @@ -8,46 +8,30 @@ import { ActivationOtpResApiProps, ActivationReqProps, ActivationReqResApiProps, -} from '~/common/types/auth'; +} from '~/types/auth'; const BASE_PATH = '/api/v1/user'; export const registerUser = async ( data: RegisterProps ): Promise<RegisterResApiProps> => { - const response = await odooApi('POST', `${BASE_PATH}/register`, data); - - return response; + return await odooApi('POST', `${BASE_PATH}/register`, data); }; export const activationUserToken = async ( params: ActivationTokenProps ): Promise<ActivationTokenResApiProps> => { - const response = await odooApi( - 'POST', - `${BASE_PATH}/activation-token`, - params - ); - - return response; + return await odooApi('POST', `${BASE_PATH}/activation-token`, params); }; export const activationUserOTP = async ( params: ActivationOtpProps ): Promise<ActivationOtpResApiProps> => { - const response = await odooApi('POST', `${BASE_PATH}/activation-otp`, params); - - return response; + return await odooApi('POST', `${BASE_PATH}/activation-otp`, params); }; export const activationReq = async ( params: ActivationReqProps ): Promise<ActivationReqResApiProps> => { - const response = await odooApi( - 'POST', - `${BASE_PATH}/activation-request`, - params - ); - - return response; + return await odooApi('POST', `${BASE_PATH}/activation-request`, params); }; diff --git a/src-migrate/services/banner.ts b/src-migrate/services/banner.ts index e69de29b..1b46ba06 100644 --- a/src-migrate/services/banner.ts +++ b/src-migrate/services/banner.ts @@ -0,0 +1,11 @@ +import odooApi from '~/libs/odooApi'; +import { IBanner } from '~/types/banner'; + +export const getBanner = async ({ + type, +}: { + type: string; +}): Promise<IBanner[]> => { + const searchParams = new URLSearchParams({ type }); + return await odooApi('GET', `/api/v1/banner?${searchParams.toString()}`); +}; diff --git a/src-migrate/services/cart.ts b/src-migrate/services/cart.ts new file mode 100644 index 00000000..11f87125 --- /dev/null +++ b/src-migrate/services/cart.ts @@ -0,0 +1,41 @@ +import odooApi from '~/libs/odooApi'; + +export const getUserCart = async (userId: number) => { + return await odooApi('GET', `/api/v1/user/${userId}/cart`); +}; + +interface UpsertUserCartProps { + userId: number; + type: 'product' | 'promotion'; + id: number; + qty: number; + selected: boolean; + source?: 'buy' | 'add_to_cart'; + qtyAppend?: boolean; +} + +export const upsertUserCart = async ({ + userId, + type, + id, + qty, + selected, + source = 'add_to_cart', + qtyAppend = false, +}: UpsertUserCartProps) => { + return await odooApi('POST', `/api/v1/user/${userId}/cart/create-or-update`, { + product_id: type === 'product' ? id : null, + qty, + selected, + program_line_id: type === 'promotion' ? id : null, + source, + qty_append: qtyAppend, + }); +}; + +export const deleteUserCart = async (userId: number, ids: number[]) => { + return await odooApi( + 'DELETE', + `/api/v1/user/${userId}/cart?ids=${ids.join(',')}` + ); +}; diff --git a/src-migrate/services/checkout.ts b/src-migrate/services/checkout.ts new file mode 100644 index 00000000..e6642ccb --- /dev/null +++ b/src-migrate/services/checkout.ts @@ -0,0 +1,5 @@ +import odooApi from '~/libs/odooApi'; + +export const getUserCheckout = async (userId: number) => { + return await odooApi('GET', `/api/v1/user/${userId}/sale_order/checkout`); +};
\ No newline at end of file diff --git a/src-migrate/services/pageContent.ts b/src-migrate/services/pageContent.ts index 24f2c2f0..516b4bed 100644 --- a/src-migrate/services/pageContent.ts +++ b/src-migrate/services/pageContent.ts @@ -1,14 +1,7 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; export const getPageContent = async ({ path }: { path: string }) => { - const params = new URLSearchParams({ - url_path: path, - }); + const params = new URLSearchParams({ url_path: path }); - const pageContent = await odooApi( - 'GET', - `/api/v1/page-content?${params.toString()}` - ); - - return pageContent; + return await odooApi('GET', `/api/v1/page-content?${params.toString()}`); }; diff --git a/src-migrate/services/product.ts b/src-migrate/services/product.ts new file mode 100644 index 00000000..fe415d11 --- /dev/null +++ b/src-migrate/services/product.ts @@ -0,0 +1,66 @@ +import { IProduct, IProductDetail } from '~/types/product'; +import snakeCase from 'snakecase-keys'; +import odooApi from '~/libs/odooApi'; +import { ICategoryBreadcrumb } from '~/types/category'; + +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST; + +export const getProductById = async ( + id: string, + tier: string +): Promise<IProductDetail | null> => { + const url = `${SELF_HOST}/api/shop/product-detail`; + const params = new URLSearchParams({ id, auth: tier }); + return await fetch(`${url}?${params.toString()}`) + .then((res) => res.json()) + .then((res) => { + if (res.length > 0) return snakeCase(res[0]) as IProductDetail; + return null; + }); +}; + +export interface GetProductSimilarProps { + name: string; + except?: { + productId?: number; + manufactureId?: number; + }; + limit?: number; +} + +export interface GetProductSimilarRes { + products: IProduct[]; + num_found: number; + num_found_exact: boolean; + start: number; +} + +export const getProductSimilar = async ({ + name, + except, + limit = 30, +}: GetProductSimilarProps): Promise<GetProductSimilarRes> => { + const query = [ + `q=${name}`, + 'page=1', + 'orderBy=popular-weekly', + 'operation=OR', + 'priceFrom=1', + ]; + + if (except?.productId) query.push(`fq=-product_id_i:${except.productId}`); + if (except?.manufactureId) + query.push(`fq=-manufacture_id_i:${except.manufactureId}`); + + const url = `${SELF_HOST}/api/shop/search?${query.join('&')}`; + + return await fetch(url) + .then((res) => res.json()) + .then((res) => snakeCase(res.response)); +}; + +export const getProductCategoryBreadcrumb = async ( + id: number +): Promise<ICategoryBreadcrumb[]> => { + return await odooApi('GET', `/api/v1/product/${id}/category-breadcrumb`); +}; diff --git a/src-migrate/services/productVariant.ts b/src-migrate/services/productVariant.ts new file mode 100644 index 00000000..9fec4d1f --- /dev/null +++ b/src-migrate/services/productVariant.ts @@ -0,0 +1,23 @@ +import odooApi from '~/libs/odooApi'; +import { IProductVariantSLA } from '~/types/productVariant'; +import { CategoryPromo, IPromotion } from '~/types/promotion'; + +export const getVariantById = async (variantId: number) => { + const url = `/api/product-variant/${variantId}`; + return await fetch(url).then((res) => res.json()); +}; + +export const getVariantPromoByCategory = async ( + variantId: number, + type: CategoryPromo +): Promise<{ data: IPromotion[] }> => { + const url = `/api/product-variant/${variantId}/promotion/${type}`; + return await fetch(url).then((res) => res.json()); +}; + +export const getVariantSLA = async ( + variantId: number +): Promise<IProductVariantSLA> => { + const url = `/api/v1/product_variant/${variantId}/stock`; + return await odooApi('GET', url); +}; diff --git a/src-migrate/services/promotionProgram.ts b/src-migrate/services/promotionProgram.ts new file mode 100644 index 00000000..c8c46c65 --- /dev/null +++ b/src-migrate/services/promotionProgram.ts @@ -0,0 +1,8 @@ +import { IPromotionProgram } from '~/types/promotionProgram'; + +export const getPromotionProgram = async ( + programId: number +): Promise<{ data: IPromotionProgram }> => { + const url = `/api/promotion-program/${programId}`; + return await fetch(url).then((res) => res.json()); +}; diff --git a/src-migrate/services/wishlist.ts b/src-migrate/services/wishlist.ts new file mode 100644 index 00000000..6fb8cb2e --- /dev/null +++ b/src-migrate/services/wishlist.ts @@ -0,0 +1,23 @@ +import odooApi from '~/libs/odooApi'; + +export const getUserWishlist = async ( + userId: number, + searchParams: { + product_id?: string; + } = {} +): Promise<{ product_total: number }> => { + const url = `/api/v1/user/${userId}/wishlist`; + const searchParamsObj = new URLSearchParams(searchParams); + + return await odooApi('GET', url + '?' + searchParamsObj.toString()); +}; + +export const upsertUserWishlist = async ( + userId: number, + productId: number +): Promise<{ id: number }> => { + const url = `/api/v1/user/${userId}/wishlist/create-or-delete`; + const data = { product_id: productId }; + + return await odooApi('POST', url, data); +}; diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff b/src-migrate/styles/fonts/Inter/Inter-Black.woff Binary files differindex a18593a0..a18593a0 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Black.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 b/src-migrate/styles/fonts/Inter/Inter-Black.woff2 Binary files differindex 68f64c9e..68f64c9e 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Black.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff Binary files differindex b6b01943..b6b01943 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 Binary files differindex 1c9c7ca8..1c9c7ca8 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff b/src-migrate/styles/fonts/Inter/Inter-Bold.woff Binary files differindex eaf3d4bf..eaf3d4bf 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Bold.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 b/src-migrate/styles/fonts/Inter/Inter-Bold.woff2 Binary files differindex 2846f29c..2846f29c 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Bold.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff Binary files differindex 32750761..32750761 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 Binary files differindex 0b1fe8e1..0b1fe8e1 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff Binary files differindex c2c17ede..c2c17ede 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 Binary files differindex c24c2bdc..c24c2bdc 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff Binary files differindex c42f7052..c42f7052 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 Binary files differindex 4a81dc79..4a81dc79 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff Binary files differindex d0de5f39..d0de5f39 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 Binary files differindex f2ea706f..f2ea706f 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff Binary files differindex 81f1a28e..81f1a28e 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 Binary files differindex 9af717ba..9af717ba 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff b/src-migrate/styles/fonts/Inter/Inter-Italic.woff Binary files differindex a806b382..a806b382 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Italic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 b/src-migrate/styles/fonts/Inter/Inter-Italic.woff2 Binary files differindex a619fc54..a619fc54 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Italic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff b/src-migrate/styles/fonts/Inter/Inter-Light.woff Binary files differindex c496464d..c496464d 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Light.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 b/src-migrate/styles/fonts/Inter/Inter-Light.woff2 Binary files differindex bc4be665..bc4be665 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Light.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff Binary files differindex f84a9de3..f84a9de3 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 Binary files differindex 842b2dfc..842b2dfc 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff b/src-migrate/styles/fonts/Inter/Inter-Medium.woff Binary files differindex d546843f..d546843f 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Medium.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 b/src-migrate/styles/fonts/Inter/Inter-Medium.woff2 Binary files differindex f92498a2..f92498a2 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Medium.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff Binary files differindex 459a6568..459a6568 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 Binary files differindex 0e3019f4..0e3019f4 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff b/src-migrate/styles/fonts/Inter/Inter-Regular.woff Binary files differindex 62d3a618..62d3a618 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Regular.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 b/src-migrate/styles/fonts/Inter/Inter-Regular.woff2 Binary files differindex 6c2b6893..6c2b6893 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Regular.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff Binary files differindex a815f43a..a815f43a 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff +++ b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 Binary files differindex 611e90c9..611e90c9 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff Binary files differindex 909e43a9..909e43a9 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 Binary files differindex 545685bd..545685bd 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff b/src-migrate/styles/fonts/Inter/Inter-Thin.woff Binary files differindex 62bc58cd..62bc58cd 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff +++ b/src-migrate/styles/fonts/Inter/Inter-Thin.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 b/src-migrate/styles/fonts/Inter/Inter-Thin.woff2 Binary files differindex abbc3a5c..abbc3a5c 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-Thin.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff Binary files differindex 700a7f06..700a7f06 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff +++ b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 Binary files differindex ab0b2002..ab0b2002 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 b/src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 Binary files differindex b826d5af..b826d5af 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 b/src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 Binary files differindex 6a256a06..6a256a06 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/Inter.var.woff2 b/src-migrate/styles/fonts/Inter/Inter.var.woff2 Binary files differindex 365eedc5..365eedc5 100644 --- a/src-migrate/common/styles/fonts/Inter/Inter.var.woff2 +++ b/src-migrate/styles/fonts/Inter/Inter.var.woff2 diff --git a/src-migrate/common/styles/fonts/Inter/inter.css b/src-migrate/styles/fonts/Inter/inter.css index de6ce273..de6ce273 100644 --- a/src-migrate/common/styles/fonts/Inter/inter.css +++ b/src-migrate/styles/fonts/Inter/inter.css diff --git a/src-migrate/common/styles/globals.css b/src-migrate/styles/globals.css index ea20b247..ea20b247 100644 --- a/src-migrate/common/styles/globals.css +++ b/src-migrate/styles/globals.css diff --git a/src-migrate/common/types/auth.ts b/src-migrate/types/auth.ts index 65fd06c7..e93a475a 100644 --- a/src-migrate/common/types/auth.ts +++ b/src-migrate/types/auth.ts @@ -1,12 +1,12 @@ -import { registerSchema } from '../validations/auth'; -import { OdooApiProps } from './odoo'; +import { registerSchema } from '~/validations/auth'; +import { OdooApiRes } from './odoo'; import { z } from 'zod'; export type AuthProps = { id: number; - parent_id: number; - parent_name: string; - partner_id: number; + parentId: number; + parentName: string; + partnerId: number; name: string; email: string; phone: string; @@ -15,9 +15,13 @@ export type AuthProps = { company: boolean; pricelist: string | null; token: string; + feature : { + onlyReadyStock : boolean, + soApproval : boolean + } }; -export type AuthApiProps = OdooApiProps & { result: AuthProps }; +export type AuthApiProps = OdooApiRes<AuthProps>; export type RegisterProps = z.infer<typeof registerSchema>; diff --git a/src-migrate/types/banner.ts b/src-migrate/types/banner.ts new file mode 100644 index 00000000..dbccc378 --- /dev/null +++ b/src-migrate/types/banner.ts @@ -0,0 +1,8 @@ +export interface IBanner { + background_color: string | false; + group_by_week: number | false; + image: string; + name: string; + sequence: number; + url: string; +} diff --git a/src-migrate/types/cart.ts b/src-migrate/types/cart.ts new file mode 100644 index 00000000..5a2cf4a9 --- /dev/null +++ b/src-migrate/types/cart.ts @@ -0,0 +1,76 @@ +import { CategoryPromo } from "./promotion"; + +type Price = { + price: number; + discount_percentage: number; + price_discount: number; +}; + +export type CartProduct = { + id: number; + image: string; + parent: { + id: number; + name: string; + }; + display_name: string; + name: string; + code: string; + price: Price; + qty: number; + weight: number; + package_weight: number; +}; + +export type CartItem = { + cart_id: number; + quantity: number; + selected: boolean; + can_buy: boolean; + cart_type: 'product' | 'promotion'; + id: number; + name: string; + stock: number; + weight: number; + attributes: string[]; + parent: { + id: number; + name: string; + image: string; + }; + price: Price; + manufacture: { + id: number; + name: string; + }; + has_flashsale: boolean; + subtotal: number; + + code?: string; + + image?: string; + remaining_time?: number; + promotion_type?: { + value?: CategoryPromo; + label?: string; + }; + limit_qty?: { + all?: number; + user?: number; + transaction?: number; + }; + remaining_qty?: { + all?: number; + user?: number; + transaction?: number; + }; + used_percentage?: number; + products?: CartProduct[]; + free_products?: CartProduct[]; + package_price?: number; +}; + +export type CartProps = { + product_total: number; + products: CartItem[]; +}; diff --git a/src-migrate/types/category.ts b/src-migrate/types/category.ts new file mode 100644 index 00000000..1037b5f9 --- /dev/null +++ b/src-migrate/types/category.ts @@ -0,0 +1,4 @@ +export interface ICategoryBreadcrumb { + id: number; + name: string; +} diff --git a/src-migrate/types/checkout.ts b/src-migrate/types/checkout.ts new file mode 100644 index 00000000..dc1365d8 --- /dev/null +++ b/src-migrate/types/checkout.ts @@ -0,0 +1,16 @@ +import { CartItem } from './cart'; + +export interface ICheckout { + total_purchase: number; + total_discount: number; + discount_voucher: number; + subtotal: number; + tax: number; + grand_total: number; + total_weight: { + kg: number; + g: number; + }; + has_product_without_weight: boolean; + products: CartItem[]; +} diff --git a/src-migrate/common/types/nav.ts b/src-migrate/types/nav.ts index ba97b1bf..ba97b1bf 100644 --- a/src-migrate/common/types/nav.ts +++ b/src-migrate/types/nav.ts diff --git a/src-migrate/common/types/odoo.ts b/src-migrate/types/odoo.ts index b34bc667..73a029e9 100644 --- a/src-migrate/common/types/odoo.ts +++ b/src-migrate/types/odoo.ts @@ -1,6 +1,7 @@ -export type OdooApiProps = { +export interface OdooApiRes<T> { status: { code: number; description: string; }; -}; + result: T; +} diff --git a/src-migrate/common/types/pageContent.ts b/src-migrate/types/pageContent.ts index 4361deb7..4361deb7 100644 --- a/src-migrate/common/types/pageContent.ts +++ b/src-migrate/types/pageContent.ts diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts new file mode 100644 index 00000000..681cdc8e --- /dev/null +++ b/src-migrate/types/product.ts @@ -0,0 +1,38 @@ +import { IProductVariantDetail } from './productVariant'; + +export interface IProduct { + id: number; + image: string; + code: string; + display_name: string; + name: string; + weight: number; + qty_sold: number; + stock_total: number; + variant_total: number; + description: string; + isSni: boolean; + isTkdn: boolean; + categories: { + id: string; + name: string; + }[]; + flash_sale: { + id: string; + remaining_time: number; + tag: string; + }; + lowest_price: { + price: number; + price_discount: number; + discount_percentage: number; + }; + manufacture: { + id: number; + name: string; + }; +} + +export interface IProductDetail extends IProduct { + variants: IProductVariantDetail[]; +} diff --git a/src-migrate/types/productVariant.ts b/src-migrate/types/productVariant.ts new file mode 100644 index 00000000..861b216a --- /dev/null +++ b/src-migrate/types/productVariant.ts @@ -0,0 +1,33 @@ +export interface IProductVariantDetail { + id: number; + image: string; + code: string; + name: string; + weight: number; + is_flashsale: { + remaining_time: number; + is_flashsale: boolean; + }; + price: { + price: number; + price_discount: number; + discount_percentage: number; + }; + manufacture: + | { + id: string; + name: string; + } + | {}; + parent: { + id: string; + name: string; + image: string; + }; + attributes: string[]; +} + +export interface IProductVariantSLA { + qty: number; + sla_date: string; +} diff --git a/src-migrate/types/promotion.ts b/src-migrate/types/promotion.ts new file mode 100644 index 00000000..85190aad --- /dev/null +++ b/src-migrate/types/promotion.ts @@ -0,0 +1,44 @@ +export interface IPromotion { + id: number; + program_id: number; + name: string; + type: { + value: CategoryPromo; + label: string; + }; + limit: number; + limit_user: number; + limit_trx: number; + price: number; + total_qty: number; + products: { + product_id: number; + qty: number; + }[]; + free_products: { + product_id: number; + qty: number; + }[]; +} + +export interface IProductVariantPromo { + id: number; + parent_id: number; + display_name: string; + image: string; + name: string; + default_code: string; + price: { + price: number; + discount_percentage: number; + price_discount: number; + }; + qty: number; +} + +export type CategoryPromo = 'bundling' | 'discount_loading' | 'merchandise'; + +export interface ICategoryPromo { + value: CategoryPromo; + label: string; +} diff --git a/src-migrate/types/promotionProgram.ts b/src-migrate/types/promotionProgram.ts new file mode 100644 index 00000000..205884b6 --- /dev/null +++ b/src-migrate/types/promotionProgram.ts @@ -0,0 +1,8 @@ +export type IPromotionProgram = { + id: number; + name: string; + start_time: string; + end_time: string; + applies_to: string; + time_left: number; +}; diff --git a/src-migrate/types/solr.ts b/src-migrate/types/solr.ts new file mode 100644 index 00000000..d231c305 --- /dev/null +++ b/src-migrate/types/solr.ts @@ -0,0 +1,7 @@ +export type SolrResponse<T> = { + response: { + numFound: number; + start: number; + docs: T; + }; +}; diff --git a/src-migrate/common/validations/auth.ts b/src-migrate/validations/auth.ts index 78fc5e71..78fc5e71 100644 --- a/src-migrate/common/validations/auth.ts +++ b/src-migrate/validations/auth.ts diff --git a/src/api/bannerApi.js b/src/api/bannerApi.js index 8bae131d..431225a5 100644 --- a/src/api/bannerApi.js +++ b/src/api/bannerApi.js @@ -3,3 +3,6 @@ import odooApi from '@/core/api/odooApi' export const bannerApi = ({ type }) => { return async () => await odooApi('GET', `/api/v1/banner?type=${type}`) } + +// ubah ke SOLR + diff --git a/src/api/promoApi.js b/src/api/promoApi.js new file mode 100644 index 00000000..0e82c8b9 --- /dev/null +++ b/src/api/promoApi.js @@ -0,0 +1,73 @@ +// src/api/promoApi.js +import odooApi from '@/core/api/odooApi'; +import { type } from 'os'; +// import { SolrResponse } from "../../../../src-migrate/types/solr.ts"; + +export const fetchPromoItems = async (type) => { + try { + const response = await odooApi('GET', `/api/v1/program-line?type=${type}&limit=3`); + return response.map((item) => ({ value: item.id, label: item.name, product: item.products ,price:item.price})); + } catch (error) { + console.error('Error fetching promo items:', error); + return []; + } +}; + +export const fetchPromoItemsSolr = async (type) => { + // let query = type ? `type_value_s:${type}` : '*:*'; + let sort ='sort=if(exists(sequence_i),0,1) asc, sequence_i asc, if(exists(total_qty_sold_f), total_qty_sold_f, -1) desc'; + let start = 0 + let rows = 100 + try { + const queryParams = new URLSearchParams({ q: type }); + const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=${rows}&start=${start}&${sort}`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const promotions = await map(data.response.docs); + return promotions; + } catch (error) { + console.error("Error fetching promotion data:", error); + return []; + } +}; + +export const fetchVariantSolr = async(data)=>{ + try { + const queryParams = new URLSearchParams({ q: data }); + const response = await fetch(`/solr/variants/select?${queryParams.toString()}`); + const responseData = await response.json(); + return responseData; + } catch (error) { + console.error("Error fetching promotion data:", error); + return []; + } +}; + +const map = async (promotions) => { + const result = []; + for (const promotion of promotions) { + const data = { + id: promotion.id, + program_id: promotion.program_id_i, + name: promotion.name_s, + type: { + value: promotion.type_value_s, + label: promotion.type_label_s, + }, + limit: promotion.package_limit_i, + limit_user: promotion.package_limit_user_i, + limit_trx: promotion.package_limit_trx_i, + price: promotion.price_f, + sequence: promotion.sequence_i, + total_qty: promotion.total_qty_i, + products: JSON.parse(promotion.products_s), + product_id: promotion.product_ids[0], + qty_sold_f:promotion.total_qty_sold_f, + free_products: JSON.parse(promotion.free_products_s), + }; + result.push(data); + } + return result; +};
\ No newline at end of file diff --git a/src/components/ui/HeroBanner.jsx b/src/components/ui/HeroBanner.jsx index 6cf7902c..9a62465d 100644 --- a/src/components/ui/HeroBanner.jsx +++ b/src/components/ui/HeroBanner.jsx @@ -1,42 +1,43 @@ // Swiper -import { Swiper, SwiperSlide } from 'swiper/react' -import { Pagination, Autoplay } from 'swiper' -import 'swiper/css' -import 'swiper/css/pagination' -import 'swiper/css/autoplay' +import { Autoplay, Pagination } from 'swiper'; +import 'swiper/css'; +import 'swiper/css/autoplay'; +import 'swiper/css/pagination'; +import { Swiper, SwiperSlide } from 'swiper/react'; -import DesktopView from '@/core/components/views/DesktopView' -import MobileView from '@/core/components/views/MobileView' -import { useMemo } from 'react' -import Link from '@/core/components/elements/Link/Link' -import Image from 'next/image' -import { useQuery } from 'react-query' -import { bannerApi } from '@/api/bannerApi' -import { HeroBannerSkeleton } from '../skeleton/BannerSkeleton' +import Image from 'next/image'; +import { useMemo } from 'react'; +import { useQuery } from 'react-query'; + +import { bannerApi } from '@/api/bannerApi'; +import Link from '@/core/components/elements/Link/Link'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import SmoothRender from '~/components/ui/smooth-render'; const swiperBanner = { autoplay: { delay: 6000, - disableOnInteraction: false + disableOnInteraction: false, }, modules: [Pagination, Autoplay], loop: true, className: 'border border-gray_r-6 min-h-full', - slidesPerView: 1 -} + slidesPerView: 1, +}; const HeroBanner = () => { - const heroBanner = useQuery('heroBanner', bannerApi({ type: 'index-a-1' })) + const heroBanner = useQuery('heroBanner', bannerApi({ type: 'index-a-1' })); const swiperBannerMobile = { ...swiperBanner, - pagination: { dynamicBullets: true, clickable: true } - } + pagination: { dynamicBullets: true, clickable: true }, + }; const swiperBannerDesktop = { ...swiperBanner, - pagination: { dynamicBullets: false, clickable: true } - } + pagination: { dynamicBullets: false, clickable: true }, + }; const BannerComponent = useMemo(() => { return heroBanner.data?.map((banner, index) => ( @@ -51,24 +52,29 @@ const HeroBanner = () => { /> </Link> </SwiperSlide> - )) - }, [heroBanner.data]) - - if (heroBanner.isLoading) return <HeroBannerSkeleton /> + )); + }, [heroBanner.data]); return ( - heroBanner.data && ( - <> - <MobileView> + <> + <MobileView> + <SmoothRender + isLoaded={heroBanner.data?.length > 0} + height='68vw' + duration='750ms' + delay='100ms' + > <Swiper {...swiperBannerMobile}>{BannerComponent}</Swiper> - </MobileView> + </SmoothRender> + </MobileView> - <DesktopView> + <DesktopView> + {heroBanner.data?.length > 0 && ( <Swiper {...swiperBannerDesktop}>{BannerComponent}</Swiper> - </DesktopView> - </> - ) - ) -} + )} + </DesktopView> + </> + ); +}; -export default HeroBanner +export default HeroBanner; diff --git a/src/core/components/ScrollToTop.jsx b/src/core/components/ScrollToTop.jsx new file mode 100644 index 00000000..f8e85167 --- /dev/null +++ b/src/core/components/ScrollToTop.jsx @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; +import { useRouter } from 'next/router'; + +const ScrollToTop = () => { + const router = useRouter(); + + useEffect(() => { + const handleRouteChange = (url, { shallow }) => { + if (!shallow) { + window.scrollTo(0, 0); + } + }; + + router.events.on('routeChangeComplete', handleRouteChange); + + return () => { + router.events.off('routeChangeComplete', handleRouteChange); + }; + }, [router.events]); + + return null; +}; + +export default ScrollToTop; diff --git a/src/core/components/elements/Footer/BasicFooter.jsx b/src/core/components/elements/Footer/BasicFooter.jsx index 28a3764c..6129143d 100644 --- a/src/core/components/elements/Footer/BasicFooter.jsx +++ b/src/core/components/elements/Footer/BasicFooter.jsx @@ -41,6 +41,8 @@ const BasicFooter = () => { <Form /> <CustomerGuide /> <Payments /> + <Shippings /> + <Secures /> </div> <div className='w-full mt-8 leading-5 text-caption-2 text-gray_r-12/80'> @@ -53,7 +55,7 @@ const BasicFooter = () => { <DesktopView> <footer className='bg-gray_r-3 py-6'> <div className='container mx-auto flex flex-wrap justify-between'> - <div className='w-3/12'> + <div className='w-4/12'> <NextImage src={IndoteknikLogo} alt='Logo Indoteknik' @@ -64,27 +66,40 @@ const BasicFooter = () => { PT. Indoteknik Dotcom Gemilang </div> <InformationCenter /> + <div className='h-4' /> + <OfficeLocation /> + <div className='h-4' /> + <OpenHours /> </div> - <CustomerGuide /> - <Form /> - <AboutUs /> + + <div className='w-2/12'> + <CustomerGuide /> + <div className='h-6' /> + <Form /> + </div> + + <div className='w-2/12'> + <AboutUs /> + </div> + <div className='w-3/12'> - <div className='grid grid-cols-1 gap-y-4'> - <OfficeLocation /> - {/* <WarehouseLocation /> */} - <OpenHours /> + <div className='grid grid-cols-1 gap-y-6'> <Payments /> + <Shippings /> + <Secures /> </div> </div> + <hr className='w-full my-4 border-gray_r-7' /> + <div className='w-full flex justify-between items-center'> <div className='text-caption-1'> Copyright © 2007 - {new Date().getFullYear()}, PT. Indoteknik Dotcom Gemilang </div> - <div> + {/* <div> <SocialMedias /> - </div> + </div> */} </div> </div> </footer> @@ -256,7 +271,7 @@ const InformationCenter = () => ( <li className='text-gray_r-12/80 flex items-center'> <DevicePhoneMobileIcon className='w-[18px] mr-2' /> <a href={whatsappUrl()} target='_blank' rel='noreferrer'> - 0812-8080-622 + 0817-1718-1922 </a> </li> </ul> @@ -286,7 +301,7 @@ const SocialMedias = () => ( <a target='_blank' rel='noreferrer' - href='https://www.youtube.com/@indoteknikb2bindustriale-c778' + href='https://www.youtube.com/@indoteknikcom' > <NextImage src='/images/socials/youtube.webp' @@ -369,57 +384,43 @@ const SocialMedias = () => ( const Payments = () => ( <div> - <div className={headerClassName}>Pembayaran</div> - <div className='flex flex-wrap gap-2'> - <NextImage - src='/images/payments/bca.png' - alt='Bank BCA Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/bni.png' - alt='Bank BNI Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/bri.png' - alt='Bank BRI Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/gopay.png' - alt='Gopay Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/mandiri.png' - alt='Bank Mandiri Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/mastercard.png' - alt='Mastercard Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/permata.png' - alt='Bank Permata Logo' - width={48} - height={24} - /> - <NextImage - src='/images/payments/visa.png' - alt='Visa Logo' - width={48} - height={24} - /> - </div> + <div className={headerClassName}>Metode Pembayaran</div> + <NextImage + src='/images/footer/payment-method-new.png' + alt='Metode Pembayaran - Indoteknik' + width={512} + height={512} + quality={100} + className='w-full' + /> + </div> +); + +const Shippings = () => ( + <div> + <div className={headerClassName}>Jasa Pengiriman</div> + <NextImage + src='/images/footer/shippings.png' + alt='Jasa Pengiriman - Indoteknik' + width={512} + height={512} + quality={100} + className='w-full' + /> + </div> +); + +const Secures = () => ( + <div> + <div className={headerClassName}>Keamanan Belanja</div> + <NextImage + src='/images/footer/secures.png' + alt='Keamanan Belanja - Indoteknik' + width={512} + height={512} + quality={100} + className='w-full' + /> </div> ); diff --git a/src/core/components/elements/Footer/SimpleFooter.jsx b/src/core/components/elements/Footer/SimpleFooter.jsx index 26f7f786..371b1652 100644 --- a/src/core/components/elements/Footer/SimpleFooter.jsx +++ b/src/core/components/elements/Footer/SimpleFooter.jsx @@ -22,7 +22,7 @@ const SimpleFooter = () => ( <li className='text-gray_r-12/80 flex items-center'> <DevicePhoneMobileIcon className='w-[18px] mr-2' /> <a href={whatsappUrl()} target='_blank' rel='noreferrer'> - 0812-8080-622 + 081717181922 </a> </li> </ul> diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index d9f5658e..308f2623 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -1,85 +1,86 @@ +import { useProductContext } from '@/contexts/ProductContext'; +import useAuth from '@/core/hooks/useAuth'; +import { getCountCart } from '@/core/utils/cart'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import IndoteknikLogo from '@/images/logo.png'; +import Cardheader from '@/lib/cart/components/Cartheader'; +import Category from '@/lib/category/components/Category'; import { ChevronDownIcon, + DocumentCheckIcon, HeartIcon, - ShoppingCartIcon, - DocumentCheckIcon -} from '@heroicons/react/24/outline' -import Link from '../Link/Link' -import Image from 'next/image' -import DesktopView from '../../views/DesktopView' -import dynamic from 'next/dynamic' -import IndoteknikLogo from '@/images/logo.png' -import Category from '@/lib/category/components/Category' -import { useCallback, useContext, useEffect, useState } from 'react' -import useAuth from '@/core/hooks/useAuth' -import NavbarUserDropdown from './NavbarUserDropdown' -import { getCartApi, getCountCart } from '@/core/utils/cart' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { useRouter } from 'next/router' -import { getAuth, setAuth } from '@/core/utils/auth' -import { createSlug, getIdFromSlug } from '@/core/utils/slug' -import { TopBannerSkeleton } from '../Skeleton/TopBannerSkeleton' -import { useProductContext } from '@/contexts/ProductContext' -import Cardheader from '@/lib/cart/components/Cartheader' - -const Search = dynamic(() => import('./Search')) -const TopBanner = dynamic(() => import('./TopBanner'), { - loading: () => <TopBannerSkeleton /> -}) +} from '@heroicons/react/24/outline'; +import dynamic from 'next/dynamic'; +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import DesktopView from '../../views/DesktopView'; +import Link from '../Link/Link'; +import NavbarUserDropdown from './NavbarUserDropdown'; +import NextImage from 'next/image'; + +const Search = dynamic(() => import('./Search'), { ssr: false }); +const TopBanner = dynamic(() => import('./TopBanner'), { ssr: false }); const NavbarDesktop = () => { - const [isOpenCategory, setIsOpenCategory] = useState(false) - const auth = useAuth() + const [isOpenCategory, setIsOpenCategory] = useState(false); + const auth = useAuth(); - const [cartCount, setCartCount] = useState(0) + const [cartCount, setCartCount] = useState(0); - const [templateWA, setTemplateWA] = useState(null) - const [payloadWA, setPayloadWa] = useState(null) - const [urlPath, setUrlPath] = useState(null) + const [templateWA, setTemplateWA] = useState(null); + const [payloadWA, setPayloadWa] = useState(null); + const [urlPath, setUrlPath] = useState(null); - const router = useRouter() + const router = useRouter(); - const { product } = useProductContext() + const { product } = useProductContext(); useEffect(() => { if (router.pathname === '/shop/product/[slug]') { setPayloadWa({ name: product?.name, manufacture: product?.manufacture.name, - url: createSlug('/shop/product/', product?.name, product?.id, true) - }) - setTemplateWA('product') + url: createSlug('/shop/product/', product?.name, product?.id, true), + }); + setTemplateWA('product'); - setUrlPath(router.asPath) + setUrlPath(router.asPath); } - }, [product, router]) + }, [product, router]); useEffect(() => { const handleCartChange = () => { const cart = async () => { - const listCart = await getCountCart() - setCartCount(listCart) - } - cart() - } - handleCartChange() + const listCart = await getCountCart(); + setCartCount(listCart); + }; + cart(); + }; + handleCartChange(); - window.addEventListener('localStorageChange', handleCartChange) + window.addEventListener('localStorageChange', handleCartChange); return () => { - window.removeEventListener('localStorageChange', handleCartChange) - } - }, []) + window.removeEventListener('localStorageChange', handleCartChange); + }; + }, []); return ( <DesktopView> <TopBanner /> - <div className='py-3 bg-warning-400' id='desktop-nav-top'> + <div className='py-2 bg-warning-400' id='desktop-nav-top'> <div className='container mx-auto flex justify-between'> - <Link href='/tentang-kami' className='!text-gray_r-12'> - Tentang Indoteknik.com - </Link> + <div className='flex items-start gap-5'> + <div> + <SocialMedias /> + </div> + </div> <div className='flex gap-x-6'> + <Link href='/tentang-kami' className='!text-gray_r-12'> + Tentang Indoteknik.com + </Link> <Link href='/my/pembayaran-tempo' className='!text-gray_r-12'> Pembayaran Tempo </Link> @@ -93,7 +94,12 @@ const NavbarDesktop = () => { <nav className='pt-6 sticky top-0 z-50 bg-white border-b-2 border-danger-500'> <div className='container mx-auto flex gap-x-6'> <Link href='/'> - <Image src={IndoteknikLogo} alt='Indoteknik Logo' width={210} height={210 / 3} /> + <Image + src={IndoteknikLogo} + alt='Indoteknik Logo' + width={210} + height={210 / 3} + /> </Link> <div className='flex-1 flex items-center'> <Search /> @@ -128,10 +134,15 @@ const NavbarDesktop = () => { rel='noreferrer' className='flex items-center gap-x-1 !text-gray_r-12/80' > - <Image src='/images/socials/Whatsapp-2.png' alt='Whatsapp' width={48} height={48} /> + <Image + src='/images/socials/Whatsapp-2.png' + alt='Whatsapp' + width={48} + height={48} + /> <div> <div className='font-semibold'>Whatsapp</div> - 0812 8080 622 (Chat) + 0817 1718 1922 (Chat) </div> </a> </div> @@ -146,16 +157,24 @@ const NavbarDesktop = () => { className='w-3/12 p-4 font-semibold border border-gray_r-6 rounded-t-xl flex items-center relative' > <div>Kategori Produk</div> - <ChevronDownIcon className={`ml-auto w-6 ${isOpenCategory ? 'rotate-180' : ''}`} /> + <ChevronDownIcon + className={`ml-auto w-6 ${isOpenCategory ? 'rotate-180' : ''}`} + /> - <div className={`category-mega-box-wrapper ${isOpenCategory ? 'show' : ''}`}> + <div + className={`category-mega-box-wrapper ${ + isOpenCategory ? 'show' : '' + }`} + > <Category /> </div> </button> <div className='w-6/12 flex px-1 divide-x divide-gray_r-6'> <Link href='/shop/brands' - className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition' + className={`${ + router.asPath === '/shop/brands' && 'bg-gray_r-3' + } p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition`} target='_blank' rel='noreferrer' > @@ -163,7 +182,10 @@ const NavbarDesktop = () => { </Link> <Link href='/shop/search?orderBy=stock' - className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition' + className={`${ + router.asPath === '/shop/search?orderBy=stock' && + 'bg-gray_r-3' + } p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition`} target='_blank' rel='noreferrer' > @@ -179,7 +201,9 @@ const NavbarDesktop = () => { </Link> <Link href='/video' - className='p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition' + className={`${ + router.asPath === '/video' && 'bg-gray_r-3' + } p-4 flex-1 flex justify-center items-center !text-gray_r-12/80 hover:bg-gray_r-3 idt-transition`} target='_blank' rel='noreferrer' > @@ -220,7 +244,95 @@ const NavbarDesktop = () => { </div> </nav> </DesktopView> - ) -} + ); +}; + +const SocialMedias = () => ( + <div> + {/* <div className={headerClassName + 'block md:hidden'}>Temukan Kami</div> */} + <div className='flex flex-wrap gap-3 items-start'> + <a + target='_blank' + rel='noreferrer' + href='https://www.youtube.com/@indoteknikcom' + > + <NextImage + src='/images/socials/youtube.webp' + alt='Youtube - Indoteknik.com' + width={24} + height={24} + /> + </a> + <a + target='_blank' + rel='noreferrer' + href='https://www.tiktok.com/@indoteknikcom' + > + <NextImage + src='/images/socials/tiktok.png' + alt='TikTok - Indoteknik.com' + width={24} + height={24} + /> + </a> + {/* <a target='_blank' rel='noreferrer' href={whatsappUrl(null)}> + <NextImage + src='/images/socials/Whatsapp.png' + alt='Whatsapp - Indoteknik.com' + width={24} + height={24} + /> + </a> */} + <a + target='_blank' + rel='noreferrer' + href='https://www.facebook.com/indoteknikcom' + > + <NextImage + src='/images/socials/Facebook.png' + alt='Facebook - Indoteknik.com' + width={24} + height={24} + /> + </a> + <a + target='_blank' + rel='noreferrer' + href='https://www.instagram.com/indoteknikcom/' + > + <NextImage + src='/images/socials/Instagram.png' + alt='Instagram - Indoteknik.com' + width={24} + height={24} + /> + </a> + <a + target='_blank' + rel='noreferrer' + href='https://www.linkedin.com/company/pt-indoteknik-dotcom-gemilang/' + > + <NextImage + src='/images/socials/Linkedin.png' + alt='Linkedin - Indoteknik.com' + width={24} + height={24} + /> + </a> + <a + target='_blank' + rel='noreferrer' + href='https://goo.gl/maps/GF8EmDjpQTHZPsJ1A' + > + <NextImage + src='/images/socials/g_maps.png' + alt='Maps - Indoteknik.com' + width={24} + height={24} + /> + </a> + </div> + </div> +); -export default NavbarDesktop +export default NavbarDesktop; diff --git a/src/core/components/elements/Navbar/NavbarMobile.jsx b/src/core/components/elements/Navbar/NavbarMobile.jsx index 704e91b6..bcf45e0a 100644 --- a/src/core/components/elements/Navbar/NavbarMobile.jsx +++ b/src/core/components/elements/Navbar/NavbarMobile.jsx @@ -1,51 +1,60 @@ -import Image from 'next/image' -import MobileView from '../../views/MobileView' -import Link from '../Link/Link' -import { Bars3Icon, HeartIcon, ShoppingCartIcon } from '@heroicons/react/24/outline' -import useSidebar from '@/core/hooks/useSidebar' -import dynamic from 'next/dynamic' -import IndoteknikLogo from '@/images/logo.png' -import { useEffect, useState } from 'react' -import { getCart, getCountCart } from '@/core/utils/cart' -import TopBanner from './TopBanner' +import useSidebar from '@/core/hooks/useSidebar'; +import { getCountCart } from '@/core/utils/cart'; +import IndoteknikLogo from '@/images/logo.png'; +import { + Bars3Icon, + HeartIcon, + ShoppingCartIcon, +} from '@heroicons/react/24/outline'; +import dynamic from 'next/dynamic'; +import Image from 'next/image'; +import { useEffect, useState } from 'react'; +import MobileView from '../../views/MobileView'; +import Link from '../Link/Link'; +// import TopBanner from './TopBanner'; -const Search = dynamic(() => import('./Search')) +const Search = dynamic(() => import('./Search')); const NavbarMobile = () => { - const { Sidebar, open } = useSidebar() + const { Sidebar, open } = useSidebar(); - const [cartCount, setCartCount] = useState(0) + const [cartCount, setCartCount] = useState(0); useEffect(() => { const handleCartChange = () => { const cart = async () => { - const listCart = await getCountCart() - setCartCount(listCart) - } - cart() - } - handleCartChange() + const listCart = await getCountCart(); + setCartCount(listCart); + }; + cart(); + }; + handleCartChange(); - window.addEventListener('localStorageChange', handleCartChange) + window.addEventListener('localStorageChange', handleCartChange); return () => { - window.removeEventListener('localStorageChange', handleCartChange) - } - }, []) + window.removeEventListener('localStorageChange', handleCartChange); + }; + }, []); return ( <MobileView> - <TopBanner /> + {/* <TopBanner /> */} <nav className='px-4 py-2 pb-3 sticky top-0 z-50 bg-white shadow'> <div className='flex justify-between items-center mb-2'> <Link href='/'> - <Image src={IndoteknikLogo} alt='Indoteknik Logo' width={120} height={40} /> + <Image + src={IndoteknikLogo} + alt='Indoteknik Logo' + width={120} + height={40} + /> </Link> <div className='flex gap-x-3'> - <Link href='/my/wishlist'> + <Link href='/my/wishlist' aria-label='Wishlist'> <HeartIcon className='w-6 text-gray_r-12' /> </Link> - <Link href='/shop/cart' className='relative'> + <Link href='/shop/cart' className='relative' aria-label='Cart'> <ShoppingCartIcon className='w-6 text-gray_r-12' /> {cartCount > 0 && ( <span className='absolute -top-2 -right-2 badge-solid-red rounded-full w-5 h-5 flex items-center justify-center'> @@ -62,7 +71,7 @@ const NavbarMobile = () => { </nav> {Sidebar} </MobileView> - ) -} + ); +}; -export default NavbarMobile +export default NavbarMobile; diff --git a/src/core/components/elements/Navbar/NavbarUserDropdown.jsx b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx index 1851ce84..42bdc12a 100644 --- a/src/core/components/elements/Navbar/NavbarUserDropdown.jsx +++ b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx @@ -2,9 +2,11 @@ import { deleteAuth } from '@/core/utils/auth' import Link from '../Link/Link' import { useRouter } from 'next/router' import { signOut, useSession } from 'next-auth/react' +import useAuth from '@/core/hooks/useAuth' const NavbarUserDropdown = () => { const router = useRouter() + const atuh = useAuth() const logout = async () => { deleteAuth().then(() => { @@ -21,6 +23,9 @@ const NavbarUserDropdown = () => { <Link href='/my/invoices'>Invoice & Faktur Pajak</Link> <Link href='/my/wishlist'>Wishlist</Link> <Link href='/my/address'>Daftar Alamat</Link> + {!atuh?.external && + <Link href='/my/recomendation'>Dashboard Recomendation</Link> + } <button type='button' onClick={logout}> Keluar Akun </button> diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index a757c260..722a7501 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -1,33 +1,40 @@ -import odooApi from '@/core/api/odooApi' -import { useQuery } from 'react-query' -import Image from 'next/image' -import Link from '../Link/Link' -import { TopBannerSkeleton } from '../Skeleton/TopBannerSkeleton' +import Image from 'next/image'; +import { useQuery } from 'react-query'; + +import odooApi from '@/core/api/odooApi'; +import SmoothRender from '~/components/ui/smooth-render'; +import Link from '../Link/Link'; const TopBanner = () => { - const fetchTopBanner = async () => await odooApi('GET', '/api/v1/banner?type=top-banner') - const topBanner = useQuery('topBanner', fetchTopBanner, { refetchOnWindowFocus: false }) + const topBanner = useQuery({ + queryKey: 'topBanner', + queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), + refetchOnWindowFocus: false, + }); - if (topBanner.isLoading) { - return <TopBannerSkeleton /> - } + const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; + const hasData = topBanner.data?.length > 0; + const data = topBanner.data?.[0] || null; return ( - topBanner.isFetched && - topBanner.data?.length > 0 && ( - <div style={{ backgroundColor: topBanner.data[0]?.backgroundColor || 'transparent' }}> - <Link href={topBanner.data[0]?.url}> - <Image - src={topBanner.data[0].image} - alt={topBanner.data[0].name} - width={1440} - height={40} - className='object-cover object-center h-full mx-auto' - /> - </Link> - </div> - ) - ) -} + <SmoothRender + isLoaded={hasData} + height='36px' + duration='700ms' + delay='300ms' + style={{ backgroundColor }} + > + <Link href={data?.url}> + <Image + src={data?.image} + alt={data?.name} + width={1440} + height={40} + className='object-cover object-center h-full mx-auto' + /> + </Link> + </SmoothRender> + ); +}; -export default TopBanner +export default TopBanner; diff --git a/src/core/components/elements/Skeleton/TopBannerSkeleton.jsx b/src/core/components/elements/Skeleton/TopBannerSkeleton.jsx index f7d2e748..8d1a51d2 100644 --- a/src/core/components/elements/Skeleton/TopBannerSkeleton.jsx +++ b/src/core/components/elements/Skeleton/TopBannerSkeleton.jsx @@ -1,19 +1,17 @@ -import useDevice from '@/core/hooks/useDevice' -import classNames from 'classnames' -import Skeleton from 'react-loading-skeleton' +import useDevice from '@/core/hooks/useDevice'; +import classNames from 'classnames'; +import { Skeleton } from '@chakra-ui/react'; const TopBannerSkeleton = () => { - const { isDesktop, isMobile } = useDevice() + const { isDesktop, isMobile } = useDevice(); const deviceClassName = { - 'h-10': isDesktop, - 'h-2.5': isMobile - } - const combinedClassName = classNames(deviceClassName) + '!h-[36px]': isDesktop, + 'h-2.5': isMobile, + }; + const combinedClassName = classNames(deviceClassName); - return ( - <Skeleton className={combinedClassName} count={1} containerClassName='w-full h-full block' /> - ) -} + return <Skeleton className={combinedClassName} />; +}; -export { TopBannerSkeleton } +export { TopBannerSkeleton }; diff --git a/src/core/components/layouts/AppLayout.jsx b/src/core/components/layouts/AppLayout.jsx index d74d61e3..ebbc1ad5 100644 --- a/src/core/components/layouts/AppLayout.jsx +++ b/src/core/components/layouts/AppLayout.jsx @@ -1,6 +1,12 @@ -import AppBar from '../elements/Appbar/Appbar' -import BasicFooter from '../elements/Footer/BasicFooter' -import AnimationLayout from './AnimationLayout' +import dynamic from 'next/dynamic'; +import AnimationLayout from './AnimationLayout'; + +const AppBar = dynamic(() => import('../elements/Appbar/Appbar'), { + ssr: false, +}); +const BasicFooter = dynamic(() => import('../elements/Footer/BasicFooter'), { + ssr: false, +}); const AppLayout = ({ children, title, withFooter = true }) => { return ( @@ -11,7 +17,7 @@ const AppLayout = ({ children, title, withFooter = true }) => { </AnimationLayout> {withFooter && <BasicFooter />} </> - ) -} + ); +}; -export default AppLayout +export default AppLayout; diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index 9441dbd7..a4f3a856 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -1,55 +1,63 @@ -import dynamic from 'next/dynamic' -import BasicFooter from '../elements/Footer/BasicFooter' -import Image from 'next/image' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { useEffect, useState } from 'react' -import axios from 'axios' -import odooApi from '@/core/api/odooApi' -import { useRouter } from 'next/router' -import productApi from '@/lib/product/api/productApi' -import { getAuth, setAuth } from '@/core/utils/auth' -import { createSlug, getIdFromSlug } from '@/core/utils/slug' -import { useSession } from 'next-auth/react' -import { setCookie } from 'cookies-next' -import { useProductContext } from '@/contexts/ProductContext' +import dynamic from 'next/dynamic'; +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; -const Navbar = dynamic(() => import('../elements/Navbar/Navbar')) -const AnimationLayout = dynamic(() => import('./AnimationLayout')) +import { useProductContext } from '@/contexts/ProductContext'; +import odooApi from '@/core/api/odooApi'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import Navbar from '../elements/Navbar/Navbar'; + +const AnimationLayout = dynamic(() => import('./AnimationLayout'), { + ssr: false, +}); +const BasicFooter = dynamic(() => import('../elements/Footer/BasicFooter'), { + ssr: false, +}); const BasicLayout = ({ children }) => { - const [templateWA, setTemplateWA] = useState(null) - const [payloadWA, setPayloadWa] = useState(null) - const [urlPath, setUrlPath] = useState(null) + const [templateWA, setTemplateWA] = useState(null); + const [payloadWA, setPayloadWa] = useState(null); + const [urlPath, setUrlPath] = useState(null); - const router = useRouter() + const router = useRouter(); - const { product } = useProductContext() + const { product } = useProductContext(); useEffect(() => { - if (router.pathname === '/shop/product/[slug]' || router.pathname === '/shop/product/variant/[slug]') { + if ( + router.pathname === '/shop/product/[slug]' || + router.pathname === '/shop/product/variant/[slug]' + ) { setPayloadWa({ name: product?.name, manufacture: product?.manufacture.name, - url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath - }) - setTemplateWA('product') + url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath, + }); + setTemplateWA('product'); - setUrlPath(router.asPath) + setUrlPath(router.asPath); } - }, [product, router]) + }, [product, router]); + + const recordActivity = async (pathname) => { + const ONLY_ON_PATH = false; + const recordedPath = []; + if (ONLY_ON_PATH && !recordedPath.includes(pathname)) return; + + const ip = await odooApi('GET', '/api/ip-address'); + const data = new URLSearchParams({ + page_title: document.title, + url: window.location.href, + ip, + }); + fetch(`/api/user-activity?${data.toString()}`); + }; useEffect(() => { - const getIP = async () => { - const ip = await odooApi('GET', '/api/ip-address') - const data = { - page_title: document.title, - url: window.location.href, - ip: ip - } - axios.get(`/api/user-activity?page_title=${data.page_title}&url=${data.url}&ip=${data.ip}`) - } - getIP() - }, []) + recordActivity(router.pathname); + }, [router.pathname]); + return ( <> <Navbar /> @@ -82,7 +90,7 @@ const BasicLayout = ({ children }) => { </AnimationLayout> <BasicFooter /> </> - ) -} + ); +}; -export default BasicLayout +export default BasicLayout; diff --git a/src/core/utils/auth.js b/src/core/utils/auth.js index a7244747..03b20ae2 100644 --- a/src/core/utils/auth.js +++ b/src/core/utils/auth.js @@ -29,7 +29,7 @@ const setAuth = (user) => { * @returns {boolean} - Returns `true`. */ const deleteAuth = async() => { - // await signOut() + await signOut() deleteCookie('auth') return true } diff --git a/src/core/utils/googleTag.js b/src/core/utils/googleTag.js index 6d7476bd..96a6bd2e 100644 --- a/src/core/utils/googleTag.js +++ b/src/core/utils/googleTag.js @@ -2,7 +2,7 @@ const mapVariants = (variants) => { return variants.map((variant) => { const res = { item_id: variant.id, - item_name: variant.parent.name, + item_name: variant.name, discount: variant.price.price - variant.price.priceDiscount, item_brand: variant.manufacture?.name, item_variant: variant.code || variant.id, @@ -33,6 +33,20 @@ const sumTotal = (variants) => { } } +const mapProducts = (product) => { + const res = { + item_id: product.id, + item_name: product.name, + discount: product.lowest_price.price_discount || 0, + // index: 0, + item_brand: product.manufacture.name, + item_category: product.categories, + item_variant: product.variants, + price: product.lowest_price.price, + quantity: product.stock_total + } + return res +} export const gtagAddToCart = (variant, quantity) => { const param = { currency: 'IDR', @@ -77,3 +91,13 @@ export const gtagPurchase = (variants, shipping, transactionId) => { } gtag('event', 'purchase', param) } + +export const gtagProductDetail = (product) => { + const items = mapProducts(product) + const param = { + currency: 'IDR', + value: product.id, + items + } + gtag('event', 'view_item', param) +}
\ No newline at end of file diff --git a/src/core/utils/slug.js b/src/core/utils/slug.js index e91bcf83..19c7b115 100644 --- a/src/core/utils/slug.js +++ b/src/core/utils/slug.js @@ -1,4 +1,4 @@ -import toTitleCase from './toTitleCase' +import toTitleCase from './toTitleCase'; /** * Creates a slug from input parameters by converting the name and appending it with an ID. @@ -10,19 +10,20 @@ import toTitleCase from './toTitleCase' * @returns {string} - The generated slug with the prefix, name, and ID. */ const createSlug = (prefix, name, id, withHost = false) => { + name ||= ''; let slug = name ?.trim() .replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-') .toLowerCase() + '-' + - id - let splitSlug = slug.split('-') - let filterSlugFromEmptyChar = splitSlug.filter((x) => x != '') - slug = prefix + filterSlugFromEmptyChar.join('-') - if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug - return slug -} + id; + let splitSlug = slug.split('-'); + let filterSlugFromEmptyChar = splitSlug.filter((x) => x != ''); + slug = prefix + filterSlugFromEmptyChar.join('-'); + if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug; + return slug; +}; /** * Extracts the ID from a slug. @@ -32,9 +33,9 @@ const createSlug = (prefix, name, id, withHost = false) => { * @returns {string} - The extracted ID from the slug. */ const getIdFromSlug = (slug) => { - let id = slug.split('-') - return id[id.length - 1] -} + let id = slug.split('-'); + return id[id.length - 1]; +}; /** * Extracts the name from a slug. @@ -45,9 +46,10 @@ const getIdFromSlug = (slug) => { * @returns {string} - The extracted name from the slug in title case. */ const getNameFromSlug = (slug) => { - let name = slug.split('-') - name.pop() - return toTitleCase(name.join(' ')) -} + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +}; + +export { createSlug, getIdFromSlug, getNameFromSlug }; -export { createSlug, getIdFromSlug, getNameFromSlug } diff --git a/src/core/utils/whatsappUrl.js b/src/core/utils/whatsappUrl.js index 9a92f424..7a129aa6 100644 --- a/src/core/utils/whatsappUrl.js +++ b/src/core/utils/whatsappUrl.js @@ -7,7 +7,7 @@ const whatsappUrl = (template = 'default', payload, urlPath = null) => { if(!urlPath) return '/login' } let parentName = user.parentName || '-' - let url = 'https://wa.me/628128080622' + let url = 'https://wa.me/6281717181922' let text = 'Hallo Indoteknik.com,' switch (template) { case 'product': diff --git a/src/fonts/Inter/inter.css b/src/fonts/Inter/inter.css index de6ce273..3a1de02a 100644 --- a/src/fonts/Inter/inter.css +++ b/src/fonts/Inter/inter.css @@ -1,57 +1,6 @@ @font-face { font-family: 'Inter'; font-style: normal; - font-weight: 100; - font-display: swap; - src: url('Inter-Thin.woff2?v=3.19') format('woff2'), - url('Inter-Thin.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 100; - font-display: swap; - src: url('Inter-ThinItalic.woff2?v=3.19') format('woff2'), - url('Inter-ThinItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url('Inter-ExtraLight.woff2?v=3.19') format('woff2'), - url('Inter-ExtraLight.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 200; - font-display: swap; - src: url('Inter-ExtraLightItalic.woff2?v=3.19') format('woff2'), - url('Inter-ExtraLightItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url('Inter-Light.woff2?v=3.19') format('woff2'), - url('Inter-Light.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 300; - font-display: swap; - src: url('Inter-LightItalic.woff2?v=3.19') format('woff2'), - url('Inter-LightItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; font-weight: 400; font-display: swap; src: url('Inter-Regular.woff2?v=3.19') format('woff2'), @@ -117,40 +66,6 @@ url('Inter-BoldItalic.woff?v=3.19') format('woff'); } -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url('Inter-ExtraBold.woff2?v=3.19') format('woff2'), - url('Inter-ExtraBold.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url('Inter-ExtraBoldItalic.woff2?v=3.19') format('woff2'), - url('Inter-ExtraBoldItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url('Inter-Black.woff2?v=3.19') format('woff2'), - url('Inter-Black.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url('Inter-BlackItalic.woff2?v=3.19') format('woff2'), - url('Inter-BlackItalic.woff?v=3.19') format('woff'); -} - /* ------------------------------------------------------- Variable font. Usage: diff --git a/src/images/logo-idul-fitri.png b/src/images/logo-idul-fitri.png Binary files differnew file mode 100644 index 00000000..db04faa5 --- /dev/null +++ b/src/images/logo-idul-fitri.png diff --git a/src/lib/auth/components/LoginDesktop.jsx b/src/lib/auth/components/LoginDesktop.jsx index 1333db14..9a68dc53 100644 --- a/src/lib/auth/components/LoginDesktop.jsx +++ b/src/lib/auth/components/LoginDesktop.jsx @@ -8,6 +8,7 @@ import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'; +import Image from 'next/image'; const LoginDesktop = () => { const { @@ -108,7 +109,7 @@ const LoginDesktop = () => { {!isLoading ? 'Masuk' : 'Loading...'} </button> </form> - {/* <div className='flex items-center mt-3 mb-3'> + <div className='flex items-center mt-3 mb-3'> <hr className='flex-1' /> <p className='text-gray-400'>ATAU</p> <hr className='flex-1' /> @@ -127,7 +128,7 @@ const LoginDesktop = () => { height={10} /> <p>Masuk dengan Google</p> - </button> */} + </button> <div className='text-gray_r-11 mt-10'> Belum punya akun Indoteknik?{' '} diff --git a/src/lib/auth/components/LoginMobile.jsx b/src/lib/auth/components/LoginMobile.jsx index 40924fbe..d2bf704f 100644 --- a/src/lib/auth/components/LoginMobile.jsx +++ b/src/lib/auth/components/LoginMobile.jsx @@ -117,7 +117,7 @@ const LoginMobile = () => { {!isLoading ? 'Masuk' : 'Loading...'} </button> </form> - {/* <div className='flex items-center mt-3 mb-3'> + <div className='flex items-center mt-3 mb-3'> <hr className='flex-1' /> <p className='text-gray-400'>ATAU</p> <hr className='flex-1' /> @@ -136,7 +136,7 @@ const LoginMobile = () => { height={10} /> <p>Masuk dengan Google</p> - </button> */} + </button> <div className='text-gray_r-11 mt-4'> Belum punya akun Indoteknik?{' '} diff --git a/src/lib/auth/hooks/useLogin.js b/src/lib/auth/hooks/useLogin.js index dc9580ea..dd5a4b03 100644 --- a/src/lib/auth/hooks/useLogin.js +++ b/src/lib/auth/hooks/useLogin.js @@ -74,7 +74,7 @@ const useLogin = () => { if (data.isAuth) { session.odooUser = data.user; setCookie('auth', JSON.stringify(session?.odooUser)); - router.push(decodeURIComponent(router?.query?.next) ?? '/'); + router.push(router?.query?.next || '/'); return; } }; diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx index bb1a17f7..731214ff 100644 --- a/src/lib/brand/components/BrandCard.jsx +++ b/src/lib/brand/components/BrandCard.jsx @@ -1,4 +1,4 @@ -import Image from '@/core/components/elements/Image/Image' +import Image from '~/components/ui/image' import Link from '@/core/components/elements/Link/Link' import useDevice from '@/core/hooks/useDevice' import { createSlug } from '@/core/utils/slug' @@ -16,6 +16,8 @@ const BrandCard = ({ brand }) => { <Image src={brand.logo} alt={brand.name} + width={128} + height={128} className='h-full w-full object-contain object-center' /> )} diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 580dfc8c..19f79bc9 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -1,14 +1,9 @@ import { useCallback, useEffect, useMemo, useState } from 'react' import { getCartApi } from '../api/CartApi' -import currencyFormat from '@/core/utils/currencyFormat' -import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { AnimatePresence, motion } from 'framer-motion' const { ShoppingCartIcon, PhotoIcon } = require('@heroicons/react/24/outline') const { default: Link } = require('next/link') @@ -114,182 +109,6 @@ const Cardheader = (cartCount) => { </span> </Link> </div> - - <AnimatePresence> - {isHovered && ( - <> - <motion.div - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - exit={{ opacity: 0 }} - transition={{ duration: 0.15 }} - className='fixed top-[155px] left-0 w-full h-full bg-black/50 z-10' - /> - - <motion.div - initial={{ opacity: 0 }} - animate={{ opacity: 1, transition: { duration: 0.2 } }} - exit={{ opacity: 0, transition: { duration: 0.3 } }} - className='absolute z-10 left-0 w-96' - onMouseEnter={handleMouseEnter} - onMouseLeave={handleMouseLeave} - > - <motion.div - initial={{ height: 0 }} - animate={{ height: 'auto' }} - exit={{ height: 0 }} - className='w-full max-w-md p-2 bg-white border border-gray-200 rounded-lg shadow overflow-hidden' - > - <div className='p-2 flex justify-between items-center'> - <h5 className='text-base font-semibold leading-none'>Keranjang Belanja</h5> - <Link href='/shop/cart' class='text-sm font-medium text-red-600 underline'> - Lihat Semua - </Link> - </div> - <hr className='mt-3 mb-3 border border-gray-100' /> - <div className='flow-root max-h-[250px] overflow-y-auto'> - {!auth && ( - <div className='justify-center p-4'> - <p className='text-gray-500 text-center '> - Silahkan{' '} - <Link href='/login' className='text-red-600 underline leading-6'> - Login - </Link>{' '} - Untuk Melihat Daftar Keranjang Belanja Anda - </p> - </div> - )} - {isLoading && - itemLoading.map((item) => ( - <div key={item} role='status' className='max-w-sm animate-pulse'> - <div className='flex items-center space-x-4 mb- 2'> - <div className='flex-shrink-0'> - <PhotoIcon className='h-16 w-16 text-gray-500' /> - </div> - <div className='flex-1 min-w-0'> - <div className='h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4'></div> - <div className='h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5'></div> - <div className='h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5'></div> - </div> - </div> - </div> - ))} - {auth && products.length === 0 && !isLoading && ( - <div className='justify-center p-4'> - <p className='text-gray-500 text-center '> - Tidak Ada Produk di Keranjang Belanja Anda - </p> - </div> - )} - {auth && products.length > 0 && !isLoading && ( - <> - <ul role='list' className='divide-y divide-gray-200 dark:divide-gray-700'> - {products && - products?.map((product, index) => ( - <> - <li className='py-1 sm:py-2'> - <div className='flex items-center space-x-4'> - <div className='flex-shrink-0'> - <Link - href={createSlug( - '/shop/product/', - product?.parent.name, - product?.parent.id - )} - className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' - > - <Image - src={product?.parent?.image} - alt={product?.name} - className='object-contain object-center border border-gray_r-6 h-16 w-16 rounded-md' - /> - </Link> - </div> - <div className='flex-1 min-w-0'> - <Link - href={createSlug( - '/shop/product/', - product?.parent.name, - product?.parent.id - )} - className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' - > - {' '} - <p className='text-caption-2 font-medium text-gray-900 truncate dark:text-white'> - {product.parent.name} - </p> - </Link> - - {product?.hasFlashsale && ( - <div className='flex gap-x-1 items-center mb-2 mt-1'> - <div className='badge-solid-red'> - {product?.price?.discountPercentage}% - </div> - <div className='text-gray_r-11 line-through text-caption-2'> - {currencyFormat(product?.price?.price)} - </div> - </div> - )} - <div className='flex justify-between items-center'> - <div className='font-semibold text-sm text-red-600'> - {product?.price?.priceDiscount > 0 ? ( - currencyFormat(product?.price?.priceDiscount) - ) : ( - <span className='text-gray_r-12/90 font-normal text-caption-1'> - <a - href={whatsappUrl('product', { - name: product.name, - manufacture: product.manufacture?.name, - url: createSlug( - '/shop/product/', - product.name, - product.id, - true - ) - })} - className='text-danger-500 underline' - rel='noopener noreferrer' - target='_blank' - > - Call For Price - </a> - </span> - )} - </div> - </div> - </div> - </div> - </li> - </> - ))} - </ul> - <hr /> - </> - )} - </div> - {auth && products.length > 0 && !isLoading && ( - <> - <div className='mt-3'> - <span className='text-gray-400 text-caption-2'>Subtotal Sebelum PPN : </span> - <span className='font-semibold text-red-600'>{currencyFormat(subTotal)}</span> - </div> - <div className='mt-5 mb-2'> - <button - type='button' - className='btn-solid-red rounded-lg w-full' - onClick={handleCheckout} - disabled={buttonLoading} - > - {buttonLoading ? 'Loading...' : 'Lanjutkan Ke Pembayaran'} - </button> - </div> - </> - )} - </motion.div> - </motion.div> - </> - )} - </AnimatePresence> </div> ) } diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 9a799010..4aafdece 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -1,191 +1,201 @@ -import Alert from '@/core/components/elements/Alert/Alert' -import Divider from '@/core/components/elements/Divider/Divider' -import Link from '@/core/components/elements/Link/Link' -import useAuth from '@/core/hooks/useAuth' -import { getItemAddress } from '@/core/utils/address' -import addressesApi from '@/lib/address/api/addressesApi' +import { Skeleton, Spinner } from '@chakra-ui/react'; import { BanknotesIcon, ChevronLeftIcon, ClockIcon, - ExclamationCircleIcon -} from '@heroicons/react/24/outline' -import React, { useEffect, useRef, useState } from 'react' -import _ from 'lodash' -import { deleteItemCart, getCartApi } from '@/core/utils/cart' -import currencyFormat from '@/core/utils/currencyFormat' -import { toast } from 'react-hot-toast' -import getFileBase64 from '@/core/utils/getFileBase64' -import { useRouter } from 'next/router' -import VariantGroupCard from '@/lib/variant/components/VariantGroupCard' -import axios from 'axios' -import Image from '@/core/components/elements/Image/Image' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import ExpedisiList from '../api/ExpedisiList' -import whatsappUrl from '@/core/utils/whatsappUrl' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import { useQuery } from 'react-query' -import { gtagPurchase } from '@/core/utils/googleTag' -import { findVoucher, getVoucher } from '../api/getVoucher' -import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList' -import { Spinner } from '@chakra-ui/react' -import { AnimatePresence, motion } from 'framer-motion' - -const SELF_PICKUP_ID = 32 - -const { checkoutApi } = require('../api/checkoutApi') -const { getProductsCheckout } = require('../api/checkoutApi') + ExclamationCircleIcon, +} from '@heroicons/react/24/outline'; +import axios from 'axios'; +import { AnimatePresence, motion } from 'framer-motion'; +import { useRouter } from 'next/router'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { toast } from 'react-hot-toast'; +import { useQuery } from 'react-query'; +import snakecaseKeys from 'snakecase-keys'; + +import Alert from '@/core/components/elements/Alert/Alert'; +import Divider from '@/core/components/elements/Divider/Divider'; +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import useAuth from '@/core/hooks/useAuth'; +import { getItemAddress } from '@/core/utils/address'; +import { deleteItemCart } from '@/core/utils/cart'; +import currencyFormat from '@/core/utils/currencyFormat'; +import getFileBase64 from '@/core/utils/getFileBase64'; +import { gtagPurchase } from '@/core/utils/googleTag'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import addressesApi from '@/lib/address/api/addressesApi'; +import CartItem from '~/modules/cart/components/Item.tsx'; +import ExpedisiList from '../api/ExpedisiList'; +import { findVoucher, getVoucher } from '../api/getVoucher'; + +const SELF_PICKUP_ID = 32; + +const { checkoutApi } = require('../api/checkoutApi'); +const { getProductsCheckout } = require('../api/checkoutApi'); const Checkout = () => { - const router = useRouter() - const query = router.query.source ?? null - const auth = useAuth() + const router = useRouter(); + const query = router.query.source ?? null; + const auth = useAuth(); - const [activeVoucher, SetActiveVoucher] = useState(null) + const [activeVoucher, SetActiveVoucher] = useState(null); const { data: cartCheckout } = useQuery('cartCheckout-' + activeVoucher, () => getProductsCheckout(activeVoucher, query) - ) + ); const [selectedAddress, setSelectedAddress] = useState({ shipping: null, - invoicing: null - }) - const [addresses, setAddresses] = useState(null) + invoicing: null, + }); + const [addresses, setAddresses] = useState(null); useEffect(() => { - if (!auth) return + if (!auth) return; const getAddresses = async () => { - const dataAddresses = await addressesApi() - setAddresses(dataAddresses) - } + const dataAddresses = await addressesApi(); + setAddresses(dataAddresses); + }; - getAddresses() - }, [auth]) + getAddresses(); + }, [auth]); useEffect(() => { - if (!addresses) return + if (!addresses) return; const matchAddress = (key) => { - const addressToMatch = getItemAddress(key) - const foundAddress = addresses.filter((address) => address.id == addressToMatch) + const addressToMatch = getItemAddress(key); + const foundAddress = addresses.filter( + (address) => address.id == addressToMatch + ); if (foundAddress.length > 0) { - return foundAddress[0] + return foundAddress[0]; } - return addresses[0] - } + return addresses[0]; + }; setSelectedAddress({ shipping: matchAddress('shipping'), - invoicing: matchAddress('invoicing') - }) - }, [addresses]) - - const [products, setProducts] = useState(null) - const [totalWeight, setTotalWeight] = useState(0) - const [priceCheck, setPriceCheck] = useState(false) - const [listExpedisi, setExpedisi] = useState([]) - const [listserviceExpedisi, setListServiceExpedisi] = useState([]) - const [selectedExpedisi, setSelectedExpedisi] = useState(0) - const [selectedCarrierId, setselectedCarrierId] = useState(0) - const [selectedCarrier, setselectedCarrier] = useState(0) - const [biayaKirim, setBiayaKirim] = useState(0) - const [checkWeigth, setCheckWeight] = useState(false) - const [selectedServiceType, setSelectedServiceType] = useState(null) - const [selectedExpedisiService, setselectedExpedisiService] = useState(null) - const [etd, setEtd] = useState(null) - const [etdFix, setEtdFix] = useState(null) - const [bottomPopup, SetBottomPopup] = useState(null) - const [bottomPopupTnC, SetBottomPopupTnC] = useState(null) - const [itemTnC, setItemTnC] = useState(null) - const [listVouchers, SetListVoucher] = useState(null) - const [discountVoucher, SetDiscountVoucher] = useState(0) - const [codeVoucher, SetCodeVoucher] = useState(null) - const [findCodeVoucher, SetFindVoucher] = useState(null) - const [selisihHargaCode, SetSelisihHargaCode] = useState(null) - const [buttonTerapkan, SetButtonTerapkan] = useState(false) - const [checkoutValidation, setCheckoutValidation] = useState(false) - const [loadingVoucher, setLoadingVoucher] = useState(true) - const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false) - - const expedisiValidation = useRef(null) + invoicing: matchAddress('invoicing'), + }); + }, [addresses]); + + const [products, setProducts] = useState(null); + const [totalWeight, setTotalWeight] = useState(0); + const [priceCheck, setPriceCheck] = useState(false); + const [listExpedisi, setExpedisi] = useState([]); + const [listserviceExpedisi, setListServiceExpedisi] = useState([]); + const [selectedExpedisi, setSelectedExpedisi] = useState(0); + const [selectedCarrierId, setselectedCarrierId] = useState(0); + const [selectedCarrier, setselectedCarrier] = useState(0); + const [biayaKirim, setBiayaKirim] = useState(0); + const [checkWeigth, setCheckWeight] = useState(false); + const [selectedServiceType, setSelectedServiceType] = useState(null); + const [selectedExpedisiService, setselectedExpedisiService] = useState(null); + const [etd, setEtd] = useState(null); + const [etdFix, setEtdFix] = useState(null); + const [bottomPopup, SetBottomPopup] = useState(null); + const [bottomPopupTnC, SetBottomPopupTnC] = useState(null); + const [itemTnC, setItemTnC] = useState(null); + const [listVouchers, SetListVoucher] = useState(null); + const [discountVoucher, SetDiscountVoucher] = useState(0); + const [codeVoucher, SetCodeVoucher] = useState(null); + const [findCodeVoucher, SetFindVoucher] = useState(null); + const [selisihHargaCode, SetSelisihHargaCode] = useState(null); + const [buttonTerapkan, SetButtonTerapkan] = useState(false); + const [checkoutValidation, setCheckoutValidation] = useState(false); + const [loadingVoucher, setLoadingVoucher] = useState(true); + const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false); + const [grandTotal, setGrandTotal] = useState(0); + const [hasFlashSale, setHasFlashSale] = useState(false); + + const expedisiValidation = useRef(null); const voucher = async () => { if (!listVouchers) { try { - let dataVoucher = await getVoucher(auth?.id, query) - SetListVoucher(dataVoucher) + let dataVoucher = await getVoucher(auth?.id, query); + SetListVoucher(dataVoucher); } finally { - setLoadingVoucher(false) + setLoadingVoucher(false); } } - } + }; const VoucherCode = async (code) => { - let dataVoucher = await findVoucher(code, auth.id, query) + let dataVoucher = await findVoucher(code, auth.id, query); if (dataVoucher.length <= 0) { - SetFindVoucher(1) - return + SetFindVoucher(1); + return; } - let addNewLine = dataVoucher[0] - let checkList = listVouchers.findIndex((voucher) => voucher.code == addNewLine.code) + let addNewLine = dataVoucher[0]; + let checkList = listVouchers.findIndex( + (voucher) => voucher.code == addNewLine.code + ); if (checkList >= 0) { if (listVouchers[checkList].canApply) { - ToggleSwitch(code) - SetCodeVoucher(null) + ToggleSwitch(code); + SetCodeVoucher(null); } else { - SetSelisihHargaCode(listVouchers[checkList].differenceToApply) - SetFindVoucher(2) + SetSelisihHargaCode(listVouchers[checkList].differenceToApply); + SetFindVoucher(2); } - return + return; } if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) { - SetSelisihHargaCode(currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal)) - SetFindVoucher(2) - return + SetSelisihHargaCode( + currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal) + ); + SetFindVoucher(2); + return; } else { - SetFindVoucher(3) - SetButtonTerapkan(true) + SetFindVoucher(3); + SetButtonTerapkan(true); } - SetListVoucher((prevList) => [addNewLine, ...prevList]) - SetActiveVoucher(addNewLine.code) - } + SetListVoucher((prevList) => [addNewLine, ...prevList]); + SetActiveVoucher(addNewLine.code); + }; useEffect(() => { - SetFindVoucher(null) - }, [bottomPopup]) + SetFindVoucher(null); + }, [bottomPopup]); useEffect(() => { const loadExpedisi = async () => { - let dataExpedisi = await ExpedisiList() + let dataExpedisi = await ExpedisiList(); dataExpedisi = dataExpedisi.map((expedisi) => ({ value: expedisi.id, label: expedisi.name, - carrierId: expedisi.deliveryCarrierId - })) - setExpedisi(dataExpedisi) - } - loadExpedisi() + carrierId: expedisi.deliveryCarrierId, + })); + setExpedisi(dataExpedisi); + }; + loadExpedisi(); const handlePopState = () => { - router.push('/shop/cart') - } + router.push('/shop/cart'); + }; - window.onpopstate = handlePopState + window.onpopstate = handlePopState; return () => { - window.onpopstate = null - } + window.onpopstate = null; + }; // voucher() - }, []) + }, []); const hitungDiscountVoucher = (code) => { - let dataVoucherIndex = listVouchers.findIndex((voucher) => voucher.code == code) - let dataActiveVoucher = listVouchers[dataVoucherIndex] + let dataVoucherIndex = listVouchers.findIndex( + (voucher) => voucher.code == code + ); + let dataActiveVoucher = listVouchers[dataVoucherIndex]; - let countDiscount = dataActiveVoucher.discountVoucher + let countDiscount = dataActiveVoucher.discountVoucher; /*if (dataActiveVoucher.discountType === 'percentage') { countDiscount = cartCheckout?.subtotal * (dataActiveVoucher.discountAmount / 100) @@ -199,215 +209,257 @@ const Checkout = () => { countDiscount = dataActiveVoucher.discountAmount }*/ - return countDiscount - } + return countDiscount; + }; useEffect(() => { - if (!listVouchers) return - if (!activeVoucher) return + if (!listVouchers) return; + if (!activeVoucher) return; - const countDiscount = hitungDiscountVoucher(activeVoucher) + const countDiscount = hitungDiscountVoucher(activeVoucher); - SetDiscountVoucher(countDiscount) - }, [activeVoucher, listVouchers]) + SetDiscountVoucher(countDiscount); + }, [activeVoucher, listVouchers]); useEffect(() => { - setProducts(cartCheckout?.products) - setCheckWeight(cartCheckout?.hasProductWithoutWeight) - setTotalWeight(cartCheckout?.totalWeight.g) - }, [cartCheckout]) + setProducts(cartCheckout?.products); + setCheckWeight(cartCheckout?.hasProductWithoutWeight); + setTotalWeight(cartCheckout?.totalWeight.g); + setHasFlashSale(cartCheckout?.products[0]?.hasFlashsale ? cartCheckout.products[0].hasFlashsale : false); + }, [cartCheckout]); + useEffect(() => { - setCheckoutValidation(false) + setCheckoutValidation(false); const loadServiceRajaOngkir = async () => { - setLoadingRajaOngkir(true) + setLoadingRajaOngkir(true); const body = { origin: 2127, destination: selectedAddress.shipping.rajaongkirCityId, weight: totalWeight, courier: selectedCarrier, originType: 'subdistrict', - destinationType: 'subdistrict' - } - setBiayaKirim(0) - const dataService = await axios('/api/rajaongkir-service?body=' + JSON.stringify(body)) - setLoadingRajaOngkir(false) - setListServiceExpedisi(dataService.data[0].costs) + destinationType: 'subdistrict', + }; + setBiayaKirim(0); + const dataService = await axios( + '/api/rajaongkir-service?body=' + JSON.stringify(body) + ); + setLoadingRajaOngkir(false); + setListServiceExpedisi(dataService.data[0].costs); if (dataService.data[0].costs[0]) { - setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value) + setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value); setselectedExpedisiService( - dataService.data[0].costs[0]?.description + '-' + dataService.data[0].costs[0]?.service - ) - setEtd(dataService.data[0].costs[0]?.cost[0].etd) - toast.success('Harap pilih tipe layanan pengiriman') + dataService.data[0].costs[0]?.description + + '-' + + dataService.data[0].costs[0]?.service + ); + setEtd(dataService.data[0].costs[0]?.cost[0].etd); + toast.success('Harap pilih tipe layanan pengiriman'); } else { - toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.') + toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); } - } + }; if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) { - loadServiceRajaOngkir() + loadServiceRajaOngkir(); } else { - setListServiceExpedisi() - setBiayaKirim(0) - setselectedExpedisiService() - setEtd() + setListServiceExpedisi(); + setBiayaKirim(0); + setselectedExpedisiService(); + setEtd(); } - }, [selectedCarrier, selectedAddress, totalWeight]) + }, [selectedCarrier, selectedAddress, totalWeight]); useEffect(() => { if (selectedServiceType) { - let serviceType = selectedServiceType.split(',') - setBiayaKirim(serviceType[0]) - setselectedExpedisiService(serviceType[1]) - setEtd(serviceType[2]) + let serviceType = selectedServiceType.split(','); + setBiayaKirim(serviceType[0]); + setselectedExpedisiService(serviceType[1]); + setEtd(serviceType[2]); } - }, [selectedServiceType]) + }, [selectedServiceType]); useEffect(() => { - if (etd) setEtdFix(calculateEstimatedArrival(etd)) - }, [etd]) + if (etd) setEtdFix(calculateEstimatedArrival(etd)); + }, [etd]); useEffect(() => { if (selectedExpedisi) { - let serviceType = selectedExpedisi.split(',') - if (serviceType[0] === 0) return + let serviceType = selectedExpedisi.split(','); + if (serviceType[0] === 0) return; - setselectedCarrier(serviceType[0]) - setselectedCarrierId(serviceType[1]) - setListServiceExpedisi([]) + setselectedCarrier(serviceType[0]); + setselectedCarrierId(serviceType[1]); + setListServiceExpedisi([]); } - }, [selectedExpedisi]) + }, [selectedExpedisi]); + + const poNumber = useRef(null); + const poFile = useRef(null); - const poNumber = useRef(null) - const poFile = useRef(null) + const [isLoading, setIsLoading] = useState(false); - const [isLoading, setIsLoading] = useState(false) + useEffect(() => { + const GT = + cartCheckout?.grandTotal + + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000; + const finalGT = GT < 0 ? 0 : GT; + setGrandTotal(finalGT); + }, [biayaKirim, cartCheckout?.grandTotal, activeVoucher]); const checkout = async () => { - const file = poFile.current.files[0] + const file = poFile.current.files[0]; if (typeof file !== 'undefined' && file.size > 5000000) { - toast.error('Maksimal ukuran file adalah 5MB', { position: 'bottom-center' }) - return + toast.error('Maksimal ukuran file adalah 5MB', { + position: 'bottom-center', + }); + return; } if (selectedExpedisi === 0) { - setCheckoutValidation(true) + setCheckoutValidation(true); if (expedisiValidation.current) { - const position = expedisiValidation.current.getBoundingClientRect() + const position = expedisiValidation.current.getBoundingClientRect(); window.scrollTo({ top: position.top - 300 + window.pageYOffset, - behavior: 'smooth' - }) + behavior: 'smooth', + }); } - return + return; } if (selectedCarrier != 1 && biayaKirim == 0) { - toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.') - return + toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); + return; } - setIsLoading(true) + setIsLoading(true); const productOrder = products.map((product) => ({ product_id: product.id, - quantity: product.quantity - })) + quantity: product.quantity, + })); let data = { - partner_shipping_id: auth.partnerId, - partner_invoice_id: auth.partnerId, + // partner_shipping_id: auth.partnerId, + // partner_invoice_id: auth.partnerId, + partner_shipping_id: selectedAddress?.shipping?.id || auth.partnerId, + partner_invoice_id: selectedAddress?.invoicing?.id || auth.partnerId, user_id: auth.id, order_line: JSON.stringify(productOrder), delivery_amount: biayaKirim, carrier_id: selectedCarrierId, estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, + flash_sale : hasFlashSale, // dibuat negasi untuk ngetest kebalikan nilai false voucher: activeVoucher, - type: 'sale_order' - } + type: 'sale_order', + }; if (query) { - data.source = 'buy' + data.source = 'buy'; } - if (poNumber.current.value) data.po_number = poNumber.current.value - if (typeof file !== 'undefined') data.po_file = await getFileBase64(file) + if (poNumber.current.value) data.po_number = poNumber.current.value; + if (typeof file !== 'undefined') data.po_file = await getFileBase64(file); - const isCheckouted = await checkoutApi({ data }) + const isCheckouted = await checkoutApi({ data }); if (!isCheckouted?.id) { - toast.error('Gagal melakukan transaksi, terjadi kesalahan internal') - return + toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); + return; } - - gtagPurchase(products, biayaKirim, isCheckouted.name) + + gtagPurchase(products, biayaKirim, isCheckouted.name); const midtrans = async () => { - for (const product of products) deleteItemCart({ productId: product.id }) - const payment = await axios.post( - `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/midtrans-payment?transactionId=${isCheckouted.id}` - ) - setIsLoading(false) - window.location.href = payment.data.redirectUrl - } + for (const product of products) deleteItemCart({ productId: product.id }); + if (grandTotal > 0) { + const payment = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/midtrans-payment?transactionId=${isCheckouted.id}` + ); + setIsLoading(false); + window.location.href = payment.data.redirectUrl; + } else { + window.location.href = `${ + process.env.NEXT_PUBLIC_SELF_HOST + }/shop/checkout/success?order_id=${isCheckouted.name.replace( + /\//g, + '-' + )}`; + } + }; gtag('event', 'conversion', { send_to: 'AW-954540379/nDymCL3BhaQYENvClMcD', - value: cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000, + value: + cartCheckout?.grandTotal + + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000, currency: 'IDR', transaction_id: isCheckouted.id, - event_callback: midtrans - }) - } + event_callback: midtrans, + }); + }; const handlingActivateCode = async () => { - VoucherCode(codeVoucher) - } + VoucherCode(codeVoucher); + }; const handleUseVoucher = async (code, isCheck) => { if (isCheck) { if (code === activeVoucher) { - SetActiveVoucher(null) - SetDiscountVoucher(0) + SetActiveVoucher(null); + SetDiscountVoucher(0); } else { - SetActiveVoucher(code) - SetFindVoucher(null) - document.getElementById('uniqCode').value = '' - SetButtonTerapkan(false) + SetActiveVoucher(code); + SetFindVoucher(null); + document.getElementById('uniqCode').value = ''; + SetButtonTerapkan(false); } } else { - SetActiveVoucher(code) - SetFindVoucher(null) - document.getElementById('uniqCode').value = '' - SetButtonTerapkan(false) + SetActiveVoucher(code); + SetFindVoucher(null); + document.getElementById('uniqCode').value = ''; + SetButtonTerapkan(false); } - } + }; const onChangeCodeVoucher = async (e) => { - SetCodeVoucher(e.target.value) - SetButtonTerapkan(false) - } + SetCodeVoucher(e.target.value); + SetButtonTerapkan(false); + }; - const [isChecked, setIsChecked] = useState(false) + const [isChecked, setIsChecked] = useState(false); const ToggleSwitch = (code) => { - setIsChecked(!isChecked) - handleUseVoucher(code, !isChecked) - } + setIsChecked(!isChecked); + handleUseVoucher(code, !isChecked); + }; const handlingTnC = async (item) => { - setItemTnC(item) - SetBottomPopupTnC(true) - } + setItemTnC(item); + SetBottomPopupTnC(true); + }; // const taxTotal = (totalAmount - totalDiscountAmount - discountVoucher) * 0.11 + const hasNoPrice = useMemo(() => { + if (!products) return false; + for (const item of products) { + if (item.price.priceDiscount == 0) return true; + } + return false; + }, [products]); + return ( <> <BottomPopup className='w-full md:!w-[40%] !min-h-[90vh]' active={bottomPopupTnC} close={() => { - SetBottomPopupTnC(false) - SetBottomPopup(false) + SetBottomPopupTnC(false); + SetBottomPopup(false); }} title={ <div> - <button className='flex gap-x-2 items-center' onClick={() => SetBottomPopupTnC(false)}> - <ChevronLeftIcon class='h- w-5 text-black' /> <span className='text-lg'>Voucher</span> + <button + className='flex gap-x-2 items-center' + onClick={() => SetBottomPopupTnC(false)} + > + <ChevronLeftIcon class='h- w-5 text-black' />{' '} + <span className='text-lg'>Voucher</span> </button>{' '} </div> } @@ -420,13 +472,17 @@ const Checkout = () => { <span className='text-sm'> {' '} Berakhir dalam :{' '} - <span className='text-sm text-red-500'>{itemTnC?.remainingTime} lagi</span> + <span className='text-sm text-red-500'> + {itemTnC?.remainingTime} lagi + </span> </span> </div> <div className='flex items-center gap-x-1'> <BanknotesIcon class='h-6 w-6 text-green-500' /> <span className='text-sm'> Kode Voucher : </span> - <span className='text-red-500 font-semibold'>{itemTnC?.code}</span> + <span className='text-red-500 font-semibold'> + {itemTnC?.code} + </span> </div> </div> <div> @@ -441,6 +497,7 @@ const Checkout = () => { </div> </div> </BottomPopup> + <BottomPopup className='w-full md:!w-[40%] !min-h-[350px]' active={bottomPopup} @@ -448,8 +505,8 @@ const Checkout = () => { title='Gunakan Promo' > <div className='row'> - <div className='flex justify-between items-center'> - <div className='flex md:w-[70%]'> + <div className='flex justify-between items-center gap-x-4'> + <div className='flex flex-1 md:w-[70%]'> <input type='text' id='uniqCode' @@ -481,15 +538,16 @@ const Checkout = () => { {findCodeVoucher === 1 && ( <div className='mt-2'> <span className='text-caption-1 mt-2 text-red-600'> - Kode voucher salah / sudah tidak berlaku lagi. Coba voucher lainnya, ya. + Kode voucher salah / sudah tidak berlaku lagi. Coba voucher + lainnya, ya. </span> </div> )} {findCodeVoucher === 2 && ( <div className='mt-2'> <span className='text-caption-1 mt-2 text-red-600'> - Tambah <span className='text-red-600'>{selisihHargaCode}</span> untuk pakai promo - ini + Tambah <span className='text-red-600'>{selisihHargaCode}</span>{' '} + untuk pakai promo ini </span> </div> )} @@ -500,15 +558,21 @@ const Checkout = () => { <div className='flex items-center justify-center mt-4 mb-4'> <div className='text-center'> <h1 className='font-bold mb-4'>Tidak ada voucher tersedia</h1> - <p className='text-gray-500'>Maaf, saat ini tidak ada voucher yang tersedia.</p> + <p className='text-gray-500'> + Maaf, saat ini tidak ada voucher yang tersedia. + </p> </div> </div> ) : ( - <h3 className='font-semibold mb-4'>Promo Khusus Untuk {auth?.name}</h3> + <h3 className='font-semibold mb-4'> + Promo Khusus Untuk {auth?.name} + </h3> )} {loadingVoucher && ( <> - <div className={`border border-solid w-full hover:cursor-pointer p-2`}> + <div + className={`border border-solid w-full hover:cursor-pointer p-2`} + > <div class='flex items-center space-x-3'> <div class='flex items-center justify-center h-28 w-48 mb-4 bg-gray-300 rounded dark:bg-gray-700'> <svg @@ -529,7 +593,9 @@ const Checkout = () => { </div> </div> </div> - <div className={`border border-solid w-full hover:cursor-pointer p-2`}> + <div + className={`border border-solid w-full hover:cursor-pointer p-2`} + > <div class='flex items-center space-x-3'> <div class='flex items-center justify-center h-28 w-48 mb-4 bg-gray-300 rounded dark:bg-gray-700'> <svg @@ -579,7 +645,9 @@ const Checkout = () => { > <p> Voucher tidak bisa di gunakan,{' '} - <span className='text-red font-bold'>Baca Selengkapnya !</span> + <span className='text-red font-bold'> + Baca Selengkapnya ! + </span> </p> </div> )} @@ -589,14 +657,20 @@ const Checkout = () => { <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0 z-50' /> )} <div className='hidden md:w-[250px] md:block'> - <Image src={item.image} alt={item.name} className={`object-cover`} /> + <Image + src={item.image} + alt={item.name} + className={`object-cover`} + /> </div> <div className='w-full'> <div className='flex justify-between gap-x-2 mb-1 items-center'> <div className=''> <h3 className='font-semibold'>{item.name}</h3> <div className='mt-1'> - <span className='text-sm line-clamp-3'>{item.description} </span> + <span className='text-sm line-clamp-3'> + {item.description}{' '} + </span> </div> </div> <div className='flex justify-end'> @@ -605,7 +679,9 @@ const Checkout = () => { type='checkbox' value='' class='sr-only peer' - checked={activeVoucher === item.code ? true : false} + checked={ + activeVoucher === item.code ? true : false + } onChange={() => ToggleSwitch(item.code)} /> <div class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-green-300 dark:peer-focus:ring-green-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-green-600"></div> @@ -616,11 +692,15 @@ const Checkout = () => { <div className='flex justify-between items-center'> <p className='text-justify text-sm md:text-xs'> Kode Voucher :{' '} - <span className='text-red-500 font-semibold'>{item.code}</span> + <span className='text-red-500 font-semibold'> + {item.code} + </span> </p> <p className='text-sm md:text-xs'> {activeVoucher === item.code && ( - <span className=' text-green-600'>Voucher digunakan </span> + <span className=' text-green-600'> + Voucher digunakan{' '} + </span> )} </p> </div> @@ -642,7 +722,10 @@ const Checkout = () => { <div className='flex justify-between items-center'> <div className='text-left ml-3 text-sm '> Berakhir dalam{' '} - <span className='text-red-600'>{item.remainingTime}</span> lagi,{' '} + <span className='text-red-600'> + {item.remainingTime} + </span>{' '} + lagi,{' '} </div> <div className='text-sm ml-2 text-red-600' @@ -670,6 +753,7 @@ const Checkout = () => { </div> </div> </BottomPopup> + <MobileView> <div className='p-4'> <Alert type='info' className='text-caption-2 flex gap-x-3'> @@ -677,8 +761,8 @@ const Checkout = () => { <ExclamationCircleIcon className='w-7 text-blue-700' /> </div> <span className='leading-5'> - Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami - disini + Jika mengalami kesulitan dalam melakukan pembelian di website + Indoteknik. Hubungi kami disini </span> </Alert> </div> @@ -701,16 +785,22 @@ const Checkout = () => { </svg> <span class='sr-only'>Info</span> <div className='text-justify'> - Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. Apa bila memilih - fitur ini, anda akan dihubungi setelah barang siap diambil. + Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. + Apa bila memilih fitur ini, anda akan dihubungi setelah barang + siap diambil. </div> </div> </div> )} - {selectedCarrierId == SELF_PICKUP_ID && <PickupAddress label='Alamat Pickup' />} + {selectedCarrierId == SELF_PICKUP_ID && ( + <PickupAddress label='Alamat Pickup' /> + )} {selectedCarrierId != SELF_PICKUP_ID && ( - <> + <Skeleton + isLoaded={!!selectedAddress.invoicing && !!selectedAddress.shipping} + minHeight={320} + > <SectionAddress address={selectedAddress.shipping} label='Alamat Pengiriman' @@ -722,7 +812,7 @@ const Checkout = () => { label='Alamat Penagihan' url='/my/address?select=invoice' /> - </> + </Skeleton> )} <Divider /> <SectionValidation address={selectedAddress.invoicing} /> @@ -742,7 +832,10 @@ const Checkout = () => { /> <div className='p-4 flex flex-col gap-y-4'> - {products && <VariantGroupCard openOnClick={false} variants={products} />} + {!!products && + snakecaseKeys(products).map((item, index) => ( + <CartItem key={index} item={item} editable={false} /> + ))} </div> <Divider /> @@ -750,7 +843,6 @@ const Checkout = () => { <div className='p-4'> <div className='flex justify-between items-center'> <div className='font-medium'>Ringkasan Pesanan</div> - <div className='text-gray_r-11 text-caption-1'>{products?.length} Barang</div> </div> <hr className='my-4 border-gray_r-6' /> {!cartCheckout ? ( @@ -804,7 +896,9 @@ const Checkout = () => { {activeVoucher && ( <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Diskon Voucher</div> - <div className='text-danger-500'>- {currencyFormat(discountVoucher)}</div> + <div className='text-danger-500'> + - {currencyFormat(discountVoucher)} + </div> </div> )} <div className='flex gap-x-2 justify-between'> @@ -819,7 +913,11 @@ const Checkout = () => { <div className='text-gray_r-11'> Biaya Kirim <p className='text-xs mt-3'>{etdFix}</p> </div> - <div>{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}</div> + <div> + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} + </div> </div> </div> )} @@ -839,9 +937,7 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat( - cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + {currencyFormat(grandTotal)} </div> </div> )} @@ -852,8 +948,8 @@ const Checkout = () => { <button type='button' onClick={() => { - SetBottomPopup(true) - voucher() + SetBottomPopup(true); + voucher(); }} className='text-gray-900 p-4 flex items-center justify-between rounded-lg bg-white border font-medium border-gray-300 hover:bg-gray-100 py-2.5 h-[50px] w-[100%]' > @@ -886,7 +982,8 @@ const Checkout = () => { </div> {/* <p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p> */} <p className='text-caption-2 text-gray_r-10 leading-5'> - Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} + Dengan melakukan pembelian melalui website Indoteknik, saya + menyetujui{' '} <Link href='/syarat-ketentuan' className='inline font-normal'> Syarat & Ketentuan </Link>{' '} @@ -911,10 +1008,16 @@ const Checkout = () => { </div> <div className='w-6/12'> <label className='form-label font-normal'>Nomor PO</label> - <input type='text' className='form-input mt-2 h-12' ref={poNumber} /> + <input + type='text' + className='form-input mt-2 h-12' + ref={poNumber} + /> </div> </div> - <p className='text-caption-2 text-gray_r-11 mt-2'>Ukuran dokumen PO Maksimal 5MB</p> + <p className='text-caption-2 text-gray_r-11 mt-2'> + Ukuran dokumen PO Maksimal 5MB + </p> </div> <Divider /> @@ -923,7 +1026,13 @@ const Checkout = () => { <button className='flex-1 btn-yellow' onClick={checkout} - disabled={isLoading || !products || products?.length == 0 || priceCheck} + disabled={ + isLoading || + !products || + products?.length == 0 || + priceCheck || + hasNoPrice + } > {isLoading ? 'Loading...' : 'Lanjut Pembayaran'} </button> @@ -957,8 +1066,9 @@ const Checkout = () => { </svg> <span class='sr-only'>Info</span> <div> - Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. Apa bila memilih - fitur ini, anda akan dihubungi setelah barang siap diambil. + Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. + Apa bila memilih fitur ini, anda akan dihubungi setelah barang + siap diambil. </div> </div> )} @@ -966,9 +1076,16 @@ const Checkout = () => { <div className='flex'> {' '} <div className='w-3/4 border border-gray_r-6 rounded bg-white'> - {selectedCarrierId == SELF_PICKUP_ID && <PickupAddress label='Alamat Pickup' />} + {selectedCarrierId == SELF_PICKUP_ID && ( + <PickupAddress label='Alamat Pickup' /> + )} {selectedCarrierId != SELF_PICKUP_ID && ( - <> + <Skeleton + isLoaded={ + !!selectedAddress.invoicing && !!selectedAddress.shipping + } + minHeight={290} + > <SectionAddress address={selectedAddress.shipping} label='Alamat Pengiriman' @@ -980,7 +1097,7 @@ const Checkout = () => { label='Alamat Penagihan' url='/my/address?select=invoice' /> - </> + </Skeleton> )} <Divider /> <SectionValidation address={selectedAddress.invoicing} /> @@ -1000,170 +1117,13 @@ const Checkout = () => { /> <div className='p-4'> - <div className='font-medium'>Detail Pesanan</div> - <CardProdcuctsList isLoading={isLoading} products={products} /> - - {/* <table className='table-checkout'> - <thead> - <tr> - <th>Nama Produk</th> - <th>Jumlah</th> - <th>Harga</th> - <th>Subtotal</th> - </tr> - </thead> - <tbody> - {!products ? ( - <tr> - <td colSpan={4}> - <div className='container my-4'> - <div class='h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4'></div> - <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5'></div> - <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5'></div> - <div class='h-2 bg-gray-200 rounded-full dark:bg-gray-700'></div> - </div> - </td> - </tr> - ) : ( - products?.map((product) => ( - <> - <tr - key={product.id} - className={`${product.program ? '!border-t-0 !border-b-0' : ''}`} - > - <td className='flex'> - <div className='w-[20%] flex-shrink-0'> - <Image - src={product?.parent?.image} - alt={product?.name} - className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' - /> - </div> - <div className='px-2 text-left'> - <div className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'> - {product?.parent?.name} - </div> - <div className='text-gray_r-11 mt-2'> - {product?.code}{' '} - {product?.attributes.length > 0 - ? `| ${product?.attributes.join(', ')}` - : ''} - </div> - <div className='text-gray_r-11 mt-2'> - Berat item : {product?.weight} Kg - </div> - </div> - </td> - <td> - <input - className='form-input w-16 py-2 text-center bg-gray_r-1' - type='number' - value={product?.quantity} - disabled - /> - </td> - <td> - {product?.hasFlashsale ? ( - <> - <div className='flex gap-x-1 items-center justify-center mt-3'> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(product?.price?.price)} - </div> - <div className='badge-solid-red'> - {product?.price?.discountPercentage}% - </div> - </div> - <div className='font-normal mt-1'> - {currencyFormat(product?.price?.priceDiscount)} - </div> - </> - ) : ( - <div className='font-normal mt-1'> - {product.price.priceDiscount > 0 - ? currencyFormat(product?.price?.priceDiscount) - : 'Call for Inquiry'} - </div> - )} - </td> - <td> - <div className='text-danger-500 font-medium'> - {product.price.priceDiscount > 0 ? ( - currencyFormat(product?.price?.priceDiscount * product?.quantity) - ) : ( - <a - href={whatsappUrl('product', { - name: product.name, - url: createSlug( - '/shop/product/', - product.name, - product.id, - true - ) - })} - className='underline' - > - Call for Inquiry{' '} - </a> - )} - </div> - </td> - </tr> - {product.program && - product.program.items && - product.program.items.map((item) => ( - <> - <tr key={product?.program?.id} className='!border-t-0'> - <td className='flex'> - <div className='w-[20%] flex-shrink-0'> - <Image - src={item.parent.image} - alt={item.name} - className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' - /> - </div> - <div className='px-2 text-left'> - <div className=''> - <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'> - {product.program.type.label} - </span> - </div> - <div className='mt-2 line-clamp-2 leading-6'>{item.name}</div> - </div> - </td> - <td> - <input - className='form-input w-16 py-2 text-center bg-gray_r-1' - type='number' - value={1} - disabled - /> - </td> - <td> - {item?.price?.discountPercentage > 0 && ( - <div className='flex gap-x-1 items-center justify-center mt-3'> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(product?.price?.price)} - </div> - </div> - )} - <div className='font-normal mt-1'> - {item?.price.priceDiscount > 0 ? 'Gratis' : ''} - </div> - </td> - <td> - <div className='text-danger-500 font-medium'> - {item.price.priceDiscount > 0 ? 'Gratis' : ''} - </div> - </td> - <td></td> - </tr> - </> - ))} - </> - )) - )} - </tbody> - </table> */} + <div className='font-medium mb-6'>Detail Pesanan</div> + <div className='flex flex-col gap-y-8 border-t border-gray-300 pt-8'> + {!!products && + snakecaseKeys(products).map((item, index) => ( + <CartItem key={index} item={item} editable={false} /> + ))} + </div> </div> </div> <div className='w-1/4 pl-4'> @@ -1171,7 +1131,7 @@ const Checkout = () => { <div className='flex justify-between items-center'> <div className='font-medium'>Ringkasan Pesanan</div> <div className='text-gray_r-11 text-caption-1'> - {products?.length} Barang - {cartCheckout?.totalWeight.kg} Kg + {cartCheckout?.totalWeight.kg} Kg </div> </div> @@ -1227,7 +1187,9 @@ const Checkout = () => { {activeVoucher && ( <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Diskon Voucher</div> - <div className='text-danger-500'>- {currencyFormat(discountVoucher)}</div> + <div className='text-danger-500'> + - {currencyFormat(discountVoucher)} + </div> </div> )} <div className='flex gap-x-2 justify-between'> @@ -1244,7 +1206,9 @@ const Checkout = () => { <p className='text-xs mt-3'>{etdFix}</p> </div> <div> - {currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)} + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} </div> </div> </div> @@ -1265,10 +1229,7 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat( - cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + {currencyFormat(grandTotal)} </div> </div> )} @@ -1279,8 +1240,8 @@ const Checkout = () => { <button type='button' onClick={() => { - SetBottomPopup(true) - voucher() + SetBottomPopup(true); + voucher(); }} className='text-gray-900 p-3 flex items-center justify-between rounded-lg bg-white border font-medium border-gray-300 hover:bg-gray-100 py-2.5 h-[50px] w-[100%]' > @@ -1312,7 +1273,8 @@ const Checkout = () => { </div> <p className='text-caption-2 text-gray_r-11 leading-5'> - Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} + Dengan melakukan pembelian melalui website Indoteknik, saya + menyetujui{' '} <Link href='/syarat-ketentuan' className='inline font-normal'> Syarat & Ketentuan </Link>{' '} @@ -1322,7 +1284,8 @@ const Checkout = () => { <hr className='my-4 border-gray_r-6' /> <div className='font-medium mt-4'> - Purchase Order <span className='font-normal text-gray_r-11'>(Opsional)</span> + Purchase Order{' '} + <span className='font-normal text-gray_r-11'>(Opsional)</span> </div> <div className='mt-4 flex gap-x-3'> @@ -1337,17 +1300,29 @@ const Checkout = () => { </div> <div className='w-6/12'> <label className='form-label font-normal'>Nomor PO</label> - <input type='text' className='form-input mt-2 h-12' ref={poNumber} /> + <input + type='text' + className='form-input mt-2 h-12' + ref={poNumber} + /> </div> </div> - <p className='text-caption-2 text-gray_r-11 mt-2'>Ukuran dokumen PO Maksimal 5MB</p> + <p className='text-caption-2 text-gray_r-11 mt-2'> + Ukuran dokumen PO Maksimal 5MB + </p> <hr className='my-4 border-gray_r-6' /> <button className='w-full btn-yellow mt-4' onClick={checkout} - disabled={isLoading || !products || products?.length == 0 || priceCheck} + disabled={ + isLoading || + !products || + products?.length == 0 || + priceCheck || + hasNoPrice + } > {isLoading ? 'Loading...' : 'Lanjut Pembayaran'} </button> @@ -1367,8 +1342,8 @@ const Checkout = () => { </div> </DesktopView> </> - ) -} + ); +}; const SectionAddress = ({ address, label, url }) => ( <div className='p-4'> @@ -1382,7 +1357,9 @@ const SectionAddress = ({ address, label, url }) => ( {address && ( <div className='mt-4 text-caption-1'> <div className='badge-red mb-2'> - {address.type.charAt(0).toUpperCase() + address.type.slice(1) + ' Address'} + {address.type.charAt(0).toUpperCase() + + address.type.slice(1) + + ' Address'} </div> <p className='font-medium'>{address.name}</p> <p className='mt-2 text-gray_r-11'>{address.mobile}</p> @@ -1392,7 +1369,7 @@ const SectionAddress = ({ address, label, url }) => ( </div> )} </div> -) +); const SectionValidation = ({ address }) => address?.rajaongkirCityId == 0 && ( @@ -1409,7 +1386,7 @@ const SectionValidation = ({ address }) => </Link> </div> </BottomPopup> - ) + ); const SectionExpedisi = ({ address, @@ -1418,7 +1395,7 @@ const SectionExpedisi = ({ checkWeigth, checkoutValidation, expedisiValidation, - loadingRajaOngkir + loadingRajaOngkir, }) => address?.rajaongkirCityId > 0 && ( <div className='p-4' ref={expedisiValidation}> @@ -1427,7 +1404,9 @@ const SectionExpedisi = ({ <div className='w-[250px]'> <div className='flex items-center gap-x-4'> <select - className={`form-input ${checkoutValidation ? 'border-red-500 shake' : ''}`} + className={`form-input ${ + checkoutValidation ? 'border-red-500 shake' : '' + }`} onChange={(e) => setSelectedExpedisi(e.target.value)} required > @@ -1453,7 +1432,7 @@ const SectionExpedisi = ({ animate={{ opacity: 1, width: '28px' }} exit={{ opacity: 0, width: 0 }} transition={{ - duration: 0.25 + duration: 0.25, }} className='overflow-hidden' > @@ -1463,7 +1442,9 @@ const SectionExpedisi = ({ </AnimatePresence> </div> {checkoutValidation && ( - <span className='text-sm text-red-500'>*silahkan pilih expedisi</span> + <span className='text-sm text-red-500'> + *silahkan pilih expedisi + </span> )} </div> <style jsx>{` @@ -1474,18 +1455,19 @@ const SectionExpedisi = ({ </div> {checkWeigth == true && ( <p className='mt-4 text-gray_r-11 leading-6'> - Mohon maaf, pengiriman hanya tersedia untuk self pickup karena terdapat barang yang belum - diatur beratnya. Mohon atur berat barang dengan menghubungi admin melalui{' '} + Mohon maaf, pengiriman hanya tersedia untuk self pickup karena + terdapat barang yang belum diatur beratnya. Mohon atur berat barang + dengan menghubungi admin melalui{' '} <a className='text-danger-500 inline' - href='https://api.whatsapp.com/send?phone=628128080622' + href='https://api.whatsapp.com/send?phone=6281717181922' > tautan ini </a> </p> )} </div> - ) + ); const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) => listserviceExpedisi?.length > 0 && ( @@ -1494,7 +1476,10 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) => <div className='flex justify-between items-center'> <div className='font-medium'>Tipe Layanan Ekspedisi: </div> <div> - <select className='form-input' onChange={(e) => setSelectedServiceType(e.target.value)}> + <select + className='form-input' + onChange={(e) => setSelectedServiceType(e.target.value)} + > {listserviceExpedisi.map((service) => ( <option value={ @@ -1511,7 +1496,9 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) => {' '} {service.description} - {service.service.toUpperCase()} {extractDuration(service.cost[0].etd) && - ` (Estimasi Tiba ${extractDuration(service.cost[0].etd)} Hari)`} + ` (Estimasi Tiba ${extractDuration( + service.cost[0].etd + )} Hari)`} </option> ))} </select> @@ -1520,73 +1507,73 @@ const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) => </div> <Divider /> </> - ) + ); function addDays(date, days) { - const result = new Date(date) - result.setDate(result.getDate() + days) - return result + const result = new Date(date); + result.setDate(result.getDate() + days); + return result; } function formatDate(date) { - const day = date.getDate() - const month = date.toLocaleString('default', { month: 'short' }) - return `${day} ${month}` + const day = date.getDate(); + const month = date.toLocaleString('default', { month: 'short' }); + return `${day} ${month}`; } function calculateEstimatedArrival(duration) { if (duration) { - let estimationDate = duration.split('-') - estimationDate[0] = parseInt(estimationDate[0]) - estimationDate[1] = parseInt(estimationDate[1]) - const from = addDays(new Date(), estimationDate[0] + 3) - const to = addDays(new Date(), estimationDate[1] + 3) + let estimationDate = duration.split('-'); + estimationDate[0] = parseInt(estimationDate[0]); + estimationDate[1] = parseInt(estimationDate[1]); + const from = addDays(new Date(), estimationDate[0] + 3); + const to = addDays(new Date(), estimationDate[1] + 3); - let etdText = `*Estimasi tiba ${formatDate(from)}` + let etdText = `*Estimasi tiba ${formatDate(from)}`; if (estimationDate[1] > estimationDate[0]) { - etdText += ` - ${formatDate(to)}` + etdText += ` - ${formatDate(to)}`; } - return etdText + return etdText; } - return '' + return ''; } function splitDuration(duration) { if (duration) { - let estimationDate = null + let estimationDate = null; if (duration.includes('-')) { - estimationDate = duration.split('-') - estimationDate = parseInt(estimationDate[1]) + estimationDate = duration.split('-'); + estimationDate = parseInt(estimationDate[1]); } else { - estimationDate = parseInt(duration) + estimationDate = parseInt(duration); } - return estimationDate + return estimationDate; } - return '' + return ''; } const extractDuration = (text) => { - const matches = text.match(/\d+(?:-\d+)?/g) + const matches = text.match(/\d+(?:-\d+)?/g); if (matches && matches.length === 1) { - const parts = matches[0].split('-') - const min = parseInt(parts[0]) - const max = parseInt(parts[1]) + const parts = matches[0].split('-'); + const min = parseInt(parts[0]); + const max = parseInt(parts[1]); if (min === max) { - return min.toString() + return min.toString(); } - return matches[0] + return matches[0]; } - return '' -} + return ''; +}; const PickupAddress = ({ label }) => ( <div className='p-4'> @@ -1596,13 +1583,14 @@ const PickupAddress = ({ label }) => ( <div className='mt-4 text-caption-1'> <p className='font-medium'>Indoteknik</p> <p className='mt-2 mb-2 text-gray_r-11 leading-6'> - Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec. Penjaringan, Kota Jkt Utara, - Daerah Khusus Ibukota Jakarta, Indonesia Kodepos : 14440 + Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec. + Penjaringan, Kota Jkt Utara, Daerah Khusus Ibukota Jakarta, Indonesia + Kodepos : 14440 </p> <p className='mt-1 text-gray_r-11'>Telp : 021-2933 8828/29</p> <p className='mt-1 text-gray_r-11'>Mobile : 0813 9000 7430</p> </div> </div> -) +); -export default Checkout +export default Checkout; diff --git a/src/lib/checkout/components/CheckoutOld.jsx b/src/lib/checkout/components/CheckoutOld.jsx index d57fbd66..e2c45ce6 100644 --- a/src/lib/checkout/components/CheckoutOld.jsx +++ b/src/lib/checkout/components/CheckoutOld.jsx @@ -696,7 +696,7 @@ const SectionExpedisi = ({ address, listExpedisi, setSelectedExpedisi, checkWeig diatur beratnya. Mohon atur berat barang dengan menghubungi admin melalui{' '} <a className='text-danger-500 inline' - href='https://api.whatsapp.com/send?phone=628128080622' + href='https://api.whatsapp.com/send?phone=6281717181922' > tautan ini </a> diff --git a/src/lib/checkout/components/CheckoutSection.jsx b/src/lib/checkout/components/CheckoutSection.jsx new file mode 100644 index 00000000..affe6138 --- /dev/null +++ b/src/lib/checkout/components/CheckoutSection.jsx @@ -0,0 +1,257 @@ +import Link from 'next/link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import { AnimatePresence, motion } from 'framer-motion'; +import { Divider, Spinner } from '@chakra-ui/react'; + +export const SectionAddress = ({ address, label, url }) => { + return ( + <div className='p-4'> + <div className='flex justify-between items-center'> + <div className='font-medium'>{label}</div> + <Link className='text-caption-1' href={url}> + Pilih Alamat Lain + </Link> + </div> + + {address && ( + <div className='mt-4 text-caption-1'> + <div className='badge-red mb-2'> + {address.type.charAt(0).toUpperCase() + + address.type.slice(1) + + ' Address'} + </div> + <p className='font-medium'>{address.name}</p> + <p className='mt-2 text-gray_r-11'>{address.mobile}</p> + <p className='mt-1 text-gray_r-11'> + {address.street}, {address?.city?.name} + </p> + </div> + )} + </div> + ); +}; + +export const SectionValidation = ({ address }) => + address?.rajaongkirCityId == 0 && ( + <BottomPopup active={true} title='Update Alamat'> + <div className='leading-7 text-gray_r-12/80'> + Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} + </div> + <div className='flex justify-center mt-6 gap-x-4'> + <Link + className='btn-solid-red w-full md:w-fit text-white' + href={`/my/address/${address?.id}/edit`} + > + Update Alamat + </Link> + </div> + </BottomPopup> + ); + +export const SectionExpedisi = ({ + address, + listExpedisi, + setSelectedExpedisi, + checkWeigth, + checkoutValidation, + expedisiValidation, + loadingRajaOngkir, +}) => + address?.rajaongkirCityId > 0 && ( + <div className='p-4' ref={expedisiValidation}> + <div className='flex justify-between items-center'> + <div className='font-medium'>Pilih Ekspedisi: </div> + <div className='w-[250px]'> + <div className='flex items-center gap-x-4'> + <select + className={`form-input ${ + checkoutValidation ? 'border-red-500 shake' : '' + }`} + onChange={(e) => setSelectedExpedisi(e.target.value)} + required + > + <option value='0,0'>Pilih Pengiriman</option> + <option value='1,32'>SELF PICKUP</option> + {checkWeigth != true && + listExpedisi.map((expedisi) => ( + <option + disabled={checkWeigth} + value={expedisi.label + ',' + expedisi.carrierId} + key={expedisi.value} + > + {' '} + {expedisi.label.toUpperCase()}{' '} + </option> + ))} + </select> + + <AnimatePresence> + {loadingRajaOngkir && ( + <motion.div + initial={{ opacity: 0, width: 0 }} + animate={{ opacity: 1, width: '28px' }} + exit={{ opacity: 0, width: 0 }} + transition={{ + duration: 0.25, + }} + className='overflow-hidden' + > + <Spinner thickness='3px' speed='0.5s' color='red.500' /> + </motion.div> + )} + </AnimatePresence> + </div> + {checkoutValidation && ( + <span className='text-sm text-red-500'> + *silahkan pilih expedisi + </span> + )} + </div> + <style jsx>{` + .shake { + animation: shake 0.4s ease-in-out; + } + `}</style> + </div> + {checkWeigth == true && ( + <p className='mt-4 text-gray_r-11 leading-6'> + Mohon maaf, pengiriman hanya tersedia untuk self pickup karena + terdapat barang yang belum diatur beratnya. Mohon atur berat barang + dengan menghubungi admin melalui{' '} + <a + className='text-danger-500 inline' + href='https://api.whatsapp.com/send?phone=6281717181922' + > + tautan ini + </a> + </p> + )} + </div> + ); + +export const SectionListService = ({ + listserviceExpedisi, + setSelectedServiceType, +}) => + listserviceExpedisi?.length > 0 && ( + <> + <div className='p-4'> + <div className='flex justify-between items-center'> + <div className='font-medium'>Tipe Layanan Ekspedisi: </div> + <div> + <select + className='form-input' + onChange={(e) => setSelectedServiceType(e.target.value)} + > + {listserviceExpedisi.map((service) => ( + <option + value={ + service.cost[0].value + + ',' + + service.description + + '-' + + service.service + + ',' + + extractDuration(service.cost[0].etd) + } + key={service.service} + > + {' '} + {service.description} - {service.service.toUpperCase()} + {extractDuration(service.cost[0].etd) && + ` (Estimasi Tiba ${extractDuration( + service.cost[0].etd + )} Hari)`} + </option> + ))} + </select> + </div> + </div> + </div> + <Divider /> + </> + ); + +export const PickupAddress = ({ label }) => ( + <div className='p-4'> + <div className='flex justify-between items-center'> + <div className='font-medium'>{label}</div> + </div> + <div className='mt-4 text-caption-1'> + <p className='font-medium'>Indoteknik</p> + <p className='mt-2 mb-2 text-gray_r-11 leading-6'> + Jl. Bandengan Utara Raya No.85, RT.3/RW.16, Penjaringan, Kec. + Penjaringan, Kota Jkt Utara, Daerah Khusus Ibukota Jakarta, Indonesia + Kodepos : 14440 + </p> + <p className='mt-1 text-gray_r-11'>Telp : 021-2933 8828/29</p> + <p className='mt-1 text-gray_r-11'>Mobile : 0813 9000 7430</p> + </div> + </div> +); + +const extractDuration = (text) => { + const matches = text.match(/\d+(?:-\d+)?/g); + + if (matches && matches.length === 1) { + const parts = matches[0].split('-'); + const min = parseInt(parts[0]); + const max = parseInt(parts[1]); + + if (min === max) { + return min.toString(); + } + + return matches[0]; + } + + return ''; +}; + +export function calculateEstimatedArrival(duration) { + if (duration) { + let estimationDate = duration.split('-'); + estimationDate[0] = parseInt(estimationDate[0]); + estimationDate[1] = parseInt(estimationDate[1]); + const from = addDays(new Date(), estimationDate[0] + 3); + const to = addDays(new Date(), estimationDate[1] + 3); + + let etdText = `*Estimasi tiba ${formatDate(from)}`; + + if (estimationDate[1] > estimationDate[0]) { + etdText += ` - ${formatDate(to)}`; + } + + return etdText; + } + + return ''; +} + +function addDays(date, days) { + const result = new Date(date); + result.setDate(result.getDate() + days); + return result; +} + +function formatDate(date) { + const day = date.getDate(); + const month = date.toLocaleString('default', { month: 'short' }); + return `${day} ${month}`; +} + +export function splitDuration(duration) { + if (duration) { + let estimationDate = null; + if (duration.includes('-')) { + estimationDate = duration.split('-'); + estimationDate = parseInt(estimationDate[1]); + } else { + estimationDate = parseInt(duration); + } + + return estimationDate; + } + + return ''; +}
\ No newline at end of file diff --git a/src/lib/checkout/email/FinishCheckoutEmail.jsx b/src/lib/checkout/email/FinishCheckoutEmail.jsx index d40ce7d4..d19ba1ca 100644 --- a/src/lib/checkout/email/FinishCheckoutEmail.jsx +++ b/src/lib/checkout/email/FinishCheckoutEmail.jsx @@ -14,8 +14,10 @@ import { Section, Text } from '@react-email/components' +import FinishCheckout from '../components/FinishCheckout' const FinishCheckoutEmail = ({ transaction, payment, statusPayment }) => { + return ( <Html> <Head /> @@ -38,7 +40,10 @@ const FinishCheckoutEmail = ({ transaction, payment, statusPayment }) => { </Heading> <Text style={style.text}>Hai {transaction.address.customer.name},</Text> - <Text style={style.text}> + + {transaction.amountTotal > 0 ? + <div> + <Text style={style.text}> {statusPayment == 'success' && ( <> Terima kasih atas kepercayaan anda berbelanja di Indoteknik. Dengan ini kami @@ -71,202 +76,204 @@ const FinishCheckoutEmail = ({ transaction, payment, statusPayment }) => { & Solution </> )} - </Text> - <Text style={style.text}> - {['pending', 'failed'].includes(statusPayment) && ( - <> - Jika anda mengalami kesulitan, dapat menghubungi Customer Service kami untuk - menanyakan transaksi anda lakukan melalui Whatsapp kami. - </> - )} - {statusPayment == 'success' && ( - <> - Anda dapat menghubungi Customer Service kami untuk menanyakan status pesanan yang - sudah berhasil anda lakukan melalui Whatsapp kami. - </> - )} - {statusPayment == 'manual' && ( + </Text> + <Text style={style.text}> + {['pending', 'failed'].includes(statusPayment) && ( + <> + Jika anda mengalami kesulitan, dapat menghubungi Customer Service kami untuk + menanyakan transaksi anda lakukan melalui Whatsapp kami. + </> + )} + {statusPayment == 'success' && ( + <> + Anda dapat menghubungi Customer Service kami untuk menanyakan status pesanan yang + sudah berhasil anda lakukan melalui Whatsapp kami. + </> + )} + {statusPayment == 'manual' && ( + <> + Kami mohon kepada {transaction.address.customer.name} untuk dapat segera + menyelesaikan transaksi dengan detail dibawah ini: + <ul> + <li>Nomor Pembelian: {transaction.name}</li> + <li>Nominal: {currencyFormat(transaction.amountTotal)}</li> + <li>Tanggal: {transaction.dateOrder}</li> + </ul> + </> + )} + </Text> + + {['pending', 'failed', 'success'].includes(statusPayment) && ( <> - Kami mohon kepada {transaction.address.customer.name} untuk dapat segera - menyelesaikan transaksi dengan detail dibawah ini: - <ul> - <li>Nomor Pembelian: {transaction.name}</li> - <li>Nominal: {currencyFormat(transaction.amountTotal)}</li> - <li>Tanggal: {transaction.dateOrder}</li> - </ul> - </> - )} - </Text> + <Text style={{ ...style.text, lineHeight: '100%', marginTop: '24px' }}> + <strong>Detail Transaksi</strong> + </Text> + + <Hr style={style.hr} /> - {['pending', 'failed', 'success'].includes(statusPayment) && ( - <> - <Text style={{ ...style.text, lineHeight: '100%', marginTop: '24px' }}> - <strong>Detail Transaksi</strong> - </Text> + <Section style={style.alert}> + {statusPayment == 'success' && + 'Struk ini dapat anda simpan sebagai bukti tambahan dalam transaksi yang telah dilakukan.'} + {statusPayment == 'pending' && + 'Kami akan menginformasikan melalui email setelah anda berhasil melakukan pembayaran.'} + {statusPayment == 'failed' && + 'Dimohon untuk tidak melakukan pembayaran. Karena transaksi anda tidak berhasil dibuat.'} + </Section> - <Hr style={style.hr} /> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>No Transaksi (SO)</Column> + <Column style={style.descriptionRCol}>{transaction.name}</Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Tanggal Transaksi</Column> + <Column style={style.descriptionRCol}>{payment.transactionTime}</Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Status Pembayaran</Column> + <Column style={{ ...style.descriptionRCol }}> + {statusPayment == 'success' && ( + <div style={{ ...style.badge, ...style.badgeGreen }}>Berhasil</div> + )} + {statusPayment == 'pending' && ( + <div style={{ ...style.badge, ...style.badgeRed }}>Pending</div> + )} + {statusPayment == 'failed' && ( + <div style={{ ...style.badge, ...style.badgeRed }}>Tidak Berhasil</div> + )} + </Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Metode Pembayaran</Column> + <Column style={style.descriptionRCol}> + {toTitleCase(payment.paymentType.replaceAll('_', ' '))} + </Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Batas Akhir Pembayaran</Column> + <Column style={style.descriptionRCol}>{payment.expiryTime}</Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Nominal Transfer</Column> + <Column style={style.descriptionRCol}> + <span style={{ fontWeight: '600' }}>{currencyFormat(payment.grossAmount)}</span> + </Column> + </Row> - <Section style={style.alert}> - {statusPayment == 'success' && - 'Struk ini dapat anda simpan sebagai bukti tambahan dalam transaksi yang telah dilakukan.'} - {statusPayment == 'pending' && - 'Kami akan menginformasikan melalui email setelah anda berhasil melakukan pembayaran.'} - {statusPayment == 'failed' && - 'Dimohon untuk tidak melakukan pembayaran. Karena transaksi anda tidak berhasil dibuat.'} - </Section> + <Text style={{ ...style.text, lineHeight: '100%', marginTop: '24px' }}> + <strong>Detail Produk</strong> + </Text> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>No Transaksi (SO)</Column> - <Column style={style.descriptionRCol}>{transaction.name}</Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Tanggal Transaksi</Column> - <Column style={style.descriptionRCol}>{payment.transactionTime}</Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Status Pembayaran</Column> - <Column style={{ ...style.descriptionRCol }}> - {statusPayment == 'success' && ( - <div style={{ ...style.badge, ...style.badgeGreen }}>Berhasil</div> - )} - {statusPayment == 'pending' && ( - <div style={{ ...style.badge, ...style.badgeRed }}>Pending</div> - )} - {statusPayment == 'failed' && ( - <div style={{ ...style.badge, ...style.badgeRed }}>Tidak Berhasil</div> - )} - </Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Metode Pembayaran</Column> - <Column style={style.descriptionRCol}> - {toTitleCase(payment.paymentType.replaceAll('_', ' '))} - </Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Batas Akhir Pembayaran</Column> - <Column style={style.descriptionRCol}>{payment.expiryTime}</Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Nominal Transfer</Column> - <Column style={style.descriptionRCol}> - <span style={{ fontWeight: '600' }}>{currencyFormat(payment.grossAmount)}</span> - </Column> - </Row> + <Hr style={style.hr} /> - <Text style={{ ...style.text, lineHeight: '100%', marginTop: '24px' }}> - <strong>Detail Produk</strong> - </Text> + {transaction.products.map((product) => ( + <Row style={style.productRow} key={product.id}> + <Column style={style.productLCol}> + <Img src={product.parent.image} width='100%' /> + </Column> + <Column style={style.productRCol}> + <Text style={style.productName}>{product.name}</Text> + <Text style={style.productCode}>{product.code}</Text> + <div style={{ dislay: 'flex' }}> + <span style={style.productPriceA}> + {currencyFormat(product.price.priceDiscount)} + </span> + {product.price.discountPercentage > 0 && ( + <> + + <span style={style.productPriceB}> + {currencyFormat(product.price.price)} + </span> + </> + )} + x {product.quantity} barang + </div> + </Column> + </Row> + ))} - <Hr style={style.hr} /> + <Hr style={style.hr} /> - {transaction.products.map((product) => ( - <Row style={style.productRow} key={product.id}> - <Column style={style.productLCol}> - <Img src={product.parent.image} width='100%' /> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Subtotal</Column> + <Column style={style.descriptionRCol}> + {currencyFormat(transaction.subtotal)} </Column> - <Column style={style.productRCol}> - <Text style={style.productName}>{product.name}</Text> - <Text style={style.productCode}>{product.code}</Text> - <div style={{ dislay: 'flex' }}> - <span style={style.productPriceA}> - {currencyFormat(product.price.priceDiscount)} - </span> - {product.price.discountPercentage > 0 && ( - <> - - <span style={style.productPriceB}> - {currencyFormat(product.price.price)} - </span> - </> - )} - x {product.quantity} barang - </div> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Total Diskon</Column> + <Column style={{ ...style.descriptionRCol, color: '#E20613' }}> + {currencyFormat(transaction.discountTotal)} + </Column> + </Row> + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>PPN 11% (Incl.)</Column> + <Column style={style.descriptionRCol}> + {currencyFormat(transaction.subtotal * 0.11)} </Column> </Row> - ))} - - <Hr style={style.hr} /> - - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Subtotal</Column> - <Column style={style.descriptionRCol}> - {currencyFormat(transaction.subtotal)} - </Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Total Diskon</Column> - <Column style={{ ...style.descriptionRCol, color: '#E20613' }}> - {currencyFormat(transaction.discountTotal)} - </Column> - </Row> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>PPN 11% (Incl.)</Column> - <Column style={style.descriptionRCol}> - {currencyFormat(transaction.subtotal * 0.11)} - </Column> - </Row> - - <Hr style={style.hr} /> - <Row style={style.descriptionRow}> - <Column style={style.descriptionLCol}>Grand Total</Column> - <Column style={style.descriptionRCol}> - <span style={{ fontWeight: '600' }}> - {currencyFormat(transaction.amountTotal)} - </span> - </Column> - </Row> + <Hr style={style.hr} /> - <Hr style={style.hr} /> - </> - )} + <Row style={style.descriptionRow}> + <Column style={style.descriptionLCol}>Grand Total</Column> + <Column style={style.descriptionRCol}> + <span style={{ fontWeight: '600' }}> + {transaction.amountTotal > 0 ? currencyFormat(transaction.amountTotal) : '0'} + </span> + </Column> + </Row> - {statusPayment == 'manual' && ( - <> - <Text style={style.text}> - Dengan cara dibawah ini: - <ul> - <li> - Lakukan pembayaran manual via mobile app perbankan{' '} - {transaction.address.customer.name} - <br /> - Nama Bank: Bank Central Asia (BCA) - <br /> - No. Rek: 8870400081 - <br /> - A/N: INDOTEKNIK DOTCOM GEMILANG PT - </li> - <li> - Setelah berhasil melakukan pembayaran, mohon agar melakukan Screen Capture bukti - bayar sebagai bukti untuk kami bahwa {transaction.address.customer.name} telah - melakukan transaksi pembayaran - </li> - <li> - Kirimkan bukti transaksi pembayaran anda dengan melakukan reply / balas email - ini dengan melampirkan bukti di attachment / lampiran - </li> - <li> - Transaksi {transaction.address.customer.name} akan segera diproses oleh salah - satu Account Representative Indoteknik - </li> - </ul> - </Text> - <Text style={style.text}> - Jika ada pertanyaan seputar teknis pembayaran {transaction.address.customer.name}{' '} - dapat hubungi kami melalui Email{' '} - <a href='mailto:sales@indoteknik.com'>(sales@indoteknik.com)</a> atau Whatsapp{' '} - <a href={whatsappUrl()} target='_blank' rel='noreferrer'> - (+62 812-8080-622) - </a> - . - </Text> - <Text style={style.text}> - Terima kasih atas perhatiannya, selamat kembali beraktifitas - </Text> - </> - )} + <Hr style={style.hr} /> + </> + )} + {statusPayment == 'manual' && ( + <> + <Text style={style.text}> + Dengan cara dibawah ini: + <ul> + <li> + Lakukan pembayaran manual via mobile app perbankan{' '} + {transaction.address.customer.name} + <br /> + Nama Bank: Bank Central Asia (BCA) + <br /> + No. Rek: 8870400081 + <br /> + A/N: INDOTEKNIK DOTCOM GEMILANG PT + </li> + <li> + Setelah berhasil melakukan pembayaran, mohon agar melakukan Screen Capture bukti + bayar sebagai bukti untuk kami bahwa {transaction.address.customer.name} telah + melakukan transaksi pembayaran + </li> + <li> + Kirimkan bukti transaksi pembayaran anda dengan melakukan reply / balas email + ini dengan melampirkan bukti di attachment / lampiran + </li> + <li> + Transaksi {transaction.address.customer.name} akan segera diproses oleh salah + satu Account Representative Indoteknik + </li> + </ul> + </Text> + <Text style={style.text}> + Jika ada pertanyaan seputar teknis pembayaran {transaction.address.customer.name}{' '} + dapat hubungi kami melalui Email{' '} + <a href='mailto:sales@indoteknik.com'>(sales@indoteknik.com)</a> atau Whatsapp{' '} + <a href={whatsappUrl()} target='_blank' rel='noreferrer'> + (+62 812-8080-622) + </a> + . + </Text> + <Text style={style.text}> + Terima kasih atas perhatiannya, selamat kembali beraktifitas + </Text> + </> + )} + </div> + : <FinishCheckout query={{order_id:transaction.name}}/> + } <Text style={{ ...style.text, margin: '12px 0 3px' }}>Best regards,</Text> <Text style={{ ...style.text, margin: '3px 0 0' }}> diff --git a/src/lib/flashSale/components/FlashSale.jsx b/src/lib/flashSale/components/FlashSale.jsx index 3d5c4e0e..5be6d4e3 100644 --- a/src/lib/flashSale/components/FlashSale.jsx +++ b/src/lib/flashSale/components/FlashSale.jsx @@ -1,26 +1,28 @@ -import { useEffect, useState } from 'react' -import flashSaleApi from '../api/flashSaleApi' -import Image from 'next/image' -import CountDown from '@/core/components/elements/CountDown/CountDown' -import productSearchApi from '@/lib/product/api/productSearchApi' -import ProductSlider from '@/lib/product/components/ProductSlider' -import { FlashSaleSkeleton } from '../skeleton/FlashSaleSkeleton' +import Image from 'next/image'; +import { useEffect, useState } from 'react'; + +import CountDown from '@/core/components/elements/CountDown/CountDown'; +import productSearchApi from '@/lib/product/api/productSearchApi'; +import ProductSlider from '@/lib/product/components/ProductSlider'; + +import flashSaleApi from '../api/flashSaleApi'; +import { FlashSaleSkeleton } from '../skeleton/FlashSaleSkeleton'; const FlashSale = () => { - const [flashSales, setFlashSales] = useState(null) - const [isLoading, setIsLoading] = useState(true) + const [flashSales, setFlashSales] = useState(null); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { const loadFlashSales = async () => { - const dataFlashSales = await flashSaleApi() - setFlashSales(dataFlashSales) - setIsLoading(false) - } - loadFlashSales() - }, []) + const dataFlashSales = await flashSaleApi(); + setFlashSales(dataFlashSales); + setIsLoading(false); + }; + loadFlashSales(); + }, []); if (isLoading) { - return <FlashSaleSkeleton /> + return <FlashSaleSkeleton />; } return ( @@ -29,7 +31,9 @@ const FlashSale = () => { {flashSales.map((flashSale, index) => ( <div key={index}> <div className='flex gap-x-3 mb-4 justify-between sm:justify-start'> - <div className='font-medium sm:text-h-lg mt-1.5'>{flashSale.name}</div> + <div className='font-medium sm:text-h-lg mt-1.5'> + {flashSale.name} + </div> <CountDown initialTime={flashSale.duration} /> </div> @@ -54,24 +58,24 @@ const FlashSale = () => { ))} </div> ) - ) -} + ); +}; const FlashSaleProduct = ({ flashSaleId }) => { - const [products, setProducts] = useState(null) + const [products, setProducts] = useState(null); useEffect(() => { const loadProducts = async () => { const dataProducts = await productSearchApi({ query: `fq=flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale-price-asc`, - operation: 'AND' - }) - setProducts(dataProducts.response) - } - loadProducts() - }, [flashSaleId]) + operation: 'AND', + }); + setProducts(dataProducts.response); + }; + loadProducts(); + }, [flashSaleId]); - return <ProductSlider products={products} /> -} + return <ProductSlider products={products} />; +}; -export default FlashSale +export default FlashSale; diff --git a/src/lib/form/components/KunjunganSales.jsx b/src/lib/form/components/KunjunganSales.jsx index 7470395a..ffa8f135 100644 --- a/src/lib/form/components/KunjunganSales.jsx +++ b/src/lib/form/components/KunjunganSales.jsx @@ -10,6 +10,9 @@ import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import useAuth from '@/core/hooks/useAuth' +import { useRouter } from 'next/router' + const KunjunganSales = () => { const { register, @@ -23,10 +26,18 @@ const KunjunganSales = () => { }) const [cities, setCities] = useState([]) const [companyTypes, setCompanyTypes] = useState([]) + const router = useRouter() + + const auth = useAuth() + + const recaptchaRef = useRef(null) useEffect(() => { + if(auth == false) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name })) @@ -39,7 +50,7 @@ const KunjunganSales = () => { loadCompanyTypes() loadCities() - }, []) + }, [auth]) const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue() diff --git a/src/lib/form/components/KunjunganService.jsx b/src/lib/form/components/KunjunganService.jsx index 1cb0b446..5720d14e 100644 --- a/src/lib/form/components/KunjunganService.jsx +++ b/src/lib/form/components/KunjunganService.jsx @@ -8,6 +8,9 @@ import { toast } from 'react-hot-toast' import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const CreateKunjunganService = () => { const { @@ -22,17 +25,24 @@ const CreateKunjunganService = () => { }) const [cities, setCities] = useState([]) const [company_unit, setCompany_unit] = useState([]) + + const router = useRouter() + + const auth = useAuth() const recaptchaRef = useRef(null) useEffect(() => { + if(auth == false) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })) setCities(dataCities) } loadCities() - }, []) + }, [auth]) const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue() diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index 6c1af231..85f72bf8 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -8,6 +8,9 @@ import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createLeadApi from '../api/createLeadApi'; import PageContent from '@/lib/content/components/PageContent'; +import { useRouter } from 'next/router'; +import useAuth from '@/core/hooks/useAuth' + const CreateMerchant = () => { const { @@ -50,8 +53,14 @@ const CreateMerchant = () => { const [company_unit, setCompany_unit] = useState(list_unit); const recaptchaRef = useRef(null); + const router = useRouter() + + const auth = useAuth() useEffect(() => { + if(auth == false) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi(); dataCities = dataCities.map((city) => ({ @@ -61,7 +70,7 @@ const CreateMerchant = () => { setCities(dataCities); }; loadCities(); - }, []); + }, [auth]); const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue(); diff --git a/src/lib/form/components/PembayaranTempo.jsx b/src/lib/form/components/PembayaranTempo.jsx index 8c624fe2..fc4d248a 100644 --- a/src/lib/form/components/PembayaranTempo.jsx +++ b/src/lib/form/components/PembayaranTempo.jsx @@ -1,12 +1,15 @@ import getFileBase64 from '@/core/utils/getFileBase64' import { yupResolver } from '@hookform/resolvers/yup' -import React, { useRef } from 'react' +import React, { useEffect, useRef } from 'react' import ReCAPTCHA from 'react-google-recaptcha' import { useForm } from 'react-hook-form' import { toast } from 'react-hot-toast' import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const PembayaranTempo = () => { @@ -21,6 +24,15 @@ const PembayaranTempo = () => { }) const recaptchaRef = useRef(null) + const router = useRouter() + + const auth = useAuth() + + useEffect(() => { + if(auth == false) { + router.push('/login') + } + },[auth]) const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue() diff --git a/src/lib/form/components/RequestForQuotation.jsx b/src/lib/form/components/RequestForQuotation.jsx index fa526d5f..68b7fa17 100644 --- a/src/lib/form/components/RequestForQuotation.jsx +++ b/src/lib/form/components/RequestForQuotation.jsx @@ -10,6 +10,9 @@ import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import getFileBase64 from '@/core/utils/getFileBase64' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const RequestForQuotation = () => { const { @@ -26,15 +29,22 @@ const RequestForQuotation = () => { const quotationFileRef = useRef(null) const recaptchaRef = useRef(null) + const router = useRouter() + + const auth = useAuth() + useEffect(() => { + if(auth == false) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name })) setCities(dataCities) } loadCities() - }, []) + }, [auth]) const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue() diff --git a/src/lib/form/components/SuratDukungan.jsx b/src/lib/form/components/SuratDukungan.jsx index d73c3fab..31e7ee83 100644 --- a/src/lib/form/components/SuratDukungan.jsx +++ b/src/lib/form/components/SuratDukungan.jsx @@ -10,6 +10,9 @@ import createLeadsApi from '../api/createLeadApi'; import PageContent from '@/lib/content/components/PageContent'; +import useAuth from '@/core/hooks/useAuth' +import { useRouter } from 'next/router'; + const CreateSuratDukungan = () => { const { register, @@ -25,8 +28,14 @@ const CreateSuratDukungan = () => { const [company_unit, setCompany_unit] = useState([]); const recaptchaRef = useRef(null); + const router = useRouter() + + const auth = useAuth() useEffect(() => { + if(auth == false) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi(); dataCities = dataCities.map((city) => ({ @@ -36,7 +45,7 @@ const CreateSuratDukungan = () => { setCities(dataCities); }; loadCities(); - }, []); + }, [auth]); const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue(); diff --git a/src/lib/home/api/categoryHomeApi.js b/src/lib/home/api/categoryHomeApi.js index 9e7d1402..e5def608 100644 --- a/src/lib/home/api/categoryHomeApi.js +++ b/src/lib/home/api/categoryHomeApi.js @@ -1,11 +1,10 @@ -import odooApi from '@/core/api/odooApi' -import axios from 'axios' +import axios from 'axios'; const categoryHomeIdApi = async ({ id }) => { - // const dataCategoryHomeIdO = await odooApi('GET', `/api/v1/product/category-homepage?id=${id}`) - // console.log('ini adalah odoo', dataCategoryHomeIdO) - const dataCategoryHomeId = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-homepage?id=` + id) - return dataCategoryHomeId.data -} + const dataCategoryHomeId = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-homepage?id=` + id + ); + return dataCategoryHomeId.data; +}; -export default categoryHomeIdApi +export default categoryHomeIdApi; diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 571c4745..ec09aa4e 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,13 +1,41 @@ import { Swiper, SwiperSlide } from 'swiper/react' +import { useCallback, useEffect, useState } from 'react' import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' import useDevice from '@/core/hooks/useDevice' import Link from '@/core/components/elements/Link/Link' +import axios from 'axios' const PreferredBrand = () => { let query = 'level_s' let params = 'prioritas' + const [isLoading, setIsLoading] = useState(true) + const [startWith, setStartWith] = useState(null) + const [manufactures, setManufactures] = useState([]) + + const loadBrand = useCallback(async () => { + setIsLoading(true) + const name = startWith ? `${startWith}*` : '' + const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`) + + setIsLoading(false) + setManufactures((manufactures) => [...result.data]) + }, [startWith]) + + const toggleStartWith = (alphabet) => { + setManufactures([]) + if (alphabet == startWith) { + setStartWith(null) + return + } + setStartWith(alphabet) + } + + useEffect(() => { + loadBrand() + }, [loadBrand]) + const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() @@ -21,12 +49,12 @@ const PreferredBrand = () => { </Link> )} </div> - {preferredBrands.isLoading && <PreferredBrandSkeleton />} - {!preferredBrands.isLoading && ( + {manufactures.isLoading && <PreferredBrandSkeleton />} + {!manufactures.isLoading && ( <Swiper slidesPerView={isMobile ? 3.5 : 7.5} spaceBetween={isMobile ? 12 : 24} freeMode> - {preferredBrands.data?.data.map((brand) => ( - <SwiperSlide key={brand.id}> - <BrandCard brand={brand} /> + {manufactures.map((manufacture) => ( + <SwiperSlide key={manufacture.id}> + <BrandCard brand={manufacture} /> </SwiperSlide> ))} </Swiper> diff --git a/src/lib/home/components/PromotionProgram.jsx b/src/lib/home/components/PromotionProgram.jsx new file mode 100644 index 00000000..b204df8e --- /dev/null +++ b/src/lib/home/components/PromotionProgram.jsx @@ -0,0 +1,66 @@ +import Link from '@/core/components/elements/Link/Link' +import Image from 'next/image' +import { bannerApi } from '@/api/bannerApi'; +import useDevice from '@/core/hooks/useDevice' +import { Swiper, SwiperSlide } from 'swiper/react'; +const { useQuery } = require('react-query') +const BannerSection = () => { + const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' })); + const { isMobile, isDesktop } = useDevice() + + return ( + <div className='px-4 sm:px-0'> + <div className='flex justify-between items-center mb-4 '> + <div className='font-semibold sm:text-h-lg'>Promo Tersedia</div> + {isDesktop && ( + <div></div> + // <Link href='/shop/promo' className='!text-red-500 font-semibold'> + // Lihat Semua + // </Link> + )} + </div> + {isDesktop && (promotionProgram.data && + promotionProgram.data?.length > 0 && ( + <div className='grid grid-cols-3 sm:grid-cols-3 gap-4 rounded-md'> + {promotionProgram.data?.map((banner) => ( + <Link key={banner.id} href={banner.url}> + <Image + width={439} + height={150} + quality={100} + src={banner.image} + alt={banner.name} + className='h-auto w-full rounded hover:scale-105 transition duration-500 ease-in-out' + /> + </Link> + ))} + </div> + + ))} + +{isMobile && ( + + <Swiper slidesPerView={1.1} spaceBetween={8} freeMode> + {promotionProgram.data?.map((banner) => ( + <SwiperSlide key={banner.id}> + <Link key={banner.id} href={banner.url}> + <Image + width={439} + height={150} + quality={100} + src={banner.image} + alt={banner.name} + className='h-auto w-full rounded ' + /> + </Link> + </SwiperSlide> + ))} + </Swiper> + + )} + </div> + + ) +} + +export default BannerSection diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx index 5f034c09..444ddd8e 100644 --- a/src/lib/product/components/Product/ProductDesktop.jsx +++ b/src/lib/product/components/Product/ProductDesktop.jsx @@ -1,416 +1,442 @@ -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import DesktopView from '@/core/components/views/DesktopView' -import currencyFormat from '@/core/utils/currencyFormat' -import { HeartIcon } from '@heroicons/react/24/outline' -import { useCallback, useEffect, useRef, useState } from 'react' -import LazyLoad from 'react-lazy-load' -import ProductSimilar from '../ProductSimilar' -import { toast } from 'react-hot-toast' -import { updateItemCart } from '@/core/utils/cart' -import { useRouter } from 'next/router' -import { createSlug } from '@/core/utils/slug' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import ProductCard from '../ProductCard' -import productSimilarApi from '../../api/productSimilarApi' -import whatsappUrl from '@/core/utils/whatsappUrl' -import odooApi from '@/core/api/odooApi' -import PromotionType from '@/lib/promotinProgram/components/PromotionType' -import useAuth from '@/core/hooks/useAuth' -import ImageNext from 'next/image' -import CountDown2 from '@/core/components/elements/CountDown/CountDown2' -import { LazyLoadComponent } from 'react-lazy-load-image-component' -import ColumnsSLA from './ColumnsSLA' -import { useProductCartContext } from '@/contexts/ProductCartContext' -import { Box, Skeleton, Tooltip } from '@chakra-ui/react' -import { Info } from 'lucide-react' -import Breadcrumb from './Breadcrumb' -import { sellingProductFormat } from '@/core/utils/formatValue' +import { useEffect, useRef, useState } from 'react'; +import ImageNext from 'next/image'; +import { LazyLoadComponent } from 'react-lazy-load-image-component'; +import { Box, Skeleton, Tooltip } from '@chakra-ui/react'; +import { HeartIcon } from '@heroicons/react/24/outline'; +import { Info } from 'lucide-react'; +import LazyLoad from 'react-lazy-load'; +import { toast } from 'react-hot-toast'; +import { useRouter } from 'next/router'; + +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import DesktopView from '@/core/components/views/DesktopView'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import CountDown2 from '@/core/components/elements/CountDown/CountDown2'; + +import currencyFormat from '@/core/utils/currencyFormat'; +import { updateItemCart } from '@/core/utils/cart'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import { sellingProductFormat } from '@/core/utils/formatValue'; + +import odooApi from '@/core/api/odooApi'; +import useAuth from '@/core/hooks/useAuth'; + +import { useProductCartContext } from '@/contexts/ProductCartContext'; + +import PromotionType from '@/lib/promotinProgram/components/PromotionType'; + +import ProductSimilar from '../ProductSimilar'; +import ProductCard from '../ProductCard'; +import productSimilarApi from '../../api/productSimilarApi'; +import ColumnsSLA from './ColumnsSLA'; +import Breadcrumb from './Breadcrumb'; + +import ProductPromoSection from '~/modules/product-promo/components/Section'; const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { - const router = useRouter() - const auth = useAuth() - const { slug } = router.query + const router = useRouter(); + const auth = useAuth(); + const { slug } = router.query; - const [quantityActive, setQuantity] = useState(null) - const [lowestPrice, setLowestPrice] = useState(null) - const [product, setProducts] = useState(products) + const [quantityActive, setQuantity] = useState(null); + const [lowestPrice, setLowestPrice] = useState(null); + const [product, setProducts] = useState(products); - const [addCartAlert, setAddCartAlert] = useState(false) - const [isLoadingSLA, setIsLoadingSLA] = useState(true) - const [promotionType, setPromotionType] = useState(false) - const [promotionActiveId, setPromotionActiveId] = useState(null) - const [selectVariantPromoActive, setSelectVariantPromoActive] = useState(null) - const [backgorundFlashSale, setBackgorundFlashSale] = useState(null) + const [addCartAlert, setAddCartAlert] = useState(false); + const [isLoadingSLA, setIsLoadingSLA] = useState(true); + const [promotionType, setPromotionType] = useState(false); + const [promotionActiveId, setPromotionActiveId] = useState(null); + const [selectVariantPromoActive, setSelectVariantPromoActive] = + useState(null); + const [backgorundFlashSale, setBackgorundFlashSale] = useState(null); - const { setRefreshCart, refreshCart } = useProductCartContext() + const { setRefreshCart, refreshCart } = useProductCartContext(); useEffect(() => { - setLowestPrice({ price: product?.lowestPrice }) - }, [product]) + setLowestPrice({ price: product?.lowestPrice }); + }, [product]); useEffect(() => { const getBackgound = async () => { - const get = await odooApi('GET', '/api/v1/banner?type=flash-sale-background-banner') - setBackgorundFlashSale(get[0].image) - } - getBackgound() - }, []) + const get = await odooApi( + 'GET', + '/api/v1/banner?type=flash-sale-background-banner' + ); + setBackgorundFlashSale(get[0].image); + }; + getBackgound(); + }, []); - const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) + const [informationTab, setInformationTab] = useState( + informationTabOptions[0].value + ); - const variantQuantityRefs = useRef([]) + const variantQuantityRefs = useRef([]); const setVariantQuantityRef = (variantId) => (element) => { if (element) { - let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) - product.variants[variantIndex].quantity = element?.value + let variantIndex = product.variants.findIndex( + (varian) => varian.id == variantId + ); + product.variants[variantIndex].quantity = element?.value; } - variantQuantityRefs.current[variantId] = element - } + variantQuantityRefs.current[variantId] = element; + }; const validQuantity = (quantity) => { - let isValid = true + let isValid = true; if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { - toast.error('Jumlah barang minimal 1') - isValid = false + toast.error('Jumlah barang minimal 1'); + isValid = false; } - return isValid - } + return isValid; + }; const updateCart = (variantId, quantity, source) => { let dataUpdate = { productId: variantId, quantity, selected: true, - source: source === 'buy' ? 'buy' : null - } + source: source === 'buy' ? 'buy' : null, + }; if (product.variants.length > 1) { - let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) - dataUpdate['programLineId'] = product.variants[variantIndex].programActive + let variantIndex = product.variants.findIndex( + (varian) => varian.id == variantId + ); + dataUpdate['programLineId'] = + product.variants[variantIndex].programActive; } else { - dataUpdate['programLineId'] = promotionActiveId + dataUpdate['programLineId'] = promotionActiveId; } - updateItemCart(dataUpdate) - } + updateItemCart(dataUpdate); + }; const redirectToLogin = (action, variantId, quantity) => { - const nextURL = `/shop/product/${slug}?action=${action}&variantId=${variantId}&qty=${quantity}` - router.push(`/login?next=${encodeURIComponent(nextURL)}`) - return true - } + const nextURL = `/shop/product/${slug}?action=${action}&variantId=${variantId}&qty=${quantity}`; + router.push(`/login?next=${encodeURIComponent(nextURL)}`); + return true; + }; const handleAddToCart = (variantId) => { - const quantity = variantQuantityRefs.current[variantId].value + const quantity = variantQuantityRefs.current[variantId].value; - if (!validQuantity(quantity)) return + if (!validQuantity(quantity)) return; if (!auth) { - return redirectToLogin('add_to_cart', variantId, quantity) + return redirectToLogin('add_to_cart', variantId, quantity); } - let source = 'cart' - updateCart(variantId, quantity, source) - setRefreshCart(true) - setAddCartAlert(true) - } + let source = 'cart'; + updateCart(variantId, quantity, source); + setRefreshCart(true); + setAddCartAlert(true); + }; const handleQuantityChange = (variantId) => (event) => { - const { value } = event.target - const variantIndex = product.variants.findIndex((variant) => variant.id === variantId) + const { value } = event.target; + const variantIndex = product.variants.findIndex( + (variant) => variant.id === variantId + ); if (variantIndex !== -1) { - product.variants[variantIndex].quantity = parseInt(value, 10) // Pastikan untuk mengubah ke tipe number jika diperlukan + product.variants[variantIndex].quantity = parseInt(value, 10); // Pastikan untuk mengubah ke tipe number jika diperlukan // Lakukan sesuatu jika nilai quantity diubah } - } + }; const handleBuy = (variant) => { - const quantity = variantQuantityRefs.current[variant].value - if (!validQuantity(quantity)) return + const quantity = variantQuantityRefs.current[variant].value; + if (!validQuantity(quantity)) return; if (!auth) { - return redirectToLogin('buy', variant, quantity) + return redirectToLogin('buy', variant, quantity); } - let source = 'buy' - updateCart(variant, quantity, source) - router.push(`/shop/checkout?source=buy`) - } + let source = 'buy'; + updateCart(variant, quantity, source); + router.push(`/shop/checkout?source=buy`); + }; - const variantSectionRef = useRef(null) + const variantSectionRef = useRef(null); const goToVariantSection = () => { if (variantSectionRef.current) { - const position = variantSectionRef.current.getBoundingClientRect() + const position = variantSectionRef.current.getBoundingClientRect(); window.scrollTo({ top: position.top - 120 + window.pageYOffset, - behavior: 'smooth' - }) + behavior: 'smooth', + }); } - } + }; const handlePromoClick = (variantId) => { - setSelectVariantPromoActive(variantId) - setPromotionType(true) - } + setSelectVariantPromoActive(variantId); + setPromotionType(true); + }; const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=-manufacture_id_i:${product.manufacture?.id || 0}` - ].join('&') + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); - const [productSimilarInBrand, setProductSimilarInBrand] = useState(null) + const [productSimilarInBrand, setProductSimilarInBrand] = useState(null); useEffect(() => { const loadProductSimilarInBrand = async () => { - const productSimilarQuery = [product?.name, `fq=-product_id_i:${product.id}`].join('&') - const source = 'right' - const dataProductSimilar = await productSimilarApi({ query: productSimilarQuery, source }) - setProductSimilarInBrand(dataProductSimilar.products) - } - if (!productSimilarInBrand) loadProductSimilarInBrand() - }, [product, productSimilarInBrand]) + const productSimilarQuery = [ + product?.name, + `fq=-product_id_i:${product.id}`, + ].join('&'); + const source = 'right'; + const dataProductSimilar = await productSimilarApi({ + query: productSimilarQuery, + source, + }); + setProductSimilarInBrand(dataProductSimilar.products); + }; + if (!productSimilarInBrand) loadProductSimilarInBrand(); + }, [product, productSimilarInBrand]); useEffect(() => { const fetchData = async () => { const promises = product.variants.map(async (variant) => { - const dataSLA = await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`) + const dataSLA = await odooApi( + 'GET', + `/api/v1/product_variant/${variant.id}/stock` + ); return { ...variant, - sla: dataSLA - } - }) - const variantData = await Promise.all(promises) - product.variants = variantData + sla: dataSLA, + }; + }); + const variantData = await Promise.all(promises); + product.variants = variantData; - setIsLoadingSLA(false) - } - if (product.variantTotal == 1) fetchData() - }, [product]) + setIsLoadingSLA(false); + }; + if (product.variantTotal == 1) fetchData(); + }, [product]); return ( <DesktopView> <div className='container mx-auto pt-10'> <Breadcrumb productId={product.id} productName={product.name} /> - <div className='flex'> - <div className='w-full flex flex-wrap'> - <div className='w-5/12'> - <div className='relative mb-2'> - {product?.flashSale?.remainingTime > 0 && - lowestPrice?.price.discountPercentage > 0 && ( - <div className={`absolute bottom-0 w-full`}> - <div className='absolute bottom-0 w-full h-full'> - <ImageNext - src={backgorundFlashSale || '/images/GAMBAR-BG-FLASH-SALE.jpg'} - width={1000} - height={100} - /> - </div> - <div className='relative'> - <div className='flex gap-x-2 items-center p-2'> - <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> - <span className='text-lg font-bold'> - {Math.floor(product.lowestPrice.discountPercentage)}% - </span> - </div> - <div - className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-4`} - > - <ImageNext - src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' - width={17} - height={10} - /> - <span className='text-white text-lg font-semibold'> - {product?.flashSale?.tag != 'false' || product?.flashSale?.tag - ? product?.flashSale?.tag - : 'FLASH SALE'} - </span> - </div> - <div> - <CountDown2 initialTime={product.flashSale.remainingTime} /> - </div> + + <div className='w-full flex flex-wrap'> + <div className='w-3/12'> + <div className='relative mb-2'> + {product?.flashSale?.remainingTime > 0 && + lowestPrice?.price.discountPercentage > 0 && ( + <div className={`absolute bottom-0 w-full`}> + <div className='absolute bottom-0 w-full h-full'> + <ImageNext + src={ + backgorundFlashSale || + '/images/BG-FLASH-SALE.jpg' + } + width={1000} + height={100} + className='h-full' + /> + </div> + <div className='relative'> + <div className='flex gap-x-2 items-center p-2'> + <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> + <span className='text-lg font-bold'> + {Math.floor(product.lowestPrice.discountPercentage)} + % + </span> + </div> + <div + className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-1`} + > + <ImageNext + src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' + width={17} + height={10} + /> + <span className='text-white text-sm font-semibold'> + {product?.flashSale?.tag != 'false' || + product?.flashSale?.tag + ? product?.flashSale?.tag + : 'FLASH SALE'} + </span> + </div> + <div> + <CountDown2 + initialTime={product.flashSale.remainingTime} + /> </div> </div> </div> - )} - <Image - src={product.image} - alt={product.name} - className='h-[430px] object-contain object-center w-full border border-gray_r-4' - /> - </div> - <div> - <p className='text-justify text-xs leading-5'> - <span className='font-semibold '>Keterangan : </span>Gambar atau foto berperan - sebagai ilustrasi produk. Kadang tidak sesuai dengan kondisi terbaru dengan - berbagai perubahan dan perbaikan. Hubungi tim sales kami untuk informasi yang - lebih baik perihal gambar di 021-2933 8828. - </p> - </div> - </div> - - <div className='w-7/12 px-4'> - <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> - <div className='mt-10'> - <div className='flex p-3'> - <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> - <div className='w-8/12'>SKU-{product.id}</div> - </div> - <div className='flex p-3 bg-gray_r-4'> - <div className='w-4/12 text-gray_r-12/70'>Part Number</div> - <div className='w-8/12'>{product.code || '-'}</div> - </div> - <div className='flex p-3'> - <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> - <div className='w-8/12'> - {product.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product.manufacture?.name, - product.manufacture?.id - )} - > - {product.manufacture?.name} - </Link> - ) : ( - <div>-</div> - )} </div> - </div> - <div className='flex p-3 items-center bg-gray_r-4'> - <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> - <div className='w-8/12'> - {product.variants.length > 1 && ( - <button - type='button' - onClick={goToVariantSection} - className={`flex gap-x-1 items-center p-2 rounded-lg w-auto btn-light`} - > - <span className='text-red-600 text-sm'>Lihat Selengkapnya</span> - </button> - )} + )} + <Image + src={product.image} + alt={product.name} + className='h-[430px] object-contain object-center w-full border border-gray_r-4' + /> + </div> + <div> + <p className='text-justify text-xs leading-5'> + <span className='font-semibold '>Keterangan : </span>Gambar atau + foto berperan sebagai ilustrasi produk. Kadang tidak sesuai + dengan kondisi terbaru dengan berbagai perubahan dan perbaikan. + Hubungi tim sales kami untuk informasi yang lebih baik perihal + gambar di 021-2933 8828. + </p> + </div> + </div> - {product.variants.length === 1 && ( - <> - {!product.variants[0]?.sla && <Skeleton width='20%' height='16px' />} - {product.variants[0]?.sla && ( - <Tooltip - placement='top' - label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`} - > - <Box className='w-fit flex items-center gap-x-2'> - {product.variants[0]?.sla?.slaDate} - <Info size={16} /> - </Box> - </Tooltip> - )} - </> - )} - </div> + <div className='w-6/12 px-6'> + <h1 className='text-title-md leading-10 font-medium'> + {product?.name} + </h1> + <div className='mt-10'> + <div className='flex p-3'> + <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> + <div className='w-8/12'>SKU-{product.id}</div> + </div> + <div className='flex p-3 bg-gray_r-4'> + <div className='w-4/12 text-gray_r-12/70'>Part Number</div> + <div className='w-8/12'>{product.code || '-'}</div> + </div> + <div className='flex p-3'> + <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> + <div className='w-8/12'> + {product.manufacture?.name ? ( + <Link + href={createSlug( + '/shop/brands/', + product.manufacture?.name, + product.manufacture?.id + )} + > + {product.manufacture?.name} + </Link> + ) : ( + <div>-</div> + )} </div> + </div> + <div className='flex p-3 items-center bg-gray_r-4'> + <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> + <div className='w-8/12'> + {product.variants.length > 1 && ( + <button + type='button' + onClick={goToVariantSection} + className={`flex gap-x-1 items-center p-2 rounded-lg w-auto btn-light`} + > + <span className='text-red-600 text-sm'> + Lihat Selengkapnya + </span> + </button> + )} - {product.variants.length === 1 && ( - <div className='flex p-3 '> - <div className='w-4/12 text-gray_r-12/70'>Stock</div> - <div className='w-8/12'> - {!product.variants[0]?.sla && <Skeleton width='10%' height='16px' />} - {product?.variants[0].sla?.qty > 0 && ( - <span>{product?.variants[0].sla?.qty}</span> + {product.variants.length === 1 && ( + <> + {!product.variants[0]?.sla && ( + <Skeleton width='20%' height='16px' /> )} - {product?.variants[0].sla?.qty == 0 && ( - <a - href={whatsappUrl('product', { - name: product.name, - manufacture: product?.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 font-medium' + {product.variants[0]?.sla && ( + <Tooltip + placement='top' + label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`} > - Tanya Admin - </a> + <Box className='w-fit flex items-center gap-x-2'> + {product.variants[0]?.sla?.slaDate} + <Info size={16} /> + </Box> + </Tooltip> )} - </div> - </div> - )} + </> + )} + </div> + </div> - <div className={`flex p-3 ${product.variants.length > 1 ? '' : 'bg-gray_r-4'} `}> - <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + {product.variants.length === 1 && ( + <div className='flex p-3 '> + <div className='w-4/12 text-gray_r-12/70'>Stock</div> <div className='w-8/12'> - {product?.weight > 0 && <span>{product?.weight} KG</span>} - {product?.weight == 0 && ( + {!product.variants[0]?.sla && ( + <Skeleton width='10%' height='16px' /> + )} + {product?.variants[0].sla?.qty > 0 && ( + <span>{product?.variants[0].sla?.qty}</span> + )} + {product?.variants[0].sla?.qty == 0 && ( <a - href={whatsappUrl('productWeight', { + href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + manufacture: product?.manufacture?.name, + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > - Tanya Berat + Tanya Admin </a> )} </div> </div> - {product.variants.length <= 1 && ( - <div className='pt-3'> - <div className='flex mt-1'> - <PromotionType - variantId={product.variants[0].id} - setPromotionActiveId={setPromotionActiveId} - promotionActiveId={promotionActiveId} - quantity={quantityActive} - product={product} - ></PromotionType> - </div> - </div> - )} - </div> - </div> + )} - <div className='w-full'> - <div className='mt-12'> - <div className='text-h-lg font-semibold'>Informasi Produk</div> - <div className='flex gap-x-4 mt-6 mb-4'> - {informationTabOptions.map((option) => ( - <TabButton - value={option.value} - key={option.value} - active={informationTab == option.value} - onClick={() => setInformationTab(option.value)} + <div + className={`flex p-3 ${ + product.variants.length > 1 ? '' : 'bg-gray_r-4' + } `} + > + <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + <div className='w-8/12'> + {product?.weight > 0 && <span>{product?.weight} KG</span>} + {product?.weight == 0 && ( + <a + href={whatsappUrl('productWeight', { + name: product.name, + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), + })} + className='text-danger-500 font-medium' > - {option.label} - </TabButton> - ))} + Tanya Berat + </a> + )} </div> - <div className='flex'> - <div className='w-3/4 leading-8 product__description'> - <TabContent active={informationTab == 'description'}> - <span - dangerouslySetInnerHTML={{ - __html: - product.description != '' - ? product.description - : 'Belum ada deskripsi produk.' - }} - /> - </TabContent> - - <TabContent active={informationTab == 'information'}> - Belum ada informasi. - </TabContent> + </div> + {product.variants.length <= 1 && ( + <div className='pt-3'> + <div className='flex mt-1'> + <PromotionType + variantId={product.variants[0].id} + setPromotionActiveId={setPromotionActiveId} + promotionActiveId={promotionActiveId} + quantity={quantityActive} + product={product} + ></PromotionType> + <ProductPromoSection productId={product.variants[0].id} /> </div> </div> - </div> + )} </div> </div> - <div className='w-[30%]'> - {product.variants.length > 1 && product.lowestPrice.priceDiscount > 0 && ( - <div className='text-gray_r-12/80'>Harga mulai dari: </div> - )} + <div className='w-3/12'> + {product.variants.length > 1 && + product.lowestPrice.priceDiscount > 0 && ( + <div className='text-gray_r-12/80'>Harga mulai dari: </div> + )} {/* {lowestPrice?.discountPercentage > 0 && ( <div className='flex gap-x-1 items-center mt-2'> @@ -441,7 +467,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { {sellingProductFormat(product?.qtySold) + ' Terjual'} </div> )} - {product?.flashSale?.id && lowestPrice?.price.discountPercentage > 0 ? ( + {product?.flashSale?.id && + lowestPrice?.price.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 items-center mt-2'> <div className='badge-solid-red text-caption-1'> @@ -456,7 +483,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(lowestPrice?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + lowestPrice?.price.priceDiscount * + process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -466,7 +496,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { {currencyFormat(lowestPrice?.price.price)} <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(lowestPrice?.price.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + lowestPrice?.price.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -476,7 +508,12 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { href={whatsappUrl('product', { name: product.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 underline' rel='noopener noreferrer' @@ -524,7 +561,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { )} <div className='flex mt-4'> - <button className='flex items-center gap-x-1' onClick={toggleWishlist}> + <button + className='flex items-center gap-x-1' + onClick={toggleWishlist} + > {wishlist.data?.productTotal > 0 ? ( <HeartIcon className='w-6 fill-danger-500 text-danger-500' /> ) : ( @@ -538,7 +578,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className='font-medium text-center p-4 bg-gray_r-1 border-b border-gray_r-6 sticky top-0 z-10'> Produk Serupa </div> - <div className='h-full divide-y divide-gray_r-6 max-h-96'> + <div className='h-full divide-y divide-gray_r-6 max-h-[550px]'> {productSimilarInBrand && productSimilarInBrand?.map((product) => ( <div className='py-2' key={product.id}> @@ -550,6 +590,42 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> </div> + <div className='w-full'> + <div className='mt-12'> + <div className='text-h-lg font-semibold'>Informasi Produk</div> + <div className='flex gap-x-4 mt-6 mb-4'> + {informationTabOptions.map((option) => ( + <TabButton + value={option.value} + key={option.value} + active={informationTab == option.value} + onClick={() => setInformationTab(option.value)} + > + {option.label} + </TabButton> + ))} + </div> + <div className='flex'> + <div className='w-3/4 leading-8 product__description'> + <TabContent active={informationTab == 'description'}> + <span + dangerouslySetInnerHTML={{ + __html: + product.description != '' + ? product.description + : 'Belum ada deskripsi produk.', + }} + /> + </TabContent> + + <TabContent active={informationTab == 'information'}> + Belum ada informasi. + </TabContent> + </div> + </div> + </div> + </div> + {product.variants.length > 1 && ( <div className='mt-12' ref={variantSectionRef}> <div className='text-h-lg font-semibold mb-6'>Varian Produk</div> @@ -571,7 +647,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <tr key={variant.id}> <td className='flex items-center justify-center gap-x-1'> {variant.isFlashsale && ( - <span className='blink-color-flash-sale'>🗲</span> + <span className='blink-color-flash-sale'> + 🗲 + </span> )} {variant.code} </td> @@ -580,11 +658,13 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <ColumnsSLA variant={variant} product={product} /> </LazyLoadComponent> <td> - {variant.isFlashsale && variant?.price?.discountPercentage > 0 ? ( + {variant.isFlashsale && + variant?.price?.discountPercentage > 0 ? ( <> <div className='flex items-center gap-x-1 justify-center'> <div className='badge-solid-red text-caption-1'> - {Math.floor(variant?.price?.discountPercentage)}% + {Math.floor(variant?.price?.discountPercentage)} + % </div> <div className='line-through text-caption-1 text-gray_r-11'> {currencyFormat(variant?.price?.price)} @@ -596,7 +676,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className=' text-caption-1 text-gray_r-11 mb-1'> Inc. PPN:{' '} {currencyFormat( - variant.price.priceDiscount * process.env.NEXT_PUBLIC_PPN + variant.price.priceDiscount * + process.env.NEXT_PUBLIC_PPN )} </div> </> @@ -610,7 +691,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className=' text-caption-1 text-gray_r-11 mb-1'> Inc. PPN:{' '} {currencyFormat( - variant?.price?.price * process.env.NEXT_PUBLIC_PPN + variant?.price?.price * + process.env.NEXT_PUBLIC_PPN )} </div> </> @@ -619,7 +701,12 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { href={whatsappUrl('product', { name: variant.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-red_r-11' rel='noopener noreferrer' @@ -705,11 +792,14 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { )} <div className='my-12'> - <div className='text-h-lg font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-lg font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> </div> + <BottomPopup className=' !h-[75%]' title='Pakai Promo' @@ -728,6 +818,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { ></PromotionType> </div> </BottomPopup> + <BottomPopup className='!container' title='Berhasil Ditambahkan' @@ -742,16 +833,23 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { className='h-32 object-contain object-center w-full border border-gray_r-4' /> </div> - <div className='ml-3 flex flex-1 items-center font-normal'>{product.name}</div> + <div className='ml-3 flex flex-1 items-center font-normal'> + {product.name} + </div> <div className='ml-3 flex items-center font-normal'> - <Link href='/shop/cart' className='flex-1 py-2 text-gray_r-12 btn-yellow'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > Lihat Keranjang </Link> </div> </div> <div className='mt-8 mb-4'> - <div className='text-h-sm font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> @@ -759,29 +857,33 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </BottomPopup> </div> </DesktopView> - ) -} + ); +}; const informationTabOptions = [ { value: 'description', label: 'Deskripsi' }, - { value: 'information', label: 'Info Penting' } -] + { value: 'information', label: 'Info Penting' }, +]; const TabButton = ({ children, active, ...props }) => { const activeClassName = active ? 'text-danger-500 underline underline-offset-4' - : 'text-gray_r-12/80' + : 'text-gray_r-12/80'; return ( - <button {...props} type='button' className={`font-medium ${activeClassName}`}> + <button + {...props} + type='button' + className={`font-medium ${activeClassName}`} + > {children} </button> - ) -} + ); +}; const TabContent = ({ children, active, className = '', ...props }) => ( <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}> {children} </div> -) +); -export default ProductDesktop +export default ProductDesktop; diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index ef61bafd..09b30a44 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -1,137 +1,155 @@ -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import DesktopView from '@/core/components/views/DesktopView' -import currencyFormat from '@/core/utils/currencyFormat' -import { HeartIcon } from '@heroicons/react/24/outline' -import { useCallback, useEffect, useRef, useState } from 'react' -import LazyLoad from 'react-lazy-load' -import ProductSimilar from '../ProductSimilar' -import { toast } from 'react-hot-toast' -import { updateItemCart } from '@/core/utils/cart' -import { useRouter } from 'next/router' -import { createSlug } from '@/core/utils/slug' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import ProductCard from '../ProductCard' -import productSimilarApi from '../../api/productSimilarApi' -import whatsappUrl from '@/core/utils/whatsappUrl' -import useAuth from '@/core/hooks/useAuth' -import odooApi from '@/core/api/odooApi' -import { useProductCartContext } from '@/contexts/ProductCartContext' -import { Box, Skeleton, Tooltip } from '@chakra-ui/react' -import { Info } from 'lucide-react' - -const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) => { - const router = useRouter() - const auth = useAuth() - const { slug } = router.query - - const [lowestPrice, setLowestPrice] = useState(null) - - const [addCartAlert, setAddCartAlert] = useState(false) - const [isLoadingSLA, setIsLoadingSLA] = useState(true) - - const { setRefreshCart } = useProductCartContext() + +import { Box, Skeleton, Tooltip } from '@chakra-ui/react'; +import { HeartIcon } from '@heroicons/react/24/outline'; +import { Info } from 'lucide-react'; +import { useRouter } from 'next/router'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { toast } from 'react-hot-toast'; +import LazyLoad from 'react-lazy-load'; + +import { useProductCartContext } from '@/contexts/ProductCartContext'; +import odooApi from '@/core/api/odooApi'; +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import DesktopView from '@/core/components/views/DesktopView'; +import useAuth from '@/core/hooks/useAuth'; +import { updateItemCart } from '@/core/utils/cart'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; + +import productSimilarApi from '../../api/productSimilarApi'; +import ProductCard from '../ProductCard'; +import ProductSimilar from '../ProductSimilar'; + +const ProductDesktopVariant = ({ + product, + wishlist, + toggleWishlist, + isVariant, +}) => { + const router = useRouter(); + const auth = useAuth(); + const { slug } = router.query; + + const [lowestPrice, setLowestPrice] = useState(null); + + const [addCartAlert, setAddCartAlert] = useState(false); + const [isLoadingSLA, setIsLoadingSLA] = useState(true); + + const { setRefreshCart } = useProductCartContext(); const getLowestPrice = useCallback(() => { - const lowest = product.price + const lowest = product.price; /* const lowest = prices.reduce((lowest, price) => { return price.priceDiscount < lowest.priceDiscount ? price : lowest }, prices[0])*/ - return lowest - }, [product]) + return lowest; + }, [product]); useEffect(() => { - const lowest = getLowestPrice() - setLowestPrice(lowest) - }, [getLowestPrice]) + const lowest = getLowestPrice(); + setLowestPrice(lowest); + }, [getLowestPrice]); - const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) + const [informationTab, setInformationTab] = useState( + informationTabOptions[0].value + ); - const variantQuantityRefs = useRef([]) + const variantQuantityRefs = useRef([]); const setVariantQuantityRef = (variantId) => (element) => { - variantQuantityRefs.current[variantId] = element - } + variantQuantityRefs.current[variantId] = element; + }; const validQuantity = (quantity) => { - let isValid = true + let isValid = true; if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { - toast.error('Jumlah barang minimal 1') - isValid = false + toast.error('Jumlah barang minimal 1'); + isValid = false; } - return isValid - } + return isValid; + }; const handleAddToCart = (variant) => { if (!auth) { - router.push(`/login?next=/shop/product/${slug}`) - return + router.push(`/login?next=/shop/product/${slug}`); + return; } - const quantity = variantQuantityRefs.current[product.id].value - if (!validQuantity(quantity)) return + const quantity = variantQuantityRefs.current[product.id].value; + if (!validQuantity(quantity)) return; updateItemCart({ productId: product.id, quantity, programLineId: null, selected: true, - source: null + source: null, }).then(() => { - setRefreshCart(true) - }) - setAddCartAlert(true) - } + setRefreshCart(true); + }); + setAddCartAlert(true); + }; const handleBuy = (variant) => { - const quantity = variantQuantityRefs.current[product.id].value - if (!validQuantity(quantity)) return + const quantity = variantQuantityRefs.current[product.id].value; + if (!validQuantity(quantity)) return; updateItemCart({ productId: variant, quantity, programLineId: null, selected: true, - source: 'buy' - }) - router.push(`/shop/checkout?source=buy`) - } + source: 'buy', + }); + router.push(`/shop/checkout?source=buy`); + }; - const variantSectionRef = useRef(null) + const variantSectionRef = useRef(null); const goToVariantSection = () => { if (variantSectionRef.current) { - const position = variantSectionRef.current.getBoundingClientRect() + const position = variantSectionRef.current.getBoundingClientRect(); window.scrollTo({ top: position.top - 120 + window.pageYOffset, - behavior: 'smooth' - }) + behavior: 'smooth', + }); } - } + }; const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=-manufacture_id_i:${product.manufacture?.id || 0}` - ].join('&') + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); - const [productSimilarInBrand, setProductSimilarInBrand] = useState(null) + const [productSimilarInBrand, setProductSimilarInBrand] = useState(null); useEffect(() => { const loadProductSimilarInBrand = async () => { - const productSimilarQuery = [product?.name, `fq=-product_id_i:${product.id}`].join('&') - const dataProductSimilar = await productSimilarApi({ query: productSimilarQuery }) - setProductSimilarInBrand(dataProductSimilar.products) - } - if (!productSimilarInBrand) loadProductSimilarInBrand() - }, [product, productSimilarInBrand]) + const productSimilarQuery = [ + product?.name, + `fq=-product_id_i:${product.id}`, + ].join('&'); + const dataProductSimilar = await productSimilarApi({ + query: productSimilarQuery, + }); + setProductSimilarInBrand(dataProductSimilar.products); + }; + if (!productSimilarInBrand) loadProductSimilarInBrand(); + }, [product, productSimilarInBrand]); useEffect(() => { const fetchData = async () => { - const dataSLA = await odooApi('GET', `/api/v1/product_variant/${product.id}/stock`) - product.sla = dataSLA + const dataSLA = await odooApi( + 'GET', + `/api/v1/product_variant/${product.id}/stock` + ); + product.sla = dataSLA; - setIsLoadingSLA(false) - } - fetchData() - }, [product]) + setIsLoadingSLA(false); + }; + fetchData(); + }, [product]); return ( <DesktopView> @@ -140,14 +158,16 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) <div className='w-full flex flex-wrap'> <div className='w-5/12'> <Image - src={product.image} + src={product.image + '?variant=True'} alt={product.name} className='h-[430px] object-contain object-center w-full border border-gray_r-4' /> </div> <div className='w-7/12 px-4'> - <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> + <h1 className='text-title-md leading-10 font-medium'> + {product?.name} + </h1> <div className='mt-10'> <div className='flex p-3'> <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> @@ -177,7 +197,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> <div className='flex p-3 items-center bg-gray_r-4'> - <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> + <div className='w-4/12 text-gray_r-12/70'> + Persiapan Barang + </div> <div className='w-8/12'> {!product?.sla && <Skeleton width='20%' height='16px' />} {product?.sla && ( @@ -203,8 +225,13 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) <a href={whatsappUrl('product', { name: product.name, - manufacture: product?.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + manufacture: product?.manufacture?.name, + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -221,7 +248,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) <a href={whatsappUrl('productWeight', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -233,44 +265,23 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> </div> - {/* <div className='w-full'> - <div className='mt-12'> - <div className='text-h-lg font-semibold'>Informasi Produk</div> - <div className='flex gap-x-4 mt-6 mb-4'> - {informationTabOptions.map((option) => ( - <TabButton - value={option.value} - key={option.value} - active={informationTab == option.value} - onClick={() => setInformationTab(option.value)} - > - {option.label} - </TabButton> - ))} - </div> - <div className='flex'> - <div className='w-3/4 leading-7 product__description'> - <TabContent active={informationTab == 'description'}> - <span - dangerouslySetInnerHTML={{ - __html: - product.description != '' - ? product.description - : 'Belum ada deskripsi produk.' - }} - /> - </TabContent> - - <TabContent active={informationTab == 'information'}> - Belum ada informasi. - </TabContent> - </div> - </div> - </div> - </div> */} + <div className='p-4 md:p-6 md:bg-gray-50 rounded-xl'> + <h2 className='text-h-md md:text-h-lg font-medium'>Informasi Produk</h2> + <div className='h-4' /> + <div + className='leading-relaxed text-gray-700' + dangerouslySetInnerHTML={{ + __html: + !product.parent.description || product.parent.description == '<p><br></p>' + ? 'Belum ada deskripsi' + : product.parent.description, + }} + /> + </div> </div> <div className='w-[25%]'> - {product?.isFlashsale > 0 && product?.price?.discountPercentage > 0? ( + {product?.isFlashsale > 0 && + product?.price?.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 items-center mt-2'> <div className='badge-solid-red text-caption-1'> @@ -285,7 +296,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -295,7 +308,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) {currencyFormat(product?.price?.price)} <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(product?.price?.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product?.price?.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -305,7 +320,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) href={whatsappUrl('product', { name: product.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 underline' rel='noopener noreferrer' @@ -340,7 +360,10 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </button> </div> <div className='flex mt-4'> - <button className='flex items-center gap-x-1' onClick={toggleWishlist}> + <button + className='flex items-center gap-x-1' + onClick={toggleWishlist} + > {wishlist.data?.productTotal > 0 ? ( <HeartIcon className='w-6 fill-danger-500 text-danger-500' /> ) : ( @@ -366,7 +389,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </div> <div className='my-12'> - <div className='text-h-lg font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-lg font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> @@ -381,21 +406,28 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) <div className='flex mt-4'> <div className='w-[10%]'> <Image - src={product.image} + src={product.image + '?variant=True'} alt={product.name} className='h-32 object-contain object-center w-full border border-gray_r-4' /> </div> - <div className='ml-3 flex flex-1 items-center font-normal'>{product.name}</div> + <div className='ml-3 flex flex-1 items-center font-normal'> + {product.name} + </div> <div className='ml-3 flex items-center font-normal'> - <Link href='/shop/cart' className='flex-1 py-2 text-gray_r-12 btn-yellow'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > Lihat Keranjang </Link> </div> </div> <div className='mt-8 mb-4'> - <div className='text-h-sm font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> @@ -403,29 +435,33 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) </BottomPopup> </div> </DesktopView> - ) -} + ); +}; const informationTabOptions = [ { value: 'description', label: 'Deskripsi' }, - { value: 'information', label: 'Info Penting' } -] + { value: 'information', label: 'Info Penting' }, +]; const TabButton = ({ children, active, ...props }) => { const activeClassName = active ? 'text-danger-500 underline underline-offset-4' - : 'text-gray_r-12/80' + : 'text-gray_r-12/80'; return ( - <button {...props} type='button' className={`font-medium ${activeClassName}`}> + <button + {...props} + type='button' + className={`font-medium ${activeClassName}`} + > {children} </button> - ) -} + ); +}; const TabContent = ({ children, active, className = '', ...props }) => ( <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}> {children} </div> -) +); -export default ProductDesktopVariant +export default ProductDesktopVariant; diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx index e23e2fb9..113a1e42 100644 --- a/src/lib/product/components/Product/ProductMobile.jsx +++ b/src/lib/product/components/Product/ProductMobile.jsx @@ -1,60 +1,66 @@ -import Divider from '@/core/components/elements/Divider/Divider' -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import currencyFormat from '@/core/utils/currencyFormat' -import { useEffect, useState } from 'react' -import Select from 'react-select' -import ProductSimilar from '../ProductSimilar' -import LazyLoad from 'react-lazy-load' -import { updateItemCart } from '@/core/utils/cart' -import { HeartIcon } from '@heroicons/react/24/outline' -import { useRouter } from 'next/router' -import MobileView from '@/core/components/views/MobileView' -import { toast } from 'react-hot-toast' -import { createSlug } from '@/core/utils/slug' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import whatsappUrl from '@/core/utils/whatsappUrl' -import PromotionType from '@/lib/promotinProgram/components/PromotionType' -import { gtagAddToCart } from '@/core/utils/googleTag' -import odooApi from '@/core/api/odooApi' -import ImageNext from 'next/image' -import CountDown2 from '@/core/components/elements/CountDown/CountDown2' -import Breadcrumb from './Breadcrumb' -import useAuth from '@/core/hooks/useAuth' -import { sellingProductFormat } from '@/core/utils/formatValue' +import Divider from '@/core/components/elements/Divider/Divider'; +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { useEffect, useState } from 'react'; +import Select from 'react-select'; +import ProductSimilar from '../ProductSimilar'; +import LazyLoad from 'react-lazy-load'; +import { updateItemCart } from '@/core/utils/cart'; +import { HeartIcon } from '@heroicons/react/24/outline'; +import { useRouter } from 'next/router'; +import MobileView from '@/core/components/views/MobileView'; +import { toast } from 'react-hot-toast'; +import { createSlug } from '@/core/utils/slug'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import PromotionType from '@/lib/promotinProgram/components/PromotionType'; +import { gtagAddToCart } from '@/core/utils/googleTag'; +import odooApi from '@/core/api/odooApi'; +import ImageNext from 'next/image'; +import CountDown2 from '@/core/components/elements/CountDown/CountDown2'; +import Breadcrumb from './Breadcrumb'; +import useAuth from '@/core/hooks/useAuth'; +import { sellingProductFormat } from '@/core/utils/formatValue'; +import ProductPromoSection from '~/modules/product-promo/components/Section'; const ProductMobile = ({ product, wishlist, toggleWishlist }) => { - const router = useRouter() - const auth = useAuth() - const { slug } = router.query - - const [quantity, setQuantity] = useState('1') - const [selectedVariant, setSelectedVariant] = useState(null) - const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) - const [addCartAlert, setAddCartAlert] = useState(false) - - const [isLoadingSLA, setIsLoadingSLA] = useState(true) - const [promotionType, setPromotionType] = useState(false) - const [promotionActiveId, setPromotionActiveId] = useState(null) - const [backgorundFlashSale, setBackgorundFlashSale] = useState(null) + const router = useRouter(); + const auth = useAuth(); + const { slug } = router.query; + + const [quantity, setQuantity] = useState('1'); + const [selectedVariant, setSelectedVariant] = useState(null); + const [informationTab, setInformationTab] = useState( + informationTabOptions[0].value + ); + const [addCartAlert, setAddCartAlert] = useState(false); + + const [isLoadingSLA, setIsLoadingSLA] = useState(true); + const [promotionType, setPromotionType] = useState(false); + const [promotionActiveId, setPromotionActiveId] = useState(null); + const [backgorundFlashSale, setBackgorundFlashSale] = useState(null); const getLowestPrice = () => { - const prices = product.variants.map((variant) => variant.price) + const prices = product.variants.map((variant) => variant.price); const lowest = prices.reduce((lowest, price) => { - return price.priceDiscount < lowest.priceDiscount ? price : lowest - }, prices[0]) - return lowest - } + return price.priceDiscount < lowest.priceDiscount ? price : lowest; + }, prices[0]); + return lowest; + }; useEffect(() => { const getBackgound = async () => { - const get = await odooApi('GET', '/api/v1/banner?type=flash-sale-background-banner') + const get = await odooApi( + 'GET', + '/api/v1/banner?type=flash-sale-background-banner' + ); if (get.length > 0) { - setBackgorundFlashSale(get[0].image) + setBackgorundFlashSale(get[0].image); } - } - getBackgound() - }, []) + }; + getBackgound(); + }, []); const [activeVariant, setActiveVariant] = useState({ id: null, @@ -64,40 +70,44 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { stock: product.stockTotal, weight: product.weight, hasProgram: false, - qtySold: product.qtySold - }) + qtySold: product.qtySold, + }); const variantOptions = product.variants?.map((variant) => { - let label = [] + let label = []; if (variant.isFlashsale) { - label.push("<span class='blink-color-flash-sale'>🗲</span>") + label.push("<span class='blink-color-flash-sale'>🗲</span>"); } if (variant.code) { - label.push(`[${variant.code}]`) + label.push(`[${variant.code}]`); } if (variant.attributes.length > 0) { - label.push(variant.attributes.join(', ')) + label.push(variant.attributes.join(', ')); } else { - label.push(product.name) + label.push(product.name); } return { value: variant.id, - label: label.join(' ') - } - }) + label: label.join(' '), + }; + }); useEffect(() => { if (!selectedVariant && variantOptions.length == 1) { - setSelectedVariant(variantOptions[0]) + setSelectedVariant(variantOptions[0]); } - }, [selectedVariant, variantOptions]) + }, [selectedVariant, variantOptions]); useEffect(() => { if (selectedVariant) { - const variant = product.variants.find((variant) => variant.id == selectedVariant.value) + const variant = product.variants.find( + (variant) => variant.id == selectedVariant.value + ); const variantAttributes = - variant.attributes.length > 0 ? ' - ' + variant.attributes.join(', ') : '' + variant.attributes.length > 0 + ? ' - ' + variant.attributes.join(', ') + : ''; const newActiveVariant = { id: variant.id, @@ -108,60 +118,63 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { weight: variant.weight, hasProgram: variant.hasProgram, isFlashsale: variant.isFlashsale, - qtySold: variant.qtySold - } + qtySold: variant.qtySold, + }; - setActiveVariant(newActiveVariant) + setActiveVariant(newActiveVariant); const fetchSLA = async () => { - const dataSLA = await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`) - setActiveVariant({ ...newActiveVariant, sla: dataSLA }) - } - fetchSLA() + const dataSLA = await odooApi( + 'GET', + `/api/v1/product_variant/${variant.id}/stock` + ); + setActiveVariant({ ...newActiveVariant, sla: dataSLA }); + }; + fetchSLA(); } - }, [selectedVariant, product]) + }, [selectedVariant, product]); const validAction = () => { - let isValid = true + let isValid = true; if (!selectedVariant) { - toast.error('Pilih varian terlebih dahulu') - isValid = false + toast.error('Pilih varian terlebih dahulu'); + isValid = false; } if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { - toast.error('Jumlah barang minimal 1') - isValid = false + toast.error('Jumlah barang minimal 1'); + isValid = false; } - return isValid - } + return isValid; + }; const redirectToLogin = (action) => { - const nextURL = `/shop/product/${slug}?action=${action}&variantId=${activeVariant.id}&qty=${quantity}` - router.push(`/login?next=${encodeURIComponent(nextURL)}`) - return true - } + const nextURL = `/shop/product/${slug}?action=${action}&variantId=${activeVariant.id}&qty=${quantity}`; + router.push(`/login?next=${encodeURIComponent(nextURL)}`); + return true; + }; const handleClickCart = () => { - if (!validAction()) return - gtagAddToCart(activeVariant, quantity) + if (!validAction()) return; + gtagAddToCart(activeVariant, quantity); if (!auth) { - return redirectToLogin('add_to_cart') + return redirectToLogin('add_to_cart'); } updateItemCart({ productId: activeVariant.id, quantity, programLineId: promotionActiveId, - selected: true - }) - setAddCartAlert(true) - } + selected: true, + }); + setAddCartAlert(true); + }; const handleClickBuy = () => { - if (!validAction()) return + if (!validAction()) return; if (!auth) { - return redirectToLogin('buy') + return redirectToLogin('buy'); } updateItemCart({ @@ -169,58 +182,60 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { quantity, programLineId: promotionActiveId, selected: true, - source: 'buy' - }) - router.push(`/shop/checkout?source=buy`) - } + source: 'buy', + }); + router.push(`/shop/checkout?source=buy`); + }; const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=-manufacture_id_i:${product.manufacture?.id || 0}` - ].join('&') + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); return ( <MobileView> <Breadcrumb productId={product.id} productName={product.name} /> <div className='relative'> - {product?.flashSale?.remainingTime > 0 && activeVariant?.price.discountPercentage > 0 && ( - <div className={`absolute bottom-0 w-full`}> - <div className='absolute bottom-0 w-full'> - <ImageNext - src={backgorundFlashSale || '/images/GAMBAR-BG-FLASH-SALE.jpg'} - width={1000} - height={100} - /> - </div> - <div className='relative'> - <div className='flex gap-x-2 items-center p-2'> - <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> - <span className='text-lg font-bold'> - {Math.floor(product.lowestPrice.discountPercentage)}% - </span> - </div> - <div - className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-4`} - > - <ImageNext - src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' - width={17} - height={10} - /> - <span className='text-white text-lg font-semibold'> - {product?.flashSale?.tag != 'false' || product?.flashSale?.tag - ? product?.flashSale?.tag - : 'FLASH SALE'} - </span> - </div> - <div> - <CountDown2 initialTime={product.flashSale.remainingTime} /> + {product?.flashSale?.remainingTime > 0 && + activeVariant?.price.discountPercentage > 0 && ( + <div className={`absolute bottom-0 w-full`}> + <div className='absolute bottom-0 w-full'> + <ImageNext + src={backgorundFlashSale || '/images/BG-FLASH-SALE.jpg'} + width={1000} + height={100} + /> + </div> + <div className='relative'> + <div className='flex gap-x-2 items-center p-2'> + <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> + <span className='text-lg font-bold'> + {Math.floor(product.lowestPrice.discountPercentage)}% + </span> + </div> + <div + className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-4`} + > + <ImageNext + src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' + width={17} + height={10} + /> + <span className='text-white text-lg font-semibold'> + {product?.flashSale?.tag != 'false' || + product?.flashSale?.tag + ? product?.flashSale?.tag + : 'FLASH SALE'} + </span> + </div> + <div> + <CountDown2 initialTime={product.flashSale.remainingTime} /> + </div> </div> </div> </div> - </div> - )} + )} <Image src={product.image} alt={product.name} @@ -232,7 +247,11 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { <div className='flex items-end mb-2'> {product.manufacture?.name ? ( <Link - href={createSlug('/shop/brands/', product.manufacture?.name, product.manufacture?.id)} + href={createSlug( + '/shop/brands/', + product.manufacture?.name, + product.manufacture?.id + )} > {product.manufacture?.name} </Link> @@ -249,18 +268,25 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { </div> <h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1> {product?.qtySold > 0 && ( - <div className='text-gray_r-9'>{sellingProductFormat(activeVariant?.qtySold) + ' Terjual'}</div> + <div className='text-gray_r-9'> + {sellingProductFormat(activeVariant?.qtySold) + ' Terjual'} + </div> )} {product.variants.length > 1 && activeVariant.price.priceDiscount > 0 && !selectedVariant && ( - <div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'>Harga mulai dari: </div> + <div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'> + Harga mulai dari:{' '} + </div> )} - {activeVariant.isFlashsale && activeVariant?.price?.discountPercentage > 0 ? ( + {activeVariant.isFlashsale && + activeVariant?.price?.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 items-center'> - <div className='badge-solid-red'>{Math.floor(activeVariant?.price?.discountPercentage)}%</div> + <div className='badge-solid-red'> + {Math.floor(activeVariant?.price?.discountPercentage)}% + </div> <div className='text-gray_r-11 line-through text-caption-1'> {currencyFormat(activeVariant?.price?.price)} </div> @@ -270,7 +296,9 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { </div> <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -280,7 +308,9 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { {currencyFormat(activeVariant?.price?.price)} <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -289,7 +319,12 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { <a href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 underline' > @@ -307,13 +342,17 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { <div> <label className='flex justify-between'> Pilih Varian: - <span className='text-gray_r-11'>{product?.variantTotal} Varian</span> + <span className='text-gray_r-11'> + {product?.variantTotal} Varian + </span> </label> <Select name='variant' classNamePrefix='form-select' options={variantOptions} - formatOptionLabel={({ label }) => <div dangerouslySetInnerHTML={{ __html: label }} />} + formatOptionLabel={({ label }) => ( + <div dangerouslySetInnerHTML={{ __html: label }} /> + )} className='mt-2' value={selectedVariant} onChange={(option) => setSelectedVariant(option)} @@ -342,15 +381,27 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { onChange={(e) => setQuantity(e.target.value)} /> </div> - <button type='button' className='btn-yellow flex-1' onClick={handleClickCart}> + <button + type='button' + className='btn-yellow flex-1' + onClick={handleClickCart} + > Keranjang </button> - <button type='button' className='btn-solid-red flex-1' onClick={handleClickBuy}> + <button + type='button' + className='btn-solid-red flex-1' + onClick={handleClickBuy} + > Beli </button> </div> + + <div className='h-4' /> </div> + <ProductPromoSection productId={activeVariant.id} /> + <Divider /> <div className='p-4'> @@ -380,12 +431,16 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { type='button' title={`Masa Persiapan Barang ${activeVariant?.sla?.slaDate}`} className={`flex gap-x-1 items-center p-2 h-8 rounded-lg w-full ${ - activeVariant?.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light' + activeVariant?.sla?.slaDate === 'indent' + ? 'bg-indigo-900' + : 'btn-light' }`} > <div className={`flex-1 text-sm ${ - activeVariant?.sla?.slaDate === 'indent' ? 'text-white' : '' + activeVariant?.sla?.slaDate === 'indent' + ? 'text-white' + : '' }`} > {activeVariant?.sla?.slaDate} @@ -397,7 +452,9 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { stroke='currentColor' stroke-width='1.5' className={`w-7 h-7 text-sm ${ - activeVariant?.sla?.slaDate === 'indent' ? 'text-white' : '' + activeVariant?.sla?.slaDate === 'indent' + ? 'text-white' + : '' }`} > <path @@ -436,7 +493,12 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { <a href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -445,12 +507,19 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { )} </SpecificationContent> <SpecificationContent label='Berat Barang'> - {activeVariant?.weight > 0 && <span>{activeVariant?.weight} KG</span>} + {activeVariant?.weight > 0 && ( + <span>{activeVariant?.weight} KG</span> + )} {activeVariant?.weight == 0 && ( <a href={whatsappUrl('productWeight', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -464,7 +533,10 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { active={informationTab == 'description'} className='leading-6 text-gray_r-11' dangerouslySetInnerHTML={{ - __html: product.description != '' ? product.description : 'Belum ada deskripsi produk.' + __html: + product.description != '' + ? product.description + : 'Belum ada deskripsi produk.', }} /> </div> @@ -491,50 +563,63 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { className='h-20 object-contain object-center w-full border border-gray_r-4' /> </div> - <div className='ml-3 flex flex-1 items-center text-sm font-normal'>{product.name}</div> + <div className='ml-3 flex flex-1 items-center text-sm font-normal'> + {product.name} + </div> <div className='ml-3 flex items-center text-sm font-normal'> - <Link href='/shop/cart' className='flex-1 py-2 text-gray_r-12 btn-yellow'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > Lihat Keranjang </Link> </div> </div> <div className='mt-8 mb-4'> - <div className='text-h-sm font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> </div> </BottomPopup> </MobileView> - ) -} + ); +}; const informationTabOptions = [ { value: 'specification', label: 'Spesifikasi' }, { value: 'description', label: 'Deskripsi' }, - { value: 'information', label: 'Info Penting' } -] + { value: 'information', label: 'Info Penting' }, +]; const TabButton = ({ children, active, ...props }) => { - const activeClassName = active ? 'text-danger-500 underline underline-offset-4' : 'text-gray_r-11' + const activeClassName = active + ? 'text-danger-500 underline underline-offset-4' + : 'text-gray_r-11'; return ( - <button {...props} type='button' className={`font-medium pb-1 ${activeClassName}`}> + <button + {...props} + type='button' + className={`font-medium pb-1 ${activeClassName}`} + > {children} </button> - ) -} + ); +}; const TabContent = ({ children, active, className, ...props }) => ( <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}> {children} </div> -) +); const SpecificationContent = ({ children, label }) => ( <div className='flex justify-between p-3 items-center'> <span className='text-gray_r-11'>{label}</span> {children} </div> -) +); -export default ProductMobile +export default ProductMobile; diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index 9888e482..af9e52bb 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -1,37 +1,40 @@ -import Divider from '@/core/components/elements/Divider/Divider' -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import currencyFormat from '@/core/utils/currencyFormat' -import { useEffect, useState } from 'react' -import Select from 'react-select' -import ProductSimilar from '../ProductSimilar' -import LazyLoad from 'react-lazy-load' -import { updateItemCart } from '@/core/utils/cart' -import { HeartIcon } from '@heroicons/react/24/outline' -import { useRouter } from 'next/router' -import MobileView from '@/core/components/views/MobileView' -import { toast } from 'react-hot-toast' -import { createSlug } from '@/core/utils/slug' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { gtagAddToCart } from '@/core/utils/googleTag' -import odooApi from '@/core/api/odooApi' -import { Skeleton } from '@chakra-ui/react' +import { Skeleton } from '@chakra-ui/react'; +import { HeartIcon } from '@heroicons/react/24/outline'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { toast } from 'react-hot-toast'; +import LazyLoad from 'react-lazy-load'; + +import odooApi from '@/core/api/odooApi'; +import Divider from '@/core/components/elements/Divider/Divider'; +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import MobileView from '@/core/components/views/MobileView'; +import { updateItemCart } from '@/core/utils/cart'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { gtagAddToCart } from '@/core/utils/googleTag'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; + +import ProductSimilar from '../ProductSimilar'; const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { - const router = useRouter() + const router = useRouter(); - const [quantity, setQuantity] = useState('1') - const [selectedVariant, setSelectedVariant] = useState(product.id) - const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) - const [addCartAlert, setAddCartAlert] = useState(false) + const [quantity, setQuantity] = useState('1'); + const [selectedVariant, setSelectedVariant] = useState(product.id); + const [informationTab, setInformationTab] = useState( + informationTabOptions[0].value + ); + const [addCartAlert, setAddCartAlert] = useState(false); - const [isLoadingSLA, setIsLoadingSLA] = useState(true) + const [isLoadingSLA, setIsLoadingSLA] = useState(true); const getLowestPrice = () => { - const lowest = product.lowestPrice - return lowest - } + const lowest = product.lowestPrice; + return lowest; + }; const [activeVariant, setActiveVariant] = useState({ id: null, @@ -40,8 +43,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { price: getLowestPrice(), stock: product.stockTotal, weight: product.weight, - isFlashSale: product.isFlashSale - }) + isFlashSale: product.isFlashSale, + }); useEffect(() => { if (selectedVariant) { @@ -52,70 +55,73 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { price: product.price, stock: product.stockTotal, weight: product.weight, - isFlashSale: product.isFlashSale - }) + isFlashSale: product.isFlashSale, + }); } - }, [selectedVariant, product]) + }, [selectedVariant, product]); const validAction = () => { - let isValid = true + let isValid = true; if (!selectedVariant) { - toast.error('Pilih varian terlebih dahulu') - isValid = false + toast.error('Pilih varian terlebih dahulu'); + isValid = false; } if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { - toast.error('Jumlah barang minimal 1') - isValid = false + toast.error('Jumlah barang minimal 1'); + isValid = false; } - return isValid - } + return isValid; + }; const handleClickCart = () => { - if (!validAction()) return - gtagAddToCart(activeVariant, quantity) + if (!validAction()) return; + gtagAddToCart(activeVariant, quantity); updateItemCart({ productId: variant, quantity, programLineId: null, selected: true, - source: null - }) - setAddCartAlert(true) - } + source: null, + }); + setAddCartAlert(true); + }; const handleClickBuy = () => { - if (!validAction()) return + if (!validAction()) return; updateItemCart({ productId: product.id, quantity, programLineId: null, selected: true, - source: 'buy' - }) - router.push(`/shop/checkout?source=buy`) - } + source: 'buy', + }); + router.push(`/shop/checkout?source=buy`); + }; const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=-manufacture_id_i:${product.manufacture?.id || 0}` - ].join('&') + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); useEffect(() => { const fetchData = async () => { - const dataSLA = await odooApi('GET', `/api/v1/product_variant/${product.id}/stock`) - product.sla = dataSLA + const dataSLA = await odooApi( + 'GET', + `/api/v1/product_variant/${product.id}/stock` + ); + product.sla = dataSLA; - setIsLoadingSLA(false) - } - fetchData() - }, [product]) + setIsLoadingSLA(false); + }; + fetchData(); + }, [product]); return ( <MobileView> <Image - src={product.image} + src={product.image + '?variant=True'} alt={product.name} className='h-72 object-contain object-center w-full border-b border-gray_r-4' /> @@ -124,7 +130,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { <div className='flex items-end mb-2'> {product.manufacture?.name ? ( <Link - href={createSlug('/shop/brands/', product.manufacture?.name, product.manufacture?.id)} + href={createSlug( + '/shop/brands/', + product.manufacture?.name, + product.manufacture?.id + )} > {product.manufacture?.name} </Link> @@ -141,10 +151,13 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { </div> <h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1> - {activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? ( + {activeVariant.isFlashSale && + activeVariant?.price?.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 items-center'> - <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div> + <div className='badge-solid-red'> + {activeVariant?.price?.discountPercentage}% + </div> <div className='text-gray_r-11 line-through text-caption-1'> {currencyFormat(activeVariant?.price?.price)} </div> @@ -154,7 +167,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { </div> <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -164,7 +179,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { {currencyFormat(activeVariant?.price?.price)} <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -173,7 +190,12 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { <a href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 underline' > @@ -199,10 +221,18 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { onChange={(e) => setQuantity(e.target.value)} /> </div> - <button type='button' className='btn-yellow flex-1' onClick={handleClickCart}> + <button + type='button' + className='btn-yellow flex-1' + onClick={handleClickCart} + > Keranjang </button> - <button type='button' className='btn-solid-red flex-1' onClick={handleClickBuy}> + <button + type='button' + className='btn-solid-red flex-1' + onClick={handleClickBuy} + > Beli </button> </div> @@ -238,7 +268,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { type='button' title={`Masa Persiapan Barang ${product?.sla?.slaDate}`} className={`flex gap-x-1 items-center p-2 h-8 rounded-lg w-full ${ - product?.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light' + product?.sla?.slaDate === 'indent' + ? 'bg-indigo-900' + : 'btn-light' }`} > <div @@ -281,14 +313,21 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { {activeVariant?.stock > 0 && ( <span className='flex gap-x-1.5'> <div className='badge-solid-red'>Ready Stock</div> - <div className='badge-gray'>{activeVariant?.stock > 5 ? '> 5' : '< 5'}</div> + <div className='badge-gray'> + {activeVariant?.stock > 5 ? '> 5' : '< 5'} + </div> </span> )} {activeVariant?.stock == 0 && ( <a href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -297,12 +336,19 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { )} </SpecificationContent> <SpecificationContent label='Berat Barang'> - {activeVariant?.weight > 0 && <span>{activeVariant?.weight} KG</span>} + {activeVariant?.weight > 0 && ( + <span>{activeVariant?.weight} KG</span> + )} {activeVariant?.weight == 0 && ( <a href={whatsappUrl('productWeight', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > @@ -316,7 +362,10 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { active={informationTab == 'description'} className='leading-6 text-gray_r-11' dangerouslySetInnerHTML={{ - __html: product.description != '' ? product.description : 'Belum ada deskripsi produk.' + __html: + product.description != '' + ? product.description + : 'Belum ada deskripsi produk.', }} /> </div> @@ -338,55 +387,68 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { <div className='flex mt-4'> <div className='w-[15%]'> <Image - src={product.image} + src={product.image + '?variant=True'} alt={product.name} className='h-20 object-contain object-center w-full border border-gray_r-4' /> </div> - <div className='ml-3 flex flex-1 items-center text-sm font-normal'>{product.name}</div> + <div className='ml-3 flex flex-1 items-center text-sm font-normal'> + {product.name} + </div> <div className='ml-3 flex items-center text-sm font-normal'> - <Link href='/shop/cart' className='flex-1 py-2 text-gray_r-12 btn-yellow'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > Lihat Keranjang </Link> </div> </div> <div className='mt-8 mb-4'> - <div className='text-h-sm font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> </div> </BottomPopup> </MobileView> - ) -} + ); +}; const informationTabOptions = [ - { value: 'specification', label: 'Spesifikasi' } + { value: 'specification', label: 'Spesifikasi' }, // { value: 'description', label: 'Deskripsi' }, // { value: 'information', label: 'Info Penting' } -] +]; const TabButton = ({ children, active, ...props }) => { - const activeClassName = active ? 'text-danger-500 underline underline-offset-4' : 'text-gray_r-11' + const activeClassName = active + ? 'text-danger-500 underline underline-offset-4' + : 'text-gray_r-11'; return ( - <button {...props} type='button' className={`font-medium pb-1 ${activeClassName}`}> + <button + {...props} + type='button' + className={`font-medium pb-1 ${activeClassName}`} + > {children} </button> - ) -} + ); +}; const TabContent = ({ children, active, className, ...props }) => ( <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}> {children} </div> -) +); const SpecificationContent = ({ children, label }) => ( <div className='flex justify-between p-3'> <span className='text-gray_r-11'>{label}</span> {children} </div> -) +); -export default ProductMobileVariant +export default ProductMobileVariant; diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index fa555bcf..98732407 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -1,38 +1,85 @@ -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import currencyFormat from '@/core/utils/currencyFormat' -import { sellingProductFormat } from '@/core/utils/formatValue' -import { createSlug } from '@/core/utils/slug' -import whatsappUrl from '@/core/utils/whatsappUrl' -import ImageNext from 'next/image' -import { useRouter } from 'next/router' +import clsx from 'clsx'; +import ImageNext from 'next/image'; +import { useRouter } from 'next/router'; +import { useMemo, useEffect, useState } from 'react'; + +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { sellingProductFormat } from '@/core/utils/formatValue'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import useUtmSource from '~/hooks/useUtmSource'; const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { - const router = useRouter() + const router = useRouter(); + const utmSource = useUtmSource(); + const callForPriceWhatsapp = whatsappUrl('product', { name: product.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) - }) + url: createSlug('/shop/product/', product.name, product.id, true), + }); + + const image = useMemo(() => { + if (product.image) return product.image + '?ratio=square'; + return '/images/noimage.jpeg'; + }, [product.image]); + + const URL = { + product: + createSlug('/shop/product/', product?.name, product?.id) + + `?utm_source=${utmSource}`, + manufacture: createSlug( + '/shop/brands/', + product?.manufacture?.name, + product?.manufacture.id + ), + }; if (variant == 'vertical') { return ( <div className='rounded shadow-sm border border-gray_r-4 bg-white h-[300px] md:h-[350px]'> - <Link - href={createSlug('/shop/product/', product?.name, product?.id)} - className='border-b border-gray_r-4 relative' - > + <Link href={URL.product} className='border-b border-gray_r-4 relative'> + <div className="relative"> <Image - src={product?.image} + src={image} alt={product?.name} - className='w-full object-contain object-center h-36 sm:h-48' + className="gambarA w-full object-contain object-center h-36 sm:h-48" /> + <div className="absolute top-0 right-0 flex mt-3"> + <div className="gambarB "> + {product?.isSni && ( + <ImageNext + src="/images/sni-logo.png" + alt="SNI Logo" + className="w-4 h-5 object-contain object-top sm:h-6" + width={50} + height={50} + /> + )} + </div> + <div className="gambarC "> + {product?.isTkdn && ( + <ImageNext + src="/images/TKDN.png" + alt="TKDN" + className="w-11 h-6 object-contain object-top ml-1 mr-1 sm:h-6" + width={50} + height={50} + /> + )} + </div> + </div> + </div> + + {router.pathname != '/' && product?.flashSale?.id > 0 && ( <div className='absolute bottom-0 w-full grid'> <div className='absolute bottom-0 w-full h-full'> <ImageNext - src='/images/GAMBAR-BG-FLASH-SALE.jpg' + src='/images/BG-FLASH-SALE.jpg' className='h-full' width={1000} height={100} @@ -52,7 +99,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { height={5} /> <span className='text-white text-[9px] md:text-[10px] font-semibold'> - {product?.flashSale?.tag != 'false' || product?.flashSale?.tag + {product?.flashSale?.tag != 'false' || + product?.flashSale?.tag ? product?.flashSale?.tag : 'FLASH SALE'} </span> @@ -69,27 +117,21 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </Link> <div className='p-2 sm:p-3 pb-3 text-caption-2 sm:text-body-2 leading-5'> {product?.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product?.manufacture?.name, - product?.manufacture.id - )} - className='mb-1' - > + <Link href={URL.manufacture} className='mb-1'> {product.manufacture.name} </Link> ) : ( <div>-</div> )} <Link - href={createSlug('/shop/product/', product?.name, product?.id)} + href={URL.product} className={`mb-2 !text-gray_r-12 leading-6 block line-clamp-3 h-[64px]`} title={product?.name} > {product?.name} </Link> - {product?.flashSale?.id > 0 && product?.lowestPrice.discountPercentage > 0 ? ( + {product?.flashSale?.id > 0 && + product?.lowestPrice.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 mb-1 items-center'> <div className='text-gray_r-11 line-through text-[11px] sm:text-caption-2'> @@ -103,7 +145,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {product?.lowestPrice.priceDiscount > 0 ? ( currencyFormat(product?.lowestPrice.priceDiscount) ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -116,11 +162,17 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {currencyFormat(product?.lowestPrice.price)} <div className='text-gray_r-9 text-[10px] font-normal mt-2'> Inc. PPN:{' '} - {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -128,7 +180,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <div className='flex w-full items-center gap-x-1 '> - {product?.stockTotal > 0 && <div className='badge-solid-red'>Ready Stock</div>} + {product?.stockTotal > 0 && ( + <div className='badge-solid-red'>Ready Stock</div> + )} {/* <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div> */} {product?.qtySold > 0 && ( <div className='text-gray_r-9 text-[11px]'> @@ -138,22 +192,45 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> </div> </div> - ) + ); } if (variant == 'horizontal') { return ( <div className='flex bg-white'> <div className='w-4/12'> - <Link - href={createSlug('/shop/product/', product?.name, product?.id)} - className='relative' - > + <Link href={URL.product} className='relative'> + <div className="relative"> <Image - src={product?.image} + src={image} alt={product?.name} - className='w-full object-contain object-center h-36' + className="gambarA w-full object-contain object-center h-36 sm:h-48" /> + <div className="absolute top-0 right-0 flex mt-3"> + <div className="gambarB "> + {product?.isSni && ( + <ImageNext + src="/images/sni-logo.png" + alt="SNI Logo" + className="w-4 h-5 object-contain object-top sm:h-6" + width={50} + height={50} + /> + )} + </div> + <div className="gambarC "> + {product?.isTkdn && ( + <ImageNext + src="/images/TKDN.png" + alt="TKDN" + className="w-11 h-6 object-contain object-top ml-1 sm:h-6" + width={50} + height={50} + /> + )} + </div> + </div> + </div> {product.variantTotal > 1 && ( <div className='absolute badge-gray bottom-1.5 left-1.5'> {product.variantTotal} Varian @@ -178,26 +255,20 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> )} {product?.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product?.manufacture?.name, - product?.manufacture.id - )} - className='mb-1' - > + <Link href={URL.manufacture} className='mb-1'> {product.manufacture.name} </Link> ) : ( <div>-</div> )} <Link - href={createSlug('/shop/product/', product?.name, product?.id)} + href={URL.product} className={`mb-3 !text-gray_r-12 leading-6 line-clamp-3`} > {product?.name} </Link> - {product?.flashSale?.id > 0 && product?.lowestPrice?.discountPercentage > 0 ? ( + {product?.flashSale?.id > 0 && + product?.lowestPrice?.discountPercentage > 0 ? ( <> {product?.lowestPrice.discountPercentage > 0 && ( <div className='flex gap-x-1 mb-1 items-center'> @@ -214,7 +285,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {product?.lowestPrice?.priceDiscount > 0 ? ( currencyFormat(product?.lowestPrice?.priceDiscount) ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -227,11 +302,17 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {currencyFormat(product?.lowestPrice.price)} <div className='text-gray_r-9 text-[11px] sm:text-caption-2 font-normal mt-2'> Inc. PPN:{' '} - {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -239,7 +320,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <div className='flex w-full items-center gap-x-1 '> - {product?.stockTotal > 0 && <div className='badge-solid-red'>Ready Stock</div>} + {product?.stockTotal > 0 && ( + <div className='badge-solid-red'>Ready Stock</div> + )} {/* <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div> */} {product?.qtySold > 0 && ( <div className='text-gray_r-9 text-[11px]'> @@ -249,8 +332,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> </div> </div> - ) + ); } -} +}; -export default ProductCard +export default ProductCard; diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index e4a62abb..a8073036 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -21,6 +21,7 @@ import Image from '@/core/components/elements/Image/Image' import { formatCurrency } from '@/core/utils/formatValue' const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => { + const router = useRouter() const { query } = router const [order, setOrder] = useState(query?.orderBy) @@ -102,7 +103,14 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu } params = _.pickBy(params, _.identity) params = toQuery(params) - router.push(`${prefixUrl}?${params}`) + + const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug; + + if (slug) { + router.push(`${prefixUrl}/${slug}?${params}`) + } else { + router.push(`${prefixUrl}?${params}`) + } } diff --git a/src/lib/product/components/ProductFilterDesktopPromotion.jsx b/src/lib/product/components/ProductFilterDesktopPromotion.jsx new file mode 100644 index 00000000..0815b881 --- /dev/null +++ b/src/lib/product/components/ProductFilterDesktopPromotion.jsx @@ -0,0 +1,132 @@ +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import _ from 'lodash'; +import { toQuery } from 'lodash-contrib'; +import { Button } from '@chakra-ui/react'; +import { MultiSelect } from 'react-multi-select-component'; + +const ProductFilterDesktop = ({ brands, categories, prefixUrl }) => { + const router = useRouter(); + const { query } = router; + const [order, setOrder] = useState(query?.orderBy); + const [brandValues, setBrand] = useState([]); + const [categoryValues, setCategory] = useState([]); + const [priceFrom, setPriceFrom] = useState(query?.priceFrom); + const [priceTo, setPriceTo] = useState(query?.priceTo); + const [stock, setStock] = useState(query?.stock); + const [activeRange, setActiveRange] = useState(null); + const [isBrandDropdownClicked, setIsBrandDropdownClicked] = useState(false); + const [isCategoryDropdownClicked, setIsCategoryDropdownClicked] = useState(false); + + // Effect to set brandValues from query parameter 'brand' + useEffect(() => { + const brandParam = query?.brand; + if (brandParam) { + const brandsArray = brandParam.split(',').map((b) => ({ + label: b, + value: b, + })); + setBrand(brandsArray); + } + + }, [query.brand]); // Trigger effect whenever query.brand changes + + useEffect(() => { + const categoryParam = query?.category; + if (categoryParam) { + const categoriesArray = categoryParam.split(',').map((c) => ({ + label: c, + value: c, + })); + setCategory(categoriesArray); + } + }, [query.category]); // Trigger effect whenever query.category changes + + const handleSubmit = () => { + let params = { + q: router.query.q, + orderBy: order, + brand: brandValues.map((b) => b.value).join(','), + category: categoryValues.map((c) => c.value).join(','), + priceFrom, + priceTo, + stock: stock, + }; + params = _.pickBy(params, _.identity); + params = toQuery(params); + + const slug = Array.isArray(router.query.slug) + ? router.query.slug[0] + : router.query.slug; + + if (slug) { + router.push(`${prefixUrl}/${slug}?${params}`); + } else { + router.push(`${prefixUrl}?${params}`); + } + }; + + + const brandOptions = brands.map((brand) => ({ + label: `${brand.brand} (${brand.qty})`, + value: brand.brand, + })); + + const categoryOptions = categories.map((category) => ({ + label: `${category.name} (${category.qty})`, + value: category.name, + })); + + return ( + <> + <div className='flex h-full w-[100%] justify-end '> + {/* Brand MultiSelect */} + <div className='mb-[20px] mr-4 w-64 h-full flex justify-start '> + <div className='relative'> + <label>Brand</label> + <div className='h-auto z-50 w-64 '> + <MultiSelect + options={brandOptions} + value={brandValues} + onChange={setBrand} + labelledBy='Select Brand' + onMenuToggle={(isOpen) => setIsBrandDropdownClicked(isOpen)} + hasSelectAll={false} + /> + </div> + </div> + </div> + + {/* Category MultiSelect */} + <div className='mb-[20px] mr-4 w-64 h-full flex justify-start '> + <div className='relative'> + <label>Kategori</label> + <div className=' h-auto w-64'> + <MultiSelect + options={categoryOptions} + value={categoryValues} + onChange={setCategory} + labelledBy='Select Kategori' + onMenuToggle={() => + setIsCategoryDropdownClicked(!isCategoryDropdownClicked) + } + hasSelectAll={false} + /> + </div> + </div> + </div> + + {/* Apply Button */} + <div className='TOMBOL mb-1 h-24 flex justify-center items-center w-24'> + <div className=' bottom-1 pb-1 left-0 right-0 flex justify-center rounded' > + <Button colorScheme='red' width={"full"} onClick={handleSubmit}> + Terapkan + </Button> + </div> + </div> + </div> + </> + ); +}; + +export default ProductFilterDesktop; diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 29bb987e..b1a5d409 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -1,171 +1,204 @@ -import { useEffect, useMemo, useState } from 'react' -import useProductSearch from '../hooks/useProductSearch' -import ProductCard from './ProductCard' -import Pagination from '@/core/components/elements/Pagination/Pagination' -import { toQuery } from 'lodash-contrib' -import _ from 'lodash' -import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton' -import ProductFilter from './ProductFilter' -import useActive from '@/core/hooks/useActive' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import NextImage from 'next/image' -import ProductFilterDesktop from './ProductFilterDesktop' -import { useRouter } from 'next/router' -import searchSpellApi from '@/core/api/searchSpellApi' -import Link from '@/core/components/elements/Link/Link' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react' -import odooApi from '@/core/api/odooApi' -import { formatCurrency } from '@/core/utils/formatValue' -import axios from 'axios' -import Skeleton from 'react-loading-skeleton' -import { createSlug } from '@/core/utils/slug' - -const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) => { - const router = useRouter() - const { page = 1 } = query - const [q, setQ] = useState(query?.q || '*') - const [search, setSearch] = useState(query?.q || '*') - const [limit, setLimit] = useState(query?.limit || 30) - const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular') - if (defaultBrand) query.brand = defaultBrand.toLowerCase() +import NextImage from 'next/image'; +import { useRouter } from 'next/router'; +import { useEffect, useMemo, useState } from 'react'; + +import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; +import axios from 'axios'; +import _ from 'lodash'; +import { toQuery } from 'lodash-contrib'; + +import odooApi from '@/core/api/odooApi'; +import searchSpellApi from '@/core/api/searchSpellApi'; +import Link from '@/core/components/elements/Link/Link'; +import Pagination from '@/core/components/elements/Pagination/Pagination'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import useActive from '@/core/hooks/useActive'; +import { formatCurrency } from '@/core/utils/formatValue'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; + +import useProductSearch from '../hooks/useProductSearch'; +import ProductCard from './ProductCard'; +import ProductFilter from './ProductFilter'; +import ProductFilterDesktop from './ProductFilterDesktop'; +import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; + +import SideBanner from '~/modules/side-banner'; +import FooterBanner from '~/modules/footer-banner'; + +const ProductSearch = ({ + query, + prefixUrl, + defaultBrand = null, + brand = null, +}) => { + const router = useRouter(); + const { page = 1 } = query; + const [q, setQ] = useState(query?.q || '*'); + const [search, setSearch] = useState(query?.q || '*'); + const [limit, setLimit] = useState(query?.limit || 30); + const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); + if (defaultBrand) query.brand = defaultBrand.toLowerCase(); const { productSearch } = useProductSearch({ query: { ...query, q, limit, orderBy }, - operation: 'AND' - }) - const [products, setProducts] = useState(null) - const [spellings, setSpellings] = useState(null) - const [bannerPromotionHeader, setBannerPromotionHeader] = useState(null) - const [bannerPromotionFooter, setBannerPromotionFooter] = useState(null) - const [isBrand, setIsBrand] = useState(null) - const popup = useActive() - const numRows = [30, 50, 80, 100] + operation: 'AND', + }); + const [products, setProducts] = useState(null); + const [spellings, setSpellings] = useState(null); + const [bannerPromotionHeader, setBannerPromotionHeader] = useState(null); + const [bannerPromotionFooter, setBannerPromotionFooter] = useState(null); + const [isBrand, setIsBrand] = useState(null); + const popup = useActive(); + const numRows = [30, 50, 80, 100]; const [brandValues, setBrand] = useState( - !router.pathname.includes('brands') ? (query.brand ? query.brand.split(',') : []) : [] - ) - const [categoryValues, setCategory] = useState(query?.category?.split(',') || []) - const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null) - const [priceTo, setPriceTo] = useState(query?.priceTo || null) - - const pageCount = Math.ceil(productSearch.data?.response.numFound / limit) - const productStart = productSearch.data?.responseHeader.params.start - const productRows = limit - const productFound = productSearch.data?.response.numFound + !router.pathname.includes('brands') + ? query.brand + ? query.brand.split(',') + : [] + : [] + ); + const [categoryValues, setCategory] = useState( + query?.category?.split(',') || [] + ); + const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null); + const [priceTo, setPriceTo] = useState(query?.priceTo || null); + + const pageCount = Math.ceil(productSearch.data?.response.numFound / limit); + const productStart = productSearch.data?.responseHeader.params.start; + const productRows = limit; + const productFound = productSearch.data?.response.numFound; useEffect(() => { if (productFound == 0 && query.q && !spellings) { searchSpellApi({ query: query.q }).then((response) => { const oddIndexSuggestions = response.data.spellcheck.suggestions.filter( (_, index) => index % 2 === 1 - ) + ); const oddIndexCollations = response.data.spellcheck.collations.filter( (_, index) => index % 2 === 1 - ) + ); const dataSpellings = oddIndexSuggestions.reduce((acc, curr) => { oddIndexCollations.forEach((collation) => { - acc.push(collation.collationQuery) - }) + acc.push(collation.collationQuery); + }); curr.suggestion.forEach((s) => { - if (!acc.includes(s.word)) acc.push(s.word) - }) - return acc - }, []) + if (!acc.includes(s.word)) acc.push(s.word); + }); + return acc; + }, []); if (dataSpellings.length > 0) { - setQ(dataSpellings[0]) + setQ(dataSpellings[0]); } - setSpellings(dataSpellings) - }) + setSpellings(dataSpellings); + }); } - }, [productFound, query, spellings]) + }, [productFound, query, spellings]); useEffect(() => { const checkIfBrand = async () => { const brand = await axios( `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=search&q=${search}` - ) - console.log('ini brand', brand) + ); + if (brand.data.length > 0) { - setIsBrand(brand?.data[0]) + setIsBrand(brand?.data[0]); } else { - setIsBrand(null) + setIsBrand(null); } + }; + if (router.pathname.includes('search') && q !== '*') { + checkIfBrand(); } - if (router.pathname.includes('search')) { - checkIfBrand() - } - }, [q]) + }, [q]); - const brands = [] + const brands = []; for ( let i = 0; i < productSearch.data?.facetCounts?.facetFields?.manufactureNameS.length; i += 2 ) { - const brand = productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i] - const qty = productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i + 1] + const brand = + productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i]; + const qty = + productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i + 1]; if (qty > 0) { - brands.push({ brand, qty }) + brands.push({ brand, qty }); } } + - const categories = [] - for (let i = 0; i < productSearch.data?.facetCounts?.facetFields?.categoryName.length; i += 2) { - const name = productSearch.data?.facetCounts?.facetFields?.categoryName[i] - const qty = productSearch.data?.facetCounts?.facetFields?.categoryName[i + 1] + const categories = []; + for ( + let i = 0; + i < productSearch.data?.facetCounts?.facetFields?.categoryName.length; + i += 2 + ) { + const name = productSearch.data?.facetCounts?.facetFields?.categoryName[i]; + const qty = + productSearch.data?.facetCounts?.facetFields?.categoryName[i + 1]; if (qty > 0) { - categories.push({ name, qty }) + categories.push({ name, qty }); } } + const orderOptions = [ { value: 'price-asc', label: 'Harga Terendah' }, { value: 'price-desc', label: 'Harga Tertinggi' }, { value: 'popular', label: 'Populer' }, - { value: 'stock', label: 'Ready Stock' } - ] + { value: 'stock', label: 'Ready Stock' }, + ]; const handleOrderBy = (e) => { let params = { ...router.query, - orderBy: e.target.value - } - params = _.pickBy(params, _.identity) - params = toQuery(params) - router.push(`${prefixUrl}?${params}`) - } + orderBy: e.target.value, + }; + params = _.pickBy(params, _.identity); + params = toQuery(params); + router.push(`${prefixUrl}?${params}`); + }; const handleLimit = (e) => { let params = { ...router.query, - limit: e.target.value - } - params = _.pickBy(params, _.identity) - params = toQuery(params) - router.push(`${prefixUrl}?${params}`) - } + limit: e.target.value, + }; + params = _.pickBy(params, _.identity); + params = toQuery(params); + router.push(`${prefixUrl}?${params}`); + }; const getBanner = async () => { if (router.pathname.includes('search')) { - const getBannerHeader = await odooApi('GET', '/api/v1/banner?type=promotion-header') - const getBannerFooter = await odooApi('GET', '/api/v1/banner?type=promotion-footer') - var randomIndex = Math.floor(Math.random() * getBannerHeader.length) - var randomIndexFooter = Math.floor(Math.random() * getBannerFooter.length) - setBannerPromotionHeader(getBannerHeader[randomIndex]) - setBannerPromotionFooter(getBannerFooter[randomIndexFooter]) + const getBannerHeader = await odooApi( + 'GET', + '/api/v1/banner?type=promotion-header' + ); + const getBannerFooter = await odooApi( + 'GET', + '/api/v1/banner?type=promotion-footer' + ); + var randomIndex = Math.floor(Math.random() * getBannerHeader.length); + var randomIndexFooter = Math.floor( + Math.random() * getBannerFooter.length + ); + setBannerPromotionHeader(getBannerHeader[randomIndex]); + setBannerPromotionFooter(getBannerFooter[randomIndexFooter]); } - } + }; useEffect(() => { - getBanner() - }, []) + getBanner(); + }, []); useEffect(() => { - setProducts(productSearch.data?.response?.products) - }, [productSearch]) + setProducts(productSearch.data?.response?.products); + }, [productSearch]); const SpellingComponent = useMemo(() => { return ( @@ -182,8 +215,8 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) </Link> ))} </> - ) - }, [spellings]) + ); + }, [spellings]); const handleDeleteFilter = async (source, value) => { let params = { @@ -192,51 +225,64 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) brand: brandValues.join(','), category: categoryValues.join(','), priceFrom, - priceTo - } + priceTo, + }; - let brands = brandValues - let catagories = categoryValues + let brands = brandValues; + let catagories = categoryValues; switch (source) { case 'brands': - brands = brandValues.filter((item) => item !== value) - params.brand = brands.join(',') - await setBrand(brands) - break + brands = brandValues.filter((item) => item !== value); + params.brand = brands.join(','); + await setBrand(brands); + break; case 'category': - catagories = categoryValues.filter((item) => item !== value) - params.category = catagories.join(',') - await setCategory(catagories) - break + catagories = categoryValues.filter((item) => item !== value); + params.category = catagories.join(','); + await setCategory(catagories); + break; case 'price': - params.priceFrom = null - params.priceTo = null - break + params.priceFrom = null; + params.priceTo = null; + break; case 'delete': params = { q: router.query.q, - orderBy: orderBy - } - break + orderBy: orderBy, + }; + break; } - handleSubmitFilter(params) - } + handleSubmitFilter(params); + }; const handleSubmitFilter = (params) => { - params = _.pickBy(params, _.identity) - params = toQuery(params) - router.push(`${prefixUrl}?${params}`) - } + params = _.pickBy(params, _.identity); + params = toQuery(params); + router.push(`${prefixUrl}?${params}`); + }; + + const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; return ( <> <MobileView> {productSearch.isLoading && <ProductSearchSkeleton />} <div className='p-4 pt-0'> - {isBrand && isBrand.logo && ( + {isNotReadyStockPage && isBrand && isBrand.logo && ( <div className='mb-3'> - <h1 className='mb-2 font-semibold text-h-sm'>Brand Pencarian {q}</h1> - <Image src={isBrand?.logo} alt='' className='object-cover object-center h-[60px]' /> + <h1 className='mb-2 font-semibold text-h-sm'> + Brand Pencarian {q} + </h1> + <Link + href={createSlug('/shop/brands/', isBrand.name, isBrand.id)} + className='inline' + > + <Image + src={isBrand?.logo} + alt='' + className='object-cover object-center h-[60px]' + /> + </Link> </div> )} <h1 className='mb-2 font-semibold text-h-sm'>Produk</h1> @@ -255,7 +301,8 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) {pageCount > 1 ? ( <> {productStart + 1}- - {parseInt(productStart) + parseInt(productRows) > productFound + {parseInt(productStart) + parseInt(productRows) > + productFound ? productFound : parseInt(productStart) + parseInt(productRows)} dari @@ -267,7 +314,8 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) produk{' '} {query.q && ( <> - untuk pencarian <span className='font-semibold'>{query.q}</span> + untuk pencarian{' '} + <span className='font-semibold'>{query.q}</span> </> )} </> @@ -279,7 +327,10 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) {productFound > 0 && ( <div className='flex items-center gap-x-2 mb-5 justify-between'> <div> - <button className='btn-light py-2 px-5 h-[40px]' onClick={popup.activate}> + <button + className='btn-light py-2 px-5 h-[40px]' + onClick={popup.activate} + > Filter </button> </div> @@ -303,7 +354,9 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) <div className='grid grid-cols-2 gap-3'> {products && - products.map((product) => <ProductCard product={product} key={product.id} />)} + products.map((product) => ( + <ProductCard product={product} key={product.id} /> + ))} </div> <Pagination @@ -329,7 +382,9 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) <div className='w-3/12'> {brand && ( <div className='p-4'> - <div className='text-caption-1 text-gray_r-11 mb-2'>Produk dari brand:</div> + <div className='text-caption-1 text-gray_r-11 mb-2'> + Produk dari brand: + </div> {brand?.data?.logo && ( <Image src={brand?.data?.logo} @@ -351,6 +406,10 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) prefixUrl={prefixUrl} defaultBrand={defaultBrand} /> + + <div className='h-6' /> + + <SideBanner /> </div> <div className='w-9/12 pl-6'> {bannerPromotionHeader && bannerPromotionHeader?.image && ( @@ -363,14 +422,20 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) </div> )} - {isBrand && isBrand.logo && ( + {isNotReadyStockPage && isBrand && isBrand.logo && ( <div className='mb-3'> - <h1 className='text-2xl mb-2 font-semibold'>Brand Pencarian {q}</h1> + <h1 className='text-2xl mb-2 font-semibold'> + Brand Pencarian {q} + </h1> <Link href={createSlug('/shop/brands/', isBrand.name, isBrand.id)} className='inline' > - <Image src={isBrand?.logo} alt='' className='object-cover object-center h-24' /> + <Image + src={isBrand?.logo} + alt='' + className='object-cover object-center h-24' + /> </Link> </div> )} @@ -391,7 +456,8 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) {pageCount > 1 ? ( <> {productStart + 1}- - {parseInt(productStart) + parseInt(productRows) > productFound + {parseInt(productStart) + parseInt(productRows) > + productFound ? productFound : parseInt(productStart) + parseInt(productRows)} dari @@ -403,7 +469,8 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) produk{' '} {query.q && ( <> - untuk pencarian <span className='font-semibold'>{query.q}</span> + untuk pencarian{' '} + <span className='font-semibold'>{query.q}</span> </> )} </> @@ -447,7 +514,9 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) {productSearch.isLoading && <ProductSearchSkeleton />} <div className='grid grid-cols-5 gap-x-3 gap-y-6'> {products && - products.map((product) => <ProductCard product={product} key={product.id} />)} + products.map((product) => ( + <ProductCard product={product} key={product.id} /> + ))} </div> <div className='flex justify-between items-center mt-6 mb-2'> <div className='pt-2 pb-6 flex items-center gap-x-3'> @@ -464,7 +533,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) href={ query?.q ? whatsappUrl('productSearch', { - name: query.q + name: query.q, }) : whatsappUrl() } @@ -492,44 +561,66 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) /> </div> )} + <FooterBanner /> </div> </div> </DesktopView> </> - ) -} + ); +}; -export default ProductSearch +export default ProductSearch; const FilterChoicesComponent = ({ brandValues, categoryValues, priceFrom, priceTo, - handleDeleteFilter + handleDeleteFilter, }) => ( <div className='flex items-center'> <HStack spacing={2} className='flex-wrap'> {brandValues?.map((value, index) => ( - <Tag size='lg' key={index} borderRadius='lg' variant='outline' colorScheme='gray'> + <Tag + size='lg' + key={index} + borderRadius='lg' + variant='outline' + colorScheme='gray' + > <TagLabel>{value}</TagLabel> <TagCloseButton onClick={() => handleDeleteFilter('brands', value)} /> </Tag> ))} {categoryValues?.map((value, index) => ( - <Tag size='lg' key={index} borderRadius='lg' variant='outline' colorScheme='gray'> + <Tag + size='lg' + key={index} + borderRadius='lg' + variant='outline' + colorScheme='gray' + > <TagLabel>{value}</TagLabel> - <TagCloseButton onClick={() => handleDeleteFilter('category', value)} /> + <TagCloseButton + onClick={() => handleDeleteFilter('category', value)} + /> </Tag> ))} {priceFrom && priceTo && ( <Tag size='lg' borderRadius='lg' variant='outline' colorScheme='gray'> - <TagLabel>{formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)}</TagLabel> - <TagCloseButton onClick={() => handleDeleteFilter('price', priceFrom)} /> + <TagLabel> + {formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)} + </TagLabel> + <TagCloseButton + onClick={() => handleDeleteFilter('price', priceFrom)} + /> </Tag> )} - {brandValues?.length > 0 || categoryValues?.length > 0 || priceFrom || priceTo ? ( + {brandValues?.length > 0 || + categoryValues?.length > 0 || + priceFrom || + priceTo ? ( <span> <button className='btn-transparent py-2 px-5 h-[40px] text-red-700' @@ -543,4 +634,4 @@ const FilterChoicesComponent = ({ )} </HStack> </div> -) +); diff --git a/src/lib/promo/components/Promocrumb.jsx b/src/lib/promo/components/Promocrumb.jsx new file mode 100644 index 00000000..4f5cf346 --- /dev/null +++ b/src/lib/promo/components/Promocrumb.jsx @@ -0,0 +1,40 @@ +import { Breadcrumb as ChakraBreadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react' +import Link from 'next/link' +import React from 'react' + +/** + * Renders a breadcrumb component with links to navigate through different pages. + * + * @param {Object} props - The props object containing the brand name. + * @param {string} props.brandName - The name of the brand to display in the breadcrumb. + * @return {JSX.Element} The rendered breadcrumb component. + */ +const Breadcrumb = ({ brandName }) => { + return ( + <div className='container mx-auto py-4 md:py-6'> + <ChakraBreadcrumb> + <BreadcrumbItem> + <BreadcrumbLink as={Link} href='/' className='!text-danger-500 whitespace-nowrap'> + Shop + </BreadcrumbLink> + </BreadcrumbItem> + + {/* <BreadcrumbItem> + <BreadcrumbLink + as={Link} + href='/shop/promo' + className='!text-danger-500 whitespace-nowrap' + > + Promo + </BreadcrumbLink> + </BreadcrumbItem> */} + + <BreadcrumbItem isCurrentPage> + <BreadcrumbLink className='whitespace-nowrap'>{brandName}</BreadcrumbLink> + </BreadcrumbItem> + </ChakraBreadcrumb> + </div> + ) +} + +export default Breadcrumb diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index 8c379ead..8855c6c4 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -1,102 +1,295 @@ -import Alert from '@/core/components/elements/Alert/Alert' -import Divider from '@/core/components/elements/Divider/Divider' -import Link from '@/core/components/elements/Link/Link' -import useAuth from '@/core/hooks/useAuth' -import CartApi from '@/lib/cart/api/CartApi' -import { ExclamationCircleIcon } from '@heroicons/react/24/outline' -import { useEffect, useState } from 'react' -import _ from 'lodash' -import { deleteItemCart, getCart, getItemCart } from '@/core/utils/cart' -import currencyFormat from '@/core/utils/currencyFormat' -import { toast } from 'react-hot-toast' +import Alert from '@/core/components/elements/Alert/Alert'; +import Divider from '@/core/components/elements/Divider/Divider'; +import Link from '@/core/components/elements/Link/Link'; +import useAuth from '@/core/hooks/useAuth'; +import CartApi from '@/lib/cart/api/CartApi'; +import { ExclamationCircleIcon } from '@heroicons/react/24/outline'; +import { useEffect, useRef, useState } from 'react'; +import _ from 'lodash'; +import { deleteItemCart, getCart, getItemCart } from '@/core/utils/cart'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { toast } from 'react-hot-toast'; // import checkoutApi from '@/lib/checkout/api/checkoutApi' -import { useRouter } from 'next/router' -import VariantGroupCard from '@/lib/variant/components/VariantGroupCard' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import Image from '@/core/components/elements/Image/Image' -import { useQuery } from 'react-query' -import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList' +import { useRouter } from 'next/router'; +import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; +import Image from '@/core/components/elements/Image/Image'; +import { useQuery } from 'react-query'; +import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'; +import { Skeleton } from '@chakra-ui/react'; +import { + PickupAddress, + SectionAddress, + SectionExpedisi, + SectionListService, + SectionValidation, + calculateEstimatedArrival, + splitDuration, +} from '../../checkout/components/CheckoutSection'; +import addressesApi from '@/lib/address/api/addressesApi'; +import { getItemAddress } from '@/core/utils/address'; +import ExpedisiList from '../../checkout/api/ExpedisiList'; +import axios from 'axios'; -const { checkoutApi } = require('@/lib/checkout/api/checkoutApi') -const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi') +const { checkoutApi } = require('@/lib/checkout/api/checkoutApi'); +const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi'); const Quotation = () => { - const router = useRouter() - const auth = useAuth() + const router = useRouter(); + const auth = useAuth(); - const { data: cartCheckout } = useQuery('cartCheckout', () => getProductsCheckout()) + const { data: cartCheckout } = useQuery('cartCheckout', () => + getProductsCheckout() + ); - const [products, setProducts] = useState(null) - const [totalAmount, setTotalAmount] = useState(0) - const [totalDiscountAmount, setTotalDiscountAmount] = useState(0) + const SELF_PICKUP_ID = 32; + + const [products, setProducts] = useState(null); + const [totalAmount, setTotalAmount] = useState(0); + const [totalDiscountAmount, setTotalDiscountAmount] = useState(0); + + //start set up address and carrier + const [selectedCarrierId, setselectedCarrierId] = useState(0); + const [listExpedisi, setExpedisi] = useState([]); + const [selectedExpedisi, setSelectedExpedisi] = useState(0); + const [checkWeigth, setCheckWeight] = useState(false); + const [checkoutValidation, setCheckoutValidation] = useState(false); + const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false); + + const [listserviceExpedisi, setListServiceExpedisi] = useState([]); + const [selectedServiceType, setSelectedServiceType] = useState(null); + + const [selectedCarrier, setselectedCarrier] = useState(0); + const [totalWeight, setTotalWeight] = useState(0); + + const [biayaKirim, setBiayaKirim] = useState(0); + const [selectedExpedisiService, setselectedExpedisiService] = useState(null); + const [etd, setEtd] = useState(null); + const [etdFix, setEtdFix] = useState(null); + + const [isApproval, setIsApproval] = useState(false); + + const expedisiValidation = useRef(null); + + const [selectedAddress, setSelectedAddress] = useState({ + shipping: null, + invoicing: null, + }); + + const [addresses, setAddresses] = useState(null); + + useEffect(() => { + if (!auth) return; + + const getAddresses = async () => { + const dataAddresses = await addressesApi(); + setAddresses(dataAddresses); + }; + + getAddresses(); + setIsApproval(auth?.feature?.soApproval); + }, [auth]); + + useEffect(() => { + if (!addresses) return; + + const matchAddress = (key) => { + const addressToMatch = getItemAddress(key); + const foundAddress = addresses.filter( + (address) => address.id == addressToMatch + ); + if (foundAddress.length > 0) { + return foundAddress[0]; + } + return addresses[0]; + }; + + setSelectedAddress({ + shipping: matchAddress('shipping'), + invoicing: matchAddress('invoicing'), + }); + }, [addresses]); + + const loadExpedisi = async () => { + let dataExpedisi = await ExpedisiList(); + dataExpedisi = dataExpedisi.map((expedisi) => ({ + value: expedisi.id, + label: expedisi.name, + carrierId: expedisi.deliveryCarrierId, + })); + setExpedisi(dataExpedisi); + }; + + const loadServiceRajaOngkir = async () => { + setLoadingRajaOngkir(true); + const body = { + origin: 2127, + destination: selectedAddress.shipping.rajaongkirCityId, + weight: totalWeight, + courier: selectedCarrier, + originType: 'subdistrict', + destinationType: 'subdistrict', + }; + setBiayaKirim(0); + const dataService = await axios( + '/api/rajaongkir-service?body=' + JSON.stringify(body) + ); + setLoadingRajaOngkir(false); + setListServiceExpedisi(dataService.data[0].costs); + if (dataService.data[0].costs[0]) { + setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value); + setselectedExpedisiService( + dataService.data[0].costs[0]?.description + + '-' + + dataService.data[0].costs[0]?.service + ); + setEtd(dataService.data[0].costs[0]?.cost[0].etd); + toast.success('Harap pilih tipe layanan pengiriman'); + } else { + toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); + } + }; + + useEffect(() => { + setCheckoutValidation(false); + + if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) { + loadServiceRajaOngkir(); + } else { + setListServiceExpedisi(); + setBiayaKirim(0); + setselectedExpedisiService(); + setEtd(); + } + }, [selectedCarrier, selectedAddress, totalWeight]); + + useEffect(() => { + if (selectedExpedisi) { + let serviceType = selectedExpedisi.split(','); + if (serviceType[0] === 0) return; + + setselectedCarrier(serviceType[0]); + setselectedCarrierId(serviceType[1]); + setListServiceExpedisi([]); + } + }, [selectedExpedisi]); + + useEffect(() => { + if (selectedServiceType) { + let serviceType = selectedServiceType.split(','); + setBiayaKirim(serviceType[0]); + setselectedExpedisiService(serviceType[1]); + setEtd(serviceType[2]); + } + }, [selectedServiceType]); + + useEffect(() => { + if (etd) setEtdFix(calculateEstimatedArrival(etd)); + }, [etd]); + + useEffect(() => { + if (isApproval) { + setselectedCarrierId(1); + setselectedExpedisiService('indoteknik'); + } + }, [isApproval]); + + // end set up address and carrier useEffect(() => { const loadProducts = async () => { - const cart = getCart() + const cart = getCart(); const variantIds = _.filter(cart, (o) => o.selected == true) .map((o) => o.productId) - .join(',') - const dataProducts = await CartApi({ variantIds }) + .join(','); + const dataProducts = await CartApi({ variantIds }); const productsWithQuantity = dataProducts?.map((product) => { return { ...product, - quantity: getItemCart({ productId: product.id }).quantity - } - }) + quantity: getItemCart({ productId: product.id }).quantity, + }; + }); if (productsWithQuantity) { Promise.all(productsWithQuantity).then((resolvedProducts) => { - setProducts(resolvedProducts) - }) + setProducts(resolvedProducts); + }); } - } + }; + loadExpedisi(); // loadProducts() - }, []) + }, []); useEffect(() => { - setProducts(cartCheckout?.products) - }, [cartCheckout]) + setProducts(cartCheckout?.products); + setCheckWeight(cartCheckout?.hasProductWithoutWeight); + setTotalWeight(cartCheckout?.totalWeight.g); + }, [cartCheckout]); useEffect(() => { if (products) { - let calculateTotalAmount = 0 - let calculateTotalDiscountAmount = 0 + let calculateTotalAmount = 0; + let calculateTotalDiscountAmount = 0; products.forEach((product) => { - calculateTotalAmount += product.price.price * product.quantity + calculateTotalAmount += product.price.price * product.quantity; calculateTotalDiscountAmount += - (product.price.price - product.price.priceDiscount) * product.quantity - }) - setTotalAmount(calculateTotalAmount) - setTotalDiscountAmount(calculateTotalDiscountAmount) + (product.price.price - product.price.priceDiscount) * + product.quantity; + }); + setTotalAmount(calculateTotalAmount); + setTotalDiscountAmount(calculateTotalDiscountAmount); } - }, [products]) + }, [products]); - const [isLoading, setIsLoading] = useState(false) + const [isLoading, setIsLoading] = useState(false); const checkout = async () => { - if (!products || products.length == 0) return - setIsLoading(true) + // validation checkout + if (selectedExpedisi === 0 && !isApproval) { + setCheckoutValidation(true); + if (expedisiValidation.current) { + const position = expedisiValidation.current.getBoundingClientRect(); + window.scrollTo({ + top: position.top - 300 + window.pageYOffset, + behavior: 'smooth', + }); + } + return; + } + if (selectedCarrier != 1 && biayaKirim == 0 && !isApproval) { + toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); + return; + } + + if (!products || products.length == 0) return; + setIsLoading(true); const productOrder = products.map((product) => ({ product_id: product.id, - quantity: product.quantity - })) + quantity: product.quantity, + })); let data = { - partner_shipping_id: auth.partnerId, - partner_invoice_id: auth.partnerId, + partner_shipping_id: selectedAddress.shipping.id, + partner_invoice_id: selectedAddress.invoicing.id, user_id: auth.id, - order_line: JSON.stringify(productOrder) - } - const isSuccess = await checkoutApi({ data }) - setIsLoading(false) + order_line: JSON.stringify(productOrder), + delivery_amount: biayaKirim, + carrier_id: selectedCarrierId, + estimated_arrival_days: splitDuration(etd), + delivery_service_type: selectedExpedisiService, + }; + console.log('data checkout', data); + const isSuccess = await checkoutApi({ data }); + console.log('isSuccess', isSuccess); + setIsLoading(false); if (isSuccess?.id) { - for (const product of products) deleteItemCart({ productId: product.id }) - router.push(`/shop/quotation/finish?id=${isSuccess.id}`) - return + for (const product of products) deleteItemCart({ productId: product.id }); + router.push(`/shop/quotation/finish?id=${isSuccess.id}`); + return; } - toast.error('Gagal melakukan transaksi, terjadi kesalahan internal') - } + toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); + }; - const taxTotal = (totalAmount - totalDiscountAmount) * 0.11 + const taxTotal = (totalAmount - totalDiscountAmount) * 0.11; return ( <> @@ -107,16 +300,85 @@ const Quotation = () => { <ExclamationCircleIcon className='w-7 text-blue-700' /> </div> <span className='leading-5'> - Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami - disini + Jika mengalami kesulitan dalam melakukan pembelian di website + Indoteknik. Hubungi kami disini </span> </Alert> </div> <Divider /> + {selectedCarrierId == SELF_PICKUP_ID && ( + <div className='p-4'> + <div + class='flex items-center p-4 mb-4 text-sm border border-yellow-500 text-yellow-800 rounded-lg bg-yellow-50' + role='alert' + > + <svg + class='flex-shrink-0 inline w-4 h-4 mr-3' + aria-hidden='true' + fill='currentColor' + viewBox='0 0 20 20' + > + <path d='M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z' /> + </svg> + <span class='sr-only'>Info</span> + <div className='text-justify'> + Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. + Apa bila memilih fitur ini, anda akan dihubungi setelah barang + siap diambil. + </div> + </div> + </div> + )} + + {selectedCarrierId == SELF_PICKUP_ID && ( + <PickupAddress label='Alamat Pickup' /> + )} + {selectedCarrierId != SELF_PICKUP_ID && ( + <Skeleton + isLoaded={!!selectedAddress.invoicing && !!selectedAddress.shipping} + minHeight={320} + > + <SectionAddress + address={selectedAddress.shipping} + label='Alamat Pengiriman' + url='/my/address?select=shipping' + /> + <Divider /> + <SectionAddress + address={selectedAddress.invoicing} + label='Alamat Penagihan' + url='/my/address?select=invoice' + /> + </Skeleton> + )} + <Divider /> + <SectionValidation address={selectedAddress.invoicing} /> + {!isApproval && ( + <> + <SectionExpedisi + address={selectedAddress.shipping} + listExpedisi={listExpedisi} + setSelectedExpedisi={setSelectedExpedisi} + checkWeigth={checkWeigth} + checkoutValidation={checkoutValidation} + expedisiValidation={expedisiValidation} + loadingRajaOngkir={loadingRajaOngkir} + /> + <Divider /> + </> + )} + + <SectionListService + listserviceExpedisi={listserviceExpedisi} + setSelectedServiceType={setSelectedServiceType} + /> + <div className='p-4 flex flex-col gap-y-4'> - {products && <VariantGroupCard openOnClick={false} variants={products} />} + {products && ( + <VariantGroupCard openOnClick={false} variants={products} /> + )} </div> <Divider /> @@ -124,7 +386,9 @@ const Quotation = () => { <div className='p-4'> <div className='flex justify-between items-center'> <div className='font-medium'>Ringkasan Penawaran</div> - <div className='text-gray_r-11 text-caption-1'>{products?.length} Barang</div> + <div className='text-gray_r-11 text-caption-1'> + {products?.length} Barang + </div> </div> <hr className='my-4 border-gray_r-6' /> <div className='flex flex-col gap-y-4'> @@ -134,7 +398,9 @@ const Quotation = () => { </div> <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Diskon Produk</div> - <div className='text-danger-500'>- {currencyFormat(cartCheckout?.totalDiscount)}</div> + <div className='text-danger-500'> + - {currencyFormat(cartCheckout?.totalDiscount)} + </div> </div> <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Subtotal</div> @@ -144,17 +410,33 @@ const Quotation = () => { <div className='text-gray_r-11'>PPN 11%</div> <div>{currencyFormat(cartCheckout?.tax)}</div> </div> + <div className='flex gap-x-2 justify-between'> + <div className='text-gray_r-11'> + Biaya Kirim <p className='text-xs mt-3'>{etdFix}</p> + </div> + <div> + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} + </div> + </div> </div> <hr className='my-4 border-gray_r-6' /> <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat(cartCheckout?.grandTotal)} + {currencyFormat( + cartCheckout?.grandTotal + + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} </div> </div> - <p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p> + <p className='text-caption-2 text-gray_r-10 mb-2'> + *) Belum termasuk biaya pengiriman + </p> <p className='text-caption-2 text-gray_r-10 leading-5'> - Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} + Dengan melakukan pembelian melalui website Indoteknik, saya + menyetujui{' '} <Link href='/syarat-ketentuan' className='inline font-normal'> Syarat & Ketentuan </Link>{' '} @@ -165,7 +447,11 @@ const Quotation = () => { <Divider /> <div className='flex gap-x-3 p-4'> - <button className='flex-1 btn-yellow' onClick={checkout} disabled={isLoading}> + <button + className='flex-1 btn-yellow' + onClick={checkout} + disabled={isLoading} + > {isLoading ? 'Loading...' : 'Quotation'} </button> </div> @@ -174,15 +460,65 @@ const Quotation = () => { <DesktopView> <div className='container mx-auto py-10 flex'> <div className='w-3/4 border border-gray_r-6 rounded bg-white p-4'> - <div className='font-medium'>Detail Barang</div> - <CardProdcuctsList isLoading={isLoading} products={products} source='checkout' /> + {selectedCarrierId == SELF_PICKUP_ID && ( + <PickupAddress label='Alamat Pickup' /> + )} + {selectedCarrierId != SELF_PICKUP_ID && ( + <Skeleton + isLoaded={ + !!selectedAddress.invoicing && !!selectedAddress.shipping + } + minHeight={290} + > + <SectionAddress + address={selectedAddress.shipping} + label='Alamat Pengiriman' + url='/my/address?select=shipping' + /> + <Divider /> + <SectionAddress + address={selectedAddress.invoicing} + label='Alamat Penagihan' + url='/my/address?select=invoice' + /> + </Skeleton> + )} + <Divider /> + <SectionValidation address={selectedAddress.invoicing} /> + {!isApproval && ( + <SectionExpedisi + address={selectedAddress.shipping} + listExpedisi={listExpedisi} + setSelectedExpedisi={setSelectedExpedisi} + checkWeigth={checkWeigth} + checkoutValidation={checkoutValidation} + expedisiValidation={expedisiValidation} + loadingRajaOngkir={loadingRajaOngkir} + /> + )} + + <Divider /> + <SectionListService + listserviceExpedisi={listserviceExpedisi} + setSelectedServiceType={setSelectedServiceType} + /> + {/* <div className='p-4'> */} + <div className='font-medium mb-6'>Detail Barang</div> + <CardProdcuctsList + isLoading={isLoading} + products={products} + source='checkout' + /> + {/* </div> */} </div> <div className='w-1/4 pl-4'> <div className='sticky top-48 border border-gray_r-6 bg-white rounded p-4'> <div className='flex justify-between items-center'> <div className='font-medium'>Ringkasan Pesanan</div> - <div className='text-gray_r-11 text-caption-1'>{products?.length} Barang</div> + <div className='text-gray_r-11 text-caption-1'> + {products?.length} Barang + </div> </div> <hr className='my-4 border-gray_r-6' /> @@ -205,6 +541,16 @@ const Quotation = () => { <div className='text-gray_r-11'>PPN 11%</div> <div>{currencyFormat(cartCheckout?.tax)}</div> </div> + <div className='flex gap-x-2 justify-between'> + <div className='text-gray_r-11'> + Biaya Kirim <p className='text-xs mt-3'>{etdFix}</p> + </div> + <div> + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} + </div> + </div> </div> <hr className='my-4 border-gray_r-6' /> @@ -212,14 +558,18 @@ const Quotation = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat(cartCheckout?.grandTotal)} + {currencyFormat( + cartCheckout?.grandTotal + + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} </div> </div> - <p className='text-caption-2 text-gray_r-11 mb-2'> + {/* <p className='text-caption-2 text-gray_r-11 mb-2'> *) Belum termasuk biaya pengiriman - </p> + </p> */} <p className='text-caption-2 text-gray_r-11 leading-5'> - Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} + Dengan melakukan pembelian melalui website Indoteknik, saya + menyetujui{' '} <Link href='/syarat-ketentuan' className='inline font-normal'> Syarat & Ketentuan </Link>{' '} @@ -240,7 +590,7 @@ const Quotation = () => { </div> </DesktopView> </> - ) -} + ); +}; -export default Quotation +export default Quotation; diff --git a/src/lib/transaction/api/approveApi.js b/src/lib/transaction/api/approveApi.js new file mode 100644 index 00000000..891f0235 --- /dev/null +++ b/src/lib/transaction/api/approveApi.js @@ -0,0 +1,13 @@ +import odooApi from '@/core/api/odooApi' +import { getAuth } from '@/core/utils/auth' + +const aprpoveApi = async ({ id }) => { + const auth = getAuth() + const dataCheckout = await odooApi( + 'POST', + `/api/v1/partner/${auth?.partnerId}/sale_order/${id}/approve` + ) + return dataCheckout +} + +export default aprpoveApi diff --git a/src/lib/transaction/api/listSiteApi.js b/src/lib/transaction/api/listSiteApi.js new file mode 100644 index 00000000..8b7740c5 --- /dev/null +++ b/src/lib/transaction/api/listSiteApi.js @@ -0,0 +1,10 @@ +import odooApi from '@/core/api/odooApi' +import { getAuth } from '@/core/utils/auth' + +const getSite = async () => { + const auth = getAuth() + const dataSite = await odooApi('GET', `/api/v1/partner/${auth?.partnerId}/list/site`) + return dataSite +} + +export default getSite
\ No newline at end of file diff --git a/src/lib/transaction/api/rejectApi.js b/src/lib/transaction/api/rejectApi.js new file mode 100644 index 00000000..127c0d38 --- /dev/null +++ b/src/lib/transaction/api/rejectApi.js @@ -0,0 +1,13 @@ +import odooApi from '@/core/api/odooApi' +import { getAuth } from '@/core/utils/auth' + +const rejectApi = async ({ id }) => { + const auth = getAuth() + const dataCheckout = await odooApi( + 'POST', + `/api/v1/partner/${auth?.partnerId}/sale_order/${id}/reject` + ) + return dataCheckout +} + +export default rejectApi diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 82eb1775..c6152ca9 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -1,83 +1,120 @@ -import Spinner from '@/core/components/elements/Spinner/Spinner' -import useTransaction from '../hooks/useTransaction' -import TransactionStatusBadge from './TransactionStatusBadge' -import Divider from '@/core/components/elements/Divider/Divider' -import { useMemo, useRef, useState } from 'react' -import { downloadPurchaseOrder, downloadQuotation } from '../utils/transactions' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import uploadPoApi from '../api/uploadPoApi' -import { toast } from 'react-hot-toast' -import getFileBase64 from '@/core/utils/getFileBase64' -import currencyFormat from '@/core/utils/currencyFormat' -import VariantGroupCard from '@/lib/variant/components/VariantGroupCard' -import { ChevronDownIcon, ChevronRightIcon, ChevronUpIcon } from '@heroicons/react/24/outline' -import Link from '@/core/components/elements/Link/Link' -import checkoutPoApi from '../api/checkoutPoApi' -import cancelTransactionApi from '../api/cancelTransactionApi' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import Menu from '@/lib/auth/components/Menu' -import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' -import toTitleCase from '@/core/utils/toTitleCase' -import useAirwayBill from '../hooks/useAirwayBill' -import Manifest from '@/lib/treckingAwb/component/Manifest' +import Spinner from '@/core/components/elements/Spinner/Spinner'; +import useTransaction from '../hooks/useTransaction'; +import TransactionStatusBadge from './TransactionStatusBadge'; +import Divider from '@/core/components/elements/Divider/Divider'; +import { useEffect, useMemo, useRef, useState } from 'react'; +import ImageNext from 'next/image'; +import { + downloadPurchaseOrder, + downloadQuotation, +} from '../utils/transactions'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import uploadPoApi from '../api/uploadPoApi'; +import { toast } from 'react-hot-toast'; +import getFileBase64 from '@/core/utils/getFileBase64'; +import currencyFormat from '@/core/utils/currencyFormat'; +import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'; +import { + ChevronDownIcon, + ChevronRightIcon, + ChevronUpIcon, +} from '@heroicons/react/24/outline'; +import Link from '@/core/components/elements/Link/Link'; +import checkoutPoApi from '../api/checkoutPoApi'; +import cancelTransactionApi from '../api/cancelTransactionApi'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; +import Menu from '@/lib/auth/components/Menu'; +import Image from '@/core/components/elements/Image/Image'; +import { createSlug } from '@/core/utils/slug'; +import toTitleCase from '@/core/utils/toTitleCase'; +import useAirwayBill from '../hooks/useAirwayBill'; +import Manifest from '@/lib/treckingAwb/component/Manifest'; +import useAuth from '@/core/hooks/useAuth'; +import StepApproval from './stepper'; +import aprpoveApi from '../api/approveApi'; +import rejectApi from '../api/rejectApi'; const Transaction = ({ id }) => { - const { transaction } = useTransaction({ id }) - const { queryAirwayBill } = useAirwayBill({ orderId: id }) + const auth = useAuth(); + const { transaction } = useTransaction({ id }); - const [airwayBillPopup, setAirwayBillPopup] = useState(null) + const statusApprovalWeb = transaction.data?.approvalStep; + + const { queryAirwayBill } = useAirwayBill({ orderId: id }); + const [airwayBillPopup, setAirwayBillPopup] = useState(null); + + const poNumber = useRef(null); + const poFile = useRef(null); + const [uploadPo, setUploadPo] = useState(false); + const [idAWB, setIdAWB] = useState(null); + const openUploadPo = () => setUploadPo(true); + const closeUploadPo = () => setUploadPo(false); - const poNumber = useRef(null) - const poFile = useRef(null) - const [uploadPo, setUploadPo] = useState(false) - const [idAWB, setIdAWB] = useState(null) - const openUploadPo = () => setUploadPo(true) - const closeUploadPo = () => setUploadPo(false) const submitUploadPo = async () => { - const file = poFile.current.files[0] - const name = poNumber.current.value + const file = poFile.current.files[0]; + const name = poNumber.current.value; if (typeof file === 'undefined' || !name) { - toast.error('Nomor dan Dokumen PO harus diisi') - return + toast.error('Nomor dan Dokumen PO harus diisi'); + return; } if (file.size > 5000000) { - toast.error('Maksimal ukuran file adalah 5MB') - return + toast.error('Maksimal ukuran file adalah 5MB'); + return; } - const data = { name, file: await getFileBase64(file) } - const isUploaded = await uploadPoApi({ id, data }) + const data = { name, file: await getFileBase64(file) }; + const isUploaded = await uploadPoApi({ id, data }); if (isUploaded) { - toast.success('Berhasil upload PO') - transaction.refetch() - closeUploadPo() - return + toast.success('Berhasil upload PO'); + transaction.refetch(); + closeUploadPo(); + return; } - toast.error('Terjadi kesalahan internal, coba lagi nanti atau hubungi kami') - } + toast.error( + 'Terjadi kesalahan internal, coba lagi nanti atau hubungi kami' + ); + }; + + const [cancelTransaction, setCancelTransaction] = useState(false); + const openCancelTransaction = () => setCancelTransaction(true); + const closeCancelTransaction = () => setCancelTransaction(false); - const [cancelTransaction, setCancelTransaction] = useState(false) - const openCancelTransaction = () => setCancelTransaction(true) - const closeCancelTransaction = () => setCancelTransaction(false) + const [rejectTransaction, setRejectTransaction] = useState(false); + + const openRejectTransaction = () => setRejectTransaction(true); + const closeRejectTransaction = () => setRejectTransaction(false); const submitCancelTransaction = async () => { - const isCancelled = await cancelTransactionApi({ transaction: transaction.data }) + const isCancelled = await cancelTransactionApi({ + transaction: transaction.data, + }); if (isCancelled) { - toast.success('Berhasil batalkan transaksi') - transaction.refetch() + toast.success('Berhasil batalkan transaksi'); + transaction.refetch(); } - closeCancelTransaction() - } + closeCancelTransaction(); + }; const checkout = async () => { if (!transaction.data?.purchaseOrderFile) { - toast.error('Mohon upload dokumen PO anda sebelum melanjutkan pesanan') - return + toast.error('Mohon upload dokumen PO anda sebelum melanjutkan pesanan'); + return; } - await checkoutPoApi({ id }) - toast.success('Berhasil melanjutkan pesanan') - transaction.refetch() - } + await checkoutPoApi({ id }); + toast.success('Berhasil melanjutkan pesanan'); + transaction.refetch(); + }; + + const handleApproval = async () => { + await aprpoveApi({ id }); + toast.success('Berhasil melanjutkan approval'); + transaction.refetch(); + }; + + const handleReject = async () => { + await rejectApi({ id }); + closeRejectTransaction(); + transaction.refetch(); + }; const memoizeVariantGroupCard = useMemo( () => ( @@ -102,19 +139,19 @@ const Transaction = ({ id }) => { </div> ), [transaction.data] - ) + ); if (transaction.isLoading) { return ( <div className='flex justify-center my-6'> <Spinner className='w-6 text-gray_r-12/50 fill-gray_r-12' /> </div> - ) + ); } const closePopup = () => { - setIdAWB(null) - } + setIdAWB(null); + }; return ( transaction.data?.name && ( @@ -146,6 +183,33 @@ const Transaction = ({ id }) => { </div> </BottomPopup> + <BottomPopup + active={rejectTransaction} + close={closeRejectTransaction} + title='Batalkan Transaksi' + > + <div className='leading-7 text-gray_r-12/80'> + Apakah anda yakin Membatalkan transaksi{' '} + <span className='underline'>{transaction.data?.name}</span>? + </div> + <div className='flex justify-end mt-6 gap-x-4'> + <button + className='btn-solid-red w-full md:w-fit' + type='button' + onClick={handleReject} + > + Ya, Batalkan + </button> + <button + className='btn-light w-full md:w-fit' + type='button' + onClick={closeRejectTransaction} + > + Batal + </button> + </div> + </BottomPopup> + <BottomPopup title='Upload PO' close={closeUploadPo} active={uploadPo}> <div> <label>Nomor PO</label> @@ -156,10 +220,18 @@ const Transaction = ({ id }) => { <input type='file' className='form-input mt-3 py-2' ref={poFile} /> </div> <div className='grid grid-cols-2 gap-x-3 mt-6'> - <button type='button' className='btn-light w-full' onClick={closeUploadPo}> + <button + type='button' + className='btn-light w-full' + onClick={closeUploadPo} + > Batal </button> - <button type='button' className='btn-solid-red w-full' onClick={submitUploadPo}> + <button + type='button' + className='btn-solid-red w-full' + onClick={submitUploadPo} + > Upload </button> </div> @@ -167,18 +239,33 @@ const Transaction = ({ id }) => { <Manifest idAWB={idAWB} closePopup={closePopup}></Manifest> <MobileView> + <div className='p-4'> + {auth?.feature?.soApproval && ( + <StepApproval + layer={statusApprovalWeb} + status={transaction?.data?.status} + className='ml-auto' + /> + )} + </div> <div className='flex flex-col gap-y-4 p-4'> <DescriptionRow label='Status Transaksi'> <div className='flex justify-end'> <TransactionStatusBadge status={transaction.data?.status} /> </div> </DescriptionRow> - <DescriptionRow label='No Transaksi'>{transaction.data?.name}</DescriptionRow> + <DescriptionRow label='No Transaksi'> + {transaction.data?.name} + </DescriptionRow> <DescriptionRow label='Ketentuan Pembayaran'> {transaction.data?.paymentTerm} </DescriptionRow> - <DescriptionRow label='Nama Sales'>{transaction.data?.sales}</DescriptionRow> - <DescriptionRow label='Waktu Transaksi'>{transaction.data?.dateOrder}</DescriptionRow> + <DescriptionRow label='Nama Sales'> + {transaction.data?.sales} + </DescriptionRow> + <DescriptionRow label='Waktu Transaksi'> + {transaction.data?.dateOrder} + </DescriptionRow> </div> <Divider /> @@ -214,25 +301,27 @@ const Transaction = ({ id }) => { <Divider /> - <div className='p-4 flex flex-col gap-y-4'> - <DescriptionRow label='Purchase Order'> - {transaction.data?.purchaseOrderName || '-'} - </DescriptionRow> - <div className='flex items-center'> - <p className='text-gray_r-11 leading-none'>Dokumen PO</p> - <button - type='button' - className='btn-light py-1.5 px-3 ml-auto' - onClick={ - transaction.data?.purchaseOrderFile - ? () => downloadPurchaseOrder(transaction.data) - : openUploadPo - } - > - {transaction.data?.purchaseOrderFile ? 'Download' : 'Upload'} - </button> + {!auth?.feature.soApproval && ( + <div className='p-4 flex flex-col gap-y-4'> + <DescriptionRow label='Purchase Order'> + {transaction.data?.purchaseOrderName || '-'} + </DescriptionRow> + <div className='flex items-center'> + <p className='text-gray_r-11 leading-none'>Dokumen PO</p> + <button + type='button' + className='btn-light py-1.5 px-3 ml-auto' + onClick={ + transaction.data?.purchaseOrderFile + ? () => downloadPurchaseOrder(transaction.data) + : openUploadPo + } + > + {transaction.data?.purchaseOrderFile ? 'Download' : 'Upload'} + </button> + </div> </div> - </div> + )} <Divider /> @@ -278,11 +367,43 @@ const Transaction = ({ id }) => { <Divider /> <div className='p-4 pt-0'> - {transaction.data?.status == 'draft' && ( - <button className='btn-yellow w-full mt-4' onClick={checkout}> - Lanjutkan Transaksi - </button> - )} + {transaction.data?.status == 'draft' && + auth?.feature.soApproval && ( + <div className='flex gap-x-2'> + <button + className='btn-yellow w-full' + onClick={checkout} + disabled={ + transaction.data?.status === 'cancel' + ? true + : false || auth?.webRole === statusApprovalWeb + ? true + : false + } + > + Approve + </button> + <button + className='btn-solid-red px-7 w-full' + onClick={checkout} + disabled={ + transaction.data?.status === 'cancel' + ? true + : false || auth?.webRole === statusApprovalWeb + ? true + : false + } + > + Reject + </button> + </div> + )} + {transaction.data?.status == 'draft' && + !auth?.feature?.soApproval && ( + <button className='btn-yellow w-full mt-4' onClick={checkout}> + Lanjutkan Transaksi + </button> + )} <button className='btn-light w-full mt-4' disabled={transaction.data?.status != 'draft'} @@ -308,10 +429,23 @@ const Transaction = ({ id }) => { <Menu /> </div> <div className='w-9/12 p-4 py-6 bg-white border border-gray_r-6 rounded'> - <h1 className='text-title-sm font-semibold mb-6'>Detail Transaksi</h1> + <div className='flex justify-between'> + <h1 className='text-title-sm font-semibold mb-6'> + Detail Transaksi + </h1> + {auth?.feature?.soApproval && ( + <StepApproval + layer={statusApprovalWeb} + status={transaction?.data?.status} + className='ml-auto' + /> + )} + </div> <div className='flex items-center gap-x-2 mb-3'> - <span className='text-h-sm font-medium'>{transaction?.data?.name}</span> + <span className='text-h-sm font-medium'> + {transaction?.data?.name} + </span> <TransactionStatusBadge status={transaction?.data?.status} /> </div> <div className='flex gap-x-4'> @@ -322,20 +456,58 @@ const Transaction = ({ id }) => { > Download </button> - {transaction.data?.status == 'draft' && ( - <button className='btn-yellow' onClick={checkout}> - Lanjutkan Transaksi - </button> - )} - {transaction.data?.status != 'draft' && ( - <button - className='btn-light' - disabled={transaction.data?.status != 'waiting'} - onClick={openCancelTransaction} - > - Batalkan Transaksi - </button> - )} + {transaction.data?.status == 'draft' && + auth?.feature?.soApproval && + auth?.webRole && ( + <div className='flex gap-x-2'> + <button + className='btn-yellow' + onClick={handleApproval} + disabled={ + transaction.data?.status === 'cancel' + ? true + : false || auth?.webRole === statusApprovalWeb + ? true + : false || statusApprovalWeb < 1 + ? true + : false + } + > + Approve + </button> + <button + className='btn-solid-red px-7' + onClick={openRejectTransaction} + disabled={ + transaction.data?.status === 'cancel' + ? true + : false || auth?.webRole === statusApprovalWeb + ? true + : false || statusApprovalWeb < 1 + ? true + : false + } + > + Reject + </button> + </div> + )} + {transaction.data?.status == 'draft' && + !auth?.feature.soApproval && ( + <button className='btn-yellow' onClick={checkout}> + Lanjutkan Transaksi + </button> + )} + {transaction.data?.status != 'draft' && + !auth?.feature.soApproval && ( + <button + className='btn-light' + disabled={transaction.data?.status != 'waiting'} + onClick={openCancelTransaction} + > + Batalkan Transaksi + </button> + )} </div> <div className='grid grid-cols-2 gap-x-6 mt-6'> @@ -350,33 +522,50 @@ const Transaction = ({ id }) => { <div>Ketentuan Pembayaran</div> <div>: {transaction?.data?.paymentTerm}</div> - <div>Purchase Order</div> - <div> - : {transaction?.data?.purchaseOrderName}{' '} - <button - type='button' - className='inline-block text-danger-500' - onClick={ - transaction.data?.purchaseOrderFile - ? () => downloadPurchaseOrder(transaction.data) - : openUploadPo - } - > - {transaction?.data?.purchaseOrderFile ? 'Download' : 'Upload'} - </button> - </div> + {!auth?.feature?.soApproval ? ( + <> + <div>Purchase Order</div> + <div> + : {transaction?.data?.purchaseOrderName}{' '} + <button + type='button' + className='inline-block text-danger-500' + onClick={ + transaction.data?.purchaseOrderFile + ? () => downloadPurchaseOrder(transaction.data) + : openUploadPo + } + > + {transaction?.data?.purchaseOrderFile + ? 'Download' + : 'Upload'} + </button> + </div> + </> + ) : ( + <> + <div>Site</div> + <div>: {transaction?.data?.sitePartner}</div> + </> + )} </div> </div> - <div className='text-h-sm font-semibold mt-10 mb-4'>Informasi Pelanggan</div> + <div className='text-h-sm font-semibold mt-10 mb-4'> + Informasi Pelanggan + </div> <div className='grid grid-cols-2 gap-x-4'> <div className='border border-gray_r-6 rounded p-3'> <div className='font-medium mb-4'>Detail Pelanggan</div> - <SectionContent address={transaction?.data?.address?.customer} /> + <SectionContent + address={transaction?.data?.address?.customer} + /> </div> </div> - <div className='text-h-sm font-semibold mt-10 mb-4'>Pengiriman</div> + <div className='text-h-sm font-semibold mt-10 mb-4'> + Pengiriman + </div> <div className='grid grid-cols-3 gap-1'> {transaction?.data?.pickings?.map((airway) => ( <button @@ -403,12 +592,14 @@ const Transaction = ({ id }) => { <div className='badge-red text-sm'>Belum ada pengiriman</div> )} - <div className='text-h-sm font-semibold mt-10 mb-4'>Rincian Pembelian</div> + <div className='text-h-sm font-semibold mt-10 mb-4'> + Rincian Pembelian + </div> <table className='table-data'> <thead> <tr> <th>Nama Produk</th> - <th>Diskon</th> + {/* <th>Diskon</th> */} <th>Jumlah</th> <th>Harga</th> <th>Subtotal</th> @@ -426,11 +617,37 @@ const Transaction = ({ id }) => { )} className='w-[20%] flex-shrink-0' > - <Image - src={product?.parent?.image} - alt={product?.name} - className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' - /> + <div className='relative'> + <Image + src={product?.parent?.image} + alt={product?.name} + className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' + /> + <div className='absolute top-0 right-4 flex mt-3'> + <div className='gambarB '> + {product.isSni && ( + <ImageNext + src='/images/sni-logo.png' + alt='SNI Logo' + className='w-2 h-4 object-contain object-top sm:h-4' + width={50} + height={50} + /> + )} + </div> + <div className='gambarC '> + {product.isTkdn && ( + <ImageNext + src='/images/TKDN.png' + alt='TKDN' + className='w-5 h-4 object-contain object-top ml-1 sm:h-4' + width={50} + height={50} + /> + )} + </div> + </div> + </div> </Link> <div className='px-2 text-left'> <Link @@ -451,18 +668,18 @@ const Transaction = ({ id }) => { </div> </div> </td> - <td> + {/* <td> {product.price.discountPercentage > 0 ? `${product.price.discountPercentage}%` : ''} - </td> + </td> */} <td>{product.quantity}</td> <td> - {product.price.discountPercentage > 0 && ( + {/* {product.price.discountPercentage > 0 && ( <div className='line-through mb-1 text-caption-1 text-gray_r-12/70'> {currencyFormat(product.price.price)} </div> - )} + )} */} <div>{currencyFormat(product.price.priceDiscount)}</div> </td> <td>{currencyFormat(product.price.subtotal)}</td> @@ -483,7 +700,9 @@ const Transaction = ({ id }) => { {currencyFormat(transaction.data?.amountTax)} </div> - <div className='text-right whitespace-nowrap'>Biaya Pengiriman</div> + <div className='text-right whitespace-nowrap'> + Biaya Pengiriman + </div> <div className='text-right font-medium'> {currencyFormat(transaction.data?.deliveryAmount)} </div> @@ -578,18 +797,18 @@ const Transaction = ({ id }) => { ))} */} </> ) - ) -} + ); +}; const SectionAddress = ({ address }) => { const [section, setSection] = useState({ customer: false, invoice: false, - shipping: false - }) + shipping: false, + }); const toggleSection = (name) => { - setSection({ ...section, [name]: !section[name] }) - } + setSection({ ...section, [name]: !section[name] }); + }; return ( <> @@ -620,39 +839,50 @@ const SectionAddress = ({ address }) => { /> {section.invoice && <SectionContent address={address?.invoice} />} */} </> - ) -} + ); +}; const SectionButton = ({ label, active, toggle }) => ( - <button className='p-4 font-medium flex justify-between w-full' onClick={toggle}> + <button + className='p-4 font-medium flex justify-between w-full' + onClick={toggle} + > <span>{label}</span> - {active ? <ChevronUpIcon className='w-5' /> : <ChevronDownIcon className='w-5' />} + {active ? ( + <ChevronUpIcon className='w-5' /> + ) : ( + <ChevronDownIcon className='w-5' /> + )} </button> -) +); const SectionContent = ({ address }) => { - let fullAddress = [] - if (address?.street) fullAddress.push(address.street) - if (address?.subDistrict?.name) fullAddress.push(toTitleCase(address.subDistrict.name)) - if (address?.district?.name) fullAddress.push(toTitleCase(address.district.name)) - if (address?.city?.name) fullAddress.push(toTitleCase(address.city.name)) - fullAddress = fullAddress.join(', ') + let fullAddress = []; + if (address?.street) fullAddress.push(address.street); + if (address?.subDistrict?.name) + fullAddress.push(toTitleCase(address.subDistrict.name)); + if (address?.district?.name) + fullAddress.push(toTitleCase(address.district.name)); + if (address?.city?.name) fullAddress.push(toTitleCase(address.city.name)); + fullAddress = fullAddress.join(', '); return ( <div className='flex flex-col gap-y-4 p-4 md:p-0 border-t border-gray_r-6 md:border-0'> <DescriptionRow label='Nama'>{address.name}</DescriptionRow> <DescriptionRow label='Email'>{address.email || '-'}</DescriptionRow> - <DescriptionRow label='No Telepon'>{address.mobile || '-'}</DescriptionRow> + <DescriptionRow label='No Telepon'> + {address.mobile || '-'} + </DescriptionRow> <DescriptionRow label='Alamat'>{fullAddress}</DescriptionRow> </div> - ) -} + ); +}; const DescriptionRow = ({ children, label }) => ( <div className='grid grid-cols-2'> <span className='text-gray_r-11'>{label}</span> <span className='text-right leading-6'>{children}</span> </div> -) +); -export default Transaction +export default Transaction; diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx index be63effd..92bdd276 100644 --- a/src/lib/transaction/components/Transactions.jsx +++ b/src/lib/transaction/components/Transactions.jsx @@ -1,63 +1,163 @@ -import { useRouter } from 'next/router' -import { useState } from 'react' -import { toast } from 'react-hot-toast' -import { EllipsisVerticalIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline' +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { toast } from 'react-hot-toast'; +import { + EllipsisVerticalIcon, + MagnifyingGlassIcon, +} from '@heroicons/react/24/outline'; +import useAuth from '@/core/hooks/useAuth'; -import { downloadPurchaseOrder, downloadQuotation } from '../utils/transactions' -import useTransactions from '../hooks/useTransactions' -import currencyFormat from '@/core/utils/currencyFormat' -import cancelTransactionApi from '../api/cancelTransactionApi' -import TransactionStatusBadge from './TransactionStatusBadge' -import Spinner from '@/core/components/elements/Spinner/Spinner' -import Link from '@/core/components/elements/Link/Link' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import Pagination from '@/core/components/elements/Pagination/Pagination' -import { toQuery } from 'lodash-contrib' -import _ from 'lodash' -import Alert from '@/core/components/elements/Alert/Alert' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import Menu from '@/lib/auth/components/Menu' +import { + downloadPurchaseOrder, + downloadQuotation, +} from '../utils/transactions'; +import useTransactions from '../hooks/useTransactions'; +import currencyFormat from '@/core/utils/currencyFormat'; +import cancelTransactionApi from '../api/cancelTransactionApi'; +import TransactionStatusBadge from './TransactionStatusBadge'; +import Spinner from '@/core/components/elements/Spinner/Spinner'; +import Link from '@/core/components/elements/Link/Link'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import Pagination from '@/core/components/elements/Pagination/Pagination'; +import { toQuery } from 'lodash-contrib'; +import _ from 'lodash'; +import Alert from '@/core/components/elements/Alert/Alert'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; +import Menu from '@/lib/auth/components/Menu'; +import * as XLSX from 'xlsx'; +import getSite from '../api/listSiteApi'; +import transactionsApi from '../api/transactionsApi'; const Transactions = ({ context = '' }) => { - const router = useRouter() - const { q = '', page = 1 } = router.query + const auth = useAuth(); + const router = useRouter(); + const { q = '', page = 1, site = null } = router.query; - const limit = 15 + const limit = 15; + + const [inputQuery, setInputQuery] = useState(q); + const [toOthers, setToOthers] = useState(null); + const [toCancel, setToCancel] = useState(null); + const [listSites, setListSites] = useState([]); + + const [siteFilter, setSiteFilter] = useState(site); const query = { name: q, offset: (page - 1) * limit, context, - limit - } - const { transactions } = useTransactions({ query }) + limit, + site: + siteFilter || (auth?.webRole === null && auth?.site ? auth.site : null), + }; + + const { transactions } = useTransactions({ query }); - const [inputQuery, setInputQuery] = useState(q) - const [toOthers, setToOthers] = useState(null) - const [toCancel, setToCancel] = useState(null) + const fetchSite = async () => { + const site = await getSite(); + setListSites(site.sites); + }; const submitCancelTransaction = async () => { const isCancelled = await cancelTransactionApi({ - transaction: toCancel - }) + transaction: toCancel, + }); if (isCancelled) { - toast.success('Berhasil batalkan transaksi') - transactions.refetch() + toast.success('Berhasil batalkan transaksi'); + transactions.refetch(); } - setToCancel(null) - } + setToCancel(null); + }; - const pageCount = Math.ceil(transactions?.data?.saleOrderTotal / limit) - let pageQuery = _.omit(query, ['limit', 'offset', 'context']) - pageQuery = _.pickBy(pageQuery, _.identity) - pageQuery = toQuery(pageQuery) + const pageCount = Math.ceil(transactions?.data?.saleOrderTotal / limit); + let pageQuery = _.omit(query, ['limit', 'offset', 'context']); + pageQuery = _.pickBy( + pageQuery, + (value, key) => value !== '' && !(key === 'page' && value === '1') + ); + pageQuery = toQuery(pageQuery); const handleSubmit = (e) => { - e.preventDefault() - router.push(`${router.pathname}?q=${inputQuery}`) - } + e.preventDefault(); + const queryParams = {}; + if (inputQuery) queryParams.q = inputQuery; + if (siteFilter) queryParams.site = siteFilter; + router.push({ + pathname: router.pathname, + query: queryParams, + }); + }; + + const handleSiteFilterChange = (e) => { + setSiteFilter(e.target.value); + const queryParams = {}; + if (inputQuery) queryParams.q = inputQuery; + if (e.target.value) queryParams.site = e.target.value; + router.push({ + pathname: router.pathname, + query: queryParams, + }); + }; + + const exportToExcel = (data, siteFilter) => { + const fieldsToExport = [ + 'No. Transaksi', + 'No. PO', + 'Tanggal', + 'Created By', + 'Salesperson', + 'Total', + 'Status', + ]; + const rowsToExport = []; + + data.forEach((saleOrder) => { + const row = { + 'No. Transaksi': saleOrder.name, + 'No. PO': saleOrder.purchaseOrderName || '-', + Tanggal: saleOrder.dateOrder || '-', + 'Created By': saleOrder.address.customer?.name || '-', + Salesperson: saleOrder.sales, + Total: currencyFormat(saleOrder.amountTotal), + Status: saleOrder.status, + }; + if (siteFilter) { + row['Site'] = siteFilter; + } + rowsToExport.push(row); + }); + const worksheet = XLSX.utils.json_to_sheet(rowsToExport, { + header: fieldsToExport, + }); + + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); + XLSX.writeFile(workbook, 'transactions.xlsx'); + }; + + const getAllData = async () => { + const query = { + name: q, + context, + site: + siteFilter || (auth?.webRole === null && auth?.site ? auth.site : null), + }; + const queryString = toQuery(query) + const data = await transactionsApi({ query: queryString }); + return data; + }; + + const handleExportExcel = async () => { + const dataToExport = await getAllData(); + + exportToExcel(dataToExport?.saleOrders, siteFilter); + }; + + useEffect(() => { + fetchSite(); + }, []); return ( <> <MobileView> @@ -81,17 +181,23 @@ const Transactions = ({ context = '' }) => { </div> )} - {!transactions.isLoading && transactions.data?.saleOrders?.length === 0 && ( - <Alert type='info' className='text-center'> - Tidak ada transaksi - </Alert> - )} + {!transactions.isLoading && + transactions.data?.saleOrders?.length === 0 && ( + <Alert type='info' className='text-center'> + Tidak ada transaksi + </Alert> + )} {transactions.data?.saleOrders?.map((saleOrder, index) => ( - <div className='p-4 shadow border border-gray_r-3 rounded-md' key={index}> + <div + className='p-4 shadow border border-gray_r-3 rounded-md' + key={index} + > <div className='grid grid-cols-2'> <Link href={`${router.pathname}/${saleOrder.id}`}> - <span className='text-caption-2 text-gray_r-11'>No. Transaksi</span> + <span className='text-caption-2 text-gray_r-11'> + No. Transaksi + </span> <h2 className='text-danger-500 mt-1'>{saleOrder.name}</h2> </Link> <div className='flex gap-x-1 justify-end'> @@ -105,13 +211,17 @@ const Transactions = ({ context = '' }) => { <Link href={`${router.pathname}/${saleOrder.id}`}> <div className='grid grid-cols-2 mt-3'> <div> - <span className='text-caption-2 text-gray_r-11'>No. Purchase Order</span> + <span className='text-caption-2 text-gray_r-11'> + No. Purchase Order + </span> <p className='mt-1 font-medium text-gray_r-12'> {saleOrder.purchaseOrderName || '-'} </p> </div> <div className='text-right'> - <span className='text-caption-2 text-gray_r-11'>Total Invoice</span> + <span className='text-caption-2 text-gray_r-11'> + Total Invoice + </span> <p className='mt-1 font-medium text-gray_r-12'> {saleOrder.invoiceCount} Invoice </p> @@ -120,10 +230,14 @@ const Transactions = ({ context = '' }) => { <div className='grid grid-cols-2 mt-3'> <div> <span className='text-caption-2 text-gray_r-11'>Sales</span> - <p className='mt-1 font-medium text-gray_r-12'>{saleOrder.sales}</p> + <p className='mt-1 font-medium text-gray_r-12'> + {saleOrder.sales} + </p> </div> <div className='text-right'> - <span className='text-caption-2 text-gray_r-11'>Total Harga</span> + <span className='text-caption-2 text-gray_r-11'> + Total Harga + </span> <p className='mt-1 font-medium text-gray_r-12'> {currencyFormat(saleOrder.amountTotal)} </p> @@ -140,14 +254,18 @@ const Transactions = ({ context = '' }) => { className='mt-2 mb-2' /> - <BottomPopup title='Lainnya' active={toOthers} close={() => setToOthers(null)}> + <BottomPopup + title='Lainnya' + active={toOthers} + close={() => setToOthers(null)} + > <div className='flex flex-col gap-y-4 mt-2'> <button className='text-left disabled:opacity-60' disabled={!toOthers?.purchaseOrderFile} onClick={() => { - downloadPurchaseOrder(toOthers) - setToOthers(null) + downloadPurchaseOrder(toOthers); + setToOthers(null); }} > Download PO @@ -156,8 +274,8 @@ const Transactions = ({ context = '' }) => { className='text-left disabled:opacity-60' disabled={toOthers?.status != 'draft'} onClick={() => { - downloadQuotation(toOthers) - setToOthers(null) + downloadQuotation(toOthers); + setToOthers(null); }} > Download Quotation @@ -166,8 +284,8 @@ const Transactions = ({ context = '' }) => { className='text-left disabled:opacity-60' disabled={toOthers?.status != 'waiting'} onClick={() => { - setToCancel(toOthers) - setToOthers(null) + setToCancel(toOthers); + setToOthers(null); }} > Batalkan Transaksi @@ -175,7 +293,11 @@ const Transactions = ({ context = '' }) => { </div> </BottomPopup> - <BottomPopup active={toCancel} close={() => setToCancel(null)} title='Batalkan Transaksi'> + <BottomPopup + active={toCancel} + close={() => setToCancel(null)} + title='Batalkan Transaksi' + > <div className='leading-7 text-gray_r-12/80'> Apakah anda yakin membatalkan transaksi{' '} <span className='underline'>{toCancel?.name}</span>? @@ -188,7 +310,11 @@ const Transactions = ({ context = '' }) => { > Ya, Batalkan </button> - <button className='btn-light flex-1' type='button' onClick={() => setToCancel(null)}> + <button + className='btn-light flex-1' + type='button' + onClick={() => setToCancel(null)} + > Batal </button> </div> @@ -205,21 +331,50 @@ const Transactions = ({ context = '' }) => { <div className='flex mb-6 items-center justify-between'> <h1 className='text-title-sm font-semibold'> Daftar Transaksi{' '} - {transactions?.data?.saleOrders ? `(${transactions?.data?.saleOrders.length})` : ''} + {transactions?.data?.saleOrders + ? `(${transactions?.data?.saleOrders.length})` + : ''} </h1> - <form className='flex gap-x-2' onSubmit={handleSubmit}> - <input - type='text' - className='form-input' - placeholder='Cari Transaksi...' - value={inputQuery} - onChange={(e) => setInputQuery(e.target.value)} - /> - <button className='btn-light bg-transparent px-3' type='submit'> - <MagnifyingGlassIcon className='w-6' /> - </button> - </form> + <div className='grid grid-cols-2 gap-2'> + {listSites?.length > 0 ? ( + <select + value={siteFilter} + onChange={handleSiteFilterChange} + className='form-input' + > + <option value=''>Pilih Site</option> + {listSites.map((site) => ( + <option value={site} key={site}> + {site} + </option> + ))} + </select> + ) : (<div></div>)} + + <form className='flex gap-x-1' onSubmit={handleSubmit}> + <input + type='text' + className='form-input' + placeholder='Cari Transaksi...' + value={inputQuery} + onChange={(e) => setInputQuery(e.target.value)} + /> + <button + className='btn-light bg-transparent px-3' + type='submit' + > + <MagnifyingGlassIcon className='w-6' /> + </button> + </form> + </div> </div> + <button + onClick={handleExportExcel} + type='button' + className='btn-solid-red px-3 py-2 mr-auto mb-2' + > + <span>Download</span> + </button> <table className='table-data'> <thead> <tr> @@ -227,6 +382,9 @@ const Transactions = ({ context = '' }) => { <th>No. PO</th> <th>Tanggal</th> <th>Created By</th> + {auth?.feature?.soApproval && ( + <th>Site</th> + )} <th className='!text-left'>Salesperson</th> <th className='!text-left'>Total</th> <th>Status</th> @@ -252,13 +410,23 @@ const Transactions = ({ context = '' }) => { {transactions.data?.saleOrders?.map((saleOrder) => ( <tr key={saleOrder.id}> <td> - <Link className='whitespace-nowrap' href={`${router.pathname}/${saleOrder.id}`}>{saleOrder.name}</Link> + <Link + className='whitespace-nowrap' + href={`${router.pathname}/${saleOrder.id}`} + > + {saleOrder.name} + </Link> </td> <td>{saleOrder.purchaseOrderName || '-'}</td> <td>{saleOrder.dateOrder || '-'}</td> <td>{saleOrder.address.customer?.name || '-'}</td> + {auth?.feature?.soApproval && ( + <td>{saleOrder.sitePartner || '-'}</td> + )} <td className='!text-left'>{saleOrder.sales}</td> - <td className='!text-left'>{currencyFormat(saleOrder.amountTotal)}</td> + <td className='!text-left'> + {currencyFormat(saleOrder.amountTotal)} + </td> <td> <div className='flex justify-center'> <TransactionStatusBadge status={saleOrder.status} /> @@ -272,14 +440,14 @@ const Transactions = ({ context = '' }) => { <Pagination pageCount={pageCount} currentPage={parseInt(page)} - url={router.pathname + pageQuery} + url={router.pathname + (pageQuery ? `?${pageQuery}` : '')} className='mt-2 mb-2' /> </div> </div> </DesktopView> </> - ) -} + ); +}; -export default Transactions +export default Transactions; diff --git a/src/lib/transaction/components/stepper.jsx b/src/lib/transaction/components/stepper.jsx new file mode 100644 index 00000000..9b0da0d9 --- /dev/null +++ b/src/lib/transaction/components/stepper.jsx @@ -0,0 +1,83 @@ +import { + Box, + Step, + StepDescription, + StepIcon, + StepIndicator, + StepNumber, + StepSeparator, + StepStatus, + StepTitle, + Stepper, + useSteps, +} from '@chakra-ui/react'; +import Image from 'next/image'; + +const StepApproval = ({ layer, status }) => { + const steps = [ + { title: 'Indoteknik', layer_approval: 1 }, + { title: 'Manager', layer_approval: 2 }, + { title: 'Director', layer_approval: 3 }, + ]; + const { activeStep } = useSteps({ + index: layer, + count: steps.length, + }); + return ( + <Stepper size='md' index={layer} colorScheme='green'> + {steps.map((step, index) => ( + <Step key={index}> + <StepIndicator> + {layer === step.layer_approval && status === 'cancel' ? ( + <StepStatus + complete={ + <Image + src='/images/remove.png' + width={20} + height={20} + alt='' + className='w-full' + /> + } + incomplete={<StepNumber />} + active={<StepNumber />} + /> + ) : ( + <StepStatus + complete={<StepIcon />} + incomplete={<StepNumber />} + active={<StepNumber />} + /> + )} + </StepIndicator> + + <Box flexShrink='0'> + <StepTitle className='md:text-xs'>{step.title}</StepTitle> + {status === 'cancel' ? ( + layer > step.layer_approval ? ( + <StepDescription className='md:text-[8px]'> + Approved + </StepDescription> + ) : ( + <StepDescription className='md:text-[8px]'> + Rejected + </StepDescription> + ) + ) : layer >= step.layer_approval ? ( + <StepDescription className='md:text-[8px]'> + Approved + </StepDescription> + ) : ( + <StepDescription className='md:text-[8px]'> + Pending + </StepDescription> + )} + </Box> + <StepSeparator _horizontal={{ ml: '0' }} /> + </Step> + ))} + </Stepper> + ); +}; + +export default StepApproval; diff --git a/src/lib/variant/components/VariantCard.jsx b/src/lib/variant/components/VariantCard.jsx index 9f1b5733..9f65fc3c 100644 --- a/src/lib/variant/components/VariantCard.jsx +++ b/src/lib/variant/components/VariantCard.jsx @@ -7,9 +7,14 @@ import { createSlug } from '@/core/utils/slug' import currencyFormat from '@/core/utils/currencyFormat' import { updateItemCart } from '@/core/utils/cart' import whatsappUrl from '@/core/utils/whatsappUrl' +import ImageNext from 'next/image'; +import { useMemo, useEffect, useState } from 'react'; const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { const router = useRouter() + + + const addItemToCart = () => { toast.success('Berhasil menambahkan ke keranjang', { duration: 1500 }) @@ -27,11 +32,39 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { const Card = () => ( <div className='flex gap-x-3'> <div className='w-4/12 flex items-center gap-x-2'> - <Image + + <div className="relative"> + <Image src={product.parent.image} alt={product.parent.name} className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' /> + <div className="absolute top-0 right-4 flex mt-3"> + <div className="gambarB "> + {product.isSni && ( + <ImageNext + src="/images/sni-logo.png" + alt="SNI Logo" + className="w-2 h-5 object-contain object-top sm:h-6" + width={50} + height={50} + /> + )} + </div> + <div className="gambarC "> + {product.isTkdn && ( + <ImageNext + src="/images/TKDN.png" + alt="TKDN" + className="w-5 h-6 object-contain object-top ml-1 mr-1 sm:h-6" + width={50} + height={50} + /> + )} + </div> + </div> + </div> + </div> <div className='w-8/12 flex flex-col'> <p className='product-card__title wrap-line-ellipsis-2'>{product.parent.name}</p> diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index 3fe1d3cf..bcb41dd6 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,69 +1,99 @@ -import '@/fonts/Inter/inter.css' -import '@/styles/globals.css' -import 'react-loading-skeleton/dist/skeleton.css' +import '@/fonts/Inter/inter.css'; +import '@/styles/globals.css'; +import '@/styles/normalize.css'; +// import 'react-loading-skeleton/dist/skeleton.css'; -import NextProgress from 'next-progress' -import { useRouter, Router } from 'next/router' -import { AnimatePresence, motion } from 'framer-motion' -import { Toaster } from 'react-hot-toast' -import { QueryClient, QueryClientProvider } from 'react-query' -import useDevice from '@/core/hooks/useDevice' -import { useEffect, useState } from 'react' -import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' -import { SessionProvider } from 'next-auth/react' -import { ProductProvider } from '@/contexts/ProductContext' -import { ProductCartProvider } from '@/contexts/ProductCartContext' -import { ChakraProvider } from '@chakra-ui/react' -import theme from '../../chakra.theme' +import { useEffect, useState } from 'react'; +import dynamic from 'next/dynamic'; +import { useRouter, Router } from 'next/router'; +import { AnimatePresence, motion } from 'framer-motion'; +import { QueryClient, QueryClientProvider } from 'react-query'; -const queryClient = new QueryClient() +import useDevice from '@/core/hooks/useDevice'; +import theme from '../../chakra.theme'; + +const NextProgress = dynamic(() => import('next-progress'), { ssr: false }); +const ChakraProvider = dynamic( + () => import('@chakra-ui/react').then((mod) => mod.ChakraProvider), + { ssr: false } +); +const ProductProvider = dynamic( + () => import('@/contexts/ProductContext').then((mod) => mod.ProductProvider), + { ssr: false } +); +const ProductCartProvider = dynamic( + () => + import('@/contexts/ProductCartContext').then( + (mod) => mod.ProductCartProvider + ), + { ssr: false } +); +const SessionProvider = dynamic( + () => import('next-auth/react').then((mod) => mod.SessionProvider), + { ssr: false } +); +const LogoSpinner = dynamic( + () => import('@/core/components/elements/Spinner/LogoSpinner'), + { ssr: false } +); +const ScrollToTop = dynamic(() => import('@/core/components/ScrollToTop'), { + ssr: false, +}); +const Toaster = dynamic( + () => import('react-hot-toast').then((mod) => mod.Toaster), + { ssr: false } +); + +const queryClient = new QueryClient(); function MyApp({ Component, pageProps: { session, ...pageProps } }) { - const router = useRouter() - const { isMobile } = useDevice() + const router = useRouter(); + const { isMobile } = useDevice(); - const [animateLoader, setAnimateLoader] = useState(false) + const [animateLoader, setAnimateLoader] = useState(false); useEffect(() => { - const handleRouteChangeStart = () => setAnimateLoader(true) - const handleRouteChangeComplete = () => setAnimateLoader(false) + const handleRouteChangeStart = () => setAnimateLoader(true); + const handleRouteChangeComplete = () => setAnimateLoader(false); - Router.events.on('routeChangeStart', handleRouteChangeStart) - Router.events.on('routeChangeComplete', handleRouteChangeComplete) - Router.events.on('routeChangeError', handleRouteChangeComplete) + Router.events.on('routeChangeStart', handleRouteChangeStart); + Router.events.on('routeChangeComplete', handleRouteChangeComplete); + Router.events.on('routeChangeError', handleRouteChangeComplete); return () => { - Router.events.off('routeChangeStart', handleRouteChangeStart) - Router.events.off('routeChangeComplete', handleRouteChangeComplete) - Router.events.off('routeChangeError', handleRouteChangeComplete) - } - }, []) + Router.events.off('routeChangeStart', handleRouteChangeStart); + Router.events.off('routeChangeComplete', handleRouteChangeComplete); + Router.events.off('routeChangeError', handleRouteChangeComplete); + }; + }, []); - const [toasterStyle, setToasterStyle] = useState({}) + const [toasterStyle, setToasterStyle] = useState({}); useEffect(() => { - let elems = document.querySelectorAll('nav') - let totalNavHeight = 0 + let elems = document.querySelectorAll('nav'); + let totalNavHeight = 0; elems.forEach(function (elem) { - totalNavHeight += elem.offsetHeight - }) + totalNavHeight += elem.offsetHeight; + }); setToasterStyle({ - marginTop: isMobile ? totalNavHeight - 8 : totalNavHeight - }) - }, [isMobile]) + marginTop: isMobile ? totalNavHeight - 8 : totalNavHeight, + }); + }, [isMobile]); return ( <SessionProvider session={session}> + <ScrollToTop /> + <AnimatePresence> {animateLoader && ( <motion.div - initial={{ opacity: 0.4 }} + initial={{ opacity: 0.25 }} animate={{ opacity: 1 }} - exit={{ opacity: 0.4 }} + exit={{ opacity: 0.25 }} transition={{ - duration: 0.1 + duration: 0.1, }} className='fixed w-screen h-screen z-[500] bg-white flex justify-center items-center' > @@ -76,7 +106,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { containerStyle={toasterStyle} toastOptions={{ duration: 3000, - className: 'border border-gray_r-8' + className: 'border border-gray_r-8', }} /> <NextProgress color='#F01C21' options={{ showSpinner: false }} /> @@ -90,7 +120,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { </ProductProvider> </QueryClientProvider> </SessionProvider> - ) + ); } -export default MyApp +export default MyApp; diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index 3762c63b..cd60bd89 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -1,16 +1,34 @@ -import { Html, Head, Main, NextScript } from 'next/document' -import Script from 'next/script' +import { Html, Head, Main, NextScript } from 'next/document'; +import Script from 'next/script'; export default function MyDocument() { - const env = process.env.NODE_ENV + const env = process.env.NODE_ENV; return ( <Html> <Head> + <link rel='preconnect' href='https://connect.facebook.net' /> + <link rel='dns-prefetch' href='https://connect.facebook.net' /> + + <link rel='preconnect' href='https://googleads.g.doubleclick.net' /> + <link rel='dns-prefetch' href='https://googleads.g.doubleclick.net' /> + + <link rel='preconnect' href='https://www.googletagmanager.com' /> + <link rel='dns-prefetch' href='https://www.googletagmanager.com' /> + + <link rel='preconnect' href={process.env.NEXT_PUBLIC_ODOO_API_HOST} /> + <link rel='dns-prefetch' href={process.env.NEXT_PUBLIC_ODOO_API_HOST} /> + + <link rel='preconnect' href='/images/logo-indoteknik-gear.png' /> + <link rel='dns-prefetch' href='/images/logo-indoteknik-gear.png' /> + <link rel='icon' href='/favicon.ico' /> <link rel='manifest' href='/manifest.json' /> <link rel='apple-touch-icon' href='/icon.jpg'></link> - <link rel='apple-touch-startup-image' href='/images/splash/launch.png' /> + <link + rel='apple-touch-startup-image' + href='/images/splash/launch.png' + /> <meta name='mobile-web-app-capable' content='yes' /> <meta name='apple-mobile-web-app-capable' content='yes' /> @@ -18,9 +36,11 @@ export default function MyDocument() { <meta name='apple-mobile-web-app-title' content='Indoteknik.com' /> <meta name='theme-color' content='#fff' /> - <link rel='prefetch' href='/images/logo-indoteknik-gear.png' /> + <meta + name='facebook-domain-verification' + content='328wmjs7hcnz74rwsqzxvq50rmbtm2' + /> - <meta name='facebook-domain-verification' content='328wmjs7hcnz74rwsqzxvq50rmbtm2' /> <Script async strategy='beforeInteractive' @@ -28,6 +48,7 @@ export default function MyDocument() { /> <Script + async id='google-analytics-ua' strategy='beforeInteractive' dangerouslySetInnerHTML={{ @@ -36,7 +57,7 @@ export default function MyDocument() { function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-10501937-1'); - ` + `, }} /> @@ -47,6 +68,7 @@ export default function MyDocument() { /> <Script + async id='google-analytics-ga' strategy='beforeInteractive' dangerouslySetInnerHTML={{ @@ -55,11 +77,12 @@ export default function MyDocument() { function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-G1W8MNZ11P'); - ` + `, }} /> <Script + async id='google-tag-manager' strategy='afterInteractive' dangerouslySetInnerHTML={{ @@ -68,7 +91,7 @@ export default function MyDocument() { f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-PHRB7RP'); - ` + `, }} /> @@ -79,6 +102,7 @@ export default function MyDocument() { /> <Script + async id='google-ads' strategy='afterInteractive' dangerouslySetInnerHTML={{ @@ -87,7 +111,7 @@ export default function MyDocument() { function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); - gtag('config', 'AW-954540379');` + gtag('config', 'AW-954540379');`, }} /> @@ -119,5 +143,5 @@ export default function MyDocument() { <NextScript /> </body> </Html> - ) + ); } diff --git a/src/pages/api/product-variant/[id].js b/src/pages/api/product-variant/[id].js new file mode 100644 index 00000000..4186a724 --- /dev/null +++ b/src/pages/api/product-variant/[id].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]'; +export default handler; diff --git a/src/pages/api/product-variant/[id]/promotion/[category].js b/src/pages/api/product-variant/[id]/promotion/[category].js new file mode 100644 index 00000000..aef03c22 --- /dev/null +++ b/src/pages/api/product-variant/[id]/promotion/[category].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]/promotion/[category]'; +export default handler; diff --git a/src/pages/api/product-variant/[id]/promotion/highlight.js b/src/pages/api/product-variant/[id]/promotion/highlight.js new file mode 100644 index 00000000..93b1e781 --- /dev/null +++ b/src/pages/api/product-variant/[id]/promotion/highlight.js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]/promotion/highlight'; +export default handler;
\ No newline at end of file diff --git a/src/pages/api/promotion-program/[id].js b/src/pages/api/promotion-program/[id].js new file mode 100644 index 00000000..f2bb550e --- /dev/null +++ b/src/pages/api/promotion-program/[id].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/promotion-program/[id]'; +export default handler; diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index dbbfcfe3..cc64a7e7 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -1,36 +1,37 @@ -import axios from 'axios' +import axios from 'axios'; + +const SOLR_HOST = process.env.SOLR_HOST; export default async function handler(req, res) { try { - let params = '*:*' - let sort = 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc ' - let rows = 2000 + let params = '*:*'; + let sort = + 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc '; + let rows = 2000; if (req.query.params) { - rows = 100 + rows = 100; switch (req?.query?.params) { case 'level_s': - params = 'level_s:prioritas' - break + params = 'level_s:prioritas'; + break; case 'search': - params = `name_s:${req?.query?.q.toLowerCase()}` - sort = '' - rows = 1 + params = `name_s:"${req?.query?.q.toLowerCase()}"`; + sort = ''; + rows = 1; break; default: - params = `name_s:${req.query.params}` + params = `name_s:${req.query.params}`.toLowerCase(); } } - let brands = await axios( - process.env.SOLR_HOST + - `/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}` - ) - let dataBrands = responseMap(brands.data.response.docs) + const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; + let brands = await axios(url); + let dataBrands = responseMap(brands.data.response.docs); - res.status(200).json(dataBrands) + res.status(200).json(dataBrands); } catch (error) { - console.error('Error fetching data from Solr:', error) - res.status(500).json({ error: 'Internal Server Error' }) + console.error('Error fetching data from Solr:', error); + res.status(500).json({ error: 'Internal Server Error' }); } } @@ -40,9 +41,9 @@ const responseMap = (brands) => { id: brand.id, name: brand.display_name_s, logo: brand.image_s || '', - sequance: brand.sequence_i || '' - } + sequance: brand.sequence_i || '', + }; - return brandMapping - }) -} + return brandMapping; + }); +}; diff --git a/src/pages/api/shop/generate-recomendation.js b/src/pages/api/shop/generate-recomendation.js new file mode 100644 index 00000000..dce8ae72 --- /dev/null +++ b/src/pages/api/shop/generate-recomendation.js @@ -0,0 +1,64 @@ +import { productMappingSolr } from '@/utils/solrMapping' +import axios from 'axios'; +import camelcaseObjectDeep from 'camelcase-object-deep'; + +export default async function handler(req, res) { + const { q = null, op = 'AND' } = req.query + + if (!q) { + return res.status(422).json({ error: 'parameter missing' }) + } + + /*let parameter = [ + `q=${escapeSolrQuery(q)}`, + `q.op=${op}`, + `indent=true`, + `fq=-publish_b:false`, + `qf=name_s^2 description_s`, + `facetch=true`, + `fq=price_tier1_v2_f:[1 TO *]`, + `rows=10`, + `sort=product_rating_f DESC, price_discount_f DESC`, + ]; + let result = await axios( + process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') + );*/ + let parameter = [ + `q=${q}`, + `q.op=${op}`, + `debugQuery=on`, + `defType=edismax`, + `df=display_name_s`, + `fq=-publish_b:false`, + `rows=5`, + ]; + if(op == 'AND'){ + parameter.push(`sort=product_rating_f DESC, price_discount_f DESC`); + parameter.push(`rows=1`); + } + + let result = await axios( + process.env.SOLR_HOST + '/solr/recommendation/select?' + parameter.join('&') + ); + try { + result.data = camelcaseObjectDeep(result.data) + res.status(200).json(result.data) + } catch (error) { + res.status(400).json({ error: error.message }); + } +} + +const escapeSolrQuery = (query) => { + if (query == '*') return query; + + const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g; + const words = query.split(/\s+/); + const escapedWords = words.map((word) => { + if (specialChars.test(word)) { + return `"${word.replace(specialChars, '\\$1')}"`; + } + return word; + }); + + return escapedWords.join(' '); +}; diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 576d028a..b6b8c795 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -1,6 +1,6 @@ -import { productMappingSolr } from '@/utils/solrMapping' -import axios from 'axios' -import camelcaseObjectDeep from 'camelcase-object-deep' +import { productMappingSolr } from '@/utils/solrMapping'; +import axios from 'axios'; +import camelcaseObjectDeep from 'camelcase-object-deep'; export default async function handler(req, res) { const { @@ -14,35 +14,36 @@ export default async function handler(req, res) { operation = 'AND', fq = '', limit = 30, - stock = '' - } = req.query + } = req.query; - let paramOrderBy = '' + let { stock = '' } = req.query; + + let paramOrderBy = ''; switch (orderBy) { case 'price-asc': - paramOrderBy += 'price_tier1_v2_f ASC' - break + paramOrderBy += 'price_tier1_v2_f ASC'; + break; case 'price-desc': - paramOrderBy += 'price_tier1_v2_f DESC' - break + paramOrderBy += 'price_tier1_v2_f DESC'; + break; case 'popular': - paramOrderBy += 'product_rating_f DESC, search_rank_i DESC,' - break + paramOrderBy += 'product_rating_f DESC, search_rank_i DESC,'; + break; case 'popular-weekly': - paramOrderBy += 'search_rank_weekly_i DESC' - break + paramOrderBy += 'search_rank_weekly_i DESC'; + break; case 'stock': - paramOrderBy += 'stock_total_f DESC' - break + paramOrderBy += 'product_rating_f DESC, stock_total_f DESC'; + break; case 'flashsale-price-asc': - paramOrderBy += 'flashsale_price_f ASC' - break + paramOrderBy += 'flashsale_price_f ASC'; + break; default: - paramOrderBy += 'product_rating_f DESC, price_discount_f DESC' - break + paramOrderBy += 'product_rating_f DESC, price_discount_f DESC'; + break; } - let offset = (page - 1) * limit + let offset = (page - 1) * limit; let parameter = [ 'facet.field=manufacture_name_s', 'facet.field=category_name', @@ -55,59 +56,82 @@ export default async function handler(req, res) { `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, - `fq=-publish_b:false` - ] + `fq=-publish_b:false`, + ]; if (priceFrom > 0 || priceTo > 0) { parameter.push( `fq=price_tier1_v2_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ priceTo == '' ? '*' : priceTo }]` - ) + ); + } + + let { auth } = req.cookies; + if (auth) { + auth = JSON.parse(auth); + if (auth.feature.onlyReadyStock) stock = true; } - if (brand) parameter.push(`fq=${brand.split(',').map(manufacturer => `manufacture_name:"${manufacturer}"`).join(" OR ")}`) - if (category) parameter.push(`fq=${category.split(',').map(cat => `category_name:"${cat}"`).join(' OR ')}`) + if (brand) + parameter.push( + `fq=${brand + .split(',') + .map((manufacturer) => `manufacture_name:"${encodeURIComponent(manufacturer)}"`) + .join(' OR ')}` + ); + if (category) + parameter.push( + `fq=${category + .split(',') + .map((cat) => `category_name:"${encodeURIComponent(cat)}"`) + .join(' OR ')}` + ); // if (category) parameter.push(`fq=category_name:${capitalizeFirstLetter(category.replace(/,/g, ' OR '))}`) - if (stock) parameter.push(`fq=stock_total_f:{1 TO *}`) + if (stock) parameter.push(`fq=stock_total_f:{1 TO *}`); // Single fq in url params - if (typeof fq === 'string') parameter.push(`fq=${fq}`) + if (typeof fq === 'string') parameter.push(`fq=${fq}`); // Multi fq in url params - if (Array.isArray(fq)) parameter = parameter.concat(fq.map((val) => `fq=${val}`)) + if (Array.isArray(fq)) + parameter = parameter.concat(fq.map((val) => `fq=${val}`)); - let result = await axios(process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&')) + let result = await axios( + process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') + ); try { - let { auth } = req.cookies - if (auth) auth = JSON.parse(auth) result.data.response.products = productMappingSolr( result.data.response.docs, auth?.pricelist || false - ) - result.data.responseHeader.params.start = parseInt(result.data.responseHeader.params.start) - result.data.responseHeader.params.rows = parseInt(result.data.responseHeader.params.rows) - delete result.data.response.docs - result.data = camelcaseObjectDeep(result.data) - res.status(200).json(result.data) + ); + result.data.responseHeader.params.start = parseInt( + result.data.responseHeader.params.start + ); + result.data.responseHeader.params.rows = parseInt( + result.data.responseHeader.params.rows + ); + delete result.data.response.docs; + result.data = camelcaseObjectDeep(result.data); + res.status(200).json(result.data); } catch (error) { - res.status(400).json({ error: error.message }) + res.status(400).json({ error: error.message }); } } const escapeSolrQuery = (query) => { - if (query == '*') return query + if (query == '*') return query; - const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g - const words = query.split(/\s+/) + const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g; + const words = query.split(/\s+/); const escapedWords = words.map((word) => { if (specialChars.test(word)) { - return `"${word.replace(specialChars, '\\$1')}"` + return `"${word.replace(specialChars, '\\$1')}"`; } - return word - }) + return word; + }); - return escapedWords.join(' ') -} + return escapedWords.join(' '); +}; /*const productResponseMap = (products, pricelist) => { return products.map((product) => { diff --git a/src/pages/api/shop/variant-detail.js b/src/pages/api/shop/variant-detail.js index fadbe000..08ce75b8 100644 --- a/src/pages/api/shop/variant-detail.js +++ b/src/pages/api/shop/variant-detail.js @@ -8,7 +8,10 @@ export default async function handler(req, res) { `/solr/variants/select?q=id:${req.query.id}&q.op=OR&indent=true` ) let auth = req.query.auth === 'false' ? JSON.parse(req.query.auth) : req.query.auth - let result = variantsMappingSolr('',productVariants.data.response.docs, auth || false) + let productTemplate = await axios( + process.env.SOLR_HOST + `/solr/product/select?q=id:${req.query.id}&q.op=OR&indent=true` + ) + let result = variantsMappingSolr(productTemplate.data.response.docs, productVariants.data.response.docs, auth || false) res.status(200).json(result) } catch (error) { diff --git a/src/pages/google_merchant/products/[page].js b/src/pages/google_merchant/products/[page].js index c8b4079b..6e0eb703 100644 --- a/src/pages/google_merchant/products/[page].js +++ b/src/pages/google_merchant/products/[page].js @@ -1,94 +1,102 @@ -import { createSlug } from '@/core/utils/slug' -import toTitleCase from '@/core/utils/toTitleCase' -import productSearchApi from '@/lib/product/api/productSearchApi' -import variantSearchApi from '@/lib/product/api/variantSearchApi' -import axios from 'axios' -import _ from 'lodash-contrib' -import { create } from 'xmlbuilder' +import { createSlug } from '@/core/utils/slug'; +import toTitleCase from '@/core/utils/toTitleCase'; +import variantSearchApi from '@/lib/product/api/variantSearchApi'; +import axios from 'axios'; +import _ from 'lodash-contrib'; +import { create } from 'xmlbuilder'; export async function getServerSideProps({ res, query }) { - const titleContent = 'Indoteknik.com: B2B Industrial Supply & Solution' + const titleContent = 'Indoteknik.com: B2B Industrial Supply & Solution'; const descriptionContent = - 'Temukan pilihan produk B2B Industri & Alat Teknik untuk Perusahaan, UMKM & Pemerintah dengan lengkap, mudah dan transparan.' + 'Temukan pilihan produk B2B Industri & Alat Teknik untuk Perusahaan, UMKM & Pemerintah dengan lengkap, mudah dan transparan.'; - const { page } = query - const limit = 5000 + const { page } = query; + const limit = 5000; const queries = { limit, page: page.replace('.xml', ''), priceFrom: 1, orderBy: 'popular', - fq: 'image_s:["" TO *]' - } - const products = await variantSearchApi({ query: _.toQuery(queries) }) + fq: 'image_s:["" TO *]', + }; + const products = await variantSearchApi({ query: _.toQuery(queries) }); - const brandsData = {} - const categoriesData = {} + const brandsData = {}; + const categoriesData = {}; - const productItems = [] + const productItems = []; for (const product of products.response.products) { - const productUrl = createSlug('/shop/product/variant/', product.name, product.id, true) - const productId = product.code != '' ? product.code : product.id - const regexHtmlTags = /(<([^>]+)>)/gi - product.description = product.description?.replace(regexHtmlTags, ' ').trim() + const productUrl = createSlug( + '/shop/product/variant/', + product.name, + product.id, + true + ); + const productId = product.code != '' ? product.code : product.id; + const regexHtmlTags = /(<([^>]+)>)/gi; + product.description = product.description + ?.replace(regexHtmlTags, ' ') + .trim(); const defaultProductDescription = - 'Indoteknik.com menawarkan berbagai produk industri, konstruksi, dan teknik terpercaya. Temukan mesin industri, peralatan listrik, alat pengukur, dan banyak lagi. Pengalaman berbelanja mudah dengan deskripsi produk lengkap, spesifikasi teknis, dan gambar jelas. Pembayaran aman, pengiriman cepat ke seluruh Indonesia. Solusi lengkap untuk kebutuhan Kantor, Industri & Teknik Anda.' + 'Indoteknik.com menawarkan berbagai produk industri, konstruksi, dan teknik terpercaya. Temukan mesin industri, peralatan listrik, alat pengukur, dan banyak lagi. Pengalaman berbelanja mudah dengan deskripsi produk lengkap, spesifikasi teknis, dan gambar jelas. Pembayaran aman, pengiriman cepat ke seluruh Indonesia. Solusi lengkap untuk kebutuhan Kantor, Industri & Teknik Anda.'; if (!product.description) { - product.description = defaultProductDescription + product.description = defaultProductDescription; } - let categoryName = null + let categoryName = null; - let brandId = product.manufacture?.id ?? null - let categoryId = null + let brandId = product.manufacture?.id ?? null; + let categoryId = null; if (brandId && brandId in brandsData) { - categoryId = brandsData[brandId].category_ids?.[0] ?? null + categoryId = brandsData[brandId].category_ids?.[0] ?? null; } else { - const solrBrand = await getBrandById(brandId) - brandsData[brandId] = solrBrand - categoryId = solrBrand?.category_ids?.[0] ?? null + const solrBrand = await getBrandById(brandId); + brandsData[brandId] = solrBrand; + categoryId = solrBrand?.category_ids?.[0] ?? null; } if (categoryId && categoryId in categoriesData) { - categoryName = categoriesData[categoryId].name_s ?? null + categoryName = categoriesData[categoryId].name_s ?? null; } else { - const solrCategory = await getCategoryById(categoryId) - categoriesData[categoryId] = solrCategory - categoryName = solrCategory?.name_s ?? null + const solrCategory = await getCategoryById(categoryId); + categoriesData[categoryId] = solrCategory; + categoryName = solrCategory?.name_s ?? null; } - const availability = 'in_stock' + const availability = 'in_stock'; const item = { 'g:id': { '#text': productId }, 'g:title': { '#text': toTitleCase(product.name) }, 'g:description': { '#text': product.description }, 'g:link': { '#text': productUrl }, - 'g:image_link': { '#text': product.image }, + 'g:image_link': { '#text': product.image + '?variant=True' }, 'g:condition': { '#text': 'new' }, 'g:availability': { '#text': availability }, 'g:brand': { '#text': product.manufacture?.name || '' }, - 'g:price': { '#text': `${Math.round(product.lowestPrice.price * 1.11)} IDR` } - } + 'g:price': { + '#text': `${Math.round(product.lowestPrice.price * 1.11)} IDR`, + }, + }; if (product.stockTotal == 0) { - item['g:custom_label_0'] = { '#text': 'Stok Tidak Tersedia' } + item['g:custom_label_0'] = { '#text': 'Stok Tidak Tersedia' }; } else { - item['g:custom_label_1'] = { '#text': 'Stok Tersedia' } + item['g:custom_label_1'] = { '#text': 'Stok Tersedia' }; } if (categoryName) { - item['g:custom_label_2'] = { '#text': categoryName } + item['g:custom_label_2'] = { '#text': categoryName }; } if (product.lowestPrice.discountPercentage > 0) { item['g:sale_price'] = { - '#text': `${Math.round(product.lowestPrice.priceDiscount * 1.11)} IDR` - } + '#text': `${Math.round(product.lowestPrice.priceDiscount * 1.11)} IDR`, + }; } - productItems.push(item) + productItems.push(item); } const googleMerchant = { @@ -99,28 +107,32 @@ export async function getServerSideProps({ res, query }) { title: { '#text': `<![CDATA[${titleContent}]]>` }, link: { '#text': process.env.SELF_HOST }, description: { '#text': `<![CDATA[${descriptionContent}]]>` }, - item: productItems - } - } - } + item: productItems, + }, + }, + }; - res.setHeader('Content-Type', 'text/xml;charset=iso-8859-1') - res.write(create(googleMerchant).end()) - res.end() + res.setHeader('Content-Type', 'text/xml;charset=iso-8859-1'); + res.write(create(googleMerchant).end()); + res.end(); - return { props: {} } + return { props: {} }; } const getBrandById = async (id) => { - const brand = await axios(`${process.env.SOLR_HOST}/solr/brands/select?q=id:${id}`) - return brand.data.response.docs[0] ?? null -} + const brand = await axios( + `${process.env.SOLR_HOST}/solr/brands/select?q=id:${id}` + ); + return brand.data.response.docs[0] ?? null; +}; const getCategoryById = async (id) => { - const category = await axios(`${process.env.SOLR_HOST}/solr/categories/select?q=id:${id}`) - return category.data.response.docs[0] ?? null -} + const category = await axios( + `${process.env.SOLR_HOST}/solr/categories/select?q=id:${id}` + ); + return category.data.response.docs[0] ?? null; +}; export default function GoogleMerchantPage() { - return null + return null; } diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 65d953d2..8af963fb 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -1,15 +1,18 @@ import dynamic from 'next/dynamic'; -import MobileView from '@/core/components/views/MobileView'; -import DesktopView from '@/core/components/views/DesktopView'; import { useRef } from 'react'; -import Seo from '@/core/components/Seo'; -import DelayRender from '@/core/components/elements/DelayRender/DelayRender'; + import { HeroBannerSkeleton } from '@/components/skeleton/BannerSkeleton'; import { PopularProductSkeleton } from '@/components/skeleton/PopularProductSkeleton'; -import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; -import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBrandSkeleton'; +import Seo from '@/core/components/Seo'; +import DelayRender from '@/core/components/elements/DelayRender/DelayRender'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; import { FlashSaleSkeleton } from '@/lib/flashSale/skeleton/FlashSaleSkeleton'; +import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBrandSkeleton'; +import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; +import useProductDetail from '~/modules/product-detail/stores/useProductDetail'; +import { getAuth } from '~/libs/auth'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -40,6 +43,11 @@ const FlashSale = dynamic( loading: () => <FlashSaleSkeleton />, } ); + +const ProgramPromotion = dynamic(() => + import('@/lib/home/components/PromotionProgram') +); + const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection') ); @@ -55,6 +63,8 @@ export default function Home() { const bannerRef = useRef(null); const wrapperRef = useRef(null); + const auth = getAuth(); + const handleOnLoad = () => { wrapperRef.current.style.height = bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; @@ -74,8 +84,9 @@ export default function Home() { ]} /> + <PagePopupIformation /> + <DesktopView> - <PagePopupIformation /> <div className='container mx-auto'> <div className='flex min-h-[400px] h-[460px]' @@ -95,10 +106,16 @@ export default function Home() { </div> </div> - <div className='my-16 flex flex-col gap-y-16'> + <div className='my-16 flex flex-col gap-y-8'> <ServiceList /> - <PreferredBrand /> - <FlashSale /> + <div id='flashsale'> + <PreferredBrand /> + </div> + {!auth?.feature?.soApproval && ( + <> + <ProgramPromotion /> <FlashSale /> + </> + )} <PromotinProgram /> <CategoryHomeId /> <BannerSection /> @@ -108,7 +125,6 @@ export default function Home() { </DesktopView> <MobileView> - <PagePopupIformation /> <DelayRender renderAfter={200}> <HeroBanner /> </DelayRender> @@ -117,11 +133,20 @@ export default function Home() { <ServiceList /> </DelayRender> <DelayRender renderAfter={400}> - <PreferredBrand /> - </DelayRender> - <DelayRender renderAfter={600}> - <FlashSale /> + <div id='flashsale'> + <PreferredBrand /> + </div> </DelayRender> + {!auth?.feature?.soApproval && ( + <> + <DelayRender renderAfter={400}> + <ProgramPromotion /> + </DelayRender> + <DelayRender renderAfter={600}> + <FlashSale /> + </DelayRender> + </> + )} <DelayRender renderAfter={600}> <PromotinProgram /> </DelayRender> diff --git a/src/pages/my/recomendation/api/recomendation.js b/src/pages/my/recomendation/api/recomendation.js new file mode 100644 index 00000000..8ff760d0 --- /dev/null +++ b/src/pages/my/recomendation/api/recomendation.js @@ -0,0 +1,17 @@ +import axios from 'axios'; +import { useQuery } from 'react-query'; + +const GenerateRecomendations = ({ query }) => { + const queryString = _.toQuery(query); + const GenerateRecomendationProducts = async () => + await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/recomendation?${queryString}` + ); + const productSearch = useQuery( + `generateRecomendation-${ququeryStringery}`, + GenerateRecomendationProducts + ); + + return productSearch; +}; +export default GenerateRecomendations; diff --git a/src/pages/my/recomendation/components/products-recomendatison.jsx b/src/pages/my/recomendation/components/products-recomendatison.jsx new file mode 100644 index 00000000..d39d2a99 --- /dev/null +++ b/src/pages/my/recomendation/components/products-recomendatison.jsx @@ -0,0 +1,477 @@ +import Menu from '@/lib/auth/components/Menu'; +import { useEffect, useState } from 'react'; +import * as XLSX from 'xlsx'; +import GenerateRecomendations from '../api/recomendation'; +import axios from 'axios'; +import { Button, Link } from '@chakra-ui/react'; +import Image from 'next/image'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import formatCurrency from '~/libs/formatCurrency'; + +const exportToExcel = (data) => { + const worksheet = XLSX.utils.json_to_sheet(data); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Results'); + + // Generate Excel file and trigger download in the browser + XLSX.writeFile(workbook, 'ProductRecommendations.xlsx'); +}; + +const ProductsRecomendation = ({ id }) => { + const [excelData, setExcelData] = useState(null); + const [products, setProducts] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [variantsOpen, setVariantsOpen] = useState([]); + const [otherRec, setOtherRec] = useState(false); + + const mappingProducts = async ({ index, product, result, variants }) => { + const resultMapping = { + index: index, + product: product, + result: { + id: result?.id || '-', + name: result?.nameS || '-', + code: result?.defaultCodeS || '-', + }, + }; + + return resultMapping; + }; + + const searchRecomendation = async ({ product, index, operator = 'AND' }) => { + let variants = []; + let resultMapping = {}; + const searchProduct = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/generate-recomendation?q=${product}&op=${operator}` + ); + + if (operator === 'AND') { + const result = + searchProduct.data.response.numFound > 0 + ? searchProduct.data.response.products[0] + : null; + + if (result?.variantTotal > 1) { + const searchVariants = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=${result.id}` + ); + variants = searchVariants.data[0].variants; + } + + resultMapping = await mappingProducts({ + index, + product, + result, + variants, + }); + } else { + const result = + searchProduct.data.response.numFound > 0 + ? searchProduct.data.response.products + : null; + + result.map((item) => { + if (item.variantTotal > 1) { + const searchVariants = axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=${item.id}` + ); + variants = searchVariants.data[0].variants; + } + }); + + console.log('ini result', searchProduct.data.response); + } + + return resultMapping; + }; + + const handleSubmit = async (e) => { + setIsLoading(true); + e.preventDefault(); + if (excelData) { + const results = await Promise.all( + excelData.map(async (row, i) => { + const index = i + 1; + const product = row['product']; + return await generateProductRecomendation({ product, index }); + }) + ); + + const formattedResults = results.map((result) => { + const formattedResult = { product: result.product }; + for (let i = 0; i <= 5; i++) { + formattedResult[`recomendation product ${i + 1} - code`] = result.result[i] == null ? '-' : result.result[i]?.code; + formattedResult[`recomendation product ${i + 1} - name`] = result.result[i] == null ? '-' : result.result[i]?.name ; + } + return formattedResult; + }); + + exportToExcel(formattedResults); + setProducts(results); + setIsLoading(false); + } else { + setIsLoading(false); + console.log('No excel data available'); + } + }; + + const handleFileChange = (e) => { + setIsLoading(true); + const file = e.target.files[0]; + const reader = new FileReader(); + reader.onload = (event) => { + const data = new Uint8Array(event.target.result); + const workbook = XLSX.read(data, { type: 'array' }); + + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName]; + const jsonData = XLSX.utils.sheet_to_json(worksheet); + + setExcelData(jsonData); + console.log('ini json data', jsonData); + + setIsLoading(false); + }; + reader.readAsArrayBuffer(file); + }; + + const handleVariantsOpen = ({ variants }) => { + setVariantsOpen(variants); + setIsOpen(true); + }; + const hadnliChooseVariants = ({ id, variant }) => { + let foundIndex = products.findIndex((item) => item.result.id === id); + if (foundIndex !== -1) { + products[foundIndex].result.code = variant?.code; + products[foundIndex].result.name = variant?.name; + } else { + console.log('Data not found.'); + } + setIsOpen(false); + }; + + const handlingOtherRec = ({ product }) => { + console.log('ini product', product); + const result = async () => + await searchRecomendation({ product, index: 0, operator: 'OR' }); + + result(); + }; + + const generateProductRecomendation = async ({ product, index }) => { + let variants = []; + let resultMapping = {}; + const searchProduct = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/generate-recomendation?q=${product}&op=AND` + ); + const searchProductOR = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/generate-recomendation?q=${product}&op=OR` + ); + const resultAND = + searchProduct.data.response.numFound > 0 + ? searchProduct.data.response.docs[0] + : null; // hasil satu + const resultOR = + searchProductOR.data.response.numFound > 0 + ? searchProductOR.data.response.docs + : []; // hasil 5 + + resultMapping = { + index: index, + product: product, + result: {}, + }; + + // Add resultAND to resultMapping if it exists + resultMapping.result[0] = resultAND + ? { + id: resultAND?.id || '-', + name: resultAND?.nameS || '-', + code: resultAND?.defaultCodeS || '-', + } + : null; + + // Add resultOR to resultMapping + if (resultOR.length > 0) { + resultOR.forEach((item, idx) => { + resultMapping.result[idx + 1] = { + id: item?.id || '-', + name: item?.nameS || '-', + code: item?.defaultCodeS || '-', + }; + }); + } else { + for (let i = 0; i <= 5; i++) { + resultMapping.result[i + 1] = null; + } + } + return resultMapping; + }; + return ( + <> + <BottomPopup + active={isOpen} + close={() => setIsOpen(false)} + className='w-full md:!w-[60%]' + title='List Variants' + > + <div className='container'> + <table className='table-data'> + <thead> + <tr> + <th>Part Number</th> + <th>Variants </th> + <th>Harga </th> + <th></th> + </tr> + </thead> + <tbody> + {variantsOpen?.map((variant, index) => ( + <tr key={index}> + <td>{variant.code}</td> + <td>{variant.attributes.join(', ') || '-'}</td> + <td> + {variant.price.discountPercentage > 0 && ( + <div className='flex items-center gap-x-1'> + <div className={style['disc-badge']}> + {Math.floor(variant.price.discountPercentage)}% + </div> + <div className={style['disc-price']}> + Rp {formatCurrency(variant.price.price)} + </div> + </div> + )} + {variant.price.priceDiscount > 0 && + `Rp ${formatCurrency(variant.price.priceDiscount)}`} + {variant.price.priceDiscount === 0 && '-'} + </td> + <td> + <Button + size='sm' + w='100%' + onClick={() => + hadnliChooseVariants({ + id: variant.parent.id, + variant: variant, + }) + } + > + Pilih + </Button> + </td> + </tr> + ))} + </tbody> + </table> + </div> + </BottomPopup> + <BottomPopup + active={otherRec} + close={() => setOtherRec(false)} + className='w-full md:!w-[60%]' + title='Other Recomendations' + > + <div className='container'> + <table className='table-data'> + <thead> + <tr> + <th>Product</th> + <th>Item Code </th> + <th>Description</th> + <th>Brand</th> + <th>Price</th> + <th>Image</th> + </tr> + </thead> + <tbody> + {variantsOpen?.map((variant, index) => ( + <tr key={index}> + <td>{variant.code}</td> + <td>{variant.attributes.join(', ') || '-'}</td> + <td> + {variant.price.discountPercentage > 0 && ( + <div className='flex items-center gap-x-1'> + <div className={style['disc-badge']}> + {Math.floor(variant.price.discountPercentage)}% + </div> + <div className={style['disc-price']}> + Rp {formatCurrency(variant.price.price)} + </div> + </div> + )} + {variant.price.priceDiscount > 0 && + `Rp ${formatCurrency(variant.price.priceDiscount)}`} + {variant.price.priceDiscount === 0 && '-'} + </td> + <td> + <Button + size='sm' + w='100%' + onClick={() => + hadnliChooseVariants({ + id: variant.parent.id, + variant: variant, + }) + } + > + Pilih + </Button> + </td> + </tr> + ))} + </tbody> + </table> + </div> + </BottomPopup> + <div className='container mx-auto flex py-10'> + <div className='w-3/12 pr-4'> + <Menu /> + </div> + <div className='w-9/12 p-4 bg-white border border-gray_r-6 rounded'> + <div className='flex mb-6 items-center justify-between'> + <h1 className='text-title-sm font-semibold'> + Generate Recomendation + </h1> + </div> + <div className='group'> + <h1 className='text-sm font-semibold'>Contoh Excel</h1> + <table className='table-data'> + <thead> + <tr> + <th>Product</th> + <th>Qty</th> + </tr> + </thead> + <tbody> + <tr> + <td>Tekiro Long Nose Pliers Tang Lancip</td> + <td>10</td> + </tr> + </tbody> + </table> + </div> + <div className='container mx-auto mt-8'> + <div className='mb-4'> + <label htmlFor='excelFile' className='text-sm font-semibold'> + Upload Excel File (.xlsx) + </label> + <input + type='file' + id='excelFile' + accept='.xlsx' + onChange={handleFileChange} + className='mt-1 p-2 block w-full border border-gray-300 rounded-md focus:outline-none focus:border-blue-500' + /> + </div> + <Button + colorScheme='red' + w='l' + isDisabled={isLoading} + onClick={handleSubmit} + > + Generate + </Button> + </div> + {/* <div className='grup mt-8'> + {products && products.length > 0 && ( + <div className='group'> + <table className='table-data'> + <thead> + <tr> + <th>Product</th> + <th>Item Code </th> + <th>Description</th> + <th>Brand</th> + <th>Price</th> + <th>Image</th> + <th>lainnya</th> + </tr> + </thead> + <tbody> + {products.map((product, index) => ( + <tr key={index}> + <td>{product?.product}</td> + <td> + {product?.result?.code === '-' && + product.result.variantTotal > 1 && ( + <Button + border='2px' + borderColor='yellow.300' + size='sm' + onClick={() => + handleVariantsOpen({ + variants: product?.result?.variants, + }) + } + > + Lihat Variants + </Button> + )} + {product?.result.code !== '-' && + product?.result.variantTotal > 1 ? ( + <> + {product?.result.code} + <Button + variant='link' + colorScheme='yellow' + size='sm' + onClick={() => + handleVariantsOpen({ + variants: product?.result?.variants, + }) + } + > + Variants lainya + </Button> + </> + ) : ( + <>{product?.result.code}</> + )} + </td> + <td>{product?.result.name}</td> + <td>{product?.result.manufacture}</td> + <td> + {product?.result.price !== '-' + ? `Rp ${formatCurrency(product?.result.price)}` + : '-'} + </td> + <td> + {product?.result.image !== '-' ? ( + <Image + src={product?.result.image} + width={100} + height={100} + alt={product?.result.name} + /> + ) : ( + '-' + )} + </td> + <td> + {' '} + <Button + border='2px' + borderColor='red.500' + size='sm' + onClick={() => + handlingOtherRec({ product: product.product }) + } + > + Other + </Button> + </td> + </tr> + ))} + </tbody> + </table> + </div> + )} + </div> */} + </div> + </div> + </> + ); +}; + +export default ProductsRecomendation; diff --git a/src/pages/my/recomendation/index.jsx b/src/pages/my/recomendation/index.jsx new file mode 100644 index 00000000..684b30c2 --- /dev/null +++ b/src/pages/my/recomendation/index.jsx @@ -0,0 +1,26 @@ +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import IsAuth from '../../../lib/auth/components/IsAuth'; +import AppLayout from '@/core/components/layouts/AppLayout'; +import BasicLayout from '@/core/components/layouts/BasicLayout'; +import dynamic from 'next/dynamic'; +import Seo from '@/core/components/Seo' + +const ProductsRecomendation = dynamic(() => import('./components/products-recomendatison')) +export default function MyRecomendation() { + return ( + <IsAuth> + + <Seo title='Dashboard Rekomendasi - Indoteknik.com' /> + + <MobileView> + <AppLayout></AppLayout> + </MobileView> + <DesktopView> + <BasicLayout> + <ProductsRecomendation /> + </BasicLayout> + </DesktopView> + </IsAuth> + ); +} diff --git a/src/pages/shop/cart.jsx b/src/pages/shop/cart.jsx index 2da58c96..7475b23d 100644 --- a/src/pages/shop/cart.jsx +++ b/src/pages/shop/cart.jsx @@ -1,14 +1,14 @@ -import Seo from '@/core/components/Seo' -import BasicLayout from '@/core/components/layouts/BasicLayout' -import DesktopView from '@/core/components/views/DesktopView' -import MobileView from '@/core/components/views/MobileView' -import IsAuth from '@/lib/auth/components/IsAuth' -import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react' -import dynamic from 'next/dynamic' -import Link from 'next/link' +import Seo from '@/core/components/Seo'; +import BasicLayout from '@/core/components/layouts/BasicLayout'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import IsAuth from '@/lib/auth/components/IsAuth'; +import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react'; +import dynamic from 'next/dynamic'; +import Link from 'next/link'; -const AppLayout = dynamic(() => import('@/core/components/layouts/AppLayout')) -const CartComponent = dynamic(() => import('@/lib/cart/components/Cart')) +const AppLayout = dynamic(() => import('@/core/components/layouts/AppLayout')); +const CartDetail = dynamic(() => import('~/pages/shop/cart')); export default function Cart() { return ( @@ -18,7 +18,9 @@ export default function Cart() { <IsAuth> <MobileView> <AppLayout title='Keranjang' withFooter={false}> - <CartComponent /> + <div className='p-4'> + <CartDetail /> + </div> </AppLayout> </MobileView> @@ -27,20 +29,29 @@ export default function Cart() { <div className='container mx-auto py-4 md:py-6 pb-0'> <Breadcrumb> <BreadcrumbItem> - <BreadcrumbLink as={Link} href='/' className='!text-danger-500 whitespace-nowrap'> + <BreadcrumbLink + as={Link} + href='/' + className='!text-danger-500 whitespace-nowrap' + > Home </BreadcrumbLink> </BreadcrumbItem> <BreadcrumbItem isCurrentPage> - <BreadcrumbLink className='whitespace-nowrap'>Keranjang</BreadcrumbLink> + <BreadcrumbLink className='whitespace-nowrap'> + Keranjang + </BreadcrumbLink> </BreadcrumbItem> </Breadcrumb> + + <div className='h-10' /> + + <CartDetail /> </div> - <CartComponent /> </BasicLayout> </DesktopView> </IsAuth> </> - ) + ); } diff --git a/src/pages/shop/category/[slug].jsx b/src/pages/shop/category/[slug].jsx index 6d3985a8..1afe30bf 100644 --- a/src/pages/shop/category/[slug].jsx +++ b/src/pages/shop/category/[slug].jsx @@ -1,25 +1,31 @@ -import dynamic from 'next/dynamic' -import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug' -import { useRouter } from 'next/router' -import _ from 'lodash' -import Seo from '@/core/components/Seo' -import Breadcrumb from '@/lib/category/components/Breadcrumb' +import _ from 'lodash'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; -const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) -const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')) +import Seo from '@/core/components/Seo'; +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; +import Breadcrumb from '@/lib/category/components/Breadcrumb'; + +const BasicLayout = dynamic(() => + import('@/core/components/layouts/BasicLayout') +); +const ProductSearch = dynamic(() => + import('@/lib/product/components/ProductSearch') +); export default function CategoryDetail() { - const router = useRouter() - const { slug = '' } = router.query + const router = useRouter(); + const { slug = '', page = 1 } = router.query; - const categoryName = getNameFromSlug(slug) - const categoryId = getIdFromSlug(slug) - const q = router?.query.q || null + const categoryName = getNameFromSlug(slug); + const categoryId = getIdFromSlug(slug); + const q = router?.query.q || null; const query = { - fq: `category_id_i:${categoryId}` - } + fq: `category_id_i:${categoryId}`, + page, + }; if (q) { - query.q = q + query.q = q; } return ( @@ -30,8 +36,8 @@ export default function CategoryDetail() { additionalMetaTags={[ { property: 'keywords', - content: `Jual ${categoryName}, harga ${categoryName}, ${categoryName} murah, toko ${categoryName}, ${categoryName} jakarta, ${categoryName} surabaya` - } + content: `Jual ${categoryName}, harga ${categoryName}, ${categoryName} murah, toko ${categoryName}, ${categoryName} jakarta, ${categoryName} surabaya`, + }, ]} /> @@ -41,5 +47,5 @@ export default function CategoryDetail() { <ProductSearch query={query} prefixUrl={`/shop/category/${slug}`} /> )} </BasicLayout> - ) + ); } diff --git a/src/pages/shop/product/[slug].jsx b/src/pages/shop/product/[slug].jsx index d8366d3c..73e8987c 100644 --- a/src/pages/shop/product/[slug].jsx +++ b/src/pages/shop/product/[slug].jsx @@ -1,110 +1,6 @@ -import Seo from '@/core/components/Seo' -import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' -import { getIdFromSlug } from '@/core/utils/slug' -import productApi from '@/lib/product/api/productApi' -import PageNotFound from '@/pages/404' -import dynamic from 'next/dynamic' -import { useRouter } from 'next/router' -import cookie from 'cookie' -import axios from 'axios' -import { useProductContext } from '@/contexts/ProductContext' -import { useEffect } from 'react' -import { updateItemCart } from '@/core/utils/cart' +import ProductDetailPage, { + getServerSideProps, +} from '~/pages/shop/product/[slug]'; -const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) -const Product = dynamic(() => import('@/lib/product/components/Product/Product')) - -export async function getServerSideProps(context) { - const { slug } = context.query - const cookies = context.req.headers.cookie - const cookieObj = cookies ? cookie.parse(cookies) : {} - const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {} - const tier = auth.pricelist ? auth.pricelist : false - const authToken = auth?.token || '' - - let response = await axios( - `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=` + - getIdFromSlug(slug) + - '&auth=' + - tier - ) - let product = response.data - // let productSolr = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } }) - // let productSolr = null - if (product?.length == 1) { - product = product[0] - } else { - product = null - } - - return { - props: { product } - } -} - -export default function ProductDetail({ product }) { - const router = useRouter() - const { setProduct } = useProductContext() - - useEffect(() => { - if (product) { - setProduct(product) - } - }, [product, setProduct]) - - useEffect(() => { - const { action, variantId, qty } = router.query - const addToCart = async () => { - const data = { - productId: variantId, - quantity: qty, - selected: true, - programLineId: null, - source: action - } - console.log('data dr test', data) - await updateItemCart(data) - const redirectURL = action === 'buy' ? '/shop/checkout?source=buy' : '/shop/cart' - router.push(redirectURL) - } - - if (action && variantId && qty) { - addToCart() - } - }, [router]) - - if (!product) return <PageNotFound /> - - return ( - <BasicLayout> - <Seo - title={product?.name || '' + ' - Indoteknik.com' || ''} - description='Temukan pilihan produk B2B Industri & Alat Teknik untuk Perusahaan, UMKM & Pemerintah dengan lengkap, mudah dan transparan.' - openGraph={{ - url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath, - images: [ - { - url: product?.image, - width: 800, - height: 800, - alt: product?.name - } - ], - type: 'product' - }} - additionalMetaTags={[ - { - name: 'keywords', - content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}` - } - ]} - /> - {!product && ( - <div className='container mx-auto flex justify-center pt-10'> - <LogoSpinner width={36} height={36} /> - </div> - )} - {product && <Product product={product} />} - </BasicLayout> - ) -} +export { getServerSideProps }; +export default ProductDetailPage; diff --git a/src/pages/shop/product/variant/[slug].jsx b/src/pages/shop/product/variant/[slug].jsx index 401bce82..cb335e0a 100644 --- a/src/pages/shop/product/variant/[slug].jsx +++ b/src/pages/shop/product/variant/[slug].jsx @@ -1,37 +1,41 @@ -import Seo from '@/core/components/Seo' -import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner' -import { getIdFromSlug } from '@/core/utils/slug' -import PageNotFound from '@/pages/404' -import dynamic from 'next/dynamic' -import { useRouter } from 'next/router' -import cookie from 'cookie' -import variantApi from '@/lib/product/api/variantApi' -import axios from 'axios' -import { useProductContext } from '@/contexts/ProductContext' -import { useEffect } from 'react' +import axios from 'axios'; +import cookie from 'cookie'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; +import { useEffect } from 'react'; -const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) -const Product = dynamic(() => import('@/lib/product/components/Product/Product')) +import { useProductContext } from '@/contexts/ProductContext'; +import Seo from '@/core/components/Seo'; +import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'; +import { getIdFromSlug } from '@/core/utils/slug'; +import PageNotFound from '@/pages/404'; + +const BasicLayout = dynamic(() => + import('@/core/components/layouts/BasicLayout') +); +const Product = dynamic(() => + import('@/lib/product/components/Product/Product') +); export async function getServerSideProps(context) { - const { slug } = context.query - const cookies = context.req.headers.cookie - const cookieObj = cookies ? cookie.parse(cookies) : {} - const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {} - const tier = auth.pricelist ? auth.pricelist : false - const authToken = auth?.token || '' + const { slug } = context.query; + const cookies = context.req.headers.cookie; + const cookieObj = cookies ? cookie.parse(cookies) : {}; + const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {}; + const tier = auth.pricelist ? auth.pricelist : false; + const authToken = auth?.token || ''; let response = await axios( `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/variant-detail?id=` + getIdFromSlug(slug) + '&auth=' + tier - ) - let product = response.data + ); + let product = response.data; // let product = await variantApi({ id: getIdFromSlug(slug), headers: { Token: authToken } }) if (product?.length == 1) { - product = product[0] + product = product[0]; /* const regexHtmlTags = /(<([^>]+)>)/gi const regexHtmlTagsExceptP = /<\/?(?!p\b)[^>]*>/g product.description = product.description @@ -39,26 +43,26 @@ export async function getServerSideProps(context) { .replace(regexHtmlTags, ' ') .trim()*/ } else { - product = null + product = null; } return { - props: { product } - } + props: { product }, + }; } export default function ProductDetail({ product }) { - const router = useRouter() + const router = useRouter(); - const { setProduct } = useProductContext() + const { setProduct } = useProductContext(); useEffect(() => { if (product) { - setProduct(product) + setProduct(product); } - }, [product, setProduct]) + }, [product, setProduct]); - if (!product) return <PageNotFound /> + if (!product) return <PageNotFound />; return ( <BasicLayout> @@ -72,16 +76,16 @@ export default function ProductDetail({ product }) { url: product?.image, width: 800, height: 800, - alt: product?.name - } + alt: product?.name, + }, ], - type: 'product' + type: 'product', }} additionalMetaTags={[ { name: 'keywords', - content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}` - } + content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}`, + }, ]} /> {!product && ( @@ -91,5 +95,5 @@ export default function ProductDetail({ product }) { )} {product && <Product product={product} isVariant={true} />} </BasicLayout> - ) + ); } diff --git a/src/pages/shop/promo/[slug].tsx b/src/pages/shop/promo/[slug].tsx new file mode 100644 index 00000000..bd69c071 --- /dev/null +++ b/src/pages/shop/promo/[slug].tsx @@ -0,0 +1,523 @@ +import dynamic from 'next/dynamic' +import NextImage from 'next/image'; +import { useEffect, useState } from 'react' +import { useRouter } from 'next/router' +import Seo from '../../../core/components/Seo' +import Promocrumb from '../../../lib/promo/components/Promocrumb' +import { fetchPromoItemsSolr, fetchVariantSolr } from '../../../api/promoApi' +import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx' +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card' +import { IPromotion } from '../../../../src-migrate/types/promotion' +import React from 'react' +import { SolrResponse } from "../../../../src-migrate/types/solr.ts"; +import DesktopView from '../../../core/components/views/DesktopView'; +import MobileView from '../../../core/components/views/MobileView'; +import 'swiper/swiper-bundle.css'; +import useDevice from '../../../core/hooks/useDevice' +import ProductFilterDesktop from '../../../lib/product/components/ProductFilterDesktopPromotion'; +import ProductFilter from '../../../lib/product/components/ProductFilter'; +import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; +import { formatCurrency } from '../../../core/utils/formatValue'; +import Pagination from '../../../core/components/elements/Pagination/Pagination'; +import SideBanner from '../../../../src-migrate/modules/side-banner'; +import whatsappUrl from '../../../core/utils/whatsappUrl'; +import { cons, toQuery } from 'lodash-contrib'; +import _ from 'lodash'; +import useActive from '../../../core/hooks/useActive'; + +const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout')) + +export default function PromoDetail() { + const router = useRouter() + const { slug = '', brand ='', category='', priceFrom = '', priceTo = '', page = '1' } = router.query + const [promoItems, setPromoItems] = useState<any[]>([]) + const [promoData, setPromoData] = useState<IPromotion[] | null>(null) + const [currentPage, setCurrentPage] = useState(parseInt(page as string, 10) || 1); + const itemsPerPage = 12; // Jumlah item yang ingin ditampilkan per halaman + const [loading, setLoading] = useState(true); + const { isMobile, isDesktop } = useDevice() + const [brands, setBrands] = useState<Brand[]>([]); + const [categories, setCategories] = useState<Category[]>([]); + const [brandValues, setBrandValues] = useState<string[]>([]); + const [categoryValues, setCategoryValues] = useState<string[]>([]); + const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); + const popup = useActive(); + const prefixUrl = `/shop/promo/${slug}` + + useEffect(() => { + if (router.query.brand) { + let brandsArray: string[] = []; + if (Array.isArray(router.query.brand)) { + brandsArray = router.query.brand; + } else if (typeof router.query.brand === 'string') { + brandsArray = router.query.brand.split(',').map((brand) => brand.trim()); + } + setBrandValues(brandsArray); + } else { + setBrandValues([]); + } + + if (router.query.category) { + let categoriesArray: string[] = []; + + if (Array.isArray(router.query.category)) { + categoriesArray = router.query.category; + } else if (typeof router.query.category === 'string') { + categoriesArray = router.query.category.split(',').map((category) => category.trim()); + } + setCategoryValues(categoriesArray); + } else { + setCategoryValues([]); + } + }, [router.query.brand, router.query.category]); + + interface Brand { + brand: string; + qty: number; + } + + interface Category { + name: string; + qty: number; + } + + useEffect(() => { + const loadPromo = async () => { + setLoading(true); + const brandsData: Brand[] = []; + const categoriesData: Category[] = []; + + const pageNumber = Array.isArray(page) ? parseInt(page[0], 10) : parseInt(page, 10); + setCurrentPage(pageNumber) + + try { + const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`); + setPromoItems(items); + + if (items.length === 0) { + setPromoData([]) + setLoading(false); + return; + } + + const brandArray = Array.isArray(brand) ? brand : brand.split(','); + const categoryArray = Array.isArray(category) ? category : category.split(','); + + const promoDataPromises = items.map(async (item) => { + + try { + let brandQuery = ''; + if (brand) { + brandQuery = brandArray.map(b => `manufacture_name_s:${b}`).join(' OR '); + brandQuery = `(${brandQuery})`; + } + + let categoryQuery = ''; + if (category) { + categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); + categoryQuery = `(${categoryQuery})`; + } + + let priceQuery = ''; + if (priceFrom && priceTo) { + priceQuery = `price_f:[${priceFrom} TO ${priceTo}]`; + } else if (priceFrom) { + priceQuery = `price_f:[${priceFrom} TO *]`; + } else if (priceTo) { + priceQuery = `price_f:[* TO ${priceTo}]`; + } + + let combinedQuery = ''; + let combinedQueryPrice = `${priceQuery}`; + if (brand && category && priceFrom || priceTo) { + combinedQuery = `${brandQuery} AND ${categoryQuery} `; + } else if (brand && category) { + combinedQuery = `${brandQuery} AND ${categoryQuery}`; + } else if (brand && priceFrom || priceTo) { + combinedQuery = `${brandQuery}`; + } else if (category && priceFrom || priceTo) { + combinedQuery = `${categoryQuery}`; + } else if (brand) { + combinedQuery = brandQuery; + } else if (category) { + combinedQuery = categoryQuery; + } + + if (combinedQuery && priceFrom || priceTo) { + const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); + const product = response.response.docs[0]; + const product_id = product.id; + const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} AND ${combinedQueryPrice}`); + return response2; + }else if(combinedQuery){ + const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); + const product = response.response.docs[0]; + const product_id = product.id; + const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} `); + return response2; + } else { + const response = await fetchPromoItemsSolr(`id:${item.id}`); + return response; + } + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + + const dataBrandCategoryPromises = promoDataArray.map(async (promoData) => { + if (promoData) { + const dataBrandCategory = promoData.map(async (item) => { + let response; + if(category){ + const categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); + response = await fetchVariantSolr(`id:${item.products[0].product_id} AND (${categoryQuery})`); + }else{ + response = await fetchVariantSolr(`id:${item.products[0].product_id}`) + } + + + if (response.response?.docs?.length > 0) { + const product = response.response.docs[0]; + const manufactureNameS = product.manufacture_name; + if (Array.isArray(manufactureNameS)) { + for (let i = 0; i < manufactureNameS.length; i += 2) { + const brand = manufactureNameS[i]; + const qty = 1; + const existingBrandIndex = brandsData.findIndex(b => b.brand === brand); + if (existingBrandIndex !== -1) { + brandsData[existingBrandIndex].qty += qty; + } else { + brandsData.push({ brand, qty }); + } + } + } + + const categoryNameS = product.category_name; + if (Array.isArray(categoryNameS)) { + for (let i = 0; i < categoryNameS.length; i += 2) { + const name = categoryNameS[i]; + const qty = 1; + const existingCategoryIndex = categoriesData.findIndex(c => c.name === name); + if (existingCategoryIndex !== -1) { + categoriesData[existingCategoryIndex].qty += qty; + } else { + categoriesData.push({ name, qty }); + } + } + } + } + }); + + return Promise.all(dataBrandCategory); + } + }); + + await Promise.all(dataBrandCategoryPromises); + setBrands(brandsData); + setCategories(categoriesData); + setLoading(false); + + } catch (loadError) { + // console.error("Error loading promo items:", loadError) + setLoading(false); + } + } + + if (slug) { + loadPromo() + } + },[slug, brand, category, priceFrom, priceTo, currentPage]); + + + function capitalizeFirstLetter(string) { + string = string.replace(/_/g, ' '); + return string.replace(/(^\w|\s\w)/g, function(match) { + return match.toUpperCase(); + }); + } + + const handleDeleteFilter = async (source, value) => { + let params = { + q: router.query.q, + orderBy: '', + brand: brandValues.join(','), + category: categoryValues.join(','), + priceFrom: priceFrom || '', + priceTo: priceTo || '', + }; + + let brands = brandValues; + let catagories = categoryValues; + switch (source) { + case 'brands': + brands = brandValues.filter((item) => item !== value); + params.brand = brands.join(','); + await setBrandValues(brands); + break; + case 'category': + catagories = categoryValues.filter((item) => item !== value); + params.category = catagories.join(','); + await setCategoryValues(catagories); + break; + case 'price': + params.priceFrom = ''; + params.priceTo = ''; + break; + case 'delete': + params = { + q: router.query.q, + orderBy: '', + brand: '', + category: '', + priceFrom: '', + priceTo: '', + }; + break; + } + + handleSubmitFilter(params); + }; + const handleSubmitFilter = (params) => { + params = _.pickBy(params, _.identity); + params = toQuery(params); + router.push(`${slug}?${params}`); + }; + + const visiblePromotions = promoData?.slice( (currentPage-1) * itemsPerPage, currentPage * 12) + + const toQuery = (obj) => { + const str = Object.keys(obj) + .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`) + .join('&') + return str + } + + const whatPromo = capitalizeFirstLetter(slug) + const queryWithoutSlug = _.omit(router.query, ['slug']) + const queryString = toQuery(queryWithoutSlug) + + return ( + <BasicLayout> + <Seo + title={`Promo ${Array.isArray(slug) ? slug[0] : slug} Terkini`} + description='B2B Marketplace MRO & Industri dengan Layanan Pembayaran Tempo, Faktur Pajak, Online Quotation, Garansi Resmi & Harga Kompetitif' + /> + <Promocrumb brandName={whatPromo} /> + <MobileView> + <div className='p-4 pt-0'> + <h1 className='mb-2 font-semibold text-h-sm'>Promo {whatPromo}</h1> + + <FilterChoicesComponent + brandValues={brandValues} + categoryValues={categoryValues} + priceFrom={priceFrom} + priceTo={priceTo} + handleDeleteFilter={handleDeleteFilter} + /> + {promoItems.length >= 1 && ( + <div className='flex items-center gap-x-2 mb-5 justify-between'> + <div> + <button + className='btn-light py-2 px-5 h-[40px]' + onClick={popup.activate} + > + Filter + </button> + </div> + </div> + )} + + {loading ? ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + ) : promoData && promoItems.length >= 1 ? ( + <> + <div className='grid grid-cols-1 gap-x-1 gap-y-1'> + {visiblePromotions?.map((promotion) => ( + <div key={promotion.id} className="min-w-36 max-w-[400px] mb-[20px] sm:w-full md:w-1/2 lg:w-1/3 xl:w-1/4 "> + <ProductPromoCard promotion={promotion}/> + </div> + ))} + </div> + </> + ) : ( + <div className="text-center my-8"> + <p>Belum ada promo pada kategori ini</p> + </div> + )} + + <Pagination + pageCount={Math.ceil((promoData?.length ?? 0) / itemsPerPage)} + currentPage={currentPage} + url={`${prefixUrl}?${toQuery(_.omit(queryWithoutSlug, ['page']))}`} + className='mt-6 mb-2' + /> + <ProductFilter + active={popup.active} + close={popup.deactivate} + brands={brands || []} + categories={categories || []} + prefixUrl={router.asPath.includes('?') ? `${router.asPath}` : `${router.asPath}?`} + defaultBrand={null} + /> + </div> + + </MobileView> + <DesktopView> + <div className='container mx-auto flex mb-3 flex-col'> + <div className='w-full pl-6'> + <h1 className='text-2xl mb-2 font-semibold'>Promo {whatPromo}</h1> + <div className=' w-full h-full flex flex-row items-center '> + + <div className='detail-filter w-1/2 flex justify-start items-center mt-4'> + + <FilterChoicesComponent + brandValues={brandValues} + categoryValues={categoryValues} + priceFrom={priceFrom} + priceTo={priceTo} + handleDeleteFilter={handleDeleteFilter} + /> + </div> + <div className='Filter w-1/2 flex flex-col'> + + <ProductFilterDesktop + brands={brands || []} + categories={categories || []} + prefixUrl={'/shop/promo'} + // defaultBrand={null} + /> + </div> + </div> + {loading ? ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + ) : promoData && promoItems.length >= 1 ? ( + <> + <div className='grid grid-cols-1 gap-x-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3'> + {visiblePromotions?.map((promotion) => ( + <div key={promotion.id} className="min-w-[400px] max-w-[400px] mb-[20px] sm:min-w-[350px] md:min-w-[380px] lg:min-w-[400px] xl:min-w-[400px] "> + <ProductPromoCard promotion={promotion}/> + </div> + ))} + </div> + </> + ) : ( + <div className="text-center my-8"> + <p>Belum ada promo pada kategori ini</p> + </div> + )} + <div className='flex justify-between items-center mt-6 mb-2'> + <div className='pt-2 pb-6 flex items-center gap-x-3'> + <NextImage + src='/images/logo-question.png' + alt='Logo Question Indoteknik' + width={60} + height={60} + /> + <div className='text-gray_r-12/90'> + <span> + Barang yang anda cari tidak ada?{' '} + <a + href={ + router.query?.q + ? whatsappUrl('productSearch', { + name: router.query.q, + }) + : whatsappUrl() + } + className='text-danger-500' + > + Hubungi Kami + </a> + </span> + </div> + </div> + + + + <Pagination + pageCount={Math.ceil((promoData?.length ?? 0) / itemsPerPage)} + currentPage={currentPage} + url={`${prefixUrl}?${toQuery(_.omit(queryWithoutSlug, ['page']))}`} + className='mt-6 mb-2' + /> + </div> + + </div> + </div> + </DesktopView> + </BasicLayout> + ) + } + +const FilterChoicesComponent = ({ + brandValues, + categoryValues, + priceFrom, + priceTo, + handleDeleteFilter, + }) => ( + <div className='flex items-center mb-4'> + <HStack spacing={2} className='flex-wrap'> + {brandValues?.map((value, index) => ( + <Tag + size='lg' + key={index} + borderRadius='lg' + variant='outline' + colorScheme='gray' + > + <TagLabel>{value}</TagLabel> + <TagCloseButton onClick={() => handleDeleteFilter('brands', value)} /> + </Tag> + ))} + + {categoryValues?.map((value, index) => ( + <Tag + size='lg' + key={index} + borderRadius='lg' + variant='outline' + colorScheme='gray' + > + <TagLabel>{value}</TagLabel> + <TagCloseButton + onClick={() => handleDeleteFilter('category', value)} + /> + </Tag> + ))} + {priceFrom && priceTo && ( + <Tag size='lg' borderRadius='lg' variant='outline' colorScheme='gray'> + <TagLabel> + {formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)} + </TagLabel> + <TagCloseButton + onClick={() => handleDeleteFilter('price', priceFrom)} + /> + </Tag> + )} + {brandValues?.length > 0 || + categoryValues?.length > 0 || + priceFrom || + priceTo ? ( + <span> + <button + className='btn-transparent py-2 px-5 h-[40px] text-red-700' + onClick={() => handleDeleteFilter('delete')} + > + Hapus Semua + </button> + </span> + ) : ( + '' + )} + </HStack> + </div> +); diff --git a/src/pages/shop/promo/index.tsx b/src/pages/shop/promo/index.tsx new file mode 100644 index 00000000..7ec4f6b0 --- /dev/null +++ b/src/pages/shop/promo/index.tsx @@ -0,0 +1,186 @@ +import dynamic from 'next/dynamic' +import { useEffect, useState } from 'react' +import { useRouter } from 'next/router' +import Seo from '../../../core/components/Seo.jsx' +import Promocrumb from '../../../lib/promo/components/Promocrumb.jsx' +import { fetchPromoItemsSolr } from '../../../api/promoApi.js' +import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx' +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card.tsx' +import { IPromotion } from '../../../../src-migrate/types/promotion.ts' +import React from 'react' +import { SolrResponse } from "../../../../src-migrate/types/solr.ts"; + +const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout.jsx')) + +export default function Promo() { + const router = useRouter() + const { slug = '' } = router.query + const [promoItems, setPromoItems] = useState<any[]>([]) + const [promoData, setPromoData] = useState<IPromotion[] | null>(null) + const [loading, setLoading] = useState(true) + const [currentPage, setCurrentPage] = useState(1) + const [fetchingData, setFetchingData] = useState(false) + + useEffect(() => { + const loadPromo = async () => { + try { + const items = await fetchPromoItemsSolr(`*:*`) + + + setPromoItems(items) + + + if (items.length === 0) { + setPromoData([]) + setLoading(false); + return; + } + + const promoDataPromises = items.map(async (item) => { + const queryParams = new URLSearchParams({ q: `id:${item.id}` }) + + + try { + const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}`) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data: SolrResponse<any[]> = await response.json() + + + const promotions = await map(data.response.docs) + return promotions; + } catch (fetchError) { + console.error("Error fetching promotion data:", fetchError) + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + setTimeout(() => setLoading(false), 120); // Menambahkan delay 200ms sebelum mengubah status loading + } catch (loadError) { + console.error("Error loading promo items:", loadError) + setLoading(false); + } + } + + if (slug) { + loadPromo() + } + }, [slug]) + + const map = async (promotions: any[]): Promise<IPromotion[]> => { + const result: IPromotion[] = [] + + for (const promotion of promotions) { + const data: IPromotion = { + id: promotion.id, + program_id: promotion.program_id_i, + name: promotion.name_s, + type: { + value: promotion.type_value_s, + label: promotion.type_label_s, + }, + limit: promotion.package_limit_i, + limit_user: promotion.package_limit_user_i, + limit_trx: promotion.package_limit_trx_i, + price: promotion.price_f, + total_qty: promotion.total_qty_i, + products: JSON.parse(promotion.products_s), + free_products: JSON.parse(promotion.free_products_s), + } + + result.push(data) + } + + return result + } + + + + + useEffect(() => { + const handleScroll = () => { + if ( + !fetchingData && + window.innerHeight + document.documentElement.scrollTop >= 0.95 * document.documentElement.offsetHeight + ) { + // User has scrolled to 95% of page height + + setTimeout(() => setFetchingData(true), 120); + setCurrentPage((prevPage) => prevPage + 1) + } + } + + window.addEventListener('scroll', handleScroll) + return () => window.removeEventListener('scroll', handleScroll) + }, [fetchingData]) + + useEffect(() => { + if (fetchingData) { + // Fetch more data + // You may need to adjust this logic according to your API + fetchMoreData() + } + }, [fetchingData]) + + const fetchMoreData = async () => { + try { + // Add a delay of approximately 150ms + setTimeout(async () => { + // Fetch more data + // Update promoData state with the new data + }, 150) + } catch (error) { + console.error('Error fetching more data:', error) + } finally { + setTimeout(() => setFetchingData(false), 120); + + } + } + + const visiblePromotions = promoData?.slice(0, currentPage * 12) + + return ( + <BasicLayout> + <Seo + title={`Promo ${Array.isArray(slug) ? slug[0] : slug} Terkini`} + description='B2B Marketplace MRO & Industri dengan Layanan Pembayaran Tempo, Faktur Pajak, Online Quotation, Garansi Resmi & Harga Kompetitif' + /> + {/* <Promocrumb brandName={capitalizeFirstLetter(Array.isArray(slug) ? slug[0] : slug)} /> */} + <div className='container mx-auto mt-1 flex mb-1'> + <div className=''> + <h1 className='font-semibold'>Semua Promo di Indoteknik</h1> + </div> + </div> + {loading ? ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + ) : promoData && promoItems.length >= 1 ? ( + <> + <div className='flex flex-wrap justify-center'> + {visiblePromotions?.map((promotion) => ( + <div key={promotion.id} className="min-w-[40px] max-w-[400px] mr-[20px] mb-[20px] sm:w-full md:w-1/2 lg:w-1/3 xl:w-1/4"> + <ProductPromoCard promotion={promotion} /> + </div> + ))} + </div> + {fetchingData && ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + )} + </> + ) : ( + <div className="text-center my-8"> + <p>Belum ada promo pada kategori ini</p> + </div> + )} + </BasicLayout> + ) +} diff --git a/src/pages/video.jsx b/src/pages/video.jsx index 61790dbb..7d1f8372 100644 --- a/src/pages/video.jsx +++ b/src/pages/video.jsx @@ -44,7 +44,7 @@ export default function Video() { </LazyLoadComponent> <div className='p-3'> <a - href='https://www.youtube.com/@indoteknikb2bindustriale-c778' + href='https://www.youtube.com/@indoteknikcom' className='text-danger-500 mb-2 block' > {video.channelName} diff --git a/src/styles/globals.css b/src/styles/globals.css index bf9fec10..f6561b00 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -107,7 +107,7 @@ button { disabled:bg-gray_r-5; } - .form-input[aria-invalid="true"] { + .form-input[aria-invalid='true'] { @apply border-danger-500 focus:border-danger-500; } @@ -676,3 +676,21 @@ button { @apply text-warning-500; } } + +::-webkit-scrollbar { + width: 12px; +} + +::-webkit-scrollbar-track { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: #888; + border-radius: 6px; + border: 3px solid #f5f5f5; +} + +::-webkit-scrollbar-thumb:hover { + background-color: #555; +} diff --git a/src/styles/normalize.css b/src/styles/normalize.css new file mode 100644 index 00000000..92aed47e --- /dev/null +++ b/src/styles/normalize.css @@ -0,0 +1,351 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { + /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { + /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type='button']::-moz-focus-inner, +[type='reset']::-moz-focus-inner, +[type='submit']::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type='button']:-moz-focusring, +[type='reset']:-moz-focusring, +[type='submit']:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type='checkbox'], +[type='radio'] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type='number']::-webkit-inner-spin-button, +[type='number']::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js index 41d24b53..dd90ac7d 100644 --- a/src/utils/solrMapping.js +++ b/src/utils/solrMapping.js @@ -1,17 +1,18 @@ export const productMappingSolr = (products, pricelist) => { return products.map((product) => { - let price = product.price_tier1_v2_f || 0 - let priceDiscount = 0 - let discountPercentage = 0 + let price = product.price_tier1_v2_f || 0; + let priceDiscount = price; + let discountPercentage = 0; if (pricelist && product?.[`price_${pricelist}_f`] < price) { - price = product?.[`price_${pricelist}_f`] || 0 + price = product?.[`price_${pricelist}_f`] || 0; + priceDiscount = price; } - if (product?.flashsale_id_i > 0 ) { - price = product?.flashsale_base_price_f || 0 - priceDiscount = product?.flashsale_price_f || 0 - discountPercentage = product?.flashsale_discount_f || 0 + if (product?.flashsale_id_i > 0) { + price = product?.flashsale_base_price_f || 0; + priceDiscount = product?.flashsale_price_f || 0; + discountPercentage = product?.flashsale_discount_f || 0; } let productMapped = { @@ -29,48 +30,50 @@ export const productMappingSolr = (products, pricelist) => { categories: [], flashSale: { id: product?.flashsale_id_i, - remainingTime: flashsaleTime(product?.flashsale_end_date_s)?.remainingTime, + remainingTime: flashsaleTime(product?.flashsale_end_date_s) + ?.remainingTime, name: product?.product?.flashsale_name_s, - tag: product?.flashsale_tag_s || 'FLASH SALE' + tag: product?.flashsale_tag_s || 'FLASH SALE', }, - qtySold : product?.qty_sold_f || 0 - } + qtySold: product?.qty_sold_f || 0, + isTkdn:product?.tkdn_b || false, + isSni:product?.sni_b || false, + }; if (product.manufacture_id_i && product.manufacture_name_s) { productMapped.manufacture = { id: product.manufacture_id_i || '', name: product.manufacture_name_s || '', imagePromotion1: product.image_promotion_1_s || '', - imagePromotion2: product.image_promotion_2_s || '' - } + imagePromotion2: product.image_promotion_2_s || '', + }; } productMapped.categories = [ { id: product.category_id_i || '', - name: product.category_name_s || '' - } - ] - return productMapped - }) -} + name: product.category_name_s || '', + }, + ]; + return productMapped; + }); +}; export const variantsMappingSolr = (parent, products, pricelist) => { return products.map((product) => { - let price = product.price_tier1_v2_f || 0 - let priceDiscount = 0 - let discountPercentage = 0 + let price = product.price_tier1_v2_f || 0; + let priceDiscount = price; + let discountPercentage = 0; - if (pricelist) { - if (product?.[`price_${pricelist}_f`] < price) { - price = product?.[`price_${pricelist}_f`] || 0 - } + if (pricelist && product?.[`price_${pricelist}_f`] < price) { + price = product?.[`price_${pricelist}_f`] || 0; + priceDiscount = price; } if (product?.flashsale_id_i > 0 && product?.flashsale_price_f < price) { - price = product?.flashsale_base_price_f || 0 - priceDiscount = product?.flashsale_price_f || 0 - discountPercentage = product?.flashsale_discount_f || 0 + price = product?.flashsale_base_price_f || 0; + priceDiscount = product?.flashsale_price_f || 0; + discountPercentage = product?.flashsale_discount_f || 0; } let productMapped = { @@ -87,30 +90,34 @@ export const variantsMappingSolr = (parent, products, pricelist) => { weight: product.weight_f || 0, manufacture: {}, parent: {}, - qtySold : product?.qty_sold_f || 0 - } + qtySold: product?.qty_sold_f || 0, + }; if (product.manufacture_id_i && product.manufacture_name_s) { productMapped.manufacture = { id: product.manufacture_id_i || '', - name: product.manufacture_name_s || '' - } + name: product.manufacture_name_s || '', + }; } productMapped.parent = { - id: parent.product_id_i || '', - image: parent.image_s || '', - name: parent.name_s || '' - } - return productMapped - }) -} + id: parent[0]?.product_id_i || '', + image: parent[0]?.image_s || '', + name: parent[0]?.name_s || '', + description: parent[0]?.description_t || '', + }; + return productMapped; + }); +}; const flashsaleTime = (endDate) => { - const flashsaleEndDate = new Date(endDate) - const currentTime = new Date() + const flashsaleEndDate = new Date(endDate); + const currentTime = new Date(); - const timeDifferenceInMillis = flashsaleEndDate - currentTime - const timeDifferenceInSeconds = timeDifferenceInMillis / 1000 + const timeDifferenceInMillis = flashsaleEndDate - currentTime; + const timeDifferenceInSeconds = timeDifferenceInMillis / 1000; - return { remainingTime: timeDifferenceInSeconds, isFlashSale: flashsaleEndDate > currentTime } -} + return { + remainingTime: timeDifferenceInSeconds, + isFlashSale: flashsaleEndDate > currentTime, + }; +}; diff --git a/tsconfig.json b/tsconfig.json index b2e205a3..8613c022 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,8 +32,9 @@ "next-env.d.ts", "**/*.ts", "**/*.tsx", + "**/*.jsx", ".next/types/**/*.ts" - ], +, "src/pages/shop/promo/index.tsx", "src/pages/shop/promo/[slug].jsx" ], "exclude": [ "node_modules", "src" |
