1 line
43 KiB
Plaintext
1 line
43 KiB
Plaintext
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/App.vue?633e","webpack:///./src/components/Layers.vue?483f","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/App.vue?eabf","webpack:///./src/store.js","webpack:///./src/main.js","webpack:///./src/components/Wood.vue?ca33","webpack:///./src/components/Settings.vue?800c"],"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","id","accept","href","target","saveFilename","save","load","scale","for","checked","settings","borders","$store","commit","$event","boardThickness","parseFloatDef","boardLength","bladeKerf","crosscutWidth","alternateDirection","millimetersPerInch","millimetersPerCentimeter","pixelsPerMillimeter","units","toPixels","this","toMillimeters","console","error","fromMillimeters","computed","state","methods","parsedValue","parseFloat","is","NaN","render","__scopeId","addLayer","layers","layer","index","wood","item","width","removeLayer","boards","board","addWood","color","removeWood","viewportWidth","height","viewportHeight","viewBox","x","y","getLayerOffset","style","getLayerStyle","props","Number","boardWidth","boardHeight","map","currentValue","reduce","accumulator","Math","floor","offset","woodIndex","borderStyle","stripsPerBoard","strip","xlink:href","transform","getLayerTransform","stripAndKerf","components","EndGrainPreview","EdgeGrainPreview","Settings","Layers","Wood","getters","blob","Blob","loadFile","document","getElementById","files","toLowerCase","endsWith","substring","reader","FileReader","addEventListener","event","readAsBinaryString","mergeObject","source","createStore","mutations","payload","forEach","updateSettings","parsedPayload","JSON","parse","newBoards","newWood","stringify","createApp","App","use","store","mount"],"mappings":"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","file":"js/app.ed26f79c.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","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=420bc5c9&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=535527d4&lang=scss&scoped=true\"","<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 <input type=\"text\" v-model=\"saveFilename\" />\n <button @click=\"save()\">Save</button>\n </p>\n\n <p>\n <input type=\"file\" id=\"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 <EndGrainPreview :scale=\"1\" />\n\n <h1>End grain</h1>\n <EdgeGrainPreview :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';\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 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 = document.getElementById(\"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</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, .todo\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\" disabled>\r\n <option value=\"mm\">Millimeters</option>\r\n <option value=\"cm\">Centimeters</option>\r\n <option value=\"inch\">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 toPixels(value, units)\r\n {\r\n return 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 'inch': 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 'inch': 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\r\nexport { units }","import { render } from \"./Settings.vue?vue&type=template&id=660f17f9&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=660f17f9&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-660f17f9\"\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 <span class=\"header\"> </span>\r\n <span class=\"header\">Wood type</span>\r\n <span class=\"header\">Width</span>\r\n <span class=\"header\"> </span>\r\n\r\n <template v-for=\"(layer, index) in layers\">\r\n <div class=\"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 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</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 .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=535527d4&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=535527d4&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-535527d4\"\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\"> </span>\r\n <span class=\"header\">Name</span>\r\n <span class=\"header\">Colour</span>\r\n <span class=\"header\"> </span>\r\n\r\n <template v-for=\"(item, index) in wood\">\r\n <span> </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 <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.toPixels(this.settings.boardLength); },\n\n boardHeight()\n {\n return this.layers\n .map(currentValue => currentValue.width)\n .reduce((accumulator, currentValue) => accumulator + currentValue);\n },\n\n viewportWidth() { return Math.floor(this.boardWidth * this.scale); },\n viewportHeight() { return Math.floor(this.boardHeight * this.scale); },\n viewBox() { return '0 0 ' + this.boardWidth + ' ' + this.boardHeight; }\n },\n\n\n methods: {\n toPixels(value)\n {\n return units.toPixels(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 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 \"./EndGrainPreview.vue?vue&type=template&id=f0162250\"\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 <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=\"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 const boardWidth = this.stripsPerBoard * this.settings.boardThickness;\n return this.toPixels(boardWidth);\n },\n\n boardHeight()\n {\n return this.layers\n .map(currentValue => currentValue.width)\n .reduce((accumulator, currentValue) => accumulator + currentValue);\n },\n\n viewportWidth() { return Math.floor(this.boardWidth * this.scale); },\n viewportHeight() { return Math.floor(this.boardHeight * this.scale); },\n viewBox() { return '0 0 ' + this.boardWidth + ' ' + this.boardHeight; }\n },\n\n\n methods: {\n toPixels(value)\n {\n return units.toPixels(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 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.boardHeight + ')';\n }\n }\n}\n</script>","import { render } from \"./EdgeGrainPreview.vue?vue&type=template&id=e3d956ee\"\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","import { render } from \"./App.vue?vue&type=template&id=420bc5c9\"\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=420bc5c9&lang=scss\"\nscript.render = render\n\nexport default script","import { createStore } from 'vuex';\nimport { units } from './lib/units';\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\nexport default createStore({\n state: {\n settings: {\n units: 'mm',\n borders: false,\n boardThickness: 20,\n boardLength: 700,\n bladeKerf: 3.5,\n crosscutWidth: 30,\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: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 },\n { wood: 0, width: 20 },\n { wood: 1, width: 20 }\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 if (payload.layer < 0 || payload.layer >= state.boards[payload.board].length)\n return;\n\n state.boards[payload.board].layers.splice(payload.layer, 1);\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 mergeObject(payload, state.settings);\n },\n\n\n load(state, payload)\n {\n const parsedPayload = JSON.parse(payload);\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 // TODO validate layers and wood types and apply the new sets\n }\n },\n\n getters: {\n save(state)\n {\n return JSON.stringify(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=660f17f9&lang=scss&scoped=true\""],"sourceRoot":""} |