1
0
mirror of synced 2024-07-05 23:00:37 +00:00
CuttingBoard/docs/js/app.112e05e3.js.map

1 line
65 KiB
Plaintext

{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/App.vue","webpack:///./src/components/Settings.vue","webpack:///./src/lib/units.js","webpack:///./src/components/Settings.vue?b32f","webpack:///./src/components/Layers.vue","webpack:///./src/components/Layers.vue?f1ba","webpack:///./src/components/Wood.vue","webpack:///./src/components/Wood.vue?85c2","webpack:///./src/components/EndGrainPreview.vue","webpack:///./src/components/EndGrainPreview.vue?ab3d","webpack:///./src/components/EdgeGrainPreview.vue","webpack:///./src/components/EdgeGrainPreview.vue?0ca3","webpack:///./src/lib/base64.js","webpack:///./src/App.vue?eabf","webpack:///./src/store.js","webpack:///./src/main.js","webpack:///./src/components/Wood.vue?ca33","webpack:///./src/components/Settings.vue?59e7","webpack:///./src/App.vue?71f7","webpack:///./src/components/Layers.vue?fb1c"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","class","type","ref","accept","href","target","saveFilename","save","load","scale","for","id","settings","units","$store","commit","$event","checked","borders","boardThickness","parseFloatDef","boardLength","bladeKerf","crosscutWidth","alternateDirection","millimetersPerInch","millimetersPerCentimeter","pixelsPerMillimeter","convert","fromUnits","toUnits","millimeters","this","toMillimeters","fromMillimeters","toPixels","Math","ceil","console","error","display","displayValue","limitDecimals","decimals","power","pow","round","computed","state","methods","parsedValue","parseFloat","is","NaN","render","__scopeId","addLayer","layers","layer","index","dropTarget","startDrag","wood","item","width","removeLayer","dragIndex","boards","board","dragMouseMove","event","getTargetLayer","pageY","document","removeEventListener","from","to","addEventListener","yPos","firstLayer","getPageOffsetRect","$refs","layer0","lastLayer","bottom","top","currentTarget","testTarget","element","clientRect","getBoundingClientRect","scrollLeft","pageXOffset","documentElement","scrollTop","pageYOffset","left","right","addWood","color","removeWood","boardWidth","boardHeight","viewportWidth","height","viewportHeight","viewBox","x","y","getLayerOffset","style","getLayerStyle","stripsPerBoard","strip","xlink:href","transform","getLayerTransform","props","Number","stripAndKerf","floor","map","currentValue","reduce","accumulator","boardPixelWidth","boardPixelHeight","offset","woodIndex","borderStyle","base64abc","base64codes","getBase64Code","charCode","Error","code","bytesToBase64","bytes","base64ToBytes","str","indexOf","buffer","missingOctets","endsWith","Uint8Array","charCodeAt","subarray","components","EndGrainPreview","EdgeGrainPreview","Settings","Layers","Wood","created","self","checkHash","location","hash","substring","decoded","e","getters","saveMsgPack","blob","Blob","loadFile","files","toLowerCase","reader","FileReader","readAsBinaryString","watch","newValue","history","replaceState","mergeObject","source","loadObject","parsedPayload","newBoards","newWood","createStore","mutations","payload","moveLayer","forEach","updateSettings","oldUnits","JSON","parse","loadMsgPack","deserialize","stringify","serialize","createApp","App","use","store","mount"],"mappings":"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","file":"js/app.112e05e3.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","<template>\n <div class=\"app-settings\">\n <h1>Settings</h1>\n <Settings class=\"block\" />\n\n <h1>Layers</h1>\n <Layers class=\"block\" />\n\n <h1>Wood types</h1>\n <Wood class=\"block\" />\n\n <h1>Save / load</h1>\n <div class=\"loadSave block\">\n <p>\n Below you can download the current settings or load them again from a file. You can also bookmark the current page or copy the URL from the address bar instead, as it is automatically updated whenever you change anything.\n </p>\n\n <p>\n <input type=\"text\" v-model=\"saveFilename\" />\n <button @click=\"save()\">Save</button>\n </p>\n\n <p>\n <input type=\"file\" ref=\"loadFile\" accept=\".json\" />\n <button @click=\"load()\">Load</button>\n </p>\n </div>\n\n <h1>About / feedback</h1>\n <div class=\"about block\">\n <p>\n Created by Mark van Renswoude. Open-source and available under the Unlicense to the public domain on <a href=\"https://github.com/MvRens/CuttingBoard\" target=\"_blank\">Github</a>, where feedback is welcome under Issues.\n </p>\n <p>\n Heavily inspired by <a href=\"http://www.lastalias.com/cbdesigner/\">CBdesigner</a>.\n </p>\n </div>\n </div>\n\n <div class=\"app-preview\">\n <h1>Edge grain</h1>\n <EdgeGrainPreview :scale=\"1\" />\n\n <h1>End grain</h1>\n <EndGrainPreview :scale=\"1\" />\n </div>\n</template>\n\n<script>\nimport Settings from './components/Settings.vue'\nimport Layers from './components/Layers.vue'\nimport Wood from './components/Wood.vue'\nimport EndGrainPreview from './components/EndGrainPreview.vue'\nimport EdgeGrainPreview from './components/EdgeGrainPreview.vue'\n\nimport { saveAs } from 'file-saver';\nimport { bytesToBase64, base64ToBytes } from './lib/base64';\n\nexport default {\n name: 'App',\n components: {\n EndGrainPreview,\n EdgeGrainPreview,\n Settings,\n Layers,\n Wood\n },\n\n data()\n {\n return {\n saveFilename: 'My cutting board'\n }\n },\n\n created()\n {\n const self = this;\n const checkHash = () =>\n {\n if (!location.hash)\n return;\n\n const hash = location.hash.substring(1);\n try\n {\n const decoded = base64ToBytes(hash);\n if (decoded)\n self.$store.commit('loadMsgPack', decoded);\n }\n catch (e)\n {\n console.error(e);\n }\n }\n\n checkHash();\n\n window.addEventListener('hashchange', () =>\n {\n checkHash();\n });\n },\n\n computed: {\n hash()\n {\n return bytesToBase64(this.$store.getters.saveMsgPack);\n }\n },\n\n methods: {\n save()\n {\n const state = this.$store.getters.save;\n const blob = new Blob([state], { type: 'text/plain; charset=utf-8' });\n\n saveAs(blob, this.saveFilename + '.json');\n },\n\n\n load()\n {\n const loadFile = this.$refs.loadFile.files[0];\n if (!loadFile)\n return;\n\n this.saveFilename = loadFile.name.toLowerCase().endsWith('.json')\n ? loadFile.name.substring(0, loadFile.name.length - 5)\n : loadFile.name;\n\n const reader = new FileReader();\n reader.addEventListener('load', (event) =>\n {\n this.$store.commit('load', event.target.result);\n });\n reader.readAsBinaryString(loadFile);\n }\n },\n\n watch: {\n hash: (newValue) =>\n {\n history.replaceState({}, '', '#' + newValue);\n }\n }\n}\n</script>\n\n<style lang=\"scss\">\n#app {\n background-color: white;\n color: black;\n font-family: 'Verdana', 'Arial', sans-serif;\n font-size: 10pt;\n\n display: flex;\n flex-direction: horizontal;\n}\n\n\nh1\n{\n background-color: #f0f0f0;\n border-bottom: solid 1px #c0c0c0;\n font-size: 100%;\n margin-top: 0;\n margin-bottom: .5em;\n padding: .25em;\n}\n\n.app-settings\n{\n margin-right: 1em;\n\n .block\n {\n margin-bottom: 2em;\n }\n}\n\n.app-preview\n{\n .preview\n {\n margin-bottom: 1em;\n }\n}\n\n.about\n{\n width: 30em;\n}\n</style>\n","<template>\r\n <div class=\"settings\">\r\n <h2>Designer</h2>\r\n\r\n <label for=\"units\">Units</label>\r\n <select id=\"units\" :value=\"settings.units\" @change=\"$store.commit('updateSettings', { units: $event.target.value })\">\r\n <option value=\"mm\">Millimeters</option>\r\n <option value=\"cm\">Centimeters</option>\r\n <option value=\"inchdecimal\">Inches (decimal)</option>\r\n <!--<option value=\"inchfractional\">Inches (fractional)</option>-->\r\n </select>\r\n\r\n <label for=\"borders\">Show borders</label>\r\n <input id=\"borders\" type=\"checkbox\" :checked=\"settings.borders\" @change=\"$store.commit('updateSettings', { borders: $event.target.checked })\" />\r\n\r\n <h2>Material</h2>\r\n <label for=\"boardThickness\">Board thickness</label>\r\n <input id=\"boardThickness\" type=\"number\" :value=\"settings.boardThickness\" @change=\"$store.commit('updateSettings', { boardThickness: parseFloatDef($event.target.value) })\" />\r\n\r\n <label for=\"boardLength\">Board length</label>\r\n <input id=\"boardLength\" type=\"number\" :value=\"settings.boardLength\" @change=\"$store.commit('updateSettings', { boardLength: parseFloatDef($event.target.value) })\" />\r\n\r\n <label for=\"bladeKerf\">Blade kerf</label>\r\n <input id=\"bladeKerf\" type=\"number\" :value=\"settings.bladeKerf\" @change=\"$store.commit('updateSettings', { bladeKerf: parseFloatDef($event.target.value) })\" />\r\n\r\n <h2>End grain</h2>\r\n <label for=\"crosscutWidth\">Crosscut width</label>\r\n <input id=\"crosscutWidth\" type=\"number\" :value=\"settings.crosscutWidth\" @change=\"$store.commit('updateSettings', { crosscutWidth: parseFloatDef($event.target.value) })\" />\r\n\r\n <label for=\"alternateDirection\">Alternate direction</label>\r\n <input id=\"alternateDirection\" type=\"checkbox\" :checked=\"settings.alternateDirection\" @change=\"$store.commit('updateSettings', { alternateDirection: $event.target.checked })\" />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { units } from '../lib/units';\r\n\r\nexport default {\r\n computed: {\r\n settings() { return this.$store.state.settings; }\r\n },\r\n\r\n\r\n methods: {\r\n parseFloatDef(value)\r\n {\r\n const parsedValue = parseFloat(value);\r\n return Object.is(parsedValue, NaN) ? 0 : parsedValue;\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.settings\r\n{\r\n display: inline-grid;\r\n grid-template-columns: auto auto;\r\n grid-column-gap: 1em;\r\n grid-row-gap: .25em;\r\n\r\n h2\r\n {\r\n font-size: 80%;\r\n margin-top: 1em;\r\n margin-bottom: 0;\r\n grid-column: 1 / 3;\r\n }\r\n}\r\n</style>","const millimetersPerInch = 25.4;\r\nconst millimetersPerCentimeter = 10;\r\nconst pixelsPerMillimeter = 1;\r\n\r\n\r\n\r\nconst units = {\r\n convert(value, fromUnits, toUnits)\r\n {\r\n const millimeters = this.toMillimeters(value, fromUnits);\r\n return this.fromMillimeters(millimeters, toUnits);\r\n },\r\n\r\n\r\n toPixels(value, units)\r\n {\r\n return Math.ceil(this.toMillimeters(value, units) * pixelsPerMillimeter);\r\n },\r\n\r\n\r\n toMillimeters(value, units)\r\n {\r\n switch (units)\r\n {\r\n case 'mm': return value;\r\n case 'cm': return value * millimetersPerCentimeter;\r\n case 'inchdecimal': return value * millimetersPerInch;\r\n }\r\n\r\n console.error('Invalid units type: ' + units);\r\n return 0;\r\n },\r\n\r\n\r\n fromMillimeters(value, units)\r\n {\r\n switch (units)\r\n {\r\n case 'mm': return value;\r\n case 'cm': return value / millimetersPerCentimeter;\r\n case 'inchdecimal': return value / millimetersPerInch;\r\n }\r\n\r\n console.error('Invalid units type: ' + units);\r\n return 0;\r\n },\r\n\r\n\r\n display(value, units)\r\n {\r\n const displayValue = this.limitDecimals(value, 3);\r\n\r\n switch (units)\r\n {\r\n case 'mm': return displayValue + ' mm';\r\n case 'cm': return displayValue + ' cm';\r\n case 'inchdecimal': return displayValue + ' inch';\r\n }\r\n\r\n console.error('Invalid units type: ' + units);\r\n return displayValue;\r\n },\r\n\r\n\r\n limitDecimals(value, decimals)\r\n {\r\n // toFixed turns it into a string and pads it with zeroes\r\n const power = Math.pow(10, decimals);\r\n return Math.round(value * power) / power;\r\n }\r\n};\r\n\r\n\r\nexport { units }","import { render } from \"./Settings.vue?vue&type=template&id=7f9fc5e0&scoped=true\"\nimport script from \"./Settings.vue?vue&type=script&lang=js\"\nexport * from \"./Settings.vue?vue&type=script&lang=js\"\n\nimport \"./Settings.vue?vue&type=style&index=0&id=7f9fc5e0&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-7f9fc5e0\"\n\nexport default script","<template>\r\n <div class=\"layers\">\r\n <div class=\"add\">\r\n <button @click=\"addLayer()\">Add layer</button>\r\n </div>\r\n\r\n <div class=\"hint\">\r\n Tip: click and drag the layer number to move a layer\r\n </div>\r\n\r\n\r\n <span class=\"header\">&nbsp;</span>\r\n <span class=\"header\">Wood type</span>\r\n <span class=\"header\">Width</span>\r\n <span class=\"header\">&nbsp;</span>\r\n\r\n <template v-for=\"(layer, index) in layers\">\r\n <div class=\"index\" :class=\"{ dropTargetAbove: dropTarget === index, dropTargetBelow: dropTarget === layers.length && index === layers.length - 1 }\" :ref=\"'layer' + index\" @mousedown.prevent=\"startDrag(index)\">{{ index + 1 }}</div>\r\n <select v-model=\"layer.wood\" class=\"wood\">\r\n <option v-for=\"(item, index) in wood\" :value=\"index\">{{ item.name }}</option>\r\n </select>\r\n <input type=\"number\" class=\"width\" :value=\"layer.width\" @input=\"layer.width = parseFloatDef($event.target.value)\" />\r\n\r\n <div class=\"remove\">\r\n <button @click=\"removeLayer(index)\">X</button>\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { units } from '../lib/units';\r\n\r\nexport default {\r\n data()\r\n {\r\n return {\r\n dragIndex: null,\r\n dropTarget: null\r\n }\r\n },\r\n\r\n\r\n computed: {\r\n settings() { return this.$store.state.settings; },\r\n wood() { return this.$store.state.wood; },\r\n layers() { return this.$store.state.boards[0].layers; },\r\n },\r\n\r\n\r\n methods: {\r\n parseFloatDef(value)\r\n {\r\n const parsedValue = parseFloat(value);\r\n return Object.is(parsedValue, NaN) ? 0 : parsedValue;\r\n },\r\n\r\n\r\n addLayer()\r\n {\r\n this.$store.commit('addLayer', 0);\r\n },\r\n\r\n\r\n removeLayer(index)\r\n {\r\n this.$store.commit('removeLayer', { board: 0, layer: index });\r\n },\r\n\r\n\r\n startDrag(index)\r\n {\r\n this.dragIndex = index;\r\n this.dropTarget = index;\r\n\r\n const dragMouseMove = (event) =>\r\n {\r\n this.dropTarget = this.getTargetLayer(event.pageY);\r\n };\r\n\r\n let dragMouseUp;\r\n dragMouseUp = () =>\r\n {\r\n document.removeEventListener('mousemove', dragMouseMove);\r\n document.removeEventListener('mouseup', dragMouseUp);\r\n\r\n if (this.dragIndex !== this.dropTarget)\r\n this.$store.commit('moveLayer', { board: 0, from: this.dragIndex, to: this.dropTarget });\r\n\r\n this.dropTarget = null;\r\n this.dragIndex = null;\r\n };\r\n\r\n document.addEventListener('mousemove', dragMouseMove);\r\n document.addEventListener('mouseup', dragMouseUp);\r\n },\r\n\r\n\r\n getTargetLayer(yPos)\r\n {\r\n if (this.layers.length == 0)\r\n return null;\r\n\r\n const firstLayer = this.getPageOffsetRect(this.$refs.layer0);\r\n const lastLayer = this.getPageOffsetRect(this.$refs['layer' + (this.layers.length - 1)]);\r\n\r\n // On or above the first item\r\n if (yPos <= firstLayer.bottom)\r\n return 0;\r\n\r\n // Below the last item\r\n if (yPos >= lastLayer.bottom)\r\n return this.layers.length;\r\n\r\n // On the last item\r\n if (yPos >= lastLayer.top)\r\n return this.layers.length - 1;\r\n\r\n // Check the previous target first, as it is most likely unchanged due to how\r\n // often mouseMove events occur\r\n if (this.dropTarget !== null && this.dropTarget > 0 && this.dropTarget < this.layers.length - 1)\r\n {\r\n const currentTarget = this.getPageOffsetRect(this.$refs['layer' + this.dropTarget]);\r\n if (yPos >= currentTarget.top && yPos < currentTarget.bottom)\r\n return this.dropTarget;\r\n }\r\n\r\n // Just loop through all the layers, there shouldn't be enough to warrant anything more efficient\r\n for (let i = 1; i < this.layers.length - 1; i++)\r\n {\r\n const testTarget = this.getPageOffsetRect(this.$refs['layer' + i]);\r\n if (yPos >= testTarget.top && yPos < testTarget.bottom)\r\n return i;\r\n }\r\n\r\n // This should never occur, so it probably will!\r\n return null;\r\n },\r\n\r\n\r\n getPageOffsetRect(element)\r\n {\r\n const clientRect = element.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n\r\n return {\r\n top: clientRect.top + scrollTop,\r\n left: clientRect.left + scrollLeft,\r\n right: clientRect.right + scrollLeft,\r\n bottom: clientRect.bottom + scrollTop\r\n };\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.layers\r\n{\r\n display: inline-grid;\r\n grid-template-columns: 3em 20em 5em 3em;\r\n grid-column-gap: 1em;\r\n\r\n .hint\r\n {\r\n color: #808080;\r\n text-align: center;\r\n\r\n grid-column: 1 / 5;\r\n margin-bottom: 1em;\r\n }\r\n\r\n .index\r\n {\r\n cursor: pointer;\r\n\r\n &.dropTargetAbove\r\n {\r\n border-top: solid 1px black;\r\n }\r\n\r\n &.dropTargetBelow\r\n {\r\n border-bottom: solid 1px black;\r\n }\r\n }\r\n\r\n .add\r\n {\r\n grid-column: 2 / 5;\r\n padding-bottom: 1em;\r\n }\r\n\r\n .header\r\n {\r\n font-weight: bold;\r\n margin-bottom: .25em;\r\n }\r\n}\r\n</style>","import { render } from \"./Layers.vue?vue&type=template&id=631d833e&scoped=true\"\nimport script from \"./Layers.vue?vue&type=script&lang=js\"\nexport * from \"./Layers.vue?vue&type=script&lang=js\"\n\nimport \"./Layers.vue?vue&type=style&index=0&id=631d833e&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-631d833e\"\n\nexport default script","<template>\r\n <div class=\"wood\">\r\n <div class=\"add\">\r\n <button @click=\"addWood()\">Add wood type</button>\r\n </div>\r\n\r\n <span class=\"header\">&nbsp;</span>\r\n <span class=\"header\">Name</span>\r\n <span class=\"header\">Colour</span>\r\n <span class=\"header\">&nbsp;</span>\r\n\r\n <template v-for=\"(item, index) in wood\">\r\n <span>&nbsp;</span>\r\n <input type=\"text\" class=\"name\" v-model=\"item.name\" />\r\n <input type=\"color\" class=\"color\" v-model=\"item.color\" />\r\n\r\n <div class=\"remove\">\r\n <button @click=\"removeWood(index)\">X</button>\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n computed: {\r\n settings() { return this.$store.state.settings; },\r\n wood() { return this.$store.state.wood; }\r\n },\r\n\r\n\r\n methods: {\r\n addWood()\r\n {\r\n this.$store.commit('addWood');\r\n },\r\n\r\n\r\n removeWood(index)\r\n {\r\n this.$store.commit('removeWood', index);\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.wood\r\n{\r\n display: inline-grid;\r\n grid-template-columns: 3em 20em 5em 3em;\r\n grid-column-gap: 1em;\r\n\r\n .add\r\n {\r\n grid-column: 2 / 5;\r\n padding-bottom: 1em;\r\n }\r\n\r\n .header\r\n {\r\n font-weight: bold;\r\n margin-bottom: .25em;\r\n }\r\n}\r\n</style>","import { render } from \"./Wood.vue?vue&type=template&id=55181d8c&scoped=true\"\nimport script from \"./Wood.vue?vue&type=script&lang=js\"\nexport * from \"./Wood.vue?vue&type=script&lang=js\"\n\nimport \"./Wood.vue?vue&type=style&index=0&id=55181d8c&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-55181d8c\"\n\nexport default script","<template>\n <div class=\"preview\">\n <div class=\"dimensions\">Dimensions: {{ display(boardWidth) }} x {{ display(boardHeight) }} x {{ display(settings.crosscutWidth) }}</div>\n\n <svg\n :width=\"viewportWidth\"\n :height=\"viewportHeight\"\n :viewBox=\"viewBox\">\n <defs>\n <g id=\"strip\">\n <rect\n v-for=\"(layer, index) in layers\"\n :width=\"toPixels(settings.boardThickness)\"\n :height=\"toPixels(layer.width)\"\n x=\"0\"\n :y=\"getLayerOffset(index)\"\n :style=\"getLayerStyle(index)\" />\n </g>\n </defs>\n\n <use\n v-for=\"(strip, index) in stripsPerBoard\"\n xlink:href=\"#strip\"\n :x=\"toPixels(index * settings.boardThickness)\"\n y=\"0\"\n :transform=\"getLayerTransform(index)\" />\n </svg>\n </div>\n</template>\n\n<script>\nimport { units } from '../lib/units';\n\nexport default {\n props: {\n scale: Number\n },\n\n\n computed: {\n settings() { return this.$store.state.settings; },\n wood() { return this.$store.state.wood; },\n layers() { return this.$store.state.boards[0].layers; },\n\n stripsPerBoard()\n {\n const stripAndKerf = this.settings.crosscutWidth + this.settings.bladeKerf;\n if (stripAndKerf === 0)\n return 0;\n\n return Math.floor((this.settings.boardLength + this.settings.bladeKerf) / stripAndKerf);\n },\n\n boardWidth()\n {\n return this.stripsPerBoard * this.settings.boardThickness;\n },\n\n boardHeight()\n {\n if (this.layers.length == 0)\n return 0;\n\n return this.layers\n .map(currentValue => currentValue.width)\n .reduce((accumulator, currentValue) => accumulator + currentValue);\n },\n\n boardPixelWidth()\n {\n return this.toPixels(this.boardWidth);\n },\n\n boardPixelHeight()\n {\n return this.toPixels(this.boardHeight);\n },\n\n viewportWidth() { return Math.floor(this.boardPixelWidth * this.scale); },\n viewportHeight() { return Math.floor(this.boardPixelHeight * this.scale); },\n viewBox() { return '0 0 ' + this.boardPixelWidth + ' ' + this.boardPixelHeight; }\n },\n\n\n methods: {\n toPixels(value)\n {\n return units.toPixels(value, this.settings.units);\n },\n\n display(value)\n {\n return units.display(value, this.settings.units);\n },\n\n getLayerOffset(index)\n {\n if (index < 0 || index >= this.layers.length)\n return 0;\n\n let offset = 0;\n\n for (let i = 0; i < index; i++)\n offset += this.layers[i].width;\n\n return this.toPixels(offset);\n },\n\n getLayerStyle(index)\n {\n if (index < 0 || index >= this.layers.length)\n return 'fill: fuchsia';\n\n const woodIndex = this.layers[index].wood;\n if (woodIndex === null)\n return '';\n\n const borderStyle = this.settings.borders\n ? '; stroke-width: 1; stroke: black'\n : '';\n\n return 'fill: ' + this.wood[woodIndex].color + borderStyle;\n },\n\n getLayerTransform(index)\n {\n if (!this.settings.alternateDirection || (index % 2) == 0)\n return '';\n\n return 'scale(1, -1) translate(0, -' + this.boardPixelHeight + ')';\n }\n }\n}\n</script>","import { render } from \"./EndGrainPreview.vue?vue&type=template&id=d894300e\"\nimport script from \"./EndGrainPreview.vue?vue&type=script&lang=js\"\nexport * from \"./EndGrainPreview.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script","<template>\n <div class=\"preview\">\n <div class=\"dimensions\">Dimensions: {{ display(boardWidth) }} x {{ display(boardHeight) }} x {{ display(settings.boardThickness) }}</div>\n\n <svg\n :width=\"viewportWidth\"\n :height=\"viewportHeight\"\n :viewBox=\"viewBox\">\n\n <rect\n v-for=\"(layer, index) in layers\"\n :width=\"toPixels(settings.boardLength)\"\n :height=\"toPixels(layer.width)\"\n x=\"0\"\n :y=\"getLayerOffset(index)\"\n :style=\"getLayerStyle(index)\" />\n </svg>\n </div>\n</template>\n\n<script>\nimport { units } from '../lib/units';\n\nexport default {\n props: {\n scale: Number\n },\n\n\n computed: {\n settings() { return this.$store.state.settings; },\n wood() { return this.$store.state.wood; },\n layers() { return this.$store.state.boards[0].layers; },\n\n boardWidth() { return this.settings.boardLength; },\n\n boardHeight()\n {\n if (this.layers.length == 0)\n return 0;\n\n return this.layers\n .map(currentValue => currentValue.width)\n .reduce((accumulator, currentValue) => accumulator + currentValue);\n },\n\n boardPixelWidth()\n {\n return this.toPixels(this.boardWidth);\n },\n\n boardPixelHeight()\n {\n return this.toPixels(this.boardHeight);\n },\n\n viewportWidth() { return Math.floor(this.boardPixelWidth * this.scale); },\n viewportHeight() { return Math.floor(this.boardPixelHeight * this.scale); },\n viewBox() { return '0 0 ' + this.boardPixelWidth + ' ' + this.boardPixelHeight; }\n },\n\n\n methods: {\n toPixels(value)\n {\n return units.toPixels(value, this.settings.units);\n },\n\n display(value)\n {\n return units.display(value, this.settings.units);\n },\n\n getLayerOffset(index)\n {\n if (index < 0 || index >= this.layers.length)\n return 0;\n\n let offset = 0;\n\n for (let i = 0; i < index; i++)\n offset += this.layers[i].width;\n\n return this.toPixels(offset);\n },\n\n getLayerStyle(index)\n {\n if (index < 0 || index >= this.layers.length)\n return 'fill: fuchsia';\n\n const woodIndex = this.layers[index].wood;\n if (woodIndex === null)\n return '';\n\n const borderStyle = this.settings.borders\n ? '; stroke-width: 1; stroke: black'\n : '';\n\n return 'fill: ' + this.wood[woodIndex].color + borderStyle;\n }\n }\n}\n</script>","import { render } from \"./EdgeGrainPreview.vue?vue&type=template&id=ae7ca8c0\"\nimport script from \"./EdgeGrainPreview.vue?vue&type=script&lang=js\"\nexport * from \"./EdgeGrainPreview.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script","/*\r\nMIT License\r\nCopyright (c) 2020 Egor Nepomnyaschih\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n*/\r\n\r\n/*\r\n// This constant can also be computed with the following algorithm:\r\nconst base64abc = [],\r\n A = \"A\".charCodeAt(0),\r\n a = \"a\".charCodeAt(0),\r\n n = \"0\".charCodeAt(0);\r\nfor (let i = 0; i < 26; ++i) {\r\n base64abc.push(String.fromCharCode(A + i));\r\n}\r\nfor (let i = 0; i < 26; ++i) {\r\n base64abc.push(String.fromCharCode(a + i));\r\n}\r\nfor (let i = 0; i < 10; ++i) {\r\n base64abc.push(String.fromCharCode(n + i));\r\n}\r\nbase64abc.push(\"+\");\r\nbase64abc.push(\"/\");\r\n*/\r\nconst base64abc = [\r\n \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\",\r\n \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\",\r\n \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\",\r\n \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\",\r\n \"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"+\", \"/\"\r\n];\r\n\r\n/*\r\n// This constant can also be computed with the following algorithm:\r\nconst l = 256, base64codes = new Uint8Array(l);\r\nfor (let i = 0; i < l; ++i) {\r\n base64codes[i] = 255; // invalid character\r\n}\r\nbase64abc.forEach((char, index) => {\r\n base64codes[char.charCodeAt(0)] = index;\r\n});\r\nbase64codes[\"=\".charCodeAt(0)] = 0; // ignored anyway, so we just need to prevent an error\r\n*/\r\nconst base64codes = [\r\n 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r\n 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r\n 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,\r\n 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255,\r\n 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,\r\n 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,\r\n 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\r\n 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51\r\n];\r\n\r\nfunction getBase64Code(charCode) {\r\n if (charCode >= base64codes.length) {\r\n throw new Error(\"Unable to parse base64 string.\");\r\n }\r\n const code = base64codes[charCode];\r\n if (code === 255) {\r\n throw new Error(\"Unable to parse base64 string.\");\r\n }\r\n return code;\r\n}\r\n\r\nexport function bytesToBase64(bytes) {\r\n let result = '', i, l = bytes.length;\r\n for (i = 2; i < l; i += 3) {\r\n result += base64abc[bytes[i - 2] >> 2];\r\n result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];\r\n result += base64abc[((bytes[i - 1] & 0x0F) << 2) | (bytes[i] >> 6)];\r\n result += base64abc[bytes[i] & 0x3F];\r\n }\r\n if (i === l + 1) { // 1 octet yet to write\r\n result += base64abc[bytes[i - 2] >> 2];\r\n result += base64abc[(bytes[i - 2] & 0x03) << 4];\r\n result += \"==\";\r\n }\r\n if (i === l) { // 2 octets yet to write\r\n result += base64abc[bytes[i - 2] >> 2];\r\n result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];\r\n result += base64abc[(bytes[i - 1] & 0x0F) << 2];\r\n result += \"=\";\r\n }\r\n return result;\r\n}\r\n\r\nexport function base64ToBytes(str) {\r\n if (str.length % 4 !== 0) {\r\n throw new Error(\"Unable to parse base64 string.\");\r\n }\r\n const index = str.indexOf(\"=\");\r\n if (index !== -1 && index < str.length - 2) {\r\n throw new Error(\"Unable to parse base64 string.\");\r\n }\r\n let missingOctets = str.endsWith(\"==\") ? 2 : str.endsWith(\"=\") ? 1 : 0,\r\n n = str.length,\r\n result = new Uint8Array(3 * (n / 4)),\r\n buffer;\r\n for (let i = 0, j = 0; i < n; i += 4, j += 3) {\r\n buffer =\r\n getBase64Code(str.charCodeAt(i)) << 18 |\r\n getBase64Code(str.charCodeAt(i + 1)) << 12 |\r\n getBase64Code(str.charCodeAt(i + 2)) << 6 |\r\n getBase64Code(str.charCodeAt(i + 3));\r\n result[j] = buffer >> 16;\r\n result[j + 1] = (buffer >> 8) & 0xFF;\r\n result[j + 2] = buffer & 0xFF;\r\n }\r\n return result.subarray(0, result.length - missingOctets);\r\n}\r\n\r\nexport function base64encode(str, encoder = new TextEncoder()) {\r\n return bytesToBase64(encoder.encode(str));\r\n}\r\n\r\nexport function base64decode(str, decoder = new TextDecoder()) {\r\n return decoder.decode(base64ToBytes(str));\r\n}","import { render } from \"./App.vue?vue&type=template&id=2392c0c2\"\nimport script from \"./App.vue?vue&type=script&lang=js\"\nexport * from \"./App.vue?vue&type=script&lang=js\"\n\nimport \"./App.vue?vue&type=style&index=0&id=2392c0c2&lang=scss\"\nscript.render = render\n\nexport default script","import { createStore } from 'vuex';\nimport { units } from './lib/units';\n\nimport { serialize, deserialize } from '@ygoe/msgpack';\n\n\nfunction mergeObject(source, target)\n{\n for (const property in source)\n {\n if (!source.hasOwnProperty(property) || !target.hasOwnProperty(property))\n continue;\n\n target[property] = source[property];\n }\n}\n\n\nfunction parseFloatDef(value)\n{\n const parsedValue = parseFloat(value);\n return Object.is(parsedValue, NaN) ? 0 : parsedValue;\n}\n\n\n\nfunction loadObject(state, parsedPayload)\n{\n if (parsedPayload.hasOwnProperty('settings'))\n mergeObject(parsedPayload.settings, state.settings);\n\n if (parsedPayload.hasOwnProperty('boards'))\n {\n\n const newBoards = parsedPayload.boards.map(board =>\n {\n if (!board.hasOwnProperty('layers'))\n {\n return {\n layers: []\n };\n }\n\n return {\n layers: board.layers.map(layer =>\n {\n return {\n wood: parseFloatDef(layer.wood),\n width: parseFloatDef(layer.width)\n }\n })\n };\n })\n\n if (newBoards.length === 0)\n newBoards.push({ layers: [] });\n\n state.boards = newBoards;\n }\n\n if (parsedPayload.hasOwnProperty('wood'))\n {\n const newWood = parsedPayload.wood.map(item =>\n {\n return {\n name: item.name,\n color: item.color\n };\n });\n\n state.wood = newWood;\n }\n}\n\n\n\nexport default createStore({\n state: {\n settings: {\n units: 'cm',\n borders: false,\n boardThickness: 2,\n boardLength: 70,\n bladeKerf: 0.35,\n crosscutWidth: 3,\n\n alternateDirection: true\n },\n\n wood: [\n { name: 'Walnut', color: '#58443f' },\n { name: 'Maple', color: '#f2e0aa' },\n { name: 'Cherry', color: '#bb8359' },\n { name: 'Mahogany', color: '#98473f' },\n { name: 'Yellowheart', color: '#ffff84' },\n { name: 'White oak', color: '#fdf4b9' },\n { name: 'Bubinga', color: '#7e3c34' },\n { name: 'Jatoba', color: '#9b281c' },\n { name: 'Padouk', color: '#933350' }\n ],\n\n boards: [\n {\n layers: [\n { wood: 8, width: 1 },\n { wood: 1, width: 1.5 },\n { wood: 8, width: 2 },\n { wood: 1, width: 2 },\n { wood: 8, width: 15 },\n { wood: 1, width: 2 },\n { wood: 8, width: 1.5 },\n { wood: 1, width: 1 }\n ]\n }\n ]\n },\n\n mutations: {\n addLayer(state, board)\n {\n if (board < 0 || board >= state.boards.length)\n return;\n\n state.boards[board].layers.push({\n wood: 0,\n width: units.fromMillimeters(20, state.settings.units)\n });\n },\n\n removeLayer(state, payload)\n {\n if (payload.board < 0 || payload.board >= state.boards.length)\n return;\n\n const board = state.boards[payload.board];\n\n if (payload.layer < 0 || payload.layer >= board.layers.length)\n return;\n\n board.layers.splice(payload.layer, 1);\n },\n\n moveLayer(state, payload)\n {\n if (payload.board < 0 || payload.board >= state.boards.length)\n return;\n\n const board = state.boards[payload.board];\n\n if (payload.from < 0 || payload.from >= board.layers.length)\n return;\n\n if (payload.to < 0 || payload.to > board.layers.length)\n return;\n\n if (payload.to == board.layers.length)\n {\n // Move to end\n board.layers.push(board.layers[payload.from]);\n board.layers.splice(payload.from, 1);\n }\n else\n {\n const item = board.layers[payload.from];\n board.layers.splice(payload.from, 1);\n\n if (payload.to > payload.from)\n payload.to--;\n\n board.layers.splice(payload.to, 0, item);\n }\n },\n\n\n addWood(state)\n {\n state.wood.push({\n name: 'Wood #' + (state.wood.length + 1),\n color: '#f2e0aa'\n });\n },\n\n removeWood(state, index)\n {\n if (index < 0 || index >= state.wood.length)\n return;\n\n // Update all layers\n state.boards.forEach(board =>\n {\n board.layers.forEach(layer =>\n {\n if (layer.wood === index)\n layer.wood = null\n else if (layer.wood > index)\n layer.wood--;\n });\n });\n\n state.wood.splice(index, 1);\n },\n\n\n updateSettings(state, payload)\n {\n const oldUnits = state.settings.units;\n\n mergeObject(payload, state.settings);\n\n if (oldUnits !== state.settings.units)\n {\n // Convert the settings\n state.settings.boardThickness = units.limitDecimals(units.convert(state.settings.boardThickness, oldUnits, state.settings.units), 3);\n state.settings.boardLength = units.limitDecimals(units.convert(state.settings.boardLength, oldUnits, state.settings.units), 3);\n state.settings.bladeKerf = units.limitDecimals(units.convert(state.settings.bladeKerf, oldUnits, state.settings.units), 3);\n state.settings.crosscutWidth = units.limitDecimals(units.convert(state.settings.crosscutWidth, oldUnits, state.settings.units), 3);\n\n // Convert the layers\n state.boards.forEach(board =>\n {\n board.layers.forEach(layer =>\n {\n layer.width = units.limitDecimals(units.convert(layer.width, oldUnits, state.settings.units), 3);\n });\n });\n }\n },\n\n\n load(state, payload)\n {\n const parsedPayload = JSON.parse(payload);\n loadObject(state, parsedPayload);\n },\n\n loadMsgPack(state, payload)\n {\n try\n {\n const parsedPayload = deserialize(payload);\n loadObject(state, parsedPayload);\n }\n catch(e)\n {\n console.error(e);\n }\n }\n },\n\n getters: {\n save(state)\n {\n return JSON.stringify(state);\n },\n\n saveMsgPack(state)\n {\n return serialize(state);\n }\n }\n})\n","import { createApp } from 'vue'\nimport App from './App.vue'\nimport store from './store'\n\ncreateApp(App).use(store).mount('#app')\n","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Wood.vue?vue&type=style&index=0&id=55181d8c&lang=scss&scoped=true\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Settings.vue?vue&type=style&index=0&id=7f9fc5e0&lang=scss&scoped=true\"","export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../node_modules/vue-loader-v16/dist/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./App.vue?vue&type=style&index=0&id=2392c0c2&lang=scss\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Layers.vue?vue&type=style&index=0&id=631d833e&lang=scss&scoped=true\""],"sourceRoot":""}