").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("
").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})})(jQuery);(function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=h(),n=s._rgba=[];return i=i.toLowerCase(),f(l,function(t,a){var o,r=a.re.exec(i),l=r&&a.parse(r),h=a.space||"rgba";return l?(o=s[h](l),s[c[h].cache]=o[c[h].cache],n=s._rgba=o._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,a.transparent),s):a[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,l=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=h.support={},p=t("
")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(n,o,r,l){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(o),o=e);var u=this,d=t.type(n),p=this._rgba=[];return o!==e&&(n=[n,o,r,l],d="array"),"string"===d?this.parse(s(n)||a._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof h?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var a=s.cache;f(s.props,function(t,e){if(!u[a]&&s.to){if("alpha"===t||null==n[t])return;u[a]=s.to(u._rgba)}u[a][e.idx]=i(n[t],e,!0)}),u[a]&&0>t.inArray(null,u[a].slice(0,3))&&(u[a][3]=1,s.from&&(u._rgba=s.from(u[a])))}),this):e},is:function(t){var i=h(t),s=!0,n=this;return f(c,function(t,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),n=s._space(),a=c[n],o=0===this.alpha()?h("transparent"):this,r=o[a.cache]||a.to(o._rgba),l=r.slice();return s=s[a.cache],f(a.props,function(t,n){var a=n.idx,o=r[a],h=s[a],c=u[n.type]||{};null!==h&&(null===o?l[a]=h:(c.mod&&(h-o>c.mod/2?o+=c.mod:o-h>c.mod/2&&(o-=c.mod)),l[a]=i((h-o)*e+o,n)))}),this[n](l)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,a=t[2]/255,o=t[3],r=Math.max(s,n,a),l=Math.min(s,n,a),h=r-l,c=r+l,u=.5*c;return e=l===r?0:s===r?60*(n-a)/h+360:n===r?60*(a-s)/h+120:60*(s-n)/h+240,i=0===h?0:.5>=u?h/c:h/(2-c),[Math.round(e)%360,i,u,null==o?1:o]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],a=t[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,e+1/3)),Math.round(255*n(r,o,e)),Math.round(255*n(r,o,e-1/3)),a]},f(c,function(s,n){var a=n.props,o=n.cache,l=n.to,c=n.from;h.fn[s]=function(s){if(l&&!this[o]&&(this[o]=l(this._rgba)),s===e)return this[o].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[o].slice();return f(a,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=h(c(d)),n[o]=d,n):h(d)},f(a,function(e,i){h.fn[e]||(h.fn[e]=function(n){var a,o=t.type(n),l="alpha"===e?this._hsla?"hsla":"rgba":s,h=this[l](),c=h[i.idx];return"undefined"===o?c:("function"===o&&(n=n.call(this,c),o=t.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=c+parseFloat(a[2])*("+"===a[1]?1:-1))),h[i.idx]=n,this[l](h)))})})}),h.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var a,o,r="";if("transparent"!==n&&("string"!==t.type(n)||(a=s(n)))){if(n=h(a||n),!d.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&o&&o.style;)try{r=t.css(o,"backgroundColor"),o=o.parentNode}catch(l){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(l){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook(o),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},a=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function s(e,i){var s,n,o={};for(s in i)n=i[s],e[s]!==n&&(a[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(o[s]=n));return o}var n=["add","remove","toggle"],a={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,a,o,r){var l=t.speed(a,o,r);return this.queue(function(){var a,o=t(this),r=o.attr("class")||"",h=l.children?o.find("*").addBack():o;h=h.map(function(){var e=t(this);return{el:e,start:i(this)}}),a=function(){t.each(n,function(t,i){e[i]&&o[i+"Class"](e[i])})},a(),h=h.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),o.attr("class",r),h=h.map(function(){var e=this,i=t.Deferred(),s=t.extend({},l,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,h.get()).done(function(){a(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),l.complete.call(o[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,a){return s?t.effects.animateClass.call(this,{add:i},s,n,a):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,a){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,a):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,a,o,r){return"boolean"==typeof n||n===e?a?t.effects.animateClass.call(this,n?{add:s}:{remove:s},a,o,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,a,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,a){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,a)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.4",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,a;for(a=0;s.length>a;a++)null!==s[a]&&(n=t.data(i+s[a]),n===e&&(n=""),t.css(s[a],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return e.wrap(s),(e[0]===a||t.contains(e[0],a))&&t(a).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var a=e.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(a)&&a.call(n[0]),t.isFunction(e)&&e()}var n=t(this),a=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):o.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,a=i.queue,o=t.effects.effect[i.effect];return t.fx.off||!o?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):a===!1?this.each(e):this.queue(a||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()})(jQuery);(function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var a,o,r,l=t(this),h=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(l,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",g=i.test(u),m={},v="show"===c;l.parent().is(".ui-effects-wrapper")?t.effects.save(l.parent(),h):t.effects.save(l,h),l.show(),a=t.effects.createWrapper(l).css({overflow:"hidden"}),o=a[p](),r=parseFloat(a.css(f))||0,m[p]=v?o:0,g||(l.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),m[f]=v?r:o+r),v&&(a.css(p,0),g||a.css(f,r+o)),a.animate(m,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&l.hide(),t.effects.restore(l,h),t.effects.removeWrapper(l),n()}})}})(jQuery);(function(t){t.effects.effect.bounce=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],l=t.effects.setMode(o,e.mode||"effect"),h="hide"===l,c="show"===l,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||h?1:0),g=e.duration/f,m=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=o.queue(),y=b.length;for((c||h)&&r.push("opacity"),t.effects.save(o,r),o.show(),t.effects.createWrapper(o),d||(d=o["top"===v?"outerHeight":"outerWidth"]()/3),c&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,_?2*-d:2*d).animate(a,g,m)),h&&(d/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,o.animate(n,g,m).animate(a,g,m),d=h?2*d:d/2;h&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,o.animate(n,g,m)),o.queue(function(){h&&o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),o.dequeue()}})(jQuery);(function(t){t.effects.effect.clip=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],l=t.effects.setMode(o,e.mode||"hide"),h="show"===l,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(o,r),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[d](),h&&(n.css(d,0),n.css(p,a/2)),f[d]=h?a:0,f[p]=h?0:a/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){h||o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","opacity","height","width"],o=t.effects.setMode(n,e.mode||"hide"),r="show"===o,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,a),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(h,"pos"===c?-s:s),u[h]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),g||p.hide(),i()}var a,o,r,l,h,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(a=0;u>a;a++)for(l=m.top+a*_,c=a-(u-1)/2,o=0;d>o;o++)r=m.left+o*v,h=o-(d-1)/2,p.clone().appendTo("body").wrap("
").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(g?h*v:0),top:l+(g?c*_:0),opacity:g?0:1}).animate({left:r+(g?0:h*v),top:l+(g?0:c*_),opacity:g?1:0},e.duration||500,e.easing,s)}})(jQuery);(function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}})(jQuery);(function(t){t.effects.effect.fold=function(e,i){var s,n,a=t(this),o=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(a,e.mode||"hide"),l="show"===r,h="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=l!==d,f=p?["width","height"]:["height","width"],g=e.duration/2,m={},v={};t.effects.save(a,o),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[h?0:1]),l&&s.css(d?{height:0,width:c}:{height:c,width:0}),m[f[0]]=l?n[0]:c,v[f[1]]=l?n[1]:0,s.animate(m,g,e.easing).animate(v,g,e.easing,function(){h&&a.hide(),t.effects.restore(a,o),t.effects.removeWrapper(a),i()})}})(jQuery);(function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],a=t.effects.setMode(s,e.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(o,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&s.hide(),t.effects.restore(s,n),i()}})}})(jQuery);(function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),a=t.effects.setMode(n,e.mode||"show"),o="show"===a,r="hide"===a,l=o||"hide"===a,h=2*(e.times||5)+(l?1:0),c=e.duration/h,u=0,d=n.queue(),p=d.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;h>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,h+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),a="hide"===n,o=parseInt(e.percent,10)||150,r=o/100,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?l:{height:l.height*r,width:l.width*r,outerHeight:l.outerHeight*r,outerWidth:l.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),a=t.effects.setMode(s,e.mode||"effect"),o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===a?0:100),r=e.direction||"both",l=e.origin,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=l||["middle","center"],n.restore=!0),n.from=e.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:h),n.to={height:h.height*c.y,width:h.width*c.x,outerHeight:h.outerHeight*c.y,outerWidth:h.outerWidth*c.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],l=["position","top","bottom","left","right","overflow","opacity"],h=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(o,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=o.css("position"),_=f?r:l,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===e.mode&&"show"===p?(o.from=e.to||b,o.to=e.from||s):(o.from=e.from||("show"===p?b:s),o.to=e.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===g||"both"===g)&&(a.from.y!==a.to.y&&(_=_.concat(u),o.from=t.effects.setTransition(o,u,a.from.y,o.from),o.to=t.effects.setTransition(o,u,a.to.y,o.to)),a.from.x!==a.to.x&&(_=_.concat(d),o.from=t.effects.setTransition(o,d,a.from.x,o.from),o.to=t.effects.setTransition(o,d,a.to.x,o.to))),("content"===g||"both"===g)&&a.from.y!==a.to.y&&(_=_.concat(c).concat(h),o.from=t.effects.setTransition(o,c,a.from.y,o.from),o.to=t.effects.setTransition(o,c,a.to.y,o.to)),t.effects.save(o,_),o.show(),t.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(n=t.effects.getBaseline(m,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),h=r.concat(u).concat(d),o.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,h),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=t.effects.setTransition(i,u,a.from.y,i.from),i.to=t.effects.setTransition(i,u,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=t.effects.setTransition(i,d,a.from.x,i.from),i.to=t.effects.setTransition(i,d,a.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,h)})})),o.animate(o.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),t.effects.restore(o,_),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):t.each(["top","left"],function(t,e){o.css(e,function(e,i){var s=parseInt(i,10),n=t?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","height","width"],o=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",l=e.distance||20,h=e.times||3,c=2*h+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},g={},m={},v=n.queue(),_=v.length;for(t.effects.save(n,a),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+l,g[d]=(p?"+=":"-=")+2*l,m[d]=(p?"-=":"+=")+2*l,n.animate(f,u,e.easing),s=1;h>s;s++)n.animate(g,u,e.easing).animate(m,u,e.easing);n.animate(g,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","width","height"],o=t.effects.setMode(n,e.mode||"show"),r="show"===o,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l,u={};t.effects.save(n,a),n.show(),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(h,c?isNaN(s)?"-"+s:-s:s),u[h]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),a="fixed"===n.css("position"),o=t("body"),r=a?o.scrollTop():0,l=a?o.scrollLeft():0,h=n.offset(),c={top:h.top-r,left:h.left-l,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("
").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-l,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}})(jQuery);
\ No newline at end of file
diff --git a/web/system/.htaccess b/web/system/.htaccess
new file mode 100644
index 0000000..14249c5
--- /dev/null
+++ b/web/system/.htaccess
@@ -0,0 +1 @@
+Deny from all
\ No newline at end of file
diff --git a/web/system/engine/.htaccess b/web/system/engine/.htaccess
new file mode 100644
index 0000000..14249c5
--- /dev/null
+++ b/web/system/engine/.htaccess
@@ -0,0 +1 @@
+Deny from all
\ No newline at end of file
diff --git a/web/system/engine/SMTP.php b/web/system/engine/SMTP.php
new file mode 100644
index 0000000..61bb3ba
--- /dev/null
+++ b/web/system/engine/SMTP.php
@@ -0,0 +1,80 @@
+from = $from;
+ $this->to = $to;
+ $this->subject = $subject;
+ $this->msg = $msg;
+ $this->user = $user;
+ $this->password = $password;
+ $this->port = $port;
+ $this->server = $server;
+ }
+
+ public function send($html=false)
+ {
+ $err = null;
+ $errstr = "";
+ $this->smtpserverconn = fsockopen($this->server, $this->port, $err, $errstr, 100);
+ $response = fgets($this->smtpserverconn, 515);
+ if ($response === false)
+ {
+ throw new Exception("Could not connect to SMTP server!");
+ }
+
+ if ($this->user != null && $this->password != null)
+ {
+ $this->sendCommand("AUTH LOGIN");
+ $this->sendCommand(base64_encode($this->user));
+ $this->sendCommand(base64_encode($this->password));
+ }
+
+ $this->sendCommand("HELO " . $_SERVER["SERVER_NAME"]);
+ $this->sendCommand("MAIL FROM: " . $this->from);
+ $this->sendCommand("RCPT TO: " . $this->to);
+ $this->sendCommand("DATA");
+
+ if ($html)
+ {
+ $this->sendCommand("MIME-Version: 1.0", false);
+ $this->sendCommand("Content-type: text/html; charset=iso-8859-1", false);
+ }
+
+ $this->sendCommand("From: " . $this->from, false);
+ $this->sendCommand("To: " . $this->to, false);
+ $this->sendCommand("Subject: " . $this->subject, false);
+
+
+ $this->sendCommand($this->msg, false);
+
+ $this->sendCommand("", false);
+ $this->sendCommand(".", false);
+ $this->sendCommand("QUIT");
+
+ }
+
+ private function sendCommand($command, $return = true)
+ {
+ fputs($this->smtpserverconn, $command . "\r\n");
+ if ($return)
+ return fgets($this->smtpserverconn, 515);
+ else
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/web/system/engine/config-default.php b/web/system/engine/config-default.php
new file mode 100644
index 0000000..d91e51a
--- /dev/null
+++ b/web/system/engine/config-default.php
@@ -0,0 +1,15 @@
+config = $config;
+ $this->tpl = $tpl;
+ $this->core = $core;
+ }
+
+ public function loadRender($template, $parameters=array())
+ {
+ $this->tpl->loadTemplate($template);
+ return $this->tpl->render($parameters);
+ }
+
+}
\ No newline at end of file
diff --git a/web/system/engine/core.php b/web/system/engine/core.php
new file mode 100644
index 0000000..268e137
--- /dev/null
+++ b/web/system/engine/core.php
@@ -0,0 +1,270 @@
+config = array_merge($config, $newconfig);
+ if ($this->config["USE_H20_TPL"])
+ $this->tpl = new H2o(null, array(
+ "searchpath" => getcwd() . "/application/views/",
+ "cache_dir" => "application/tmp/",
+ 'cache' => 'file'
+ ));
+ set_error_handler("HF_Core::error_handler");
+ $this->findController();
+ }
+
+ public function siteURL()
+ {
+ if (isvarset($this->config["SITE_URL"]))
+ {
+ return $this->config["SITE_URL"];
+ }
+ $path = explode("/", $_SERVER["REQUEST_URI"]);
+ $path = array_filter($path, 'strlen');
+ if (count($path) == 0)
+ {
+ return $_SERVER["HTTP_HOST"] . "/";
+ } else {
+ if (in_array($this->classname, $path))
+ {
+ $newpath = implode("/", array_splice($path, 0, -2));
+ return $_SERVER["HTTP_HOST"] . "/" . $newpath . "/";
+ } else {
+ $newpath = implode("/", $path);
+ return $_SERVER["HTTP_HOST"] . "/" . $newpath . "/";
+ }
+ }
+ }
+
+ private function findController()
+ {
+ try
+ {
+ if (isvarset($_SERVER["PATH_INFO"]))
+ {
+ $request = $_SERVER["PATH_INFO"];
+ //$request = $_SERVER["PHP_SELF"];
+ $splitreq = explode("/", $request);
+ /*$request = "";
+ for($i = 0; $i < count($splitreq); $i++)
+ {
+ if ($splitreq[$i] == "index.php")
+ {
+ $request = implode("/", array_splice($splitreq, $i+1));
+ }
+ }*/
+ //print $request;
+ //$request = substr($request, 1);
+ //$request = substr($request, 0, -1);
+ } else {
+ $request = "";
+ }
+ if ($request == "" || $request == "/")
+ {
+ require("application/controllers/" . $this->config["DEFAULT_ROUTE"] . ".php");
+ $this->loadController(new $this->config["DEFAULT_ROUTE"]($this->config, $this, $this->tpl), $this->config["DEFAULT_ROUTE"], "index");
+ return;
+ }
+ if ($request[strlen($request)-1] == "/")
+ $request = substr($request, 0, -1);
+ $arr = explode("/", $request);
+ $path = "application/controllers/";
+ for($i = 0; $i < count($arr); $i++)
+ {
+ if (is_file($path . $arr[$i] . ".php")) // found the controller
+ {
+ include($path . $arr[$i] . ".php");
+ if ($i + 1 < count($arr)) // if there is a define after the controller name - this would be the method name
+ {
+ $this->loadController(new $arr[$i]($this->config, $this, $this->tpl), $arr[$i], $arr[$i+1], array_slice ($arr, 2));
+ } else { // call index
+ $this->loadController(new $arr[$i]($this->config, $this, $this->tpl), $arr[$i], "index");
+ }
+ return;
+ }
+
+ if (is_dir($path . $arr[$i])) // controller is hidden deeper
+ {
+ $path = $path . $arr[$i] . "/";
+ continue;
+ }
+
+ include($path . $this->config["DEFAULT_ROUTE"] . ".php");
+ $this->loadController(new $this->config["DEFAULT_ROUTE"]($this->config, $this, $this->tpl), $this->config["DEFAULT_ROUTE"], "index");
+ //$this->load404Controller();
+ break;
+ // throw exception controller not found
+ }
+ } catch (Exception $e) {
+ if ($this->config["DEBUG"])
+ echo vdump($e, $this);
+ else
+ $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
+ }
+ }
+
+ private function load404Controller()
+ {
+ if (is_file(getcwd() . "/application/status.php"))
+ {
+ include_once (getcwd() . "/application/status.php");
+ $this->loadController(new status($this->config, $this, $this->tpl), "status", "Status404");
+ } else {
+ include_once(getcwd() . "/system/engine/status.php");
+ $this->loadController(new HF_Status($this->config, $this, $this->tpl), "HF_Status", "Status404");
+
+ }
+ }
+
+ private function load500Controller()
+ {
+ if (is_file(getcwd() . "/application/status.php"))
+ {
+ include_once (getcwd() . "/application/status.php");
+ $this->loadController(new status($this->config, $this, $this->tpl), "status", "Status500");
+ } else {
+ include_once (getcwd() . "/system/engine/status.php");
+ $this->loadController(new HF_Status($this->config, $this, $this->tpl), "HF_Status", "Status500");
+
+ }
+ }
+
+ private function loadController($class, $classname, $method, $args = array())
+ {
+ $this->class = $class;
+ $this->classname = $classname;
+ $this->method = $method;
+ $this->args = $args;
+ }
+
+ public function run($err=false)
+ {
+ try
+ {
+ $call = new ReflectionMethod($this->classname, $this->method);
+ if ($err)
+ {
+ $call->invokeArgs($this->class, $this->args);
+ return;
+ }
+
+ $numOfReqPara = $call->getNumberOfRequiredParameters();
+ $numOfOptPara = $call->getNumberOfParameters() - $numOfReqPara;
+ $remainparas = count($this->args) - $numOfReqPara;
+ if ($numOfReqPara == 0 || ($remainparas >= 0 && $remainparas <= $numOfOptPara))
+ {
+ $call->invokeArgs($this->class, $this->args);
+ }
+ else
+ {
+ $this->load404Controller();
+ $this->run(true);
+ }
+
+ } catch (ReflectionException $e)
+ {
+ if (strstr($e->getMessage(), "does not exist") !== false)
+ {
+ $this->load404Controller();
+ } else {
+ $this->load500Controller();
+ }
+ $this->run(true);
+ if ($this->config["DEBUG"])
+ echo vdump($e, $this);
+ else
+ $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
+
+
+ } catch (Exception $e) {
+ $this->load500Controller();
+ $this->run(true);
+ if ($this->config["DEBUG"])
+ echo vdump($e, $this);
+ else
+ $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
+ }
+ }
+
+ public function mail_admins($subject, $msg, $html = false)
+ {
+ if (array_key_exists("ADMINS", $this->config))
+ {
+ foreach($this->config["ADMINS"] as $email)
+ {
+ $this->mail_user($email, $subject, $msg, $html);
+ }
+ }
+ }
+
+ public function mail_user($to, $subject, $msg, $html = false)
+ {
+ if ($this->config["USE_HF_SMTP"])
+ {
+ $smtp = new HF_SMTP($this->config["SMTP_FROM"], $to, $subject, $msg, $this->config["SMTP_SERVER"], $this->config["SMTP_USER"], $this->config["SMTP_PASS"], $this->config["SMTP_PORT"]);
+ $smtp->send($html);
+ } else {
+ require_once "Mail.php";
+ $smtp = null;
+ if ($this->$this->config["SMTP_USER"] && $this->config["SMTP_PASS"])
+ $smtp = Mail::factory('smtp', array(
+ "host" => $this->config["SMTP_SERVER"],
+ "port" => $this->config["SMTP_PORT"],
+ "auth" => true,
+ 'username' => $this->config["SMTP_USER"],
+ 'password' => $this->config["SMTP_PASS"]
+ ));
+ else
+ $smtp = Mail::factory('smtp', array(
+ "host" => $this->config["SMTP_SERVER"],
+ "port" => $this->config["SMTP_PORT"]
+ ));
+ $headers = array ('From' => $this->config["SMTP_FROM"],
+ 'To' => $to,
+ 'Subject' => $subject);
+ $smtp->send($to, $headers, $msg);
+ }
+ }
+
+ public static function error_handler($err_severity, $err_msg, $err_file, $err_line, array $err_context)
+ {
+ if (0 === error_reporting()) { return false;}
+ switch($err_severity)
+ {
+ case E_ERROR: throw new ErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_WARNING: throw new WarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_PARSE: throw new ParseException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_NOTICE: throw new NoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_CORE_ERROR: throw new CoreErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_CORE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_COMPILE_ERROR: throw new CompileErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_COMPILE_WARNING: throw new CoreWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_USER_ERROR: throw new UserErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_USER_WARNING: throw new UserWarningException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_USER_NOTICE: throw new UserNoticeException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_STRICT: throw new StrictException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_RECOVERABLE_ERROR: throw new RecoverableErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_DEPRECATED: throw new DeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ case E_USER_DEPRECATED: throw new UserDeprecatedException ($err_msg, 0, $err_severity, $err_file, $err_line);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/web/system/engine/exceptions.php b/web/system/engine/exceptions.php
new file mode 100644
index 0000000..a180229
--- /dev/null
+++ b/web/system/engine/exceptions.php
@@ -0,0 +1,18 @@
+
+ ********************************** 80 Columns *********************************
+ */
+class DB
+{
+ static $q,$c,$p,$i = '`';
+
+ /**
+ * Fetch a column offset from the result set (COUNT() queries)
+ *
+ * @param string $query query string
+ * @param array $params query parameters
+ * @param integer $key index of column offset
+ * @return array|null
+ */
+ static function column($query, $params = NULL, $key = 0)
+ {
+ if($statement = DB::query($query, $params))
+ return $statement->fetchColumn($key);
+ }
+
+ /**
+ * Fetch a single query result row
+ *
+ * @param string $query query string
+ * @param array $params query parameters
+ * @return mixed
+ */
+ static function row($query, $params = NULL)
+ {
+ if($statement = DB::query($query, $params))
+ return $statement->fetch();
+ }
+
+ /**
+ * Fetches an associative array of all rows as key-value pairs (first
+ * column is the key, second column is the value).
+ *
+ * @param string $query query string
+ * @param array $params query parameters
+ * @return array
+ */
+ static function pairs($query, $params = NULL)
+ {
+ $data = array();
+
+ if($statement = DB::query($query, $params))
+ while($row = $statement->fetch(\PDO::FETCH_NUM))
+ $data[$row[0]] = $row[1];
+
+ return $data;
+ }
+
+ /**
+ * Fetch all query result rows
+ *
+ * @param string $query query string
+ * @param array $params query parameters
+ * @param int $column the optional column to return
+ * @return array
+ */
+ static function fetch($query, $params = NULL, $column = NULL)
+ {
+ if( ! $statement = DB::query($query, $params)) return;
+
+ // Return an array of records
+ if($column === NULL) return $statement->fetchAll();
+
+ // Fetch a certain column from all rows
+ return $statement->fetchAll(\PDO::FETCH_COLUMN, $column);
+ }
+
+ /**
+ * Prepare and send a query returning the PDOStatement
+ *
+ * @param string $query query string
+ * @param array $params query parameters
+ * @return object|null
+ */
+ static function query($query, $params = NULL)
+ {
+ $statement = static::$c->prepare(DB::$q[] = strtr($query, '`', DB::$i));
+ $statement->execute($params);
+ return $statement;
+ }
+
+ /**
+ * Insert a row into the database
+ *
+ * @param string $table name
+ * @param array $data
+ * @return integer|null
+ */
+ static function insert($table, array $data)
+ {
+ $query = "INSERT INTO`$table`(`" . implode('`,`', array_keys($data))
+ . '`)VALUES(' . rtrim(str_repeat('?,', count($data = array_values($data))), ',') . ')';
+ return DB::$p
+ ? DB::column($query . 'RETURNING`id`', $data)
+ : (DB::query($query, $data) ? static::$c->lastInsertId() : NULL);
+ }
+
+ /**
+ * Update a database row
+ *
+ * @param string $table name
+ * @param array $data
+ * @param array $w where conditions
+ * @return integer|null
+ */
+ static function update($table, $data, $value, $column = 'id')
+ {
+ $keys = implode('`=?,`', array_keys($data));
+ if($statement = DB::query(
+ "UPDATE`$table`SET`$keys`=? WHERE`$column`=?",
+ array_values($data + array($value))
+ ))
+ return $statement->rowCount();
+ }
+}
\ No newline at end of file
diff --git a/web/system/vendor/README.md b/web/system/vendor/README.md
new file mode 100644
index 0000000..74e50fa
--- /dev/null
+++ b/web/system/vendor/README.md
@@ -0,0 +1,453 @@
+H2O template markup
+========================
+Being a martial arts fan, I borrow a quote.
+
+
+
+H2O template
+------------------------
+H2O is markup language for PHP that has taken a lot of inspiration from Django.
+
+
+__Features__
+ * Readable and human-friendly syntax.
+ * Easy to use and maintain
+ * Encourages reuse in templates by allowing template inclusion and inheritance.
+ * Highly extensible through filters, tags, and template extensions.
+ * Includes a rich set of filters and tags for string formatting, HTML helpers and
+ internationalization support.
+
+
+Requirement
+------------------------
+
+ - PHP 5.1 +
+
+
+News
+------------------------
+
+ - version 0.4
+ 1. **Breaking changes** autoescape is now turned on by default
+ 2. Improved searchpath and file loading handling
+ 3. Improved handling on PHP overloaded objects
+ 4. Plenty of bug fixes
+ - version 0.3
+ 1. Support internationalized templates and translation parsing toolkit
+ 2. Performance optimization on context lookup
+ 3. Fixed operator parsing
+
+Getting started
+------------------------
+
+### Getting h2o
+
+Download
+
+[
](http://code.google.com/p/h2o-template/downloads)
+
+With Git
+
+`git clone http://github.com/speedmax/h2o-php.git`
+
+With SVN
+
+`svn checkout http://h2o-template.googlecode.com/svn/trunk/ h2o`
+
+### Installation
+ 1. Download and extract h2o into your project path or your php include path
+
+ Sample file structure setup
+
+ myawesome_app/
+ index.php
+ templates/
+ index.html
+ h2o/
+
+
+ 2. Use `require 'h2o/h2o.php'` in your php files to include the h2o library.
+ 3. Below is a basic code sample to get your project going.
+ 3. Check out the *\example* and *\specs* dirs to see some of h2o's more interesting features in action.
+
+*templates/index.html*
+
+
+
Hello world
+
+ Greetings {{ name }}
+
+
+
+*index.php*
+
+ render(array('name'=>'Peter Jackson'));
+ ?>
+
+
+Useful links
+------------------------
+
+ * Please submit patches or bug reports to our [lighthouse bug tracker][issue].
+ * Check out our [Google group][group] for h2o-related discussion.
+
+ [issue]:http://idealian.lighthouseapp.com/projects/11041-h2o-template-language
+ [group]:http://groups.google.com/group/h2o-template-php
+
+
+Syntax explanation
+------------------------
+
+## variable
+`{{ variable }}`
+
+Use dot (.) to access attributes of a variable
+
+#### variable lookup order
+1. key of an associative array
+2. array-index
+3. object attribute
+4. object method call
+
+**Example**
+
+*in your template*
+
+ {{ person.name }}
+
+*in php*
+
+ 'Peter Jackson', 'age' => 25
+ );
+ $h2o->render(compact('person'));
+ ?>
+
+Let's say that you have assigned the value `Peter Jackson` to a 'person' variable in your php script. The following
+variable tag will print out `Peter Jackson`.
+
+## Filters
+
+Filters are variable modifiers that manipulate or format the value of a variable.
+A filter usually looks like this `{{ person.name|capitalize }}`, a pipe ( | )
+character after a variable, plus a filter name, will cause H2O to apply the filter.
+
+__Filter chaining__
+
+![filter chaining](http://wiki.shopify.com/upload/8/8c/Filterchain.jpg)
+Let me borrow the image from liquid template
+
+You can chain multiple filters together and use a pipe ( | ) character to separate
+them. `{{ document.body|escape|nl2br }}`
+
+__Filter arguments__
+Filters can accept arguments. For example:
+`{{ document.description|truncate 20 }}`
+will display the first 20 characters of the document's description.
+
+Moreover, there are cases where you might want to pass in multiple arguments.
+Use commas ( , ) to separate them:
+`{{ person.bio|truncate 20, "..." }}`
+
+__Filter named arguments__
+h2o uses colons ( : ) for named arguments. These allow you to build 'optional argument' arrays.
+
+`{{ '/images/logo.png' | image_tag width:450, height:250, alt:"company logo" }}`
+
+The above code translated to php will be like the below snippet, which resembles what happens internally:
+
+ 450,
+ 'height' => 250,
+ 'alt'=>'company logo'
+ ));
+ ?>
+
+Note: Difference with Django, Smarty
+H2o does not use the colon ( : ) character to separate arguments for readability reasons,
+H2o uses the comma ( , ) which is more logical.
+
+
+## Tag
+
+`{% tag %}`
+
+Tags are very powerful, as they control the logical flow and structure of a template,
+There are inline tags `{% inline_tag %}` or tags that requires a
+close tag. For example: `{% if condition %} ... {% endif %}`
+
+
+### The "if" tag
+
+`if` tags evaluate either a variable or a simple expression. If the result of the `if`
+expression is *true*, then the contents of the `if` block will be allowed to render.
+
+ {% if person.is_adult %}
+ You are old enough.
+ {% else %}
+ sorry, you are too young for that.
+ {% endif %}
+
+### The "for" tag
+
+`for` tags allow iteratation over an array of items.
+
+ {% for task in tasks %}
+ {{ task }}
+ {% endfor %}
+
+The above snippet will print out each "task" in the "tasks" array.
+
+Template inheritance
+------------------------
+H2o supports template inheritance. Inheritance allows you to factor out a lot
+of common code that would otherwise be duplicated across most of your templates.
+
+Template inheritance is implemented using the `block` and `extends` tags, with child templates
+*extending* their parent templates.
+**Word of Caution:**
+ * H2o templates only support single inheritance (just like PHP!), and currently do not support deep inheritance chains.
+
+
+Quote from the Django docs:
+> ... a base skeleton template that contains all the common elements of your
+> site and defines blocks that child templates can override.
+
+
+*Example:*
+
+_base.html_ - defines the base structure of our pages.
+
+
+
{%block title %}This is a page title {% endblock %}
+
+
+ {% block content%}
+
Page title
+
H2O template inheritance is a powerful tool
+ {% endblock %}
+
+
+
+
+
+
+As you can see, the base template is a typical web page using a two column layout.
+We defined two blocks (`content` and `sidebar`) and HTML code common across all of our pages.
+
+
+_page.html_ - defines a page-specific template.
+
+ {% extends 'base.html' %}
+
+ {% block content %}
+
extended page
+
Body of extended page
+ {% endblock %}
+
+ {% block sidebar %}
+ Sidebar contains use links.
+ {% endblock %}
+
+
+The `page.html` extends `base.html`, allowing us to override any block
+previously defined in `base.html`.
+
+Below is an excellent article about template inheritance in Django. If you wish to understand H2o's
+template-inheritance system, this would be a great spot to start, since H2o's template-inheritance system
+is strongly influenced by Django's.
+
+[Power of inheritance][3] is a very good blog post explaining inheritance
+
+ [3]:http://www2.jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/
+
+*Tips*
+
+* If you have found that you have several common elements inside the same template, it may be a
+ good idea to put that portion of the template inside a `block` in a base template.
+* `block` give you a hook, which is useful, since these can help with javascript and css too.
+* When defining a block use a short and distinctive name
+
+
+
+### Configuration
+There are a range of options for configuring the template engine.
+
+ [option_value]
+ ));
+ ?>
+
+#### Loader
+The name of the loader or an instance of H2o_Loader
+
+__Use file loader [default]__
+
+` $template = new H2o('index.html', array('loader'=>'file'); `
+
+
+__Advanced setup__
+ $loader );
+ ?>
+
+__Use dictionary loader__
+
+If you want to load templates from resources other than files, then this will be your
+friend. H2o uses `dict_loader()` for testing.
+
+ 'Hello {{ person }}'
+ ));
+ $template = new H2o('index.html', array('loader' => $loader'));
+ ?>
+
+#### Searchpath
+
+default: this will be the base path of your template
+
+H2o use this path to load additional templates and extensions.
+
+You can either explicity set the search path,
+
+`$template = new H2o('index.html', array('searchpath' => '/sites/common_templates'));`
+
+or h2o will try to find the searchpath for you.
+
+`$template = new H2o('/sites/common_templates/index.html');`
+
+#### Cache
+You can define the type of caching engine h2o should use, if any.
+Set 'cache' to false to disable caching.
+You can read more about performance and caching in following sections
+
+Use file cache [default]
+
+`$template = new H2o('index.html', array('cache'=>'file'));`
+
+Use apc cache:
+
+`$template = new H2o('index.html', array('cache'=>'apc'));`
+
+Use memcache cache
+
+`$template = new H2o('index.html', array('cache'=>'memcache'));`
+
+Disable caching
+
+`$template = new H2o('index.html', array('cache'=>false));`
+
+#### Cache_dir
+When the file cache is used, you can define where you want templates to be cached.
+
+It will put a cached template in same location as the normal template
+
+`$template = new H2o('index.html', array('cache_dir'=>'/tmp/cached_templates'));`
+
+#### Cache_ttl
+"cache_ttl" specifies how long a cached template should be used (defaults: 1 hour) before it is recompiled. The template fragment cache
+that is bundled in the cache extension will use this as default ttl value.
+
+`$template = new H2o('index.html', array('cache_ttl' => 3600));`
+
+
+Performance and Caching
+------------------------
+
+Caching can increase performance since it skips step of inefficient template parsing.
+H2o caches the template objects (the internal data structure of a template) and the bundled
+caching backends include File, APC, and Memcache.
+
+### File cache
+By default h2o uses the file cache to store template objects. Change h2o option `cache_dir` to where you
+want to store template cache (ie: /tmp).
+
+ 'file',
+ 'cache_dir' => '/tmp'
+ ));
+ ?>
+
+### APC cache
+APC is an op-code and object cache extension for php whose performance is
+generally 10-30% better than just plain file caching.
+
+ 'apc'));
+ ?>
+
+### Memcache
+Currently not implemented
+
+
+Extending H2o
+------------------------
+
+
+Known issues
+------------------------
+Yes, h2o has them. However, if you are careful, these shouldn't hinder your template development.
+The deep inheritance issue is a bit problematic for some template architectures, but again, if you
+are careful, and perhaps a bit inventive, it won't hinder you terribly much.
+
+ * `{{ block.super }}` doesn't work with more than 1 level of inheritance yet, so if `{{ block.super }}`
+ invokes another `{{ block.super }}` it won't work just yet.
+ * 'if' conditions don't support multiple expressions or mathematical expressions yet, like:
+ `{% if something > 3 or something < 2 %}` or `{% if something + else > 12 %}`
+ These likely will not be implemented in the future unless some daring soul implements them and
+ contributes the code back to the h2o-php project.
+
+
+Contributors
+---
+ - Taylor Luk - Founder of [Issue publishing](http://issueapp.com)
+ - jlogsdon - Major refactoring (wip) and bug fixes
+ - cyberklin - Added filter support for any context resolve
+ - idlesign - Added if_changed tag support
+ - metropolis - Improved our test coverage
+ - plus many others
+
+
+Credit
+------------------------
+H2o borrows ideas and/or concepts from the following projects:
+
+ - Django template - Django web development framework.
+ - Ptemplates - Armin Ronacher's pet project for a django port in PHP.
+ - Jinja - Django inspired template in Python.
+
+Special Thanks: Armin Ronacher, since early versions of h2o were based off of his Ptemplates project.
+
+The MIT License
+------------------------
+Copyright (c) 2008 Taylor Luk
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/web/system/vendor/StackTracePrint.php b/web/system/vendor/StackTracePrint.php
new file mode 100644
index 0000000..bbd689b
--- /dev/null
+++ b/web/system/vendor/StackTracePrint.php
@@ -0,0 +1,69 @@
+";
+
+ $ret .- "
".htmlspecialchars(trim($code[$backtrace[0]['line']-1]))."\n";
+
+ $ret .= "\n";
+
+ ob_start();
+
+ foreach ($args as $arg)
+ var_dump($arg);
+
+ var_dump($_SERVER);
+ var_dump($_COOKIE);
+
+ $str = ob_get_contents();
+
+ ob_end_clean();
+
+ $str = preg_replace('/=>(\s+)/', ' => ', $str);
+ $str = preg_replace('/ => NULL/', ' →
NULL', $str);
+ $str = preg_replace('/}\n(\s+)\[/', "}\n\n".'$1[', $str);
+ $str = preg_replace('/ (float|int)\((\-?[\d\.]+)\)/', "
$1 $2", $str);
+
+ $str = preg_replace('/array\((\d+)\) {\s+}\n/', "
array•$1 []", $str);
+ $str = preg_replace('/ string\((\d+)\) \"(.*)\"/', "
str•$1 '$2'", $str);
+ $str = preg_replace('/\[\"(.+)\"\] => /', "
'$1' → ", $str);
+ $str = preg_replace('/object\((\S+)\)#(\d+) \((\d+)\) {/', "
obj•$2 $1[$3] {", $str);
+ $str = str_replace("bool(false)", "
bool•false", $str);
+ $str = str_replace("bool(true)", "
bool•true", $str);
+
+ $ret .= $str;
+
+
+
+ $ret .= "";
+
+ return $ret;
+
+
+
+}
+
+// Original - http://www.php.net/manual/en/function.debug-print-backtrace.php#86932
+function debug_string_backtrace() {
+ ob_start();
+ debug_print_backtrace();
+ $trace = ob_get_contents();
+ ob_end_clean();
+
+ // Remove first item from backtrace as it's this function which
+ // is redundant.
+ $trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);
+
+ // Renumber backtrace items.
+ $trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);
+
+ $trace = wordwrap($trace, 123, "
");
+ return $trace;
+}
\ No newline at end of file
diff --git a/web/system/vendor/h2o.php b/web/system/vendor/h2o.php
new file mode 100644
index 0000000..e03d293
--- /dev/null
+++ b/web/system/vendor/h2o.php
@@ -0,0 +1,266 @@
+'file'));
+ *
+ *
+ * $h2o = new H2O('template.html', array("loader"=>'hash'));
+ */
+class H2o {
+ var $searchpath;
+ var $context;
+ var $loader = false;
+
+ static $tags = array();
+ static $filters = array();
+ static $extensions = array();
+
+ static function getOptions($options = array()) {
+ return array_merge(array(
+ 'loader' => 'file',
+ 'cache' => 'file', // file | apc | memcache
+ 'cache_prefix' => 'h2o_',
+ 'cache_ttl' => 3600, // file | apc | memcache
+ 'searchpath' => false,
+ 'autoescape' => true,
+
+ // Enviroment setting
+ 'BLOCK_START' => '{%',
+ 'BLOCK_END' => '%}',
+ 'VARIABLE_START' => '{{',
+ 'VARIABLE_END' => '}}',
+ 'COMMENT_START' => '{*',
+ 'COMMENT_END' => '*}',
+ 'TRIM_TAGS' => true
+ ), $options);
+ }
+
+ function __construct($file = null, $options = array()) {
+ # Init a environment
+ $this->options = $this->getOptions($options);
+ $loader = $this->options['loader'];
+
+ if (!$loader)
+ return true;
+
+ if (is_object($loader)) {
+ $this->loader = $loader;
+ $this->loader->setOptions($this->options);
+ } else {
+ $loader = "H2o_{$loader}_Loader";
+ if (!class_exists($loader, false))
+ throw new Exception('Invalid template loader');
+
+ if (isset($options['searchpath'])){
+ $this->searchpath = $options['searchpath'];
+ } else if ($file) {
+ $this->searchpath = dirname(realpath($file)).DS;
+ } else {
+ $this->searchpath = getcwd().DS;
+ }
+
+ $loader_searchpath = is_array($this->searchpath) ? $this->searchpath : array($this->searchpath);
+ $this->loader = new $loader($loader_searchpath, $this->options);
+ }
+ $this->loader->runtime = $this;
+
+ if (isset($options['i18n'])) {
+ h2o::load('i18n');
+ $this->i18n = new H2o_I18n($this->searchpath, $options['i18n']);
+ }
+
+ if ($file) {
+ $this->nodelist = $this->loadTemplate($file);
+ }
+ }
+
+ function loadTemplate($file) {
+ return $this->nodelist = $this->loader->read_cache($file);
+ }
+
+ function loadSubTemplate($file) {
+ return $this->loader->read($file);
+ }
+
+ # Build a finalized nodelist from template ready to be cached
+ function parse($source, $filename = '', $env = null) {
+ if (!$env)
+ $env = $this->options;
+
+ if (!class_exists('H2o_Parser', false))
+ require H2O_ROOT.'h2o/parser.php';
+
+ $parser = new H2o_Parser($source, $filename, $this, $env);
+ $nodelist = $parser->parse();
+ return $nodelist;
+ }
+
+ function set($context, $value = null) {
+ # replace with new context object
+ if (is_object($context) && $context instanceof H2o_Context) {
+ return $this->context = $context;
+ }
+
+ # Init context
+ if (!$this->context) {
+ $this->context = new H2o_Context($this->defaultContext(), $this->options);
+ }
+
+ # Extend or set value
+ if (is_array($context)) {
+ return $this->context->extend($context);
+ }
+ elseif (is_string($context)) {
+ return $this->context[$context] = $value;
+ }
+ return false;
+ }
+
+ # Render the nodelist
+ function render($context = array()) {
+ $this->set($context);
+
+ $this->stream = new StreamWriter;
+ $this->nodelist->render($this->context, $this->stream);
+ return $this->stream->close();
+ }
+
+ static function parseString($source, $options = array()) {
+ $instance = new H2o(null, array_merge($options, array('loader' => false)));
+ $instance->nodelist = $instance->parse($source);
+ return $instance;
+ }
+
+ static function &createTag($tag, $args = null, $parser, $position = 0) {
+ if (!isset(self::$tags[$tag])) {
+ throw new H2o_Error($tag . " tag doesn't exist");
+ }
+ $tagClass = self::$tags[$tag];
+ $tag = new $tagClass($args, $parser, $position);
+ return $tag;
+ }
+
+ /**
+ * Register a new tag
+ *
+ *
+ * h2o::addTag('tag_name', 'ClassName');
+ *
+ * h2o::addTag(array(
+ * 'tag_name' => 'MagClass',
+ * 'tag_name2' => 'TagClass2'
+ * ));
+ *
+ * h2o::addTag('tag_name'); // Tag_name_Tag
+ *
+ * h2o::addTag(array('tag_name',
+ * @param unknown_type $tag
+ * @param unknown_type $class
+ */
+ static function addTag($tag, $class = null) {
+ $tags = array();
+ if (is_string($tag)) {
+ if (is_null($class))
+ $class = ucwords("{$tag}_Tag");
+ $tags[$tag] = $class;
+ } elseif (is_array($tag)) {
+ $tags = $tag;
+ }
+
+ foreach ($tags as $tag => $tagClass) {
+ if (is_integer($tag)) {
+ unset($tags[$tag]);
+ $tag = $tagClass;
+ $tagClass = ucwords("{$tagClass}_Tag");
+ }
+ if (!class_exists($tagClass, false)) {
+ throw new H2o_Error("{$tagClass} tag is not found");
+ }
+ $tags[$tag] = $tagClass;
+ }
+ self::$tags = array_merge(self::$tags, $tags);
+ }
+
+ /**
+ * Register a new filter to h2o runtime
+ *
+ * @param unknown_type $filter
+ * @param unknown_type $callback
+ * @return unknown
+ */
+ static function addFilter($filter, $callback = null) {
+ if (is_array($filter)) {
+ $filters = $filter;
+ foreach($filters as $key => $filter) {
+ if (is_numeric($key))
+ $key = $filter;
+ self::addFilter($key, $filter);
+ }
+ return true;
+ } elseif (is_string($filter) && class_exists($filter, false) && is_subclass_of($filter, 'FilterCollection')) {
+ foreach (get_class_methods($filter) as $f) {
+ if (is_callable(array($filter, $f)))
+ self::$filters[$f] = array($filter, $f);
+ }
+ return true;
+ }
+ if (is_null($callback))
+ $callback = $filter;
+
+ if (!is_callable($callback)) {
+ return false;
+ }
+ self::$filters[$filter] = $callback;
+ }
+
+ static function addLookup($callback) {
+ if (is_callable($callback)) {
+ H2o_Context::$lookupTable[] = $callback;
+ } else die('damm it');
+ }
+
+ static function load($extension, $file = null) {
+ if (!$file) {
+ $file = H2O_ROOT.'ext'.DS.$extension.'.php';
+ }
+ if (is_file($file)) {
+ include_once ($file);
+ self::$extensions[$extension] = $file;
+ }
+ }
+
+ function defaultContext() {
+ return array('h2o' => new H2o_Info);
+ }
+}
+
+/**
+ * Convenient wrapper for loading template file or string
+ * @param $name
+ * @param $options - H2o options
+ * @return Instance of H2o Template
+ */
+function h2o($name, $options = array()) {
+ $is_file = '/([^\s]*?)(\.[^.\s]*$)/';
+
+ if (!preg_match($is_file, $name)) {
+ return H2o::parseString($name, $options);
+ }
+
+ $instance = new H2o($name, $options);
+ return $instance;
+}
+
+?>
diff --git a/web/system/vendor/h2o/.htaccess b/web/system/vendor/h2o/.htaccess
new file mode 100644
index 0000000..14249c5
--- /dev/null
+++ b/web/system/vendor/h2o/.htaccess
@@ -0,0 +1 @@
+Deny from all
\ No newline at end of file
diff --git a/web/system/vendor/h2o/context.php b/web/system/vendor/h2o/context.php
new file mode 100644
index 0000000..ab09dbc
--- /dev/null
+++ b/web/system/vendor/h2o/context.php
@@ -0,0 +1,266 @@
+ 0, 'last'=> 1, 'length'=> 2, 'size'=> 3);
+ static $lookupTable = array();
+
+ function __construct($context = array(), $options = array()){
+ if (is_object($context))
+ $context = get_object_vars($context);
+ $this->scopes = array($context);
+
+ if (isset($options['safeClass']))
+ $this->safeClass = array_merge($this->safeClass, $options['safeClass']);
+
+ if (isset($options['autoescape']))
+ $this->autoescape = $options['autoescape'];
+
+ $this->options = $options;
+ }
+
+ function push($layer = array()){
+ return array_unshift($this->scopes, $layer);
+ }
+
+ /**
+ * pop the most recent layer
+ */
+ function pop() {
+ if (!isset($this->scopes[1]))
+ throw new Exception('cannnot pop from empty stack');
+ return array_shift($this->scopes);
+ }
+
+ function offsetExists($offset) {
+ foreach ($this->scopes as $layer) {
+ if (isset($layer[$offset])) return true;
+ }
+ return false;
+ }
+
+ function offsetGet($key) {
+ foreach ($this->scopes as $layer) {
+ if (isset($layer[$key]))
+ return $layer[$key];
+ }
+ return;
+ }
+
+ function offsetSet($key, $value) {
+ if (strpos($key, '.') > -1)
+ throw new Exception('cannot set non local variable');
+ return $this->scopes[0][$key] = $value;
+ }
+
+ function offsetUnset($key) {
+ foreach ($this->scopes as $layer) {
+ if (isset($layer[$key])) unset($layer[$key]);
+ }
+ }
+
+ function extend($context) {
+ $this->scopes[0] = array_merge($this->scopes[0], $context);
+ }
+
+ function set($key, $value) {
+ return $this->offsetSet($key, $value);
+ }
+
+ function get($key) {
+ return $this->offsetGet($key);
+ }
+
+ function isDefined($key) {
+ return $this->offsetExists($key);
+ }
+ /**
+ *
+ *
+ *
+ * Variable name
+ *
+ * @param $var variable name or array(0 => variable name, 'filters' => filters array)
+ * @return unknown_type
+ */
+ function resolve($var) {
+
+ # if $var is array - it contains filters to apply
+ $filters = array();
+ if ( is_array($var) ) {
+
+ $name = array_shift($var);
+ $filters = isset($var['filters'])? $var['filters'] : array();
+
+ }
+ else $name = $var;
+
+ $result = null;
+
+ # Lookup basic types, null, boolean, numeric and string
+ # Variable starts with : (:users.name) to short-circuit lookup
+ if ($name[0] === ':') {
+ $object = $this->getVariable(substr($name, 1));
+ if (!is_null($object)) $result = $object;
+ } else {
+ if ($name === 'true') {
+ $result = true;
+ }
+ elseif ($name === 'false') {
+ $result = false;
+ }
+ elseif (preg_match('/^-?\d+(\.\d+)?$/', $name, $matches)) {
+ $result = isset($matches[1])? floatval($name) : intval($name);
+ }
+ elseif (preg_match('/^"([^"\\\\]*(?:\\.[^"\\\\]*)*)"|' .
+ '\'([^\'\\\\]*(?:\\.[^\'\\\\]*)*)\'$/', $name)) {
+ $result = stripcslashes(substr($name, 1, -1));
+ }
+ }
+ if (!empty(self::$lookupTable) && $result == Null) {
+ $result = $this->externalLookup($name);
+ }
+ $result = $this->applyFilters($result,$filters);
+ return $result;
+ }
+
+ function getVariable($name) {
+ # Local variables. this gives as a bit of performance improvement
+ if (!strpos($name, '.'))
+ return $this[$name];
+
+ # Prepare for Big lookup
+ $parts = explode('.', $name);
+ $object = $this[array_shift($parts)];
+
+ # Lookup context
+ foreach ($parts as $part) {
+ if (is_array($object) or $object instanceof ArrayAccess) {
+ if (isset($object[$part])) {
+ $object = $object[$part];
+ } elseif ($part === 'first') {
+ $object = isset($object[0])?$object[0]:null;
+ } elseif ($part === 'last') {
+ $last = count($object)-1;
+ $object = isset($object[$last])?$object[$last]:null;
+ } elseif ($part === 'size' or $part === 'length') {
+ return count($object);
+ } else {
+ return null;
+ }
+ }
+ elseif (is_object($object)) {
+ if (isset($object->$part))
+ $object = $object->$part;
+ elseif (is_callable(array($object, $part))) {
+ $methodAllowed = in_array(get_class($object), $this->safeClass) ||
+ (isset($object->h2o_safe) && (
+ $object->h2o_safe === true || in_array($part, $object->h2o_safe)
+ )
+ );
+ $object = $methodAllowed ? $object->$part() : null;
+ }
+ else return null;
+ }
+ else return null;
+ }
+ return $object;
+ }
+
+ function applyFilters($object, $filters) {
+
+ foreach ($filters as $filter) {
+ $name = substr(array_shift($filter), 1);
+ $args = $filter;
+
+ if (isset(h2o::$filters[$name])) {
+ foreach ($args as $i => $argument) {
+ # name args
+ if (is_array($argument)) {
+ foreach ($argument as $n => $arg) {
+ $args[$i][$n] = $this->resolve($arg);
+ }
+ } else {
+ # resolve argument values
+ $args[$i] = $this->resolve($argument);
+ }
+ }
+ array_unshift($args, $object);
+ $object = call_user_func_array(h2o::$filters[$name], $args);
+ }
+ }
+ return $object;
+ }
+
+ function escape($value, $var) {
+
+ $safe = false;
+ $filters = (is_array($var) && isset($var['filters']))? $var['filters'] : array();
+
+ foreach ( $filters as $filter ) {
+
+ $name = substr(array_shift($filter), 1);
+ $safe = !$safe && ($name === 'safe');
+
+ $escaped = $name === 'escape';
+ }
+
+ $should_escape = $this->autoescape || isset($escaped) && $escaped;
+
+ if ( ($should_escape && !$safe)) {
+ $value = htmlspecialchars($value);
+ }
+
+ return $value;
+ }
+
+ function externalLookup($name) {
+ if (!empty(self::$lookupTable)) {
+ foreach (self::$lookupTable as $lookup) {
+ $tmp = call_user_func_array($lookup, array($name, $this));
+ if ($tmp !== null)
+ return $tmp;
+ }
+ }
+ return null;
+ }
+}
+
+class BlockContext {
+ var $h2o_safe = array('name', 'depth', 'super');
+ var $block, $index;
+ private $context;
+
+ function __construct($block, $context, $index) {
+ $this->block =& $block;
+ $this->context = $context;
+ $this->index = $index;
+ }
+
+ function name() {
+ return $this->block->name;
+ }
+
+ function depth() {
+ return $this->index;
+ }
+
+ function super() {
+ $stream = new StreamWriter;
+ $this->block->parent->render($this->context, $stream, $this->index+1);
+ return $stream->close();
+ }
+
+ function __toString() {
+ return "[BlockContext : {$this->block->name}, {$this->block->filename}]";
+ }
+}
+?>
diff --git a/web/system/vendor/h2o/datatype.php b/web/system/vendor/h2o/datatype.php
new file mode 100644
index 0000000..0495f4a
--- /dev/null
+++ b/web/system/vendor/h2o/datatype.php
@@ -0,0 +1,173 @@
+close = false;
+ }
+
+ function write($data) {
+ if ($this->close)
+ new Exception('tried to write to closed stream');
+ $this->buffer[] = $data;
+ }
+
+ function close() {
+ $this->close = true;
+ return implode('', $this->buffer);
+ }
+}
+
+class Evaluator {
+ static function gt($l, $r) { return $l > $r; }
+ static function ge($l, $r) { return $l >= $r; }
+
+ static function lt($l, $r) { return $l < $r; }
+ static function le($l, $r) { return $l <= $r; }
+
+ static function eq($l, $r) { return $l == $r; }
+ static function ne($l, $r) { return $l != $r; }
+
+ static function not_($bool) { return !$bool; }
+ static function and_($l, $r) { return ($l && $r); }
+ static function or_($l, $r) { return ($l && $r); }
+
+ # Currently only support single expression with no preceddence ,no boolean expression
+ # [expression] = [optional binary] ? operant [ optional compare operant]
+ # [operant] = variable|string|numeric|boolean
+ # [compare] = > | < | == | >= | <=
+ # [binary] = not | !
+ static function exec($args, $context) {
+ $argc = count($args);
+ $first = array_shift($args);
+ $first = $context->resolve($first);
+ switch ($argc) {
+ case 1 :
+ return $first;
+ case 2 :
+ if (is_array($first) && isset($first['operator']) && $first['operator'] == 'not') {
+ $operant = array_shift($args);
+ $operant = $context->resolve($operant);
+ return !($operant);
+ }
+ case 3 :
+ list($op, $right) = $args;
+ $right = $context->resolve($right);
+ return call_user_func(array("Evaluator", $op['operator']), $first, $right);
+ default:
+ return false;
+ }
+ }
+}
+
+/**
+ * $type of token, Block | Variable
+ */
+class H2o_Token {
+ function __construct ($type, $content, $position) {
+ $this->type = $type;
+ $this->content = $content;
+ $this->result='';
+ $this->position = $position;
+ }
+
+ function write($content){
+ $this->result= $content;
+ }
+}
+
+/**
+ * a token stream
+ */
+class TokenStream {
+ var $pushed;
+ var $stream;
+ var $closed;
+ var $c;
+
+ function __construct() {
+ $this->pushed = array();
+ $this->stream = array();
+ $this->closed = false;
+ }
+
+ function pop() {
+ if (count($this->pushed))
+ return array_pop($this->pushed);
+ return array_pop($this->stream);
+ }
+
+ function feed($type, $contents, $position) {
+ if ($this->closed)
+ throw new Exception('cannot feed closed stream');
+ $this->stream[] = new H2o_Token($type, $contents, $position);
+ }
+
+ function push($token) {
+ if (is_null($token))
+ throw new Exception('cannot push NULL');
+ if ($this->closed)
+ $this->pushed[] = $token;
+ else
+ $this->stream[] = $token;
+ }
+
+ function close() {
+ if ($this->closed)
+ new Exception('cannot close already closed stream');
+ $this->closed = true;
+ $this->stream = array_reverse($this->stream);
+ }
+
+ function isClosed() {
+ return $this->closed;
+ }
+
+ function current() {
+ return $this->c ;
+ }
+
+ function next() {
+ return $this->c = $this->pop();
+ }
+}
+
+class H2o_Info {
+ var $h2o_safe = array('filters', 'extensions', 'tags');
+ var $name = 'H2o Template engine';
+ var $description = "Django inspired template system";
+ var $version = H2O_VERSION;
+
+ function filters() {
+ return array_keys(h2o::$filters);
+ }
+
+ function tags() {
+ return array_keys(h2o::$tags);
+ }
+
+ function extensions() {
+ return array_keys(h2o::$extensions);
+ }
+}
+
+/**
+ * Functions
+ */
+function sym_to_str($string) {
+ return substr($string, 1);
+}
+
+function is_sym($string) {
+ return isset($string[0]) && $string[0] === ':';
+}
+
+function symbol($string) {
+ return ':'.$string;
+}
+
+function strip_regex($regex, $delimiter = '/') {
+ return substr($regex, 1, strrpos($regex, $delimiter)-1);
+}
+?>
diff --git a/web/system/vendor/h2o/errors.php b/web/system/vendor/h2o/errors.php
new file mode 100644
index 0000000..4f214e9
--- /dev/null
+++ b/web/system/vendor/h2o/errors.php
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/web/system/vendor/h2o/filters.php b/web/system/vendor/h2o/filters.php
new file mode 100644
index 0000000..2e72e9a
--- /dev/null
+++ b/web/system/vendor/h2o/filters.php
@@ -0,0 +1,369 @@
+ $value) {
+ $result .= $name.'='.urlencode($value).'&'.$querystring;
+ }
+ $querystring = substr($result, 0, strlen($result)-1);
+ return htmlspecialchars($result);
+ } else {
+ return urlencode($data);
+ }
+ }
+
+ static function hyphenize ($string) {
+ $rules = array('/[^\w\s-]+/'=>'','/\s+/'=>'-', '/-{2,}/'=>'-');
+ $string = preg_replace(array_keys($rules), $rules, trim($string));
+ return $string = trim(strtolower($string));
+ }
+
+ static function urlize( $string, $truncate = false ) {
+ $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
+ preg_match_all($reg_exUrl, $string, $matches);
+ $usedPatterns = array();
+ foreach($matches[0] as $pattern){
+ if(!array_key_exists($pattern, $usedPatterns)){
+ $usedPatterns[$pattern]=true;
+ $string = str_replace($pattern, "
{$pattern}", $string);
+ }
+ }
+
+ $reg_exEmail = "/[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/";
+ preg_match_all($reg_exEmail, $string, $matches);
+ $usedPatterns = array();
+ foreach($matches[0] as $pattern){
+ if(!array_key_exists($pattern, $usedPatterns)){
+ $usedPatterns[$pattern]=true;
+ $string = str_replace($pattern, "
{$pattern}", $string);
+ }
+ }
+ return $string;
+ }
+
+ static function set_default($object, $default) {
+ return !$object ? $default : $object;
+ }
+}
+
+class StringFilters extends FilterCollection {
+
+ static function humanize($string) {
+ $string = preg_replace('/\s+/', ' ', trim(preg_replace('/[^A-Za-z0-9()!,?$]+/', ' ', $string)));
+ return capfirst($string);
+ }
+
+ static function capitalize($string) {
+ return ucwords(strtolower($string)) ;
+ }
+
+ static function titlize($string) {
+ return self::capitalize($string);
+ }
+
+ static function capfirst($string) {
+ $string = strtolower($string);
+ return strtoupper($string{0}). substr($string, 1, strlen($string));
+ }
+
+ static function tighten_space($value) {
+ return preg_replace("/\s{2,}/", ' ', $value);
+ }
+
+ static function escape($value, $attribute = false) {
+ return htmlspecialchars($value, $attribute ? ENT_QUOTES : ENT_NOQUOTES);
+ }
+
+ static function escapejson($value) {
+ // The standard django escapejs converts all non-ascii characters into hex codes.
+ // This function encodes the entire data structure, and strings get quotes around them.
+ return json_encode($value);
+ }
+
+ static function force_escape($value, $attribute = false) {
+ return self::escape($value, $attribute);
+ }
+
+ static function e($value, $attribute = false) {
+ return self::escape($value, $attribute);
+ }
+
+ static function safe($value) {
+ return $value;
+ }
+
+ static function truncate ($string, $max = 50, $ends = '...') {
+ return (strlen($string) > $max ? substr($string, 0, $max).$ends : $string);
+ }
+
+ static function limitwords($text, $limit = 50, $ends = '...') {
+ if (strlen($text) > $limit) {
+ $words = str_word_count($text, 2);
+ $pos = array_keys($words);
+
+ if (isset($pos[$limit])) {
+ $text = substr($text, 0, $pos[$limit]) . $ends;
+ }
+ }
+ return $text;
+ }
+}
+
+class NumberFilters extends FilterCollection {
+ static function filesize ($bytes, $round = 1) {
+ if ($bytes === 0)
+ return '0 bytes';
+ elseif ($bytes === 1)
+ return '1 byte';
+
+ $units = array(
+ 'bytes' => pow(2, 0), 'kB' => pow(2, 10),
+ 'BM' => pow(2, 20), 'GB' => pow(2, 30),
+ 'TB' => pow(2, 40), 'PB' => pow(2, 50),
+ 'EB' => pow(2, 60), 'ZB' => pow(2, 70)
+ );
+
+ $lastUnit = 'bytes';
+ foreach ($units as $unitName => $unitFactor) {
+ if ($bytes >= $unitFactor) {
+ $lastUnit = $unitName;
+ } else {
+ $number = round( $bytes / $units[$lastUnit], $round );
+ return number_format($number) . ' ' . $lastUnit;
+ }
+ }
+ }
+
+ static function currency($amount, $currency = 'USD', $precision = 2, $negateWithParentheses = false) {
+ $definition = array(
+ 'EUR' => array('�','.',','), 'GBP' => '�', 'JPY' => '�',
+ 'USD'=>'$', 'AU' => '$', 'CAN' => '$'
+ );
+ $negative = false;
+ $separator = ',';
+ $decimals = '.';
+ $currency = strtoupper($currency);
+
+ // Is negative
+ if (strpos('-', $amount) !== false) {
+ $negative = true;
+ $amount = str_replace("-","",$amount);
+ }
+ $amount = (float) $amount;
+
+ if (!$negative) {
+ $negative = $amount < 0;
+ }
+ if ($negateWithParentheses) {
+ $amount = abs($amount);
+ }
+
+ // Get rid of negative zero
+ $zero = round(0, $precision);
+ if (round($amount, $precision) === $zero) {
+ $amount = $zero;
+ }
+
+ if (isset($definition[$currency])) {
+ $symbol = $definition[$currency];
+ if (is_array($symbol))
+ @list($symbol, $separator, $decimals) = $symbol;
+ } else {
+ $symbol = $currency;
+ }
+ $amount = number_format($amount, $precision, $decimals, $separator);
+
+ return $negateWithParentheses ? "({$symbol}{$amount})" : "{$symbol}{$amount}";
+ }
+}
+
+class HtmlFilters extends FilterCollection {
+ static function base_url($url, $options = array()) {
+ return $url;
+ }
+
+ static function asset_url($url, $options = array()) {
+ return self::base_url($url, $options);
+ }
+
+ static function image_tag($url, $options = array()) {
+ $attr = self::htmlAttribute(array('alt','width','height','border'), $options);
+ return sprintf('
', $url, $attr);
+ }
+
+ static function css_tag($url, $options = array()) {
+ $attr = self::htmlAttribute(array('media'), $options);
+ return sprintf('
', $url, $attr);
+ }
+
+ static function script_tag($url, $options = array()) {
+ return sprintf('', $url);
+ }
+
+ static function links_to($text, $url, $options = array()) {
+ $attrs = self::htmlAttribute(array('ref'), $options);
+ $url = self::base_url($url, $options);
+ return sprintf('
%s', $url, $attrs, $text);
+ }
+
+ static function links_with ($url, $text, $options = array()) {
+ return self::links_to($text, $url, $options);
+ }
+
+ static function strip_tags($text) {
+ $text = preg_replace(array('/', '/>/'), array(' <', '> '),$text);
+ return strip_tags($text);
+ }
+
+ static function linebreaks($value, $format = 'p') {
+ if ($format === 'br')
+ return HtmlFilters::nl2br($value);
+ return HtmlFilters::nl2pbr($value);
+ }
+
+ static function nl2br($value) {
+ return str_replace("\n", "
\n", $value);
+ }
+
+ static function nl2pbr($value) {
+ $result = array();
+ $parts = preg_split('/(\r?\n){2,}/m', $value);
+ foreach ($parts as $part) {
+ array_push($result, '
' . HtmlFilters::nl2br($part) . '
');
+ }
+ return implode("\n", $result);
+ }
+
+ protected static function htmlAttribute($attrs = array(), $data = array()) {
+ $attrs = self::extract(array_merge(array('id', 'class', 'title', "style"), $attrs), $data);
+
+ $result = array();
+ foreach ($attrs as $name => $value) {
+ $result[] = "{$name}=\"{$value}\"";
+ }
+ return join(' ', $result);
+ }
+
+ protected static function extract($attrs = array(), $data=array()) {
+ $result = array();
+ if (empty($data)) return array();
+ foreach($data as $k => $e) {
+ if (in_array($k, $attrs)) $result[$k] = $e;
+ }
+ return $result;
+ }
+}
+
+class DatetimeFilters extends FilterCollection {
+ static function date($time, $format = 'jS F Y H:i') {
+ if ($time instanceof DateTime)
+ $time = (int) $time->format('U');
+ if (!is_numeric($time))
+ $time = strtotime($time);
+
+ return date($format, $time);
+ }
+
+ static function relative_time($timestamp, $format = 'g:iA') {
+ if ($timestamp instanceof DateTime)
+ $timestamp = (int) $timestamp->format('U');
+
+ $timestamp = is_numeric($timestamp) ? $timestamp: strtotime($timestamp);
+
+ $time = mktime(0, 0, 0);
+ $delta = time() - $timestamp;
+ $string = '';
+
+ if ($timestamp < $time - 86400) {
+ return date("F j, Y, g:i a", $timestamp);
+ }
+ if ($delta > 86400 && $timestamp < $time) {
+ return "Yesterday at " . date("g:i a", $timestamp);
+ }
+
+ if ($delta > 7200)
+ $string .= floor($delta / 3600) . " hours, ";
+ else if ($delta > 3660)
+ $string .= "1 hour, ";
+ else if ($delta >= 3600)
+ $string .= "1 hour ";
+ $delta %= 3600;
+
+ if ($delta > 60)
+ $string .= floor($delta / 60) . " minutes ";
+ else
+ $string .= $delta . " seconds ";
+ return "$string ago";
+ }
+
+ static function relative_date($time) {
+ if ($time instanceof DateTime)
+ $time = (int) $time->format('U');
+
+ $time = is_numeric($time) ? $time: strtotime($time);
+ $today = strtotime(date('M j, Y'));
+ $reldays = ($time - $today)/86400;
+
+ if ($reldays >= 0 && $reldays < 1)
+ return 'today';
+ else if ($reldays >= 1 && $reldays < 2)
+ return 'tomorrow';
+ else if ($reldays >= -1 && $reldays < 0)
+ return 'yesterday';
+
+ if (abs($reldays) < 7) {
+ if ($reldays > 0) {
+ $reldays = floor($reldays);
+ return 'in ' . $reldays . ' day' . ($reldays != 1 ? 's' : '');
+ } else {
+ $reldays = abs(floor($reldays));
+ return $reldays . ' day' . ($reldays != 1 ? 's' : '') . ' ago';
+ }
+ }
+ if (abs($reldays) < 182)
+ return date('l, F j',$time ? $time : time());
+ else
+ return date('l, F j, Y',$time ? $time : time());
+ }
+
+ static function relative_datetime($time) {
+ $date = self::relative_date($time);
+
+ if ($date === 'today')
+ return self::relative_time($time);
+
+ return $date;
+ }
+}
+
+/* Ultizie php funciton as Filters */
+h2o::addFilter(array('md5', 'sha1', 'numberformat'=>'number_format', 'wordwrap', 'trim', 'upper' => 'strtoupper', 'lower' => 'strtolower'));
+
+/* Add filter collections */
+h2o::addFilter(array('CoreFilters', 'StringFilters', 'NumberFilters', 'DatetimeFilters', 'HtmlFilters'));
+
+/* Alias default to set_default */
+h2o::addFilter('default', array('CoreFilters', 'set_default'));
+
+?>
diff --git a/web/system/vendor/h2o/loaders.php b/web/system/vendor/h2o/loaders.php
new file mode 100644
index 0000000..91a392f
--- /dev/null
+++ b/web/system/vendor/h2o/loaders.php
@@ -0,0 +1,290 @@
+searchpath = (array) $searchpath;
+ $this->setOptions($options);
+ }
+
+ function setOptions($options = array()) {
+ if (isset($options['cache']) && $options['cache']) {
+ $this->cache = h2o_cache($options);
+ }
+ }
+
+ function read($filename) {
+
+ if (!is_file($filename))
+ $filename = $this->get_template_path($this->searchpath,$filename);
+
+ if (is_file($filename)) {
+ $source = file_get_contents($filename);
+ return $this->runtime->parse($source);
+ } else {
+ throw new TemplateNotFound($filename);
+ }
+ }
+
+ function get_template_path($search_path, $filename){
+
+
+ for ($i=0 ; $i < count($search_path) ; $i++)
+ {
+
+ if(file_exists($search_path[$i] . $filename)) {
+ $filename = $search_path[$i] . $filename;
+ return $filename;
+ break;
+ } else {
+ continue;
+ }
+
+ }
+
+ throw new Exception('TemplateNotFound - Looked for template: ' . $filename);
+
+
+
+ }
+
+ function read_cache($filename) {
+ if (!$this->cache){
+ $filename = $this->get_template_path($this->searchpath,$filename);
+ return $this->read($filename);
+ }
+
+ if (!is_file($filename)){
+ $filename = $this->get_template_path($this->searchpath,$filename);
+ }
+
+ $filename = realpath($filename);
+
+ $cache = md5($filename);
+ $object = $this->cache->read($cache);
+ $this->cached = $object && !$this->expired($object);
+
+ if (!$this->cached) {
+ $nodelist = $this->read($filename);
+ $object = (object) array(
+ 'filename' => $filename,
+ 'content' => serialize($nodelist),
+ 'created' => time(),
+ 'templates' => $nodelist->parser->storage['templates'],
+ 'included' => $nodelist->parser->storage['included'] + array_values(h2o::$extensions)
+ );
+ $this->cache->write($cache, $object);
+ } else {
+ foreach($object->included as $ext => $file) {
+ include_once (h2o::$extensions[$ext] = $file);
+ }
+ }
+ return unserialize($object->content);
+ }
+
+ function flush_cache() {
+ $this->cache->flush();
+ }
+
+ function expired($object) {
+ if (!$object) return false;
+
+ $files = array_merge(array($object->filename), $object->templates);
+ foreach ($files as $file) {
+ if (!is_file($file))
+ $file = $this->get_template_path($this->searchpath, $file);
+
+ if ($object->created < filemtime($file))
+ return true;
+ }
+ return false;
+ }
+}
+
+function file_loader($file) {
+ return new H2o_File_Loader($file);
+}
+
+class H2o_Hash_Loader {
+
+ function __construct($scope, $options = array()) {
+ $this->scope = $scope;
+ }
+
+ function setOptions() {}
+
+ function read($file) {
+ if (!isset($this->scope[$file]))
+ throw new TemplateNotFound;
+ return $this->runtime->parse($this->scope[$file], $file);
+ }
+
+ function read_cache($file) {
+ return $this->read($file);
+ }
+}
+
+function hash_loader($hash = array()) {
+ return new H2o_Hash_Loader($hash);
+}
+
+/**
+ * Cache subsystem
+ *
+ */
+function h2o_cache($options = array()) {
+ $type = $options['cache'];
+ $className = "H2o_".ucwords($type)."_Cache";
+
+ if (class_exists($className, false)) {
+ return new $className($options);
+ }
+ return false;
+}
+
+class H2o_File_Cache {
+ var $ttl = 3600;
+ var $prefix = 'h2o_';
+
+ function __construct($options = array()) {
+ if (isset($options['cache_dir']) && is_writable($options['cache_dir'])) {
+ $path = $options['cache_dir'];
+ } else {
+ $path = dirname($tmp = tempnam(uniqid(rand(), true), ''));
+
+ if (file_exists($tmp)) unlink($tmp);
+ }
+ if (isset($options['cache_ttl'])) {
+ $this->ttl = $options['cache_ttl'];
+ }
+ if(isset($options['cache_prefix'])) {
+ $this->prefix = $options['cache_prefix'];
+ }
+
+ $this->path = realpath($path). DS;
+ }
+
+ function read($filename) {
+ if (!file_exists($this->path . $this->prefix. $filename))
+ return false;
+
+ $content = file_get_contents($this->path . $this->prefix. $filename);
+ $expires = (int)substr($content, 0, 10);
+
+ if (time() >= $expires)
+ return false;
+ return unserialize(trim(substr($content, 10)));
+ }
+
+ function write($filename, &$object) {
+ $expires = time() + $this->ttl;
+ $content = $expires . serialize($object);
+ return file_put_contents($this->path . $this->prefix. $filename, $content);
+ }
+
+ function flush() {
+ foreach (glob($this->path. $this->prefix. '*') as $file) {
+ @unlink($file);
+ }
+ }
+}
+
+class H2o_Apc_Cache {
+ var $ttl = 3600;
+ var $prefix = 'h2o_';
+
+ function __construct($options = array()) {
+ if (!function_exists('apc_add'))
+ throw new Exception('APC extension needs to be loaded to use APC cache');
+
+ if (isset($options['cache_ttl'])) {
+ $this->ttl = $options['cache_ttl'];
+ }
+ if(isset($options['cache_prefix'])) {
+ $this->prefix = $options['cache_prefix'];
+ }
+ }
+
+ function read($filename) {
+ return apc_fetch($this->prefix.$filename);
+ }
+
+ function write($filename, $object) {
+ return apc_store($this->prefix.$filename, $object, $this->ttl);
+ }
+
+ function flush() {
+ return apc_clear_cache('user');
+ }
+}
+
+
+class H2o_Memcache_Cache {
+ var $ttl = 3600;
+ var $prefix = 'h2o_';
+ /**
+ * @var host default is file socket
+ */
+ var $host = 'unix:///tmp/memcached.sock';
+ var $port = 0;
+ var $object;
+ function __construct( $scope, $options = array() ) {
+ if ( !function_exists( 'memcache_set' ) )
+ throw new Exception( 'Memcache extension needs to be loaded to use memcache' );
+
+ if ( isset( $options['cache_ttl'] ) ) {
+ $this->ttl = $options['cache_ttl'];
+ }
+ if( isset( $options['cache_prefix'] ) ) {
+ $this->prefix = $options['cache_prefix'];
+ }
+
+ if( isset( $options['host'] ) ) {
+ $this->host = $options['host'];
+ }
+
+ if( isset( $options['port'] ) ) {
+ $this->port = $options['port'];
+ }
+
+ $this->object = memcache_connect( $this->host, $this->port );
+ }
+
+ function read( $filename ){
+ return memcache_get( $this->object, $this->prefix.$filename );
+ }
+
+ function write( $filename, $content ) {
+ return memcache_set( $this->object,$this->prefix.$filename,$content , MEMCACHE_COMPRESSED,$this->ttl );
+ }
+
+ function flush(){
+ return memcache_flush( $this->object );
+ }
+}
\ No newline at end of file
diff --git a/web/system/vendor/h2o/nodes.php b/web/system/vendor/h2o/nodes.php
new file mode 100644
index 0000000..11dad3f
--- /dev/null
+++ b/web/system/vendor/h2o/nodes.php
@@ -0,0 +1,84 @@
+parser = $parser;
+ if (is_null($initial))
+ $initial = array();
+ $this->list = $initial;
+ $this->position = $position;
+ }
+
+ function render($context, $stream) {
+ foreach($this->list as $node) {
+ $node->render($context, $stream);
+ }
+ }
+
+ function append($node) {
+ array_push($this->list, $node);
+ }
+
+ function extend($nodes) {
+ array_merge($this->list, $nodes);
+ }
+
+ function getLength() {
+ return count($this->list);
+ }
+
+ function getIterator() {
+ return new ArrayIterator( $this->list );
+ }
+}
+
+class VariableNode extends H2o_Node {
+ private $filters = array();
+ var $variable;
+
+ function __construct($variable, $filters, $position = 0) {
+ if (!empty($filters))
+ $this->filters = $filters;
+ $this->variable = $variable;
+ }
+
+ function render($context, $stream) {
+ $value = $context->resolve($this->variable);
+ $value = $context->escape($value, $this->variable);
+ $stream->write($value);
+ }
+}
+
+class CommentNode extends H2o_Node {}
+
+class TextNode extends H2o_Node {
+ var $content;
+ function __construct($content, $position = 0) {
+ $this->content = $content;
+ $this->position = $position;
+ }
+
+ function render($context, $stream) {
+ $stream->write($this->content);
+ }
+
+ function is_blank() {
+ return strlen(trim($this->content));
+ }
+}
+
+
+?>
\ No newline at end of file
diff --git a/web/system/vendor/h2o/parser.php b/web/system/vendor/h2o/parser.php
new file mode 100644
index 0000000..a805243
--- /dev/null
+++ b/web/system/vendor/h2o/parser.php
@@ -0,0 +1,290 @@
+options = $options;
+
+ $trim = '';
+ if ($this->options['TRIM_TAGS'])
+ $trim = '(?:\r?\n)?';
+
+ $this->pattern = ('/\G(.*?)(?:' .
+ preg_quote($this->options['BLOCK_START']). '(.*?)' .preg_quote($this->options['BLOCK_END']) . $trim . '|' .
+ preg_quote($this->options['VARIABLE_START']). '(.*?)' .preg_quote($this->options['VARIABLE_END']) . '|' .
+ preg_quote($this->options['COMMENT_START']). '(.*?)' .preg_quote($this->options['COMMENT_END']) . $trim . ')/sm'
+ );
+ }
+
+ function tokenize($source) {
+ $result = new TokenStream;
+ $pos = 0;
+ $matches = array();
+ preg_match_all($this->pattern, $source, $matches, PREG_SET_ORDER);
+
+ foreach ($matches as $match) {
+ if ($match[1])
+ $result->feed('text', $match[1], $pos);
+ $tagpos = $pos + strlen($match[1]);
+ if ($match[2])
+ $result->feed('block', trim($match[2]), $tagpos);
+ elseif ($match[3])
+ $result->feed('variable', trim($match[3]), $tagpos);
+ elseif ($match[4])
+ $result->feed('comment', trim($match[4]), $tagpos);
+ $pos += strlen($match[0]);
+ }
+ if ($pos < strlen($source)){
+ $result->feed('text', substr($source, $pos), $pos);
+ }
+ $result->close();
+ return $result;
+ }
+}
+
+class H2o_Parser {
+ var $first;
+ var $storage = array();
+ var $filename;
+ var $runtime;
+
+ function __construct($source, $filename, $runtime, $options) {
+ $this->options = $options;
+ //$this->source = $source;
+ $this->runtime = $runtime;
+ $this->filename = $filename;
+ $this->first = true;
+
+ $this->lexer = new H2o_Lexer($options);
+ $this->tokenstream = $this->lexer->tokenize($source);
+ $this->storage = array(
+ 'blocks' => array(),
+ 'templates' => array(),
+ 'included' => array()
+ );
+ }
+
+ function &parse() {
+ $until = func_get_args();
+ $nodelist = new NodeList($this);
+ while($token = $this->tokenstream->next()) {
+ //$token = $this->tokenstream->current();
+ switch($token->type) {
+ case 'text' :
+ $node = new TextNode($token->content, $token->position);
+ break;
+ case 'variable' :
+ $args = H2o_Parser::parseArguments($token->content, $token->position);
+ $variable = array_shift($args);
+ $filters = $args;
+ $node = new VariableNode($variable, $filters, $token->position);
+ break;
+ case 'comment' :
+ $node = new CommentNode($token->content);
+ break;
+ case 'block' :
+ if (in_array($token->content, $until)) {
+ $this->token = $token;
+ return $nodelist;
+ }
+ $temp = preg_split('/\s+/',$token->content, 2);
+ $name = $temp[0];
+ $args = (count($temp) > 1 ? $temp[1] : null);
+ $node = H2o::createTag($name, $args, $this, $token->position);
+ $this->token = $token;
+ }
+ $this->searching = join(',',$until);
+ $this->first = false;
+ $nodelist->append($node);
+ }
+
+ if ($until) {
+ throw new TemplateSyntaxError('Unclose tag, expecting '. $until[0]);
+ }
+ return $nodelist;
+ }
+
+ function skipTo($until) {
+ $this->parse($until);
+ return null;
+ }
+
+ # Parse arguments
+ static function parseArguments($source = null, $fpos = 0){
+ $parser = new ArgumentLexer($source, $fpos);
+ $result = array();
+ $current_buffer = &$result;
+ $filter_buffer = array();
+ $tokens = $parser->parse();
+ foreach ($tokens as $token) {
+ list($token, $data) = $token;
+ if ($token == 'filter_start') {
+ $filter_buffer = array();
+ $current_buffer = &$filter_buffer;
+ }
+ elseif ($token == 'filter_end') {
+ if (count($filter_buffer)) {
+
+ $i = count($result)-1;
+ if ( is_array($result[$i]) ) $result[$i]['filters'][] = $filter_buffer;
+ else $result[$i] = array(0 => $result[$i], 'filters' => array($filter_buffer));
+ }
+ $current_buffer = &$result;
+ }
+ elseif ($token == 'boolean') {
+ $current_buffer[] = ($data === 'true'? true : false);
+ }
+ elseif ($token == 'name') {
+ $current_buffer[] = symbol($data);
+ }
+ elseif ($token == 'number' || $token == 'string') {
+ $current_buffer[] = $data;
+ }
+ elseif ($token == 'named_argument') {
+ $last = $current_buffer[count($current_buffer) - 1];
+ if (!is_array($last))
+ $current_buffer[] = array();
+
+ $namedArgs =& $current_buffer[count($current_buffer) - 1];
+ list($name,$value) = array_map('trim', explode(':', $data, 2));
+
+ # if argument value is variable mark it
+ $value = self::parseArguments($value);
+ $namedArgs[$name] = $value[0];
+ }
+ elseif( $token == 'operator') {
+ $current_buffer[] = array('operator'=>$data);
+ }
+ }
+ return $result;
+ }
+}
+
+class H2O_RE {
+ static $whitespace, $seperator, $parentheses, $pipe, $filter_end, $operator, $boolean, $number, $string, $i18n_string, $name, $named_args;
+
+ static function init() {
+ $r = 'strip_regex';
+
+ self::$whitespace = '/\s+/m';
+ self::$parentheses = '/\(|\)/m';
+ self::$filter_end = '/;/';
+ self::$boolean = '/true|false/';
+ self::$seperator = '/,/';
+ self::$pipe = '/\|/';
+ self::$operator = '/\s?(>|<|>=|<=|!=|==|!|and |not |or )\s?/i';
+ self::$number = '/\d+(\.\d*)?/';
+ self::$name = '/[a-zA-Z][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*/';
+
+ self::$string = '/(?:
+ "([^"\\\\]*(?:\\\\.[^"\\\\]*)*)" | # Double Quote string
+ \'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\' # Single Quote String
+ )/xsm';
+ self::$i18n_string = "/_\({$r(self::$string)}\) | {$r(self::$string)}/xsm";
+
+ self::$named_args = "{
+ ({$r(self::$name)})(?:{$r(self::$whitespace)})?
+ :
+ (?:{$r(self::$whitespace)})?({$r(self::$i18n_string)}|{$r(self::$number)}|{$r(self::$name)})
+ }x";
+ }
+}
+H2O_RE::init();
+
+class ArgumentLexer {
+ private $source;
+ private $match;
+ private $pos = 0, $fpos, $eos;
+ private $operator_map = array(
+ '!' => 'not', '!='=> 'ne', '==' => 'eq', '>' => 'gt', '<' => 'lt', '<=' => 'le', '>=' => 'ge'
+ );
+
+ function __construct($source, $fpos = 0){
+ if (!is_null($source))
+ $this->source = $source;
+ $this->fpos=$fpos;
+ }
+
+ function parse(){
+ $result = array();
+ $filtering = false;
+ while (!$this->eos()) {
+ $this->scan(H2O_RE::$whitespace);
+ if (!$filtering) {
+ if ($this->scan(H2O_RE::$operator)){
+ $operator = trim($this->match);
+ if(isset($this->operator_map[$operator]))
+ $operator = $this->operator_map[$operator];
+ $result[] = array('operator', $operator);
+ }
+ elseif ($this->scan(H2O_RE::$boolean))
+ $result[] = array('boolean', $this->match);
+ elseif ($this->scan(H2O_RE::$named_args))
+ $result[] = array('named_argument', $this->match);
+ elseif ($this->scan(H2O_RE::$name))
+ $result[] = array('name', $this->match);
+ elseif ($this->scan(H2O_RE::$pipe)) {
+ $filtering = true;
+ $result[] = array('filter_start', $this->match);
+ }
+ elseif ($this->scan(H2O_RE::$seperator))
+ $result[] = array('separator', null);
+ elseif ($this->scan(H2O_RE::$i18n_string))
+ $result[] = array('string', $this->match);
+ elseif ($this->scan(H2O_RE::$number))
+ $result[] = array('number', $this->match);
+ else
+ throw new TemplateSyntaxError('unexpected character in filters : "'. $this->source[$this->pos]. '" at '.$this->getPosition());
+ }
+ else {
+ // parse filters, with chaining and ";" as filter end character
+ if ($this->scan(H2O_RE::$pipe)) {
+ $result[] = array('filter_end', null);
+ $result[] = array('filter_start', null);
+ }
+ elseif ($this->scan(H2O_RE::$seperator))
+ $result[] = array('separator', null);
+ elseif ($this->scan(H2O_RE::$filter_end)) {
+ $result[] = array('filter_end', null);
+ $filtering = false;
+ }
+ elseif ($this->scan(H2O_RE::$boolean))
+ $result[] = array('boolean', $this->match);
+ elseif ($this->scan(H2O_RE::$named_args))
+ $result[] = array('named_argument', $this->match);
+ elseif ($this->scan(H2O_RE::$name))
+ $result[] = array('name', $this->match);
+ elseif ($this->scan(H2O_RE::$i18n_string))
+ $result[] = array('string', $this->match);
+ elseif ($this->scan(H2O_RE::$number))
+ $result[] = array('number', $this->match);
+ else
+ throw new TemplateSyntaxError('unexpected character in filters : "'. $this->source[$this->pos]. '" at '.$this->getPosition());
+ }
+ }
+ // if we are still in the filter state, we add a filter_end token.
+ if ($filtering)
+ $result[] = array('filter_end', null);
+ return $result;
+ }
+
+ # String scanner
+ function scan($regexp) {
+ if (preg_match($regexp . 'A', $this->source, $match, null, $this->pos)) {
+ $this->match = $match[0];
+ $this->pos += strlen($this->match);
+ return true;
+ }
+ return false;
+ }
+
+ function eos() {
+ return $this->pos >= strlen($this->source);
+ }
+
+ /**
+ * return the position in the template
+ */
+ function getPosition() {
+ return $this->fpos + $this->pos;
+ }
+}
+?>
diff --git a/web/system/vendor/h2o/tags.php b/web/system/vendor/h2o/tags.php
new file mode 100644
index 0000000..ea2fdbf
--- /dev/null
+++ b/web/system/vendor/h2o/tags.php
@@ -0,0 +1,483 @@
+nodelist_true = $parser->parse('endifchanged', 'else');
+
+ if ($parser->token->content === 'else')
+ $this->nodelist_false = $parser->parse('endifchanged');
+
+ $this->_varlist = current(H2o_Parser::parseArguments($argstring));
+
+ if (!$this->_varlist)
+ throw new TemplateSyntaxError('H2o doesn\'t support lazy ifchanged yet. Please, supply a variable.');
+
+ }
+
+ function render($context, $stream) {
+
+ if ($this->_varlist) {
+ $compare_to = $context->resolve($this->_varlist);
+ } else {
+ /**
+ * @todo Rendering method $this->nodelist_true->render() should return a result.
+ * Further more $compare_to variable should be set to this result.
+ */
+ $compare_to = '';
+ }
+
+ if ($compare_to != $this->_last_seen) {
+ $this->_last_seen = $compare_to;
+ $this->nodelist_true->render($context, $stream);
+ } elseif ($this->nodelist_false) {
+ $this->nodelist_false->render($context, $stream);
+ }
+
+ }
+}
+
+class If_Tag extends H2o_Node {
+ private $body;
+ private $else;
+ private $negate;
+
+ function __construct($argstring, $parser, $position = 0) {
+ if (preg_match('/\s(and|or)\s/', $argstring))
+ throw new TemplateSyntaxError('H2o doesn\'t support multiple expressions');
+
+ $this->body = $parser->parse('endif', 'else');
+
+ if ($parser->token->content === 'else')
+ $this->else = $parser->parse('endif');
+
+ $this->args = H2o_Parser::parseArguments($argstring);
+
+ $first = current($this->args);
+ if (isset($first['operator']) && $first['operator'] === 'not') {
+ array_shift($this->args);
+ $this->negate = true;
+ }
+ }
+
+ function render($context, $stream) {
+ if ($this->test($context))
+ $this->body->render($context, $stream);
+ elseif ($this->else)
+ $this->else->render($context, $stream);
+ }
+
+ function test($context) {
+ $test = Evaluator::exec($this->args, $context);
+ return $this->negate? !$test : $test;
+ }
+}
+
+class For_Tag extends H2o_Node {
+ public $position;
+ private $iteratable, $key, $item, $body, $else, $limit, $reversed;
+ private $syntax = '{
+ ([a-zA-Z][a-zA-Z0-9-_]*)(?:,\s?([a-zA-Z][a-zA-Z0-9-_]*))?
+ \s+in\s+
+ ([a-zA-Z][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*)\s* # Iteratable name
+ (?:limit\s*:\s*(\d+))?\s*
+ (reversed)? # Reverse keyword
+ }x';
+
+ function __construct($argstring, $parser, $position) {
+ if (!preg_match($this->syntax, $argstring, $match))
+ throw new TemplateSyntaxError("Invalid for loop syntax ");
+
+ $this->body = $parser->parse('endfor', 'else');
+
+ if ($parser->token->content === 'else')
+ $this->else = $parser->parse('endfor');
+
+ $match = array_pad($match, 6, '');
+ list(,$this->key, $this->item, $this->iteratable, $this->limit, $this->reversed) = $match;
+
+ if ($this->limit)
+ $this->limit = (int) $this->limit;
+
+ # Swap value if no key found
+ if (!$this->item) {
+ list($this->key, $this->item) = array($this->item, $this->key);
+ }
+ $this->iteratable = symbol($this->iteratable);
+ $this->reversed = (bool) $this->reversed;
+ }
+
+ function render($context, $stream) {
+ $iteratable = $context->resolve($this->iteratable);
+
+ if ($this->reversed)
+ $iteratable = array_reverse($iteratable);
+
+ if ($this->limit)
+ $iteratable = array_slice($iteratable, 0, $this->limit);
+
+ $length = count($iteratable);
+
+ if ($length) {
+ $parent = $context['loop'];
+ $context->push();
+ $rev_count = $is_even = $idx = 0;
+ foreach($iteratable as $key => $value) {
+ $is_even = $idx % 2;
+ $rev_count = $length - $idx;
+
+ if ($this->key) {
+ $context[$this->key] = $key;
+ }
+ $context[$this->item] = $value;
+ $context['loop'] = array(
+ 'parent' => $parent,
+ 'first' => $idx === 0,
+ 'last' => $rev_count === 1,
+ 'odd' => !$is_even,
+ 'even' => $is_even,
+ 'length' => $length,
+ 'counter' => $idx + 1,
+ 'counter0' => $idx,
+ 'revcounter' => $rev_count,
+ 'revcounter0' => $rev_count - 1
+ );
+ $this->body->render($context, $stream);
+ ++$idx;
+ }
+ $context->pop();
+ } elseif ($this->else)
+ $this->else->render($context, $stream);
+ }
+}
+
+class Block_Tag extends H2o_Node {
+ public $name;
+ public $position;
+ public $stack;
+ private $syntax = '/^[a-zA-Z_][a-zA-Z0-9_-]*$/';
+
+ function __construct($argstring, $parser, $position) {
+ if (!preg_match($this->syntax, $argstring))
+ throw new TemplateSyntaxError('Block tag expects a name, example: block [content]');
+
+ $this->name = $argstring;
+
+ if (isset($parser->storage['blocks'][$this->name]))
+ throw new TemplateSyntaxError('Block name exists, Please select a different block name');
+
+ $this->filename = $parser->filename;
+ $this->stack = array($parser->parse('endblock', "endblock {$this->name}"));
+
+ $parser->storage['blocks'][$this->name] = $this;
+ $this->position = $position;
+ }
+
+ function addLayer(&$nodelist) {
+ $nodelist->parent = $this;
+ array_push($this->stack, $nodelist);
+ }
+
+ function render($context, $stream, $index = 1) {
+ $key = count($this->stack) - $index;
+
+ if (isset($this->stack[$key])) {
+ $context->push();
+ $context['block'] = new BlockContext($this, $context, $index);
+ $this->stack[$key]->render($context, $stream);
+ $context->pop();
+ }
+ }
+}
+
+class Extends_Tag extends H2o_Node {
+ public $filename;
+ public $position;
+ public $nodelist;
+ private $syntax = '/^["\'](.*?)["\']$/';
+
+ function __construct($argstring, $parser, $position = 0) {
+ if (!$parser->first)
+ throw new TemplateSyntaxError('extends must be first in file');
+
+ if (!preg_match($this->syntax, $argstring))
+ throw new TemplatesyntaxError('filename must be quoted');
+
+ $this->filename = stripcslashes(substr($argstring, 1, -1));
+
+ # Parse the current template
+ $parser->parse();
+
+ # Parse parent template
+ $this->nodelist = $parser->runtime->loadSubTemplate($this->filename, $parser->options);
+ $parser->storage['templates'] = array_merge(
+ $parser->storage['templates'], $this->nodelist->parser->storage['templates']
+ );
+ $parser->storage['templates'][] = $this->filename;
+
+ if (!isset($this->nodelist->parser->storage['blocks']) || !isset($parser->storage['blocks']))
+ return ;
+
+ # Blocks of parent template
+ $blocks =& $this->nodelist->parser->storage['blocks'];
+
+ # Push child blocks on top of parent blocks
+ foreach($parser->storage['blocks'] as $name => &$block) {
+ if (isset($blocks[$name])) {
+ $blocks[$name]->addLayer($block);
+ }
+ }
+ }
+
+ function render($context, $stream) {
+ $this->nodelist->render($context, $stream);
+ }
+}
+
+/**
+ * include tag
+ *
+ * Usage:
+ *
+ * Simple inclusion
+ * {% include "./subtemplate.html" %}
+ *
+ *
+ * Inclusion with additional context variables passing:
+ * {% include "./subtemplate.html" with foo=bar spam="eggs" %}
+ *
+ * Note: Double quotes matter. In this example 'foo' template variable of subtemplate.html
+ * would be initialized with 'bar' variable contents (from main template context),
+ * while 'spam' template variable of subtemplate.html would be set to simple string ('eggs').
+ *
+ */
+class Include_Tag extends H2o_Node {
+ private $nodelist;
+ private $syntax = '/^["\'](.*?)["\'](\s+with\s+(.+))?$/';
+ private $_additional_context = array();
+
+ function __construct($argstring, $parser, $position = 0) {
+ if (!preg_match($this->syntax, $argstring, $matches)) {
+ throw new TemplateSyntaxError();
+ }
+
+ $matches_count = count($matches);
+
+ if ($matches_count > 2) {
+ // "with" statement supplied.
+ $with_vars = explode(' ', $matches[3]);
+ foreach ($with_vars as $var_str) {
+ $eq_pos = strpos($var_str, '=');
+ $this->_additional_context[substr($var_str, 0, $eq_pos)] = substr($var_str, $eq_pos+1);
+ }
+ }
+
+ $this->filename = stripcslashes($matches[1]);
+ $this->nodelist = $parser->runtime->loadSubTemplate($this->filename, $parser->options);
+ $parser->storage['templates'] = array_merge(
+ $this->nodelist->parser->storage['templates'], $parser->storage['templates']
+ );
+ $parser->storage['templates'][] = $this->filename;
+ }
+
+ function render($context, $stream) {
+ foreach ($this->_additional_context as $key => $value) {
+ if (strpos($value, '"') === false) {
+ // Context variable supplied as value. Needs to be resolved.
+ $value = $context->getVariable($value);
+ } else {
+ $value = trim($value, '"');
+ }
+ $context[$key] = $value;
+ }
+
+ $this->nodelist->render($context, $stream);
+ }
+}
+
+class With_Tag extends H2o_Node {
+ public $position;
+ private $variable, $shortcut;
+ private $nodelist;
+ private $syntax = '/^([\w]+(:?\.[\w\d]+)*)\s+as\s+([\w]+(:?\.[\w\d]+)?)$/';
+
+ function __construct($argstring, $parser, $position = 0) {
+ if (!preg_match($this->syntax, $argstring, $matches))
+ throw new TemplateSyntaxError('Invalid with tag syntax');
+
+ # extract the long name and shortcut
+ list(,$this->variable, ,$this->shortcut) = $matches;
+ $this->nodelist = $parser->parse('endwith');
+ }
+
+ function render($context, $stream) {
+ $variable = $context->getVariable($this->variable);
+
+ $context->push(array($this->shortcut => $variable));
+ $this->nodelist->render($context, $stream);
+ $context->pop();
+ }
+}
+
+class Cycle_Tag extends H2o_Node {
+ private $uid;
+ private $sequence;
+
+ function __construct($argstring, $parser, $pos) {
+ $args = h2o_parser::parseArguments($argstring);
+
+ if (count($args) < 2) {
+ throw new Exception('Cycle tag require more than two items');
+ }
+ $this->sequence = $args;
+ $this->uid = '__cycle__'.$pos;
+ }
+
+ function render($context, $stream) {
+ if (!is_null($item = $context->getVariable($this->uid))) {
+ $item = ($item + 1) % count($this->sequence);
+ } else {
+ $item = 0;
+ }
+ $stream->write($context->resolve($this->sequence[$item]));
+ $context->set($this->uid, $item);
+ }
+}
+
+class Load_Tag extends H2o_Node {
+ public $position;
+ private $searchpath = array(H2O_ROOT);
+ private $extension;
+
+ function __construct($argstring, $parser, $pos = 0) {
+ $this->extension = stripcslashes(preg_replace("/^[\"'](.*)[\"']$/", "$1", $argstring));
+
+ if ($parser->runtime->searchpath)
+ $this->appendPath($parser->runtime->searchpath);
+
+ $parser->storage['included'][$this->extension] = $file = $this->load();
+ $this->position = $pos;
+ }
+
+ function render($context, $stream) {
+ $this->load();
+ }
+
+ function appendPath($path) {
+ $this->searchpath[] = $path;
+ }
+
+ private function load() {
+ if (isset(h2o::$extensions[$this->extension])) {
+ return true;
+ }
+ foreach($this->searchpath as $path) {
+ $file = $path.'ext'.DS.$this->extension.'.php';
+ if (is_file($file)) {
+ h2o::load($this->extension, $file);
+ return $file;
+ }
+ }
+ throw new H2o_Error(
+ "Extension: {$this->extension} cannot be loaded, please confirm it exist in extension path"
+ );
+ }
+}
+
+class Debug_Tag extends H2o_Node {
+ private $argument;
+ function __construct($argstring, $parser, $pos = 0) {
+ $this->argument = $argstring;
+ }
+
+ function render($context, $stream) {
+ if ($this->argument) {
+ $object = $context->resolve(symbol($this->argument));
+ } else {
+ $object = $context->scopes[0];
+ }
+ $output = "
" . htmlspecialchars( print_r($object, true) ) . "
";
+ $stream->write($output);
+ }
+}
+
+class Comment_Tag extends H2o_Node {
+ function __construct($argstring, $parser, $position) {
+ $parser->parse('endcomment');
+ }
+
+ function render($context, $stream, $index = 1) {
+ }
+}
+
+class Now_Tag extends H2o_Node {
+ function __construct($argstring, $parser, $pos=0) {
+ $this->format = $argstring;
+ if (!$this->format) {
+ $this->format = "D M j G:i:s T Y";
+ }
+ }
+
+ function render($contxt, $stream) {
+ $time = date($this->format);
+ $stream->write($time);
+ }
+}
+
+class Autoescape_Tag extends H2o_Node {
+ protected $enable;
+
+ function __construct($argstring, $parser, $pos = 0) {
+ if ($argstring === 'on')
+ $this->enable = true;
+ elseif ($argstring === 'off')
+ $this->enable = false;
+ else throw new H2o_Error(
+ "Invalid syntax : autoescape on|off "
+ );
+ }
+
+ function render($context, $stream) {
+ $context->autoescape = $this->enable;
+ }
+}
+
+class Csrf_token_Tag extends H2o_Node {
+ function render($context, $stream) {
+ $token = "";
+ if (isset($_COOKIE["csrftoken"]))
+ $token = $_COOKIE["csrftoken"];
+ else {
+ global $SECRET_KEY;
+ if (defined('SECRET_KEY'))
+ $token = md5(mt_rand() . SECRET_KEY);
+ else
+ $token = md5(mt_rand());
+ }
+ setcookie("csrftoken", $token, time()+60*60*24*365, "/");
+ $stream->write("
");
+ }
+}
+
+H2o::addTag(array('block', 'extends', 'include', 'if', 'ifchanged', 'for', 'with', 'cycle', 'load', 'debug', 'comment', 'now', 'autoescape', 'csrf_token'));
diff --git a/web/system/vendor/isvarset.php b/web/system/vendor/isvarset.php
new file mode 100644
index 0000000..ab68f38
--- /dev/null
+++ b/web/system/vendor/isvarset.php
@@ -0,0 +1,6 @@
+