{"version":3,"sources":["heleprs/spin.js","components/Player/index.js","App.js","serviceWorker.js","index.js"],"names":["vals","apply2DSpin","attrName","direction","maxWidth","player","a","window","getConfigurator","configurator","add2DSpin","getImg","curPct","tools","addTool","key","active","enabled","handlers","drag","handle","ev","config","getConfiguration","deltaT","deltaX","Math","max","rect","width","newPct","abs","curIndex","getOptionIndex","newOption","getOptionByIndex","newIndex","setConfiguration","momentum","index","option","findIndex","val","_","isEqual","Player","props","useState","attrs","setAttrs","useEffect","threekitPlayer","authToken","el","document","getElementById","assetId","display","showConfigurator","then","when","prefetchAttributes","getDisplayAttributes","id","style","height","className","map","e","type","name","values","f","value","onClick","event","attr","target","App","Boolean","location","hostname","match","ReactDOM","render","navigator","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.38bf59b7.chunk.js","sourcesContent":["/****************************************************\n Nothing here should need to be changed\n****************************************************/\nimport _ from \"lodash\";\n\nlet vals = [0, 30, 60, 90, 120, 150,180,210, 240, 270, 300, 330, 359]\nexport function apply2DSpin({ attrName = 'Rotate', direction = 1, maxWidth = 500 }) {\n return async (player) => {\n const configurator = await window.player.getConfigurator();\n add2DSpin({\n attrName,\n configurator,\n direction,\n maxWidth,\n player,\n });\n return player;\n };\n}\n/****************************************************\n Handler\n****************************************************/\nexport function add2DSpin(\n { attrName = 'Rotate', configurator, direction = 1, maxWidth = 100, player },\n getImg\n) {\n let curPct = 0;\n const attrCount = 12;\n // this is -1 because the final Rotate is 'whitesweep' used for renders\n const threshold = 1 / attrCount;\n return window.player.tools.addTool({\n key: '2dspin',\n active: true,\n enabled: true,\n handlers: {\n drag: () => ({\n handle: async (ev) => {\n const config = configurator.getConfiguration();\n const deltaT = ev.deltaX / Math.max(ev.rect.width, maxWidth);\n const newPct = curPct + deltaT;\n if (Math.abs(newPct) > threshold) {\n const curIndex = getOptionIndex(configurator, attrName, config[attrName]);\n const increment = (newPct > 0 ? 1 : -1) * (direction < 0 ? -1 : 1);\n const newIndex = (curIndex + increment) % attrCount;\n const newOption = getOptionByIndex(\n configurator,\n attrName,\n newIndex < 0 ? attrCount + newIndex : newIndex\n );\n configurator.setConfiguration({ [attrName]: newOption });\n }\n curPct = newPct % threshold;\n },\n momentum: true,\n }),\n },\n });\n}\nfunction getOptionByIndex(configurator, attrName, index) {\n if (!configurator) return null;\n return vals[index];\n}\nfunction getOptionIndex(configurator, attrName, option) {\n if (!configurator) return null;\n return vals.findIndex((val) => _.isEqual(val, option));\n}","import React, { useState, useEffect } from 'react';\nimport { apply2DSpin } from '../../heleprs/spin';\nimport \"./style.css\"\nfunction Player(props) {\n\tconst [attrs, setAttrs] = useState([]);\n\n /* \n Set config will interact with our configurator API. Only available after the player is initialized \n https://docs.threekit.com/docs/configurator-api\n */\n\tconst setConfig = (attr, val) => {\n\t\twindow.configurator.setConfiguration({ [attr]: { assetId: val } });\n\t};\n\tuseEffect(() => {\n\t\t/* This code will not need to be updated other than the Auth Token. Threekit needs to be\n authorized on a per-dmain basis. \n */\n\t\twindow\n\t\t\t.threekitPlayer({\n\t\t\t\tauthToken: 'bd2ce0d9-476d-4ab0-8f0c-f261baaeb29e',\n\t\t\t\tel: document.getElementById('player'),\n\t\t\t\tassetId: 'ada8ee80-68a6-4dca-811a-c429ca4b4a73',\n\t\t\t\tdisplay: 'image',\n\t\t\t\t// You can set showConfigurator to 'true' to see our default config form.\n\t\t\t\tshowConfigurator: false,\n\t\t\t})\n\t\t\t.then(async (player) => {\n\t\t\t\twindow.player = player;\n\t\t\t\twindow.configurator = await player.getConfigurator();\n\n\t\t\t\tawait player.when('loaded');\n\n\t\t\t\t// This helps preload all the images\n\t\t\t\tawait window.configurator.prefetchAttributes(['Rotate']);\n\n\t\t\t\tapply2DSpin({ attrName: 'Rotate', direction: 1 })(player);\n\t\t\t\t// End Spin\n\n\t\t\t\t// Storing the displayattributs in state. More info below. \n\t\t\t\tsetAttrs(window.configurator.getDisplayAttributes());\n\t\t\t});\n\t}, []);\n\treturn (\n\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t\t{attrs.map((e) => {\n\t\t\t\t\t/* \n\t\t\t\t\tWe can use our getDisplayAttributes() API to create UI elements for the available\n\t\t\t\t\tattributes. \n\t\t\t\t\thttps://docs.threekit.com/docs/202190-april-23-2021\n\n\t\t\t\t\tWe are only creating UI options for Asset types, the only other type of attribute \n here drives rotations and we don't need an input for that\n */\n\t\t\t\t\tif (e.type === 'Asset') {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

{e.name}

\n\t\t\t\t\t\t\t\t{e.values.map((f) => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t setConfig(e.name, event.target.value)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{f.name}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t})}\n\t\t\t
\n\t\t
\n\t);\n}\n\nexport default Player;\n","import React from 'react';\nimport Player from \"./components/Player\"\nfunction App(props) {\n\treturn (\n\t\t
\n\t\t\t\n\t\t
\n\t);\n}\n\nexport default App;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(, document.getElementById('root'));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}