casper's Profile Image

Full Stack Web/Mobile Developer

Jan, 18, 2025

Next Js Tutorial #9 - Ecommerce App - Cart Page

We created cart page and cart components.

Next Js Tutorial #9 - Ecommerce App - Cart Page Image

You can also watch the YouTube video:

Next Js Tutorial #9 | Ecommerce App - Cart Page

Installing Required Dependencies

yarn add zustand

Installing Required ShadCN UI Components

npx shadcn@latest add scroll-area separator

Create useCart.js in hooks folder:

import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";

export const useCart = create()(
  persist(
    (set) => ({
      items: [],
      addItem: (product) => {
        set((state) => {
          const isAddedBefore = state.items.find(
            (item) => item.product.id === product.id
          );

          if (isAddedBefore) {
            const index = state.items.findIndex(
              (item) => item.product.id === isAddedBefore.product.id
            );

            state.items[index] = {
              product: isAddedBefore.product,
              quantity: isAddedBefore.quantity + 1,
            };

            return {
              items: [...state.items],
            };
          } else {
            return { items: [...state.items, { product, quantity: 1 }] };
          }
        });
      },
      removeItem: (id) =>
        set((state) => ({
          items: state.items.filter((item) => item.product.id !== id),
        })),
      increaseQuantity: (id) => {
        set((state) => {
          const cartItem = state.items.find((item) => item.product.id === id);

          if (cartItem) {
            const index = state.items.findIndex(
              (item) => item.product.id === cartItem.product.id
            );

            state.items[index] = {
              product: cartItem.product,
              quantity: cartItem.quantity + 1,
            };
          }

          return { items: [...state.items] };
        });
      },
      decreaseQuantity: (id) => {
        set((state) => {
          const cartItem = state.items.find((item) => item.product.id === id);

          if (cartItem) {
            const index = state.items.findIndex(
              (item) => item.product.id === cartItem.product.id
            );

            if (cartItem.quantity > 1) {
              state.items[index] = {
                product: cartItem.product,
                quantity: cartItem.quantity - 1,
              };
            } else {
              state.items.splice(index, 1);
            }
          }

          return { items: [...state.items] };
        });
      },
      clearCart: () => set({ items: [] }),
    }),
    {
      name: "cart-storage",
      storage: createJSONStorage(() => localStorage),
    }
  )
);

We'll need empty cart image so you can find it on internet or you can use the image down below:

Create empty-cart.svg in public folder:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="450px" height="450px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
<g><path style="opacity:0.01" fill="#f1763c" d="M 68.5,46.5 C 68.369,45.7611 68.5357,45.0944 69,44.5C 69.6917,45.4368 69.525,46.1034 68.5,46.5 Z"/></g>
<g><path style="opacity:0.677" fill="#f4773d" d="M 68.5,46.5 C 68.7329,49.5418 69.7329,52.2084 71.5,54.5C 71.2627,55.791 71.596,56.791 72.5,57.5C 73.2635,61.1368 74.5968,64.4701 76.5,67.5C 76.6085,69.5138 75.9418,71.1805 74.5,72.5C 73.8333,72.5 73.1667,72.5 72.5,72.5C 71.134,69.768 69.8007,67.1013 68.5,64.5C 68.2041,62.597 67.5375,60.9303 66.5,59.5C 66.0198,56.5568 65.0198,53.8902 63.5,51.5C 63.5979,49.4471 62.9313,47.7804 61.5,46.5C 63.7937,42.6525 66.127,42.6525 68.5,46.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1763b" d="M 61.5,46.5 C 61.631,47.2389 61.4643,47.9056 61,48.5C 60.3083,47.5632 60.475,46.8966 61.5,46.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 62.5,51.5 C 61.475,51.1034 61.3083,50.4368 62,49.5C 62.4643,50.0944 62.631,50.7611 62.5,51.5 Z"/></g>
<g><path style="opacity:0.011" fill="#dfe8f8" d="M 211.5,51.5 C 220.324,50.3427 229.324,50.176 238.5,51C 229.506,51.4998 220.506,51.6664 211.5,51.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1753b" d="M 23.5,51.5 C 24.8333,52.1667 24.8333,52.1667 23.5,51.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f0753b" d="M 62.5,51.5 C 62.8333,51.5 63.1667,51.5 63.5,51.5C 63.1667,54.1667 62.8333,54.1667 62.5,51.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 201.5,52.5 C 203.966,51.3659 206.633,51.1993 209.5,52C 206.854,52.4974 204.187,52.6641 201.5,52.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 239.5,52.5 C 241.966,51.3659 244.633,51.1993 247.5,52C 244.854,52.4974 242.187,52.6641 239.5,52.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f1753c" d="M 51.5,80.5 C 51.5,79.8333 51.1667,79.5 50.5,79.5C 50.5,78.8333 50.1667,78.5 49.5,78.5C 49.5,77.8333 49.1667,77.5 48.5,77.5C 48.5,76.8333 48.1667,76.5 47.5,76.5C 47.5,75.8333 47.1667,75.5 46.5,75.5C 46.5,74.8333 46.1667,74.5 45.5,74.5C 45.5,73.8333 45.1667,73.5 44.5,73.5C 44.5,72.8333 44.1667,72.5 43.5,72.5C 43.5,71.8333 43.1667,71.5 42.5,71.5C 42.5,70.8333 42.1667,70.5 41.5,70.5C 41.5,69.8333 41.1667,69.5 40.5,69.5C 40.5,68.8333 40.1667,68.5 39.5,68.5C 39.5,67.8333 39.1667,67.5 38.5,67.5C 38.5,66.8333 38.1667,66.5 37.5,66.5C 37.5,65.8333 37.1667,65.5 36.5,65.5C 36.5,64.8333 36.1667,64.5 35.5,64.5C 35.5,63.8333 35.1667,63.5 34.5,63.5C 34.5,62.8333 34.1667,62.5 33.5,62.5C 33.5,61.8333 33.1667,61.5 32.5,61.5C 32.5,60.8333 32.1667,60.5 31.5,60.5C 31.5,59.8333 31.1667,59.5 30.5,59.5C 30.5,58.8333 30.1667,58.5 29.5,58.5C 29.5,57.8333 29.1667,57.5 28.5,57.5C 28.5,56.8333 28.1667,56.5 27.5,56.5C 27.5,55.8333 27.1667,55.5 26.5,55.5C 26.5,54.8333 26.1667,54.5 25.5,54.5C 25.369,53.7611 25.5357,53.0944 26,52.5C 35.1667,61.6667 44.3333,70.8333 53.5,80C 52.9056,80.4643 52.2389,80.631 51.5,80.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f2763c" d="M 71.5,54.5 C 71.369,53.7611 71.5357,53.0944 72,52.5C 72.6917,53.4368 72.525,54.1034 71.5,54.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 195.5,53.5 C 196.946,52.3871 198.613,52.2204 200.5,53C 198.866,53.4935 197.199,53.6602 195.5,53.5 Z"/></g>
<g><path style="opacity:0.993" fill="#dfe8f8" d="M 239.5,52.5 C 242.287,53.4767 245.287,53.81 248.5,53.5C 252.267,54.7947 256.267,55.4613 260.5,55.5C 262.905,56.7682 265.572,57.4349 268.5,57.5C 273.617,59.537 278.95,61.2036 284.5,62.5C 285.78,63.9313 287.447,64.5979 289.5,64.5C 297.461,68.4806 305.461,72.4806 313.5,76.5C 316.291,78.7349 319.291,80.7349 322.5,82.5C 336.757,92.7557 349.424,104.756 360.5,118.5C 360.5,118.833 360.5,119.167 360.5,119.5C 354.824,119.334 349.157,119.501 343.5,120C 339.42,122.312 336.92,125.812 336,130.5C 334.402,136.091 333.235,141.758 332.5,147.5C 328.756,148.761 324.756,149.428 320.5,149.5C 272.835,146.304 225.168,143.304 177.5,140.5C 175.052,139.527 172.385,139.194 169.5,139.5C 170.571,111.292 158.571,90.9583 133.5,78.5C 134.167,78.5 134.5,78.1667 134.5,77.5C 138.173,75.9998 141.506,73.9998 144.5,71.5C 145.492,71.6716 146.158,71.3382 146.5,70.5C 147.492,70.6716 148.158,70.3382 148.5,69.5C 149.492,69.6716 150.158,69.3382 150.5,68.5C 154.787,67.3517 158.787,65.685 162.5,63.5C 164.553,63.5979 166.22,62.9313 167.5,61.5C 168.791,61.7373 169.791,61.404 170.5,60.5C 171.791,60.7373 172.791,60.404 173.5,59.5C 195.118,53.8018 217.118,51.4685 239.5,52.5 Z"/></g>
<g><path style="opacity:0.009" fill="#e0e8f8" d="M 248.5,53.5 C 250.288,52.3775 252.288,52.2109 254.5,53C 252.527,53.4955 250.527,53.6621 248.5,53.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 255.5,54.5 C 256.601,53.4017 257.934,53.235 259.5,54C 258.207,54.49 256.873,54.6567 255.5,54.5 Z"/></g>
<g><path style="opacity:0.397" fill="#f5773d" d="M 23.5,52.5 C 23.8333,53.5 24.5,54.1667 25.5,54.5C 26.1667,54.5 26.5,54.8333 26.5,55.5C 27.1667,55.5 27.5,55.8333 27.5,56.5C 28.1667,56.5 28.5,56.8333 28.5,57.5C 29.1667,57.5 29.5,57.8333 29.5,58.5C 30.1667,58.5 30.5,58.8333 30.5,59.5C 31.1667,59.5 31.5,59.8333 31.5,60.5C 32.1667,60.5 32.5,60.8333 32.5,61.5C 33.1667,61.5 33.5,61.8333 33.5,62.5C 34.1667,62.5 34.5,62.8333 34.5,63.5C 35.1667,63.5 35.5,63.8333 35.5,64.5C 36.1667,64.5 36.5,64.8333 36.5,65.5C 37.1667,65.5 37.5,65.8333 37.5,66.5C 38.1667,66.5 38.5,66.8333 38.5,67.5C 39.1667,67.5 39.5,67.8333 39.5,68.5C 40.1667,68.5 40.5,68.8333 40.5,69.5C 41.1667,69.5 41.5,69.8333 41.5,70.5C 42.1667,70.5 42.5,70.8333 42.5,71.5C 43.1667,71.5 43.5,71.8333 43.5,72.5C 44.1667,72.5 44.5,72.8333 44.5,73.5C 45.1667,73.5 45.5,73.8333 45.5,74.5C 46.1667,74.5 46.5,74.8333 46.5,75.5C 47.1667,75.5 47.5,75.8333 47.5,76.5C 48.1667,76.5 48.5,76.8333 48.5,77.5C 49.1667,77.5 49.5,77.8333 49.5,78.5C 50.1667,78.5 50.5,78.8333 50.5,79.5C 51.1667,79.5 51.5,79.8333 51.5,80.5C 51.8333,81.5 52.5,82.1667 53.5,82.5C 53.2671,84.0618 52.6005,85.3951 51.5,86.5C 40.5869,77.0906 30.0869,67.0906 20,56.5C 19.8319,54.1589 20.9986,52.8256 23.5,52.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 260.5,55.5 C 261.251,54.4265 262.251,54.2599 263.5,55C 262.552,55.4828 261.552,55.6495 260.5,55.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f2753d" d="M 73.5,57.5 C 73.1667,57.5 72.8333,57.5 72.5,57.5C 72.8333,54.8333 73.1667,54.8333 73.5,57.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 181.5,56.5 C 182.251,55.4265 183.251,55.2599 184.5,56C 183.552,56.4828 182.552,56.6495 181.5,56.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 268.5,57.5 C 269.251,56.4265 270.251,56.2599 271.5,57C 270.552,57.4828 269.552,57.6495 268.5,57.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1763c" d="M 73.5,57.5 C 74.525,57.8966 74.6917,58.5632 74,59.5C 73.5357,58.9056 73.369,58.2389 73.5,57.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e9f8" d="M 173.5,59.5 C 172.761,59.631 172.094,59.4643 171.5,59C 172.437,58.3083 173.103,58.475 173.5,59.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f2763c" d="M 66.5,59.5 C 66.631,60.2389 66.4643,60.9056 66,61.5C 65.3083,60.5632 65.475,59.8966 66.5,59.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dee9f7" d="M 170.5,60.5 C 169.761,60.631 169.094,60.4643 168.5,60C 169.437,59.3083 170.103,59.475 170.5,60.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f9" d="M 167.5,61.5 C 166.761,61.631 166.094,61.4643 165.5,61C 166.437,60.3083 167.103,60.475 167.5,61.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f7" d="M 162.5,62.5 C 162.897,61.475 163.563,61.3083 164.5,62C 163.906,62.4643 163.239,62.631 162.5,62.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 284.5,62.5 C 284.897,61.475 285.563,61.3083 286.5,62C 285.906,62.4643 285.239,62.631 284.5,62.5 Z"/></g>
<g><path style="opacity:0.012" fill="#e0e9f8" d="M 162.5,62.5 C 162.5,62.8333 162.5,63.1667 162.5,63.5C 159.833,63.1667 159.833,62.8333 162.5,62.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 289.5,63.5 C 288.761,63.631 288.094,63.4643 287.5,63C 288.437,62.3083 289.103,62.475 289.5,63.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 157.5,64.5 C 157.897,63.475 158.563,63.3083 159.5,64C 158.906,64.4643 158.239,64.631 157.5,64.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 289.5,64.5 C 289.5,64.1667 289.5,63.8333 289.5,63.5C 292.167,63.8333 292.167,64.1667 289.5,64.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f2763c" d="M 68.5,64.5 C 68.631,65.2389 68.4643,65.9056 68,66.5C 67.3083,65.5632 67.475,64.8966 68.5,64.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dee9f8" d="M 292.5,64.5 C 293.833,65.1667 293.833,65.1667 292.5,64.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1753b" d="M 76.5,67.5 C 76.369,66.7611 76.5357,66.0944 77,65.5C 77.6917,66.4368 77.525,67.1034 76.5,67.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 151.5,66.5 C 152.833,67.1667 152.833,67.1667 151.5,66.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 150.5,68.5 C 149.833,67.1667 149.833,67.1667 150.5,68.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f2753c" d="M 77.5,68.5 C 78.525,68.8966 78.6917,69.5632 78,70.5C 77.5357,69.9056 77.369,69.2389 77.5,68.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f7" d="M 148.5,69.5 C 147.833,68.1667 147.833,68.1667 148.5,69.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f7" d="M 146.5,70.5 C 145.833,69.1667 145.833,69.1667 146.5,70.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 144.5,71.5 C 143.833,70.1667 143.833,70.1667 144.5,71.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dee9f8" d="M 141.5,71.5 C 142.833,72.1667 142.833,72.1667 141.5,71.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 72.5,72.5 C 71.8333,73.1667 71.8333,73.1667 72.5,72.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 74.5,72.5 C 75.8333,73.1667 75.8333,73.1667 74.5,72.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1753c" d="M 101.5,73.5 C 107.653,72.3467 113.986,72.18 120.5,73C 114.175,73.4995 107.842,73.6662 101.5,73.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f1763b" d="M 74.5,73.5 C 73.8333,74.1667 73.8333,74.1667 74.5,73.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 96.5,74.5 C 97.6009,73.4017 98.9343,73.235 100.5,74C 99.2068,74.49 97.8734,74.6567 96.5,74.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 125.5,74.5 C 124.127,74.6567 122.793,74.49 121.5,74C 123.066,73.235 124.399,73.4017 125.5,74.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 96.5,74.5 C 96.5,74.8333 96.5,75.1667 96.5,75.5C 92.5,75.1667 92.5,74.8333 96.5,74.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 125.5,75.5 C 125.5,75.1667 125.5,74.8333 125.5,74.5C 129.5,74.8333 129.5,75.1667 125.5,75.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f2753d" d="M 92.5,76.5 C 91.7611,76.631 91.0944,76.4643 90.5,76C 91.4368,75.3083 92.1034,75.475 92.5,76.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1763c" d="M 129.5,76.5 C 129.897,75.475 130.563,75.3083 131.5,76C 130.906,76.4643 130.239,76.631 129.5,76.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe8f7" d="M 134.5,75.5 C 135.833,76.1667 135.833,76.1667 134.5,75.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 313.5,75.5 C 314.833,76.1667 314.833,76.1667 313.5,75.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 87.5,77.5 C 87.8966,76.475 88.5632,76.3083 89.5,77C 88.9056,77.4643 88.2389,77.631 87.5,77.5 Z"/></g>
<g><path style="opacity:0.994" fill="#f2763d" d="M 125.5,75.5 C 126.568,76.4345 127.901,76.7678 129.5,76.5C 130.514,77.6737 131.847,78.3404 133.5,78.5C 158.571,90.9583 170.571,111.292 169.5,139.5C 165.315,165.532 150.649,182.532 125.5,190.5C 99.8297,195.28 78.8297,187.613 62.5,167.5C 61.4884,166.128 60.4884,164.795 59.5,163.5C 51.8466,148.912 49.8466,133.578 53.5,117.5C 54.7384,115.786 55.405,113.786 55.5,111.5C 59.4604,103.1 64.7938,95.6002 71.5,89C 77.9349,83.7866 84.9349,79.6199 92.5,76.5C 94.099,76.7678 95.4324,76.4345 96.5,75.5C 106.167,74.1667 115.833,74.1667 125.5,75.5 Z"/></g>
<g><path style="opacity:0.012" fill="#ee9e7e" d="M 134.5,76.5 C 134.5,76.8333 134.5,77.1667 134.5,77.5C 131.833,77.1667 131.833,76.8333 134.5,76.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 315.5,76.5 C 316.833,77.1667 316.833,77.1667 315.5,76.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 54.5,82.5 C 53.8333,81.1667 53.8333,81.1667 54.5,82.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1763c" d="M 78.5,81.5 C 79.8333,82.1667 79.8333,82.1667 78.5,81.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dee9f7" d="M 322.5,81.5 C 323.833,82.1667 323.833,82.1667 322.5,81.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 54.5,82.5 C 55.525,82.8966 55.6917,83.5632 55,84.5C 54.5357,83.9056 54.369,83.2389 54.5,82.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 324.5,82.5 C 325.833,83.1667 325.833,83.1667 324.5,82.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f1763c" d="M 51.5,86.5 C 52.8333,87.1667 52.8333,87.1667 51.5,86.5 Z"/></g>
<g><path style="opacity:0.006" fill="#f1763c" d="M 51.5,87.5 C 51.1034,88.525 50.4368,88.6917 49.5,88C 50.0944,87.5357 50.7611,87.369 51.5,87.5 Z"/></g>
<g><path style="opacity:0.626" fill="#f4773d" d="M 16.5,94.5 C 21.8785,96.5932 27.5451,97.9265 33.5,98.5C 34.5676,99.4345 35.901,99.7678 37.5,99.5C 40.6057,99.7884 42.6057,101.455 43.5,104.5C 42.5,104.833 41.8333,105.5 41.5,106.5C 40.5,106.5 39.5,106.5 38.5,106.5C 37.4324,105.566 36.099,105.232 34.5,105.5C 33.4324,104.566 32.099,104.232 30.5,104.5C 23.3533,102.211 16.0199,100.211 8.5,98.5C 8.28649,96.8561 8.61983,95.3561 9.5,94C 11.7972,93.9822 14.1305,94.1489 16.5,94.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f2753c" d="M 16.5,94.5 C 17.6009,93.4017 18.9343,93.235 20.5,94C 19.2068,94.49 17.8734,94.6567 16.5,94.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f0763b" d="M 6.5,94.5 C 7.83333,95.1667 7.83333,95.1667 6.5,94.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 21.5,95.5 C 22.2506,94.4265 23.2506,94.2599 24.5,95C 23.552,95.4828 22.552,95.6495 21.5,95.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 25.5,96.5 C 26.2506,95.4265 27.2506,95.2599 28.5,96C 27.552,96.4828 26.552,96.6495 25.5,96.5 Z"/></g>
<g><path style="opacity:0.006" fill="#f1753c" d="M 7.5,98.5 C 6.47498,98.1034 6.30831,97.4368 7,96.5C 7.46434,97.0944 7.63101,97.7611 7.5,98.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1763c" d="M 29.5,97.5 C 30.2506,96.4265 31.2506,96.2599 32.5,97C 31.552,97.4828 30.552,97.6495 29.5,97.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753d" d="M 33.5,98.5 C 34.2506,97.4265 35.2506,97.2599 36.5,98C 35.552,98.4828 34.552,98.6495 33.5,98.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f0763c" d="M 7.5,98.5 C 7.83333,98.5 8.16667,98.5 8.5,98.5C 8.5,98.8333 8.5,99.1667 8.5,99.5C 8.16667,99.1667 7.83333,98.8333 7.5,98.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f2763c" d="M 37.5,99.5 C 38.2506,98.4265 39.2506,98.2599 40.5,99C 39.552,99.4828 38.552,99.6495 37.5,99.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 8.5,99.5 C 9.83333,100.167 9.83333,100.167 8.5,99.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 10.5,101.5 C 11.2506,100.427 12.2506,100.26 13.5,101C 12.552,101.483 11.552,101.649 10.5,101.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f2753c" d="M 44.5,104.5 C 44.369,103.761 44.5357,103.094 45,102.5C 45.6917,103.437 45.525,104.103 44.5,104.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1763c" d="M 57.5,103.5 C 58.8333,104.167 58.8333,104.167 57.5,103.5 Z"/></g>
<g><path style="opacity:1" fill="#fefaf9" d="M 135.5,121.5 C 138.825,135.036 135.825,146.869 126.5,157C 116.313,163.147 106.313,162.98 96.5,156.5C 89.8526,149.729 86.8526,141.562 87.5,132C 86.5696,114.774 94.5696,104.94 111.5,102.5C 123.813,103.628 131.813,109.961 135.5,121.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 30.5,104.5 C 29.3991,105.598 28.0657,105.765 26.5,105C 27.7932,104.51 29.1266,104.343 30.5,104.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1763c" d="M 43.5,104.5 C 43.8333,104.5 44.1667,104.5 44.5,104.5C 44.3147,105.17 43.9813,105.17 43.5,104.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1753c" d="M 34.5,105.5 C 33.7494,106.573 32.7494,106.74 31.5,106C 32.448,105.517 33.448,105.351 34.5,105.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1763c" d="M 56.5,105.5 C 57.8333,106.167 57.8333,106.167 56.5,105.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1763c" d="M 38.5,106.5 C 37.7494,107.573 36.7494,107.74 35.5,107C 36.448,106.517 37.448,106.351 38.5,106.5 Z"/></g>
<g><path style="opacity:0.004" fill="#f1763c" d="M 41.5,106.5 C 42.8333,107.167 42.8333,107.167 41.5,106.5 Z"/></g>
<g><path style="opacity:0.006" fill="#f1763c" d="M 41.5,107.5 C 41.1034,108.525 40.4368,108.692 39.5,108C 40.0944,107.536 40.7611,107.369 41.5,107.5 Z"/></g>
<g><path style="opacity:0.012" fill="#f1763c" d="M 55.5,107.5 C 56.8333,108.167 56.8333,108.167 55.5,107.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 55.5,111.5 C 55.1667,111.5 54.8333,111.5 54.5,111.5C 54.8333,108.833 55.1667,108.833 55.5,111.5 Z"/></g>
<g><path style="opacity:0.01" fill="#f1753c" d="M 54.5,111.5 C 54.631,112.239 54.4643,112.906 54,113.5C 53.3083,112.563 53.475,111.897 54.5,111.5 Z"/></g>
<g><path style="opacity:0.008" fill="#f1753b" d="M 53.5,117.5 C 53.1667,117.5 52.8333,117.5 52.5,117.5C 52.8333,113.5 53.1667,113.5 53.5,117.5 Z"/></g>
<g><path style="opacity:1" fill="#ed4614" d="M 118.5,121.5 C 114.812,119.753 111.645,120.42 109,123.5C 107.25,126.246 106.25,129.246 106,132.5C 105.751,137.047 105.585,141.38 105.5,145.5C 101.751,136.916 101.584,128.249 105,119.5C 108.07,115.293 111.903,114.46 116.5,117C 117.582,118.33 118.249,119.83 118.5,121.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1763c" d="M 52.5,117.5 C 52.6495,118.552 52.4828,119.552 52,120.5C 51.2599,119.251 51.4265,118.251 52.5,117.5 Z"/></g>
<g><path style="opacity:0.01" fill="#4499dd" d="M 360.5,118.5 C 360.369,117.761 360.536,117.094 361,116.5C 364.745,117.297 368.579,117.797 372.5,118C 368.514,118.499 364.514,118.666 360.5,118.5 Z"/></g>
<g><path style="opacity:0.012" fill="#3494db" d="M 375.5,119.5 C 376.601,118.402 377.934,118.235 379.5,119C 378.207,119.49 376.873,119.657 375.5,119.5 Z"/></g>
<g><path style="opacity:0.986" fill="#3794dc" d="M 360.5,119.5 C 368.111,118.979 375.444,119.979 382.5,122.5C 382.5,125.167 382.5,127.833 382.5,130.5C 381.566,131.568 381.232,132.901 381.5,134.5C 380.833,134.5 380.5,134.833 380.5,135.5C 378.521,137.168 376.188,137.834 373.5,137.5C 366.557,136.206 359.557,136.206 352.5,137.5C 351.372,142.348 350.039,147.015 348.5,151.5C 343.13,151.608 337.797,151.275 332.5,150.5C 332.5,149.5 332.5,148.5 332.5,147.5C 333.235,141.758 334.402,136.091 336,130.5C 336.92,125.812 339.42,122.312 343.5,120C 349.157,119.501 354.824,119.334 360.5,119.5 Z"/></g>
<g><path style="opacity:0.008" fill="#3594dc" d="M 380.5,119.5 C 381.833,120.167 381.833,120.167 380.5,119.5 Z"/></g>
<g><path style="opacity:0.009" fill="#f1753d" d="M 50.5,121.5 C 51.6129,122.946 51.7796,124.613 51,126.5C 50.5065,124.866 50.3398,123.199 50.5,121.5 Z"/></g>
<g><path style="opacity:0.008" fill="#3594dc" d="M 383.5,122.5 C 382.833,121.167 382.833,121.167 383.5,122.5 Z"/></g>
<g><path style="opacity:1" fill="#f1763d" d="M 118.5,121.5 C 121.357,129.892 120.857,138.226 117,146.5C 114.159,148.504 110.993,149.004 107.5,148C 106.619,147.292 105.953,146.458 105.5,145.5C 105.585,141.38 105.751,137.047 106,132.5C 106.25,129.246 107.25,126.246 109,123.5C 111.645,120.42 114.812,119.753 118.5,121.5 Z"/></g>
<g><path style="opacity:0.007" fill="#3594db" d="M 383.5,122.5 C 384.573,123.251 384.74,124.251 384,125.5C 383.517,124.552 383.351,123.552 383.5,122.5 Z"/></g>
<g><path style="opacity:0.008" fill="#3594db" d="M 383.5,130.5 C 383.343,129.127 383.51,127.793 384,126.5C 384.765,128.066 384.598,129.399 383.5,130.5 Z"/></g>
<g><path style="opacity:0.005" fill="#f2753d" d="M 49.5,128.5 C 50.6408,131.64 50.8075,134.973 50,138.5C 49.5017,135.183 49.335,131.85 49.5,128.5 Z"/></g>
<g><path style="opacity:0.01" fill="#3494db" d="M 382.5,130.5 C 382.833,130.5 383.167,130.5 383.5,130.5C 383.768,132.099 383.434,133.432 382.5,134.5C 382.5,133.167 382.5,131.833 382.5,130.5 Z"/></g>
<g><path style="opacity:0.012" fill="#3594dc" d="M 381.5,134.5 C 381.833,134.5 382.167,134.5 382.5,134.5C 382.315,135.17 381.981,135.17 381.5,134.5 Z"/></g>
<g><path style="opacity:0.004" fill="#3594db" d="M 380.5,135.5 C 380.833,135.5 381.167,135.5 381.5,135.5C 381.315,136.17 380.981,136.17 380.5,135.5 Z"/></g>
<g><path style="opacity:0.993" fill="#dfe8f8" d="M 373.5,137.5 C 373.932,138.71 374.599,139.71 375.5,140.5C 375.992,142.819 376.992,144.819 378.5,146.5C 379.659,150.151 381.326,153.485 383.5,156.5C 383.402,158.553 384.069,160.22 385.5,161.5C 385.402,163.553 386.069,165.22 387.5,166.5C 387.263,167.791 387.596,168.791 388.5,169.5C 388.595,171.786 389.262,173.786 390.5,175.5C 390.898,179.761 391.898,183.761 393.5,187.5C 393.216,189.415 393.549,191.081 394.5,192.5C 394.624,197.049 395.291,201.382 396.5,205.5C 397.418,220.828 397.085,236.162 395.5,251.5C 393.882,256.256 392.882,261.256 392.5,266.5C 391.076,268.515 390.41,270.848 390.5,273.5C 389.596,274.209 389.263,275.209 389.5,276.5C 388.596,277.209 388.263,278.209 388.5,279.5C 387.596,280.209 387.263,281.209 387.5,282.5C 386.596,283.209 386.263,284.209 386.5,285.5C 385.069,286.78 384.402,288.447 384.5,290.5C 383.662,290.842 383.328,291.508 383.5,292.5C 382.069,293.78 381.402,295.447 381.5,297.5C 380.662,297.842 380.328,298.508 380.5,299.5C 379.662,299.842 379.328,300.508 379.5,301.5C 378.662,301.842 378.328,302.508 378.5,303.5C 377.662,303.842 377.328,304.508 377.5,305.5C 376.662,305.842 376.328,306.508 376.5,307.5C 375.833,307.5 375.5,307.833 375.5,308.5C 374.662,308.842 374.328,309.508 374.5,310.5C 373.662,310.842 373.328,311.508 373.5,312.5C 372.662,312.842 372.328,313.508 372.5,314.5C 371.833,314.5 371.5,314.833 371.5,315.5C 370.662,315.842 370.328,316.508 370.5,317.5C 369.833,317.5 369.5,317.833 369.5,318.5C 368.662,318.842 368.328,319.508 368.5,320.5C 367.833,320.5 367.5,320.833 367.5,321.5C 366.662,321.842 366.328,322.508 366.5,323.5C 365.833,323.5 365.5,323.833 365.5,324.5C 364.094,324.973 363.427,325.973 363.5,327.5C 362.833,327.5 362.5,327.833 362.5,328.5C 361.094,328.973 360.427,329.973 360.5,331.5C 359.833,331.5 359.5,331.833 359.5,332.5C 357.457,333.579 356.124,335.246 355.5,337.5C 354.833,337.5 354.5,337.833 354.5,338.5C 353.833,338.5 353.5,338.833 353.5,339.5C 352.833,339.5 352.5,339.833 352.5,340.5C 351.833,340.5 351.5,340.833 351.5,341.5C 350.833,341.5 350.5,341.833 350.5,342.5C 349.833,342.5 349.5,342.833 349.5,343.5C 347.167,345.167 345.167,347.167 343.5,349.5C 342.833,349.5 342.5,349.833 342.5,350.5C 341.833,350.5 341.5,350.833 341.5,351.5C 340.833,351.5 340.5,351.833 340.5,352.5C 339.833,352.5 339.5,352.833 339.5,353.5C 338.833,353.5 338.5,353.833 338.5,354.5C 337.833,354.5 337.5,354.833 337.5,355.5C 335.246,356.124 333.579,357.457 332.5,359.5C 331.833,359.5 331.5,359.833 331.5,360.5C 329.973,360.427 328.973,361.094 328.5,362.5C 327.833,362.5 327.5,362.833 327.5,363.5C 325.973,363.427 324.973,364.094 324.5,365.5C 323.833,365.5 323.5,365.833 323.5,366.5C 322.508,366.328 321.842,366.662 321.5,367.5C 320.833,367.5 320.5,367.833 320.5,368.5C 319.508,368.328 318.842,368.662 318.5,369.5C 317.833,369.5 317.5,369.833 317.5,370.5C 316.508,370.328 315.842,370.662 315.5,371.5C 314.833,371.5 314.5,371.833 314.5,372.5C 313.508,372.328 312.842,372.662 312.5,373.5C 311.508,373.328 310.842,373.662 310.5,374.5C 309.508,374.328 308.842,374.662 308.5,375.5C 307.833,375.5 307.5,375.833 307.5,376.5C 306.508,376.328 305.842,376.662 305.5,377.5C 304.508,377.328 303.842,377.662 303.5,378.5C 302.508,378.328 301.842,378.662 301.5,379.5C 300.508,379.328 299.842,379.662 299.5,380.5C 298.508,380.328 297.842,380.662 297.5,381.5C 295.447,381.402 293.78,382.069 292.5,383.5C 291.508,383.328 290.842,383.662 290.5,384.5C 288.447,384.402 286.78,385.069 285.5,386.5C 284.209,386.263 283.209,386.596 282.5,387.5C 281.209,387.263 280.209,387.596 279.5,388.5C 278.209,388.263 277.209,388.596 276.5,389.5C 275.209,389.263 274.209,389.596 273.5,390.5C 270.848,390.41 268.515,391.076 266.5,392.5C 261.256,392.882 256.256,393.882 251.5,395.5C 236.162,397.085 220.828,397.418 205.5,396.5C 201.382,395.291 197.049,394.624 192.5,394.5C 191.081,393.549 189.415,393.216 187.5,393.5C 183.761,391.898 179.761,390.898 175.5,390.5C 173.786,389.262 171.786,388.595 169.5,388.5C 168.791,387.596 167.791,387.263 166.5,387.5C 165.22,386.069 163.553,385.402 161.5,385.5C 160.22,384.069 158.553,383.402 156.5,383.5C 153.485,381.326 150.151,379.659 146.5,378.5C 143.001,376.25 139.335,374.25 135.5,372.5C 130.68,368.922 125.68,365.588 120.5,362.5C 106.09,350.759 93.4235,337.425 82.5,322.5C 80.7349,319.291 78.7349,316.291 76.5,313.5C 72.4806,305.461 68.4806,297.461 64.5,289.5C 64.5979,287.447 63.9313,285.78 62.5,284.5C 61.2036,278.95 59.537,273.617 57.5,268.5C 57.4349,265.572 56.7682,262.905 55.5,260.5C 55.4613,256.267 54.7947,252.267 53.5,248.5C 53.81,245.287 53.4767,242.287 52.5,239.5C 51.4685,217.118 53.8018,195.118 59.5,173.5C 60.404,172.791 60.7373,171.791 60.5,170.5C 61.1667,169.5 61.8333,168.5 62.5,167.5C 78.8297,187.613 99.8297,195.28 125.5,190.5C 125.5,193.167 125.5,195.833 125.5,198.5C 127.929,219.461 130.096,240.461 132,261.5C 133.11,269.282 137.277,274.782 144.5,278C 195.812,281.737 247.146,285.237 298.5,288.5C 296.537,294.352 295.204,300.352 294.5,306.5C 284.649,308.421 277.316,313.754 272.5,322.5C 245.515,320.635 218.515,318.968 191.5,317.5C 189.052,316.527 186.385,316.194 183.5,316.5C 181.424,308.59 176.424,303.423 168.5,301C 155.715,298.142 146.549,302.642 141,314.5C 138.361,334.854 147.194,344.687 167.5,344C 173.969,341.867 178.969,337.867 182.5,332C 185.146,331.503 187.813,331.336 190.5,331.5C 217.467,333.675 244.467,335.341 271.5,336.5C 278.266,352.38 289.6,356.88 305.5,350C 313.39,343.663 316.557,335.496 315,325.5C 313.219,321.907 311.719,318.24 310.5,314.5C 312.678,303.458 315.011,292.458 317.5,281.5C 328.436,238.416 338.77,195.083 348.5,151.5C 350.039,147.015 351.372,142.348 352.5,137.5C 359.557,136.206 366.557,136.206 373.5,137.5 Z"/></g>
<g><path style="opacity:0.016" fill="#97bfeb" d="M 375.5,140.5 C 375.843,138.775 376.843,138.275 378.5,139C 377.473,139.513 376.473,140.013 375.5,140.5 Z"/></g>
<g><path style="opacity:1" fill="#3b93d9" d="M 169.5,139.5 C 172.385,139.194 175.052,139.527 177.5,140.5C 173.222,171.449 155.889,190.782 125.5,198.5C 125.5,195.833 125.5,193.167 125.5,190.5C 150.649,182.532 165.315,165.532 169.5,139.5 Z"/></g>
<g><path style="opacity:1" fill="#4fb3f2" d="M 177.5,140.5 C 225.168,143.304 272.835,146.304 320.5,149.5C 324.756,149.428 328.756,148.761 332.5,147.5C 332.5,148.5 332.5,149.5 332.5,150.5C 337.797,151.275 343.13,151.608 348.5,151.5C 338.77,195.083 328.436,238.416 317.5,281.5C 312.801,286.625 306.467,288.958 298.5,288.5C 247.146,285.237 195.812,281.737 144.5,278C 137.277,274.782 133.11,269.282 132,261.5C 130.096,240.461 127.929,219.461 125.5,198.5C 155.889,190.782 173.222,171.449 177.5,140.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 379.5,146.5 C 379.167,146.5 378.833,146.5 378.5,146.5C 378.833,143.833 379.167,143.833 379.5,146.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 379.5,146.5 C 380.833,147.167 380.833,147.167 379.5,146.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 380.5,148.5 C 381.833,149.167 381.833,149.167 380.5,148.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f9" d="M 384.5,156.5 C 384.167,156.5 383.833,156.5 383.5,156.5C 383.833,153.833 384.167,153.833 384.5,156.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f8" d="M 384.5,156.5 C 385.525,156.897 385.692,157.563 385,158.5C 384.536,157.906 384.369,157.239 384.5,156.5 Z"/></g>
<g><path style="opacity:1" fill="#ec400a" d="M 96.5,156.5 C 106.313,162.98 116.313,163.147 126.5,157C 135.825,146.869 138.825,135.036 135.5,121.5C 137.006,123.311 138.172,125.978 139,129.5C 140.716,139.457 139.049,148.79 134,157.5C 126.916,165.485 118.082,168.318 107.5,166C 103.103,164.383 99.2692,161.883 96,158.5C 95.3083,157.563 95.475,156.897 96.5,156.5 Z"/></g>
<g><path style="opacity:0.012" fill="#e0e9f8" d="M 386.5,161.5 C 386.167,161.5 385.833,161.5 385.5,161.5C 385.833,158.833 386.167,158.833 386.5,161.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f9" d="M 386.5,161.5 C 387.525,161.897 387.692,162.563 387,163.5C 386.536,162.906 386.369,162.239 386.5,161.5 Z"/></g>
<g><path style="opacity:0.016" fill="#f1763c" d="M 59.5,163.5 C 58.8333,164.167 58.8333,164.167 59.5,163.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 387.5,166.5 C 387.369,165.761 387.536,165.094 388,164.5C 388.692,165.437 388.525,166.103 387.5,166.5 Z"/></g>
<g><path style="opacity:0.012" fill="#e0e8f9" d="M 388.5,169.5 C 388.369,168.761 388.536,168.094 389,167.5C 389.692,168.437 389.525,169.103 388.5,169.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f8" d="M 60.5,170.5 C 59.475,170.103 59.3083,169.437 60,168.5C 60.4643,169.094 60.631,169.761 60.5,170.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e9f8" d="M 59.5,173.5 C 58.475,173.103 58.3083,172.437 59,171.5C 59.4643,172.094 59.631,172.761 59.5,173.5 Z"/></g>
<g><path style="opacity:1" fill="#1d77c7" d="M 201.5,175.5 C 201.97,179.97 200.97,180.47 198.5,177C 193.269,175.276 189.435,176.776 187,181.5C 186.505,179.527 186.338,177.527 186.5,175.5C 187.649,171.997 190.149,170.331 194,170.5C 197.82,170.318 200.32,171.985 201.5,175.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe9f8" d="M 390.5,175.5 C 390.351,174.448 390.517,173.448 391,172.5C 391.74,173.749 391.573,174.749 390.5,175.5 Z"/></g>
<g><path style="opacity:1" fill="#3594dc" d="M 186.5,175.5 C 186.338,177.527 186.505,179.527 187,181.5C 189.435,176.776 193.269,175.276 198.5,177C 200.97,180.47 201.97,179.97 201.5,175.5C 205.301,199.23 207.467,223.23 208,247.5C 204.58,251.753 200.413,252.587 195.5,250C 194.299,249.097 193.465,247.931 193,246.5C 190.646,223.982 188.146,201.482 185.5,179C 185.514,177.615 185.848,176.449 186.5,175.5 Z"/></g>
<g><path style="opacity:1" fill="#1d77c7" d="M 277.5,186.5 C 275.702,184.888 273.702,183.388 271.5,182C 267.726,180.817 264.559,181.651 262,184.5C 261.601,184.272 261.435,183.938 261.5,183.5C 262.392,177.048 266.059,174.548 272.5,176C 276.981,178.061 278.648,181.561 277.5,186.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e9f8" d="M 55.5,181.5 C 56.5735,182.251 56.7401,183.251 56,184.5C 55.5172,183.552 55.3505,182.552 55.5,181.5 Z"/></g>
<g><path style="opacity:1" fill="#3594dc" d="M 277.5,186.5 C 272.326,208.186 266.826,229.853 261,251.5C 253.672,257.698 248.506,256.198 245.5,247C 250.78,225.689 256.114,204.523 261.5,183.5C 261.435,183.938 261.601,184.272 262,184.5C 264.559,181.651 267.726,180.817 271.5,182C 273.702,183.388 275.702,184.888 277.5,186.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 393.5,187.5 C 393.343,186.127 393.51,184.793 394,183.5C 394.765,185.066 394.598,186.399 393.5,187.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f9" d="M 394.5,192.5 C 394.343,191.127 394.51,189.793 395,188.5C 395.765,190.066 395.598,191.399 394.5,192.5 Z"/></g>
<g><path style="opacity:0.011" fill="#e0e8f8" d="M 395.5,193.5 C 396.598,194.601 396.765,195.934 396,197.5C 395.51,196.207 395.343,194.873 395.5,193.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 52.5,195.5 C 53.6129,196.946 53.7796,198.613 53,200.5C 52.5065,198.866 52.3398,197.199 52.5,195.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 396.5,205.5 C 396.337,203.143 396.503,200.81 397,198.5C 397.796,201.039 397.629,203.372 396.5,205.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 51.5,201.5 C 52.6341,203.966 52.8007,206.633 52,209.5C 51.5026,206.854 51.3359,204.187 51.5,201.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 397.5,206.5 C 398.648,210.981 398.815,215.648 398,220.5C 397.501,215.845 397.334,211.179 397.5,206.5 Z"/></g>
<g><path style="opacity:0.011" fill="#dfe8f8" d="M 50.5,211.5 C 51.6573,220.324 51.824,229.324 51,238.5C 50.5002,229.506 50.3336,220.506 50.5,211.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 397.5,228.5 C 398.648,232.981 398.815,237.648 398,242.5C 397.501,237.845 397.334,233.179 397.5,228.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 52.5,239.5 C 52.6641,242.187 52.4974,244.854 52,247.5C 51.1993,244.633 51.3659,241.966 52.5,239.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 396.5,244.5 C 397.622,246.288 397.789,248.288 397,250.5C 396.505,248.527 396.338,246.527 396.5,244.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 53.5,248.5 C 53.6621,250.527 53.4955,252.527 53,254.5C 52.2109,252.288 52.3775,250.288 53.5,248.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 395.5,251.5 C 396.613,252.946 396.78,254.613 396,256.5C 395.506,254.866 395.34,253.199 395.5,251.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f8" d="M 53.5,255.5 C 54.5983,256.601 54.765,257.934 54,259.5C 53.51,258.207 53.3433,256.873 53.5,255.5 Z"/></g>
<g><path style="opacity:0.011" fill="#dfe8f8" d="M 394.5,257.5 C 395.598,258.601 395.765,259.934 395,261.5C 394.51,260.207 394.343,258.873 394.5,257.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 55.5,260.5 C 55.6495,261.552 55.4828,262.552 55,263.5C 54.2599,262.251 54.4265,261.251 55.5,260.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 393.5,262.5 C 394.573,263.251 394.74,264.251 394,265.5C 393.517,264.552 393.351,263.552 393.5,262.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 392.5,266.5 C 393.573,267.251 393.74,268.251 393,269.5C 392.517,268.552 392.351,267.552 392.5,266.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f9" d="M 57.5,268.5 C 57.6495,269.552 57.4828,270.552 57,271.5C 56.2599,270.251 56.4265,269.251 57.5,268.5 Z"/></g>
<g><path style="opacity:0.009" fill="#e0e9f8" d="M 391.5,273.5 C 391.351,272.448 391.517,271.448 392,270.5C 392.74,271.749 392.573,272.749 391.5,273.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 390.5,273.5 C 390.833,273.5 391.167,273.5 391.5,273.5C 391.737,274.791 391.404,275.791 390.5,276.5C 390.5,275.5 390.5,274.5 390.5,273.5 Z"/></g>
<g><path style="opacity:0.007" fill="#dfe8f8" d="M 389.5,276.5 C 389.833,276.5 390.167,276.5 390.5,276.5C 390.737,277.791 390.404,278.791 389.5,279.5C 389.5,278.5 389.5,277.5 389.5,276.5 Z"/></g>
<g><path style="opacity:0.007" fill="#dfe9f8" d="M 388.5,279.5 C 388.833,279.5 389.167,279.5 389.5,279.5C 389.737,280.791 389.404,281.791 388.5,282.5C 388.5,281.5 388.5,280.5 388.5,279.5 Z"/></g>
<g><path style="opacity:0.008" fill="#e0e8f8" d="M 387.5,282.5 C 387.833,282.5 388.167,282.5 388.5,282.5C 388.737,283.791 388.404,284.791 387.5,285.5C 387.5,284.5 387.5,283.5 387.5,282.5 Z"/></g>
<g><path style="opacity:1" fill="#3894dc" d="M 317.5,281.5 C 315.011,292.458 312.678,303.458 310.5,314.5C 309.883,314.611 309.383,314.944 309,315.5C 305.027,311.453 300.194,309.453 294.5,309.5C 294.5,308.5 294.5,307.5 294.5,306.5C 295.204,300.352 296.537,294.352 298.5,288.5C 306.467,288.958 312.801,286.625 317.5,281.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f8" d="M 62.5,284.5 C 62.631,285.239 62.4643,285.906 62,286.5C 61.3083,285.563 61.475,284.897 62.5,284.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e9f8" d="M 386.5,285.5 C 386.833,285.5 387.167,285.5 387.5,285.5C 387.167,288.167 386.833,288.167 386.5,285.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 63.5,289.5 C 62.475,289.103 62.3083,288.437 63,287.5C 63.4643,288.094 63.631,288.761 63.5,289.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 385.5,290.5 C 385.369,289.761 385.536,289.094 386,288.5C 386.692,289.437 386.525,290.103 385.5,290.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 63.5,289.5 C 63.8333,289.5 64.1667,289.5 64.5,289.5C 64.1667,292.167 63.8333,292.167 63.5,289.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 384.5,290.5 C 384.833,290.5 385.167,290.5 385.5,290.5C 385.672,291.492 385.338,292.158 384.5,292.5C 384.5,291.833 384.5,291.167 384.5,290.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 64.5,292.5 C 65.8333,293.167 65.8333,293.167 64.5,292.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 383.5,292.5 C 383.833,292.5 384.167,292.5 384.5,292.5C 384.167,295.167 383.833,295.167 383.5,292.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 382.5,295.5 C 383.833,296.167 383.833,296.167 382.5,295.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 381.5,297.5 C 382.833,298.167 382.833,298.833 381.5,299.5C 381.5,298.833 381.5,298.167 381.5,297.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 380.5,299.5 C 380.833,299.5 381.167,299.5 381.5,299.5C 381.672,300.492 381.338,301.158 380.5,301.5C 380.5,300.833 380.5,300.167 380.5,299.5 Z"/></g>
<g><path style="opacity:1" fill="#52b4f2" d="M 191.5,317.5 C 189.167,317.5 186.833,317.5 184.5,317.5C 184.886,321.876 184.219,326.043 182.5,330C 185.365,330.183 188.031,330.683 190.5,331.5C 187.813,331.336 185.146,331.503 182.5,332C 178.969,337.867 173.969,341.867 167.5,344C 147.194,344.687 138.361,334.854 141,314.5C 146.549,302.642 155.715,298.142 168.5,301C 176.424,303.423 181.424,308.59 183.5,316.5C 186.385,316.194 189.052,316.527 191.5,317.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f8" d="M 379.5,301.5 C 379.833,301.5 380.167,301.5 380.5,301.5C 380.672,302.492 380.338,303.158 379.5,303.5C 379.5,302.833 379.5,302.167 379.5,301.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 378.5,303.5 C 378.833,303.5 379.167,303.5 379.5,303.5C 379.672,304.492 379.338,305.158 378.5,305.5C 378.5,304.833 378.5,304.167 378.5,303.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 377.5,305.5 C 377.833,305.5 378.167,305.5 378.5,305.5C 378.315,306.17 377.981,306.17 377.5,305.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 376.5,307.5 C 377.833,308.167 377.833,308.167 376.5,307.5 Z"/></g>
<g><path style="opacity:0.006" fill="#dfe9f8" d="M 375.5,308.5 C 375.833,308.5 376.167,308.5 376.5,308.5C 376.672,309.492 376.338,310.158 375.5,310.5C 375.5,309.833 375.5,309.167 375.5,308.5 Z"/></g>
<g><path style="opacity:1" fill="#52b4f2" d="M 294.5,306.5 C 294.5,307.5 294.5,308.5 294.5,309.5C 300.194,309.453 305.027,311.453 309,315.5C 309.383,314.944 309.883,314.611 310.5,314.5C 311.719,318.24 313.219,321.907 315,325.5C 316.557,335.496 313.39,343.663 305.5,350C 289.6,356.88 278.266,352.38 271.5,336.5C 271.283,331.77 271.617,327.103 272.5,322.5C 277.316,313.754 284.649,308.421 294.5,306.5 Z"/></g>
<g><path style="opacity:1" fill="#fafcfe" d="M 158.5,309.5 C 171.572,309.724 176.406,316.057 173,328.5C 165.144,336.828 157.811,336.495 151,327.5C 148.272,319.292 150.772,313.292 158.5,309.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 374.5,310.5 C 374.833,310.5 375.167,310.5 375.5,310.5C 375.672,311.492 375.338,312.158 374.5,312.5C 374.5,311.833 374.5,311.167 374.5,310.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dee9f7" d="M 373.5,312.5 C 373.833,312.5 374.167,312.5 374.5,312.5C 374.315,313.17 373.981,313.17 373.5,312.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 76.5,313.5 C 75.8333,314.167 75.8333,314.167 76.5,313.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 372.5,314.5 C 373.833,315.167 373.833,315.167 372.5,314.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe8f8" d="M 76.5,315.5 C 77.8333,316.167 77.8333,316.167 76.5,315.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 371.5,315.5 C 371.833,315.5 372.167,315.5 372.5,315.5C 372.672,316.492 372.338,317.158 371.5,317.5C 371.5,316.833 371.5,316.167 371.5,315.5 Z"/></g>
<g><path style="opacity:1" fill="#3a95dc" d="M 191.5,317.5 C 218.515,318.968 245.515,320.635 272.5,322.5C 271.617,327.103 271.283,331.77 271.5,336.5C 244.467,335.341 217.467,333.675 190.5,331.5C 188.031,330.683 185.365,330.183 182.5,330C 184.219,326.043 184.886,321.876 184.5,317.5C 186.833,317.5 189.167,317.5 191.5,317.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 370.5,317.5 C 370.833,317.5 371.167,317.5 371.5,317.5C 371.315,318.17 370.981,318.17 370.5,317.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 369.5,318.5 C 369.833,318.5 370.167,318.5 370.5,318.5C 370.672,319.492 370.338,320.158 369.5,320.5C 369.5,319.833 369.5,319.167 369.5,318.5 Z"/></g>
<g><path style="opacity:1" fill="#fafcfe" d="M 289.5,318.5 C 302.572,318.724 307.406,325.057 304,337.5C 296.224,345.767 288.89,345.434 282,336.5C 279.272,328.292 281.772,322.292 289.5,318.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f7" d="M 368.5,320.5 C 368.833,320.5 369.167,320.5 369.5,320.5C 369.315,321.17 368.981,321.17 368.5,320.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 367.5,321.5 C 367.833,321.5 368.167,321.5 368.5,321.5C 368.672,322.492 368.338,323.158 367.5,323.5C 367.5,322.833 367.5,322.167 367.5,321.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dee8f7" d="M 82.5,322.5 C 81.8333,323.167 81.8333,323.167 82.5,322.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 366.5,323.5 C 366.833,323.5 367.167,323.5 367.5,323.5C 367.315,324.17 366.981,324.17 366.5,323.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 82.5,324.5 C 83.8333,325.167 83.8333,325.167 82.5,324.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f7" d="M 365.5,324.5 C 365.833,324.5 366.167,324.5 366.5,324.5C 366.315,325.17 365.981,325.17 365.5,324.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 364.5,326.5 C 365.833,327.167 365.833,327.167 364.5,326.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 363.5,327.5 C 363.833,327.5 364.167,327.5 364.5,327.5C 364.315,328.17 363.981,328.17 363.5,327.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 362.5,328.5 C 362.833,328.5 363.167,328.5 363.5,328.5C 363.315,329.17 362.981,329.17 362.5,328.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 361.5,330.5 C 362.833,331.167 362.833,331.167 361.5,330.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 360.5,331.5 C 360.833,331.5 361.167,331.5 361.5,331.5C 361.315,332.17 360.981,332.17 360.5,331.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 359.5,332.5 C 359.833,332.5 360.167,332.5 360.5,332.5C 360.315,333.17 359.981,333.17 359.5,332.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 355.5,337.5 C 356.833,338.167 356.833,338.167 355.5,337.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 354.5,338.5 C 354.833,338.5 355.167,338.5 355.5,338.5C 355.315,339.17 354.981,339.17 354.5,338.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 353.5,339.5 C 353.833,339.5 354.167,339.5 354.5,339.5C 354.315,340.17 353.981,340.17 353.5,339.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f7" d="M 352.5,340.5 C 352.833,340.5 353.167,340.5 353.5,340.5C 353.315,341.17 352.981,341.17 352.5,340.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 351.5,341.5 C 351.833,341.5 352.167,341.5 352.5,341.5C 352.315,342.17 351.981,342.17 351.5,341.5 Z"/></g>
<g><path style="opacity:0.004" fill="#e0e9f8" d="M 350.5,342.5 C 350.833,342.5 351.167,342.5 351.5,342.5C 350.968,345.46 350.301,345.793 349.5,343.5C 350.167,343.5 350.5,343.167 350.5,342.5 Z"/></g>
<g><path style="opacity:0.004" fill="#dfe9f8" d="M 343.5,349.5 C 345.793,350.301 345.46,350.968 342.5,351.5C 342.5,351.167 342.5,350.833 342.5,350.5C 343.167,350.5 343.5,350.167 343.5,349.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 341.5,351.5 C 341.833,351.5 342.167,351.5 342.5,351.5C 342.315,352.17 341.981,352.17 341.5,351.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 340.5,352.5 C 340.833,352.5 341.167,352.5 341.5,352.5C 341.315,353.17 340.981,353.17 340.5,352.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dee9f8" d="M 339.5,353.5 C 339.833,353.5 340.167,353.5 340.5,353.5C 340.315,354.17 339.981,354.17 339.5,353.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 338.5,354.5 C 338.833,354.5 339.167,354.5 339.5,354.5C 339.315,355.17 338.981,355.17 338.5,354.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 337.5,355.5 C 337.833,355.5 338.167,355.5 338.5,355.5C 338.315,356.17 337.981,356.17 337.5,355.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 332.5,359.5 C 333.833,360.167 333.833,360.167 332.5,359.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 331.5,360.5 C 331.833,360.5 332.167,360.5 332.5,360.5C 332.315,361.17 331.981,361.17 331.5,360.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 331.5,361.5 C 330.833,362.167 330.833,362.167 331.5,361.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe8f8" d="M 120.5,362.5 C 120.5,362.833 120.5,363.167 120.5,363.5C 119.83,363.019 119.83,362.685 120.5,362.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f7" d="M 328.5,362.5 C 329.833,363.167 329.833,363.167 328.5,362.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 120.5,363.5 C 121.833,364.167 121.833,364.167 120.5,363.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe8f8" d="M 327.5,363.5 C 327.833,363.5 328.167,363.5 328.5,363.5C 328.315,364.17 327.981,364.17 327.5,363.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 327.5,364.5 C 326.833,365.167 326.833,365.167 327.5,364.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 324.5,365.5 C 325.833,366.167 325.833,366.167 324.5,365.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 323.5,366.5 C 323.833,366.5 324.167,366.5 324.5,366.5C 324.315,367.17 323.981,367.17 323.5,366.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f9" d="M 321.5,368.5 C 321.5,368.167 321.5,367.833 321.5,367.5C 322.167,367.5 322.833,367.5 323.5,367.5C 323.158,368.338 322.492,368.672 321.5,368.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dee8f7" d="M 320.5,368.5 C 320.833,368.5 321.167,368.5 321.5,368.5C 321.315,369.17 320.981,369.17 320.5,368.5 Z"/></g>
<g><path style="opacity:0.008" fill="#e0e9f8" d="M 318.5,370.5 C 318.5,370.167 318.5,369.833 318.5,369.5C 319.167,369.5 319.833,369.5 320.5,369.5C 320.158,370.338 319.492,370.672 318.5,370.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 317.5,370.5 C 317.833,370.5 318.167,370.5 318.5,370.5C 318.315,371.17 317.981,371.17 317.5,370.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f9" d="M 315.5,372.5 C 315.5,372.167 315.5,371.833 315.5,371.5C 316.167,371.5 316.833,371.5 317.5,371.5C 317.158,372.338 316.492,372.672 315.5,372.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f9" d="M 135.5,372.5 C 135.5,372.833 135.5,373.167 135.5,373.5C 132.833,373.167 132.833,372.833 135.5,372.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dee9f8" d="M 314.5,372.5 C 314.833,372.5 315.167,372.5 315.5,372.5C 315.315,373.17 314.981,373.17 314.5,372.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 135.5,373.5 C 136.833,374.167 136.833,374.167 135.5,373.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f8" d="M 312.5,373.5 C 313.833,374.167 313.833,374.167 312.5,373.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 310.5,375.5 C 310.5,375.167 310.5,374.833 310.5,374.5C 311.167,374.5 311.833,374.5 312.5,374.5C 312.158,375.338 311.492,375.672 310.5,375.5 Z"/></g>
<g><path style="opacity:0.006" fill="#dfe9f8" d="M 308.5,376.5 C 308.5,376.167 308.5,375.833 308.5,375.5C 309.167,375.5 309.833,375.5 310.5,375.5C 310.158,376.338 309.492,376.672 308.5,376.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe8f8" d="M 307.5,376.5 C 307.833,376.5 308.167,376.5 308.5,376.5C 308.315,377.17 307.981,377.17 307.5,376.5 Z"/></g>
<g><path style="opacity:0.016" fill="#dfe9f7" d="M 305.5,377.5 C 306.833,378.167 306.833,378.167 305.5,377.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f9" d="M 146.5,378.5 C 146.5,378.833 146.5,379.167 146.5,379.5C 143.833,379.167 143.833,378.833 146.5,378.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 303.5,379.5 C 303.5,379.167 303.5,378.833 303.5,378.5C 304.167,378.5 304.833,378.5 305.5,378.5C 305.158,379.338 304.492,379.672 303.5,379.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 146.5,379.5 C 147.833,380.167 147.833,380.167 146.5,379.5 Z"/></g>
<g><path style="opacity:0.01" fill="#e0e8f9" d="M 301.5,380.5 C 301.5,380.167 301.5,379.833 301.5,379.5C 302.167,379.5 302.833,379.5 303.5,379.5C 303.158,380.338 302.492,380.672 301.5,380.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 148.5,380.5 C 149.833,381.167 149.833,381.167 148.5,380.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 299.5,381.5 C 299.5,381.167 299.5,380.833 299.5,380.5C 300.167,380.5 300.833,380.5 301.5,380.5C 301.158,381.338 300.492,381.672 299.5,381.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 297.5,381.5 C 298.167,381.5 298.833,381.5 299.5,381.5C 298.833,382.833 298.167,382.833 297.5,381.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 295.5,382.5 C 296.833,383.167 296.833,383.167 295.5,382.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 156.5,383.5 C 156.5,383.833 156.5,384.167 156.5,384.5C 153.833,384.167 153.833,383.833 156.5,383.5 Z"/></g>
<g><path style="opacity:0.008" fill="#e0e8f8" d="M 292.5,384.5 C 292.5,384.167 292.5,383.833 292.5,383.5C 295.167,383.833 295.167,384.167 292.5,384.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 156.5,384.5 C 157.239,384.369 157.906,384.536 158.5,385C 157.563,385.692 156.897,385.525 156.5,384.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 290.5,385.5 C 290.5,385.167 290.5,384.833 290.5,384.5C 291.167,384.5 291.833,384.5 292.5,384.5C 292.158,385.338 291.492,385.672 290.5,385.5 Z"/></g>
<g><path style="opacity:0.012" fill="#e0e8f8" d="M 161.5,385.5 C 161.5,385.833 161.5,386.167 161.5,386.5C 158.833,386.167 158.833,385.833 161.5,385.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe9f8" d="M 290.5,385.5 C 290.103,386.525 289.437,386.692 288.5,386C 289.094,385.536 289.761,385.369 290.5,385.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 161.5,386.5 C 162.239,386.369 162.906,386.536 163.5,387C 162.563,387.692 161.897,387.525 161.5,386.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 285.5,387.5 C 285.5,387.167 285.5,386.833 285.5,386.5C 288.167,386.833 288.167,387.167 285.5,387.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f7" d="M 166.5,387.5 C 166.103,388.525 165.437,388.692 164.5,388C 165.094,387.536 165.761,387.369 166.5,387.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 282.5,388.5 C 282.5,388.167 282.5,387.833 282.5,387.5C 283.5,387.5 284.5,387.5 285.5,387.5C 284.791,388.404 283.791,388.737 282.5,388.5 Z"/></g>
<g><path style="opacity:0.012" fill="#dfe9f8" d="M 169.5,388.5 C 169.103,389.525 168.437,389.692 167.5,389C 168.094,388.536 168.761,388.369 169.5,388.5 Z"/></g>
<g><path style="opacity:0.007" fill="#dfe8f8" d="M 279.5,389.5 C 279.5,389.167 279.5,388.833 279.5,388.5C 280.5,388.5 281.5,388.5 282.5,388.5C 281.791,389.404 280.791,389.737 279.5,389.5 Z"/></g>
<g><path style="opacity:0.007" fill="#e0e9f8" d="M 276.5,390.5 C 276.5,390.167 276.5,389.833 276.5,389.5C 277.5,389.5 278.5,389.5 279.5,389.5C 278.791,390.404 277.791,390.737 276.5,390.5 Z"/></g>
<g><path style="opacity:0.009" fill="#e0e8f8" d="M 175.5,390.5 C 174.749,391.573 173.749,391.74 172.5,391C 173.448,390.517 174.448,390.351 175.5,390.5 Z"/></g>
<g><path style="opacity:0.008" fill="#e0e8f8" d="M 273.5,391.5 C 273.5,391.167 273.5,390.833 273.5,390.5C 274.5,390.5 275.5,390.5 276.5,390.5C 275.791,391.404 274.791,391.737 273.5,391.5 Z"/></g>
<g><path style="opacity:0.009" fill="#e0e8f8" d="M 273.5,391.5 C 272.749,392.573 271.749,392.74 270.5,392C 271.448,391.517 272.448,391.351 273.5,391.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f9" d="M 266.5,392.5 C 267.552,392.351 268.552,392.517 269.5,393C 268.251,393.74 267.251,393.573 266.5,392.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe9f8" d="M 187.5,393.5 C 186.399,394.598 185.066,394.765 183.5,394C 184.793,393.51 186.127,393.343 187.5,393.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 262.5,394.5 C 263.251,393.427 264.251,393.26 265.5,394C 264.552,394.483 263.552,394.649 262.5,394.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 192.5,394.5 C 191.399,395.598 190.066,395.765 188.5,395C 189.793,394.51 191.127,394.343 192.5,394.5 Z"/></g>
<g><path style="opacity:0.011" fill="#dfe9f8" d="M 257.5,395.5 C 258.601,394.402 259.934,394.235 261.5,395C 260.207,395.49 258.873,395.657 257.5,395.5 Z"/></g>
<g><path style="opacity:0.011" fill="#e0e9f8" d="M 193.5,396.5 C 194.601,395.402 195.934,395.235 197.5,396C 196.207,396.49 194.873,396.657 193.5,396.5 Z"/></g>
<g><path style="opacity:0.009" fill="#e0e8f9" d="M 251.5,395.5 C 253.199,395.34 254.866,395.506 256.5,396C 254.613,396.78 252.946,396.613 251.5,395.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f8" d="M 205.5,396.5 C 203.372,397.629 201.039,397.796 198.5,397C 200.81,396.503 203.143,396.337 205.5,396.5 Z"/></g>
<g><path style="opacity:0.01" fill="#dfe8f9" d="M 244.5,397.5 C 246.288,396.378 248.288,396.211 250.5,397C 248.527,397.495 246.527,397.662 244.5,397.5 Z"/></g>
<g><path style="opacity:0.008" fill="#dfe8f8" d="M 206.5,398.5 C 210.981,397.352 215.648,397.185 220.5,398C 215.845,398.499 211.179,398.666 206.5,398.5 Z"/></g>
<g><path style="opacity:0.009" fill="#dfe8f8" d="M 228.5,398.5 C 232.981,397.352 237.648,397.185 242.5,398C 237.845,398.499 233.179,398.666 228.5,398.5 Z"/></g>
</svg>

Edit Header.jsx in components folder:

// Import Cart Component
import Cart from "./Cart";

<ThemeSwitcherDropdown /> // find this line

<Cart /> // add this line

Create Cart.jsx in components folder:

"use client";
import { useCart } from "@/hooks/useCart";
import { ShoppingCart } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import CartItem from "./CartItem";
import { Button } from "./ui/button";
import { ScrollArea } from "./ui/scroll-area";
import { Separator } from "./ui/separator";
import {
  Sheet,
  SheetContent,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "./ui/sheet";

const Cart = () => {
  const { items } = useCart();
  const itemCount = items.length;

  const cartTotal = items.reduce(
    (total, { product, quantity }) => total + product.price * quantity,
    0
  );

  const fee = 1;

  return (
    <Sheet>
      <SheetTrigger className="group -m-2 flex items-center p-2">
        <ShoppingCart aria-hidden="true" className="h-6 w-6 flex-shrink-0" />
        <span className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-400">
          {itemCount}
        </span>
      </SheetTrigger>

      <SheetContent className="flex w-full flex-col pr-0 sm:max-w-lg">
        <SheetHeader className="space-y-2.5 pr-6">
          <SheetTitle>Cart ({itemCount})</SheetTitle>
        </SheetHeader>

        {itemCount > 0 ? (
          <>
            <div className="flex flex-col w-full pr-6">
              <ScrollArea>
                {items.map(({ product, quantity }) => (
                  <CartItem
                    product={product}
                    quantity={quantity}
                    key={product.id}
                  />
                ))}
              </ScrollArea>
            </div>

            <div className="space-y-4 pr-6">
              <Separator />

              <div className="space-y-1.5 text-sm">
                <div className="flex">
                  <span className="flex-1">Shipping</span>
                  <span>Free</span>
                </div>

                <div className="flex">
                  <span className="flex-1">Transaction Fee</span>
                  <span>${fee} USD</span>
                </div>

                <div className="flex">
                  <span className="flex-1">Total</span>
                  <span>${cartTotal + fee} USD</span>
                </div>
              </div>

              <SheetFooter>
                <SheetTrigger asChild>
                  <Link href="/cart">
                    <Button className="w-full">Continue to checkout</Button>
                  </Link>
                </SheetTrigger>
              </SheetFooter>
            </div>
          </>
        ) : (
          <div className="flex h-full flex-col items-center justify-center space-y-1">
            <div
              className="relative mb-4 h-60 w-60 text-muted-foreground"
              aria-hidden="true"
            >
              <Image
                src="/empty-cart.svg"
                fill
                alt="Empty shopping cart image"
              />
            </div>

            <div className="text-xl font-semibold">Your cart is empty</div>

            <SheetTrigger asChild>
              <Link href="/">
                <Button variant="link" size="sm">
                  Add items to your cart to checkout
                </Button>
              </Link>
            </SheetTrigger>
          </div>
        )}
      </SheetContent>
    </Sheet>
  );
};

export default Cart;

Create CartItem.jsx in components folder:

import { useCart } from "@/hooks/useCart";
import { X } from "lucide-react";
import Image from "next/image";

const CartItem = ({ product, quantity }) => {
  const { removeItem } = useCart();

  return (
    <div className="space-y-3 py-2">
      <div className="flex items-start justify-between gap-4">
        <div className="flex items-center space-x-4">
          <div className="relative aspect-square h-16 w-16 min-w-fit overflow-hidden rounded">
            <Image
              src={product.image}
              alt={product.title}
              fill
              className="absolute object-cover"
            />
          </div>

          <div className="flex flex-col self-start">
            <span className="line-clamp-1 text-sm font-medium mb-1">
              {product.title} {quantity > 1 ? `(${quantity})` : null}
            </span>

            <div className="mt-4 text-xs text-muted-foreground">
              <div>
                <button
                  onClick={() => removeItem(product.id)}
                  className="flex items-center gap-0.5"
                >
                  <X className="w-3 h-4" />
                </button>
                <span className="sr-only">Remove</span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex flex-col space-y-1 font-medium">
          <span className="ml-auto line-clamp-1 text-sm">
            ${product.price * quantity} USD
          </span>
        </div>
      </div>
    </div>
  );
};

export default CartItem;

Create AddToCartButton.jsx in components folder:

"use client";
import { useCart } from "@/hooks/useCart";
import { useEffect, useState } from "react";
import { Button } from "./ui/button";

const AddToCartButton = ({ product }) => {
  const { addItem } = useCart();
  const [isSuccess, setIsSuccess] = useState(false);

  useEffect(() => {
    const timeout = setTimeout(() => {
      setIsSuccess(false);
    }, 2000);

    return () => clearTimeout(timeout);
  }, [isSuccess]);

  return (
    <Button
      onClick={() => {
        addItem(product);
        setIsSuccess(true);
      }}
      size="lg"
      className="w-full"
    >
      {isSuccess ? "Added!" : "Add to cart"}
    </Button>
  );
};

export default AddToCartButton;

Edit page.js in app/[id] folder:

// import the button component
import AddToCartButton from "@/components/AddToCartButton";

// Replace the regular button with AddToCartButton component
<Button>Add to cart</Button>; // delete this line
<AddToCartButton product={product} />; // add this line

Create page.js in app/cart folder:

"use client";
import { Button } from "@/components/ui/button";
import { useCart } from "@/hooks/useCart";
import { cn } from "@/lib/utils";
import { Minus, Plus, X } from "lucide-react";
import Image from "next/image";
import Link from "next/link";

const CartPage = () => {
  const { items, removeItem, increaseQuantity, decreaseQuantity, clearCart } =
    useCart();

  const productIDs = items.map(({ product }) => product.id);

  const cartTotal = items.reduce(
    (total, { product, quantity }) => total + product.price * quantity,
    0
  );

  return (
    <div>
      <div className="mx-auto max-w-2xl px-4 pb-24 pt-16 sm:px-6 lg:max-w-7xl lg:px-8">
        <h1 className="text-3xl font-bold tracking-tight  sm:text-4xl">
          Shopping Cart
        </h1>

        <div className="mt-12 lg:grid lg:grid-cols-12 lg:items-start lg:gap-x-12 xl:gap-x-16">
          <div
            className={cn("lg:col-span-7", {
              "rounded-lg border-2 border-dashed border-zinc-200 p-12":
                items.length === 0,
            })}
          >
            <h2 className="sr-only">Items in your shopping cart</h2>

            {items.length === 0 ? (
              <div className="flex flex-col h-full items-center justify-center space-y-1">
                <div
                  aria-hidden="true"
                  className="relative mb-4 h-40 w-40 text-muted-foreground"
                >
                  <Image
                    src="/empty-cart.svg"
                    fill
                    loading="eager"
                    alt="Empty shopping cart"
                  />
                </div>

                <h3 className="font-semibold text-2xl">Your cart is empty</h3>

                <p className="text-muted-foreground text-center">
                  Nothing to show here yet.
                </p>
              </div>
            ) : null}

            <ul
              className={cn({
                "divide-y divide-gray-200 border-b border-t border-gray-200":
                  items.length > 0,
              })}
            >
              {items.map(({ product, quantity }) => {
                return (
                  <li key={product.id} className="flex py-6 sm:py-10">
                    <div className="flex-shrink-0">
                      <div className="relative h-24 w-24">
                        <Image
                          fill
                          src={product.image}
                          alt="product image"
                          className="h-full w-full rounded-md object-cover object-center sm:h-48 sm:w-48"
                        />
                      </div>
                    </div>

                    <div className="ml-4 flex flex-1 flex-col justify-between sm:ml-6">
                      <div className="relative pr-9 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:pr-0">
                        <div>
                          <div className="flex justify-between">
                            <h3 className="text-sm">
                              <Link
                                href={`/${product.slug}`}
                                className="font-medium text-gray-700 dark:text-gray-50 dark:hover:text-gray-200 hover:text-gray-800"
                              >
                                {product.title}{" "}
                                {quantity > 1 ? `(${quantity})` : null}
                              </Link>
                            </h3>
                          </div>

                          <p className="mt-1 text-sm font-medium text-gray-900 dark:text-gray-50">
                            ${product.price * quantity} USD
                          </p>
                        </div>

                        <div className="mt-4 sm:mt-0 sm:pr-9 w-20">
                          <div className="absolute right-0 top-0">
                            <Button
                              aria-label="Remove product"
                              onClick={() => increaseQuantity(product.id)}
                              variant="ghost"
                            >
                              <Plus className="h-5 w-5" aria-hidden="true" />
                            </Button>
                          </div>

                          <div className="absolute right-0 top-10">
                            <Button
                              aria-label="Remove product"
                              onClick={() => decreaseQuantity(product.id)}
                              variant="ghost"
                            >
                              <Minus className="h-5 w-5" aria-hidden="true" />
                            </Button>
                          </div>

                          <div className="absolute right-0 top-20">
                            <Button
                              aria-label="Remove product"
                              onClick={() => removeItem(product.id)}
                              variant="ghost"
                            >
                              <X className="h-5 w-5" aria-hidden="true" />
                            </Button>
                          </div>
                        </div>
                      </div>
                    </div>
                  </li>
                );
              })}
            </ul>
          </div>

          <section className="mt-16 rounded-lg bg-gray-50 dark:bg-zinc-800 px-4 py-6 sm:p-6 lg:col-span-5 lg:mt-0 lg:p-8">
            <h2 className="text-lg font-medium text-gray-900 dark:text-gray-50">
              Order Summary
            </h2>

            <div className="mt-6 space-y-4">
              <div className="flex items-center justify-between">
                <p className="text-sm text-gray-600 dark:text-gray-50">
                  Subtotal
                </p>
                <p className="text-sm font-medium text-gray-900 dark:text-gray-50">
                  {cartTotal}
                </p>
              </div>

              <div className="flex items-center justify-between border-t border-gray-200 pt-4">
                <div className="flex items-center text-sm text-muted-foreground">
                  <span>Flat Transaction Fee</span>
                </div>

                <div className="text-sm font-medium text-gray-900 dark:text-gray-50">
                  {1}
                </div>
              </div>

              <div className="flex items-center justify-between border-t border-gray-200 pt-4">
                <div className="text-base font-medium text-gray-900 dark:text-gray-50">
                  Order Total
                </div>

                <div className="text-base font-medium text-gray-900 dark:text-gray-50">
                  {cartTotal + 1}
                </div>
              </div>
            </div>

            <div className="mt-6">
              <Button
                disabled={items.length === 0}
                className="w-full"
                size="lg"
              >
                Checkout
              </Button>
            </div>
          </section>
        </div>
      </div>
    </div>
  );
};

export default CartPage;

That's it for this tutorial, we created cart page and cart components.

Next tutorial we'll create my orders page and api route for it.

0
0

Comments (0)