[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/styles/configs/style.json from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
    "typeScale": [
        3, 2.25, 1.5, 1.25, 1, 0.875, 0.75
      ],
      "spacing": [0.125, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 8, 16],
      "customMedia": [
        { "s": 20 },
        { "ns": {
            "value": 40,
            "minWidth": true
          }
        },
        { "m": {
            "value": 40,
            "minWidth": true
          }
        },
        { "l": {
          "value": 64,
          "minWidth": true
        }
        },
        { "xl": {
            "value": 80,
            "minWidth": true
          }
        }
      ],
      "colors": {
        "black-90": "rgba(0,0,0,.9)",
        "black-80": "rgba(0,0,0,.8)",
        "black-70": "rgba(0,0,0,.7)",
        "black-60": "rgba(0,0,0,.6)",
        "black-50": "rgba(0,0,0,.5)",
        "black-40": "rgba(0,0,0,.4)",
        "black-30": "rgba(0,0,0,.3)",
        "black-20": "rgba(0,0,0,.2)",
        "black-10": "rgba(0,0,0,.1)",
        "black-05": "rgba(0,0,0,.05)",
        "black-025": "rgba(0,0,0,.025)",
        "black-0125": "rgba(0,0,0,.0125)",

        "white-90": "rgba(255,255,255,.9)",
        "white-80": "rgba(255,255,255,.8)",
        "white-70": "rgba(255,255,255,.7)",
        "white-60": "rgba(255,255,255,.6)",
        "white-50": "rgba(255,255,255,.5)",
        "white-40": "rgba(255,255,255,.4)",
        "white-30": "rgba(255,255,255,.3)",
        "white-20": "rgba(255,255,255,.2)",
        "white-10": "rgba(255,255,255,.1)",
        "white-05": "rgba(255,255,255,.05)",
        "white-025": "rgba(255,255,255,.025)",
        "white-0125": "rgba(255,255,255,.0125)"
      },
      "semanticColors": {
        "background": {
          "base": "#ffffff",
          "base--inverted": "#03044e",
          "action-primary": "#52BAB7",
          "action-secondary": "#E8CCC9",
          "emphasis": "#f71963",
          "disabled": "#f2f4f5",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "hover-background": {
          "action-primary": "#45A6A3",
          "action-secondary": "#DCC0BD",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#e13232",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "active-background": {
          "action-primary": "#3D9391",
          "action-secondary": "#CAABA8",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "text": {
          "action-primary": "#0F3E99",
          "action-secondary": "#eef3f7",
          "link": "#0F3E99",
          "emphasis": "#f71963",
          "disabled": "#979899",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#52bab7",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "visited-text": {
          "link": "#0c389f"
        },
        "hover-text": {
          "action-primary": "#072c75",
          "action-secondary": "#dbe9fd",
          "link": "#0c389f",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#e13232",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0"
        },
        "active-text": {
          "link": "#0c389f",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0"
        },
        "border": {
          "action-primary": "#52BAB7",
          "action-secondary": "#F7EEED",
          "emphasis": "#f71963",
          "disabled": "#e3e4e6",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "hover-border": {
          "action-primary": "#45A6A3",
          "action-secondary": "#DCC0BD",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#e13232",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "active-border": {
          "action-primary": "#3D9391",
          "action-secondary": "#CAABA8",
          "emphasis": "#dd1659",
          "success": "#8bc34a",
          "success--faded": "#eafce3",
          "danger": "#ff4c4c",
          "danger--faded": "#ffe6e6",
          "warning": "#ffb100",
          "warning--faded": "#fff6e0",
          "muted-1": "#727273",
          "muted-2": "#979899",
          "muted-3": "#cacbcc",
          "muted-4": "#e3e4e6",
          "muted-5": "#f2f4f5"
        },
        "on": {
          "base": "#3f3f40",
          "base--inverted": "#ffffff",
          "action-primary": "#ffffff",
          "action-secondary": "#0F3E99",
          "emphasis": "#ffffff",
          "disabled": "#979899",
          "success": "#ffffff",
          "success--faded": "#3f3f40",
          "danger": "#ffffff",
          "danger--faded": "#3f3f40",
          "warning": "#ffffff",
          "warning--faded": "#1a1a1a",
          "muted-1": "#ffffff",
          "muted-2": "#ffffff",
          "muted-3": "#3f3f40",
          "muted-4": "#3f3f40",
          "muted-5": "#3f3f40"
        },
        "hover-on": {
          "action-primary": "#ffffff",
          "action-secondary": "#0F3E99",
          "emphasis": "#ffffff",
          "success": "#ffffff",
          "success--faded": "#3f3f40",
          "danger": "#ffffff",
          "danger--faded": "#3f3f40",
          "warning": "#ffffff",
          "warning--faded": "#1a1a1a"
        },
        "active-on": {
          "action-primary": "#ffffff",
          "action-secondary": "#0F3E99",
          "emphasis": "#ffffff",
          "success": "#ffffff",
          "success--faded": "#3f3f40",
          "danger": "#ffffff",
          "danger--faded": "#3f3f40",
          "warning": "#ffffff",
          "warning--faded": "#1a1a1a"
        }
      },
      "borderWidths": [0, 0.125, 0.25, 0.5, 1, 2],
      "borderRadius": [0, 0.125, 0.25, 0.5, 1],
      "widths": [1, 2, 4, 8, 16],
      "maxWidths": [1, 2, 4, 8, 16, 32, 48, 64, 96],
      "heights": [1, 2, 4, 8, 16],
      "sizes": [
        {"name": "small", "value": 2},
        {"name": "regular", "value": 2.5},
        {"name": "large", "value": 3}
      ],
      "typography":{
        "measure": [30, 34, 20],
        "styles": {
          "heading-1": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "700",
            "fontSize": "3rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "heading-2": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "500",
            "fontSize": "2.25rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "heading-3": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "700",
            "fontSize": "1.75rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "heading-4": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "normal",
            "fontSize": "1.5rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "heading-5": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "normal",
            "fontSize": "1.25rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "heading-6": {
            "fontFamily": "Playfair Display, serif",
            "fontWeight": "normal",
            "fontSize": "1.25rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "body": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "normal",
            "fontSize": "1rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "small": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "normal",
            "fontSize": "0.875rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "mini": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "normal",
            "fontSize": "0.75rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          },
          "action": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "500",
            "fontSize": "1rem",
            "textTransform": "uppercase",
            "letterSpacing": "0"
          },
          "action--small": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "500",
            "fontSize": "0.875rem",
            "textTransform": "uppercase",
            "letterSpacing": "0"
          },
          "action--large": {
            "fontFamily": "Roboto, San Francisco, -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif",
            "fontWeight": "500",
            "fontSize": "1.25rem",
            "textTransform": "uppercase",
            "letterSpacing": "0"
          },
          "code": {
            "fontFamily": "Consolas, monaco, monospace",
            "fontWeight": "normal",
            "fontSize": "1rem",
            "textTransform": "initial",
            "letterSpacing": "0"
          }
        }
      },
      "opacity": [1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05, 0.025, 0]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/product.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.product": {
    "children": [
      "flex-layout.row#product-breadcrumb",
      "flex-layout.row#product-main",
      "shelf#related"
    ]
  },

  "shelf#related": {
    "blocks": ["product-summary.shelf"],
    "props": {
      "recomendation": "editor.relatedProducts.similars",
      "orderBy": "OrderByTopSaleDESC",
      "productList": {
        "maxItems": 10,
        "itemsPerPage": 5,
        "minItemsPerPage": 1.5,
        "scroll": "BY_PAGE",
        "arrows": true,
        "titleText": "More options for this style"
      }
    }
  },

  "flex-layout.row#product-breadcrumb": {
    "props": {
      "marginTop": 20
    },
    "children": ["breadcrumb"]
  },
  "flex-layout.row#product-main": {
    "props": {
      "colGap": 9,
      "rowGap": 7,
      "marginTop": 4,
      "marginBottom": 7,
      "paddingTop": 7,
      "paddingBottom": 7,
      "blockClass": "product-main"
    },
    "children": [
      "flex-layout.col#stack",
      "flex-layout.col#right-col"
    ]
  },

  "stack-layout": {
    "children": [
      "flex-layout.row#product-image",
      "product-specification-badges"
    ]
  },

  "product-specification-badges": {
    "props": {
      "specificationGroupName": "Group",
      "specificationName": "On Sale",
      "visibleWhen": "True",
      "displayValue": "SPECIFICATION_NAME"
    }
  },

  "flex-layout.col#stack": {
    "children": ["stack-layout"],
    "props": {
      "width": "70%",
      "rowGap": 0
    }
  },

  "flex-layout.row#product-image": {
    "children": ["product-images"]
  },

  "product-images": {
    "props": {
      "displayThumbnailsArrows": true,
      "thumbnailsOrientation": "vertical"
    }
  },

  "flex-layout.col#right-col": {
    "props": {
      "preventVerticalStretch": true,
      "rowGap": 0
    },
    "children": [
      "product-name",
      "product-price#product-details",
      "sku-selector",
      "flex-layout.row#buy-button",
      "shipping-simulator",
      "share#default"
    ]
  },

  "product-price#product-details": {
    "props": {
      "showInstallments": true,
      "showSavings": true
    }
  },

  "flex-layout.row#buy-button": {
    "props": {
      "marginTop": 4,
      "marginBottom": 7
    },
    "children": ["buy-button"]
  },

  "share#default": {
    "props": {
      "social": {
        "Facebook": true,
        "WhatsApp": true,
        "Twitter": false,
        "Pinterest": true
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/search.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.search": {
    "blocks": ["search-result-layout#cat"]
  },

  "store.search#brand": {
    "blocks": ["search-result-layout"],
    "props": {
      "context": {
        "orderByField": "OrderByReleaseDateDESC",
        "hideUnavailableItems": true,
        "maxItemsPerPage": 10
      }
    }
  },

  "store.search#department": {
    "blocks": ["search-result-layout#department"]
  },

  "store.search#category": {
    "blocks": ["search-result-layout#cat"]
  },

  "store.search#subcategory": {
    "blocks": ["search-result-layout#cat"]
  },

  "search-result-layout#department": {
    "blocks": [
      "search-result-layout.desktop#dep",
      "search-result-layout.mobile#dep",
      "search-not-found-layout"
    ]
  },
  "search-result-layout#cat": {
    "blocks": [
      "search-result-layout.desktop#cat",
      "search-result-layout.mobile#cat",
      "search-not-found-layout"
    ]
  },

  "info-card#depbanner": {
    "props": {
      "imageUrl": "https://image.shutterstock.com/z/stock-photo-party-with-best-friends-group-of-cheerful-young-people-enjoying-home-party-with-snacks-and-drinks-492006757.jpg",
      "callToActionMode": "none",
      "isFullModeStyle": true,
      "headline": " ",
      "blockClass": "depbanner"
    }
  },

  "search-result-layout.desktop#dep": {
    "children": [
      "flex-layout.row#depBanner",
      "flex-layout.row#searchbread",
      "flex-layout.row#searchtitle",
      "flex-layout.row#result"
    ],
    "props": {
      "pagination": "show-more",
      "mobileLayout": {
        "mode1": "small",
        "mode2": "normal"
      }
    }
  },
  "search-result-layout.desktop#cat": {
    "children": [
      "flex-layout.row#searchbread",
      "flex-layout.row#searchtitle",
      "flex-layout.row#result"
    ],
    "props": {
      "pagination": "show-more",
      "mobileLayout": {
        "mode1": "small",
        "mode2": "normal"
      }
    }
  },
  "flex-layout.row#searchbread": {
    "children": ["breadcrumb.search"],
    "props": {
      "preserveLayoutOnMobile": true,
      "fullWidth": true
    }
  },
  "flex-layout.row#searchtitle": {
    "children": ["search-title.v2"]
  },
  "flex-layout.row#result": {
    "children": ["flex-layout.col#filter", "flex-layout.col#content"],
    "props": {
      "preventHorizontalStretch": true,
      "fullWidth": true
    }
  },
  "flex-layout.col#filter": {
    "children": ["filter-navigator.v3"],
    "props": {
      "blockClass": "filterCol"
    }
  },
  "flex-layout.col#content": {
    "children": [
      "flex-layout.row#searchinfo",
      "flex-layout.row#fetchprevious",
      "flex-layout.row#products",
      "flex-layout.row#fetchmore"
    ],
    "props": {
      "width": "grow"
    }
  },
  "flex-layout.row#searchinfo": {
    "children": ["flex-layout.col#productCount", "flex-layout.col#orderby"]
  },
  "flex-layout.col#productCount": {
    "children": ["total-products.v2"],
    "props": {
      "blockClass": "productCountCol"
    }
  },
  "flex-layout.col#orderby": {
    "children": ["order-by.v2"],
    "props": {
      "blockClass": "orderByCol"
    }
  },
  "flex-layout.row#fetchprevious": {
    "props": {
      "marginBottom": 3
    },
    "children": ["search-fetch-previous"]
  },
  "flex-layout.row#fetchmore": {
    "props": {
      "marginTop": 3
    },
    "children": ["search-fetch-more"]
  },
  "flex-layout.row#products": {
    "children": ["search-content"]
  },
  "search-content": {
    "blocks": ["gallery", "not-found"]
  },

  "flex-layout.row#depBanner": {
    "children": [
      "info-card#depbanner"
    ]
  },

  "search-result-layout.mobile#dep": {
    "children": [
      "flex-layout.row#depBanner",
      "flex-layout.row#searchinfomobile",
      "flex-layout.row#searchbread",
      "flex-layout.row#productCountMobile",
      "flex-layout.row#contentmobile"
    ],
    "props": {
      "pagination": "show-more",
      "mobileLayout": {
        "mode1": "small",
        "mode2": "normal"
      }
    }
  },
  "search-result-layout.mobile#cat": {
    "children": [
      "flex-layout.row#searchinfomobile",
      "flex-layout.row#searchbread",
      "flex-layout.row#productCountMobile",
      "flex-layout.row#contentmobile"
    ],
    "props": {
      "pagination": "show-more",
      "mobileLayout": {
        "mode1": "small",
        "mode2": "normal"
      }
    }
  },
  "flex-layout.row#contentmobile": {
    "children": ["search-content"],
    "props": {
      "preserveLayoutOnMobile": true
    }
  },

  "flex-layout.row#searchinfomobile": {
    "children": [
      "flex-layout.col#orderByMobile",
      "flex-layout.col#filterMobile",
      "flex-layout.col#switcherMobile"
    ],
    "props": {
      "preserveLayoutOnMobile": true,
      "colSizing": "auto",
      "colJustify": "around"
    }
  },

  "flex-layout.col#orderByMobile": {
    "children": ["order-by.v2"],
    "props": {
      "blockClass": "orderByMobileCol"
    }
  },

  "flex-layout.row#productCountMobile": {
    "children": ["total-products.v2"],
    "props": {
      "blockClass": "productCountMobileRow"
    }
  },

  "flex-layout.col#filterMobile": {
    "children": ["filter-navigator.v3"],
    "props": {
      "blockClass": "filterMobileCol"
    }
  },
  "flex-layout.col#switcherMobile": {
    "children": ["search-layout-switcher"],
    "props": {
      "blockClass": "switcherMobileCol"
    }
  },
  "search-not-found-layout": {
    "children": ["flex-layout.row#searchbread", "flex-layout.row#notfound"]
  },

  "flex-layout.row#notfound": {
    "children": ["not-found"],
    "props": {
      "fullWidth": true
    }
  },

  "breadcrumb": {
    "props": {
      "showOnMobile": true
    }
  },

  "gallery": {
    "blocks": ["product-summary.shelf"]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/home/newsletter.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "flex-layout.row#newsletter": {
    "children": [
      "flex-layout.col#newsletter"
    ],
    "props": {
      "blockClass": "newsletter",
      "marginTop": 5
    }
  },
  "flex-layout.col#newsletter": {
    "children": [
      "rich-text#newsletter",
      "rich-text#style-text",
      "flex-layout.row#newsletter-container"
    ],
    "props": {
      "blockClass": "newsletter"
    }
  },
  "rich-text#style-text": {
    "props": {
      "textAlignment": "CENTER",
      "textPosition": "CENTER",
      "text": "Be first to receive exclusive offers and updates",
      "blockClass": "newsletter",
      "textColor": "c-muted-1"
    }
  },

  "rich-text#newsletter": {
    "props": {
      "textAlignment": "CENTER",
      "textPosition": "CENTER",
      "text": "Join our mailing list",
      "textColor": "c-muted-1",
      "font": "t-heading-2"
    }
  },

  "flex-layout.row#newsletter-container": {
    "children": [
      "newsletter#home"
    ],
    "props": {
      "blockClass": "newsletterContainer"
    }
  },

  "newsletter#home": {
    "props": {
      "hideLabel": true,
      "placeholder": ""
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/home/styles-section.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json

{
  "slider-layout#styles": {
    "props": {
      "itemsPerPage": {
        "desktop": 1,
        "tablet": 1,
        "mobile": 1
      },
      "blockClass": "styles",
      "showPaginationDots": "never"
    },
    "children": [
      "image#style1",
      "image#style2"
    ]
  },
  "image#style1": {
    "props": {
      "src":"https://user-images.githubusercontent.com/194400/49531010-48dad180-f8b1-11e8-8d89-1e61320e1d82.png"
    }
  },
  "image#style2": {
    "props": {
      "src": "https://user-images.githubusercontent.com/194400/49531010-48dad180-f8b1-11e8-8d89-1e61320e1d82.png"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/home/home.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.home": {
    "blocks": [
      "flex-layout.row#slider",
      "shelf#new-arrivals",
      "shelf#clearence",
      "flex-layout.row#newsletter",
      "rich-text#brands",
      "flex-layout.row#brands",
      "rich-text#instagram",
      "flex-layout.row#instagram"
    ]
  },

  "carousel#home": {
    "props": {
      "autoplay": true,
      "autoplaySpeed": 4,
      "banners": [],
      "height": 440,
      "showArrows": true,
      "showDots": true
    }
  },

  "flex-layout.row#slider": {
    "children": [
      // "slider-layout#styles",
      "carousel#home"
    ]
  },

  "flex-layout.row#brands": {
    "children": [
      "slider-layout#brands"
    ],
    "props": {
      "marginTop": 4,
      "marginBottom": 8
    }
  },

  "shelf#new-arrivals": {
    "blocks": ["product-summary.shelf"],
    "props": {
      "orderBy": "OrderByTopSaleDESC",
      "paginationDotsVisibility": "never",
      "collection": "139",
      "productList": {
        "maxItems": 9,
        "itemsPerPage": 3,
        "minItemsPerPage": 1.5,
        "scroll": "BY_PAGE",
        "arrows": true,
        "titleText": "New arrivals"
      }
    }
  },

  "shelf#clearence": {
    "blocks": ["product-summary.shelf"],
    "props": {
      "orderBy": "OrderByTopSaleDESC",
      "collection": "140",
      "paginationDotsVisibility": "desktopOnly",
      "productList": {
        "maxItems": 9,
        "itemsPerPage": 3,
        "minItemsPerPage": 1.5,
        "scroll": "BY_PAGE",
        "arrows": true,
        "titleText": "Clearence"
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/home/instagram.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "rich-text#instagram": {
    "props": {
      "textAlignment": "CENTER",
      "textPosition": "CENTER",
      "text": "Visit us on Instagram",
      "blockClass": "ocasiao",
      "textColor": "c-muted-1",
      "font": "t-heading-2"
    }
  },

  "flex-layout.row#instagram": {
    "children": [
      "flex-layout.col#instagram-post1",
      "flex-layout.col#instagram-post2",
      "flex-layout.col#instagram-post3",
      "flex-layout.col#instagram-post4"
    ]
  },
  "flex-layout.col#instagram-post1": {
    "children": [
      "sandbox#instagram-post1"
    ]
  },
  "flex-layout.col#instagram-post2": {
    "children": [
      "sandbox#instagram-post2"
    ]
  },
  "flex-layout.col#instagram-post3": {
    "children": [
      "sandbox#instagram-post3"
    ]
  },
  "flex-layout.col#instagram-post4": {
    "children": [
      "sandbox#instagram-post4"
    ]
  },
  "sandbox#instagram-post1": {
    "props": {
      "initialContent": "<iframe src=\"https://www.instagram.com/p/B33OxNrHlhU/embed\" height=460 frameBorder=\"0\"/>"
    }
  },
  "sandbox#instagram-post2": {
    "props": {
      "initialContent": "<iframe src=\"https://www.instagram.com/p/ByIy5EVhT6t/embed\" height=460 frameBorder=\"0\"/>"
    }
  },
  "sandbox#instagram-post3": {
    "props": {
      "initialContent": "<iframe src=\"https://www.instagram.com/p/BxUV2aIhnBr/embed\" height=460 frameBorder=\"0\"/>"
    }
  },
  "sandbox#instagram-post4": {
    "props": {
      "initialContent": "<iframe src=\"https://www.instagram.com/p/BxZtvPShdRW/embed\" height=460 frameBorder=\"0\"/>"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/home/brands.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "rich-text#brands": {
    "props": {
      "textAlignment": "CENTER",
      "textPosition": "CENTER",
      "text": "Our brands",
      "blockClass": "ocasiao",
      "textColor": "c-muted-1",
      "font": "t-heading-2"
    }
  },

  "slider-layout#brands": {
    "children": [
      "image#brand-1",
      "image#brand-2",
      "image#brand-3",
      "image#brand-4",
      "image#brand-5",
      "image#brand-6",
      "image#brand-7",
      "image#brand-8"
    ],
    "props": {
      "itemsPerPage": {
        "desktop": 4,
        "tablet": 4,
        "phone": 2
      },
      "navigationStep": 2,
      "showPaginationDots": "never"
    }
  },

  "image#brand-1": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square1.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-2": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square2.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-3": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square3.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-4": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square4.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-5": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square5.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-6": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square6.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-7": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square7.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  },

  "image#brand-8": {
    "props": {
      "src": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square8.png",
      "maxWidth": "140px",
      "maxHeight": "100px",
      "link": "https://alfredo--appliancetheme.myvtex.com/major-appliances"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/footer/footer.json from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "footer": {
    "blocks": ["footer-layout.desktop", "footer-layout.mobile"]
  },
  "footer-layout.desktop": {
    "children": [
      "flex-layout.row#footer-1-desktop"
    ]
  },
  "flex-layout.row#footer-1-desktop": {
    "children": [
      "flex-layout.col#footer-left-desktop",
      "flex-layout.col#footer-right-desktop"
    ],
    "props": {
      "blockClass": "footer-row",
      "paddingTop": 7,
      "paddingBottom": 7
    }
  },

  "flex-layout.col#footer-left-desktop": {
    "children": ["vtex.menu@2.x:menu#category-menu"],
    "props": {
      "blockClass": "footer-menu"
    }
  },

  "flex-layout.col#footer-right-desktop": {
    "children": ["accepted-payment-methods"],
    "props": {
      "blockClass": "footer-payment-methods"
    }
  },

  "accepted-payment-methods": {
    "props": {
      "paymentMethods": ["MasterCard", "Visa", "Diners Club"]
    }
  },
  "footer-layout.mobile": {

    "children": [
      "flex-layout.row#mid-footer"
    ]
  },
  "flex-layout.row#mid-footer": {
    "props": {
      "blockClass": "footer-row"
    },
    "children": [
      "flex-layout.col#colFoot"
    ]
  },

  "flex-layout.col#colFoot": {
    "children": [
      "vtex.menu@2.x:menu#footer"
    ]
  },
  "vtex.menu@2.x:menu#footer": {
    "props": {
      "orientation": "vertical"
    },
    "children": [
      "menu-item#category-electronics",
      "menu-item#category-major-appliances",
      "menu-item#category-small-appliances"
    ]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/footer/category-menu.json from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "vtex.menu@2.x:menu#category-menu": {
    "children": [
      "menu-item#category-electronics",
      "menu-item#category-major-appliances",
      "menu-item#category-small-appliances"
    ]
  },
  "menu-item#category-electronics": {
    "props": {
      "id": "menu-item-category-electronics",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/electronics/",
        "noFollow": true,
        "tagTitle": "Electronics",
        "text": "Electronics"
      }
    }
  },

  "menu-item#category-major-appliances": {
    "props": {
      "id": "menu-item-category-major-appliances",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/major-appliances/",
        "noFollow": true,
        "tagTitle": "Major Appliances",
        "text": "Major Appliances"
      }
    }
  },
  "menu-item#category-small-appliances": {
    "props": {
      "id": "menu-item-category-small-appliances",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/sale/d",
        "noFollow": true,
        "tagTitle": "Small appliances",
        "text": "Small appliances"
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/custom/styles-page.json from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.custom#styles": {
    "blocks": [
      "flex-layout.row#style-slider",
      "shelf#styles",
      "flex-layout.row#pink",
      "search-result#styles"
    ]
  },

  "flex-layout.row#style-slider": {
    "children": [
      "info-card#styles"
    ]
  },

  "info-card#styles": {
    "props": {
      "imageUrl": "https://image.shutterstock.com/z/stock-photo-party-with-best-friends-group-of-cheerful-young-people-enjoying-home-party-with-snacks-and-drinks-492006757.jpg",
      "callToActionMode": "none",
      "isFullModeStyle": true,
      "headline": " ",
      "blockClass": "depbanner"
    }
  },

  "shelf#styles": {
    "blocks": ["product-summary.shelf"],
    "props": {
      "orderBy": "OrderByTopSaleDESC",
      "paginationDotsVisibility": "never",
      "collection": "139",
      "productList": {
        "maxItems": 10,
        "itemsPerPage": 3,
        "minItemsPerPage": 1.5,
        "scroll": "BY_PAGE",
        "arrows": true,
        "titleText": ""
      }
    }
  },

  "flex-layout.row#pink": {
    "props":{
      "horizontalAlign": "center",
      "blockClass": "pinkRow"
    },
    "children": [
      "flex-layout.col#pink"
    ]
  },

  "flex-layout.col#pink": {
    "props":{
      "blockClass": "pinkCol",
      "horizontalAlign": "center",
      "verticalAlign": "center"

    },
    "children": [
      "rich-text#concepts-title",
      "rich-text#concepts"
    ]
  },

  "rich-text#concepts-title": {
    "props": {
      "font": "t-heading-2",
      "textColor": "c-muted-1",
      "text": "A new concept",
      "textAlignment": "CENTER",
      "textPosition": "CENTER"
    }
  },

  "rich-text#concepts": {
    "props": {
      "textColor": "c-muted-1",
      "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque id consectetur erat. Etiam nulla eros, scelerisque laoreet consequat sit amet, pharetra nec nibh. Nulla porta non sapien sed feugiat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ullamcorper justo enim, dictum vehicula mauris volutpat quis.",
      "textAlignment": "CENTER",
      "textPosition": "CENTER"
    }
  },

  "search-result#styles": {
    "blocks": [
      "gallery",
      "not-found",
      "order-by",
      "total-products",
      "search-title"
    ],
    "props": {
      "context": {
        "maxItemsPerPage": 2,
        "orderByField": "OrderByReleaseDateDESC"
      },
      "pagination": "show-more"
    }
  }

}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/header/category-menu.json from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "vtex.menu@2.x:menu#category-menu": {
    "children": [
      "menu-item#category-electronics",
      "menu-item#category-major-appliances",
      "menu-item#category-small-appliances"
    ]
  },
  "menu-item#category-electronics": {
    "props": {
      "id": "menu-item-category-electronics",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/electronics/",
        "noFollow": true,
        "tagTitle": "Electronics",
        "text": "Electronics"
      }
    }
  },

  "menu-item#category-major-appliances": {
    "props": {
      "id": "menu-item-category-major-appliances",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/major-appliances/",
        "noFollow": true,
        "tagTitle": "Major Appliances",
        "text": "Major Appliances"
      }
    }
  },
  "menu-item#category-small-appliances": {
    "props": {
      "id": "menu-item-category-small-appliances",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/small-appliances",
        "noFollow": true,
        "tagTitle": "Small appliances",
        "text": "Small appliances"
      }
    }
  },
  "menu-item#login": {
    "props": {
      "id": "menu-item-custom-login",
      "type": "custom",
      "iconId": null,
      "highlight": false,
      "itemProps": {
        "type": "internal",
        "href": "/account",
        "noFollow": true,
        "tagTitle": "My account",
        "text": "My account"
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of assemblers-theme/store/blocks/header/header.jsonc from the assemblers-theme VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "header": {
    "blocks": [
      "header-layout.desktop",
      "header-layout.mobile"
    ]
  },
  "header.full": {
    "blocks": [
      "header-layout.desktop",
      "header-layout.mobile"
    ]
  },
  "header-layout.desktop": {
    "children": [
      "header-row#4-desktop",
      "header-row#5-desktop"
    ]
  },

  "header-row#4-desktop": {
    "children": [
      "logo#desktop"
    ],
    "props": {
      "sticky": true,
      "blockClass": "main-header"
    }
  },

  "header-row#5-desktop": {
    "children": [
      "vtex.menu@2.x:menu#category-menu",
      "header-spacer",
      "header-spacer",
      "search-bar",
      "login",
      "minicart"
    ],
    "props": {
      "blockClass": "main-topbar"
    }
  },

  "logo#desktop": {
    "props": {
      "title": "Logo",
      "href": "/",
      "url": "https://appliancetheme.vteximg.com.br/arquivos/flatflat-logo-large.png",
      "width": "110"
    }
  },

  "minicart": {
    "blocks": [
      "product-summary"
    ],
    "props": {
      "type": "popup",
      "showRemoveButton": true,
      "showDiscount": true,
      "showSku": true,
      "labelMiniCartEmpty": "",
      "labelButtonFinishShopping": "Go to checkout",
      "enableQuantitySelector": true,
      "maxQuantity": 10,
      "labelClasses": "gray"
    }
  },

  "header-layout.mobile": {
    "children": [
      "header-row#1-mobile"
    ]
  },

  "header-row#1-mobile": {
    "children": [
      "drawer",
      "logo#mobile",
      "header-spacer",
      "header-spacer",
      "minicart"
    ],
    "props": {
      "sticky": true,
      "blockClass": "main-header-mobile"
    }
  },

  "drawer": {
    "children": [
      "menu#drawer"
    ]
  },

  "menu#drawer": {
    "children": [
      "menu-item#category-electronics",
      "menu-item#category-major-appliances",
      "menu-item#category-small-appliances",
      "menu-item#login"
    ],
    "props": {
      "orientation": "vertical"
    }
  },

  "logo#mobile": {
    "props": {
      "title": "Logo",
      "href": "/",
      "url": "https://storecomponents.vteximg.com.br/arquivos/store-theme-logo-mobile.png",
      "width": "70"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/pages/pages.json from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "pages": {
    "bubbles": {
      "path": "/bubbles",
      "auth": true
    }
  },
  "extensions": {
    "bubbles": {
      "component": "Bubbles",
      "ssr": false
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/global.css from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```css
@import '//io.vtex.com.br/fonts/fabriga/stylesheet.css';

html,
body,
#render-container,
#render-provider,
.render-container,
.render-provider,

/* Fixes Safari position:fixed + z-index bug https://www.queness.com/code-snippet/16824/fix-mobile-safari-positionfixed-and-z-index-issue */
.safari-positioning {
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
}

.font-display,
.font-body {
  font-family: 'Fabriga', 'Helvetica Neue', 'Arial', sans-serif;
}

body {
  margin: 0;
  padding: 0;
  overflow-y: hidden;
  background: #142032;
}

.container{
	width: 100vw;
  height: 100vh;
	position: relative;
}

a[href^="http://maps.google.com/maps"]{display:none !important}
a[href^="https://maps.google.com/maps"]{display:none !important}

.gmnoprint a, .gmnoprint span, .gm-style-cc {
    display:none;
}

.logovtex {
  position: absolute;
  z-index: 9999;
  bottom: 10px;
  left: 15px;
  width: 250px;
  /* opacity: .5; */
}

#stats {
  z-index: 9999;
  display: none;
}

.image {
  position: absolute;
  z-index: 1;
  bottom: 20px;
  right: 35px;
}

.clip-svg {
  background-color: #fff;
  width: 380px;
  min-height: 380px;
  height: auto;
  border-radius: 20px;
  padding: 8px;
  /*border: 7px solid #F71963;*/
}

.label {
  position: absolute;
  bottom: 0;
  width: 90%;
  left: 5%;
}

.t { z-index: 9999; position: absolute; width: 200px; }

@keyframes pulse {
  0%{
    transform: scale(0) translate3d(0,0,0);
  }
  3%{
    transform: scale(0) translate3d(0,0,0);
  }
  100%{
    transform: scale(1.0) translate3d(0,0,0);
  }
}

@keyframes fade {
  0%{
    opacity: 0.7;
  }
  3%{
    opacity: 0.7;
  }
  100%{
    opacity: 0;
  }
}

@keyframes shrink {
  0%{
    transform: scale(0) translate3d(0,0,0);
  }
  3%{
    transform: scale(1) translate3d(0,0,0);
  }
  100%{
    transform: scale(0) translate3d(0,0,0);
  }
}

.Marker-point,
.Marker-pulse {
  background:#F71963;
  border-radius:100%;
  position:absolute;
  width:30px;
  height:30px;
  top:-15px;
  left:-15px;
}
.Marker-point {
  width:16px;
  height:16px;
  top:-8px;
  left:-8px;
  /* animation: shrink cubic-bezier(0.000, 1.035, 0.220, 1.000) 20s both; */
  animation: shrink ease-out 2.5s both;
}
.Marker-pulse {
  width:200px;
  height:200px;
  top:-100px;
  left:-100px;
  animation: pulse cubic-bezier(0.165, 0.840, 0.440, 1.000) 2.5s both, fade cubic-bezier(0.000, 0.875, 0.375, 1.010) 2.5s both;
}

.x1 .Marker-pulse {
  width:80px;
  height:80px;
  top:-40px;
  left:-40px;
}
.x2 .Marker-pulse {
  width:100px;
  height:100px;
  top:-50px;
  left:-50px;
}
.x3 .Marker-pulse {
  width:150px;
  height:150px;
  top:-75px;
  left:-75px;
}
.x4 .Marker-pulse {
  width:180px;
  height:180px;
  top:-90px;
  left:-90px;
}
.x5 .Marker-pulse {
  width:200px;
  height:200px;
  top:-100px;
  left:-100px;
}

.x1 .Marker-point {
  /* animation-duration: 2s; */
}
.x2 .Marker-point {
  /* animation-duration: 5s; */
}
.x3 .Marker-point {
  /* animation-duration: 10s; */
}
.x4 .Marker-point {
  /* animation-duration: 20s; */
}
.x5 .Marker-point {
  /* animation-duration: 20s; */
}

#overlay,
#image-gallery,
#map,
#map-borders,
#heatmap {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 999;
  pointer-events:none;
}

#overlay {
  /* mix-blend-mode: lighten; */
}

#heatmap{
  opacity: 0.3;
}

#world-map {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
}

.login {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 99999;
}

.reset {
  display: none;
  position: fixed;
  left: 150px;
  top: 0;
  z-index: 99999;
}

.loading {
  display: none;
  position: fixed;
  left: 20px;
  top: 10px;
  color:#fff;
  pointer-events: none;
  z-index: 99999;
}

.valid {
  display: none;
  position: fixed;
  top: 60px;
  left: 20px;
  color: #fff;
  pointer-events: none;
  z-index: 99999;
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/typings.d.ts from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

declare module 'vtex.styleguide' {
  import { ReactElement } from 'react'

  const Badge: ReactElement
  const Button: ReactElement
  const Checkbox: ReactElement
  const Dropdown: ReactElement
  const IconCaretRight: ReactElement
  const Input: ReactElement
  const Tab: ReactElement
  const Tabs: ReactElement
  const Textarea: ReactElement
  const Radio: ReactElement
  const Spinner: ReactElement
  const PageHeader: ReactElement

  export { Badge, Button, Checkbox, Dropdown, IconCaretRight, Input, Tab, Tabs, Textarea, Radio, Spinner, PageHeader }
}

declare module 'render' {
  import { ReactElement } from 'react'
  import { Helmet } from 'react-helmet'

  const NoSSR: ReactElement
  const Link: ReactElement
  const withRuntimeContext: ReactElement

  export { NoSSR, Helmet, Link, withRuntimeContext }
}

interface Project {
  demoURL?: string
  description?: string
  edition?: string
  id?: string
  name?: string
  owner?: string
  team?: ProfileData[]
}

interface ProfileData {
  id: string
  name: string
  email: string
  picture: string
}

interface RuntimeProps {
  runtime: any
}

enum States {
  Registration = 'REGISTRATION',
  Running = 'RUNNING',
  Voting = 'VOTING',
  Results = 'RESULTS'
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/package.json from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.bubbles",
  "version": null,
  "scripts": {
    "lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'"
  },
  "dependencies": {
    "axios": "^0.18.0",
    "dat.gui": "^0.7.7",
    "stats.js": "^0.17.0"
  },
  "devDependencies": {
    "@types/graphql": "^0.13.3",
    "@types/node": "^9.4.7",
    "@types/prop-types": "^15.5.2",
    "@types/react": "^16.3.16",
    "@types/react-dom": "^16.0.5",
    "@types/react-helmet": "^5.0.5",
    "@types/react-intl": "^2.3.5",
    "graphql": "^0.13.0",
    "react": "^16.2.0",
    "react-apollo": "^2.0.4",
    "react-dom": "^16.2.0",
    "react-intl": "^2.4.0",
    "tslint": "^5.11.0",
    "tslint-config-vtex": "^2.0.0",
    "typescript": "3.9.7"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/Bubbles.tsx from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Helmet } from 'render'

import './js/daynightoverlay.js'
//@ts-ignore
import { IMAGE_ROOT, start } from './js/main.js'

import './global.css'

export default class Bubbles extends Component {
  public componentDidMount() {
    start()
    if (window.localStorage.getItem('autCookie')) {
      //@ts-ignore
      document.querySelector('.reset').style.display = 'block'
      setTimeout(() => {
        //@ts-ignore
        document.querySelector('.reset').style.display = 'none'
      }, 5*1000)
    }
  }

  private handleReset = () => {
    window.localStorage.removeItem('autCookie')
    window.location.reload()
  }

  private handleLogin = () => {
    const token = window.prompt('Paste token here:')
    window.localStorage.setItem('autCookie', String(token))
    try {
      //@ts-ignore
      document!.querySelector('.login')!.style.display = "none"
      //@ts-ignore
      document!.querySelector('.loading')!.style.display = "block"
    } catch(e){}
    // this.initGoogle(() => {
    //   const genericWindow = window as any
    //   const GoogleAuth = genericWindow.gapi.auth2.getAuthInstance()

    //   if (false) {
    //     // GoogleAuth.grantOfflineAccess().then((v: OfflineAccessResponse) =>
    //     //   exchangeCode(v)
    //     // )
    //   } else {
    //     GoogleAuth.signIn().then(
    //       () => {
    //         this.loginSucceed(GoogleAuth)
    //       },
    //       (error: any) => {
    //         // loginFailed()
    //         console.log('erro no login')
    //       }
    //     )
    //   }
    // }
  }

  private initGoogle = (callback: () => void) => {
    const genericWindow = window as any
    genericWindow.gapi.load('auth2', () => {
      genericWindow.gapi.auth2
        .init({
          client_id:
            '388920801697-jo8o228hlp7k5ifqhosum7tqml2br3kh.apps.googleusercontent.com',
        })
        .then(callback)
    })
  }

  private loginSucceed = (GoogleAuth: any) => {
    const profile = GoogleAuth.currentUser.get().getBasicProfile()
    console.log('login funcionou')
    console.log(profile)
    // if (!profile) {
    //   loginFailed()
    //   return
    // }
    // const email = profile.getEmail()
    // const image = profile.getImageUrl()
    // if (email.split('@')[1] === 'vtex.com.br') {
    //   props.cookies.set(
    //     keepLogged ? props.COOKIE_NAME : props.TEMPORARY_COOKIE_NAME,
    //     GoogleAuth.currentUser.get().getAuthResponse().id_token,
    //     {
    //       maxAge: 2147483647,
    //     }
    //   )
    //   props.setEmail(email)
    //   props.setImageUrl(image)
    //   props.setLogin(true)
    // } else {
    //   setInvalidUser(true)
    //   props.setLogin(false)
    // }
  }

  public render() {
    return (
      <div>
        <Helmet>
          <title>VTEX Order Map</title>
          <link rel="shortcut icon" href="https://io.vtex.com.br/favico/1.3.0/favico.ico"></link>
          <script src="https://io.vtex.com.br/front-libs/jquery/2.0.3/jquery-2.0.3.min.js"></script>
          <script src="https://vtexid.vtex.com.br/api/vtexid/pub/authentication/vtexid.min.js"></script>
        </Helmet>
        <div className="container" id="container" style={{ background: '#142032' }}>
          <canvas id="map"></canvas>
          {/* <canvas id="heatmap"></canvas> */}
          <canvas id="overlay"></canvas>
          <canvas id="map-borders"></canvas>
          <canvas id="image-gallery"></canvas>
          <a href="https://en.vtex.com/" rel="noopener noreferrer" target="_blank">
            <img src={`${IMAGE_ROOT}/vtex-logo.svg`} className="logovtex" alt="Logo VTEX"/>
          </a>
        </div>
        <div id="stats"></div>
        <button onClick={this.handleLogin} className="login">Login</button>
        <button onClick={this.handleReset} className="reset">Reset Token</button>
        <div className="loading">Connecting...</div>
        <div className="valid"></div>
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/js/main.js from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```javascript
import axios from 'axios'
import Stats from 'stats.js'

const stats = new Stats()
stats.showPanel(0)

const isLinked = window && window.location && window.location.hostname.match('myvtex.com')

const IMAGE_ROOT = isLinked
? `/_v/private/assets/v1/linked/${process.env.VTEX_APP_ID}/public/img`
: `https://vtexpages.vteximg.com.br/_v/public/assets/v1/published/${process.env.VTEX_APP_ID}/public/img`

function Queue(){var a=[],b=0;this.getLength=function(){return a.length-b};this.isEmpty=function(){return 0==a.length};this.enqueue=function(b){a.push(b)};this.dequeue=function(){if(0!=a.length){var c=a[b];2*++b>=a.length&&(a=a.slice(b),b=0);return c}};this.peek=function(){return 0<a.length?a[b]:void 0}};

const start = () => {
  var heatmap
  var heatmapData=[]
  var markers = []
  var images = []
  var markerInterval
  var messageInterval
  var timeConnect
  var connection
  var nextTime
  var queueImage = new Queue()
  var queueMarker = new Queue()
  var pendingMarkers = 0
  var pulseCanvas = document.querySelector('#overlay')
  var pulseContext = pulseCanvas.getContext('2d')
  var pulseResolution = 1
  // var heatmapCanvas = document.querySelector('#heatmap')
  // var heatmapContext = heatmapCanvas.getContext('2d')
  var galleryCanvas = document.querySelector('#image-gallery')
  var galleryContext = galleryCanvas.getContext('2d')
  var galleryResolution = 0.8
  var mapCanvas = document.querySelector('#map')
  var mapContext = mapCanvas.getContext('2d')
  var bordersMapCanvas = document.querySelector('#map-borders')
  var bordersMapContext = bordersMapCanvas.getContext('2d')
  var dayMapURL = `${IMAGE_ROOT}/world-map-2.svg`
  var nightMapURL = `${IMAGE_ROOT}/world-map-2-night.svg`
  var bordersMapURL = `${IMAGE_ROOT}/world-map-2-borders.svg`
  var nightBordersMapURL = `${IMAGE_ROOT}/world-map-2-night-borders.svg`
  var fps = 60
  var frame = 1000 / fps
  var errorCount = 0
  const imagesLimit = 200

  var dayMapImage
  var nightMapImage
  var bordersMapImage
  var nightBordersMapImage

  // size of the map image
  var mapWidth = 1009
  var mapHeight = 665

  var mapViewBounds = {
    bottomLeft: {
      x:50,
      y:600,
    },
    topRight: {
      x:900,
      y:280,
    }
  }

  var boundsSize = {
    width: mapViewBounds.topRight.x - mapViewBounds.bottomLeft.x,
    height: mapViewBounds.bottomLeft.y - mapViewBounds.topRight.y,
  }

  var boundsRatios = {
    width: mapWidth / boundsSize.width,
    height: mapHeight / boundsSize.height,
  }
  var boundsRatio = boundsSize.width/boundsSize.height
  var windowRatio = window.innerWidth/window.innerHeight
  var mapScale
  var mapOffset

  if (windowRatio < boundsRatio) {
    mapScale = window.innerWidth / boundsSize.width
    mapOffset = {
      x: -mapViewBounds.bottomLeft.x,
      y: -mapViewBounds.topRight.y + ((window.innerHeight/mapScale) - boundsSize.height)/2,
    }
  } else {
    mapScale = window.innerHeight / boundsSize.height
    mapOffset = {
      y: -mapViewBounds.topRight.y,
      x: -mapViewBounds.bottomLeft.x + ((window.innerWidth/mapScale) - boundsSize.width)/2,
    }
  }

  document.querySelector('#stats').appendChild(stats.dom)
  // AQUI
  // document.querySelector("#world-map").style.transform = "scale("+mapScale+") translate3d("+mapOffset.x+"px, "+mapOffset.y+"px, 0)"

  // Hardcoded rates for currency conversion. We don't need the most updated and precise numbers,
  //   just a slight idea of proportions.
  var conversionRates = {
    'ARS': 0.055,
    'BRL': 1,
    'CLP': 0.0068,
    'COP': 0.0014,
    'MXN': 0.26,
    'PEN': 1.38,
    'PYG': 0.00082,
    'RON': 1.26,
    'USD': 5.57,
    'CAD': 4.40,
    'UYU': 0.13,
    'EUR': 6.24,
    'CRC': 0.0087,
    'BOB': 0.81,
    'GTQ': 0.72,
  };

  function attempt() {
    console.log('attempt')
    connection = connect();
    if (localStorage.getItem('autCookie')) {
      document.querySelector('.loading').style.display='block'
    }
    openSocket();
  }

  function openSocket() {
    clearInterval(timeConnect)
    clearInterval(markerInterval)
    clearInterval(messageInterval)

    function onClose(event) {
      alert('on close '+String(event))
      setTimeout(attempt, 5000)
      // window.localStorage.removeItem('autCookie')
      // setTimeout(() => {
      //   var curAddress = window.location.href
      //   localStorage.removeItem('autCookie')
      //   // window.location.href = `/_v/auth-server/v1/login?ReturnUrl=${curAddress}`
      // }, 10000)

      // console.log('Closed')
      // clearInterval(timeConnect)
      // timeConnect = setInterval(openSocket, 1000)

      document.querySelector('.login').style.display = "block"
      document.querySelector('.loading').style.display='none'
    }

    function parseJwt (token) {
      try {
        var base64Url = token.split('.')[1];
        var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
        var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));

        return JSON.parse(jsonPayload);
      } catch (e) {
        return null
      }
    };

    function onError(event) {
      if (event) {
        // alert('on error '+event.message)
        console.log('error message', event)
        console.log(JSON.stringify(event))
        console.table(event)
      } else {
        // alert('on error, no event')
      }
      errorCount++
      if (errorCount > 2) {
        window.localStorage.removeItem('autCookie')
      }
      setTimeout(attempt, 5000)
      document.querySelector('.login').style.display = "block"
      document.querySelector('.loading').style.display='none'
    }

    function onOpen() {
      // Connected
      console.log('Connected')
      document.querySelector('.login').style.display='none'
      document.querySelector('.loading').style.display='none'
      updateTokenMessage({ initial: true })
    }

    function updateTokenMessage({ initial }) {
      const jwt = parseJwt(localStorage.getItem('autCookie'))
      if (!jwt) {
        return
      }
      const expiry = new Date(jwt.exp*1000)
      const remaining = (jwt.exp-Date.now()/1000)
      const remainingHours = Math.floor(remaining/60/60)
      const remainingMinutes = Math.floor(((remaining/60/60)-remainingHours)*60)

      if (remainingHours > 1 && !initial) {
        return
      }

      document.querySelector('.valid').style.display='block'
      document.querySelector('.valid').innerHTML = `Token valid until ${expiry}. <br> Please refresh the page and generate a new token before then. <br> ${remainingHours} hour(s) ${remainingMinutes} minute(s) left`
      if (initial) {
        setTimeout(() => {
          document.querySelector('.valid').style.display='none'
        }, 5 * 1000)
      }
    }

    if (!connection) {
      console.log('no autCookie, no connection')
      onError()
      return
    }

    connection.onopen = onOpen
    connection.onerror = onError
    connection.onclose = onClose

    connection.onmessage = function onMessage (msg) {
      // console.log(msg.data)
      queueMarker.enqueue(msg.data)
      nextTime = getNextTime()
      errorCount = 0
    };

    markerInterval = setInterval(function handleMarkerQueue() {
      var now = new Date()
      var _nextTime = nextTime || getNextTime()
      var slots = Math.floor( (_nextTime - now.getTime()) / 2000)
      var chunk = 0

      if (slots > 0) {
        chunk = Math.ceil( queueMarker.getLength()/slots);
      }

      for (var i = chunk; i >= 0; i--) {
        moveQueue(chunk ? i*2000/chunk : 1)
      }

    }, 2000)

    messageInterval = setInterval(() => {
      updateTokenMessage({})
    }, 1000 * 60)

    function moveQueue(time) {
      pendingMarkers++
      var timeVariation=time*0.2
      setTimeout(function moveQueue() {
        if (!queueMarker.isEmpty()) {
          var markerData=queueMarker.dequeue()
          renderMarkers(markerData)
          pendingMarkers--
        }
      }, time + (-timeVariation + (Math.random()*timeVariation*2)))
    }

  } // End openSocket

  function connect() {
    console.log('connect')
    function getCookie(name) {
      var value = "; " + document.cookie;
      var parts = value.split("; " + name + "=");
      if (parts.length == 2) return parts.pop().split(";").shift();
    }
    // TEMP FIX
    var autCookie = getCookie('VtexIdclientAutCookie') || null
    var url = "https://storedash-api.vtex.com/api/storedash/orderStream"

    if (!autCookie) {
      autCookie = localStorage.getItem('autCookie')
    }

    // if (!autCookie || autCookie === 'null') {
    //   autCookie = window.prompt('authToken')
    //   localStorage.setItem('autCookie', autCookie)
    // }

    if(autCookie) {
      url+='?authToken='+autCookie
    }

    if (!autCookie) {
      return
    }

    var evtSource = new EventSource(url);

    // evtSource.onerror = function (event) {
    //   console.log("Couldn't connect to Storedash OrderStream evtSource.");
    //   document.querySelector('.login').style.display='block'
    //   attempt()
    // };

    return evtSource;
  }

  function initialize() {
    document.getElementById('container').style.height = window.innerHeight + 'px'

    dayMapImage = new Image()
    nightMapImage = new Image()
    bordersMapImage = new Image()
    nightBordersMapImage = new Image()
    Promise.all([
      new Promise(function(resolve) {
        dayMapImage.addEventListener('load', function() {
          resolve(dayMapImage)
        })
      }),
      new Promise(function(resolve) {
        nightMapImage.addEventListener('load', function() {
          resolve(nightMapImage)
        })
      }),
      new Promise(function(resolve) {
        bordersMapImage.addEventListener('load', function() {
          resolve(bordersMapImage)
        })
      }),
      new Promise(function(resolve) {
        nightBordersMapImage.addEventListener('load', function() {
          resolve(nightBordersMapImage)
        })
      }),
    ]).then(function(){

      mapCanvas.setAttribute('width', window.innerWidth)
      mapCanvas.setAttribute('height', window.innerHeight)

      mapContext.save()

      mapContext.scale(mapScale, mapScale)
      mapContext.translate(mapOffset.x, mapOffset.y)
      mapContext.drawImage(dayMapImage, 0, 0)

      mapContext.save()

      var overlay = new DayNightOverlay()
      overlay.onAdd()
      overlay.draw(mapContext, mapWidth, mapHeight+390)
      mapContext.clip()
      mapContext.drawImage(nightMapImage, 0, 0)

      bordersMapCanvas.setAttribute('width', window.innerWidth)
      bordersMapCanvas.setAttribute('height', window.innerHeight)

      bordersMapContext.save()

      bordersMapContext.scale(mapScale, mapScale)
      bordersMapContext.translate(mapOffset.x, mapOffset.y)
      bordersMapContext.drawImage(bordersMapImage, 0, 0)

      bordersMapContext.save()

      overlay.draw(bordersMapContext, mapWidth, mapHeight+390)
      bordersMapContext.clip()
      bordersMapContext.drawImage(nightBordersMapImage, 0, 0)
    })
    dayMapImage.src = dayMapURL
    nightMapImage.src = nightMapURL
    bordersMapImage.src = bordersMapURL
    nightBordersMapImage.src = nightBordersMapURL

    initCanvas()
  }

  function initCanvas() {
    pulseCanvas.setAttribute('width',window.innerWidth*pulseResolution)
    pulseCanvas.setAttribute('height',window.innerHeight*pulseResolution)
    pulseCanvas.style.width = window.innerWidth+'px'
    pulseCanvas.style.height = window.innerHeight+'px'
    // heatmapCanvas.setAttribute('width',window.innerWidth)
    // heatmapCanvas.setAttribute('height',window.innerHeight)
    galleryCanvas.setAttribute('width',window.innerWidth*galleryResolution)
    galleryCanvas.setAttribute('height',window.innerHeight*galleryResolution)
    galleryCanvas.style.width = window.innerWidth+'px'
    galleryCanvas.style.height = window.innerHeight+'px'

    var markerSpeed = 0.002
    var markerColor = '#F71963'
    var highlightMarkerColor = '#ffc4dd'

    var imageSpeed = 0.0025

    function easeOutElastic(t, b, c, d) {
      var s=1.10158; var p=0;var a=c;
      if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.35;
      if (a < Math.abs(c)) { a=c; var s=p/4; }
      else var s = p/(2*Math.PI) * Math.asin (c/a);
      return a*Math.pow(2,-15*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
    }

    var start = null
    function update(delta) {
      pulseContext.clearRect(0,0, window.innerWidth*pulseResolution, window.innerHeight*pulseResolution)

      pulseContext.strokeStyle = markerColor

      for(let i=0; i< markers.length; i++){
        let marker = markers[i]
        var pulseT = Math.max(0, Math.min(1,marker.t*8)-(0.01+Math.min(0.13, marker.value*0.00001)))

        if(pulseT < 0.5) {
          // var pulseScale = Math.log10(Math.max(1, marker.value/200))+1
          var pulseScale = Math.log10(Math.max(1, marker.value/200))+1

          var initialPulseSize = 55*pulseScale
          // var initialPulseSize = 55*pulseScale

          var pulseSize = initialPulseSize*Math.pow(pulseT,1/2)
          // pulseContext.globalAlpha = Math.pow(1-pulseT,1/4)*0.4
          // pulseContext.lineWidth = pulseSize*2*Math.pow(1-pulseT, 8) * pulseResolution

          // pulseContext.lineWidth = (pulseSize*1.3)*1*Math.pow(1-pulseT, 8) * pulseResolution

          pulseContext.lineWidth = (pulseSize*2)*1*Math.pow(1-pulseT, 8) * pulseResolution

          // var lineWidth = pulseSize*2*Math.pow(1-pulseT, 8) * pulseResolution
          // pulseContext.strokeStyle = markerColor

          pulseContext.beginPath()
          pulseContext.arc(
            marker.x*pulseResolution, marker.y*pulseResolution,
            pulseSize*pulseResolution,
            0, 2*Math.PI
          )
          pulseContext.globalAlpha = 1
          pulseContext.stroke()
        }
        marker.t += markerSpeed*delta
      }

      pulseContext.globalAlpha = 1
      for(let i=0; i< markers.length; i++){
        let marker = markers[i]
        if(marker.t >= 1) continue

        pulseContext.beginPath()
        pulseContext.fillStyle = marker.t < 0.01 ? highlightMarkerColor : markerColor
        pulseContext.moveTo(marker.x*pulseResolution, marker.y*pulseResolution)
        pulseContext.arc(
          marker.x*pulseResolution, marker.y*pulseResolution,
          10*Math.pow(1-Math.abs(marker.t-(0+Math.min(marker.value*0.00001,0.02))),30)*pulseResolution,
          0, 2*Math.PI
        )
        pulseContext.fill()
      }
      pulseContext.globalAlpha = 1

      galleryContext.clearRect(0, 0, window.innerWidth*galleryResolution, window.innerHeight*galleryResolution)
      for(let i =0; i<images.length; i++){
        let image = images[i]
        if(image.t >= 1) continue

        var offset = Math.pow(image.t, 1/3) * 350
        var scale = Math.max(0.1, easeOutElastic(Math.min(1,image.t*2), 0, 1, 1))*(1+image.scale*0.6)
        var imageSize = 100
        var origin = {
          x: window.innerWidth - 100 - (image.origin * 60),
          y: window.innerHeight + 0,
        }
        var gravity = {
          x: 0,
          y: image.t * -(window.innerHeight - 300 + (image.gravityIncrease*300)),
        }
        var targetSize = imageSize * scale
        var oscilation = Math.sin(image.t*image.oscilationFreq*14)*image.oscilationAmp*40*(1+image.t*0.1)
        var targetPos = {
          x: origin.x+(Math.cos(image.direction)*offset)+oscilation+gravity.x,
          y: origin.y+(Math.sin(image.direction)*offset)+gravity.y,
        }
        image.y = targetPos.y

        galleryContext.drawImage(
          image.image,
          (targetPos.x - (targetSize/2))*galleryResolution,
          (targetPos.y - (targetSize/2))*galleryResolution,
          targetSize*galleryResolution,
          targetSize*galleryResolution,
        )

        // galleryContext.restore()

        // var speedIncreaseFactor = 0.2
        // image.t += imageSpeed*delta + (image.speedIncrease * speedIncreaseFactor)*Math.max(0, 1-image.t*4)*delta
        // image.speedIncrease *= 1 - speedIncreaseFactor*delta
        image.t += imageSpeed*delta
      }

      requestAnimationFrame(updateAgain)
    }
    let shouldUpdate = true
    function updateAgain(t){
      stats.begin()
      if(!start) start = t
      shouldUpdate = !shouldUpdate
      if(!shouldUpdate){
        requestAnimationFrame(updateAgain)
        return
      }
      var delta = (t - start)/frame
      start = t
      update(delta)
      stats.end()
    }
    updateAgain(performance.now())

    setInterval(function(){
      let i
      for(i = markers.length-1; i >= 0; i--){
        let marker = markers[i]
        if(marker.t >= 0.2) {
          markers.splice(i, 1)
        }
      }
      for(i = images.length-1; i >= 0; i--){
        let image = images[i]
        if(image.y < -100) {
          image.image = null
          images.splice(i, 1)
        }
      }
    }, 1000)
  }

  function getNextTime() {
    return new Date().getTime() + 15000
  }

  function addHeatMapPoint(x,y){
    heatmapContext.fillStyle='#ffc4dd'
    // heatmapContext.fillStyle='#F71963'
    heatmapContext.globalAlpha = 0.15
    heatmapContext.beginPath()
    heatmapContext.arc(x, y, 8, 0, 2*Math.PI)
    heatmapContext.fill()

    heatmapContext.globalAlpha = 1
    heatmapContext.beginPath()
    heatmapContext.arc(x, y, 0.5+(Math.random()*1.5), 0, 2*Math.PI)
    heatmapContext.fill()
  }

  function latLngToPoint(latitude, longitude, mapWidth, mapHeight) {
    // get x value
    const x = (longitude+180)*(mapWidth/360)

    // convert from degrees to radians
    const latRad = latitude*Math.PI/180;

    // get y value
    const mercN = Math.log(Math.tan((Math.PI/4)+(latRad/2)));
    const y     = (mapHeight/2)-(mapWidth*mercN/(2*Math.PI));

    return {x: x, y: y}
  }

  function renderMarkers(data) {
    data = JSON.parse(data)

    if (data.lat != 0 && data.long != 0 && data.transactionTotal) {
      var pos = latLngToPoint(data.lat, data.long, mapWidth*mapScale, mapHeight*mapScale)
      pos.x += (-30*mapScale)+(mapOffset.x*mapScale)
      pos.y += (130*mapScale)+(mapOffset.y*mapScale)

      const st = 1
      for (let i = 0; i<st; i++) {
        setTimeout(() => {
          showImage(data.accountName, data.salesChannel, data.sku, pos.x, pos.y)
            .then(function(){
              let value = 1
              if (conversionRates[data.transactionCurrency]) {
                value = data.transactionTotal * conversionRates[data.transactionCurrency];
              } else {
                console.warn('Missing conversion rate for ' + data.transactionCurrency);
              }

              var variation = 3
              pos.x += -variation + (Math.random() * variation * 2)
              pos.y += -variation + (Math.random() * variation * 2)

              markers.push({
                x: pos.x+(i>0 ? Math.random()*10 : 0),
                y: pos.y+(i>0 ? Math.random()*10 : 0),
                t: 0,
                value: value,
              })

              // addHeatMapPoint(pos.x, pos.y)
            })
        }, (2000/st)*i)
      }
    }
  }

  let statsVisible = false
  document.addEventListener('keydown', event => {
    if (event.key === 'f') {
      statsVisible = !statsVisible
      document.querySelector('#stats').style.display = statsVisible ? 'block' : 'none'
    }
  })
  var pending = 0

  async function getImageUrl(an, sc, skuId) {
    if (pending.length > 10) return Promise.reject()

    pending++

    const response = await axios({
      method: 'get',
      url: '/api/catalog_system/pub/products/search',
      params: {
        an: an,
        sc: sc,
        timeout: 500,
        fq: `skuId:${skuId}`,
      }
    })

    const {data} = response
    const sku = data[0].items.find(({itemId}) => itemId === skuId)
    const imageUrl = sku.images && sku.images.length > 0 && sku.images[0].imageUrl

    pending--
    if (imageUrl) {
      return imageUrl
    }

    throw new Error(`Couldn't load image. an=${an} sc=${sc} skuId=${skuId}`)
  }

  function resizeImageUrl(url, size){
    if(!url) return
    var idsRegex = /\/ids\/(\d*)\//

    var ids = url.match(idsRegex)
    if(ids && ids[1]){
      ids = ids[1]
    }else{
      return url
    }

    return url.replace(idsRegex, '/ids/'+ids+'-'+size+'-'+size+'/')
  }

  var loadImageDelay = 350
  var shouldLoadImage = true

  const loadImage = url => new Promise((resolve, reject) => {
    if(!shouldLoadImage){
      reject()
      return
    }
    var image=new Image()
    function onImageLoad(){
      image.removeEventListener('load', onImageLoad)
      resolve(image)
    }
    image.addEventListener('load', onImageLoad)
    image.src = url
    setTimeout(()=>{
      image.removeEventListener('load', onImageLoad)
      reject()
    }, 3000)

    shouldLoadImage = false
    setTimeout(() => { shouldLoadImage = true }, loadImageDelay)
  })

  function maskImage(image, size) {
    var canvas=document.createElement('canvas')
    canvas.setAttribute('width', size)
    canvas.setAttribute('height', size)
    var context = canvas.getContext('2d')

    context.fillStyle = 'white'
    context.save()
    context.globalAlpha = 1
    context.beginPath()
    context.arc(
      (size/2)*galleryResolution, (size/2)*galleryResolution,
      (size/2)*galleryResolution-2, 0, 2*Math.PI
    )
    context.fill()

    if (image){
      // context.strokeStyle = '#142032'
      // context.lineWidth = 2
      // context.stroke()

      context.beginPath()
      context.arc(
        (size/2)*galleryResolution, (size/2)*galleryResolution,
        (size/2)*galleryResolution-2, 0, 2*Math.PI
      )
      context.clip()

      context.drawImage(image, 1, 1)
    }
    return canvas
  }

  function addDummyImage(sourceX, sourceY){
    if (images.length >= imagesLimit) {
      return
    }
    images.unshift({
      image: maskImage(null, 100),
      t: 0,
      direction: -Math.PI/2, // + (-variation + Math.random()*variation*2),
      // oscilationFreq: Math.random(),
      // oscilationAmp: Math.random(),
      oscilationFreq: Math.random(),
      oscilationAmp: -1+(Math.random()*2),
      sourceX: sourceX,
      sourceY: sourceY,
      scale: -0.85-Math.random()*0.1,
      origin: 1,
      speedIncrease: 0,
      gravityIncrease: 1+Math.random()*2,
    })
  }
  function showImage(an, sc, skuId, sourceX, sourceY) {
    return new Promise(function(resolve) {
      getImageUrl(an, sc, skuId)
        .then(function(response) {
          var resizedUrl = resizeImageUrl(response, 100*galleryResolution)
          loadImage(resizedUrl).then(image=>{
            var variation = Math.PI/18
            // var speedIncrease = 0.05
            // images.forEach(image => {
            //   image.speedIncrease += 0.05
            // })
            var maskedImage = maskImage(image, 100)
            setTimeout(() => {
              images.push({
                image: maskedImage,
                t: 0,
                direction: -Math.PI/2, // + (-variation + Math.random()*variation*2),
                // oscilationFreq: Math.random(),
                // oscilationAmp: Math.random(),
                oscilationFreq: Math.random(),
                oscilationAmp: -1+(Math.random()*2),
                sourceX: sourceX,
                sourceY: sourceY,
                scale: Math.random(),
                origin: 1,
                speedIncrease: 0,
                gravityIncrease: Math.random(),
              })
              resolve()
            }, Math.random()*1000)
          }).catch(()=>{
            setTimeout(() => {
              addDummyImage(sourceX, sourceY)
              resolve()
            }, Math.random()*1000)
          })
        })
        .catch(function handleError() {
          setTimeout(() => {
            addDummyImage(sourceX, sourceY)
            resolve()
          }, Math.random()*1000)
        })
    })
  }

  initialize()

  attempt()

  setInterval(function reloadWindow() {
    window.location.reload(false);
  }, 10 * 60 * 1000);
}

export {
  IMAGE_ROOT,
  start
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of bubbles/react/js/daynightoverlay.js from the bubbles VTEX app.

[Assistant]
Here's the implementation:

```javascript
/**
 * Day/Night Overlay
 * Version 1.3
 *
 * @author kaktus621@gmail.com (Martin Matysiak)
 * @fileoverview This class provides a custom overlay which shows an
 * approximation of where the day/night line runs at any given date.
 */

/**
 * @license Copyright 2011-2012 Martin Matysiak.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * DayNightOverlayOptions
 *
 * {string} fillColor A color string that will be used when drawing
 * the night area.
 * {string} id A unique identifiert which will be assigned to the
 * canvas on which we will draw.
 * {Date} date A specific point of time for which the day/night-
 * overview shall be calculated (UTC date is taken).
 * {google.maps.Map} map A handle to the Google Maps map on which the
 * overlay shall be shown.
 */

/**
 * The Class which represents the Overlay.
 *
 * @constructor
 * @param {DayNightOverlayOptions=} opt_params A set of optional parameters.
 * @extends {google.maps.OverlayView}
 */
var DayNightOverlay = function(opt_params) {

  /**
   * The canvas on which we will draw later on.
   * @type {?element}
   * @private
   */
  this.canvas_ = null;

  /**
   * The color with which the night area shall be filled.
   * @type {!string}
   * @private
   */
  this.fillColor_ = 'rgba(0,0,0,0.5)';

  /**
   * If specified, this ID will be assigned to the Canvas element which will be
   * created later on.
   * @type {?string}
   * @private
   */
  this.id_ = null;

  /**
   * If specified, this fixed date will be drawn instead of the current time.
   * The date should always be specified in UTC! Please not that not only the
   * time, but also the day counts because of the sun's movement between the
   * Solstices.
   * @type {?Date} A date object that should be displayed
   * @private
   */
  this.date_ = null;

  if (typeof opt_params == 'object') {
    // Check which defaults shall be overwritten
    if (typeof opt_params.fillColor != 'undefined') {
      this.fillColor_ = opt_params.fillColor;
    }

    if (typeof opt_params.id != 'undefined') {
      this.id_ = opt_params.id;
    }

    if (typeof opt_params.date != 'undefined') {
      this.date_ = opt_params.date;
    }

    if (typeof opt_params.map != 'undefined') {
      this.setMap(opt_params.map);
    }
  }
};

// AQUI
// DayNightOverlay.prototype = new google.maps.OverlayView();

/**
 * A fixed reference to a very northern point on the world. Note: latitudes
 * over 85 degrees result in a strange bug where the calculated pixel
 * coordinates are _way_ outside the map. Therefore I use latitudes of +-85
 * degrees which result in being placed very close to the visible borders
 * of the map. I suppose this behaviour has to do with the mecrator projection.
 *
 * @type {google.maps.LatLng}
 * @private
 * @const
 */
// DayNightOverlay.NORTH_ = new google.maps.LatLng(85, 0);
DayNightOverlay.NORTH_ = {lat: 85, lng: 0}

/**
 * A fixed reference to a very southern point on the world. Note: see
 * DayNightOverlay.NORTH_.
 *
 * @type {google.maps.LatLng}
 * @private
 * @const
 */
// DayNightOverlay.SOUTH_ = new google.maps.LatLng(-85, 0);
DayNightOverlay.SOUTH_ = {lat: -85, lng: 0}

/** @override */
DayNightOverlay.prototype.onAdd = function() {
  this.canvas_ = document.createElement('canvas');
  this.canvas_.style.position = 'absolute';

  if (this.id_) {
    this.canvas_.id = this.id_;
  }

  // this.getPanes().overlayLayer.appendChild(this.canvas_);
  //AQUI
};

/** @override */
DayNightOverlay.prototype.onRemove = function() {
  this.canvas_.parentNode.removeChild(this.canvas_);
  this.canvas_ = null;
};

/** @override */
DayNightOverlay.prototype.draw = function(ctx, width, height) {

  // Adjust the canvas to the current map's size

  // AQUI
  // var projection = this.getProjection();
  var projection = {
    width: width,
    height: height,
  }

  console.log(projection)

  var worldDim = this.getWorldDimensions_(projection);
  var visibleDim = this.getVisibleDimensions_(projection, 0);

  // The viewport dimensions seem to be a bit buggy on small zoom levels.
  // Therefore we adjust the viewport to the world's dimensions, extended by
  // half a world width on the left and right
  // AQUI
  // if (this.getMap().getZoom() < 3) {
  //   visibleDim.x = worldDim.x - worldDim.width;
  //   visibleDim.y = worldDim.y;
  //   visibleDim.width = worldDim.width * 3;
  //   visibleDim.height = worldDim.height;
  // }

  // Resize canvas to current viewport
  this.canvas_.style.left = visibleDim.x + 'px';
  this.canvas_.style.top = visibleDim.y + 'px';
  this.canvas_.style.width = visibleDim.width + 'px';
  this.canvas_.style.height = visibleDim.height + 'px';
  // Important: resize not only CSS dimensions, but also canvas dimensions
  this.canvas_.width = visibleDim.width;
  this.canvas_.height = visibleDim.height;

  // Clear the current canvas
  // var ctx = this.canvas_.getContext('2d');
  // ctx.clearRect(0, 0, visibleDim.width, visibleDim.height);

  // Redraw the wave which approximately describes where it's currently night
  var terminator = this.createTerminatorFunc_(visibleDim, worldDim);
  var northernSun = this.isNorthernSun_(this.date_ ? this.date_ : new Date());

  ctx.fillStyle = this.fillColor_;
  ctx.beginPath();
  ctx.moveTo(0, northernSun ? visibleDim.height : 0);
  for (var x = 0; x < visibleDim.width; x++) {
    ctx.lineTo(x, terminator(x));
  }
  ctx.lineTo(visibleDim.width, northernSun ? visibleDim.height : 0);
  // ctx.fill();
};

/**
 * Setter for date_.
 *
 * @param {?Date} date A specific point of time for which the day/night-
 * overview shall be calculated (UTC date is taken) or null if the current
 * time shall be taken.
 */
DayNightOverlay.prototype.setDate = function(date) {
  this.date_ = date;

  // Redraw the line if we're added to a maps canvas
  if (this.canvas_ !== null) {
    this.draw();
  }
};

/**
 * Returns the coordinates of the world map, based on the current maps view.
 *
 * @private
 * @param {google.maps.MapCanvasProjection} projection The projection object for
 * the current maps view.
 * @return {Object} The dimensions, containing x and y coordinates of the upper
 * left point as well as width and height of the rectangular world map.
 */
DayNightOverlay.prototype.getWorldDimensions_ = function(projection) {
  // AQUI
  return {
    x: 0,
    y: 0,
    width: projection.width,
    height: projection.height,
  }
  // var north = projection.fromLatLngToDivPixel(DayNightOverlay.NORTH_);
  // var south = projection.fromLatLngToDivPixel(DayNightOverlay.SOUTH_);
  // var width = projection.getWorldWidth();

  // return {
  //   x: north.x - width / 2,
  //   y: north.y,
  //   width: width,
  //   height: south.y - north.y
  // };
};

/**
 * Returns the coordinates of the currently visible viewport plus a specifiable
 * margin around it.
 *
 * @private
 * @param {google.maps.MapCanvasProjection} projection The projection object for
 * the current maps view.
 * @param {number} margin The number of pixels by which the dimensions of the
 * current viewport shall be increased.
 * @return {Object} The dimensions, containing x and y coordinates of the upper
 * left point as well as width and height of the rectangular viewport.
 */
DayNightOverlay.prototype.getVisibleDimensions_ = function(projection, margin) {
  // var ne = projection.fromLatLngToDivPixel(
  //     this.getMap().getBounds().getNorthEast()
  //     );
  // var sw = projection.fromLatLngToDivPixel(
  //     this.getMap().getBounds().getSouthWest()
  //     );

  // AQUI
  return {
    x: 0,
    y: 0,
    width: projection.width,
    height: projection.height,
  }

  // return {
  //   x: sw.x - margin,
  //   y: ne.y - margin,
  //   width: ne.x - sw.x + 2 * margin,
  //   height: sw.y - ne.y + 2 * margin
  // };
};

/**
 * Generates a function which in turn calculates the day/night terminator curve
 * based on the current viewport. The generated function awaits an x-coordinate
 * in the scope of the current viewport (i.e. from 0 to viewport.width) and
 * returns the corresponding y-coordinate of the curve (limited to the bounds
 * of the current viewport).
 *
 * If you don't like mathematics, feel free to skip this code ;-) It's roughly
 * based on http://www.geoastro.de/map/index.html
 *
 * This version uses a lot of variables to make the calculation a bit more
 * understandable. You might want to inline them in a minified version.
 *
 * @private
 * @param {Object} viewport The dimensions of the currently visible viewport.
 * @param {Object} world The dimensions of the world as it's seen in every
 * atlas (i.e. the rectangular area from (90Â°N,180Â°W) to (90Â°S,180Â°E)).
 * @return {function(number): number} A function which calculates the day/night
 * terminator curve.
 */
DayNightOverlay.prototype.createTerminatorFunc_ = function(viewport, world) {

  var date = this.date_ ? this.date_ : new Date();
  console.log({ date })

  // Precalculate some constants to make the actual terminator function faster

  var TWO_PI = 2 * Math.PI;

  var WORLD_WIDTH = world.width;
  var WORLD_HEIGHT = world.height;
  var HALF_WORLD_HEIGHT = world.height / 2;

  var VISIBLE_WIDTH = viewport.width;
  var VISIBLE_HEIGHT = viewport.height;

  var WORLD_OFFSET_X = viewport.x - world.x;
  var WORLD_OFFSET_Y = viewport.y - world.y;

  // Scaling factors

  // Used for scaling the x-coordinate in the scope of the world with
  // onto the range of [0, 2*PI)
  var X_SCALE = TWO_PI / WORLD_WIDTH;

  // Used for scaling the output of the crazy function below ([-PI/2, PI/2]) to
  // the range of the world's height ([-world.height/2, world.height/2])
  var Y_SCALE = WORLD_HEIGHT / Math.PI;

  // Offset calculation

  // The current (or specified) UTC time in seconds.
  var TIME_SECS = date.getUTCHours() * 3600 +
      date.getUTCMinutes() * 60 +
      date.getUTCSeconds();

  // Since the world's borders are at longitude +-180 degrees but we are
  // are comparing to UTC time (which takes place at longitude 0 degrees),
  // we have to shift the time by exactly 12 hours using NOON_SECS.
  var NOON_SECS = 86400 / 2;

  // We calculate the horizontal offset on the basis of seconds. Therefore we
  // divide the maximum offset (2 * PI) by the amount of seconds in a day.
  var PI_STEP = TWO_PI / 86400;

  // Now let's add everything together... the offset is now in the
  // range of [0, 2*PI)
  var TIME_OFFSET_X = (TIME_SECS + NOON_SECS) * PI_STEP;

  // And now the vertical offset... throughout the year, the sun's position
  // varies between +-23.44 degrees around the equatorial line (it's exactly
  // over the equator on the vernal and autumnal equinox, 23.44Â° north at the
  // summer solstice and 23.44Â° south at the winter solstice). Between those
  // dates, the sun moves on a sine wave.

  // The first thing we do is calculating the sun's position by using the
  // vernal equinox as a reference point.
  var DAY_OF_YEAR = this.getDayOfYear_(date);
  var VERNAL_EQUINOX = this.getDayOfYear_(
      new Date(Date.UTC(date.getFullYear(), 2, 20))
      );

  var MAX_DECLINATION = 23.44 * Math.PI / 90;
  var DECLINATION = Math.sin(TWO_PI * (DAY_OF_YEAR - VERNAL_EQUINOX) / 365) *
      MAX_DECLINATION;

  // The returned method first translates the viewport x to world x,
  // calculates the world y and translates it back to the viewport y
  return function(x) {
    // x in range [0, visible_width]

    // World x in the range [0, 2PI) ("longitude")
    var worldX = (x + WORLD_OFFSET_X) * X_SCALE + TIME_OFFSET_X;

    // World y in the range [-PI/2, PI/2] ("latitude")
    // This is the main function for calculating the terminator line!!
    var worldY = Math.atan(-Math.cos(worldX) / Math.tan(DECLINATION));

    // Translate to range [0, world_height]
    worldY = HALF_WORLD_HEIGHT + worldY * Y_SCALE;

    // Crop to visible range
    return Math.min(VISIBLE_HEIGHT, Math.max(0, worldY - WORLD_OFFSET_Y));
  };
};

/**
 * Returns true if sun is currently north of the equatorial line. That's
 * basically always between the vernal and autumnal equinax (i.e. Mar - Sep)
 *
 * @private
 * @param {Date} date The date for which the sun's position shall be determined.
 * @return {boolean} true if the sun is north of the equatorial line, false
 * otherwise.
 */
DayNightOverlay.prototype.isNorthernSun_ = function(date) {
  var vernalEq = new Date(Date.UTC(date.getFullYear(), 2, 19));
  var autumnalEq = new Date(Date.UTC(date.getFullYear(), 8, 18));
  // var autumnalEq = new Date(Date.UTC(date.getFullYear(), 8, 23));

  return (date.getTime() > vernalEq.getTime()) &&
      (date.getTime() <= autumnalEq.getTime());
};

/**
 * Calculates the day of year based on the given date. Method: the timestamp
 * of the given date is substracted by the timestamp of the first day of the
 * respective year. The resulting time difference is then divided by the number
 * of milliseconds per day, which results in the day of the year.
 *
 * @private
 * @param {Date} date A date for which the day of year shall be calculated.
 * @return {number} The date's day of year.
 */
DayNightOverlay.prototype.getDayOfYear_ = function(date) {
  // Yes, the month has to be zero thanks to JavaScript's great Date class.....
  var firstDay = new Date(Date.UTC(date.getFullYear(), 0, 1));

  return Math.ceil((date.getTime() - firstDay.getTime()) / 86400000);
};

if (window && window.document) {
  window.DayNightOverlay = DayNightOverlay
}

export default {}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of lomadee/docs/README.md from the lomadee VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Lomadee
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)

VTEX Lomadee first-party app

## How to install

Open the VTEX App Store and install this app on your store.

Now, open the app settings on your admin and fill in the Lomadee options.

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table>
  <tr>
    <td align="center"><a href="https://github.com/juliomoreira"><img src="https://avatars2.githubusercontent.com/u/1207017?v=4" width="100px;" alt="Julio Moreira"/><br /><sub><b>Julio Moreira</b></sub></a><br /><a href="https://github.com/vtex-apps/lomadee/commits?author=juliomoreira" title="Code">💻</a></td>
  </tr>
</table>

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of lomadee/react/index.tsx from the lomadee VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { getProductPrice, getProductAvable } from "./helpers/index";
import { PixelMessage } from "./typings/events";
import { canUseDOM } from "vtex.render-runtime";

function purchaseInjection(advertiserId: string, lomadeeEventId: string, transactionId: string, transactionTotalWithoutFreight: string) {
  const img = document.createElement("img");
  const url = `https://secure.lomadee.com/at/actionlog?adv=${advertiserId}&country=BR&transaction=${transactionId}&event1=${lomadeeEventId}&value1=${transactionTotalWithoutFreight}`;
  img.setAttribute("id", "lomadee-pixel");
  img.setAttribute("src", url);
  document.body.appendChild(img);
}

function handleMessages(e: PixelMessage) {
  let lomadee_datalayer: any;

  switch (e.data.eventName) {
    case "vtex:pageInfo": {
      lomadee_datalayer = {
        page: "home"
      };
      break;
    }

    case "vtex:orderPlaced": {
      lomadee_datalayer = {
        page: "conversion",
        conversion: {
          transactionId: e.data.transactionId,
          amount: e.data.transactionSubtotal,
          currency: "BRL",
          paymentType: e.data.transactionPaymentType[0].paymentSystemName,
          items: e.data.transactionProducts
        }
      };

      purchaseInjection(window.advertiserId, window.lomadeeEventId, e.data.transactionId, e.data.transactionSubtotal);
      break;
    }

    case "vtex:productView": {
      const {
        product: { productId, productName }
      } = e.data;
      lomadee_datalayer = {
        page: "product",
        product: {
          sku: productId,
          name: productName,
          price: getProductPrice(e.data.product),
          available: getProductAvable(e.data.product)
        }
      };
      break;
    }

    case "vtex:addToCart": {
      lomadee_datalayer = {
        page: "cart",
        cart: {
          skus: e.data.items[0].skuId
        }
      };

      break;
    }

    case "vtex:internalSiteSearchView": {
      const category = e.data.products[0].categories[0].split("/");
      lomadee_datalayer = {
        page: "search",
        keyword: category[2]
      };
      break;
    }

    case "vtex:categoryView": {
      const category = e.data.products[0].categories[0].split("/");
      lomadee_datalayer = {
        page: "category",
        category: {
          name: category[2]
        }
      };
      break;
    }

    default: {
      lomadee_datalayer = {
        page: "visit"
      };
      break;
    }
  }
}

if (canUseDOM) {
  window.addEventListener("message", handleMessages);
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of lomadee/react/package.json from the lomadee VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.lomadee-pixel",
  "version": "0.0.0",
  "scripts": {
    "lint": "tsc --noEmit --pretty && tslint -c tslint.json './**/*.ts'"
  },
  "devDependencies": {
    "@types/node": "^12.7.1",
    "tslint": "^5.11.0",
    "tslint-config-vtex": "^2.0.0",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "3.5.2"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of lomadee/store/interfaces.json from the lomadee VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "pixel.lomadee": {
    "component": "index"
  }
}

```