{"version":3,"file":"vendor~dynamic-render.bundle.js","mappings":";;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,GAAG;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,EAAE;AACrB;AACA,wBAAwB,EAAE;AAC1B;AACA;AACA;AACA,kBAAkB,SAAS,IAAI,aAAa,EAAE,EAAE;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gCAAgC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAyB,IAAI,WAAW;AAC1D;AACA;;;;;;;;;;;;;;;;;ACjGuC;;AAEvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uDAAS;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uDAAS;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEO;AACP;AACA;;;;;;;;;;;;;;;AC3JO;AACP;AACA;AACA;;AAEA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCgC;AACF;;;;;;;;;;;;;;;;ACDG;;AAEjC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB;AAChB;;AAEA;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA,YAAY,kDAAS;AACrB;AACA;AACA;AACA;;AAEA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;;;;;;;;;;;;;;;;;;ACxF6C;AACH;AACY;;AAEtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,gCAAgC,MAAM;AACtC,4BAA4B;AAC5B,6BAA6B;AAC7B,qBAAqB;AACrB,sBAAsB;AACtB;AACA;AACA;AACA;AACA;;;AAGO;AACP,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA,0BAA0B,sDAAU;;AAEpC;;AAEA;AACA,eAAe,oDAAQ;AACvB;;AAEA;AACA,eAAe,mDAAO;AACtB;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;AC1EkC;;AAElC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kDAAQ;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA,sBAAsB;AACtB;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kDAAQ;AAC9B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEO;AACP;AACA;AACA,KAAK;AACL;AACA;;;;;;;;;;;;;;;;;;;ACjSyH;AACrF;AACD;AACK;;AAExC;;AAEO;AACP;AACA;AACA,oDAAoD,mDAAS,wDAAwD,wDAAW;AAChI,oDAAoD,mDAAS,wDAAwD,wDAAW;AAChI;AACA;AACA;AACA,0BAA0B,mDAAS;AACnC,0BAA0B,mDAAS;AACnC;;AAEA,2BAA2B,iDAAW;AACtC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,6BAA6B,KAAK,4BAA4B;AACvH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,iDAAO;AAC5B;AACA;AACA,sBAAsB;AACtB;AACA,wBAAwB,qDAAU;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qDAAY;AAC5B;AACA,UAAU;;AAEV;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0CAAI;AAC5B;AACA,wDAAwD,kDAAQ;AAChE,wDAAwD,kDAAQ;AAChE;AACA;AACA;AACA;AACA,wBAAwB,0CAAI;AAC5B;AACA,wDAAwD,kDAAQ;AAChE,wDAAwD,kDAAQ;AAChE;AACA;AACA;;AAEA;AACA;AACA;AACA,4BAA4B,0CAAI;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,4BAA4B,0CAAI;AAChC;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,oBAAoB,gBAAgB;AACpC;AACA;AACA;AACA,+BAA+B,0CAAI;AACnC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,mCAAmC,0CAAI;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,gBAAgB;AACpC;AACA,2BAA2B,0CAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,sDAAY;;AAEzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,wBAAwB,UAAU;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0CAAI;AAC3C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,uCAAuC,0CAAI;AAC3C;AACA;AACA,mEAAmE,kDAAQ;AAC3E;AACA;AACA;;AAEA,kBAAkB;AAClB;AACA,uCAAuC,0CAAI;AAC3C;AACA;AACA;AACA;AACA,sBAAsB;AACtB,uCAAuC,0CAAI;AAC3C;AACA;AACA,mEAAmE,kDAAQ;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,UAAU,iDAAO;AACnC;AACA;AACA,2CAA2C,0CAAI;AAC/C;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,oCAAoC,0CAAI;AACxC;AACA,2EAA2E,kDAAQ;AACnF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sBAAsB;AACtB;AACA,gCAAgC,0CAAI;AACpC;AACA,uEAAuE,kDAAQ;AAC/E;AACA;AACA,oDAAoD;AACpD;AACA,sBAAsB;AACtB;AACA,gCAAgC,0CAAI;AACpC;AACA,wEAAwE,kDAAQ;AAChF,wEAAwE,kDAAQ;AAChF;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,2DAAiB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,yCAAyC,mBAAmB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,0CAAI;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,uCAAuC,0CAAI;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,mCAAmC,0CAAI;AACvC;AACA;AACA,+DAA+D,kDAAQ;AACvE;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA,mCAAmC,0CAAI;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,mCAAmC,0CAAI;AACvC;AACA;AACA,+DAA+D,kDAAQ;AACvE;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,kBAAkB;AACtD,6BAA6B,sDAAY;AACzC;AACA;AACA;AACA;AACA,oCAAoC,0CAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,0CAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,0CAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,0CAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;;;;;;;;ACleO,sCAAsC;AAC7C;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC9BA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA,+BAA+B,sBAAsB;AACrD,eAAe;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;;AAEA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;;AAEA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA8B,iBAAiB;AAC/C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP;AACA;;;;;;;;;;;;;;;;;;;;;;AClMO;AACP,4BAA4B;AAC5B;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,YAAY,GAAG,0CAA0C;AACxF;AACA;AACA,+BAA+B,YAAY,GAAG,iBAAiB;AAC/D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;;AAGO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAc;AACd,wCAAwC,YAAY,GAAG,iBAAiB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,YAAY,GAAG,0CAA0C;AAChG;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;;;AAGO,yBAAyB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA,0BAA0B,oBAAoB;AAC9C;AACA,8BAA8B,oBAAoB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,sCAAsC,YAAY;AAClD;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;ACxWiC;AACE;AACK;;;;;;;;;;;;;;;;;;;;ACFuB;AACtB;;;;;;;;;;;;;;;ACDzC;AACA,8BAA8B,WAAW;AACzC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC;AAClC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,aAAa;AACb,YAAY;AACZ,YAAY;AACZ,cAAc;AACd,aAAa;AACb,cAAc;AACd,cAAc;AACd,cAAc;AACd;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,oBAAoB;AACpB,yBAAyB;;AAEzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,yBAAyB;AACzB,yBAAyB;AACzB,yBAAyB,gBAAgB,MAAM;AAC/C,yBAAyB;AACzB,yBAAyB;AACzB,yBAAyB;;AAEzB;AACA,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,wDAAwD;AACxD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,kDAAkD,iBAAiB;AACnE;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB;AAC1B;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM,uCAAuC;AAC7C;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,eAAe;AAC5D;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,eAAe;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,WAAW,UAAU,SAAS,KAAK,oBAAoB;AACvH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,eAAe;AAC5D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,gDAAgD,iBAAiB;AACjE;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iEAAe,QAAQ,EAAC","sources":["webpack://sfra-boilerplate/./node_modules/diff-dom/src/TraceLogger.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/dom/apply.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/dom/fromVirtual.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/dom/index.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/dom/undo.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/index.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/apply.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/diff.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/fromDOM.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/fromString.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/helpers.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/diffDOM/virtual/index.js","webpack://sfra-boilerplate/./node_modules/diff-dom/src/index.js","webpack://sfra-boilerplate/./node_modules/mustache/mustache.mjs"],"sourcesContent":["/**\n * Use TraceLogger to figure out function calls inside\n * JS objects by wrapping an object with a TraceLogger\n * instance.\n *\n * Pretty-prints the call trace (using unicode box code)\n * when tracelogger.toString() is called.\n */\n\n/**\n * Wrap an object by calling new TraceLogger(obj)\n *\n * If you're familiar with Python decorators, this\n * does roughly the same thing, adding pre/post\n * call hook logging calls so that you can see\n * what's going on.\n */\nexport class TraceLogger {\n    constructor(obj = {}) {\n        this.pad = \"│   \"\n        this.padding = \"\"\n        this.tick = 1\n        this.messages = []\n        const wrapkey = (obj, key) => {\n            // trace this function\n            const oldfn = obj[key]\n            obj[key] = (...args) => {\n                this.fin(key, Array.prototype.slice.call(args))\n                const result = oldfn.apply(obj, args)\n                this.fout(key, result)\n                return result\n            }\n        }\n        // can't use Object.keys for prototype walking\n        for (let key in obj) {\n            if (typeof obj[key] === \"function\") {\n                wrapkey(obj, key)\n            }\n        }\n        this.log(\"┌ TRACELOG START\")\n    }\n    // called when entering a function\n    fin(fn, args) {\n        this.padding += this.pad\n        this.log(`├─> entering ${fn}`, args)\n    }\n    // called when exiting a function\n    fout(fn, result) {\n        this.log(\"│<──┘ generated return value\", result)\n        this.padding = this.padding.substring(0, this.padding.length - this.pad.length)\n    }\n    // log message formatting\n    format(s, tick) {\n        let nf = function(t) {\n            t = `${t}`\n            while (t.length < 4) {\n                t = `0${t}`\n            }\n            return t\n        }\n        return `${nf(tick)}> ${this.padding}${s}`\n    }\n    // log a trace message\n    log() {\n        let s = Array.prototype.slice.call(arguments)\n        const stringCollapse = function(v) {\n            if (!v) {\n                return \"<falsey>\"\n            }\n            if (typeof v === \"string\") {\n                return v\n            }\n            if (v instanceof HTMLElement) {\n                return v.outerHTML || \"<empty>\"\n            }\n            if (v instanceof Array) {\n                return `[${v.map(stringCollapse).join(\",\")}]`\n            }\n            return v.toString() || v.valueOf() || \"<unknown>\"\n        }\n        s = s.map(stringCollapse).join(\", \")\n        this.messages.push(this.format(s, this.tick++))\n    }\n    // turn the log into a structured string with\n    // unicode box codes to make it a sensible trace.\n    toString() {\n        let cap = \"×   \"\n        let terminator = \"└───\"\n        while (terminator.length <= this.padding.length + this.pad.length) {\n            terminator += cap\n        }\n        let _ = this.padding\n        this.padding = \"\"\n        terminator = this.format(terminator, this.tick)\n        this.padding = _\n        return `${this.messages.join(\"\\n\")}\\n${terminator}`\n    }\n}\n","import {objToNode} from \"./fromVirtual\"\n\n// ===== Apply a diff =====\n\nfunction getFromRoute(node, route) {\n    route = route.slice()\n    while (route.length > 0) {\n        if (!node.childNodes) {\n            return false\n        }\n        const c = route.splice(0, 1)[0]\n        node = node.childNodes[c]\n    }\n    return node\n}\n\nexport function applyDiff(\n        tree,\n        diff,\n        options // {preDiffApply, postDiffApply, textDiff, valueDiffing, _const}\n    ) {\n    let node = getFromRoute(tree, diff[options._const.route])\n    let newNode\n    let reference\n    let route\n    let nodeArray\n    let c\n\n    // pre-diff hook\n    const info = {\n        diff,\n        node\n    }\n\n    if (options.preDiffApply(info)) {\n        return true\n    }\n\n    switch (diff[options._const.action]) {\n        case options._const.addAttribute:\n            if (!node || !node.setAttribute) {\n                return false\n            }\n            node.setAttribute(diff[options._const.name], diff[options._const.value])\n            break\n        case options._const.modifyAttribute:\n            if (!node || !node.setAttribute) {\n                return false\n            }\n            node.setAttribute(diff[options._const.name], diff[options._const.newValue])\n            if (node.nodeName === 'INPUT' && diff[options._const.name] === 'value') {\n                node.value = diff[options._const.newValue]\n            }\n            break\n        case options._const.removeAttribute:\n            if (!node || !node.removeAttribute) {\n                return false\n            }\n            node.removeAttribute(diff[options._const.name])\n            break\n        case options._const.modifyTextElement:\n            if (!node || node.nodeType !== 3) {\n                return false\n            }\n            options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue])\n            break\n        case options._const.modifyValue:\n            if (!node || typeof node.value === 'undefined') {\n                return false\n            }\n            node.value = diff[options._const.newValue]\n            break\n        case options._const.modifyComment:\n            if (!node || typeof node.data === 'undefined') {\n                return false\n            }\n            options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue])\n            break\n        case options._const.modifyChecked:\n            if (!node || typeof node.checked === 'undefined') {\n                return false\n            }\n            node.checked = diff[options._const.newValue]\n            break\n        case options._const.modifySelected:\n            if (!node || typeof node.selected === 'undefined') {\n                return false\n            }\n            node.selected = diff[options._const.newValue]\n            break\n        case options._const.replaceElement:\n            node.parentNode.replaceChild(\n                objToNode(\n                    diff[options._const.newValue],\n                    node.namespaceURI === 'http://www.w3.org/2000/svg',\n                    options\n                ),\n                node\n            )\n            break\n        case options._const.relocateGroup:\n            nodeArray = Array(...new Array(diff.groupLength)).map(() => node.removeChild(node.childNodes[diff[options._const.from]]))\n            nodeArray.forEach((childNode, index) => {\n                if (index === 0) {\n                    reference = node.childNodes[diff[options._const.to]]\n                }\n                node.insertBefore(childNode, reference || null)\n            })\n            break\n        case options._const.removeElement:\n            node.parentNode.removeChild(node)\n            break\n        case options._const.addElement:\n            route = diff[options._const.route].slice()\n            c = route.splice(route.length - 1, 1)[0]\n            node = getFromRoute(tree, route)\n            node.insertBefore(\n                objToNode(\n                    diff[options._const.element],\n                    node.namespaceURI === 'http://www.w3.org/2000/svg',\n                    options\n                ),\n                node.childNodes[c] || null\n            )\n            break\n        case options._const.removeTextElement:\n            if (!node || node.nodeType !== 3) {\n                return false\n            }\n            node.parentNode.removeChild(node)\n            break\n        case options._const.addTextElement:\n            route = diff[options._const.route].slice()\n            c = route.splice(route.length - 1, 1)[0]\n            newNode = options.document.createTextNode(diff[options._const.value])\n            node = getFromRoute(tree, route)\n            if (!node || !node.childNodes) {\n                return false\n            }\n            node.insertBefore(newNode, node.childNodes[c] || null)\n            break\n        default:\n            console.log('unknown action')\n    }\n\n    // if a new node was created, we might be interested in its\n    // post diff hook\n    info.newNode = newNode\n    options.postDiffApply(info)\n\n    return true\n}\n\nexport function applyDOM(tree, diffs, options) {\n    return diffs.every(diff => applyDiff(tree, diff, options))\n}\n","export function objToNode(objNode, insideSvg, options) {\n    let node\n    if (objNode.nodeName === '#text') {\n        node = options.document.createTextNode(objNode.data)\n\n    } else if (objNode.nodeName === '#comment') {\n        node = options.document.createComment(objNode.data)\n    } else {\n        if (insideSvg) {\n            node = options.document.createElementNS('http://www.w3.org/2000/svg', objNode.nodeName)\n        } else if (objNode.nodeName.toLowerCase() === 'svg') {\n            node = options.document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n            insideSvg = true\n        } else {\n            node = options.document.createElement(objNode.nodeName)\n        }\n        if (objNode.attributes) {\n            Object.entries(objNode.attributes).forEach(([key, value]) => node.setAttribute(key, value))\n        }\n        if (objNode.childNodes) {\n            objNode.childNodes.forEach(childNode => node.appendChild(objToNode(childNode, insideSvg, options)))\n        }\n        if (options.valueDiffing) {\n            if (objNode.value) {\n                node.value = objNode.value\n            }\n            if (objNode.checked) {\n                node.checked = objNode.checked\n            }\n            if (objNode.selected) {\n                node.selected = objNode.selected\n            }\n        }\n    }\n    return node\n}\n","export {applyDOM} from \"./apply\"\nexport {undoDOM} from \"./undo\"\n","import {applyDiff} from \"./apply\"\n\n// ===== Undo a diff =====\n\nfunction swap(obj, p1, p2) {\n    const tmp = obj[p1]\n    obj[p1] = obj[p2]\n    obj[p2] = tmp\n}\n\nfunction undoDiff(\n    tree,\n    diff,\n    options // {preDiffApply, postDiffApply, textDiff, valueDiffing, _const}\n) {\n\n    switch (diff[options._const.action]) {\n        case options._const.addAttribute:\n            diff[options._const.action] = options._const.removeAttribute\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifyAttribute:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.removeAttribute:\n            diff[options._const.action] = options._const.addAttribute\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifyTextElement:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifyValue:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifyComment:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifyChecked:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.modifySelected:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.replaceElement:\n            swap(diff, options._const.oldValue, options._const.newValue)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.relocateGroup:\n            swap(diff, options._const.from, options._const.to)\n            applyDiff(tree, diff, options)\n            break\n        case options._const.removeElement:\n            diff[options._const.action] = options._const.addElement\n            applyDiff(tree, diff, options)\n            break\n        case options._const.addElement:\n            diff[options._const.action] = options._const.removeElement\n            applyDiff(tree, diff, options)\n            break\n        case options._const.removeTextElement:\n            diff[options._const.action] = options._const.addTextElement\n            applyDiff(tree, diff, options)\n            break\n        case options._const.addTextElement:\n            diff[options._const.action] = options._const.removeTextElement\n            applyDiff(tree, diff, options)\n            break\n        default:\n            console.log('unknown action')\n    }\n\n}\n\nexport function undoDOM(tree, diffs, options) {\n    if (!diffs.length) {\n        diffs = [diffs]\n    }\n    diffs = diffs.slice()\n    diffs.reverse()\n    diffs.forEach(diff => {\n        undoDiff(tree, diff, options)\n    })\n}\n","import {applyDOM, undoDOM} from \"./dom/index\"\nimport {DiffFinder} from \"./virtual/index\"\nexport {nodeToObj, stringToObj} from \"./virtual/index\"\n\nconst DEFAULT_OPTIONS = {\n    debug: false,\n    diffcap: 10, // Limit for how many diffs are accepting when debugging. Inactive when debug is false.\n    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.\n    maxChildCount: 50, // False or a numeral. If set to a numeral, only does a simplified form of diffing of contents so that the number of diffs cannot be higher than the number of child nodes.\n    valueDiffing: true, // Whether to take into consideration the values of forms that differ from auto assigned values (when a user fills out a form).\n    // syntax: textDiff: function (node, currentValue, expectedValue, newValue)\n    textDiff(node, currentValue, expectedValue, newValue) {\n        node.data = newValue\n        return\n    },\n    // empty functions were benchmarked as running faster than both\n    // `f && f()` and `if (f) { f(); }`\n    preVirtualDiffApply() {},\n    postVirtualDiffApply() {},\n    preDiffApply() {},\n    postDiffApply() {},\n    filterOuterDiff: null,\n    compress: false, // Whether to work with compressed diffs\n    _const: false, // object with strings for every change types to be used in diffs.\n    document: window && window.document ? window.document : false\n}\n\n\nexport class DiffDOM {\n    constructor(options = {}) {\n\n        this.options = options\n        // IE11 doesn't have Object.assign and buble doesn't translate object spreaders\n        // by default, so this is the safest way of doing it currently.\n        Object.entries(DEFAULT_OPTIONS).forEach(([key, value]) => {\n            if (!Object.prototype.hasOwnProperty.call(this.options, key)) {\n                this.options[key] = value\n            }\n        })\n\n        if (!this.options._const) {\n            const varNames = [\"addAttribute\", \"modifyAttribute\", \"removeAttribute\",\n                \"modifyTextElement\", \"relocateGroup\", \"removeElement\", \"addElement\",\n                \"removeTextElement\", \"addTextElement\", \"replaceElement\", \"modifyValue\",\n                \"modifyChecked\", \"modifySelected\", \"modifyComment\", \"action\", \"route\",\n                \"oldValue\", \"newValue\", \"element\", \"group\", \"from\", \"to\", \"name\",\n                \"value\", \"data\", \"attributes\", \"nodeName\", \"childNodes\", \"checked\",\n                \"selected\"\n            ]\n            this.options._const = {}\n            if (this.options.compress) {\n                varNames.forEach((varName, index) => this.options._const[varName] = index)\n            } else {\n                varNames.forEach(varName => this.options._const[varName] = varName)\n            }\n        }\n\n        this.DiffFinder = DiffFinder\n\n    }\n\n    apply(tree, diffs) {\n        return applyDOM(tree, diffs, this.options)\n    }\n\n    undo(tree, diffs) {\n        return undoDOM(tree, diffs, this.options)\n    }\n\n    diff(t1Node, t2Node) {\n        const finder = new this.DiffFinder(t1Node, t2Node, this.options)\n        return finder.init()\n    }\n\n}\n","import {cloneObj} from \"./helpers\"\n\n// ===== Apply a virtual diff =====\n\nfunction getFromVirtualRoute(tree, route) {\n    let node = tree\n    let parentNode\n    let nodeIndex\n\n    route = route.slice()\n    while (route.length > 0) {\n        if (!node.childNodes) {\n            return false\n        }\n        nodeIndex = route.splice(0, 1)[0]\n        parentNode = node\n        node = node.childNodes[nodeIndex]\n    }\n    return {\n        node,\n        parentNode,\n        nodeIndex\n    }\n}\n\nfunction applyVirtualDiff(\n        tree,\n        diff,\n        options // {preVirtualDiffApply, postVirtualDiffApply, _const}\n    ) {\n    const routeInfo = getFromVirtualRoute(tree, diff[options._const.route])\n    let node = routeInfo.node\n    const parentNode = routeInfo.parentNode\n    const nodeIndex = routeInfo.nodeIndex\n    const newSubsets = []\n\n    // pre-diff hook\n    const info = {\n        diff,\n        node\n    }\n\n    if (options.preVirtualDiffApply(info)) {\n        return true\n    }\n\n    let newNode\n    let nodeArray\n    let route\n    let c\n    switch (diff[options._const.action]) {\n        case options._const.addAttribute:\n            if (!node.attributes) {\n                node.attributes = {}\n            }\n\n            node.attributes[diff[options._const.name]] = diff[options._const.value]\n\n            if (diff[options._const.name] === 'checked') {\n                node.checked = true\n            } else if (diff[options._const.name] === 'selected') {\n                node.selected = true\n            } else if (node.nodeName === 'INPUT' && diff[options._const.name] === 'value') {\n                node.value = diff[options._const.value]\n            }\n\n            break\n        case options._const.modifyAttribute:\n            node.attributes[diff[options._const.name]] = diff[options._const.newValue]\n            break\n        case options._const.removeAttribute:\n\n            delete node.attributes[diff[options._const.name]]\n\n            if (Object.keys(node.attributes).length === 0) {\n                delete node.attributes\n            }\n\n            if (diff[options._const.name] === 'checked') {\n                node.checked = false\n            } else if (diff[options._const.name] === 'selected') {\n                delete node.selected\n            } else if (node.nodeName === 'INPUT' && diff[options._const.name] === 'value') {\n                delete node.value\n            }\n\n            break\n        case options._const.modifyTextElement:\n            node.data = diff[options._const.newValue]\n            break\n        case options._const.modifyValue:\n            node.value = diff[options._const.newValue]\n            break\n        case options._const.modifyComment:\n            node.data = diff[options._const.newValue]\n            break\n        case options._const.modifyChecked:\n            node.checked = diff[options._const.newValue]\n            break\n        case options._const.modifySelected:\n            node.selected = diff[options._const.newValue]\n            break\n        case options._const.replaceElement:\n            newNode = cloneObj(diff[options._const.newValue])\n            newNode.outerDone = true\n            newNode.innerDone = true\n            newNode.valueDone = true\n            parentNode.childNodes[nodeIndex] = newNode\n            break\n        case options._const.relocateGroup:\n            nodeArray = node.childNodes.splice(diff[options._const.from], diff.groupLength).reverse()\n            nodeArray.forEach(movedNode => node.childNodes.splice(diff[options._const.to], 0, movedNode))\n            if (node.subsets) {\n                node.subsets.forEach(map => {\n                    if (diff[options._const.from] < diff[options._const.to] && map.oldValue <= diff[options._const.to] && map.oldValue > diff[options._const.from]) {\n                        map.oldValue -= diff.groupLength\n                        const splitLength = map.oldValue + map.length - diff[options._const.to]\n                        if (splitLength > 0) {\n                            // new insertion splits map.\n                            newSubsets.push({\n                                oldValue: diff[options._const.to] + diff.groupLength,\n                                newValue: map.newValue + map.length - splitLength,\n                                length: splitLength\n                            })\n                            map.length -= splitLength\n                        }\n                    } else if (diff[options._const.from] > diff[options._const.to] && map.oldValue > diff[options._const.to] && map.oldValue < diff[options._const.from]) {\n                        map.oldValue += diff.groupLength\n                        const splitLength = map.oldValue + map.length - diff[options._const.to]\n                        if (splitLength > 0) {\n                            // new insertion splits map.\n                            newSubsets.push({\n                                oldValue: diff[options._const.to] + diff.groupLength,\n                                newValue: map.newValue + map.length - splitLength,\n                                length: splitLength\n                            })\n                            map.length -= splitLength\n                        }\n                    } else if (map.oldValue === diff[options._const.from]) {\n                        map.oldValue = diff[options._const.to]\n                    }\n                })\n            }\n\n            break\n        case options._const.removeElement:\n            parentNode.childNodes.splice(nodeIndex, 1)\n            if (parentNode.subsets) {\n                parentNode.subsets.forEach(map => {\n                    if (map.oldValue > nodeIndex) {\n                        map.oldValue -= 1\n                    } else if (map.oldValue === nodeIndex) {\n                        map.delete = true\n                    } else if (map.oldValue < nodeIndex && (map.oldValue + map.length) > nodeIndex) {\n                        if (map.oldValue + map.length - 1 === nodeIndex) {\n                            map.length--\n                        } else {\n                            newSubsets.push({\n                                newValue: map.newValue + nodeIndex - map.oldValue,\n                                oldValue: nodeIndex,\n                                length: map.length - nodeIndex + map.oldValue - 1\n                            })\n                            map.length = nodeIndex - map.oldValue\n                        }\n                    }\n                })\n            }\n            node = parentNode\n            break\n        case options._const.addElement:\n            route = diff[options._const.route].slice()\n            c = route.splice(route.length - 1, 1)[0]\n            node = getFromVirtualRoute(tree, route).node\n            newNode = cloneObj(diff[options._const.element])\n            newNode.outerDone = true\n            newNode.innerDone = true\n            newNode.valueDone = true\n\n            if (!node.childNodes) {\n                node.childNodes = []\n            }\n\n            if (c >= node.childNodes.length) {\n                node.childNodes.push(newNode)\n            } else {\n                node.childNodes.splice(c, 0, newNode)\n            }\n            if (node.subsets) {\n                node.subsets.forEach(map => {\n                    if (map.oldValue >= c) {\n                        map.oldValue += 1\n                    } else if (map.oldValue < c && (map.oldValue + map.length) > c) {\n                        const splitLength = map.oldValue + map.length - c\n                        newSubsets.push({\n                            newValue: map.newValue + map.length - splitLength,\n                            oldValue: c + 1,\n                            length: splitLength\n                        })\n                        map.length -= splitLength\n                    }\n                })\n            }\n            break\n        case options._const.removeTextElement:\n            parentNode.childNodes.splice(nodeIndex, 1)\n            if (parentNode.nodeName === 'TEXTAREA') {\n                delete parentNode.value\n            }\n            if (parentNode.subsets) {\n                parentNode.subsets.forEach(map => {\n                    if (map.oldValue > nodeIndex) {\n                        map.oldValue -= 1\n                    } else if (map.oldValue === nodeIndex) {\n                        map.delete = true\n                    } else if (map.oldValue < nodeIndex && (map.oldValue + map.length) > nodeIndex) {\n                        if (map.oldValue + map.length - 1 === nodeIndex) {\n                            map.length--\n                        } else {\n                            newSubsets.push({\n                                newValue: map.newValue + nodeIndex - map.oldValue,\n                                oldValue: nodeIndex,\n                                length: map.length - nodeIndex + map.oldValue - 1\n                            })\n                            map.length = nodeIndex - map.oldValue\n                        }\n                    }\n                })\n            }\n            node = parentNode\n            break\n        case options._const.addTextElement:\n            route = diff[options._const.route].slice()\n            c = route.splice(route.length - 1, 1)[0]\n            newNode = {}\n            newNode.nodeName = '#text'\n            newNode.data = diff[options._const.value]\n            node = getFromVirtualRoute(tree, route).node\n            if (!node.childNodes) {\n                node.childNodes = []\n            }\n\n            if (c >= node.childNodes.length) {\n                node.childNodes.push(newNode)\n            } else {\n                node.childNodes.splice(c, 0, newNode)\n            }\n            if (node.nodeName === 'TEXTAREA') {\n                node.value = diff[options._const.newValue]\n            }\n            if (node.subsets) {\n                node.subsets.forEach(map => {\n                    if (map.oldValue >= c) {\n                        map.oldValue += 1\n                    }\n                    if (map.oldValue < c && (map.oldValue + map.length) > c) {\n                        const splitLength = map.oldValue + map.length - c\n                        newSubsets.push({\n                            newValue: map.newValue + map.length - splitLength,\n                            oldValue: c + 1,\n                            length: splitLength\n                        })\n                        map.length -= splitLength\n                    }\n                })\n            }\n            break\n        default:\n            console.log('unknown action')\n    }\n\n    if (node.subsets) {\n        node.subsets = node.subsets.filter(map => !map.delete && map.oldValue !== map.newValue)\n        if (newSubsets.length) {\n            node.subsets = node.subsets.concat(newSubsets)\n        }\n    }\n\n    // capture newNode for the callback\n    info.newNode = newNode\n    options.postVirtualDiffApply(info)\n\n    return\n}\n\nexport function applyVirtual(tree, diffs, options) {\n    diffs.forEach(diff => {\n        applyVirtualDiff(tree, diff, options)\n    })\n    return true\n}\n","import {Diff, DiffTracker, cloneObj, getGapInformation, isEqual, markSubTrees, removeDone, roughlyEqual} from \"./helpers\"\nimport {applyVirtual} from \"./apply\"\nimport {nodeToObj} from \"./fromDOM\"\nimport {stringToObj} from \"./fromString\"\n\n// ===== Create a diff =====\n\nexport class DiffFinder {\n    constructor(t1Node, t2Node, options) {\n        this.options = options\n        this.t1 = (t1Node instanceof HTMLElement) ? nodeToObj(t1Node, this.options) : (typeof t1Node === 'string') ? stringToObj(t1Node, this.options) : JSON.parse(JSON.stringify(t1Node))\n        this.t2 = (t2Node instanceof HTMLElement) ? nodeToObj(t2Node, this.options) : (typeof t2Node === 'string') ? stringToObj(t2Node, this.options) : JSON.parse(JSON.stringify(t2Node))\n        this.diffcount = 0\n        this.foundAll = false\n        if (this.debug) {\n            this.t1Orig = nodeToObj(t1Node, this.options)\n            this.t2Orig = nodeToObj(t2Node, this.options)\n        }\n\n        this.tracker = new DiffTracker()\n    }\n\n    init() {\n        return this.findDiffs(this.t1, this.t2)\n    }\n\n    findDiffs(t1, t2) {\n        let diffs\n        do {\n            if (this.options.debug) {\n                this.diffcount += 1\n                if (this.diffcount > this.options.diffcap) {\n                    window.diffError = [this.t1Orig, this.t2Orig]\n                    throw new Error(`surpassed diffcap:${JSON.stringify(this.t1Orig)} -> ${JSON.stringify(this.t2Orig)}`)\n                }\n            }\n            diffs = this.findNextDiff(t1, t2, [])\n\n            if (diffs.length === 0) {\n                // Last check if the elements really are the same now.\n                // If not, remove all info about being done and start over.\n                // Sometimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed again.\n                if (!isEqual(t1, t2)) {\n                    if (this.foundAll) {\n                        console.error('Could not find remaining diffs!')\n                    } else {\n                        this.foundAll = true\n                        removeDone(t1)\n                        diffs = this.findNextDiff(t1, t2, [])\n                    }\n                }\n            }\n            if (diffs.length > 0) {\n                this.foundAll = false\n                this.tracker.add(diffs)\n                applyVirtual(t1, diffs, this.options)\n            }\n        } while (diffs.length > 0)\n\n        return this.tracker.list\n    }\n\n    findNextDiff(t1, t2, route) {\n        let diffs\n        let fdiffs\n\n        if (this.options.maxDepth && route.length > this.options.maxDepth) {\n            return []\n        }\n        // outer differences?\n        if (!t1.outerDone) {\n            diffs = this.findOuterDiff(t1, t2, route)\n            if (this.options.filterOuterDiff) {\n                fdiffs = this.options.filterOuterDiff(t1, t2, diffs)\n                if (fdiffs) diffs = fdiffs\n            }\n            if (diffs.length > 0) {\n                t1.outerDone = true\n                return diffs\n            } else {\n                t1.outerDone = true\n            }\n        }\n        // inner differences?\n        if (!t1.innerDone) {\n            diffs = this.findInnerDiff(t1, t2, route)\n            if (diffs.length > 0) {\n                return diffs\n            } else {\n                t1.innerDone = true\n            }\n        }\n\n        if (this.options.valueDiffing && !t1.valueDone) {\n            // value differences?\n            diffs = this.findValueDiff(t1, t2, route)\n\n            if (diffs.length > 0) {\n                t1.valueDone = true\n                return diffs\n            } else {\n                t1.valueDone = true\n            }\n        }\n\n        // no differences\n        return []\n    }\n\n    findOuterDiff(t1, t2, route) {\n        const diffs = []\n        let attr\n        let attr1\n        let attr2\n        let attrLength\n        let pos\n        let i\n        if (t1.nodeName !== t2.nodeName) {\n            if (!route.length) {\n                throw new Error('Top level nodes have to be of the same kind.')\n            }\n            return [new Diff()\n                .setValue(this.options._const.action, this.options._const.replaceElement)\n                .setValue(this.options._const.oldValue, cloneObj(t1))\n                .setValue(this.options._const.newValue, cloneObj(t2))\n                .setValue(this.options._const.route, route)\n            ]\n        }\n        if (route.length && this.options.maxNodeDiffCount < Math.abs((t1.childNodes || []).length - (t2.childNodes || []).length)) {\n            return [new Diff()\n                .setValue(this.options._const.action, this.options._const.replaceElement)\n                .setValue(this.options._const.oldValue, cloneObj(t1))\n                .setValue(this.options._const.newValue, cloneObj(t2))\n                .setValue(this.options._const.route, route)\n            ]\n        }\n\n        if (t1.data !== t2.data) {\n            // Comment or text node.\n            if (t1.nodeName === '#text') {\n                return [new Diff()\n                    .setValue(this.options._const.action, this.options._const.modifyTextElement)\n                    .setValue(this.options._const.route, route)\n                    .setValue(this.options._const.oldValue, t1.data)\n                    .setValue(this.options._const.newValue, t2.data)\n                ]\n            } else {\n                return [new Diff()\n                    .setValue(this.options._const.action, this.options._const.modifyComment)\n                    .setValue(this.options._const.route, route)\n                    .setValue(this.options._const.oldValue, t1.data)\n                    .setValue(this.options._const.newValue, t2.data)\n                ]\n            }\n\n        }\n\n        attr1 = t1.attributes ? Object.keys(t1.attributes).sort() : []\n        attr2 = t2.attributes ? Object.keys(t2.attributes).sort() : []\n\n        attrLength = attr1.length\n        for (i = 0; i < attrLength; i++) {\n            attr = attr1[i]\n            pos = attr2.indexOf(attr)\n            if (pos === -1) {\n                diffs.push(new Diff()\n                    .setValue(this.options._const.action, this.options._const.removeAttribute)\n                    .setValue(this.options._const.route, route)\n                    .setValue(this.options._const.name, attr)\n                    .setValue(this.options._const.value, t1.attributes[attr])\n                )\n            } else {\n                attr2.splice(pos, 1)\n                if (t1.attributes[attr] !== t2.attributes[attr]) {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.modifyAttribute)\n                        .setValue(this.options._const.route, route)\n                        .setValue(this.options._const.name, attr)\n                        .setValue(this.options._const.oldValue, t1.attributes[attr])\n                        .setValue(this.options._const.newValue, t2.attributes[attr])\n                    )\n                }\n            }\n        }\n\n        attrLength = attr2.length\n        for (i = 0; i < attrLength; i++) {\n            attr = attr2[i]\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.addAttribute)\n                .setValue(this.options._const.route, route)\n                .setValue(this.options._const.name, attr)\n                .setValue(this.options._const.value, t2.attributes[attr])\n            )\n        }\n\n        return diffs\n    }\n\n    findInnerDiff(t1, t2, route) {\n        const t1ChildNodes = t1.childNodes ? t1.childNodes.slice() : []\n        const t2ChildNodes = t2.childNodes ? t2.childNodes.slice() : []\n        const last = Math.max(t1ChildNodes.length, t2ChildNodes.length)\n        let childNodesLengthDifference = Math.abs(t1ChildNodes.length - t2ChildNodes.length)\n        let diffs = []\n        let index = 0\n        if (!this.options.maxChildCount || last < this.options.maxChildCount) {\n            const subtrees = t1.subsets && t1.subsetsAge-- ? t1.subsets : (t1.childNodes && t2.childNodes) ? markSubTrees(t1, t2) : []\n\n            if (subtrees.length > 0) {\n                /* One or more groups have been identified among the childnodes of t1\n                 * and t2.\n                 */\n                diffs = this.attemptGroupRelocation(t1, t2, subtrees, route)\n                if (diffs.length > 0) {\n                    return diffs\n                }\n            }\n        }\n\n\n        /* 0 or 1 groups of similar child nodes have been found\n         * for t1 and t2. 1 If there is 1, it could be a sign that the\n         * contents are the same. When the number of groups is below 2,\n         * t1 and t2 are made to have the same length and each of the\n         * pairs of child nodes are diffed.\n         */\n\n        for (let i = 0; i < last; i += 1) {\n            const e1 = t1ChildNodes[i]\n            const e2 = t2ChildNodes[i]\n\n            if (childNodesLengthDifference) {\n                /* t1 and t2 have different amounts of childNodes. Add\n                 * and remove as necessary to obtain the same length */\n                if (e1 && !e2) {\n                    if (e1.nodeName === '#text') {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeTextElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.value, e1.data)\n                        )\n                        index -= 1\n                    } else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.element, cloneObj(e1))\n                        )\n                        index -= 1\n                    }\n\n                } else if (e2 && !e1) {\n                    if (e2.nodeName === '#text') {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.addTextElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.value, e2.data)\n                        )\n                    } else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.addElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.element, cloneObj(e2))\n                        )\n                    }\n                }\n            }\n            /* We are now guaranteed that childNodes e1 and e2 exist,\n             * and that they can be diffed.\n             */\n            /* Diffs in child nodes should not affect the parent node,\n             * so we let these diffs be submitted together with other\n             * diffs.\n             */\n\n            if (e1 && e2) {\n                if (!this.options.maxChildCount || last < this.options.maxChildCount) {\n                    diffs = diffs.concat(this.findNextDiff(e1, e2, route.concat(index)))\n                } else if (!isEqual(e1, e2)) {\n                    if (t1ChildNodes.length > t2ChildNodes.length) {\n                        if (e1.nodeName === '#text') {\n                            diffs.push(new Diff()\n                                .setValue(this.options._const.action, this.options._const.removeTextElement)\n                                .setValue(this.options._const.route, route.concat(index))\n                                .setValue(this.options._const.value, e1.data)\n                            )\n                        } else {\n                            diffs.push(\n                                new Diff()\n                                    .setValue(this.options._const.action, this.options._const.removeElement)\n                                    .setValue(this.options._const.element, cloneObj(e1))\n                                    .setValue(this.options._const.route, route.concat(index))\n                            )\n                        }\n                        t1ChildNodes.splice(i, 1)\n                        i -= 1\n                        index -= 1\n\n                        childNodesLengthDifference -= 1\n                    } else if (t1ChildNodes.length < t2ChildNodes.length) {\n                        diffs = diffs.concat([\n                            new Diff()\n                                .setValue(this.options._const.action, this.options._const.addElement)\n                                .setValue(this.options._const.element, cloneObj(e2))\n                                .setValue(this.options._const.route, route.concat(index))\n                        ])\n                        t1ChildNodes.splice(i, 0, {})\n                        childNodesLengthDifference -= 1\n                    } else {\n                        diffs = diffs.concat([\n                            new Diff()\n                                .setValue(this.options._const.action, this.options._const.replaceElement)\n                                .setValue(this.options._const.oldValue, cloneObj(e1))\n                                .setValue(this.options._const.newValue, cloneObj(e2))\n                                .setValue(this.options._const.route, route.concat(index))\n                        ])\n                    }\n\n                }\n\n            }\n            index += 1\n\n        }\n        t1.innerDone = true\n        return diffs\n    }\n\n    attemptGroupRelocation(t1, t2, subtrees, route) {\n        /* Either t1.childNodes and t2.childNodes have the same length, or\n         * there are at least two groups of similar elements can be found.\n         * attempts are made at equalizing t1 with t2. First all initial\n         * elements with no group affiliation (gaps=true) are removed (if\n         * only in t1) or added (if only in t2). Then the creation of a group\n         * relocation diff is attempted.\n         */\n        const gapInformation = getGapInformation(t1, t2, subtrees)\n        const gaps1 = gapInformation.gaps1\n        const gaps2 = gapInformation.gaps2\n        let shortest = Math.min(gaps1.length, gaps2.length)\n        let destinationDifferent\n        let toGroup\n        let group\n        let node\n        let similarNode\n        let testI\n        const diffs = []\n\n\n        for (let index2 = 0, index1 = 0; index2 < shortest; index1 += 1, index2 += 1) {\n            if (gaps1[index2] === true) {\n                node = t1.childNodes[index1]\n                if (node.nodeName === '#text') {\n                    if (t2.childNodes[index2].nodeName === '#text') {\n                        if (node.data !== t2.childNodes[index2].data) {\n                            testI = index1\n                            while (t1.childNodes.length > testI + 1 && t1.childNodes[testI + 1].nodeName === '#text') {\n                                testI += 1\n                                if (t2.childNodes[index2].data === t1.childNodes[testI].data) {\n                                    similarNode = true\n                                    break\n                                }\n                            }\n                            if (!similarNode) {\n                                diffs.push(new Diff()\n                                    .setValue(this.options._const.action, this.options._const.modifyTextElement)\n                                    .setValue(this.options._const.route, route.concat(index2))\n                                    .setValue(this.options._const.oldValue, node.data)\n                                    .setValue(this.options._const.newValue, t2.childNodes[index2].data)\n                                )\n                                return diffs\n                            }\n                        }\n                    } else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeTextElement)\n                            .setValue(this.options._const.route, route.concat(index2))\n                            .setValue(this.options._const.value, node.data)\n                        )\n                        gaps1.splice(index2, 1)\n                        shortest = Math.min(gaps1.length, gaps2.length)\n                        index2 -= 1\n                    }\n                } else {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.removeElement)\n                        .setValue(this.options._const.route, route.concat(index2))\n                        .setValue(this.options._const.element, cloneObj(node))\n                    )\n                    gaps1.splice(index2, 1)\n                    shortest = Math.min(gaps1.length, gaps2.length)\n                    index2 -= 1\n                }\n\n            } else if (gaps2[index2] === true) {\n                node = t2.childNodes[index2]\n                if (node.nodeName === '#text') {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.addTextElement)\n                        .setValue(this.options._const.route, route.concat(index2))\n                        .setValue(this.options._const.value, node.data)\n                    )\n                    gaps1.splice(index2, 0, true)\n                    shortest = Math.min(gaps1.length, gaps2.length)\n                    index1 -= 1\n                } else {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.addElement)\n                        .setValue(this.options._const.route, route.concat(index2))\n                        .setValue(this.options._const.element, cloneObj(node))\n                    )\n                    gaps1.splice(index2, 0, true)\n                    shortest = Math.min(gaps1.length, gaps2.length)\n                    index1 -= 1\n                }\n\n            } else if (gaps1[index2] !== gaps2[index2]) {\n                if (diffs.length > 0) {\n                    return diffs\n                }\n                // group relocation\n                group = subtrees[gaps1[index2]]\n                toGroup = Math.min(group.newValue, (t1.childNodes.length - group.length))\n                if (toGroup !== group.oldValue) {\n                    // Check whether destination nodes are different than originating ones.\n                    destinationDifferent = false\n                    for (let j = 0; j < group.length; j += 1) {\n                        if (!roughlyEqual(t1.childNodes[toGroup + j], t1.childNodes[group.oldValue + j], [], false, true)) {\n                            destinationDifferent = true\n                        }\n                    }\n                    if (destinationDifferent) {\n                        return [new Diff()\n                            .setValue(this.options._const.action, this.options._const.relocateGroup)\n                            .setValue('groupLength', group.length)\n                            .setValue(this.options._const.from, group.oldValue)\n                            .setValue(this.options._const.to, toGroup)\n                            .setValue(this.options._const.route, route)\n                        ]\n                    }\n                }\n            }\n        }\n        return diffs\n    }\n\n    findValueDiff(t1, t2, route) {\n        // Differences of value. Only useful if the value/selection/checked value\n        // differs from what is represented in the DOM. For example in the case\n        // of filled out forms, etc.\n        const diffs = []\n\n        if (t1.selected !== t2.selected) {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifySelected)\n                .setValue(this.options._const.oldValue, t1.selected)\n                .setValue(this.options._const.newValue, t2.selected)\n                .setValue(this.options._const.route, route)\n            )\n        }\n\n        if ((t1.value || t2.value) && t1.value !== t2.value && t1.nodeName !== 'OPTION') {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifyValue)\n                .setValue(this.options._const.oldValue, t1.value || \"\")\n                .setValue(this.options._const.newValue, t2.value || \"\")\n                .setValue(this.options._const.route, route)\n            )\n        }\n        if (t1.checked !== t2.checked) {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifyChecked)\n                .setValue(this.options._const.oldValue, t1.checked)\n                .setValue(this.options._const.newValue, t2.checked)\n                .setValue(this.options._const.route, route)\n            )\n        }\n\n        return diffs\n    }\n\n}\n","export function nodeToObj(aNode, options = {}) {\n    const objNode = {}\n    objNode.nodeName = aNode.nodeName\n    if (objNode.nodeName === '#text' || objNode.nodeName === '#comment') {\n        objNode.data = aNode.data\n    } else {\n        if (aNode.attributes && aNode.attributes.length > 0) {\n            objNode.attributes = {}\n            const nodeArray = Array.prototype.slice.call(aNode.attributes)\n            nodeArray.forEach(attribute => objNode.attributes[attribute.name] = attribute.value)\n        }\n        if (objNode.nodeName === 'TEXTAREA') {\n            objNode.value = aNode.value\n        } else if (aNode.childNodes && aNode.childNodes.length > 0) {\n            objNode.childNodes = []\n            const nodeArray = Array.prototype.slice.call(aNode.childNodes)\n            nodeArray.forEach(childNode => objNode.childNodes.push(nodeToObj(childNode, options)))\n        }\n        if (options.valueDiffing) {\n            if (aNode.checked !== undefined && aNode.type && ['radio', 'checkbox'].includes(aNode.type.toLowerCase())) {\n                objNode.checked = aNode.checked\n            } else if (aNode.value !== undefined) {\n                objNode.value = aNode.value\n            }\n            if (aNode.selected !== undefined) {\n                objNode.selected = aNode.selected\n            }\n        }\n    }\n    return objNode\n}\n","// from html-parse-stringify (MIT)\n\nconst tagRE = /<(?:\"[^\"]*\"['\"]*|'[^']*'['\"]*|[^'\">])+>/g\n// re-used obj for quick lookups of components\nconst empty = Object.create ? Object.create(null) : {}\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g\n\n\nfunction unescape(string) {\n    return string.replace(/&lt;/g, '<').replace(/&gt;/g, '>')\n.replace(/&amp;/g, '&')\n}\n\n// create optimized lookup object for\n// void elements as listed here:\n// http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements\nconst lookup = {\n    area: true,\n    base: true,\n    br: true,\n    col: true,\n    embed: true,\n    hr: true,\n    img: true,\n    input: true,\n    keygen: true,\n    link: true,\n    menuItem: true,\n    meta: true,\n    param: true,\n    source: true,\n    track: true,\n    wbr: true\n}\n\n\nfunction parseTag(tag) {\n    const res = {\n        nodeName: '',\n        attributes: {}\n    }\n\n    let tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n    if (tagMatch) {\n        res.nodeName = tagMatch[1].toUpperCase()\n        if (lookup[tagMatch[1].toLowerCase()] || tag.charAt(tag.length - 2) === '/') {\n            res.voidElement = true\n        }\n\n        // handle comment tag\n        if (res.nodeName.startsWith('!--')) {\n            const endIndex = tag.indexOf('-->')\n            return {\n                type: 'comment',\n                data: endIndex !== -1 ? tag.slice(4, endIndex) : ''\n            }\n        }\n    }\n\n    let reg = new RegExp(attrRE)\n    let result = null\n    let done = false\n    while (!done) {\n        result = reg.exec(tag)\n\n        if (result === null) {\n            done = true\n        } else if (result[0].trim()) {\n            if (result[1]) {\n                let attr = result[1].trim()\n                let arr = [attr, \"\"]\n\n                if (attr.indexOf(\"=\") > -1) arr = attr.split(\"=\")\n\n                res.attributes[arr[0]] = arr[1]\n                reg.lastIndex--\n            } else if (result[2]) res.attributes[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n        }\n    }\n\n    return res\n}\n\nfunction parse(\n    html,\n    options = {components: empty}\n) {\n    const result = []\n    let current\n    let level = -1\n    const arr = []\n    let inComponent = false\n\n    html.replace(tagRE, (tag, index) => {\n        if (inComponent) {\n            if (tag !== (`</${current.nodeName}>`)) {\n                return\n            } else {\n                inComponent = false\n            }\n        }\n        const isOpen = tag.charAt(1) !== '/'\n        const isComment = tag.startsWith('<!--')\n        const start = index + tag.length\n        const nextChar = html.charAt(start)\n        let parent\n\n        if (isComment) {\n            const comment = parseTag(tag)\n\n            // if we're at root, push new base node\n            if (level < 0) {\n                result.push(comment)\n                return result\n            }\n            parent = arr[level]\n            if (parent) {\n                if (!parent.childNodes) {\n                    parent.childNodes = []\n                }\n                parent.childNodes.push(comment)\n            }\n\n            return result\n        }\n\n        if (isOpen) {\n            current = parseTag(tag)\n            level++\n            if (current.type === 'tag' && options.components[current.nodeName]) {\n                current.type = 'component'\n                inComponent = true\n            }\n\n            if (!current.voidElement && !inComponent && nextChar && nextChar !== '<') {\n                if (!current.childNodes) {\n                    current.childNodes = []\n                }\n                current.childNodes.push({\n                    nodeName: '#text',\n                    data: unescape(html.slice(start, html.indexOf('<', start)))\n                })\n            }\n\n            // if we're at root, push new base node\n            if (level === 0) {\n                result.push(current)\n            }\n\n            parent = arr[level - 1]\n\n            if (parent) {\n                if (!parent.childNodes) {\n                    parent.childNodes = []\n                }\n                parent.childNodes.push(current)\n            }\n\n            arr[level] = current\n        }\n\n        if (!isOpen || current.voidElement) {\n            level--\n            if (!inComponent && nextChar !== '<' && nextChar) {\n                // trailing text node\n                // if we're at the root, push a base text node. otherwise add as\n                // a child to the current node.\n                parent = level === -1 ? result : arr[level].childNodes || []\n\n                // calculate correct end of the data slice in case there's\n                // no tag after the text node.\n                const end = html.indexOf('<', start)\n                const data = unescape(html.slice(start, end === -1 ? undefined : end))\n                parent.push({\n                    nodeName: '#text',\n                    data\n                })\n            }\n        }\n    })\n\n    return result[0]\n}\n\nfunction cleanObj(obj) {\n    delete obj.voidElement\n    if (obj.childNodes) {\n        obj.childNodes.forEach(child => cleanObj(child))\n    }\n    return obj\n}\n\nexport function stringToObj(string) {\n    return cleanObj(parse(string))\n}\n","export class Diff {\n    constructor(options = {}) {\n        Object.entries(options).forEach(([key, value]) => this[key] = value)\n    }\n\n    toString() {\n        return JSON.stringify(this)\n    }\n\n    setValue(aKey, aValue) {\n        this[aKey] = aValue\n        return this\n    }\n}\n\nfunction elementDescriptors(el) {\n    const output = []\n    output.push(el.nodeName)\n    if (el.nodeName !== '#text' && el.nodeName !== '#comment') {\n        if (el.attributes) {\n            if (el.attributes['class']) {\n                output.push(`${el.nodeName}.${el.attributes['class'].replace(/ /g, '.')}`)\n            }\n            if (el.attributes.id) {\n                output.push(`${el.nodeName}#${el.attributes.id}`)\n            }\n        }\n\n    }\n    return output\n}\n\nfunction findUniqueDescriptors(li) {\n    const uniqueDescriptors = {}\n    const duplicateDescriptors = {}\n\n    li.forEach(node => {\n        elementDescriptors(node).forEach(descriptor => {\n            const inUnique = descriptor in uniqueDescriptors\n            const inDupes = descriptor in duplicateDescriptors\n            if (!inUnique && !inDupes) {\n                uniqueDescriptors[descriptor] = true\n            } else if (inUnique) {\n                delete uniqueDescriptors[descriptor]\n                duplicateDescriptors[descriptor] = true\n            }\n        })\n    })\n\n    return uniqueDescriptors\n}\n\nfunction uniqueInBoth(l1, l2) {\n    const l1Unique = findUniqueDescriptors(l1)\n    const l2Unique = findUniqueDescriptors(l2)\n    const inBoth = {}\n\n    Object.keys(l1Unique).forEach(key => {\n        if (l2Unique[key]) {\n            inBoth[key] = true\n        }\n    })\n\n    return inBoth\n}\n\nexport function removeDone(tree) {\n    delete tree.outerDone\n    delete tree.innerDone\n    delete tree.valueDone\n    if (tree.childNodes) {\n        return tree.childNodes.every(removeDone)\n    } else {\n        return true\n    }\n}\n\nexport function isEqual(e1, e2) {\n    if (!['nodeName', 'value', 'checked', 'selected', 'data'].every(element => {\n            if (e1[element] !== e2[element]) {\n                return false\n            }\n            return true\n        })) {\n        return false\n    }\n\n    if (Boolean(e1.attributes) !== Boolean(e2.attributes)) {\n        return false\n    }\n\n    if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) {\n        return false\n    }\n    if (e1.attributes) {\n        const e1Attributes = Object.keys(e1.attributes)\n        const e2Attributes = Object.keys(e2.attributes)\n\n        if (e1Attributes.length !== e2Attributes.length) {\n            return false\n        }\n        if (!e1Attributes.every(attribute => {\n                if (e1.attributes[attribute] !== e2.attributes[attribute]) {\n                    return false\n                }\n                return true\n            })) {\n            return false\n        }\n    }\n    if (e1.childNodes) {\n        if (e1.childNodes.length !== e2.childNodes.length) {\n            return false\n        }\n        if (!e1.childNodes.every((childNode, index) => isEqual(childNode, e2.childNodes[index]))) {\n\n            return false\n        }\n\n    }\n\n    return true\n}\n\n\nexport function roughlyEqual(e1, e2, uniqueDescriptors, sameSiblings, preventRecursion) {\n\n    if (!e1 || !e2) {\n        return false\n    }\n\n    if (e1.nodeName !== e2.nodeName) {\n        return false\n    }\n\n    if (e1.nodeName === '#text') {\n        // Note that we initially don't care what the text content of a node is,\n        // the mere fact that it's the same tag and \"has text\" means it's roughly\n        // equal, and then we can find out the true text difference later.\n        return preventRecursion ? true : e1.data === e2.data\n    }\n\n\n    if (e1.nodeName in uniqueDescriptors) {\n        return true\n    }\n\n    if (e1.attributes && e2.attributes) {\n\n        if (e1.attributes.id) {\n            if (e1.attributes.id !== e2.attributes.id) {\n                return false\n            } else {\n                const idDescriptor = `${e1.nodeName}#${e1.attributes.id}`\n                if (idDescriptor in uniqueDescriptors) {\n                    return true\n                }\n            }\n        }\n        if (e1.attributes['class'] && e1.attributes['class'] === e2.attributes['class']) {\n            const classDescriptor = `${e1.nodeName}.${e1.attributes['class'].replace(/ /g, '.')}`\n            if (classDescriptor in uniqueDescriptors) {\n                return true\n            }\n        }\n    }\n\n    if (sameSiblings) {\n        return true\n    }\n\n    const nodeList1 = e1.childNodes ? e1.childNodes.slice().reverse() : []\n    const nodeList2 = e2.childNodes ? e2.childNodes.slice().reverse() : []\n\n    if (nodeList1.length !== nodeList2.length) {\n        return false\n    }\n\n    if (preventRecursion) {\n        return nodeList1.every((element, index) => element.nodeName === nodeList2[index].nodeName)\n    } else {\n        // note: we only allow one level of recursion at any depth. If 'preventRecursion'\n        // was not set, we must explicitly force it to true for child iterations.\n        const childUniqueDescriptors = uniqueInBoth(nodeList1, nodeList2)\n        return nodeList1.every((element, index) => roughlyEqual(element, nodeList2[index], childUniqueDescriptors, true, true))\n    }\n}\n\n\nexport function cloneObj(obj) { //  TODO: Do we really need to clone here? Is it not enough to just return the original object?\n    return JSON.parse(JSON.stringify(obj))\n}\n/**\n * based on https://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#JavaScript\n */\nfunction findCommonSubsets(c1, c2, marked1, marked2) {\n    let lcsSize = 0\n    let index = []\n    const c1Length = c1.length\n    const c2Length = c2.length\n\n    const // set up the matching table\n        matches = Array(...new Array(c1Length + 1)).map(() => [])\n\n    const uniqueDescriptors = uniqueInBoth(c1, c2)\n\n    let // If all of the elements are the same tag, id and class, then we can\n        // consider them roughly the same even if they have a different number of\n        // children. This will reduce removing and re-adding similar elements.\n        subsetsSame = c1Length === c2Length\n\n    if (subsetsSame) {\n\n        c1.some((element, i) => {\n            const c1Desc = elementDescriptors(element)\n            const c2Desc = elementDescriptors(c2[i])\n            if (c1Desc.length !== c2Desc.length) {\n                subsetsSame = false\n                return true\n            }\n            c1Desc.some((description, i) => {\n                if (description !== c2Desc[i]) {\n                    subsetsSame = false\n                    return true\n                }\n            })\n            if (!subsetsSame) {\n                return true\n            }\n        })\n    }\n\n    // fill the matches with distance values\n    for (let c1Index = 0; c1Index < c1Length; c1Index++) {\n        const c1Element = c1[c1Index]\n        for (let c2Index = 0; c2Index < c2Length; c2Index++) {\n            const c2Element = c2[c2Index]\n            if (!marked1[c1Index] && !marked2[c2Index] && roughlyEqual(c1Element, c2Element, uniqueDescriptors, subsetsSame)) {\n                matches[c1Index + 1][c2Index + 1] = (matches[c1Index][c2Index] ? matches[c1Index][c2Index] + 1 : 1)\n                if (matches[c1Index + 1][c2Index + 1] >= lcsSize) {\n                    lcsSize = matches[c1Index + 1][c2Index + 1]\n                    index = [c1Index + 1, c2Index + 1]\n                }\n            } else {\n                matches[c1Index + 1][c2Index + 1] = 0\n            }\n        }\n    }\n\n    if (lcsSize === 0) {\n        return false\n    }\n\n    return {\n        oldValue: index[0] - lcsSize,\n        newValue: index[1] - lcsSize,\n        length: lcsSize\n    }\n}\n\n/**\n * This should really be a predefined function in Array...\n */\nfunction makeArray(n, v) {\n    return Array(...new Array(n)).map(() => v)\n}\n\n/**\n * Generate arrays that indicate which node belongs to which subset,\n * or whether it's actually an orphan node, existing in only one\n * of the two trees, rather than somewhere in both.\n *\n * So if t1 = <img><canvas><br>, t2 = <canvas><br><img>.\n * The longest subset is \"<canvas><br>\" (length 2), so it will group 0.\n * The second longest is \"<img>\" (length 1), so it will be group 1.\n * gaps1 will therefore be [1,0,0] and gaps2 [0,0,1].\n *\n * If an element is not part of any group, it will stay being 'true', which\n * is the initial value. For example:\n * t1 = <img><p></p><br><canvas>, t2 = <b></b><br><canvas><img>\n *\n * The \"<p></p>\" and \"<b></b>\" do only show up in one of the two and will\n * therefore be marked by \"true\". The remaining parts are parts of the\n * groups 0 and 1:\n * gaps1 = [1, true, 0, 0], gaps2 = [true, 0, 0, 1]\n *\n */\nexport function getGapInformation(t1, t2, stable) {\n    const gaps1 = t1.childNodes ? makeArray(t1.childNodes.length, true) : []\n    const gaps2 = t2.childNodes ? makeArray(t2.childNodes.length, true) : []\n    let group = 0\n\n    // give elements from the same subset the same group number\n    stable.forEach(subset => {\n        const endOld = subset.oldValue + subset.length\n        const endNew = subset.newValue + subset.length\n\n        for (let j = subset.oldValue; j < endOld; j += 1) {\n            gaps1[j] = group\n        }\n        for (let j = subset.newValue; j < endNew; j += 1) {\n            gaps2[j] = group\n        }\n        group += 1\n    })\n\n    return {\n        gaps1,\n        gaps2\n    }\n}\n\n/**\n * Find all matching subsets, based on immediate child differences only.\n */\nexport function markSubTrees(oldTree, newTree) {\n    // note: the child lists are views, and so update as we update old/newTree\n    const oldChildren = oldTree.childNodes ? oldTree.childNodes : []\n\n    const newChildren = newTree.childNodes ? newTree.childNodes : []\n    const marked1 = makeArray(oldChildren.length, false)\n    const marked2 = makeArray(newChildren.length, false)\n    const subsets = []\n    let subset = true\n\n    const returnIndex = function() {\n        return arguments[1]\n    }\n\n    const markBoth = i => {\n        marked1[subset.oldValue + i] = true\n        marked2[subset.newValue + i] = true\n    }\n\n    while (subset) {\n        subset = findCommonSubsets(oldChildren, newChildren, marked1, marked2)\n        if (subset) {\n            subsets.push(subset)\n            const subsetArray = Array(...new Array(subset.length)).map(returnIndex)\n            subsetArray.forEach(item => markBoth(item))\n        }\n    }\n\n    oldTree.subsets = subsets\n    oldTree.subsetsAge = 100\n    return subsets\n}\n\nexport class DiffTracker {\n    constructor() {\n        this.list = []\n    }\n\n    add(diffs) {\n        this.list.push(...diffs)\n    }\n    forEach(fn) {\n        this.list.forEach(li => fn(li))\n    }\n\n}\n","export {DiffFinder} from \"./diff\"\nexport {nodeToObj} from \"./fromDOM\"\nexport {stringToObj} from \"./fromString\"\n","export {DiffDOM, nodeToObj, stringToObj} from \"./diffDOM/index\"\nexport {TraceLogger} from \"./TraceLogger\"\n","/*!\n * mustache.js - Logic-less {{mustache}} templates with JavaScript\n * http://github.com/janl/mustache.js\n */\n\nvar objectToString = Object.prototype.toString;\nvar isArray = Array.isArray || function isArrayPolyfill (object) {\n  return objectToString.call(object) === '[object Array]';\n};\n\nfunction isFunction (object) {\n  return typeof object === 'function';\n}\n\n/**\n * More correct typeof string handling array\n * which normally returns typeof 'object'\n */\nfunction typeStr (obj) {\n  return isArray(obj) ? 'array' : typeof obj;\n}\n\nfunction escapeRegExp (string) {\n  return string.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n}\n\n/**\n * Null safe way of checking whether or not an object,\n * including its prototype, has a given property\n */\nfunction hasProperty (obj, propName) {\n  return obj != null && typeof obj === 'object' && (propName in obj);\n}\n\n/**\n * Safe way of detecting whether or not the given thing is a primitive and\n * whether it has the given property\n */\nfunction primitiveHasOwnProperty (primitive, propName) {\n  return (\n    primitive != null\n    && typeof primitive !== 'object'\n    && primitive.hasOwnProperty\n    && primitive.hasOwnProperty(propName)\n  );\n}\n\n// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577\n// See https://github.com/janl/mustache.js/issues/189\nvar regExpTest = RegExp.prototype.test;\nfunction testRegExp (re, string) {\n  return regExpTest.call(re, string);\n}\n\nvar nonSpaceRe = /\\S/;\nfunction isWhitespace (string) {\n  return !testRegExp(nonSpaceRe, string);\n}\n\nvar entityMap = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;',\n  '/': '&#x2F;',\n  '`': '&#x60;',\n  '=': '&#x3D;'\n};\n\nfunction escapeHtml (string) {\n  return String(string).replace(/[&<>\"'`=\\/]/g, function fromEntityMap (s) {\n    return entityMap[s];\n  });\n}\n\nvar whiteRe = /\\s*/;\nvar spaceRe = /\\s+/;\nvar equalsRe = /\\s*=/;\nvar curlyRe = /\\s*\\}/;\nvar tagRe = /#|\\^|\\/|>|\\{|&|=|!/;\n\n/**\n * Breaks up the given `template` string into a tree of tokens. If the `tags`\n * argument is given here it must be an array with two string values: the\n * opening and closing tags used in the template (e.g. [ \"<%\", \"%>\" ]). Of\n * course, the default is to use mustaches (i.e. mustache.tags).\n *\n * A token is an array with at least 4 elements. The first element is the\n * mustache symbol that was used inside the tag, e.g. \"#\" or \"&\". If the tag\n * did not contain a symbol (i.e. {{myValue}}) this element is \"name\". For\n * all text that appears outside a symbol this element is \"text\".\n *\n * The second element of a token is its \"value\". For mustache tags this is\n * whatever else was inside the tag besides the opening symbol. For text tokens\n * this is the text itself.\n *\n * The third and fourth elements of the token are the start and end indices,\n * respectively, of the token in the original template.\n *\n * Tokens that are the root node of a subtree contain two more elements: 1) an\n * array of tokens in the subtree and 2) the index in the original template at\n * which the closing tag for that section begins.\n *\n * Tokens for partials also contain two more elements: 1) a string value of\n * indendation prior to that tag and 2) the index of that tag on that line -\n * eg a value of 2 indicates the partial is the third tag on this line.\n */\nfunction parseTemplate (template, tags) {\n  if (!template)\n    return [];\n  var lineHasNonSpace = false;\n  var sections = [];     // Stack to hold section tokens\n  var tokens = [];       // Buffer to hold the tokens\n  var spaces = [];       // Indices of whitespace tokens on the current line\n  var hasTag = false;    // Is there a {{tag}} on the current line?\n  var nonSpace = false;  // Is there a non-space char on the current line?\n  var indentation = '';  // Tracks indentation for tags that use it\n  var tagIndex = 0;      // Stores a count of number of tags encountered on a line\n\n  // Strips all whitespace tokens array for the current line\n  // if there was a {{#tag}} on it and otherwise only space.\n  function stripSpace () {\n    if (hasTag && !nonSpace) {\n      while (spaces.length)\n        delete tokens[spaces.pop()];\n    } else {\n      spaces = [];\n    }\n\n    hasTag = false;\n    nonSpace = false;\n  }\n\n  var openingTagRe, closingTagRe, closingCurlyRe;\n  function compileTags (tagsToCompile) {\n    if (typeof tagsToCompile === 'string')\n      tagsToCompile = tagsToCompile.split(spaceRe, 2);\n\n    if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)\n      throw new Error('Invalid tags: ' + tagsToCompile);\n\n    openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\\\s*');\n    closingTagRe = new RegExp('\\\\s*' + escapeRegExp(tagsToCompile[1]));\n    closingCurlyRe = new RegExp('\\\\s*' + escapeRegExp('}' + tagsToCompile[1]));\n  }\n\n  compileTags(tags || mustache.tags);\n\n  var scanner = new Scanner(template);\n\n  var start, type, value, chr, token, openSection;\n  while (!scanner.eos()) {\n    start = scanner.pos;\n\n    // Match any text between tags.\n    value = scanner.scanUntil(openingTagRe);\n\n    if (value) {\n      for (var i = 0, valueLength = value.length; i < valueLength; ++i) {\n        chr = value.charAt(i);\n\n        if (isWhitespace(chr)) {\n          spaces.push(tokens.length);\n          indentation += chr;\n        } else {\n          nonSpace = true;\n          lineHasNonSpace = true;\n          indentation += ' ';\n        }\n\n        tokens.push([ 'text', chr, start, start + 1 ]);\n        start += 1;\n\n        // Check for whitespace on the current line.\n        if (chr === '\\n') {\n          stripSpace();\n          indentation = '';\n          tagIndex = 0;\n          lineHasNonSpace = false;\n        }\n      }\n    }\n\n    // Match the opening tag.\n    if (!scanner.scan(openingTagRe))\n      break;\n\n    hasTag = true;\n\n    // Get the tag type.\n    type = scanner.scan(tagRe) || 'name';\n    scanner.scan(whiteRe);\n\n    // Get the tag value.\n    if (type === '=') {\n      value = scanner.scanUntil(equalsRe);\n      scanner.scan(equalsRe);\n      scanner.scanUntil(closingTagRe);\n    } else if (type === '{') {\n      value = scanner.scanUntil(closingCurlyRe);\n      scanner.scan(curlyRe);\n      scanner.scanUntil(closingTagRe);\n      type = '&';\n    } else {\n      value = scanner.scanUntil(closingTagRe);\n    }\n\n    // Match the closing tag.\n    if (!scanner.scan(closingTagRe))\n      throw new Error('Unclosed tag at ' + scanner.pos);\n\n    if (type == '>') {\n      token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];\n    } else {\n      token = [ type, value, start, scanner.pos ];\n    }\n    tagIndex++;\n    tokens.push(token);\n\n    if (type === '#' || type === '^') {\n      sections.push(token);\n    } else if (type === '/') {\n      // Check section nesting.\n      openSection = sections.pop();\n\n      if (!openSection)\n        throw new Error('Unopened section \"' + value + '\" at ' + start);\n\n      if (openSection[1] !== value)\n        throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + start);\n    } else if (type === 'name' || type === '{' || type === '&') {\n      nonSpace = true;\n    } else if (type === '=') {\n      // Set the tags for the next time around.\n      compileTags(value);\n    }\n  }\n\n  stripSpace();\n\n  // Make sure there are no open sections when we're done.\n  openSection = sections.pop();\n\n  if (openSection)\n    throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + scanner.pos);\n\n  return nestTokens(squashTokens(tokens));\n}\n\n/**\n * Combines the values of consecutive text tokens in the given `tokens` array\n * to a single token.\n */\nfunction squashTokens (tokens) {\n  var squashedTokens = [];\n\n  var token, lastToken;\n  for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n    token = tokens[i];\n\n    if (token) {\n      if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {\n        lastToken[1] += token[1];\n        lastToken[3] = token[3];\n      } else {\n        squashedTokens.push(token);\n        lastToken = token;\n      }\n    }\n  }\n\n  return squashedTokens;\n}\n\n/**\n * Forms the given array of `tokens` into a nested tree structure where\n * tokens that represent a section have two additional items: 1) an array of\n * all tokens that appear in that section and 2) the index in the original\n * template that represents the end of that section.\n */\nfunction nestTokens (tokens) {\n  var nestedTokens = [];\n  var collector = nestedTokens;\n  var sections = [];\n\n  var token, section;\n  for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n    token = tokens[i];\n\n    switch (token[0]) {\n      case '#':\n      case '^':\n        collector.push(token);\n        sections.push(token);\n        collector = token[4] = [];\n        break;\n      case '/':\n        section = sections.pop();\n        section[5] = token[2];\n        collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;\n        break;\n      default:\n        collector.push(token);\n    }\n  }\n\n  return nestedTokens;\n}\n\n/**\n * A simple string scanner that is used by the template parser to find\n * tokens in template strings.\n */\nfunction Scanner (string) {\n  this.string = string;\n  this.tail = string;\n  this.pos = 0;\n}\n\n/**\n * Returns `true` if the tail is empty (end of string).\n */\nScanner.prototype.eos = function eos () {\n  return this.tail === '';\n};\n\n/**\n * Tries to match the given regular expression at the current position.\n * Returns the matched text if it can match, the empty string otherwise.\n */\nScanner.prototype.scan = function scan (re) {\n  var match = this.tail.match(re);\n\n  if (!match || match.index !== 0)\n    return '';\n\n  var string = match[0];\n\n  this.tail = this.tail.substring(string.length);\n  this.pos += string.length;\n\n  return string;\n};\n\n/**\n * Skips all text until the given regular expression can be matched. Returns\n * the skipped string, which is the entire tail if no match can be made.\n */\nScanner.prototype.scanUntil = function scanUntil (re) {\n  var index = this.tail.search(re), match;\n\n  switch (index) {\n    case -1:\n      match = this.tail;\n      this.tail = '';\n      break;\n    case 0:\n      match = '';\n      break;\n    default:\n      match = this.tail.substring(0, index);\n      this.tail = this.tail.substring(index);\n  }\n\n  this.pos += match.length;\n\n  return match;\n};\n\n/**\n * Represents a rendering context by wrapping a view object and\n * maintaining a reference to the parent context.\n */\nfunction Context (view, parentContext) {\n  this.view = view;\n  this.cache = { '.': this.view };\n  this.parent = parentContext;\n}\n\n/**\n * Creates a new context using the given view with this context\n * as the parent.\n */\nContext.prototype.push = function push (view) {\n  return new Context(view, this);\n};\n\n/**\n * Returns the value of the given name in this context, traversing\n * up the context hierarchy if the value is absent in this context's view.\n */\nContext.prototype.lookup = function lookup (name) {\n  var cache = this.cache;\n\n  var value;\n  if (cache.hasOwnProperty(name)) {\n    value = cache[name];\n  } else {\n    var context = this, intermediateValue, names, index, lookupHit = false;\n\n    while (context) {\n      if (name.indexOf('.') > 0) {\n        intermediateValue = context.view;\n        names = name.split('.');\n        index = 0;\n\n        /**\n         * Using the dot notion path in `name`, we descend through the\n         * nested objects.\n         *\n         * To be certain that the lookup has been successful, we have to\n         * check if the last object in the path actually has the property\n         * we are looking for. We store the result in `lookupHit`.\n         *\n         * This is specially necessary for when the value has been set to\n         * `undefined` and we want to avoid looking up parent contexts.\n         *\n         * In the case where dot notation is used, we consider the lookup\n         * to be successful even if the last \"object\" in the path is\n         * not actually an object but a primitive (e.g., a string, or an\n         * integer), because it is sometimes useful to access a property\n         * of an autoboxed primitive, such as the length of a string.\n         **/\n        while (intermediateValue != null && index < names.length) {\n          if (index === names.length - 1)\n            lookupHit = (\n              hasProperty(intermediateValue, names[index])\n              || primitiveHasOwnProperty(intermediateValue, names[index])\n            );\n\n          intermediateValue = intermediateValue[names[index++]];\n        }\n      } else {\n        intermediateValue = context.view[name];\n\n        /**\n         * Only checking against `hasProperty`, which always returns `false` if\n         * `context.view` is not an object. Deliberately omitting the check\n         * against `primitiveHasOwnProperty` if dot notation is not used.\n         *\n         * Consider this example:\n         * ```\n         * Mustache.render(\"The length of a football field is {{#length}}{{length}}{{/length}}.\", {length: \"100 yards\"})\n         * ```\n         *\n         * If we were to check also against `primitiveHasOwnProperty`, as we do\n         * in the dot notation case, then render call would return:\n         *\n         * \"The length of a football field is 9.\"\n         *\n         * rather than the expected:\n         *\n         * \"The length of a football field is 100 yards.\"\n         **/\n        lookupHit = hasProperty(context.view, name);\n      }\n\n      if (lookupHit) {\n        value = intermediateValue;\n        break;\n      }\n\n      context = context.parent;\n    }\n\n    cache[name] = value;\n  }\n\n  if (isFunction(value))\n    value = value.call(this.view);\n\n  return value;\n};\n\n/**\n * A Writer knows how to take a stream of tokens and render them to a\n * string, given a context. It also maintains a cache of templates to\n * avoid the need to parse the same template twice.\n */\nfunction Writer () {\n  this.templateCache = {\n    _cache: {},\n    set: function set (key, value) {\n      this._cache[key] = value;\n    },\n    get: function get (key) {\n      return this._cache[key];\n    },\n    clear: function clear () {\n      this._cache = {};\n    }\n  };\n}\n\n/**\n * Clears all cached templates in this writer.\n */\nWriter.prototype.clearCache = function clearCache () {\n  if (typeof this.templateCache !== 'undefined') {\n    this.templateCache.clear();\n  }\n};\n\n/**\n * Parses and caches the given `template` according to the given `tags` or\n * `mustache.tags` if `tags` is omitted,  and returns the array of tokens\n * that is generated from the parse.\n */\nWriter.prototype.parse = function parse (template, tags) {\n  var cache = this.templateCache;\n  var cacheKey = template + ':' + (tags || mustache.tags).join(':');\n  var isCacheEnabled = typeof cache !== 'undefined';\n  var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined;\n\n  if (tokens == undefined) {\n    tokens = parseTemplate(template, tags);\n    isCacheEnabled && cache.set(cacheKey, tokens);\n  }\n  return tokens;\n};\n\n/**\n * High-level method that is used to render the given `template` with\n * the given `view`.\n *\n * The optional `partials` argument may be an object that contains the\n * names and templates of partials that are used in the template. It may\n * also be a function that is used to load partial templates on the fly\n * that takes a single argument: the name of the partial.\n *\n * If the optional `config` argument is given here, then it should be an\n * object with a `tags` attribute or an `escape` attribute or both.\n * If an array is passed, then it will be interpreted the same way as\n * a `tags` attribute on a `config` object.\n *\n * The `tags` attribute of a `config` object must be an array with two\n * string values: the opening and closing tags used in the template (e.g.\n * [ \"<%\", \"%>\" ]). The default is to mustache.tags.\n *\n * The `escape` attribute of a `config` object must be a function which\n * accepts a string as input and outputs a safely escaped string.\n * If an `escape` function is not provided, then an HTML-safe string\n * escaping function is used as the default.\n */\nWriter.prototype.render = function render (template, view, partials, config) {\n  var tags = this.getConfigTags(config);\n  var tokens = this.parse(template, tags);\n  var context = (view instanceof Context) ? view : new Context(view, undefined);\n  return this.renderTokens(tokens, context, partials, template, config);\n};\n\n/**\n * Low-level method that renders the given array of `tokens` using\n * the given `context` and `partials`.\n *\n * Note: The `originalTemplate` is only ever used to extract the portion\n * of the original template that was contained in a higher-order section.\n * If the template doesn't use higher-order sections, this argument may\n * be omitted.\n */\nWriter.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, config) {\n  var buffer = '';\n\n  var token, symbol, value;\n  for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n    value = undefined;\n    token = tokens[i];\n    symbol = token[0];\n\n    if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);\n    else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);\n    else if (symbol === '>') value = this.renderPartial(token, context, partials, config);\n    else if (symbol === '&') value = this.unescapedValue(token, context);\n    else if (symbol === 'name') value = this.escapedValue(token, context, config);\n    else if (symbol === 'text') value = this.rawValue(token);\n\n    if (value !== undefined)\n      buffer += value;\n  }\n\n  return buffer;\n};\n\nWriter.prototype.renderSection = function renderSection (token, context, partials, originalTemplate, config) {\n  var self = this;\n  var buffer = '';\n  var value = context.lookup(token[1]);\n\n  // This function is used to render an arbitrary template\n  // in the current context by higher-order sections.\n  function subRender (template) {\n    return self.render(template, context, partials, config);\n  }\n\n  if (!value) return;\n\n  if (isArray(value)) {\n    for (var j = 0, valueLength = value.length; j < valueLength; ++j) {\n      buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);\n    }\n  } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {\n    buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);\n  } else if (isFunction(value)) {\n    if (typeof originalTemplate !== 'string')\n      throw new Error('Cannot use higher-order sections without the original template');\n\n    // Extract the portion of the original template that the section contains.\n    value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);\n\n    if (value != null)\n      buffer += value;\n  } else {\n    buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);\n  }\n  return buffer;\n};\n\nWriter.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate, config) {\n  var value = context.lookup(token[1]);\n\n  // Use JavaScript's definition of falsy. Include empty arrays.\n  // See https://github.com/janl/mustache.js/issues/186\n  if (!value || (isArray(value) && value.length === 0))\n    return this.renderTokens(token[4], context, partials, originalTemplate, config);\n};\n\nWriter.prototype.indentPartial = function indentPartial (partial, indentation, lineHasNonSpace) {\n  var filteredIndentation = indentation.replace(/[^ \\t]/g, '');\n  var partialByNl = partial.split('\\n');\n  for (var i = 0; i < partialByNl.length; i++) {\n    if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {\n      partialByNl[i] = filteredIndentation + partialByNl[i];\n    }\n  }\n  return partialByNl.join('\\n');\n};\n\nWriter.prototype.renderPartial = function renderPartial (token, context, partials, config) {\n  if (!partials) return;\n  var tags = this.getConfigTags(config);\n\n  var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];\n  if (value != null) {\n    var lineHasNonSpace = token[6];\n    var tagIndex = token[5];\n    var indentation = token[4];\n    var indentedValue = value;\n    if (tagIndex == 0 && indentation) {\n      indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);\n    }\n    var tokens = this.parse(indentedValue, tags);\n    return this.renderTokens(tokens, context, partials, indentedValue, config);\n  }\n};\n\nWriter.prototype.unescapedValue = function unescapedValue (token, context) {\n  var value = context.lookup(token[1]);\n  if (value != null)\n    return value;\n};\n\nWriter.prototype.escapedValue = function escapedValue (token, context, config) {\n  var escape = this.getConfigEscape(config) || mustache.escape;\n  var value = context.lookup(token[1]);\n  if (value != null)\n    return (typeof value === 'number' && escape === mustache.escape) ? String(value) : escape(value);\n};\n\nWriter.prototype.rawValue = function rawValue (token) {\n  return token[1];\n};\n\nWriter.prototype.getConfigTags = function getConfigTags (config) {\n  if (isArray(config)) {\n    return config;\n  }\n  else if (config && typeof config === 'object') {\n    return config.tags;\n  }\n  else {\n    return undefined;\n  }\n};\n\nWriter.prototype.getConfigEscape = function getConfigEscape (config) {\n  if (config && typeof config === 'object' && !isArray(config)) {\n    return config.escape;\n  }\n  else {\n    return undefined;\n  }\n};\n\nvar mustache = {\n  name: 'mustache.js',\n  version: '4.2.0',\n  tags: [ '{{', '}}' ],\n  clearCache: undefined,\n  escape: undefined,\n  parse: undefined,\n  render: undefined,\n  Scanner: undefined,\n  Context: undefined,\n  Writer: undefined,\n  /**\n   * Allows a user to override the default caching strategy, by providing an\n   * object with set, get and clear methods. This can also be used to disable\n   * the cache by setting it to the literal `undefined`.\n   */\n  set templateCache (cache) {\n    defaultWriter.templateCache = cache;\n  },\n  /**\n   * Gets the default or overridden caching object from the default writer.\n   */\n  get templateCache () {\n    return defaultWriter.templateCache;\n  }\n};\n\n// All high-level mustache.* functions use this writer.\nvar defaultWriter = new Writer();\n\n/**\n * Clears all cached templates in the default writer.\n */\nmustache.clearCache = function clearCache () {\n  return defaultWriter.clearCache();\n};\n\n/**\n * Parses and caches the given template in the default writer and returns the\n * array of tokens it contains. Doing this ahead of time avoids the need to\n * parse templates on the fly as they are rendered.\n */\nmustache.parse = function parse (template, tags) {\n  return defaultWriter.parse(template, tags);\n};\n\n/**\n * Renders the `template` with the given `view`, `partials`, and `config`\n * using the default writer.\n */\nmustache.render = function render (template, view, partials, config) {\n  if (typeof template !== 'string') {\n    throw new TypeError('Invalid template! Template should be a \"string\" ' +\n                        'but \"' + typeStr(template) + '\" was given as the first ' +\n                        'argument for mustache#render(template, view, partials)');\n  }\n\n  return defaultWriter.render(template, view, partials, config);\n};\n\n// Export the escaping function so that the user may override it.\n// See https://github.com/janl/mustache.js/issues/244\nmustache.escape = escapeHtml;\n\n// Export these mainly for testing, but also for advanced usage.\nmustache.Scanner = Scanner;\nmustache.Context = Context;\nmustache.Writer = Writer;\n\nexport default mustache;\n"],"names":[],"sourceRoot":""}