Files
notifications-admin/paas-failwhale/static_503/all.js

1361 lines
156 KiB
JavaScript
Raw Normal View History

2017-03-28 13:15:01 +01:00
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each(
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</tex
}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.exten
//# sourceMappingURL=jquery.min.map
!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){!function(a,c){"undefined"!=typeof b&&b.exports?b.exports=c():"function"==typeof define&&define.amd?define(c):this[a]=c()}("bowser",function(){function a(a){function c(b){var c=a.match(b);return c&&c.length>1&&c[1]||""}function d(b){var c=a.match(b);return c&&c.length>1&&c[2]||""}var e,f=c(/(ipod|iphone|ipad)/i).toLowerCase(),g=/like android/i.test(a),h=!g&&/android/i.test(a),i=/CrOS/.test(a),j=c(/edge\/(\d+(\.\d+)?)/i),k=c(/version\/(\d+(\.\d+)?)/i),l=/tablet/i.test(a),m=!l&&/[^-]mobi/i.test(a);/opera|opr/i.test(a)?e={name:"Opera",opera:b,version:k||c(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)}:/yabrowser/i.test(a)?e={name:"Yandex Browser",yandexbrowser:b,version:k||c(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)}:/windows phone/i.test(a)?(e={name:"Windows Phone",windowsphone:b},j?(e.msedge=b,e.version=j):(e.msie=b,e.version=c(/iemobile\/(\d+(\.\d+)?)/i))):/msie|trident/i.test(a)?e={name:"Internet Explorer",msie:b,version:c(/(?:msie |rv:)(\d+(\.\d+)?)/i)}:i?e={name:"Chrome",chromeBook:b,chrome:b,version:c(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:/chrome.+? edge/i.test(a)?e={name:"Microsoft Edge",msedge:b,version:j}:/chrome|crios|crmo/i.test(a)?e={name:"Chrome",chrome:b,version:c(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:f?(e={name:"iphone"==f?"iPhone":"ipad"==f?"iPad":"iPod"},k&&(e.version=k)):/sailfish/i.test(a)?e={name:"Sailfish",sailfish:b,version:c(/sailfish\s?browser\/(\d+(\.\d+)?)/i)}:/seamonkey\//i.test(a)?e={name:"SeaMonkey",seamonkey:b,version:c(/seamonkey\/(\d+(\.\d+)?)/i)}:/firefox|iceweasel/i.test(a)?(e={name:"Firefox",firefox:b,version:c(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)},/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(a)&&(e.firefoxos=b)):/silk/i.test(a)?e={name:"Amazon Silk",silk:b,version:c(/silk\/(\d+(\.\d+)?)/i)}:h?e={name:"Android",version:k}:/phantom/i.test(a)?e={name:"PhantomJS",phantom:b,version:c(/phantomjs\/(\d+(\.\d+)?)/i)}:/blackberry|\bbb\d+/i.test(a)||/rim\stablet/i.test(a)?e={name:"BlackBerry",blackberry:b,version:k||c(/blackberry[\d]+\/(\d+(\.\d+)?)/i)}:/(web|hpw)os/i.test(a)?(e={name:"WebOS",webos:b,version:k||c(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)},/touchpad\//i.test(a)&&(e.touchpad=b)):e=/bada/i.test(a)?{name:"Bada",bada:b,version:c(/dolfin\/(\d+(\.\d+)?)/i)}:/tizen/i.test(a)?{name:"Tizen",tizen:b,version:c(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i)||k}:/safari/i.test(a)?{name:"Safari",safari:b,version:k}:{name:c(/^(.*)\/(.*) /),version:d(/^(.*)\/(.*) /)},!e.msedge&&/(apple)?webkit/i.test(a)?(e.name=e.name||"Webkit",e.webkit=b,!e.version&&k&&(e.version=k)):!e.opera&&/gecko\//i.test(a)&&(e.name=e.name||"Gecko",e.gecko=b,e.version=e.version||c(/gecko\/(\d+(\.\d+)?)/i)),e.msedge||!h&&!e.silk?f&&(e[f]=b,e.ios=b):e.android=b;var n="";e.windowsphone?n=c(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i):f?(n=c(/os (\d+([_\s]\d+)*) like mac os x/i),n=n.replace(/[_\s]/g,".")):h?n=c(/android[ \/-](\d+(\.\d+)*)/i):e.webos?n=c(/(?:web|hpw)os\/(\d+(\.\d+)*)/i):e.blackberry?n=c(/rim\stablet\sos\s(\d+(\.\d+)*)/i):e.bada?n=c(/bada\/(\d+(\.\d+)*)/i):e.tizen&&(n=c(/tizen[\/\s](\d+(\.\d+)*)/i)),n&&(e.osversion=n);var o=n.split(".")[0];return l||"ipad"==f||h&&(3==o||4==o&&!m)||e.silk?e.tablet=b:(m||"iphone"==f||"ipod"==f||h||e.blackberry||e.webos||e.bada)&&(e.mobile=b),e.msedge||e.msie&&e.version>=10||e.yandexbrowser&&e.version>=15||e.chrome&&e.version>=20||e.firefox&&e.version>=20||e.safari&&e.version>=6||e.opera&&e.version>=10||e.ios&&e.osversion&&e.osversion.split(".")[0]>=6||e.blackberry&&e.version>=10.1?e.a=b:e.msie&&e.version<10||e.chrome&&e.version<20||e.firefox&&e.version<20||e.safari&&e.version<6||e.opera&&e.version<10||e.ios&&e.osversion&&e.osversion.split(".")[0]<
(function() {
"use strict";
var diffcount;
var Diff = function (options) {
var diff = this;
Object.keys(options).forEach(function(option) {
diff[option] = options[option];
});
};
Diff.prototype = {
toString: function() {
return JSON.stringify(this);
}
// TODO: compress diff output by replacing these keys with numbers or alike:
/* 'addAttribute' = 0,
'modifyAttribute' = 1,
'removeAttribute' = 2,
'modifyTextElement' = 3,
'relocateGroup' = 4,
'removeElement' = 5,
'addElement' = 6,
'removeTextElement' = 7,
'addTextElement' = 8,
'replaceElement' = 9,
'modifyValue' = 10,
'modifyChecked' = 11,
'modifySelected' = 12,
'modifyComment' = 13,
'action' = 14,
'route' = 15,
'oldValue' = 16,
'newValue' = 17,
'element' = 18,
'group' = 19,
'from' = 20,
'to' = 21,
'name' = 22,
'value' = 23,
'data' = 24,
'attributes' = 25,
'nodeName' = 26,
'childNodes' = 27,
'checked' = 28,
'selected' = 29;*/
};
var SubsetMapping = function SubsetMapping(a, b) {
this.oldValue = a;
this.newValue = b;
};
SubsetMapping.prototype = {
contains: function contains(subset) {
if (subset.length < this.length) {
return subset.newValue >= this.newValue && subset.newValue < this.newValue + this.length;
}
return false;
},
toString: function toString() {
return this.length + " element subset, first mapping: old " + this.oldValue + " → new " + this.newValue;
}
};
var elementDescriptors = function(el) {
var output = [];
if (el.nodeName !== '#text' && el.nodeName !== '#comment') {
output.push(el.nodeName);
if (el.attributes) {
if (el.attributes['class']) {
output.push(el.nodeName + '.' + el.attributes['class'].replace(/ /g, '.'));
}
if (el.attributes.id) {
output.push(el.nodeName + '#' + el.attributes.id);
}
}
}
return output;
};
var findUniqueDescriptors = function(li) {
var uniqueDescriptors = {},
duplicateDescriptors = {};
li.forEach(function(node) {
elementDescriptors(node).forEach(function(descriptor) {
var inUnique = descriptor in uniqueDescriptors,
inDupes = descriptor in duplicateDescriptors;
if (!inUnique && !inDupes) {
uniqueDescriptors[descriptor] = true;
} else if (inUnique) {
delete uniqueDescriptors[descriptor];
duplicateDescriptors[descriptor] = true;
}
});
});
return uniqueDescriptors;
};
var uniqueInBoth = function(l1, l2) {
var l1Unique = findUniqueDescriptors(l1),
l2Unique = findUniqueDescriptors(l2),
inBoth = {};
Object.keys(l1Unique).forEach(function(key) {
if (l2Unique[key]) {
inBoth[key] = true;
}
});
return inBoth;
};
var removeDone = function(tree) {
delete tree.outerDone;
delete tree.innerDone;
delete tree.valueDone;
if (tree.childNodes) {
return tree.childNodes.every(removeDone);
} else {
return true;
}
};
var isEqual = function(e1, e2) {
var e1Attributes, e2Attributes;
if (!['nodeName', 'value', 'checked', 'selected', 'data'].every(function(element) {
if (e1[element] !== e2[element]) {
return false;
}
return true;
})) {
return false;
}
if (Boolean(e1.attributes) !== Boolean(e2.attributes)) {
return false;
}
if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) {
return false;
}
if (e1.attributes) {
e1Attributes = Object.keys(e1.attributes);
e2Attributes = Object.keys(e2.attributes);
if (e1Attributes.length !== e2Attributes.length) {
return false;
}
if (!e1Attributes.every(function(attribute) {
if (e1.attributes[attribute] !== e2.attributes[attribute]) {
return false;
}
})) {
return false;
}
}
if (e1.childNodes) {
if (e1.childNodes.length !== e2.childNodes.length) {
return false;
}
if (!e1.childNodes.every(function(childNode, index) {
return isEqual(childNode, e2.childNodes[index]);
})) {
return false;
}
}
return true;
};
var roughlyEqual = function(e1, e2, uniqueDescriptors, sameSiblings, preventRecursion) {
var childUniqueDescriptors, nodeList1, nodeList2;
if (!e1 || !e2) {
return false;
}
if (e1.nodeName !== e2.nodeName) {
return false;
}
if (e1.nodeName === '#text') {
// Note that we initially don't care what the text content of a node is,
// the mere fact that it's the same tag and "has text" means it's roughly
// equal, and then we can find out the true text difference later.
return preventRecursion ? true : e1.data === e2.data;
}
if (e1.nodeName in uniqueDescriptors) {
return true;
}
if (e1.attributes && e2.attributes) {
if (e1.attributes.id && e1.attributes.id === e2.attributes.id) {
var idDescriptor = e1.nodeName + '#' + e1.attributes.id;
if (idDescriptor in uniqueDescriptors) {
return true;
}
}
if (e1.attributes['class'] && e1.attributes['class'] === e2.attributes['class']) {
var classDescriptor = e1.nodeName + '.' + e1.attributes['class'].replace(/ /g, '.');
if (classDescriptor in uniqueDescriptors) {
return true;
}
}
}
if (sameSiblings) {
return true;
}
nodeList1 = e1.childNodes ? e1.childNodes.slice().reverse() : [];
nodeList2 = e2.childNodes ? e2.childNodes.slice().reverse() : [];
if (nodeList1.length !== nodeList2.length) {
return false;
}
if (preventRecursion) {
return nodeList1.every(function(element, index) {
return element.nodeName === nodeList2[index].nodeName;
});
} else {
// note: we only allow one level of recursion at any depth. If 'preventRecursion'
// was not set, we must explicitly force it to true for child iterations.
childUniqueDescriptors = uniqueInBoth(nodeList1, nodeList2);
return nodeList1.every(function(element, index) {
return roughlyEqual(element, nodeList2[index], childUniqueDescriptors, true, true);
});
}
};
var cloneObj = function(obj) {
// TODO: Do we really need to clone here? Is it not enough to just return the original object?
return JSON.parse(JSON.stringify(obj));
//return obj;
};
/**
* based on https://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#JavaScript
*/
var findCommonSubsets = function(c1, c2, marked1, marked2) {
var lcsSize = 0,
index = [],
matches = Array.apply(null, new Array(c1.length + 1)).map(function() {
return [];
}), // set up the matching table
uniqueDescriptors = uniqueInBoth(c1, c2),
// If all of the elements are the same tag, id and class, then we can
// consider them roughly the same even if they have a different number of
// children. This will reduce removing and re-adding similar elements.
subsetsSame = c1.length === c2.length,
origin, ret;
if (subsetsSame) {
c1.some(function(element, i) {
var c1Desc = elementDescriptors(element),
c2Desc = elementDescriptors(c2[i]);
if (c1Desc.length !== c2Desc.length) {
subsetsSame = false;
return true;
}
c1Desc.some(function(description, i) {
if (description !== c2Desc[i]) {
subsetsSame = false;
return true;
}
});
if (!subsetsSame) {
return true;
}
});
}
// fill the matches with distance values
c1.forEach(function(c1Element, c1Index) {
c2.forEach(function(c2Element, c2Index) {
if (!marked1[c1Index] && !marked2[c2Index] && roughlyEqual(c1Element, c2Element, uniqueDescriptors, subsetsSame)) {
matches[c1Index + 1][c2Index + 1] = (matches[c1Index][c2Index] ? matches[c1Index][c2Index] + 1 : 1);
if (matches[c1Index + 1][c2Index + 1] >= lcsSize) {
lcsSize = matches[c1Index + 1][c2Index + 1];
index = [c1Index + 1, c2Index + 1];
}
} else {
matches[c1Index + 1][c2Index + 1] = 0;
}
});
});
if (lcsSize === 0) {
return false;
}
origin = [index[0] - lcsSize, index[1] - lcsSize];
ret = new SubsetMapping(origin[0], origin[1]);
ret.length = lcsSize;
return ret;
};
/**
* This should really be a predefined function in Array...
*/
var makeArray = function(n, v) {
return Array.apply(null, new Array(n)).map(function() {
return v;
});
};
/**
* Generate arrays that indicate which node belongs to which subset,
* or whether it's actually an orphan node, existing in only one
* of the two trees, rather than somewhere in both.
*
* So if t1 = <img><canvas><br>, t2 = <canvas><br><img>.
* The longest subset is "<canvas><br>" (length 2), so it will group 0.
* The second longest is "<img>" (length 1), so it will be group 1.
* gaps1 will therefore be [1,0,0] and gaps2 [0,0,1].
*
* If an element is not part of any group, it will stay being 'true', which
* is the initial value. For example:
* t1 = <img><p></p><br><canvas>, t2 = <b></b><br><canvas><img>
*
* The "<p></p>" and "<b></b>" do only show up in one of the two and will
* therefore be marked by "true". The remaining parts are parts of the
* groups 0 and 1:
* gaps1 = [1, true, 0, 0], gaps2 = [true, 0, 0, 1]
*
*/
var getGapInformation = function(t1, t2, stable) {
var gaps1 = t1.childNodes ? makeArray(t1.childNodes.length, true) : [],
gaps2 = t2.childNodes ? makeArray(t2.childNodes.length, true) : [],
group = 0;
// give elements from the same subset the same group number
stable.forEach(function(subset) {
var i, endOld = subset.oldValue + subset.length,
endNew = subset.newValue + subset.length;
for (i = subset.oldValue; i < endOld; i += 1) {
gaps1[i] = group;
}
for (i = subset.newValue; i < endNew; i += 1) {
gaps2[i] = group;
}
group += 1;
});
return {
gaps1: gaps1,
gaps2: gaps2
};
};
/**
* Find all matching subsets, based on immediate child differences only.
*/
var markSubTrees = function(oldTree, newTree) {
// note: the child lists are views, and so update as we update old/newTree
var oldChildren = oldTree.childNodes ? oldTree.childNodes : [],
newChildren = newTree.childNodes ? newTree.childNodes : [],
marked1 = makeArray(oldChildren.length, false),
marked2 = makeArray(newChildren.length, false),
subsets = [],
subset = true,
returnIndex = function() {
return arguments[1];
},
markBoth = function(i) {
marked1[subset.oldValue + i] = true;
marked2[subset.newValue + i] = true;
};
while (subset) {
subset = findCommonSubsets(oldChildren, newChildren, marked1, marked2);
if (subset) {
subsets.push(subset);
Array.apply(null, new Array(subset.length)).map(returnIndex).forEach(markBoth);
}
}
return subsets;
};
function swap(obj, p1, p2) {
(function(_) {
obj[p1] = obj[p2];
obj[p2] = _;
}(obj[p1]));
}
var DiffTracker = function() {
this.list = [];
};
DiffTracker.prototype = {
list: false,
add: function(diffs) {
var list = this.list;
diffs.forEach(function(diff) {
list.push(diff);
});
},
forEach: function(fn) {
this.list.forEach(fn);
}
};
var diffDOM = function(options) {
var defaults = {
debug: false,
diffcap: 10, // Limit for how many diffs are accepting when debugging. Inactive when debug is false.
maxDepth: false, // False or a numeral. If set to a numeral, limits the level of depth that the the diff mechanism looks for differences. If false, goes through the entire tree.
valueDiffing: true, // Whether to take into consideration the values of forms that differ from auto assigned values (when a user fills out a form).
// syntax: textDiff: function (node, currentValue, expectedValue, newValue)
textDiff: function() {
arguments[0].data = arguments[3];
return;
},
// empty functions were benchmarked as running faster than both
// `f && f()` and `if (f) { f(); }`
preVirtualDiffApply: function () {},
postVirtualDiffApply: function () {},
preDiffApply: function () {},
postDiffApply: function () {}
},
i;
if (typeof options === "undefined") {
options = {};
}
for (i in defaults) {
if (typeof options[i] === "undefined") {
this[i] = defaults[i];
} else {
this[i] = options[i];
}
}
};
diffDOM.prototype = {
// ===== Create a diff =====
diff: function(t1Node, t2Node) {
var t1 = this.nodeToObj(t1Node),
t2 = this.nodeToObj(t2Node);
diffcount = 0;
if (this.debug) {
this.t1Orig = this.nodeToObj(t1Node);
this.t2Orig = this.nodeToObj(t2Node);
}
this.tracker = new DiffTracker();
return this.findDiffs(t1, t2);
},
findDiffs: function(t1, t2) {
var diffs;
do {
if (this.debug) {
diffcount += 1;
if (diffcount > this.diffcap) {
window.diffError = [this.t1Orig, this.t2Orig];
throw new Error("surpassed diffcap:" + JSON.stringify(this.t1Orig) + " -> " + JSON.stringify(this.t2Orig));
}
}
diffs = this.findNextDiff(t1, t2, []);
if (diffs.length === 0) {
// Last check if the elements really are the same now.
// If not, remove all info about being done and start over.
// Somtimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed anyway.
if (!isEqual(t1, t2)) {
removeDone(t1);
diffs = this.findNextDiff(t1, t2, []);
}
}
if (diffs.length > 0) {
this.tracker.add(diffs);
this.applyVirtual(t1, diffs);
}
} while (diffs.length > 0);
return this.tracker.list;
},
findNextDiff: function(t1, t2, route) {
var diffs;
if (this.maxDepth && route.length > this.maxDepth) {
return [];
}
// outer differences?
if (!t1.outerDone) {
diffs = this.findOuterDiff(t1, t2, route);
if (diffs.length > 0) {
t1.outerDone = true;
return diffs;
} else {
t1.outerDone = true;
}
}
// inner differences?
if (!t1.innerDone) {
diffs = this.findInnerDiff(t1, t2, route);
if (diffs.length > 0) {
return diffs;
} else {
t1.innerDone = true;
}
}
if (this.valueDiffing && !t1.valueDone) {
// value differences?
diffs = this.findValueDiff(t1, t2, route);
if (diffs.length > 0) {
t1.valueDone = true;
return diffs;
} else {
t1.valueDone = true;
}
}
// no differences
return [];
},
findOuterDiff: function(t1, t2, route) {
var diffs = [],
attr1, attr2;
if (t1.nodeName !== t2.nodeName) {
return [new Diff({
action: 'replaceElement',
oldValue: cloneObj(t1),
newValue: cloneObj(t2),
route: route
})];
}
if (t1.data !== t2.data) {
// Comment or text node.
if (t1.nodeName === '#text') {
return [new Diff({
action: 'modifyComment',
route: route,
oldValue: t1.data,
newValue: t2.data
})];
} else {
return [new Diff({
action: 'modifyTextElement',
route: route,
oldValue: t1.data,
newValue: t2.data
})];
}
}
attr1 = t1.attributes ? Object.keys(t1.attributes).sort() : [];
attr2 = t2.attributes ? Object.keys(t2.attributes).sort() : [];
attr1.forEach(function(attr) {
var pos = attr2.indexOf(attr);
if (pos === -1) {
diffs.push(new Diff({
action: 'removeAttribute',
route: route,
name: attr,
value: t1.attributes[attr]
}));
} else {
attr2.splice(pos, 1);
if (t1.attributes[attr] !== t2.attributes[attr]) {
diffs.push(new Diff({
action: 'modifyAttribute',
route: route,
name: attr,
oldValue: t1.attributes[attr],
newValue: t2.attributes[attr]
}));
}
}
});
attr2.forEach(function(attr) {
diffs.push(new Diff({
action: 'addAttribute',
route: route,
name: attr,
value: t2.attributes[attr]
}));
});
return diffs;
},
nodeToObj: function(node) {
var objNode = {}, dobj = this;
objNode.nodeName = node.nodeName;
if (objNode.nodeName === '#text' || objNode.nodeName === '#comment') {
objNode.data = node.data;
} else {
if (node.attributes && node.attributes.length > 0) {
objNode.attributes = {};
Array.prototype.slice.call(node.attributes).forEach(
function(attribute) {
objNode.attributes[attribute.name] = attribute.value;
}
);
}
if (node.childNodes && node.childNodes.length > 0) {
objNode.childNodes = [];
Array.prototype.slice.call(node.childNodes).forEach(
function(childNode) {
objNode.childNodes.push(dobj.nodeToObj(childNode));
}
);
}
if (this.valueDiffing) {
if (node.value !== undefined) {
objNode.value = node.value;
}
if (node.checked !== undefined) {
objNode.checked = node.checked;
}
if (node.selected !== undefined) {
objNode.selected = node.selected;
}
}
}
return objNode;
},
objToNode: function(objNode, insideSvg) {
var node, dobj = this;
if (objNode.nodeName === '#text') {
node = document.createTextNode(objNode.data);
} else if (objNode.nodeName === '#comment') {
node = document.createComment(objNode.data);
} else {
if (objNode.nodeName === 'svg' || insideSvg) {
node = document.createElementNS('http://www.w3.org/2000/svg', objNode.nodeName);
insideSvg = true;
} else {
node = document.createElement(objNode.nodeName);
}
if (objNode.attributes) {
Object.keys(objNode.attributes).forEach(function(attribute) {
node.setAttribute(attribute, objNode.attributes[attribute]);
});
}
if (objNode.childNodes) {
objNode.childNodes.forEach(function(childNode) {
node.appendChild(dobj.objToNode(childNode, insideSvg));
});
}
if (this.valueDiffing) {
if (objNode.value) {
node.value = objNode.value;
}
if (objNode.checked) {
node.checked = objNode.checked;
}
if (objNode.selected) {
node.selected = objNode.selected;
}
}
}
return node;
},
findInnerDiff: function(t1, t2, route) {
var subtrees = (t1.childNodes && t2.childNodes) ? markSubTrees(t1, t2) : [],
t1ChildNodes = t1.childNodes ? t1.childNodes : [],
t2ChildNodes = t2.childNodes ? t2.childNodes : [],
childNodesLengthDifference, diffs = [],
index = 0,
last, e1, e2, i;
if (subtrees.length > 1) {
/* Two or more groups have been identified among the childnodes of t1
* and t2.
*/
return this.attemptGroupRelocation(t1, t2, subtrees, route);
}
/* 0 or 1 groups of similar child nodes have been found
* for t1 and t2. 1 If there is 1, it could be a sign that the
* contents are the same. When the number of groups is below 2,
* t1 and t2 are made to have the same length and each of the
* pairs of child nodes are diffed.
*/
last = Math.max(t1ChildNodes.length, t2ChildNodes.length);
if (t1ChildNodes.length !== t2ChildNodes.length) {
childNodesLengthDifference = true;
}
for (i = 0; i < last; i += 1) {
e1 = t1ChildNodes[i];
e2 = t2ChildNodes[i];
if (childNodesLengthDifference) {
/* t1 and t2 have different amounts of childNodes. Add
* and remove as necessary to obtain the same length */
if (e1 && !e2) {
if (e1.nodeName === '#text') {
diffs.push(new Diff({
action: 'removeTextElement',
route: route.concat(index),
value: e1.data
}));
index -= 1;
} else {
diffs.push(new Diff({
action: 'removeElement',
route: route.concat(index),
element: cloneObj(e1)
}));
index -= 1;
}
} else if (e2 && !e1) {
if (e2.nodeName === '#text') {
diffs.push(new Diff({
action: 'addTextElement',
route: route.concat(index),
value: e2.data
}));
} else {
diffs.push(new Diff({
action: 'addElement',
route: route.concat(index),
element: cloneObj(e2)
}));
}
}
}
/* We are now guaranteed that childNodes e1 and e2 exist,
* and that they can be diffed.
*/
/* Diffs in child nodes should not affect the parent node,
* so we let these diffs be submitted together with other
* diffs.
*/
if (e1 && e2) {
diffs = diffs.concat(this.findNextDiff(e1, e2, route.concat(index)));
}
index += 1;
}
t1.innerDone = true;
return diffs;
},
attemptGroupRelocation: function(t1, t2, subtrees, route) {
/* Either t1.childNodes and t2.childNodes have the same length, or
* there are at least two groups of similar elements can be found.
* attempts are made at equalizing t1 with t2. First all initial
* elements with no group affiliation (gaps=true) are removed (if
* only in t1) or added (if only in t2). Then the creation of a group
* relocation diff is attempted.
*/
var gapInformation = getGapInformation(t1, t2, subtrees),
gaps1 = gapInformation.gaps1,
gaps2 = gapInformation.gaps2,
shortest = Math.min(gaps1.length, gaps2.length),
destinationDifferent, toGroup,
group, node, similarNode, testI, diffs = [],
index1, index2, j;
for (index2 = 0, index1 = 0; index2 < shortest; index1 += 1, index2 += 1) {
if (gaps1[index2] === true) {
node = t1.childNodes[index1];
if (node.nodeName === '#text') {
if (t2.childNodes[index2].nodeName === '#text' && node.data !== t2.childNodes[index2].data) {
testI = index1;
while (t1.childNodes.length > testI + 1 && t1.childNodes[testI + 1].nodeName === '#text') {
testI += 1;
if (t2.childNodes[index2].data === t1.childNodes[testI].data) {
similarNode = true;
break;
}
}
if (!similarNode) {
diffs.push(new Diff({
action: 'modifyTextElement',
route: route.concat(index2),
oldValue: node.data,
newValue: t2.childNodes[index2].data
}));
}
}
diffs.push(new Diff({
action: 'removeTextElement',
route: route.concat(index2),
value: node.data
}));
gaps1.splice(index2, 1);
shortest = Math.min(gaps1.length, gaps2.length);
index2 -= 1;
} else {
diffs.push(new Diff({
action: 'removeElement',
route: route.concat(index2),
element: cloneObj(node)
}));
gaps1.splice(index2, 1);
shortest = Math.min(gaps1.length, gaps2.length);
index2 -= 1;
}
} else if (gaps2[index2] === true) {
node = t2.childNodes[index2];
if (node.nodeName === '#text') {
diffs.push(new Diff({
action: 'addTextElement',
route: route.concat(index2),
value: node.data
}));
gaps1.splice(index2, 0, true);
shortest = Math.min(gaps1.length, gaps2.length);
index1 -= 1;
} else {
diffs.push(new Diff({
action: 'addElement',
route: route.concat(index2),
element: cloneObj(node)
}));
gaps1.splice(index2, 0, true);
shortest = Math.min(gaps1.length, gaps2.length);
index1 -= 1;
}
} else if (gaps1[index2] !== gaps2[index2]) {
if (diffs.length > 0) {
return diffs;
}
// group relocation
group = subtrees[gaps1[index2]];
toGroup = Math.min(group.newValue, (t1.childNodes.length - group.length));
if (toGroup !== group.oldValue) {
// Check whether destination nodes are different than originating ones.
destinationDifferent = false;
for (j = 0; j < group.length; j += 1) {
if (!roughlyEqual(t1.childNodes[toGroup + j], t1.childNodes[group.oldValue + j], [], false, true)) {
destinationDifferent = true;
}
}
if (destinationDifferent) {
return [new Diff({
action: 'relocateGroup',
groupLength: group.length,
from: group.oldValue,
to: toGroup,
route: route
})];
}
}
}
}
return diffs;
},
findValueDiff: function(t1, t2, route) {
// Differences of value. Only useful if the value/selection/checked value
// differs from what is represented in the DOM. For example in the case
// of filled out forms, etc.
var diffs = [];
if (t1.selected !== t2.selected) {
diffs.push(new Diff({
action: 'modifySelected',
oldValue: t1.selected,
newValue: t2.selected,
route: route
}));
}
if ((t1.value || t2.value) && t1.value !== t2.value && t1.nodeName !== 'OPTION') {
diffs.push(new Diff({
action: 'modifyValue',
oldValue: t1.value,
newValue: t2.value,
route: route
}));
}
if (t1.checked !== t2.checked) {
diffs.push(new Diff({
action: 'modifyChecked',
oldValue: t1.checked,
newValue: t2.checked,
route: route
}));
}
return diffs;
},
// ===== Apply a virtual diff =====
applyVirtual: function(tree, diffs) {
var dobj = this;
if (diffs.length === 0) {
return true;
}
diffs.forEach(function(diff) {
dobj.applyVirtualDiff(tree, diff);
});
return true;
},
getFromVirtualRoute: function(tree, route) {
var node = tree,
parentNode, nodeIndex;
route = route.slice();
while (route.length > 0) {
if (!node.childNodes) {
return false;
}
nodeIndex = route.splice(0, 1)[0];
parentNode = node;
node = node.childNodes[nodeIndex];
}
return {
node: node,
parentNode: parentNode,
nodeIndex: nodeIndex
};
},
applyVirtualDiff: function(tree, diff) {
var routeInfo = this.getFromVirtualRoute(tree, diff.route),
node = routeInfo.node,
parentNode = routeInfo.parentNode,
nodeIndex = routeInfo.nodeIndex,
newNode, route, c;
// pre-diff hook
var info = {
diff: diff,
node: node
};
if (this.preVirtualDiffApply(info)) { return true; }
switch (diff.action) {
case 'addAttribute':
if (!node.attributes) {
node.attributes = {};
}
node.attributes[diff.name] = diff.value;
if (diff.name === 'checked') {
node.checked = true;
} else if (diff.name === 'selected') {
node.selected = true;
} else if (node.nodeName === 'INPUT' && diff.name === 'value') {
node.value = diff.value;
}
break;
case 'modifyAttribute':
node.attributes[diff.name] = diff.newValue;
if (node.nodeName === 'INPUT' && diff.name === 'value') {
node.value = diff.value;
}
break;
case 'removeAttribute':
delete node.attributes[diff.name];
if (Object.keys(node.attributes).length === 0) {
delete node.attributes;
}
if (diff.name === 'checked') {
delete node.checked;
} else if (diff.name === 'selected') {
delete node.selected;
} else if (node.nodeName === 'INPUT' && diff.name === 'value') {
delete node.value;
}
break;
case 'modifyTextElement':
node.data = diff.newValue;
if (parentNode.nodeName === 'TEXTAREA') {
parentNode.value = diff.newValue;
}
break;
case 'modifyValue':
node.value = diff.newValue;
break;
case 'modifyComment':
node.data = diff.newValue;
break;
case 'modifyChecked':
node.checked = diff.newValue;
break;
case 'modifySelected':
node.selected = diff.newValue;
break;
case 'replaceElement':
newNode = cloneObj(diff.newValue);
newNode.outerDone = true;
newNode.innerDone = true;
newNode.valueDone = true;
parentNode.childNodes[nodeIndex] = newNode;
break;
case 'relocateGroup':
node.childNodes.splice(diff.from, diff.groupLength).reverse()
.forEach(function(movedNode) {
node.childNodes.splice(diff.to, 0, movedNode);
});
break;
case 'removeElement':
parentNode.childNodes.splice(nodeIndex, 1);
break;
case 'addElement':
route = diff.route.slice();
c = route.splice(route.length - 1, 1)[0];
node = this.getFromVirtualRoute(tree, route).node;
newNode = cloneObj(diff.element);
newNode.outerDone = true;
newNode.innerDone = true;
newNode.valueDone = true;
if (!node.childNodes) {
node.childNodes = [];
}
if (c >= node.childNodes.length) {
node.childNodes.push(newNode);
} else {
node.childNodes.splice(c, 0, newNode);
}
break;
case 'removeTextElement':
parentNode.childNodes.splice(nodeIndex, 1);
if (parentNode.nodeName === 'TEXTAREA') {
delete parentNode.value;
}
break;
case 'addTextElement':
route = diff.route.slice();
c = route.splice(route.length - 1, 1)[0];
newNode = {};
newNode.nodeName = '#text';
newNode.data = diff.value;
node = this.getFromVirtualRoute(tree, route).node;
if (!node.childNodes) {
node.childNodes = [];
}
if (c >= node.childNodes.length) {
node.childNodes.push(newNode);
} else {
node.childNodes.splice(c, 0, newNode);
}
if (node.nodeName === 'TEXTAREA') {
node.value = diff.newValue;
}
break;
default:
console.log('unknown action');
}
// capture newNode for the callback
info.newNode = newNode;
this.postVirtualDiffApply(info);
return;
},
// ===== Apply a diff =====
apply: function(tree, diffs) {
var dobj = this;
if (diffs.length === 0) {
return true;
}
diffs.forEach(function(diff) {
if (!dobj.applyDiff(tree, diff)) {
return false;
}
});
return true;
},
getFromRoute: function(tree, route) {
route = route.slice();
var c, node = tree;
while (route.length > 0) {
if (!node.childNodes) {
return false;
}
c = route.splice(0, 1)[0];
node = node.childNodes[c];
}
return node;
},
applyDiff: function(tree, diff) {
var node = this.getFromRoute(tree, diff.route),
newNode, reference, route, c;
// pre-diff hook
var info = {
diff: diff,
node: node
};
if (this.preDiffApply(info)) { return true; }
switch (diff.action) {
case 'addAttribute':
if (!node || !node.setAttribute) {
return false;
}
node.setAttribute(diff.name, diff.value);
break;
case 'modifyAttribute':
if (!node || !node.setAttribute) {
return false;
}
node.setAttribute(diff.name, diff.newValue);
break;
case 'removeAttribute':
if (!node || !node.removeAttribute) {
return false;
}
node.removeAttribute(diff.name);
break;
case 'modifyTextElement':
if (!node || node.nodeType !== 3) {
return false;
}
this.textDiff(node, node.data, diff.oldValue, diff.newValue);
break;
case 'modifyValue':
if (!node || typeof node.value === 'undefined') {
return false;
}
node.value = diff.newValue;
break;
case 'modifyComment':
if (!node || typeof node.data === 'undefined') {
return false;
}
this.textDiff(node, node.data, diff.oldValue, diff.newValue);
break;
case 'modifyChecked':
if (!node || typeof node.checked === 'undefined') {
return false;
}
node.checked = diff.newValue;
break;
case 'modifySelected':
if (!node || typeof node.selected === 'undefined') {
return false;
}
node.selected = diff.newValue;
break;
case 'replaceElement':
node.parentNode.replaceChild(this.objToNode(diff.newValue, node.namespaceURI === 'http://www.w3.org/2000/svg'), node);
break;
case 'relocateGroup':
Array.apply(null, new Array(diff.groupLength)).map(function() {
return node.removeChild(node.childNodes[diff.from]);
}).forEach(function(childNode, index) {
if (index === 0) {
reference = node.childNodes[diff.to];
}
node.insertBefore(childNode, reference);
});
break;
case 'removeElement':
node.parentNode.removeChild(node);
break;
case 'addElement':
route = diff.route.slice();
c = route.splice(route.length - 1, 1)[0];
node = this.getFromRoute(tree, route);
node.insertBefore(this.objToNode(diff.element, node.namespaceURI === 'http://www.w3.org/2000/svg'), node.childNodes[c]);
break;
case 'removeTextElement':
if (!node || node.nodeType !== 3) {
return false;
}
node.parentNode.removeChild(node);
break;
case 'addTextElement':
route = diff.route.slice();
c = route.splice(route.length - 1, 1)[0];
newNode = document.createTextNode(diff.value);
node = this.getFromRoute(tree, route);
if (!node || !node.childNodes) {
return false;
}
node.insertBefore(newNode, node.childNodes[c]);
break;
default:
console.log('unknown action');
}
// if a new node was created, we might be interested in it
// post diff hook
info.newNode = newNode;
this.postDiffApply(info);
return true;
},
// ===== Undo a diff =====
undo: function(tree, diffs) {
diffs = diffs.slice();
var dobj = this;
if (!diffs.length) {
diffs = [diffs];
}
diffs.reverse();
diffs.forEach(function(diff) {
dobj.undoDiff(tree, diff);
});
},
undoDiff: function(tree, diff) {
switch (diff.action) {
case 'addAttribute':
diff.action = 'removeAttribute';
this.applyDiff(tree, diff);
break;
case 'modifyAttribute':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'removeAttribute':
diff.action = 'addAttribute';
this.applyDiff(tree, diff);
break;
case 'modifyTextElement':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'modifyValue':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'modifyComment':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'modifyChecked':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'modifySelected':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'replaceElement':
swap(diff, 'oldValue', 'newValue');
this.applyDiff(tree, diff);
break;
case 'relocateGroup':
swap(diff, 'from', 'to');
this.applyDiff(tree, diff);
break;
case 'removeElement':
diff.action = 'addElement';
this.applyDiff(tree, diff);
break;
case 'addElement':
diff.action = 'removeElement';
this.applyDiff(tree, diff);
break;
case 'removeTextElement':
diff.action = 'addTextElement';
this.applyDiff(tree, diff);
break;
case 'addTextElement':
diff.action = 'removeTextElement';
this.applyDiff(tree, diff);
break;
default:
console.log('unknown action');
}
}
};
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = diffDOM;
}
exports.diffDOM = diffDOM;
} else {
// `window` in the browser, or `exports` on the server
this.diffDOM = diffDOM;
}
}.call(this));
"use strict";!function(t,e){e.GOVUK=e.GOVUK||{},GOVUK.Modules=GOVUK.Modules||{},GOVUK.modules={find:function(e){var n,r="[data-module]",e=e||t("body");return n=e.find(r),e.is(r)&&(n=n.add(e)),n},start:function(e){function n(t){return u(r(t))}function r(t){return t.replace(/-([a-z])/g,function(t){return t[1].toUpperCase()})}function u(t){return t.charAt(0).toUpperCase()+t.slice(1)}for(var o=this.find(e),d=0,a=o.length;a>d;d++){var i,s=t(o[d]),f=n(s.data("module")),c=s.data("module-started");"function"!=typeof GOVUK.Modules[f]||c||(i=new GOVUK.Modules[f],i.start(s),s.data("module-started",!0))}}}}(jQuery,window);
"use strict";(function(){var e=this,t=e.jQuery;"undefined"==typeof GOVUK&&(e.GOVUK={});var s=function(e,s){var i;this.selectedClass="selected",this.focusedClass="focused",void 0!==s&&t.each(s,function(e,t){this[e]=t}.bind(this)),"string"==typeof e?(i=t(e),this.selector=e,this.setInitialState(t(this.selector))):void 0!==e&&(this.$elms=e,this.setInitialState(this.$elms)),this.addEvents()};s.prototype.addEvents=function(){"undefined"!=typeof this.$elms?this.addElementLevelEvents():this.addDocumentLevelEvents()},s.prototype.setInitialState=function(e){e.each(function(e,s){var i=t(s);i.is(":checked")&&this.markSelected(i)}.bind(this))},s.prototype.markFocused=function(e,t){"focused"===t?e.parent("label").addClass(this.focusedClass):e.parent("label").removeClass(this.focusedClass)},s.prototype.markSelected=function(e){var s;"radio"===e.attr("type")?(s=e.attr("name"),t(e[0].form).find('input[name="'+s+'"]').parent("label").removeClass(this.selectedClass),e.parent("label").addClass(this.selectedClass)):e.is(":checked")?e.parent("label").addClass(this.selectedClass):e.parent("label").removeClass(this.selectedClass)},s.prototype.addElementLevelEvents=function(){this.clickHandler=this.getClickHandler(),this.focusHandler=this.getFocusHandler({level:"element"}),this.$elms.on("click",this.clickHandler).on("focus blur",this.focusHandler)},s.prototype.addDocumentLevelEvents=function(){this.clickHandler=this.getClickHandler(),this.focusHandler=this.getFocusHandler({level:"document"}),t(document).on("click",this.selector,this.clickHandler).on("focus blur",this.selector,this.focusHandler)},s.prototype.getClickHandler=function(){return function(e){this.markSelected(t(e.target))}.bind(this)},s.prototype.getFocusHandler=function(e){var s="document"===e.level?"focusin":"focus";return function(e){var i=e.type===s?"focused":"blurred";this.markFocused(t(e.target),i)}.bind(this)},s.prototype.destroy=function(){"undefined"!=typeof this.selector?t(document).off("click",this.selector,this.clickHandler).off("focus blur",this.selector,this.focusHandler):this.$elms.off("click",this.clickHandler).off("focus blur",this.focusHandler)},e.GOVUK.SelectionButtons=s}).call(void 0);
"use strict";!function(){function e(e,t,n){e.addEventListener?e.addEventListener(t,function(e){n(e,e.target)},!1):e.attachEvent&&e.attachEvent("on"+t,function(e){n(e,e.srcElement)})}function t(t,n){e(t,"keypress",function(e,t){"SUMMARY"===t.nodeName&&32===e.keyCode&&(e.preventDefault?e.preventDefault():e.returnValue=!1)}),e(t,"keyup",function(e,t){(13===e.keyCode||32===e.keyCode)&&n(e,t)}),e(t,"mouseup",function(e,t){n(e,t)})}function n(e,t){do if(!e||e.nodeName.toLowerCase()===t)break;while(e=e.parentNode);return e}function a(e){function a(e){var t="true"===e.__details.__summary.getAttribute("aria-expanded"),n="true"===e.__details.__content.getAttribute("aria-hidden");if(e.__details.__summary.setAttribute("aria-expanded",t?"false":"true"),e.__details.__content.setAttribute("aria-hidden",n?"false":"true"),!r){e.__details.__content.style.display=t?"none":"";var a=null!==e.__details.getAttribute("open");a?e.__details.removeAttribute("open"):e.__details.setAttribute("open","open")}return e.__twisty&&(e.__twisty.firstChild.nodeValue=t?"►":"▼",e.__twisty.setAttribute("class",t?"arrow arrow-closed":"arrow arrow-open")),!0}if(!i&&(i=!0,0!==(e=document.getElementsByTagName("details")).length)){var o=e.length,s=0;for(s;o>s;s++){var u=e[s];u.__summary=u.getElementsByTagName("summary").item(0),u.__content=u.getElementsByTagName("div").item(0),u.__content.id||(u.__content.id="details-content-"+s),u.setAttribute("role","group"),u.__summary.setAttribute("role","button"),u.__summary.setAttribute("aria-controls",u.__content.id),r||(u.__summary.tabIndex=0);var _=null!==u.getAttribute("open");if(_===!0?(u.__summary.setAttribute("aria-expanded","true"),u.__content.setAttribute("aria-hidden","false")):(u.__summary.setAttribute("aria-expanded","false"),u.__content.setAttribute("aria-hidden","true"),r||(u.__content.style.display="none")),u.__summary.__details=u,!r){var d=document.createElement("i");_===!0?(d.className="arrow arrow-open",d.appendChild(document.createTextNode("▼"))):(d.className="arrow arrow-closed",d.appendChild(document.createTextNode("►"))),u.__summary.__twisty=u.__summary.insertBefore(d,u.__summary.firstChild),u.__summary.__twisty.setAttribute("aria-hidden","true")}}t(document,function(e,t){return(t=n(t,"summary"))?a(t):!0})}}var r="boolean"==typeof document.createElement("details").open,i=!1;e(document,"DOMContentLoaded",a),e(window,"load",a)}();
"use strict";!function(e){document.queryCommandSupported("copy")&&(e.ApiKey=function(){var e={keyVisible:function(e,n){return'\n <span class="api-key-key">'+e+"</span>\n <input type='button' class='api-key-button-copy' value='Copy "+n+" to clipboard' />\n "},keyCopied:function(e){return"\n <span class=\"api-key-key\">Copied to clipboard</span>\n <input type='button' class='api-key-button-show' value='Show "+e+"' />\n "}};this.copyKey=function(e,n){var t=window.getSelection?window.getSelection():document.selection,o=document.createRange();t.removeAllRanges(),o.selectNodeContents(e),t.addRange(o),document.execCommand("copy"),t.removeAllRanges(),n()},this.start=function(n){var t=this,o=$(n),i=o.data("key"),a=o.data("thing");o.html(e.keyVisible(i,a)).attr("aria-live","polite").on("click",".api-key-button-copy",function(){return t.copyKey($(".api-key-key",n)[0],function(){return o.html(e.keyCopied(a))})}).on("click",".api-key-button-show",function(){return o.html(e.keyVisible(i,a))})}})}(window.GOVUK.Modules);
"use strict";!function(t){t.Autofocus=function(){this.start=function(t){$("input, textarea, select",t).eq(0).trigger("focus")}}}(window.GOVUK.Modules);
"use strict";!function(t){if("oninput"in document.createElement("input")){var e=/\(\(([^\)\((\?)]+)(\?\?)?([^\)\(]*)\)\)/g;t.HighlightTags=function(){var t=this;this.start=function(t){this.$textbox=$(t).wrap("\n <div class='textbox-highlight-wrapper' />\n ").after(this.$background=$('\n <div class="textbox-highlight-background" aria-hidden="true" />\n ')).on("input",this.update),this.initialHeight=this.$textbox.height(),this.$background.css({width:this.$textbox.outerWidth(),"border-width":this.$textbox.css("border-width")}),this.$textbox.trigger("input")},this.resize=function(){return t.$textbox.height(Math.max(t.initialHeight,t.$background.outerHeight()))},this.escapedMessage=function(){return $("<div/>").text(t.$textbox.val()).html()},this.replacePlaceholders=function(){return t.$background.html(t.escapedMessage().replace(e,function(t,e,i,n){return n&&i?"<span class='placeholder-conditional'>(("+e+"??</span>"+n+"))":"<span class='placeholder'>(("+e+n+"))</span>"}))},this.update=function(){return t.replacePlaceholders()&&t.resize()}}}}(window.GOVUK.Modules);
"use strict";!function(t){t.FileUpload=function(){var t=this;this.submit=function(){return t.$form.trigger("submit")},this.showCancelButton=function(){return $(".file-upload-button",t.$form).replaceWith("\n <a href=\"\" class='file-upload-button-cancel'>Cancel upload</a>\n ")},this.start=function(t){var n=this;this.$form=$(t),$(window).on("pageshow",function(){return n.$form[0].reset()}),this.$form.on("change",".file-upload-field",function(){return n.submit()&&n.showCancelButton()})}}}(window.GOVUK.Modules);
"use strict";!function(n){var t,e={},r=new diffDOM,u=function(n){return function(t){return function(){var e=n.get(0),u=$(t[n.data("key")]).get(0),i=r.diff(e,u);r.apply(e,i)}}},i=function(n){return e[n]=e[n]||[]},o=function(n,t){for(;n.length;)n.shift()(t)},a=function(n){return n.length=0},f=function c(n,e,r,u){var i=arguments;1===r.push(n)&&$.ajax(e).done(function(n){return o(r,n)}).fail(function(){return a(r)}),t=setTimeout(function(){return c.apply(void 0,i)},u)};n.UpdateContent=function(){this.start=function(n){return f(u($(n)),$(n).data("resource"),i($(n).data("resource")),1e3*($(n).data("interval-seconds")||1.5))}}}(window.GOVUK.Modules);
"use strict";!function(t){t.ExpandCollapse=function(){var t=this;this.start=function(t){this.$component=$(t),this.$toggle=this.$component.find(".toggle").on("click",this.change).on("keydown",this.filterKeyPresses([32,13],this.change)),this.getNativeHeight()<this.$component.data("max-height")&&this.change()},this.filterKeyPresses=function(t,e){return function(n){t.indexOf(n.keyCode)||(n.preventDefault(),e())}},this.getNativeHeight=function(){var t=this.$component.clone().css({position:"absolute",left:"9999px",width:this.$component.width(),"font-size":this.$component.css("font-size"),"line-height":this.$component.css("line-height")}).addClass("expanded");$("body").append(t);var e=t.height();return t.remove(),e},this.change=function(){return t.toggleCollapsed()&&t.$toggle.remove()},this.toggleCollapsed=function(){return t.$component.addClass("expanded")}}}(window.GOVUK.Modules);
"use strict";$(function(){return GOVUK.modules.start()}),$(function(){return new GOVUK.SelectionButtons(".block-label input, .sms-message-option input")}),$(function(){return $(".error-message").eq(0).parent("label").next("input").trigger("focus")});