",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e){function t(e){return parseInt(e,10)||0}function i(e){return!isNaN(parseInt(e,10))}e.widget("ui.resizable",e.ui.mouse,{version:"1.10.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("
"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=e(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=t(this.helper.css("left")),n=t(this.helper.css("top")),o.containment&&(s+=e(o.containment).scrollLeft()||0,n+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(t){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,u=this.size.height,c=t.pageX-a.left||0,d=t.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[t,c,d]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==u&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(n)||this._trigger("resize",t,this.ui()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&e.ui.hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||e)&&(t=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(e){this.offset=this.helper.offset(),i(e.left)&&(this.position.left=e.left),i(e.top)&&(this.position.top=e.top),i(e.height)&&(this.size.height=e.height),i(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,s=this.size,n=this.axis;return i(e.height)?e.width=e.height*this.aspectRatio:i(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===n&&(e.left=t.left+(s.width-e.width),e.top=null),"nw"===n&&(e.top=t.top+(s.height-e.height),e.left=t.left+(s.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,s=this.axis,n=i(e.width)&&t.maxWidth&&t.maxWidth
e.width,r=i(e.height)&&t.minHeight&&t.minHeight>e.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,u=/sw|nw|w/.test(s),c=/nw|ne|n/.test(s);return o&&(e.width=t.minWidth),r&&(e.height=t.minHeight),n&&(e.width=t.maxWidth),a&&(e.height=t.maxHeight),o&&u&&(e.left=h-t.minWidth),n&&u&&(e.left=h-t.maxWidth),r&&c&&(e.top=l-t.minHeight),a&&c&&(e.top=l-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var e,t,i,s,n,a=this.helper||this.element;for(e=0;this._proportionallyResizeElements.length>e;e++){if(n=this._proportionallyResizeElements[e],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],t=0;i.length>t;t++)this.borderDif[t]=(parseInt(i[t],10)||0)+(parseInt(s[t],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e(""),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&e.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=e(this).data("ui-resizable"),u=l.options,c=l.element,d=u.containment,p=d instanceof e?d.get(0):/parent/.test(d)?c.parent().get(0):d;p&&(l.containerElement=e(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(i=e(p),s=[],e(["Top","Right","Left","Bottom"]).each(function(e,n){s[e]=t(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=e.ui.hasScroll(p,"left")?p.scrollWidth:o,h=e.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(t){var i,s,n,a,o=e(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,c={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(c=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-c.left),u&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=o.parentData.left),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(t,s){e(t).each(function(){var t=e(this),n=e(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var i=(n[t]||0)+(r[t]||0);i&&i>=0&&(a[t]=i||null)}),t.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):e.each(n.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size,n=t.originalSize,a=t.originalPosition,o=t.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,u=Math.round((s.width-n.width)/h)*h,c=Math.round((s.height-n.height)/l)*l,d=n.width+u,p=n.height+c,f=i.maxWidth&&d>i.maxWidth,m=i.maxHeight&&p>i.maxHeight,g=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,g&&(d+=h),v&&(p+=l),f&&(d-=h),m&&(p-=l),/^(se|s|e)$/.test(o)?(t.size.width=d,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.top=a.top-c):/^(sw)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.left=a.left-u):(t.size.width=d,t.size.height=p,t.position.top=a.top-c,t.position.left=a.left-u)}})})(jQuery);
\ No newline at end of file
diff --git a/cmd/present/local.go b/cmd/present/local.go
new file mode 100644
index 00000000..fdc265da
--- /dev/null
+++ b/cmd/present/local.go
@@ -0,0 +1,122 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "go/build"
+ "log"
+ "net"
+ "net/http"
+ "net/url"
+ "os"
+ "runtime"
+ "strings"
+
+ "code.google.com/p/go.tools/playground/socket"
+ "code.google.com/p/go.tools/present"
+)
+
+const basePkg = "code.google.com/p/go.tools/cmd/present"
+
+var (
+ basePath string
+ nativeClient bool
+)
+
+func main() {
+ httpListen := flag.String("http", "127.0.0.1:3999", "host:port to listen on")
+ flag.StringVar(&basePath, "base", "", "base path for slide template and static resources")
+ flag.BoolVar(&present.PlayEnabled, "play", true, "enable playground (permit execution of arbitrary user code)")
+ flag.BoolVar(&nativeClient, "nacl", false, "use Native Client environment playground (prevents non-Go code execution)")
+ flag.Parse()
+
+ if basePath == "" {
+ p, err := build.Default.Import(basePkg, "", build.FindOnly)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Couldn't find gopresent files: %v\n", err)
+ fmt.Fprintf(os.Stderr, basePathMessage, basePkg)
+ os.Exit(1)
+ }
+ basePath = p.Dir
+ }
+
+ if present.PlayEnabled {
+ if nativeClient {
+ socket.RunScripts = false
+ socket.Environ = func() []string {
+ if runtime.GOARCH == "amd64" {
+ return environ("GOOS=nacl", "GOARCH=amd64p32")
+ }
+ return environ("GOOS=nacl")
+ }
+ }
+ playScript(basePath, "SocketTransport")
+
+ host, port, err := net.SplitHostPort(*httpListen)
+ if err != nil {
+ log.Fatal(err)
+ }
+ origin := &url.URL{Scheme: "http", Host: host + ":" + port}
+ http.Handle("/socket", socket.NewHandler(origin))
+ }
+ http.Handle("/static/", http.FileServer(http.Dir(basePath)))
+
+ if !strings.HasPrefix(*httpListen, "127.0.0.1") &&
+ !strings.HasPrefix(*httpListen, "localhost") &&
+ present.PlayEnabled && !nativeClient {
+ log.Print(localhostWarning)
+ }
+
+ log.Printf("Open your web browser and visit http://%s/", *httpListen)
+ log.Fatal(http.ListenAndServe(*httpListen, nil))
+}
+
+func playable(c present.Code) bool {
+ return present.PlayEnabled && c.Play
+}
+
+func environ(vars ...string) []string {
+ env := os.Environ()
+ for _, r := range vars {
+ k := strings.SplitAfter(r, "=")[0]
+ var found bool
+ for i, v := range env {
+ if strings.HasPrefix(v, k) {
+ env[i] = r
+ found = true
+ }
+ }
+ if !found {
+ env = append(env, r)
+ }
+ }
+ return env
+}
+
+const basePathMessage = `
+By default, gopresent locates the slide template files and associated
+static content by looking for a %q package
+in your Go workspaces (GOPATH).
+
+You may use the -base flag to specify an alternate location.
+`
+
+const localhostWarning = `
+WARNING! WARNING! WARNING!
+
+The present server appears to be listening on an address that is not localhost.
+Anyone with access to this address and port will have access to this machine as
+the user running present.
+
+To avoid this message, listen on localhost or run with -play=false.
+
+If you don't understand this message, hit Control-C to terminate this process.
+
+WARNING! WARNING! WARNING!
+`
diff --git a/cmd/present/play.go b/cmd/present/play.go
new file mode 100644
index 00000000..d347e311
--- /dev/null
+++ b/cmd/present/play.go
@@ -0,0 +1,43 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "path/filepath"
+ "time"
+
+ "code.google.com/p/go.tools/godoc/static"
+)
+
+var scripts = []string{"jquery.js", "jquery-ui.js", "playground.js", "play.js"}
+
+// playScript registers an HTTP handler at /play.js that serves all the
+// scripts specified by the variable above, and appends a line that
+// initializes the playground with the specified transport.
+func playScript(root, transport string) {
+ modTime := time.Now()
+ var buf bytes.Buffer
+ for _, p := range scripts {
+ if s, ok := static.Files[p]; ok {
+ buf.WriteString(s)
+ continue
+ }
+ b, err := ioutil.ReadFile(filepath.Join(root, "js", p))
+ if err != nil {
+ panic(err)
+ }
+ buf.Write(b)
+ }
+ fmt.Fprintf(&buf, "\ninitPlayground(new %v());\n", transport)
+ b := buf.Bytes()
+ http.HandleFunc("/play.js", func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-type", "application/javascript")
+ http.ServeContent(w, r, "", modTime, bytes.NewReader(b))
+ })
+}
diff --git a/cmd/present/static/article.css b/cmd/present/static/article.css
new file mode 100644
index 00000000..e6ab1e84
--- /dev/null
+++ b/cmd/present/static/article.css
@@ -0,0 +1,136 @@
+body {
+ margin: 0;
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 16px;
+}
+pre,
+code {
+ font-family: Menlo, monospace;
+ font-size: 14px;
+}
+pre {
+ line-height: 18px;
+ margin: 0;
+ padding: 0;
+}
+a {
+ color: #375EAB;
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+p, ul, ol {
+ margin: 20px;
+}
+
+h1, h2, h3, h4 {
+ margin: 20px 0;
+ padding: 0;
+ color: #375EAB;
+ font-weight: bold;
+}
+h1 {
+ font-size: 24px;
+}
+h2 {
+ font-size: 20px;
+ background: #E0EBF5;
+ padding: 2px 5px;
+}
+h3 {
+ font-size: 20px;
+}
+h3, h4 {
+ margin: 20px 5px;
+}
+h4 {
+ font-size: 16px;
+}
+
+div#heading {
+ float: left;
+ margin: 0 0 10px 0;
+ padding: 21px 0;
+ font-size: 20px;
+ font-weight: normal;
+}
+
+div#topbar {
+ background: #E0EBF5;
+ height: 64px;
+ overflow: hidden;
+}
+
+body {
+ text-align: center;
+}
+div#page {
+ width: 100%;
+}
+div#page > .container,
+div#topbar > .container {
+ text-align: left;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 20px;
+ width: 900px;
+}
+div#page.wide > .container,
+div#topbar.wide > .container {
+ width: auto;
+}
+
+div#footer {
+ text-align: center;
+ color: #666;
+ font-size: 14px;
+ margin: 40px 0;
+}
+
+.author p {
+ margin: 20, 0, 0, 0px;
+}
+
+div.code,
+div.output {
+ margin: 20px;
+ padding: 10px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+
+div.code { background: #e9e9e9; }
+div.output { background: black; }
+div.output .stdout { color: #e6e6e6; }
+div.output .stderr { color: rgb(244, 74, 63); }
+div.output .system { color: rgb(255, 209, 77) }
+
+.buttons {
+ margin-left: 20px;
+}
+div.output .buttons {
+ margin-left: 0;
+ margin-bottom: 10px;
+}
+
+#toc {
+ float: right;
+ margin: 0px 10px;
+ padding: 10px;
+ border: 1px solid #e5ecf9;
+ background-color: white;
+ max-width: 33%;
+
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+
+#toc ul, #toc a {
+ list-style-type: none;
+ padding-left: 10px;
+ color: black;
+ margin: 0px;
+}
diff --git a/cmd/present/static/dir.css b/cmd/present/static/dir.css
new file mode 100644
index 00000000..97587e62
--- /dev/null
+++ b/cmd/present/static/dir.css
@@ -0,0 +1,186 @@
+/* copied from $GOROOT/doc/style.css */
+
+body {
+ margin: 0;
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 16px;
+}
+pre,
+code {
+ font-family: Menlo, monospace;
+ font-size: 14px;
+}
+pre {
+ line-height: 18px;
+}
+pre .comment {
+ color: #375EAB;
+}
+pre .highlight,
+pre .highlight-comment,
+pre .selection-highlight,
+pre .selection-highlight-comment {
+ background: #FFFF00;
+}
+pre .selection,
+pre .selection-comment {
+ background: #FF9632;
+}
+pre .ln {
+ color: #999;
+}
+body {
+ color: #222;
+}
+a,
+.exampleHeading .text {
+ color: #375EAB;
+ text-decoration: none;
+}
+a:hover,
+.exampleHeading .text:hover {
+ text-decoration: underline;
+}
+p,
+pre,
+ul,
+ol {
+ margin: 20px;
+}
+pre {
+ background: #e9e9e9;
+ padding: 10px;
+
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+
+h1,
+h2,
+h3,
+h4,
+.rootHeading {
+ margin: 20px 0;
+ padding: 0;
+ color: #375EAB;
+ font-weight: bold;
+}
+h1 {
+ font-size: 24px;
+}
+h2 {
+ font-size: 20px;
+ background: #E0EBF5;
+ padding: 2px 5px;
+}
+h3 {
+ font-size: 20px;
+}
+h3,
+h4 {
+ margin: 20px 5px;
+}
+h4 {
+ font-size: 16px;
+}
+
+dl {
+ margin: 20px;
+}
+dd {
+ margin: 2px 20px;
+}
+dl,
+dd {
+ font-size: 14px;
+}
+div#nav table td {
+ vertical-align: top;
+}
+
+div#heading {
+ float: left;
+ margin: 0 0 10px 0;
+ padding: 21px 0;
+ font-size: 20px;
+ font-weight: normal;
+}
+div#heading a {
+ color: #222;
+ text-decoration: none;
+}
+
+div#topbar {
+ background: #E0EBF5;
+ height: 64px;
+}
+
+body {
+ text-align: center;
+}
+div#page,
+div#topbar > .container {
+ clear: both;
+ text-align: left;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 20px;
+ width: 900px;
+}
+div#page.wide,
+div#topbar > .wide {
+ width: auto;
+}
+div#plusone {
+ float: right;
+}
+
+div#footer {
+ color: #666;
+ font-size: 14px;
+ margin: 40px 0;
+}
+
+div#menu > a,
+div#menu > input {
+ padding: 10px;
+
+ text-decoration: none;
+ font-size: 16px;
+
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+div#menu > a,
+div#menu > input {
+ border: 1px solid #375EAB;
+}
+div#menu > a {
+ color: white;
+ background: #375EAB;
+}
+
+div#menu {
+ float: right;
+ min-width: 590px;
+ padding: 10px 0;
+ text-align: right;
+}
+div#menu > a {
+ margin-right: 5px;
+ margin-bottom: 10px;
+
+ padding: 10px;
+}
+div#menu > input {
+ position: relative;
+ top: 1px;
+ width: 60px;
+ background: white;
+ color: #222;
+}
+div#menu > input.inactive {
+ color: #999;
+}
diff --git a/cmd/present/static/dir.js b/cmd/present/static/dir.js
new file mode 100644
index 00000000..5b0c37e5
--- /dev/null
+++ b/cmd/present/static/dir.js
@@ -0,0 +1,41 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// copied from $GOROOT/doc/godocs.js
+
+function bindEvent(el, e, fn) {
+ if (el.addEventListener){
+ el.addEventListener(e, fn, false);
+ } else if (el.attachEvent){
+ el.attachEvent('on'+e, fn);
+ }
+}
+
+function godocs_bindSearchEvents() {
+ var search = document.getElementById('search');
+ if (!search) {
+ // no search box (index disabled)
+ return;
+ }
+ function clearInactive() {
+ if (search.className == "inactive") {
+ search.value = "";
+ search.className = "";
+ }
+ }
+ function restoreInactive() {
+ if (search.value !== "") {
+ return;
+ }
+ if (search.type != "search") {
+ search.value = search.getAttribute("placeholder");
+ }
+ search.className = "inactive";
+ }
+ restoreInactive();
+ bindEvent(search, 'focus', clearInactive);
+ bindEvent(search, 'blur', restoreInactive);
+}
+
+bindEvent(window, 'load', godocs_bindSearchEvents);
diff --git a/cmd/present/static/favicon.ico b/cmd/present/static/favicon.ico
new file mode 100644
index 00000000..48854ff3
Binary files /dev/null and b/cmd/present/static/favicon.ico differ
diff --git a/cmd/present/static/print.css b/cmd/present/static/print.css
new file mode 100644
index 00000000..6c582572
--- /dev/null
+++ b/cmd/present/static/print.css
@@ -0,0 +1,51 @@
+/* set page layout */
+@page {
+ size: A4 landscape;
+}
+
+body {
+ display: block !important;
+}
+
+.slides {
+ left: 0;
+ top: 0;
+}
+
+.slides > article {
+ position: relative;
+
+ left: 0;
+ top: 0;
+
+ margin: 0 !important;
+ page-break-inside: avoid;
+
+ text-shadow: none; /* disable shadow */
+
+ display: block !important;
+ transform: translate(0) !important;
+ -o-transform: translate(0) !important;
+ -moz-transform: translate(0) !important;
+ -webkit-transform: translate3d(0, 0, 0) !important;
+}
+
+div.code {
+ background: rgb(240, 240, 240);
+}
+
+/* hide click areas */
+.slide-area, #prev-slide-area, #next-slide-area {
+ display: none;
+}
+
+/* add explicit links */
+a:link:after, a:visited:after {
+ content: " (" attr(href) ") ";
+ font-size: 50%;
+}
+
+/* white background */
+body {
+ background: rgb(255,255,255) !important;
+}
diff --git a/cmd/present/static/slides.js b/cmd/present/static/slides.js
new file mode 100644
index 00000000..489fb6bd
--- /dev/null
+++ b/cmd/present/static/slides.js
@@ -0,0 +1,516 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var PERMANENT_URL_PREFIX = '/static/';
+
+var SLIDE_CLASSES = ['far-past', 'past', 'current', 'next', 'far-next'];
+
+var PM_TOUCH_SENSITIVITY = 15;
+
+var curSlide;
+
+/* ---------------------------------------------------------------------- */
+/* classList polyfill by Eli Grey
+ * (http://purl.eligrey.com/github/classList.js/blob/master/classList.js) */
+
+if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
+
+(function (view) {
+
+var
+ classListProp = "classList"
+ , protoProp = "prototype"
+ , elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
+ , objCtr = Object
+ strTrim = String[protoProp].trim || function () {
+ return this.replace(/^\s+|\s+$/g, "");
+ }
+ , arrIndexOf = Array[protoProp].indexOf || function (item) {
+ for (var i = 0, len = this.length; i < len; i++) {
+ if (i in this && this[i] === item) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ // Vendors: please allow content code to instantiate DOMExceptions
+ , DOMEx = function (type, message) {
+ this.name = type;
+ this.code = DOMException[type];
+ this.message = message;
+ }
+ , checkTokenAndGetIndex = function (classList, token) {
+ if (token === "") {
+ throw new DOMEx(
+ "SYNTAX_ERR"
+ , "An invalid or illegal string was specified"
+ );
+ }
+ if (/\s/.test(token)) {
+ throw new DOMEx(
+ "INVALID_CHARACTER_ERR"
+ , "String contains an invalid character"
+ );
+ }
+ return arrIndexOf.call(classList, token);
+ }
+ , ClassList = function (elem) {
+ var
+ trimmedClasses = strTrim.call(elem.className)
+ , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
+ ;
+ for (var i = 0, len = classes.length; i < len; i++) {
+ this.push(classes[i]);
+ }
+ this._updateClassName = function () {
+ elem.className = this.toString();
+ };
+ }
+ , classListProto = ClassList[protoProp] = []
+ , classListGetter = function () {
+ return new ClassList(this);
+ }
+;
+// Most DOMException implementations don't allow calling DOMException's toString()
+// on non-DOMExceptions. Error's toString() is sufficient here.
+DOMEx[protoProp] = Error[protoProp];
+classListProto.item = function (i) {
+ return this[i] || null;
+};
+classListProto.contains = function (token) {
+ token += "";
+ return checkTokenAndGetIndex(this, token) !== -1;
+};
+classListProto.add = function (token) {
+ token += "";
+ if (checkTokenAndGetIndex(this, token) === -1) {
+ this.push(token);
+ this._updateClassName();
+ }
+};
+classListProto.remove = function (token) {
+ token += "";
+ var index = checkTokenAndGetIndex(this, token);
+ if (index !== -1) {
+ this.splice(index, 1);
+ this._updateClassName();
+ }
+};
+classListProto.toggle = function (token) {
+ token += "";
+ if (checkTokenAndGetIndex(this, token) === -1) {
+ this.add(token);
+ } else {
+ this.remove(token);
+ }
+};
+classListProto.toString = function () {
+ return this.join(" ");
+};
+
+if (objCtr.defineProperty) {
+ var classListPropDesc = {
+ get: classListGetter
+ , enumerable: true
+ , configurable: true
+ };
+ try {
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ } catch (ex) { // IE 8 doesn't support enumerable:true
+ if (ex.number === -0x7FF5EC54) {
+ classListPropDesc.enumerable = false;
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ }
+ }
+} else if (objCtr[protoProp].__defineGetter__) {
+ elemCtrProto.__defineGetter__(classListProp, classListGetter);
+}
+
+}(self));
+
+}
+/* ---------------------------------------------------------------------- */
+
+/* Slide movement */
+
+function getSlideEl(no) {
+ if ((no < 0) || (no >= slideEls.length)) {
+ return null;
+ } else {
+ return slideEls[no];
+ }
+};
+
+function updateSlideClass(slideNo, className) {
+ var el = getSlideEl(slideNo);
+
+ if (!el) {
+ return;
+ }
+
+ if (className) {
+ el.classList.add(className);
+ }
+
+ for (var i in SLIDE_CLASSES) {
+ if (className != SLIDE_CLASSES[i]) {
+ el.classList.remove(SLIDE_CLASSES[i]);
+ }
+ }
+};
+
+function updateSlides() {
+ for (var i = 0; i < slideEls.length; i++) {
+ switch (i) {
+ case curSlide - 2:
+ updateSlideClass(i, 'far-past');
+ break;
+ case curSlide - 1:
+ updateSlideClass(i, 'past');
+ break;
+ case curSlide:
+ updateSlideClass(i, 'current');
+ break;
+ case curSlide + 1:
+ updateSlideClass(i, 'next');
+ break;
+ case curSlide + 2:
+ updateSlideClass(i, 'far-next');
+ break;
+ default:
+ updateSlideClass(i);
+ break;
+ }
+ }
+
+ triggerLeaveEvent(curSlide - 1);
+ triggerEnterEvent(curSlide);
+
+ window.setTimeout(function() {
+ // Hide after the slide
+ disableSlideFrames(curSlide - 2);
+ }, 301);
+
+ enableSlideFrames(curSlide - 1);
+ enableSlideFrames(curSlide + 2);
+
+ updateHash();
+};
+
+function prevSlide() {
+ if (curSlide > 0) {
+ curSlide--;
+
+ updateSlides();
+ }
+};
+
+function nextSlide() {
+ if (curSlide < slideEls.length - 1) {
+ curSlide++;
+
+ updateSlides();
+ }
+};
+
+/* Slide events */
+
+function triggerEnterEvent(no) {
+ var el = getSlideEl(no);
+ if (!el) {
+ return;
+ }
+
+ var onEnter = el.getAttribute('onslideenter');
+ if (onEnter) {
+ new Function(onEnter).call(el);
+ }
+
+ var evt = document.createEvent('Event');
+ evt.initEvent('slideenter', true, true);
+ evt.slideNumber = no + 1; // Make it readable
+
+ el.dispatchEvent(evt);
+};
+
+function triggerLeaveEvent(no) {
+ var el = getSlideEl(no);
+ if (!el) {
+ return;
+ }
+
+ var onLeave = el.getAttribute('onslideleave');
+ if (onLeave) {
+ new Function(onLeave).call(el);
+ }
+
+ var evt = document.createEvent('Event');
+ evt.initEvent('slideleave', true, true);
+ evt.slideNumber = no + 1; // Make it readable
+
+ el.dispatchEvent(evt);
+};
+
+/* Touch events */
+
+function handleTouchStart(event) {
+ if (event.touches.length == 1) {
+ touchDX = 0;
+ touchDY = 0;
+
+ touchStartX = event.touches[0].pageX;
+ touchStartY = event.touches[0].pageY;
+
+ document.body.addEventListener('touchmove', handleTouchMove, true);
+ document.body.addEventListener('touchend', handleTouchEnd, true);
+ }
+};
+
+function handleTouchMove(event) {
+ if (event.touches.length > 1) {
+ cancelTouch();
+ } else {
+ touchDX = event.touches[0].pageX - touchStartX;
+ touchDY = event.touches[0].pageY - touchStartY;
+ event.preventDefault();
+ }
+};
+
+function handleTouchEnd(event) {
+ var dx = Math.abs(touchDX);
+ var dy = Math.abs(touchDY);
+
+ if ((dx > PM_TOUCH_SENSITIVITY) && (dy < (dx * 2 / 3))) {
+ if (touchDX > 0) {
+ prevSlide();
+ } else {
+ nextSlide();
+ }
+ }
+
+ cancelTouch();
+};
+
+function cancelTouch() {
+ document.body.removeEventListener('touchmove', handleTouchMove, true);
+ document.body.removeEventListener('touchend', handleTouchEnd, true);
+};
+
+/* Preloading frames */
+
+function disableSlideFrames(no) {
+ var el = getSlideEl(no);
+ if (!el) {
+ return;
+ }
+
+ var frames = el.getElementsByTagName('iframe');
+ for (var i = 0, frame; frame = frames[i]; i++) {
+ disableFrame(frame);
+ }
+};
+
+function enableSlideFrames(no) {
+ var el = getSlideEl(no);
+ if (!el) {
+ return;
+ }
+
+ var frames = el.getElementsByTagName('iframe');
+ for (var i = 0, frame; frame = frames[i]; i++) {
+ enableFrame(frame);
+ }
+};
+
+function disableFrame(frame) {
+ frame.src = 'about:blank';
+};
+
+function enableFrame(frame) {
+ var src = frame._src;
+
+ if (frame.src != src && src != 'about:blank') {
+ frame.src = src;
+ }
+};
+
+function setupFrames() {
+ var frames = document.querySelectorAll('iframe');
+ for (var i = 0, frame; frame = frames[i]; i++) {
+ frame._src = frame.src;
+ disableFrame(frame);
+ }
+
+ enableSlideFrames(curSlide);
+ enableSlideFrames(curSlide + 1);
+ enableSlideFrames(curSlide + 2);
+};
+
+function setupInteraction() {
+ /* Clicking and tapping */
+
+ var el = document.createElement('div');
+ el.className = 'slide-area';
+ el.id = 'prev-slide-area';
+ el.addEventListener('click', prevSlide, false);
+ document.querySelector('section.slides').appendChild(el);
+
+ var el = document.createElement('div');
+ el.className = 'slide-area';
+ el.id = 'next-slide-area';
+ el.addEventListener('click', nextSlide, false);
+ document.querySelector('section.slides').appendChild(el);
+
+ /* Swiping */
+
+ document.body.addEventListener('touchstart', handleTouchStart, false);
+}
+
+/* Hash functions */
+
+function getCurSlideFromHash() {
+ var slideNo = parseInt(location.hash.substr(1));
+
+ if (slideNo) {
+ curSlide = slideNo - 1;
+ } else {
+ curSlide = 0;
+ }
+};
+
+function updateHash() {
+ location.replace('#' + (curSlide + 1));
+};
+
+/* Event listeners */
+
+function handleBodyKeyDown(event) {
+ // If we're in a code element, only handle pgup/down.
+ var inCode = event.target.classList.contains("code");
+
+ switch (event.keyCode) {
+ case 39: // right arrow
+ case 13: // Enter
+ case 32: // space
+ if (inCode) break;
+ case 34: // PgDn
+ nextSlide();
+ event.preventDefault();
+ break;
+
+ case 37: // left arrow
+ case 8: // Backspace
+ if (inCode) break;
+ case 33: // PgUp
+ prevSlide();
+ event.preventDefault();
+ break;
+
+ case 40: // down arrow
+ if (inCode) break;
+ nextSlide();
+ event.preventDefault();
+ break;
+
+ case 38: // up arrow
+ if (inCode) break;
+ prevSlide();
+ event.preventDefault();
+ break;
+ }
+};
+
+function addEventListeners() {
+ document.addEventListener('keydown', handleBodyKeyDown, false);
+};
+
+/* Initialization */
+
+function addFontStyle() {
+ var el = document.createElement('link');
+ el.rel = 'stylesheet';
+ el.type = 'text/css';
+ el.href = '//fonts.googleapis.com/css?family=' +
+ 'Open+Sans:regular,semibold,italic,italicsemibold|Droid+Sans+Mono';
+
+ document.body.appendChild(el);
+};
+
+function addGeneralStyle() {
+ var el = document.createElement('link');
+ el.rel = 'stylesheet';
+ el.type = 'text/css';
+ el.href = PERMANENT_URL_PREFIX + 'styles.css';
+ document.body.appendChild(el);
+
+ var el = document.createElement('meta');
+ el.name = 'viewport';
+ el.content = 'width=1100,height=750';
+ document.querySelector('head').appendChild(el);
+
+ var el = document.createElement('meta');
+ el.name = 'apple-mobile-web-app-capable';
+ el.content = 'yes';
+ document.querySelector('head').appendChild(el);
+};
+
+function addPrintStyle() {
+ var el = document.createElement('link');
+ el.rel = 'stylesheet';
+ el.type = 'text/css';
+ el.media = "print";
+ el.href = PERMANENT_URL_PREFIX + 'print.css';
+ document.body.appendChild(el);
+};
+
+function handleDomLoaded() {
+ slideEls = document.querySelectorAll('section.slides > article');
+
+ setupFrames();
+
+ addFontStyle();
+ addGeneralStyle();
+ addPrintStyle();
+ addEventListeners();
+
+ updateSlides();
+
+ setupInteraction();
+
+ document.body.classList.add('loaded');
+};
+
+function initialize() {
+ getCurSlideFromHash();
+
+ if (window['_DEBUG']) {
+ PERMANENT_URL_PREFIX = '../';
+ }
+
+ if (window['_DCL']) {
+ handleDomLoaded();
+ } else {
+ document.addEventListener('DOMContentLoaded', handleDomLoaded, false);
+ }
+}
+
+// If ?debug exists then load the script relative instead of absolute
+if (!window['_DEBUG'] && document.location.href.indexOf('?debug') !== -1) {
+ document.addEventListener('DOMContentLoaded', function() {
+ // Avoid missing the DomContentLoaded event
+ window['_DCL'] = true
+ }, false);
+
+ window['_DEBUG'] = true;
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = '../slides.js';
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(script, s);
+
+ // Remove this script
+ s.parentNode.removeChild(s);
+} else {
+ initialize();
+}
diff --git a/cmd/present/static/styles.css b/cmd/present/static/styles.css
new file mode 100644
index 00000000..adaa9f67
--- /dev/null
+++ b/cmd/present/static/styles.css
@@ -0,0 +1,455 @@
+/* Framework */
+
+html {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+
+ display: block !important;
+
+ height: 100%;
+ min-height: 740px;
+
+ overflow-x: hidden;
+ overflow-y: auto;
+
+ background: rgb(215, 215, 215);
+ background: -o-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
+ background: -moz-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
+ background: -webkit-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
+ background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(rgb(240, 240, 240)), to(rgb(190, 190, 190)));
+
+ -webkit-font-smoothing: antialiased;
+}
+
+.slides {
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+
+ position: absolute;
+
+ -webkit-transform: translate3d(0, 0, 0);
+}
+
+.slides > article {
+ display: block;
+
+ position: absolute;
+ overflow: hidden;
+
+ width: 900px;
+ height: 700px;
+
+ left: 50%;
+ top: 50%;
+
+ margin-left: -450px;
+ margin-top: -350px;
+
+ padding: 40px 60px;
+
+ box-sizing: border-box;
+ -o-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+
+ border-radius: 10px;
+ -o-border-radius: 10px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+
+ background-color: white;
+
+ border: 1px solid rgba(0, 0, 0, .3);
+
+ /*
+ transition: transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ -moz-transition: -moz-transform .3s ease-out;
+ -webkit-transition: -webkit-transform .3s ease-out;
+ */
+}
+.slides.layout-widescreen > article {
+ margin-left: -550px;
+ width: 1100px;
+}
+.slides.layout-faux-widescreen > article {
+ margin-left: -550px;
+ width: 1100px;
+
+ padding: 40px 160px;
+}
+
+.slides.layout-widescreen > article:not(.nobackground):not(.biglogo),
+.slides.layout-faux-widescreen > article:not(.nobackground):not(.biglogo) {
+ background-position-x: 0, 840px;
+}
+
+/* Clickable/tappable areas */
+
+.slide-area {
+ z-index: 1000;
+
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 150px;
+ height: 700px;
+
+ left: 50%;
+ top: 50%;
+
+ cursor: pointer;
+ margin-top: -350px;
+
+ tap-highlight-color: transparent;
+ -o-tap-highlight-color: transparent;
+ -moz-tap-highlight-color: transparent;
+ -webkit-tap-highlight-color: transparent;
+}
+#prev-slide-area {
+ margin-left: -550px;
+}
+#next-slide-area {
+ margin-left: 400px;
+}
+.slides.layout-widescreen #prev-slide-area,
+.slides.layout-faux-widescreen #prev-slide-area {
+ margin-left: -650px;
+}
+.slides.layout-widescreen #next-slide-area,
+.slides.layout-faux-widescreen #next-slide-area {
+ margin-left: 500px;
+}
+
+/* Slides */
+
+.slides > article {
+ display: none;
+}
+.slides > article.far-past {
+ display: block;
+ transform: translate(-2040px);
+ -o-transform: translate(-2040px);
+ -moz-transform: translate(-2040px);
+ -webkit-transform: translate3d(-2040px, 0, 0);
+}
+.slides > article.past {
+ display: block;
+ transform: translate(-1020px);
+ -o-transform: translate(-1020px);
+ -moz-transform: translate(-1020px);
+ -webkit-transform: translate3d(-1020px, 0, 0);
+}
+.slides > article.current {
+ display: block;
+ transform: translate(0);
+ -o-transform: translate(0);
+ -moz-transform: translate(0);
+ -webkit-transform: translate3d(0, 0, 0);
+}
+.slides > article.next {
+ display: block;
+ transform: translate(1020px);
+ -o-transform: translate(1020px);
+ -moz-transform: translate(1020px);
+ -webkit-transform: translate3d(1020px, 0, 0);
+}
+.slides > article.far-next {
+ display: block;
+ transform: translate(2040px);
+ -o-transform: translate(2040px);
+ -moz-transform: translate(2040px);
+ -webkit-transform: translate3d(2040px, 0, 0);
+}
+
+.slides.layout-widescreen > article.far-past,
+.slides.layout-faux-widescreen > article.far-past {
+ display: block;
+ transform: translate(-2260px);
+ -o-transform: translate(-2260px);
+ -moz-transform: translate(-2260px);
+ -webkit-transform: translate3d(-2260px, 0, 0);
+}
+.slides.layout-widescreen > article.past,
+.slides.layout-faux-widescreen > article.past {
+ display: block;
+ transform: translate(-1130px);
+ -o-transform: translate(-1130px);
+ -moz-transform: translate(-1130px);
+ -webkit-transform: translate3d(-1130px, 0, 0);
+}
+.slides.layout-widescreen > article.current,
+.slides.layout-faux-widescreen > article.current {
+ display: block;
+ transform: translate(0);
+ -o-transform: translate(0);
+ -moz-transform: translate(0);
+ -webkit-transform: translate3d(0, 0, 0);
+}
+.slides.layout-widescreen > article.next,
+.slides.layout-faux-widescreen > article.next {
+ display: block;
+ transform: translate(1130px);
+ -o-transform: translate(1130px);
+ -moz-transform: translate(1130px);
+ -webkit-transform: translate3d(1130px, 0, 0);
+}
+.slides.layout-widescreen > article.far-next,
+.slides.layout-faux-widescreen > article.far-next {
+ display: block;
+ transform: translate(2260px);
+ -o-transform: translate(2260px);
+ -moz-transform: translate(2260px);
+ -webkit-transform: translate3d(2260px, 0, 0);
+}
+
+/* Styles for slides */
+
+.slides > article {
+ font-family: 'Open Sans', Arial, sans-serif;
+
+ color: black;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, .1);
+
+ font-size: 26px;
+ line-height: 36px;
+
+ letter-spacing: -1px;
+}
+
+b {
+ font-weight: 600;
+}
+
+a {
+ color: rgb(0, 102, 204);
+ text-decoration: none;
+}
+a:visited {
+ color: rgba(0, 102, 204, .75);
+}
+a:hover {
+ color: black;
+}
+
+p {
+ margin: 0;
+ padding: 0;
+
+ margin-top: 20px;
+}
+p:first-child {
+ margin-top: 0;
+}
+
+h1 {
+ font-size: 60px;
+ line-height: 60px;
+
+ padding: 0;
+ margin: 0;
+ margin-top: 200px;
+ margin-bottom: 5px;
+ padding-right: 40px;
+
+ font-weight: 600;
+
+ letter-spacing: -3px;
+
+ color: rgb(51, 51, 51);
+}
+
+h2 {
+ font-size: 45px;
+ line-height: 45px;
+
+ position: absolute;
+ bottom: 150px;
+
+ padding: 0;
+ margin: 0;
+ padding-right: 40px;
+
+ font-weight: 600;
+
+ letter-spacing: -2px;
+
+ color: rgb(51, 51, 51);
+}
+
+h3 {
+ font-size: 30px;
+ line-height: 36px;
+
+ padding: 0;
+ margin: 0;
+ padding-right: 40px;
+
+ font-weight: 600;
+
+ letter-spacing: -1px;
+
+ color: rgb(51, 51, 51);
+}
+
+ul {
+ margin: 0;
+ padding: 0;
+ margin-top: 20px;
+ margin-left: 1.5em;
+}
+li {
+ padding: 0;
+ margin: 0 0 .5em 0;
+}
+
+div.code {
+ padding: 5px 10px;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+
+ background: rgb(240, 240, 240);
+ border: 1px solid rgb(224, 224, 224);
+}
+pre {
+ margin: 0;
+ padding: 0;
+
+ font-family: 'Droid Sans Mono', 'Courier New', monospace;
+ font-size: 18px;
+ line-height: 24px;
+ letter-spacing: -1px;
+
+ color: black;
+}
+
+code {
+ font-size: 95%;
+ font-family: 'Droid Sans Mono', 'Courier New', monospace;
+
+ color: black;
+}
+
+article > .image {
+ text-align: center;
+ margin-top: 40px;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 40px;
+}
+th {
+ font-weight: 600;
+ text-align: left;
+}
+td,
+th {
+ border: 1px solid rgb(224, 224, 224);
+ padding: 5px 10px;
+ vertical-align: top;
+}
+
+p.link {
+ margin-left: 20px;
+}
+
+/* Code */
+div.code {
+ outline: 0px solid transparent;
+}
+div.playground {
+ position: relative;
+}
+div.output {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ right: 40px;
+ bottom: 40px;
+ background: #202020;
+ padding: 5px 10px;
+ z-index: 2;
+
+ border-radius: 10px;
+ -o-border-radius: 10px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+
+}
+div.output pre {
+ margin: 0;
+ padding: 0;
+ background: none;
+ border: none;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+}
+div.output .stdout, div.output pre {
+ color: #e6e6e6;
+}
+div.output .stderr, div.output .error {
+ color: rgb(255, 200, 200);
+}
+div.output .system, div.output .exit {
+ color: rgb(255, 230, 120)
+}
+.buttons {
+ position: relative;
+ float: right;
+ top: -60px;
+ right: 10px;
+}
+div.output .buttons {
+ position: absolute;
+ float: none;
+ top: auto;
+ right: 5px;
+ bottom: 5px;
+}
+
+/* Presenter details */
+.presenter {
+ margin-top: 20px;
+}
+.presenter p,
+.presenter .link {
+ margin: 0;
+ font-size: 28px;
+ line-height: 1.2em;
+}
+
+/* Output resize details */
+.ui-resizable-handle {
+ position: absolute;
+}
+.ui-resizable-n {
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0;
+}
+.ui-resizable-w {
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0;
+ height: 100%;
+}
+.ui-resizable-nw {
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
+}
diff --git a/cmd/present/templates/action.tmpl b/cmd/present/templates/action.tmpl
new file mode 100644
index 00000000..1fa0073b
--- /dev/null
+++ b/cmd/present/templates/action.tmpl
@@ -0,0 +1,46 @@
+{/*
+This is the action template.
+It determines how the formatting actions are rendered.
+*/}
+
+{{define "section"}}
+ {{.FormattedNumber}} {{.Title}}
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+{{end}}
+
+{{define "list"}}
+
+ {{range .Bullet}}
+ - {{style .}}
+ {{end}}
+
+{{end}}
+
+{{define "text"}}
+ {{if .Pre}}
+ {{range .Lines}}{{.}}{{end}}
+ {{else}}
+
+ {{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}
+ {{end}}{{style $l}}{{end}}
+
+ {{end}}
+{{end}}
+
+{{define "code"}}
+ {{.Text}}
+{{end}}
+
+{{define "image"}}
+
+

+
+{{end}}
+
+{{define "iframe"}}
+
+{{end}}
+
+{{define "link"}}{{style .Label}}
{{end}}
+
+{{define "html"}}{{.HTML}}{{end}}
diff --git a/cmd/present/templates/article.tmpl b/cmd/present/templates/article.tmpl
new file mode 100644
index 00000000..40d1c936
--- /dev/null
+++ b/cmd/present/templates/article.tmpl
@@ -0,0 +1,58 @@
+{/* This is the article template. It defines how articles are formatted. */}
+
+{{define "root"}}
+
+
+
+ {{.Title}}
+
+
+
+
+
+
+
+
{{.Title}}
+ {{with .Subtitle}}{{.}}{{end}}
+
+
+
+
+
+ {{with .Sections}}
+
+ {{template "TOC" .}}
+
+ {{end}}
+
+ {{range .Sections}}
+ {{elem $.Template .}}
+ {{end}}{{/* of Section block */}}
+
+ {{if .Authors}}
+
Authors
+ {{range .Authors}}
+
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+ {{end}}
+
+
+
+
+
+{{end}}
+
+{{define "TOC"}}
+
+ {{range .}}
+ - {{.Title}}
+ {{with .Sections}}{{template "TOC" .}}{{end}}
+ {{end}}
+
+{{end}}
+
+{{define "newline"}}
+{{/* No automatic line break. Paragraphs are free-form. */}}
+{{end}}
diff --git a/cmd/present/templates/slides.tmpl b/cmd/present/templates/slides.tmpl
new file mode 100644
index 00000000..d2abfa18
--- /dev/null
+++ b/cmd/present/templates/slides.tmpl
@@ -0,0 +1,58 @@
+{/* This is the slide template. It defines how presentations are formatted. */}
+
+{{define "root"}}
+
+
+
+ {{.Title}}
+
+
+
+
+
+
+
+
+
+ {{.Title}}
+ {{with .Subtitle}}{{.}}
{{end}}
+ {{if not .Time.IsZero}}{{.Time.Format "2 January 2006"}}
{{end}}
+ {{range .Authors}}
+
+ {{range .TextElem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+
+
+ {{range $i, $s := .Sections}}
+
+
+ {{if $s.Elem}}
+ {{$s.Title}}
+ {{range $s.Elem}}{{elem $.Template .}}{{end}}
+ {{else}}
+ {{$s.Title}}
+ {{end}}
+
+
+ {{end}}{{/* of Slide block */}}
+
+
+ Thank you
+ {{range .Authors}}
+
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+
+
+
+ {{if .PlayEnabled}}
+
+ {{end}}
+
+{{end}}
+
+{{define "newline"}}
+
+{{end}}