var QRCode;!function(){function c(n){var t;this.mode=r.MODE_8BIT_BYTE;this.data=n;this.parsedData=[];for(var i=[],u=0,f=this.data.length;f>u;u++)t=this.data.charCodeAt(u),t>65536?(i[0]=240|(1835008&t)>>>18,i[1]=128|(258048&t)>>>12,i[2]=128|(4032&t)>>>6,i[3]=128|63&t):t>2048?(i[0]=224|(61440&t)>>>12,i[1]=128|(4032&t)>>>6,i[2]=128|63&t):t>128?(i[0]=192|(1984&t)>>>6,i[1]=128|63&t):i[0]=t,this.parsedData=this.parsedData.concat(i);this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function u(n,t){this.typeNumber=n;this.errorCorrectLevel=t;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function s(n,t){var i,r;if(void 0==n.length)throw new Error(n.length+"/"+t);for(i=0;i<n.length&&0==n[i];)i++;for(this.num=new Array(n.length-i+t),r=0;r<n.length-i;r++)this.num[r]=n[r+i]}function f(n,t){this.totalCount=n;this.dataCount=t}function l(){this.buffer=[];this.length=0}function v(){return"undefined"!=typeof CanvasRenderingContext2D}function a(){var n=!1,t=navigator.userAgent;return/android/i.test(t)&&(n=!0,aMat=t.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(n=parseFloat(aMat[1]))),n}function y(n,t){for(var r,u=1,f=p(n),i=0,o=h.length;o>=i;i++){r=0;switch(t){case e.L:r=h[i][0];break;case e.M:r=h[i][1];break;case e.Q:r=h[i][2];break;case e.H:r=h[i][3]}if(r>=f)break;u++}if(u>h.length)throw new Error("Too long data");return u}function p(n){var t=encodeURI(n).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return t.length+(t.length!=n?3:0)}var i;c.prototype={getLength:function(){return this.parsedData.length},write:function(n){for(var t=0,i=this.parsedData.length;i>t;t++)n.put(this.parsedData[t],8)}};u.prototype={addData:function(n){var t=new c(n);this.dataList.push(t);this.dataCache=null},isDark:function(n,t){if(0>n||this.moduleCount<=n||0>t||this.moduleCount<=t)throw new Error(n+","+t);return this.modules[n][t]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(n,t){var i,r;for(this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount),i=0;i<this.moduleCount;i++)for(this.modules[i]=new Array(this.moduleCount),r=0;r<this.moduleCount;r++)this.modules[i][r]=null;this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(n,t);this.typeNumber>=7&&this.setupTypeNumber(n);null==this.dataCache&&(this.dataCache=u.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,t)},setupPositionProbePattern:function(n,t){for(var r,i=-1;7>=i;i++)if(!(-1>=n+i||this.moduleCount<=n+i))for(r=-1;7>=r;r++)-1>=t+r||this.moduleCount<=t+r||(this.modules[n+i][t+r]=i>=0&&6>=i&&(0==r||6==r)||r>=0&&6>=r&&(0==i||6==i)||i>=2&&4>=i&&r>=2&&4>=r?!0:!1)},getBestMaskPattern:function(){for(var i,r=0,u=0,t=0;8>t;t++)this.makeImpl(!0,t),i=n.getLostPoint(this),(0==t||r>i)&&(r=i,u=t);return u},createMovieClip:function(n,t,i){var r=n.createEmptyMovieClip(t,i),u=1,f,e,o,s,h;for(this.make(),f=0;f<this.modules.length;f++)for(e=f*u,o=0;o<this.modules[f].length;o++)s=o*u,h=this.modules[f][o],h&&(r.beginFill(0,100),r.moveTo(s,e),r.lineTo(s+u,e),r.lineTo(s+u,e+u),r.lineTo(s,e+u),r.endFill());return r},setupTimingPattern:function(){for(var t,n=8;n<this.moduleCount-8;n++)null==this.modules[n][6]&&(this.modules[n][6]=0==n%2);for(t=8;t<this.moduleCount-8;t++)null==this.modules[6][t]&&(this.modules[6][t]=0==t%2)},setupPositionAdjustPattern:function(){for(var f,e,o,t,i,r=n.getPatternPosition(this.typeNumber),u=0;u<r.length;u++)for(f=0;f<r.length;f++)if(e=r[u],o=r[f],null==this.modules[e][o])for(t=-2;2>=t;t++)for(i=-2;2>=i;i++)this.modules[e+t][o+i]=-2==t||2==t||-2==i||2==i||0==t&&0==i?!0:!1},setupTypeNumber:function(t){for(var r,u=n.getBCHTypeNumber(this.typeNumber),i=0;18>i;i++)r=!t&&1==(1&u>>i),this.modules[Math.floor(i/3)][i%3+this.moduleCount-11]=r;for(i=0;18>i;i++)r=!t&&1==(1&u>>i),this.modules[i%3+this.moduleCount-11][Math.floor(i/3)]=r},setupTypeInfo:function(t,i){for(var u,e=this.errorCorrectLevel<<3|i,f=n.getBCHTypeInfo(e),r=0;15>r;r++)u=!t&&1==(1&f>>r),6>r?this.modules[r][8]=u:8>r?this.modules[r+1][8]=u:this.modules[this.moduleCount-15+r][8]=u;for(r=0;15>r;r++)u=!t&&1==(1&f>>r),8>r?this.modules[8][this.moduleCount-r-1]=u:9>r?this.modules[8][15-r]=u:this.modules[8][14-r]=u;this.modules[this.moduleCount-8][8]=!t},mapData:function(t,i){for(var f,e,c,o=-1,r=this.moduleCount-1,s=7,h=0,u=this.moduleCount-1;u>0;u-=2)for(6==u&&u--;;){for(f=0;2>f;f++)null==this.modules[r][u-f]&&(e=!1,h<t.length&&(e=1==(1&t[h]>>>s)),c=n.getMask(i,r,u-f),c&&(e=!e),this.modules[r][u-f]=e,s--,-1==s&&(h++,s=7));if(r+=o,0>r||this.moduleCount<=r){r-=o;o=-o;break}}}};u.PAD0=236;u.PAD1=17;u.createData=function(t,i,r){for(var h,s,c=f.getRSBlocks(t,i),e=new l,o=0;o<r.length;o++)h=r[o],e.put(h.mode,4),e.put(h.getLength(),n.getLengthInBits(h.mode,t)),h.write(e);for(s=0,o=0;o<c.length;o++)s+=c[o].dataCount;if(e.getLengthInBits()>8*s)throw new Error("code length overflow. ("+e.getLengthInBits()+">"+8*s+")");for(e.getLengthInBits()+4<=8*s&&e.put(0,4);0!=e.getLengthInBits()%8;)e.putBit(!1);for(;;){if(e.getLengthInBits()>=8*s)break;if(e.put(u.PAD0,8),e.getLengthInBits()>=8*s)break;e.put(u.PAD1,8)}return u.createBytes(e,c)};u.createBytes=function(t,i){for(var o,l,v,y,r,w=0,h=0,c=0,f=new Array(i.length),e=new Array(i.length),u=0;u<i.length;u++){for(o=i[u].dataCount,l=i[u].totalCount-o,h=Math.max(h,o),c=Math.max(c,l),f[u]=new Array(o),r=0;r<f[u].length;r++)f[u][r]=255&t.buffer[r+w];w+=o;var a=n.getErrorCorrectPolynomial(l),d=new s(f[u],a.getLength()-1),b=d.mod(a);for(e[u]=new Array(a.getLength()-1),r=0;r<e[u].length;r++)v=r+b.getLength()-e[u].length,e[u][r]=v>=0?b.get(v):0}for(y=0,r=0;r<i.length;r++)y+=i[r].totalCount;for(var p=new Array(y),k=0,r=0;h>r;r++)for(u=0;u<i.length;u++)r<f[u].length&&(p[k++]=f[u][r]);for(r=0;c>r;r++)for(u=0;u<i.length;u++)r<e[u].length&&(p[k++]=e[u][r]);return p};for(var r={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},e={L:1,M:0,Q:3,H:2},o={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},n={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(t){for(var i=t<<10;n.getBCHDigit(i)-n.getBCHDigit(n.G15)>=0;)i^=n.G15<<n.getBCHDigit(i)-n.getBCHDigit(n.G15);return(t<<10|i)^n.G15_MASK},getBCHTypeNumber:function(t){for(var i=t<<12;n.getBCHDigit(i)-n.getBCHDigit(n.G18)>=0;)i^=n.G18<<n.getBCHDigit(i)-n.getBCHDigit(n.G18);return t<<12|i},getBCHDigit:function(n){for(var t=0;0!=n;)t++,n>>>=1;return t},getPatternPosition:function(t){return n.PATTERN_POSITION_TABLE[t-1]},getMask:function(n,t,i){switch(n){case o.PATTERN000:return 0==(t+i)%2;case o.PATTERN001:return 0==t%2;case o.PATTERN010:return 0==i%3;case o.PATTERN011:return 0==(t+i)%3;case o.PATTERN100:return 0==(Math.floor(t/2)+Math.floor(i/3))%2;case o.PATTERN101:return 0==t*i%2+t*i%3;case o.PATTERN110:return 0==(t*i%2+t*i%3)%2;case o.PATTERN111:return 0==(t*i%3+(t+i)%2)%2;default:throw new Error("bad maskPattern:"+n);}},getErrorCorrectPolynomial:function(n){for(var i=new s([1],0),r=0;n>r;r++)i=i.multiply(new s([1,t.gexp(r)],0));return i},getLengthInBits:function(n,t){if(t>=1&&10>t)switch(n){case r.MODE_NUMBER:return 10;case r.MODE_ALPHA_NUM:return 9;case r.MODE_8BIT_BYTE:return 8;case r.MODE_KANJI:return 8;default:throw new Error("mode:"+n);}else if(27>t)switch(n){case r.MODE_NUMBER:return 12;case r.MODE_ALPHA_NUM:return 11;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 10;default:throw new Error("mode:"+n);}else{if(!(41>t))throw new Error("type:"+t);switch(n){case r.MODE_NUMBER:return 14;case r.MODE_ALPHA_NUM:return 13;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 12;default:throw new Error("mode:"+n);}}},getLostPoint:function(n){for(var u,f,h,t,c,r=n.getModuleCount(),o=0,i=0;r>i;i++)for(t=0;r>t;t++){for(var s=0,l=n.isDark(i,t),e=-1;1>=e;e++)if(!(0>i+e||i+e>=r))for(u=-1;1>=u;u++)0>t+u||t+u>=r||(0!=e||0!=u)&&l==n.isDark(i+e,t+u)&&s++;s>5&&(o+=3+s-5)}for(i=0;r-1>i;i++)for(t=0;r-1>t;t++)f=0,n.isDark(i,t)&&f++,n.isDark(i+1,t)&&f++,n.isDark(i,t+1)&&f++,n.isDark(i+1,t+1)&&f++,(0==f||4==f)&&(o+=3);for(i=0;r>i;i++)for(t=0;r-6>t;t++)n.isDark(i,t)&&!n.isDark(i,t+1)&&n.isDark(i,t+2)&&n.isDark(i,t+3)&&n.isDark(i,t+4)&&!n.isDark(i,t+5)&&n.isDark(i,t+6)&&(o+=40);for(t=0;r>t;t++)for(i=0;r-6>i;i++)n.isDark(i,t)&&!n.isDark(i+1,t)&&n.isDark(i+2,t)&&n.isDark(i+3,t)&&n.isDark(i+4,t)&&!n.isDark(i+5,t)&&n.isDark(i+6,t)&&(o+=40);for(h=0,t=0;r>t;t++)for(i=0;r>i;i++)n.isDark(i,t)&&h++;return c=Math.abs(100*h/r/r-50)/5,o+10*c}},t={glog:function(n){if(1>n)throw new Error("glog("+n+")");return t.LOG_TABLE[n]},gexp:function(n){for(;0>n;)n+=255;for(;n>=256;)n-=255;return t.EXP_TABLE[n]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},i=0;8>i;i++)t.EXP_TABLE[i]=1<<i;for(i=8;256>i;i++)t.EXP_TABLE[i]=t.EXP_TABLE[i-4]^t.EXP_TABLE[i-5]^t.EXP_TABLE[i-6]^t.EXP_TABLE[i-8];for(i=0;255>i;i++)t.LOG_TABLE[t.EXP_TABLE[i]]=i;s.prototype={get:function(n){return this.num[n]},getLength:function(){return this.num.length},multiply:function(n){for(var r,u=new Array(this.getLength()+n.getLength()-1),i=0;i<this.getLength();i++)for(r=0;r<n.getLength();r++)u[i+r]^=t.gexp(t.glog(this.get(i))+t.glog(n.get(r)));return new s(u,0)},mod:function(n){var i;if(this.getLength()-n.getLength()<0)return this;for(var u=t.glog(this.get(0))-t.glog(n.get(0)),r=new Array(this.getLength()),i=0;i<this.getLength();i++)r[i]=this.get(i);for(i=0;i<n.getLength();i++)r[i]^=t.gexp(t.glog(n.get(i))+u);return new s(r,0).mod(n)}};f.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];f.getRSBlocks=function(n,t){var i=f.getRsBlockTable(n,t);if(void 0==i)throw new Error("bad rs block @ typeNumber:"+n+"/errorCorrectLevel:"+t);for(var o=i.length/3,u=[],r=0;o>r;r++)for(var s=i[3*r+0],h=i[3*r+1],c=i[3*r+2],e=0;s>e;e++)u.push(new f(h,c));return u};f.getRsBlockTable=function(n,t){switch(t){case e.L:return f.RS_BLOCK_TABLE[4*(n-1)+0];case e.M:return f.RS_BLOCK_TABLE[4*(n-1)+1];case e.Q:return f.RS_BLOCK_TABLE[4*(n-1)+2];case e.H:return f.RS_BLOCK_TABLE[4*(n-1)+3];default:return void 0}};l.prototype={get:function(n){var t=Math.floor(n/8);return 1==(1&this.buffer[t]>>>7-n%8)},put:function(n,t){for(var i=0;t>i;i++)this.putBit(1==(1&n>>>t-i-1))},getLengthInBits:function(){return this.length},putBit:function(n){var t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0);n&&(this.buffer[t]|=128>>>this.length%8);this.length++}};var h=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],w=function(){var n=function(n,t){this._el=n;this._htOption=t};return n.prototype.draw=function(n){function e(n,t){var r=document.createElementNS("http://www.w3.org/2000/svg",n);for(var i in t)t.hasOwnProperty(i)&&r.setAttribute(i,t[i]);return r}var f=this._htOption,s=this._el,t=n.getModuleCount(),i,r,u,o;for(Math.floor(f.width/t),Math.floor(f.height/t),this.clear(),i=e("svg",{viewBox:"0 0 "+String(t)+" "+String(t),width:"100%",height:"100%",fill:f.colorLight}),i.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),s.appendChild(i),i.appendChild(e("rect",{fill:f.colorDark,width:"1",height:"1",id:"template"})),r=0;t>r;r++)for(u=0;t>u;u++)n.isDark(r,u)&&(o=e("use",{x:String(r),y:String(u)}),o.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),i.appendChild(o))},n.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},n}(),b="svg"===document.documentElement.tagName.toLowerCase(),k=b?w:v()?function(){function r(){this._elImage.src=this._elCanvas.toDataURL("image/png");this._elImage.style.display="block";this._elCanvas.style.display="none"}function u(n,t){var i=this;if(i._fFail=t,i._fSuccess=n,null===i._bSupportDataURI){var r=document.createElement("img"),u=function(){i._bSupportDataURI=!1;i._fFail&&_fFail.call(i)},f=function(){i._bSupportDataURI=!0;i._fSuccess&&i._fSuccess.call(i)};return r.onabort=u,r.onerror=u,r.onload=f,r.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}i._bSupportDataURI===!0&&i._fSuccess?i._fSuccess.call(i):i._bSupportDataURI===!1&&i._fFail&&i._fFail.call(i)}var t,i,n;return this._android&&this._android<=2.1&&(t=1/window.devicePixelRatio,i=CanvasRenderingContext2D.prototype.drawImage,CanvasRenderingContext2D.prototype.drawImage=function(n,r,u,f,e,o,s,h){if("nodeName"in n&&/img/i.test(n.nodeName))for(var c=arguments.length-1;c>=1;c--)arguments[c]=arguments[c]*t;else"undefined"==typeof h&&(arguments[1]*=t,arguments[2]*=t,arguments[3]*=t,arguments[4]*=t);i.apply(this,arguments)}),n=function(n,t){this._bIsPainted=!1;this._android=a();this._htOption=t;this._elCanvas=document.createElement("canvas");this._elCanvas.width=t.width;this._elCanvas.height=t.height;n.appendChild(this._elCanvas);this._el=n;this._oContext=this._elCanvas.getContext("2d");this._bIsPainted=!1;this._elImage=document.createElement("img");this._elImage.style.display="none";this._el.appendChild(this._elImage);this._bSupportDataURI=null},n.prototype.draw=function(n){var v=this._elImage,t=this._oContext,i=this._htOption,f=n.getModuleCount(),e=i.width/f,o=i.height/f,c=Math.round(e),l=Math.round(o),r,u;for(v.style.display="none",this.clear(),r=0;f>r;r++)for(u=0;f>u;u++){var a=n.isDark(r,u),s=u*e,h=r*o;t.strokeStyle=a?i.colorDark:i.colorLight;t.lineWidth=1;t.fillStyle=a?i.colorDark:i.colorLight;t.fillRect(s,h,e,o);t.strokeRect(Math.floor(s)+.5,Math.floor(h)+.5,c,l);t.strokeRect(Math.ceil(s)-.5,Math.ceil(h)-.5,c,l)}this._bIsPainted=!0},n.prototype.makeImage=function(){this._bIsPainted&&u.call(this,r)},n.prototype.isPainted=function(){return this._bIsPainted},n.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height);this._bIsPainted=!1},n.prototype.round=function(n){return n?Math.floor(1e3*n)/1e3:n},n}():function(){var n=function(n,t){this._el=n;this._htOption=t};return n.prototype.draw=function(n){for(var u,t=this._htOption,o=this._el,r=n.getModuleCount(),c=Math.floor(t.width/r),l=Math.floor(t.height/r),i=['<table style="border:0;border-collapse:collapse;">'],f=0;r>f;f++){for(i.push("<tr>"),u=0;r>u;u++)i.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+c+"px;height:"+l+"px;background-color:"+(n.isDark(f,u)?t.colorDark:t.colorLight)+';"><\/td>');i.push("<\/tr>")}i.push("<\/table>");o.innerHTML=i.join("");var e=o.childNodes[0],s=(t.width-e.offsetWidth)/2,h=(t.height-e.offsetHeight)/2;s>0&&h>0&&(e.style.margin=h+"px "+s+"px")},n.prototype.clear=function(){this._el.innerHTML=""},n}();QRCode=function(n,t){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:e.H},"string"==typeof t&&(t={text:t}),t)for(var i in t)this._htOption[i]=t[i];"string"==typeof n&&(n=document.getElementById(n));this._android=a();this._el=n;this._oQRCode=null;this._oDrawing=new k(this._el,this._htOption);this._htOption.text&&this.makeCode(this._htOption.text)};QRCode.prototype.makeCode=function(n){this._oQRCode=new u(y(n,this._htOption.correctLevel),this._htOption.correctLevel);this._oQRCode.addData(n);this._oQRCode.make();this._el.title=n;this._oDrawing.draw(this._oQRCode);this.makeImage()};QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()};QRCode.prototype.clear=function(){this._oDrawing.clear()};QRCode.CorrectLevel=e}();(function(n){var t=function(){var n=Array.prototype.slice.apply(arguments),i=null,t=[],r;Object.prototype.toString.call(n[0])==="[object Array]"&&(n=n[0]);switch(n.length){case 0:i=new Date;break;case 1:i=new Date(n[0]);break;case 2:i=new Date(n[0],n[1]);break;default:for(r=0;r<7;r++)t[r]=n[r]||0;i=new Date(Date.UTC(t[0],t[1],t[2],t[3],t[4],t[5],t[6]))}this._day=0;this.year=0;this.month=0;this.date=0;this.hours=0;this.minutes=0;this.seconds=0;this.milliseconds=0;this.setFromTimeProxy(i.getTime())};t.prototype={getDate:function(){return this.getUTCDateProxy().getUTCDate()},getDay:function(){return this.getUTCDateProxy().getUTCDay()},getFullYear:function(){return this.getUTCDateProxy().getUTCFullYear()},getMonth:function(){return this.getUTCDateProxy().getUTCMonth()},getHours:function(){return this.getUTCDateProxy().getUTCHours()},getMilliseconds:function(){return this.getUTCDateProxy().getUTCMilliseconds()},getMinutes:function(){return this.getUTCDateProxy().getUTCMinutes()},getSeconds:function(){return this.getUTCDateProxy().getUTCSeconds()},getUTCDate:function(){return this.getUTCDateProxy().getUTCDate()},getUTCDay:function(){return this.getUTCDateProxy().getUTCDay()},getUTCFullYear:function(){return this.getUTCDateProxy().getUTCFullYear()},getUTCHours:function(){return this.getUTCDateProxy().getUTCHours()},getUTCMilliseconds:function(){return this.getUTCDateProxy().getUTCMilliseconds()},getUTCMinutes:function(){return this.getUTCDateProxy().getUTCMinutes()},getUTCMonth:function(){return this.getUTCDateProxy().getUTCMonth()},getUTCSeconds:function(){return this.getUTCDateProxy().getUTCSeconds()},getTime:function(){return this._dateProxy.getTime()},getUTCDateProxy:function(){return this._dateProxy},setDate:function(n){return this.setUTCDate(n),this.getTime()},setFullYear:function(n,t,i){return this.setUTCFullYear(i),this.getTime()},setMonth:function(n){return this.setUTCMonth(n),this.getTime()},setYear:function(n){return this.setUTCYear(n),this.getTime()},setHours:function(n){return this.setUTCHours(n),this.getTime()},setMinutes:function(n){return this.setUTCMinutes(n),this.getTime()},setSeconds:function(n){return this.setUTCSeconds(n),this.getTime()},setMilliseconds:function(n){return this.setUTCMilliseconds(n),this.getTime()},setTime:function(n){if(isNaN(n))throw new Error("Units must be a number.");return this.setFromTimeProxy(n,this.timezone),this.getTime()},setUTCFullYear:function(n){return this.setUTCAttribute("year",n),this.getTime()},setUTCMonth:function(n){return this.setUTCAttribute("month",n),this.getTime()},setUTCDate:function(n){return this.setUTCAttribute("date",n),this.getTime()},setUTCHours:function(n){return this.setUTCAttribute("hours",n),this.getTime()},setUTCMinutes:function(n){return this.setUTCAttribute("minutes",n),this.getTime()},setUTCSeconds:function(n){return this.setUTCAttribute("seconds",n),this.getTime()},setUTCMilliseconds:function(n){return this.setUTCAttribute("milliseconds",n),this.getTime()},setFromDateObjProxy:function(n){this.year=n.getUTCFullYear();this.month=n.getUTCMonth();this.date=n.getUTCDate();this.hours=n.getUTCHours();this.minutes=n.getUTCMinutes();this.seconds=n.getUTCSeconds();this.milliseconds=n.getUTCMilliseconds();this._day=n.getUTCDay();this._dateProxy=n},setFromTimeProxy:function(n){var t=new Date(n);this.setFromDateObjProxy(t)},setAttribute:function(n,t){if(isNaN(t))throw new Error("Units must be a number.");var i=this._dateProxy,r=n==="year"?"FullYear":n.substr(0,1).toUpperCase()+n.substr(1);i["setUTC"+r](t);this.setFromDateObjProxy(i)},setUTCAttribute:function(n,t){if(isNaN(t))throw new Error("Units must be a number.");var r=n==="year"?"FullYear":n.substr(0,1).toUpperCase()+n.substr(1),i=this.getUTCDateProxy();i["setUTC"+r](t);this.setFromTimeProxy(i.getTime(),this.timezone)},valueOf:function(){return this.getTime()},toString:function(n){n||(n="yyyy-MM-dd HH:mm:ss");var u=n,t=this,i=function(n,t){if(typeof n!="number")throw"not a number: "+n;var u=n>1e3,i=n.toString(),r=i.length;if(u&&r>t)return i.substr(r-t,r);for(i=[i];r<t;)i.unshift("0"),r++;return i.join("")},r=t.getUTCHours();return u.replace(/a+/g,function(){return"k"}).replace(/y+/g,function(n){return i(t.getUTCFullYear(),n.length)}).replace(/d+/g,function(n){return i(t.getUTCDate(),n.length)}).replace(/m+/g,function(n){return i(t.getUTCMinutes(),n.length)}).replace(/s+/g,function(n){return i(t.getUTCSeconds(),n.length)}).replace(/S+/g,function(n){return i(t.getUTCMilliseconds(),n.length)}).replace(/h+/g,function(n){return i(r%12==0?12:r%12,n.length)}).replace(/M+/g,function(n){var r=t.getMonth(),u=n.length;return i(r+1,u)}).replace(/H+/g,function(n){return i(r,n.length)}).replace(/E+/g,function(n){return DAYS[t.getUTCDay()].substring(0,n.length)})}};n.UtcDate=t})(this);/*!
 * rrule.js - Library for working with recurrence rules for calendar dates.
 * https://github.com/jakubroztocil/rrule
 *
 * Copyright 2010, Jakub Roztocil and Lars Schoning
 * Licenced under the BSD licence.
 * https://github.com/jakubroztocil/rrule/blob/master/LICENCE
 *
 * Based on:
 * python-dateutil - Extensions to the standard Python datetime module.
 * Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
 * Copyright (c) 2012 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
 * https://github.com/jakubroztocil/rrule/blob/master/LICENCE
 *
 */
(function(n){var b=typeof module!="undefined"&&module.exports,v,c,k,tt,y,i,t,l,p,d;if(b)try{v=require("timezone-js")}catch(lt){}else n.timezoneJS?v=n.timezoneJS:v||typeof require=="undefined"||(v=require("timezone-js"));if(c=v?v.Date:Date,k=!1,n.UtcDate&&(c=UtcDate,k=!0),b)try{tt=require("./utcdate");c=tt.UtcDate;k=!0}catch(lt){}y=function(){if(!y._nlp)if(b)y._nlp=require("./nlp");else if(!(y._nlp=n._RRuleNLP))throw new Error("You need to include rrule/nlp.js for fromText/toText to work.");return y._nlp};i={MONTH_DAYS:[31,28,31,30,31,30,31,31,30,31,30,31],ONE_DAY:864e5,MAXYEAR:9999,ORDINAL_BASE:new Date(1970,0,1),PY_WEEKDAYS:[6,0,1,2,3,4,5],getYearDay:function(n){var t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return Math.ceil((t-new Date(n.getFullYear(),0,1))/i.ONE_DAY)+1},isLeapYear:function(n){return n instanceof Date&&(n=n.getFullYear()),n%4==0&&n%100!=0||n%400==0},tzOffset:function(n){return n.getTimezoneOffset()*6e4},daysBetween:function(n,t){var r=n.getTime()-i.tzOffset(n),u=t.getTime()-i.tzOffset(t),f=Math.abs(r-u);return Math.round(f/i.ONE_DAY)},toOrdinal:function(n){return i.daysBetween(n,i.ORDINAL_BASE)},fromOrdinal:function(n){var t=n*i.ONE_DAY;return new Date(i.ORDINAL_BASE.getTime()-i.tzOffset(i.ORDINAL_BASE)+t+i.tzOffset(new Date(t)))},monthRange:function(n,t){var r=new Date(n,t,1);return[i.getWeekday(r),i.getMonthDays(r)]},getMonthDays:function(n){var t=n.getMonth();return t==1&&i.isLeapYear(n)?29:i.MONTH_DAYS[t]},getWeekday:function(n){return i.PY_WEEKDAYS[n.getDay()]},combine:function(n,t){return t=t||n,v&&t.getTimezone()?new c(n.getFullYear(),n.getMonth(),n.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getTimezone()):new c(n.getFullYear(),n.getMonth(),n.getDate(),t.getHours(),t.getMinutes(),t.getSeconds())},clone:function(n){var t=new c(n.getTime());return t.setMilliseconds(0),v&&t.setTimezone(n.getTimezone()),t},cloneDates:function(n){for(var r=[],t=0;t<n.length;t++)r.push(i.clone(n[t]));return r},sort:function(n){n.sort(function(n,t){return n.getTime()-t.getTime()})},timeToUntilString:function(n){for(var t=new Date(n),i,r=[t.getUTCFullYear(),t.getUTCMonth()+1,t.getUTCDate(),"T",t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds(),"Z"],u=0;u<r.length;u++)i=r[u],!/[TZ]/.test(i)&&i<10&&(r[u]="0"+String(i));return r.join("")},untilStringToDate:function(n,t){var i=/^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z)?$/.exec(n);if(!i)throw new Error("Invalid UNTIL value: "+n);return v&&t?new c(Date.UTC(i[1],i[2]-1,i[3],i[5]||0,i[6]||0,i[7]||0),t):new c(Date.UTC(i[1],i[2]-1,i[3],i[5]||0,i[6]||0,i[7]||0))}};i.Time=function(n,t,i,r){this.hour=n;this.minute=t;this.second=i;this.timezone=r};i.Time.prototype={getHours:function(){return this.hour},getMinutes:function(){return this.minute},getSeconds:function(){return this.second},getTimezone:function(){return this.timezone},getTime:function(){return(this.hour*3600+this.minute*60+this.second)*1e3}};var a=function(n,t){var r,i;for(arguments.length===1&&(t=n,n=0),r=[],i=n;i<t;i++)r.push(i);return r},u=function(n,t){var i=0,r=[];if(n instanceof Array)for(;i<t;i++)r[i]=[].concat(n);else for(;i<t;i++)r[i]=n;return r},h=function(n,t){var i=n%t;return i*t<0?i+t:i},w=function(n,t){return{div:Math.floor(n/t),mod:h(n,t)}},f=function(n){return n instanceof Array&&n.length==0?!1:Boolean(n)},e=function(n,t){return n.indexOf(t)!=-1},rt=[].concat(u(1,31),u(2,28),u(3,31),u(4,30),u(5,31),u(6,30),u(7,31),u(8,31),u(9,30),u(10,31),u(11,30),u(12,31),u(1,7)),ut=[].concat(u(1,31),u(2,29),u(3,31),u(4,30),u(5,31),u(6,30),u(7,31),u(8,31),u(9,30),u(10,31),u(11,30),u(12,31),u(1,7)),g=a(1,29),nt=a(1,30),o=a(1,31),r=a(1,32),ft=[].concat(r,nt,r,o,r,o,r,r,o,r,o,r,r.slice(0,7)),et=[].concat(r,g,r,o,r,o,r,r,o,r,o,r,r.slice(0,7));g=a(-28,0);nt=a(-29,0);o=a(-30,0);r=a(-31,0);var ot=[].concat(r,nt,r,o,r,o,r,r,o,r,o,r,r.slice(0,7)),st=[].concat(r,g,r,o,r,o,r,r,o,r,o,r,r.slice(0,7)),ht=[0,31,60,91,121,152,182,213,244,274,305,335,366],ct=[0,31,59,90,120,151,181,212,243,273,304,334,365],it=function(){for(var n=[],t=0;t<55;t++)n=n.concat(a(7));return n}(),s=function(n,t){if(t===0)throw new Error("Can't create weekday with n == 0");this.weekday=n;this.n=t};s.prototype={nth:function(n){return this.n==n?this:new s(this.weekday,n)},equals:function(n){return this.weekday==n.weekday&&this.n==n.n},toString:function(){var n=["MO","TU","WE","TH","FR","SA","SU"][this.weekday];return this.n&&(n=(this.n>0?"+":"")+String(this.n)+n),n},getJsWeekday:function(){return this.weekday==6?0:this.weekday+1}};t=function(n,r){var u,o,b,d,h,a,v,l,tt,y,it,p,rt;this._string=null;n=n||{};this._cache=r?null:{all:!1,before:[],after:[],between:[]};this.origOptions={};var w=[],g=Object.keys(n),nt=Object.keys(t.DEFAULT_OPTIONS);if(g.forEach(function(t){this.origOptions[t]=n[t];e(nt,t)||w.push(t)},this),w.length)throw new Error("Invalid options: "+w.join(", "));if(!t.FREQUENCIES[n.freq]&&n.byeaster===null)throw new Error("Invalid frequency: "+String(n.freq));if(nt.forEach(function(i){e(g,i)||(n[i]=t.DEFAULT_OPTIONS[i])}),u=this.options=n,u.byeaster!==null&&(u.freq=t.YEARLY),u.dtstart?k&&(u.dtstart=new c(u.dtstart.getTime())):(u.dtstart=new c,u.dtstart.setMilliseconds(0)),this.timezone=u.dtstart.timezone,u.wkst===null?u.wkst=t.MO.weekday:typeof u.wkst=="number"||(u.wkst=u.wkst.weekday),u.bysetpos!==null)for(typeof u.bysetpos=="number"&&(u.bysetpos=[u.bysetpos]),o=0;o<u.bysetpos.length;o++)if(h=u.bysetpos[o],h==0||!(-366<=h&&h<=366))throw new Error("bysetpos must be between 1 and 366, or between -366 and -1");if(!(f(u.byweekno)||f(u.byyearday)||f(u.bymonthday)||u.byweekday!==null||u.byeaster!==null))switch(u.freq){case t.YEARLY:u.bymonth||(u.bymonth=u.dtstart.getMonth()+1);u.bymonthday=u.dtstart.getDate();break;case t.MONTHLY:u.bymonthday=u.dtstart.getDate();break;case t.WEEKLY:u.byweekday=i.getWeekday(u.dtstart)}if(u.bymonth===null||u.bymonth instanceof Array||(u.bymonth=[u.bymonth]),u.byyearday===null||u.byyearday instanceof Array||(u.byyearday=[u.byyearday]),u.bymonthday===null)u.bymonthday=[],u.bynmonthday=[];else if(u.bymonthday instanceof Array){for(b=[],d=[],o=0;o<u.bymonthday.length;o++)h=u.bymonthday[o],h>0?b.push(h):h<0&&d.push(h);u.bymonthday=b;u.bynmonthday=d}else u.bymonthday<0?(u.bynmonthday=[u.bymonthday],u.bymonthday=[]):(u.bynmonthday=[],u.bymonthday=[u.bymonthday]);if(u.byweekno===null||u.byweekno instanceof Array||(u.byweekno=[u.byweekno]),u.byweekday===null)u.bynweekday=null;else if(typeof u.byweekday=="number")u.byweekday=[u.byweekday],u.bynweekday=null;else if(u.byweekday instanceof s)!u.byweekday.n||u.freq>t.MONTHLY?(u.byweekday=[u.byweekday.weekday],u.bynweekday=null):(u.bynweekday=[[u.byweekday.weekday,u.byweekday.n]],u.byweekday=null);else{for(a=[],v=[],o=0;o<u.byweekday.length;o++)l=u.byweekday[o],typeof l=="number"?a.push(l):!l.n||u.freq>t.MONTHLY?a.push(l.weekday):v.push([l.weekday,l.n]);u.byweekday=f(a)?a:null;u.bynweekday=f(v)?v:null}if(u.byhour===null?u.byhour=u.freq<t.HOURLY?[u.dtstart.getHours()]:null:typeof u.byhour=="number"&&(u.byhour=[u.byhour]),u.byminute===null?u.byminute=u.freq<t.MINUTELY?[u.dtstart.getMinutes()]:null:typeof u.byminute=="number"&&(u.byminute=[u.byminute]),u.bysecond===null?u.bysecond=u.freq<t.SECONDLY?[u.dtstart.getSeconds()]:null:typeof u.bysecond=="number"&&(u.bysecond=[u.bysecond]),u.freq>=t.HOURLY)this.timeset=null;else{for(this.timeset=[],o=0;o<u.byhour.length;o++)for(tt=u.byhour[o],y=0;y<u.byminute.length;y++)for(it=u.byminute[y],p=0;p<u.bysecond.length;p++)rt=u.bysecond[p],this.timeset.push(new i.Time(tt,it,rt,this.timezone));i.sort(this.timeset)}};t.FREQUENCIES=["YEARLY","MONTHLY","WEEKLY","DAILY","HOURLY","MINUTELY","SECONDLY"];t.YEARLY=0;t.MONTHLY=1;t.WEEKLY=2;t.DAILY=3;t.HOURLY=4;t.MINUTELY=5;t.SECONDLY=6;t.MO=new s(0);t.TU=new s(1);t.WE=new s(2);t.TH=new s(3);t.FR=new s(4);t.SA=new s(5);t.SU=new s(6);t.DEFAULT_OPTIONS={freq:null,dtstart:null,interval:1,wkst:t.MO,count:null,until:null,bysetpos:null,bymonth:null,bymonthday:null,byyearday:null,byweekno:null,byweekday:null,byhour:null,byminute:null,bysecond:null,byeaster:null};t.parseText=function(n,t){return y().parseText(n,t)};t.fromText=function(n,t){return y().fromText(n,t)};t.optionsToString=function(n){var l,h,p,r,c,a=[],o,f,v,u,y;for(h=Object.keys(n),p=Object.keys(t.DEFAULT_OPTIONS),u=0;u<h.length;u++)if(e(p,h[u])&&(l=h[u].toUpperCase(),r=n[h[u]],c=[],r!==null&&(!(r instanceof Array)||r.length))){switch(l){case"FREQ":r=t.FREQUENCIES[n.freq];break;case"WKST":r=r.toString();break;case"BYWEEKDAY":for(l="BYDAY",r instanceof Array||(r=[r]),f=0;f<r.length;f++)o=r[f],o instanceof s||(o=o instanceof Array?new s(o[0],o[1]):new s(o)),c[f]=o.toString();r=c;break;case"DTSTART":r.timezone&&a.push(["TZID",r.timezone]);case"UNTIL":r=i.timeToUntilString(r);break;default:if(r instanceof Array){for(f=0;f<r.length;f++)c[f]=String(r[f]);r=c}else r=String(r)}a.push([l,r])}for(v=[],u=0;u<a.length;u++)y=a[u],v.push(y[0]+"="+y[1].toString());return v.join(";")};t.prototype={all:function(n){if(n)return this._iter(new d("all",{},n));var t=this._cacheGet("all");return t===!1&&(t=this._iter(new p("all",{})),this._cacheAdd("all",t)),t},between:function(n,t,i,r){var f={before:t,after:n,inc:i},u;return r?this._iter(new d("between",f,r)):(u=this._cacheGet("between",f),u===!1&&(u=this._iter(new p("between",f)),this._cacheAdd("between",u,f)),u)},before:function(n,t){var r={dt:n,inc:t},i=this._cacheGet("before",r);return i===!1&&(i=this._iter(new p("before",r)),this._cacheAdd("before",i,r)),i},after:function(n,t){var r={dt:n,inc:t},i=this._cacheGet("after",r);return i===!1&&(i=this._iter(new p("after",r)),this._cacheAdd("after",i,r)),i},count:function(){return this.all().length},toString:function(){return t.optionsToString(this.origOptions)},toText:function(n,t){return y().toText(this,n,t)},isFullyConvertibleToText:function(){return y().isFullyConvertible(this)},_cacheAdd:function(n,t,r){this._cache&&(t&&(t=t instanceof c?i.clone(t):i.cloneDates(t)),n=="all"?this._cache.all=t:(r._value=t,this._cache[n].push(r)))},_cacheGet:function(n,t){var r,e,f,o,u;if(!this._cache)return!1;if(r=!1,n=="all")r=this._cache.all;else n:for(u=0;u<this._cache[n].length;u++){e=this._cache[n][u];for(f in t)if(t.hasOwnProperty(f)&&String(t[f])!=String(e[f]))continue n;r=e._value;break}if(!r&&this._cache.all){for(o=new p(n,t),u=0;u<this._cache.all.length;u++)if(!o.accept(this._cache.all[u]))break;r=o.getValue();this._cacheAdd(n,r,t)}return r instanceof Array?i.cloneDates(r):r instanceof c?i.clone(r):r},clone:function(){return new t(this.origOptions)},_iter:function(n){var tt=this.options.dtstart,p=tt.getFullYear(),a=tt.getMonth()+1,it=tt.getDate(),u=tt.getHours(),v=tt.getMinutes(),rt=tt.getSeconds(),gt=i.getWeekday(tt),wi=i.getYearDay(tt),d=this.options.freq,b=this.options.interval,ni=this.options.wkst,ti=this.options.until,ci=this.options.bymonth,yi=this.options.byweekno,wt=this.options.byyearday,li=this.options.byweekday,pi=this.options.byeaster,ai=this.options.bymonthday,vi=this.options.bynmonthday,fi=this.options.bysetpos,ot=this.options.byhour,lt=this.options.byminute,ii=this.options.bysecond,r=new l(this),nt,g,ut,kt,ei,pt,yt,oi,hi,si,ft,dt;r.rebuild(p,a);nt={};nt[t.YEARLY]=r.ydayset;nt[t.MONTHLY]=r.mdayset;nt[t.WEEKLY]=r.wdayset;nt[t.DAILY]=r.ddayset;nt[t.HOURLY]=r.ddayset;nt[t.MINUTELY]=r.ddayset;nt[t.SECONDLY]=r.ddayset;nt=nt[d];d<t.HOURLY?g=this.timeset:(ut={},ut[t.HOURLY]=r.htimeset,ut[t.MINUTELY]=r.mtimeset,ut[t.SECONDLY]=r.stimeset,ut=ut[d],g=d>=t.HOURLY&&f(ot)&&!e(ot,u)||d>=t.MINUTELY&&f(lt)&&!e(lt,v)||d>=t.SECONDLY&&f(ii)&&!e(ii,v)?[]:ut.call(r,u,v,rt));for(var at,et=0,vt=this.options.count,o,y,st,c,s,k,ht,yt,bt,ri,ui,ct;;){for(ht=nt.call(r,p,a,it),bt=ht[0],ri=ht[1],ui=ht[2],at=!1,y=ri;y<ui;y++)o=bt[y],(f(ci)&&!e(ci,r.mmask[o])||f(yi)&&!r.wnomask[o]||f(li)&&!e(li,r.wdaymask[o])||f(r.nwdaymask)&&!r.nwdaymask[o]||pi!==null&&!e(r.eastermask,o)||(f(ai)||f(vi))&&!e(ai,r.mdaymask[o])&&!e(vi,r.nmdaymask[o])||f(wt)&&(o<r.yearlen&&!e(wt,o+1)&&!e(wt,-r.yearlen+o)||o>=r.yearlen&&!e(wt,o+1-r.yearlen)&&!e(wt,-r.nextyearlen+o-r.yearlen)))&&(bt[o]=null,at=!0);if(f(fi)&&f(g)){for(pt=[],o,y=0;y<fi.length;y++){yt=fi[y];yt<0?(kt=Math.floor(yt/g.length),ei=h(yt,g.length)):(kt=Math.floor((yt-1)/g.length),ei=h(yt-1,g.length));try{for(ht=[],st=ri;st<ui;st++)(oi=bt[st],oi!==null)&&ht.push(oi);o=kt<0?ht.slice(kt)[0]:ht[kt];var si=g[ei],hi=i.fromOrdinal(r.yearordinal+o),ft=i.combine(hi,si);e(pt,ft)||pt.push(ft)}catch(bi){}}for(i.sort(pt),y=0;y<pt.length;y++){if(ft=pt[y],ti&&ft>ti)return this._len=et,n.getValue();if(ft>=tt){if(++et,!n.accept(ft))return n.getValue();if(vt&&(--vt,!vt))return this._len=et,n.getValue()}}}else for(y=ri;y<ui;y++)if(o=bt[y],o!==null)for(hi=i.fromOrdinal(r.yearordinal+o),st=0;st<g.length;st++){if(si=g[st],ft=i.combine(hi,si),ti&&ft>ti)return this._len=et,n.getValue();if(ft>=tt){if(++et,!n.accept(ft))return n.getValue();if(vt&&(--vt,!vt))return this._len=et,n.getValue()}}if(ct=!1,d==t.YEARLY){if(p+=b,p>i.MAXYEAR)return this._len=et,n.getValue();r.rebuild(p,a)}else if(d==t.MONTHLY){if(a+=b,a>12&&(s=Math.floor(a/12),k=h(a,12),a=k,p+=s,a==0&&(a=12,--p),p>i.MAXYEAR))return this._len=et,n.getValue();r.rebuild(p,a)}else if(d==t.WEEKLY)it+=ni>gt?-(gt+1+(6-ni))+b*7:-(gt-ni)+b*7,gt=ni,ct=!0;else if(d==t.DAILY)it+=b,ct=!0;else if(d==t.HOURLY){for(at&&(u+=Math.floor((23-u)/b)*b);;)if(u+=b,c=w(u,24),s=c.div,k=c.mod,s&&(u=k,it+=s,ct=!0),!f(ot)||e(ot,u))break;g=ut.call(r,u,v,rt)}else if(d==t.MINUTELY){for(at&&(v+=Math.floor((1439-(u*60+v))/b)*b);;)if(v+=b,c=w(v,60),s=c.div,k=c.mod,s&&(v=k,u+=s,c=w(u,24),s=c.div,k=c.mod,s&&(u=k,it+=s,ct=!0,at=!1)),(!f(ot)||e(ot,u))&&(!f(lt)||e(lt,v)))break;g=ut.call(r,u,v,rt)}else if(d==t.SECONDLY){for(at&&(rt+=Math.floor((86399-(u*3600+v*60+rt))/b)*b);;)if(rt+=b,c=w(rt,60),s=c.div,k=c.mod,s&&(rt=k,v+=s,c=w(v,60),s=c.div,k=c.mod,s&&(v=k,u+=s,c=w(u,24),s=c.div,k=c.mod,s&&(u=k,it+=s,ct=!0))),(!f(ot)||e(ot,u))&&(!f(lt)||e(lt,v))&&(!f(ii)||e(ii,rt)))break;g=ut.call(r,u,v,rt)}if(ct&&it>28&&(dt=i.monthRange(p,a-1)[1],it>dt)){while(it>dt){if(it-=dt,++a,a==13&&(a=1,++p,p>i.MAXYEAR))return this._len=et,n.getValue();dt=i.monthRange(p,a-1)[1]}r.rebuild(p,a)}}}};t.parseString=function(n){var c,f,o,r,l,a,p,v,u,w,h,e,y;if(n=n.replace(/^\s+|\s+$/,""),!n.length)return null;for(v=n.split(";"),u={},c=0;c<v.length;c++){l=v[c].split("=");o=l[0];r=l[1];switch(o){case"FREQ":u.freq=t[r];break;case"WKST":u.wkst=t[r];break;case"COUNT":case"INTERVAL":case"BYSETPOS":case"BYMONTH":case"BYMONTHDAY":case"BYYEARDAY":case"BYWEEKNO":case"BYHOUR":case"BYMINUTE":case"BYSECOND":if(r.indexOf(",")!=-1)for(r=r.split(","),f=0;f<r.length;f++)/^[+-]?\d+$/.test(r[f])&&(r[f]=Number(r[f]));else/^[+-]?\d+$/.test(r)&&(r=Number(r));o=o.toLowerCase();u[o]=r;break;case"BYDAY":for(y=r.split(","),u.byweekday=[],f=0;f<y.length;f++)e=y[f],e.length==2?(h=t[e],u.byweekday.push(h)):(e=e.match(/^([+-]?\d)([A-Z]{2})$/),w=Number(e[1]),h=e[2],h=t[h].weekday,u.byweekday.push(new s(h,w)));break;case"DTSTART":a=r;break;case"TZID":p=r;break;case"UNTIL":u.until=i.untilStringToDate(r);break;case"BYEASTER":u.byeaster=Number(r);break;default:throw new Error("Unknown RRULE property '"+o+"'");}}return a&&(u.dtstart=i.untilStringToDate(a,p)),u};t.fromString=function(n){return new t(t.parseString(n))};l=function(n){this.rrule=n;this.lastyear=null;this.lastmonth=null;this.yearlen=null;this.nextyearlen=null;this.yearordinal=null;this.yearweekday=null;this.mmask=null;this.mrange=null;this.mdaymask=null;this.nmdaymask=null;this.wdaymask=null;this.wnomask=null;this.nwdaymask=null;this.eastermask=null};l.prototype.easter=function(n,t){t=t||0;var f=n%19,i=Math.floor(n/100),e=n%100,s=Math.floor(i/4),h=i%4,c=Math.floor((i+8)/25),l=Math.floor((i-c+1)/3),r=Math.floor(19*f+i-s-l+15)%30,a=Math.floor(e/4),v=e%4,u=Math.floor(32+2*h+2*a-r-v)%7,o=Math.floor((f+11*r+22*u)/451),y=Math.floor((r+u-7*o+114)/31),p=(r+u-7*o+114)%31+1,w=Date.UTC(n,y-1,p+t),b=Date.UTC(n,0,1);return[Math.ceil((w-b)/864e5)]};l.prototype.rebuild=function(n,r){var s=this.rrule,d,l,w,b,k,o,y,c,v,p,a;if(n!=this.lastyear)if(this.yearlen=i.isLeapYear(n)?366:365,this.nextyearlen=i.isLeapYear(n+1)?366:365,d=new Date(n,0,1),this.yearordinal=i.toOrdinal(d),this.yearweekday=i.getWeekday(d),p=i.getWeekday(new Date(n,0,1)),this.yearlen==365?(this.mmask=[].concat(rt),this.mdaymask=[].concat(et),this.nmdaymask=[].concat(st),this.wdaymask=it.slice(p),this.mrange=[].concat(ct)):(this.mmask=[].concat(ut),this.mdaymask=[].concat(ft),this.nmdaymask=[].concat(ot),this.wdaymask=it.slice(p),this.mrange=[].concat(ht)),f(s.options.byweekno)){this.wnomask=u(0,this.yearlen+7);l=w=h(7-this.yearweekday+s.options.wkst,7);l>=4?(l=0,b=this.yearlen+h(this.yearweekday-s.options.wkst,7)):b=this.yearlen-l;var yt=Math.floor(b/7),pt=h(b,7),g=Math.floor(yt+pt/4);for(c=0;c<s.options.byweekno.length;c++)if(a=s.options.byweekno[c],a<0&&(a+=g+1),0<a&&a<=g)for(a>1?(o=l+(a-1)*7,l!=w&&(o-=7-w)):o=l,v=0;v<7;v++)if(this.wnomask[o]=1,o++,this.wdaymask[o]==s.options.wkst)break;if(e(s.options.byweekno,1)&&(o=l+g*7,l!=w&&(o-=7-w),o<this.yearlen))for(c=0;c<7;c++)if(this.wnomask[o]=1,o+=1,this.wdaymask[o]==s.options.wkst)break;if(l){if(e(s.options.byweekno,-1))k=-1;else{var tt=i.getWeekday(new Date(n-1,0,1)),lt=h(7-tt+s.options.wkst,7),wt=i.isLeapYear(n-1)?366:365;lt>=4?(lt=0,k=Math.floor(52+h(wt+h(tt-s.options.wkst,7),7)/4)):k=Math.floor(52+h(this.yearlen-l,7)/4)}if(e(s.options.byweekno,k))for(o=0;o<l;o++)this.wnomask[o]=1}}else this.wnomask=null;if(f(s.options.bynweekday)&&(r!=this.lastmonth||n!=this.lastyear)){if(y=[],s.options.freq==t.YEARLY)if(f(s.options.bymonth))for(c=0;c<s.options.bymonth.length;c++)r=s.options.bymonth[c],y.push(this.mrange.slice(r-1,r+1));else y=[[0,this.yearlen]];else s.options.freq==t.MONTHLY&&(y=[this.mrange.slice(r-1,r+1)]);if(f(y))for(this.nwdaymask=u(0,this.yearlen),c=0;c<y.length;c++){var at=y[c],vt=at[0],nt=at[1];for(nt-=1,v=0;v<s.options.bynweekday.length;v++)p=s.options.bynweekday[v][0],a=s.options.bynweekday[v][1],a<0?(o=nt+(a+1)*7,o-=h(this.wdaymask[o]-p,7)):(o=vt+(a-1)*7,o+=h(7-this.wdaymask[o]+p,7)),vt<=o&&o<=nt&&(this.nwdaymask[o]=1)}this.lastyear=n;this.lastmonth=r}s.options.byeaster!==null&&(this.eastermask=this.easter(n,s.options.byeaster))};l.prototype.ydayset=function(){return[a(this.yearlen),0,this.yearlen]};l.prototype.mdayset=function(n,t){for(var r=u(null,this.yearlen),f=this.mrange[t-1],e=this.mrange[t],i=f;i<e;i++)r[i]=i;return[r,f,e]};l.prototype.wdayset=function(n,t,r){for(var e=u(null,this.yearlen+7),f=i.toOrdinal(new Date(n,t-1,r))-this.yearordinal,s=f,o=0;o<7;o++)if(e[f]=f,++f,this.wdaymask[f]==this.rrule.options.wkst)break;return[e,s,f]};l.prototype.ddayset=function(n,t,r){var e=u(null,this.yearlen),f=i.toOrdinal(new Date(n,t-1,r))-this.yearordinal;return e[f]=f,[e,f,f+1]};l.prototype.htimeset=function(n,t,r){for(var f,e=[],u=this.rrule,o=0;o<u.options.byminute.length;o++)for(t=u.options.byminute[o],f=0;f<u.options.bysecond.length;f++)r=u.options.bysecond[f],e.push(new i.Time(n,t,r,u.timezone));return i.sort(e),e};l.prototype.mtimeset=function(n,t,r){for(var u=[],f=this.rrule,e=0;e<f.options.bysecond.length;e++)r=f.options.bysecond[e],u.push(new i.Time(n,t,r,f.timezone));return i.sort(u),u};l.prototype.stimeset=function(n,t,r){return[new i.Time(n,t,r,this.rrule.timezone)]};p=function(n,t){this.init(n,t)};p.prototype={init:function(n,t){this.method=n;this.args=t;this._result=[];this.minDate=null;this.maxDate=null;n=="between"?(this.maxDate=t.inc?t.before:new Date(t.before.getTime()-1),this.minDate=t.inc?t.after:new Date(t.after.getTime()+1)):n=="before"?this.maxDate=t.inc?t.dt:new Date(t.dt.getTime()-1):n=="after"&&(this.minDate=t.inc?t.dt:new Date(t.dt.getTime()+1))},accept:function(n){var t=this.minDate&&n<this.minDate,i=this.maxDate&&n>this.maxDate;if(this.method=="between"){if(t)return!0;if(i)return!1}else if(this.method=="before"){if(i)return!1}else if(this.method=="after")return t?!0:(this.add(n),!1);return this.add(n)},add:function(n){return this._result.push(n),!0},getValue:function(){switch(this.method){case"all":case"between":return this._result;case"before":case"after":return this._result.length?this._result[this._result.length-1]:null}}};d=function(n,t,i){if(!e(["all","between"],n))throw new Error('Invalid method "'+n+'". Only all and between works with iterator.');this.add=function(n){return i(n,this._result.length)?(this._result.push(n),!0):!1};this.init(n,t)};d.prototype=p.prototype;b&&(module.exports={RRule:t});typeof ender=="undefined"&&(n.RRule=t);typeof define=="function"&&define.amd&&define("rrule",[],function(){return t})})(this);/**
 * eContent.TimeIntervalHelper_rrule - utility for working with eT4 META API TimeIntervals, based on rrule.js + moment.js
 * needs rrule.js using UtcDate, moment.js and moment-timezone.js for accurate operation
 */
(function (root) {

	root.eContent = root.eContent || {};

	root.eContent.TimeIntervalHelper_rrule = function(intervals, exceptions) {
		if (typeof moment == 'undefined')
			throw new Error("eContent.TimeIntervalHelper_rrule needs moment.js (2.8.0+) and moment-timezone.js (0.2.1+)! (get it at http://momentjs.com/)");
		if (typeof RRule == 'undefined')
			throw new Error("eContent.TimeIntervalHelper_rrule needs rrule.js (based on https://github.com/jakubroztocil/rrule) with UtcDate support");
	
		var self = this;
		
		var fixProtobufDate = function(d) {
			if (d && d.timestamp)
            {
                var offsetMinutes = d.offsetMinutes || 0;
				return moment.unix(d.timestamp).zone(-offsetMinutes).format() //- because js handles offset the other way round
            }
			else return d;
		}
		
		this._intervals = intervals.map(function(iv) {
			iv.start = fixProtobufDate(iv.start);
			iv.end = fixProtobufDate(iv.end);
			iv.repeatUntil = fixProtobufDate(iv.repeatUntil);
			
			iv.mstart = self._parseDate(iv.start,iv.tz);
			iv.mend = self._parseDate(iv.end,iv.tz);
			return iv;
		});

		this._exdates = null; // unrolled exceptions
		if (exceptions && intervals.length > 0) {
			this._exdates = exceptions.map((ex) => { ex.start = fixProtobufDate(ex.start); ex.repeatDailyUntil = fixProtobufDate(ex.repeatDailyUntil); return ex; })
				.map((ex) => this._unrollException(ex))
				.flat();
			// console.log("ed", this._exdates);

			this._exdatesByPrefix = {}; // a map by date(in timezone)
			this._exdatesUtcDateStringSet = {}; // map UtcDateString -> true (UtcDate.toString() format like "2021-04-04 12:00:00" (normalized UTC))
			for (const exdate of this._exdates) {
				const asUtcDateString = new UtcDate(moment.tz(new Date(exdate.start.substr(0, 19) + 'Z'), "Etc/UTC").toDate()).toString();
				this._exdatesUtcDateStringSet[asUtcDateString] = exdate;

				const exdateMoment = this._parseDate(exdate.start,this._intervals[0].tz);
				const curDayKey = moment(exdateMoment).startOf('day').format();
				if (!this._exdatesByPrefix[curDayKey]) this._exdatesByPrefix[curDayKey] = [];
				this._exdatesByPrefix[curDayKey].push(exdate);
			}
		}
	}

	root.eContent.TimeIntervalHelper_rrule.prototype = {
		betweenIntersects: function (from, until, f, emitExceptions) {
			var self = this;
			
			var from = moment(from);
			var until = moment(until);
			
			var iterStartFrom = moment(from);
			
			var possibleEventsBefore = this._intervals.filter(function(x) { return x.mstart < from && x.mend > from; });
			if (possibleEventsBefore.length>0) {
				iterStartFrom = possibleEventsBefore.map(function(x) { return x.mstart; }).reduce(function (p, v) { return ( p < v ? p : v );});
			}
			
			iterStartFrom = moment(iterStartFrom).add(-1, 'days');
			
			var ofilter = function(o) {
				return o.start < until && o.end > from;
			};
			
			this.between(iterStartFrom, until, function(o) {
				if (ofilter(o)) f(o);
			}, emitExceptions);
		},
		
		between: function(from, until, f, emitExceptions) { //or separate fException
		
			var ret = [];
			for (var i=0;i<this._intervals.length;i++) {
				var iv = this._intervals[i];
				
				var rr = this._iv2rr(iv);
				
				//console.log("rrule is", rr.toString());
				
				var starts = rr.between(moment(from).toDate(), moment(until).toDate());
				for (var j=0;j<starts.length;j++) {
					//var next = moment(starts[j].getTime());	next.tz(iv.tz); //stay at same instant, just set tz
					var next = moment.tz(starts[j].toString(), iv.tz); //re-interpret local to global
					
					var duration = (iv.mend.toDate()-iv.mstart.toDate())/1000.0;
					var nextEnd = moment(next);
					nextEnd.add(duration, 'seconds');
					nextEnd.hour(iv.mend.hour());
					nextEnd.minute(iv.mend.minute());
					nextEnd.second(iv.mend.second());
					if (nextEnd <= next) nextEnd.add(1, 'days'); //worst part of the hack: spanning after midnight
					
					var occ = {
						start: next,
						end: nextEnd,
						duration: (nextEnd.toDate()-next.toDate())/1000.0,
						allDay: (next.format('HHmmss') == '000000' && nextEnd.format('HHmmss') == '000000'),
						freq: iv.freq
					};
					if (iv.hideEnd) occ.hideEnd = iv.hideEnd;

					// newer rrule version would have rruleset with exdate/exrule, but we have an old and custom utcdate version
					if (this._exdatesUtcDateStringSet) {
						if (this._exdatesUtcDateStringSet[starts[j].toString()] !== undefined) {
							occ.isException = true;
							occ.exceptionTitle = this._exdatesUtcDateStringSet[starts[j].toString()].title;
							if (!emitExceptions) continue;
						}
					}
					ret.push(occ);
				}
			}
			
			ret.sort(function(a,b){return a.start>b.start?1:-1;});
			for (var i=0;i<ret.length;i++) {
				f(ret[i]);
			}
		},
		
		_iv2rr: function(iv) {
			var def = {
				//dtstart: this._parseDate(iv.start,iv.tz).toDate()
				dtstart: moment.tz(new Date(iv.start.substr(0,19)+'Z'), "Etc/UTC").toDate()
			};
			
			if (iv.repeatCount) def.count = iv.repeatCount;
			if (iv.repeatUntil) def.until = moment.tz(new Date(iv.repeatUntil.substr(0, 19) + 'Z'), "Etc/UTC").toDate();
			if (iv.interval) def.interval = iv.interval;
			
			if (!iv.freq && iv.repeatUntil && iv.weekdays) iv.freq = 'weekly';
			
			if (iv.dayOfMonth && (iv.weekday || iv.dayOrdinal))
				throw new Error('invalid timeinterval: dayOfMonth is not allowed in combination with weekday and/or dayOrdinal');
			
			switch((iv.freq || 'single').toLowerCase()) {
				case 'single':
					def.freq = RRule.DAILY;
					def.count = 1;
					break;
				case 'daily':
					def.freq = RRule.DAILY;
					break;
				case 'weekly':
					def.freq = RRule.WEEKLY;
					def.byweekday = iv.weekdays.map(this._mapWeekday);
					break;
				case 'monthly':
					def.freq = RRule.MONTHLY;
					if (iv.dayOfMonth) def.bymonthday = iv.dayOfMonth;
					if (iv.weekday && iv.dayOrdinal) def.byweekday = this._mapWeekday(iv.weekday).nth(iv.dayOrdinal);
					break;
				case 'yearly':
					def.freq = RRule.YEARLY;
					def.bymonth = iv.month;
					if (iv.dayOfMonth) def.bymonthday = iv.dayOfMonth;
					if (iv.weekday && iv.dayOrdinal) def.byweekday = this._mapWeekday(iv.weekday).nth(iv.dayOrdinal);
					break;
			}
			
			var rrule = new RRule(def);
			return rrule;
		
			/*var rrecur = Rrecur.create({
				dtstart: {
					zoneless: iv.start, //moment.tz(iv.start,iv.tz).toDate(),
					//zoneless: iv.start,
					locale: 'GMT+0000'
				},
				rrule: {}
			});
			return rrecur;	*/			
		},
		
		_mapWeekday: function(wd) {
			switch(wd) {
				case 0: return RRule.SU;
				case 1: return RRule.MO;
				case 2: return RRule.TU;
				case 3: return RRule.WE;
				case 4: return RRule.TH;
				case 5: return RRule.FR;
				case 6: return RRule.SA;
				
				case 'Sunday': return RRule.SU;
				case 'Monday': return RRule.MO;
				case 'Tuesday': return RRule.TU;
				case 'Wednesday': return RRule.WE;
				case 'Thursday': return RRule.TH;
				case 'Friday': return RRule.FR;
				case 'Saturday': return RRule.SA;					
			}
			throw new Error("huh?");
		},
		
		_parseDate: function(s,tzHint) { 
			if (s.zone) return moment(s); //already a moment..?
			//return moment.tz(s, tzHint || 'Europe/Berlin'); //verified, sort of slow
			return moment.tz(new Date(s), tzHint || 'Europe/Berlin'); //faster, still correct? tested in chrome,firefox,msie10 but only very minimally faster?
		},
		
		_toFakeUtc: function(date) {
			return new Date(Date.UTC.apply(Date, date.format('YYYY-MM-DD-hh-mm-ss').split('-')));
		},

		_unrollException: function (exception) {
			// returns utcdated values, not real ones, to be compatible with iv2rr
			// const tz = this._intervals[0].tz;
			const ret = [];

			if (exception.repeatDailyUntil) {
				const start = this._parseDate(exception.start);
				const until = this._parseDate(exception.repeatDailyUntil);
				let current = moment(start);

				while (current.isSameOrBefore(until)) {
					ret.push({ start: current.format(), title: exception.title });
					current = current.add(1, 'days');
				}
			} else {
				ret.push(exception);
			}

			return ret;

		},
		
		getCurrentStatus: function() {
			//TODO
			//ist jetzt offen? - gruen heute offen von 08:00 bis 18:00
			//macht in x stunden auf
			//ganztaegig offen / immer offen? flag
			
			//keine wiederholungsregeln, keine termine, keine oeffungszeiten, unbekannt
			if (this._intervals == null || this._intervals.length == 0)
				return { status: 'unknown', text: 'unbekannt' };
				
			var occs = [];
				
			this.betweenIntersects( moment().add(-1, 'days'), moment().add(1, 'days'), function(occ) {
				occs.push(occ);
			});
			
			for (var i=0;i<occs.length;i++) {
				if (this.occurrenceIsNow(occs[i])) {
					return { status: 'open', today: true, text: 'aktuell geöffnet', occurrence: occs[i] };
				}
			}
			
			for (var i=0;i<occs.length;i++) {
				if (this.occurrenceIsToday(occs[i])) {
					return { status: 'closed-outside-business-hours', today: true, text: 'geschlossen [hat heute offen]', occurrence: occs[i] };
				}
			}
			
			if (occs.length>0)
				return { status: 'closed', text: 'geschlossen [Termin in der nähe aber nicht heute]', occurrence: occs[0] };
				
			return { status: 'closed', text: 'geschlossen [keine Termine im Zeitraum]' };
		},
		
		occurrenceIsNow: function(occ) {
			var now = moment();
			return occ.start <= now && occ.end > now;
		},
		
		occurrenceIsToday: function(occ) {
			//todo timezone?
			var now = moment();
			return occ.start.format('YYYYMMDD') == now.format('YYYYMMDD');
		},
		
		/**
		 * create grouped opening hours information
		 */
		getOpeningHours: function (from, until, groupdays, addcloseddays, onlyweeklyrules) {
			var self = this;
			var now = from === undefined ? moment() : from;
			var future = until === undefined ? moment().add(7, 'days') : until;
			if (groupdays === undefined) groupdays = true;
			if (addcloseddays == undefined) addcloseddays = false;
			if (onlyweeklyrules == undefined) onlyweeklyrules = false;

			var byWeekDay = {};
			
			var zone = null, tz = null;
			
			function hoursHash(ivs) {
				var ret = '';
				for (var i=0;i<ivs.length;i++) {
					ret += ivs[i].start + ivs[i].end + ";";
				}
				return ret;
			}
			
			function getRanges(array) {
				var ranges = [], rstart, rend;
				for (var i = 0; i < array.length; i++) {
					rstart = array[i];
					rend = rstart;
					while (((array[i + 1]+6)%7) - ((array[i]+6)%7) == 1) {
						rend = array[i + 1]; // increment the index if the numbers sequential
						i++;
					}
					ranges.push(rstart == rend ? [rstart] : [rstart, rend]);
				}
				return ranges;
			}
			
			this.betweenIntersects(now, future, function (occ) {
				if (onlyweeklyrules && occ.freq != 'weekly' && occ.freq != 'Weekly') return; //next
				
				if (zone===null) zone = occ.start.zone();
				if (tz===null) tz = occ.start.tz();
				
				if (byWeekDay[occ.start.day()] == null) byWeekDay[occ.start.day()] = [];
				
				var byThisDay = byWeekDay[occ.start.day()];
				
				var newHours = {
					occurrence: occ,
					start: occ.start.format('HH:mm'),
					end: occ.end.format('HH:mm'),
					now: self.occurrenceIsNow(occ)
				};
				
				for (var i=0;i<byThisDay.length;i++) {
					if (byThisDay[i].start == newHours.start && byThisDay[i].end == newHours.end) {
						if (newHours.now) byThisDay[i].now = true;
						return; //ignore duplicate for the same time
					}
				}
				
				if (newHours.start == "00:00" && newHours.end == "00:00") newHours.allDay = true;
				
				byThisDay.push(newHours);
				
			});
			
			var grouped = [];
			
			for (var i=0;i<7;i++) {
				if (!byWeekDay[i])
					if (addcloseddays) {
						var g = { weekdays: [], hours: null };
						g.weekdays.push(i);
						grouped.push(g);
						continue;
					}
					else
						continue;
				byWeekDay[i].sort(function(a,b) { return a.start>b.start?1:-1; });
				var dayHours = byWeekDay[i];
				
				//find in grouped
				var group = null;
				if (groupdays)
					for (var j = 0; j < grouped.length; j++) {
						if (hoursHash(dayHours) == hoursHash(grouped[j].hours)) {
							group = grouped[j];
							//copy "now" info
							for (var k = 0; k < dayHours.length; k++)
								if (dayHours[k].now) group.hours[k].now = true;
							break;
						}
					}

				if (!group) {
					group = { weekdays: [], hours: dayHours };
					grouped.push(group);
				}
				
				group.weekdays.push(i);
			}
			
			for (var j=0;j<grouped.length;j++) {
				var group = grouped[j];
				
				group.weekdays.sort(function(a,b) { return (a+6)%7 - (b+6)%7; });
				group.weekdays = getRanges(group.weekdays);
			}
			
			if (groupdays)
				grouped.sort(function(a,b) { return (a.weekdays[0][0]+6)%7 - (b.weekdays[0][0]+6)%7; }); //sort sundays(0) to the back
			
			return {
				zone: zone,
				tz: tz,
				byWeekDay: byWeekDay,
				grouped: grouped
			};
		
		},

		/**
		 * simple version of getOpeningHours, with no grouping of similar days, and intended to display a range of specific days(a week) instead of something generic
		 * returns 
		 * {
		 *	zone,
		 *	tz,
		 *	grouped: [
		 *		{date:'', weekday: 1, hours: [{start, end, now, allDay, isException, title, occurrence}]
		 *	]
		 * }
		 */
		getOpeningHoursForDateRange: function(options) {
			const now = options.from === undefined ? moment() : options.from; // moment
			const future = options.until === undefined ? moment().add(7, 'days') : options.until; // moment
			// options.onlyweeklyrules default false

			const retDays = [];
			let zone = null, tz = null;

			// prefill retDays
			{
				let curDayMoment = moment(now).startOf('day');
				while (curDayMoment.isBefore(future)) {
					const curDayKey = curDayMoment.format();
					const curDayInfo = { date: curDayKey, weekday: curDayMoment.day(), hours: [] };
					retDays.push(curDayInfo);
					/*
					if (this._exdatesByPrefix && this._exdatesByPrefix[curDayKey]) {
						for (const ex of this._exdatesByPrefix[curDayKey]) {
							const exStart = this._parseDate(ex.start, this._intervals[0].tz);
							curDayInfo.hours.push({isException: true, title: ex.title, start: exStart.format('HH:mm')});
						}
					}
					*/
					curDayMoment = curDayMoment.add(1, 'days');
				}
			}

			this.betweenIntersects(now, future, (occ) => {
				if (options.onlyweeklyrules && occ.freq != 'weekly' && occ.freq != 'Weekly') return; //next

				if (zone === null) zone = occ.start.zone();
				if (tz === null) tz = occ.start.tz();

				// find day, adding should not be needed since all prefilled
				const curDayKey = moment(occ.start).startOf('day').format();
				let curDay = retDays.find((x) => x.date === curDayKey);
				/*if (!curDay) {
					curDay = { date: curDayKey, weekday: occ.start.day(), hours: [] };
					retDays.push(curDay);
				}*/

				var newHours = {
					occurrence: occ,
					start: occ.start.format('HH:mm'),
					end: occ.end.format('HH:mm'),
					now: this.occurrenceIsNow(occ)
				};
				if (newHours.start == "00:00" && newHours.end == "00:00") newHours.allDay = true;

				if (occ.isException) {
					newHours.isException = true;
					newHours.title = occ.exceptionTitle;
				}

				curDay.hours.push(newHours);

			}, true);

			return {
				zone: zone,
				tz: tz,
				grouped: retDays,
			};
		},
		
		/**
		 * relevant occurrences, now and at the given time
		 */
		getRelevantOccurrences: function(from, options) {
			var self = this;
			var options = options || {};
			var targetCount = options.targetCount || 10;
			var maxDaysFuture = options.maxDaysFuture || 90;
			var stepDays = options.stepDays || 7;
			
			var now = moment();
			//var occs = []; //list to sort+return later
			//var occsMark = {}; //hash to mark occ start dates that were already encountered
			var occs = {}; //temp occs by hash, later to be sorted
			var maxEnd = null;
			function mergeOccs(from_, until_) {
				self.betweenIntersects(from_, until_, function(occ) {
					var k = occ.start.format();
					var batchKey = from_.format();//  + '-' + until.format();
					if (occs[k]) {
						occs[k]._batch.push(batchKey);
					} else {
						occ._batch = [batchKey];
						occs[k] = occ;
						
						if (occ.end > maxEnd) maxEnd = occ.end;
					}
				});
			}

			//optimize "from": if all intervals are in the future it it makes no sense to start earlier.
			if (this._intervals.length > 0) {
				var minStart = this._intervals
					.map(function (x) { return x.mstart; })
					.sort(function (a, b) { return a > b ? 1 : -1; })[0];
				if (minStart > from) from = minStart;
			}
			
			var until = moment(from).add(stepDays, 'days');
			mergeOccs(from, until);
			mergeOccs(now, moment(now).add(stepDays, 'days'));
			
			var maxUntil = moment(from).add(maxDaysFuture, 'days');
			while (Object.keys(occs).length < targetCount && until < maxUntil) {
				if (maxEnd) from = moment(maxEnd); //continue from previous max occurrence end to detect gaps, even multi-day ones; maxEnd is set by mergeOccs if there is something
				until = moment(until).add(stepDays, 'days');
				mergeOccs(from, until);
			}
			
			var occsList = [];
			for (var k in occs) {
				occsList.push(occs[k]);
			}
			occsList.sort(function(a,b){return a.start>b.start?1:-1;});
			
			var occsWithGaps = [], prevBatch = [];
			for (var i=0;i<occsList.length;i++) {
				var occ = occsList[i];
				
				var overlap = false;
				for (var j=0;j<prevBatch.length;j++) {
					if (occ._batch.indexOf(prevBatch[j]) != -1) {
						overlap = true;
						break;
					}
				}
				
				if (!overlap && i > 0) {
					occsWithGaps.push({gap:true});
				}
				
				occsWithGaps.push(occ);
				prevBatch = occ._batch;
			}
			
			return occsWithGaps;
		},
		
		
		/**
		 * util to create a html li element for one occurrence, with intelligent german date range formatting
		 * 100% no jquery
		 * @returns HTMLElement
		 */
		createOccurrenceElement: function(occ, options) {
			var $occ = document.createElement('li');
			$occ.className = 'occ';
			if (occ.gap) {
				$occ.textContent = '⋮';
				$occ.className += ' occ-gap';
				return $occ;
			}
			
			var options = options || {};
			var now = options.now || moment();
			
			var almostEnd = moment(occ.end).add(-1,'seconds');
			var endsOnSameDay = almostEnd.format('YYYYMMDD') == occ.start.format('YYYYMMDD');
			
			if (now.format('YYYYMMDD') == occ.start.format('YYYYMMDD')) $occ.className += ' today';
			if (occ.start <= now && occ.end > now ) $occ.className += ' open';
			if (options.highlight && options.highlight.isSame(occ.start)) $occ.className += ' highlight';

			if (occ.allDay) {
				var $start = document.createElement('span');
				$start.className = 'occ-start';
				$start.textContent = occ.start.format('dddd, DD.MM.YYYY');
				$occ.appendChild($start);
					
				if (!endsOnSameDay) {
					$occ.appendChild(document.createTextNode(' - '));
					
					var $end = document.createElement('span');
					$end.className = 'occ-end';
					$end.textContent = almostEnd.format('dddd, DD.MM.YYYY');
					$occ.appendChild($end);
				}
			} else {
				var $start = document.createElement('span');
				$start.className = 'occ-start';
				$start.textContent = occ.start.format('dddd, DD.MM.YYYY HH:mm');
				$occ.appendChild($start);
				
				if (!occ.hideEnd) {
					$occ.appendChild(document.createTextNode(' - '));

					var $end = document.createElement('span');
					$end.className = 'occ-end';
					$end.textContent = occ.end.format(endsOnSameDay ? 'HH:mm' : 'dddd, DD.MM.YYYY HH:mm');
					$occ.appendChild($end);
				}
			}
			return $occ;
		}
	}

	root.eContent.TimeIntervalHelper_rrule.forItem = function (item, type) {
		// type: (default), kitchen, delivery
		if (!type) type = 'default';

		const ivs = type == 'kitchen' ? item.kitchenTimeIntervals
			: type == 'delivery' ? item.deliveryTimeIntervals
				: item.timeIntervals;
		const exs = (item.timeIntervalExceptions || []).filter((ex) => ex.type === 'all' || ((ex.type || 'default') === type));

		return new root.eContent.TimeIntervalHelper_rrule(ivs || [], exs);

	};
	
	if (!root.eContent.TimeIntervalHelper) root.eContent.TimeIntervalHelper = root.eContent.TimeIntervalHelper_rrule;


})(this);
