UNPKG

79.6 kBJavaScriptView Raw
1import dmp from 'diff-match-patch';
2import chalk from 'chalk';
3
4var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
5 return typeof obj;
6} : function (obj) {
7 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
8};
9
10
11
12
13
14
15
16
17
18
19
20var classCallCheck = function (instance, Constructor) {
21 if (!(instance instanceof Constructor)) {
22 throw new TypeError("Cannot call a class as a function");
23 }
24};
25
26var createClass = function () {
27 function defineProperties(target, props) {
28 for (var i = 0; i < props.length; i++) {
29 var descriptor = props[i];
30 descriptor.enumerable = descriptor.enumerable || false;
31 descriptor.configurable = true;
32 if ("value" in descriptor) descriptor.writable = true;
33 Object.defineProperty(target, descriptor.key, descriptor);
34 }
35 }
36
37 return function (Constructor, protoProps, staticProps) {
38 if (protoProps) defineProperties(Constructor.prototype, protoProps);
39 if (staticProps) defineProperties(Constructor, staticProps);
40 return Constructor;
41 };
42}();
43
44
45
46
47
48
49
50var get = function get(object, property, receiver) {
51 if (object === null) object = Function.prototype;
52 var desc = Object.getOwnPropertyDescriptor(object, property);
53
54 if (desc === undefined) {
55 var parent = Object.getPrototypeOf(object);
56
57 if (parent === null) {
58 return undefined;
59 } else {
60 return get(parent, property, receiver);
61 }
62 } else if ("value" in desc) {
63 return desc.value;
64 } else {
65 var getter = desc.get;
66
67 if (getter === undefined) {
68 return undefined;
69 }
70
71 return getter.call(receiver);
72 }
73};
74
75var inherits = function (subClass, superClass) {
76 if (typeof superClass !== "function" && superClass !== null) {
77 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
78 }
79
80 subClass.prototype = Object.create(superClass && superClass.prototype, {
81 constructor: {
82 value: subClass,
83 enumerable: false,
84 writable: true,
85 configurable: true
86 }
87 });
88 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
89};
90
91
92
93
94
95
96
97
98
99
100
101var possibleConstructorReturn = function (self, call) {
102 if (!self) {
103 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
104 }
105
106 return call && (typeof call === "object" || typeof call === "function") ? call : self;
107};
108
109
110
111
112
113var slicedToArray = function () {
114 function sliceIterator(arr, i) {
115 var _arr = [];
116 var _n = true;
117 var _d = false;
118 var _e = undefined;
119
120 try {
121 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
122 _arr.push(_s.value);
123
124 if (i && _arr.length === i) break;
125 }
126 } catch (err) {
127 _d = true;
128 _e = err;
129 } finally {
130 try {
131 if (!_n && _i["return"]) _i["return"]();
132 } finally {
133 if (_d) throw _e;
134 }
135 }
136
137 return _arr;
138 }
139
140 return function (arr, i) {
141 if (Array.isArray(arr)) {
142 return arr;
143 } else if (Symbol.iterator in Object(arr)) {
144 return sliceIterator(arr, i);
145 } else {
146 throw new TypeError("Invalid attempt to destructure non-iterable instance");
147 }
148 };
149}();
150
151var Processor = function () {
152 function Processor(options) {
153 classCallCheck(this, Processor);
154
155 this.selfOptions = options || {};
156 this.pipes = {};
157 }
158
159 createClass(Processor, [{
160 key: 'options',
161 value: function options(_options) {
162 if (_options) {
163 this.selfOptions = _options;
164 }
165 return this.selfOptions;
166 }
167 }, {
168 key: 'pipe',
169 value: function pipe(name, pipeArg) {
170 var pipe = pipeArg;
171 if (typeof name === 'string') {
172 if (typeof pipe === 'undefined') {
173 return this.pipes[name];
174 } else {
175 this.pipes[name] = pipe;
176 }
177 }
178 if (name && name.name) {
179 pipe = name;
180 if (pipe.processor === this) {
181 return pipe;
182 }
183 this.pipes[pipe.name] = pipe;
184 }
185 pipe.processor = this;
186 return pipe;
187 }
188 }, {
189 key: 'process',
190 value: function process(input, pipe) {
191 var context = input;
192 context.options = this.options();
193 var nextPipe = pipe || input.pipe || 'default';
194 var lastPipe = void 0;
195 var lastContext = void 0;
196 while (nextPipe) {
197 if (typeof context.nextAfterChildren !== 'undefined') {
198 // children processed and coming back to parent
199 context.next = context.nextAfterChildren;
200 context.nextAfterChildren = null;
201 }
202
203 if (typeof nextPipe === 'string') {
204 nextPipe = this.pipe(nextPipe);
205 }
206 nextPipe.process(context);
207 lastContext = context;
208 lastPipe = nextPipe;
209 nextPipe = null;
210 if (context) {
211 if (context.next) {
212 context = context.next;
213 nextPipe = lastContext.nextPipe || context.pipe || lastPipe;
214 }
215 }
216 }
217 return context.hasResult ? context.result : undefined;
218 }
219 }]);
220 return Processor;
221}();
222
223var Pipe = function () {
224 function Pipe(name) {
225 classCallCheck(this, Pipe);
226
227 this.name = name;
228 this.filters = [];
229 }
230
231 createClass(Pipe, [{
232 key: 'process',
233 value: function process(input) {
234 if (!this.processor) {
235 throw new Error('add this pipe to a processor before using it');
236 }
237 var debug = this.debug;
238 var length = this.filters.length;
239 var context = input;
240 for (var index = 0; index < length; index++) {
241 var filter = this.filters[index];
242 if (debug) {
243 this.log('filter: ' + filter.filterName);
244 }
245 filter(context);
246 if ((typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' && context.exiting) {
247 context.exiting = false;
248 break;
249 }
250 }
251 if (!context.next && this.resultCheck) {
252 this.resultCheck(context);
253 }
254 }
255 }, {
256 key: 'log',
257 value: function log(msg) {
258 console.log('[jsondiffpatch] ' + this.name + ' pipe, ' + msg);
259 }
260 }, {
261 key: 'append',
262 value: function append() {
263 var _filters;
264
265 (_filters = this.filters).push.apply(_filters, arguments);
266 return this;
267 }
268 }, {
269 key: 'prepend',
270 value: function prepend() {
271 var _filters2;
272
273 (_filters2 = this.filters).unshift.apply(_filters2, arguments);
274 return this;
275 }
276 }, {
277 key: 'indexOf',
278 value: function indexOf(filterName) {
279 if (!filterName) {
280 throw new Error('a filter name is required');
281 }
282 for (var index = 0; index < this.filters.length; index++) {
283 var filter = this.filters[index];
284 if (filter.filterName === filterName) {
285 return index;
286 }
287 }
288 throw new Error('filter not found: ' + filterName);
289 }
290 }, {
291 key: 'list',
292 value: function list() {
293 var names = [];
294
295 var _iteratorNormalCompletion = true;
296 var _didIteratorError = false;
297 var _iteratorError = undefined;
298
299 try {
300 for (var _iterator = this.filters[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
301 var filter = _step.value;
302
303 names.push(filter.filterName);
304 }
305 } catch (err) {
306 _didIteratorError = true;
307 _iteratorError = err;
308 } finally {
309 try {
310 if (!_iteratorNormalCompletion && _iterator.return) {
311 _iterator.return();
312 }
313 } finally {
314 if (_didIteratorError) {
315 throw _iteratorError;
316 }
317 }
318 }
319
320 return names;
321 }
322 }, {
323 key: 'after',
324 value: function after(filterName) {
325 var index = this.indexOf(filterName);
326 var params = Array.prototype.slice.call(arguments, 1);
327 if (!params.length) {
328 throw new Error('a filter is required');
329 }
330 params.unshift(index + 1, 0);
331 Array.prototype.splice.apply(this.filters, params);
332 return this;
333 }
334 }, {
335 key: 'before',
336 value: function before(filterName) {
337 var index = this.indexOf(filterName);
338 var params = Array.prototype.slice.call(arguments, 1);
339 if (!params.length) {
340 throw new Error('a filter is required');
341 }
342 params.unshift(index, 0);
343 Array.prototype.splice.apply(this.filters, params);
344 return this;
345 }
346 }, {
347 key: 'replace',
348 value: function replace(filterName) {
349 var index = this.indexOf(filterName);
350 var params = Array.prototype.slice.call(arguments, 1);
351 if (!params.length) {
352 throw new Error('a filter is required');
353 }
354 params.unshift(index, 1);
355 Array.prototype.splice.apply(this.filters, params);
356 return this;
357 }
358 }, {
359 key: 'remove',
360 value: function remove(filterName) {
361 var index = this.indexOf(filterName);
362 this.filters.splice(index, 1);
363 return this;
364 }
365 }, {
366 key: 'clear',
367 value: function clear() {
368 this.filters.length = 0;
369 return this;
370 }
371 }, {
372 key: 'shouldHaveResult',
373 value: function shouldHaveResult(should) {
374 if (should === false) {
375 this.resultCheck = null;
376 return;
377 }
378 if (this.resultCheck) {
379 return;
380 }
381 var pipe = this;
382 this.resultCheck = function (context) {
383 if (!context.hasResult) {
384 console.log(context);
385 var error = new Error(pipe.name + ' failed');
386 error.noResult = true;
387 throw error;
388 }
389 };
390 return this;
391 }
392 }]);
393 return Pipe;
394}();
395
396var Context = function () {
397 function Context() {
398 classCallCheck(this, Context);
399 }
400
401 createClass(Context, [{
402 key: 'setResult',
403 value: function setResult(result) {
404 this.result = result;
405 this.hasResult = true;
406 return this;
407 }
408 }, {
409 key: 'exit',
410 value: function exit() {
411 this.exiting = true;
412 return this;
413 }
414 }, {
415 key: 'switchTo',
416 value: function switchTo(next, pipe) {
417 if (typeof next === 'string' || next instanceof Pipe) {
418 this.nextPipe = next;
419 } else {
420 this.next = next;
421 if (pipe) {
422 this.nextPipe = pipe;
423 }
424 }
425 return this;
426 }
427 }, {
428 key: 'push',
429 value: function push(child, name) {
430 child.parent = this;
431 if (typeof name !== 'undefined') {
432 child.childName = name;
433 }
434 child.root = this.root || this;
435 child.options = child.options || this.options;
436 if (!this.children) {
437 this.children = [child];
438 this.nextAfterChildren = this.next || null;
439 this.next = child;
440 } else {
441 this.children[this.children.length - 1].next = child;
442 this.children.push(child);
443 }
444 child.next = this;
445 return this;
446 }
447 }]);
448 return Context;
449}();
450
451var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
452 return a instanceof Array;
453};
454
455function cloneRegExp(re) {
456 var regexMatch = /^\/(.*)\/([gimyu]*)$/.exec(re.toString());
457 return new RegExp(regexMatch[1], regexMatch[2]);
458}
459
460function clone(arg) {
461 if ((typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) !== 'object') {
462 return arg;
463 }
464 if (arg === null) {
465 return null;
466 }
467 if (isArray(arg)) {
468 return arg.map(clone);
469 }
470 if (arg instanceof Date) {
471 return new Date(arg.getTime());
472 }
473 if (arg instanceof RegExp) {
474 return cloneRegExp(arg);
475 }
476 var cloned = {};
477 for (var name in arg) {
478 if (Object.prototype.hasOwnProperty.call(arg, name)) {
479 cloned[name] = clone(arg[name]);
480 }
481 }
482 return cloned;
483}
484
485var DiffContext = function (_Context) {
486 inherits(DiffContext, _Context);
487
488 function DiffContext(left, right) {
489 classCallCheck(this, DiffContext);
490
491 var _this = possibleConstructorReturn(this, (DiffContext.__proto__ || Object.getPrototypeOf(DiffContext)).call(this));
492
493 _this.left = left;
494 _this.right = right;
495 _this.pipe = 'diff';
496 return _this;
497 }
498
499 createClass(DiffContext, [{
500 key: 'setResult',
501 value: function setResult(result) {
502 if (this.options.cloneDiffValues && (typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object') {
503 var clone$$1 = typeof this.options.cloneDiffValues === 'function' ? this.options.cloneDiffValues : clone;
504 if (_typeof(result[0]) === 'object') {
505 result[0] = clone$$1(result[0]);
506 }
507 if (_typeof(result[1]) === 'object') {
508 result[1] = clone$$1(result[1]);
509 }
510 }
511 return Context.prototype.setResult.apply(this, arguments);
512 }
513 }]);
514 return DiffContext;
515}(Context);
516
517var PatchContext = function (_Context) {
518 inherits(PatchContext, _Context);
519
520 function PatchContext(left, delta) {
521 classCallCheck(this, PatchContext);
522
523 var _this = possibleConstructorReturn(this, (PatchContext.__proto__ || Object.getPrototypeOf(PatchContext)).call(this));
524
525 _this.left = left;
526 _this.delta = delta;
527 _this.pipe = 'patch';
528 return _this;
529 }
530
531 return PatchContext;
532}(Context);
533
534var ReverseContext = function (_Context) {
535 inherits(ReverseContext, _Context);
536
537 function ReverseContext(delta) {
538 classCallCheck(this, ReverseContext);
539
540 var _this = possibleConstructorReturn(this, (ReverseContext.__proto__ || Object.getPrototypeOf(ReverseContext)).call(this));
541
542 _this.delta = delta;
543 _this.pipe = 'reverse';
544 return _this;
545 }
546
547 return ReverseContext;
548}(Context);
549
550var isArray$1 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
551 return a instanceof Array;
552};
553
554var diffFilter = function trivialMatchesDiffFilter(context) {
555 if (context.left === context.right) {
556 context.setResult(undefined).exit();
557 return;
558 }
559 if (typeof context.left === 'undefined') {
560 if (typeof context.right === 'function') {
561 throw new Error('functions are not supported');
562 }
563 context.setResult([context.right]).exit();
564 return;
565 }
566 if (typeof context.right === 'undefined') {
567 context.setResult([context.left, 0, 0]).exit();
568 return;
569 }
570 if (typeof context.left === 'function' || typeof context.right === 'function') {
571 throw new Error('functions are not supported');
572 }
573 context.leftType = context.left === null ? 'null' : _typeof(context.left);
574 context.rightType = context.right === null ? 'null' : _typeof(context.right);
575 if (context.leftType !== context.rightType) {
576 context.setResult([context.left, context.right]).exit();
577 return;
578 }
579 if (context.leftType === 'boolean' || context.leftType === 'number') {
580 context.setResult([context.left, context.right]).exit();
581 return;
582 }
583 if (context.leftType === 'object') {
584 context.leftIsArray = isArray$1(context.left);
585 }
586 if (context.rightType === 'object') {
587 context.rightIsArray = isArray$1(context.right);
588 }
589 if (context.leftIsArray !== context.rightIsArray) {
590 context.setResult([context.left, context.right]).exit();
591 return;
592 }
593
594 if (context.left instanceof RegExp) {
595 if (context.right instanceof RegExp) {
596 context.setResult([context.left.toString(), context.right.toString()]).exit();
597 } else {
598 context.setResult([context.left, context.right]).exit();
599 }
600 }
601};
602diffFilter.filterName = 'trivial';
603
604var patchFilter = function trivialMatchesPatchFilter(context) {
605 if (typeof context.delta === 'undefined') {
606 context.setResult(context.left).exit();
607 return;
608 }
609 context.nested = !isArray$1(context.delta);
610 if (context.nested) {
611 return;
612 }
613 if (context.delta.length === 1) {
614 context.setResult(context.delta[0]).exit();
615 return;
616 }
617 if (context.delta.length === 2) {
618 if (context.left instanceof RegExp) {
619 var regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]);
620 if (regexArgs) {
621 context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit();
622 return;
623 }
624 }
625 context.setResult(context.delta[1]).exit();
626 return;
627 }
628 if (context.delta.length === 3 && context.delta[2] === 0) {
629 context.setResult(undefined).exit();
630 }
631};
632patchFilter.filterName = 'trivial';
633
634var reverseFilter = function trivialReferseFilter(context) {
635 if (typeof context.delta === 'undefined') {
636 context.setResult(context.delta).exit();
637 return;
638 }
639 context.nested = !isArray$1(context.delta);
640 if (context.nested) {
641 return;
642 }
643 if (context.delta.length === 1) {
644 context.setResult([context.delta[0], 0, 0]).exit();
645 return;
646 }
647 if (context.delta.length === 2) {
648 context.setResult([context.delta[1], context.delta[0]]).exit();
649 return;
650 }
651 if (context.delta.length === 3 && context.delta[2] === 0) {
652 context.setResult([context.delta[0]]).exit();
653 }
654};
655reverseFilter.filterName = 'trivial';
656
657function collectChildrenDiffFilter(context) {
658 if (!context || !context.children) {
659 return;
660 }
661 var length = context.children.length;
662 var child = void 0;
663 var result = context.result;
664 for (var index = 0; index < length; index++) {
665 child = context.children[index];
666 if (typeof child.result === 'undefined') {
667 continue;
668 }
669 result = result || {};
670 result[child.childName] = child.result;
671 }
672 if (result && context.leftIsArray) {
673 result._t = 'a';
674 }
675 context.setResult(result).exit();
676}
677collectChildrenDiffFilter.filterName = 'collectChildren';
678
679function objectsDiffFilter(context) {
680 if (context.leftIsArray || context.leftType !== 'object') {
681 return;
682 }
683
684 var name = void 0;
685 var child = void 0;
686 var propertyFilter = context.options.propertyFilter;
687 for (name in context.left) {
688 if (!Object.prototype.hasOwnProperty.call(context.left, name)) {
689 continue;
690 }
691 if (propertyFilter && !propertyFilter(name, context)) {
692 continue;
693 }
694 child = new DiffContext(context.left[name], context.right[name]);
695 context.push(child, name);
696 }
697 for (name in context.right) {
698 if (!Object.prototype.hasOwnProperty.call(context.right, name)) {
699 continue;
700 }
701 if (propertyFilter && !propertyFilter(name, context)) {
702 continue;
703 }
704 if (typeof context.left[name] === 'undefined') {
705 child = new DiffContext(undefined, context.right[name]);
706 context.push(child, name);
707 }
708 }
709
710 if (!context.children || context.children.length === 0) {
711 context.setResult(undefined).exit();
712 return;
713 }
714 context.exit();
715}
716objectsDiffFilter.filterName = 'objects';
717
718var patchFilter$1 = function nestedPatchFilter(context) {
719 if (!context.nested) {
720 return;
721 }
722 if (context.delta._t) {
723 return;
724 }
725 var name = void 0;
726 var child = void 0;
727 for (name in context.delta) {
728 child = new PatchContext(context.left[name], context.delta[name]);
729 context.push(child, name);
730 }
731 context.exit();
732};
733patchFilter$1.filterName = 'objects';
734
735var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
736 if (!context || !context.children) {
737 return;
738 }
739 if (context.delta._t) {
740 return;
741 }
742 var length = context.children.length;
743 var child = void 0;
744 for (var index = 0; index < length; index++) {
745 child = context.children[index];
746 if (Object.prototype.hasOwnProperty.call(context.left, child.childName) && child.result === undefined) {
747 delete context.left[child.childName];
748 } else if (context.left[child.childName] !== child.result) {
749 context.left[child.childName] = child.result;
750 }
751 }
752 context.setResult(context.left).exit();
753};
754collectChildrenPatchFilter.filterName = 'collectChildren';
755
756var reverseFilter$1 = function nestedReverseFilter(context) {
757 if (!context.nested) {
758 return;
759 }
760 if (context.delta._t) {
761 return;
762 }
763 var name = void 0;
764 var child = void 0;
765 for (name in context.delta) {
766 child = new ReverseContext(context.delta[name]);
767 context.push(child, name);
768 }
769 context.exit();
770};
771reverseFilter$1.filterName = 'objects';
772
773function collectChildrenReverseFilter(context) {
774 if (!context || !context.children) {
775 return;
776 }
777 if (context.delta._t) {
778 return;
779 }
780 var length = context.children.length;
781 var child = void 0;
782 var delta = {};
783 for (var index = 0; index < length; index++) {
784 child = context.children[index];
785 if (delta[child.childName] !== child.result) {
786 delta[child.childName] = child.result;
787 }
788 }
789 context.setResult(delta).exit();
790}
791collectChildrenReverseFilter.filterName = 'collectChildren';
792
793/*
794
795LCS implementation that supports arrays or strings
796
797reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
798
799*/
800
801var defaultMatch = function defaultMatch(array1, array2, index1, index2) {
802 return array1[index1] === array2[index2];
803};
804
805var lengthMatrix = function lengthMatrix(array1, array2, match, context) {
806 var len1 = array1.length;
807 var len2 = array2.length;
808 var x = void 0,
809 y = void 0;
810
811 // initialize empty matrix of len1+1 x len2+1
812 var matrix = [len1 + 1];
813 for (x = 0; x < len1 + 1; x++) {
814 matrix[x] = [len2 + 1];
815 for (y = 0; y < len2 + 1; y++) {
816 matrix[x][y] = 0;
817 }
818 }
819 matrix.match = match;
820 // save sequence lengths for each coordinate
821 for (x = 1; x < len1 + 1; x++) {
822 for (y = 1; y < len2 + 1; y++) {
823 if (match(array1, array2, x - 1, y - 1, context)) {
824 matrix[x][y] = matrix[x - 1][y - 1] + 1;
825 } else {
826 matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
827 }
828 }
829 }
830 return matrix;
831};
832
833var backtrack = function backtrack(matrix, array1, array2, index1, index2, context) {
834 if (index1 === 0 || index2 === 0) {
835 return {
836 sequence: [],
837 indices1: [],
838 indices2: []
839 };
840 }
841
842 if (matrix.match(array1, array2, index1 - 1, index2 - 1, context)) {
843 var subsequence = backtrack(matrix, array1, array2, index1 - 1, index2 - 1, context);
844 subsequence.sequence.push(array1[index1 - 1]);
845 subsequence.indices1.push(index1 - 1);
846 subsequence.indices2.push(index2 - 1);
847 return subsequence;
848 }
849
850 if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) {
851 return backtrack(matrix, array1, array2, index1, index2 - 1, context);
852 } else {
853 return backtrack(matrix, array1, array2, index1 - 1, index2, context);
854 }
855};
856
857var get$1 = function get(array1, array2, match, context) {
858 var innerContext = context || {};
859 var matrix = lengthMatrix(array1, array2, match || defaultMatch, innerContext);
860 var result = backtrack(matrix, array1, array2, array1.length, array2.length, innerContext);
861 if (typeof array1 === 'string' && typeof array2 === 'string') {
862 result.sequence = result.sequence.join('');
863 }
864 return result;
865};
866
867var lcs = {
868 get: get$1
869};
870
871var ARRAY_MOVE = 3;
872
873var isArray$2 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
874 return a instanceof Array;
875};
876
877var arrayIndexOf = typeof Array.prototype.indexOf === 'function' ? function (array, item) {
878 return array.indexOf(item);
879} : function (array, item) {
880 var length = array.length;
881 for (var i = 0; i < length; i++) {
882 if (array[i] === item) {
883 return i;
884 }
885 }
886 return -1;
887};
888
889function arraysHaveMatchByRef(array1, array2, len1, len2) {
890 for (var index1 = 0; index1 < len1; index1++) {
891 var val1 = array1[index1];
892 for (var index2 = 0; index2 < len2; index2++) {
893 var val2 = array2[index2];
894 if (index1 !== index2 && val1 === val2) {
895 return true;
896 }
897 }
898 }
899}
900
901function matchItems(array1, array2, index1, index2, context) {
902 var value1 = array1[index1];
903 var value2 = array2[index2];
904 if (value1 === value2) {
905 return true;
906 }
907 if ((typeof value1 === 'undefined' ? 'undefined' : _typeof(value1)) !== 'object' || (typeof value2 === 'undefined' ? 'undefined' : _typeof(value2)) !== 'object') {
908 return false;
909 }
910 var objectHash = context.objectHash;
911 if (!objectHash) {
912 // no way to match objects was provided, try match by position
913 return context.matchByPosition && index1 === index2;
914 }
915 var hash1 = void 0;
916 var hash2 = void 0;
917 if (typeof index1 === 'number') {
918 context.hashCache1 = context.hashCache1 || [];
919 hash1 = context.hashCache1[index1];
920 if (typeof hash1 === 'undefined') {
921 context.hashCache1[index1] = hash1 = objectHash(value1, index1);
922 }
923 } else {
924 hash1 = objectHash(value1);
925 }
926 if (typeof hash1 === 'undefined') {
927 return false;
928 }
929 if (typeof index2 === 'number') {
930 context.hashCache2 = context.hashCache2 || [];
931 hash2 = context.hashCache2[index2];
932 if (typeof hash2 === 'undefined') {
933 context.hashCache2[index2] = hash2 = objectHash(value2, index2);
934 }
935 } else {
936 hash2 = objectHash(value2);
937 }
938 if (typeof hash2 === 'undefined') {
939 return false;
940 }
941 return hash1 === hash2;
942}
943
944var diffFilter$1 = function arraysDiffFilter(context) {
945 if (!context.leftIsArray) {
946 return;
947 }
948
949 var matchContext = {
950 objectHash: context.options && context.options.objectHash,
951 matchByPosition: context.options && context.options.matchByPosition
952 };
953 var commonHead = 0;
954 var commonTail = 0;
955 var index = void 0;
956 var index1 = void 0;
957 var index2 = void 0;
958 var array1 = context.left;
959 var array2 = context.right;
960 var len1 = array1.length;
961 var len2 = array2.length;
962
963 var child = void 0;
964
965 if (len1 > 0 && len2 > 0 && !matchContext.objectHash && typeof matchContext.matchByPosition !== 'boolean') {
966 matchContext.matchByPosition = !arraysHaveMatchByRef(array1, array2, len1, len2);
967 }
968
969 // separate common head
970 while (commonHead < len1 && commonHead < len2 && matchItems(array1, array2, commonHead, commonHead, matchContext)) {
971 index = commonHead;
972 child = new DiffContext(context.left[index], context.right[index]);
973 context.push(child, index);
974 commonHead++;
975 }
976 // separate common tail
977 while (commonTail + commonHead < len1 && commonTail + commonHead < len2 && matchItems(array1, array2, len1 - 1 - commonTail, len2 - 1 - commonTail, matchContext)) {
978 index1 = len1 - 1 - commonTail;
979 index2 = len2 - 1 - commonTail;
980 child = new DiffContext(context.left[index1], context.right[index2]);
981 context.push(child, index2);
982 commonTail++;
983 }
984 var result = void 0;
985 if (commonHead + commonTail === len1) {
986 if (len1 === len2) {
987 // arrays are identical
988 context.setResult(undefined).exit();
989 return;
990 }
991 // trivial case, a block (1 or more consecutive items) was added
992 result = result || {
993 _t: 'a'
994 };
995 for (index = commonHead; index < len2 - commonTail; index++) {
996 result[index] = [array2[index]];
997 }
998 context.setResult(result).exit();
999 return;
1000 }
1001 if (commonHead + commonTail === len2) {
1002 // trivial case, a block (1 or more consecutive items) was removed
1003 result = result || {
1004 _t: 'a'
1005 };
1006 for (index = commonHead; index < len1 - commonTail; index++) {
1007 result['_' + index] = [array1[index], 0, 0];
1008 }
1009 context.setResult(result).exit();
1010 return;
1011 }
1012 // reset hash cache
1013 delete matchContext.hashCache1;
1014 delete matchContext.hashCache2;
1015
1016 // diff is not trivial, find the LCS (Longest Common Subsequence)
1017 var trimmed1 = array1.slice(commonHead, len1 - commonTail);
1018 var trimmed2 = array2.slice(commonHead, len2 - commonTail);
1019 var seq = lcs.get(trimmed1, trimmed2, matchItems, matchContext);
1020 var removedItems = [];
1021 result = result || {
1022 _t: 'a'
1023 };
1024 for (index = commonHead; index < len1 - commonTail; index++) {
1025 if (arrayIndexOf(seq.indices1, index - commonHead) < 0) {
1026 // removed
1027 result['_' + index] = [array1[index], 0, 0];
1028 removedItems.push(index);
1029 }
1030 }
1031
1032 var detectMove = true;
1033 if (context.options && context.options.arrays && context.options.arrays.detectMove === false) {
1034 detectMove = false;
1035 }
1036 var includeValueOnMove = false;
1037 if (context.options && context.options.arrays && context.options.arrays.includeValueOnMove) {
1038 includeValueOnMove = true;
1039 }
1040
1041 var removedItemsLength = removedItems.length;
1042 for (index = commonHead; index < len2 - commonTail; index++) {
1043 var indexOnArray2 = arrayIndexOf(seq.indices2, index - commonHead);
1044 if (indexOnArray2 < 0) {
1045 // added, try to match with a removed item and register as position move
1046 var isMove = false;
1047 if (detectMove && removedItemsLength > 0) {
1048 for (var removeItemIndex1 = 0; removeItemIndex1 < removedItemsLength; removeItemIndex1++) {
1049 index1 = removedItems[removeItemIndex1];
1050 if (matchItems(trimmed1, trimmed2, index1 - commonHead, index - commonHead, matchContext)) {
1051 // store position move as: [originalValue, newPosition, ARRAY_MOVE]
1052 result['_' + index1].splice(1, 2, index, ARRAY_MOVE);
1053 if (!includeValueOnMove) {
1054 // don't include moved value on diff, to save bytes
1055 result['_' + index1][0] = '';
1056 }
1057
1058 index2 = index;
1059 child = new DiffContext(context.left[index1], context.right[index2]);
1060 context.push(child, index2);
1061 removedItems.splice(removeItemIndex1, 1);
1062 isMove = true;
1063 break;
1064 }
1065 }
1066 }
1067 if (!isMove) {
1068 // added
1069 result[index] = [array2[index]];
1070 }
1071 } else {
1072 // match, do inner diff
1073 index1 = seq.indices1[indexOnArray2] + commonHead;
1074 index2 = seq.indices2[indexOnArray2] + commonHead;
1075 child = new DiffContext(context.left[index1], context.right[index2]);
1076 context.push(child, index2);
1077 }
1078 }
1079
1080 context.setResult(result).exit();
1081};
1082diffFilter$1.filterName = 'arrays';
1083
1084var compare = {
1085 numerically: function numerically(a, b) {
1086 return a - b;
1087 },
1088 numericallyBy: function numericallyBy(name) {
1089 return function (a, b) {
1090 return a[name] - b[name];
1091 };
1092 }
1093};
1094
1095var patchFilter$2 = function nestedPatchFilter(context) {
1096 if (!context.nested) {
1097 return;
1098 }
1099 if (context.delta._t !== 'a') {
1100 return;
1101 }
1102 var index = void 0;
1103 var index1 = void 0;
1104
1105 var delta = context.delta;
1106 var array = context.left;
1107
1108 // first, separate removals, insertions and modifications
1109 var toRemove = [];
1110 var toInsert = [];
1111 var toModify = [];
1112 for (index in delta) {
1113 if (index !== '_t') {
1114 if (index[0] === '_') {
1115 // removed item from original array
1116 if (delta[index][2] === 0 || delta[index][2] === ARRAY_MOVE) {
1117 toRemove.push(parseInt(index.slice(1), 10));
1118 } else {
1119 throw new Error('only removal or move can be applied at original array indices,' + (' invalid diff type: ' + delta[index][2]));
1120 }
1121 } else {
1122 if (delta[index].length === 1) {
1123 // added item at new array
1124 toInsert.push({
1125 index: parseInt(index, 10),
1126 value: delta[index][0]
1127 });
1128 } else {
1129 // modified item at new array
1130 toModify.push({
1131 index: parseInt(index, 10),
1132 delta: delta[index]
1133 });
1134 }
1135 }
1136 }
1137 }
1138
1139 // remove items, in reverse order to avoid sawing our own floor
1140 toRemove = toRemove.sort(compare.numerically);
1141 for (index = toRemove.length - 1; index >= 0; index--) {
1142 index1 = toRemove[index];
1143 var indexDiff = delta['_' + index1];
1144 var removedValue = array.splice(index1, 1)[0];
1145 if (indexDiff[2] === ARRAY_MOVE) {
1146 // reinsert later
1147 toInsert.push({
1148 index: indexDiff[1],
1149 value: removedValue
1150 });
1151 }
1152 }
1153
1154 // insert items, in reverse order to avoid moving our own floor
1155 toInsert = toInsert.sort(compare.numericallyBy('index'));
1156 var toInsertLength = toInsert.length;
1157 for (index = 0; index < toInsertLength; index++) {
1158 var insertion = toInsert[index];
1159 array.splice(insertion.index, 0, insertion.value);
1160 }
1161
1162 // apply modifications
1163 var toModifyLength = toModify.length;
1164 var child = void 0;
1165 if (toModifyLength > 0) {
1166 for (index = 0; index < toModifyLength; index++) {
1167 var modification = toModify[index];
1168 child = new PatchContext(context.left[modification.index], modification.delta);
1169 context.push(child, modification.index);
1170 }
1171 }
1172
1173 if (!context.children) {
1174 context.setResult(context.left).exit();
1175 return;
1176 }
1177 context.exit();
1178};
1179patchFilter$2.filterName = 'arrays';
1180
1181var collectChildrenPatchFilter$1 = function collectChildrenPatchFilter(context) {
1182 if (!context || !context.children) {
1183 return;
1184 }
1185 if (context.delta._t !== 'a') {
1186 return;
1187 }
1188 var length = context.children.length;
1189 var child = void 0;
1190 for (var index = 0; index < length; index++) {
1191 child = context.children[index];
1192 context.left[child.childName] = child.result;
1193 }
1194 context.setResult(context.left).exit();
1195};
1196collectChildrenPatchFilter$1.filterName = 'arraysCollectChildren';
1197
1198var reverseFilter$2 = function arraysReverseFilter(context) {
1199 if (!context.nested) {
1200 if (context.delta[2] === ARRAY_MOVE) {
1201 context.newName = '_' + context.delta[1];
1202 context.setResult([context.delta[0], parseInt(context.childName.substr(1), 10), ARRAY_MOVE]).exit();
1203 }
1204 return;
1205 }
1206 if (context.delta._t !== 'a') {
1207 return;
1208 }
1209 var name = void 0;
1210 var child = void 0;
1211 for (name in context.delta) {
1212 if (name === '_t') {
1213 continue;
1214 }
1215 child = new ReverseContext(context.delta[name]);
1216 context.push(child, name);
1217 }
1218 context.exit();
1219};
1220reverseFilter$2.filterName = 'arrays';
1221
1222var reverseArrayDeltaIndex = function reverseArrayDeltaIndex(delta, index, itemDelta) {
1223 if (typeof index === 'string' && index[0] === '_') {
1224 return parseInt(index.substr(1), 10);
1225 } else if (isArray$2(itemDelta) && itemDelta[2] === 0) {
1226 return '_' + index;
1227 }
1228
1229 var reverseIndex = +index;
1230 for (var deltaIndex in delta) {
1231 var deltaItem = delta[deltaIndex];
1232 if (isArray$2(deltaItem)) {
1233 if (deltaItem[2] === ARRAY_MOVE) {
1234 var moveFromIndex = parseInt(deltaIndex.substr(1), 10);
1235 var moveToIndex = deltaItem[1];
1236 if (moveToIndex === +index) {
1237 return moveFromIndex;
1238 }
1239 if (moveFromIndex <= reverseIndex && moveToIndex > reverseIndex) {
1240 reverseIndex++;
1241 } else if (moveFromIndex >= reverseIndex && moveToIndex < reverseIndex) {
1242 reverseIndex--;
1243 }
1244 } else if (deltaItem[2] === 0) {
1245 var deleteIndex = parseInt(deltaIndex.substr(1), 10);
1246 if (deleteIndex <= reverseIndex) {
1247 reverseIndex++;
1248 }
1249 } else if (deltaItem.length === 1 && deltaIndex <= reverseIndex) {
1250 reverseIndex--;
1251 }
1252 }
1253 }
1254
1255 return reverseIndex;
1256};
1257
1258function collectChildrenReverseFilter$1(context) {
1259 if (!context || !context.children) {
1260 return;
1261 }
1262 if (context.delta._t !== 'a') {
1263 return;
1264 }
1265 var length = context.children.length;
1266 var child = void 0;
1267 var delta = {
1268 _t: 'a'
1269 };
1270
1271 for (var index = 0; index < length; index++) {
1272 child = context.children[index];
1273 var name = child.newName;
1274 if (typeof name === 'undefined') {
1275 name = reverseArrayDeltaIndex(context.delta, child.childName, child.result);
1276 }
1277 if (delta[name] !== child.result) {
1278 delta[name] = child.result;
1279 }
1280 }
1281 context.setResult(delta).exit();
1282}
1283collectChildrenReverseFilter$1.filterName = 'arraysCollectChildren';
1284
1285var diffFilter$2 = function datesDiffFilter(context) {
1286 if (context.left instanceof Date) {
1287 if (context.right instanceof Date) {
1288 if (context.left.getTime() !== context.right.getTime()) {
1289 context.setResult([context.left, context.right]);
1290 } else {
1291 context.setResult(undefined);
1292 }
1293 } else {
1294 context.setResult([context.left, context.right]);
1295 }
1296 context.exit();
1297 } else if (context.right instanceof Date) {
1298 context.setResult([context.left, context.right]).exit();
1299 }
1300};
1301diffFilter$2.filterName = 'dates';
1302
1303/* global diff_match_patch */
1304var TEXT_DIFF = 2;
1305var DEFAULT_MIN_LENGTH = 60;
1306var cachedDiffPatch = null;
1307
1308var getDiffMatchPatch = function getDiffMatchPatch(required) {
1309 /* jshint camelcase: false */
1310
1311 if (!cachedDiffPatch) {
1312 var instance = void 0;
1313 /* eslint-disable camelcase, new-cap */
1314 if (typeof diff_match_patch !== 'undefined') {
1315 // already loaded, probably a browser
1316 instance = typeof diff_match_patch === 'function' ? new diff_match_patch() : new diff_match_patch.diff_match_patch();
1317 } else if (dmp) {
1318 try {
1319 instance = dmp && new dmp();
1320 } catch (err) {
1321 instance = null;
1322 }
1323 }
1324 /* eslint-enable camelcase, new-cap */
1325 if (!instance) {
1326 if (!required) {
1327 return null;
1328 }
1329 var error = new Error('text diff_match_patch library not found');
1330 // eslint-disable-next-line camelcase
1331 error.diff_match_patch_not_found = true;
1332 throw error;
1333 }
1334 cachedDiffPatch = {
1335 diff: function diff(txt1, txt2) {
1336 return instance.patch_toText(instance.patch_make(txt1, txt2));
1337 },
1338 patch: function patch(txt1, _patch) {
1339 var results = instance.patch_apply(instance.patch_fromText(_patch), txt1);
1340 for (var i = 0; i < results[1].length; i++) {
1341 if (!results[1][i]) {
1342 var _error = new Error('text patch failed');
1343 _error.textPatchFailed = true;
1344 }
1345 }
1346 return results[0];
1347 }
1348 };
1349 }
1350 return cachedDiffPatch;
1351};
1352
1353var diffFilter$3 = function textsDiffFilter(context) {
1354 if (context.leftType !== 'string') {
1355 return;
1356 }
1357 var minLength = context.options && context.options.textDiff && context.options.textDiff.minLength || DEFAULT_MIN_LENGTH;
1358 if (context.left.length < minLength || context.right.length < minLength) {
1359 context.setResult([context.left, context.right]).exit();
1360 return;
1361 }
1362 // large text, try to use a text-diff algorithm
1363 var diffMatchPatch = getDiffMatchPatch();
1364 if (!diffMatchPatch) {
1365 // diff-match-patch library not available,
1366 // fallback to regular string replace
1367 context.setResult([context.left, context.right]).exit();
1368 return;
1369 }
1370 var diff = diffMatchPatch.diff;
1371 context.setResult([diff(context.left, context.right), 0, TEXT_DIFF]).exit();
1372};
1373diffFilter$3.filterName = 'texts';
1374
1375var patchFilter$3 = function textsPatchFilter(context) {
1376 if (context.nested) {
1377 return;
1378 }
1379 if (context.delta[2] !== TEXT_DIFF) {
1380 return;
1381 }
1382
1383 // text-diff, use a text-patch algorithm
1384 var patch = getDiffMatchPatch(true).patch;
1385 context.setResult(patch(context.left, context.delta[0])).exit();
1386};
1387patchFilter$3.filterName = 'texts';
1388
1389var textDeltaReverse = function textDeltaReverse(delta) {
1390 var i = void 0;
1391 var l = void 0;
1392 var lines = void 0;
1393 var line = void 0;
1394 var lineTmp = void 0;
1395 var header = null;
1396 var headerRegex = /^@@ +-(\d+),(\d+) +\+(\d+),(\d+) +@@$/;
1397 var lineHeader = void 0;
1398 lines = delta.split('\n');
1399 for (i = 0, l = lines.length; i < l; i++) {
1400 line = lines[i];
1401 var lineStart = line.slice(0, 1);
1402 if (lineStart === '@') {
1403 header = headerRegex.exec(line);
1404 lineHeader = i;
1405
1406 // fix header
1407 lines[lineHeader] = '@@ -' + header[3] + ',' + header[4] + ' +' + header[1] + ',' + header[2] + ' @@';
1408 } else if (lineStart === '+') {
1409 lines[i] = '-' + lines[i].slice(1);
1410 if (lines[i - 1].slice(0, 1) === '+') {
1411 // swap lines to keep default order (-+)
1412 lineTmp = lines[i];
1413 lines[i] = lines[i - 1];
1414 lines[i - 1] = lineTmp;
1415 }
1416 } else if (lineStart === '-') {
1417 lines[i] = '+' + lines[i].slice(1);
1418 }
1419 }
1420 return lines.join('\n');
1421};
1422
1423var reverseFilter$3 = function textsReverseFilter(context) {
1424 if (context.nested) {
1425 return;
1426 }
1427 if (context.delta[2] !== TEXT_DIFF) {
1428 return;
1429 }
1430
1431 // text-diff, use a text-diff algorithm
1432 context.setResult([textDeltaReverse(context.delta[0]), 0, TEXT_DIFF]).exit();
1433};
1434reverseFilter$3.filterName = 'texts';
1435
1436var DiffPatcher = function () {
1437 function DiffPatcher(options) {
1438 classCallCheck(this, DiffPatcher);
1439
1440 this.processor = new Processor(options);
1441 this.processor.pipe(new Pipe('diff').append(collectChildrenDiffFilter, diffFilter, diffFilter$2, diffFilter$3, objectsDiffFilter, diffFilter$1).shouldHaveResult());
1442 this.processor.pipe(new Pipe('patch').append(collectChildrenPatchFilter, collectChildrenPatchFilter$1, patchFilter, patchFilter$3, patchFilter$1, patchFilter$2).shouldHaveResult());
1443 this.processor.pipe(new Pipe('reverse').append(collectChildrenReverseFilter, collectChildrenReverseFilter$1, reverseFilter, reverseFilter$3, reverseFilter$1, reverseFilter$2).shouldHaveResult());
1444 }
1445
1446 createClass(DiffPatcher, [{
1447 key: 'options',
1448 value: function options() {
1449 var _processor;
1450
1451 return (_processor = this.processor).options.apply(_processor, arguments);
1452 }
1453 }, {
1454 key: 'diff',
1455 value: function diff(left, right) {
1456 return this.processor.process(new DiffContext(left, right));
1457 }
1458 }, {
1459 key: 'patch',
1460 value: function patch(left, delta) {
1461 return this.processor.process(new PatchContext(left, delta));
1462 }
1463 }, {
1464 key: 'reverse',
1465 value: function reverse(delta) {
1466 return this.processor.process(new ReverseContext(delta));
1467 }
1468 }, {
1469 key: 'unpatch',
1470 value: function unpatch(right, delta) {
1471 return this.patch(right, this.reverse(delta));
1472 }
1473 }, {
1474 key: 'clone',
1475 value: function clone$$1(value) {
1476 return clone(value);
1477 }
1478 }]);
1479 return DiffPatcher;
1480}();
1481
1482var isArray$3 = typeof Array.isArray === 'function' ? Array.isArray : function (a) {
1483 return a instanceof Array;
1484};
1485
1486var getObjectKeys = typeof Object.keys === 'function' ? function (obj) {
1487 return Object.keys(obj);
1488} : function (obj) {
1489 var names = [];
1490 for (var property in obj) {
1491 if (Object.prototype.hasOwnProperty.call(obj, property)) {
1492 names.push(property);
1493 }
1494 }
1495 return names;
1496};
1497
1498var trimUnderscore = function trimUnderscore(str) {
1499 if (str.substr(0, 1) === '_') {
1500 return str.slice(1);
1501 }
1502 return str;
1503};
1504
1505var arrayKeyToSortNumber = function arrayKeyToSortNumber(key) {
1506 if (key === '_t') {
1507 return -1;
1508 } else {
1509 if (key.substr(0, 1) === '_') {
1510 return parseInt(key.slice(1), 10);
1511 } else {
1512 return parseInt(key, 10) + 0.1;
1513 }
1514 }
1515};
1516
1517var arrayKeyComparer = function arrayKeyComparer(key1, key2) {
1518 return arrayKeyToSortNumber(key1) - arrayKeyToSortNumber(key2);
1519};
1520
1521var BaseFormatter = function () {
1522 function BaseFormatter() {
1523 classCallCheck(this, BaseFormatter);
1524 }
1525
1526 createClass(BaseFormatter, [{
1527 key: 'format',
1528 value: function format(delta, left) {
1529 var context = {};
1530 this.prepareContext(context);
1531 this.recurse(context, delta, left);
1532 return this.finalize(context);
1533 }
1534 }, {
1535 key: 'prepareContext',
1536 value: function prepareContext(context) {
1537 context.buffer = [];
1538 context.out = function () {
1539 var _buffer;
1540
1541 (_buffer = this.buffer).push.apply(_buffer, arguments);
1542 };
1543 }
1544 }, {
1545 key: 'typeFormattterNotFound',
1546 value: function typeFormattterNotFound(context, deltaType) {
1547 throw new Error('cannot format delta type: ' + deltaType);
1548 }
1549 }, {
1550 key: 'typeFormattterErrorFormatter',
1551 value: function typeFormattterErrorFormatter(context, err) {
1552 return err.toString();
1553 }
1554 }, {
1555 key: 'finalize',
1556 value: function finalize(_ref) {
1557 var buffer = _ref.buffer;
1558
1559 if (isArray$3(buffer)) {
1560 return buffer.join('');
1561 }
1562 }
1563 }, {
1564 key: 'recurse',
1565 value: function recurse(context, delta, left, key, leftKey, movedFrom, isLast) {
1566 var useMoveOriginHere = delta && movedFrom;
1567 var leftValue = useMoveOriginHere ? movedFrom.value : left;
1568
1569 if (typeof delta === 'undefined' && typeof key === 'undefined') {
1570 return undefined;
1571 }
1572
1573 var type = this.getDeltaType(delta, movedFrom);
1574 var nodeType = type === 'node' ? delta._t === 'a' ? 'array' : 'object' : '';
1575
1576 if (typeof key !== 'undefined') {
1577 this.nodeBegin(context, key, leftKey, type, nodeType, isLast);
1578 } else {
1579 this.rootBegin(context, type, nodeType);
1580 }
1581
1582 var typeFormattter = void 0;
1583 try {
1584 typeFormattter = this['format_' + type] || this.typeFormattterNotFound(context, type);
1585 typeFormattter.call(this, context, delta, leftValue, key, leftKey, movedFrom);
1586 } catch (err) {
1587 this.typeFormattterErrorFormatter(context, err, delta, leftValue, key, leftKey, movedFrom);
1588 if (typeof console !== 'undefined' && console.error) {
1589 console.error(err.stack);
1590 }
1591 }
1592
1593 if (typeof key !== 'undefined') {
1594 this.nodeEnd(context, key, leftKey, type, nodeType, isLast);
1595 } else {
1596 this.rootEnd(context, type, nodeType);
1597 }
1598 }
1599 }, {
1600 key: 'formatDeltaChildren',
1601 value: function formatDeltaChildren(context, delta, left) {
1602 var self = this;
1603 this.forEachDeltaKey(delta, left, function (key, leftKey, movedFrom, isLast) {
1604 self.recurse(context, delta[key], left ? left[leftKey] : undefined, key, leftKey, movedFrom, isLast);
1605 });
1606 }
1607 }, {
1608 key: 'forEachDeltaKey',
1609 value: function forEachDeltaKey(delta, left, fn) {
1610 var keys = getObjectKeys(delta);
1611 var arrayKeys = delta._t === 'a';
1612 var moveDestinations = {};
1613 var name = void 0;
1614 if (typeof left !== 'undefined') {
1615 for (name in left) {
1616 if (Object.prototype.hasOwnProperty.call(left, name)) {
1617 if (typeof delta[name] === 'undefined' && (!arrayKeys || typeof delta['_' + name] === 'undefined')) {
1618 keys.push(name);
1619 }
1620 }
1621 }
1622 }
1623 // look for move destinations
1624 for (name in delta) {
1625 if (Object.prototype.hasOwnProperty.call(delta, name)) {
1626 var value = delta[name];
1627 if (isArray$3(value) && value[2] === 3) {
1628 moveDestinations[value[1].toString()] = {
1629 key: name,
1630 value: left && left[parseInt(name.substr(1))]
1631 };
1632 if (this.includeMoveDestinations !== false) {
1633 if (typeof left === 'undefined' && typeof delta[value[1]] === 'undefined') {
1634 keys.push(value[1].toString());
1635 }
1636 }
1637 }
1638 }
1639 }
1640 if (arrayKeys) {
1641 keys.sort(arrayKeyComparer);
1642 } else {
1643 keys.sort();
1644 }
1645 for (var index = 0, length = keys.length; index < length; index++) {
1646 var key = keys[index];
1647 if (arrayKeys && key === '_t') {
1648 continue;
1649 }
1650 var leftKey = arrayKeys ? typeof key === 'number' ? key : parseInt(trimUnderscore(key), 10) : key;
1651 var isLast = index === length - 1;
1652 fn(key, leftKey, moveDestinations[leftKey], isLast);
1653 }
1654 }
1655 }, {
1656 key: 'getDeltaType',
1657 value: function getDeltaType(delta, movedFrom) {
1658 if (typeof delta === 'undefined') {
1659 if (typeof movedFrom !== 'undefined') {
1660 return 'movedestination';
1661 }
1662 return 'unchanged';
1663 }
1664 if (isArray$3(delta)) {
1665 if (delta.length === 1) {
1666 return 'added';
1667 }
1668 if (delta.length === 2) {
1669 return 'modified';
1670 }
1671 if (delta.length === 3 && delta[2] === 0) {
1672 return 'deleted';
1673 }
1674 if (delta.length === 3 && delta[2] === 2) {
1675 return 'textdiff';
1676 }
1677 if (delta.length === 3 && delta[2] === 3) {
1678 return 'moved';
1679 }
1680 } else if ((typeof delta === 'undefined' ? 'undefined' : _typeof(delta)) === 'object') {
1681 return 'node';
1682 }
1683 return 'unknown';
1684 }
1685 }, {
1686 key: 'parseTextDiff',
1687 value: function parseTextDiff(value) {
1688 var output = [];
1689 var lines = value.split('\n@@ ');
1690 for (var i = 0, l = lines.length; i < l; i++) {
1691 var line = lines[i];
1692 var lineOutput = {
1693 pieces: []
1694 };
1695 var location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1);
1696 lineOutput.location = {
1697 line: location[0],
1698 chr: location[1]
1699 };
1700 var pieces = line.split('\n').slice(1);
1701 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
1702 var piece = pieces[pieceIndex];
1703 if (!piece.length) {
1704 continue;
1705 }
1706 var pieceOutput = {
1707 type: 'context'
1708 };
1709 if (piece.substr(0, 1) === '+') {
1710 pieceOutput.type = 'added';
1711 } else if (piece.substr(0, 1) === '-') {
1712 pieceOutput.type = 'deleted';
1713 }
1714 pieceOutput.text = piece.slice(1);
1715 lineOutput.pieces.push(pieceOutput);
1716 }
1717 output.push(lineOutput);
1718 }
1719 return output;
1720 }
1721 }]);
1722 return BaseFormatter;
1723}();
1724
1725
1726
1727var base = Object.freeze({
1728 default: BaseFormatter
1729});
1730
1731var HtmlFormatter = function (_BaseFormatter) {
1732 inherits(HtmlFormatter, _BaseFormatter);
1733
1734 function HtmlFormatter() {
1735 classCallCheck(this, HtmlFormatter);
1736 return possibleConstructorReturn(this, (HtmlFormatter.__proto__ || Object.getPrototypeOf(HtmlFormatter)).apply(this, arguments));
1737 }
1738
1739 createClass(HtmlFormatter, [{
1740 key: 'typeFormattterErrorFormatter',
1741 value: function typeFormattterErrorFormatter(context, err) {
1742 context.out('<pre class="jsondiffpatch-error">' + err + '</pre>');
1743 }
1744 }, {
1745 key: 'formatValue',
1746 value: function formatValue(context, value) {
1747 context.out('<pre>' + htmlEscape(JSON.stringify(value, null, 2)) + '</pre>');
1748 }
1749 }, {
1750 key: 'formatTextDiffString',
1751 value: function formatTextDiffString(context, value) {
1752 var lines = this.parseTextDiff(value);
1753 context.out('<ul class="jsondiffpatch-textdiff">');
1754 for (var i = 0, l = lines.length; i < l; i++) {
1755 var line = lines[i];
1756 context.out('<li><div class="jsondiffpatch-textdiff-location">' + ('<span class="jsondiffpatch-textdiff-line-number">' + line.location.line + '</span><span class="jsondiffpatch-textdiff-char">' + line.location.chr + '</span></div><div class="jsondiffpatch-textdiff-line">'));
1757 var pieces = line.pieces;
1758 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
1759 /* global decodeURI */
1760 var piece = pieces[pieceIndex];
1761 context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + htmlEscape(decodeURI(piece.text)) + '</span>');
1762 }
1763 context.out('</div></li>');
1764 }
1765 context.out('</ul>');
1766 }
1767 }, {
1768 key: 'rootBegin',
1769 value: function rootBegin(context, type, nodeType) {
1770 var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : '');
1771 context.out('<div class="jsondiffpatch-delta ' + nodeClass + '">');
1772 }
1773 }, {
1774 key: 'rootEnd',
1775 value: function rootEnd(context) {
1776 context.out('</div>' + (context.hasArrows ? '<script type="text/javascript">setTimeout(' + (adjustArrows.toString() + ',10);</script>') : ''));
1777 }
1778 }, {
1779 key: 'nodeBegin',
1780 value: function nodeBegin(context, key, leftKey, type, nodeType) {
1781 var nodeClass = 'jsondiffpatch-' + type + (nodeType ? ' jsondiffpatch-child-node-type-' + nodeType : '');
1782 context.out('<li class="' + nodeClass + '" data-key="' + leftKey + '">' + ('<div class="jsondiffpatch-property-name">' + leftKey + '</div>'));
1783 }
1784 }, {
1785 key: 'nodeEnd',
1786 value: function nodeEnd(context) {
1787 context.out('</li>');
1788 }
1789
1790 /* jshint camelcase: false */
1791 /* eslint-disable camelcase */
1792
1793 }, {
1794 key: 'format_unchanged',
1795 value: function format_unchanged(context, delta, left) {
1796 if (typeof left === 'undefined') {
1797 return;
1798 }
1799 context.out('<div class="jsondiffpatch-value">');
1800 this.formatValue(context, left);
1801 context.out('</div>');
1802 }
1803 }, {
1804 key: 'format_movedestination',
1805 value: function format_movedestination(context, delta, left) {
1806 if (typeof left === 'undefined') {
1807 return;
1808 }
1809 context.out('<div class="jsondiffpatch-value">');
1810 this.formatValue(context, left);
1811 context.out('</div>');
1812 }
1813 }, {
1814 key: 'format_node',
1815 value: function format_node(context, delta, left) {
1816 // recurse
1817 var nodeType = delta._t === 'a' ? 'array' : 'object';
1818 context.out('<ul class="jsondiffpatch-node jsondiffpatch-node-type-' + nodeType + '">');
1819 this.formatDeltaChildren(context, delta, left);
1820 context.out('</ul>');
1821 }
1822 }, {
1823 key: 'format_added',
1824 value: function format_added(context, delta) {
1825 context.out('<div class="jsondiffpatch-value">');
1826 this.formatValue(context, delta[0]);
1827 context.out('</div>');
1828 }
1829 }, {
1830 key: 'format_modified',
1831 value: function format_modified(context, delta) {
1832 context.out('<div class="jsondiffpatch-value jsondiffpatch-left-value">');
1833 this.formatValue(context, delta[0]);
1834 context.out('</div>' + '<div class="jsondiffpatch-value jsondiffpatch-right-value">');
1835 this.formatValue(context, delta[1]);
1836 context.out('</div>');
1837 }
1838 }, {
1839 key: 'format_deleted',
1840 value: function format_deleted(context, delta) {
1841 context.out('<div class="jsondiffpatch-value">');
1842 this.formatValue(context, delta[0]);
1843 context.out('</div>');
1844 }
1845 }, {
1846 key: 'format_moved',
1847 value: function format_moved(context, delta) {
1848 context.out('<div class="jsondiffpatch-value">');
1849 this.formatValue(context, delta[0]);
1850 context.out('</div><div class="jsondiffpatch-moved-destination">' + delta[1] + '</div>');
1851
1852 // draw an SVG arrow from here to move destination
1853 context.out(
1854 /* jshint multistr: true */
1855 '<div class="jsondiffpatch-arrow" ' + 'style="position: relative; left: -34px;">\n <svg width="30" height="60" ' + 'style="position: absolute; display: none;">\n <defs>\n <marker id="markerArrow" markerWidth="8" markerHeight="8"\n refx="2" refy="4"\n orient="auto" markerUnits="userSpaceOnUse">\n <path d="M1,1 L1,7 L7,4 L1,1" style="fill: #339;" />\n </marker>\n </defs>\n <path d="M30,0 Q-10,25 26,50"\n style="stroke: #88f; stroke-width: 2px; fill: none; ' + 'stroke-opacity: 0.5; marker-end: url(#markerArrow);"\n ></path>\n </svg>\n </div>');
1856 context.hasArrows = true;
1857 }
1858 }, {
1859 key: 'format_textdiff',
1860 value: function format_textdiff(context, delta) {
1861 context.out('<div class="jsondiffpatch-value">');
1862 this.formatTextDiffString(context, delta[0]);
1863 context.out('</div>');
1864 }
1865 }]);
1866 return HtmlFormatter;
1867}(BaseFormatter);
1868
1869function htmlEscape(text) {
1870 var html = text;
1871 var replacements = [[/&/g, '&amp;'], [/</g, '&lt;'], [/>/g, '&gt;'], [/'/g, '&apos;'], [/"/g, '&quot;']];
1872 for (var i = 0; i < replacements.length; i++) {
1873 html = html.replace(replacements[i][0], replacements[i][1]);
1874 }
1875 return html;
1876}
1877
1878var adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) {
1879 var node = nodeArg || document;
1880 var getElementText = function getElementText(_ref) {
1881 var textContent = _ref.textContent,
1882 innerText = _ref.innerText;
1883 return textContent || innerText;
1884 };
1885 var eachByQuery = function eachByQuery(el, query, fn) {
1886 var elems = el.querySelectorAll(query);
1887 for (var i = 0, l = elems.length; i < l; i++) {
1888 fn(elems[i]);
1889 }
1890 };
1891 var eachChildren = function eachChildren(_ref2, fn) {
1892 var children = _ref2.children;
1893
1894 for (var i = 0, l = children.length; i < l; i++) {
1895 fn(children[i], i);
1896 }
1897 };
1898 eachByQuery(node, '.jsondiffpatch-arrow', function (_ref3) {
1899 var parentNode = _ref3.parentNode,
1900 children = _ref3.children,
1901 style = _ref3.style;
1902
1903 var arrowParent = parentNode;
1904 var svg = children[0];
1905 var path = svg.children[1];
1906 svg.style.display = 'none';
1907 var destination = getElementText(arrowParent.querySelector('.jsondiffpatch-moved-destination'));
1908 var container = arrowParent.parentNode;
1909 var destinationElem = void 0;
1910 eachChildren(container, function (child) {
1911 if (child.getAttribute('data-key') === destination) {
1912 destinationElem = child;
1913 }
1914 });
1915 if (!destinationElem) {
1916 return;
1917 }
1918 try {
1919 var distance = destinationElem.offsetTop - arrowParent.offsetTop;
1920 svg.setAttribute('height', Math.abs(distance) + 6);
1921 style.top = -8 + (distance > 0 ? 0 : distance) + 'px';
1922 var curve = distance > 0 ? 'M30,0 Q-10,' + Math.round(distance / 2) + ' 26,' + (distance - 4) : 'M30,' + -distance + ' Q-10,' + Math.round(-distance / 2) + ' 26,4';
1923 path.setAttribute('d', curve);
1924 svg.style.display = '';
1925 } catch (err) {}
1926 });
1927};
1928
1929/* jshint camelcase: true */
1930/* eslint-enable camelcase */
1931
1932var showUnchanged = function showUnchanged(show, node, delay) {
1933 var el = node || document.body;
1934 var prefix = 'jsondiffpatch-unchanged-';
1935 var classes = {
1936 showing: prefix + 'showing',
1937 hiding: prefix + 'hiding',
1938 visible: prefix + 'visible',
1939 hidden: prefix + 'hidden'
1940 };
1941 var list = el.classList;
1942 if (!list) {
1943 return;
1944 }
1945 if (!delay) {
1946 list.remove(classes.showing);
1947 list.remove(classes.hiding);
1948 list.remove(classes.visible);
1949 list.remove(classes.hidden);
1950 if (show === false) {
1951 list.add(classes.hidden);
1952 }
1953 return;
1954 }
1955 if (show === false) {
1956 list.remove(classes.showing);
1957 list.add(classes.visible);
1958 setTimeout(function () {
1959 list.add(classes.hiding);
1960 }, 10);
1961 } else {
1962 list.remove(classes.hiding);
1963 list.add(classes.showing);
1964 list.remove(classes.hidden);
1965 }
1966 var intervalId = setInterval(function () {
1967 adjustArrows(el);
1968 }, 100);
1969 setTimeout(function () {
1970 list.remove(classes.showing);
1971 list.remove(classes.hiding);
1972 if (show === false) {
1973 list.add(classes.hidden);
1974 list.remove(classes.visible);
1975 } else {
1976 list.add(classes.visible);
1977 list.remove(classes.hidden);
1978 }
1979 setTimeout(function () {
1980 list.remove(classes.visible);
1981 clearInterval(intervalId);
1982 }, delay + 400);
1983 }, delay);
1984};
1985
1986var hideUnchanged = function hideUnchanged(node, delay) {
1987 return showUnchanged(false, node, delay);
1988};
1989
1990var defaultInstance = void 0;
1991
1992function format(delta, left) {
1993 if (!defaultInstance) {
1994 defaultInstance = new HtmlFormatter();
1995 }
1996 return defaultInstance.format(delta, left);
1997}
1998
1999
2000
2001var html = Object.freeze({
2002 showUnchanged: showUnchanged,
2003 hideUnchanged: hideUnchanged,
2004 default: HtmlFormatter,
2005 format: format
2006});
2007
2008var AnnotatedFormatter = function (_BaseFormatter) {
2009 inherits(AnnotatedFormatter, _BaseFormatter);
2010
2011 function AnnotatedFormatter() {
2012 classCallCheck(this, AnnotatedFormatter);
2013
2014 var _this = possibleConstructorReturn(this, (AnnotatedFormatter.__proto__ || Object.getPrototypeOf(AnnotatedFormatter)).call(this));
2015
2016 _this.includeMoveDestinations = false;
2017 return _this;
2018 }
2019
2020 createClass(AnnotatedFormatter, [{
2021 key: 'prepareContext',
2022 value: function prepareContext(context) {
2023 get(AnnotatedFormatter.prototype.__proto__ || Object.getPrototypeOf(AnnotatedFormatter.prototype), 'prepareContext', this).call(this, context);
2024 context.indent = function (levels) {
2025 this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels);
2026 this.indentPad = new Array(this.indentLevel + 1).join('&nbsp;&nbsp;');
2027 };
2028 context.row = function (json, htmlNote) {
2029 context.out('<tr><td style="white-space: nowrap;">' + '<pre class="jsondiffpatch-annotated-indent"' + ' style="display: inline-block">');
2030 context.out(context.indentPad);
2031 context.out('</pre><pre style="display: inline-block">');
2032 context.out(json);
2033 context.out('</pre></td><td class="jsondiffpatch-delta-note"><div>');
2034 context.out(htmlNote);
2035 context.out('</div></td></tr>');
2036 };
2037 }
2038 }, {
2039 key: 'typeFormattterErrorFormatter',
2040 value: function typeFormattterErrorFormatter(context, err) {
2041 context.row('', '<pre class="jsondiffpatch-error">' + err + '</pre>');
2042 }
2043 }, {
2044 key: 'formatTextDiffString',
2045 value: function formatTextDiffString(context, value) {
2046 var lines = this.parseTextDiff(value);
2047 context.out('<ul class="jsondiffpatch-textdiff">');
2048 for (var i = 0, l = lines.length; i < l; i++) {
2049 var line = lines[i];
2050 context.out('<li><div class="jsondiffpatch-textdiff-location">' + ('<span class="jsondiffpatch-textdiff-line-number">' + line.location.line + '</span><span class="jsondiffpatch-textdiff-char">' + line.location.chr + '</span></div><div class="jsondiffpatch-textdiff-line">'));
2051 var pieces = line.pieces;
2052 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
2053 var piece = pieces[pieceIndex];
2054 context.out('<span class="jsondiffpatch-textdiff-' + piece.type + '">' + piece.text + '</span>');
2055 }
2056 context.out('</div></li>');
2057 }
2058 context.out('</ul>');
2059 }
2060 }, {
2061 key: 'rootBegin',
2062 value: function rootBegin(context, type, nodeType) {
2063 context.out('<table class="jsondiffpatch-annotated-delta">');
2064 if (type === 'node') {
2065 context.row('{');
2066 context.indent();
2067 }
2068 if (nodeType === 'array') {
2069 context.row('"_t": "a",', 'Array delta (member names indicate array indices)');
2070 }
2071 }
2072 }, {
2073 key: 'rootEnd',
2074 value: function rootEnd(context, type) {
2075 if (type === 'node') {
2076 context.indent(-1);
2077 context.row('}');
2078 }
2079 context.out('</table>');
2080 }
2081 }, {
2082 key: 'nodeBegin',
2083 value: function nodeBegin(context, key, leftKey, type, nodeType) {
2084 context.row('&quot;' + key + '&quot;: {');
2085 if (type === 'node') {
2086 context.indent();
2087 }
2088 if (nodeType === 'array') {
2089 context.row('"_t": "a",', 'Array delta (member names indicate array indices)');
2090 }
2091 }
2092 }, {
2093 key: 'nodeEnd',
2094 value: function nodeEnd(context, key, leftKey, type, nodeType, isLast) {
2095 if (type === 'node') {
2096 context.indent(-1);
2097 }
2098 context.row('}' + (isLast ? '' : ','));
2099 }
2100
2101 /* jshint camelcase: false */
2102
2103 /* eslint-disable camelcase */
2104
2105 }, {
2106 key: 'format_unchanged',
2107 value: function format_unchanged() {}
2108 }, {
2109 key: 'format_movedestination',
2110 value: function format_movedestination() {}
2111 }, {
2112 key: 'format_node',
2113 value: function format_node(context, delta, left) {
2114 // recurse
2115 this.formatDeltaChildren(context, delta, left);
2116 }
2117 }]);
2118 return AnnotatedFormatter;
2119}(BaseFormatter);
2120
2121/* eslint-enable camelcase */
2122
2123var wrapPropertyName = function wrapPropertyName(name) {
2124 return '<pre style="display:inline-block">&quot;' + name + '&quot;</pre>';
2125};
2126
2127var deltaAnnotations = {
2128 added: function added(delta, left, key, leftKey) {
2129 var formatLegend = ' <pre>([newValue])</pre>';
2130 if (typeof leftKey === 'undefined') {
2131 return 'new value' + formatLegend;
2132 }
2133 if (typeof leftKey === 'number') {
2134 return 'insert at index ' + leftKey + formatLegend;
2135 }
2136 return 'add property ' + wrapPropertyName(leftKey) + formatLegend;
2137 },
2138 modified: function modified(delta, left, key, leftKey) {
2139 var formatLegend = ' <pre>([previousValue, newValue])</pre>';
2140 if (typeof leftKey === 'undefined') {
2141 return 'modify value' + formatLegend;
2142 }
2143 if (typeof leftKey === 'number') {
2144 return 'modify at index ' + leftKey + formatLegend;
2145 }
2146 return 'modify property ' + wrapPropertyName(leftKey) + formatLegend;
2147 },
2148 deleted: function deleted(delta, left, key, leftKey) {
2149 var formatLegend = ' <pre>([previousValue, 0, 0])</pre>';
2150 if (typeof leftKey === 'undefined') {
2151 return 'delete value' + formatLegend;
2152 }
2153 if (typeof leftKey === 'number') {
2154 return 'remove index ' + leftKey + formatLegend;
2155 }
2156 return 'delete property ' + wrapPropertyName(leftKey) + formatLegend;
2157 },
2158 moved: function moved(delta, left, key, leftKey) {
2159 return 'move from <span title="(position to remove at original state)">' + ('index ' + leftKey + '</span> to <span title="(position to insert at final') + (' state)">index ' + delta[1] + '</span>');
2160 },
2161 textdiff: function textdiff(delta, left, key, leftKey) {
2162 var location = typeof leftKey === 'undefined' ? '' : typeof leftKey === 'number' ? ' at index ' + leftKey : ' at property ' + wrapPropertyName(leftKey);
2163 return 'text diff' + location + ', format is <a href="https://code.google.com/' + 'p/google-diff-match-patch/wiki/Unidiff">a variation of Unidiff</a>';
2164 }
2165};
2166
2167var formatAnyChange = function formatAnyChange(context, delta) {
2168 var deltaType = this.getDeltaType(delta);
2169 var annotator = deltaAnnotations[deltaType];
2170 var htmlNote = annotator && annotator.apply(annotator, Array.prototype.slice.call(arguments, 1));
2171 var json = JSON.stringify(delta, null, 2);
2172 if (deltaType === 'textdiff') {
2173 // split text diffs lines
2174 json = json.split('\\n').join('\\n"+\n "');
2175 }
2176 context.indent();
2177 context.row(json, htmlNote);
2178 context.indent(-1);
2179};
2180
2181/* eslint-disable camelcase */
2182AnnotatedFormatter.prototype.format_added = formatAnyChange;
2183AnnotatedFormatter.prototype.format_modified = formatAnyChange;
2184AnnotatedFormatter.prototype.format_deleted = formatAnyChange;
2185AnnotatedFormatter.prototype.format_moved = formatAnyChange;
2186AnnotatedFormatter.prototype.format_textdiff = formatAnyChange;
2187var defaultInstance$1 = void 0;
2188
2189function format$1(delta, left) {
2190 if (!defaultInstance$1) {
2191 defaultInstance$1 = new AnnotatedFormatter();
2192 }
2193 return defaultInstance$1.format(delta, left);
2194}
2195
2196
2197
2198var annotated = Object.freeze({
2199 default: AnnotatedFormatter,
2200 format: format$1
2201});
2202
2203var OPERATIONS = {
2204 add: 'add',
2205 remove: 'remove',
2206 replace: 'replace',
2207 move: 'move'
2208};
2209
2210var JSONFormatter = function (_BaseFormatter) {
2211 inherits(JSONFormatter, _BaseFormatter);
2212
2213 function JSONFormatter() {
2214 classCallCheck(this, JSONFormatter);
2215
2216 var _this = possibleConstructorReturn(this, (JSONFormatter.__proto__ || Object.getPrototypeOf(JSONFormatter)).call(this));
2217
2218 _this.includeMoveDestinations = true;
2219 return _this;
2220 }
2221
2222 createClass(JSONFormatter, [{
2223 key: 'prepareContext',
2224 value: function prepareContext(context) {
2225 get(JSONFormatter.prototype.__proto__ || Object.getPrototypeOf(JSONFormatter.prototype), 'prepareContext', this).call(this, context);
2226 context.result = [];
2227 context.path = [];
2228 context.pushCurrentOp = function (obj) {
2229 var op = obj.op,
2230 value = obj.value;
2231
2232 var val = {
2233 op: op,
2234 path: this.currentPath()
2235 };
2236 if (typeof value !== 'undefined') {
2237 val.value = value;
2238 }
2239 this.result.push(val);
2240 };
2241
2242 context.pushMoveOp = function (to) {
2243 var finalTo = '/' + to;
2244 var from = this.currentPath();
2245 this.result.push({ op: OPERATIONS.move, from: from, path: finalTo });
2246 };
2247
2248 context.currentPath = function () {
2249 return '/' + this.path.join('/');
2250 };
2251 }
2252 }, {
2253 key: 'typeFormattterErrorFormatter',
2254 value: function typeFormattterErrorFormatter(context, err) {
2255 context.out('[ERROR] ' + err);
2256 }
2257 }, {
2258 key: 'rootBegin',
2259 value: function rootBegin() {}
2260 }, {
2261 key: 'rootEnd',
2262 value: function rootEnd() {}
2263 }, {
2264 key: 'nodeBegin',
2265 value: function nodeBegin(_ref, key, leftKey) {
2266 var path = _ref.path;
2267
2268 path.push(leftKey);
2269 }
2270 }, {
2271 key: 'nodeEnd',
2272 value: function nodeEnd(_ref2) {
2273 var path = _ref2.path;
2274
2275 path.pop();
2276 }
2277
2278 /* jshint camelcase: false */
2279 /* eslint-disable camelcase */
2280
2281 }, {
2282 key: 'format_unchanged',
2283 value: function format_unchanged() {}
2284 }, {
2285 key: 'format_movedestination',
2286 value: function format_movedestination() {}
2287 }, {
2288 key: 'format_node',
2289 value: function format_node(context, delta, left) {
2290 this.formatDeltaChildren(context, delta, left);
2291 }
2292 }, {
2293 key: 'format_added',
2294 value: function format_added(context, delta) {
2295 context.pushCurrentOp({ op: OPERATIONS.add, value: delta[0] });
2296 }
2297 }, {
2298 key: 'format_modified',
2299 value: function format_modified(context, delta) {
2300 context.pushCurrentOp({ op: OPERATIONS.replace, value: delta[1] });
2301 }
2302 }, {
2303 key: 'format_deleted',
2304 value: function format_deleted(context) {
2305 context.pushCurrentOp({ op: OPERATIONS.remove });
2306 }
2307 }, {
2308 key: 'format_moved',
2309 value: function format_moved(context, delta) {
2310 var to = delta[1];
2311 context.pushMoveOp(to);
2312 }
2313 }, {
2314 key: 'format_textdiff',
2315 value: function format_textdiff() {
2316 throw new Error('Not implemented');
2317 }
2318 }, {
2319 key: 'format',
2320 value: function format(delta, left) {
2321 var context = {};
2322 this.prepareContext(context);
2323 this.recurse(context, delta, left);
2324 return context.result;
2325 }
2326 }]);
2327 return JSONFormatter;
2328}(BaseFormatter);
2329
2330var last = function last(arr) {
2331 return arr[arr.length - 1];
2332};
2333
2334var sortBy = function sortBy(arr, pred) {
2335 arr.sort(pred);
2336 return arr;
2337};
2338
2339var compareByIndexDesc = function compareByIndexDesc(indexA, indexB) {
2340 var lastA = parseInt(indexA, 10);
2341 var lastB = parseInt(indexB, 10);
2342 if (!(isNaN(lastA) || isNaN(lastB))) {
2343 return lastB - lastA;
2344 } else {
2345 return 0;
2346 }
2347};
2348
2349var opsByDescendingOrder = function opsByDescendingOrder(removeOps) {
2350 return sortBy(removeOps, function (a, b) {
2351 var splitA = a.path.split('/');
2352 var splitB = b.path.split('/');
2353 if (splitA.length !== splitB.length) {
2354 return splitA.length - splitB.length;
2355 } else {
2356 return compareByIndexDesc(last(splitA), last(splitB));
2357 }
2358 });
2359};
2360
2361var partition = function partition(arr, pred) {
2362 var left = [];
2363 var right = [];
2364
2365 arr.forEach(function (el) {
2366 var coll = pred(el) ? left : right;
2367 coll.push(el);
2368 });
2369 return [left, right];
2370};
2371
2372var partitionRemovedOps = function partitionRemovedOps(jsonFormattedDiff) {
2373 var isRemoveOp = function isRemoveOp(_ref3) {
2374 var op = _ref3.op;
2375 return op === 'remove';
2376 };
2377 var removeOpsOtherOps = partition(jsonFormattedDiff, isRemoveOp);
2378 return removeOpsOtherOps;
2379};
2380
2381var reorderOps = function reorderOps(jsonFormattedDiff) {
2382 var _partitionRemovedOps = partitionRemovedOps(jsonFormattedDiff),
2383 _partitionRemovedOps2 = slicedToArray(_partitionRemovedOps, 2),
2384 removeOps = _partitionRemovedOps2[0],
2385 otherOps = _partitionRemovedOps2[1];
2386
2387 var removeOpsReverse = opsByDescendingOrder(removeOps);
2388 return removeOpsReverse.concat(otherOps);
2389};
2390
2391var defaultInstance$2 = void 0;
2392
2393var format$2 = function format(delta, left) {
2394 if (!defaultInstance$2) {
2395 defaultInstance$2 = new JSONFormatter();
2396 }
2397 return reorderOps(defaultInstance$2.format(delta, left));
2398};
2399
2400var log = function log(delta, left) {
2401 console.log(format$2(delta, left));
2402};
2403
2404
2405
2406var jsonpatch = Object.freeze({
2407 default: JSONFormatter,
2408 format: format$2,
2409 log: log
2410});
2411
2412function chalkColor(name) {
2413 return chalk && chalk[name] || function () {
2414 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
2415 args[_key] = arguments[_key];
2416 }
2417
2418 return args;
2419 };
2420}
2421
2422var colors = {
2423 added: chalkColor('green'),
2424 deleted: chalkColor('red'),
2425 movedestination: chalkColor('gray'),
2426 moved: chalkColor('yellow'),
2427 unchanged: chalkColor('gray'),
2428 error: chalkColor('white.bgRed'),
2429 textDiffLine: chalkColor('gray')
2430};
2431
2432var ConsoleFormatter = function (_BaseFormatter) {
2433 inherits(ConsoleFormatter, _BaseFormatter);
2434
2435 function ConsoleFormatter() {
2436 classCallCheck(this, ConsoleFormatter);
2437
2438 var _this = possibleConstructorReturn(this, (ConsoleFormatter.__proto__ || Object.getPrototypeOf(ConsoleFormatter)).call(this));
2439
2440 _this.includeMoveDestinations = false;
2441 return _this;
2442 }
2443
2444 createClass(ConsoleFormatter, [{
2445 key: 'prepareContext',
2446 value: function prepareContext(context) {
2447 get(ConsoleFormatter.prototype.__proto__ || Object.getPrototypeOf(ConsoleFormatter.prototype), 'prepareContext', this).call(this, context);
2448 context.indent = function (levels) {
2449 this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels);
2450 this.indentPad = new Array(this.indentLevel + 1).join(' ');
2451 this.outLine();
2452 };
2453 context.outLine = function () {
2454 this.buffer.push('\n' + (this.indentPad || ''));
2455 };
2456 context.out = function () {
2457 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2458 args[_key2] = arguments[_key2];
2459 }
2460
2461 for (var i = 0, l = args.length; i < l; i++) {
2462 var lines = args[i].split('\n');
2463 var text = lines.join('\n' + (this.indentPad || ''));
2464 if (this.color && this.color[0]) {
2465 text = this.color[0](text);
2466 }
2467 this.buffer.push(text);
2468 }
2469 };
2470 context.pushColor = function (color) {
2471 this.color = this.color || [];
2472 this.color.unshift(color);
2473 };
2474 context.popColor = function () {
2475 this.color = this.color || [];
2476 this.color.shift();
2477 };
2478 }
2479 }, {
2480 key: 'typeFormattterErrorFormatter',
2481 value: function typeFormattterErrorFormatter(context, err) {
2482 context.pushColor(colors.error);
2483 context.out('[ERROR]' + err);
2484 context.popColor();
2485 }
2486 }, {
2487 key: 'formatValue',
2488 value: function formatValue(context, value) {
2489 context.out(JSON.stringify(value, null, 2));
2490 }
2491 }, {
2492 key: 'formatTextDiffString',
2493 value: function formatTextDiffString(context, value) {
2494 var lines = this.parseTextDiff(value);
2495 context.indent();
2496 for (var i = 0, l = lines.length; i < l; i++) {
2497 var line = lines[i];
2498 context.pushColor(colors.textDiffLine);
2499 context.out(line.location.line + ',' + line.location.chr + ' ');
2500 context.popColor();
2501 var pieces = line.pieces;
2502 for (var pieceIndex = 0, piecesLength = pieces.length; pieceIndex < piecesLength; pieceIndex++) {
2503 var piece = pieces[pieceIndex];
2504 context.pushColor(colors[piece.type]);
2505 context.out(piece.text);
2506 context.popColor();
2507 }
2508 if (i < l - 1) {
2509 context.outLine();
2510 }
2511 }
2512 context.indent(-1);
2513 }
2514 }, {
2515 key: 'rootBegin',
2516 value: function rootBegin(context, type, nodeType) {
2517 context.pushColor(colors[type]);
2518 if (type === 'node') {
2519 context.out(nodeType === 'array' ? '[' : '{');
2520 context.indent();
2521 }
2522 }
2523 }, {
2524 key: 'rootEnd',
2525 value: function rootEnd(context, type, nodeType) {
2526 if (type === 'node') {
2527 context.indent(-1);
2528 context.out(nodeType === 'array' ? ']' : '}');
2529 }
2530 context.popColor();
2531 }
2532 }, {
2533 key: 'nodeBegin',
2534 value: function nodeBegin(context, key, leftKey, type, nodeType) {
2535 context.pushColor(colors[type]);
2536 context.out(leftKey + ': ');
2537 if (type === 'node') {
2538 context.out(nodeType === 'array' ? '[' : '{');
2539 context.indent();
2540 }
2541 }
2542 }, {
2543 key: 'nodeEnd',
2544 value: function nodeEnd(context, key, leftKey, type, nodeType, isLast) {
2545 if (type === 'node') {
2546 context.indent(-1);
2547 context.out(nodeType === 'array' ? ']' : '}' + (isLast ? '' : ','));
2548 }
2549 if (!isLast) {
2550 context.outLine();
2551 }
2552 context.popColor();
2553 }
2554
2555 /* jshint camelcase: false */
2556 /* eslint-disable camelcase */
2557
2558 }, {
2559 key: 'format_unchanged',
2560 value: function format_unchanged(context, delta, left) {
2561 if (typeof left === 'undefined') {
2562 return;
2563 }
2564 this.formatValue(context, left);
2565 }
2566 }, {
2567 key: 'format_movedestination',
2568 value: function format_movedestination(context, delta, left) {
2569 if (typeof left === 'undefined') {
2570 return;
2571 }
2572 this.formatValue(context, left);
2573 }
2574 }, {
2575 key: 'format_node',
2576 value: function format_node(context, delta, left) {
2577 // recurse
2578 this.formatDeltaChildren(context, delta, left);
2579 }
2580 }, {
2581 key: 'format_added',
2582 value: function format_added(context, delta) {
2583 this.formatValue(context, delta[0]);
2584 }
2585 }, {
2586 key: 'format_modified',
2587 value: function format_modified(context, delta) {
2588 context.pushColor(colors.deleted);
2589 this.formatValue(context, delta[0]);
2590 context.popColor();
2591 context.out(' => ');
2592 context.pushColor(colors.added);
2593 this.formatValue(context, delta[1]);
2594 context.popColor();
2595 }
2596 }, {
2597 key: 'format_deleted',
2598 value: function format_deleted(context, delta) {
2599 this.formatValue(context, delta[0]);
2600 }
2601 }, {
2602 key: 'format_moved',
2603 value: function format_moved(context, delta) {
2604 context.out('==> ' + delta[1]);
2605 }
2606 }, {
2607 key: 'format_textdiff',
2608 value: function format_textdiff(context, delta) {
2609 this.formatTextDiffString(context, delta[0]);
2610 }
2611 }]);
2612 return ConsoleFormatter;
2613}(BaseFormatter);
2614
2615var defaultInstance$3 = void 0;
2616
2617var format$3 = function format(delta, left) {
2618 if (!defaultInstance$3) {
2619 defaultInstance$3 = new ConsoleFormatter();
2620 }
2621 return defaultInstance$3.format(delta, left);
2622};
2623
2624function log$1(delta, left) {
2625 console.log(format$3(delta, left));
2626}
2627
2628
2629
2630var console$1 = Object.freeze({
2631 default: ConsoleFormatter,
2632 format: format$3,
2633 log: log$1
2634});
2635
2636
2637
2638var index = Object.freeze({
2639 base: base,
2640 html: html,
2641 annotated: annotated,
2642 jsonpatch: jsonpatch,
2643 console: console$1
2644});
2645
2646// use as 2nd parameter for JSON.parse to revive Date instances
2647function dateReviver(key, value) {
2648 var parts = void 0;
2649 if (typeof value === 'string') {
2650 // eslint-disable-next-line max-len
2651 parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d*))?(Z|([+-])(\d{2}):(\d{2}))$/.exec(value);
2652 if (parts) {
2653 return new Date(Date.UTC(+parts[1], +parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6], +(parts[7] || 0)));
2654 }
2655 }
2656 return value;
2657}
2658
2659function create(options) {
2660 return new DiffPatcher(options);
2661}
2662
2663var defaultInstance$4 = void 0;
2664
2665function diff() {
2666 if (!defaultInstance$4) {
2667 defaultInstance$4 = new DiffPatcher();
2668 }
2669 return defaultInstance$4.diff.apply(defaultInstance$4, arguments);
2670}
2671
2672function patch() {
2673 if (!defaultInstance$4) {
2674 defaultInstance$4 = new DiffPatcher();
2675 }
2676 return defaultInstance$4.patch.apply(defaultInstance$4, arguments);
2677}
2678
2679function unpatch() {
2680 if (!defaultInstance$4) {
2681 defaultInstance$4 = new DiffPatcher();
2682 }
2683 return defaultInstance$4.unpatch.apply(defaultInstance$4, arguments);
2684}
2685
2686function reverse() {
2687 if (!defaultInstance$4) {
2688 defaultInstance$4 = new DiffPatcher();
2689 }
2690 return defaultInstance$4.reverse.apply(defaultInstance$4, arguments);
2691}
2692
2693function clone$1() {
2694 if (!defaultInstance$4) {
2695 defaultInstance$4 = new DiffPatcher();
2696 }
2697 return defaultInstance$4.clone.apply(defaultInstance$4, arguments);
2698}
2699
2700export { DiffPatcher, index as formatters, console$1 as console, create, dateReviver, diff, patch, unpatch, reverse, clone$1 as clone };
2701//# sourceMappingURL=jsondiffpatch.esm.js.map