happo 2.7.7 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/happo +1 -1
- data/lib/happo/public/0144a92667ed2e8a8b13.worker.js +56 -0
- data/lib/happo/public/0622a1eb2a5b4dab0d7d.worker.js +62 -0
- data/lib/happo/public/088cc9d4615d51d37661.worker.js +68 -0
- data/lib/happo/public/11b439cedd6aa6a01e71.worker.js +68 -0
- data/lib/happo/public/15b1495833b5b13f5f51.worker.js +62 -0
- data/lib/happo/public/167f0a5b59a8c27815fe.worker.js +62 -0
- data/lib/happo/public/19f5f7403fb4a2ba42e2.worker.js +62 -0
- data/lib/happo/public/1a86029ce53b1aa81f68.worker.js +62 -0
- data/lib/happo/public/1b6803fbc7b07f61cba2.worker.js +74 -0
- data/lib/happo/public/1d3dc560f1f39393dafe.worker.js +62 -0
- data/lib/happo/public/203272bf00c349325c60.worker.js +62 -0
- data/lib/happo/public/220e711d4abdbc4bd32f.worker.js +62 -0
- data/lib/happo/public/25ad7a1e52bd424ca81d.worker.js +62 -0
- data/lib/happo/public/26d95a76207ba0fe6c25.worker.js +74 -0
- data/lib/happo/public/28237f0668f12dfb456c.worker.js +62 -0
- data/lib/happo/public/2a7a935f3b9526c6f7ab.worker.js +74 -0
- data/lib/happo/public/2c00cb8d0a2eb5dd4078.worker.js +68 -0
- data/lib/happo/public/2c71ddb5b15a755d4644.worker.js +68 -0
- data/lib/happo/public/32648d3dfb22995f4066.worker.js +68 -0
- data/lib/happo/public/3452650686a8096b2bb7.worker.js +68 -0
- data/lib/happo/public/346cefcc1572890455b8.worker.js +68 -0
- data/lib/happo/public/35bd63f58bb69ac267ea.worker.js +68 -0
- data/lib/happo/public/360e0acb872760f43b07.worker.js +68 -0
- data/lib/happo/public/3818f1c91ce4d4d8b724.worker.js +62 -0
- data/lib/happo/public/3cc2e649d9b6ff62f4ab.worker.js +62 -0
- data/lib/happo/public/3deccedc8fbb96bb1aa7.worker.js +68 -0
- data/lib/happo/public/3e672be26a7a8864a342.worker.js +68 -0
- data/lib/happo/public/41aa7471344a79ff98f2.worker.js +68 -0
- data/lib/happo/public/423ba9f549f3829873e6.worker.js +62 -0
- data/lib/happo/public/463eb0ecadbb11365ca4.worker.js +62 -0
- data/lib/happo/public/47c52ff0e060fedb841f.worker.js +62 -0
- data/lib/happo/public/4e685162de1d8a9b102d.worker.js +56 -0
- data/lib/happo/public/4eea1b4008ed68e41f82.worker.js +62 -0
- data/lib/happo/public/4f6b0faf1b43e93a1404.worker.js +62 -0
- data/lib/happo/public/54ba8bc7a595358209d2.worker.js +68 -0
- data/lib/happo/public/589c2f9547d240ac8a57.worker.js +68 -0
- data/lib/happo/public/5a8c0588ca745d7904f7.worker.js +68 -0
- data/lib/happo/public/5b3cabd81f7d8688f7a5.worker.js +62 -0
- data/lib/happo/public/5f5c9f07cb5117c523a2.worker.js +68 -0
- data/lib/happo/public/5fb8c7066659ea1b57e2.worker.js +62 -0
- data/lib/happo/public/5fb962cc191a60b42af0.worker.js +68 -0
- data/lib/happo/public/62c7585d1d23297b316f.worker.js +62 -0
- data/lib/happo/public/62e676d31cbf8aaa9359.worker.js +68 -0
- data/lib/happo/public/65efcf6aee5e3ef33539.worker.js +68 -0
- data/lib/happo/public/693d4918a5dae465c134.worker.js +68 -0
- data/lib/happo/public/69d106b071dd31ad86de.worker.js +68 -0
- data/lib/happo/public/730c035f5c2b404ff225.worker.js +62 -0
- data/lib/happo/public/7609088c49b73ee2e3e1.worker.js +68 -0
- data/lib/happo/public/76161d401db5bb36980a.worker.js +62 -0
- data/lib/happo/public/7d9febb46b37ddffa2d5.worker.js +62 -0
- data/lib/happo/public/7f29af56bd0ea82d77d9.worker.js +68 -0
- data/lib/happo/public/80009e8bc0ffd29d3390.worker.js +62 -0
- data/lib/happo/public/830db6cc9c99c2e8e9c1.worker.js +62 -0
- data/lib/happo/public/85ad69599657de02d20d.worker.js +68 -0
- data/lib/happo/public/875e790f3e64476b3aa0.worker.js +68 -0
- data/lib/happo/public/8fa9a7b2a5f19075eedc.worker.js +74 -0
- data/lib/happo/public/906ce908877052838b8e.worker.js +62 -0
- data/lib/happo/public/9472102d9a6d2577f988.worker.js +62 -0
- data/lib/happo/public/9ac309ab34f48e7af07c.worker.js +68 -0
- data/lib/happo/public/9cdd6f0763fd866a5118.worker.js +62 -0
- data/lib/happo/public/HappoApp.bundle.js +2 -0
- data/lib/happo/public/a8bfebcafc4935d15b00.worker.js +1 -0
- data/lib/happo/public/aa7ae8013f9780eb8acb.worker.js +68 -0
- data/lib/happo/public/b20a32590dfe259f4fe3.worker.js +62 -0
- data/lib/happo/public/b25ebdd4e2d2dee8c7b1.worker.js +68 -0
- data/lib/happo/public/b7a49d603b1d50f535b2.worker.js +68 -0
- data/lib/happo/public/b8e667564ad96f5c77f4.worker.js +68 -0
- data/lib/happo/public/b913c562805ec9a01635.worker.js +68 -0
- data/lib/happo/public/bab832c7110d15a5f43b.worker.js +62 -0
- data/lib/happo/public/bfcf99c9b2bf3d58ec7f.worker.js +62 -0
- data/lib/happo/public/c0aeff8b32c9911c8547.worker.js +68 -0
- data/lib/happo/public/c2297ce40f0d071ec173.worker.js +1 -0
- data/lib/happo/public/c3d7b17359c21ff82281.worker.js +68 -0
- data/lib/happo/public/c9f7adcce3de80eb759a.worker.js +68 -0
- data/lib/happo/public/card-current.png +0 -0
- data/lib/happo/public/card-previous.png +0 -0
- data/lib/happo/public/d7b87aec5f1e4f2a7a5d.worker.js +68 -0
- data/lib/happo/public/d8fefa1bd98baa4e38da.worker.js +62 -0
- data/lib/happo/public/db617ae6458966f4acae.worker.js +68 -0
- data/lib/happo/public/dialog-current.png +0 -0
- data/lib/happo/public/dialog-previous.png +0 -0
- data/lib/happo/public/e247eaa7506f44b5b847.worker.js +62 -0
- data/lib/happo/public/e92bb4e1e06843fa771e.worker.js +62 -0
- data/lib/happo/public/e9e2d97848e0059e15c5.worker.js +62 -0
- data/lib/happo/public/ea87c48552c960ed7a1c.worker.js +74 -0
- data/lib/happo/public/eb5aafba8d16a397517a.worker.js +68 -0
- data/lib/happo/public/edc218b655b9ef694b3e.worker.js +74 -0
- data/lib/happo/public/eea64a6efa0620a576d7.worker.js +68 -0
- data/lib/happo/public/f269a8e7ffca13e9366a.worker.js +68 -0
- data/lib/happo/public/f81ed0eec7edfa2dfadb.worker.js +62 -0
- data/lib/happo/public/fcd20ee3e5a10e8667bb.worker.js +68 -0
- data/lib/happo/public/full-page-large-current.png +0 -0
- data/lib/happo/public/full-page-large-previous.png +0 -0
- data/lib/happo/public/full-page-small-current.png +0 -0
- data/lib/happo/public/full-page-small-previous.png +0 -0
- data/lib/happo/public/happo-styles.css +28 -3
- data/lib/happo/public/major-diff-large-current.png +0 -0
- data/lib/happo/public/major-diff-large-previous.png +0 -0
- data/lib/happo/public/major-diff-small-current.png +0 -0
- data/lib/happo/public/major-diff-small-previous.png +0 -0
- data/lib/happo/public/modal-current.png +0 -0
- data/lib/happo/public/modal-previous.png +0 -0
- data/lib/happo/public/small-current.png +0 -0
- data/lib/happo/public/small-previous.png +0 -0
- data/lib/happo/public/wide-current.png +0 -0
- data/lib/happo/public/wide-previous.png +0 -0
- data/lib/happo/runner.rb +25 -31
- data/lib/happo/server.rb +81 -12
- data/lib/happo/uploader.rb +1 -2
- data/lib/happo/utils.rb +1 -1
- data/lib/happo/version.rb +1 -1
- data/lib/happo/views/diffs.erb +9 -14
- data/lib/happo.rb +0 -1
- metadata +107 -21
- data/lib/happo/public/HappoDiffs.jsx +0 -391
- data/lib/happo/snapshot_comparer.rb +0 -81
- data/lib/happo/snapshot_comparison_image/base.rb +0 -108
- data/lib/happo/snapshot_comparison_image/gutter.rb +0 -34
- data/lib/happo/snapshot_comparison_image/overlayed.rb +0 -88
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/******/ (function(modules) { // webpackBootstrap
|
|
2
|
+
/******/ // The module cache
|
|
3
|
+
/******/ var installedModules = {};
|
|
4
|
+
|
|
5
|
+
/******/ // The require function
|
|
6
|
+
/******/ function __webpack_require__(moduleId) {
|
|
7
|
+
|
|
8
|
+
/******/ // Check if module is in cache
|
|
9
|
+
/******/ if(installedModules[moduleId])
|
|
10
|
+
/******/ return installedModules[moduleId].exports;
|
|
11
|
+
|
|
12
|
+
/******/ // Create a new module (and put it into the cache)
|
|
13
|
+
/******/ var module = installedModules[moduleId] = {
|
|
14
|
+
/******/ exports: {},
|
|
15
|
+
/******/ id: moduleId,
|
|
16
|
+
/******/ loaded: false
|
|
17
|
+
/******/ };
|
|
18
|
+
|
|
19
|
+
/******/ // Execute the module function
|
|
20
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
21
|
+
|
|
22
|
+
/******/ // Flag the module as loaded
|
|
23
|
+
/******/ module.loaded = true;
|
|
24
|
+
|
|
25
|
+
/******/ // Return the exports of the module
|
|
26
|
+
/******/ return module.exports;
|
|
27
|
+
/******/ }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
31
|
+
/******/ __webpack_require__.m = modules;
|
|
32
|
+
|
|
33
|
+
/******/ // expose the module cache
|
|
34
|
+
/******/ __webpack_require__.c = installedModules;
|
|
35
|
+
|
|
36
|
+
/******/ // __webpack_public_path__
|
|
37
|
+
/******/ __webpack_require__.p = "";
|
|
38
|
+
|
|
39
|
+
/******/ // Load entry module and return exports
|
|
40
|
+
/******/ return __webpack_require__(0);
|
|
41
|
+
/******/ })
|
|
42
|
+
/************************************************************************/
|
|
43
|
+
/******/ ([
|
|
44
|
+
/* 0 */
|
|
45
|
+
/***/ function(module, exports, __webpack_require__) {
|
|
46
|
+
|
|
47
|
+
eval("'use strict';\n\nvar _getDiffPixel2 = __webpack_require__(1);\n\nvar _getDiffPixel3 = _interopRequireDefault(_getDiffPixel2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar RED = [255, 0, 0, 255];\nvar GREEN = [0, 200, 0, 255];\nvar GRAY = [100, 100, 100, 255];\n\nvar GUTTER_WIDTH = 20 * 4;\nvar GUTTER_GAP = 4 * 4;\n\nfunction getDataIndex(row, width, index) {\n return GUTTER_WIDTH * (row + 1) + width * row + index;\n}\n\nself.addEventListener('message', function (_ref) {\n var _ref$data = _ref.data;\n var previousImageData = _ref$data.previousImageData;\n var currentImageData = _ref$data.currentImageData;\n\n var width = previousImageData[0].length;\n var height = previousImageData.length;\n\n var diffImageSize = (GUTTER_WIDTH + width) * height;\n\n var data = new Uint8ClampedArray(diffImageSize);\n\n for (var row = 0; row < height; row++) {\n // Render image\n var isRowChanged = false;\n for (var index = 0; index < width; index += 4) {\n var _getDiffPixel = (0, _getDiffPixel3.default)([previousImageData[row][index], previousImageData[row][index + 1], previousImageData[row][index + 2], previousImageData[row][index + 3]], [currentImageData[row][index], currentImageData[row][index + 1], currentImageData[row][index + 2], currentImageData[row][index + 3]]);\n\n var diff = _getDiffPixel.diff;\n var pixel = _getDiffPixel.pixel;\n\n\n if (diff > 0) {\n isRowChanged = true;\n }\n\n var dataIndex = getDataIndex(row, width, index);\n data[dataIndex + 0] = pixel[0]; // r\n data[dataIndex + 1] = pixel[1]; // g\n data[dataIndex + 2] = pixel[2]; // b\n data[dataIndex + 3] = pixel[3]; // a\n }\n\n // Render gutter\n var gutterColor = void 0;\n if (previousImageData[row][3] === 0) {\n // Pixel is transparent in previous image, which means that a row was\n // added here.\n gutterColor = GREEN;\n } else if (currentImageData[row][3] === 0) {\n // Pixel is transparent in current image, which means that a row was\n // removed here.\n gutterColor = RED;\n } else if (isRowChanged) {\n gutterColor = GRAY;\n } else {\n gutterColor = null;\n }\n\n for (var _index = 0; _index < GUTTER_WIDTH - GUTTER_GAP; _index += 4) {\n if (gutterColor !== null) {\n var _dataIndex = getDataIndex(row, width, _index) - GUTTER_WIDTH;\n data[_dataIndex + 0] = gutterColor[0];\n data[_dataIndex + 1] = gutterColor[1];\n data[_dataIndex + 2] = gutterColor[2];\n data[_dataIndex + 3] = gutterColor[3];\n }\n }\n }\n\n self.postMessage({\n data: data,\n width: (GUTTER_WIDTH + width) / 4,\n height: height\n });\n\n self.close();\n});//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvd29ya2Vycy9JbWFnZURpZmZXb3JrZXIuanM/ZjExYiJdLCJuYW1lcyI6WyJSRUQiLCJHUkVFTiIsIkdSQVkiLCJHVVRURVJfV0lEVEgiLCJHVVRURVJfR0FQIiwiZ2V0RGF0YUluZGV4Iiwicm93Iiwid2lkdGgiLCJpbmRleCIsInNlbGYiLCJhZGRFdmVudExpc3RlbmVyIiwiZGF0YSIsInByZXZpb3VzSW1hZ2VEYXRhIiwiY3VycmVudEltYWdlRGF0YSIsImxlbmd0aCIsImhlaWdodCIsImRpZmZJbWFnZVNpemUiLCJVaW50OENsYW1wZWRBcnJheSIsImlzUm93Q2hhbmdlZCIsImRpZmYiLCJwaXhlbCIsImRhdGFJbmRleCIsImd1dHRlckNvbG9yIiwicG9zdE1lc3NhZ2UiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7Ozs7O0FBRUEsSUFBTUEsTUFBTSxDQUFDLEdBQUQsRUFBTSxDQUFOLEVBQVMsQ0FBVCxFQUFZLEdBQVosQ0FBWjtBQUNBLElBQU1DLFFBQVEsQ0FBQyxDQUFELEVBQUksR0FBSixFQUFTLENBQVQsRUFBWSxHQUFaLENBQWQ7QUFDQSxJQUFNQyxPQUFPLENBQUMsR0FBRCxFQUFNLEdBQU4sRUFBVyxHQUFYLEVBQWdCLEdBQWhCLENBQWI7O0FBRUEsSUFBTUMsZUFBZSxLQUFLLENBQTFCO0FBQ0EsSUFBTUMsYUFBYSxJQUFJLENBQXZCOztBQUVBLFNBQVNDLFlBQVQsQ0FBc0JDLEdBQXRCLEVBQTJCQyxLQUEzQixFQUFrQ0MsS0FBbEMsRUFBeUM7QUFDdkMsU0FBUUwsZ0JBQWdCRyxNQUFNLENBQXRCLENBQUQsR0FBOEJDLFFBQVFELEdBQXRDLEdBQTZDRSxLQUFwRDtBQUNEOztBQUVEQyxLQUFLQyxnQkFBTCxDQUFzQixTQUF0QixFQUFpQyxnQkFLM0I7QUFBQSx1QkFKSkMsSUFJSTtBQUFBLE1BSEZDLGlCQUdFLGFBSEZBLGlCQUdFO0FBQUEsTUFGRkMsZ0JBRUUsYUFGRkEsZ0JBRUU7O0FB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QUFFRjs7QUFFRGIsT0FBS2MsV0FBTCxDQUFpQjtBQUNmWixjQURlO0FBRWZKLFdBQU8sQ0FBQ0osZUFBZUksS0FBaEIsSUFBeUIsQ0FGakI7QUFHZlE7QUFIZSxHQUFqQjs7QUFNQU4sT0FBS2UsS0FBTDtBQUNELENBOUVEIiwiZmlsZSI6IjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZ2V0RGlmZlBpeGVsIGZyb20gJy4uL2dldERpZmZQaXhlbCc7XG5cbmNvbnN0IFJFRCA9IFsyNTUsIDAsIDAsIDI1NV07XG5jb25zdCBHUkVFTiA9IFswLCAyMDAsIDAsIDI1NV07XG5jb25zdCBHUkFZID0gWzEwMCwgMTAwLCAxMDAsIDI1NV07XG5cbmNvbnN0IEdVVFRFUl9XSURUSCA9IDIwICogNDtcbmNvbnN0IEdVVFRFUl9HQVAgPSA0ICogNDtcblxuZnVuY3Rpb24gZ2V0RGF0YUluZGV4KHJvdywgd2lkdGgsIGluZGV4KSB7XG4gIHJldHVybiAoR1VUVEVSX1dJRFRIICogKHJvdyArIDEpKSArICh3aWR0aCAqIHJvdykgKyBpbmRleDtcbn1cblxuc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgKHtcbiAgZGF0YToge1xuICAgIHByZXZpb3VzSW1hZ2VEYXRhLFxuICAgIGN1cnJlbnRJbWFnZURhdGEsXG4gIH0sXG59KSA9PiB7XG4gIGNvbnN0IHdpZHRoID0gcHJldmlvdXNJbWFnZURhdGFbMF0ubGVuZ3RoO1xuICBjb25zdCBoZWlnaHQgPSBwcmV2aW91c0ltYWdlRGF0YS5sZW5ndGg7XG5cbiAgY29uc3QgZGlmZkltYWdlU2l6ZSA9IChHVVRURVJfV0lEVEggKyB3aWR0aCkgKiBoZWlnaHQ7XG5cbiAgY29uc3QgZGF0YSA9IG5ldyBVaW50OENsYW1wZWRBcnJheShkaWZmSW1hZ2VTaXplKTtcblxuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBoZWlnaHQ7IHJvdysrKSB7XG4gICAgLy8gUmVuZGVyIGltYWdlXG4gICAgbGV0IGlzUm93Q2hhbmdlZCA9IGZhbHNlO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB3aWR0aDsgaW5kZXggKz0gNCkge1xuICAgICAgY29uc3QgeyBkaWZmLCBwaXhlbCB9ID0gZ2V0RGlmZlBpeGVsKFxuICAgICAgICBbXG4gICAgICAgICAgcHJldmlvdXNJbWFnZURhdGFbcm93XVtpbmRleF0sXG4gICAgICAgICAgcHJldmlvdXNJbWFnZURhdGFbcm93XVtpbmRleCArIDFdLFxuICAgICAgICAgIHByZXZpb3VzSW1hZ2VEYXRhW3Jvd11baW5kZXggKyAyXSxcbiAgICAgICAgICBwcmV2aW91c0ltYWdlRGF0YVtyb3ddW2luZGV4ICsgM10sXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICBjdXJyZW50SW1hZ2VEYXRhW3Jvd11baW5kZXhdLFxuICAgICAgICAgIGN1cnJlbnRJbWFnZURhdGFbcm93XVtpbmRleCArIDFdLFxuICAgICAgICAgIGN1cnJlbnRJbWFnZURhdGFbcm93XVtpbmRleCArIDJdLFxuICAgICAgICAgIGN1cnJlbnRJbWFnZURhdGFbcm93XVtpbmRleCArIDNdLFxuICAgICAgICBdXG4gICAgICApO1xuXG4gICAgICBpZiAoZGlmZiA+IDApIHtcbiAgICAgICAgaXNSb3dDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YUluZGV4ID0gZ2V0RGF0YUluZGV4KHJvdywgd2lkdGgsIGluZGV4KTtcbiAgICAgIGRhdGFbZGF0YUluZGV4ICsgMF0gPSBwaXhlbFswXTsgLy8gclxuICAgICAgZGF0YVtkYXRhSW5kZXggKyAxXSA9IHBpeGVsWzFdOyAvLyBnXG4gICAgICBkYXRhW2RhdGFJbmRleCArIDJdID0gcGl4ZWxbMl07IC8vIGJcbiAgICAgIGRhdGFbZGF0YUluZGV4ICsgM10gPSBwaXhlbFszXTsgLy8gYVxuICAgIH1cblxuICAgIC8vIFJlbmRlciBndXR0ZXJcbiAgICBsZXQgZ3V0dGVyQ29sb3I7XG4gICAgaWYgKHByZXZpb3VzSW1hZ2VEYXRhW3Jvd11bM10gPT09IDApIHtcbiAgICAgIC8vIFBpeGVsIGlzIHRyYW5zcGFyZW50IGluIHByZXZpb3VzIGltYWdlLCB3aGljaCBtZWFucyB0aGF0IGEgcm93IHdhc1xuICAgICAgLy8gYWRkZWQgaGVyZS5cbiAgICAgIGd1dHRlckNvbG9yID0gR1JFRU47XG4gICAgfSBlbHNlIGlmIChjdXJyZW50SW1hZ2VEYXRhW3Jvd11bM10gPT09IDApIHtcbiAgICAgIC8vIFBpeGVsIGlzIHRyYW5zcGFyZW50IGluIGN1cnJlbnQgaW1hZ2UsIHdoaWNoIG1lYW5zIHRoYXQgYSByb3cgd2FzXG4gICAgICAvLyByZW1vdmVkIGhlcmUuXG4gICAgICBndXR0ZXJDb2xvciA9IFJFRDtcbiAgICB9IGVsc2UgaWYgKGlzUm93Q2hhbmdlZCkge1xuICAgICAgZ3V0dGVyQ29sb3IgPSBHUkFZO1xuICAgIH0gZWxzZSB7XG4gICAgICBndXR0ZXJDb2xvciA9IG51bGw7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IEdVVFRFUl9XSURUSCAtIEdVVFRFUl9HQVA7IGluZGV4ICs9IDQpIHtcbiAgICAgIGlmIChndXR0ZXJDb2xvciAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBnZXREYXRhSW5kZXgocm93LCB3aWR0aCwgaW5kZXgpIC0gR1VUVEVSX1dJRFRIO1xuICAgICAgICBkYXRhW2RhdGFJbmRleCArIDBdID0gZ3V0dGVyQ29sb3JbMF07XG4gICAgICAgIGRhdGFbZGF0YUluZGV4ICsgMV0gPSBndXR0ZXJDb2xvclsxXTtcbiAgICAgICAgZGF0YVtkYXRhSW5kZXggKyAyXSA9IGd1dHRlckNvbG9yWzJdO1xuICAgICAgICBkYXRhW2RhdGFJbmRleCArIDNdID0gZ3V0dGVyQ29sb3JbM107XG4gICAgICB9XG4gICAgfVxuXG4gIH1cblxuICBzZWxmLnBvc3RNZXNzYWdlKHtcbiAgICBkYXRhLFxuICAgIHdpZHRoOiAoR1VUVEVSX1dJRFRIICsgd2lkdGgpIC8gNCxcbiAgICBoZWlnaHQsXG4gIH0pO1xuXG4gIHNlbGYuY2xvc2UoKTtcbn0pO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9qcy9zcmMvd29ya2Vycy9JbWFnZURpZmZXb3JrZXIuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9");
|
|
48
|
+
|
|
49
|
+
/***/ },
|
|
50
|
+
/* 1 */
|
|
51
|
+
/***/ function(module, exports, __webpack_require__) {
|
|
52
|
+
|
|
53
|
+
eval("'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = getDiffPixel;\n\nvar _compose = __webpack_require__(2);\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _euclideanDistance = __webpack_require__(3);\n\nvar _euclideanDistance2 = _interopRequireDefault(_euclideanDistance);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar WHITE = [255, 255, 255, 255];\n\nfunction getDiffPixel(previousPixel, currentPixel) {\n // Compute a score that represents the difference between 2 pixels\n //\n // This method simply takes the Euclidean distance between the RGBA channels\n // of 2 colors over the maximum possible Euclidean distance. This gives us a\n // percentage of how different the two colors are.\n //\n // Although it would be more perceptually accurate to calculate a proper\n // Delta E in Lab colorspace, we probably don't need perceptual accuracy for\n // this application, and it is nice to avoid the overhead of converting RGBA\n // to Lab.\n var diff = (0, _euclideanDistance2.default)(previousPixel, currentPixel) / _euclideanDistance.MAX_EUCLIDEAN_DISTANCE;\n\n if (diff === 0) {\n return {\n diff: diff,\n pixel: (0, _compose2.default)([currentPixel[0], currentPixel[1], currentPixel[2], 40], WHITE)\n };\n }\n\n return {\n diff: diff,\n pixel: (0, _compose2.default)([179, 54, 130, 255 * Math.max(0.2, diff)], WHITE)\n };\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvZ2V0RGlmZlBpeGVsLmpzPzRiNjgiXSwibmFtZXMiOlsiZ2V0RGlmZlBpeGVsIiwiV0hJVEUiLCJwcmV2aW91c1BpeGVsIiwiY3VycmVudFBpeGVsIiwiZGlmZiIsInBpeGVsIiwiTWF0aCIsIm1heCJdLCJtYXBwaW5ncyI6Ijs7Ozs7a0JBS3dCQSxZOztBQUx4Qjs7OztBQUNBOzs7Ozs7QUFFQSxJQUFNQyxRQUFRLENBQUMsR0FBRCxFQUFNLEdBQU4sRUFBVyxHQUFYLEVBQWdCLEdBQWhCLENBQWQ7O0FBRWUsU0FBU0QsWUFBVCxDQUFzQkUsYUFBdEIsRUFBcUNDLFlBQXJDLEVBQW1EO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUMsT0FBTyxpQ0FBa0JGLGFBQWxCLEVBQWlDQyxZQUFqQyw2Q0FBYjs7QUFFQSxNQUFJQyxTQUFTLENBQWIsRUFBZ0I7QUFDZCxXQUFPO0FBQ0xBLGdCQURLO0FBRUxDLGFBQU8sdUJBQ0wsQ0FBQ0YsYUFBYSxDQUFiLENBQUQsRUFBa0JBLGFBQWEsQ0FBYixDQUFsQixFQUFtQ0EsYUFBYSxDQUFiLENBQW5DLEVBQW9ELEVBQXBELENBREssRUFFTEYsS0FGSztBQUZGLEtBQVA7QUFPRDs7QUFFRCxTQUFPO0FBQ0xHLGNBREs7QUFFTEMsV0FBTyx1QkFDTCxDQUFDLEdBQUQsRUFBTSxFQUFOLEVBQVUsR0FBVixFQUFlLE1BQU1DLEtBQUtDLEdBQUwsQ0FBUyxHQUFULEVBQWNILElBQWQsQ0FBckIsQ0FESyxFQUVMSCxLQUZLO0FBRkYsR0FBUDtBQU9EIiwiZmlsZSI6IjEuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29tcG9zZSBmcm9tICcuL2NvbXBvc2UnO1xuaW1wb3J0IGV1Y2xpZGVhbkRpc3RhbmNlLCB7IE1BWF9FVUNMSURFQU5fRElTVEFOQ0UgfSBmcm9tICcuL2V1Y2xpZGVhbkRpc3RhbmNlJztcblxuY29uc3QgV0hJVEUgPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RGlmZlBpeGVsKHByZXZpb3VzUGl4ZWwsIGN1cnJlbnRQaXhlbCkge1xuICAvLyBDb21wdXRlIGEgc2NvcmUgdGhhdCByZXByZXNlbnRzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gMiBwaXhlbHNcbiAgLy9cbiAgLy8gVGhpcyBtZXRob2Qgc2ltcGx5IHRha2VzIHRoZSBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0aGUgUkdCQSBjaGFubmVsc1xuICAvLyBvZiAyIGNvbG9ycyBvdmVyIHRoZSBtYXhpbXVtIHBvc3NpYmxlIEV1Y2xpZGVhbiBkaXN0YW5jZS4gVGhpcyBnaXZlcyB1cyBhXG4gIC8vIHBlcmNlbnRhZ2Ugb2YgaG93IGRpZmZlcmVudCB0aGUgdHdvIGNvbG9ycyBhcmUuXG4gIC8vXG4gIC8vIEFsdGhvdWdoIGl0IHdvdWxkIGJlIG1vcmUgcGVyY2VwdHVhbGx5IGFjY3VyYXRlIHRvIGNhbGN1bGF0ZSBhIHByb3BlclxuICAvLyBEZWx0YSBFIGluIExhYiBjb2xvcnNwYWNlLCB3ZSBwcm9iYWJseSBkb24ndCBuZWVkIHBlcmNlcHR1YWwgYWNjdXJhY3kgZm9yXG4gIC8vIHRoaXMgYXBwbGljYXRpb24sIGFuZCBpdCBpcyBuaWNlIHRvIGF2b2lkIHRoZSBvdmVyaGVhZCBvZiBjb252ZXJ0aW5nIFJHQkFcbiAgLy8gdG8gTGFiLlxuICBjb25zdCBkaWZmID0gZXVjbGlkZWFuRGlzdGFuY2UocHJldmlvdXNQaXhlbCwgY3VycmVudFBpeGVsKSAvIE1BWF9FVUNMSURFQU5fRElTVEFOQ0U7XG5cbiAgaWYgKGRpZmYgPT09IDApIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGlmZixcbiAgICAgIHBpeGVsOiBjb21wb3NlKFxuICAgICAgICBbY3VycmVudFBpeGVsWzBdLCBjdXJyZW50UGl4ZWxbMV0sIGN1cnJlbnRQaXhlbFsyXSwgNDBdLFxuICAgICAgICBXSElURVxuICAgICAgKSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBkaWZmLFxuICAgIHBpeGVsOiBjb21wb3NlKFxuICAgICAgWzE3OSwgNTQsIDEzMCwgMjU1ICogTWF0aC5tYXgoMC4yLCBkaWZmKV0sXG4gICAgICBXSElURVxuICAgICksXG4gIH07XG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2pzL3NyYy9nZXREaWZmUGl4ZWwuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9");
|
|
54
|
+
|
|
55
|
+
/***/ },
|
|
56
|
+
/* 2 */
|
|
57
|
+
/***/ function(module, exports) {
|
|
58
|
+
|
|
59
|
+
eval("\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = compose;\nfunction isOpaque(color) {\n return color[3] === 255;\n}\n\nfunction isFullyTransparent(color) {\n return color[3] === 0;\n}\n\n/**\n * Multiplies two fractions using integer math, where the fractions are stored\n * using an integer between 0 and 255. This method is used as a helper method\n * for compositing colors using integer math.\n *\n * This is a quicker implementation of Math.round((a * b) / 255.0)\n */\nfunction int8Mult(a, b) {\n var t = a * b + 0x80;\n return (t >> 8) + t >> 8;\n}\n\n/**\n * Composes two colors with an alpha channel using integer math.\n *\n * This version is faster than a version based on floating point math.\n */\nfunction compose(foreground, background) {\n if (isOpaque(foreground) || isFullyTransparent(background)) {\n return foreground;\n }\n\n if (isFullyTransparent(foreground)) {\n return background;\n }\n\n var aCom = int8Mult(0xff - foreground[3], background[3]);\n return [int8Mult(foreground[3], foreground[0]) + int8Mult(aCom, background[0]), int8Mult(foreground[3], foreground[1]) + int8Mult(aCom, background[1]), int8Mult(foreground[3], foreground[2]) + int8Mult(aCom, background[2]), foreground[3] + aCom];\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvY29tcG9zZS5qcz8wZWM5Il0sIm5hbWVzIjpbImNvbXBvc2UiLCJpc09wYXF1ZSIsImNvbG9yIiwiaXNGdWxseVRyYW5zcGFyZW50IiwiaW50OE11bHQiLCJhIiwiYiIsInQiLCJmb3JlZ3JvdW5kIiwiYmFja2dyb3VuZCIsImFDb20iXSwibWFwcGluZ3MiOiI7Ozs7O2tCQXlCd0JBLE87QUF6QnhCLFNBQVNDLFFBQVQsQ0FBa0JDLEtBQWxCLEVBQXlCO0FBQ3ZCLFNBQU9BLE1BQU0sQ0FBTixNQUFhLEdBQXBCO0FBQ0Q7O0FBRUQsU0FBU0Msa0JBQVQsQ0FBNEJELEtBQTVCLEVBQW1DO0FBQ2pDLFNBQU9BLE1BQU0sQ0FBTixNQUFhLENBQXBCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7QUFPQSxTQUFTRSxRQUFULENBQWtCQyxDQUFsQixFQUFxQkMsQ0FBckIsRUFBd0I7QUFDdEIsTUFBTUMsSUFBS0YsSUFBSUMsQ0FBTCxHQUFVLElBQXBCO0FBQ0EsU0FBUSxDQUFDQyxLQUFLLENBQU4sSUFBV0EsQ0FBWixJQUFrQixDQUF6QjtBQUNEOztBQUVEOzs7OztBQUtlLFNBQVNQLE9BQVQsQ0FBaUJRLFVBQWpCLEVBQTZCQyxVQUE3QixFQUF5QztBQUN0RCxNQUFJUixTQUFTTyxVQUFULEtBQXdCTCxtQkFBbUJNLFVBQW5CLENBQTVCLEVBQTREO0FBQzFELFdBQU9ELFVBQVA7QUFDRDs7QUFFRCxNQUFJTCxtQkFBbUJLLFVBQW5CLENBQUosRUFBb0M7QUFDbEMsV0FBT0MsVUFBUDtBQUNEOztBQUVELE1BQU1DLE9BQU9OLFNBQVMsT0FBT0ksV0FBVyxDQUFYLENBQWhCLEVBQStCQyxXQUFXLENBQVgsQ0FBL0IsQ0FBYjtBQUNBLFNBQU8sQ0FDTEwsU0FBU0ksV0FBVyxDQUFYLENBQVQsRUFBd0JBLFdBQVcsQ0FBWCxDQUF4QixJQUF5Q0osU0FBU00sSUFBVCxFQUFlRCxXQUFXLENBQVgsQ0FBZixDQURwQyxFQUVMTCxTQUFTSSxXQUFXLENBQVgsQ0FBVCxFQUF3QkEsV0FBVyxDQUFYLENBQXhCLElBQXlDSixTQUFTTSxJQUFULEVBQWVELFdBQVcsQ0FBWCxDQUFmLENBRnBDLEVBR0xMLFNBQVNJLFdBQVcsQ0FBWCxDQUFULEVBQXdCQSxXQUFXLENBQVgsQ0FBeEIsSUFBeUNKLFNBQVNNLElBQVQsRUFBZUQsV0FBVyxDQUFYLENBQWYsQ0FIcEMsRUFJTEQsV0FBVyxDQUFYLElBQWdCRSxJQUpYLENBQVA7QUFNRCIsImZpbGUiOiIyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gaXNPcGFxdWUoY29sb3IpIHtcbiAgcmV0dXJuIGNvbG9yWzNdID09PSAyNTU7XG59XG5cbmZ1bmN0aW9uIGlzRnVsbHlUcmFuc3BhcmVudChjb2xvcikge1xuICByZXR1cm4gY29sb3JbM10gPT09IDA7XG59XG5cbi8qKlxuICogTXVsdGlwbGllcyB0d28gZnJhY3Rpb25zIHVzaW5nIGludGVnZXIgbWF0aCwgd2hlcmUgdGhlIGZyYWN0aW9ucyBhcmUgc3RvcmVkXG4gKiB1c2luZyBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMjU1LiBUaGlzIG1ldGhvZCBpcyB1c2VkIGFzIGEgaGVscGVyIG1ldGhvZFxuICogZm9yIGNvbXBvc2l0aW5nIGNvbG9ycyB1c2luZyBpbnRlZ2VyIG1hdGguXG4gKlxuICogVGhpcyBpcyBhIHF1aWNrZXIgaW1wbGVtZW50YXRpb24gb2YgTWF0aC5yb3VuZCgoYSAqIGIpIC8gMjU1LjApXG4gKi9cbmZ1bmN0aW9uIGludDhNdWx0KGEsIGIpIHtcbiAgY29uc3QgdCA9IChhICogYikgKyAweDgwO1xuICByZXR1cm4gKCh0ID4+IDgpICsgdCkgPj4gODtcbn1cblxuLyoqXG4gKiBDb21wb3NlcyB0d28gY29sb3JzIHdpdGggYW4gYWxwaGEgY2hhbm5lbCB1c2luZyBpbnRlZ2VyIG1hdGguXG4gKlxuICogVGhpcyB2ZXJzaW9uIGlzIGZhc3RlciB0aGFuIGEgdmVyc2lvbiBiYXNlZCBvbiBmbG9hdGluZyBwb2ludCBtYXRoLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wb3NlKGZvcmVncm91bmQsIGJhY2tncm91bmQpIHtcbiAgaWYgKGlzT3BhcXVlKGZvcmVncm91bmQpIHx8IGlzRnVsbHlUcmFuc3BhcmVudChiYWNrZ3JvdW5kKSkge1xuICAgIHJldHVybiBmb3JlZ3JvdW5kO1xuICB9XG5cbiAgaWYgKGlzRnVsbHlUcmFuc3BhcmVudChmb3JlZ3JvdW5kKSkge1xuICAgIHJldHVybiBiYWNrZ3JvdW5kO1xuICB9XG5cbiAgY29uc3QgYUNvbSA9IGludDhNdWx0KDB4ZmYgLSBmb3JlZ3JvdW5kWzNdLCBiYWNrZ3JvdW5kWzNdKTtcbiAgcmV0dXJuIFtcbiAgICBpbnQ4TXVsdChmb3JlZ3JvdW5kWzNdLCBmb3JlZ3JvdW5kWzBdKSArIGludDhNdWx0KGFDb20sIGJhY2tncm91bmRbMF0pLFxuICAgIGludDhNdWx0KGZvcmVncm91bmRbM10sIGZvcmVncm91bmRbMV0pICsgaW50OE11bHQoYUNvbSwgYmFja2dyb3VuZFsxXSksXG4gICAgaW50OE11bHQoZm9yZWdyb3VuZFszXSwgZm9yZWdyb3VuZFsyXSkgKyBpbnQ4TXVsdChhQ29tLCBiYWNrZ3JvdW5kWzJdKSxcbiAgICBmb3JlZ3JvdW5kWzNdICsgYUNvbSxcbiAgXTtcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vanMvc3JjL2NvbXBvc2UuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9");
|
|
60
|
+
|
|
61
|
+
/***/ },
|
|
62
|
+
/* 3 */
|
|
63
|
+
/***/ function(module, exports) {
|
|
64
|
+
|
|
65
|
+
eval("\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = euclideanDistance;\nfunction euclideanDistance(rgba1, rgba2) {\n return Math.sqrt(Math.pow(rgba1[0] - rgba2[0], 2) + Math.pow(rgba1[1] - rgba2[1], 2) + Math.pow(rgba1[2] - rgba2[2], 2) + Math.pow(rgba1[3] - rgba2[3], 2));\n}\n\nvar MAX_EUCLIDEAN_DISTANCE = exports.MAX_EUCLIDEAN_DISTANCE = Math.sqrt(Math.pow(255, 2) * 4);//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvZXVjbGlkZWFuRGlzdGFuY2UuanM/ZDgzYiJdLCJuYW1lcyI6WyJldWNsaWRlYW5EaXN0YW5jZSIsInJnYmExIiwicmdiYTIiLCJNYXRoIiwic3FydCIsInBvdyIsIk1BWF9FVUNMSURFQU5fRElTVEFOQ0UiXSwibWFwcGluZ3MiOiI7Ozs7O2tCQUF3QkEsaUI7QUFBVCxTQUFTQSxpQkFBVCxDQUEyQkMsS0FBM0IsRUFBa0NDLEtBQWxDLEVBQXlDO0FBQ3RELFNBQU9DLEtBQUtDLElBQUwsQ0FDTEQsS0FBS0UsR0FBTCxDQUFTSixNQUFNLENBQU4sSUFBV0MsTUFBTSxDQUFOLENBQXBCLEVBQThCLENBQTlCLElBQ0VDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQURGLEdBRUVDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQUZGLEdBR0VDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQUpHLENBQVA7QUFNRDs7QUFFTSxJQUFNSSwwREFBeUJILEtBQUtDLElBQUwsQ0FBVUQsS0FBS0UsR0FBTCxDQUFTLEdBQVQsRUFBYyxDQUFkLElBQW1CLENBQTdCLENBQS9CIiwiZmlsZSI6IjMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBldWNsaWRlYW5EaXN0YW5jZShyZ2JhMSwgcmdiYTIpIHtcbiAgcmV0dXJuIE1hdGguc3FydChcbiAgICBNYXRoLnBvdyhyZ2JhMVswXSAtIHJnYmEyWzBdLCAyKVxuICAgICsgTWF0aC5wb3cocmdiYTFbMV0gLSByZ2JhMlsxXSwgMilcbiAgICArIE1hdGgucG93KHJnYmExWzJdIC0gcmdiYTJbMl0sIDIpXG4gICAgKyBNYXRoLnBvdyhyZ2JhMVszXSAtIHJnYmEyWzNdLCAyKVxuICApO1xufVxuXG5leHBvcnQgY29uc3QgTUFYX0VVQ0xJREVBTl9ESVNUQU5DRSA9IE1hdGguc3FydChNYXRoLnBvdygyNTUsIDIpICogNCk7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2pzL3NyYy9ldWNsaWRlYW5EaXN0YW5jZS5qc1xuICoqLyJdLCJzb3VyY2VSb290IjoiIn0=");
|
|
66
|
+
|
|
67
|
+
/***/ }
|
|
68
|
+
/******/ ]);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/******/ (function(modules) { // webpackBootstrap
|
|
2
|
+
/******/ // The module cache
|
|
3
|
+
/******/ var installedModules = {};
|
|
4
|
+
|
|
5
|
+
/******/ // The require function
|
|
6
|
+
/******/ function __webpack_require__(moduleId) {
|
|
7
|
+
|
|
8
|
+
/******/ // Check if module is in cache
|
|
9
|
+
/******/ if(installedModules[moduleId])
|
|
10
|
+
/******/ return installedModules[moduleId].exports;
|
|
11
|
+
|
|
12
|
+
/******/ // Create a new module (and put it into the cache)
|
|
13
|
+
/******/ var module = installedModules[moduleId] = {
|
|
14
|
+
/******/ exports: {},
|
|
15
|
+
/******/ id: moduleId,
|
|
16
|
+
/******/ loaded: false
|
|
17
|
+
/******/ };
|
|
18
|
+
|
|
19
|
+
/******/ // Execute the module function
|
|
20
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
21
|
+
|
|
22
|
+
/******/ // Flag the module as loaded
|
|
23
|
+
/******/ module.loaded = true;
|
|
24
|
+
|
|
25
|
+
/******/ // Return the exports of the module
|
|
26
|
+
/******/ return module.exports;
|
|
27
|
+
/******/ }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
31
|
+
/******/ __webpack_require__.m = modules;
|
|
32
|
+
|
|
33
|
+
/******/ // expose the module cache
|
|
34
|
+
/******/ __webpack_require__.c = installedModules;
|
|
35
|
+
|
|
36
|
+
/******/ // __webpack_public_path__
|
|
37
|
+
/******/ __webpack_require__.p = "";
|
|
38
|
+
|
|
39
|
+
/******/ // Load entry module and return exports
|
|
40
|
+
/******/ return __webpack_require__(0);
|
|
41
|
+
/******/ })
|
|
42
|
+
/************************************************************************/
|
|
43
|
+
/******/ ([
|
|
44
|
+
/* 0 */
|
|
45
|
+
/***/ function(module, exports, __webpack_require__) {
|
|
46
|
+
|
|
47
|
+
eval("'use strict';\n\nvar _adiff = __webpack_require__(1);\n\nvar _adiff2 = _interopRequireDefault(_adiff);\n\nvar _flattenImageData = __webpack_require__(2);\n\nvar _flattenImageData2 = _interopRequireDefault(_flattenImageData);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar TRANSPARENT_PIXEL = [0, 0, 0, 0];\n\n/**\n * Construct a line of transparent pixels\n *\n * @param {Number} width\n * @return {Array}\n */\nfunction constructTransparentLine(width) {\n var line = [];\n for (var i = 0; i < width; i++) {\n line.push(TRANSPARENT_PIXEL);\n }\n return line;\n}\n\nfunction imageTo2DArray(_ref, paddingRight) {\n var data = _ref.data;\n var width = _ref.width;\n var height = _ref.height;\n\n // The imageData is a 1D array. Each element in the array corresponds to a\n // decimal value that represents one of the RGBA channels for that pixel.\n var rowSize = width * 4;\n var getPixelAt = function getPixelAt(x, y) {\n var startIndex = y * rowSize + x * 4;\n return [data[startIndex], data[startIndex + 1], data[startIndex + 2], data[startIndex + 3]];\n };\n\n var newData = [];\n for (var row = 0; row < height; row++) {\n var pixelsInRow = [];\n for (var col = 0; col < width; col++) {\n pixelsInRow.push(getPixelAt(col, row));\n }\n for (var pad = 0; pad < paddingRight; pad++) {\n pixelsInRow.push(TRANSPARENT_PIXEL);\n }\n newData.push(pixelsInRow);\n }\n return newData;\n}\n\nfunction getAdiffResults(_ref2) {\n var previousData = _ref2.previousData;\n var currentData = _ref2.currentData;\n var previousImageData = _ref2.previousImageData;\n var currentImageData = _ref2.currentImageData;\n\n if (previousData.width !== currentData.width) {\n // we know that all rows will be different here, so we can take a shortcut\n var diff = [0, // diff starts at index 0\n previousData.height];\n diff.length = currentData.height + 2; // number of additions\n return [diff];\n }\n\n var hashedPreviousData = previousImageData.map(JSON.stringify);\n self.postMessage({ progress: 40 });\n var hashedCurrentData = currentImageData.map(JSON.stringify);\n self.postMessage({ progress: 60 });\n\n return _adiff2.default.diff(hashedPreviousData, hashedCurrentData);\n}\n\n/**\n * Takes two 2d images, computes the diff between the two, and injects pixels to\n * both in order to:\n * a) make both images the same height\n * b) properly visualize differences\n *\n * Please note that this method MUTATES data.\n *\n * @param {Array} previousData\n * @param {Array} currentData\n */\nfunction computeAndInjectDiffs(_ref3) {\n var previousData = _ref3.previousData;\n var currentData = _ref3.currentData;\n\n var maxWidth = Math.max(previousData.width, currentData.width);\n\n var transparentLine = constructTransparentLine(maxWidth);\n\n var previousImageData = imageTo2DArray(previousData, maxWidth - previousData.width);\n\n var currentImageData = imageTo2DArray(currentData, maxWidth - currentData.width);\n\n self.postMessage({ progress: 20 });\n\n var adiffResults = getAdiffResults({\n previousData: previousData,\n currentData: currentData,\n previousImageData: previousImageData,\n currentImageData: currentImageData\n });\n\n self.postMessage({ progress: 85 });\n\n // iterate and apply changes to previous data\n adiffResults.forEach(function (instruction) {\n var atIndex = instruction[0];\n var deletedItems = instruction[1];\n var addedItems = instruction.length - 2;\n\n for (var y = 0; y < Math.max(deletedItems, addedItems); y++) {\n if (y < deletedItems) {\n // ignore, we just keep the old line\n } else {\n previousImageData.splice(atIndex + y, 0, transparentLine);\n }\n }\n });\n self.postMessage({ progress: 95 });\n\n // iterate backwards and apply changes to current data\n for (var i = adiffResults.length - 1; i >= 0; i--) {\n var instruction = adiffResults[i];\n var atIndex = instruction[0];\n var deletedItems = instruction[1];\n var addedItems = instruction.length - 2;\n\n for (var y = 0; y < Math.max(deletedItems, addedItems); y++) {\n if (y < addedItems) {\n // ignore, we just keep the old line\n } else {\n currentImageData.splice(atIndex + y, 0, transparentLine);\n }\n }\n }\n self.postMessage({ progress: 98 });\n\n return {\n currentData: {\n data: (0, _flattenImageData2.default)(currentImageData),\n height: currentImageData.length,\n width: maxWidth\n },\n previousData: {\n data: (0, _flattenImageData2.default)(previousImageData),\n height: previousImageData.length,\n width: maxWidth\n }\n };\n}\n\nself.addEventListener('message', function (_ref4) {\n var _ref4$data = _ref4.data;\n var previousData = _ref4$data.previousData;\n var currentData = _ref4$data.currentData;\n\n var result = computeAndInjectDiffs({ previousData: previousData, currentData: currentData });\n self.postMessage(result);\n self.close();\n});//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvd29ya2Vycy9Db21wdXRlQW5kSW5qZWN0RGlmZnNXb3JrZXIuanM/ZGRiNSJdLCJuYW1lcyI6WyJUUkFOU1BBUkVOVF9QSVhFTCIsImNvbnN0cnVjdFRyYW5zcGFyZW50TGluZSIsIndpZHRoIiwibGluZSIsImkiLCJwdXNoIiwiaW1hZ2VUbzJEQXJyYXkiLCJwYWRkaW5nUmlnaHQiLCJkYXRhIiwiaGVpZ2h0Iiwicm93U2l6ZSIsImdldFBpeGVsQXQiLCJ4IiwieSIsInN0YXJ0SW5kZXgiLCJuZXdEYXRhIiwicm93IiwicGl4ZWxzSW5Sb3ciLCJjb2wiLCJwYWQiLCJnZXRBZGlmZlJlc3VsdHMiLCJwcmV2aW91c0RhdGEiLCJjdXJyZW50RGF0YSIsInByZXZpb3VzSW1hZ2VEYXRhIiwiY3VycmVudEltYWdlRGF0YSIsImRpZmYiLCJsZW5ndGgiLCJoYXNoZWRQcmV2aW91c0RhdGEiLCJtYXAiLCJKU09OIiwic3RyaW5naWZ5Iiwic2VsZiIsInBvc3RNZXNzYWdlIiwicHJvZ3Jlc3MiLCJoYXNoZWRDdXJyZW50RGF0YSIsImNvbXB1dGVBbmRJbmplY3REaWZmcyIsIm1heFdpZHRoIiwiTWF0aCIsIm1heCIsInRyYW5zcGFyZW50TGluZSIsImFkaWZmUmVzdWx0cyIsImZvckVhY2giLCJpbnN0cnVjdGlvbiIsImF0SW5kZXgiLCJkZWxldGVkSXRlbXMiLCJhZGRlZEl0ZW1zIiwic3BsaWNlIiwiYWRkRXZlbnRMaXN0ZW5lciIsInJlc3VsdCIsImNsb3NlIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBRUE7Ozs7OztBQUVBLElBQU1BLG9CQUFvQixDQUFDLENBQUQsRUFBSSxDQUFKLEVBQU8sQ0FBUCxFQUFVLENBQVYsQ0FBMUI7O0FBRUE7Ozs7OztBQU1BLFNBQVNDLHdCQUFULENBQWtDQyxLQUFsQyxFQUF5QztBQUN2QyxNQUFNQyxPQUFPLEVBQWI7QUFDQSxPQUFLLElBQUlDLElBQUksQ0FBYixFQUFnQkEsSUFBSUYs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YixJQUFJLENBQWIsRUFBZ0JBLElBQUl3QixLQUFLQyxHQUFMLENBQVNNLFlBQVQsRUFBdUJDLFVBQXZCLENBQXBCLEVBQXdEaEMsR0FBeEQsRUFBNkQ7QUFDM0QsVUFBSUEsSUFBSWdDLFVBQVIsRUFBb0I7QUFDbEI7QUFDRCxPQUZELE1BRU87QUFDTHJCLHlCQUFpQnNCLE1BQWpCLENBQXdCSCxVQUFVOUIsQ0FBbEMsRUFBcUMsQ0FBckMsRUFBd0MwQixlQUF4QztBQUNEO0FBQ0Y7QUFDRjtBQUNEUixPQUFLQyxXQUFMLENBQWlCLEVBQUVDLFVBQVUsRUFBWixFQUFqQjs7QUFFQSxTQUFPO0FBQ0xYLGlCQUFhO0FBQ1hkLFlBQU0sZ0NBQWlCZ0IsZ0JBQWpCLENBREs7QUFFWGYsY0FBUWUsaUJBQWlCRSxNQUZkO0FBR1h4QixhQUFPa0M7QUFISSxLQURSO0FBTUxmLGtCQUFjO0FBQ1piLFlBQU0sZ0NBQWlCZSxpQkFBakIsQ0FETTtBQUVaZCxjQUFRYyxrQkFBa0JHLE1BRmQ7QUFHWnhCLGFBQU9rQztBQUhLO0FBTlQsR0FBUDtBQVlEOztBQUVETCxLQUFLZ0IsZ0JBQUwsQ0FBc0IsU0FBdEIsRUFBaUMsaUJBQTZDO0FBQUEseUJBQTFDdkMsSUFBMEM7QUFBQSxNQUFsQ2EsWUFBa0MsY0FBbENBLFlBQWtDO0FBQUEsTUFBcEJDLFdBQW9CLGNBQXBCQSxXQUFvQjs7QUFDNUUsTUFBTTBCLFNBQVNiLHNCQUFzQixFQUFFZCwwQkFBRixFQUFnQkMsd0JBQWhCLEVBQXRCLENBQWY7QUFDQVMsT0FBS0MsV0FBTCxDQUFpQmdCLE1BQWpCO0FBQ0FqQixPQUFLa0IsS0FBTDtBQUNELENBSkQiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhZGlmZiBmcm9tICdhZGlmZic7XG5cbmltcG9ydCBmbGF0dGVuSW1hZ2VEYXRhIGZyb20gJy4uL2ZsYXR0ZW5JbWFnZURhdGEnO1xuXG5jb25zdCBUUkFOU1BBUkVOVF9QSVhFTCA9IFswLCAwLCAwLCAwXTtcblxuLyoqXG4gKiBDb25zdHJ1Y3QgYSBsaW5lIG9mIHRyYW5zcGFyZW50IHBpeGVsc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIGNvbnN0cnVjdFRyYW5zcGFyZW50TGluZSh3aWR0aCkge1xuICBjb25zdCBsaW5lID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgd2lkdGg7IGkrKykge1xuICAgIGxpbmUucHVzaChUUkFOU1BBUkVOVF9QSVhFTCk7XG4gIH1cbiAgcmV0dXJuIGxpbmU7XG59XG5cbmZ1bmN0aW9uIGltYWdlVG8yREFycmF5KHsgZGF0YSwgd2lkdGgsIGhlaWdodCB9LCBwYWRkaW5nUmlnaHQpIHtcbiAgLy8gVGhlIGltYWdlRGF0YSBpcyBhIDFEIGFycmF5LiBFYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IGNvcnJlc3BvbmRzIHRvIGFcbiAgLy8gZGVjaW1hbCB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgb25lIG9mIHRoZSBSR0JBIGNoYW5uZWxzIGZvciB0aGF0IHBpeGVsLlxuICBjb25zdCByb3dTaXplID0gd2lkdGggKiA0O1xuICBjb25zdCBnZXRQaXhlbEF0ID0gKHgsIHkpID0+IHtcbiAgICBjb25zdCBzdGFydEluZGV4ID0gKHkgKiByb3dTaXplKSArICh4ICogNCk7XG4gICAgcmV0dXJuIFtcbiAgICAgIGRhdGFbc3RhcnRJbmRleF0sXG4gICAgICBkYXRhW3N0YXJ0SW5kZXggKyAxXSxcbiAgICAgIGRhdGFbc3RhcnRJbmRleCArIDJdLFxuICAgICAgZGF0YVtzdGFydEluZGV4ICsgM10sXG4gICAgXTtcbiAgfTtcblxuICBjb25zdCBuZXdEYXRhID0gW107XG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IGhlaWdodDsgcm93KyspIHtcbiAgICBjb25zdCBwaXhlbHNJblJvdyA9IFtdO1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IHdpZHRoOyBjb2wrKykge1xuICAgICAgcGl4ZWxzSW5Sb3cucHVzaChnZXRQaXhlbEF0KGNvbCwgcm93KSk7XG4gICAgfVxuICAgIGZvciAobGV0IHBhZCA9IDA7IHBhZCA8IHBhZGRpbmdSaWdodDsgcGFkKyspIHtcbiAgICAgIHBpeGVsc0luUm93LnB1c2goVFJBTlNQQVJFTlRfUElYRUwpO1xuICAgIH1cbiAgICBuZXdEYXRhLnB1c2gocGl4ZWxzSW5Sb3cpO1xuICB9XG4gIHJldHVybiBuZXdEYXRhO1xufVxuXG5mdW5jdGlvbiBnZXRBZGlmZlJlc3VsdHMoe1xuICBwcmV2aW91c0RhdGEsXG4gIGN1cnJlbnREYXRhLFxuICBwcmV2aW91c0ltYWdlRGF0YSxcbiAgY3VycmVudEltYWdlRGF0YSxcbn0pIHtcbiAgaWYgKHByZXZpb3VzRGF0YS53aWR0aCAhPT0gY3VycmVudERhdGEud2lkdGgpIHtcbiAgICAvLyB3ZSBrbm93IHRoYXQgYWxsIHJvd3Mgd2lsbCBiZSBkaWZmZXJlbnQgaGVyZSwgc28gd2UgY2FuIHRha2UgYSBzaG9ydGN1dFxuICAgIGNvbnN0IGRpZmYgPSBbXG4gICAgICAwLCAvLyBkaWZmIHN0YXJ0cyBhdCBpbmRleCAwXG4gICAgICBwcmV2aW91c0RhdGEuaGVpZ2h0LCAvLyBudW1iZXIgb2YgZGVsZXRpb25zXG4gICAgXTtcbiAgICBkaWZmLmxlbmd0aCA9IGN1cnJlbnREYXRhLmhlaWdodCArIDI7IC8vIG51bWJlciBvZiBhZGRpdGlvbnNcbiAgICByZXR1cm4gW2RpZmZdO1xuICB9XG5cbiAgY29uc3QgaGFzaGVkUHJldmlvdXNEYXRhID0gcHJldmlvdXNJbWFnZURhdGEubWFwKEpTT04uc3RyaW5naWZ5KTtcbiAgc2VsZi5wb3N0TWVzc2FnZSh7IHByb2dyZXNzOiA0MCB9KTtcbiAgY29uc3QgaGFzaGVkQ3VycmVudERhdGEgPSBjdXJyZW50SW1hZ2VEYXRhLm1hcChKU09OLnN0cmluZ2lmeSk7XG4gIHNlbGYucG9zdE1lc3NhZ2UoeyBwcm9ncmVzczogNjAgfSk7XG5cbiAgcmV0dXJuIGFkaWZmLmRpZmYoXG4gICAgaGFzaGVkUHJldmlvdXNEYXRhLFxuICAgIGhhc2hlZEN1cnJlbnREYXRhXG4gICk7XG59XG5cbi8qKlxuICogVGFrZXMgdHdvIDJkIGltYWdlcywgY29tcHV0ZXMgdGhlIGRpZmYgYmV0d2VlbiB0aGUgdHdvLCBhbmQgaW5qZWN0cyBwaXhlbHMgdG9cbiAqIGJvdGggaW4gb3JkZXIgdG86XG4gKiBhKSBtYWtlIGJvdGggaW1hZ2VzIHRoZSBzYW1lIGhlaWdodFxuICogYikgcHJvcGVybHkgdmlzdWFsaXplIGRpZmZlcmVuY2VzXG4gKlxuICogUGxlYXNlIG5vdGUgdGhhdCB0aGlzIG1ldGhvZCBNVVRBVEVTIGRhdGEuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcHJldmlvdXNEYXRhXG4gKiBAcGFyYW0ge0FycmF5fSBjdXJyZW50RGF0YVxuICovXG5mdW5jdGlvbiBjb21wdXRlQW5kSW5qZWN0RGlmZnMoeyBwcmV2aW91c0RhdGEsIGN1cnJlbnREYXRhIH0pIHtcbiAgY29uc3QgbWF4V2lkdGggPSBNYXRoLm1heChwcmV2aW91c0RhdGEud2lkdGgsIGN1cnJlbnREYXRhLndpZHRoKTtcblxuICBjb25zdCB0cmFuc3BhcmVudExpbmUgPSBjb25zdHJ1Y3RUcmFuc3BhcmVudExpbmUobWF4V2lkdGgpO1xuXG4gIGNvbnN0IHByZXZpb3VzSW1hZ2VEYXRhID0gaW1hZ2VUbzJEQXJyYXkoXG4gICAgcHJldmlvdXNEYXRhLCBtYXhXaWR0aCAtIHByZXZpb3VzRGF0YS53aWR0aCk7XG5cbiAgY29uc3QgY3VycmVudEltYWdlRGF0YSA9IGltYWdlVG8yREFycmF5KFxuICAgIGN1cnJlbnREYXRhLCBtYXhXaWR0aCAtIGN1cnJlbnREYXRhLndpZHRoKTtcblxuICBzZWxmLnBvc3RNZXNzYWdlKHsgcHJvZ3Jlc3M6IDIwIH0pO1xuXG4gIGNvbnN0IGFkaWZmUmVzdWx0cyA9IGdldEFkaWZmUmVzdWx0cyh7XG4gICAgcHJldmlvdXNEYXRhLFxuICAgIGN1cnJlbnREYXRhLFxuICAgIHByZXZpb3VzSW1hZ2VEYXRhLFxuICAgIGN1cnJlbnRJbWFnZURhdGEsXG4gIH0pO1xuXG4gIHNlbGYucG9zdE1lc3NhZ2UoeyBwcm9ncmVzczogODUgfSk7XG5cbiAgLy8gaXRlcmF0ZSBhbmQgYXBwbHkgY2hhbmdlcyB0byBwcmV2aW91cyBkYXRhXG4gIGFkaWZmUmVzdWx0cy5mb3JFYWNoKChpbnN0cnVjdGlvbikgPT4ge1xuICAgIGNvbnN0IGF0SW5kZXggPSBpbnN0cnVjdGlvblswXTtcbiAgICBjb25zdCBkZWxldGVkSXRlbXMgPSBpbnN0cnVjdGlvblsxXTtcbiAgICBjb25zdCBhZGRlZEl0ZW1zID0gaW5zdHJ1Y3Rpb24ubGVuZ3RoIC0gMjtcblxuICAgIGZvciAobGV0IHkgPSAwOyB5IDwgTWF0aC5tYXgoZGVsZXRlZEl0ZW1zLCBhZGRlZEl0ZW1zKTsgeSsrKSB7XG4gICAgICBpZiAoeSA8IGRlbGV0ZWRJdGVtcykge1xuICAgICAgICAvLyBpZ25vcmUsIHdlIGp1c3Qga2VlcCB0aGUgb2xkIGxpbmVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByZXZpb3VzSW1hZ2VEYXRhLnNwbGljZShhdEluZGV4ICsgeSwgMCwgdHJhbnNwYXJlbnRMaW5lKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBzZWxmLnBvc3RNZXNzYWdlKHsgcHJvZ3Jlc3M6IDk1IH0pO1xuXG4gIC8vIGl0ZXJhdGUgYmFja3dhcmRzIGFuZCBhcHBseSBjaGFuZ2VzIHRvIGN1cnJlbnQgZGF0YVxuICBmb3IgKGxldCBpID0gYWRpZmZSZXN1bHRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgaW5zdHJ1Y3Rpb24gPSBhZGlmZlJlc3VsdHNbaV07XG4gICAgY29uc3QgYXRJbmRleCA9IGluc3RydWN0aW9uWzBdO1xuICAgIGNvbnN0IGRlbGV0ZWRJdGVtcyA9IGluc3RydWN0aW9uWzFdO1xuICAgIGNvbnN0IGFkZGVkSXRlbXMgPSBpbnN0cnVjdGlvbi5sZW5ndGggLSAyO1xuXG4gICAgZm9yIChsZXQgeSA9IDA7IHkgPCBNYXRoLm1heChkZWxldGVkSXRlbXMsIGFkZGVkSXRlbXMpOyB5KyspIHtcbiAgICAgIGlmICh5IDwgYWRkZWRJdGVtcykge1xuICAgICAgICAvLyBpZ25vcmUsIHdlIGp1c3Qga2VlcCB0aGUgb2xkIGxpbmVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnRJbWFnZURhdGEuc3BsaWNlKGF0SW5kZXggKyB5LCAwLCB0cmFuc3BhcmVudExpbmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzZWxmLnBvc3RNZXNzYWdlKHsgcHJvZ3Jlc3M6IDk4IH0pO1xuXG4gIHJldHVybiB7XG4gICAgY3VycmVudERhdGE6IHtcbiAgICAgIGRhdGE6IGZsYXR0ZW5JbWFnZURhdGEoY3VycmVudEltYWdlRGF0YSksXG4gICAgICBoZWlnaHQ6IGN1cnJlbnRJbWFnZURhdGEubGVuZ3RoLFxuICAgICAgd2lkdGg6IG1heFdpZHRoLFxuICAgIH0sXG4gICAgcHJldmlvdXNEYXRhOiB7XG4gICAgICBkYXRhOiBmbGF0dGVuSW1hZ2VEYXRhKHByZXZpb3VzSW1hZ2VEYXRhKSxcbiAgICAgIGhlaWdodDogcHJldmlvdXNJbWFnZURhdGEubGVuZ3RoLFxuICAgICAgd2lkdGg6IG1heFdpZHRoLFxuICAgIH0sXG4gIH07XG59XG5cbnNlbGYuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsICh7IGRhdGE6IHsgcHJldmlvdXNEYXRhLCBjdXJyZW50RGF0YSB9IH0pID0+IHtcbiAgY29uc3QgcmVzdWx0ID0gY29tcHV0ZUFuZEluamVjdERpZmZzKHsgcHJldmlvdXNEYXRhLCBjdXJyZW50RGF0YSB9KTtcbiAgc2VsZi5wb3N0TWVzc2FnZShyZXN1bHQpO1xuICBzZWxmLmNsb3NlKCk7XG59KTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vanMvc3JjL3dvcmtlcnMvQ29tcHV0ZUFuZEluamVjdERpZmZzV29ya2VyLmpzXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ==");
|
|
48
|
+
|
|
49
|
+
/***/ },
|
|
50
|
+
/* 1 */
|
|
51
|
+
/***/ function(module, exports) {
|
|
52
|
+
|
|
53
|
+
eval("function head (a) {\n return a[0]\n}\n\nfunction last (a) {\n return a[a.length - 1]\n}\n\nfunction tail(a) {\n return a.slice(1)\n}\n\nfunction retreat (e) {\n return e.pop()\n}\n\nfunction hasLength (e) {\n return e.length\n}\n\nfunction any(ary, test) {\n for(var i=0;i<ary.length;i++)\n if(test(ary[i]))\n return true\n return false\n}\n\nfunction score (a) {\n return a.reduce(function (s, a) {\n return s + a.length + a[1] + 1\n }, 0)\n}\n\nfunction best (a, b) {\n return score(a) <= score(b) ? a : b\n}\n\n\nvar _rules // set at the bottom \n\n// note, naive implementation. will break on circular objects.\n\nfunction _equal(a, b) {\n if(a && !b) return false\n if(Array.isArray(a))\n if(a.length != b.length) return false\n if(a && 'object' == typeof a) {\n for(var i in a)\n if(!_equal(a[i], b[i])) return false\n for(var i in b)\n if(!_equal(a[i], b[i])) return false\n return true\n }\n return a == b\n}\n\nfunction getArgs(args) {\n return args.length == 1 ? args[0] : [].slice.call(args)\n}\n\n// return the index of the element not like the others, or -1\nfunction oddElement(ary, cmp) {\n var c\n function guess(a) {\n var odd = -1\n c = 0\n for (var i = a; i < ary.length; i ++) {\n if(!cmp(ary[a], ary[i])) {\n odd = i, c++\n }\n }\n return c > 1 ? -1 : odd\n }\n //assume that it is the first element.\n var g = guess(0)\n if(-1 != g) return g\n //0 was the odd one, then all the other elements are equal\n //else there more than one different element\n guess(1)\n return c == 0 ? 0 : -1\n}\nvar exports = module.exports = function (deps, exports) {\n var equal = (deps && deps.equal) || _equal\n exports = exports || {} \n exports.lcs = \n function lcs() {\n var cache = {}\n var args = getArgs(arguments)\n var a = args[0], b = args[1]\n\n function key (a,b){\n return a.length + ':' + b.length\n }\n\n //find length that matches at the head\n\n if(args.length > 2) {\n //if called with multiple sequences\n //recurse, since lcs(a, b, c, d) == lcs(lcs(a,b), lcs(c,d))\n args.push(lcs(args.shift(), args.shift()))\n return lcs(args)\n }\n \n //this would be improved by truncating input first\n //and not returning an lcs as an intermediate step.\n //untill that is a performance problem.\n\n var start = 0, end = 0\n for(var i = 0; i < a.length && i < b.length \n && equal(a[i], b[i])\n ; i ++\n )\n start = i + 1\n\n if(a.length === start)\n return a.slice()\n\n for(var i = 0; i < a.length - start && i < b.length - start\n && equal(a[a.length - 1 - i], b[b.length - 1 - i])\n ; i ++\n )\n end = i\n\n function recurse (a, b) {\n if(!a.length || !b.length) return []\n //avoid exponential time by caching the results\n if(cache[key(a, b)]) return cache[key(a, b)]\n\n if(equal(a[0], b[0]))\n return [head(a)].concat(recurse(tail(a), tail(b)))\n else { \n var _a = recurse(tail(a), b)\n var _b = recurse(a, tail(b))\n return cache[key(a,b)] = _a.length > _b.length ? _a : _b \n }\n }\n \n var middleA = a.slice(start, a.length - end)\n var middleB = b.slice(start, b.length - end)\n\n return (\n a.slice(0, start).concat(\n recurse(middleA, middleB)\n ).concat(a.slice(a.length - end))\n )\n }\n\n // given n sequences, calc the lcs, and then chunk strings into stable and unstable sections.\n // unstable chunks are passed to build\n exports.chunk =\n function (q, build) {\n var q = q.map(function (e) { return e.slice() })\n var lcs = exports.lcs.apply(null, q)\n var all = [lcs].concat(q)\n\n function matchLcs (e) {\n if(e.length && !lcs.length || !e.length && lcs.length)\n return false //incase the last item is null\n return equal(last(e), last(lcs)) || ((e.length + lcs.length) === 0)\n }\n\n while(any(q, hasLength)) {\n //if each element is at the lcs then this chunk is stable.\n while(q.every(matchLcs) && q.every(hasLength))\n all.forEach(retreat)\n //collect the changes in each array upto the next match with the lcs\n var c = false\n var unstable = q.map(function (e) {\n var change = []\n while(!matchLcs(e)) {\n change.unshift(retreat(e))\n c = true\n }\n return change\n })\n if(c) build(q[0].length, unstable)\n }\n }\n\n //calculate a diff this is only updates\n exports.optimisticDiff =\n function (a, b) {\n var M = Math.max(a.length, b.length)\n var m = Math.min(a.length, b.length)\n var patch = []\n for(var i = 0; i < M; i++)\n if(a[i] !== b[i]) {\n var cur = [i,0], deletes = 0\n while(a[i] !== b[i] && i < m) {\n cur[1] = ++deletes\n cur.push(b[i++])\n }\n //the rest are deletes or inserts\n if(i >= m) {\n //the rest are deletes\n if(a.length > b.length)\n cur[1] += a.length - b.length\n //the rest are inserts\n else if(a.length < b.length)\n cur = cur.concat(b.slice(a.length))\n }\n patch.push(cur)\n }\n\n return patch\n }\n\n exports.diff =\n function (a, b) {\n var optimistic = exports.optimisticDiff(a, b)\n var changes = []\n exports.chunk([a, b], function (index, unstable) {\n var del = unstable.shift().length\n var insert = unstable.shift()\n changes.push([index, del].concat(insert))\n })\n return best(optimistic, changes)\n }\n\n exports.patch = function (a, changes, mutate) {\n if(mutate !== true) a = a.slice(a)//copy a\n changes.forEach(function (change) {\n [].splice.apply(a, change)\n })\n return a\n }\n\n // http://en.wikipedia.org/wiki/Concestor\n // me, concestor, you...\n exports.merge = function () {\n var args = getArgs(arguments)\n var patch = exports.diff3(args)\n return exports.patch(args[0], patch)\n }\n\n exports.diff3 = function () {\n var args = getArgs(arguments)\n var r = []\n exports.chunk(args, function (index, unstable) {\n var mine = unstable[0]\n var insert = resolve(unstable)\n if(equal(mine, insert)) return \n r.push([index, mine.length].concat(insert)) \n })\n return r\n }\n exports.oddOneOut =\n function oddOneOut (changes) {\n changes = changes.slice()\n //put the concestor first\n changes.unshift(changes.splice(1,1)[0])\n var i = oddElement(changes, equal)\n if(i == 0) // concestor was different, 'false conflict'\n return changes[1]\n if (~i)\n return changes[i] \n }\n exports.insertMergeOverDelete = \n //i've implemented this as a seperate rule,\n //because I had second thoughts about this.\n function insertMergeOverDelete (changes) {\n changes = changes.slice()\n changes.splice(1,1)// remove concestor\n \n //if there is only one non empty change thats okay.\n //else full confilct\n for (var i = 0, nonempty; i < changes.length; i++)\n if(changes[i].length) \n if(!nonempty) nonempty = changes[i]\n else return // full conflict\n return nonempty\n }\n\n var rules = (deps && deps.rules) || [exports.oddOneOut, exports.insertMergeOverDelete]\n\n function resolve (changes) {\n var l = rules.length\n for (var i in rules) { // first\n \n var c = rules[i] && rules[i](changes)\n if(c) return c\n }\n changes.splice(1,1) // remove concestor\n //returning the conflicts as an object is a really bad idea,\n // because == will not detect they are the same. and conflicts build.\n // better to use\n // '<<<<<<<<<<<<<'\n // of course, i wrote this before i started on snob, so i didn't know that then.\n /*var conflict = ['>>>>>>>>>>>>>>>>']\n while(changes.length)\n conflict = conflict.concat(changes.shift()).concat('============')\n conflict.pop()\n conflict.push ('<<<<<<<<<<<<<<<')\n changes.unshift ('>>>>>>>>>>>>>>>')\n return conflict*/\n //nah, better is just to use an equal can handle objects\n return {'?': changes}\n }\n return exports\n}\nexports(null, exports)\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2FkaWZmL2luZGV4LmpzPzA0ZDYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGNBQWMsYUFBYTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLG1CQUFtQjtBQUNuRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixPQUFPO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0Isb0JBQW9CO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLDBCQUEwQjs7QUFFMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gaGVhZCAoYSkge1xuICByZXR1cm4gYVswXVxufVxuXG5mdW5jdGlvbiBsYXN0IChhKSB7XG4gIHJldHVybiBhW2EubGVuZ3RoIC0gMV1cbn1cblxuZnVuY3Rpb24gdGFpbChhKSB7XG4gIHJldHVybiBhLnNsaWNlKDEpXG59XG5cbmZ1bmN0aW9uIHJldHJlYXQgKGUpIHtcbiAgcmV0dXJuIGUucG9wKClcbn1cblxuZnVuY3Rpb24gaGFzTGVuZ3RoIChlKSB7XG4gIHJldHVybiBlLmxlbmd0aFxufVxuXG5mdW5jdGlvbiBhbnkoYXJ5LCB0ZXN0KSB7XG4gIGZvcih2YXIgaT0wO2k8YXJ5Lmxlbmd0aDtpKyspXG4gICAgaWYodGVzdChhcnlbaV0pKVxuICAgICAgcmV0dXJuIHRydWVcbiAgcmV0dXJuIGZhbHNlXG59XG5cbmZ1bmN0aW9uIHNjb3JlIChhKSB7XG4gIHJldHVybiBhLnJlZHVjZShmdW5jdGlvbiAocywgYSkge1xuICAgICAgcmV0dXJuIHMgKyBhLmxlbmd0aCArIGFbMV0gKyAxXG4gIH0sIDApXG59XG5cbmZ1bmN0aW9uIGJlc3QgKGEsIGIpIHtcbiAgcmV0dXJuIHNjb3JlKGEpIDw9IHNjb3JlKGIpID8gYSA6IGJcbn1cblxuXG52YXIgX3J1bGVzIC8vIHNldCBhdCB0aGUgYm90dG9tICBcblxuLy8gbm90ZSwgbmFpdmUgaW1wbGVtZW50YXRpb24uIHdpbGwgYnJlYWsgb24gY2lyY3VsYXIgb2JqZWN0cy5cblxuZnVuY3Rpb24gX2VxdWFsKGEsIGIpIHtcbiAgaWYoYSAmJiAhYikgcmV0dXJuIGZhbHNlXG4gIGlmKEFycmF5LmlzQXJyYXkoYSkpXG4gICAgaWYoYS5sZW5ndGggIT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICBpZihhICYmICdvYmplY3QnID09IHR5cGVvZiBhKSB7XG4gICAgZm9yKHZhciBpIGluIGEpXG4gICAgICBpZighX2VxdWFsKGFbaV0sIGJbaV0pKSByZXR1cm4gZmFsc2VcbiAgICBmb3IodmFyIGkgaW4gYilcbiAgICAgIGlmKCFfZXF1YWwoYVtpXSwgYltpXSkpIHJldHVybiBmYWxzZVxuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuIGEgPT0gYlxufVxuXG5mdW5jdGlvbiBnZXRBcmdzKGFyZ3MpIHtcbiAgcmV0dXJuIGFyZ3MubGVuZ3RoID09IDEgPyBhcmdzWzBdIDogW10uc2xpY2UuY2FsbChhcmdzKVxufVxuXG4vLyByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IG5vdCBsaWtlIHRoZSBvdGhlcnMsIG9yIC0xXG5mdW5jdGlvbiBvZGRFbGVtZW50KGFyeSwgY21wKSB7XG4gIHZhciBjXG4gIGZ1bmN0aW9uIGd1ZXNzKGEpIHtcbiAgICB2YXIgb2RkID0gLTFcbiAgICBjID0gMFxuICAgIGZvciAodmFyIGkgPSBhOyBpIDwgYXJ5Lmxlbmd0aDsgaSArKykge1xuICAgICAgaWYoIWNtcChhcnlbYV0sIGFyeVtpXSkpIHtcbiAgICAgICAgb2RkID0gaSwgYysrXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjID4gMSA/IC0xIDogb2RkXG4gIH1cbiAgLy9hc3N1bWUgdGhhdCBpdCBpcyB0aGUgZmlyc3QgZWxlbWVudC5cbiAgdmFyIGcgPSBndWVzcygwKVxuICBpZigtMSAhPSBnKSByZXR1cm4gZ1xuICAvLzAgd2FzIHRoZSBvZGQgb25lLCB0aGVuIGFsbCB0aGUgb3RoZXIgZWxlbWVudHMgYXJlIGVxdWFsXG4gIC8vZWxzZSB0aGVyZSBtb3JlIHRoYW4gb25lIGRpZmZlcmVudCBlbGVtZW50XG4gIGd1ZXNzKDEpXG4gIHJldHVybiBjID09IDAgPyAwIDogLTFcbn1cbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZGVwcywgZXhwb3J0cykge1xuICB2YXIgZXF1YWwgPSAoZGVwcyAmJiBkZXBzLmVxdWFsKSB8fCBfZXF1YWxcbiAgZXhwb3J0cyA9IGV4cG9ydHMgfHwge30gXG4gIGV4cG9ydHMubGNzID0gXG4gIGZ1bmN0aW9uIGxjcygpIHtcbiAgICB2YXIgY2FjaGUgPSB7fVxuICAgIHZhciBhcmdzID0gZ2V0QXJncyhhcmd1bWVudHMpXG4gICAgdmFyIGEgPSBhcmdzWzBdLCBiID0gYXJnc1sxXVxuXG4gICAgZnVuY3Rpb24ga2V5IChhLGIpe1xuICAgICAgcmV0dXJuIGEubGVuZ3RoICsgJzonICsgYi5sZW5ndGhcbiAgICB9XG5cbiAgICAvL2ZpbmQgbGVuZ3RoIHRoYXQgbWF0Y2hlcyBhdCB0aGUgaGVhZFxuXG4gICAgaWYoYXJncy5sZW5ndGggPiAyKSB7XG4gICAgICAvL2lmIGNhbGxlZCB3aXRoIG11bHRpcGxlIHNlcXVlbmNlc1xuICAgICAgLy9yZWN1cnNlLCBzaW5jZSBsY3MoYSwgYiwgYywgZCkgPT0gbGNzKGxjcyhhLGIpLCBsY3MoYyxkKSlcbiAgICAgIGFyZ3MucHVzaChsY3MoYXJncy5zaGlmdCgpLCBhcmdzLnNoaWZ0KCkpKVxuICAgICAgcmV0dXJuIGxjcyhhcmdzKVxuICAgIH1cbiAgICBcbiAgICAvL3RoaXMgd291bGQgYmUgaW1wcm92ZWQgYnkgdHJ1bmNhdGluZyBpbnB1dCBmaXJzdFxuICAgIC8vYW5kIG5vdCByZXR1cm5pbmcgYW4gbGNzIGFzIGFuIGludGVybWVkaWF0ZSBzdGVwLlxuICAgIC8vdW50aWxsIHRoYXQgaXMgYSBwZXJmb3JtYW5jZSBwcm9ibGVtLlxuXG4gICAgdmFyIHN0YXJ0ID0gMCwgZW5kID0gMFxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aCAmJiBpIDwgYi5sZW5ndGggXG4gICAgICAmJiBlcXVhbChhW2ldLCBiW2ldKVxuICAgICAgOyBpICsrXG4gICAgKVxuICAgICAgc3RhcnQgPSBpICsgMVxuXG4gICAgaWYoYS5sZW5ndGggPT09IHN0YXJ0KVxuICAgICAgcmV0dXJuIGEuc2xpY2UoKVxuXG4gICAgZm9yKHZhciBpID0gMDsgIGkgPCBhLmxlbmd0aCAtIHN0YXJ0ICYmIGkgPCBiLmxlbmd0aCAtIHN0YXJ0XG4gICAgICAmJiBlcXVhbChhW2EubGVuZ3RoIC0gMSAtIGldLCBiW2IubGVuZ3RoIC0gMSAtIGldKVxuICAgICAgOyBpICsrXG4gICAgKVxuICAgICAgZW5kID0gaVxuXG4gICAgZnVuY3Rpb24gcmVjdXJzZSAoYSwgYikge1xuICAgICAgaWYoIWEubGVuZ3RoIHx8ICFiLmxlbmd0aCkgcmV0dXJuIFtdXG4gICAgICAvL2F2b2lkIGV4cG9uZW50aWFsIHRpbWUgYnkgY2FjaGluZyB0aGUgcmVzdWx0c1xuICAgICAgaWYoY2FjaGVba2V5KGEsIGIpXSkgcmV0dXJuIGNhY2hlW2tleShhLCBiKV1cblxuICAgICAgaWYoZXF1YWwoYVswXSwgYlswXSkpXG4gICAgICAgIHJldHVybiBbaGVhZChhKV0uY29uY2F0KHJlY3Vyc2UodGFpbChhKSwgdGFpbChiKSkpXG4gICAgICBlbHNlIHsgXG4gICAgICAgIHZhciBfYSA9IHJlY3Vyc2UodGFpbChhKSwgYilcbiAgICAgICAgdmFyIF9iID0gcmVjdXJzZShhLCB0YWlsKGIpKVxuICAgICAgICByZXR1cm4gY2FjaGVba2V5KGEsYildID0gX2EubGVuZ3RoID4gX2IubGVuZ3RoID8gX2EgOiBfYiAgXG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHZhciBtaWRkbGVBID0gYS5zbGljZShzdGFydCwgYS5sZW5ndGggLSBlbmQpXG4gICAgdmFyIG1pZGRsZUIgPSBiLnNsaWNlKHN0YXJ0LCBiLmxlbmd0aCAtIGVuZClcblxuICAgIHJldHVybiAoXG4gICAgICBhLnNsaWNlKDAsIHN0YXJ0KS5jb25jYXQoXG4gICAgICAgIHJlY3Vyc2UobWlkZGxlQSwgbWlkZGxlQilcbiAgICAgICkuY29uY2F0KGEuc2xpY2UoYS5sZW5ndGggLSBlbmQpKVxuICAgIClcbiAgfVxuXG4gIC8vIGdpdmVuIG4gc2VxdWVuY2VzLCBjYWxjIHRoZSBsY3MsIGFuZCB0aGVuIGNodW5rIHN0cmluZ3MgaW50byBzdGFibGUgYW5kIHVuc3RhYmxlIHNlY3Rpb25zLlxuICAvLyB1bnN0YWJsZSBjaHVua3MgYXJlIHBhc3NlZCB0byBidWlsZFxuICBleHBvcnRzLmNodW5rID1cbiAgZnVuY3Rpb24gKHEsIGJ1aWxkKSB7XG4gICAgdmFyIHEgPSBxLm1hcChmdW5jdGlvbiAoZSkgeyByZXR1cm4gZS5zbGljZSgpIH0pXG4gICAgdmFyIGxjcyA9IGV4cG9ydHMubGNzLmFwcGx5KG51bGwsIHEpXG4gICAgdmFyIGFsbCA9IFtsY3NdLmNvbmNhdChxKVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hMY3MgKGUpIHtcbiAgICAgIGlmKGUubGVuZ3RoICYmICFsY3MubGVuZ3RoIHx8ICFlLmxlbmd0aCAmJiBsY3MubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2UgLy9pbmNhc2UgdGhlIGxhc3QgaXRlbSBpcyBudWxsXG4gICAgICByZXR1cm4gZXF1YWwobGFzdChlKSwgbGFzdChsY3MpKSB8fCAoKGUubGVuZ3RoICsgbGNzLmxlbmd0aCkgPT09IDApXG4gICAgfVxuXG4gICAgd2hpbGUoYW55KHEsIGhhc0xlbmd0aCkpIHtcbiAgICAgIC8vaWYgZWFjaCBlbGVtZW50IGlzIGF0IHRoZSBsY3MgdGhlbiB0aGlzIGNodW5rIGlzIHN0YWJsZS5cbiAgICAgIHdoaWxlKHEuZXZlcnkobWF0Y2hMY3MpICYmIHEuZXZlcnkoaGFzTGVuZ3RoKSlcbiAgICAgICAgYWxsLmZvckVhY2gocmV0cmVhdClcbiAgICAgIC8vY29sbGVjdCB0aGUgY2hhbmdlcyBpbiBlYWNoIGFycmF5IHVwdG8gdGhlIG5leHQgbWF0Y2ggd2l0aCB0aGUgbGNzXG4gICAgICB2YXIgYyA9IGZhbHNlXG4gICAgICB2YXIgdW5zdGFibGUgPSBxLm1hcChmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgY2hhbmdlID0gW11cbiAgICAgICAgd2hpbGUoIW1hdGNoTGNzKGUpKSB7XG4gICAgICAgICAgY2hhbmdlLnVuc2hpZnQocmV0cmVhdChlKSlcbiAgICAgICAgICBjID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGFuZ2VcbiAgICAgIH0pXG4gICAgICBpZihjKSBidWlsZChxWzBdLmxlbmd0aCwgdW5zdGFibGUpXG4gICAgfVxuICB9XG5cbiAgLy9jYWxjdWxhdGUgYSBkaWZmIHRoaXMgaXMgb25seSB1cGRhdGVzXG4gIGV4cG9ydHMub3B0aW1pc3RpY0RpZmYgPVxuICBmdW5jdGlvbiAoYSwgYikge1xuICAgIHZhciBNID0gTWF0aC5tYXgoYS5sZW5ndGgsIGIubGVuZ3RoKVxuICAgIHZhciBtID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICAgIHZhciBwYXRjaCA9IFtdXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IE07IGkrKylcbiAgICAgIGlmKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgICAgdmFyIGN1ciA9IFtpLDBdLCBkZWxldGVzID0gMFxuICAgICAgICB3aGlsZShhW2ldICE9PSBiW2ldICYmIGkgPCBtKSB7XG4gICAgICAgICAgY3VyWzFdID0gKytkZWxldGVzXG4gICAgICAgICAgY3VyLnB1c2goYltpKytdKVxuICAgICAgICB9XG4gICAgICAgIC8vdGhlIHJlc3QgYXJlIGRlbGV0ZXMgb3IgaW5zZXJ0c1xuICAgICAgICBpZihpID49IG0pIHtcbiAgICAgICAgICAvL3RoZSByZXN0IGFyZSBkZWxldGVzXG4gICAgICAgICAgaWYoYS5sZW5ndGggPiBiLmxlbmd0aClcbiAgICAgICAgICAgIGN1clsxXSArPSBhLmxlbmd0aCAtIGIubGVuZ3RoXG4gICAgICAgICAgLy90aGUgcmVzdCBhcmUgaW5zZXJ0c1xuICAgICAgICAgIGVsc2UgaWYoYS5sZW5ndGggPCBiLmxlbmd0aClcbiAgICAgICAgICAgIGN1ciA9IGN1ci5jb25jYXQoYi5zbGljZShhLmxlbmd0aCkpXG4gICAgICAgIH1cbiAgICAgICAgcGF0Y2gucHVzaChjdXIpXG4gICAgICB9XG5cbiAgICByZXR1cm4gcGF0Y2hcbiAgfVxuXG4gIGV4cG9ydHMuZGlmZiA9XG4gIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgdmFyIG9wdGltaXN0aWMgPSBleHBvcnRzLm9wdGltaXN0aWNEaWZmKGEsIGIpXG4gICAgdmFyIGNoYW5nZXMgPSBbXVxuICAgIGV4cG9ydHMuY2h1bmsoW2EsIGJdLCBmdW5jdGlvbiAoaW5kZXgsIHVuc3RhYmxlKSB7XG4gICAgICB2YXIgZGVsID0gdW5zdGFibGUuc2hpZnQoKS5sZW5ndGhcbiAgICAgIHZhciBpbnNlcnQgPSB1bnN0YWJsZS5zaGlmdCgpXG4gICAgICBjaGFuZ2VzLnB1c2goW2luZGV4LCBkZWxdLmNvbmNhdChpbnNlcnQpKVxuICAgIH0pXG4gICAgcmV0dXJuIGJlc3Qob3B0aW1pc3RpYywgY2hhbmdlcylcbiAgfVxuXG4gIGV4cG9ydHMucGF0Y2ggPSBmdW5jdGlvbiAoYSwgY2hhbmdlcywgbXV0YXRlKSB7XG4gICAgaWYobXV0YXRlICE9PSB0cnVlKSBhID0gYS5zbGljZShhKS8vY29weSBhXG4gICAgY2hhbmdlcy5mb3JFYWNoKGZ1bmN0aW9uIChjaGFuZ2UpIHtcbiAgICAgIFtdLnNwbGljZS5hcHBseShhLCBjaGFuZ2UpXG4gICAgfSlcbiAgICByZXR1cm4gYVxuICB9XG5cbiAgLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXN0b3JcbiAgLy8gbWUsIGNvbmNlc3RvciwgeW91Li4uXG4gIGV4cG9ydHMubWVyZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBnZXRBcmdzKGFyZ3VtZW50cylcbiAgICB2YXIgcGF0Y2ggPSBleHBvcnRzLmRpZmYzKGFyZ3MpXG4gICAgcmV0dXJuIGV4cG9ydHMucGF0Y2goYXJnc1swXSwgcGF0Y2gpXG4gIH1cblxuICBleHBvcnRzLmRpZmYzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gZ2V0QXJncyhhcmd1bWVudHMpXG4gICAgdmFyIHIgPSBbXVxuICAgIGV4cG9ydHMuY2h1bmsoYXJncywgZnVuY3Rpb24gKGluZGV4LCB1bnN0YWJsZSkge1xuICAgICAgdmFyIG1pbmUgPSB1bnN0YWJsZVswXVxuICAgICAgdmFyIGluc2VydCA9IHJlc29sdmUodW5zdGFibGUpXG4gICAgICBpZihlcXVhbChtaW5lLCBpbnNlcnQpKSByZXR1cm4gXG4gICAgICByLnB1c2goW2luZGV4LCBtaW5lLmxlbmd0aF0uY29uY2F0KGluc2VydCkpIFxuICAgIH0pXG4gICAgcmV0dXJuIHJcbiAgfVxuICBleHBvcnRzLm9kZE9uZU91dCA9XG4gICAgZnVuY3Rpb24gb2RkT25lT3V0IChjaGFuZ2VzKSB7XG4gICAgICBjaGFuZ2VzID0gY2hhbmdlcy5zbGljZSgpXG4gICAgICAvL3B1dCB0aGUgY29uY2VzdG9yIGZpcnN0XG4gICAgICBjaGFuZ2VzLnVuc2hpZnQoY2hhbmdlcy5zcGxpY2UoMSwxKVswXSlcbiAgICAgIHZhciBpID0gb2RkRWxlbWVudChjaGFuZ2VzLCBlcXVhbClcbiAgICAgIGlmKGkgPT0gMCkgLy8gY29uY2VzdG9yIHdhcyBkaWZmZXJlbnQsICdmYWxzZSBjb25mbGljdCdcbiAgICAgICAgcmV0dXJuIGNoYW5nZXNbMV1cbiAgICAgIGlmICh+aSlcbiAgICAgICAgcmV0dXJuIGNoYW5nZXNbaV0gXG4gICAgfVxuICBleHBvcnRzLmluc2VydE1lcmdlT3ZlckRlbGV0ZSA9IFxuICAgIC8vaSd2ZSBpbXBsZW1lbnRlZCB0aGlzIGFzIGEgc2VwZXJhdGUgcnVsZSxcbiAgICAvL2JlY2F1c2UgSSBoYWQgc2Vjb25kIHRob3VnaHRzIGFib3V0IHRoaXMuXG4gICAgZnVuY3Rpb24gaW5zZXJ0TWVyZ2VPdmVyRGVsZXRlIChjaGFuZ2VzKSB7XG4gICAgICBjaGFuZ2VzID0gY2hhbmdlcy5zbGljZSgpXG4gICAgICBjaGFuZ2VzLnNwbGljZSgxLDEpLy8gcmVtb3ZlIGNvbmNlc3RvclxuICAgICAgXG4gICAgICAvL2lmIHRoZXJlIGlzIG9ubHkgb25lIG5vbiBlbXB0eSBjaGFuZ2UgdGhhdHMgb2theS5cbiAgICAgIC8vZWxzZSBmdWxsIGNvbmZpbGN0XG4gICAgICBmb3IgKHZhciBpID0gMCwgbm9uZW1wdHk7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICBpZihjaGFuZ2VzW2ldLmxlbmd0aCkgXG4gICAgICAgICAgaWYoIW5vbmVtcHR5KSBub25lbXB0eSA9IGNoYW5nZXNbaV1cbiAgICAgICAgICBlbHNlIHJldHVybiAvLyBmdWxsIGNvbmZsaWN0XG4gICAgICByZXR1cm4gbm9uZW1wdHlcbiAgICB9XG5cbiAgdmFyIHJ1bGVzID0gKGRlcHMgJiYgZGVwcy5ydWxlcykgfHwgW2V4cG9ydHMub2RkT25lT3V0LCBleHBvcnRzLmluc2VydE1lcmdlT3ZlckRlbGV0ZV1cblxuICBmdW5jdGlvbiByZXNvbHZlIChjaGFuZ2VzKSB7XG4gICAgdmFyIGwgPSBydWxlcy5sZW5ndGhcbiAgICBmb3IgKHZhciBpIGluIHJ1bGVzKSB7IC8vIGZpcnN0XG4gICAgICBcbiAgICAgIHZhciBjID0gcnVsZXNbaV0gJiYgcnVsZXNbaV0oY2hhbmdlcylcbiAgICAgIGlmKGMpIHJldHVybiBjXG4gICAgfVxuICAgIGNoYW5nZXMuc3BsaWNlKDEsMSkgLy8gcmVtb3ZlIGNvbmNlc3RvclxuICAgIC8vcmV0dXJuaW5nIHRoZSBjb25mbGljdHMgYXMgYW4gb2JqZWN0IGlzIGEgcmVhbGx5IGJhZCBpZGVhLFxuICAgIC8vIGJlY2F1c2UgPT0gd2lsbCBub3QgZGV0ZWN0IHRoZXkgYXJlIHRoZSBzYW1lLiBhbmQgY29uZmxpY3RzIGJ1aWxkLlxuICAgIC8vIGJldHRlciB0byB1c2VcbiAgICAvLyAnPDw8PDw8PDw8PDw8PCdcbiAgICAvLyBvZiBjb3Vyc2UsIGkgd3JvdGUgdGhpcyBiZWZvcmUgaSBzdGFydGVkIG9uIHNub2IsIHNvIGkgZGlkbid0IGtub3cgdGhhdCB0aGVuLlxuICAgIC8qdmFyIGNvbmZsaWN0ID0gWyc+Pj4+Pj4+Pj4+Pj4+Pj4+J11cbiAgICB3aGlsZShjaGFuZ2VzLmxlbmd0aClcbiAgICAgIGNvbmZsaWN0ID0gY29uZmxpY3QuY29uY2F0KGNoYW5nZXMuc2hpZnQoKSkuY29uY2F0KCc9PT09PT09PT09PT0nKVxuICAgIGNvbmZsaWN0LnBvcCgpXG4gICAgY29uZmxpY3QucHVzaCAgICAgICAgICAoJzw8PDw8PDw8PDw8PDw8PCcpXG4gICAgY2hhbmdlcy51bnNoaWZ0ICAgICAgICgnPj4+Pj4+Pj4+Pj4+Pj4+JylcbiAgICByZXR1cm4gY29uZmxpY3QqL1xuICAgIC8vbmFoLCBiZXR0ZXIgaXMganVzdCB0byB1c2UgYW4gZXF1YWwgY2FuIGhhbmRsZSBvYmplY3RzXG4gICAgcmV0dXJuIHsnPyc6IGNoYW5nZXN9XG4gIH1cbiAgcmV0dXJuIGV4cG9ydHNcbn1cbmV4cG9ydHMobnVsbCwgZXhwb3J0cylcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2FkaWZmL2luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ==");
|
|
54
|
+
|
|
55
|
+
/***/ },
|
|
56
|
+
/* 2 */
|
|
57
|
+
/***/ function(module, exports) {
|
|
58
|
+
|
|
59
|
+
eval("\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = flattenImageData;\n/**\n * @param {Array} imageData a 2d array\n * @return {Uint8ClampedArray}\n */\nfunction flattenImageData(imageData) {\n var width = imageData[0].length;\n var result = new Uint8ClampedArray(imageData.length * width * 4);\n imageData.forEach(function (row, y) {\n row.forEach(function (pixel, x) {\n var index = y * width * 4 + x * 4;\n result[index] = pixel[0];\n result[index + 1] = pixel[1];\n result[index + 2] = pixel[2];\n result[index + 3] = pixel[3];\n });\n });\n return result;\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvZmxhdHRlbkltYWdlRGF0YS5qcz8yZGRiIl0sIm5hbWVzIjpbImZsYXR0ZW5JbWFnZURhdGEiLCJpbWFnZURhdGEiLCJ3aWR0aCIsImxlbmd0aCIsInJlc3VsdCIsIlVpbnQ4Q2xhbXBlZEFycmF5IiwiZm9yRWFjaCIsInJvdyIsInkiLCJwaXhlbCIsIngiLCJpbmRleCJdLCJtYXBwaW5ncyI6Ijs7Ozs7a0JBSXdCQSxnQjtBQUp4Qjs7OztBQUllLFNBQVNBLGdCQUFULENBQTBCQyxTQUExQixFQUFxQztBQUNsRCxNQUFNQyxRQUFRRCxVQUFVLENBQVYsRUFBYUUsTUFBM0I7QUFDQSxNQUFNQyxTQUFTLElBQUlDLGlCQUFKLENBQXNCSixVQUFVRSxNQUFWLEdBQW1CRCxLQUFuQixHQUEyQixDQUFqRCxDQUFmO0FBQ0FELFlBQVVLLE9BQVYsQ0FBa0IsVUFBQ0MsR0FBRCxFQUFNQyxDQUFOLEVBQVk7QUFDNUJELFFBQUlELE9BQUosQ0FBWSxVQUFDRyxLQUFELEVBQVFDLENBQVIsRUFBYztBQUN4QixVQUFNQyxRQUFTSCxJQUFJTixLQUFKLEdBQVksQ0FBYixHQUFtQlEsSUFBSSxDQUFyQztBQUNBTixhQUFPTyxLQUFQLElBQWdCRixNQUFNLENBQU4sQ0FBaEI7QUFDQUwsYUFBT08sUUFBUSxDQUFmLElBQW9CRixNQUFNLENBQU4sQ0FBcEI7QUFDQUwsYUFBT08sUUFBUSxDQUFmLElBQW9CRixNQUFNLENBQU4sQ0FBcEI7QUFDQUwsYUFBT08sUUFBUSxDQUFmLElBQW9CRixNQUFNLENBQU4sQ0FBcEI7QUFDRCxLQU5EO0FBT0QsR0FSRDtBQVNBLFNBQU9MLE1BQVA7QUFDRCIsImZpbGUiOiIyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcGFyYW0ge0FycmF5fSBpbWFnZURhdGEgYSAyZCBhcnJheVxuICogQHJldHVybiB7VWludDhDbGFtcGVkQXJyYXl9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZsYXR0ZW5JbWFnZURhdGEoaW1hZ2VEYXRhKSB7XG4gIGNvbnN0IHdpZHRoID0gaW1hZ2VEYXRhWzBdLmxlbmd0aDtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KGltYWdlRGF0YS5sZW5ndGggKiB3aWR0aCAqIDQpO1xuICBpbWFnZURhdGEuZm9yRWFjaCgocm93LCB5KSA9PiB7XG4gICAgcm93LmZvckVhY2goKHBpeGVsLCB4KSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9ICh5ICogd2lkdGggKiA0KSArICh4ICogNCk7XG4gICAgICByZXN1bHRbaW5kZXhdID0gcGl4ZWxbMF07XG4gICAgICByZXN1bHRbaW5kZXggKyAxXSA9IHBpeGVsWzFdO1xuICAgICAgcmVzdWx0W2luZGV4ICsgMl0gPSBwaXhlbFsyXTtcbiAgICAgIHJlc3VsdFtpbmRleCArIDNdID0gcGl4ZWxbM107XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9qcy9zcmMvZmxhdHRlbkltYWdlRGF0YS5qc1xuICoqLyJdLCJzb3VyY2VSb290IjoiIn0=");
|
|
60
|
+
|
|
61
|
+
/***/ }
|
|
62
|
+
/******/ ]);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/******/ (function(modules) { // webpackBootstrap
|
|
2
|
+
/******/ // The module cache
|
|
3
|
+
/******/ var installedModules = {};
|
|
4
|
+
|
|
5
|
+
/******/ // The require function
|
|
6
|
+
/******/ function __webpack_require__(moduleId) {
|
|
7
|
+
|
|
8
|
+
/******/ // Check if module is in cache
|
|
9
|
+
/******/ if(installedModules[moduleId])
|
|
10
|
+
/******/ return installedModules[moduleId].exports;
|
|
11
|
+
|
|
12
|
+
/******/ // Create a new module (and put it into the cache)
|
|
13
|
+
/******/ var module = installedModules[moduleId] = {
|
|
14
|
+
/******/ exports: {},
|
|
15
|
+
/******/ id: moduleId,
|
|
16
|
+
/******/ loaded: false
|
|
17
|
+
/******/ };
|
|
18
|
+
|
|
19
|
+
/******/ // Execute the module function
|
|
20
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
21
|
+
|
|
22
|
+
/******/ // Flag the module as loaded
|
|
23
|
+
/******/ module.loaded = true;
|
|
24
|
+
|
|
25
|
+
/******/ // Return the exports of the module
|
|
26
|
+
/******/ return module.exports;
|
|
27
|
+
/******/ }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
31
|
+
/******/ __webpack_require__.m = modules;
|
|
32
|
+
|
|
33
|
+
/******/ // expose the module cache
|
|
34
|
+
/******/ __webpack_require__.c = installedModules;
|
|
35
|
+
|
|
36
|
+
/******/ // __webpack_public_path__
|
|
37
|
+
/******/ __webpack_require__.p = "";
|
|
38
|
+
|
|
39
|
+
/******/ // Load entry module and return exports
|
|
40
|
+
/******/ return __webpack_require__(0);
|
|
41
|
+
/******/ })
|
|
42
|
+
/************************************************************************/
|
|
43
|
+
/******/ ([
|
|
44
|
+
/* 0 */
|
|
45
|
+
/***/ function(module, exports, __webpack_require__) {
|
|
46
|
+
|
|
47
|
+
eval("'use strict';\n\nvar _getDiffPixel = __webpack_require__(1);\n\nvar _getDiffPixel2 = _interopRequireDefault(_getDiffPixel);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nself.addEventListener('message', function (_ref) {\n var _ref$data = _ref.data;\n var previousImageData = _ref$data.previousImageData;\n var currentImageData = _ref$data.currentImageData;\n\n var size = previousImageData[0].length * previousImageData.length;\n var data = new Uint8ClampedArray(size);\n\n for (var row = 0; row < previousImageData.length; row++) {\n for (var index = 0; index < previousImageData[0].length; index += 4) {\n var pixel = (0, _getDiffPixel2.default)([previousImageData[row][index], previousImageData[row][index + 1], previousImageData[row][index + 2], previousImageData[row][index + 3]], [currentImageData[row][index], currentImageData[row][index + 1], currentImageData[row][index + 2], currentImageData[row][index + 3]]);\n\n data[row * previousImageData.length + index + 0] = pixel[0]; // r\n data[row * previousImageData.lengt + index + 1] = pixel[1]; // g\n data[row * previousImageData.lengt + index + 2] = pixel[2]; // b\n data[row * previousImageData.lengt + index + 3] = pixel[3]; // a\n }\n }\n\n self.postMessage(data);\n self.close();\n});//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvd29ya2Vycy9JbWFnZURpZmZXb3JrZXIuanM/ZjExYiJdLCJuYW1lcyI6WyJzZWxmIiwiYWRkRXZlbnRMaXN0ZW5lciIsImRhdGEiLCJwcmV2aW91c0ltYWdlRGF0YSIsImN1cnJlbnRJbWFnZURhdGEiLCJzaXplIiwibGVuZ3RoIiwiVWludDhDbGFtcGVkQXJyYXkiLCJyb3ciLCJpbmRleCIsInBpeGVsIiwibGVuZ3QiLCJwb3N0TWVzc2FnZSIsImNsb3NlIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7QUFFQUEsS0FBS0MsZ0JBQUwsQ0FBc0IsU0FBdEIsRUFBaUMsZ0JBSzNCO0FBQUEsdUJBSkpDLElBSUk7QUFBQSxNQUhGQyxpQkFHRSxhQUhGQSxpQkFHRTtBQUFBLE1BRkZDLGdCQUVFLGFBRkZBLGdCQUVFOztBQUNKLE1BQU1DLE9BQU9GLGtCQUFrQixDQUFsQixFQUFxQkcsTUFBckIsR0FBOEJILGtCQUFrQkcsTUFBN0Q7QUFDQSxNQUFNSixPQUFPLElBQUlLLGlCQUFKLENBQXNCRixJQUF0QixDQUFiOztBQUVBLE9BQUssSUFBSUcsTUFBTSxDQUFmLEVBQWtCQSxNQUFNTCxrQkFBa0JHLE1BQTFDLEVBQWtERSxLQUFsRCxFQUF5RDtBQUN2RCxTQUFLLElBQUlDLFFBQVEsQ0FBakIsRUFBb0JBLFFBQVFOLGtCQUFrQixDQUFsQixFQUFxQkcsTUFBakQsRUFBeURHLFNBQVMsQ0FBbEUsRUFBcUU7QUFDbkUsVUFBTUMsUUFBUSw0QkFDWixDQUNFUCxrQkFBa0JLLEdBQWxCLEVBQXVCQyxLQUF2QixDQURGLEVBRUVOLGtCQUFrQkssR0FBbEIsRUFBdUJDLFFBQVEsQ0FBL0IsQ0FGRixFQUdFTixrQkFBa0JLLEdBQWxCLEVBQXVCQyxRQUFRLENBQS9CLENBSEYsRUFJRU4sa0JBQWtCSyxHQUFsQixFQUF1QkMsUUFBUSxDQUEvQixDQUpGLENBRFksRUFPWixDQUNFTCxpQkFBaUJJLEdBQWpCLEVBQXNCQyxLQUF0QixDQURGLEVBRUVMLGlCQUFpQkksR0FBakIsRUFBc0JDLFFBQVEsQ0FBOUIsQ0FGRixFQUdFTCxpQkFBaUJJLEdBQWpCLEVBQXNCQyxRQUFRLENBQTlCLENBSEYsRUFJRUwsaUJBQWlCSSxHQUFqQixFQUFzQkMsUUFBUSxDQUE5QixDQUpGLENBUFksQ0FBZDs7QUFlQVAsV0FBTU0sTUFBTUwsa0JBQWtCRyxNQUF6QixHQUFtQ0csS0FBbkMsR0FBMkMsQ0FBaEQsSUFBcURDLE1BQU0sQ0FBTixDQUFyRCxDQWhCbUUsQ0FnQko7QUFDL0RSLFdBQU1NLE1BQU1MLGtCQUFrQlEsS0FBekIsR0FBa0NGLEtBQWxDLEdBQTBDLENBQS9DLElBQW9EQyxNQUFNLENBQU4sQ0FBcEQsQ0FqQm1FLENBaUJMO0FBQzlEUixXQUFNTSxNQUFNTCxrQkFBa0JRLEtBQXpCLEdBQWtDRixLQUFsQyxHQUEwQyxDQUEvQyxJQUFvREMsTUFBTSxDQUFOLENBQXBELENBbEJtRSxDQWtCTDtBQUM5RFIsV0FBTU0sTUFBTUwsa0JBQWtCUSxLQUF6QixHQUFrQ0YsS0FBbEMsR0FBMEMsQ0FBL0MsSUFBb0RDLE1BQU0sQ0FBTixDQUFwRCxDQW5CbUUsQ0FtQkw7QUFDL0Q7QUFDRjs7QUFFRFYsT0FBS1ksV0FBTCxDQUFpQlYsSUFBakI7QUFDQUYsT0FBS2EsS0FBTDtBQUNELENBbkNEIiwiZmlsZSI6IjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZ2V0RGlmZlBpeGVsIGZyb20gJy4uL2dldERpZmZQaXhlbCc7XG5cbnNlbGYuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsICh7XG4gIGRhdGE6IHtcbiAgICBwcmV2aW91c0ltYWdlRGF0YSxcbiAgICBjdXJyZW50SW1hZ2VEYXRhLFxuICB9LFxufSkgPT4ge1xuICBjb25zdCBzaXplID0gcHJldmlvdXNJbWFnZURhdGFbMF0ubGVuZ3RoICogcHJldmlvdXNJbWFnZURhdGEubGVuZ3RoO1xuICBjb25zdCBkYXRhID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHNpemUpO1xuXG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHByZXZpb3VzSW1hZ2VEYXRhLmxlbmd0aDsgcm93KyspIHtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcHJldmlvdXNJbWFnZURhdGFbMF0ubGVuZ3RoOyBpbmRleCArPSA0KSB7XG4gICAgICBjb25zdCBwaXhlbCA9IGdldERpZmZQaXhlbChcbiAgICAgICAgW1xuICAgICAgICAgIHByZXZpb3VzSW1hZ2VEYXRhW3Jvd11baW5kZXhdLFxuICAgICAgICAgIHByZXZpb3VzSW1hZ2VEYXRhW3Jvd11baW5kZXggKyAxXSxcbiAgICAgICAgICBwcmV2aW91c0ltYWdlRGF0YVtyb3ddW2luZGV4ICsgMl0sXG4gICAgICAgICAgcHJldmlvdXNJbWFnZURhdGFbcm93XVtpbmRleCArIDNdLFxuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgY3VycmVudEltYWdlRGF0YVtyb3ddW2luZGV4XSxcbiAgICAgICAgICBjdXJyZW50SW1hZ2VEYXRhW3Jvd11baW5kZXggKyAxXSxcbiAgICAgICAgICBjdXJyZW50SW1hZ2VEYXRhW3Jvd11baW5kZXggKyAyXSxcbiAgICAgICAgICBjdXJyZW50SW1hZ2VEYXRhW3Jvd11baW5kZXggKyAzXSxcbiAgICAgICAgXVxuICAgICAgKTtcblxuICAgICAgZGF0YVsocm93ICogcHJldmlvdXNJbWFnZURhdGEubGVuZ3RoKSArIGluZGV4ICsgMF0gPSBwaXhlbFswXTsgLy8gclxuICAgICAgZGF0YVsocm93ICogcHJldmlvdXNJbWFnZURhdGEubGVuZ3QpICsgaW5kZXggKyAxXSA9IHBpeGVsWzFdOyAvLyBnXG4gICAgICBkYXRhWyhyb3cgKiBwcmV2aW91c0ltYWdlRGF0YS5sZW5ndCkgKyBpbmRleCArIDJdID0gcGl4ZWxbMl07IC8vIGJcbiAgICAgIGRhdGFbKHJvdyAqIHByZXZpb3VzSW1hZ2VEYXRhLmxlbmd0KSArIGluZGV4ICsgM10gPSBwaXhlbFszXTsgLy8gYVxuICAgIH1cbiAgfVxuXG4gIHNlbGYucG9zdE1lc3NhZ2UoZGF0YSk7XG4gIHNlbGYuY2xvc2UoKTtcbn0pO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9qcy9zcmMvd29ya2Vycy9JbWFnZURpZmZXb3JrZXIuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9");
|
|
48
|
+
|
|
49
|
+
/***/ },
|
|
50
|
+
/* 1 */
|
|
51
|
+
/***/ function(module, exports, __webpack_require__) {
|
|
52
|
+
|
|
53
|
+
eval("'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = getDiffPixel;\n\nvar _compose = __webpack_require__(2);\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _euclideanDistance = __webpack_require__(3);\n\nvar _euclideanDistance2 = _interopRequireDefault(_euclideanDistance);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar WHITE = [255, 255, 255, 255];\n\nfunction getDiffPixel(previousPixel, currentPixel) {\n if (!previousPixel) {\n return currentPixel;\n }\n\n if (!currentPixel) {\n return previousPixel;\n }\n\n // Compute a score that represents the difference between 2 pixels\n //\n // This method simply takes the Euclidean distance between the RGBA channels\n // of 2 colors over the maximum possible Euclidean distance. This gives us a\n // percentage of how different the two colors are.\n //\n // Although it would be more perceptually accurate to calculate a proper\n // Delta E in Lab colorspace, we probably don't need perceptual accuracy for\n // this application, and it is nice to avoid the overhead of converting RGBA\n // to Lab.\n var diff = (0, _euclideanDistance2.default)(previousPixel, currentPixel) / _euclideanDistance.MAX_EUCLIDEAN_DISTANCE;\n\n if (diff === 0) {\n return (0, _compose2.default)([currentPixel[0], currentPixel[1], currentPixel[2], 40], WHITE);\n }\n\n debugger;\n return (0, _compose2.default)([179, 54, 130, 255 * Math.max(0.2, diff)], WHITE);\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvZ2V0RGlmZlBpeGVsLmpzPzRiNjgiXSwibmFtZXMiOlsiZ2V0RGlmZlBpeGVsIiwiV0hJVEUiLCJwcmV2aW91c1BpeGVsIiwiY3VycmVudFBpeGVsIiwiZGlmZiIsIk1hdGgiLCJtYXgiXSwibWFwcGluZ3MiOiI7Ozs7O2tCQUt3QkEsWTs7QUFMeEI7Ozs7QUFDQTs7Ozs7O0FBRUEsSUFBTUMsUUFBUSxDQUFDLEdBQUQsRUFBTSxHQUFOLEVBQVcsR0FBWCxFQUFnQixHQUFoQixDQUFkOztBQUVlLFNBQVNELFlBQVQsQ0FBc0JFLGFBQXRCLEVBQXFDQyxZQUFyQyxFQUFtRDtBQUNoRSxNQUFJLENBQUNELGFBQUwsRUFBb0I7QUFDbEIsV0FBT0MsWUFBUDtBQUNEOztBQUVELE1BQUksQ0FBQ0EsWUFBTCxFQUFtQjtBQUNqQixXQUFPRCxhQUFQO0FBQ0Q7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNRSxPQUFPLGlDQUFrQkYsYUFBbEIsRUFBaUNDLFlBQWpDLDZDQUFiOztBQUVBLE1BQUlDLFNBQVMsQ0FBYixFQUFnQjtBQUNkLFdBQU8sdUJBQ0wsQ0FBQ0QsYUFBYSxDQUFiLENBQUQsRUFBa0JBLGFBQWEsQ0FBYixDQUFsQixFQUFtQ0EsYUFBYSxDQUFiLENBQW5DLEVBQW9ELEVBQXBELENBREssRUFFTEYsS0FGSyxDQUFQO0FBSUQ7O0FBRUQ7QUFDQSxTQUFPLHVCQUNMLENBQUMsR0FBRCxFQUFNLEVBQU4sRUFBVSxHQUFWLEVBQWUsTUFBTUksS0FBS0MsR0FBTCxDQUFTLEdBQVQsRUFBY0YsSUFBZCxDQUFyQixDQURLLEVBRUxILEtBRkssQ0FBUDtBQUlEIiwiZmlsZSI6IjEuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29tcG9zZSBmcm9tICcuL2NvbXBvc2UnO1xuaW1wb3J0IGV1Y2xpZGVhbkRpc3RhbmNlLCB7IE1BWF9FVUNMSURFQU5fRElTVEFOQ0UgfSBmcm9tICcuL2V1Y2xpZGVhbkRpc3RhbmNlJztcblxuY29uc3QgV0hJVEUgPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RGlmZlBpeGVsKHByZXZpb3VzUGl4ZWwsIGN1cnJlbnRQaXhlbCkge1xuICBpZiAoIXByZXZpb3VzUGl4ZWwpIHtcbiAgICByZXR1cm4gY3VycmVudFBpeGVsO1xuICB9XG5cbiAgaWYgKCFjdXJyZW50UGl4ZWwpIHtcbiAgICByZXR1cm4gcHJldmlvdXNQaXhlbDtcbiAgfVxuXG4gIC8vIENvbXB1dGUgYSBzY29yZSB0aGF0IHJlcHJlc2VudHMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiAyIHBpeGVsc1xuICAvL1xuICAvLyBUaGlzIG1ldGhvZCBzaW1wbHkgdGFrZXMgdGhlIEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBSR0JBIGNoYW5uZWxzXG4gIC8vIG9mIDIgY29sb3JzIG92ZXIgdGhlIG1heGltdW0gcG9zc2libGUgRXVjbGlkZWFuIGRpc3RhbmNlLiBUaGlzIGdpdmVzIHVzIGFcbiAgLy8gcGVyY2VudGFnZSBvZiBob3cgZGlmZmVyZW50IHRoZSB0d28gY29sb3JzIGFyZS5cbiAgLy9cbiAgLy8gQWx0aG91Z2ggaXQgd291bGQgYmUgbW9yZSBwZXJjZXB0dWFsbHkgYWNjdXJhdGUgdG8gY2FsY3VsYXRlIGEgcHJvcGVyXG4gIC8vIERlbHRhIEUgaW4gTGFiIGNvbG9yc3BhY2UsIHdlIHByb2JhYmx5IGRvbid0IG5lZWQgcGVyY2VwdHVhbCBhY2N1cmFjeSBmb3JcbiAgLy8gdGhpcyBhcHBsaWNhdGlvbiwgYW5kIGl0IGlzIG5pY2UgdG8gYXZvaWQgdGhlIG92ZXJoZWFkIG9mIGNvbnZlcnRpbmcgUkdCQVxuICAvLyB0byBMYWIuXG4gIGNvbnN0IGRpZmYgPSBldWNsaWRlYW5EaXN0YW5jZShwcmV2aW91c1BpeGVsLCBjdXJyZW50UGl4ZWwpIC8gTUFYX0VVQ0xJREVBTl9ESVNUQU5DRTtcblxuICBpZiAoZGlmZiA9PT0gMCkge1xuICAgIHJldHVybiBjb21wb3NlKFxuICAgICAgW2N1cnJlbnRQaXhlbFswXSwgY3VycmVudFBpeGVsWzFdLCBjdXJyZW50UGl4ZWxbMl0sIDQwXSxcbiAgICAgIFdISVRFXG4gICAgKTtcbiAgfVxuXG4gIGRlYnVnZ2VyO1xuICByZXR1cm4gY29tcG9zZShcbiAgICBbMTc5LCA1NCwgMTMwLCAyNTUgKiBNYXRoLm1heCgwLjIsIGRpZmYpXSxcbiAgICBXSElURVxuICApO1xufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9qcy9zcmMvZ2V0RGlmZlBpeGVsLmpzXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ==");
|
|
54
|
+
|
|
55
|
+
/***/ },
|
|
56
|
+
/* 2 */
|
|
57
|
+
/***/ function(module, exports) {
|
|
58
|
+
|
|
59
|
+
eval("\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = compose;\nfunction isOpaque(color) {\n return color[3] === 255;\n}\n\nfunction isFullyTransparent(color) {\n return color[3] === 0;\n}\n\n/**\n * Multiplies two fractions using integer math, where the fractions are stored\n * using an integer between 0 and 255. This method is used as a helper method\n * for compositing colors using integer math.\n *\n * This is a quicker implementation of Math.round((a * b) / 255.0)\n */\nfunction int8Mult(a, b) {\n var t = a * b + 0x80;\n return (t >> 8) + t >> 8;\n}\n\n/**\n * Composes two colors with an alpha channel using integer math.\n *\n * This version is faster than a version based on floating point math.\n */\nfunction compose(foreground, background) {\n if (isOpaque(foreground) || isFullyTransparent(background)) {\n return foreground;\n }\n\n if (isFullyTransparent(foreground)) {\n return background;\n }\n\n var aCom = int8Mult(0xff - foreground[3], background[3]);\n return [int8Mult(foreground[3], foreground[0]) + int8Mult(aCom, background[0]), int8Mult(foreground[3], foreground[1]) + int8Mult(aCom, background[1]), int8Mult(foreground[3], foreground[2]) + int8Mult(aCom, background[2]), foreground[3] + aCom];\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvY29tcG9zZS5qcz8wZWM5Il0sIm5hbWVzIjpbImNvbXBvc2UiLCJpc09wYXF1ZSIsImNvbG9yIiwiaXNGdWxseVRyYW5zcGFyZW50IiwiaW50OE11bHQiLCJhIiwiYiIsInQiLCJmb3JlZ3JvdW5kIiwiYmFja2dyb3VuZCIsImFDb20iXSwibWFwcGluZ3MiOiI7Ozs7O2tCQXlCd0JBLE87QUF6QnhCLFNBQVNDLFFBQVQsQ0FBa0JDLEtBQWxCLEVBQXlCO0FBQ3ZCLFNBQU9BLE1BQU0sQ0FBTixNQUFhLEdBQXBCO0FBQ0Q7O0FBRUQsU0FBU0Msa0JBQVQsQ0FBNEJELEtBQTVCLEVBQW1DO0FBQ2pDLFNBQU9BLE1BQU0sQ0FBTixNQUFhLENBQXBCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7QUFPQSxTQUFTRSxRQUFULENBQWtCQyxDQUFsQixFQUFxQkMsQ0FBckIsRUFBd0I7QUFDdEIsTUFBTUMsSUFBS0YsSUFBSUMsQ0FBTCxHQUFVLElBQXBCO0FBQ0EsU0FBUSxDQUFDQyxLQUFLLENBQU4sSUFBV0EsQ0FBWixJQUFrQixDQUF6QjtBQUNEOztBQUVEOzs7OztBQUtlLFNBQVNQLE9BQVQsQ0FBaUJRLFVBQWpCLEVBQTZCQyxVQUE3QixFQUF5QztBQUN0RCxNQUFJUixTQUFTTyxVQUFULEtBQXdCTCxtQkFBbUJNLFVBQW5CLENBQTVCLEVBQTREO0FBQzFELFdBQU9ELFVBQVA7QUFDRDs7QUFFRCxNQUFJTCxtQkFBbUJLLFVBQW5CLENBQUosRUFBb0M7QUFDbEMsV0FBT0MsVUFBUDtBQUNEOztBQUVELE1BQU1DLE9BQU9OLFNBQVMsT0FBT0ksV0FBVyxDQUFYLENBQWhCLEVBQStCQyxXQUFXLENBQVgsQ0FBL0IsQ0FBYjtBQUNBLFNBQU8sQ0FDTEwsU0FBU0ksV0FBVyxDQUFYLENBQVQsRUFBd0JBLFdBQVcsQ0FBWCxDQUF4QixJQUF5Q0osU0FBU00sSUFBVCxFQUFlRCxXQUFXLENBQVgsQ0FBZixDQURwQyxFQUVMTCxTQUFTSSxXQUFXLENBQVgsQ0FBVCxFQUF3QkEsV0FBVyxDQUFYLENBQXhCLElBQXlDSixTQUFTTSxJQUFULEVBQWVELFdBQVcsQ0FBWCxDQUFmLENBRnBDLEVBR0xMLFNBQVNJLFdBQVcsQ0FBWCxDQUFULEVBQXdCQSxXQUFXLENBQVgsQ0FBeEIsSUFBeUNKLFNBQVNNLElBQVQsRUFBZUQsV0FBVyxDQUFYLENBQWYsQ0FIcEMsRUFJTEQsV0FBVyxDQUFYLElBQWdCRSxJQUpYLENBQVA7QUFNRCIsImZpbGUiOiIyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gaXNPcGFxdWUoY29sb3IpIHtcbiAgcmV0dXJuIGNvbG9yWzNdID09PSAyNTU7XG59XG5cbmZ1bmN0aW9uIGlzRnVsbHlUcmFuc3BhcmVudChjb2xvcikge1xuICByZXR1cm4gY29sb3JbM10gPT09IDA7XG59XG5cbi8qKlxuICogTXVsdGlwbGllcyB0d28gZnJhY3Rpb25zIHVzaW5nIGludGVnZXIgbWF0aCwgd2hlcmUgdGhlIGZyYWN0aW9ucyBhcmUgc3RvcmVkXG4gKiB1c2luZyBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMjU1LiBUaGlzIG1ldGhvZCBpcyB1c2VkIGFzIGEgaGVscGVyIG1ldGhvZFxuICogZm9yIGNvbXBvc2l0aW5nIGNvbG9ycyB1c2luZyBpbnRlZ2VyIG1hdGguXG4gKlxuICogVGhpcyBpcyBhIHF1aWNrZXIgaW1wbGVtZW50YXRpb24gb2YgTWF0aC5yb3VuZCgoYSAqIGIpIC8gMjU1LjApXG4gKi9cbmZ1bmN0aW9uIGludDhNdWx0KGEsIGIpIHtcbiAgY29uc3QgdCA9IChhICogYikgKyAweDgwO1xuICByZXR1cm4gKCh0ID4+IDgpICsgdCkgPj4gODtcbn1cblxuLyoqXG4gKiBDb21wb3NlcyB0d28gY29sb3JzIHdpdGggYW4gYWxwaGEgY2hhbm5lbCB1c2luZyBpbnRlZ2VyIG1hdGguXG4gKlxuICogVGhpcyB2ZXJzaW9uIGlzIGZhc3RlciB0aGFuIGEgdmVyc2lvbiBiYXNlZCBvbiBmbG9hdGluZyBwb2ludCBtYXRoLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wb3NlKGZvcmVncm91bmQsIGJhY2tncm91bmQpIHtcbiAgaWYgKGlzT3BhcXVlKGZvcmVncm91bmQpIHx8IGlzRnVsbHlUcmFuc3BhcmVudChiYWNrZ3JvdW5kKSkge1xuICAgIHJldHVybiBmb3JlZ3JvdW5kO1xuICB9XG5cbiAgaWYgKGlzRnVsbHlUcmFuc3BhcmVudChmb3JlZ3JvdW5kKSkge1xuICAgIHJldHVybiBiYWNrZ3JvdW5kO1xuICB9XG5cbiAgY29uc3QgYUNvbSA9IGludDhNdWx0KDB4ZmYgLSBmb3JlZ3JvdW5kWzNdLCBiYWNrZ3JvdW5kWzNdKTtcbiAgcmV0dXJuIFtcbiAgICBpbnQ4TXVsdChmb3JlZ3JvdW5kWzNdLCBmb3JlZ3JvdW5kWzBdKSArIGludDhNdWx0KGFDb20sIGJhY2tncm91bmRbMF0pLFxuICAgIGludDhNdWx0KGZvcmVncm91bmRbM10sIGZvcmVncm91bmRbMV0pICsgaW50OE11bHQoYUNvbSwgYmFja2dyb3VuZFsxXSksXG4gICAgaW50OE11bHQoZm9yZWdyb3VuZFszXSwgZm9yZWdyb3VuZFsyXSkgKyBpbnQ4TXVsdChhQ29tLCBiYWNrZ3JvdW5kWzJdKSxcbiAgICBmb3JlZ3JvdW5kWzNdICsgYUNvbSxcbiAgXTtcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vanMvc3JjL2NvbXBvc2UuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9");
|
|
60
|
+
|
|
61
|
+
/***/ },
|
|
62
|
+
/* 3 */
|
|
63
|
+
/***/ function(module, exports) {
|
|
64
|
+
|
|
65
|
+
eval("\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = euclideanDistance;\nfunction euclideanDistance(rgba1, rgba2) {\n return Math.sqrt(Math.pow(rgba1[0] - rgba2[0], 2) + Math.pow(rgba1[1] - rgba2[1], 2) + Math.pow(rgba1[2] - rgba2[2], 2) + Math.pow(rgba1[3] - rgba2[3], 2));\n}\n\nvar MAX_EUCLIDEAN_DISTANCE = exports.MAX_EUCLIDEAN_DISTANCE = Math.sqrt(Math.pow(255, 2) * 4);//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9zcmMvZXVjbGlkZWFuRGlzdGFuY2UuanM/ZDgzYiJdLCJuYW1lcyI6WyJldWNsaWRlYW5EaXN0YW5jZSIsInJnYmExIiwicmdiYTIiLCJNYXRoIiwic3FydCIsInBvdyIsIk1BWF9FVUNMSURFQU5fRElTVEFOQ0UiXSwibWFwcGluZ3MiOiI7Ozs7O2tCQUF3QkEsaUI7QUFBVCxTQUFTQSxpQkFBVCxDQUEyQkMsS0FBM0IsRUFBa0NDLEtBQWxDLEVBQXlDO0FBQ3RELFNBQU9DLEtBQUtDLElBQUwsQ0FDTEQsS0FBS0UsR0FBTCxDQUFTSixNQUFNLENBQU4sSUFBV0MsTUFBTSxDQUFOLENBQXBCLEVBQThCLENBQTlCLElBQ0VDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQURGLEdBRUVDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQUZGLEdBR0VDLEtBQUtFLEdBQUwsQ0FBU0osTUFBTSxDQUFOLElBQVdDLE1BQU0sQ0FBTixDQUFwQixFQUE4QixDQUE5QixDQUpHLENBQVA7QUFNRDs7QUFFTSxJQUFNSSwwREFBeUJILEtBQUtDLElBQUwsQ0FBVUQsS0FBS0UsR0FBTCxDQUFTLEdBQVQsRUFBYyxDQUFkLElBQW1CLENBQTdCLENBQS9CIiwiZmlsZSI6IjMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBldWNsaWRlYW5EaXN0YW5jZShyZ2JhMSwgcmdiYTIpIHtcbiAgcmV0dXJuIE1hdGguc3FydChcbiAgICBNYXRoLnBvdyhyZ2JhMVswXSAtIHJnYmEyWzBdLCAyKVxuICAgICsgTWF0aC5wb3cocmdiYTFbMV0gLSByZ2JhMlsxXSwgMilcbiAgICArIE1hdGgucG93KHJnYmExWzJdIC0gcmdiYTJbMl0sIDIpXG4gICAgKyBNYXRoLnBvdyhyZ2JhMVszXSAtIHJnYmEyWzNdLCAyKVxuICApO1xufVxuXG5leHBvcnQgY29uc3QgTUFYX0VVQ0xJREVBTl9ESVNUQU5DRSA9IE1hdGguc3FydChNYXRoLnBvdygyNTUsIDIpICogNCk7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2pzL3NyYy9ldWNsaWRlYW5EaXN0YW5jZS5qc1xuICoqLyJdLCJzb3VyY2VSb290IjoiIn0=");
|
|
66
|
+
|
|
67
|
+
/***/ }
|
|
68
|
+
/******/ ]);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -55,8 +55,13 @@ body {
|
|
|
55
55
|
padding: 20px 10px 15px;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.HappoDiffs__header >
|
|
58
|
+
.HappoDiffs__header > * {
|
|
59
59
|
margin-right: 10px;
|
|
60
|
+
margin-bottom: 5px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.HappoDiffs__header > :last-child {
|
|
64
|
+
margin-right: 0;
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
.HappoDiffs__headerTitle {
|
|
@@ -67,8 +72,11 @@ body {
|
|
|
67
72
|
padding: 10px;
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
.Diff__images
|
|
75
|
+
.Diff__images,
|
|
76
|
+
.NewImage__image {
|
|
71
77
|
white-space: nowrap;
|
|
78
|
+
max-width: 100%;
|
|
79
|
+
overflow-x: auto;
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
.Diff__buttons {
|
|
@@ -79,7 +87,8 @@ body {
|
|
|
79
87
|
border: 1px solid #ccc;
|
|
80
88
|
border-left-width: 0;
|
|
81
89
|
background-color: #f0f0f0;
|
|
82
|
-
padding:
|
|
90
|
+
padding: 10px 20px;
|
|
91
|
+
cursor: pointer;
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
.Diff__button[aria-pressed="true"] {
|
|
@@ -125,3 +134,19 @@ body {
|
|
|
125
134
|
.SideBySide__image {
|
|
126
135
|
vertical-align: top;
|
|
127
136
|
}
|
|
137
|
+
|
|
138
|
+
.SmoothProgress {
|
|
139
|
+
overflow: hidden;
|
|
140
|
+
height: 10px;
|
|
141
|
+
width: 100%;
|
|
142
|
+
border: 1px solid #cccccc;
|
|
143
|
+
border-radius: 5px;
|
|
144
|
+
transition: opacity 1s;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.SmoothProgress__bar {
|
|
148
|
+
background-color: rgba(179, 54, 130, .5);
|
|
149
|
+
height: 100%;
|
|
150
|
+
width: 100%;
|
|
151
|
+
transition: transform 1s ease-in-out;
|
|
152
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/happo/runner.rb
CHANGED
|
@@ -152,52 +152,45 @@ begin
|
|
|
152
152
|
# 1. Delete previous.png if it exists.
|
|
153
153
|
# 2. Compare the current snapshot in memory against current.png if it
|
|
154
154
|
# exists.
|
|
155
|
-
# 3. If there is a diff, move current.png to previous.png
|
|
156
|
-
# diff.png to disk and the current snapshot to current.png.
|
|
155
|
+
# 3. If there is a diff, move current.png to previous.png
|
|
157
156
|
# 4. If there is no diff, return, leaving the old current.png in place.
|
|
158
157
|
previous_image_path = Happo::Utils.path_to(
|
|
159
|
-
description, viewport['name'], 'previous.png'
|
|
158
|
+
description, viewport['name'], 'previous.png'
|
|
159
|
+
)
|
|
160
160
|
current_image_path = Happo::Utils.path_to(
|
|
161
|
-
description, viewport['name'], 'current.png'
|
|
162
|
-
|
|
163
|
-
description, viewport['name'], 'diff.png')
|
|
161
|
+
description, viewport['name'], 'current.png'
|
|
162
|
+
)
|
|
164
163
|
|
|
165
|
-
# We no longer need the old previous.png
|
|
166
|
-
#
|
|
164
|
+
# We no longer need the old previous.png so lets remove it to keep things
|
|
165
|
+
# clean.
|
|
167
166
|
File.delete previous_image_path if File.exist? previous_image_path
|
|
168
|
-
File.delete diff_image_path if File.exist? diff_image_path
|
|
169
167
|
|
|
170
168
|
if File.exist? current_image_path
|
|
171
|
-
|
|
172
|
-
ChunkyPNG::Image.from_file(current_image_path),
|
|
173
|
-
screenshot
|
|
174
|
-
).compare!
|
|
169
|
+
current_image = ChunkyPNG::Image.from_file(current_image_path)
|
|
175
170
|
log.log '.', false
|
|
176
171
|
|
|
177
|
-
if
|
|
172
|
+
if current_image.eql?(screenshot)
|
|
173
|
+
# No visual difference was found, so we don't need to do any more
|
|
174
|
+
# work.
|
|
175
|
+
log.log ' No diff.'
|
|
176
|
+
result_summary[:okay_examples] << {
|
|
177
|
+
description: description,
|
|
178
|
+
viewport: viewport['name'],
|
|
179
|
+
height: current_image.height,
|
|
180
|
+
}
|
|
181
|
+
else
|
|
178
182
|
# There was a visual difference between the new snapshot and the
|
|
179
|
-
# previous, so we want to write the
|
|
180
|
-
#
|
|
181
|
-
comparison[:diff_image].save(diff_image_path, :fast_rgba)
|
|
182
|
-
log.log '.', false
|
|
183
|
-
|
|
183
|
+
# previous, so we want to write the new snapshot image to disk. This
|
|
184
|
+
# will allow it to be reviewed by someone.
|
|
184
185
|
File.rename(current_image_path, previous_image_path)
|
|
185
186
|
screenshot.save(current_image_path, :fast_rgba)
|
|
186
187
|
log.log '.', false
|
|
187
188
|
|
|
188
|
-
|
|
189
|
-
log.log log.cyan(" #{percent}% (#{current_image_path})")
|
|
189
|
+
log.log log.cyan(" DIFF (#{current_image_path})")
|
|
190
190
|
result_summary[:diff_examples] << {
|
|
191
191
|
description: description,
|
|
192
|
-
viewport: viewport['name']
|
|
193
|
-
|
|
194
|
-
else
|
|
195
|
-
# No visual difference was found, so we don't need to do any more
|
|
196
|
-
# work.
|
|
197
|
-
log.log ' No diff.'
|
|
198
|
-
result_summary[:okay_examples] << {
|
|
199
|
-
description: description,
|
|
200
|
-
viewport: viewport['name']
|
|
192
|
+
viewport: viewport['name'],
|
|
193
|
+
height: [screenshot.height, current_image.height].max,
|
|
201
194
|
}
|
|
202
195
|
end
|
|
203
196
|
else
|
|
@@ -212,7 +205,8 @@ begin
|
|
|
212
205
|
log.log " First snapshot created (#{current_image_path})"
|
|
213
206
|
result_summary[:new_examples] << {
|
|
214
207
|
description: description,
|
|
215
|
-
viewport: viewport['name']
|
|
208
|
+
viewport: viewport['name'],
|
|
209
|
+
height: screenshot.height,
|
|
216
210
|
}
|
|
217
211
|
end
|
|
218
212
|
end
|