1 line
55 KiB
Plaintext
1 line
55 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/App.vue?eabf","webpack:///./src/store.js","webpack:///./src/main.js","webpack:///./src/components/Wood.vue?ca33","webpack:///./src/App.vue?2a08","webpack:///./src/components/Settings.vue?59e7","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","components","EndGrainPreview","EdgeGrainPreview","Settings","Layers","Wood","getters","blob","Blob","loadFile","files","toLowerCase","endsWith","substring","reader","FileReader","readAsBinaryString","mergeObject","source","createStore","mutations","payload","moveLayer","forEach","updateSettings","oldUnits","parsedPayload","JSON","parse","newBoards","newWood","stringify","createApp","App","use","store","mount"],"mappings":"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","file":"js/app.0b618788.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 <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';\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 = 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</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\"> </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\" :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\"> </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 <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\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 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=5cda0da4\"\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 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=0e942631\"\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=539f9f59\"\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=539f9f59&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: '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\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!./App.vue?vue&type=style&index=0&id=539f9f59&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!./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!./Layers.vue?vue&type=style&index=0&id=631d833e&lang=scss&scoped=true\""],"sourceRoot":""} |