1class ProductGetTheLook extends HTMLElement{constructor(){super(),this.selectors={quickAddOpen:"[js-quick-add-open]",quickAddForm:"[js-quick-add-form]",quickAddClose:"[js-quick-add-close]",quickAddSubmit:"[js-quick-add-submit]",quickAddInput:"[js-quick-add-input]",quickAddError:"[js-quick-add-error]",quickAddSingleVariant:"[js-quick-add-single]",quickAddCell:"[js-quick-add-cell]",quickAddGrid:"[js-quick-add-grid]",quickAddProductData:"#quickadd-product-data",relatedCore:"[js-related-core-colors]",relatedSeasonal:"[js-related-seasonal-colors]",relatedGroup:"[js-related-colors-group]",productCardTitle:"[js-productcard-title]",productCardImgUrl:"[js-productcard-imgurl]",productCardTitleUrl:"[js-productcard-titleurl]",productCardId:"[js-productcard-id]",productCardPriceContainer:"[js-productcard-price-container]",productCardPrice:"[js-productcard-price]",productCardComparePrice:"[js-productcard-compareprice]",productCardDiscount:"[js-productcard-discount]",productCardImages:"[js-productcard-images]",productBadge:"[js-product-badge]",productCardRemainingUrl:"[js-remaining-url]",sizeSelect:"[js-size-select]",atcButton:"[js-product-atc-button]",gtlProductData:"[js-gtl-product-data]",detailsButton:"[js-product-details-button]"},this.cachedElements={},this.cartDrawer=null}connectedCallback(){this._cacheElements(),this._initRelatedSeasonalColors(),this._initAtcButton()}disconnectedCallback(){if(this._swiperHandlers){const{wrapper,enter,leave}=this._swiperHandlers;wrapper.removeEventListener("mouseenter",enter),wrapper.removeEventListener("mouseleave",leave)}this._swiperInstance&&(this._swiperInstance.destroy(!0,!0),this._swiperInstance=null)}_cacheElements(){this.cachedElements.quickAddOpen=this.querySelector(this.selectors.quickAddOpen),this.cachedElements.quickAddForm=this.querySelector(this.selectors.quickAddForm),this.cachedElements.quickAddSingleVariant=this.querySelector(this.selectors.quickAddSingleVariant),this.cachedElements.sizeSelect=this.querySelector(this.selectors.sizeSelect),this.cachedElements.atcButton=this.querySelector(this.selectors.atcButton),this.cartDrawer=document.querySelector("#CartDrawer")}_initImageSwiper(){const swiperWrapper=this.querySelector(".product-image-carousel");if(!swiperWrapper||!window.Swiper)return;const disableMobileCarousel=this.dataset.disableMobileCarousel==="true",disableDesktopCarousel=this.dataset.disableDesktopCarousel==="true",isDesktop=window.matchMedia("(min-width: 768px)").matches;if(!(isDesktop&&!disableDesktopCarousel||!isDesktop&&!disableMobileCarousel))return;let hoverTimeout;const debounceHover=(callback,delay=100)=>{clearTimeout(hoverTimeout),hoverTimeout=setTimeout(callback,delay)};let config={slidesPerView:1,resistanceRatio:0,touchReleaseOnEdges:!1,loop:!1,pagination:{el:this.querySelector(".swiper-pagination"),clickable:!1}};isDesktop&&(config={...config,effect:"fade",fadeEffect:{crossFade:!0},allowTouchMove:!1,navigation:{nextEl:this.querySelector(".swiper-button-next"),prevEl:this.querySelector(".swiper-button-prev")}});const swiper=new window.Swiper(swiperWrapper,config);[this.querySelector(".swiper-button-next"),this.querySelector(".swiper-button-prev")].forEach(btn=>{btn&&btn.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation()})}),this._swiperInstance=swiper;const handleMouseEnter=()=>{debounceHover(()=>{swiper.slides.length>1&&swiper.slideTo(1,300)})},handleMouseLeave=()=>{debounceHover(()=>{swiper.slideTo(0,300)})};let pressTimer;const handleTouchStart=()=>{pressTimer=setTimeout(()=>{swiper.slides.length>1&&swiper.slideTo(1,300),console.log("Long Press Triggered")},600)},handleTouchEnd=()=>{clearTimeout(pressTimer),swiper.slideTo(0,300)},handleTouchMove=()=>{clearTimeout(pressTimer)};window.innerWidth>768&&(swiperWrapper.addEventListener("mouseenter",handleMouseEnter,{passive:!0}),swiperWrapper.addEventListener("mouseleave",handleMouseLeave,{passive:!0})),this._swiperHandlers={wrapper:swiperWrapper,enter:handleMouseEnter,leave:handleMouseLeave}}_initQuickAdd(){const{quickAddOpen,quickAddSingleVariant}=this.cachedElements;quickAddOpen?(this.addEventListener("mouseleave",this._hideForm.bind(this)),quickAddOpen.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),window.innerWidth<=768?this._dataToQuickAddDrawer():this._showForm()})):quickAddSingleVariant&&quickAddSingleVariant.addEventListener("click",this._submitSingle.bind(this)),this.addEventListener("click",e=>{const quickAddCell=e.target.closest(this.selectors.quickAddCell);quickAddCell&&this._handleQuickAddCell(e,quickAddCell)})}_initAtcButton(){const{atcButton,sizeSelect}=this.cachedElements;atcButton&&(sizeSelect&&sizeSelect.addEventListener("change",()=>{this._updateAtcButtonState(sizeSelect.value)}),atcButton.addEventListener("click",()=>{const state=atcButton.dataset.state,selectedVariantId=sizeSelect?sizeSelect.value:null,variantId=atcButton.dataset.variantId||selectedVariantId;if(!variantId){this._setSelectSizeState();return}state==="select-size"&&this._updateAtcButtonState(variantId),atcButton.dataset.state==="notify"?this._openNotifyPopup(variantId):this._addToCart(variantId)}))}_setSelectSizeState(){const atcButton=this.cachedElements.atcButton;atcButton&&(atcButton.textContent="Select A Size",atcButton.dataset.state="select-size",atcButton.classList.remove("is-select-size","is-atc","is-notify"),atcButton.classList.add("is-select-size"))}_updateAtcButtonState(variantId){const atcButton=this.cachedElements.atcButton;if(!atcButton)return;const stateClasses=["is-select-size","is-atc","is-notify"];if(!variantId){this._setSelectSizeState();return}const productDataEl=this.querySelector(this.selectors.gtlProductData);if(!productDataEl)return;const productData=JSON.parse(productDataEl.textContent),variant=productData.variants.find(v=>String(v.id)===String(variantId));atcButton.classList.remove(...stateClasses),productData.prevent_atc||variant&&!variant.available?(atcButton.textContent="Notify Me When Available",atcButton.dataset.state="notify",atcButton.classList.add("is-notify")):(atcButton.textContent="Add to Cart",atcButton.dataset.state="atc",atcButton.classList.add("is-atc"))}_openNotifyPopup(variantId){const productDataEl=this.querySelector(this.selectors.gtlProductData);if(!productDataEl)return;const productData=JSON.parse(productDataEl.textContent),variant=productData.variants.find(v=>String(v.id)===String(variantId));if(!variant)return;const pname=this.querySelector(this.selectors.productCardTitle)?.textContent?.trim()||"",optionName=variant.option1||"",prodId=String(productData.id),notifyPopup=document.querySelector(".collection_notify_popup"),overlay=document.querySelector(".notify-overlay"),klaviyoForm=notifyPopup?notifyPopup.querySelector(".form-klaviyo-bis"):null;if(notifyPopup){notifyPopup.classList.add("active-notify");const nameElement=notifyPopup.querySelector(".Product_name");nameElement&&(nameElement.textContent=optionName?`${pname} - ${optionName}`:pname),klaviyoForm&&(klaviyoForm.setAttribute("data-variant-id",variantId),klaviyoForm.setAttribute("data-product-id",prodId)),overlay&&overlay.classList.add("active-notify"),document.body.classList.add("active-notify")}
1}_handleQuickAddCell(e,cell){if(e.preventDefault(),cell.classList.contains("out-of-stock")){const pname=cell.closest("product-card").querySelector(".product-card__title-link").textContent,varId=cell.getAttribute("data-variantid"),prodId=cell.getAttribute("data-productid"),optionName=cell.textContent,notifyPopup=document.querySelector(".collection_notify_popup"),overlay=document.querySelector(".notify-overlay"),klaviyoForm=notifyPopup?notifyPopup.querySelector(".form-klaviyo-bis"):null;if(notifyPopup){notifyPopup.classList.add("active-notify");const nameElement=notifyPopup.querySelector(".Product_name");nameElement&&(optionName?nameElement.textContent=`${pname} - ${optionName}`:nameElement.textContent=pname),klaviyoForm&&(klaviyoForm.setAttribute("data-variant-id",varId),klaviyoForm.setAttribute("data-product-id",prodId)),overlay&&overlay.classList.add("active-notify"),document.body.classList.add("active-notify")}return}const variantId=cell.getAttribute("data-variantId");if(!variantId){console.error("No variant ID found");return}this._addToCart(variantId)}_dataToQuickAddDrawer(){const productDataEl=this.querySelector(this.selectors.quickAddProductData);if(!productDataEl)return;const product=JSON.parse(productDataEl.textContent),drawer=document.querySelector("#ProductCardQuickAdd");if(!drawer)return;const titleEl=drawer.querySelector("[js-quickadd-drawer-title]"),variantsEl=drawer.querySelector("[js-quickadd-drawer-variants]");titleEl&&(titleEl.textContent=product.title),titleEl&&titleEl.setAttribute("data-product-id",product.id),variantsEl&&(variantsEl.innerHTML=product.variants.map(variant=>`<div class="product-variant-option ${product.prevent_atc?"out-of-stock":variant.available?"":"out-of-stock"}" data-variant-id="${variant.id}" js-quickadd-drawer-variant-option>${variant.option1}</div>`).join(""),variantsEl.innerHTML+=` 2 <div class="quick-add-wrapper-inner" style="z-index: -1;" js-product-card-spinner> 3 <loading-spinner style="--color: #333; --width: 24px; --height: 24px; --background: rgba(255,255,255);"></loading-spinner> 4 </div> 5 `),drawer.open()}_showForm(){const form=this.cachedElements.quickAddForm;form&&form.classList.add("-translate-y-full")}_hideForm(){const form=this.cachedElements.quickAddForm;form&&form.classList.remove("-translate-y-full")}_submitForm(){const checkedInput=this.querySelector(`${this.selectors.quickAddInput}:checked`),errorEl=this.querySelector(this.selectors.quickAddError);if(!checkedInput){errorEl&&(errorEl.classList.remove("hidden"),errorEl.classList.add("block"));return}errorEl&&(errorEl.classList.add("hidden"),errorEl.classList.remove("block")),this._addToCart(checkedInput.value,!0)}_submitSingle(e){const variantId=e.target.dataset.variantId;if(!variantId){console.error("No variant ID found");return}const cart=document.querySelector("cart-drawer");cart&&cart.setActiveElement(document.activeElement),this._addToCart(variantId,!0)}async _addToCart(variantId,reloadNosto=!1){if(!variantId){console.error("No variant ID provided");return}const spinnerWrapper=this.querySelector("[js-product-card-spinner]"),spinner=this.querySelector("loading-spinner");spinnerWrapper&&spinner&&(spinnerWrapper.style.zIndex=1,spinner.setAttribute("loading",""));try{const data=await(await fetch(window.Shopify.routes.root+"cart/add.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({items:[{id:variantId,quantity:1}]})})).json();if(data.status){this._handleErrorMessage(data.description),spinnerWrapper&&spinner&&(spinnerWrapper.style.zIndex=-1,spinner.removeAttribute("loading"));return}window.renderCart&&await window.renderCart(),reloadNosto&&window.Nosto&&window.Nosto.reloadCart(),this.cartDrawer&&this.cartDrawer.open(),spinnerWrapper&&spinner&&(spinnerWrapper.style.zIndex=-1,spinner.removeAttribute("loading"))}catch(error){console.error("Error adding to cart:",error),spinnerWrapper&&spinner&&(spinnerWrapper.style.zIndex=-1,spinner.removeAttribute("loading"))}}_handleErrorMessage(message){console.error("Cart error:",message)}async _initRelatedSeasonalColors(){const containers=this.querySelectorAll(this.selectors.relatedGroup);if(containers.length===0)return;const firstContainer=containers[0],currentProductHandle=firstContainer.getAttribute("data-handle"),relatedColorsGroup=firstContainer.getAttribute("data-group"),finalColor=firstContainer.getAttribute("data-color");
5if(currentProductHandle&&!relatedColorsGroup)try{const colorEntry=window.color_data.find(color=>{if(color.name==finalColor.toLowerCase().toString())return color});if(!colorEntry)return;const productJSON=[{handle:currentProductHandle,meta_swatch:colorEntry}],{orderedList,remainingCount}=this._buildSwatchList(productJSON,currentProductHandle),relatedColorsMarkup=this._renderSwatches(orderedList,currentProductHandle,remainingCount);containers.forEach(container=>{container.innerHTML=relatedColorsMarkup}),this._attachSwatchListeners();return}catch(error){console.error("Error loading related seasonal colors:",error)}else try{const targetURL=`/collections/all/${relatedColorsGroup}/?view=json`;let relatedColorsJSON=await this._getRelatedColorJSON(targetURL);if(relatedColorsJSON.length===0)return;relatedColorsJSON=relatedColorsJSON.filter(product=>product.available==!0);const{orderedList,remainingCount}=this._buildSwatchList(relatedColorsJSON,currentProductHandle),relatedColorsMarkup=this._renderSwatches(orderedList,currentProductHandle,remainingCount);containers.forEach(container=>{container.innerHTML=relatedColorsMarkup}),this._attachSwatchListeners()}catch(error){console.error("Error loading related seasonal colors:",error)}}_buildSwatchList(products,currentHandle){const currentProduct=products.find(p=>p.handle===currentHandle),otherProducts=products.filter(p=>p.handle!==currentHandle),orderedList=currentProduct?[currentProduct]:[];let maxSwatches;this.closest("#CartDrawer")?maxSwatches=window.innerWidth<=767?3:4:maxSwatches=window.innerWidth<=767?4:5;const remainingSlots=maxSwatches-orderedList.length,visibleOthers=otherProducts.slice(0,remainingSlots);return orderedList.push(...visibleOthers),{orderedList,remainingCount:otherProducts.length-visibleOthers.length}}_renderSwatches(orderedList,currentHandle,remainingCount){const swatches=orderedList.map(product=>{const swatch=this._createSwatchHTML(product),isActive=product.handle===currentHandle?"active":"";return`<div data-handle="${product.handle}" class="product-card-swatch ${isActive}" aria-label="${product.color}">${swatch}</div>`}).join(""),remainingHTML=remainingCount>0?`<a href="/products/${currentHandle}" class="product-card-remaining" js-remaining-url>+${remainingCount}</a>`:"";return swatches+remainingHTML}_createSwatchHTML(product){return product.meta_swatch&&product.meta_swatch.color_code?`<div class="product-card-swatch-inner" style="background: ${product.meta_swatch.color_code};"></div>`:product.meta_swatch&&product.meta_swatch.linear_gradient?`<div class="product-card-swatch-inner" style="background: ${product.meta_swatch.linear_gradient};"></div>`:product.meta_swatch&&product.meta_swatch.image?`<div class="product-card-swatch-inner" style="background: url(${product.meta_swatch.image});"></div>`:'<div class="product-card-swatch-inner" style="background: #000;"></div>'}_attachSwatchListeners(){this.querySelectorAll(".product-card-swatch").forEach(swatch=>{swatch.addEventListener("mouseenter",()=>{const handle=swatch.getAttribute("data-handle");handle&&this._prefetchSwatch(handle)}),swatch.addEventListener("click",e=>{e.preventDefault();const handle=swatch.getAttribute("data-handle");handle&&this._swatchClicked(handle)})})}async _prefetchSwatch(handle){const relatedGroup=this.querySelector(this.selectors.relatedGroup);if(!relatedGroup)return;const originalHandle=relatedGroup.getAttribute("data-handle");if(handle!==originalHandle&&!this._productCache.has(handle))try{const text=await(await fetch(`/products/${handle}/?view=swatch`)).text(),productInfoEl=new DOMParser().parseFromString(text,"text/html").querySelector("[js-product-json]");if(!productInfoEl)return;const productInfo=JSON.parse(productInfoEl.textContent);this._productCache.set(handle,productInfo),productInfo.images&&productInfo.images.forEach(src=>{const img=new Image;img.src=src})}catch{}}async _getRelatedColorJSON(url){try{const text=await(await fetch(url)).text(),jsonContainer=new DOMParser().parseFromString(text,"text/html").querySelector("[js-collection-json]");return jsonContainer?JSON.parse(jsonContainer.textContent):[]}catch(error){return console.error("Error fetching related colors:",error),[]}}async _swatchClicked(handle){const relatedGroup=this.querySelector(this.selectors.relatedGroup);if(!relatedGroup)return;const originalProductHandle=relatedGroup.getAttribute("data-handle");if(handle!==originalProductHandle)try{const targetURL=`/products/${handle}/?view=swatch`,text=await(await fetch(targetURL)).text(),productInfoEl=new DOMParser().parseFromString(text,"text/html").querySelector("[js-
5product-json]");if(!productInfoEl){console.error("Product info not found");return}const productInfo=JSON.parse(productInfoEl.textContent);this._updateProductCard(productInfo,handle)}catch(error){console.error("Error loading product swatch:",error)}}_updateProductCard(productInfo,handle){requestAnimationFrame(()=>{const elements={title:this.querySelector(this.selectors.productCardTitle),imgUrl:this.querySelector(this.selectors.productCardImgUrl),titleUrl:this.querySelector(this.selectors.productCardTitleUrl),productId:this.querySelector(this.selectors.productCardId),priceContainer:this.querySelector(this.selectors.productCardPriceContainer),price:this.querySelector(this.selectors.productCardPrice),comparePrice:this.querySelector(this.selectors.productCardComparePrice),discount:this.querySelector(this.selectors.productCardDiscount),badge:this.querySelector(this.selectors.productBadge),images:this.querySelectorAll(`${this.selectors.productCardImages} img`),quickAddGrid:this.querySelector(this.selectors.quickAddGrid),productData:this.querySelector(this.selectors.quickAddProductData),relatedGroup:this.querySelector(this.selectors.relatedGroup),remainingUrl:this.querySelector(this.selectors.productCardRemainingUrl),saleMessage:this.querySelector(this.selectors.productCardSaleMessage),scoreBadge:this.querySelector(this.selectors.nostoScoreBadge),sizeSelect:this.querySelector(this.selectors.sizeSelect),atcButton:this.querySelector(this.selectors.atcButton),gtlProductData:this.querySelector(this.selectors.gtlProductData),detailsButton:this.querySelector(this.selectors.detailsButton)};this._performProductCardUpdate(elements,productInfo,handle)})}_performProductCardUpdate(elements,productInfo,handle){elements.title&&(elements.title.textContent=productInfo.title),elements.price&&(elements.price.textContent=productInfo.price),elements.imgUrl&&(elements.imgUrl.href=productInfo.url),elements.titleUrl&&(elements.titleUrl.href=productInfo.url),elements.productId&&(elements.productId.id=productInfo.id),elements.relatedGroup&&elements.relatedGroup.setAttribute("data-handle",productInfo.handle);const hasComparePrice=productInfo.compare_at_price&&productInfo.compare_at_price!=="";if(elements.priceContainer&&(hasComparePrice?elements.priceContainer.classList.add("compare-price"):elements.priceContainer.classList.remove("compare-price")),elements.comparePrice&&(hasComparePrice?(elements.comparePrice.textContent=productInfo.compare_at_price,elements.comparePrice.classList.remove("hidden")):elements.comparePrice.classList.add("hidden")),elements.discount&&(hasComparePrice?(elements.discount.textContent=productInfo.price_save,elements.discount.classList.remove("hidden")):elements.discount.classList.add("hidden")),elements.badge&&(productInfo.badge&&productInfo.badge!==""?(elements.badge.textContent=productInfo.badge,elements.badge.classList.remove("hidden")):elements.badge.classList.add("hidden")),elements.images&&productInfo.images&&productInfo.images.length>0){const imageContainer=this.querySelector(".product-card__image-container"),containerHeight=imageContainer?imageContainer.offsetHeight:null;imageContainer&&containerHeight&&(imageContainer.style.minHeight=`${containerHeight}px`),elements.images.forEach((img,index)=>{if(productInfo.images[index]){const imageUrl=productInfo.images[index];let baseUrl=imageUrl,srcset="";if(imageUrl.includes("_")&&imageUrl.match(/_\d+x\d+\./)){const match=imageUrl.match(/^(.+)_\d+x\d+(\.(jpg|jpeg|png|webp|gif).*)$/i);if(match){baseUrl=match[1]+match[2];const ext=match[2];srcset=[`${match[1]}_300x${ext} 300w`,`${match[1]}_600x${ext} 600w`,`${match[1]}_900x${ext} 900w`].join(", ")}}else imageUrl.includes("?width=")&&(baseUrl=imageUrl.split("?")[0],srcset=[`${baseUrl}?width=300 300w`,`${baseUrl}?width=600 600w`,`${baseUrl}?width=900 900w`].join(", "));const imgWidth=img.width||img.naturalWidth||300,imgHeight=img.height||img.naturalHeight||450;img.src="",img.removeAttribute("srcset"),img.loading="eager",img.width=imgWidth,img.height=imgHeight,requestAnimationFrame(()=>{if(srcset){img.srcset=srcset,img.sizes="(max-width: 767px) 100v
5w, 50vw";const srcUrl=srcset.split(" ")[0];img.src=srcUrl}else img.src=imageUrl;img.alt=productInfo.title,img.onload=()=>{imageContainer&&(imageContainer.style.minHeight="")}})}}),requestAnimationFrame(()=>{setTimeout(()=>{this._swiperInstance&&(this._swiperInstance.update(),this._swiperInstance.slideTo(0,0)),imageContainer&&setTimeout(()=>{imageContainer.style.minHeight=""},300)},100)})}if(elements.sizeSelect&&productInfo.variants){const preventAtc=!!productInfo.prevent_atc;elements.sizeSelect.innerHTML='<option value="" disabled selected>Select size</option>'+productInfo.variants.map(variant=>{const label=variant.option1+(preventAtc||!variant.available&&!variant.option1.toLowerCase().includes("sold out")?" - Sold Out":"");return`<option value="${variant.id}" ${variant.available==!1?"disabled":""}>${label}</option>`}).join(""),this.cachedElements.sizeSelect=elements.sizeSelect}elements.gtlProductData&&productInfo.variants&&(elements.gtlProductData.textContent=JSON.stringify({id:productInfo.id,prevent_atc:!!productInfo.prevent_atc,variants:productInfo.variants}));const isOneSize=productInfo.variants&&productInfo.variants.length===1,sizeSelectWrapper=this.querySelector(".product-size-select-wrapper");if(sizeSelectWrapper&&sizeSelectWrapper.classList.toggle("hidden",isOneSize),elements.atcButton)if(isOneSize&&productInfo.variants){const singleVariant=productInfo.variants[0],isAvailable=!productInfo.prevent_atc&&singleVariant.available;elements.atcButton.dataset.variantId=String(singleVariant.id),elements.atcButton.classList.remove("is-select-size","is-atc","is-notify"),isAvailable?(elements.atcButton.textContent="Add to Cart",elements.atcButton.dataset.state="atc",elements.atcButton.classList.add("is-atc")):(elements.atcButton.textContent="Notify Me When Available",elements.atcButton.dataset.state="notify",elements.atcButton.classList.add("is-notify"))}else elements.atcButton.textContent="Add to Cart",elements.atcButton.dataset.state="atc",elements.atcButton.classList.remove("is-select-size","is-notify"),elements.atcButton.classList.add("is-atc");const activeSwatch=this.querySelector(".product-card-swatch.active"),newActiveSwatch=this.querySelector(`.product-card-swatch[data-handle="${handle}"]`);activeSwatch&&activeSwatch.classList.remove("active"),newActiveSwatch&&newActiveSwatch.classList.add("active"),elements.remainingUrl&&(elements.remainingUrl.href=productInfo.url),elements.detailsButton&&(elements.detailsButton.querySelector("a").href=productInfo.url)}}customElements.define("product-getthelook",ProductGetTheLook); 6//# sourceMappingURL=/cdn/shop/t/495/assets/product-getthelook.js.map?v=28533813144561664951790892735
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.