UNPKG

kmap

Version:

Karnagh Map Editor

1,504 lines (1,219 loc) 1.69 MB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Kmap"] = factory(); else root["Kmap"] = factory(); })(self, function() { return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./index.js": /*!******************!*\ !*** ./index.js ***! \******************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* reexport safe */ _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__.Kmap) /* harmony export */ }); /* harmony import */ var _src_polyfills_all__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/all */ "./src/polyfills/all.js"); /* harmony import */ var _src_kmap_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./src/kmap.scss */ "./src/kmap.scss"); /* harmony import */ var _src_Kmap_Utility_Ready__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./src/Kmap/Utility/Ready */ "./src/Kmap/Utility/Ready.js"); /* harmony import */ var _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./src/Kmap/Kmap */ "./src/Kmap/Kmap.js"); // The public-path module must be imported first! // import './src/public-path.js'; // // Automatically install into div.kmap-cl-install, where the text // contents of the tag are JSON to configure Kmap _src_Kmap_Utility_Ready__WEBPACK_IMPORTED_MODULE_2__.Ready.go(function () { var elements = document.querySelectorAll('div.kmap-cl-install'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; element.classList.remove('kmap-cl-install'); var json = element.textContent; element.innerHTML = ''; var kmap = new _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__.Kmap(element, json); kmap.startNow(); element.style.display = 'block'; } }); /***/ }), /***/ "./src/Kmap/Generator.js": /*!*******************************!*\ !*** ./src/Kmap/Generator.js ***! \*******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Generator": () => (/* binding */ Generator) /* harmony export */ }); /* harmony import */ var _Logic_Minterms__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Logic/Minterms */ "./src/Logic/Minterms.js"); /** * This object manages the practice generator section. * @param main * @param element * @constructor */ var Generator = function Generator(main, element) { var _this = this; var mintermsSpan; var options = main.options; var initialize = function initialize() { var div = document.createElement('div'); div.classList.add('kmap-cl-generator'); element.appendChild(div); // Heading var h3 = document.createElement('h3'); h3.innerText = options.fixed ? 'Minterms' : 'Minterm Generator'; div.appendChild(h3); var form = document.createElement('form'); div.appendChild(form); var p = document.createElement('p'); p.innerText = 'Size: '; div.appendChild(p); if (options.fixed) { p.appendChild(document.createTextNode('' + options.size + ' Minterms: ')); } else { // // The size select control // var select = document.createElement('select'); p.appendChild(select); var options1 = ''; var options2 = ''; for (var s = 2; s <= 4; s++) { if (s === +main.options.size) { if (main.options.genDontCare) { options1 += '<option value="' + s + '">' + s + '</option>'; if (main.options.genDontCareOption) { options2 += '<option value="' + s + 'd" selected>' + s + " w/don't cares</option>"; } } else { options1 += '<option value="' + s + '" selected>' + s + '</option>'; if (main.options.genDontCareOption) { options2 += '<option value="' + s + 'd">' + s + " w/don't cares</option>"; } } } else { options1 += '<option value="' + s + '">' + s + '</option>'; if (main.options.genDontCareOption) { options2 += '<option value="' + s + 'd">' + s + " <span>w/don't cares</span></option>"; } } } select.innerHTML = options1 + options2; select.addEventListener('change', function (event) { event.preventDefault(); var val = select.value; var newSize = parseInt(val); main.options.genDontCare = val.match(/d$/) !== null; main.newSize(newSize); }); // // The Generate button // p.appendChild(document.createTextNode(' ')); var button = document.createElement('button'); button.innerText = 'Generate'; p.appendChild(button); p.appendChild(document.createTextNode(' ')); button.addEventListener('click', function (event) { event.preventDefault(); main.generate(); }); } mintermsSpan = document.createElement('span'); p.appendChild(mintermsSpan); _this.refresh(); }; this.refresh = function () { if (main.minterms.dontcare.length > 0) { mintermsSpan.innerHTML = main.minterms.list(true) + "<br>X=" + main.minterms.list_dontcare(true); } else { mintermsSpan.innerHTML = main.minterms.list(true); } }; initialize(); }; /***/ }), /***/ "./src/Kmap/Group.js": /*!***************************!*\ !*** ./src/Kmap/Group.js ***! \***************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Group": () => (/* binding */ Group) /* harmony export */ }); /** * A single group * @param groups Kmap.Group object * @param list List to add this item to * @param selected Minterms that are selected * @param color Color to draw item * @constructor */ var Group = function Group(groups, list, selected, color) { var _this = this; this.groups = groups; this.selected = selected; this.color = color; if (list === null) { return; } var lst = ''; var first = true; for (var i = 0; i < selected.length; i++) { if (!first) { lst += ','; } else { first = false; } if (i === 8) { lst += '<br/>'; } lst += selected[i]; } // var div = $('<div class="group">' + lst + '</div>'); var div = document.createElement('div'); div.classList.add('group'); div.innerHTML = lst; // var span = $('<span></span>'); // div.append(span); var span = document.createElement('span'); div.appendChild(span); // var a = $('<a href="javascript:;"></a>'); // span.append(a); var a = document.createElement('a'); span.appendChild(a); list.appendChild(div); a.addEventListener('click', function (event) { event.preventDefault(); list.removeChild(div); groups.remove(_this); }); div.style.backgroundColor = color; // div.css("background-color", color); }; Group.prototype.draw = function (ctx, wid, hit, insetDepth) { var inset = 15; var spacing = 10; var cols, rows, mapR, mapC, max; switch (this.groups.main.options.size) { case 2: cols = 2; rows = 2; mapR = [0, 1, 0, 1]; mapC = [0, 0, 1, 1]; max = 4; break; case 3: cols = 4; rows = 2; mapR = [0, 1, 0, 1, 0, 1, 0, 1]; mapC = [0, 0, 1, 1, 3, 3, 2, 2]; max = 8; break; case 4: cols = 4; rows = 4; mapR = [0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2]; mapC = [0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 2, 2]; max = 16; break; } var cnt = this.selected.length; if (cnt === max) { // We are wrapping the whole thing this.drawGroup(ctx, 0, 0, wid, hit, inset + spacing * insetDepth); return; } if (cnt === 1) { var c1 = mapC[this.selected[0]]; var r1 = mapR[this.selected[0]]; this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit / rows, inset + spacing * insetDepth); } else if (cnt == 2) { var c1 = mapC[this.selected[0]]; var r1 = mapR[this.selected[0]]; var c2 = mapC[this.selected[1]]; var r2 = mapR[this.selected[1]]; if (r1 == r2) { // Horizontal if (c2 < c1) { var t = c1; c1 = c2; c2 = t; } if (c2 - c1 > 1) { // Not adjacent! this.drawGroup(ctx, c2 * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth); this.drawGroup(ctx, (c1 - 1) * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth); } else { this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth); } } else { // Vertical if (r2 < r1) { var t = r1; r1 = r2; r2 = t; } if (r2 - r1 > 1) { // Not adjacent this.drawGroup(ctx, c1 * wid / cols, r2 * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth); this.drawGroup(ctx, c1 * wid / cols, (r1 - 1) * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth); } else { this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth); } } } else if (cnt == 4) { var c1 = mapC[this.selected[0]]; var r1 = mapR[this.selected[0]]; var c2 = mapC[this.selected[1]]; var r2 = mapR[this.selected[1]]; var c3 = mapC[this.selected[2]]; var r3 = mapR[this.selected[2]]; var c4 = mapC[this.selected[3]]; var r4 = mapR[this.selected[3]]; // Are all in same row? if (r1 == r2 && r2 == r3 && r3 == r4) { // Size 4 cover in the same row this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid * 4 / cols, hit / rows, inset + spacing * insetDepth); } else if (c1 == c2 && c2 == c3 && c3 == c4) { // Size 4 cover in the same column this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit * 4 / rows, inset + spacing * insetDepth); } else { // This must be square var wid4 = wid * 2 / cols; var hit4 = hit * 2 / rows; if (c1 == 0 && c2 == 0 && c3 == 3 && c4 == 3) { // This is a left/right side split if (r1 == 0 && r2 == 3 && r3 == 0 && r4 == 3) { // Four corner split this.drawGroup(ctx, -1 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); this.drawGroup(ctx, -1 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth); this.drawGroup(ctx, 3 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); this.drawGroup(ctx, 3 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth); } else { if (r1 > r2) { var t = r1; r1 = r2; r2 = t; } this.drawGroup(ctx, -1 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); this.drawGroup(ctx, 3 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); } } else if (r1 == 0 && r2 == 3) { if (c1 > c3) { var t = c1; c1 = c3; c3 = t; } // This is a top-bottom split this.drawGroup(ctx, c1 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); this.drawGroup(ctx, c1 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth); } else { // Simple square! if (c1 > c3) { var t = c1; c1 = c3; c3 = t; } if (r1 > r2) { var t = r1; r1 = r2; r2 = t; } this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth); } } } else if (cnt == 8) { var c1 = mapC[this.selected[0]]; var r1 = mapR[this.selected[0]]; var c2 = mapC[this.selected[1]]; var r2 = mapR[this.selected[1]]; var c3 = mapC[this.selected[2]]; var r3 = mapR[this.selected[2]]; var c4 = mapC[this.selected[3]]; var r4 = mapR[this.selected[3]]; var c5 = mapC[this.selected[4]]; var r5 = mapR[this.selected[4]]; if (c1 == c2 && c2 == c3 && c3 == c4) { var wid8 = wid * 2 / cols; var hit8 = hit * 4 / rows; // Vertical layout if (c1 == 0 && c5 == 3) { // Left/right split this.drawGroup(ctx, -1 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth); this.drawGroup(ctx, 3 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth); } else { if (c1 > c5) { c1 = c5; } this.drawGroup(ctx, c1 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth); } } else { //Horizontal layout var wid8 = wid * 4 / cols; var hit8 = hit * 2 / rows; if (r2 - r1 > 1) { // Split this.drawGroup(ctx, 0 * wid / cols, -1 * hit / rows, wid8, hit8, inset + spacing * insetDepth); this.drawGroup(ctx, 0 * wid / cols, 3 * hit / rows, wid8, hit8, inset + spacing * insetDepth); } else { if (r1 > r2) { r1 = r2; } this.drawGroup(ctx, 0 * wid / cols, r1 * hit / rows, wid8, hit8, inset + spacing * insetDepth); } } } }; Group.prototype.drawGroup = function (ctx, x1, y1, wid, hit, inset) { var x = x1 + inset; var y = y1 + inset; var width = wid - inset * 2 - 1; var height = hit - inset * 2 - 1; var radius = 30; ctx.lineWidth = 7; ctx.strokeStyle = this.color; ctx.beginPath(); ctx.moveTo(x, y + radius); ctx.lineTo(x, y + height - radius); ctx.arcTo(x, y + height, x + radius, y + height, radius); ctx.lineTo(x + width - radius, y + height); ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius); ctx.lineTo(x + width, y + radius); ctx.arcTo(x + width, y, x + width - radius, y, radius); ctx.lineTo(x + radius, y); ctx.arcTo(x, y, x, y + radius, radius); ctx.stroke(); }; /***/ }), /***/ "./src/Kmap/Groups.js": /*!****************************!*\ !*** ./src/Kmap/Groups.js ***! \****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Groups": () => (/* binding */ Groups) /* harmony export */ }); /* harmony import */ var _MessageDialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageDialog */ "./src/Kmap/MessageDialog.js"); /* harmony import */ var _Group__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Group */ "./src/Kmap/Group.js"); /** * The groups area of the editor */ var Groups = function Groups(main, sel) { var _this = this; var that = this; this.main = main; var list; var initialize = function initialize() { var button = document.createElement('button'); sel.appendChild(button); button.innerText = 'Cover'; list = document.createElement('div'); list.classList.add('list'); sel.appendChild(list); _this.groups = []; _this.colorN = 0; button.addEventListener('click', function (event) { event.preventDefault(); var selected = main.work.map.selected; if (main.options.strict) { // Determine how many common bits there are var and1 = Math.pow(2, main.options.size) - 1; var and2 = and1; for (var i = 0; i < selected.length; i++) { var _sel = selected[i]; and1 &= _sel; and2 &= ~_sel; } var or = and1 | and2; var bits = 0; var size = main.options.size; for (var _i = 0; _i < size; _i++) { if ((or & 1) === 1) { bits++; } or >>= 1; } // Test for valid var valid = true; switch (selected.length) { case 1: break; case 2: valid = bits == size - 1; break; case 4: valid = bits == size - 2; break; case 8: valid = bits == size - 3; break; case 16: break; default: var html = '<p>Grouping must be of some power of two minterms.</p><p>The only ' + 'groupings possible are 1, 2, 4, 8, or 16, depending on the size of the ' + 'Karnaugh map.</p>'; var dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", html); dlg.open(); return; } if (!valid) { var _html = '<p>Your minterm grouping is invalid.</p><p>Groupings must be such ' + 'that there are bits in common. This means the groupings must be a rectangle ' + 'on the Karnaugh map. This can be a 1 by 4 rectangle or a 2 by 2 rectangle for ' + 'a grouping of 4, for example. Note that the map does <em>wrap around</em> at' + ' the edges, so the right side is adjacent to the left side, for example.</p>'; var _dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", _html); _dlg.open(); return; } // // Ensure this group does not already exist // for (var _i2 = 0; _i2 < that.groups.length && valid; _i2++) { if (that.groups[_i2].selected.length === selected.length) { var ok = false; for (var j = 0; j < that.groups[_i2].selected.length; j++) { if (that.groups[_i2].selected[j] !== selected[j]) { ok = true; break; } } if (!ok) { valid = false; var _html2 = '<p>This cover already exists.</p>'; var _dlg2 = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", _html2); _dlg2.open(); return; } } } } _this.add_group(selected); _this.drawGroups(); main.work.map.clear(); }); }; /** * Add a new group (cover) * @param minterms Array of minterms in the group */ this.add_group = function (minterms) { var group = new _Group__WEBPACK_IMPORTED_MODULE_1__.Group(this, list, minterms, this.colors[this.colorN]); this.colorN = (this.colorN + 1) % this.colors.length; this.groups.push(group); }; /** * Draw all of the groups on the canvas */ this.drawGroups = function () { var canvas = main.work.map.get_canvas(); var ctx = canvas.getContext("2d"); var wid = canvas.width; var hit = canvas.height; ctx.clearRect(0, 0, wid, hit); var size = main.options.size; var counter = []; for (var i = 0; i < Math.pow(2, size); i++) { counter.push(0); } for (var i = 0; i < this.groups.length; i++) { var group = this.groups[i]; var max = 1; for (var j = 0; j < group.selected.length; j++) { counter[group.selected[j]]++; if (counter[group.selected[j]] > max) { max = counter[group.selected[j]]; } } group.draw(ctx, wid, hit, max); } }; this.clear = function () { list.innerHTML = ''; this.colorN = 0; this.groups = []; this.drawGroups(); }; this.remove = function (group) { for (var i = 0; i < this.groups.length; i++) { if (this.groups[i] === group) { this.groups.splice(i, 1); } } this.drawGroups(); }; initialize(); /* '<button>Group</button>' + ' <div class="list">' + ' <div class="group">' + ' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' + ' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' + ' </div>' + ' <div class="group">' + ' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' + ' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' + ' </div>' + ' <div class="group">' + ' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' + ' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' + ' </div>' + ' <div class="group">' + ' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' + ' <span><a href="javascript:;"></a><img src="images/x.png"></a></span> ' + ' </div>' + ' <div class="group">' + ' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' + ' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' + ' </div>' + ' </div>' + */ }; Groups.prototype.colors = ["#0000FF", "#808088", "#FF8800", "#008080", "#BDB76B", "#800000", "#00FF88", "#778899", "#FFA500", "#9ACD32", "#4682B4"]; /***/ }), /***/ "./src/Kmap/Kmap.js": /*!**************************!*\ !*** ./src/Kmap/Kmap.js ***! \**************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Kmap": () => (/* binding */ Kmap) /* harmony export */ }); /* harmony import */ var _Options__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options */ "./src/Kmap/Options.js"); /* harmony import */ var _Utility_Ready__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utility/Ready */ "./src/Kmap/Utility/Ready.js"); /* harmony import */ var _Main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Main */ "./src/Kmap/Main.js"); /** * Create an instance of Kmap Karnaugh Map. * @constructor */ var Kmap = function Kmap(sel, options) { var _this = this; // // Master set of the version // var PACKAGE = __webpack_require__(/*! ../../package.json */ "./package.json"); this.version = PACKAGE.version; // The Options object that manages user options this.options = new _Options__WEBPACK_IMPORTED_MODULE_0__.Options(options); // A collection of Main objects. var mains = []; this.start = function () { _Utility_Ready__WEBPACK_IMPORTED_MODULE_1__.Ready.go(function () { _this.startNow(); }); }; /** * Start Kmap running now. Does not wait for document ready. */ this.startNow = function () { if (sel instanceof Element) { var main = new _Main__WEBPACK_IMPORTED_MODULE_2__.Main(_this, sel); mains.push(main); } else { var elements = document.querySelectorAll(sel); for (var i = 0; i < elements.length; i++) { var element = elements[i]; var _main = new _Main__WEBPACK_IMPORTED_MODULE_2__.Main(_this, element); mains.push(_main); } } if (mains.length === 1) { return mains[0]; } return null; }; }; /***/ }), /***/ "./src/Kmap/Main.js": /*!**************************!*\ !*** ./src/Kmap/Main.js ***! \**************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Main": () => (/* binding */ Main) /* harmony export */ }); /* harmony import */ var _Work__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Work */ "./src/Kmap/Work.js"); /* harmony import */ var _Generator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Generator */ "./src/Kmap/Generator.js"); /* harmony import */ var _Solution__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Solution */ "./src/Kmap/Solution.js"); /* harmony import */ var _Manual__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Manual */ "./src/Kmap/Manual.js"); /* harmony import */ var _Logic_Minterms__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Logic/Minterms */ "./src/Logic/Minterms.js"); /** * Main window management object * @param kmap Kmap object (parent) * @param element The DOM element to use * @constructor */ var Main = function Main(kmap, element) { var _this = this; this.options = kmap.options; this.element = element; // Ensure empty and add the kmap-cl class element.innerHTML = ''; element.classList.add('kmap-cl'); // The current minterms this.minterms = new _Logic_Minterms__WEBPACK_IMPORTED_MODULE_4__.Minterms(); this.work = null; this.generator = null; this.solution = null; this.manual = null; this.initialize = function () { if (_this.options.generator) { _this.generator = new _Generator__WEBPACK_IMPORTED_MODULE_1__.Generator(_this, element); } if (_this.options.manual) { _this.manual = new _Manual__WEBPACK_IMPORTED_MODULE_3__.Manual(_this, element); } if (_this.options.map) { _this.work = new _Work__WEBPACK_IMPORTED_MODULE_0__.Work(_this, element); } _this.solution = new _Solution__WEBPACK_IMPORTED_MODULE_2__.Solution(_this, element); // Generate initial minterms if (_this.options.minterms.length === 0) { _this.generate(); } else { _this.set(_this.options.minterms, _this.options.dontcare); } if (_this.options.solved) { _this.solution.solve(); } }; /** * Generate a new set of minterms with optional don't cares */ this.generate = function () { this.minterms.size = this.options.size; if (this.options.genDontCare) { var dcMax = 8; switch (this.options.size) { case 2: dcMax = 2; break; case 3: dcMax = 4; break; } this.minterms.generate_bounded(0.5, 1, Math.pow(2, this.options.size) - 1, 0.2, 1, dcMax); newMinterms(); } else { this.minterms.generate_bounded(0.5, 1, Math.pow(2, this.options.size) - 1); newMinterms(); } }; this.set = function (minterms, dontcare) { this.minterms.set_from(minterms, dontcare); newMinterms(); }; var newMinterms = function newMinterms() { if (_this.solution !== null) { _this.solution.clear(); } _this.options.minterms = _this.minterms.minterms.slice(); _this.options.dontcare = _this.minterms.dontcare.slice(); if (_this.work !== null) { _this.work.render(); } if (_this.generator !== null) { _this.generator.refresh(); } }; this.newSize = function (size) { this.options.size = size; this.generate(); }; this.initialize(); }; /***/ }), /***/ "./src/Kmap/Manual.js": /*!****************************!*\ !*** ./src/Kmap/Manual.js ***! \****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Manual": () => (/* binding */ Manual) /* harmony export */ }); /** * Manual entry of minterms and don't cares support * @param main Main object * @param element Element we are adding this component to * @constructor */ var Manual = function Manual(main, element) { var that = this; var labels = main.options.labels; var manualMinterms, manualDontCares, manualVariables; var initialize = function initialize() { var div = document.createElement('div'); div.classList.add('kmap-cl-manual'); element.appendChild(div); var h3 = document.createElement('h3'); h3.innerHTML = 'Manual Entry'; div.appendChild(h3); // var form = '<form><div class="left">' + // '<p><label for="manual-minterms">Minterms: </label><br><input type="text" id="manual-minterms" spellcheck="false"></p>' + // '<p><label for="manual-dontcares">Don\'t cares: </label><br><input type="text" id="manual-dontcares" spellcheck="false"></p>' + // '<p><button>Take</button></p>' + // '</div><div class="right">' + // '<p><label for="manual-variables">Labels: </label><br><input type="text" id="manual-variables" value="' + // labels + '" spellcheck="false"></p>' + // '</div></form>'; var form = document.createElement('form'); div.appendChild(form); // // Left div // var left = document.createElement('div'); form.appendChild(left); // <p><label for="manual-minterms">Minterms: </label><br><input type="text" id="manual-minterms" spellcheck="false"></p> var p = document.createElement('p'); left.appendChild(p); var label = document.createElement('label'); p.appendChild(label); label.innerText = 'Minterms: '; label.appendChild(document.createElement('br')); manualMinterms = document.createElement('input'); manualMinterms.setAttribute('type', 'text'); manualMinterms.setAttribute('spellcheck', 'false'); label.appendChild(manualMinterms); // <p><label for="manual-dontcares">Don\'t cares: </label><br><input type="text" id="manual-dontcares" spellcheck="false"></p> p = document.createElement('p'); left.appendChild(p); label = document.createElement('label'); p.appendChild(label); label.innerText = 'Don\'t cares: '; label.appendChild(document.createElement('br')); manualDontCares = document.createElement('input'); manualDontCares.setAttribute('type', 'text'); manualDontCares.setAttribute('spellcheck', 'false'); label.appendChild(manualDontCares); // <p><button>Take</button></p> p = document.createElement('p'); left.appendChild(p); var take = document.createElement('button'); p.appendChild(take); take.innerText = 'Take'; // // Right div // var right = document.createElement('div'); form.appendChild(right); // <p><label for="manual-variables">Labels: </label><br><input type="text" id="manual-variables" value="' + // labels + '" spellcheck="false"></p> p = document.createElement('p'); right.appendChild(p); label = document.createElement('label'); p.appendChild(label); label.innerText = 'Labels: '; label.appendChild(document.createElement('br')); manualVariables = document.createElement('input'); manualVariables.setAttribute('type', 'text'); manualVariables.setAttribute('spellcheck', 'false'); label.appendChild(manualVariables); manualVariables.value = labels; take.addEventListener('click', function (event) { event.preventDefault(); var mintermslist = parse(manualMinterms.value); var dontcarelist = parse(manualDontCares.value); // Get the labels, stripping any HTML tags just in case var labels = manualVariables.value.replace(/(<([^>]+)>)/ig, ""); main.options.labels = labels.split(","); main.set(mintermslist, dontcarelist); }); }; function parse(input) { var reM = /m/g; var re = /[, ]+/g; var items = input.replace(reM, '').split(re); var ret = []; items.forEach(function (item) { if (item !== "") { ret.push(parseInt(item)); } }); return ret; } initialize(); }; /***/ }), /***/ "./src/Kmap/Map.js": /*!*************************!*\ !*** ./src/Kmap/Map.js ***! \*************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Map": () => (/* binding */ Map) /* harmony export */ }); /* harmony import */ var _MessageDialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageDialog */ "./src/Kmap/MessageDialog.js"); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /** * The actual Karnaugh Map * @param main * @param element * @constructor */ var Map = function Map(main, element) { var _this = this; this.main = main; this.element = element; this.selected = []; var topLeft, botRight, canvas; var initialize = function initialize() { var table = document.createElement('table'); table.classList.add('kmap-cl'); element.appendChild(table); // Make a local copy of the labels, converting // _1 to <sub>1</sub> var labels = []; var _iterator = _createForOfIteratorHelper(main.options.labels), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var label = _step.value; labels.push(label.replace(/_([a-zA-Z0-9])*/g, '<sub>$1</sub>')); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var left, right, rest, colheads; if (+main.options.size === 2) { var A = labels[0]; var B = labels[1]; left = B; right = A; rest = "<th>" + A + "'</th><th>" + A + "</th>"; colheads = [B + "'", B]; } else if (+main.options.size === 3) { var _A = labels[0]; var _B = labels[1]; var C = labels[2]; left = C; right = _A + _B; rest = "<th>" + _A + "'" + _B + "'</th><th>" + _A + "'" + _B + "</th><th>" + _A + _B + "</th><th>" + _A + _B + "'</th>"; colheads = [C + "'", C]; } else { var _A2 = labels[0]; var _B2 = labels[1]; var _C = labels[2]; var D = labels[3]; left = _C + D; right = _A2 + _B2; rest = "<th>" + _A2 + "'" + _B2 + "'</th><th>" + _A2 + "'" + _B2 + "</th><th>" + _A2 + _B2 + "</th><th>" + _A2 + _B2 + "'</th>"; colheads = [_C + "'" + D + "'", _C + "'" + D, _C + D, _C + D + "'"]; } /* * Top row first */ var tr = document.createElement('tr'); tr.innerHTML = '<th><div class="kmap-cl-left">' + left + '</div><div class="kmap-cl-line"></div><div class="kmap-cl-right">' + right + '</div></th>' + rest; table.appendChild(tr); /* * Rest of the table */ var rows = +main.options.size === 4 ? 4 : 2; var cols = +main.options.size === 2 ? 2 : 4; for (var r = 1; r <= rows; r++) { tr = document.createElement('tr'); tr.innerHTML = '<th>' + colheads[r - 1] + '</th>'; for (var c = 1; c <= cols; c++) { var td = make_cell(c, r); tr.appendChild(td); if (r === 1 && c === 1) { topLeft = td; } else if (r === rows && c === cols) { botRight = td; } } table.appendChild(tr); } canvas = document.createElement('canvas'); canvas.setAttribute('width', '1000'); canvas.setAttribute('height', '1000'); _this.canvas = canvas; element.appendChild(canvas); setTimeout(function () { set_canvas(); }, 0); window.addEventListener('resize', set_canvas); }; this.get_canvas = function () { return this.canvas; }; this.destroy = function () { window.removeEventListener('resize', set_canvas); }; function set_canvas() { var tl = { left: topLeft.offsetLeft, top: topLeft.offsetTop }; var br = { left: botRight.offsetLeft, top: botRight.offsetTop }; canvas.style.top = tl.top + 'px'; canvas.style.left = tl.left + 'px'; canvas.style.width = br.left - tl.left + botRight.offsetWidth + 'px'; canvas.style.height = br.top - tl.top + botRight.offsetHeight + 'px'; } var make_cell = function make_cell(c, r) { var td = document.createElement('td'); var minterm = to_minterm(c, r); var bit = '0'; for (var i = 0; i < main.options.minterms.length; i++) { if (minterm === +main.options.minterms[i]) { bit = '1'; break; } } for (i = 0; i < main.options.dontcare.length; i++) { if (minterm === +main.options.dontcare[i]) { bit = 'X'; break; } } if (main.options.labelMinterms) { td.innerHTML = '<span class="minterm">m' + minterm + '</span>' + bit; } else { td.innerHTML = bit; } td.addEventListener('click', function (event) { event.preventDefault(); if (_this.main.options.strict && bit === '0') { var html = '<p>You are only allowed to select cells that are either true ' + 'or set to don\'t care.</p><p>We are grouping minterms that all are true ' + 'so we can minimize the circuit. So, only true cells can be grouped.</p>'; var dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", html); dlg.open(); return; } if (td.classList.contains("kmap-cl-selected")) { td.classList.remove("kmap-cl-selected"); var n = _this.selected.indexOf(minterm); if (n > -1) { _this.selected.splice(n, 1); } } else { td.classList.add("kmap-cl-selected"); if (!is_selected(minterm)) { _this.selected.push(minterm); _this.selected.sort(function (a, b) { return a - b; }); } } }); return td; }; var to_minterm = function to_minterm(c, r) { var map; if (+_this.main.options.size === 2) { map = [[0, 2], [1, 3]]; } else if (+_this.main.options.size === 3) { map = [[0, 2, 6, 4], [1, 3, 7, 5]]; } else { map = [[0, 4, 12, 8], [1, 5, 13, 9], [3, 7, 15, 11], [2, 6, 14, 10]]; } return map[r - 1][c - 1]; }; var is_selected = function is_selected(minterm) { return _this.selected.indexOf(minterm) > -1; // }; this.clear = function () { this.selected = []; var tds = this.element.querySelectorAll('td'); var _iterator2 = _createForOfIteratorHelper(tds), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var td = _step2.value; td.classList.remove('kmap-cl-selected'); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } }; initialize(); }; /***/ }), /***/ "./src/Kmap/MessageDialog.js": /*!***********************************!*\ !*** ./src/Kmap/MessageDialog.js ***! \***********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "MessageDialog": () => (/* binding */ MessageDialog) /* harmony export */ }); /** * The standard Message dialog box. * * Pretty minimalist dialog box * * @param main The Main object * @param title Title for the dialog box * @param body Body HTML to put in the dialog box * @constructor */ var MessageDialog = function MessageDialog(main, title, body) { var div = null; this.open = function () { // The top level dialog element div = document.createElement('div'); div.classList.add('kmap-cl-dlg'); main.element.appendChild(div); // The mask var mask = document.createElement('div'); div.appendChild(mask); // The dialog box itself var dlg = document.createElement('div'); div.appendChild(dlg); // Title bar var tb = document.createElement('div'); dlg.appendChild(tb); tb.innerText = title; // Body var db = document.createElement('div'); dlg.appendChild(db); db.innerHTML = body; // Controls var controls = document.createElement('div'); dlg.appendChild(controls); var ok = document.createElement('button'); controls.appendChild(ok); ok.innerText = 'Ok'; ok.addEventListener('click', function (event) { event.preventDefault(); if (div !== null) { main.element.removeChild(div); div = null; } }); }; }; /***/ }), /***/ "./src/Kmap/Options.js": /*!*****************************!*\ !*** ./src/Kmap/Options.js ***! \*****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Options": () => (/* binding */ Options) /* harmony export */ }); /** * User interface options. * * Options can be passed as a Javascript Object, JSON, or base64-encoded JSON * * @param options User provided options that override the default values. * @constructor */ var Options = function Options(options) { options = options ? options : {}; if (options !== Object(options)) { if (options.substr(0, 1) === '{') { options = JSON.parse(options); } else { // Not JSON, must be base64 encoded options = JSON.parse(atob(options)); } } /// The input size: 2, 3, or 4 this.size = 4; /// The minterms. Set to integers starting at 0 this.minterms = []; // [1, 2, 7, 8, 9, 14]; /// The don't care minterms this.dontcare = []; /// Labels for the variables. this.labels = ['A', 'B', 'C', 'D']; /// Generate don't care maps this.genDontCare = false; /// Are don't cares an option for the generator? this.genDontCareOption = true; // // User interface sections // /// Include the generator? this.generator = true; /// Include the manual data entry section? this.manual = false; /// Include the map? this.map = true; /// Include the solution section? this.solution = true; /// Include the To PNG button this.toPNG = false; /// If set true, practice generate features are disabled this.fixed = false; /// Verbose answers on mistakes this.verbose = true; /// If true, the minterm name appears in each cell. this.labelMinterms = true; /// If set true, user input is checked for selecting invalid cells /// such as zeros. this.strict = true; /// If true, the header Karnaugh Map is included with an option to hide the map this.mapHeading = true; /// A results selector. Selector that will be set to the success value /// if the expression successfully checks this.resultSel = null; /// Value resultsSel will be set to if check is successful ('fail' otherwise) this.success = 'success'; /// Selector that will be set to the expression each time check is pressed. this.expressionSel = null; /// Is the solve button provided? this.solve = false; /// Is the problem solved? this.solved = false; /// Optional application tag this.appTag = null; /// Optional name for test result this.name = null; /// Optional test result API this.testAPI = null; /// Content type to send (can be json if required) this.contentType = 'application/x-www-form-urlencoded; charset=UTF-8'; for (var property in options) { if (options.hasOwnProperty(property)) { if (!this.hasOwnProperty(property)) { throw new Error("Invalid option " + property); } this[property] = options[property]; } } }; /***/ }), /***/ "./src/Kmap/Solution.js": /*!******************************!*\ !*** ./src/Kmap/Solution.js ***! \******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Solution": () => (/* binding */ Solution) /* harmony export */ }); /* harmony import */ var _Logic_Expression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Logic/Expression */ "./src/Logic/Expression.js"); /* harmony import */ var _Logic_QuineMcCluskeySolver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Logic/QuineMcCluskeySolver */ "./src/Logic/QuineMcCluskeySolver.js"); /* harmony import */ var _Utility_Ajax__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Utility/Ajax */ "./src/Kmap/Utility/Ajax.js"); /* harmony import */ var _Utility_JsonAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Utility/JsonAPI */ "./src/Kmap/Utility/JsonAPI.js"); /* harmony import */ var _Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Vendor/Blob.js */ "./src/Vendor/Blob.js"); /* harmony import */ var _Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var _Vendor_FileSaver_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Vendor/FileSaver.js */ "./src/Vendor/FileSaver.js"); /* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! html2canvas */ "../../.yarn/cache/html2canvas-npm-1.0.0-rc.7-8212b6d6fa-c0c6626e6f.zip/node_modules/html2canvas/dist/html2canvas.js"); /* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(html2canvas__WEBPACK_IMPORTED_MODULE_6__); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /** * Practice page solution form * @param main Main object * @param element Parent element * @constructor */ var Solution = function Solution(main, element) { var _this = this; this.main = main; // The various section elements var div = null, expressionInput = null, result = null; var initialize = function initialize() { // We only create the div is the user wants the solution // interface or is a solution is presented. if (main.options.solution || main.options.solved) { div = document.createElement('div'); div.classList.add('kmap-cl-solution'); element.append(div); // If a solution is presented, we don't need the interface if (main.options.solution && !main.options.solved) { addDiv(); } // Results div result = document.createElement('div'); div.appendChild(result); } }; // Add the <div> to main var addDiv = function addDiv() { // Heading var h3 = document.createElement('h3'); h3.innerText = 'Solution'; div.appendChild(h3); var form = document.createElement('form'); div.appendChild(form); // // Enter expression // '<p><label>Enter Expression<br><input type="text" spellcheck="false" class="expression"></label></p>' // var p = document.createElement('p'); form.appendChild(p); var label = document.createElement('label'); p.appendChild(label); label.innerText = 'Enter Expression'; label.appendChild(document.createElement('br')); expressionInput = document.createElement('input'); expressionInput.setAttribute('type', 'text'); expressionInput.setAttribute('spellch