Mercurial > cgi-bin > hgwebdir.cgi > POP > oldRepo
changeset 3:32d17f6062cb
adding javascript code -- working on Display and Visualizer and srcHolder
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/9__misc/multi_reference_bug.js Sun Jul 06 12:02:12 2014 -0700 1.3 @@ -0,0 +1,90 @@ 1.4 + 1.5 + 1.6 +define(function(require, exports, module) { 1.7 + var Engine = require("famous/core/Engine"); 1.8 + var Surface = require("famous/core/Surface"); 1.9 + var Modifier = require("famous/core/Modifier"); 1.10 + var Transform = require('famous/core/Transform'); 1.11 + var StateModifier = require('famous/modifiers/StateModifier'); 1.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 1.13 + var Scrollview = require("famous/views/Scrollview"); 1.14 + 1.15 + var mainContext = Engine.createContext(); 1.16 + var mySurface1 = new Surface({ 1.17 + size: [100, 100], 1.18 + content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 1.19 + properties: { 1.20 + color: 'white', 1.21 + lineHeight: '200%', 1.22 + textAlign: 'center', 1.23 + fontSize: '36px', 1.24 + cursor: 'pointer' 1.25 + } 1.26 + }); 1.27 + 1.28 + var mySurface2 = new Surface({ 1.29 + size: [100, 100], 1.30 + content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:blue;stroke-width:3;opacity:0.5">', 1.31 + properties: { 1.32 + color: 'white', 1.33 + lineHeight: '200%', 1.34 + textAlign: 'center', 1.35 + fontSize: '36px', 1.36 + cursor: 'pointer' 1.37 + } 1.38 + }); 1.39 + var mySurface3 = new Surface({ 1.40 + size: [100, 100], 1.41 + content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:green;stroke-width:3;opacity:0.5">', 1.42 + properties: { 1.43 + color: 'white', 1.44 + lineHeight: '200%', 1.45 + textAlign: 'center', 1.46 + fontSize: '36px', 1.47 + cursor: 'pointer' 1.48 + } 1.49 + }); 1.50 + var mySurface4 = new Surface({ 1.51 + size: [100, 100], 1.52 + content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 1.53 + properties: { 1.54 + color: 'white', 1.55 + lineHeight: '200%', 1.56 + textAlign: 'center', 1.57 + fontSize: '36px', 1.58 + cursor: 'pointer' 1.59 + } 1.60 + }); 1.61 + 1.62 + var moveModifier1 = new StateModifier({ 1.63 + transform: Transform.translate(50, 50, 0) 1.64 + }); 1.65 + var moveModifier2 = new StateModifier({ 1.66 + transform: Transform.translate(100, 100, 0) 1.67 + }); 1.68 + var moveModifier3 = new StateModifier({ 1.69 + transform: Transform.translate(150, 150, 0) 1.70 + }); 1.71 + var moveModifier4 = new StateModifier({ 1.72 + transform: Transform.translate(100, 100, 0) 1.73 + }); 1.74 + var moveModifier5 = new StateModifier({ 1.75 + transform: Transform.translate(100, 100, 0) 1.76 + }); 1.77 +//A given surface object will only render once! Have to 1.78 +// clone it if want multiple versions to be drawn. 1.79 +//Same goes for modifiers -- cannot put same modifier object at multiple 1.80 +// places within tree -- it will only render children of ONE of those places! 1.81 + mainContext.add(moveModifier1).add(mySurface1); 1.82 + mainContext.add(moveModifier2).add(mySurface2); 1.83 +//uncomment this line to see the first disappear 1.84 +// mainContext.add(moveModifier3).add(mySurface1); 1.85 + 1.86 + //this shows ganged modifiers working correctly 1.87 + mainContext.add(moveModifier4).add(moveModifier5).add(mySurface3); 1.88 + 1.89 + //this shows that repeating modifier2 makes the second fail to render! 1.90 +// uncomment this line to see the second disappear! 1.91 +// mainContext.add(moveModifier2).add(moveModifier3).add(mySurface4); 1.92 + 1.93 +});
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/9__misc/terminal.js Sun Jul 06 12:02:12 2014 -0700 2.3 @@ -0,0 +1,1 @@ 2.4 +!function a(b,c,e){function f(d,j){if(!c[d]){if(!b[d]){var i=typeof require=='function'&&require;if(!j&&i)return i(d,!0);if(g)return g(d,!0);throw new Error("Cannot find module '"+d+"'")}var h=c[d]={exports:{}};b[d][0].call(h.exports,function(c){var a=b[d][1][c];return f(a?a:c)},h,h.exports,a,b,c,e)}return c[d].exports}var g=typeof require=='function'&&require;for(var d=0;d<e.length;d++)f(e[d]);return f}({1:[function(a,D,C){function b(a){window.parent&&window.parent.postMessage&&window.parent.postMessage(a,'*')}function r(){document.body.className='focused'}function t(){document.body.className=''}function v(c){document.hasFocus&&document.hasFocus()&&r(),f=c||f;var a=f.split('/')[2];a!=='log'&&b('stream:'+a),l()}function l(){c=k(f);var a=new m(u);c.pipe(a).pipe(c),c.on('end',g),c.on('connect',j)}function B(){console.log('DIS'),b('term:dis'),c.removeListener('end',g),c.end()}function g(){if(console.log('RE'),window.term)try{document.body.removeChild(window.term.element)}catch(a){}e=!0,w(),setTimeout(l,5e3)}function u(a){e&&(e=!1,j()),a.meta==='terminal'&&y(a),a.meta==='clientEvents'&&A(a),a.meta==='terminalLog'&&x(a)}function j(){document.getElementById('loader').style.display='none',b('hide:loader')}function w(){document.getElementById('loader').style.display='block',b('show:loader')}function x(a){a.on('data',function(a){b('term:data'+a)})}function y(c){window.pty=c;var a=window.term=new s({cols:80,rows:24,useStyle:!0,screenKeys:!0});c.on('data',function(a){/\[1;32mExecuting Build Command: /.test(a)&&(console.log('BUILD'),b('stream:build')),/\[1;32mExecuting Run Command: /.test(a)&&(console.log('RUN'),b('stream:run')),/Process exited with code: /.test(a)&&(console.log('ERROR'),b('stream:error'))}),a.on('data',c.write.bind(c)),a.once('data',function(a){d.emit('enableLog')}),a.open(),c.pipe(a),a.end=a.destroy;var e=z.bind(null,a);e(),setTimeout(e,1e3),window.onresize=e}function z(a){var b=document.body.clientWidth/a.element.offsetWidth,c=document.body.clientHeight/a.element.offsetHeight;b=b*a.cols|0,c=c*a.rows|0,a.resize(b,c),typeof i==='function'&&i(b,c)}function A(g){var c=a('querystring').parse(window.location.search.slice(1)),b=c.options?JSON.parse(c.options):null,e=b&&b.args?b.args:[],f=b&&b.env?b.env:{};n.toStream(d).pipe(o.stringify()).pipe(g),i=function(a,b){d.emit('resize',a,b)},d.emit('startTerminal',e,f),setInterval(function a(){d.emit('ping',!0)},1e3)}a('es5-shimify');var s=a('term.js'),k=a('shoe'),i,m=a('mux-demux'),n=a('emit-stream'),o=a('JSONStream'),p=a('events').EventEmitter,q=a('away'),f,e=!0,c,d=new p,h=q(6e5);h.on('idle',B),h.on('active',g),window.onfocus=r,window.onblur=t,window.start=v},{JSONStream:2,away:5,'emit-stream':15,'es5-shimify':17,events:7,'mux-demux':18,querystring:9,shoe:24,'term.js':26}],2:[function(a,i,c){function d(a,b){return'string'===typeof a?b==a:a&&'function'===typeof a.exec?a.exec(b):'boolean'===typeof a?a:'function'===typeof a?a(b):!1}var e=a('__browserify_process'),f=a('__browserify_Buffer').Buffer,g=a('jsonparse'),h=a('stream').Stream,b=a('through');c.parse=function(c){var h=new g,a=b(function(a){if('string'===typeof a)if(e.browser){var c=new Array(a.length);for(var b=0;b<a.length;b++)c[b]=a.charCodeAt(b);a=new Int32Array(c)}else a=new f(a);h.write(a)},function(b){b&&a.write(b),a.queue(null)});'string'===typeof c&&(c=c.split('.').map(function(a){return a==='*'?!0:a===''?{recurse:!0}:a}));var i=0;return c&&c.length||(c=null),h.onValue=function(){if(!this.root&&this.stack.length==1&&(a.root=this.value),!c)return;var e=0,b=0;while(e<c.length){var g=c[e],f;if(b++,g&&!g.recurse){if(f=b===this.stack.length?this:this.stack[b],!f)return;if(!d(g,f.key))return;e++}else{e++;var h=c[e];if(!h)return;while(!0){if(f=b===this.stack.length?this:this.stack[b],!f)return;if(d(h,f.key)){e++;break}b++}}}if(b!==this.stack.length)return;i++,a.queue(this.value[this.key]),delete this.value[this.key]},h._onToken=h.onToken,h.onToken=function(b,d){h._onToken(b,d),this.stack.length===0&&a.root&&(c||a.queue(a.root),a.emit('root',a.root,i),i=0,a.root=null)},h.onError=function(b){a.emit('error',b)},a},c.stringify=function(c,d,e){c===!1?(c='',d='\n',e=''):c==null&&(c='[\n',d='\n,\n',e='\n]\n');var a,f=!0,g=!1;return a=b(function(e){g=!0;var b=JSON.stringify(e);f?(f=!1,a.queue(c+b)):a.queue(d+b)},function(b){g||a.queue(c),a.queue(e),a.queue(null)}),a},c.stringifyObject=function(c,d,e){c===!1?(c='',d='\n',e=''):c==null&&(c='{\n',d='\n,\n',e='\n}\n');var a=new h,f=!0,g=!1;return a=b(function(e){g=!0;var b=JSON.stringify(e[0])+':'+JSON.stringify(e[1]);f?(f=!1,a.queue(c+b)):a.queue(d+b)},function(b){g||a.queue(c),a.queue(e),a.queue(null)}),a}},{__browserify_Buffer:13,__browserify_process:14,jsonparse:3,stream:10,through:4}],3:[function(T,U,V){function y(c){var d=Object.keys(a);for(var b=0,f=d.length;b<f;b++){var e=d[b];if(a[e]===c)return e}return c&&'0x'+c.toString(16)}function S(){this.tState=d,this.value=undefined,this.string=undefined,this.unicode=undefined,this.negative=undefined,this.magnatude=undefined,this.position=undefined,this.exponent=undefined,this.negativeExponent=undefined,this.key=undefined,this.mode=undefined,this.stack=[],this.state=e,this.bytes_remaining=0,this.bytes_in_sequence=0,this.temp_buffs={2:new l(2),3:new l(3),4:new l(4)}}var l=T('__browserify_Buffer').Buffer,a={},M=a.LEFT_BRACE=1,h=a.RIGHT_BRACE=2,J=a.LEFT_BRACKET=3,n=a.RIGHT_BRACKET=4,i=a.COLON=5,j=a.COMMA=6,F=a.TRUE=7,G=a.FALSE=8,H=a.NULL=9,t=a.STRING=10,f=a.NUMBER=11,d=a.START=17,u=a.TRUE1=33,v=a.TRUE2=34,w=a.TRUE3=35,x=a.FALSE1=49,L=a.FALSE2=50,z=a.FALSE3=51,A=a.FALSE4=52,B=a.NULL1=65,C=a.NULL3=66,D=a.NULL2=67,E=a.NUMBER1=81,o=a.NUMBER2=82,p=a.NUMBER3=83,q=a.NUMBER4=84,I=a.NUMBER5=85,m=a.NUMBER6=86,K=a.NUMBER7=87,s=a.NUMBER8=88,c=a.STRING1=97,N=a.STRING2=98,O=a.STRING3=99,R=a.STRING4=100,Q=a.STRING5=101,P=a.STRING6=102,e=a.VALUE=113,r=a.KEY=114,g=a.OBJECT=129,k=a.ARRAY=130,b=S.prototype;b.charError=function(b,a){this.onError(new Error('Unexpected '+JSON.stringify(String.fromCharCode(b[a]))+' at position '+a+' in state '+y(this.tState)))},b.onError=function(a){throw a},b.write=function(e){typeof e==='string'&&(e=new l(e));var a;for(var b=0,r=e.length;b<r;b++)if(this.tState===d)a=e[b],a===123?this.onToken(M,'{'):a===125?this.onToken(h,'}'):a===91?this.onToken(J,'['):a===93?this.onToken(n,']'):a===58?this.onToken(i,':'):a===44?this.onToken(j,','):a===116?this.tState=u:a===102?this.tState=x:a===110?this.tState=B:a===34?(this.string='',this.tState=c):a===45?(this.negative=!0,this.tState=E):a===48?(this.magnatude=0,this.tState=o):a>48&&a<64?(this.magnatude=a-48,this.tState=p):a===32||a===9||a===10||a===13||this.charError(e,b);else if(this.tState===c)if(a=e[b],this.bytes_remaining>0){for(var g=0;g<this.bytes_remaining;g++)this.temp_buffs[this.bytes_in_sequence][this.bytes_in_sequence-this.bytes_remaining+g]=e[g];this.string+=this.temp_buffs[this.bytes_in_sequence].toString(),this.bytes_in_sequence=this.bytes_remaining=0,b=b+g-1}else if(this.bytes_remaining===0&&a>=128)if(a>=194&&a<=223&&(this.bytes_in_sequence=2),a>=224&&a<=239&&(this.bytes_in_sequence=3),a>=240&&a<=244&&(this.bytes_in_sequence=4),this.bytes_in_sequence+b>e.length){for(var k=0;k<=e.length-1-b;k++)this.temp_buffs[this.bytes_in_sequence][k]=e[b+k];this.bytes_remaining=b+this.bytes_in_sequence-e.length,b=e.length-1}else this.string+=e.slice(b,b+this.bytes_in_sequence).toString(),b=b+this.bytes_in_sequence-1;else a===34?(this.tState=d,this.onToken(t,this.string),this.string=undefined):a===92?this.tState=N:a>=32?this.string+=String.fromCharCode(a):this.charError(e,b);else this.tState===N?(a=e[b],a===34?(this.string+='"',this.tState=c):a===92?(this.string+='\\',this.tState=c):a===47?(this.string+='/',this.tState=c):a===98?(this.string+='',this.tState=c):a===102?(this.string+='',this.tState=c):a===110?(this.string+='\n',this.tState=c):a===114?(this.string+='\r',this.tState=c):a===116?(this.string+=' ',this.tState=c):a===117?(this.unicode='',this.tState=O):this.charError(e,b)):this.tState===O||this.tState===R||this.tState===Q||this.tState===P?(a=e[b],a>=48&&a<64||a>64&&a<=70||a>96&&a<=102?(this.unicode+=String.fromCharCode(a),this.tState++===P&&(this.string+=String.fromCharCode(parseInt(this.unicode,16)),this.unicode=undefined,this.tState=c)):this.charError(e,b)):this.tState===E?(a=e[b],a===48?(this.magnatude=0,this.tState=o):a>48&&a<64?(this.magnatude=a-48,this.tState=p):this.charError(e,b)):this.tState===o?(a=e[b],a===46?(this.position=.1,this.tState=q):a===101||a===69?(this.exponent=0,this.tState=m):(this.tState=d,this.onToken(f,0),this.magnatude=undefined,this.negative=undefined,b--)):this.tState===p?(a=e[b],a===46?(this.position=.1,this.tState=q):a===101||a===69?(this.exponent=0,this.tState=m):a>=48&&a<64?this.magnatude=this.magnatude*10+a-48:(this.tState=d,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.onToken(f,this.magnatude),this.magnatude=undefined,b--)):this.tState===q?(a=e[b],a>=48&&a<64?(this.magnatude+=this.position*(a-48),this.position/=10,this.tState=I):this.charError(e,b)):this.tState===I?(a=e[b],a>=48&&a<64?(this.magnatude+=this.position*(a-48),this.position/=10):a===101||a===69?(this.exponent=0,this.tState=m):(this.tState=d,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.onToken(f,this.negative?-this.magnatude:this.magnatude),this.magnatude=undefined,this.position=undefined,b--)):this.tState===m?(a=e[b],a===43||a===45?(a===45&&(this.negativeExponent=!0),this.tState=K):a>=48&&a<64?(this.exponent=this.exponent*10+(a-48),this.tState=s):this.charError(e,b)):this.tState===K?(a=e[b],a>=48&&a<64?(this.exponent=this.exponent*10+(a-48),this.tState=s):this.charError(e,b)):this.tState===s?(a=e[b],a>=48&&a<64?this.exponent=this.exponent*10+(a-48):(this.negativeExponent&&(this.exponent=-this.exponent,this.negativeExponent=undefined),this.magnatude*=Math.pow(10,this.exponent),this.exponent=undefined,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.tState=d,this.onToken(f,this.magnatude),this.magnatude=undefined,b--)):this.tState===u?e[b]===114?this.tState=v:this.charError(e,b):this.tState===v?e[b]===117?this.tState=w:this.charError(e,b):this.tState===w?e[b]===101?(this.tState=d,this.onToken(F,!0)):this.charError(e,b):this.tState===x?e[b]===97?this.tState=L:this.charError(e,b):this.tState===L?e[b]===108?this.tState=z:this.charError(e,b):this.tState===z?e[b]===115?this.tState=A:this.charError(e,b):this.tState===A?e[b]===101?(this.tState=d,this.onToken(G,!1)):this.charError(e,b):this.tState===B?e[b]===117?this.tState=C:this.charError(e,b):this.tState===C?e[b]===108?this.tState=D:this.charError(e,b):this.tState===D&&(e[b]===108?(this.tState=d,this.onToken(H,null)):this.charError(e,b))},b.onToken=function(a,b){},b.parseError=function(b,a){this.onError(new Error('Unexpected '+y(b)+(a?'('+JSON.stringify(a)+')':'')+' in state '+y(this.state)))},b.onError=function(a){throw a},b.push=function(){this.stack.push({value:this.value,key:this.key,mode:this.mode})},b.pop=function(){var b=this.value,a=this.stack.pop();this.value=a.value,this.key=a.key,this.mode=a.mode,this.emit(b),this.mode||(this.state=e)},b.emit=function(a){this.mode&&(this.state=j),this.onValue(a)},b.onValue=function(a){},b.onToken=function(a,b){this.state===e?a===t||a===f||a===F||a===G||a===H?(this.value&&(this.value[this.key]=b),this.emit(b)):a===M?(this.push(),this.value?this.value=this.value[this.key]={}:this.value={},this.key=undefined,this.state=r,this.mode=g):a===J?(this.push(),this.value?this.value=this.value[this.key]=[]:this.value=[],this.key=0,this.mode=k,this.state=e):a===h?this.mode===g?this.pop():this.parseError(a,b):a===n?this.mode===k?this.pop():this.parseError(a,b):this.parseError(a,b):this.state===r?a===t?(this.key=b,this.state=i):a===h?this.pop():this.parseError(a,b):this.state===i?a===i?this.state=e:this.parseError(a,b):this.state===j?a===j?this.mode===k?(this.key++,this.state=e):this.mode===g&&(this.state=r):a===n&&this.mode===k||a===h&&this.mode===g?this.pop():this.parseError(a,b):this.parseError(a,b)},U.exports=S},{__browserify_Buffer:13}],4:[function(b,e,f){function a(f,g){function i(){while(b.length&&!a.paused){var c=b.shift();if(null===c)return a.emit('end');a.emit('data',c)}}function j(){a.writable=!1,g.call(a),a.readable||a.destroy()}f=f||function(a){this.queue(a)},g=g||function(){this.queue(null)};var e=!1,h=!1,b=[],a=new d;return a.readable=a.writable=!0,a.paused=!1,a.write=function(b){return f.call(this,b),!a.paused},a.queue=a.push=function(c){return b.push(c),i(),a},a.on('end',function(){a.readable=!1,a.writable||c.nextTick(function(){a.destroy()})}),a.end=function(b){return e?void 0:(e=!0,arguments.length&&a.write(b),j(),a)},a.destroy=function(){return h?void 0:(h=!0,e=!0,b.length=0,a.writable=a.readable=!1,a.emit('close'),a)},a.pause=function(){return a.paused?void 0:(a.paused=!0,a.emit('pause'),a)},a.resume=function(){return a.paused&&(a.paused=!1),i(),a.paused||a.emit('drain'),a},a}var c=b('__browserify_process'),d=b('stream');f=e.exports=a,a.through=a},{__browserify_process:14,stream:10}],5:[function(h,i,j){function e(a){a.idle=!a.idle;var d=+new Date-a.olddate;if(a.olddate=+new Date,a.idle&&d<a.timeout){a.idle=!1,clearTimeout(a.timer_id),a.enabled&&(a.timer_id=setTimeout(a.state_fn,a.timeout));return}var e=a.idle?'idle':'active',c=e==='idle'?a.idle_fn:a.active_fn;for(var b=0;b<c.length;++b)c[b]()}var c=h('xtend');i.exports=function(a){return new b({timeout:a})};var g={start:!0,enabled:!0,timeout:3e4,element:document,events:'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove'},b=function(b){var a=this;a.opt=c(g,b),a.element=a.opt.element,a.state={idle:a.opt.idle,timeout:a.opt.timeout,enabled:a.opt.enabled,idle_fn:[],active_fn:[]},a.state.state_fn=function(){e(a.state)},a.opt.start&&a.start()},a=b.prototype;a.start=function(){function g(b){if(clearTimeout(a.timer_id),!a.enabled)return;a.idle&&e(a),a.timer_id=setTimeout(a.state_fn,a.timeout)}var b=this,a=b.state,h=b.element;a.handler=g;var d=this.opt.events.split(' ');for(var c=0;c<d.length;++c){var i=d[c];f(h,i,g)}a.timer_id=setTimeout(b.state.state_fn,a.timeout)},a.on=function(d,b){var c=this,a=c.state;d==='idle'?a.idle_fn.push(b):a.active_fn.push(b)},a.getElapsed=function(){return+new Date-this.state.olddate},a.stop=function(){var e=this,a=this.state,f=e.element;a.enabled=!1,clearTimeout(a.timer_id);var c=this.opt.events.split(' ');for(var b=0;b<c.length;++b){var g=c[b];d(f,g,a.handler)}};var f=function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent('on'+b,c)},d=function(a,b,c){a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent('on'+b,c)}},{xtend:6}],6:[function(f,b,g){function c(){var f={};for(var b=0;b<arguments.length;b++){var c=arguments[b];if(!e(c))continue;var g=a(c);for(var d=0;d<g.length;d++){var h=g[d];f[h]=c[h]}}return f}function d(c){var a=[];for(var b in c)a.push(b);return a}function e(a){return a!==null&&typeof a==='object'}var a=Object.keys||d;b.exports=c},{}],7:[function(e,h,f){function g(b,c){if(b.indexOf)return b.indexOf(c);for(var a=0;a<b.length;a++)if(c===b[a])return a;return-1}var c=e('__browserify_process');c.EventEmitter||(c.EventEmitter=function(){});var a=f.EventEmitter=c.EventEmitter,b=typeof Array.isArray==='function'?Array.isArray:function(a){return Object.prototype.toString.call(a)==='[object Array]'},d=10;a.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},a.prototype.emit=function(f){if(f==='error'&&(!(this._events&&this._events.error)||b(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var a=this._events[f];if(!a)return!1;if(!(typeof a=='function'))if(b(a)){var c=Array.prototype.slice.call(arguments,1),e=a.slice();for(var d=0,g=e.length;d<g;d++)e[d].apply(this,c);return!0}else return!1;switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:var c=Array.prototype.slice.call(arguments,1);a.apply(this,c)}return!0},a.prototype.addListener=function(a,c){if('function'!==typeof c)throw new Error('addListener only takes instances of Function');if(this._events||(this._events={}),this.emit('newListener',a,c),!this._events[a])this._events[a]=c;else if(b(this._events[a])){if(!this._events[a].warned){var e;this._events.maxListeners!==undefined?e=this._events.maxListeners:e=d,e&&e>0&&this._events[a].length>e&&(this._events[a].warned=!0,console.error('(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.',this._events[a].length),console.trace())}this._events[a].push(c)}else this._events[a]=[this._events[a],c];return this},a.prototype.on=a.prototype.addListener,a.prototype.once=function(b,c){var a=this;return a.on(b,function d(){a.removeListener(b,d),c.apply(this,arguments)}),this},a.prototype.removeListener=function(a,d){if('function'!==typeof d)throw new Error('removeListener only takes instances of Function');if(!(this._events&&this._events[a]))return this;var c=this._events[a];if(b(c)){var e=g(c,d);if(e<0)return this;c.splice(e,1),c.length==0&&delete this._events[a]}else this._events[a]===d&&delete this._events[a];return this},a.prototype.removeAllListeners=function(a){return arguments.length===0?(this._events={},this):(a&&this._events&&this._events[a]&&(this._events[a]=null),this)},a.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),b(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]},a.listenerCount=function(a,c){var b;return a._events&&a._events[c]?typeof a._events[c]==='function'?b=1:b=a._events[c].length:b=0,b}},{__browserify_process:14}],8:[function(a,b,c){},{}],9:[function(u,v,l){function i(a,b){if(a[b].length==0)return a[b]={};var c={};for(var d in a[b])c[d]=a[b][d];return a[b]=c,c}function f(l,e,g,k){var j=l.shift();if(!j)a(e[g])?e[g].push(k):'object'==typeof e[g]?e[g]=k:void 0===e[g]?e[g]=k:e[g]=[e[g],k];else{var h=e[g]=e[g]||[];']'==j?a(h)?''!=k&&h.push(k):'object'==typeof h?h[d(h).length]=k:h=e[g]=[e[g],k]:~b(j,']')?(j=j.substr(0,j.length-1),!c.test(j)&&a(h)&&(h=i(e,g)),f(l,h,j,k)):(!c.test(j)&&a(h)&&(h=i(e,g)),f(l,h,j,k))}}function k(d,e,j){if(~b(e,']')){var g=e.split('['),k=g.length,l=k-1;f(g,d,'base',j)}else{if(!c.test(e)&&a(d.base)){var h={};for(var i in d.base)h[i]=d.base[i];d.base=h}t(d.base,e,j)}return d}function o(b){var a={base:{}};return j(d(b),function(c){k(a,c,b[c])}),a.base}function p(a){return m(String(a).split('&'),function(g,c){var e=b(c,'='),f=n(c),d=c.substr(0,f||e),a=c.substr(f||e,c.length),a=a.substr(b(a,'=')+1,a.length);return''==d&&(d=c,a=''),''==d?g:k(g,h(d),h(a))},{base:{}}).base}function q(b,a){if(!a)throw new TypeError('stringify expects an object');return a+'='+encodeURIComponent(b)}function r(c,d){var b=[];if(!d)throw new TypeError('stringify expects an object');for(var a=0;a<c.length;a++)b.push(e(c[a],d+'['+a+']'));return b.join('&')}function s(f,h){var b=[],g=d(f),a;for(var c=0,i=g.length;c<i;++c)a=g[c],null==f[a]?b.push(encodeURIComponent(a)+'='):b.push(e(f[a],h?h+'['+encodeURIComponent(a)+']':encodeURIComponent(a)));return b.join('&')}function t(c,d,e){var b=c[d];undefined===b?c[d]=e:a(b)?b.push(e):c[d]=[b,e]}function n(d){var e=d.length,c,b;for(var a=0;a<e;++a)if(b=d[a],']'==b&&(c=!1),'['==b&&(c=!0),'='==b&&!c)return a}function h(a){try{return decodeURIComponent(a.replace(/\+/g,' '))}catch(b){return a}}var g=Object.prototype.toString,b=typeof Array.prototype.indexOf==='function'?function(a,b){return a.indexOf(b)}:function(b,c){for(var a=0;a<b.length;a++)if(b[a]===c)return a;return-1},a=Array.isArray||function(a){return g.call(a)=='[object Array]'},d=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},j=typeof Array.prototype.forEach==='function'?function(a,b){return a.forEach(b)}:function(b,c){for(var a=0;a<b.length;a++)c(b[a])},m=function(a,d,e){if(typeof a.reduce==='function')return a.reduce(d,e);var b=e;for(var c=0;c<a.length;c++)b=d(b,a[c]);return b},c=/^[0-9]+$/;l.parse=function(a){return null==a||''==a?{}:'object'==typeof a?o(a):p(a)};var e=l.stringify=function(b,c){return a(b)?r(b,c):'[object Object]'==g.call(b)?s(b,c):'string'==typeof b?q(b,c):c+'='+encodeURIComponent(String(b))}},{}],10:[function(c,e,f){function a(){b.EventEmitter.call(this)}var b=c('events'),d=c('util');d.inherits(a,b.EventEmitter),e.exports=a,a.Stream=a,a.prototype.pipe=function(a,h){function i(c){a.writable&&!1===a.write(c)&&b.pause&&b.pause()}function j(){b.readable&&b.resume&&b.resume()}function f(){if(d)return;if(d=!0,a._pipeCount--,c(),a._pipeCount>0)return;a.end()}function g(){if(d)return;if(d=!0,a._pipeCount--,c(),a._pipeCount>0)return;a.destroy()}function e(a){if(c(),this.listeners('error').length===0)throw a}function c(){b.removeListener('data',i),a.removeListener('drain',j),b.removeListener('end',f),b.removeListener('close',g),b.removeListener('error',e),a.removeListener('error',e),b.removeListener('end',c),b.removeListener('close',c),a.removeListener('end',c),a.removeListener('close',c)}var b=this;b.on('data',i),a.on('drain',j),!a._isStdio&&(!h||h.end!==!1)&&(a._pipeCount=a._pipeCount||0,a._pipeCount++,b.on('end',f),b.on('close',g));var d=!1;return b.on('error',e),a.on('error',e),b.on('end',c),b.on('close',c),a.on('end',c),a.on('close',c),a.emit('pipe',b),a}},{events:7,util:12}],11:[function(v,y,g){function b(b,d){for(var a=0,c=b.length;a<c;a++)if(b[a]==d)return a;return-1}function h(x,X,Y){if(x&&typeof x==='object'&&x.href)return x;if(typeof x!=='string')throw new TypeError("Parameter 'url' must be a string, not "+typeof x);var g={},o=x;for(var h=0,p=o.length;h<p;h++)if(b(d,o.charAt(h))===-1)break;h!==0&&(o=o.substr(h));var s=u.exec(o);if(s){s=s[0];var M=s.toLowerCase();g.protocol=M,o=o.substr(s.length)}if(Y||s||o.match(/^\/\/[^@\/]+@[^@\/]+/)){var Q=o.substr(0,2)==='//';Q&&!(s&&f[s])&&(o=o.substr(2),g.slashes=!0)}if(!f[s]&&(Q||s&&!c[s])){var A=b(o,'@');if(A!==-1){var U=!0;for(var h=0,p=e.length;h<p;h++){var v=b(o,e[h]);if(v!==-1&&v<A){U=!1;break}}U&&(g.auth=o.substr(0,A),o=o.substr(A+1))}var y=-1;for(var h=0,p=k.length;h<p;h++){var v=b(o,k[h]);v!==-1&&(y<0||v<y)&&(y=v)}y!==-1?(g.host=o.substr(0,y),o=o.substr(y)):(g.host=o,o='');var N=w(g.host),P=j(N);for(var h=0,p=P.length;h<p;h++){var V=P[h];g[V]=N[V]}if(g.hostname=g.hostname||'',g.hostname.length>t)g.hostname='';else{var C=g.hostname.split(/\./);for(var h=0,p=C.length;h<p;h++){var z=C[h];if(!z)continue;if(!z.match(m)){var F='';for(var E=0,W=z.length;E<W;E++)z.charCodeAt(E)>127?F+='x':F+=z[E];if(!F.match(m)){var O=C.slice(0,h),H=C.slice(h+1),I=z.match(n);I&&(O.push(I[1]),H.unshift(I[2])),H.length&&(o='/'+H.join('.')+o),g.hostname=O.join('.');break}}}}g.hostname=g.hostname.toLowerCase();var R=g.hostname.split('.'),S=[];for(var h=0;h<R.length;++h){var J=R[h];S.push(J.match(/[^A-Za-z0-9_-]/)?'xn--'+r.encode(J):J)}g.hostname=S.join('.'),g.host=(g.hostname||'')+(g.port?':'+g.port:''),g.href+=g.host}if(!q[M]){for(var h=0,p=i.length;h<p;h++){var B=i[h],L=encodeURIComponent(B);L===B&&(L=escape(B)),o=o.split(B).join(L)}var G=o.length;for(var h=0,p=d.length;h<p;h++){var T=b(o,d[h]);T!==-1&&(G=Math.min(T,G))}o=o.substr(0,G)}var K=b(o,'#');K!==-1&&(g.hash=o.substr(K),o=o.slice(0,K));var D=b(o,'?');return D!==-1?(g.search=o.substr(D),g.query=o.substr(D+1),X&&(g.query=l.parse(g.query)),o=o.slice(0,D)):X&&(g.search='',g.query={}),o&&(g.pathname=o),c[s]&&g.hostname&&!g.pathname&&(g.pathname='/'),(g.pathname||g.search)&&(g.path=(g.pathname?g.pathname:'')+(g.search?g.search:'')),g.href=a(g),g}function a(a){typeof a==='string'&&(a=h(a));var b=a.auth||'';if(b){b=b.split('@').join('%40');for(var m=0,p=e.length;m<p;m++){var n=e[m];b=b.split(n).join(encodeURIComponent(n))}b+='@'}var d=a.protocol||'',f=a.host!==undefined?b+a.host:a.hostname!==undefined?b+a.hostname+(a.port?':'+a.port:''):!1,g=a.pathname||'',o=a.query&&(typeof a.query==='object'&&j(a.query).length?l.stringify(a.query):'')||'',k=a.search||o&&'?'+o||'',i=a.hash||'';return d&&d.substr(-1)!==':'&&(d+=':'),a.slashes||(!d||c[d])&&f!==!1?(f='//'+(f||''),g&&g.charAt(0)!=='/'&&(g='/'+g)):f||(f=''),i&&i.charAt(0)!=='#'&&(i='#'+i),k&&k.charAt(0)!=='?'&&(k='?'+k),d+f+g+k+i}function x(b,c){return a(o(b,c))}function o(d,e){if(!d)return e;if(d=h(a(d),!1,!0),e=h(a(e),!1,!0),d.hash=e.hash,e.href==='')return d.href=a(d),d;if(e.slashes&&!e.protocol)return e.protocol=d.protocol,c[e.protocol]&&e.hostname&&!e.pathname&&(e.path=e.pathname='/'),e.href=a(e),e;if(e.protocol&&e.protocol!==d.protocol){if(!c[e.protocol])return e.href=a(e),e;if(d.protocol=e.protocol,!(e.host||f[e.protocol])){var i=(e.pathname||'').split('/');while(i.length&&!(e.host=i.shift()));e.host||(e.host=''),e.hostname||(e.hostname=''),i[0]!==''&&i.unshift(''),i.length<2&&i.unshift(''),e.pathname=i.join('/')}return d.pathname=e.pathname,d.search=e.search,d.query=e.query,d.host=e.host||'',d.auth=e.auth,d.hostname=e.hostname||e.host,d.port=e.port,(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.slashes=d.slashes||e.slashes,d.href=a(d),d}var t=d.pathname&&d.pathname.charAt(0)==='/',q=e.host!==undefined||e.pathname&&e.pathname.charAt(0)==='/',j=q||t||d.host&&e.pathname,s=j,g=d.pathname&&d.pathname.split('/')||[],i=e.pathname&&e.pathname.split('/')||[],o=d.protocol&&!c[d.protocol];if(o&&(delete d.hostname,delete d.port,d.host&&(g[0]===''?g[0]=d.host:g.unshift(d.host)),delete d.host,e.protocol&&(delete e.hostname,delete e.port,e.host&&(i[0]===''?i[0]=e.host:i.unshift(e.host)),delete e.host),j=j&&(i[0]===''||g[0]==='')),q)d.host=e.host||e.host===''?e.host:d.host,d.hostname=e.hostname||e.hostname===''?e.hostname:d.hostname,d.search=e.search,d.query=e.query,g=i;else if(i.length)g||(g=[]),g.pop(),g=g.concat(i),d.search=e.search,d.query=e.query;else if('search'in e){if(o){d.hostname=d.host=g.shift();var k=d.host&&b(d.host,'@')>0?d.host.split('@'):!1;k&&(d.auth=k.shift(),d.host=d.hostname=k.shift())}return d.search=e.search,d.query=e.query,(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.href=a(d),d}if(!g.length)return delete d.pathname,d.search?delete d.path:d.path='/'+d.search,d.href=a(d),d;var m=g.slice(-1)[0],r=(d.host||e.host)&&(m==='.'||m==='..')||m==='',n=0;for(var l=g.length;l>=0;l--)m=g[l],m=='.'?g.splice(l,1):m==='..'?(g.splice(l,1),n++):n&&(g.splice(l,1),n--);if(!(j||s))for(;n--;n)g.unshift('..');j&&g[0]!==''&&(!g[0]||g[0].charAt(0)!=='/')&&g.unshift(''),r&&g.join('/').substr(-1)!=='/'&&g.push('');var p=g[0]===''||g[0]&&g[0].charAt(0)==='/';if(o){d.hostname=d.host=p?'':g.length?g.shift():'';var k=d.host&&b(d.host,'@')>0?d.host.split('@'):!1;k&&(d.auth=k.shift(),d.host=d.hostname=k.shift())}return j=j||d.host&&g.length,j&&!p&&g.unshift(''),d.pathname=g.join('/'),(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.auth=e.auth||d.auth,d.slashes=d.slashes||e.slashes,d.href=a(d),d}function w(a){var c={},b=s.exec(a);return b&&(b=b[0],c.port=b.substr(1),a=a.substr(0,a.length-b.length)),a&&(c.hostname=a),c}var r={encode:function(a){return a}};g.parse=h,g.resolve=x,g.resolveObject=o,g.format=a;var j=Object.keys||function a(a){if(a!==Object(a))throw new TypeError('Invalid object');var b=[];for(var c in a)a.hasOwnProperty(c)&&(b[b.length]=c);return b},u=/^([a-z0-9.+-]+:)/i,s=/:[0-9]+$/,d=['<','>','"','`',' ','\r','\n',' '],p=['{','}','|','\\','^','~','[',']','`'].concat(d),i=["'"],k=['%','/','?',';','#'].concat(p).concat(i),e=['/','@','?','#'].concat(d),t=255,m=/^[a-zA-Z0-9][a-z0-9A-Z_-]{0,62}$/,n=/^([a-zA-Z0-9][a-z0-9A-Z_-]{0,62})(.*)$/,q={javascript:!0,'javascript:':!0},f={javascript:!0,'javascript:':!0},c={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,'http:':!0,'https:':!0,'ftp:':!0,'gopher:':!0,'file:':!0},l=v('querystring')},{querystring:9}],12:[function(j,k,a){function b(a){return Array.isArray(a)||typeof a==='object'&&Object.prototype.toString.call(a)==='[object Array]'}function c(a){typeof a==='object'&&Object.prototype.toString.call(a)==='[object RegExp]'}function d(a){return typeof a==='object'&&Object.prototype.toString.call(a)==='[object Date]'}var i=j('events');a.isArray=b,a.isDate=function(a){return Object.prototype.toString.call(a)==='[object Date]'},a.isRegExp=function(a){return Object.prototype.toString.call(a)==='[object RegExp]'},a.print=function(){},a.puts=function(){},a.debug=function(){},a.inspect=function(k,l,j,m){function i(j,p){if(j&&typeof j.inspect==='function'&&j!==a&&!(j.constructor&&j.constructor.prototype===j))return j.inspect(p);switch(typeof j){case'undefined':return e('undefined','undefined');case'string':var w="'"+JSON.stringify(j).replace(/^"|"$/g,'').replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e(w,'string');case'number':return e(''+j,'number');case'boolean':return e(''+j,'boolean')}if(j===null)return e('null','null');var q=h(j),o=l?g(j):q;if(typeof j==='function'&&o.length===0)if(c(j))return e(''+j,'regexp');else{var t=j.name?': '+j.name:'';return e('[Function'+t+']','special')}if(d(j)&&o.length===0)return e(j.toUTCString(),'date');var m,r,k;if(b(j)?(r='Array',k=['[',']']):(r='Object',k=['{','}']),typeof j==='function'){var u=j.name?': '+j.name:'';m=c(j)?' '+j:' [Function'+u+']'}else m='';if(d(j)&&(m=' '+j.toUTCString()),o.length===0)return k[0]+m+k[1];if(p<0)return c(j)?e(''+j,'regexp'):e('[Object]','special');f.push(j);var n=o.map(function(d){var a,c;if(j.__lookupGetter__&&(j.__lookupGetter__(d)?j.__lookupSetter__(d)?c=e('[Getter/Setter]','special'):c=e('[Getter]','special'):j.__lookupSetter__(d)&&(c=e('[Setter]','special'))),q.indexOf(d)<0&&(a='['+d+']'),c||(f.indexOf(j[d])<0?(p===null?c=i(j[d]):c=i(j[d],p-1),c.indexOf('\n')>-1&&(b(j)?c=c.split('\n').map(function(a){return' '+a}).join('\n').substr(2):c='\n'+c.split('\n').map(function(a){return' '+a}).join('\n'))):c=e('[Circular]','special')),a===void 0){if(r==='Array'&&d.match(/^\d+$/))return c;a=JSON.stringify(''+d),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e(a,'name')):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e(a,'string'))}return a+': '+c});f.pop();var s=0,v=n.reduce(function(b,a){return s++,a.indexOf('\n')>=0&&s++,b+a.length+1},0);return v>50?n=k[0]+(m===''?'':m+'\n ')+' '+n.join(',\n ')+' '+k[1]:n=k[0]+m+' '+n.join(', ')+' '+k[1],n}var f=[],e=function(c,d){var b={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a={special:'cyan',number:'blue',boolean:'yellow',undefined:'grey',null:'bold',string:'green',date:'magenta',regexp:'red'}[d];return a?'['+b[a][0]+'m'+c+'['+b[a][1]+'m':c};return m||(e=function(a,b){return a}),i(k,j===void 0?2:j)},a.log=function(a){},a.pump=null;var h=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},g=Object.getOwnPropertyNames||function(c){var a=[];for(var b in c)Object.hasOwnProperty.call(c,b)&&a.push(b);return a},e=Object.create||function(a,d){var b;if(a===null)b={__proto__:null};else{if(typeof a!=='object')throw new TypeError('typeof prototype['+typeof a+"] != 'object'");var c=function(){};c.prototype=a,b=new c,b.__proto__=a}return d!==void 0&&Object.defineProperties&&Object.defineProperties(b,d),b};a.inherits=function(a,b){a.super_=b,a.prototype=e(b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}})};var f=/%[sdj%]/g;a.format=function(i){if(typeof i!=='string'){var g=[];for(var b=0;b<arguments.length;b++)g.push(a.inspect(arguments[b]));return g.join(' ')}var b=1,c=arguments,h=c.length,e=String(i).replace(f,function(a){if(a==='%%')return'%';if(b>=h)return a;switch(a){case'%s':return String(c[b++]);case'%d':return Number(c[b++]);case'%j':return JSON.stringify(c[b++]);default:return a}});for(var d=c[b];b<h;d=c[++b])d===null||typeof d!=='object'?e+=' '+d:e+=' '+a.inspect(d);return e}},{events:7}],13:[function(a,b,c){a=function(e,b,c,f,a){function d(a){if(!c[a]){if(!b[a]){if(e)return e(a);throw new Error("Cannot find module '"+a+"'")}var f=c[a]={exports:{}};b[a][0](function(e){var c=b[a][1][e];return d(c?c:e)},f,f.exports)}return c[a].exports}for(a=0;a<f.length;a++)d(f[a]);return d}(a!==void 0&&a,{1:[function(j,q,r){function h(a){if(Object.keys)return Object.keys(a);var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}function l(b,a){return a===undefined?''+a:typeof a==='number'&&(isNaN(a)||!isFinite(a))?a.toString():typeof a==='function'||a instanceof RegExp?a.toString():a}function g(a,b){return typeof a=='string'?a.length<b?a:a.slice(0,b):a}function b(b,c,d,e,f){throw new a.AssertionError({message:d,actual:b,expected:c,operator:e,stackStartFunction:f})}function i(c,d){c||b(c,!0,d,'==',a.ok)}function d(a,b){if(a===b)return!0;else if(e.isBuffer(a)&&e.isBuffer(b)){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0}else return a instanceof Date&&b instanceof Date?a.getTime()===b.getTime():typeof a!='object'&&typeof b!='object'?a==b:p(a,b)}function k(a){return a===null||a===undefined}function f(a){return Object.prototype.toString.call(a)=='[object Arguments]'}function p(b,e){if(k(b)||k(e))return!1;if(b.prototype!==e.prototype)return!1;if(f(b))return f(e)?(b=c.call(b),e=c.call(e),d(b,e)):!1;try{var g=h(b),i=h(e),j,a}catch(a){return!1}if(g.length!=i.length)return!1;for(g.sort(),i.sort(),a=g.length-1;a>=0;a--)if(g[a]!=i[a])return!1;for(a=g.length-1;a>=0;a--)if(j=g[a],!d(b[j],e[j]))return!1;return!0}function n(b,a){return b&&a?a instanceof RegExp?a.test(b):b instanceof a?!0:a.call({},b)===!0?!0:!1:!1}function o(e,f,a,d){var c;typeof a==='string'&&(d=a,a=null);try{f()}catch(a){c=a}if(d=(a&&a.name?' ('+a.name+').':'.')+(d?' '+d:'.'),e&&!c&&b('Missing expected exception'+d),!e&&n(c,a)&&b('Got unwanted exception'+d),e&&c&&a&&!n(c,a)||!e&&c)throw c}var m=j('util'),e=j('buffer').Buffer,c=Array.prototype.slice,a=q.exports=i;a.AssertionError=function a(a){this.name='AssertionError',this.message=a.message,this.actual=a.actual,this.expected=a.expected,this.operator=a.operator;var c=a.stackStartFunction||b;Error.captureStackTrace&&Error.captureStackTrace(this,c)},m.inherits(a.AssertionError,Error),a.AssertionError.prototype.toString=function(){return this.message?[this.name+':',this.message].join(' '):[this.name+':',g(JSON.stringify(this.actual,l),128),this.operator,g(JSON.stringify(this.expected,l),128)].join(' ')},a.AssertionError.__proto__=Error.prototype,a.fail=b,a.ok=i,a.equal=function c(c,d,e){c!=d&&b(c,d,e,'==',a.equal)},a.notEqual=function c(c,d,e){c==d&&b(c,d,e,'!=',a.notEqual)},a.deepEqual=function c(c,e,f){d(c,e)||b(c,e,f,'deepEqual',a.deepEqual)},a.notDeepEqual=function c(c,e,f){d(c,e)&&b(c,e,f,'notDeepEqual',a.notDeepEqual)},a.strictEqual=function c(c,d,e){c!==d&&b(c,d,e,'===',a.strictEqual)},a.notStrictEqual=function c(c,d,e){c===d&&b(c,d,e,'!==',a.notStrictEqual)},a.throws=function(a,b,d){o.apply(this,[!0].concat(c.call(arguments)))},a.doesNotThrow=function(a,b,d){o.apply(this,[!1].concat(c.call(arguments)))},a.ifError=function(a){if(a)throw a}},{util:2,buffer:3}],2:[function(j,k,a){function b(a){return a instanceof Array||Array.isArray(a)||a&&a!==Object.prototype&&b(a.__proto__)}function d(a){return a instanceof RegExp||typeof a==='object'&&Object.prototype.toString.call(a)==='[object RegExp]'}function e(a){if(a instanceof Date)return!0;if(typeof a!=='object')return!1;var b=Date.prototype&&c(Date.prototype),d=a.__proto__&&c(a.__proto__);return JSON.stringify(d)===JSON.stringify(b)}var i=j('events');a.isArray=b,a.isDate=function(a){return Object.prototype.toString.call(a)==='[object Date]'},a.isRegExp=function(a){return Object.prototype.toString.call(a)==='[object RegExp]'},a.print=function(){},a.puts=function(){},a.debug=function(){},a.inspect=function(k,l,j,m){function i(j,p){if(j&&typeof j.inspect==='function'&&j!==a&&!(j.constructor&&j.constructor.prototype===j))return j.inspect(p);switch(typeof j){case'undefined':return f('undefined','undefined');case'string':var w="'"+JSON.stringify(j).replace(/^"|"$/g,'').replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return f(w,'string');case'number':return f(''+j,'number');case'boolean':return f(''+j,'boolean')}if(j===null)return f('null','null');var q=h(j),o=l?c(j):q;if(typeof j==='function'&&o.length===0)if(d(j))return f(''+j,'regexp');else{var t=j.name?': '+j.name:'';return f('[Function'+t+']','special')}if(e(j)&&o.length===0)return f(j.toUTCString(),'date');var m,r,k;if(b(j)?(r='Array',k=['[',']']):(r='Object',k=['{','}']),typeof j==='function'){var u=j.name?': '+j.name:'';m=d(j)?' '+j:' [Function'+u+']'}else m='';if(e(j)&&(m=' '+j.toUTCString()),o.length===0)return k[0]+m+k[1];if(p<0)return d(j)?f(''+j,'regexp'):f('[Object]','special');g.push(j);var n=o.map(function(d){var a,c;if(j.__lookupGetter__&&(j.__lookupGetter__(d)?j.__lookupSetter__(d)?c=f('[Getter/Setter]','special'):c=f('[Getter]','special'):j.__lookupSetter__(d)&&(c=f('[Setter]','special'))),q.indexOf(d)<0&&(a='['+d+']'),c||(g.indexOf(j[d])<0?(p===null?c=i(j[d]):c=i(j[d],p-1),c.indexOf('\n')>-1&&(b(j)?c=c.split('\n').map(function(a){return' '+a}).join('\n').substr(2):c='\n'+c.split('\n').map(function(a){return' '+a}).join('\n'))):c=f('[Circular]','special')),a===void 0){if(r==='Array'&&d.match(/^\d+$/))return c;a=JSON.stringify(''+d),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=f(a,'name')):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=f(a,'string'))}return a+': '+c});g.pop();var s=0,v=n.reduce(function(b,a){return s++,a.indexOf('\n')>=0&&s++,b+a.length+1},0);return v>50?n=k[0]+(m===''?'':m+'\n ')+' '+n.join(',\n ')+' '+k[1]:n=k[0]+m+' '+n.join(', ')+' '+k[1],n}var g=[],f=function(c,d){var b={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a={special:'cyan',number:'blue',boolean:'yellow',undefined:'grey',null:'bold',string:'green',date:'magenta',regexp:'red'}[d];return a?'['+b[a][0]+'m'+c+'['+b[a][1]+'m':c};return m||(f=function(a,b){return a}),i(k,j===void 0?2:j)},a.log=function(a){},a.pump=null;var h=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},c=Object.getOwnPropertyNames||function(c){var a=[];for(var b in c)Object.hasOwnProperty.call(c,b)&&a.push(b);return a},g=Object.create||function(a,d){var b;if(a===null)b={__proto__:null};else{if(typeof a!=='object')throw new TypeError('typeof prototype['+typeof a+"] != 'object'");var c=function(){};c.prototype=a,b=new c,b.__proto__=a}return d!==void 0&&Object.defineProperties&&Object.defineProperties(b,d),b};a.inherits=function(a,b){a.super_=b,a.prototype=g(b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}})};var f=/%[sdj%]/g;a.format=function(i){if(typeof i!=='string'){var g=[];for(var b=0;b<arguments.length;b++)g.push(a.inspect(arguments[b]));return g.join(' ')}var b=1,c=arguments,h=c.length,e=String(i).replace(f,function(a){if(a==='%%')return'%';if(b>=h)return a;switch(a){case'%s':return String(c[b++]);case'%d':return Number(c[b++]);case'%j':return JSON.stringify(c[b++]);default:return a}});for(var d=c[b];b<h;d=c[++b])d===null||typeof d!=='object'?e+=' '+d:e+=' '+a.inspect(d);return e}},{events:4}],5:[function(b,c,a){a.readIEEE754=function(h,l,n,f,m){var b,d,i=m*8-f-1,j=(1<<i)-1,k=j>>1,a=-7,c=n?0:m-1,g=n?1:-1,e=h[l+c];for(c+=g,b=e&(1<<-a)-1,e>>=-a,a+=i;a>0;b=b*256+h[l+c],c+=g,a-=8);for(d=b&(1<<-a)-1,b>>=-a,a+=f;a>0;d=d*256+h[l+c],c+=g,a-=8);if(b===0)b=1-k;else if(b===j)return d?NaN:(e?-1:1)*Infinity;else d+=Math.pow(2,f),b-=k;return(e?-1:1)*d*Math.pow(2,b-f)},a.writeIEEE754=function(k,b,m,n,c,p){var a,d,f,h=p*8-c-1,i=(1<<h)-1,e=i>>1,l=c===23?Math.pow(2,-24)-Math.pow(2,-77):0,g=n?p-1:0,j=n?-1:1,o=b<0||b===0&&1/b<0?1:0;for(b=Math.abs(b),isNaN(b)||b===Infinity?(d=isNaN(b)?1:0,a=i):(a=Math.floor(Math.log(b)/Math.LN2),b*(f=Math.pow(2,-a))<1&&(a--,f*=2),a+e>=1?b+=l/f:b+=l*Math.pow(2,1-e),b*f>=2&&(a++,f/=2),a+e>=i?(d=0,a=i):a+e>=1?(d=(b*f-1)*Math.pow(2,c),a+=e):(d=b*Math.pow(2,e-1)*Math.pow(2,c),a=0));c>=8;k[m+g]=d&255,g+=j,d/=256,c-=8);for(a=a<<c|d,h+=c;h>0;k[m+g]=a&255,g+=j,a/=256,h-=8);k[m+g-j]|=o*128}},{}],6:[function(c,b,d){var a=b.exports={};a.nextTick=function(b,c,a){return b=typeof window!=='undefined'&&window.setImmediate,c=typeof window!=='undefined'&&window.postMessage&&window.addEventListener,b?function(a){return window.setImmediate(a)}:c?(a=[],window.addEventListener('message',function(b){if(b.source===window&&b.data==='process-tick'&&(b.stopPropagation(),a.length>0)){var c=a.shift();c()}},!0),function b(b){a.push(b),window.postMessage('process-tick','*')}):function a(a){setTimeout(a,0)}}(),a.title='browser',a.browser=!0,a.env={},a.argv=[],a.binding=function(a){throw new Error('process.binding is not supported')},a.cwd=function(){return'/'},a.chdir=function(a){throw new Error('process.chdir is not supported')}},{}],4:[function(a,c,b){!function(d,a,c,e){function f(b,c){if(b.indexOf)return b.indexOf(c);for(var a=0;a<b.length;a++)if(c===b[a])return a;return-1}d.EventEmitter||(d.EventEmitter=function(){}),a=b.EventEmitter=d.EventEmitter,c=typeof Array.isArray==='function'?Array.isArray:function(a){return Object.prototype.toString.call(a)==='[object Array]'},e=10,a.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},a.prototype.emit=function(f){if(f==='error'&&(!(this._events&&this._events.error)||c(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var a=this._events[f];if(!a)return!1;if(!(typeof a=='function'))if(c(a)){var b=Array.prototype.slice.call(arguments,1),e=a.slice();for(var d=0,g=e.length;d<g;d++)e[d].apply(this,b);return!0}else return!1;switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:var b=Array.prototype.slice.call(arguments,1);a.apply(this,b)}return!0},a.prototype.addListener=function(a,b){if('function'!==typeof b)throw new Error('addListener only takes instances of Function');if(this._events||(this._events={}),this.emit('newListener',a,b),!this._events[a])this._events[a]=b;else if(c(this._events[a])){if(!this._events[a].warned){var d;this._events.maxListeners!==undefined?d=this._events.maxListeners:d=e,d&&d>0&&this._events[a].length>d&&(this._events[a].warned=!0,console.error('(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.',this._events[a].length),console.trace())}this._events[a].push(b)}else this._events[a]=[this._events[a],b];return this},a.prototype.on=a.prototype.addListener,a.prototype.once=function(b,c){var a=this;return a.on(b,function d(){a.removeListener(b,d),c.apply(this,arguments)}),this},a.prototype.removeListener=function(a,d){if('function'!==typeof d)throw new Error('removeListener only takes instances of Function');if(!(this._events&&this._events[a]))return this;var b=this._events[a];if(c(b)){var e=f(b,d);if(e<0)return this;b.splice(e,1),b.length==0&&delete this._events[a]}else this._events[a]===d&&delete this._events[a];return this},a.prototype.removeAllListeners=function(a){return arguments.length===0?(this._events={},this):(a&&this._events&&this._events[a]&&(this._events[a]=null),this)},a.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),c(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]}}(a('__browserify_process'))},{__browserify_process:6}],'buffer-browserify':[function(a,b,c){b.exports=a('q9TxCC')},{}],q9TxCC:[function(e,E,f){function c(a){this.length=a}function i(a){return a<16?'0'+a.toString(16):a.toString(16)}function w(b){var c=[];for(var a=0;a<b.length;a++)if(b.charCodeAt(a)<=127)c.push(b.charCodeAt(a));else{var e=encodeURIComponent(b.charAt(a)).substr(1).split('%');for(var d=0;d<e.length;d++)c.push(parseInt(e[d],16))}return c}function B(c){var b=[];for(var a=0;a<c.length;a++)b.push(c.charCodeAt(a)&255);return b}function p(a){return e('base64-js').toByteArray(a)}function j(b,c,d,e){var a=0;while(a<e){if(a+d>=c.length||a>=b.length)break;c[a+d]=b[a],a++}return a}function u(a){try{return decodeURIComponent(a)}catch(a){return String.fromCharCode(65533)}}function l(a){return a=~~Math.ceil(+a),a<0?0:a}function a(b,f,g){if(!(this instanceof a))return new a(b,f,g);var h;if(typeof g==='number')this.length=l(f),this.parent=b,this.offset=g;else{switch(h=typeof b){case'number':this.length=l(b);break;case'string':this.length=a.byteLength(b,f);break;case'object':this.length=l(b.length);break;default:throw new Error('First argument needs to be a number, array or string.')}if(this.length>a.poolSize?(this.parent=new c(this.length),this.offset=0):((!d||d.length-d.used<this.length)&&C(),this.parent=d,this.offset=d.used,d.used+=this.length),D(b))for(var e=0;e<this.length;e++)b instanceof a?this.parent[e+this.offset]=b.readUInt8(e):this.parent[e+this.offset]=b[e];else h=='string'&&(this.length=this.write(b,0,f))}}function D(b){return Array.isArray(b)||a.isBuffer(b)||b&&typeof b==='object'&&typeof b.length==='number'}function C(){d=new c(a.poolSize),d.used=0}function o(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<a.length,'Trying to read beyond buffer length')),c>=a.length?0:(e?(d=a.parent[a.offset+c]<<8,c+1<a.length&&(d|=a.parent[a.offset+c+1])):(d=a.parent[a.offset+c],c+1<a.length&&(d|=a.parent[a.offset+c+1]<<8)),d)}function n(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),c>=a.length?0:(e?(c+1<a.length&&(d=a.parent[a.offset+c+1]<<16),c+2<a.length&&(d|=a.parent[a.offset+c+2]<<8),c+3<a.length&&(d|=a.parent[a.offset+c+3]),d+=a.parent[a.offset+c]<<24>>>0):(c+2<a.length&&(d=a.parent[a.offset+c+2]<<16),c+1<a.length&&(d|=a.parent[a.offset+c+1]<<8),d|=a.parent[a.offset+c],c+3<a.length&&(d+=a.parent[a.offset+c+3]<<24>>>0)),d)}function v(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+1<d.length,'Trying to read beyond buffer length')),c=o(d,a,e,f),g=c&32768,g?(65535-c+1)*-1:c}function r(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+3<d.length,'Trying to read beyond buffer length')),c=n(d,a,e,f),g=c&2147483648,g?(4294967295-c+1)*-1:c}function s(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,23,4)}function t(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+7<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,52,8)}function k(a,c){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a>=0,'specified a negative value for writing an unsigned value'),b.ok(a<=c,'value is larger than maximum value for type'),b.ok(Math.floor(a)===a,'value has a fractional component')}function h(d,e,c,f,g){g||(b.ok(e!==undefined&&e!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'trying to write beyond buffer length'),k(e,65535));for(var a=0;a<Math.min(d.length-c,2);a++)d.parent[d.offset+c+a]=(e&255<<8*(f?1-a:a))>>>(f?1-a:a)*8}function g(d,e,c,f,g){g||(b.ok(e!==undefined&&e!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'trying to write beyond buffer length'),k(e,4294967295));for(var a=0;a<Math.min(d.length-c,4);a++)d.parent[d.offset+c+a]=e>>>(f?3-a:a)*8&255}function m(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value'),b.ok(Math.floor(a)===a,'value has a fractional component')}function x(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value')}function y(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'Trying to write beyond buffer length'),m(a,32767,-32768)),a>=0?h(d,a,c,e,f):h(d,65535+a+1,c,e,f)}function z(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),m(a,2147483647,-2147483648)),a>=0?g(d,a,c,e,f):g(d,4294967295+a+1,c,e,f)}function A(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),x(a,3.4028234663852886e38,-3.4028234663852886e38)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,23,4)}function q(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+7<d.length,'Trying to write beyond buffer length'),x(a,1.7976931348623157e308,-1.7976931348623157e308)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,52,8)}var b=e('assert');f.INSPECT_MAX_BYTES=50,c.byteLength=function(a,b){switch(b||'utf8'){case'hex':return a.length/2;case'utf8':case'utf-8':return w(a).length;case'ascii':case'binary':return a.length;case'base64':return p(a).length;default:throw new Error('Unknown encoding')}},c.prototype.utf8Write=function(a,b,d){return c._charsWritten=j(w(a),this,b,d)},c.prototype.asciiWrite=function(a,b,d){return c._charsWritten=j(B(a),this,b,d)},c.prototype.binaryWrite=c.prototype.asciiWrite,c.prototype.base64Write=function(a,b,d){return c._charsWritten=j(p(a),this,b,d)},c.prototype.base64Slice=function(b,c){var a=Array.prototype.slice.apply(this,arguments);return e('base64-js').fromByteArray(a)},c.prototype.utf8Slice=function(){var b=Array.prototype.slice.apply(this,arguments),d='',c='',a=0;while(a<b.length)b[a]<=127?(d+=u(c)+String.fromCharCode(b[a]),c=''):c+='%'+b[a].toString(16),a++;return d+u(c)},c.prototype.asciiSlice=function(){var b=Array.prototype.slice.apply(this,arguments),c='';for(var a=0;a<b.length;a++)c+=String.fromCharCode(b[a]);return c},c.prototype.binarySlice=c.prototype.asciiSlice,c.prototype.inspect=function(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this[a]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<SlowBuffer '+b.join(' ')+'>'},c.prototype.hexSlice=function(b,a){var d=this.length;(!b||b<0)&&(b=0),(!a||a<0||a>d)&&(a=d);var e='';for(var c=b;c<a;c++)e+=i(this[c]);return e},c.prototype.toString=function(c,a,b){if(c=String(c||'utf8').toLowerCase(),a=+a||0,b===void 0&&(b=this.length),+b==a)return'';switch(c){case'hex':return this.hexSlice(a,b);case'utf8':case'utf-8':return this.utf8Slice(a,b);case'ascii':return this.asciiSlice(a,b);case'binary':return this.binarySlice(a,b);case'base64':return this.base64Slice(a,b);case'ucs2':case'ucs-2':return this.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},c.prototype.hexWrite=function(h,d,a){d=+d||0;var e=this.length-d;a?(a=+a,a>e&&(a=e)):a=e;var f=h.length;if(f%2)throw new Error('Invalid hex string');a>f/2&&(a=f/2);for(var b=0;b<a;b++){var g=parseInt(h.substr(b*2,2),16);if(isNaN(g))throw new Error('Invalid hex string');this[d+b]=g}return c._charsWritten=b*2,b},c.prototype.write=function(c,b,a,d){if(isFinite(b))isFinite(a)||(d=a,a=undefined);else{var f=d;d=b,b=a,a=f}b=+b||0;var e=this.length-b;a?(a=+a,a>e&&(a=e)):a=e,d=String(d||'utf8').toLowerCase();switch(d){case'hex':return this.hexWrite(c,b,a);case'utf8':case'utf-8':return this.utf8Write(c,b,a);case'ascii':return this.asciiWrite(c,b,a);case'binary':return this.binaryWrite(c,b,a);case'base64':return this.base64Write(c,b,a);case'ucs2':case'ucs-2':return this.ucs2Write(c,b,a);default:throw new Error('Unknown encoding')}},c.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this,b-c,+c)},c.prototype.copy=function(e,d,f,g){var c=[];for(var a=f;a<g;a++)b.ok(this[a]!==void 0,'copying undefined buffer bytes!'),c.push(this[a]);for(var a=d;a<d+c.length;a++)e[a]=c[a-d]},c.prototype.fill=function(d,c,b){if(b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');for(var a=c;a<b;a++)this[a]=d},f.SlowBuffer=c,f.Buffer=a,a.poolSize=8192;var d;a.isBuffer=function b(b){return b instanceof a||b instanceof c},a.concat=function(c,e){if(!Array.isArray(c))throw new Error('Usage: Buffer.concat(list, [totalLength])\n list should be an Array.');if(c.length===0)return new a(0);if(c.length===1)return c[0];if(typeof e!=='number'){e=0;for(var b=0;b<c.length;b++){var d=c[b];e+=d.length}}var f=new a(e),g=0;for(var b=0;b<c.length;b++){var d=c[b];d.copy(f,g),g+=d.length}return f},a.prototype.inspect=function a(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this.parent[a+this.offset]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<Buffer '+b.join(' ')+'>'},a.prototype.get=function a(a){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]},a.prototype.set=function a(a,b){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]=b},a.prototype.write=function(f,d,b,g){if(isFinite(d))isFinite(b)||(g=b,b=undefined);else{var i=g;g=d,d=b,b=i}d=+d||0;var h=this.length-d;b?(b=+b,b>h&&(b=h)):b=h,g=String(g||'utf8').toLowerCase();var e;switch(g){case'hex':e=this.parent.hexWrite(f,this.offset+d,b);break;case'utf8':case'utf-8':e=this.parent.utf8Write(f,this.offset+d,b);break;case'ascii':e=this.parent.asciiWrite(f,this.offset+d,b);break;case'binary':e=this.parent.binaryWrite(f,this.offset+d,b);break;case'base64':e=this.parent.base64Write(f,this.offset+d,b);break;case'ucs2':case'ucs-2':e=this.parent.ucs2Write(f,this.offset+d,b);break;default:throw new Error('Unknown encoding')}return a._charsWritten=c._charsWritten,e},a.prototype.toString=function(c,a,b){c=String(c||'utf8').toLowerCase(),a===void 0||a<0?a=0:a>this.length&&(a=this.length),b===void 0||b>this.length?b=this.length:b<0&&(b=0),a+=this.offset,b+=this.offset;switch(c){case'hex':return this.parent.hexSlice(a,b);case'utf8':case'utf-8':return this.parent.utf8Slice(a,b);case'ascii':return this.parent.asciiSlice(a,b);case'binary':return this.parent.binarySlice(a,b);case'base64':return this.parent.base64Slice(a,b);case'ucs2':case'ucs-2':return this.parent.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},a.byteLength=c.byteLength,a.prototype.fill=function a(a,b,c){if(a||(a=0),b||(b=0),c||(c=this.length),typeof a==='string'&&(a=a.charCodeAt(0)),!(typeof a==='number')||isNaN(a))throw new Error('value is not a number');if(c<b)throw new Error('end < start');if(c===b)return 0;if(this.length==0)return 0;if(b<0||b>=this.length)throw new Error('start out of bounds');if(c<0||c>this.length)throw new Error('end out of bounds');return this.parent.fill(a,b+this.offset,c+this.offset)},a.prototype.copy=function(d,c,b,a){var e=this;if(b||(b=0),a||(a=this.length),c||(c=0),a<b)throw new Error('sourceEnd < sourceStart');if(a===b)return 0;if(d.length==0||e.length==0)return 0;if(c<0||c>=d.length)throw new Error('targetStart out of bounds');if(b<0||b>=e.length)throw new Error('sourceStart out of bounds');if(a<0||a>e.length)throw new Error('sourceEnd out of bounds');return a>this.length&&(a=this.length),d.length-c<a-b&&(a=d.length-c+b),this.parent.copy(d.parent,c+d.offset,b+this.offset,a+this.offset)},a.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this.parent,b-c,+c+this.offset)},a.prototype.utf8Slice=function(a,b){return this.toString('utf8',a,b)},a.prototype.binarySlice=function(a,b){return this.toString('binary',a,b)},a.prototype.asciiSlice=function(a,b){return this.toString('ascii',a,b)},a.prototype.utf8Write=function(a,b){return this.write(a,b,'utf8')},a.prototype.binaryWrite=function(a,b){return this.write(a,b,'binary')},a.prototype.asciiWrite=function(a,b){return this.write(a,b,'ascii')},a.prototype.readUInt8=function(a,d){var c=this;return d||(b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'Trying to read beyond buffer length')),a>=c.length?void 0:c.parent[c.offset+a]},a.prototype.readUInt16LE=function(a,b){return o(this,a,!1,b)},a.prototype.readUInt16BE=function(a,b){return o(this,a,!0,b)},a.prototype.readUInt32LE=function(a,b){return n(this,a,!1,b)},a.prototype.readUInt32BE=function(a,b){return n(this,a,!0,b)},a.prototype.readInt8=function(c,e){var a=this,d;return e||(b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<a.length,'Trying to read beyond buffer length')),c>=a.length?void 0:(d=a.parent[a.offset+c]&128,d?(255-a.parent[a.offset+c]+1)*-1:a.parent[a.offset+c])},a.prototype.readInt16LE=function(a,b){return v(this,a,!1,b)},a.prototype.readInt16BE=function(a,b){return v(this,a,!0,b)},a.prototype.readInt32LE=function(a,b){return r(this,a,!1,b)},a.prototype.readInt32BE=function(a,b){return r(this,a,!0,b)},a.prototype.readFloatLE=function(a,b){return s(this,a,!1,b)},a.prototype.readFloatBE=function(a,b){return s(this,a,!0,b)},a.prototype.readDoubleLE=function(a,b){return t(this,a,!1,b)},a.prototype.readDoubleBE=function(a,b){return t(this,a,!0,b)},a.prototype.writeUInt8=function(d,a,e){var c=this;e||(b.ok(d!==undefined&&d!==null,'missing value'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'trying to write beyond buffer length'),k(d,255)),a<c.length&&(c.parent[c.offset+a]=d)},a.prototype.writeUInt16LE=function(a,b,c){h(this,a,b,!1,c)},a.prototype.writeUInt16BE=function(a,b,c){h(this,a,b,!0,c)},a.prototype.writeUInt32LE=function(a,b,c){g(this,a,b,!1,c)},a.prototype.writeUInt32BE=function(a,b,c){g(this,a,b,!0,c)},a.prototype.writeInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'Trying to write beyond buffer length'),m(a,127,-128)),a>=0?d.writeUInt8(a,c,e):d.writeUInt8(255+a+1,c,e)},a.prototype.writeInt16LE=function(a,b,c){y(this,a,b,!1,c)},a.prototype.writeInt16BE=function(a,b,c){y(this,a,b,!0,c)},a.prototype.writeInt32LE=function(a,b,c){z(this,a,b,!1,c)},a.prototype.writeInt32BE=function(a,b,c){z(this,a,b,!0,c)},a.prototype.writeFloatLE=function(a,b,c){A(this,a,b,!1,c)},a.prototype.writeFloatBE=function(a,b,c){A(this,a,b,!0,c)},a.prototype.writeDoubleLE=function(a,b,c){q(this,a,b,!1,c)},a.prototype.writeDoubleBE=function(a,b,c){q(this,a,b,!0,c)},c.prototype.readUInt8=a.prototype.readUInt8,c.prototype.readUInt16LE=a.prototype.readUInt16LE,c.prototype.readUInt16BE=a.prototype.readUInt16BE,c.prototype.readUInt32LE=a.prototype.readUInt32LE,c.prototype.readUInt32BE=a.prototype.readUInt32BE,c.prototype.readInt8=a.prototype.readInt8,c.prototype.readInt16LE=a.prototype.readInt16LE,c.prototype.readInt16BE=a.prototype.readInt16BE,c.prototype.readInt32LE=a.prototype.readInt32LE,c.prototype.readInt32BE=a.prototype.readInt32BE,c.prototype.readFloatLE=a.prototype.readFloatLE,c.prototype.readFloatBE=a.prototype.readFloatBE,c.prototype.readDoubleLE=a.prototype.readDoubleLE,c.prototype.readDoubleBE=a.prototype.readDoubleBE,c.prototype.writeUInt8=a.prototype.writeUInt8,c.prototype.writeUInt16LE=a.prototype.writeUInt16LE,c.prototype.writeUInt16BE=a.prototype.writeUInt16BE,c.prototype.writeUInt32LE=a.prototype.writeUInt32LE,c.prototype.writeUInt32BE=a.prototype.writeUInt32BE,c.prototype.writeInt8=a.prototype.writeInt8,c.prototype.writeInt16LE=a.prototype.writeInt16LE,c.prototype.writeInt16BE=a.prototype.writeInt16BE,c.prototype.writeInt32LE=a.prototype.writeInt32LE,c.prototype.writeInt32BE=a.prototype.writeInt32BE,c.prototype.writeFloatLE=a.prototype.writeFloatLE,c.prototype.writeFloatBE=a.prototype.writeFloatBE,c.prototype.writeDoubleLE=a.prototype.writeDoubleLE,c.prototype.writeDoubleBE=a.prototype.writeDoubleBE},{assert:1,'./buffer_ieee754':5,'base64-js':7}],7:[function(b,a,c){!function(e){'use strict';function c(a){var c,g,h,d,f,e;if(a.length%4>0)throw'Invalid string. Length must be a multiple of 4';for(f=a.indexOf('='),f=f>0?a.length-f:0,e=[],h=f>0?a.length-4:a.length,c=0,g=0;c<h;c+=4,g+=3)d=b.indexOf(a[c])<<18|b.indexOf(a[c+1])<<12|b.indexOf(a[c+2])<<6|b.indexOf(a[c+3]),e.push((d&16711680)>>16),e.push((d&65280)>>8),e.push(d&255);return f===2?(d=b.indexOf(a[c])<<2|b.indexOf(a[c+1])>>4,e.push(d&255)):f===1&&(d=b.indexOf(a[c])<<10|b.indexOf(a[c+1])<<4|b.indexOf(a[c+2])>>2,e.push(d>>8&255),e.push(d&255)),e}function d(a){function h(a){return b[a>>18&63]+b[a>>12&63]+b[a>>6&63]+b[a&63]}var e,f=a.length%3,c='',d,g;for(e=0,g=a.length-f;e<g;e+=3)d=(a[e]<<16)+(a[e+1]<<8)+a[e+2],c+=h(d);switch(f){case 1:d=a[a.length-1];c+=b[d>>2];c+=b[d<<4&63];c+='==';break;case 2:d=(a[a.length-2]<<8)+a[a.length-1];c+=b[d>>10];c+=b[d>>4&63];c+=b[d<<2&63];c+='=';break}return c}var b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';a.exports.toByteArray=c,a.exports.fromByteArray=d}()},{}],8:[function(b,c,a){a.readIEEE754=function(h,l,n,f,m){var b,d,i=m*8-f-1,j=(1<<i)-1,k=j>>1,a=-7,c=n?0:m-1,g=n?1:-1,e=h[l+c];for(c+=g,b=e&(1<<-a)-1,e>>=-a,a+=i;a>0;b=b*256+h[l+c],c+=g,a-=8);for(d=b&(1<<-a)-1,b>>=-a,a+=f;a>0;d=d*256+h[l+c],c+=g,a-=8);if(b===0)b=1-k;else if(b===j)return d?NaN:(e?-1:1)*Infinity;else d+=Math.pow(2,f),b-=k;return(e?-1:1)*d*Math.pow(2,b-f)},a.writeIEEE754=function(k,b,m,n,c,p){var a,d,f,h=p*8-c-1,i=(1<<h)-1,e=i>>1,l=c===23?Math.pow(2,-24)-Math.pow(2,-77):0,g=n?p-1:0,j=n?-1:1,o=b<0||b===0&&1/b<0?1:0;for(b=Math.abs(b),isNaN(b)||b===Infinity?(d=isNaN(b)?1:0,a=i):(a=Math.floor(Math.log(b)/Math.LN2),b*(f=Math.pow(2,-a))<1&&(a--,f*=2),a+e>=1?b+=l/f:b+=l*Math.pow(2,1-e),b*f>=2&&(a++,f/=2),a+e>=i?(d=0,a=i):a+e>=1?(d=(b*f-1)*Math.pow(2,c),a+=e):(d=b*Math.pow(2,e-1)*Math.pow(2,c),a=0));c>=8;k[m+g]=d&255,g+=j,d/=256,c-=8);for(a=a<<c|d,h+=c;h>0;k[m+g]=a&255,g+=j,a/=256,h-=8);k[m+g-j]|=o*128}},{}],3:[function(e,E,f){function c(a){this.length=a}function i(a){return a<16?'0'+a.toString(16):a.toString(16)}function w(b){var c=[];for(var a=0;a<b.length;a++)if(b.charCodeAt(a)<=127)c.push(b.charCodeAt(a));else{var e=encodeURIComponent(b.charAt(a)).substr(1).split('%');for(var d=0;d<e.length;d++)c.push(parseInt(e[d],16))}return c}function B(c){var b=[];for(var a=0;a<c.length;a++)b.push(c.charCodeAt(a)&255);return b}function p(a){return e('base64-js').toByteArray(a)}function j(b,c,d,e){var a=0;while(a<e){if(a+d>=c.length||a>=b.length)break;c[a+d]=b[a],a++}return a}function u(a){try{return decodeURIComponent(a)}catch(a){return String.fromCharCode(65533)}}function l(a){return a=~~Math.ceil(+a),a<0?0:a}function a(b,f,g){if(!(this instanceof a))return new a(b,f,g);var h;if(typeof g==='number')this.length=l(f),this.parent=b,this.offset=g;else{switch(h=typeof b){case'number':this.length=l(b);break;case'string':this.length=a.byteLength(b,f);break;case'object':this.length=l(b.length);break;default:throw new Error('First argument needs to be a number, array or string.')}if(this.length>a.poolSize?(this.parent=new c(this.length),this.offset=0):((!d||d.length-d.used<this.length)&&C(),this.parent=d,this.offset=d.used,d.used+=this.length),D(b))for(var e=0;e<this.length;e++)this.parent[e+this.offset]=b[e];else h=='string'&&(this.length=this.write(b,0,f))}}function D(b){return Array.isArray(b)||a.isBuffer(b)||b&&typeof b==='object'&&typeof b.length==='number'}function C(){d=new c(a.poolSize),d.used=0}function o(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<a.length,'Trying to read beyond buffer length')),e?(d=a.parent[a.offset+c]<<8,d|=a.parent[a.offset+c+1]):(d=a.parent[a.offset+c],d|=a.parent[a.offset+c+1]<<8),d}function n(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e?(d=a.parent[a.offset+c+1]<<16,d|=a.parent[a.offset+c+2]<<8,d|=a.parent[a.offset+c+3],d+=a.parent[a.offset+c]<<24>>>0):(d=a.parent[a.offset+c+2]<<16,d|=a.parent[a.offset+c+1]<<8,d|=a.parent[a.offset+c],d+=a.parent[a.offset+c+3]<<24>>>0),d}function v(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+1<d.length,'Trying to read beyond buffer length')),c=o(d,a,e,f),g=c&32768,g?(65535-c+1)*-1:c}function r(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+3<d.length,'Trying to read beyond buffer length')),c=n(d,a,e,f),g=c&2147483648,g?(4294967295-c+1)*-1:c}function s(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,23,4)}function t(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+7<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,52,8)}function k(a,c){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a>=0,'specified a negative value for writing an unsigned value'),b.ok(a<=c,'value is larger than maximum value for type'),b.ok(Math.floor(a)===a,'value has a fractional component')}function h(a,c,d,e,f){f||(b.ok(c!==undefined&&c!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(d!==undefined&&d!==null,'missing offset'),b.ok(d+1<a.length,'trying to write beyond buffer length'),k(c,65535)),e?(a.parent[a.offset+d]=(c&65280)>>>8,a.parent[a.offset+d+1]=c&255):(a.parent[a.offset+d+1]=(c&65280)>>>8,a.parent[a.offset+d]=c&255)}function g(a,c,d,e,f){f||(b.ok(c!==undefined&&c!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(d!==undefined&&d!==null,'missing offset'),b.ok(d+3<a.length,'trying to write beyond buffer length'),k(c,4294967295)),e?(a.parent[a.offset+d]=c>>>24&255,a.parent[a.offset+d+1]=c>>>16&255,a.parent[a.offset+d+2]=c>>>8&255,a.parent[a.offset+d+3]=c&255):(a.parent[a.offset+d+3]=c>>>24&255,a.parent[a.offset+d+2]=c>>>16&255,a.parent[a.offset+d+1]=c>>>8&255,a.parent[a.offset+d]=c&255)}function m(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value'),b.ok(Math.floor(a)===a,'value has a fractional component')}function x(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value')}function y(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'Trying to write beyond buffer length'),m(a,32767,-32768)),a>=0?h(d,a,c,e,f):h(d,65535+a+1,c,e,f)}function z(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),m(a,2147483647,-2147483648)),a>=0?g(d,a,c,e,f):g(d,4294967295+a+1,c,e,f)}function A(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),x(a,3.4028234663852886e38,-3.4028234663852886e38)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,23,4)}function q(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+7<d.length,'Trying to write beyond buffer length'),x(a,1.7976931348623157e308,-1.7976931348623157e308)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,52,8)}var b=e('assert');f.INSPECT_MAX_BYTES=50,c.byteLength=function(a,b){switch(b||'utf8'){case'hex':return a.length/2;case'utf8':case'utf-8':return w(a).length;case'ascii':return a.length;case'base64':return p(a).length;default:throw new Error('Unknown encoding')}},c.prototype.utf8Write=function(a,b,d){return c._charsWritten=j(w(a),this,b,d)},c.prototype.asciiWrite=function(a,b,d){return c._charsWritten=j(B(a),this,b,d)},c.prototype.base64Write=function(a,b,d){return c._charsWritten=j(p(a),this,b,d)},c.prototype.base64Slice=function(b,c){var a=Array.prototype.slice.apply(this,arguments);return e('base64-js').fromByteArray(a)},c.prototype.utf8Slice=function(){var b=Array.prototype.slice.apply(this,arguments),d='',c='',a=0;while(a<b.length)b[a]<=127?(d+=u(c)+String.fromCharCode(b[a]),c=''):c+='%'+b[a].toString(16),a++;return d+u(c)},c.prototype.asciiSlice=function(){var b=Array.prototype.slice.apply(this,arguments),c='';for(var a=0;a<b.length;a++)c+=String.fromCharCode(b[a]);return c},c.prototype.inspect=function(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this[a]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<SlowBuffer '+b.join(' ')+'>'},c.prototype.hexSlice=function(b,a){var d=this.length;(!b||b<0)&&(b=0),(!a||a<0||a>d)&&(a=d);var e='';for(var c=b;c<a;c++)e+=i(this[c]);return e},c.prototype.toString=function(c,a,b){if(c=String(c||'utf8').toLowerCase(),a=+a||0,b===void 0&&(b=this.length),+b==a)return'';switch(c){case'hex':return this.hexSlice(a,b);case'utf8':case'utf-8':return this.utf8Slice(a,b);case'ascii':return this.asciiSlice(a,b);case'binary':return this.binarySlice(a,b);case'base64':return this.base64Slice(a,b);case'ucs2':case'ucs-2':return this.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},c.prototype.hexWrite=function(h,d,a){d=+d||0;var e=this.length-d;a?(a=+a,a>e&&(a=e)):a=e;var f=h.length;if(f%2)throw new Error('Invalid hex string');a>f/2&&(a=f/2);for(var b=0;b<a;b++){var g=parseInt(h.substr(b*2,2),16);if(isNaN(g))throw new Error('Invalid hex string');this[d+b]=g}return c._charsWritten=b*2,b},c.prototype.write=function(c,b,a,d){if(isFinite(b))isFinite(a)||(d=a,a=undefined);else{var f=d;d=b,b=a,a=f}b=+b||0;var e=this.length-b;a?(a=+a,a>e&&(a=e)):a=e,d=String(d||'utf8').toLowerCase();switch(d){case'hex':return this.hexWrite(c,b,a);case'utf8':case'utf-8':return this.utf8Write(c,b,a);case'ascii':return this.asciiWrite(c,b,a);case'binary':return this.binaryWrite(c,b,a);case'base64':return this.base64Write(c,b,a);case'ucs2':case'ucs-2':return this.ucs2Write(c,b,a);default:throw new Error('Unknown encoding')}},c.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this,b-c,+c)},c.prototype.copy=function(e,d,f,g){var c=[];for(var a=f;a<g;a++)b.ok(this[a]!==void 0,'copying undefined buffer bytes!'),c.push(this[a]);for(var a=d;a<d+c.length;a++)e[a]=c[a-d]},f.SlowBuffer=c,f.Buffer=a,a.poolSize=8192;var d;a.isBuffer=function b(b){return b instanceof a||b instanceof c},a.concat=function(c,e){if(!Array.isArray(c))throw new Error('Usage: Buffer.concat(list, [totalLength])\n list should be an Array.');if(c.length===0)return new a(0);if(c.length===1)return c[0];if(typeof e!=='number'){e=0;for(var b=0;b<c.length;b++){var d=c[b];e+=d.length}}var f=new a(e),g=0;for(var b=0;b<c.length;b++){var d=c[b];d.copy(f,g),g+=d.length}return f},a.prototype.inspect=function a(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this.parent[a+this.offset]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<Buffer '+b.join(' ')+'>'},a.prototype.get=function a(a){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]},a.prototype.set=function a(a,b){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]=b},a.prototype.write=function(f,d,b,g){if(isFinite(d))isFinite(b)||(g=b,b=undefined);else{var i=g;g=d,d=b,b=i}d=+d||0;var h=this.length-d;b?(b=+b,b>h&&(b=h)):b=h,g=String(g||'utf8').toLowerCase();var e;switch(g){case'hex':e=this.parent.hexWrite(f,this.offset+d,b);break;case'utf8':case'utf-8':e=this.parent.utf8Write(f,this.offset+d,b);break;case'ascii':e=this.parent.asciiWrite(f,this.offset+d,b);break;case'binary':e=this.parent.binaryWrite(f,this.offset+d,b);break;case'base64':e=this.parent.base64Write(f,this.offset+d,b);break;case'ucs2':case'ucs-2':e=this.parent.ucs2Write(f,this.offset+d,b);break;default:throw new Error('Unknown encoding')}return a._charsWritten=c._charsWritten,e},a.prototype.toString=function(c,a,b){c=String(c||'utf8').toLowerCase(),a===void 0||a<0?a=0:a>this.length&&(a=this.length),b===void 0||b>this.length?b=this.length:b<0&&(b=0),a+=this.offset,b+=this.offset;switch(c){case'hex':return this.parent.hexSlice(a,b);case'utf8':case'utf-8':return this.parent.utf8Slice(a,b);case'ascii':return this.parent.asciiSlice(a,b);case'binary':return this.parent.binarySlice(a,b);case'base64':return this.parent.base64Slice(a,b);case'ucs2':case'ucs-2':return this.parent.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},a.byteLength=c.byteLength,a.prototype.fill=function a(a,b,c){if(a||(a=0),b||(b=0),c||(c=this.length),typeof a==='string'&&(a=a.charCodeAt(0)),!(typeof a==='number')||isNaN(a))throw new Error('value is not a number');if(c<b)throw new Error('end < start');if(c===b)return 0;if(this.length==0)return 0;if(b<0||b>=this.length)throw new Error('start out of bounds');if(c<0||c>this.length)throw new Error('end out of bounds');return this.parent.fill(a,b+this.offset,c+this.offset)},a.prototype.copy=function(d,c,b,a){var e=this;if(b||(b=0),a||(a=this.length),c||(c=0),a<b)throw new Error('sourceEnd < sourceStart');if(a===b)return 0;if(d.length==0||e.length==0)return 0;if(c<0||c>=d.length)throw new Error('targetStart out of bounds');if(b<0||b>=e.length)throw new Error('sourceStart out of bounds');if(a<0||a>e.length)throw new Error('sourceEnd out of bounds');return a>this.length&&(a=this.length),d.length-c<a-b&&(a=d.length-c+b),this.parent.copy(d.parent,c+d.offset,b+this.offset,a+this.offset)},a.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this.parent,b-c,+c+this.offset)},a.prototype.utf8Slice=function(a,b){return this.toString('utf8',a,b)},a.prototype.binarySlice=function(a,b){return this.toString('binary',a,b)},a.prototype.asciiSlice=function(a,b){return this.toString('ascii',a,b)},a.prototype.utf8Write=function(a,b){return this.write(a,b,'utf8')},a.prototype.binaryWrite=function(a,b){return this.write(a,b,'binary')},a.prototype.asciiWrite=function(a,b){return this.write(a,b,'ascii')},a.prototype.readUInt8=function(a,d){var c=this;return d||(b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'Trying to read beyond buffer length')),c.parent[c.offset+a]},a.prototype.readUInt16LE=function(a,b){return o(this,a,!1,b)},a.prototype.readUInt16BE=function(a,b){return o(this,a,!0,b)},a.prototype.readUInt32LE=function(a,b){return n(this,a,!1,b)},a.prototype.readUInt32BE=function(a,b){return n(this,a,!0,b)},a.prototype.readInt8=function(c,e){var a=this,d;return e||(b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<a.length,'Trying to read beyond buffer length')),d=a.parent[a.offset+c]&128,d?(255-a.parent[a.offset+c]+1)*-1:a.parent[a.offset+c]},a.prototype.readInt16LE=function(a,b){return v(this,a,!1,b)},a.prototype.readInt16BE=function(a,b){return v(this,a,!0,b)},a.prototype.readInt32LE=function(a,b){return r(this,a,!1,b)},a.prototype.readInt32BE=function(a,b){return r(this,a,!0,b)},a.prototype.readFloatLE=function(a,b){return s(this,a,!1,b)},a.prototype.readFloatBE=function(a,b){return s(this,a,!0,b)},a.prototype.readDoubleLE=function(a,b){return t(this,a,!1,b)},a.prototype.readDoubleBE=function(a,b){return t(this,a,!0,b)},a.prototype.writeUInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'trying to write beyond buffer length'),k(a,255)),d.parent[d.offset+c]=a},a.prototype.writeUInt16LE=function(a,b,c){h(this,a,b,!1,c)},a.prototype.writeUInt16BE=function(a,b,c){h(this,a,b,!0,c)},a.prototype.writeUInt32LE=function(a,b,c){g(this,a,b,!1,c)},a.prototype.writeUInt32BE=function(a,b,c){g(this,a,b,!0,c)},a.prototype.writeInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'Trying to write beyond buffer length'),m(a,127,-128)),a>=0?d.writeUInt8(a,c,e):d.writeUInt8(255+a+1,c,e)},a.prototype.writeInt16LE=function(a,b,c){y(this,a,b,!1,c)},a.prototype.writeInt16BE=function(a,b,c){y(this,a,b,!0,c)},a.prototype.writeInt32LE=function(a,b,c){z(this,a,b,!1,c)},a.prototype.writeInt32BE=function(a,b,c){z(this,a,b,!0,c)},a.prototype.writeFloatLE=function(a,b,c){A(this,a,b,!1,c)},a.prototype.writeFloatBE=function(a,b,c){A(this,a,b,!0,c)},a.prototype.writeDoubleLE=function(a,b,c){q(this,a,b,!1,c)},a.prototype.writeDoubleBE=function(a,b,c){q(this,a,b,!0,c)},c.prototype.readUInt8=a.prototype.readUInt8,c.prototype.readUInt16LE=a.prototype.readUInt16LE,c.prototype.readUInt16BE=a.prototype.readUInt16BE,c.prototype.readUInt32LE=a.prototype.readUInt32LE,c.prototype.readUInt32BE=a.prototype.readUInt32BE,c.prototype.readInt8=a.prototype.readInt8,c.prototype.readInt16LE=a.prototype.readInt16LE,c.prototype.readInt16BE=a.prototype.readInt16BE,c.prototype.readInt32LE=a.prototype.readInt32LE,c.prototype.readInt32BE=a.prototype.readInt32BE,c.prototype.readFloatLE=a.prototype.readFloatLE,c.prototype.readFloatBE=a.prototype.readFloatBE,c.prototype.readDoubleLE=a.prototype.readDoubleLE,c.prototype.readDoubleBE=a.prototype.readDoubleBE,c.prototype.writeUInt8=a.prototype.writeUInt8,c.prototype.writeUInt16LE=a.prototype.writeUInt16LE,c.prototype.writeUInt16BE=a.prototype.writeUInt16BE,c.prototype.writeUInt32LE=a.prototype.writeUInt32LE,c.prototype.writeUInt32BE=a.prototype.writeUInt32BE,c.prototype.writeInt8=a.prototype.writeInt8,c.prototype.writeInt16LE=a.prototype.writeInt16LE,c.prototype.writeInt16BE=a.prototype.writeInt16BE,c.prototype.writeInt32LE=a.prototype.writeInt32LE,c.prototype.writeInt32BE=a.prototype.writeInt32BE,c.prototype.writeFloatLE=a.prototype.writeFloatLE,c.prototype.writeFloatBE=a.prototype.writeFloatBE,c.prototype.writeDoubleLE=a.prototype.writeDoubleLE,c.prototype.writeDoubleBE=a.prototype.writeDoubleBE},{assert:1,'./buffer_ieee754':8,'base64-js':9}],9:[function(b,a,c){!function(e){'use strict';function c(a){var c,g,h,d,f,e;if(a.length%4>0)throw'Invalid string. Length must be a multiple of 4';for(f=a.indexOf('='),f=f>0?a.length-f:0,e=[],h=f>0?a.length-4:a.length,c=0,g=0;c<h;c+=4,g+=3)d=b.indexOf(a[c])<<18|b.indexOf(a[c+1])<<12|b.indexOf(a[c+2])<<6|b.indexOf(a[c+3]),e.push((d&16711680)>>16),e.push((d&65280)>>8),e.push(d&255);return f===2?(d=b.indexOf(a[c])<<2|b.indexOf(a[c+1])>>4,e.push(d&255)):f===1&&(d=b.indexOf(a[c])<<10|b.indexOf(a[c+1])<<4|b.indexOf(a[c+2])>>2,e.push(d>>8&255),e.push(d&255)),e}function d(a){function h(a){return b[a>>18&63]+b[a>>12&63]+b[a>>6&63]+b[a&63]}var e,f=a.length%3,c='',d,g;for(e=0,g=a.length-f;e<g;e+=3)d=(a[e]<<16)+(a[e+1]<<8)+a[e+2],c+=h(d);switch(f){case 1:d=a[a.length-1];c+=b[d>>2];c+=b[d<<4&63];c+='==';break;case 2:d=(a[a.length-2]<<8)+a[a.length-1];c+=b[d>>10];c+=b[d>>4&63];c+=b[d<<2&63];c+='=';break}return c}var b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';a.exports.toByteArray=c,a.exports.fromByteArray=d}()},{}]},{},[]),b.exports=a('buffer-browserify')},{}],14:[function(c,b,d){var a=b.exports={};a.nextTick=function(b,c,a){return b=typeof window!=='undefined'&&window.setImmediate,c=typeof window!=='undefined'&&window.postMessage&&window.addEventListener,b?function(a){return window.setImmediate(a)}:c?(a=[],window.addEventListener('message',function(b){var c=b.source;if((c===window||c===null)&&b.data==='process-tick'&&(b.stopPropagation(),a.length>0)){var d=a.shift();d()}},!0),function b(b){a.push(b),window.postMessage('process-tick','*')}):function a(a){setTimeout(a,0)}}(),a.title='browser',a.browser=!0,a.env={},a.argv=[],a.binding=function(a){throw new Error('process.binding is not supported')},a.cwd=function(){return'/'},a.chdir=function(a){throw new Error('process.chdir is not supported')}},{}],15:[function(c,e,a){var d=c('events').EventEmitter,b=c('through');a=e.exports=function(b){return typeof b.pipe==='function'?a.fromStream(b):a.toStream(b)},a.toStream=function(a){var c=b(function a(a){this.emit('data',a)},function b(){var b=a._emitStreams.indexOf(c);a._emitStreams.splice(b,1)});if(!a._emitStreams){a._emitStreams=[];var d=a.emit;a.emit=function(){var b=[].slice.call(arguments);a._emitStreams.forEach(function(a){a.writable&&a.write(b)}),d.apply(a,arguments)}}return a._emitStreams.push(c),c},a.fromStream=function(c){var a=new d;return c.pipe(b(function(b){a.emit.apply(a,b)})),a}},{events:7,through:16}],16:[function(b,e,f){function a(g,f,j){function k(){while(b.length&&!a.paused){var c=b.shift();if(null===c)return a.emit('end');a.emit('data',c)}}function l(){a.writable=!1,f.call(a),!a.readable&&a.autoDestroy&&a.destroy()}g=g||function(a){this.queue(a)},f=f||function(){this.queue(null)};var e=!1,h=!1,b=[],i=!1,a=new d;return a.readable=a.writable=!0,a.paused=!1,a.autoDestroy=!(j&&j.autoDestroy===!1),a.write=function(b){return g.call(this,b),!a.paused},a.queue=a.push=function(c){return i?a:(c==null&&(i=!0),b.push(c),k(),a)},a.on('end',function(){a.readable=!1,!a.writable&&a.autoDestroy&&c.nextTick(function(){a.destroy()})}),a.end=function(b){return e?void 0:(e=!0,arguments.length&&a.write(b),l(),a)},a.destroy=function(){return h?void 0:(h=!0,e=!0,b.length=0,a.writable=a.readable=!1,a.emit('close'),a)},a.pause=function(){return a.paused?void 0:(a.paused=!0,a)},a.resume=function(){return a.paused&&(a.paused=!1,a.emit('resume')),k(),a.paused||a.emit('drain'),a},a}var c=b('__browserify_process'),d=b('stream');f=e.exports=a,a.through=a},{__browserify_process:14,stream:10}],17:[function(a,b,c){!function(a){typeof define=='function'?define(a):typeof YUI=='function'?YUI.add('es5',a):a()}(function(){function j(){}function q(a){return a=+a,a!==a?a=0:a!==0&&a!==1/0&&a!==-(1/0)&&(a=(a>0||-1)*Math.floor(Math.abs(a))),a}function i(b){var a=typeof b;return b===null||a==='undefined'||a==='boolean'||a==='number'||a==='string'}function F(a){var b,c,d;if(i(a))return a;if(c=a.valueOf,typeof c==='function'&&(b=c.call(a),i(b)))return b;if(d=a.toString,typeof d==='function'&&(b=d.call(a),i(b)))return b;throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function a(d){var a=this;if(typeof a!='function')throw new TypeError('Function.prototype.bind called on incompatible '+a);var c=g.call(arguments,1),b=function(){if(this instanceof b){var e=a.apply(this,c.concat(g.call(arguments)));return Object(e)===e?e:this}else return a.apply(d,c.concat(g.call(arguments)))};return a.prototype&&(j.prototype=a.prototype,b.prototype=new j,j.prototype=null),b});var f=Function.prototype.call,s=Array.prototype,d=Object.prototype,g=s.slice,a=f.bind(d.toString),h=f.bind(d.hasOwnProperty),E,D,C,B,A;if((A=h(d,'__defineGetter__'))&&(E=f.bind(d.__defineGetter__),D=f.bind(d.__defineSetter__),C=f.bind(d.__lookupGetter__),B=f.bind(d.__lookupSetter__)),[1,2].splice(0).length!=2){var u=Array.prototype.splice;Array.prototype.splice=function(a,b){return arguments.length?u.apply(this,[a===void 0?0:a,b===void 0?this.length-a:b].concat(g.call(arguments,2))):[]}}if([].unshift(0)!=1){var r=Array.prototype.unshift;Array.prototype.unshift=function(){return r.apply(this,arguments),this.length}}Array.isArray||(Array.isArray=function b(b){return a(b)=='[object Array]'});var k=Object('a'),c=k[0]!='a'||!(0 in k);if(Array.prototype.forEach||(Array.prototype.forEach=function d(g){var f=b(this),e=c&&a(this)=='[object String]'?this.split(''):f,h=arguments[1],d=-1,i=e.length>>>0;if(a(g)!='[object Function]')throw new TypeError;while(++d<i)d in e&&g.call(h,e[d],d,f)}),Array.prototype.map||(Array.prototype.map=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=Array(h),j=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)d in e&&(i[d]=f.call(j,e[d],d,g));return i}),Array.prototype.filter||(Array.prototype.filter=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,j=e.length>>>0,h=[],i,k=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<j;d++)d in e&&(i=e[d],f.call(k,i,d,g)&&h.push(i));return h}),Array.prototype.every||(Array.prototype.every=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)if(d in e&&!f.call(i,e[d],d,g))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)if(d in e&&f.call(i,e[d],d,g))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function d(h){var i=b(this),e=c&&a(this)=='[object String]'?this.split(''):i,g=e.length>>>0;if(a(h)!='[object Function]')throw new TypeError(h+' is not a function');if(!g&&arguments.length==1)throw new TypeError('reduce of empty array with no initial value');var d=0,f;if(arguments.length>=2)f=arguments[1];else do{if(d in e){f=e[d++];break}if(++d>=g)throw new TypeError('reduce of empty array with no initial value')}while(!0);for(;d<g;d++)d in e&&(f=h.call(void 0,f,e[d],d,i));return f}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function d(g){var h=b(this),e=c&&a(this)=='[object String]'?this.split(''):h,i=e.length>>>0;if(a(g)!='[object Function]')throw new TypeError(g+' is not a function');if(!i&&arguments.length==1)throw new TypeError('reduceRight of empty array with no initial value');var f,d=i-1;if(arguments.length>=2)f=arguments[1];else do{if(d in e){f=e[d--];break}if(--d<0)throw new TypeError('reduceRight of empty array with no initial value')}while(!0);do d in this&&(f=g.call(void 0,f,e[d],d,h));while(d--);return f}),(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)&&(Array.prototype.indexOf=function d(g){var e=c&&a(this)=='[object String]'?this.split(''):b(this),f=e.length>>>0;if(!f)return-1;var d=0;for(arguments.length>1&&(d=q(arguments[1])),d=d>=0?d:Math.max(0,f+d);d<f;d++)if(d in e&&e[d]===g)return d;return-1}),(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)&&(Array.prototype.lastIndexOf=function d(g){var e=c&&a(this)=='[object String]'?this.split(''):b(this),f=e.length>>>0;if(!f)return-1;var d=f-1;for(arguments.length>1&&(d=Math.min(d,q(arguments[1]))),d=d>=0?d:f-Math.abs(d);d>=0;d--)if(d in e&&g===e[d])return d;return-1}),!Object.keys){var m=!0,n=['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','propertyIsEnumerable','constructor'],w=n.length;for(var z in{toString:null})m=!1;Object.keys=function a(a){if(typeof a!='object'&&typeof a!='function'||a===null)throw new TypeError('Object.keys called on a non-object');var b=[];for(var d in a)h(a,d)&&b.push(d);if(m)for(var c=0,f=w;c<f;c++){var e=n[c];h(a,e)&&b.push(e)}return b}}var l=-621987552e5,o='-000001';(!Date.prototype.toISOString||new Date(l).toISOString().indexOf(o)===-1)&&(Date.prototype.toISOString=function a(){var b,d,e,a,c;if(!isFinite(this))throw new RangeError('Date.prototype.toISOString called on non-finite value.');a=this.getUTCFullYear(),c=this.getUTCMonth(),a+=Math.floor(c/12),c=(c%12+12)%12,b=[c+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()],a=(a<0?'-':a>9999?'+':'')+('00000'+Math.abs(a)).slice(0<=a&&a<=9999?-4:-6),d=b.length;while(d--)e=b[d],e<10&&(b[d]='0'+e);return a+'-'+b.slice(0,2).join('-')+'T'+b.slice(2).join(':')+'.'+('000'+this.getUTCMilliseconds()).slice(-3)+'Z'});var p=!1;try{p=Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(l).toJSON().indexOf(o)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(a){}if(p||(Date.prototype.toJSON=function a(d){var a=Object(this),b=F(a),c;if(typeof b==='number'&&!isFinite(b))return null;if(c=a.toISOString,typeof c!='function')throw new TypeError('toISOString property is not callable');return c.call(a)}),(!Date.parse||'Date.parse is buggy')&&(Date=function(a,e,f,c){function b(c,e,f,g,h,j,k){var d=arguments.length;if(this instanceof a){var i=d==1&&String(c)===c?new a(b.parse(c)):d>=7?new a(c,e,f,g,h,j,k):d>=6?new a(c,e,f,g,h,j):d>=5?new a(c,e,f,g,h):d>=4?new a(c,e,f,g):d>=3?new a(c,e,f):d>=2?new a(c,e):d>=1?new a(c):new a;return i.constructor=b,i}return a.apply(this,arguments)}function d(a,c){var b=c>1?1:0;return f[c]+Math.floor((a-1969+b)/4)-Math.floor((a-1901+b)/100)+Math.floor((a-1601+b)/400)+365*(a-1970)}e=new RegExp('^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$'),f=[0,31,59,90,120,151,181,212,243,273,304,334,365];for(c in a)b[c]=a[c];return b.now=a.now,b.UTC=a.UTC,b.prototype=a.prototype,b.prototype.constructor=b,b.parse=function b(q){var b=e.exec(q);if(b){var g=Number(b[1]),f=Number(b[2]||1)-1,i=Number(b[3]||1)-1,l=Number(b[4]||0),h=Number(b[5]||0),k=Number(b[6]||0),j=Number(b[7]||0),p=!b[4]||b[8]?0:Number(new a(1970,0)),m=b[9]==='-'?1:-1,n=Number(b[10]||0),o=Number(b[11]||0),c;return l<(h>0||k>0||j>0?24:25)&&h<60&&k<60&&j<1e3&&f>-1&&f<12&&n<24&&o<60&&i>-1&&i<d(g,f+1)-d(g,f)&&(c=((d(g,f)+i)*24+l+n*m)*60,c=((c+h+o*m)*60+k)*1e3+j+p,-864e13<=c&&c<=864e13)?c:NaN}return a.parse.apply(this,arguments)},b}(Date)),Date.now||(Date.now=function a(){return new Date().getTime()}),'0'.split(void 0,0).length){var x=String.prototype.split;String.prototype.split=function(a,b){return a===void 0&&b===0?[]:x.apply(this,arguments)}}if(''.substr&&'0b'.substr(-1)!=='b'){var v=String.prototype.substr;String.prototype.substr=function(a,b){return v.call(this,a<0?(a=this.length+a)<0?0:a:a,b)}}var e=' \n\r Â áš€á Žâ€€â€â€‚         âŸã€€\u2028\u2029';if(!String.prototype.trim||e.trim()){e='['+e+']';var t=new RegExp('^'+e+e+'*'),y=new RegExp(e+e+'*$');String.prototype.trim=function a(){if(this===undefined||this===null)throw new TypeError("can't convert "+this+' to object');return String(this).replace(t,'').replace(y,'')}}var b=function(a){if(a==null)throw new TypeError("can't convert "+a+' to object');return Object(a)}})},{}],18:[function(a,d,e){var b=a('./inject'),c=a('stream-serializer');d.exports=b(function(b,a){return c(a&&a.wrapper)(b)})},{'./inject':19,'stream-serializer':21}],19:[function(a,e,f){'use strict';var b=a('through'),c=a('xtend'),d=a('duplex');e.exports=function(a){function e(h,k){function n(){return Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function g(d){e.removeListener('end',g),e.removeListener('error',g),e.removeListener('close',g);var b=d||new Error('unexpected disconnection');for(var c in i){var a=i[c];a.destroyed=!0,h.error!==!0?a.end():(a.emit('error',b),a.destroy())}}function l(c,g,d){j++;var a=b(function(d){if(!this.writable){var b=Error('stream is not writable: '+c);return b.stream=this,f.emit('error',b)}e._data([a.id,'data',d])},function(){e._data([a.id,'end']),this.readable&&!d.allowHalfOpen&&!this.ended&&this.emit('end')});return a.pause=function(){e._data([a.id,'pause'])},a.resume=function(){e._data([a.id,'resume'])},a.error=function(b){e._data([a.id,'error',b])},a.once('close',function(){delete i[c],j--,e._data([a.id,'close']),j===0&&e.emit('zero')}),a.writable=d.writable,a.readable=d.readable,i[a.id=c]=a,a.meta=g,a}'function'===typeof h&&(k=h,h=null),h=h||{};var i={},j=0,e=d();e.on('_data',function(a){if(!(Array.isArray(a)&&'string'===typeof a[0]&&'__proto__'!==a[0]&&'string'===typeof a[1]&&'__proto__'!==a[1]))return;var h=a.shift(),g=a[0],b=i[h];if(!b){if(g=='close')return;if(g!='new')return f.emit('unknown',h);e.emit('connection',l(h,a[1].meta,a[1].opts))}else if(g==='pause')b.paused=!0;else if(g==='resume'){var k=b.paused;b.paused=!1,k&&b.emit('drain')}else if(g==='error'){var d=a[1];if(typeof d==='string')b.emit('error',new Error(d));else if(typeof d.message==='string'){var j=new Error(d.message);c(j,d),b.emit('error',j)}else b.emit('error',d)}else b.emit.apply(b,a)}).on('_end',function(){g(),e._end()});var f=a(e,h);e!==f&&e.on('connection',function(a){f.emit('connection',a)}),f.close=function(a){return e.once('zero',function(){e._end(),a&&a()}),this},k&&f.on('connection',k),f.on('connection',function(a){f.listeners('connection').length===1&&a.error('remote end lacks connection listener '+f.listeners('connection').length)});var m=f.pipe;return f.pipe=function(a,b){return m.call(f,a,b),e.on('end',g),e.on('close',g),e.on('error',g),a},f.createStream=function(c,a){a=a||{},a.writable||a.readable||(a.readable=a.writable=!0);var b=l(n(),c,a),d={writable:a.readable,readable:a.writable};return e._data([b.id,'new',{meta:c,opts:d}]),b},f.createWriteStream=function(a){return f.createStream(a,{writable:!0,readable:!1})},f.createReadStream=function(a){return f.createStream(a,{writable:!1,readable:!0})},f}return e}},{duplex:20,through:22,xtend:23}],20:[function(b,d,e){var a=b('__browserify_process'),c=b('stream');d.exports=function(h,i){var b=new c,d=[],g=!1,e;b.writable=b.readable=!0,b.paused=!1,b._paused=!1,b.buffer=d,b.on('pause',function(){b._paused=!0}).on('drain',function(){b._paused=!1}),h&&b.on('_data',h),i&&b.on('_end',i),b.once('end',function(){b.readable=!1,b.writable||a.nextTick(function(){b.destroy()})}),b.once('_end',function(){b.writable=!1,b.readable||b.destroy()}),b._data=function(a){return b.paused||d.length?d.push(a):b.emit('data',a),!(b.paused||d.length)},b._end=function(a){if(a&&b._data(a),e)return;e=!0,b.drain()},b.write=function(a){return b.emit('_data',a),!b._paused},b.end=function(){if(b.writable=!1,b.ended)return;b.ended=!0,b.emit('_end')},b.drain=function(){if(!(d.length||e))return;while(!b.paused)if(d.length)b.emit('data',d.shift()),d.length==0&&b.emit('_drain');else if(e&&b.readable){b.readable=!1,b.emit('end');return}else return!0};var f=!1;return b.resume=function(){return f=!0,b.paused=!1,b.drain(),b},b.destroy=function(){if(g)return;g=!0,d.length=0,b.emit('close')},b.pause=function(){return f=!0,b.paused=!0,b.emit('_pause'),b},b._pause=function(){return b._paused||(b._paused=!0,b.emit('pause')),this},b.paused=!0,a.nextTick(function(){if(f)return;b.resume()}),b}},{__browserify_process:14,stream:10}],21:[function(c,d,a){var b=c('events').EventEmitter;a=d.exports=function(b){return'function'==typeof b?b:a[b]||a.json},a.json=function(a,d){function e(c){var b;try{b=d.parse(c)}catch(b){return b.line=c,a.emit('error',b)}b!==undefined&&f.call(a,b)}function h(b){var a=(c+b).split('\n');c=a.pop();while(a.length)e(a.shift())}d=d||JSON;var f=a.write,c='';a.write=h;var g=a.end;return a.end=function(b){return b&&a.write(b),c&&e(c),g.call(a)},a.emit=function(e,c){e=='data'&&(c=d.stringify(c)+'\n'),b.prototype.emit.call(a,e,c)},a},a.raw=function(a){return a}},{events:7}],22:[function(a,b,c){b.exports=a(16)},{__browserify_process:14,stream:10}],23:[function(c,a,d){function b(f){for(var a=1;a<arguments.length;a++){var c=arguments[a],d=Object.keys(c);for(var b=0;b<d.length;b++){var e=d[b];f[e]=c[e]}}return f}a.exports=b},{}],24:[function(a,f,g){var b=a('stream'),c=a('sockjs-client'),d=a('url').resolve,e=a('url').parse;f.exports=function(i,j){var k=e(i).protocol?i:d(window.location.href,i),a=new b;a.readable=!0,a.writable=!0;var h=!1,g=[],f=c(k);return a.sock=f,a.write=function(a){!h||g.length?g.push(a):f.send(a)},a.end=function(b){if(b!==undefined&&a.write(b),!h){a._ended=!0;return}a.writable=!1,f.close()},a.destroy=function(){a._ended=!0,a.writable=a.readable=!1,g.length=0,f.close()},f.onopen=function(){typeof j==='function'&&j(),h=!0;for(var b=0;b<g.length;b++)f.send(g[b]);g=[],a.emit('connect'),a._ended&&a.end()},f.onmessage=function(b){a.emit('data',b.data)},f.onclose=function(){a.emit('end'),a.writable=!1,a.readable=!1},a}},{'sockjs-client':25,stream:10,url:11}],25:[function(require,module,exports){var JSON;JSON||(JSON={}),function(){function str(h,i){var b,e,c,g,f=gap,d,a=i[h];a&&typeof a=='object'&&typeof a.toJSON=='function'&&(a=a.toJSON(h)),typeof rep=='function'&&(a=rep.call(i,h,a));switch(typeof a){case'string':return quote(a);case'number':return isFinite(a)?String(a):'null';case'boolean':case'null':return String(a);case'object':if(!a)return'null';gap+=indent,d=[];if(Object.prototype.toString.apply(a)==='[object Array]'){for(g=a.length,b=0;b<g;b+=1)d[b]=str(b,a)||'null';return c=d.length===0?'[]':gap?'[\n'+gap+d.join(',\n'+gap)+'\n'+f+']':'['+d.join(',')+']',gap=f,c}if(rep&&typeof rep=='object')for(g=rep.length,b=0;b<g;b+=1)typeof rep[b]=='string'&&(e=rep[b],c=str(e,a),c&&d.push(quote(e)+(gap?': ':':')+c));else for(e in a)Object.prototype.hasOwnProperty.call(a,e)&&(c=str(e,a),c&&d.push(quote(e)+(gap?': ':':')+c));c=d.length===0?'{}':gap?'{\n'+gap+d.join(',\n'+gap)+'\n'+f+'}':'{'+d.join(',')+'}',gap=f;return c}}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(b){var a=meta[b];return typeof a=='string'?a:'\\u'+('0000'+b.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function f(a){return a<10?'0'+a:a}typeof Date.prototype.toJSON!='function'&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z':null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'':'\\b',' ':'\\t','\n':'\\n','':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;typeof JSON.stringify!='function'&&(JSON.stringify=function(d,a,b){var c;if(gap='',indent='',typeof b=='number')for(c=0;c<b;c+=1)indent+=' ';else typeof b=='string'&&(indent=b);if(rep=a,!a||typeof a=='function'||typeof a=='object'&&typeof a.length=='number')return str('',{'':d});throw new Error('JSON.stringify')}),typeof JSON.parse!='function'&&(JSON.parse=function(text,reviver){function walk(d,e){var b,c,a=d[e];if(a&&typeof a=='object')for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&(c=walk(a,b),c!==undefined?a[b]=c:delete a[b]);return reviver.call(d,e,a)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'')))return j=eval('('+text+')'),typeof reviver=='function'?walk({'':j},''):j;throw new SyntaxError('JSON.parse')})}();var SockJS=function(d,c,a,m,f,l,M,g,D,S,s,O,V,a3,E,z,n,C,Q,P,p,Z,a0,x,b,t,j,X,R,$,r,a1,i,q,u,B,J,e,N,F,h,o,L,K,T,U,y,W,w,Y,v,_,G,A,I,a2,H,k){return d=document,c=window,a={},m=function(){},m.prototype.addEventListener=function(b,d){this._listeners||(this._listeners={}),b in this._listeners||(this._listeners[b]=[]);var c=this._listeners[b];a.arrIndexOf(c,d)===-1&&c.push(d);return},m.prototype.removeEventListener=function(c,e){if(!(this._listeners&&c in this._listeners))return;var b=this._listeners[c],d=a.arrIndexOf(b,e);if(d!==-1){b.length>1?this._listeners[c]=b.slice(0,d).concat(b.slice(d+1)):delete this._listeners[c];return}return},m.prototype.dispatchEvent=function(d){var a=d.type,c=Array.prototype.slice.call(arguments,0);if(this['on'+a]&&this['on'+a].apply(this,c),this._listeners&&a in this._listeners)for(var b=0;b<this._listeners[a].length;b++)this._listeners[a][b].apply(this,c)},f=function(c,a){if(this.type=c,a!==void 0)for(var b in a){if(!a.hasOwnProperty(b))continue;this[b]=a[b]}},f.prototype.toString=function(){var c=[];for(var a in this){if(!this.hasOwnProperty(a))continue;var b=this[a];typeof b==='function'&&(b='[function]'),c.push(a+'='+b)}return'SimpleEvent('+c.join(', ')+')'},l=function(a){this.events=a||[]},l.prototype.emit=function(c){var b=this,d=Array.prototype.slice.call(arguments,1);!b.nuked&&b['on'+c]&&b['on'+c].apply(b,d),a.arrIndexOf(b.events,c)===-1&&a.log('Event '+JSON.stringify(c)+' not listed '+JSON.stringify(b.events)+' in '+b)},l.prototype.nuke=function(c){var a=this;a.nuked=!0;for(var b=0;b<a.events.length;b++)delete a[a.events[b]]},M='abcdefghijklmnopqrstuvwxyz0123456789_',a.random_string=function(d,a){a=a||M.length;var b,c=[];for(b=0;b<d;b++)c.push(M.substr(Math.floor(Math.random()*a),1));return c.join('')},a.random_number=function(a){return Math.floor(Math.random()*a)},a.random_number_string=function(c){var b=(''+(c-1)).length,d=Array(b+1).join('0');return(d+a.random_number(c)).slice(-b)},a.getOrigin=function(a){a+='/';var b=a.split('/').slice(0,3);return b.join('/')},a.isSameOriginUrl=function(b,a){return a||(a=c.location.href),b.split('/').slice(0,3).join('/')===a.split('/').slice(0,3).join('/')},a.getParentDomain=function(a){if(/^[0-9.]*$/.test(a))return a;if(/^\[/.test(a))return a;if(!/[.]/.test(a))return a;var b=a.split('.').slice(1);return b.join('.')},a.objectExtend=function(c,b){for(var a in b)b.hasOwnProperty(a)&&(c[a]=b[a]);return c},g='_jp',a.polluteGlobalNamespace=function(){g in c||(c[g]={})},a.closeFrame=function(a,b){return'c'+JSON.stringify([a,b])},a.userSetCode=function(a){return a===1e3||a>=3e3&&a<=4999},a.countRTO=function(a){var b;return a>100?b=3*a:b=a+200,b},a.log=function(){c.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},a.bind=function(a,b){return a.bind?a.bind(b):function(){return a.apply(b,arguments)}},a.flatUrl=function(a){return a.indexOf('?')===-1&&a.indexOf('#')===-1},a.amendUrl=function(b){var c=d.location;if(!b)throw new Error('Wrong url for SockJS');if(!a.flatUrl(b))throw new Error('Only basic urls are supported in SockJS');return b.indexOf('//')===0&&(b=c.protocol+b),b.indexOf('/')===0&&(b=c.protocol+'//'+c.host+b),b=b.replace(/[/]+$/,''),b},a.arrIndexOf=function(b,c){for(var a=0;a<b.length;a++)if(b[a]===c)return a;return-1},a.arrSkip=function(b,e){var c=a.arrIndexOf(b,e);if(c===-1)return b.slice();else{var d=b.slice(0,c);return d.concat(b.slice(c+1))}},a.isArray=Array.isArray||function(a){return{}.toString.call(a).indexOf('Array')>=0},a.delay=function(a,b){return typeof a==='function'&&(b=a,a=0),setTimeout(b,a)},D=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,S={'�':'\\u0000','':'\\u0001','':'\\u0002','':'\\u0003','':'\\u0004','':'\\u0005','':'\\u0006','':'\\u0007','':'\\b',' ':'\\t','\n':'\\n','':'\\u000b','':'\\f','\r':'\\r','':'\\u000e','':'\\u000f','':'\\u0010','':'\\u0011','':'\\u0012','':'\\u0013','':'\\u0014','':'\\u0015','':'\\u0016','':'\\u0017','':'\\u0018','':'\\u0019','':'\\u001a','':'\\u001b','':'\\u001c','':'\\u001d','':'\\u001e','':'\\u001f','"':'\\"','\\':'\\\\','':'\\u007f','€':'\\u0080','Â':'\\u0081','‚':'\\u0082','ƒ':'\\u0083','„':'\\u0084','Â…':'\\u0085','†':'\\u0086','‡':'\\u0087','ˆ':'\\u0088','‰':'\\u0089','Š':'\\u008a','‹':'\\u008b','ÂŒ':'\\u008c','Â':'\\u008d','ÂŽ':'\\u008e','Â':'\\u008f','Â':'\\u0090','‘':'\\u0091','Â’':'\\u0092','“':'\\u0093','”':'\\u0094','•':'\\u0095','–':'\\u0096','—':'\\u0097','˜':'\\u0098','™':'\\u0099','š':'\\u009a','›':'\\u009b','œ':'\\u009c','Â':'\\u009d','ž':'\\u009e','Ÿ':'\\u009f','Â':'\\u00ad','Ø€':'\\u0600','Ø':'\\u0601','Ø‚':'\\u0602','؃':'\\u0603','Ø„':'\\u0604','Ü':'\\u070f','áž´':'\\u17b4','ážµ':'\\u17b5','‌':'\\u200c','â€':'\\u200d','‎':'\\u200e','â€':'\\u200f','\u2028':'\\u2028','\u2029':'\\u2029','‪':'\\u202a','‫':'\\u202b','‬':'\\u202c','â€':'\\u202d','‮':'\\u202e',' ':'\\u202f','â ':'\\u2060','â¡':'\\u2061','â¢':'\\u2062','â£':'\\u2063','â¤':'\\u2064','â¥':'\\u2065','â¦':'\\u2066','â§':'\\u2067','â¨':'\\u2068','â©':'\\u2069','âª':'\\u206a','â«':'\\u206b','â¬':'\\u206c','â':'\\u206d','â®':'\\u206e','â¯':'\\u206f','':'\\ufeff','ï¿°':'\\ufff0','￱':'\\ufff1','￲':'\\ufff2','￳':'\\ufff3','ï¿´':'\\ufff4','￵':'\\ufff5','ï¿¶':'\\ufff6','ï¿·':'\\ufff7','￸':'\\ufff8','':'\\ufff9','':'\\ufffa','ï¿»':'\\ufffb','':'\\ufffc','�':'\\ufffd','￾':'\\ufffe','ï¿¿':'\\uffff'},s=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,V=JSON&&JSON.stringify||function(a){return D.lastIndex=0,D.test(a)&&(a=a.replace(D,function(a){return S[a]})),'"'+a+'"'},a3=function(b){var a,c={},d=[];for(a=0;a<65536;a++)d.push(String.fromCharCode(a));return b.lastIndex=0,d.join('').replace(b,function(a){return c[a]='\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4),''}),b.lastIndex=0,c},a.quote=function(b){var a=V(b);return s.lastIndex=0,s.test(a)?(O||(O=a3(s)),a.replace(s,function(a){return O[a]})):a},E=['websocket','xdr-streaming','xhr-streaming','iframe-eventsource','iframe-htmlfile','xdr-polling','xhr-polling','iframe-xhr-polling','jsonp-polling'],a.probeProtocols=function(){var d={};for(var a=0;a<E.length;a++){var c=E[a];d[c]=b[c]&&b[c].enabled()}return d},a.detectProtocols=function(h,e,a){var b={},c=[];e||(e=E);for(var f=0;f<e.length;f++){var g=e[f];b[g]=h[g]}var d=function(a){var e=a.shift();b[e]?c.push(e):a.length>0&&d(a)};return a.websocket!==!1&&d(['websocket']),b['xhr-streaming']&&!a.null_origin?c.push('xhr-streaming'):b['xdr-streaming']&&!a.cookie_needed&&!a.null_origin?c.push('xdr-streaming'):d(['iframe-eventsource','iframe-htmlfile']),b['xhr-polling']&&!a.null_origin?c.push('xhr-polling'):b['xdr-polling']&&!a.cookie_needed&&!a.null_origin?c.push('xdr-polling'):d(['iframe-xhr-polling','jsonp-polling']),c},z='_sockjs_global',a.createHook=function(){var d='a'+a.random_string(8);if(!(z in c)){var b={};c[z]=function(a){return a in b||(b[a]={id:a,del:function(){delete b[a]}}),b[a]}}return c[z](d)},a.attachMessage=function(b){a.attachEvent('message',b)},a.attachEvent=function(a,b){c.addEventListener!==void 0?c.addEventListener(a,b,!1):(d.attachEvent('on'+a,b),c.attachEvent('on'+a,b))},a.detachMessage=function(b){a.detachEvent('message',b)},a.detachEvent=function(a,b){c.addEventListener!==void 0?c.removeEventListener(a,b,!1):(d.detachEvent('on'+a,b),c.detachEvent('on'+a,b))},n={},C=!1,Q=function(){for(var a in n)n[a](),delete n[a]},P=function(){if(C)return;C=!0,Q()},a.attachEvent('beforeunload',P),a.attachEvent('unload',P),a.unload_add=function(c){var b=a.random_string(8);return n[b]=c,C&&a.delay(Q),b},a.unload_del=function(a){a in n&&delete n[a]},a.createIframe=function(j,k){var b=d.createElement('iframe'),c,h,g=function(){clearTimeout(c);try{b.onload=null}catch(a){}b.onerror=null},e=function(){b&&(g(),setTimeout(function(){b&&b.parentNode.removeChild(b),b=null},0),a.unload_del(h))},f=function(a){b&&(e(),k(a))},i=function(a,c){try{b&&b.contentWindow&&b.contentWindow.postMessage(a,c)}catch(a){}};return b.src=j,b.style.display='none',b.style.position='absolute',b.onerror=function(){f('onerror')},b.onload=function(){clearTimeout(c),c=setTimeout(function(){f('onload timeout')},2e3)},d.body.appendChild(b),c=setTimeout(function(){f('timeout')},15e3),h=a.unload_add(e),{post:i,cleanup:e,loaded:g}},a.createHtmlfile=function(m,n){var b=new ActiveXObject('htmlfile'),j,i,d,h=function(){clearTimeout(j)},e=function(){b&&(h(),a.unload_del(i),d.parentNode.removeChild(d),d=b=null,CollectGarbage())},k=function(a){b&&(e(),n(a))},l=function(a,b){try{d&&d.contentWindow&&d.contentWindow.postMessage(a,b)}catch(a){}};b.open(),b.write('<html><script>document.domain="'+document.domain+'";'+'</s'+'cript></html>'),b.close(),b.parentWindow[g]=c[g];var f=b.createElement('div');return b.body.appendChild(f),d=b.createElement('iframe'),f.appendChild(d),d.src=m,j=setTimeout(function(){k('timeout')},15e3),i=a.unload_add(e),{post:l,cleanup:e,loaded:h}},p=function(){},p.prototype=new l(['chunk','finish']),p.prototype._start=function(g,e,h,d){var b=this;try{b.xhr=new XMLHttpRequest}catch(a){}if(!b.xhr)try{b.xhr=new c.ActiveXObject('Microsoft.XMLHTTP')}catch(a){}(c.ActiveXObject||c.XDomainRequest)&&(e+=(e.indexOf('?')===-1?'?t=':'&t=')+ +new Date),b.unload_ref=a.unload_add(function(){b._cleanup(!0)});try{b.xhr.open(g,e,!0)}catch(a){b.emit('finish',0,''),b._cleanup();return}if(d&&d.no_credentials||(b.xhr.withCredentials='true'),d&&d.headers)for(var f in d.headers)b.xhr.setRequestHeader(f,d.headers[f]);b.xhr.onreadystatechange=function(){if(b.xhr){var a=b.xhr;switch(a.readyState){case 3:try{var d=a.status,c=a.responseText}catch(a){}c&&c.length>0&&b.emit('chunk',d,c);break;case 4:b.emit('finish',a.status,a.responseText);b._cleanup(!1);break}}},b.xhr.send(h)},p.prototype._cleanup=function(c){var b=this;if(!b.xhr)return;if(a.unload_del(b.unload_ref),b.xhr.onreadystatechange=function(){},c)try{b.xhr.abort()}catch(a){}b.unload_ref=b.xhr=null},p.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)},Z=a.XHRCorsObject=function(){var b=this,c=arguments;a.delay(function(){b._start.apply(b,c)})},Z.prototype=new p,a0=a.XHRLocalObject=function(c,d,e){var b=this;a.delay(function(){b._start(c,d,e,{no_credentials:!0})})},a0.prototype=new p,x=a.XDRObject=function(c,d,e){var b=this;a.delay(function(){b._start(c,d,e)})},x.prototype=new l(['chunk','finish']),x.prototype._start=function(f,d,g){var b=this,c=new XDomainRequest;d+=(d.indexOf('?')===-1?'?t=':'&t=')+ +new Date;var e=c.ontimeout=c.onerror=function(){b.emit('finish',0,''),b._cleanup(!1)};c.onprogress=function(){b.emit('chunk',200,c.responseText)},c.onload=function(){b.emit('finish',200,c.responseText),b._cleanup(!1)},b.xdr=c,b.unload_ref=a.unload_add(function(){b._cleanup(!0)});try{b.xdr.open(f,d),b.xdr.send(g)}catch(a){e()}},x.prototype._cleanup=function(c){var b=this;if(!b.xdr)return;if(a.unload_del(b.unload_ref),b.xdr.ontimeout=b.xdr.onerror=b.xdr.onprogress=b.xdr.onload=null,c)try{b.xdr.abort()}catch(a){}b.unload_ref=b.xdr=null},x.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)},a.isXHRCorsCapable=function(){return c.XMLHttpRequest&&'withCredentials'in new XMLHttpRequest?1:c.XDomainRequest&&d.domain?2:e.enabled()?3:4},b=function(g,d,f){if(this===window)return new b(g,d,f);var c=this,e;c._options={devel:!1,debug:!1,protocols_whitelist:[],info:undefined,rtt:undefined},f&&a.objectExtend(c._options,f),c._base_url=a.amendUrl(g),c._server=c._options.server||a.random_number_string(1e3),c._options.protocols_whitelist&&c._options.protocols_whitelist.length?e=c._options.protocols_whitelist:(typeof d==='string'&&d.length>0?e=[d]:a.isArray(d)?e=d:e=null,e&&c._debug('Deprecated API: Use "protocols_whitelist" option instead of supplying protocol list as a second parameter to SockJS constructor.')),c._protocols=[],c.protocol=null,c.readyState=b.CONNECTING,c._ir=T(c._base_url),c._ir.onfinish=function(b,d){c._ir=null,b?(c._options.info&&(b=a.objectExtend(b,c._options.info)),c._options.rtt&&(d=c._options.rtt),c._applyInfo(b,d,e),c._didClose()):c._didClose(1002,"Can't connect to server",!0)}},b.prototype=new m,b.version='0.3.1.7.ga67f.dirty',b.CONNECTING=0,b.OPEN=1,b.CLOSING=2,b.CLOSED=3,b.prototype._debug=function(){this._options.debug&&a.log.apply(a,arguments)},b.prototype._dispatchOpen=function(){var a=this;a.readyState===b.CONNECTING?(a._transport_tref&&(clearTimeout(a._transport_tref),a._transport_tref=null),a.readyState=b.OPEN,a.dispatchEvent(new f('open'))):a._didClose(1006,'Server lost session')},b.prototype._dispatchMessage=function(c){var a=this;if(a.readyState!==b.OPEN)return;a.dispatchEvent(new f('message',{data:c}))},b.prototype._dispatchHeartbeat=function(c){var a=this;if(a.readyState!==b.OPEN)return;a.dispatchEvent(new f('heartbeat',{}))},b.prototype._didClose=function(e,g,h){var c=this;if(c.readyState!==b.CONNECTING&&c.readyState!==b.OPEN&&c.readyState!==b.CLOSING)throw new Error('INVALID_STATE_ERR');c._ir&&(c._ir.nuke(),c._ir=null),c._transport&&(c._transport.doCleanup(),c._transport=null);var d=new f('close',{code:e,reason:g,wasClean:a.userSetCode(e)});if(!a.userSetCode(e)&&c.readyState===b.CONNECTING&&!h){if(c._try_next_protocol(d))return;d=new f('close',{code:2e3,reason:'All transports failed',wasClean:!1,last_event:d})}c.readyState=b.CLOSED,a.delay(function(){c.dispatchEvent(d)})},b.prototype._didMessage=function(c){var b=this,e=c.slice(0,1);switch(e){case'o':b._dispatchOpen();break;case'a':var a=JSON.parse(c.slice(1)||'[]');for(var d=0;d<a.length;d++)b._dispatchMessage(a[d]);break;case'm':var a=JSON.parse(c.slice(1)||'null');b._dispatchMessage(a);break;case'c':var a=JSON.parse(c.slice(1)||'[]');b._didClose(a[0],a[1]);break;case'h':b._dispatchHeartbeat();break}},b.prototype._try_next_protocol=function(j){var c=this;c.protocol&&(c._debug('Closed transport:',c.protocol,''+j),c.protocol=null),c._transport_tref&&(clearTimeout(c._transport_tref),c._transport_tref=null);while(1){var e=c.protocol=c._protocols.shift();if(!e)return!1;if(b[e]&&b[e].need_body===!0&&(!d.body||d.readyState!==void 0&&d.readyState!=='complete'))return c._protocols.unshift(e),c.protocol='waiting-for-load',a.attachEvent('load',function(){c._try_next_protocol()}),!0;if(b[e]&&b[e].enabled(c._options)){var g=b[e].roundTrips||1,h=(c._options.rto||0)*g||5e3;c._transport_tref=a.delay(h,function(){c.readyState===b.CONNECTING&&c._didClose(2007,'Transport timeouted')});var i=a.random_string(8),f=c._base_url+'/'+c._server+'/'+i;return c._debug('Opening transport:',e,' url:'+f,' RTO:'+c._options.rto),c._transport=new b[e](c,f,c._base_url),!0}c._debug('Skipping transport:',e)}},b.prototype.close=function(d,e){var c=this;if(d&&!a.userSetCode(d))throw new Error('INVALID_ACCESS_ERR');return c.readyState!==b.CONNECTING&&c.readyState!==b.OPEN?!1:(c.readyState=b.CLOSING,c._didClose(d||1e3,e||'Normal closure'),!0)},b.prototype.send=function(d){var c=this;if(c.readyState===b.CONNECTING)throw new Error('INVALID_STATE_ERR');return c.readyState===b.OPEN&&c._transport.doSend(a.quote(''+d)),!0},b.prototype._applyInfo=function(c,e,g){var b=this;b._options.info=c,b._options.rtt=e,b._options.rto=a.countRTO(e),b._options.info.null_origin=!d.domain;var f=a.probeProtocols();b._protocols=a.detectProtocols(f,g,c)},t=b.websocket=function(f,g){var b=this,d=g+'/websocket';d.slice(0,5)==='https'?d='wss'+d.slice(5):d='ws'+d.slice(4),b.ri=f,b.url=d;var e=c.WebSocket||c.MozWebSocket;b.ws=new e(b.url),b.ws.onmessage=function(a){b.ri._didMessage(a.data)},b.unload_ref=a.unload_add(function(){b.ws.close()}),b.ws.onclose=function(){b.ri._didMessage(a.closeFrame(1006,'WebSocket connection broken'))}},t.prototype.doSend=function(a){this.ws.send('['+a+']')},t.prototype.doCleanup=function(){var b=this,c=b.ws;c&&(c.onmessage=c.onclose=null,c.close(),a.unload_del(b.unload_ref),b.unload_ref=b.ri=b.ws=null)},t.enabled=function(){return!!(c.WebSocket||c.MozWebSocket)},t.roundTrips=2,j=function(){},j.prototype.send_constructor=function(b){var a=this;a.send_buffer=[],a.sender=b},j.prototype.doSend=function(b){var a=this;a.send_buffer.push(b),a.send_stop||a.send_schedule()},j.prototype.send_schedule_wait=function(){var b=this,c;b.send_stop=function(){b.send_stop=null,clearTimeout(c)},c=a.delay(25,function(){b.send_stop=null,b.send_schedule()})},j.prototype.send_schedule=function(){var a=this;if(a.send_buffer.length>0){var b='['+a.send_buffer.join(',')+']';a.send_stop=a.sender(a.trans_url,b,function(){a.send_stop=null,a.send_schedule_wait()}),a.send_buffer=[]}},j.prototype.send_destructor=function(){var a=this;a._send_stop&&a._send_stop(),a._send_stop=null},X=function(i,j,k){var f=this;if(!('_send_form'in f)){var c=f._send_form=d.createElement('form'),e=f._send_area=d.createElement('textarea');e.name='d',c.style.display='none',c.style.position='absolute',c.method='POST',c.enctype='application/x-www-form-urlencoded',c.acceptCharset='UTF-8',c.appendChild(e),d.body.appendChild(c)}var c=f._send_form,e=f._send_area,g='a'+a.random_string(8);c.target=g,c.action=i+'/jsonp_send?i='+g;var b;try{b=d.createElement('<iframe name="'+g+'">')}catch(a){b=d.createElement('iframe'),b.name=g}b.id=g,c.appendChild(b),b.style.display='none';try{e.value=j}catch(b){a.log('Your browser is seriously broken. Go home! '+b.message)}c.submit();var h=function(c){if(!b.onerror)return;b.onreadystatechange=b.onerror=b.onload=null,a.delay(500,function(){b.parentNode.removeChild(b),b=null}),e.value='',k()};return b.onerror=b.onload=h,b.onreadystatechange=function(a){b.readyState=='complete'&&h()},h},R=function(a){return function(d,e,b){var c=new a('POST',d+'/xhr_send',e);return c.onfinish=function(a,c){b(a)},function(a){b(0,a)}}},$=function(k,i){var j,b=d.createElement('script'),c,e=function(a){c&&(c.parentNode.removeChild(c),c=null),b&&(clearTimeout(j),b.parentNode.removeChild(b),b.onreadystatechange=b.onerror=b.onload=b.onclick=null,b=null,i(a),i=null)},g=!1,h=null;if(b.id='a'+a.random_string(8),b.src=k,b.type='text/javascript',b.charset='UTF-8',b.onerror=function(b){h||(h=setTimeout(function(){g||e(a.closeFrame(1006,'JSONP script loaded abnormally (onerror)'))},1e3))},b.onload=function(b){e(a.closeFrame(1006,'JSONP script loaded abnormally (onload)'))},b.onreadystatechange=function(c){if(/loaded|closed/.test(b.readyState)){if(b&&b.htmlFor&&b.onclick){g=!0;try{b.onclick()}catch(a){}}b&&e(a.closeFrame(1006,'JSONP script loaded abnormally (onreadystatechange)'))}},b.async===void 0&&d.attachEvent)if(!/opera/i.test(navigator.userAgent)){try{b.htmlFor=b.id,b.event='onclick'}catch(a){}b.async=!0}else c=d.createElement('script'),c.text="try{var a = document.getElementById('"+b.id+"'); if(a)a.onerror();}catch(x){};",b.async=c.async=!1;b.async!==void 0&&(b.async=!0),j=setTimeout(function(){e(a.closeFrame(1006,'JSONP script loaded abnormally (timeout)'))},35e3);var f=d.getElementsByTagName('head')[0];return f.insertBefore(b,f.firstChild),c&&f.insertBefore(c,f.firstChild),e},r=b['jsonp-polling']=function(c,d){a.polluteGlobalNamespace();var b=this;b.ri=c,b.trans_url=d,b.send_constructor(X),b._schedule_recv()},r.prototype=new j,r.prototype._schedule_recv=function(){var a=this,b=function(b){a._recv_stop=null,b&&(a._is_closing||a.ri._didMessage(b)),a._is_closing||a._schedule_recv()};a._recv_stop=a1(a.trans_url+'/jsonp',$,b)},r.enabled=function(){return!0},r.need_body=!0,r.prototype.doCleanup=function(){var a=this;a._is_closing=!0,a._recv_stop&&a._recv_stop(),a.ri=a._recv_stop=null,a.send_destructor()},a1=function(i,j,k){var b='a'+a.random_string(6),d=i+'?c='+escape(g+'.'+b),e=function(a){delete c[g][b],k(a)},f=j(d,e);c[g][b]=f;var h=function(){c[g][b]&&c[g][b](a.closeFrame(1e3,'JSONP user aborted read'))};return h},i=function(){},i.prototype=new j,i.prototype.run=function(b,c,e,f,d){var a=this;a.ri=b,a.trans_url=c,a.send_constructor(R(d)),a.poll=new G(b,f,c+e,d)},i.prototype.doCleanup=function(){var a=this;a.poll&&(a.poll.abort(),a.poll=null)},q=b['xhr-streaming']=function(b,c){this.run(b,c,'/xhr_streaming',k,a.XHRCorsObject)},q.prototype=new i,q.enabled=function(){return c.XMLHttpRequest&&'withCredentials'in new XMLHttpRequest&&!/opera/i.test(navigator.userAgent)},q.roundTrips=2,q.need_body=!0,u=b['xdr-streaming']=function(b,c){this.run(b,c,'/xhr_streaming',k,a.XDRObject)},u.prototype=new i,u.enabled=function(){return!!c.XDomainRequest},u.roundTrips=2,B=b['xhr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XHRCorsObject)},B.prototype=new i,B.enabled=q.enabled,B.roundTrips=2,J=b['xdr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XDRObject)},J.prototype=new i,J.enabled=u.enabled,J.roundTrips=2,e=function(){},e.prototype.i_constructor=function(e,f,d){var b=this;b.ri=e,b.origin=a.getOrigin(d),b.base_url=d,b.trans_url=f;var c=d+'/iframe.html';b.ri._options.devel&&(c+='?t='+ +new Date),b.window_id=a.random_string(8),c+='#'+b.window_id,b.iframeObj=a.createIframe(c,function(a){b.ri._didClose(1006,'Unable to load an iframe ('+a+')')}),b.onmessage_cb=a.bind(b.onmessage,b),a.attachMessage(b.onmessage_cb)},e.prototype.doCleanup=function(){var b=this;if(b.iframeObj){a.detachMessage(b.onmessage_cb);try{b.iframeObj.iframe.contentWindow&&b.postMessage('c')}catch(a){}b.iframeObj.cleanup(),b.iframeObj=null,b.onmessage_cb=b.iframeObj=null}},e.prototype.onmessage=function(c){var a=this;if(c.origin!==a.origin)return;var d=c.data.slice(0,8),e=c.data.slice(8,9),f=c.data.slice(9);if(d!==a.window_id)return;switch(e){case's':a.iframeObj.loaded();a.postMessage('s',JSON.stringify([b.version,a.protocol,a.trans_url,a.base_url]));break;case't':a.ri._didMessage(f);break}},e.prototype.postMessage=function(b,c){var a=this;a.iframeObj.post(a.window_id+b+(c||''),a.origin)},e.prototype.doSend=function(a){this.postMessage('m',a)},e.enabled=function(){var a=navigator&&navigator.userAgent&&navigator.userAgent.indexOf('Konqueror')!==-1;return(typeof c.postMessage==='function'||typeof c.postMessage==='object')&&!a},F=function(b,d){parent!==c?parent.postMessage(N+b+(d||''),'*'):a.log("Can't postMessage, no parent window.",b,d)},h=function(){},h.prototype._didClose=function(b,c){F('t',a.closeFrame(b,c))},h.prototype._didMessage=function(a){F('t',a)},h.prototype._doSend=function(a){this._transport.doSend(a)},h.prototype._doCleanup=function(){this._transport.doCleanup()},a.parent_origin=undefined,b.bootstrap_iframe=function(){var e;N=d.location.hash.slice(1);var f=function(d){if(d.source!==parent)return;if(a.parent_origin===void 0&&(a.parent_origin=d.origin),d.origin!==a.parent_origin)return;var l=d.data.slice(0,8),m=d.data.slice(8,9),j=d.data.slice(9);if(l!==N)return;switch(m){case's':var f=JSON.parse(j);var k=f[0];var n=f[1];var g=f[2];var i=f[3];k!==b.version&&a.log('Incompatibile SockJS! Main site uses: "'+k+'", the iframe:'+' "'+b.version+'".');if(!(a.flatUrl(g)&&a.flatUrl(i))){a.log('Only basic urls are supported in SockJS');return}if(!(a.isSameOriginUrl(g)&&a.isSameOriginUrl(i))){a.log("Can't connect to different domain from within an iframe. ("+JSON.stringify([c.location.href,g,i])+')');return}e=new h;e._transport=new h[n](e,g,i);break;case'm':e._doSend(j);break;case'c':e&&e._doCleanup();e=null;break}};a.attachMessage(f),F('s')},o=function(c,d){var b=this;a.delay(function(){b.doXhr(c,d)})},o.prototype=new l(['finish']),o.prototype.doXhr=function(f,g){var c=this,e=new Date().getTime(),b=new g('GET',f+'/info'),d=a.delay(8e3,function(){b.ontimeout()});b.onfinish=function(f,g){if(clearTimeout(d),d=null,f===200){var b=new Date().getTime()-e,a=JSON.parse(g);typeof a!=='object'&&(a={}),c.emit('finish',a,b)}else c.emit('finish')},b.ontimeout=function(){b.close(),c.emit('finish')}},L=function(f){var b=this,c=function(){var a=new e;a.protocol='w-iframe-info-receiver';var c=function(c){if(typeof c==='string'&&c.substr(0,1)==='m'){var d=JSON.parse(c.substr(1)),e=d[0],f=d[1];b.emit('finish',e,f)}else b.emit('finish');a.doCleanup(),a=null},d={_options:{},_didClose:c,_didMessage:c};a.i_constructor(d,f,f)};d.body?c():a.attachEvent('load',c)},L.prototype=new l(['finish']),K=function(){var b=this;a.delay(function(){b.emit('finish',{},2e3)})},K.prototype=new l(['finish']),T=function(b){if(a.isSameOriginUrl(b))return new o(b,a.XHRLocalObject);switch(a.isXHRCorsCapable()){case 1:return new o(b,a.XHRCorsObject);case 2:return new o(b,a.XDRObject);case 3:return new L(b);default:return new K}},U=h['w-iframe-info-receiver']=function(b,e,d){var c=new o(d,a.XHRLocalObject);c.onfinish=function(a,c){b._didMessage('m'+JSON.stringify([a,c])),b._didClose()}},U.prototype.doCleanup=function(){},y=b['iframe-eventsource']=function(){var a=this;a.protocol='w-iframe-eventsource',a.i_constructor.apply(a,arguments)},y.prototype=new e,y.enabled=function(){return'EventSource'in c&&e.enabled()},y.need_body=!0,y.roundTrips=3,W=h['w-iframe-eventsource']=function(b,c){this.run(b,c,'/eventsource',A,a.XHRLocalObject)},W.prototype=new i,w=b['iframe-xhr-polling']=function(){var a=this;a.protocol='w-iframe-xhr-polling',a.i_constructor.apply(a,arguments)},w.prototype=new e,w.enabled=function(){return c.XMLHttpRequest&&e.enabled()},w.need_body=!0,w.roundTrips=3,Y=h['w-iframe-xhr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XHRLocalObject)},Y.prototype=new i,v=b['iframe-htmlfile']=function(){var a=this;a.protocol='w-iframe-htmlfile',a.i_constructor.apply(a,arguments)},v.prototype=new e,v.enabled=function(){return e.enabled()},v.need_body=!0,v.roundTrips=3,_=h['w-iframe-htmlfile']=function(b,c){this.run(b,c,'/htmlfile',H,a.XHRLocalObject)},_.prototype=new i,G=function(b,c,d,e){var a=this;a.ri=b,a.Receiver=c,a.recv_url=d,a.AjaxObject=e,a._scheduleRecv()},G.prototype._scheduleRecv=function(){var a=this,b=a.poll=new a.Receiver(a.recv_url,a.AjaxObject),c=0;b.onmessage=function(b){c+=1,a.ri._didMessage(b.data)},b.onclose=function(c){a.poll=b=b.onmessage=b.onclose=null,a.poll_is_closing||(c.reason==='permanent'?a.ri._didClose(1006,'Polling error ('+c.reason+')'):a._scheduleRecv())}},G.prototype.abort=function(){var a=this;a.poll_is_closing=!0,a.poll&&a.poll.abort()},A=function(d){var c=this,b=new EventSource(d);b.onmessage=function(a){c.dispatchEvent(new f('message',{data:unescape(a.data)}))},c.es_close=b.onerror=function(g,e){var d=e?'user':b.readyState!==2?'network':'permanent';c.es_close=b.onmessage=b.onerror=null,b.close(),b=null,a.delay(200,function(){c.dispatchEvent(new f('close',{reason:d}))})}},A.prototype=new m,A.prototype.abort=function(){var a=this;a.es_close&&a.es_close({},!0)},a2=function(){if(I===undefined)if('ActiveXObject'in c)try{I=!!new ActiveXObject('htmlfile')}catch(a){}else I=!1;return I},H=function(e){var b=this;a.polluteGlobalNamespace(),b.id='a'+a.random_string(6,26),e+=(e.indexOf('?')===-1?'?c=':'&c=')+escape(g+'.'+b.id);var h=a2()?a.createHtmlfile:a.createIframe,d;c[g][b.id]={start:function(){d.loaded()},message:function(a){b.dispatchEvent(new f('message',{data:a}))},stop:function(){b.iframe_close({},'network')}},b.iframe_close=function(e,a){d.cleanup(),b.iframe_close=d=null,delete c[g][b.id],b.dispatchEvent(new f('close',{reason:a}))},d=h(e,function(a){b.iframe_close({},'permanent')})},H.prototype=new m,H.prototype.abort=function(){var a=this;a.iframe_close&&a.iframe_close({},'user')},k=function(c,d){var a=this,b=0;a.xo=new d('POST',c,null),a.xo.onchunk=function(g,h){if(g!==200)return;while(1){var d=h.slice(b),c=d.indexOf('\n');if(c===-1)break;b+=c+1;var e=d.slice(0,c);a.dispatchEvent(new f('message',{data:e}))}},a.xo.onfinish=function(b,d){a.xo.onchunk(b,d),a.xo=null;var c=b===200?'network':'permanent';a.dispatchEvent(new f('close',{reason:c}))}},k.prototype=new m,k.prototype.abort=function(){var a=this;a.xo&&(a.xo.close(),a.dispatchEvent(new f('close',{reason:'user'})),a.xo=null)},b.getUtils=function(){return a},b.getIframeTransport=function(){return e},b}();'_sockjs_onload'in window&&setTimeout(_sockjs_onload,1),typeof define==='function'&&define.amd&&define('sockjs',[],function(){return SockJS}),typeof module==='object'&&module&&module.exports&&(module.exports=SockJS)},{}],26:[function(a,b,c){b.exports=a('./lib/index.js')},{'./lib/index.js':27}],27:[function(b,e,f){function a(b){return new a.Terminal(b)}var c=b('__browserify_Buffer').Buffer,d='/../../node_modules/term.js/lib';a.middleware=function(d){var e=b('url');return d=d||{},d.path=d.path||'/term.js',function(f,b,g){if(e.parse(f.url).pathname!==d.path)return g();if(+new Date(f.headers['if-modified-since'])===a.last){b.statusCode=304,b.end();return}b.writeHead(200,{'Content-Type':'application/javascript; charset=utf-8','Content-Length':c.byteLength(a.script),'Last-Modified':a.last}),b.end(a.script)}},a.path=d+'/../src/term.js',a.__defineGetter__('script',function(){return a._script?a._script:(a.last=+new Date,a._script=b('fs').readFileSync(a.path,'utf8'))}),a.__defineGetter__('Terminal',function(){return a._Terminal?a._Terminal:a._Terminal=b('../src/term')}),e.exports=a},{'../src/term':28,__browserify_Buffer:13,fs:8,url:11}],28:[function(c,a,d){var b=self;(function(){'use strict';function f(){this._events=this._events||{}}function b(a){var c=this;if(!(this instanceof b))return new b(arguments[0],arguments[1],arguments[2]);f.call(this),typeof a==='number'&&(a={cols:arguments[0],rows:arguments[1],handler:arguments[2]}),a=a||{},v(t(b.defaults),function(d){a[d]==null&&(a[d]=b.options[d],b[d]!==b.defaults[d]&&(a[d]=b[d])),c[d]=a[d]}),a.colors.length===8?a.colors=a.colors.concat(b._colors.slice(8)):a.colors.length===16?a.colors=a.colors.concat(b._colors.slice(16)):a.colors.length===10?a.colors=a.colors.slice(0,-2).concat(b._colors.slice(8,-2),a.colors.slice(-2)):a.colors.length===18&&(a.colors=a.colors.concat(b._colors.slice(16,-2),a.colors.slice(-2))),this.colors=a.colors,this.options=a,this.parent=a.body||a.parent||(l?l.getElementsByTagName('body')[0]:null),this.cols=a.cols||a.geometry[0],this.rows=a.rows||a.geometry[1],a.handler&&this.on('data',a.handler),this.ybase=0,this.ydisp=0,this.x=0,this.y=0,this.cursorState=0,this.cursorHidden=!1,this.convertEol,this.state=0,this.queue='',this.scrollTop=0,this.scrollBottom=this.rows-1,this.applicationKeypad=!1,this.applicationCursor=!1,this.originMode=!1,this.insertMode=!1,this.wraparoundMode=!1,this.normal=null,this.prefixMode=!1,this.selectMode=!1,this.visualMode=!1,this.searchMode=!1,this.searchDown,this.entry='',this.entryPrefix='Search: ',this._real,this._selected,this._textarea,this.charset=null,this.gcharset=null,this.glevel=0,this.charsets=[null],this.decLocator,this.x10Mouse,this.vt200Mouse,this.vt300Mouse,this.normalMouse,this.mouseEvents,this.sendFocus,this.utfMouse,this.sgrMouse,this.urxvtMouse,this.element,this.children,this.refreshStart,this.refreshEnd,this.savedX,this.savedY,this.savedCols,this.readable=!0,this.writable=!0,this.defAttr=131840,this.curAttr=this.defAttr,this.params=[],this.currentParam=0,this.prefix='',this.postfix='',this.lines=[];var d=this.rows;while(d--)this.lines.push(this.blankLine());this.tabs,this.setupStops()}function e(a,b,c,d){a.addEventListener(b,c,d||!1)}function q(a,b,c,d){a.removeEventListener(b,c,d||!1)}function d(a){return a.preventDefault&&a.preventDefault(),a.returnValue=!1,a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1}function u(a,c){function b(){this.constructor=a}b.prototype=c.prototype,a.prototype=new b}function x(c){var b=c.getElementsByTagName('body')[0],a=c.createElement('span');a.innerHTML='hello world',b.appendChild(a);var d=a.scrollWidth;a.style.fontWeight='bold';var e=a.scrollWidth;return b.removeChild(a),d!==e}function w(b,c){var a=b.length;while(a--)if(b[a]===c)return a;return-1}function m(a){return a<='ï¼€'?!1:a>='ï¼'&&a<='ï¾¾'||a>='ï¿‚'&&a<='ᅦ'||a>='ᅧ'&&a<='ï¿'||a>='ï¿’'&&a<='ï¿—'||a>='ᅳ'&&a<='ᅵ'||a>='ï¿ '&&a<='₩'||a>='│'&&a<='ï¿®'}function h(i,k,j){var f=i<<16|k<<8|j;if(h._cache[f]!=null)return h._cache[f];var g=Infinity,c=-1,a=0,d,l,m,n,e;for(;a<b.vcolors.length;a++){if(d=b.vcolors[a],l=d[0],m=d[1],n=d[2],e=h.distance(i,k,j,l,m,n),e===0){c=a;break}e<g&&(g=e,c=a)}return h._cache[f]=c}function v(a,c,d){if(a.forEach)return a.forEach(c,d);for(var b=0;b<a.length;b++)c.call(d,a[b],b,a)}function t(a){if(Object.keys)return Object.keys(a);var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}var l=this.document;f.prototype.addListener=function(a,b){this._events[a]=this._events[a]||[],this._events[a].push(b)},f.prototype.on=f.prototype.addListener,f.prototype.removeListener=function(c,d){if(!this._events[c])return;var a=this._events[c],b=a.length;while(b--)if(a[b]===d||a[b].listener===d){a.splice(b,1);return}},f.prototype.off=f.prototype.removeListener,f.prototype.removeAllListeners=function(a){this._events[a]&&delete this._events[a]},f.prototype.once=function(b,c){function a(){var d=Array.prototype.slice.call(arguments);return this.removeListener(b,a),c.apply(this,d)}return a.listener=c,this.on(b,a)},f.prototype.emit=function(c){if(!this._events[c])return;var d=Array.prototype.slice.call(arguments,1),b=this._events[c],e=b.length,a=0;for(;a<e;a++)b[a].apply(this,d)},f.prototype.listeners=function(a){return this._events[a]=this._events[a]||[]};var c=0,n=1,o=2,p=3,k=4,r=5,j=6;u(b,f),b.prototype.eraseAttr=function(){return this.defAttr&-512|this.curAttr&511},b.tangoColors=['#2e3436','#cc0000','#4e9a06','#c4a000','#3465a4','#75507b','#06989a','#d3d7cf','#555753','#ef2929','#8ae234','#fce94f','#729fcf','#ad7fa8','#34e2e2','#eeeeec'],b.xtermColors=['#000000','#cd0000','#00cd00','#cdcd00','#0000ee','#cd00cd','#00cdcd','#e5e5e5','#7f7f7f','#ff0000','#00ff00','#ffff00','#5c5cff','#ff00ff','#00ffff','#ffffff'],b.colors=function(d,c,a){function f(a,b,c){d.push('#'+e(a)+e(b)+e(c))}function e(a){return a=a.toString(16),a.length<2?'0'+a:a}for(d=b.tangoColors.slice(),c=[0,95,135,175,215,255],a=0;a<216;a++)f(c[a/36%6|0],c[a/6%6|0],c[a%6]);for(a=0;a<24;a++)c=8+a*10,f(c,c,c);return d}(),b.colors[256]='#000000',b.colors[257]='#f0f0f0',b._colors=b.colors.slice(),b.vcolors=function(d,e,a,c){for(d=[],e=b.colors,a=0;a<256;a++)c=parseInt(e[a].substring(1),16),d.push([c>>16&255,c>>8&255,c&255]);return d}(),b.defaults={colors:b.colors,convertEol:!1,termName:'xterm',geometry:[80,24],cursorBlink:!0,visualBell:!1,popOnBell:!1,scrollback:1e3,screenKeys:!1,debug:!1,useStyle:!1},b.options={},v(t(b.defaults),function(a){b[a]=b.defaults[a],b.options[a]=b.defaults[a]}),b.focus=null,b.prototype.focus=function(){if(b.focus===this)return;b.focus&&b.focus.blur(),this.sendFocus&&this.send('[I'),this.showCursor(),b.focus=this},b.prototype.blur=function(){if(b.focus!==this)return;this.cursorState=0,this.refresh(this.y,this.y),this.sendFocus&&this.send('[O'),b.focus=null},b.prototype.initGlobal=function(){var a=this.document;if(b._boundDocs=b._boundDocs||[],~w(b._boundDocs,a))return;b._boundDocs.push(a),b.bindPaste(a),b.bindKeys(a),b.bindCopy(a),b.fixIpad(a)},b.bindPaste=function(c){var a=c.defaultView;e(a,'paste',function(c){var a=b.focus;return a?(c.clipboardData?a.send(c.clipboardData.getData('text/plain')):a.context.clipboardData&&a.send(a.context.clipboardData.getData('Text')),a.element.contentEditable='inherit',d(c)):void 0})},b.bindKeys=function(a){e(a,'keydown',function(c){if(!b.focus)return;var a=c.target||c.srcElement;return a?a===b.focus.element||a===b.focus.context||a===b.focus.document||a===b.focus.body||a===b._textarea||a===b.focus.parent?b.focus.keyDown(c):void 0:void 0},!0),e(a,'keypress',function(c){if(!b.focus)return;var a=c.target||c.srcElement;return a?a===b.focus.element||a===b.focus.context||a===b.focus.document||a===b.focus.body||a===b._textarea||a===b.focus.parent?b.focus.keyPress(c):void 0:void 0},!0),e(a,'mousedown',function(c){if(!b.focus)return;var a=c.target||c.srcElement;if(!a)return;do if(a===b.focus.element)return;while(a=a.parentNode);b.focus.blur()})},b.bindCopy=function(c){var a=c.defaultView;e(a,'copy',function(e){var a=b.focus;if(!a)return;if(!a._selected)return;var c=a.getCopyTextarea(),d=a.grabText(a._selected.x1,a._selected.x2,a._selected.y1,a._selected.y2);a.emit('copy',d),c.focus(),c.textContent=d,c.value=d,c.setSelectionRange(0,d.length),i(function(){a.element.focus(),a.focus()},1)})},b.fixIpad=function(c){var a=c.createElement('textarea');a.style.position='absolute',a.style.width='0px',a.style.height='0px',a.style.opacity='0',a.style.backgroundColor='transparent',a.style.borderStyle='none',a.style.outlineStyle='none',a.autocapitalize='none',a.autocorrect='off',c.getElementsByTagName('body')[0].appendChild(a),b._textarea=a},b.prototype.open=function(f){var a=this,c=0,d;if(this.parent=f||this.parent,!this.parent)throw new Error('Terminal requires a parent element.');for(this.context=this.parent.ownerDocument.defaultView,this.document=this.parent.ownerDocument,this.body=this.document.getElementsByTagName('body')[0],this.context.navigator&&this.context.navigator.userAgent&&(this.isMac=!!~this.context.navigator.userAgent.indexOf('Mac'),this.isIpad=!!~this.context.navigator.userAgent.indexOf('iPad'),this.isIphone=!!~this.context.navigator.userAgent.indexOf('iPhone'),this.isMSIE=!!~this.context.navigator.userAgent.indexOf('MSIE')),this.element=this.document.createElement('div'),this.element.className='terminal',this.element.style.outline='none',this.element.setAttribute('tabindex',0),this.element.style.backgroundColor=this.colors[256],this.element.style.color=this.colors[257],this.children=[];c<this.rows;c++)d=this.document.createElement('div'),this.element.appendChild(d),this.children.push(d);this.parent.appendChild(this.element),this.refresh(0,this.rows-1),this.initGlobal(),this.focus(),this.startBlink(),e(this.element,'focus',function(){a.focus(),b._textarea.focus()}),e(this.element,'mousedown',function(){a.focus()}),e(this.element,'mousedown',function(c){var b=c.button!=null?+c.button:c.which!=null?c.which-1:null;if(a.isMSIE&&(b=b===1?0:b===4?1:b),b!==2)return;a.element.contentEditable='true',i(function(){a.element.contentEditable='inherit'},1)},!0),this.bindMouse(),b.brokenBold==null&&(b.brokenBold=x(this.document))},b.prototype.bindMouse=function(){function c(a){var c,d;if(c=m(a),d=l(a),!d)return;k(c,d);switch(a.type){case'mousedown':h=c;break;case'mouseup':h=32;break;case b:break}}function j(c){var a=h,b;if(b=l(c),!b)return;a+=32,k(a,b)}function i(c,b){if(!a.utfMouse){if(b===255)return c.push(0);b>127&&(b=127),c.push(b)}else{if(b===2047)return c.push(0);b<127?c.push(b):(b>2047&&(b=2047),c.push(192|b>>6),c.push(128|b&63))}}function k(b,c){if(a.vt300Mouse){b&=3,c.x-=32,c.y-=32;var d='[24';if(b===0)d+='1';else if(b===1)d+='3';else if(b===2)d+='5';else if(b===3)return;else d+='0';d+='~['+c.x+','+c.y+']\r',a.send(d);return}if(a.decLocator){b&=3,c.x-=32,c.y-=32,b===0?b=2:b===1?b=4:b===2?b=6:b===3&&(b=3),a.send('['+b+';'+(b===3?4:0)+';'+c.y+';'+c.x+';'+(c.page||0)+'&w');return}if(a.urxvtMouse){c.x-=32,c.y-=32,c.x++,c.y++,a.send('['+b+';'+c.x+';'+c.y+'M');return}if(a.sgrMouse){c.x-=32,c.y-=32,a.send('[<'+((b&3)===3?b&-4:b)+';'+c.x+';'+c.y+((b&3)===3?'m':'M'));return}var d=[];i(d,b),i(d,c.x),i(d,c.y),a.send('[M'+g.fromCharCode.apply(g,d))}function m(c){var b,f,g,e,d;switch(c.type){case'mousedown':b=c.button!=null?+c.button:c.which!=null?c.which-1:null;a.isMSIE&&(b=b===1?0:b===4?1:b);break;case'mouseup':b=3;break;case'DOMMouseScroll':b=c.detail<0?64:65;break;case'mousewheel':b=c.wheelDeltaY>0?64:65;break}return f=c.shiftKey?4:0,g=c.metaKey?8:0,e=c.ctrlKey?16:0,d=f|g|e,a.vt200Mouse?d&=e:a.normalMouse||(d=0),b=32+(d<<2)+b,b}function l(f){var c,d,g,h,e;if(f.pageX==null)return;c=f.pageX,d=f.pageY,e=a.element;while(e&&e!==a.document.documentElement)c-=e.offsetLeft,d-=e.offsetTop,e='offsetParent'in e?e.offsetParent:e.parentNode;return g=a.element.clientWidth,h=a.element.clientHeight,c=Math.round(c/g*a.cols),d=Math.round(d/h*a.rows),c<0&&(c=0),c>a.cols&&(c=a.cols),d<0&&(d=0),d>a.rows&&(d=a.rows),c+=32,d+=32,{x:c,y:d,type:f.type===b?'mousewheel':f.type}}var f=this.element,a=this,h=32,b='onmousewheel'in this.context?'mousewheel':'DOMMouseScroll';e(f,'mousedown',function(b){return a.mouseEvents?(c(b),a.focus(),a.vt200Mouse?(c({__proto__:b,type:'mouseup'}),d(b)):(a.normalMouse&&e(a.document,'mousemove',j),a.x10Mouse||e(a.document,'mouseup',function b(e){return c(e),a.normalMouse&&q(a.document,'mousemove',j),q(a.document,'mouseup',b),d(e)}),d(b))):void 0}),e(f,b,function(b){return a.mouseEvents?a.x10Mouse||a.vt300Mouse||a.decLocator?void 0:(c(b),d(b)):void 0}),e(f,b,function(b){return a.mouseEvents?void 0:a.applicationKeypad?void 0:(b.type==='DOMMouseScroll'?a.scrollDisp(b.detail<0?-5:5):a.scrollDisp(b.wheelDeltaY>0?-5:5),d(b))})},b.prototype.destroy=function(){this.readable=!1,this.writable=!1,this._events={},this.handler=function(){},this.write=function(){},this.element.parentNode&&this.element.parentNode.removeChild(this.element)},b.prototype.refresh=function(q,l){var o,g,f,n,a,h,p,c,j,k,e,d,r,i;for(l-q>=this.rows/2&&(i=this.element.parentNode,i&&i.removeChild(this.element)),p=this.cols,g=q,l>=this.lines.length&&(this.log('`end` is too large. Most likely a bad CSR.'),l=this.lines.length-1);g<=l;g++){for(r=g+this.ydisp,n=this.lines[r],a='',g===this.y&&this.cursorState&&(this.ydisp===this.ybase||this.selectMode)&&!this.cursorHidden?o=this.x:o=-1,j=this.defAttr,f=0;f<p;f++){c=n[f][0],h=n[f][1],f===o&&(c=-1),c!==j&&(j!==this.defAttr&&(a+='</span>'),c!==this.defAttr)&&(c===-1?a+='<span class="reverse-video terminal-cursor">':(a+='<span style="',k=c&511,e=c>>9&511,d=c>>18,d&1&&(b.brokenBold||(a+='font-weight:bold;'),e<8&&(e+=8)),d&2&&(a+='text-decoration:underline;'),d&4&&(d&2?(a=a.slice(0,-1),a+=' blink;'):a+='text-decoration:blink;'),d&8&&(k=c>>9&511,e=c&511,d&1&&e<8&&(e+=8)),d&16&&(a+='visibility:hidden;'),k!==256&&(a+='background-color:'+this.colors[k]+';'),e!==257&&(a+='color:'+this.colors[e]+';'),a+='">'));switch(h){case'&':a+='&';break;case'<':a+='<';break;case'>':a+='>';break;default:h<=' '?a+=' ':(m(h)&&f++,a+=h);break}j=c}j!==this.defAttr&&(a+='</span>'),this.children[g].innerHTML=a}i&&i.appendChild(this.element)},b.prototype._cursorBlink=function(){if(b.focus!==this)return;this.cursorState^=1,this.refresh(this.y,this.y)},b.prototype.showCursor=function(){this.cursorState||(this.cursorState=1,this.refresh(this.y,this.y))},b.prototype.startBlink=function(){if(!this.cursorBlink)return;var a=this;this._blinker=function(){a._cursorBlink()},this._blink=s(this._blinker,500)},b.prototype.refreshBlink=function(){if(!this.cursorBlink)return;clearInterval(this._blink),this._blink=s(this._blinker,500)},b.prototype.scroll=function(){var a;++this.ybase===this.scrollback&&(this.ybase=this.ybase/2|0,this.lines=this.lines.slice(-(this.ybase+this.rows)+1)),this.ydisp=this.ybase,a=this.ybase+this.rows-1,a-=this.rows-1-this.scrollBottom,a===this.lines.length?this.lines.push(this.blankLine()):this.lines.splice(a,0,this.blankLine()),this.scrollTop!==0&&(this.ybase!==0&&(this.ybase--,this.ydisp=this.ybase),this.lines.splice(this.ybase+this.scrollTop,1)),this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.scrollDisp=function(a){this.ydisp+=a,this.ydisp>this.ybase?this.ydisp=this.ybase:this.ydisp<0&&(this.ydisp=0),this.refresh(0,this.rows-1)},b.prototype.write=function(i){var l=i.length,f=0,h,d,a;for(this.refreshStart=this.y,this.refreshEnd=this.y,this.ybase!==this.ydisp&&(this.ydisp=this.ybase,this.maxRange());f<l;f++){a=i[f];switch(this.state){case c:switch(a){case'':this.bell();break;case'\n':case'':case'':this.convertEol&&(this.x=0);this.y++;this.y>this.scrollBottom&&(this.y--,this.scroll());break;case'\r':this.x=0;break;case'':this.x>0&&this.x--;break;case' ':this.x=this.nextStop();break;case'':this.setgLevel(1);break;case'':this.setgLevel(0);break;case'':this.state=n;break;default:if(a>=' '&&(this.charset&&this.charset[a]&&(a=this.charset[a]),this.x>=this.cols&&(this.x=0,this.y++,this.y>this.scrollBottom&&(this.y--,this.scroll())),this.lines[this.y+this.ybase][this.x]=[this.curAttr,a],this.x++,this.updateRange(this.y),m(a))){if(h=this.y+this.ybase,this.cols<2||this.x>=this.cols){this.lines[h][this.x-1]=[this.curAttr,' '];break}this.lines[h][this.x]=[this.curAttr,' '],this.x++}break}break;case n:switch(a){case'[':this.params=[];this.currentParam=0;this.state=o;break;case']':this.params=[];this.currentParam=0;this.state=p;break;case'P':this.params=[];this.currentParam=0;this.state=r;break;case'_':this.state=j;break;case'^':this.state=j;break;case'c':this.reset();break;case'E':this.x=0;case'D':this.index();break;case'M':this.reverseIndex();break;case'%':this.setgLevel(0);this.setgCharset(0,b.charsets.US);this.state=c;f++;break;case'(':case')':case'*':case'+':case'-':case'.':switch(a){case'(':this.gcharset=0;break;case')':this.gcharset=1;break;case'*':this.gcharset=2;break;case'+':this.gcharset=3;break;case'-':this.gcharset=1;break;case'.':this.gcharset=2;break}this.state=k;break;case'/':this.gcharset=3;this.state=k;f--;break;case'N':break;case'O':break;case'n':this.setgLevel(2);break;case'o':this.setgLevel(3);break;case'|':this.setgLevel(3);break;case'}':this.setgLevel(2);break;case'~':this.setgLevel(1);break;case'7':this.saveCursor();this.state=c;break;case'8':this.restoreCursor();this.state=c;break;case'#':this.state=c;f++;break;case'H':this.tabSet();break;case'=':this.log('Serial port requested application keypad.');this.applicationKeypad=!0;this.state=c;break;case'>':this.log('Switching back to normal keypad.');this.applicationKeypad=!1;this.state=c;break;default:this.state=c;this.error('Unknown ESC control: %s.',a);break}break;case k:switch(a){case'0':d=b.charsets.SCLD;break;case'A':d=b.charsets.UK;break;case'B':d=b.charsets.US;break;case'4':d=b.charsets.Dutch;break;case'C':case'5':d=b.charsets.Finnish;break;case'R':d=b.charsets.French;break;case'Q':d=b.charsets.FrenchCanadian;break;case'K':d=b.charsets.German;break;case'Y':d=b.charsets.Italian;break;case'E':case'6':d=b.charsets.NorwegianDanish;break;case'Z':d=b.charsets.Spanish;break;case'H':case'7':d=b.charsets.Swedish;break;case'=':d=b.charsets.Swiss;break;case'/':d=b.charsets.ISOLatin;f++;break;default:d=b.charsets.US;break}this.setgCharset(this.gcharset,d);this.gcharset=null;this.state=c;break;case p:if(a===''||a===''){a===''&&f++,this.params.push(this.currentParam);switch(this.params[0]){case 0:case 1:case 2:this.params[1]&&(this.title=this.params[1],this.handleTitle(this.title));break;case 3:break;case 4:case 5:break;case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:break;case 46:break;case 50:break;case 51:break;case 52:break;case 104:case 105:case 110:case 111:case 112:case 113:case 114:case 115:case 116:case 117:case 118:break}this.params=[],this.currentParam=0,this.state=c}else this.params.length?this.currentParam+=a:a>='0'&&a<='9'?this.currentParam=this.currentParam*10+a.charCodeAt(0)-48:a===';'&&(this.params.push(this.currentParam),this.currentParam='');break;case o:if(a==='?'||a==='>'||a==='!'){this.prefix=a;break}if(a>='0'&&a<='9'){this.currentParam=this.currentParam*10+a.charCodeAt(0)-48;break}if(a==='$'||a==='"'||a===' '||a==="'"){this.postfix=a;break}this.params.push(this.currentParam);this.currentParam=0;if(a===';')break;this.state=c;switch(a){case'A':this.cursorUp(this.params);break;case'B':this.cursorDown(this.params);break;case'C':this.cursorForward(this.params);break;case'D':this.cursorBackward(this.params);break;case'H':this.cursorPos(this.params);break;case'J':this.eraseInDisplay(this.params);break;case'K':this.eraseInLine(this.params);break;case'm':this.prefix||this.charAttributes(this.params);break;case'n':this.prefix||this.deviceStatus(this.params);break;case'@':this.insertChars(this.params);break;case'E':this.cursorNextLine(this.params);break;case'F':this.cursorPrecedingLine(this.params);break;case'G':this.cursorCharAbsolute(this.params);break;case'L':this.insertLines(this.params);break;case'M':this.deleteLines(this.params);break;case'P':this.deleteChars(this.params);break;case'X':this.eraseChars(this.params);break;case'`':this.charPosAbsolute(this.params);break;case'a':this.HPositionRelative(this.params);break;case'c':this.sendDeviceAttributes(this.params);break;case'd':this.linePosAbsolute(this.params);break;case'e':this.VPositionRelative(this.params);break;case'f':this.HVPosition(this.params);break;case'h':this.setMode(this.params);break;case'l':this.resetMode(this.params);break;case'r':this.setScrollRegion(this.params);break;case's':this.saveCursor(this.params);break;case'u':this.restoreCursor(this.params);break;case'I':this.cursorForwardTab(this.params);break;case'S':this.scrollUp(this.params);break;case'T':this.params.length<2&&!this.prefix&&this.scrollDown(this.params);break;case'Z':this.cursorBackwardTab(this.params);break;case'b':this.repeatPrecedingCharacter(this.params);break;case'g':this.tabClear(this.params);break;case'p':switch(this.prefix){case'!':this.softReset(this.params);break}break;default:this.error('Unknown CSI code: %s.',a);break}this.prefix='';this.postfix='';break;case r:if(a===''||a===''){a===''&&f++;switch(this.prefix){case'':break;case'$q':var e=this.currentParam,g=!1;switch(e){case'"q':e='0"q';break;case'"p':e='61"p';break;case'r':e=''+(this.scrollTop+1)+';'+(this.scrollBottom+1)+'r';break;case'm':e='0m';break;default:this.error('Unknown DCS Pt: %s.',e);e='';break}this.send('P'+ +g+'$r'+e+'\\');break;case'+p':break;case'+q':var e=this.currentParam,g=!1;this.send('P'+ +g+'+r'+e+'\\');break;default:this.error('Unknown DCS prefix: %s.',this.prefix);break}this.currentParam=0,this.prefix='',this.state=c}else this.currentParam?this.currentParam+=a:!this.prefix&&a!=='$'&&a!=='+'?this.currentParam=a:this.prefix.length===2?this.currentParam=a:this.prefix+=a;break;case j:(a===''||a==='')&&(a===''&&f++,this.state=c);break}}this.updateRange(this.y),this.refresh(this.refreshStart,this.refreshEnd)},b.prototype.writeln=function(a){this.write(a+'\r\n')},b.prototype.keyDown=function(b){var c=this,a;switch(b.keyCode){case 8:if(b.shiftKey){a='';break}a='';break;case 9:if(b.shiftKey){a='[Z';break}a=' ';break;case 13:a='\r';break;case 27:a='';break;case 37:if(this.applicationCursor){a='OD';break}a='[D';break;case 39:if(this.applicationCursor){a='OC';break}a='[C';break;case 38:if(this.applicationCursor){a='OA';break}if(b.ctrlKey)return this.scrollDisp(-1),d(b);a='[A';break;case 40:if(this.applicationCursor){a='OB';break}if(b.ctrlKey)return this.scrollDisp(1),d(b);a='[B';break;case 46:a='[3~';break;case 45:a='[2~';break;case 36:if(this.applicationKeypad){a='OH';break}a='OH';break;case 35:if(this.applicationKeypad){a='OF';break}a='OF';break;case 33:if(b.shiftKey)return this.scrollDisp(-(this.rows-1)),d(b);a='[5~';break;case 34:if(b.shiftKey)return this.scrollDisp(this.rows-1),d(b);a='[6~';break;case 112:a='OP';break;case 113:a='OQ';break;case 114:a='OR';break;case 115:a='OS';break;case 116:a='[15~';break;case 117:a='[17~';break;case 118:a='[18~';break;case 119:a='[19~';break;case 120:a='[20~';break;case 121:a='[21~';break;case 122:a='[23~';break;case 123:a='[24~';break;default:if(b.ctrlKey)if(b.keyCode>=65&&b.keyCode<=90){if(this.screenKeys&&!(this.prefixMode||this.selectMode)&&b.keyCode===65)return this.enterPrefix(),d(b);if(this.prefixMode&&b.keyCode===86){this.leavePrefix();return}if((this.prefixMode||this.selectMode)&&b.keyCode===67){this.visualMode&&i(function(){c.leaveVisual()},1);return}a=g.fromCharCode(b.keyCode-64)}else b.keyCode===32?a=g.fromCharCode(0):b.keyCode>=51&&b.keyCode<=55?a=g.fromCharCode(b.keyCode-51+27):b.keyCode===56?a=g.fromCharCode(127):b.keyCode===219?a=g.fromCharCode(27):b.keyCode===221&&(a=g.fromCharCode(29));else(!this.isMac&&b.altKey||this.isMac&&b.metaKey)&&(b.keyCode>=65&&b.keyCode<=90?a=''+g.fromCharCode(b.keyCode+32):b.keyCode===192?a='`':b.keyCode>=48&&b.keyCode<=57&&(a=''+(b.keyCode-48)));break}return a?this.prefixMode?(this.leavePrefix(),d(b)):this.selectMode?(this.keySelect(b,a),d(b)):(this.emit('keydown',b),this.emit('key',a,b),this.showCursor(),this.handler(a),b.keyCode===86&&(this.isMac&&b.metaKey||!this.isMac&&b.ctrlKey)?!0:d(b)):!0},b.prototype.setgLevel=function(a){this.glevel=a,this.charset=this.charsets[a]},b.prototype.setgCharset=function(a,b){this.charsets[a]=b,this.glevel===a&&(this.charset=b)},b.prototype.keyPress=function(a){var b;if(a.charCode)b=a.charCode;else if(a.which==null)b=a.keyCode;else if(a.which!==0&&a.charCode!==0)b=a.which;else return!1;return b===118&&(this.isMac&&a.metaKey||!this.isMac&&a.ctrlKey)||d(a),!b||a.ctrlKey||a.altKey&&b!=118||a.metaKey&&b!=118?!1:(b=g.fromCharCode(b),this.prefixMode?(this.leavePrefix(),this.keyPrefix(a,b),!1):this.selectMode?(this.keySelect(a,b),!1):(this.emit('keypress',b,a),this.emit('key',b,a),this.showCursor(),b==='v'&&(this.isMac&&a.metaKey||!this.isMac&&a.ctrlKey)||this.handler(b),!1))},b.prototype.send=function(b){var a=this;this.queue||i(function(){a.handler(a.queue),a.queue=''},1),this.queue+=b},b.prototype.bell=function(){if(!this.visualBell)return;var a=this;this.element.style.borderColor='white',i(function(){a.element.style.borderColor=''},10),this.popOnBell&&this.focus()},b.prototype.log=function(){if(!this.debug)return;if(!(this.context.console&&this.context.console.log))return;var a=Array.prototype.slice.call(arguments);this.context.console.log.apply(this.context.console,a)},b.prototype.error=function(){if(!this.debug)return;if(!(this.context.console&&this.context.console.error))return;var a=Array.prototype.slice.call(arguments);this.context.console.error.apply(this.context.console,a)},b.prototype.resize=function(b,a){var f,e,d,c,g;if(b<1&&(b=1),a<1&&(a=1),c=this.cols,c<b){g=[this.defAttr,' '],d=this.lines.length;while(d--)while(this.lines[d].length<b)this.lines[d].push(g)}else if(c>b){d=this.lines.length;while(d--)while(this.lines[d].length>b)this.lines[d].pop()}if(this.setupStops(c),this.cols=b,c=this.rows,c<a){e=this.element;while(c++<a)this.lines.length<a+this.ybase&&this.lines.push(this.blankLine()),this.children.length<a&&(f=this.document.createElement('div'),e.appendChild(f),this.children.push(f))}else if(c>a)while(c-->a)if(this.lines.length>a+this.ybase&&this.lines.pop(),this.children.length>a){if(e=this.children.pop(),!e)continue;e.parentNode.removeChild(e)}this.rows=a,this.y>=a&&(this.y=a-1),this.x>=b&&(this.x=b-1),this.scrollTop=0,this.scrollBottom=a-1,this.refresh(0,this.rows-1),this.normal=null},b.prototype.updateRange=function(a){a<this.refreshStart&&(this.refreshStart=a),a>this.refreshEnd&&(this.refreshEnd=a)},b.prototype.maxRange=function(){this.refreshStart=0,this.refreshEnd=this.rows-1},b.prototype.setupStops=function(a){for(a!=null?this.tabs[a]||(a=this.prevStop(a)):(this.tabs={},a=0);a<this.cols;a+=8)this.tabs[a]=!0},b.prototype.prevStop=function(a){a==null&&(a=this.x);while(!this.tabs[--a]&&a>0);return a>=this.cols?this.cols-1:a<0?0:a},b.prototype.nextStop=function(a){a==null&&(a=this.x);while(!this.tabs[++a]&&a<this.cols);return a>=this.cols?this.cols-1:a<0?0:a},b.prototype.eraseRight=function(a,b){var c=this.lines[this.ybase+b],d=[this.eraseAttr(),' '];for(;a<this.cols;a++)c[a]=d;this.updateRange(b)},b.prototype.eraseLeft=function(a,b){var c=this.lines[this.ybase+b],d=[this.eraseAttr(),' '];a++;while(a--)c[a]=d;this.updateRange(b)},b.prototype.eraseLine=function(a){this.eraseRight(0,a)},b.prototype.blankLine=function(e){var c=e?this.eraseAttr():this.defAttr,d=[c,' '],b=[],a=0;for(;a<this.cols;a++)b[a]=d;return b},b.prototype.ch=function(a){return a?[this.eraseAttr(),' ']:[this.defAttr,' ']},b.prototype.is=function(b){var a=this.termName;return(a+'').indexOf(b)===0},b.prototype.handler=function(a){this.emit('data',a)},b.prototype.handleTitle=function(a){this.emit('title',a)},b.prototype.index=function(){this.y++,this.y>this.scrollBottom&&(this.y--,this.scroll()),this.state=c},b.prototype.reverseIndex=function(){var a;this.y--,this.y<this.scrollTop&&(this.y++,this.lines.splice(this.y+this.ybase,0,this.blankLine(!0)),a=this.rows-1-this.scrollBottom,this.lines.splice(this.rows-1+this.ybase-a+1,1),this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)),this.state=c},b.prototype.reset=function(){this.options.rows=this.rows,this.options.cols=this.cols,b.call(this,this.options),this.refresh(0,this.rows-1)},b.prototype.tabSet=function(){this.tabs[this.x]=!0,this.state=c},b.prototype.cursorUp=function(b){var a=b[0];a<1&&(a=1),this.y-=a,this.y<0&&(this.y=0)},b.prototype.cursorDown=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.cursorForward=function(b){var a=b[0];a<1&&(a=1),this.x+=a,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.cursorBackward=function(b){var a=b[0];a<1&&(a=1),this.x-=a,this.x<0&&(this.x=0)},b.prototype.cursorPos=function(c){var b,a;b=c[0]-1,c.length>=2?a=c[1]-1:a=0,b<0?b=0:b>=this.rows&&(b=this.rows-1),a<0?a=0:a>=this.cols&&(a=this.cols-1),this.x=a,this.y=b},b.prototype.eraseInDisplay=function(b){var a;switch(b[0]){case 0:this.eraseRight(this.x,this.y);a=this.y+1;for(;a<this.rows;a++)this.eraseLine(a);break;case 1:this.eraseLeft(this.x,this.y);a=this.y;while(a--)this.eraseLine(a);break;case 2:a=this.rows;while(a--)this.eraseLine(a);break;case 3:break}},b.prototype.eraseInLine=function(a){switch(a[0]){case 0:this.eraseRight(this.x,this.y);break;case 1:this.eraseLeft(this.x,this.y);break;case 2:this.eraseLine(this.y);break}},b.prototype.charAttributes=function(c){if(c.length===1&&c[0]===0){this.curAttr=this.defAttr;return}var g=c.length,b=0,d=this.curAttr>>18,e=this.curAttr>>9&511,f=this.curAttr&511,a;for(;b<g;b++)a=c[b],a>=30&&a<=37?e=a-30:a>=40&&a<=47?f=a-40:a>=90&&a<=97?(a+=8,e=a-90):a>=100&&a<=107?(a+=8,f=a-100):a===0?(d=this.defAttr>>18,e=this.defAttr>>9&511,f=this.defAttr&511):a===1?d|=1:a===4?d|=2:a===5?d|=4:a===7?d|=8:a===8?d|=16:a===22?d&=-2:a===24?d&=-3:a===25?d&=-5:a===27?d&=-9:a===28?d&=-17:a===39?e=this.defAttr>>9&511:a===49?f=this.defAttr&511:a===38?c[b+1]===2?(b+=2,e=h(c[b]&255,c[b+1]&255,c[b+2]&255),e===-1&&(e=511),b+=2):c[b+1]===5&&(b+=2,a=c[b]&255,e=a):a===48?c[b+1]===2?(b+=2,f=h(c[b]&255,c[b+1]&255,c[b+2]&255),f===-1&&(f=511),b+=2):c[b+1]===5&&(b+=2,a=c[b]&255,f=a):a===100?(e=this.defAttr>>9&511,f=this.defAttr&511):this.error('Unknown SGR attribute: %d.',a);this.curAttr=d<<18|e<<9|f},b.prototype.deviceStatus=function(a){if(!this.prefix)switch(a[0]){case 5:this.send('[0n');break;case 6:this.send('['+(this.y+1)+';'+(this.x+1)+'R');break}else if(this.prefix==='?')switch(a[0]){case 6:this.send('[?'+(this.y+1)+';'+(this.x+1)+'R');break;case 15:break;case 25:break;case 26:break;case 53:break}},b.prototype.insertChars=function(e){var a,b,c,d;a=e[0],a<1&&(a=1),b=this.y+this.ybase,c=this.x,d=[this.eraseAttr(),' '];while(a--&&c<this.cols)this.lines[b].splice(c++,0,d),this.lines[b].pop()},b.prototype.cursorNextLine=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1),this.x=0},b.prototype.cursorPrecedingLine=function(b){var a=b[0];a<1&&(a=1),this.y-=a,this.y<0&&(this.y=0),this.x=0},b.prototype.cursorCharAbsolute=function(b){var a=b[0];a<1&&(a=1),this.x=a-1},b.prototype.insertLines=function(d){var a,c,b;a=d[0],a<1&&(a=1),c=this.y+this.ybase,b=this.rows-1-this.scrollBottom,b=this.rows-1+this.ybase-b+1;while(a--)this.lines.splice(c,0,this.blankLine(!0)),this.lines.splice(b,1);this.updateRange(this.y),this.updateRange(this.scrollBottom)},b.prototype.deleteLines=function(d){var a,c,b;a=d[0],a<1&&(a=1),c=this.y+this.ybase,b=this.rows-1-this.scrollBottom,b=this.rows-1+this.ybase-b;while(a--)this.lines.splice(b+1,0,this.blankLine(!0)),this.lines.splice(c,1);this.updateRange(this.y),this.updateRange(this.scrollBottom)},b.prototype.deleteChars=function(d){var a,b,c;a=d[0],a<1&&(a=1),b=this.y+this.ybase,c=[this.eraseAttr(),' '];while(a--)this.lines[b].splice(this.x,1),this.lines[b].push(c)},b.prototype.eraseChars=function(e){var a,c,b,d;a=e[0],a<1&&(a=1),c=this.y+this.ybase,b=this.x,d=[this.eraseAttr(),' '];while(a--&&b<this.cols)this.lines[c][b++]=d},b.prototype.charPosAbsolute=function(b){var a=b[0];a<1&&(a=1),this.x=a-1,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.HPositionRelative=function(b){var a=b[0];a<1&&(a=1),this.x+=a,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.sendDeviceAttributes=function(a){if(a[0]>0)return;this.prefix?this.prefix==='>'&&(this.is('xterm')?this.send('[>0;276;0c'):this.is('rxvt-unicode')?this.send('[>85;95;0c'):this.is('linux')?this.send(a[0]+'c'):this.is('screen')&&this.send('[>83;40003;0c')):this.is('xterm')||this.is('rxvt-unicode')||this.is('screen')?this.send('[?1;2c'):this.is('linux')&&this.send('[?6c')},b.prototype.linePosAbsolute=function(b){var a=b[0];a<1&&(a=1),this.y=a-1,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.VPositionRelative=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.HVPosition=function(a){a[0]<1&&(a[0]=1),a[1]<1&&(a[1]=1),this.y=a[0]-1,this.y>=this.rows&&(this.y=this.rows-1),this.x=a[1]-1,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.setMode=function(a){if(typeof a==='object'){var d=a.length,c=0;for(;c<d;c++)this.setMode(a[c]);return}if(!this.prefix)switch(a){case 4:this.insertMode=!0;break;case 20:break}else if(this.prefix==='?')switch(a){case 1:this.applicationCursor=!0;break;case 2:this.setgCharset(0,b.charsets.US);this.setgCharset(1,b.charsets.US);this.setgCharset(2,b.charsets.US);this.setgCharset(3,b.charsets.US);break;case 3:this.savedCols=this.cols;this.resize(132,this.rows);break;case 6:this.originMode=!0;break;case 7:this.wraparoundMode=!0;break;case 12:break;case 66:this.log('Serial port requested application keypad.');this.applicationKeypad=!0;break;case 9:case 1e3:case 1002:case 1003:this.x10Mouse=a===9;this.vt200Mouse=a===1e3;this.normalMouse=a>1e3;this.mouseEvents=!0;this.element.style.cursor='default';this.log('Binding to mouse events.');break;case 1004:this.sendFocus=!0;break;case 1005:this.utfMouse=!0;break;case 1006:this.sgrMouse=!0;break;case 1015:this.urxvtMouse=!0;break;case 25:this.cursorHidden=!1;break;case 1049:case 47:case 1047:if(!this.normal){var e={lines:this.lines,ybase:this.ybase,ydisp:this.ydisp,x:this.x,y:this.y,scrollTop:this.scrollTop,scrollBottom:this.scrollBottom,tabs:this.tabs};this.reset(),this.normal=e,this.showCursor()}break}},b.prototype.resetMode=function(a){if(typeof a==='object'){var c=a.length,b=0;for(;b<c;b++)this.resetMode(a[b]);return}if(!this.prefix)switch(a){case 4:this.insertMode=!1;break;case 20:break}else if(this.prefix==='?')switch(a){case 1:this.applicationCursor=!1;break;case 3:this.cols===132&&this.savedCols&&this.resize(this.savedCols,this.rows);delete this.savedCols;break;case 6:this.originMode=!1;break;case 7:this.wraparoundMode=!1;break;case 12:break;case 66:this.log('Switching back to normal keypad.');this.applicationKeypad=!1;break;case 9:case 1e3:case 1002:case 1003:this.x10Mouse=!1;this.vt200Mouse=!1;this.normalMouse=!1;this.mouseEvents=!1;this.element.style.cursor='';break;case 1004:this.sendFocus=!1;break;case 1005:this.utfMouse=!1;break;case 1006:this.sgrMouse=!1;break;case 1015:this.urxvtMouse=!1;break;case 25:this.cursorHidden=!0;break;case 1049:case 47:case 1047:this.normal&&(this.lines=this.normal.lines,this.ybase=this.normal.ybase,this.ydisp=this.normal.ydisp,this.x=this.normal.x,this.y=this.normal.y,this.scrollTop=this.normal.scrollTop,this.scrollBottom=this.normal.scrollBottom,this.tabs=this.normal.tabs,this.normal=null,this.refresh(0,this.rows-1),this.showCursor());break}},b.prototype.setScrollRegion=function(a){if(this.prefix)return;this.scrollTop=(a[0]||1)-1,this.scrollBottom=(a[1]||this.rows)-1,this.x=0,this.y=0},b.prototype.saveCursor=function(a){this.savedX=this.x,this.savedY=this.y},b.prototype.restoreCursor=function(a){this.x=this.savedX||0,this.y=this.savedY||0},b.prototype.cursorForwardTab=function(b){var a=b[0]||1;while(a--)this.x=this.nextStop()},b.prototype.scrollUp=function(b){var a=b[0]||1;while(a--)this.lines.splice(this.ybase+this.scrollTop,1),this.lines.splice(this.ybase+this.scrollBottom,0,this.blankLine());this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.scrollDown=function(b){var a=b[0]||1;while(a--)this.lines.splice(this.ybase+this.scrollBottom,1),this.lines.splice(this.ybase+this.scrollTop,0,this.blankLine());this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.initMouseTracking=function(a){},b.prototype.resetTitleModes=function(a){},b.prototype.cursorBackwardTab=function(b){var a=b[0]||1;while(a--)this.x=this.prevStop()},b.prototype.repeatPrecedingCharacter=function(d){var b=d[0]||1,a=this.lines[this.ybase+this.y],c=a[this.x-1]||[this.defAttr,' '];while(b--)a[this.x++]=c},b.prototype.tabClear=function(b){var a=b[0];a<=0?delete this.tabs[this.x]:a===3&&(this.tabs={})},b.prototype.mediaCopy=function(a){},b.prototype.setResources=function(a){},b.prototype.disableModifiers=function(a){},b.prototype.setPointerMode=function(a){},b.prototype.softReset=function(a){this.cursorHidden=!1,this.insertMode=!1,this.originMode=!1,this.wraparoundMode=!1,this.applicationKeypad=!1,this.applicationCursor=!1,this.scrollTop=0,this.scrollBottom=this.rows-1,this.curAttr=this.defAttr,this.x=this.y=0,this.charset=null,this.glevel=0,this.charsets=[null]},b.prototype.requestAnsiMode=function(a){},b.prototype.requestPrivateMode=function(a){},b.prototype.setConformanceLevel=function(a){},b.prototype.loadLEDs=function(a){},b.prototype.setCursorStyle=function(a){},b.prototype.setCharProtectionAttr=function(a){},b.prototype.restorePrivateValues=function(a){},b.prototype.setAttrInRectangle=function(a){var c=a[0],e=a[1],f=a[2],g=a[3],h=a[4],d,b;for(;c<f+1;c++)for(d=this.lines[this.ybase+c],b=e;b<g;b++)d[b]=[h,d[b][1]];this.updateRange(a[0]),this.updateRange(a[2])},b.prototype.savePrivateValues=function(a){},b.prototype.manipulateWindow=function(a){},b.prototype.reverseAttrInRectangle=function(a){},b.prototype.setTitleModeFeature=function(a){},b.prototype.setWarningBellVolume=function(a){},b.prototype.setMarginBellVolume=function(a){},b.prototype.copyRectangle=function(a){},b.prototype.enableFilterRectangle=function(a){},b.prototype.requestParameters=function(a){},b.prototype.selectChangeExtent=function(a){},b.prototype.fillRectangle=function(a){var e=a[0],c=a[1],f=a[2],h=a[3],i=a[4],d,b;for(;c<h+1;c++)for(d=this.lines[this.ybase+c],b=f;b<i;b++)d[b]=[d[b][0],g.fromCharCode(e)];this.updateRange(a[1]),this.updateRange(a[3])},b.prototype.enableLocatorReporting=function(a){var b=a[0]>0},b.prototype.eraseRectangle=function(a){var b=a[0],d=a[1],e=a[2],f=a[3],g,c,h;for(h=[this.eraseAttr(),' '];b<e+1;b++)for(g=this.lines[this.ybase+b],c=d;c<f;c++)g[c]=h;this.updateRange(a[0]),this.updateRange(a[2])},b.prototype.setLocatorEvents=function(a){},b.prototype.selectiveEraseRectangle=function(a){},b.prototype.requestLocatorPosition=function(a){},b.prototype.insertColumns=function(){var b=params[0],c=this.ybase+this.rows,d=[this.eraseAttr(),' '],a;while(b--)for(a=this.ybase;a<c;a++)this.lines[a].splice(this.x+1,0,d),this.lines[a].pop();this.maxRange()},b.prototype.deleteColumns=function(){var b=params[0],c=this.ybase+this.rows,d=[this.eraseAttr(),' '],a;while(b--)for(a=this.ybase;a<c;a++)this.lines[a].splice(this.x,1),this.lines[a].push(d);this.maxRange()},b.prototype.enterPrefix=function(){this.prefixMode=!0},b.prototype.leavePrefix=function(){this.prefixMode=!1},b.prototype.enterSelect=function(){this._real={x:this.x,y:this.y,ydisp:this.ydisp,ybase:this.ybase,cursorHidden:this.cursorHidden,lines:this.copyBuffer(this.lines),write:this.write},this.write=function(){},this.selectMode=!0,this.visualMode=!1,this.cursorHidden=!1,this.refresh(this.y,this.y)},b.prototype.leaveSelect=function(){this.x=this._real.x,this.y=this._real.y,this.ydisp=this._real.ydisp,this.ybase=this._real.ybase,this.cursorHidden=this._real.cursorHidden,this.lines=this._real.lines,this.write=this._real.write,delete this._real,this.selectMode=!1,this.visualMode=!1,this.refresh(0,this.rows-1)},b.prototype.enterVisual=function(){this._real.preVisual=this.copyBuffer(this.lines),this.selectText(this.x,this.x,this.ydisp+this.y,this.ydisp+this.y),this.visualMode=!0},b.prototype.leaveVisual=function(){this.lines=this._real.preVisual,delete this._real.preVisual,delete this._selected,this.visualMode=!1,this.refresh(0,this.rows-1)},b.prototype.enterSearch=function(c){this.entry='',this.searchMode=!0,this.searchDown=c,this._real.preSearch=this.copyBuffer(this.lines),this._real.preSearchX=this.x,this._real.preSearchY=this.y;var b=this.ydisp+this.rows-1;for(var a=0;a<this.entryPrefix.length;a++)this.lines[b][a]=[this.defAttr&-512|4,this.entryPrefix[a]];this.y=this.rows-1,this.x=this.entryPrefix.length,this.refresh(this.rows-1,this.rows-1)},b.prototype.leaveSearch=function(){this.searchMode=!1,this._real.preSearch&&(this.lines=this._real.preSearch,this.x=this._real.preSearchX,this.y=this._real.preSearchY,delete this._real.preSearch,delete this._real.preSearchX,delete this._real.preSearchY),this.refresh(this.rows-1,this.rows-1)},b.prototype.copyBuffer=function(b){var b=b||this.lines,d=[];for(var a=0;a<b.length;a++){d[a]=[];for(var c=0;c<b[a].length;c++)d[a][c]=[b[a][c][0],b[a][c][1]]}return d},b.prototype.getCopyTextarea=function(c){var a=this._copyTextarea,b=this.document;return a||(a=b.createElement('textarea'),a.style.position='absolute',a.style.left='-32000px',a.style.top='-32000px',a.style.width='0px',a.style.height='0px',a.style.opacity='0',a.style.backgroundColor='transparent',a.style.borderStyle='none',a.style.outlineStyle='none',b.getElementsByTagName('body')[0].appendChild(a),this._copyTextarea=a),a},b.prototype.copyText=function(b){var c=this,a=this.getCopyTextarea();this.emit('copy',b),a.focus(),a.textContent=b,a.value=b,a.setSelectionRange(0,b.length),i(function(){c.element.focus(),c.focus()},1)},b.prototype.selectText=function(f,g,b,d){var j,k,i,h,e,c,a,l,m;if(this._selected){for(j=this._selected.x1,k=this._selected.x2,i=this._selected.y1,h=this._selected.y2,h<i&&(e=k,k=j,j=e,e=h,h=i,i=e),k<j&&i===h&&(e=k,k=j,j=e),a=i;a<=h;a++)for(c=0,l=this.cols-1,a===i&&(c=j),a===h&&(l=k);c<=l;c++)this.lines[a][c].old!=null&&(m=this.lines[a][c].old,delete this.lines[a][c].old,this.lines[a][c]=[m,this.lines[a][c][1]]);b=this._selected.y1,f=this._selected.x1}for(b=Math.max(b,0),b=Math.min(b,this.ydisp+this.rows-1),d=Math.max(d,0),d=Math.min(d,this.ydisp+this.rows-1),this._selected={x1:f,x2:g,y1:b,y2:d},d<b&&(e=g,g=f,f=e,e=d,d=b,b=e),g<f&&b===d&&(e=g,g=f,f=e),a=b;a<=d;a++)for(c=0,l=this.cols-1,a===b&&(c=f),a===d&&(l=g);c<=l;c++)m=this.lines[a][c][0],this.lines[a][c]=[m&-512|261636,this.lines[a][c][1]],this.lines[a][c].old=m;b-=this.ydisp,d-=this.ydisp,b=Math.max(b,0),b=Math.min(b,this.rows-1),d=Math.max(d,0),d=Math.min(d,this.rows-1),this.refresh(0,this.rows-1)},b.prototype.grabText=function(g,c,i,d){var e='',f='',j,a,b,k,h;for(d<i&&(h=c,c=g,g=h,h=d,d=i,i=h),c<g&&i===d&&(h=c,c=g,g=h),b=i;b<=d;b++){for(a=0,k=this.cols-1,b===i&&(a=g),b===d&&(k=c);a<=k;a++){if(j=this.lines[b][a][1],j===' '){f+=j;continue}f&&(e+=f,f=''),e+=j,m(j)&&a++}f='',e+='\n'}for(a=c,b=d;a<this.cols;a++)if(this.lines[b][a][1]!==' '){e=e.slice(0,-1);break}return e},b.prototype.keyPrefix=function(b,a){a==='k'||a==='&'?this.destroy():a==='p'||a===']'?this.emit('request paste'):a==='c'?this.emit('request create'):a>='0'&&a<='9'?(a=+a-1,~a||(a=9),this.emit('request term',a)):a==='n'?this.emit('request term next'):a==='P'?this.emit('request term previous'):a===':'?this.emit('request command mode'):a==='['&&this.enterSelect()},b.prototype.keySelect=function(o,b){if(this.showCursor(),this.searchMode||b==='n'||b==='N')return this.keySearch(o,b);if(b===''){var c=this.ydisp+this.y;this.ydisp===this.ybase?(this.y=Math.min(this.y+(this.rows-1)/2|0,this.rows-1),this.refresh(0,this.rows-1)):this.scrollDisp((this.rows-1)/2|0),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.ydisp===0?(this.y=Math.max(this.y-(this.rows-1)/2|0,0),this.refresh(0,this.rows-1)):this.scrollDisp(-(this.rows-1)/2|0),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.scrollDisp(this.rows-1),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.scrollDisp(-(this.rows-1)),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b==='k'||b==='[A'){var c=this.ydisp+this.y;this.y--,this.y<0&&(this.y=0,this.scrollDisp(-1)),this.visualMode?this.selectText(this.x,this.x,c,this.ydisp+this.y):this.refresh(this.y,this.y+1);return}if(b==='j'||b==='[B'){var c=this.ydisp+this.y;this.y++,this.y>=this.rows&&(this.y=this.rows-1,this.scrollDisp(1)),this.visualMode?this.selectText(this.x,this.x,c,this.ydisp+this.y):this.refresh(this.y-1,this.y);return}if(b==='h'||b==='[D'){var a=this.x;this.x--,this.x<0&&(this.x=0),this.visualMode?this.selectText(a,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='l'||b==='[C'){var a=this.x;this.x++,this.x>=this.cols&&(this.x=this.cols-1),this.visualMode?this.selectText(a,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='v'||b===' '){this.visualMode?this.leaveVisual():this.enterVisual();return}if(b==='y'){if(this.visualMode){var n=this.grabText(this._selected.x1,this._selected.x2,this._selected.y1,this._selected.y2);this.copyText(n),this.leaveVisual()}return}if(b==='q'||b===''){this.visualMode?this.leaveVisual():this.leaveSelect();return}if(b==='w'||b==='W'){var f=this.x,g=this.y,h=this.ydisp,a=this.x,c=this.y,d=this.ydisp,i=!1;for(;;){var e=this.lines[d+c];while(a<this.cols){if(e[a][1]<=' ')i=!0;else if(i)break;a++}if(a>=this.cols&&(a=this.cols-1),a===this.cols-1&&e[a][1]<=' '){if(a=0,++c>=this.rows&&(c--,++d>this.ybase)){d=this.ybase,a=this.x;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='b'||b==='B'){var f=this.x,g=this.y,h=this.ydisp,a=this.x,c=this.y,d=this.ydisp;for(;;){var e=this.lines[d+c],i=a>0&&e[a][1]>' '&&e[a-1][1]>' ';while(a>=0){if(e[a][1]<=' ')if(i&&a+1<this.cols&&e[a+1][1]>' '){a++;break}else i=!0;a--}if(a<0&&(a=0),a===0&&(e[a][1]<=' '||!i)){if(a=this.cols-1,--c<0&&(c++,--d<0)){d++,a=0;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='e'||b==='E'){var a=this.x+1,c=this.y,d=this.ydisp;for(a>=this.cols&&a--;;){var e=this.lines[d+c];while(a<this.cols)if(e[a][1]<=' ')a++;else break;while(a<this.cols){if(e[a][1]<=' '&&a-1>=0&&e[a-1][1]>' '){a--;break}a++}if(a>=this.cols&&(a=this.cols-1),a===this.cols-1&&e[a][1]<=' '){if(a=0,++c>=this.rows&&(c--,++d>this.ybase)){d=this.ybase;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='^'||b==='0'){var f=this.x;if(b==='0')this.x=0;else if(b==='^'){var e=this.lines[this.ydisp+this.y],a=0;while(a<this.cols){if(e[a][1]>' ')break;a++}a>=this.cols&&(a=this.cols-1),this.x=a}this.visualMode?this.selectText(f,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='$'){var f=this.x,e=this.lines[this.ydisp+this.y],a=this.cols-1;while(a>=0){if(e[a][1]>' '){this.visualMode&&a<this.cols-1&&a++;break}a--}a<0&&(a=0),this.x=a,this.visualMode?this.selectText(f,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='g'||b==='G'){var f=this.x,g=this.y,h=this.ydisp;b==='g'?(this.x=0,this.y=0,this.scrollDisp(-this.ydisp)):b==='G'&&(this.x=0,this.y=this.rows-1,this.scrollDisp(this.ybase)),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='H'||b==='M'||b==='L'){var f=this.x,g=this.y;b==='H'?(this.x=0,this.y=0):b==='M'?(this.x=0,this.y=this.rows/2|0):b==='L'&&(this.x=0,this.y=this.rows-1),this.visualMode?this.selectText(f,this.x,this.ydisp+g,this.ydisp+this.y):(this.refresh(g,g),this.refresh(this.y,this.y));return}if(b==='{'||b==='}'){var f=this.x,g=this.y,h=this.ydisp,e,m=!1,k=!1,j=-1,c=this.y+(b==='{'?-1:1),d=this.ydisp,l;for(b==='{'?c<0&&(c++,d>0&&d--):b==='}'&&c>=this.rows&&(c--,d<this.ybase&&d++);;){for(e=this.lines[d+c],l=0;l<this.cols;l++)if(e[l][1]>' '){j===-1&&(j=0),m=!0;break}else if(l===this.cols-1){j===-1?j=1:j===0?k=!0:j===1&&m&&(k=!0);break}if(k)break;if(b==='{'){if(c--,c<0){if(c++,!(d>0))break;d--}}else if(b==='}'&&(c++,c>=this.rows)){if(c--,!(d<this.ybase))break;d++}}k||(b==='{'?(c=0,d=0):b==='}'&&(c=this.rows-1,d=this.ybase)),this.x=0,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='/'||b==='?'){this.visualMode||this.enterSearch(b==='/');return}return!1},b.prototype.keySearch=function(o,c){if(c===''){this.leaveSearch();return}if(c==='\r'||!this.searchMode&&(c==='n'||c==='N')){this.leaveSearch();var f=this.entry;if(!f){this.refresh(0,this.rows-1);return}var m=this.x,l=this.y,k=this.ydisp,j,h=!1,i=!1,d=this.x+1,b=this.ydisp+this.y,g,a,n=c==='N'?this.searchDown:!this.searchDown;for(;;){j=this.lines[b];while(d<this.cols){for(a=0;a<f.length;a++){if(d+a>=this.cols)break;if(j[d+a][1]!==f[a])break;if(j[d+a][1]===f[a]&&a===f.length-1){h=!0;break}}if(h)break;d+=a+1}if(h)break;if(d=0,!n){if(b++,b>this.ybase+this.rows-1){if(i)break;i=!0,b=0}}else if(b--,b<0){if(i)break;i=!0,b=this.ybase+this.rows-1}}if(h){b-this.ybase<0?(g=b,b=0,g>this.ybase&&(b=g-this.ybase,g=this.ybase)):(g=this.ybase,b-=this.ybase),this.x=d,this.y=b,this.scrollDisp(-this.ydisp+g),this.visualMode&&this.selectText(m,this.x,l+k,this.ydisp+this.y);return}this.refresh(0,this.rows-1);return}if(c===''||c===''){if(this.entry.length===0)return;var e=this.ydisp+this.rows-1;this.entry=this.entry.slice(0,-1);var a=this.entryPrefix.length+this.entry.length;this.lines[e][a]=[this.lines[e][a][0],' '],this.x--,this.refresh(this.rows-1,this.rows-1),this.refresh(this.y,this.y);return}if(c.length===1&&c>=' '&&c<='~'){var e=this.ydisp+this.rows-1;this.entry+=c;var a=this.entryPrefix.length+this.entry.length-1;this.lines[e][a]=[this.defAttr&-512|4,c],this.x++,this.refresh(this.rows-1,this.rows-1),this.refresh(this.y,this.y);return}return!1},b.charsets={},b.charsets.SCLD={'`':'â—†',a:'â–’',b:' ',c:'',d:'\r',e:'\n',f:'°',g:'±',h:'â¤',i:'',j:'┘',k:'â”',l:'┌',m:'â””',n:'┼',o:'⎺',p:'⎻',q:'─',r:'⎼',s:'⎽',t:'├',u:'┤',v:'â”´',w:'┬',x:'│',y:'≤',z:'≥','{':'Ï€','|':'≠','}':'£','~':'·'},b.charsets.UK=null,b.charsets.US=null,b.charsets.Dutch=null,b.charsets.Finnish=null,b.charsets.French=null,b.charsets.FrenchCanadian=null,b.charsets.German=null,b.charsets.Italian=null,b.charsets.NorwegianDanish=null,b.charsets.Spanish=null,b.charsets.Swedish=null,b.charsets.Swiss=null,b.charsets.ISOLatin=null;var g=this.String,i=this.setTimeout,s=this.setInterval;h._cache={},h.distance=function(a,b,c,d,e,f){return Math.pow(30*(a-d),2)+Math.pow(59*(b-e),2)+Math.pow(11*(c-f),2)},b.EventEmitter=f,b.inherits=u,b.on=e,b.off=q,b.cancel=d,a!==void 0?a.exports=b:this.Terminal=b}.call(function(){return this||(typeof window!=='undefined'?window:b)}()))},{}]},{},[1]) 2.5 \ No newline at end of file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/DESIGN_NOTES__14_Jn_22.txt Sun Jul 06 12:02:12 2014 -0700 3.3 @@ -0,0 +1,117 @@ 3.4 + 3.5 +Working on getting visual of a POP syntax graph 3.6 + 3.7 +-] Have Famo.us, which has hierarchical drawning structure that fits well to what had in mind for POP 3.8 + 3.9 +-] Famo.us has animations and physics engine, so as user modifies things, they can fly around in pleasing ways. 3.10 + 3.11 +-] Famo.us structure is almost one-to-one with the visualizer's internal structure that I was imagining.. seems wasteful to duplicate.. 3.12 + 3.13 +-] However.. need the visualization to be independent of any particular drawing facility.. for example, the visualization should be reusable with a Java based canvas that is painted via Swing, as well as via Famo.us and via C++ drawing code.. 3.14 + 3.15 +-] The visualization must be specific to the data format.. therefore, it should be part of the holder that the data is inside of. Don't want case where new syntax is added, and have to go around to all the different places, like Java app, and javascript displayer, and so on, and change code in all those! (even if they all take a plugin, that plugin will have to be in terms of the language -- java, javascript, C++, whatever -- and the plugin will have to spit out some standard thing anyway!) 3.16 +Rather, want the visualizer to be written once, in POP, and plugged into the data-holder. It spits out standardized visual elements.. any technology can then take those visual elements and paint them to a screen. 3.17 +The visualizer has fingers directly on the raw data, in whatever the internal format is for the holder.. A holder can have a different internal format vs external format.. 3.18 + 3.19 +(update: fighting with text -- haven't found any general way of calculating the width of text, given the font.. entry after entry from google search has variations on applying the text to a canvas, causing it to render, then getting the bounding box that was generated during render.. there doesn't seem to be, even for SVG, any way to predict the bounding box!!!?!?!?! So.. there is a cascade effect.. the text must be contained within something, like a rectangle or elipse or whatever.. and, as worked out during the rest of this design session, the visualizer is responsible for calculating the placement of all the SVG shapes.. then the visualizer MUST know the size of the text, in order to know the size of the shape, in order to calculate a reasonable placement of shapes.. 3.20 + it is tempting to leave all the shape placements specified as relative, and let the final values be figured out inside the Display.. this would also allow things like employing the Famous physics engine to calculate placements, even let the placements evolve by themselves (like the D3 examples with the graph nodes flying around to find their own placement).. that would happen without the visualizer setting the placements.. rather, the visualizer would establish the visual "connectivity".. noooo.. that D3 thing relied upon knowing that it was a graph and that arcs acted like springs and nodes acted like weights, and nodes exerted n-body attraction.. but that is all specific to graphs.. would it generalize to arbitrary syntax? Hmmmm.. if had an "atomic" level, where inside an atomic unit nothing moves relative, then, yes, can treat the connections between these atomic things as springs, and each atomic thing has attractive mass and inertia.. can let them run around and find a stable configuration.. 3.21 + Okay, so two issues: what about connections that go off-screen to out-side-the-view portions of syntax graph, and what about the user wanting to pin particular things in particular places.. often what a feeling of solidity, reliable placement so you know where everything is.. 3.22 + Right, so this: for now, visualizer calculates fixed positions, but have in back of mind keeping ability for multiple kinds of visualizer within the same srcHolder.. and visualizer has ability to expect things of the Display, such as providing physics, and visualizer can maybe ask Display what kinds of visualization list it understands.. so then can add, say, dynamic view hierarchy, where visualizer specifies things like masses and springs and lets Display move them around as it sees fit.. can evolve standard view lists over time.. the Commander will have to include some facility for not allowing a user to select a visualizer that is unable to generate any of the list types acceptable to the Display the user is interacting with.) 3.23 + 3.24 +-] A holder may also have other data-format-and-semantics specific things, such as a querier -- the querier defines the format of queries it accepts, and those queries are tailored to the nature of the data in the holder. Hence, say, a video holder might have a querier plugged in that accepts canonical shapes, and then searches the raw video data for frames that contain that shape. The querier would spit out things in a format that it defines. For example, it may have a data structure for a video frame, and spit out a stream of frames that contain the requested shape. 3.25 + 3.26 +-] Data formats should be visually defined.. for example, I should be able to draw a picture of a graph node, and that picture is the code that defines the data structure, which can then be used in other places in the code. For example, in the Hamiltonian Path code, could have included a picture of a graph node, and connected a line to the portion being accessed, say, in a test, or in the "for all" construct.. 3.27 + 3.28 +-] Seeing a hierarchy of holders.. so a higher level holder could have multiple lower level holders inside of it.. getting a bit awkward, say with combining queriers and visualizers -- how do you combine visualizations from siblings? there's something fundamental here.. 3.29 + 3.30 +-] No data may be warehoused outside a holder.. the holder collects the things needed to interact with the data, such as modifier, visualizer, querier, and not sure yet what all else.. 3.31 + 3.32 +-] Data outside a holder must be in the form of a data structure instance, where the structure was defined by the holder the data came from. The holder took whatever internal format the data resided in and placed it into the data structure form. All data within a POP system that is not inside a holder must be in the format of a structure defined using POP primitives. NO RAW BYTES! Bit twidling only upon bit-vector structures. An adaptor is necessary in order to get a more primitive format of data (IE, can always do conditional tests on bits held in a bit-vector format, and build up values within a higher level format structure based on the test results.. example, do the math to accumulate individual bit values from a bit-vector, but accumulate them into an integer format. Or, can test bits that represent graph edges, and build up a graph data structure. aso..) 3.33 + 3.34 +-] A visualizer can include animations as visual elements that it spits out. 3.35 + 3.36 +-] Famous will generate events that are gestures such as mouse clicks. The event handler will use the event data to connect the event to one of the original visual elements that was visualized. It will construct a structure that states the visual element and the gesture details, and send that to the commander. 3.37 + 3.38 +-] the commander will convert the visual element plus gesture into some action, such as moving the insertion point, or zooming the view, or adding a syntax node.. the command sends the command to the appropriate place -- could be the drawing engine (for zoom or pan actions).. or could be the modifier for insertion point or syntax element actions.. or could be some entity that carries out the action. For example when viewing a worksheet, a gesture could trigger re-calculation, so the action would be a "perform calculation" sent to one or more processors that are connected to the worksheet. 3.39 + 3.40 +-] The modifier has access to the holder's internal data format, and can manipulate it directly. It receives commands, such as generated by gestures performed on the display. 3.41 + 3.42 +-] A worksheet lives inside a holder as well.. the worksheet can talk to processors.. for example, the visualizer may simply include a reference to a processor that spits out data, and sends the reference in the visual element. An image may be a good example.. the image is on the worksheet for some reason.. the visualizer embeds reference to image in an element and sends that to the display. The display then directly gets the image data and paints it. 3.43 + 3.44 +-] Right, so one way to combine visualizers in a hierarchy, is for higher level visualizers to specify a lower-level one that is to fill in the internals of a given bounding box. So the lower-level is sent the bounding box, and it generates a view hierarchy that fits inside of that. Not sure whether the Display should be the one that sends the requests and integrates the various responses, or the Visualizer should send the requests and integrate the responses. 3.45 + 3.46 +============================================== 3.47 += 3.48 += 3.49 +============================================== 3.50 +So, question.. what do display list elements look like? Does visualizer produce the layout, for example, specify a bounding box and position for each element, including text, lines, etc? Does it produce the bezier curves in SVG that connect syntax graph elements? 3.51 + 3.52 +Or, does it send something with fewer details? Let the Display calculate exact placement of visual elements? 3.53 + 3.54 +What about pan and zoom? Does Visualizer handle that, or Display.. pan means moving some elements out of the painted canvas and moving others in.. zoom does too, in addition to calculating new transforms for each element painted.. So, if Display does this, then it must either have all the visual elements in it, or else it much send a request to Visualizer that triggers sending what's needed.. 3.55 + 3.56 +Soooo.. make a two-way path between Display and Visualizer, in order to handle pan, zoom, 3D rotates, and so forth? 3.57 + 3.58 +Orrrr.. leave that to the MVDM loop.. the pan/zoom/rotate gestures go into the command-maker, and thence into the visualizer, which then sends view update.. 3.59 + 3.60 +sooo.. this view update stuff.. does Display keep a full representation of the visual elements, and then translate that into Famo.us elements? Or, does it keep, say, a current visualizer list.. where visualizer updates simply modify the previous list sent.. then Display translates the updated list into Famo.us elements.. given that Famo.us doesn't support removing render tree elements, that might be a good approach.. and it simplifies the thing about how to figure out what a visualizer update is and what to do with it inside the Display. 3.61 + 3.62 +Okay.. now.. just need to figure out what the Visualizer actually sends.. how much detail.. 3.63 + 3.64 +You know what? I don't want to think about it! Just going to do something, see what happens, and then can modify later.. probably will never get modified, these choices have a way of sticking, due to momentum of volume of work and low improvement in changing.. but, don't want to stall myself, need to keep moving.. 3.65 + 3.66 +sooooo... something has to calculate placement of bounding boxes, and calculate translations and sizing.. and move things in and out based on zoom, pan, rotate.. and trigger redraws and resends of display data for graphs and calculation results.. seems like if put placement and transform calcs inside Display then are making the Display an active thing, giving it intelligence and control.. then, run into problems when have a view that is composed of pieces from many different holders and different processors.. for example, displaying a worksheet, where the worksheet itself is in a holder that generates a view, and locations on the worksheet are calculated by live processors, and locations are graphs which are generated by graphing processors that take calculations from other processors.. want the worksheet holder to handle generating the view, and collecting the data from the other processors.. don't want the Display to have any kind of intelligence related to this! 3.67 + 3.68 +Hmmm.. so, if the worksheet holder is doing all of the collecting of data and triggering re-calcs, and melding together into a view.. then Display is simply passively painting that and collecting gestures that it sends back.. the holder then knows what to do with the gestures performed upon view elements.. 3.69 + 3.70 +So that means that the Display should not be calculating pan and zoom and rotate!! Those are responses to gestures, and those trigger behaviors from the visualizer (which may, in turn, have to trigger behaviors from other processors in order to get updated calcs to put into the view) 3.71 + 3.72 +Got it, so as tempting as it is to peel off such gestures in the Display and build intelligence into there.. it will cause problems.. so best to have all the visual related processing be done inside the visualizers.. 3.73 + 3.74 +so.. means the visualizer should send out things pretty close to renderable.. 3.75 + 3.76 +Now. The question comes up.. what format? Does the visualizer send out SVG? Is that universal enough? Will that cause problems with non-browser based approaches? If not SVG, then what? Will need to represent paths.. does visualizer calculate Bezier curves and send those? Or does it just say "here are end points, connect these with a smooth path"? Does the visualizer calculate how to route arcs within a graph around the other nodes in an optimal way? If the user supplies helpers by moving things, does the Display remember that, or the Visualizer? 3.77 + 3.78 +Ahhhh.. okay.. if what the user to be able to affect the visual arrangement, then need to remember the gestures they give that are related to visual arrangement.. for example, they grab bezier control points and move them, in order to affect a curve, or add new points within a path in order to route it.. those things have to be remembered! The Display has no place to store such things!! 3.79 + 3.80 +Right.. that means that the holder must store info related to viewing the holder contents! sooooo.. the visualizer must be the thing that generates any details that a person may want to adjust. 3.81 + 3.82 +Right. Any visual arrangement that a person might want to adjust must be stored inside the holder, and so the visualizer must be the thing that generates that level of detail. Right. Got it. 3.83 + 3.84 +So. Yes. That means that the visualizer must send out bounding boxes, translations, sizing, path points, control points, and so forth. So. Yes. SVG is looking like a good way to go.. has to be something! Can invent my own equivalent, which specifies paths, shapes, widths, and so forth.. but what is the gain? The only potential is sending in binary, to save the overhead of SVG's text embodiment. The savings worth the effort? NO! 3.85 + 3.86 +Okay then. SVG. That is the visualizer's format for POP. Or perhaps it just sends the values that go into the SVG? The Display does the final conversion to text-based SVG format? Hmmmm, what about custom syntax, which is SVG from the programmer? Just send indication of SVG elements, together with the values? Maybe enums for the SVG indicators, or something.. 3.87 + 3.88 +Now. Question is, how much effort? Is it more effort to send a representation, then construct text-repr inside Display? Or more effort to construct SVG text in visualizer and send it ready-made? 3.89 + 3.90 +Seems easier to just construct SVG text inside visualizer and send that.. 3.91 + 3.92 +Heck, if send representation, then are already forcing SVG! It doesn't constrain the Display if send the text form.. the display is just as free to convert the binary form to something else as it is to convert the text form to something else.. so if Display is not browser, and doesn't have SVG drawing primitives, it has to do the extra step of parsing SVG in order to extract the values from the text, and then generate whatever internal form it has, such as calculating paths or even pixels itself.. the extraction from text does not seem like a terribly large burden compared to the rest. 3.93 + 3.94 +Buuuut.. don't really care! Going to generate text form inside visualizer, because, why not? Then the Display only translates displayList elements into its internal thing that paints. In the case of browser, Display translates display list into famo.us elements, placing the SVG verbatim onto famous surfaces, and makes the SVG bounding box the same as the famous surface size. 3.95 + 3.96 +In fact, display list is going to represent almost verbatim what a Famo.us render tree will look like! It is a fairly universal declaration.. hierarchy of local visual contexts, with relationship among those contexts, including relative placement in 3D space and relative sizing from one to another. 3.97 + 3.98 +Alright, getting to it now.. display list will be a serialization of a hierarchy.. The top of the hierarchy is the view painted onto. The Display tells the visualizer what the pixel dimensions are of the view. The visualizer makes that the top level bounding box. It then inserts bounding boxes within that, and inserts bounding boxes within those, and so forth down. Each bounding box is either a hierarchy element, relationship element, or a painted element. Hierarchy elements simply state what elements are included, and give their own bounding box. Relationship elements are attached by the parent hierarchy element. For example, it is the job of the parent to make sure all the children fit inside its bounding box. The bounding box may be 2D or 3D. A parent ensures the fit by attaching relationships to the children elements. The relationships can be translations or scalings or rotations.. or actually any arbitrary 3D transform. A hierarchy element knows nothing of the context in which it fits, so it has no way of attaching relationships to itself! Each hierarchy element is responsible for ensuring that all descendants fit within its bounding box. Any relationship attached to a hierarchy element is transitively applied to all descendants of the hierarchy element. For example, if one is rotated in 3D, then it, together with all its contents, is rotated as a unit. Each descendant maintains the same relationship to its parent as before.. but the entire bundle has been rotated as a unit! 3.99 + 3.100 +Great.. so that is the display list.. it is a serialization of that hierarchy. A display update then assumes a given hierarchy, and says "change this relationship between this parent and this child" or "remove this parent and all descendants" etc.. in effect, it specifies a change to the hierarchical structure.. 3.101 + 3.102 +Sooooo.. means that have two copies of the view hierarchy.. one inside the visualizer, which is serialized, and another inside the Display, which is translated into Display-local elements that are then painted. 3.103 + 3.104 +Not the most efficient.. hurts me.. but, well, what are you going to do? What's better? Need the flexibility of having the visualizer control all changes to the view hierarchy.. and need the visualizer to calculate all placement and path details so that user changes can be remembered inside the holder (without something clunky like "save this view modification info as a black box and hand it to the Display, which knows what it means" yuck, just begging for loss of sync when move from one Display to another or even upgrade the Display!).. 3.105 + 3.106 +so, then, there's no way around having the visualizer internally represent the bounding box hierarchy as it constructs the details. Thennnnn.. something must translate that representation into the internal Display representation! The Display could have any native form internally.. canvas with paths drawn upon it, Java 2D, even just pixels, with all the code in between.. well, in effect, every Display ends up being everything between that hierarchy and on down to pixels!! 3.107 + 3.108 +So, could just hand the data structure from visualizer to the Display..? This is fine if both are inside same hardware, sharing memory.. but need a serialization if Display has separate memory.. which it will if the src holder is on a server and the display is a browser on a client! 3.109 + 3.110 +Hmmm.. what about just handing the data structure to the Display for now.. can always add the serialization later, it's not functional! :-) Ahhh, yes.. less work. Good. Okay, will do that. save serialization for later. For now, in javascript, will build a src holder that saves syntax graph natively in JSON, as an internal data structure of the form made for GabePatterns. The visualizer in the src holder will generate a view hierarchy from that data structure. It will save any view related data within the syntax graph data structure as extra properties added to the nodes. The visualizer will then hand a reference to the view hierarchy directly to the display object. The display object will then generate famous elements from the view hierarcy elements. View updates will simply be the visualizer changing the view hierarchy then calling the display with a reference to the changed hierarchy. 3.111 + 3.112 +Done. Make it so. 3.113 + 3.114 +BTW, thinking to introduce another component, which is a helper, that maybe takes some higher level view form and generates the view hierarchy from that.. this will ease the burden on developers who make custom syntax.. it will act as a library for them, essentially.. (and, of course, there will be a serializer that turns a view hierarchy into a stream of visual objects sent to the Display, which will reconstruct the view hierarchy then translate that into into elements that it paints.. for now, that serializer is just JSON! It has provision to translate javascript objects into text form, and then on the other side parse that text form to reproduce the javascript objects.. might need extra logic in order to recreate the links among parents and children.. not sure whether JSON can go deep that way..). 3.115 + 3.116 + 3.117 + 3.118 + 3.119 + 3.120 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.html Sun Jul 06 12:02:12 2014 -0700 4.3 @@ -0,0 +1,35 @@ 4.4 +<!DOCTYPE html> 4.5 +<html> 4.6 + <head> 4.7 + <title>POP Display</title> 4.8 + <script data-main="startUpApp" src="lib/require.js"></script> 4.9 + 4.10 + <script src="lib/jquery.min.js"></script> 4.11 + 4.12 + <!-- --> 4.13 + <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" /> 4.14 + <meta name="mobile-web-app-capable" content="yes" /> 4.15 + <meta name="apple-mobile-web-app-capable" content="yes" /> 4.16 + <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 4.17 + 4.18 + <!-- shims for backwards compatibility --> 4.19 + <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script> 4.20 + <script type="text/javascript" src="../lib/classList.js"></script> 4.21 + <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script> 4.22 + 4.23 + <!-- module loader --> 4.24 + <script type="text/javascript" src="../lib/require.js"></script> 4.25 + 4.26 + <!-- famous --> 4.27 + <link rel="stylesheet" type="text/css" href="../lib/famous.css" /> 4.28 + <script type="text/javascript" src="../lib/famous.js"></script> 4.29 + 4.30 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. --> 4.31 + <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" /> 4.32 + 4.33 + </head> 4.34 + 4.35 +<body> 4.36 + 4.37 +</body> 4.38 +</html>
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.js Sun Jul 06 12:02:12 2014 -0700 5.3 @@ -0,0 +1,78 @@ 5.4 + 5.5 + 5.6 +//Make a Display object, and a number of functions that operate on it. 5.7 +// One of the functions accepts an array of visual element objects as 5.8 +// input, and turns those visual elements into a famous render tree. 5.9 +//The famous context, and the surfaces, and so on exist inside the Display 5.10 +// object. 5.11 + 5.12 +//This uses require.js to create a module. This module has the name of the 5.13 +// file (POPDisplay). Inside the define, a number of data structures and 5.14 +// functions are created, then returned at the end. The returned things are 5.15 +// what can be accessed by external functions that load this module, via 5.16 +// themselves using the require("POPDisplay") call 5.17 +define(function(require, exports, module) { 5.18 + //Create the famous infrastructure, which is used for rendering on screen 5.19 + var Engine = require("famous/core/Engine"); 5.20 + var Surface = require("famous/core/Surface"); 5.21 + var Modifier = require("famous/core/Modifier"); 5.22 + var Transform = require('famous/core/Transform'); 5.23 + var StateModifier = require('famous/modifiers/StateModifier'); 5.24 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 5.25 + 5.26 + //make the context, which controls rendering to the screen 5.27 + // once add something to this context, that add makes the thing visibly 5.28 + // have effect. 5.29 + //Note, these are available to the render function via the closure 5.30 + // mechanism 5.31 + var mainContext = Engine.createContext(); 5.32 + 5.33 + //the functions that access the Display object will be returned below 5.34 + var Display = { 5.35 + acceptViewList : function( inViewList ) { 5.36 + //modify the render tree of the mainContext according to the 5.37 + // in coming view list 5.38 + } 5.39 + 5.40 + handleGesture : function( event ) { 5.41 + //not sure this is the right form, but provide a handler for 5.42 + // gestures made by the programmer/user 5.43 + //This will make an object that pairs the gesture to the view 5.44 + // element that is represented by the surface(s) involved in 5.45 + // the gesture. 5.46 + //It will then send the object to the command generator, which 5.47 + // is part of the source holder 5.48 + } 5.49 + } 5.50 + function acceptViewList (viewList) { 5.51 + //access Display object and its values here, as a closure 5.52 + } 5.53 + 5.54 + function init() { 5.55 + // var POPStuffToDraw = 5.56 + var mySurface = new Surface({ 5.57 + size: [100, 100], 5.58 + content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 5.59 + properties: { 5.60 + color: 'white', 5.61 + lineHeight: '200%', 5.62 + textAlign: 'center', 5.63 + fontSize: '36px', 5.64 + cursor: 'pointer' 5.65 + } 5.66 + }); 5.67 + var stateModifier = new StateModifier({ 5.68 + transform: Transform.translate(250, 100, 0) 5.69 + }); 5.70 + mainContext.add(stateModifier).add(mySurface); 5.71 + 5.72 + 5.73 + 5.74 + return{ 5.75 + init: init, 5.76 + display: Display, 5.77 + acceptViewList: acceptViewList 5.78 + } 5.79 +}); 5.80 + 5.81 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/CalcCombosOfWord.js Sun Jul 06 12:02:12 2014 -0700 6.3 @@ -0,0 +1,112 @@ 6.4 +define(function () { 6.5 + 6.6 +var sortedLetters = []; 6.7 + 6.8 +var fact = []; 6.9 +var total = 0; 6.10 +var i = 0; 6.11 +fact[0] = 0; 6.12 +fact[1] = 1; 6.13 +//fill up the array of factorial values 6.14 +for( i = 2; i <= 25; i++) { 6.15 + fact[i] = i * fact[i-1]; 6.16 +} 6.17 + 6.18 +//Function to sort the letters in the input word. Returns an array of 6.19 +// objects. Each object has a field for the letter, and a field for the 6.20 +// number of times that letter appears in the input word. 6.21 +var sortLettersOfWord = function( inputWord ) { 6.22 + var letterArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 6.23 + var currLetter = ''; 6.24 + 6.25 + for( i = 0; i < inputWord.length; i++ ) { 6.26 + currLetter = inputWord.charCodeAt(i); 6.27 +// console.log(currLetter); 6.28 + index = currLetter - 'a'.charCodeAt(0); 6.29 + console.log(index); 6.30 + letterArray[index] += 1; 6.31 + } 6.32 + console.log('sorted letter A: ' + letterArray[0]); 6.33 + return letterArray; 6.34 +} 6.35 + 6.36 +//Calc the number of unique "words" producible from the sorted letters 6.37 +var calcCombosOfLetters = function( sortedLetters, totalNumLetters ) { 6.38 + console.log( "num letters: " + totalNumLetters ); 6.39 + numCombos = fact[ totalNumLetters ]; 6.40 +// console.log("numCombos: " + numCombos); 6.41 + //now, divide that by factorial of the multiplicity of each letter. 6.42 + // skip letters that only appear once (or zero). 6.43 + for( i=0; i<26; i++) { //be sure sortedLetters shrinks 6.44 + //when remove a letter object from it, so .size reflects that! 6.45 + if( sortedLetters[i] > 1 ) { 6.46 + //divide the number of combos by the factorial of, the number of 6.47 + // times the letter is repeated within the input word. 6.48 + numCombos /= fact[ sortedLetters[i] ]; 6.49 + } 6.50 + } 6.51 + console.log("numCombos: " + numCombos); 6.52 + return numCombos; 6.53 +} 6.54 + 6.55 +//Find number of rearrangements of the word's letters that come 6.56 +// alphabetically before the word. 6.57 +var rankThisWord = function(inputWordRaw) { 6.58 + var inputWord = inputWordRaw.toLowerCase(); 6.59 + 6.60 + console.log('started rank this word: ' + inputWord); 6.61 + var totalCombosComeBefore = 0; 6.62 + var numCombos = 0; 6.63 + var currPosInInputWord = 0; 6.64 + var numLettersInInputWord = inputWord.length; 6.65 + console.log("num letters: " + numLettersInInputWord); 6.66 + var numInputWordLettersLeft = inputWord.length; 6.67 + var sortedLetters = sortLettersOfWord( inputWord ); //returns array of 6.68 + //objs. Each obj pairs a letter with the multiplicity of that letter 6.69 + //the order of the objs matches the alphabetical order of the obj letters 6.70 + var firstLetter = 0; 6.71 + 6.72 + //repeat, marching down the letters of the input word 6.73 + while(currPosInInputWord < numLettersInInputWord) { 6.74 + //calc index (pos in alphabet) of current first letter in word) 6.75 + firstLetter = inputWord.charCodeAt(currPosInInputWord) - 'a'.charCodeAt(0); 6.76 + console.log("first letter:" + firstLetter + " at pos: " + currPosInInputWord); 6.77 + //Iterate over the letters that come before first 6.78 + for( currLetter=0; currLetter<26; currLetter++ ) { 6.79 + //if completed all earlier letters then terminate loop 6.80 +//Q: count duplicates of first letter? 6.81 + if( currLetter >= firstLetter ) break; 6.82 + else if( sortedLetters[currLetter] > 0) { 6.83 + console.log("earlier letter: " + currLetter); 6.84 + //for a given earlier letter, remove it from 6.85 + // the letter pool, leaving duplicates. 6.86 + sortedLetters[currLetter] -= 1; 6.87 + 6.88 + //Calculate the number of unique rearrangements of the 6.89 + // remaining letters, using the formula. 6.90 + numCombos = calcCombosOfLetters( sortedLetters, numInputWordLettersLeft - 1 ); 6.91 + 6.92 + //accumulate the total number of combos: 6.93 + totalCombosComeBefore += numCombos; 6.94 + 6.95 + //add the letter back! Need it while do other earlier letters 6.96 + sortedLetters[currLetter] += 1; 6.97 + } 6.98 + } 6.99 + 6.100 + //Now, done with first letter of input word. Delete that letter from 6.101 + // the input word, and from the sorted pool of letters, leaving 6.102 + // duplicates. 6.103 + numInputWordLettersLeft -= 1; 6.104 + currPosInInputWord += 1; 6.105 + sortedLetters[firstLetter] -= 1; 6.106 + } 6.107 + console.log("total combos come before: " + totalCombosComeBefore); 6.108 + return totalCombosComeBefore; 6.109 +} 6.110 + 6.111 + 6.112 + return { 6.113 + rankThisWord: rankThisWord 6.114 + }; 6.115 +}); 6.116 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/POPDisplay.js Sun Jul 06 12:02:12 2014 -0700 7.3 @@ -0,0 +1,74 @@ 7.4 + 7.5 + 7.6 +//Make a Display object, and a number of functions that operate on it. 7.7 +// One of the functions accepts an array of visual element objects as 7.8 +// input, and turns those visual elements into a famous render tree. 7.9 +//The famous context, and the surfaces, and so on exist inside the Display 7.10 +// object. 7.11 + 7.12 +//This uses require.js to create a module. This module has the name of the 7.13 +// file (POPDisplay). Inside the define, a number of data structures and 7.14 +// functions are created, then returned at the end. The returned things are 7.15 +// what can be accessed by external functions that load this module, via 7.16 +// themselves using the require("POPDisplay") call 7.17 +define(function(require, exports, module) { 7.18 + //Create the famous infrastructure, which is used for rendering on screen 7.19 + var Engine = require("famous/core/Engine"); 7.20 + var Surface = require("famous/core/Surface"); 7.21 + var Modifier = require("famous/core/Modifier"); 7.22 + var Transform = require('famous/core/Transform'); 7.23 + var StateModifier = require('famous/modifiers/StateModifier'); 7.24 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 7.25 + 7.26 + //make the context, which controls rendering to the screen 7.27 + // once add something to this context, that add makes the thing visibly 7.28 + // have effect. 7.29 + //Note, these are available to the render function via the closure 7.30 + // mechanism 7.31 + var mainContext = Engine.createContext(); 7.32 + 7.33 + 7.34 + var handleGesture = function( event ) { 7.35 + //not sure this is the right form, but provide a handler for 7.36 + // gestures made by the programmer/user 7.37 + //This will make an object that pairs the gesture to the view 7.38 + // element that is represented by the surface(s) involved in 7.39 + // the gesture. 7.40 + //It will then send the object to the command generator, which 7.41 + // is part of the source holder 7.42 + console.log("handleGesture"); 7.43 + } 7.44 + function acceptViewList (viewList) { 7.45 + //access Display object and its values here, as a closure 7.46 + console.log("acceptViewList"); 7.47 + } 7.48 + 7.49 + function init() { 7.50 + console.log("init"); 7.51 + // var POPStuffToDraw = 7.52 + var mySurface = new Surface({ 7.53 + size: [100, 100], 7.54 + content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 7.55 + properties: { 7.56 + color: 'white', 7.57 + lineHeight: '200%', 7.58 + textAlign: 'center', 7.59 + fontSize: '36px', 7.60 + cursor: 'pointer' 7.61 + } 7.62 + }); 7.63 + var stateModifier = new StateModifier({ 7.64 + transform: Transform.translate(250, 100, 0) 7.65 + }); 7.66 + mainContext.add(stateModifier).add(mySurface); 7.67 + } 7.68 + 7.69 + 7.70 + return{ 7.71 + init: init, 7.72 + handleGesture: handleGesture, 7.73 + acceptViewList: acceptViewList 7.74 + }; 7.75 +}); 7.76 + 7.77 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/epocratesPuzzle.js Sun Jul 06 12:02:12 2014 -0700 8.3 @@ -0,0 +1,57 @@ 8.4 +define(function (require) { 8.5 + 8.6 +//load the code that calculates the rank 8.7 +var calcNumCombos = require('./CalcCombosOfWord'); 8.8 + 8.9 +//Show title and explanation -- via DOM manipulation 8.10 +var el = document.createElement("h1") 8.11 +el.id="title"; 8.12 +el.innerHTML = "Epocrates Puzzle Test"; 8.13 +document.body.appendChild(el); 8.14 + 8.15 + 8.16 +el = document.createElement("span") 8.17 +el.style.display="block"; 8.18 +el.style.width="100%"; 8.19 +el.innerHTML = 'This program calculates the "rank" of a word. The rank equals the number of combinations of its letters, that happen to come before it alphabetically (plus 1 for itself)'; 8.20 +document.body.appendChild(el); 8.21 + 8.22 +//Get the word to calc combinations of 8.23 +//var inputword = prompt('Here you go, your chance to enter the word that you would like ranked!'); 8.24 +el1 = document.createElement("span") 8.25 +el1.style.display="block"; 8.26 +el1.style.width="100%"; 8.27 +el1.innerHTML ='<br><br>Here you go, your chance to enter the word that you would like ranked!'; 8.28 +document.body.appendChild(el1); 8.29 + 8.30 +el = document.createElement("INPUT"); 8.31 +el.setAttribute("id", "inputWord"); 8.32 +el.setAttribute("type", "text"); 8.33 +//el.setAttribute("value", "type word here, click button when done"); 8.34 +el.style.display="block"; 8.35 +el.style.width="50%"; 8.36 +document.body.appendChild(el); 8.37 + 8.38 +var inputWord = ""; 8.39 +//Now use jquery to create a button, display it, and set click event handler 8.40 +$('<button/>', { 8.41 + text: "Calc rank on this word!", 8.42 + id: 'inputIsReadyBtn', 8.43 + click: function () { inputWord = $("#inputWord").val(); 8.44 + var numEarlierWords = calcNumCombos.rankThisWord(inputWord); 8.45 + showResult( numEarlierWords ); 8.46 + } 8.47 +}).appendTo('body'); 8.48 + 8.49 + 8.50 + 8.51 +//Output the result 8.52 +var showResult = function( numEarlierWords ) { 8.53 + el = document.createElement("span") 8.54 + el.style.display="block"; 8.55 + el.style.width="100%"; 8.56 + el.innerHTML = "The rank of: " + inputWord + " is: " + (numEarlierWords + 1); 8.57 + document.body.appendChild(el); 8.58 +} 8.59 + 8.60 +}); 8.61 \ No newline at end of file
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/renderPOPSyntaxGraph.js Sun Jul 06 12:02:12 2014 -0700 9.3 @@ -0,0 +1,358 @@ 9.4 + 9.5 + 9.6 +define(function(require, exports, module) { 9.7 + var Engine = require("famous/core/Engine"); 9.8 + var Surface = require("famous/core/Surface"); 9.9 + var Modifier = require("famous/core/Modifier"); 9.10 + var Transform = require('famous/core/Transform'); 9.11 + var StateModifier = require('famous/modifiers/StateModifier'); 9.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 9.13 + 9.14 + var POPDisplay = require('./POPDisplay'); 9.15 + POPDisplay.acceptViewList("foo"); 9.16 + POPDisplay.init(); 9.17 + POPDisplay.handleGesture("foo"); 9.18 + 9.19 + var mainContext = Engine.createContext(); 9.20 + 9.21 + var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">'; 9.22 + var boxSVG = []; 9.23 + boxSVG[1] = '<svg width="'; 9.24 + boxSVG[2] = '" height="'; 9.25 + boxSVG[3] = '"><rect x="'; 9.26 + boxSVG[4] = '" y="'; 9.27 + boxSVG[5] = '" rx="' 9.28 + boxSVG[6] = '" ry="'; 9.29 + boxSVG[7] = '" width="' 9.30 + boxSVG[8] = '" height="' 9.31 + boxSVG[9] = '" style="fill:' 9.32 + boxSVG[10] = ';stroke:' 9.33 + boxSVG[11] = ';stroke-width:' 9.34 + boxSVG[12] = ';opacity:' 9.35 + boxSVG[13] = '">'; 9.36 + 9.37 + 9.38 +//Draw a simple syntax graph, with a box of the correct color for each 9.39 +// node, and curvy links with arrows going from text inside one node to 9.40 +// text inside another node. 9.41 +//Approach taken: 9.42 +//Generate the SVG from calculations -- hold strings in an array, and 9.43 +// build up an SVG string by adding string piece, then variable value then 9.44 +// another string piece, and so on. 9.45 +//Make each box a surface holding an SVG 9.46 +//Sizing of the box happens inside the SVG string 9.47 +//Positioning the box happens via a modifier 9.48 + 9.49 +//Make one container surface to hold each element node together with its 9.50 +// properties and ports 9.51 +//Make a separate surface for each SVG element -- one for each box, one for 9.52 +// each text in a box, one for each curvy connector arrow between boxes or 9.53 +// between texts. 9.54 +//For each surface, make a modifier that positions the box relative to the 9.55 +// container surface's origin 9.56 +//At the end, make transforms to move the entire container around 9.57 + 9.58 + //elem1 is the root element from the Gabe Pattern syntax graph 9.59 + // here, make the visual elements that reproduce what see in the .pdf 9.60 + var elem1Container = new ContainerSurface({ 9.61 + size: [600, 600], //size it big for now, trim to contents later 9.62 + properties: { 9.63 + overflow: 'hidden' 9.64 + } 9.65 + }); 9.66 + 9.67 +//== 9.68 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 9.69 +// 11:stroke-width 12:opacity 9.70 + var box1_1width = 66; 9.71 + var box1_1height = 86 9.72 +// var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 9.73 + var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2; 9.74 + var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 9.75 + 9.76 +//== elem1 box 1 --> box1_1 9.77 + var box1_1 = new Surface({ 9.78 + size: [true, true], 9.79 + content: boxSVGFromParts1_1 9.80 + }); 9.81 + var box1_1x = 0; 9.82 + var box1_1y = 2; 9.83 + var boxMod1_1_1 = new StateModifier({ 9.84 + transform: Transform.translate(box1_1x, box1_1y, 0) 9.85 + }); 9.86 + 9.87 +//== elem1 box 1 text 1 --> text1_1_1 9.88 + var text1_1_1 = new Surface({ 9.89 + size: [true, 11], 9.90 + content: "properties", 9.91 + properties: { 9.92 + color: 'black', 9.93 + textAlign: 'left', 9.94 + fontSize: '11px', 9.95 + cursor: 'hand' 9.96 + } 9.97 + }); 9.98 + var text1_1_2 = new Surface({ 9.99 + size: [true, true], 9.100 + content: "portsIn", 9.101 + properties: { 9.102 + color: 'black', 9.103 + textAlign: 'left', 9.104 + fontSize: '11px', 9.105 + cursor: 'pointer' 9.106 + } 9.107 + }); 9.108 + var text1_1_3 = new Surface({ 9.109 + size: [true, true], 9.110 + content: "portsOut", 9.111 + properties: { 9.112 + color: 'black', 9.113 + textAlign: 'left', 9.114 + fontSize: '11px', 9.115 + cursor: 'pointer' 9.116 + } 9.117 + }); 9.118 + var text1_1_4 = new Surface({ 9.119 + size: [true, true], 9.120 + content: "subElems", 9.121 + properties: { 9.122 + color: 'black', 9.123 + textAlign: 'left', 9.124 + fontSize: '11px', 9.125 + cursor: 'pointer' 9.126 + } 9.127 + }); 9.128 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1 9.129 + var text1_1_1x = 8; 9.130 + var text1_1_1y = 8; 9.131 + var textMod1_1_1_1 = new StateModifier({ 9.132 + transform: Transform.translate(text1_1_1x, text1_1_1y, 0) 9.133 + }); 9.134 + var textMod1_1_2_1 = new StateModifier({ 9.135 + transform: Transform.translate(8, 25, 0) 9.136 + }); 9.137 + var textMod1_1_3_1 = new StateModifier({ 9.138 + transform: Transform.translate(8, 42, 0) 9.139 + }); 9.140 + var textMod1_1_4_1 = new StateModifier({ 9.141 + transform: Transform.translate(8, 59, 0) 9.142 + }); 9.143 +//== 9.144 + elem1Container.add(boxMod1_1_1).add(box1_1); 9.145 + elem1Container.add(textMod1_1_1_1).add(text1_1_1); 9.146 + elem1Container.add(textMod1_1_2_1).add(text1_1_2); 9.147 + elem1Container.add(textMod1_1_3_1).add(text1_1_3); 9.148 + elem1Container.add(textMod1_1_4_1).add(text1_1_4); 9.149 + 9.150 +//== elem 1 box 2 --> box1_2 9.151 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 9.152 +// 11:stroke-width 12:opacity 9.153 + var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2; 9.154 + var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 9.155 + var box1_2 = new Surface({ 9.156 + size: [true, true], 9.157 + content: boxSVGFromParts1_2 9.158 + }); 9.159 + var box1_2x = 100; 9.160 + var box1_2y = 2; 9.161 + var boxMod1_2_1 = new StateModifier({ 9.162 + transform: Transform.translate(box1_2x, box1_2y, 0) 9.163 + }); 9.164 +//== elem 1 box 2 text 1 --> text1_2_1 9.165 + var text1_2_1 = new Surface({ 9.166 + size: [true, true], 9.167 + content: "propertyName: TypeOfElement", 9.168 + properties: { 9.169 + color: 'black', 9.170 + textAlign: 'left', 9.171 + fontSize: '11px', 9.172 + cursor: 'pointer' 9.173 + } 9.174 + }); 9.175 + var text1_2_2 = new Surface({ 9.176 + size: [true, true], 9.177 + content: "propertyValue: GabeTransfromRule", 9.178 + properties: { 9.179 + color: 'black', 9.180 + textAlign: 'left', 9.181 + fontSize: '11px', 9.182 + cursor: 'pointer' 9.183 + } 9.184 + }); 9.185 + var text1_2_3 = new Surface({ 9.186 + size: [true, true], 9.187 + content: "subProperties", 9.188 + properties: { 9.189 + color: 'black', 9.190 + textAlign: 'left', 9.191 + fontSize: '11px', 9.192 + cursor: 'pointer' 9.193 + } 9.194 + }); 9.195 +//== 9.196 + var textMod1_2_1_1 = new StateModifier({ 9.197 + transform: Transform.translate(108, 8, 0) 9.198 + }); 9.199 + var textMod1_2_2_1 = new StateModifier({ 9.200 + transform: Transform.translate(108, 25, 0) 9.201 + }); 9.202 + var textMod1_2_3_1 = new StateModifier({ 9.203 + transform: Transform.translate(108, 42, 0) 9.204 + }); 9.205 +//== 9.206 + elem1Container.add(boxMod1_2_1).add(box1_2); 9.207 + elem1Container.add(textMod1_2_1_1).add(text1_2_1); 9.208 + elem1Container.add(textMod1_2_2_1).add(text1_2_2); 9.209 + elem1Container.add(textMod1_2_3_1).add(text1_2_3); 9.210 + 9.211 +//Now, add bezier curve, in SVG.. 9.212 +//One end point is the end of "properties" text surface inside the elem box 9.213 +//Other end point is the middle of side of properties box 9.214 + 9.215 + var bezierSVG1 = '<svg width="106" height="106"> <path d="M3,3 C0,100 100,0 100,100" style="fill:none;stroke:black;stroke-width:4;opacity:1">'; 9.216 + 9.217 + var bezSVG = []; 9.218 + bezSVG[1] = '<svg width="' 9.219 + bezSVG[2] = '" height="' 9.220 + bezSVG[3] = '"><path d="M' //start pt x 9.221 + bezSVG[4] = ',' //start pt y 9.222 + bezSVG[5] = ' C' //control pt 1 x 9.223 + bezSVG[6] = ',' //control pt 1 y 9.224 + bezSVG[7] = ' ' //control pt 2 x 9.225 + bezSVG[8] = ',' //control pt 2 y 9.226 + bezSVG[9] = ' ' //end pt x 9.227 + bezSVG[10] = ',' //end pt y 9.228 + bezSVG[11] = '" style="fill:' 9.229 + bezSVG[12] = ';stroke:' 9.230 + bezSVG[13] = ';stroke-width:' 9.231 + bezSVG[14] = ';opacity:' 9.232 + bezSVG[15] = '">'; 9.233 + 9.234 + //now calculate the end points of the curve -- they connect to the 9.235 + // right edge of the "properties" text in the left box, and to the 9.236 + // middle of the left side of the right box 9.237 + var bezPoints = [{},{}]; 9.238 + var fontSz = 11; 9.239 + bezPoints[0].x = box1_1x + box1_1w; 9.240 + bezPoints[0].y = text1_1_1y + fontSz/2 + 8; 9.241 + bezPoints[1].x = box1_2x; 9.242 + bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2; 9.243 + 9.244 + var controlPoints = []; 9.245 + controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y}; 9.246 + controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y}; 9.247 + 9.248 + 9.249 + // 1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x 9.250 + // 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity 9.251 + var bezSVG1 = ""; 9.252 + bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6); 9.253 + bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6); 9.254 + bezSVG1 += bezSVG[3] + bezPoints[0].x; 9.255 + bezSVG1 += bezSVG[4] + bezPoints[0].y; 9.256 + bezSVG1 += bezSVG[5] + controlPoints[0].x; 9.257 + bezSVG1 += bezSVG[6] + controlPoints[0].y; 9.258 + bezSVG1 += bezSVG[7] + controlPoints[1].x; 9.259 + bezSVG1 += bezSVG[8] + controlPoints[1].y; 9.260 + bezSVG1 += bezSVG[9] + bezPoints[1].x; 9.261 + bezSVG1 += bezSVG[10] + bezPoints[1].y; 9.262 + bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15]; 9.263 + 9.264 +var bezSVG2 = '<svg width="400" height="170"><path d="M66,13.5 C66,2.5 100,13.5 100,2.5" style="fill:none;stroke:black;stroke-width:2;opacity:1">'; 9.265 +var x1 = 59; var x2 = 100; var y1 = 22; var y2 = 40; 9.266 +var bezSVG3 = '<svg width="200" height="200"><path d="M59,21 C100,21 59,38 100,38" style="fill:none;stroke:black;stroke-width:2;opacity:1">'; 9.267 + var bez1_1 = new Surface({ 9.268 + size: [true, true], 9.269 + content: bezSVG1 9.270 + }); 9.271 + 9.272 + elem1Container.add(bez1_1); 9.273 + 9.274 +var el1 = document.createElement("span") 9.275 +var displayStr = bezSVG1.replace(/</g, "<");//make the html display as text 9.276 +el1.innerHTML = (displayStr + "<br>"); 9.277 +document.body.appendChild(el1); 9.278 +el1 = document.createElement("span") 9.279 +displayStr = bezSVG3.replace(/</g, "<");//make the html display as text 9.280 +el1.innerHTML = displayStr; 9.281 +document.body.appendChild(el1); 9.282 + 9.283 + 9.284 +//== elem 1 Modifer 1 --> contMod1_1 9.285 + var contMod1_1 = new StateModifier({ 9.286 + transform: Transform.translate(50, 50, 0) 9.287 + }); 9.288 + var contMod1_2 = new StateModifier({ 9.289 + transform: Transform.scale(1, 1) 9.290 + }); 9.291 +//== 9.292 + 9.293 + mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container); 9.294 + 9.295 + //elem2 is 9.296 + var elem2Container = new ContainerSurface({ 9.297 + size: [200, 200], 9.298 + properties: { 9.299 + overflow: 'hidden' 9.300 + } 9.301 + }); 9.302 + 9.303 + 9.304 + 9.305 +//== elem 2 box 1 --> box2_1 9.306 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 9.307 +// 11:stroke-width 12:opacity 9.308 + var boxSVGFromParts2_1 = boxSVG[1] + '68' + boxSVG[2] + '88' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '66' + boxSVG[8] + '86' + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 9.309 + var box2_1 = new Surface({ 9.310 + size: [100, 100], 9.311 + content: boxSVGFromParts2_1, 9.312 + }); 9.313 + var box2_3 = new Surface({ 9.314 + size: [100, 100], 9.315 + content: boxSVGFromParts2_1, 9.316 + properties: { 9.317 + } 9.318 + }); 9.319 + var box2_4 = new Surface({ 9.320 + size: [100, 100], 9.321 + content: boxSVGFromParts2_1, 9.322 + properties: { 9.323 + } 9.324 + }); 9.325 + 9.326 +//== 9.327 + var boxMod2_1_1 = new StateModifier({ 9.328 + transform: Transform.translate(7, 90, 0) 9.329 + }); 9.330 + var boxMod2_1_2 = new StateModifier({ 9.331 + transform: Transform.scale(.3, .3) 9.332 + }); 9.333 +//== 9.334 + var boxMod2_2_1 = new StateModifier({ 9.335 + transform: Transform.translate(42, 90, 0) 9.336 + }); 9.337 + var boxMod2_2_2 = new StateModifier({ 9.338 + transform: Transform.scale(.3, .3) 9.339 + }); 9.340 +//== 9.341 + var boxMod2_3_1 = new StateModifier({ 9.342 + transform: Transform.translate(42, 2, 0) 9.343 + }); 9.344 + var boxMod2_3_2 = new StateModifier({ 9.345 + transform: Transform.scale(.3, .3) 9.346 + }); 9.347 +//== 9.348 + var boxMod2_4_1 = new StateModifier({ 9.349 + transform: Transform.translate(57, 20, 0) 9.350 + }); 9.351 + var boxMod2_4_2 = new StateModifier({ 9.352 + transform: Transform.scale(1.22, 1.22) 9.353 + }); 9.354 +//== 9.355 + var equalMod = new StateModifier({ 9.356 + transform: Transform.translate(27, 85, 0) 9.357 + }); 9.358 + 9.359 + 9.360 +// summationContainer.add(sigmaMod1).add(sigmaSurf); 9.361 +});
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/displayLoadPage.html Sun Jul 06 12:02:12 2014 -0700 10.3 @@ -0,0 +1,52 @@ 10.4 +<!DOCTYPE html> 10.5 +<html> 10.6 + <head> 10.7 + <title>famo.us App</title> 10.8 + <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" /> 10.9 + <meta name="mobile-web-app-capable" content="yes" /> 10.10 + <meta name="apple-mobile-web-app-capable" content="yes" /> 10.11 + <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 10.12 + 10.13 + <!-- shims for backwards compatibility --> 10.14 + <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script> 10.15 + <script type="text/javascript" src="../lib/classList.js"></script> 10.16 + <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script> 10.17 + 10.18 + <!-- module loader --> 10.19 + <script type="text/javascript" src="../lib/require.js"></script> 10.20 + 10.21 + <!-- famous --> 10.22 + <link rel="stylesheet" type="text/css" href="../lib/famous.css" /> 10.23 + <script type="text/javascript" src="../lib/famous.js"></script> 10.24 + 10.25 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. --> 10.26 + <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" /> 10.27 + 10.28 + <!-- load D3, to play around with also! --> 10.29 + <!--script type="text/javascript" src="d3/d3.v3.js"></script--> 10.30 + 10.31 + </head> 10.32 + 10.33 +<!-- 10.34 +<script src="terminal.js"> 10.35 +</script> 10.36 +<body onload="window.start('terminal');"> 10.37 + 10.38 +<div id="loader">...</div> 10.39 + 10.40 +<script type="text/javascript">require(['POP_Display']);</script> 10.41 + 10.42 +<script src="POP_Display.js"> 10.43 +</script> 10.44 + 10.45 +<body onload="window.start('Display.render');"> 10.46 + 10.47 +--> 10.48 +<body> 10.49 + 10.50 +<script type="text/javascript">require(['render_POP_syntax_graph']);</script> 10.51 + 10.52 +</body> 10.53 +</html> 10.54 + 10.55 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/index.html Sun Jul 06 12:02:12 2014 -0700 11.3 @@ -0,0 +1,35 @@ 11.4 +<!DOCTYPE html> 11.5 +<html> 11.6 + <head> 11.7 + <title>POP Display</title> 11.8 + <script data-main="startUpApp" src="lib/require.js"></script> 11.9 + 11.10 + <script src="lib/jquery.min.js"></script> 11.11 + 11.12 + <!-- --> 11.13 + <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" /> 11.14 + <meta name="mobile-web-app-capable" content="yes" /> 11.15 + <meta name="apple-mobile-web-app-capable" content="yes" /> 11.16 + <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 11.17 + 11.18 + <!-- shims for backwards compatibility --> 11.19 + <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script> 11.20 + <script type="text/javascript" src="../lib/classList.js"></script> 11.21 + <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script> 11.22 + 11.23 + <!-- module loader --> 11.24 + <script type="text/javascript" src="../lib/require.js"></script> 11.25 + 11.26 + <!-- famous --> 11.27 + <link rel="stylesheet" type="text/css" href="../lib/famous.css" /> 11.28 + <script type="text/javascript" src="../lib/famous.js"></script> 11.29 + 11.30 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. --> 11.31 + <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" /> 11.32 + 11.33 + </head> 11.34 + 11.35 +<body> 11.36 + 11.37 +</body> 11.38 +</html>
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/jquery.min.js Sun Jul 06 12:02:12 2014 -0700 12.3 @@ -0,0 +1,4 @@ 12.4 +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ 12.5 +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; 12.6 +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px") 12.7 +},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m}); 12.8 \ No newline at end of file
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/require.js Sun Jul 06 12:02:12 2014 -0700 13.3 @@ -0,0 +1,2076 @@ 13.4 +/** vim: et:ts=4:sw=4:sts=4 13.5 + * @license RequireJS 2.1.14 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 13.6 + * Available via the MIT or new BSD license. 13.7 + * see: http://github.com/jrburke/requirejs for details 13.8 + */ 13.9 +//Not using strict: uneven strict support in browsers, #392, and causes 13.10 +//problems with requirejs.exec()/transpiler plugins that may not be strict. 13.11 +/*jslint regexp: true, nomen: true, sloppy: true */ 13.12 +/*global window, navigator, document, importScripts, setTimeout, opera */ 13.13 + 13.14 +var requirejs, require, define; 13.15 +(function (global) { 13.16 + var req, s, head, baseElement, dataMain, src, 13.17 + interactiveScript, currentlyAddingScript, mainScript, subPath, 13.18 + version = '2.1.14', 13.19 + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, 13.20 + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, 13.21 + jsSuffixRegExp = /\.js$/, 13.22 + currDirRegExp = /^\.\//, 13.23 + op = Object.prototype, 13.24 + ostring = op.toString, 13.25 + hasOwn = op.hasOwnProperty, 13.26 + ap = Array.prototype, 13.27 + apsp = ap.splice, 13.28 + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), 13.29 + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', 13.30 + //PS3 indicates loaded and complete, but need to wait for complete 13.31 + //specifically. Sequence is 'loading', 'loaded', execution, 13.32 + // then 'complete'. The UA check is unfortunate, but not sure how 13.33 + //to feature test w/o causing perf issues. 13.34 + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? 13.35 + /^complete$/ : /^(complete|loaded)$/, 13.36 + defContextName = '_', 13.37 + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. 13.38 + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', 13.39 + contexts = {}, 13.40 + cfg = {}, 13.41 + globalDefQueue = [], 13.42 + useInteractive = false; 13.43 + 13.44 + function isFunction(it) { 13.45 + return ostring.call(it) === '[object Function]'; 13.46 + } 13.47 + 13.48 + function isArray(it) { 13.49 + return ostring.call(it) === '[object Array]'; 13.50 + } 13.51 + 13.52 + /** 13.53 + * Helper function for iterating over an array. If the func returns 13.54 + * a true value, it will break out of the loop. 13.55 + */ 13.56 + function each(ary, func) { 13.57 + if (ary) { 13.58 + var i; 13.59 + for (i = 0; i < ary.length; i += 1) { 13.60 + if (ary[i] && func(ary[i], i, ary)) { 13.61 + break; 13.62 + } 13.63 + } 13.64 + } 13.65 + } 13.66 + 13.67 + /** 13.68 + * Helper function for iterating over an array backwards. If the func 13.69 + * returns a true value, it will break out of the loop. 13.70 + */ 13.71 + function eachReverse(ary, func) { 13.72 + if (ary) { 13.73 + var i; 13.74 + for (i = ary.length - 1; i > -1; i -= 1) { 13.75 + if (ary[i] && func(ary[i], i, ary)) { 13.76 + break; 13.77 + } 13.78 + } 13.79 + } 13.80 + } 13.81 + 13.82 + function hasProp(obj, prop) { 13.83 + return hasOwn.call(obj, prop); 13.84 + } 13.85 + 13.86 + function getOwn(obj, prop) { 13.87 + return hasProp(obj, prop) && obj[prop]; 13.88 + } 13.89 + 13.90 + /** 13.91 + * Cycles over properties in an object and calls a function for each 13.92 + * property value. If the function returns a truthy value, then the 13.93 + * iteration is stopped. 13.94 + */ 13.95 + function eachProp(obj, func) { 13.96 + var prop; 13.97 + for (prop in obj) { 13.98 + if (hasProp(obj, prop)) { 13.99 + if (func(obj[prop], prop)) { 13.100 + break; 13.101 + } 13.102 + } 13.103 + } 13.104 + } 13.105 + 13.106 + /** 13.107 + * Simple function to mix in properties from source into target, 13.108 + * but only if target does not already have a property of the same name. 13.109 + */ 13.110 + function mixin(target, source, force, deepStringMixin) { 13.111 + if (source) { 13.112 + eachProp(source, function (value, prop) { 13.113 + if (force || !hasProp(target, prop)) { 13.114 + if (deepStringMixin && typeof value === 'object' && value && 13.115 + !isArray(value) && !isFunction(value) && 13.116 + !(value instanceof RegExp)) { 13.117 + 13.118 + if (!target[prop]) { 13.119 + target[prop] = {}; 13.120 + } 13.121 + mixin(target[prop], value, force, deepStringMixin); 13.122 + } else { 13.123 + target[prop] = value; 13.124 + } 13.125 + } 13.126 + }); 13.127 + } 13.128 + return target; 13.129 + } 13.130 + 13.131 + //Similar to Function.prototype.bind, but the 'this' object is specified 13.132 + //first, since it is easier to read/figure out what 'this' will be. 13.133 + function bind(obj, fn) { 13.134 + return function () { 13.135 + return fn.apply(obj, arguments); 13.136 + }; 13.137 + } 13.138 + 13.139 + function scripts() { 13.140 + return document.getElementsByTagName('script'); 13.141 + } 13.142 + 13.143 + function defaultOnError(err) { 13.144 + throw err; 13.145 + } 13.146 + 13.147 + //Allow getting a global that is expressed in 13.148 + //dot notation, like 'a.b.c'. 13.149 + function getGlobal(value) { 13.150 + if (!value) { 13.151 + return value; 13.152 + } 13.153 + var g = global; 13.154 + each(value.split('.'), function (part) { 13.155 + g = g[part]; 13.156 + }); 13.157 + return g; 13.158 + } 13.159 + 13.160 + /** 13.161 + * Constructs an error with a pointer to an URL with more information. 13.162 + * @param {String} id the error ID that maps to an ID on a web page. 13.163 + * @param {String} message human readable error. 13.164 + * @param {Error} [err] the original error, if there is one. 13.165 + * 13.166 + * @returns {Error} 13.167 + */ 13.168 + function makeError(id, msg, err, requireModules) { 13.169 + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); 13.170 + e.requireType = id; 13.171 + e.requireModules = requireModules; 13.172 + if (err) { 13.173 + e.originalError = err; 13.174 + } 13.175 + return e; 13.176 + } 13.177 + 13.178 + if (typeof define !== 'undefined') { 13.179 + //If a define is already in play via another AMD loader, 13.180 + //do not overwrite. 13.181 + return; 13.182 + } 13.183 + 13.184 + if (typeof requirejs !== 'undefined') { 13.185 + if (isFunction(requirejs)) { 13.186 + //Do not overwrite an existing requirejs instance. 13.187 + return; 13.188 + } 13.189 + cfg = requirejs; 13.190 + requirejs = undefined; 13.191 + } 13.192 + 13.193 + //Allow for a require config object 13.194 + if (typeof require !== 'undefined' && !isFunction(require)) { 13.195 + //assume it is a config object. 13.196 + cfg = require; 13.197 + require = undefined; 13.198 + } 13.199 + 13.200 + function newContext(contextName) { 13.201 + var inCheckLoaded, Module, context, handlers, 13.202 + checkLoadedTimeoutId, 13.203 + config = { 13.204 + //Defaults. Do not set a default for map 13.205 + //config to speed up normalize(), which 13.206 + //will run faster if there is no default. 13.207 + waitSeconds: 7, 13.208 + baseUrl: './', 13.209 + paths: {}, 13.210 + bundles: {}, 13.211 + pkgs: {}, 13.212 + shim: {}, 13.213 + config: {} 13.214 + }, 13.215 + registry = {}, 13.216 + //registry of just enabled modules, to speed 13.217 + //cycle breaking code when lots of modules 13.218 + //are registered, but not activated. 13.219 + enabledRegistry = {}, 13.220 + undefEvents = {}, 13.221 + defQueue = [], 13.222 + defined = {}, 13.223 + urlFetched = {}, 13.224 + bundlesMap = {}, 13.225 + requireCounter = 1, 13.226 + unnormalizedCounter = 1; 13.227 + 13.228 + /** 13.229 + * Trims the . and .. from an array of path segments. 13.230 + * It will keep a leading path segment if a .. will become 13.231 + * the first path segment, to help with module name lookups, 13.232 + * which act like paths, but can be remapped. But the end result, 13.233 + * all paths that use this function should look normalized. 13.234 + * NOTE: this method MODIFIES the input array. 13.235 + * @param {Array} ary the array of path segments. 13.236 + */ 13.237 + function trimDots(ary) { 13.238 + var i, part; 13.239 + for (i = 0; i < ary.length; i++) { 13.240 + part = ary[i]; 13.241 + if (part === '.') { 13.242 + ary.splice(i, 1); 13.243 + i -= 1; 13.244 + } else if (part === '..') { 13.245 + // If at the start, or previous value is still .., 13.246 + // keep them so that when converted to a path it may 13.247 + // still work when converted to a path, even though 13.248 + // as an ID it is less than ideal. In larger point 13.249 + // releases, may be better to just kick out an error. 13.250 + if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') { 13.251 + continue; 13.252 + } else if (i > 0) { 13.253 + ary.splice(i - 1, 2); 13.254 + i -= 2; 13.255 + } 13.256 + } 13.257 + } 13.258 + } 13.259 + 13.260 + /** 13.261 + * Given a relative module name, like ./something, normalize it to 13.262 + * a real name that can be mapped to a path. 13.263 + * @param {String} name the relative name 13.264 + * @param {String} baseName a real name that the name arg is relative 13.265 + * to. 13.266 + * @param {Boolean} applyMap apply the map config to the value. Should 13.267 + * only be done if this normalization is for a dependency ID. 13.268 + * @returns {String} normalized name 13.269 + */ 13.270 + function normalize(name, baseName, applyMap) { 13.271 + var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, 13.272 + foundMap, foundI, foundStarMap, starI, normalizedBaseParts, 13.273 + baseParts = (baseName && baseName.split('/')), 13.274 + map = config.map, 13.275 + starMap = map && map['*']; 13.276 + 13.277 + //Adjust any relative paths. 13.278 + if (name) { 13.279 + name = name.split('/'); 13.280 + lastIndex = name.length - 1; 13.281 + 13.282 + // If wanting node ID compatibility, strip .js from end 13.283 + // of IDs. Have to do this here, and not in nameToUrl 13.284 + // because node allows either .js or non .js to map 13.285 + // to same file. 13.286 + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { 13.287 + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); 13.288 + } 13.289 + 13.290 + // Starts with a '.' so need the baseName 13.291 + if (name[0].charAt(0) === '.' && baseParts) { 13.292 + //Convert baseName to array, and lop off the last part, 13.293 + //so that . matches that 'directory' and not name of the baseName's 13.294 + //module. For instance, baseName of 'one/two/three', maps to 13.295 + //'one/two/three.js', but we want the directory, 'one/two' for 13.296 + //this normalization. 13.297 + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); 13.298 + name = normalizedBaseParts.concat(name); 13.299 + } 13.300 + 13.301 + trimDots(name); 13.302 + name = name.join('/'); 13.303 + } 13.304 + 13.305 + //Apply map config if available. 13.306 + if (applyMap && map && (baseParts || starMap)) { 13.307 + nameParts = name.split('/'); 13.308 + 13.309 + outerLoop: for (i = nameParts.length; i > 0; i -= 1) { 13.310 + nameSegment = nameParts.slice(0, i).join('/'); 13.311 + 13.312 + if (baseParts) { 13.313 + //Find the longest baseName segment match in the config. 13.314 + //So, do joins on the biggest to smallest lengths of baseParts. 13.315 + for (j = baseParts.length; j > 0; j -= 1) { 13.316 + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); 13.317 + 13.318 + //baseName segment has config, find if it has one for 13.319 + //this name. 13.320 + if (mapValue) { 13.321 + mapValue = getOwn(mapValue, nameSegment); 13.322 + if (mapValue) { 13.323 + //Match, update name to the new value. 13.324 + foundMap = mapValue; 13.325 + foundI = i; 13.326 + break outerLoop; 13.327 + } 13.328 + } 13.329 + } 13.330 + } 13.331 + 13.332 + //Check for a star map match, but just hold on to it, 13.333 + //if there is a shorter segment match later in a matching 13.334 + //config, then favor over this star map. 13.335 + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { 13.336 + foundStarMap = getOwn(starMap, nameSegment); 13.337 + starI = i; 13.338 + } 13.339 + } 13.340 + 13.341 + if (!foundMap && foundStarMap) { 13.342 + foundMap = foundStarMap; 13.343 + foundI = starI; 13.344 + } 13.345 + 13.346 + if (foundMap) { 13.347 + nameParts.splice(0, foundI, foundMap); 13.348 + name = nameParts.join('/'); 13.349 + } 13.350 + } 13.351 + 13.352 + // If the name points to a package's name, use 13.353 + // the package main instead. 13.354 + pkgMain = getOwn(config.pkgs, name); 13.355 + 13.356 + return pkgMain ? pkgMain : name; 13.357 + } 13.358 + 13.359 + function removeScript(name) { 13.360 + if (isBrowser) { 13.361 + each(scripts(), function (scriptNode) { 13.362 + if (scriptNode.getAttribute('data-requiremodule') === name && 13.363 + scriptNode.getAttribute('data-requirecontext') === context.contextName) { 13.364 + scriptNode.parentNode.removeChild(scriptNode); 13.365 + return true; 13.366 + } 13.367 + }); 13.368 + } 13.369 + } 13.370 + 13.371 + function hasPathFallback(id) { 13.372 + var pathConfig = getOwn(config.paths, id); 13.373 + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { 13.374 + //Pop off the first array value, since it failed, and 13.375 + //retry 13.376 + pathConfig.shift(); 13.377 + context.require.undef(id); 13.378 + 13.379 + //Custom require that does not do map translation, since 13.380 + //ID is "absolute", already mapped/resolved. 13.381 + context.makeRequire(null, { 13.382 + skipMap: true 13.383 + })([id]); 13.384 + 13.385 + return true; 13.386 + } 13.387 + } 13.388 + 13.389 + //Turns a plugin!resource to [plugin, resource] 13.390 + //with the plugin being undefined if the name 13.391 + //did not have a plugin prefix. 13.392 + function splitPrefix(name) { 13.393 + var prefix, 13.394 + index = name ? name.indexOf('!') : -1; 13.395 + if (index > -1) { 13.396 + prefix = name.substring(0, index); 13.397 + name = name.substring(index + 1, name.length); 13.398 + } 13.399 + return [prefix, name]; 13.400 + } 13.401 + 13.402 + /** 13.403 + * Creates a module mapping that includes plugin prefix, module 13.404 + * name, and path. If parentModuleMap is provided it will 13.405 + * also normalize the name via require.normalize() 13.406 + * 13.407 + * @param {String} name the module name 13.408 + * @param {String} [parentModuleMap] parent module map 13.409 + * for the module name, used to resolve relative names. 13.410 + * @param {Boolean} isNormalized: is the ID already normalized. 13.411 + * This is true if this call is done for a define() module ID. 13.412 + * @param {Boolean} applyMap: apply the map config to the ID. 13.413 + * Should only be true if this map is for a dependency. 13.414 + * 13.415 + * @returns {Object} 13.416 + */ 13.417 + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { 13.418 + var url, pluginModule, suffix, nameParts, 13.419 + prefix = null, 13.420 + parentName = parentModuleMap ? parentModuleMap.name : null, 13.421 + originalName = name, 13.422 + isDefine = true, 13.423 + normalizedName = ''; 13.424 + 13.425 + //If no name, then it means it is a require call, generate an 13.426 + //internal name. 13.427 + if (!name) { 13.428 + isDefine = false; 13.429 + name = '_@r' + (requireCounter += 1); 13.430 + } 13.431 + 13.432 + nameParts = splitPrefix(name); 13.433 + prefix = nameParts[0]; 13.434 + name = nameParts[1]; 13.435 + 13.436 + if (prefix) { 13.437 + prefix = normalize(prefix, parentName, applyMap); 13.438 + pluginModule = getOwn(defined, prefix); 13.439 + } 13.440 + 13.441 + //Account for relative paths if there is a base name. 13.442 + if (name) { 13.443 + if (prefix) { 13.444 + if (pluginModule && pluginModule.normalize) { 13.445 + //Plugin is loaded, use its normalize method. 13.446 + normalizedName = pluginModule.normalize(name, function (name) { 13.447 + return normalize(name, parentName, applyMap); 13.448 + }); 13.449 + } else { 13.450 + // If nested plugin references, then do not try to 13.451 + // normalize, as it will not normalize correctly. This 13.452 + // places a restriction on resourceIds, and the longer 13.453 + // term solution is not to normalize until plugins are 13.454 + // loaded and all normalizations to allow for async 13.455 + // loading of a loader plugin. But for now, fixes the 13.456 + // common uses. Details in #1131 13.457 + normalizedName = name.indexOf('!') === -1 ? 13.458 + normalize(name, parentName, applyMap) : 13.459 + name; 13.460 + } 13.461 + } else { 13.462 + //A regular module. 13.463 + normalizedName = normalize(name, parentName, applyMap); 13.464 + 13.465 + //Normalized name may be a plugin ID due to map config 13.466 + //application in normalize. The map config values must 13.467 + //already be normalized, so do not need to redo that part. 13.468 + nameParts = splitPrefix(normalizedName); 13.469 + prefix = nameParts[0]; 13.470 + normalizedName = nameParts[1]; 13.471 + isNormalized = true; 13.472 + 13.473 + url = context.nameToUrl(normalizedName); 13.474 + } 13.475 + } 13.476 + 13.477 + //If the id is a plugin id that cannot be determined if it needs 13.478 + //normalization, stamp it with a unique ID so two matching relative 13.479 + //ids that may conflict can be separate. 13.480 + suffix = prefix && !pluginModule && !isNormalized ? 13.481 + '_unnormalized' + (unnormalizedCounter += 1) : 13.482 + ''; 13.483 + 13.484 + return { 13.485 + prefix: prefix, 13.486 + name: normalizedName, 13.487 + parentMap: parentModuleMap, 13.488 + unnormalized: !!suffix, 13.489 + url: url, 13.490 + originalName: originalName, 13.491 + isDefine: isDefine, 13.492 + id: (prefix ? 13.493 + prefix + '!' + normalizedName : 13.494 + normalizedName) + suffix 13.495 + }; 13.496 + } 13.497 + 13.498 + function getModule(depMap) { 13.499 + var id = depMap.id, 13.500 + mod = getOwn(registry, id); 13.501 + 13.502 + if (!mod) { 13.503 + mod = registry[id] = new context.Module(depMap); 13.504 + } 13.505 + 13.506 + return mod; 13.507 + } 13.508 + 13.509 + function on(depMap, name, fn) { 13.510 + var id = depMap.id, 13.511 + mod = getOwn(registry, id); 13.512 + 13.513 + if (hasProp(defined, id) && 13.514 + (!mod || mod.defineEmitComplete)) { 13.515 + if (name === 'defined') { 13.516 + fn(defined[id]); 13.517 + } 13.518 + } else { 13.519 + mod = getModule(depMap); 13.520 + if (mod.error && name === 'error') { 13.521 + fn(mod.error); 13.522 + } else { 13.523 + mod.on(name, fn); 13.524 + } 13.525 + } 13.526 + } 13.527 + 13.528 + function onError(err, errback) { 13.529 + var ids = err.requireModules, 13.530 + notified = false; 13.531 + 13.532 + if (errback) { 13.533 + errback(err); 13.534 + } else { 13.535 + each(ids, function (id) { 13.536 + var mod = getOwn(registry, id); 13.537 + if (mod) { 13.538 + //Set error on module, so it skips timeout checks. 13.539 + mod.error = err; 13.540 + if (mod.events.error) { 13.541 + notified = true; 13.542 + mod.emit('error', err); 13.543 + } 13.544 + } 13.545 + }); 13.546 + 13.547 + if (!notified) { 13.548 + req.onError(err); 13.549 + } 13.550 + } 13.551 + } 13.552 + 13.553 + /** 13.554 + * Internal method to transfer globalQueue items to this context's 13.555 + * defQueue. 13.556 + */ 13.557 + function takeGlobalQueue() { 13.558 + //Push all the globalDefQueue items into the context's defQueue 13.559 + if (globalDefQueue.length) { 13.560 + //Array splice in the values since the context code has a 13.561 + //local var ref to defQueue, so cannot just reassign the one 13.562 + //on context. 13.563 + apsp.apply(defQueue, 13.564 + [defQueue.length, 0].concat(globalDefQueue)); 13.565 + globalDefQueue = []; 13.566 + } 13.567 + } 13.568 + 13.569 + handlers = { 13.570 + 'require': function (mod) { 13.571 + if (mod.require) { 13.572 + return mod.require; 13.573 + } else { 13.574 + return (mod.require = context.makeRequire(mod.map)); 13.575 + } 13.576 + }, 13.577 + 'exports': function (mod) { 13.578 + mod.usingExports = true; 13.579 + if (mod.map.isDefine) { 13.580 + if (mod.exports) { 13.581 + return (defined[mod.map.id] = mod.exports); 13.582 + } else { 13.583 + return (mod.exports = defined[mod.map.id] = {}); 13.584 + } 13.585 + } 13.586 + }, 13.587 + 'module': function (mod) { 13.588 + if (mod.module) { 13.589 + return mod.module; 13.590 + } else { 13.591 + return (mod.module = { 13.592 + id: mod.map.id, 13.593 + uri: mod.map.url, 13.594 + config: function () { 13.595 + return getOwn(config.config, mod.map.id) || {}; 13.596 + }, 13.597 + exports: mod.exports || (mod.exports = {}) 13.598 + }); 13.599 + } 13.600 + } 13.601 + }; 13.602 + 13.603 + function cleanRegistry(id) { 13.604 + //Clean up machinery used for waiting modules. 13.605 + delete registry[id]; 13.606 + delete enabledRegistry[id]; 13.607 + } 13.608 + 13.609 + function breakCycle(mod, traced, processed) { 13.610 + var id = mod.map.id; 13.611 + 13.612 + if (mod.error) { 13.613 + mod.emit('error', mod.error); 13.614 + } else { 13.615 + traced[id] = true; 13.616 + each(mod.depMaps, function (depMap, i) { 13.617 + var depId = depMap.id, 13.618 + dep = getOwn(registry, depId); 13.619 + 13.620 + //Only force things that have not completed 13.621 + //being defined, so still in the registry, 13.622 + //and only if it has not been matched up 13.623 + //in the module already. 13.624 + if (dep && !mod.depMatched[i] && !processed[depId]) { 13.625 + if (getOwn(traced, depId)) { 13.626 + mod.defineDep(i, defined[depId]); 13.627 + mod.check(); //pass false? 13.628 + } else { 13.629 + breakCycle(dep, traced, processed); 13.630 + } 13.631 + } 13.632 + }); 13.633 + processed[id] = true; 13.634 + } 13.635 + } 13.636 + 13.637 + function checkLoaded() { 13.638 + var err, usingPathFallback, 13.639 + waitInterval = config.waitSeconds * 1000, 13.640 + //It is possible to disable the wait interval by using waitSeconds of 0. 13.641 + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), 13.642 + noLoads = [], 13.643 + reqCalls = [], 13.644 + stillLoading = false, 13.645 + needCycleCheck = true; 13.646 + 13.647 + //Do not bother if this call was a result of a cycle break. 13.648 + if (inCheckLoaded) { 13.649 + return; 13.650 + } 13.651 + 13.652 + inCheckLoaded = true; 13.653 + 13.654 + //Figure out the state of all the modules. 13.655 + eachProp(enabledRegistry, function (mod) { 13.656 + var map = mod.map, 13.657 + modId = map.id; 13.658 + 13.659 + //Skip things that are not enabled or in error state. 13.660 + if (!mod.enabled) { 13.661 + return; 13.662 + } 13.663 + 13.664 + if (!map.isDefine) { 13.665 + reqCalls.push(mod); 13.666 + } 13.667 + 13.668 + if (!mod.error) { 13.669 + //If the module should be executed, and it has not 13.670 + //been inited and time is up, remember it. 13.671 + if (!mod.inited && expired) { 13.672 + if (hasPathFallback(modId)) { 13.673 + usingPathFallback = true; 13.674 + stillLoading = true; 13.675 + } else { 13.676 + noLoads.push(modId); 13.677 + removeScript(modId); 13.678 + } 13.679 + } else if (!mod.inited && mod.fetched && map.isDefine) { 13.680 + stillLoading = true; 13.681 + if (!map.prefix) { 13.682 + //No reason to keep looking for unfinished 13.683 + //loading. If the only stillLoading is a 13.684 + //plugin resource though, keep going, 13.685 + //because it may be that a plugin resource 13.686 + //is waiting on a non-plugin cycle. 13.687 + return (needCycleCheck = false); 13.688 + } 13.689 + } 13.690 + } 13.691 + }); 13.692 + 13.693 + if (expired && noLoads.length) { 13.694 + //If wait time expired, throw error of unloaded modules. 13.695 + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); 13.696 + err.contextName = context.contextName; 13.697 + return onError(err); 13.698 + } 13.699 + 13.700 + //Not expired, check for a cycle. 13.701 + if (needCycleCheck) { 13.702 + each(reqCalls, function (mod) { 13.703 + breakCycle(mod, {}, {}); 13.704 + }); 13.705 + } 13.706 + 13.707 + //If still waiting on loads, and the waiting load is something 13.708 + //other than a plugin resource, or there are still outstanding 13.709 + //scripts, then just try back later. 13.710 + if ((!expired || usingPathFallback) && stillLoading) { 13.711 + //Something is still waiting to load. Wait for it, but only 13.712 + //if a timeout is not already in effect. 13.713 + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { 13.714 + checkLoadedTimeoutId = setTimeout(function () { 13.715 + checkLoadedTimeoutId = 0; 13.716 + checkLoaded(); 13.717 + }, 50); 13.718 + } 13.719 + } 13.720 + 13.721 + inCheckLoaded = false; 13.722 + } 13.723 + 13.724 + Module = function (map) { 13.725 + this.events = getOwn(undefEvents, map.id) || {}; 13.726 + this.map = map; 13.727 + this.shim = getOwn(config.shim, map.id); 13.728 + this.depExports = []; 13.729 + this.depMaps = []; 13.730 + this.depMatched = []; 13.731 + this.pluginMaps = {}; 13.732 + this.depCount = 0; 13.733 + 13.734 + /* this.exports this.factory 13.735 + this.depMaps = [], 13.736 + this.enabled, this.fetched 13.737 + */ 13.738 + }; 13.739 + 13.740 + Module.prototype = { 13.741 + init: function (depMaps, factory, errback, options) { 13.742 + options = options || {}; 13.743 + 13.744 + //Do not do more inits if already done. Can happen if there 13.745 + //are multiple define calls for the same module. That is not 13.746 + //a normal, common case, but it is also not unexpected. 13.747 + if (this.inited) { 13.748 + return; 13.749 + } 13.750 + 13.751 + this.factory = factory; 13.752 + 13.753 + if (errback) { 13.754 + //Register for errors on this module. 13.755 + this.on('error', errback); 13.756 + } else if (this.events.error) { 13.757 + //If no errback already, but there are error listeners 13.758 + //on this module, set up an errback to pass to the deps. 13.759 + errback = bind(this, function (err) { 13.760 + this.emit('error', err); 13.761 + }); 13.762 + } 13.763 + 13.764 + //Do a copy of the dependency array, so that 13.765 + //source inputs are not modified. For example 13.766 + //"shim" deps are passed in here directly, and 13.767 + //doing a direct modification of the depMaps array 13.768 + //would affect that config. 13.769 + this.depMaps = depMaps && depMaps.slice(0); 13.770 + 13.771 + this.errback = errback; 13.772 + 13.773 + //Indicate this module has be initialized 13.774 + this.inited = true; 13.775 + 13.776 + this.ignore = options.ignore; 13.777 + 13.778 + //Could have option to init this module in enabled mode, 13.779 + //or could have been previously marked as enabled. However, 13.780 + //the dependencies are not known until init is called. So 13.781 + //if enabled previously, now trigger dependencies as enabled. 13.782 + if (options.enabled || this.enabled) { 13.783 + //Enable this module and dependencies. 13.784 + //Will call this.check() 13.785 + this.enable(); 13.786 + } else { 13.787 + this.check(); 13.788 + } 13.789 + }, 13.790 + 13.791 + defineDep: function (i, depExports) { 13.792 + //Because of cycles, defined callback for a given 13.793 + //export can be called more than once. 13.794 + if (!this.depMatched[i]) { 13.795 + this.depMatched[i] = true; 13.796 + this.depCount -= 1; 13.797 + this.depExports[i] = depExports; 13.798 + } 13.799 + }, 13.800 + 13.801 + fetch: function () { 13.802 + if (this.fetched) { 13.803 + return; 13.804 + } 13.805 + this.fetched = true; 13.806 + 13.807 + context.startTime = (new Date()).getTime(); 13.808 + 13.809 + var map = this.map; 13.810 + 13.811 + //If the manager is for a plugin managed resource, 13.812 + //ask the plugin to load it now. 13.813 + if (this.shim) { 13.814 + context.makeRequire(this.map, { 13.815 + enableBuildCallback: true 13.816 + })(this.shim.deps || [], bind(this, function () { 13.817 + return map.prefix ? this.callPlugin() : this.load(); 13.818 + })); 13.819 + } else { 13.820 + //Regular dependency. 13.821 + return map.prefix ? this.callPlugin() : this.load(); 13.822 + } 13.823 + }, 13.824 + 13.825 + load: function () { 13.826 + var url = this.map.url; 13.827 + 13.828 + //Regular dependency. 13.829 + if (!urlFetched[url]) { 13.830 + urlFetched[url] = true; 13.831 + context.load(this.map.id, url); 13.832 + } 13.833 + }, 13.834 + 13.835 + /** 13.836 + * Checks if the module is ready to define itself, and if so, 13.837 + * define it. 13.838 + */ 13.839 + check: function () { 13.840 + if (!this.enabled || this.enabling) { 13.841 + return; 13.842 + } 13.843 + 13.844 + var err, cjsModule, 13.845 + id = this.map.id, 13.846 + depExports = this.depExports, 13.847 + exports = this.exports, 13.848 + factory = this.factory; 13.849 + 13.850 + if (!this.inited) { 13.851 + this.fetch(); 13.852 + } else if (this.error) { 13.853 + this.emit('error', this.error); 13.854 + } else if (!this.defining) { 13.855 + //The factory could trigger another require call 13.856 + //that would result in checking this module to 13.857 + //define itself again. If already in the process 13.858 + //of doing that, skip this work. 13.859 + this.defining = true; 13.860 + 13.861 + if (this.depCount < 1 && !this.defined) { 13.862 + if (isFunction(factory)) { 13.863 + //If there is an error listener, favor passing 13.864 + //to that instead of throwing an error. However, 13.865 + //only do it for define()'d modules. require 13.866 + //errbacks should not be called for failures in 13.867 + //their callbacks (#699). However if a global 13.868 + //onError is set, use that. 13.869 + if ((this.events.error && this.map.isDefine) || 13.870 + req.onError !== defaultOnError) { 13.871 + try { 13.872 + exports = context.execCb(id, factory, depExports, exports); 13.873 + } catch (e) { 13.874 + err = e; 13.875 + } 13.876 + } else { 13.877 + exports = context.execCb(id, factory, depExports, exports); 13.878 + } 13.879 + 13.880 + // Favor return value over exports. If node/cjs in play, 13.881 + // then will not have a return value anyway. Favor 13.882 + // module.exports assignment over exports object. 13.883 + if (this.map.isDefine && exports === undefined) { 13.884 + cjsModule = this.module; 13.885 + if (cjsModule) { 13.886 + exports = cjsModule.exports; 13.887 + } else if (this.usingExports) { 13.888 + //exports already set the defined value. 13.889 + exports = this.exports; 13.890 + } 13.891 + } 13.892 + 13.893 + if (err) { 13.894 + err.requireMap = this.map; 13.895 + err.requireModules = this.map.isDefine ? [this.map.id] : null; 13.896 + err.requireType = this.map.isDefine ? 'define' : 'require'; 13.897 + return onError((this.error = err)); 13.898 + } 13.899 + 13.900 + } else { 13.901 + //Just a literal value 13.902 + exports = factory; 13.903 + } 13.904 + 13.905 + this.exports = exports; 13.906 + 13.907 + if (this.map.isDefine && !this.ignore) { 13.908 + defined[id] = exports; 13.909 + 13.910 + if (req.onResourceLoad) { 13.911 + req.onResourceLoad(context, this.map, this.depMaps); 13.912 + } 13.913 + } 13.914 + 13.915 + //Clean up 13.916 + cleanRegistry(id); 13.917 + 13.918 + this.defined = true; 13.919 + } 13.920 + 13.921 + //Finished the define stage. Allow calling check again 13.922 + //to allow define notifications below in the case of a 13.923 + //cycle. 13.924 + this.defining = false; 13.925 + 13.926 + if (this.defined && !this.defineEmitted) { 13.927 + this.defineEmitted = true; 13.928 + this.emit('defined', this.exports); 13.929 + this.defineEmitComplete = true; 13.930 + } 13.931 + 13.932 + } 13.933 + }, 13.934 + 13.935 + callPlugin: function () { 13.936 + var map = this.map, 13.937 + id = map.id, 13.938 + //Map already normalized the prefix. 13.939 + pluginMap = makeModuleMap(map.prefix); 13.940 + 13.941 + //Mark this as a dependency for this plugin, so it 13.942 + //can be traced for cycles. 13.943 + this.depMaps.push(pluginMap); 13.944 + 13.945 + on(pluginMap, 'defined', bind(this, function (plugin) { 13.946 + var load, normalizedMap, normalizedMod, 13.947 + bundleId = getOwn(bundlesMap, this.map.id), 13.948 + name = this.map.name, 13.949 + parentName = this.map.parentMap ? this.map.parentMap.name : null, 13.950 + localRequire = context.makeRequire(map.parentMap, { 13.951 + enableBuildCallback: true 13.952 + }); 13.953 + 13.954 + //If current map is not normalized, wait for that 13.955 + //normalized name to load instead of continuing. 13.956 + if (this.map.unnormalized) { 13.957 + //Normalize the ID if the plugin allows it. 13.958 + if (plugin.normalize) { 13.959 + name = plugin.normalize(name, function (name) { 13.960 + return normalize(name, parentName, true); 13.961 + }) || ''; 13.962 + } 13.963 + 13.964 + //prefix and name should already be normalized, no need 13.965 + //for applying map config again either. 13.966 + normalizedMap = makeModuleMap(map.prefix + '!' + name, 13.967 + this.map.parentMap); 13.968 + on(normalizedMap, 13.969 + 'defined', bind(this, function (value) { 13.970 + this.init([], function () { return value; }, null, { 13.971 + enabled: true, 13.972 + ignore: true 13.973 + }); 13.974 + })); 13.975 + 13.976 + normalizedMod = getOwn(registry, normalizedMap.id); 13.977 + if (normalizedMod) { 13.978 + //Mark this as a dependency for this plugin, so it 13.979 + //can be traced for cycles. 13.980 + this.depMaps.push(normalizedMap); 13.981 + 13.982 + if (this.events.error) { 13.983 + normalizedMod.on('error', bind(this, function (err) { 13.984 + this.emit('error', err); 13.985 + })); 13.986 + } 13.987 + normalizedMod.enable(); 13.988 + } 13.989 + 13.990 + return; 13.991 + } 13.992 + 13.993 + //If a paths config, then just load that file instead to 13.994 + //resolve the plugin, as it is built into that paths layer. 13.995 + if (bundleId) { 13.996 + this.map.url = context.nameToUrl(bundleId); 13.997 + this.load(); 13.998 + return; 13.999 + } 13.1000 + 13.1001 + load = bind(this, function (value) { 13.1002 + this.init([], function () { return value; }, null, { 13.1003 + enabled: true 13.1004 + }); 13.1005 + }); 13.1006 + 13.1007 + load.error = bind(this, function (err) { 13.1008 + this.inited = true; 13.1009 + this.error = err; 13.1010 + err.requireModules = [id]; 13.1011 + 13.1012 + //Remove temp unnormalized modules for this module, 13.1013 + //since they will never be resolved otherwise now. 13.1014 + eachProp(registry, function (mod) { 13.1015 + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { 13.1016 + cleanRegistry(mod.map.id); 13.1017 + } 13.1018 + }); 13.1019 + 13.1020 + onError(err); 13.1021 + }); 13.1022 + 13.1023 + //Allow plugins to load other code without having to know the 13.1024 + //context or how to 'complete' the load. 13.1025 + load.fromText = bind(this, function (text, textAlt) { 13.1026 + /*jslint evil: true */ 13.1027 + var moduleName = map.name, 13.1028 + moduleMap = makeModuleMap(moduleName), 13.1029 + hasInteractive = useInteractive; 13.1030 + 13.1031 + //As of 2.1.0, support just passing the text, to reinforce 13.1032 + //fromText only being called once per resource. Still 13.1033 + //support old style of passing moduleName but discard 13.1034 + //that moduleName in favor of the internal ref. 13.1035 + if (textAlt) { 13.1036 + text = textAlt; 13.1037 + } 13.1038 + 13.1039 + //Turn off interactive script matching for IE for any define 13.1040 + //calls in the text, then turn it back on at the end. 13.1041 + if (hasInteractive) { 13.1042 + useInteractive = false; 13.1043 + } 13.1044 + 13.1045 + //Prime the system by creating a module instance for 13.1046 + //it. 13.1047 + getModule(moduleMap); 13.1048 + 13.1049 + //Transfer any config to this other module. 13.1050 + if (hasProp(config.config, id)) { 13.1051 + config.config[moduleName] = config.config[id]; 13.1052 + } 13.1053 + 13.1054 + try { 13.1055 + req.exec(text); 13.1056 + } catch (e) { 13.1057 + return onError(makeError('fromtexteval', 13.1058 + 'fromText eval for ' + id + 13.1059 + ' failed: ' + e, 13.1060 + e, 13.1061 + [id])); 13.1062 + } 13.1063 + 13.1064 + if (hasInteractive) { 13.1065 + useInteractive = true; 13.1066 + } 13.1067 + 13.1068 + //Mark this as a dependency for the plugin 13.1069 + //resource 13.1070 + this.depMaps.push(moduleMap); 13.1071 + 13.1072 + //Support anonymous modules. 13.1073 + context.completeLoad(moduleName); 13.1074 + 13.1075 + //Bind the value of that module to the value for this 13.1076 + //resource ID. 13.1077 + localRequire([moduleName], load); 13.1078 + }); 13.1079 + 13.1080 + //Use parentName here since the plugin's name is not reliable, 13.1081 + //could be some weird string with no path that actually wants to 13.1082 + //reference the parentName's path. 13.1083 + plugin.load(map.name, localRequire, load, config); 13.1084 + })); 13.1085 + 13.1086 + context.enable(pluginMap, this); 13.1087 + this.pluginMaps[pluginMap.id] = pluginMap; 13.1088 + }, 13.1089 + 13.1090 + enable: function () { 13.1091 + enabledRegistry[this.map.id] = this; 13.1092 + this.enabled = true; 13.1093 + 13.1094 + //Set flag mentioning that the module is enabling, 13.1095 + //so that immediate calls to the defined callbacks 13.1096 + //for dependencies do not trigger inadvertent load 13.1097 + //with the depCount still being zero. 13.1098 + this.enabling = true; 13.1099 + 13.1100 + //Enable each dependency 13.1101 + each(this.depMaps, bind(this, function (depMap, i) { 13.1102 + var id, mod, handler; 13.1103 + 13.1104 + if (typeof depMap === 'string') { 13.1105 + //Dependency needs to be converted to a depMap 13.1106 + //and wired up to this module. 13.1107 + depMap = makeModuleMap(depMap, 13.1108 + (this.map.isDefine ? this.map : this.map.parentMap), 13.1109 + false, 13.1110 + !this.skipMap); 13.1111 + this.depMaps[i] = depMap; 13.1112 + 13.1113 + handler = getOwn(handlers, depMap.id); 13.1114 + 13.1115 + if (handler) { 13.1116 + this.depExports[i] = handler(this); 13.1117 + return; 13.1118 + } 13.1119 + 13.1120 + this.depCount += 1; 13.1121 + 13.1122 + on(depMap, 'defined', bind(this, function (depExports) { 13.1123 + this.defineDep(i, depExports); 13.1124 + this.check(); 13.1125 + })); 13.1126 + 13.1127 + if (this.errback) { 13.1128 + on(depMap, 'error', bind(this, this.errback)); 13.1129 + } 13.1130 + } 13.1131 + 13.1132 + id = depMap.id; 13.1133 + mod = registry[id]; 13.1134 + 13.1135 + //Skip special modules like 'require', 'exports', 'module' 13.1136 + //Also, don't call enable if it is already enabled, 13.1137 + //important in circular dependency cases. 13.1138 + if (!hasProp(handlers, id) && mod && !mod.enabled) { 13.1139 + context.enable(depMap, this); 13.1140 + } 13.1141 + })); 13.1142 + 13.1143 + //Enable each plugin that is used in 13.1144 + //a dependency 13.1145 + eachProp(this.pluginMaps, bind(this, function (pluginMap) { 13.1146 + var mod = getOwn(registry, pluginMap.id); 13.1147 + if (mod && !mod.enabled) { 13.1148 + context.enable(pluginMap, this); 13.1149 + } 13.1150 + })); 13.1151 + 13.1152 + this.enabling = false; 13.1153 + 13.1154 + this.check(); 13.1155 + }, 13.1156 + 13.1157 + on: function (name, cb) { 13.1158 + var cbs = this.events[name]; 13.1159 + if (!cbs) { 13.1160 + cbs = this.events[name] = []; 13.1161 + } 13.1162 + cbs.push(cb); 13.1163 + }, 13.1164 + 13.1165 + emit: function (name, evt) { 13.1166 + each(this.events[name], function (cb) { 13.1167 + cb(evt); 13.1168 + }); 13.1169 + if (name === 'error') { 13.1170 + //Now that the error handler was triggered, remove 13.1171 + //the listeners, since this broken Module instance 13.1172 + //can stay around for a while in the registry. 13.1173 + delete this.events[name]; 13.1174 + } 13.1175 + } 13.1176 + }; 13.1177 + 13.1178 + function callGetModule(args) { 13.1179 + //Skip modules already defined. 13.1180 + if (!hasProp(defined, args[0])) { 13.1181 + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); 13.1182 + } 13.1183 + } 13.1184 + 13.1185 + function removeListener(node, func, name, ieName) { 13.1186 + //Favor detachEvent because of IE9 13.1187 + //issue, see attachEvent/addEventListener comment elsewhere 13.1188 + //in this file. 13.1189 + if (node.detachEvent && !isOpera) { 13.1190 + //Probably IE. If not it will throw an error, which will be 13.1191 + //useful to know. 13.1192 + if (ieName) { 13.1193 + node.detachEvent(ieName, func); 13.1194 + } 13.1195 + } else { 13.1196 + node.removeEventListener(name, func, false); 13.1197 + } 13.1198 + } 13.1199 + 13.1200 + /** 13.1201 + * Given an event from a script node, get the requirejs info from it, 13.1202 + * and then removes the event listeners on the node. 13.1203 + * @param {Event} evt 13.1204 + * @returns {Object} 13.1205 + */ 13.1206 + function getScriptData(evt) { 13.1207 + //Using currentTarget instead of target for Firefox 2.0's sake. Not 13.1208 + //all old browsers will be supported, but this one was easy enough 13.1209 + //to support and still makes sense. 13.1210 + var node = evt.currentTarget || evt.srcElement; 13.1211 + 13.1212 + //Remove the listeners once here. 13.1213 + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); 13.1214 + removeListener(node, context.onScriptError, 'error'); 13.1215 + 13.1216 + return { 13.1217 + node: node, 13.1218 + id: node && node.getAttribute('data-requiremodule') 13.1219 + }; 13.1220 + } 13.1221 + 13.1222 + function intakeDefines() { 13.1223 + var args; 13.1224 + 13.1225 + //Any defined modules in the global queue, intake them now. 13.1226 + takeGlobalQueue(); 13.1227 + 13.1228 + //Make sure any remaining defQueue items get properly processed. 13.1229 + while (defQueue.length) { 13.1230 + args = defQueue.shift(); 13.1231 + if (args[0] === null) { 13.1232 + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); 13.1233 + } else { 13.1234 + //args are id, deps, factory. Should be normalized by the 13.1235 + //define() function. 13.1236 + callGetModule(args); 13.1237 + } 13.1238 + } 13.1239 + } 13.1240 + 13.1241 + context = { 13.1242 + config: config, 13.1243 + contextName: contextName, 13.1244 + registry: registry, 13.1245 + defined: defined, 13.1246 + urlFetched: urlFetched, 13.1247 + defQueue: defQueue, 13.1248 + Module: Module, 13.1249 + makeModuleMap: makeModuleMap, 13.1250 + nextTick: req.nextTick, 13.1251 + onError: onError, 13.1252 + 13.1253 + /** 13.1254 + * Set a configuration for the context. 13.1255 + * @param {Object} cfg config object to integrate. 13.1256 + */ 13.1257 + configure: function (cfg) { 13.1258 + //Make sure the baseUrl ends in a slash. 13.1259 + if (cfg.baseUrl) { 13.1260 + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { 13.1261 + cfg.baseUrl += '/'; 13.1262 + } 13.1263 + } 13.1264 + 13.1265 + //Save off the paths since they require special processing, 13.1266 + //they are additive. 13.1267 + var shim = config.shim, 13.1268 + objs = { 13.1269 + paths: true, 13.1270 + bundles: true, 13.1271 + config: true, 13.1272 + map: true 13.1273 + }; 13.1274 + 13.1275 + eachProp(cfg, function (value, prop) { 13.1276 + if (objs[prop]) { 13.1277 + if (!config[prop]) { 13.1278 + config[prop] = {}; 13.1279 + } 13.1280 + mixin(config[prop], value, true, true); 13.1281 + } else { 13.1282 + config[prop] = value; 13.1283 + } 13.1284 + }); 13.1285 + 13.1286 + //Reverse map the bundles 13.1287 + if (cfg.bundles) { 13.1288 + eachProp(cfg.bundles, function (value, prop) { 13.1289 + each(value, function (v) { 13.1290 + if (v !== prop) { 13.1291 + bundlesMap[v] = prop; 13.1292 + } 13.1293 + }); 13.1294 + }); 13.1295 + } 13.1296 + 13.1297 + //Merge shim 13.1298 + if (cfg.shim) { 13.1299 + eachProp(cfg.shim, function (value, id) { 13.1300 + //Normalize the structure 13.1301 + if (isArray(value)) { 13.1302 + value = { 13.1303 + deps: value 13.1304 + }; 13.1305 + } 13.1306 + if ((value.exports || value.init) && !value.exportsFn) { 13.1307 + value.exportsFn = context.makeShimExports(value); 13.1308 + } 13.1309 + shim[id] = value; 13.1310 + }); 13.1311 + config.shim = shim; 13.1312 + } 13.1313 + 13.1314 + //Adjust packages if necessary. 13.1315 + if (cfg.packages) { 13.1316 + each(cfg.packages, function (pkgObj) { 13.1317 + var location, name; 13.1318 + 13.1319 + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; 13.1320 + 13.1321 + name = pkgObj.name; 13.1322 + location = pkgObj.location; 13.1323 + if (location) { 13.1324 + config.paths[name] = pkgObj.location; 13.1325 + } 13.1326 + 13.1327 + //Save pointer to main module ID for pkg name. 13.1328 + //Remove leading dot in main, so main paths are normalized, 13.1329 + //and remove any trailing .js, since different package 13.1330 + //envs have different conventions: some use a module name, 13.1331 + //some use a file name. 13.1332 + config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') 13.1333 + .replace(currDirRegExp, '') 13.1334 + .replace(jsSuffixRegExp, ''); 13.1335 + }); 13.1336 + } 13.1337 + 13.1338 + //If there are any "waiting to execute" modules in the registry, 13.1339 + //update the maps for them, since their info, like URLs to load, 13.1340 + //may have changed. 13.1341 + eachProp(registry, function (mod, id) { 13.1342 + //If module already has init called, since it is too 13.1343 + //late to modify them, and ignore unnormalized ones 13.1344 + //since they are transient. 13.1345 + if (!mod.inited && !mod.map.unnormalized) { 13.1346 + mod.map = makeModuleMap(id); 13.1347 + } 13.1348 + }); 13.1349 + 13.1350 + //If a deps array or a config callback is specified, then call 13.1351 + //require with those args. This is useful when require is defined as a 13.1352 + //config object before require.js is loaded. 13.1353 + if (cfg.deps || cfg.callback) { 13.1354 + context.require(cfg.deps || [], cfg.callback); 13.1355 + } 13.1356 + }, 13.1357 + 13.1358 + makeShimExports: function (value) { 13.1359 + function fn() { 13.1360 + var ret; 13.1361 + if (value.init) { 13.1362 + ret = value.init.apply(global, arguments); 13.1363 + } 13.1364 + return ret || (value.exports && getGlobal(value.exports)); 13.1365 + } 13.1366 + return fn; 13.1367 + }, 13.1368 + 13.1369 + makeRequire: function (relMap, options) { 13.1370 + options = options || {}; 13.1371 + 13.1372 + function localRequire(deps, callback, errback) { 13.1373 + var id, map, requireMod; 13.1374 + 13.1375 + if (options.enableBuildCallback && callback && isFunction(callback)) { 13.1376 + callback.__requireJsBuild = true; 13.1377 + } 13.1378 + 13.1379 + if (typeof deps === 'string') { 13.1380 + if (isFunction(callback)) { 13.1381 + //Invalid call 13.1382 + return onError(makeError('requireargs', 'Invalid require call'), errback); 13.1383 + } 13.1384 + 13.1385 + //If require|exports|module are requested, get the 13.1386 + //value for them from the special handlers. Caveat: 13.1387 + //this only works while module is being defined. 13.1388 + if (relMap && hasProp(handlers, deps)) { 13.1389 + return handlers[deps](registry[relMap.id]); 13.1390 + } 13.1391 + 13.1392 + //Synchronous access to one module. If require.get is 13.1393 + //available (as in the Node adapter), prefer that. 13.1394 + if (req.get) { 13.1395 + return req.get(context, deps, relMap, localRequire); 13.1396 + } 13.1397 + 13.1398 + //Normalize module name, if it contains . or .. 13.1399 + map = makeModuleMap(deps, relMap, false, true); 13.1400 + id = map.id; 13.1401 + 13.1402 + if (!hasProp(defined, id)) { 13.1403 + return onError(makeError('notloaded', 'Module name "' + 13.1404 + id + 13.1405 + '" has not been loaded yet for context: ' + 13.1406 + contextName + 13.1407 + (relMap ? '' : '. Use require([])'))); 13.1408 + } 13.1409 + return defined[id]; 13.1410 + } 13.1411 + 13.1412 + //Grab defines waiting in the global queue. 13.1413 + intakeDefines(); 13.1414 + 13.1415 + //Mark all the dependencies as needing to be loaded. 13.1416 + context.nextTick(function () { 13.1417 + //Some defines could have been added since the 13.1418 + //require call, collect them. 13.1419 + intakeDefines(); 13.1420 + 13.1421 + requireMod = getModule(makeModuleMap(null, relMap)); 13.1422 + 13.1423 + //Store if map config should be applied to this require 13.1424 + //call for dependencies. 13.1425 + requireMod.skipMap = options.skipMap; 13.1426 + 13.1427 + requireMod.init(deps, callback, errback, { 13.1428 + enabled: true 13.1429 + }); 13.1430 + 13.1431 + checkLoaded(); 13.1432 + }); 13.1433 + 13.1434 + return localRequire; 13.1435 + } 13.1436 + 13.1437 + mixin(localRequire, { 13.1438 + isBrowser: isBrowser, 13.1439 + 13.1440 + /** 13.1441 + * Converts a module name + .extension into an URL path. 13.1442 + * *Requires* the use of a module name. It does not support using 13.1443 + * plain URLs like nameToUrl. 13.1444 + */ 13.1445 + toUrl: function (moduleNamePlusExt) { 13.1446 + var ext, 13.1447 + index = moduleNamePlusExt.lastIndexOf('.'), 13.1448 + segment = moduleNamePlusExt.split('/')[0], 13.1449 + isRelative = segment === '.' || segment === '..'; 13.1450 + 13.1451 + //Have a file extension alias, and it is not the 13.1452 + //dots from a relative path. 13.1453 + if (index !== -1 && (!isRelative || index > 1)) { 13.1454 + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); 13.1455 + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); 13.1456 + } 13.1457 + 13.1458 + return context.nameToUrl(normalize(moduleNamePlusExt, 13.1459 + relMap && relMap.id, true), ext, true); 13.1460 + }, 13.1461 + 13.1462 + defined: function (id) { 13.1463 + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); 13.1464 + }, 13.1465 + 13.1466 + specified: function (id) { 13.1467 + id = makeModuleMap(id, relMap, false, true).id; 13.1468 + return hasProp(defined, id) || hasProp(registry, id); 13.1469 + } 13.1470 + }); 13.1471 + 13.1472 + //Only allow undef on top level require calls 13.1473 + if (!relMap) { 13.1474 + localRequire.undef = function (id) { 13.1475 + //Bind any waiting define() calls to this context, 13.1476 + //fix for #408 13.1477 + takeGlobalQueue(); 13.1478 + 13.1479 + var map = makeModuleMap(id, relMap, true), 13.1480 + mod = getOwn(registry, id); 13.1481 + 13.1482 + removeScript(id); 13.1483 + 13.1484 + delete defined[id]; 13.1485 + delete urlFetched[map.url]; 13.1486 + delete undefEvents[id]; 13.1487 + 13.1488 + //Clean queued defines too. Go backwards 13.1489 + //in array so that the splices do not 13.1490 + //mess up the iteration. 13.1491 + eachReverse(defQueue, function(args, i) { 13.1492 + if(args[0] === id) { 13.1493 + defQueue.splice(i, 1); 13.1494 + } 13.1495 + }); 13.1496 + 13.1497 + if (mod) { 13.1498 + //Hold on to listeners in case the 13.1499 + //module will be attempted to be reloaded 13.1500 + //using a different config. 13.1501 + if (mod.events.defined) { 13.1502 + undefEvents[id] = mod.events; 13.1503 + } 13.1504 + 13.1505 + cleanRegistry(id); 13.1506 + } 13.1507 + }; 13.1508 + } 13.1509 + 13.1510 + return localRequire; 13.1511 + }, 13.1512 + 13.1513 + /** 13.1514 + * Called to enable a module if it is still in the registry 13.1515 + * awaiting enablement. A second arg, parent, the parent module, 13.1516 + * is passed in for context, when this method is overridden by 13.1517 + * the optimizer. Not shown here to keep code compact. 13.1518 + */ 13.1519 + enable: function (depMap) { 13.1520 + var mod = getOwn(registry, depMap.id); 13.1521 + if (mod) { 13.1522 + getModule(depMap).enable(); 13.1523 + } 13.1524 + }, 13.1525 + 13.1526 + /** 13.1527 + * Internal method used by environment adapters to complete a load event. 13.1528 + * A load event could be a script load or just a load pass from a synchronous 13.1529 + * load call. 13.1530 + * @param {String} moduleName the name of the module to potentially complete. 13.1531 + */ 13.1532 + completeLoad: function (moduleName) { 13.1533 + var found, args, mod, 13.1534 + shim = getOwn(config.shim, moduleName) || {}, 13.1535 + shExports = shim.exports; 13.1536 + 13.1537 + takeGlobalQueue(); 13.1538 + 13.1539 + while (defQueue.length) { 13.1540 + args = defQueue.shift(); 13.1541 + if (args[0] === null) { 13.1542 + args[0] = moduleName; 13.1543 + //If already found an anonymous module and bound it 13.1544 + //to this name, then this is some other anon module 13.1545 + //waiting for its completeLoad to fire. 13.1546 + if (found) { 13.1547 + break; 13.1548 + } 13.1549 + found = true; 13.1550 + } else if (args[0] === moduleName) { 13.1551 + //Found matching define call for this script! 13.1552 + found = true; 13.1553 + } 13.1554 + 13.1555 + callGetModule(args); 13.1556 + } 13.1557 + 13.1558 + //Do this after the cycle of callGetModule in case the result 13.1559 + //of those calls/init calls changes the registry. 13.1560 + mod = getOwn(registry, moduleName); 13.1561 + 13.1562 + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { 13.1563 + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { 13.1564 + if (hasPathFallback(moduleName)) { 13.1565 + return; 13.1566 + } else { 13.1567 + return onError(makeError('nodefine', 13.1568 + 'No define call for ' + moduleName, 13.1569 + null, 13.1570 + [moduleName])); 13.1571 + } 13.1572 + } else { 13.1573 + //A script that does not call define(), so just simulate 13.1574 + //the call for it. 13.1575 + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); 13.1576 + } 13.1577 + } 13.1578 + 13.1579 + checkLoaded(); 13.1580 + }, 13.1581 + 13.1582 + /** 13.1583 + * Converts a module name to a file path. Supports cases where 13.1584 + * moduleName may actually be just an URL. 13.1585 + * Note that it **does not** call normalize on the moduleName, 13.1586 + * it is assumed to have already been normalized. This is an 13.1587 + * internal API, not a public one. Use toUrl for the public API. 13.1588 + */ 13.1589 + nameToUrl: function (moduleName, ext, skipExt) { 13.1590 + var paths, syms, i, parentModule, url, 13.1591 + parentPath, bundleId, 13.1592 + pkgMain = getOwn(config.pkgs, moduleName); 13.1593 + 13.1594 + if (pkgMain) { 13.1595 + moduleName = pkgMain; 13.1596 + } 13.1597 + 13.1598 + bundleId = getOwn(bundlesMap, moduleName); 13.1599 + 13.1600 + if (bundleId) { 13.1601 + return context.nameToUrl(bundleId, ext, skipExt); 13.1602 + } 13.1603 + 13.1604 + //If a colon is in the URL, it indicates a protocol is used and it is just 13.1605 + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) 13.1606 + //or ends with .js, then assume the user meant to use an url and not a module id. 13.1607 + //The slash is important for protocol-less URLs as well as full paths. 13.1608 + if (req.jsExtRegExp.test(moduleName)) { 13.1609 + //Just a plain path, not module name lookup, so just return it. 13.1610 + //Add extension if it is included. This is a bit wonky, only non-.js things pass 13.1611 + //an extension, this method probably needs to be reworked. 13.1612 + url = moduleName + (ext || ''); 13.1613 + } else { 13.1614 + //A module that needs to be converted to a path. 13.1615 + paths = config.paths; 13.1616 + 13.1617 + syms = moduleName.split('/'); 13.1618 + //For each module name segment, see if there is a path 13.1619 + //registered for it. Start with most specific name 13.1620 + //and work up from it. 13.1621 + for (i = syms.length; i > 0; i -= 1) { 13.1622 + parentModule = syms.slice(0, i).join('/'); 13.1623 + 13.1624 + parentPath = getOwn(paths, parentModule); 13.1625 + if (parentPath) { 13.1626 + //If an array, it means there are a few choices, 13.1627 + //Choose the one that is desired 13.1628 + if (isArray(parentPath)) { 13.1629 + parentPath = parentPath[0]; 13.1630 + } 13.1631 + syms.splice(0, i, parentPath); 13.1632 + break; 13.1633 + } 13.1634 + } 13.1635 + 13.1636 + //Join the path parts together, then figure out if baseUrl is needed. 13.1637 + url = syms.join('/'); 13.1638 + url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); 13.1639 + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; 13.1640 + } 13.1641 + 13.1642 + return config.urlArgs ? url + 13.1643 + ((url.indexOf('?') === -1 ? '?' : '&') + 13.1644 + config.urlArgs) : url; 13.1645 + }, 13.1646 + 13.1647 + //Delegates to req.load. Broken out as a separate function to 13.1648 + //allow overriding in the optimizer. 13.1649 + load: function (id, url) { 13.1650 + req.load(context, id, url); 13.1651 + }, 13.1652 + 13.1653 + /** 13.1654 + * Executes a module callback function. Broken out as a separate function 13.1655 + * solely to allow the build system to sequence the files in the built 13.1656 + * layer in the right sequence. 13.1657 + * 13.1658 + * @private 13.1659 + */ 13.1660 + execCb: function (name, callback, args, exports) { 13.1661 + return callback.apply(exports, args); 13.1662 + }, 13.1663 + 13.1664 + /** 13.1665 + * callback for script loads, used to check status of loading. 13.1666 + * 13.1667 + * @param {Event} evt the event from the browser for the script 13.1668 + * that was loaded. 13.1669 + */ 13.1670 + onScriptLoad: function (evt) { 13.1671 + //Using currentTarget instead of target for Firefox 2.0's sake. Not 13.1672 + //all old browsers will be supported, but this one was easy enough 13.1673 + //to support and still makes sense. 13.1674 + if (evt.type === 'load' || 13.1675 + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { 13.1676 + //Reset interactive script so a script node is not held onto for 13.1677 + //to long. 13.1678 + interactiveScript = null; 13.1679 + 13.1680 + //Pull out the name of the module and the context. 13.1681 + var data = getScriptData(evt); 13.1682 + context.completeLoad(data.id); 13.1683 + } 13.1684 + }, 13.1685 + 13.1686 + /** 13.1687 + * Callback for script errors. 13.1688 + */ 13.1689 + onScriptError: function (evt) { 13.1690 + var data = getScriptData(evt); 13.1691 + if (!hasPathFallback(data.id)) { 13.1692 + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); 13.1693 + } 13.1694 + } 13.1695 + }; 13.1696 + 13.1697 + context.require = context.makeRequire(); 13.1698 + return context; 13.1699 + } 13.1700 + 13.1701 + /** 13.1702 + * Main entry point. 13.1703 + * 13.1704 + * If the only argument to require is a string, then the module that 13.1705 + * is represented by that string is fetched for the appropriate context. 13.1706 + * 13.1707 + * If the first argument is an array, then it will be treated as an array 13.1708 + * of dependency string names to fetch. An optional function callback can 13.1709 + * be specified to execute when all of those dependencies are available. 13.1710 + * 13.1711 + * Make a local req variable to help Caja compliance (it assumes things 13.1712 + * on a require that are not standardized), and to give a short 13.1713 + * name for minification/local scope use. 13.1714 + */ 13.1715 + req = requirejs = function (deps, callback, errback, optional) { 13.1716 + 13.1717 + //Find the right context, use default 13.1718 + var context, config, 13.1719 + contextName = defContextName; 13.1720 + 13.1721 + // Determine if have config object in the call. 13.1722 + if (!isArray(deps) && typeof deps !== 'string') { 13.1723 + // deps is a config object 13.1724 + config = deps; 13.1725 + if (isArray(callback)) { 13.1726 + // Adjust args if there are dependencies 13.1727 + deps = callback; 13.1728 + callback = errback; 13.1729 + errback = optional; 13.1730 + } else { 13.1731 + deps = []; 13.1732 + } 13.1733 + } 13.1734 + 13.1735 + if (config && config.context) { 13.1736 + contextName = config.context; 13.1737 + } 13.1738 + 13.1739 + context = getOwn(contexts, contextName); 13.1740 + if (!context) { 13.1741 + context = contexts[contextName] = req.s.newContext(contextName); 13.1742 + } 13.1743 + 13.1744 + if (config) { 13.1745 + context.configure(config); 13.1746 + } 13.1747 + 13.1748 + return context.require(deps, callback, errback); 13.1749 + }; 13.1750 + 13.1751 + /** 13.1752 + * Support require.config() to make it easier to cooperate with other 13.1753 + * AMD loaders on globally agreed names. 13.1754 + */ 13.1755 + req.config = function (config) { 13.1756 + return req(config); 13.1757 + }; 13.1758 + 13.1759 + /** 13.1760 + * Execute something after the current tick 13.1761 + * of the event loop. Override for other envs 13.1762 + * that have a better solution than setTimeout. 13.1763 + * @param {Function} fn function to execute later. 13.1764 + */ 13.1765 + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { 13.1766 + setTimeout(fn, 4); 13.1767 + } : function (fn) { fn(); }; 13.1768 + 13.1769 + /** 13.1770 + * Export require as a global, but only if it does not already exist. 13.1771 + */ 13.1772 + if (!require) { 13.1773 + require = req; 13.1774 + } 13.1775 + 13.1776 + req.version = version; 13.1777 + 13.1778 + //Used to filter out dependencies that are already paths. 13.1779 + req.jsExtRegExp = /^\/|:|\?|\.js$/; 13.1780 + req.isBrowser = isBrowser; 13.1781 + s = req.s = { 13.1782 + contexts: contexts, 13.1783 + newContext: newContext 13.1784 + }; 13.1785 + 13.1786 + //Create default context. 13.1787 + req({}); 13.1788 + 13.1789 + //Exports some context-sensitive methods on global require. 13.1790 + each([ 13.1791 + 'toUrl', 13.1792 + 'undef', 13.1793 + 'defined', 13.1794 + 'specified' 13.1795 + ], function (prop) { 13.1796 + //Reference from contexts instead of early binding to default context, 13.1797 + //so that during builds, the latest instance of the default context 13.1798 + //with its config gets used. 13.1799 + req[prop] = function () { 13.1800 + var ctx = contexts[defContextName]; 13.1801 + return ctx.require[prop].apply(ctx, arguments); 13.1802 + }; 13.1803 + }); 13.1804 + 13.1805 + if (isBrowser) { 13.1806 + head = s.head = document.getElementsByTagName('head')[0]; 13.1807 + //If BASE tag is in play, using appendChild is a problem for IE6. 13.1808 + //When that browser dies, this can be removed. Details in this jQuery bug: 13.1809 + //http://dev.jquery.com/ticket/2709 13.1810 + baseElement = document.getElementsByTagName('base')[0]; 13.1811 + if (baseElement) { 13.1812 + head = s.head = baseElement.parentNode; 13.1813 + } 13.1814 + } 13.1815 + 13.1816 + /** 13.1817 + * Any errors that require explicitly generates will be passed to this 13.1818 + * function. Intercept/override it if you want custom error handling. 13.1819 + * @param {Error} err the error object. 13.1820 + */ 13.1821 + req.onError = defaultOnError; 13.1822 + 13.1823 + /** 13.1824 + * Creates the node for the load command. Only used in browser envs. 13.1825 + */ 13.1826 + req.createNode = function (config, moduleName, url) { 13.1827 + var node = config.xhtml ? 13.1828 + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : 13.1829 + document.createElement('script'); 13.1830 + node.type = config.scriptType || 'text/javascript'; 13.1831 + node.charset = 'utf-8'; 13.1832 + node.async = true; 13.1833 + return node; 13.1834 + }; 13.1835 + 13.1836 + /** 13.1837 + * Does the request to load a module for the browser case. 13.1838 + * Make this a separate function to allow other environments 13.1839 + * to override it. 13.1840 + * 13.1841 + * @param {Object} context the require context to find state. 13.1842 + * @param {String} moduleName the name of the module. 13.1843 + * @param {Object} url the URL to the module. 13.1844 + */ 13.1845 + req.load = function (context, moduleName, url) { 13.1846 + var config = (context && context.config) || {}, 13.1847 + node; 13.1848 + if (isBrowser) { 13.1849 + //In the browser so use a script tag 13.1850 + node = req.createNode(config, moduleName, url); 13.1851 + 13.1852 + node.setAttribute('data-requirecontext', context.contextName); 13.1853 + node.setAttribute('data-requiremodule', moduleName); 13.1854 + 13.1855 + //Set up load listener. Test attachEvent first because IE9 has 13.1856 + //a subtle issue in its addEventListener and script onload firings 13.1857 + //that do not match the behavior of all other browsers with 13.1858 + //addEventListener support, which fire the onload event for a 13.1859 + //script right after the script execution. See: 13.1860 + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution 13.1861 + //UNFORTUNATELY Opera implements attachEvent but does not follow the script 13.1862 + //script execution mode. 13.1863 + if (node.attachEvent && 13.1864 + //Check if node.attachEvent is artificially added by custom script or 13.1865 + //natively supported by browser 13.1866 + //read https://github.com/jrburke/requirejs/issues/187 13.1867 + //if we can NOT find [native code] then it must NOT natively supported. 13.1868 + //in IE8, node.attachEvent does not have toString() 13.1869 + //Note the test for "[native code" with no closing brace, see: 13.1870 + //https://github.com/jrburke/requirejs/issues/273 13.1871 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && 13.1872 + !isOpera) { 13.1873 + //Probably IE. IE (at least 6-8) do not fire 13.1874 + //script onload right after executing the script, so 13.1875 + //we cannot tie the anonymous define call to a name. 13.1876 + //However, IE reports the script as being in 'interactive' 13.1877 + //readyState at the time of the define call. 13.1878 + useInteractive = true; 13.1879 + 13.1880 + node.attachEvent('onreadystatechange', context.onScriptLoad); 13.1881 + //It would be great to add an error handler here to catch 13.1882 + //404s in IE9+. However, onreadystatechange will fire before 13.1883 + //the error handler, so that does not help. If addEventListener 13.1884 + //is used, then IE will fire error before load, but we cannot 13.1885 + //use that pathway given the connect.microsoft.com issue 13.1886 + //mentioned above about not doing the 'script execute, 13.1887 + //then fire the script load event listener before execute 13.1888 + //next script' that other browsers do. 13.1889 + //Best hope: IE10 fixes the issues, 13.1890 + //and then destroys all installs of IE 6-9. 13.1891 + //node.attachEvent('onerror', context.onScriptError); 13.1892 + } else { 13.1893 + node.addEventListener('load', context.onScriptLoad, false); 13.1894 + node.addEventListener('error', context.onScriptError, false); 13.1895 + } 13.1896 + node.src = url; 13.1897 + 13.1898 + //For some cache cases in IE 6-8, the script executes before the end 13.1899 + //of the appendChild execution, so to tie an anonymous define 13.1900 + //call to the module name (which is stored on the node), hold on 13.1901 + //to a reference to this node, but clear after the DOM insertion. 13.1902 + currentlyAddingScript = node; 13.1903 + if (baseElement) { 13.1904 + head.insertBefore(node, baseElement); 13.1905 + } else { 13.1906 + head.appendChild(node); 13.1907 + } 13.1908 + currentlyAddingScript = null; 13.1909 + 13.1910 + return node; 13.1911 + } else if (isWebWorker) { 13.1912 + try { 13.1913 + //In a web worker, use importScripts. This is not a very 13.1914 + //efficient use of importScripts, importScripts will block until 13.1915 + //its script is downloaded and evaluated. However, if web workers 13.1916 + //are in play, the expectation that a build has been done so that 13.1917 + //only one script needs to be loaded anyway. This may need to be 13.1918 + //reevaluated if other use cases become common. 13.1919 + importScripts(url); 13.1920 + 13.1921 + //Account for anonymous modules 13.1922 + context.completeLoad(moduleName); 13.1923 + } catch (e) { 13.1924 + context.onError(makeError('importscripts', 13.1925 + 'importScripts failed for ' + 13.1926 + moduleName + ' at ' + url, 13.1927 + e, 13.1928 + [moduleName])); 13.1929 + } 13.1930 + } 13.1931 + }; 13.1932 + 13.1933 + function getInteractiveScript() { 13.1934 + if (interactiveScript && interactiveScript.readyState === 'interactive') { 13.1935 + return interactiveScript; 13.1936 + } 13.1937 + 13.1938 + eachReverse(scripts(), function (script) { 13.1939 + if (script.readyState === 'interactive') { 13.1940 + return (interactiveScript = script); 13.1941 + } 13.1942 + }); 13.1943 + return interactiveScript; 13.1944 + } 13.1945 + 13.1946 + //Look for a data-main script attribute, which could also adjust the baseUrl. 13.1947 + if (isBrowser && !cfg.skipDataMain) { 13.1948 + //Figure out baseUrl. Get it from the script tag with require.js in it. 13.1949 + eachReverse(scripts(), function (script) { 13.1950 + //Set the 'head' where we can append children by 13.1951 + //using the script's parent. 13.1952 + if (!head) { 13.1953 + head = script.parentNode; 13.1954 + } 13.1955 + 13.1956 + //Look for a data-main attribute to set main script for the page 13.1957 + //to load. If it is there, the path to data main becomes the 13.1958 + //baseUrl, if it is not already set. 13.1959 + dataMain = script.getAttribute('data-main'); 13.1960 + if (dataMain) { 13.1961 + //Preserve dataMain in case it is a path (i.e. contains '?') 13.1962 + mainScript = dataMain; 13.1963 + 13.1964 + //Set final baseUrl if there is not already an explicit one. 13.1965 + if (!cfg.baseUrl) { 13.1966 + //Pull off the directory of data-main for use as the 13.1967 + //baseUrl. 13.1968 + src = mainScript.split('/'); 13.1969 + mainScript = src.pop(); 13.1970 + subPath = src.length ? src.join('/') + '/' : './'; 13.1971 + 13.1972 + cfg.baseUrl = subPath; 13.1973 + } 13.1974 + 13.1975 + //Strip off any trailing .js since mainScript is now 13.1976 + //like a module name. 13.1977 + mainScript = mainScript.replace(jsSuffixRegExp, ''); 13.1978 + 13.1979 + //If mainScript is still a path, fall back to dataMain 13.1980 + if (req.jsExtRegExp.test(mainScript)) { 13.1981 + mainScript = dataMain; 13.1982 + } 13.1983 + 13.1984 + //Put the data-main script in the files to load. 13.1985 + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; 13.1986 + 13.1987 + return true; 13.1988 + } 13.1989 + }); 13.1990 + } 13.1991 + 13.1992 + /** 13.1993 + * The function that handles definitions of modules. Differs from 13.1994 + * require() in that a string for the module should be the first argument, 13.1995 + * and the function to execute after dependencies are loaded should 13.1996 + * return a value to define the module corresponding to the first argument's 13.1997 + * name. 13.1998 + */ 13.1999 + define = function (name, deps, callback) { 13.2000 + var node, context; 13.2001 + 13.2002 + //Allow for anonymous modules 13.2003 + if (typeof name !== 'string') { 13.2004 + //Adjust args appropriately 13.2005 + callback = deps; 13.2006 + deps = name; 13.2007 + name = null; 13.2008 + } 13.2009 + 13.2010 + //This module may not have dependencies 13.2011 + if (!isArray(deps)) { 13.2012 + callback = deps; 13.2013 + deps = null; 13.2014 + } 13.2015 + 13.2016 + //If no name, and callback is a function, then figure out if it a 13.2017 + //CommonJS thing with dependencies. 13.2018 + if (!deps && isFunction(callback)) { 13.2019 + deps = []; 13.2020 + //Remove comments from the callback string, 13.2021 + //look for require calls, and pull them into the dependencies, 13.2022 + //but only if there are function args. 13.2023 + if (callback.length) { 13.2024 + callback 13.2025 + .toString() 13.2026 + .replace(commentRegExp, '') 13.2027 + .replace(cjsRequireRegExp, function (match, dep) { 13.2028 + deps.push(dep); 13.2029 + }); 13.2030 + 13.2031 + //May be a CommonJS thing even without require calls, but still 13.2032 + //could use exports, and module. Avoid doing exports and module 13.2033 + //work though if it just needs require. 13.2034 + //REQUIRES the function to expect the CommonJS variables in the 13.2035 + //order listed below. 13.2036 + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); 13.2037 + } 13.2038 + } 13.2039 + 13.2040 + //If in IE 6-8 and hit an anonymous define() call, do the interactive 13.2041 + //work. 13.2042 + if (useInteractive) { 13.2043 + node = currentlyAddingScript || getInteractiveScript(); 13.2044 + if (node) { 13.2045 + if (!name) { 13.2046 + name = node.getAttribute('data-requiremodule'); 13.2047 + } 13.2048 + context = contexts[node.getAttribute('data-requirecontext')]; 13.2049 + } 13.2050 + } 13.2051 + 13.2052 + //Always save off evaluating the def call until the script onload handler. 13.2053 + //This allows multiple modules to be in a file without prematurely 13.2054 + //tracing dependencies, and allows for anonymous module support, 13.2055 + //where the module name is not known until the script onload event 13.2056 + //occurs. If no context, use the global queue, and get it processed 13.2057 + //in the onscript load callback. 13.2058 + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); 13.2059 + }; 13.2060 + 13.2061 + define.amd = { 13.2062 + jQuery: true 13.2063 + }; 13.2064 + 13.2065 + 13.2066 + /** 13.2067 + * Executes the text. Normally just uses eval, but can be modified 13.2068 + * to use a better, environment-specific call. Only used for transpiling 13.2069 + * loader plugins, not for plain JS modules. 13.2070 + * @param {String} text the text to execute/evaluate. 13.2071 + */ 13.2072 + req.exec = function (text) { 13.2073 + /*jslint evil: true */ 13.2074 + return eval(text); 13.2075 + }; 13.2076 + 13.2077 + //Set up with config info. 13.2078 + req(cfg); 13.2079 +}(this)); 13.2080 \ No newline at end of file
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation.js Sun Jul 06 12:02:12 2014 -0700 14.3 @@ -0,0 +1,167 @@ 14.4 + 14.5 + 14.6 +define(function(require, exports, module) { 14.7 + var Engine = require("famous/core/Engine"); 14.8 + var Surface = require("famous/core/Surface"); 14.9 + var Modifier = require("famous/core/Modifier"); 14.10 + var Transform = require('famous/core/Transform'); 14.11 + var StateModifier = require('famous/modifiers/StateModifier'); 14.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 14.13 + var Scrollview = require("famous/views/Scrollview"); 14.14 + 14.15 + var mainContext = Engine.createContext(); 14.16 + 14.17 + var boxSVG = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">'; 14.18 + var sigmaSVG = '<svg width="500" height="1052.3622" id="svg2"> <g id="g3759"> <path d="m 54,2 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" id="path2985" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 54,64 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" id="path3757" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> </g> </svg>'; 14.19 + 14.20 +//Draw the summation symbol, with two boxes below and = sign between, and 14.21 +// big box next to it, and small box above 14.22 +//Approach taken: 14.23 +//Make a container surface to hold the sigma and all the boxes 14.24 +//Make a separate surface for each SVG element -- one for sigma, one for 14.25 +// each box. 14.26 +//For each surface, make a modifier that positions the boxes 14.27 +// relative to the sigma and scales the boxes appropriately 14.28 +//Make all positions relative to the container surface's origin 14.29 + 14.30 + var summationContainer = new ContainerSurface({ 14.31 + size: [200, 200], 14.32 + properties: { 14.33 + overflow: 'hidden' 14.34 + } 14.35 + }); 14.36 + var sigmaSurf = new Surface({ 14.37 + size: [100, 100], 14.38 + content: sigmaSVG, 14.39 + properties: { 14.40 + } 14.41 + }); 14.42 + var box1 = new Surface({ 14.43 + size: [100, 100], 14.44 + content: boxSVG, 14.45 + properties: { 14.46 + } 14.47 + }); 14.48 + var box2 = new Surface({ 14.49 + size: [100, 100], 14.50 + content: boxSVG, 14.51 + properties: { 14.52 + } 14.53 + }); 14.54 + var box3 = new Surface({ 14.55 + size: [100, 100], 14.56 + content: boxSVG, 14.57 + properties: { 14.58 + } 14.59 + }); 14.60 + var box4 = new Surface({ 14.61 + size: [100, 100], 14.62 + content: boxSVG, 14.63 + properties: { 14.64 + } 14.65 + }); 14.66 + var equalSurf = new Surface({ 14.67 + size: [10, 10], 14.68 + content: "=", 14.69 + properties: { 14.70 + } 14.71 + }); 14.72 + 14.73 + var sigmaMod1 = new StateModifier({ 14.74 + transform: Transform.translate(0, 20, 0) 14.75 + }); 14.76 +//== 14.77 + var box1Mod1 = new StateModifier({ 14.78 + transform: Transform.translate(7, 90, 0) 14.79 + }); 14.80 + var box1Mod2 = new StateModifier({ 14.81 + transform: Transform.scale(.3, .3) 14.82 + }); 14.83 +//== 14.84 + var box2Mod1 = new StateModifier({ 14.85 + transform: Transform.translate(42, 90, 0) 14.86 + }); 14.87 + var box2Mod2 = new StateModifier({ 14.88 + transform: Transform.scale(.3, .3) 14.89 + }); 14.90 +//== 14.91 + var box3Mod1 = new StateModifier({ 14.92 + transform: Transform.translate(42, 2, 0) 14.93 + }); 14.94 + var box3Mod2 = new StateModifier({ 14.95 + transform: Transform.scale(.3, .3) 14.96 + }); 14.97 +//== 14.98 + var box4Mod1 = new StateModifier({ 14.99 + transform: Transform.translate(57, 20, 0) 14.100 + }); 14.101 + var box4Mod2 = new StateModifier({ 14.102 + transform: Transform.scale(1.22, 1.22) 14.103 + }); 14.104 +//== 14.105 + var equalMod = new StateModifier({ 14.106 + transform: Transform.translate(27, 85, 0) 14.107 + }); 14.108 + 14.109 + summationContainer.add(sigmaMod1).add(sigmaSurf); 14.110 + summationContainer.add(equalMod).add(equalSurf); 14.111 + summationContainer.add(box1Mod1).add(box1Mod2).add(box1); 14.112 + summationContainer.add(box2Mod1).add(box2Mod2).add(box2); 14.113 + summationContainer.add(box3Mod1).add(box3Mod2).add(box3); 14.114 + summationContainer.add(box4Mod1).add(box4Mod2).add(box4); 14.115 + mainContext.add(summationContainer); 14.116 + 14.117 +//================== 14.118 + var moveModifier1 = new StateModifier({ 14.119 + transform: Transform.translate(250, 100, 0) 14.120 + }); 14.121 + var moveModifier2 = new StateModifier({ 14.122 + transform: Transform.translate(350, 150, 0) 14.123 + }); 14.124 + var rotateModifier = new StateModifier({ 14.125 + transform: Transform.rotateZ(Math.PI/4) 14.126 + }); 14.127 + 14.128 +//the origin is the point inside the child, relative to the child's 14.129 +// internal axes, at which the child will be pinned inside its parent. 14.130 +//The align is the point inside the parent, relative to the parent's axes, 14.131 +// at which the origins of children will be pinned. 14.132 +//The origin is also the point about which rotations are performed 14.133 + var moveRelativeModifier = new StateModifier({ 14.134 + size: [20, 20], 14.135 + align: [0.5,0], 14.136 + origin: [0.5,0] 14.137 + }); 14.138 + var moveRelativeModifier2 = new StateModifier({ 14.139 + size: [20, 20], 14.140 + align: [0.5,0], 14.141 + origin: [0.5,0] 14.142 + }); 14.143 + 14.144 + var moveModifier2 = new StateModifier({ 14.145 + transform: Transform.translate(350, 150, 0) 14.146 + }); 14.147 + 14.148 + var scaleMod = new StateModifier({ 14.149 + transform: Transform.scale(0.5, 0.5, 1) 14.150 + }); 14.151 + 14.152 + 14.153 +//can make a tree inside the context -- so, can have a transform applied 14.154 +// to multiple children.. do so by making a var that holds the transform 14.155 +// node, then add to that variable multiple times. 14.156 +//Note, though that a given surface object will only render once! Have to 14.157 +// clone it if want multiple versions to be drawn. 14.158 +//Same goes for modifiers -- cannot put same modifier object at multiple 14.159 +// places within tree -- it will only render children of ONE of those places! 14.160 +// var node = mainContext.add(rotateModifier); 14.161 +// node.add(moveModifier2).add(moveRelativeModifier).add(mySurface); 14.162 +// node.add(moveModifier1).add(scaleMod).add(mySurface2); 14.163 +// mainContext.add(moveRelativeModifier2).add(sigmaSurf); 14.164 + 14.165 +//========================================== 14.166 +// scrollview.sequenceFrom(surfaces); 14.167 +// container.add(scrollview); 14.168 + 14.169 +// mainContext.add(new Modifier({origin: [.5, .5]})).add(container); 14.170 +});
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation_SVG_in_parts.js Sun Jul 06 12:02:12 2014 -0700 15.3 @@ -0,0 +1,138 @@ 15.4 + 15.5 + 15.6 +define(function(require, exports, module) { 15.7 + var Engine = require("famous/core/Engine"); 15.8 + var Surface = require("famous/core/Surface"); 15.9 + var Modifier = require("famous/core/Modifier"); 15.10 + var Transform = require('famous/core/Transform'); 15.11 + var StateModifier = require('famous/modifiers/StateModifier'); 15.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 15.13 + var Scrollview = require("famous/views/Scrollview"); 15.14 + 15.15 + var mainContext = Engine.createContext(); 15.16 + 15.17 + var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">'; 15.18 + var boxSVG = []; 15.19 + boxSVG[1] = '<svg width="'; 15.20 + boxSVG[2] = '" height="'; 15.21 + boxSVG[3] = '"><rect x="'; 15.22 + boxSVG[4] = '" y="'; 15.23 + boxSVG[5] = '" rx="' 15.24 + boxSVG[6] = '" ry="'; 15.25 + boxSVG[7] = '" width="' 15.26 + boxSVG[8] = '" height="' 15.27 + boxSVG[9] = '" style="fill:' 15.28 + boxSVG[10] = ';stroke:' 15.29 + boxSVG[11] = ';stroke-width:' 15.30 + boxSVG[12] = ';opacity:' 15.31 + boxSVG[13] = '">'; 15.32 + 15.33 + var boxSVGFromParts1 = boxSVG[1] + '19' + boxSVG[2] + '19' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '6.5' + boxSVG[6] + '6.5' + boxSVG[7] + '17' + boxSVG[8] + '17' + boxSVG[9] + 'none' + boxSVG[10] + 'black' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 15.34 + var boxSVGFromParts2 = boxSVG[1] + '75' + boxSVG[2] + '75' + boxSVG[3] + '2' + boxSVG[4] + '2' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '70' + boxSVG[8] + '70' + boxSVG[9] + 'none' + boxSVG[10] + 'black' + boxSVG[11] + '5' + boxSVG[12] + '1' + boxSVG[13]; 15.35 + 15.36 + 15.37 +//Draw a simple syntax graph, with a box of the correct color for each 15.38 +// node, and curvy links with arrows going from text inside one node to 15.39 +// text inside another node. 15.40 +//Approach taken: 15.41 +//Generate the SVG from calculations -- hold strings, and insert variable 15.42 +// values 15.43 +//Make each box a surface holding an SVG 15.44 +//Make a container surface to hold each node, together with its properties 15.45 +//Make a container surface to hold an element node together with its ports 15.46 +//Make a separate surface for each SVG element -- one for sigma, one for 15.47 +// each box. 15.48 +//For each surface, make a modifier that positions the boxes 15.49 +// relative to the sigma and scales the boxes appropriately 15.50 +//Make all positions relative to the container surface's origin 15.51 + 15.52 + var summationContainer = new ContainerSurface({ 15.53 + size: [200, 200], 15.54 + properties: { 15.55 + overflow: 'hidden' 15.56 + } 15.57 + }); 15.58 + var box1 = new Surface({ 15.59 + size: [100, 100], 15.60 + content: boxSVGFromParts1, 15.61 + properties: { 15.62 + } 15.63 + }); 15.64 + var box2 = new Surface({ 15.65 + size: [100, 100], 15.66 + content: boxSVGFromParts1, 15.67 + properties: { 15.68 + } 15.69 + }); 15.70 + var box3 = new Surface({ 15.71 + size: [100, 100], 15.72 + content: boxSVGFromParts1, 15.73 + properties: { 15.74 + } 15.75 + }); 15.76 + var box4 = new Surface({ 15.77 + size: [100, 100], 15.78 + content: boxSVGFromParts2, 15.79 + properties: { 15.80 + } 15.81 + }); 15.82 + var equalSurf = new Surface({ 15.83 + size: [10, 10], 15.84 + content: "=", 15.85 + properties: { 15.86 + } 15.87 + }); 15.88 + 15.89 + var sigmaMod1 = new StateModifier({ 15.90 + transform: Transform.translate(0, 20, 0) 15.91 + }); 15.92 +//== 15.93 + var box1Mod1 = new StateModifier({ 15.94 + transform: Transform.translate(7, 90, 0) 15.95 + }); 15.96 + var box1Mod2 = new StateModifier({ 15.97 + transform: Transform.scale(.3, .3) 15.98 + }); 15.99 +//== 15.100 + var box2Mod1 = new StateModifier({ 15.101 + transform: Transform.translate(42, 90, 0) 15.102 + }); 15.103 + var box2Mod2 = new StateModifier({ 15.104 + transform: Transform.scale(.3, .3) 15.105 + }); 15.106 +//== 15.107 + var box3Mod1 = new StateModifier({ 15.108 + transform: Transform.translate(42, 2, 0) 15.109 + }); 15.110 + var box3Mod2 = new StateModifier({ 15.111 + transform: Transform.scale(.3, .3) 15.112 + }); 15.113 +//== 15.114 + var box4Mod1 = new StateModifier({ 15.115 + transform: Transform.translate(57, 20, 0) 15.116 + }); 15.117 + var box4Mod2 = new StateModifier({ 15.118 + transform: Transform.scale(1.22, 1.22) 15.119 + }); 15.120 +//== 15.121 + var equalMod = new StateModifier({ 15.122 + transform: Transform.translate(27, 85, 0) 15.123 + }); 15.124 +//== 15.125 + var contMod1 = new StateModifier({ 15.126 + transform: Transform.translate(50, 50, 0) 15.127 + }); 15.128 + var contMod2 = new StateModifier({ 15.129 + transform: Transform.scale(.5, .5) 15.130 + }); 15.131 + 15.132 + 15.133 +// summationContainer.add(sigmaMod1).add(sigmaSurf); 15.134 + summationContainer.add(equalMod).add(equalSurf); 15.135 + summationContainer.add(box1Mod1).add(box1); 15.136 + summationContainer.add(box2Mod1).add(box2); 15.137 + summationContainer.add(box3Mod1).add(box3); 15.138 + summationContainer.add(box4Mod1).add(box4); 15.139 + mainContext.add(contMod1).add(contMod2).add(summationContainer); 15.140 + 15.141 +});
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_syntax_graph.js Sun Jul 06 12:02:12 2014 -0700 16.3 @@ -0,0 +1,354 @@ 16.4 + 16.5 + 16.6 +define(function(require, exports, module) { 16.7 + var Engine = require("famous/core/Engine"); 16.8 + var Surface = require("famous/core/Surface"); 16.9 + var Modifier = require("famous/core/Modifier"); 16.10 + var Transform = require('famous/core/Transform'); 16.11 + var StateModifier = require('famous/modifiers/StateModifier'); 16.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 16.13 + 16.14 + var mainContext = Engine.createContext(); 16.15 + 16.16 + var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">'; 16.17 + var boxSVG = []; 16.18 + boxSVG[1] = '<svg width="'; 16.19 + boxSVG[2] = '" height="'; 16.20 + boxSVG[3] = '"><rect x="'; 16.21 + boxSVG[4] = '" y="'; 16.22 + boxSVG[5] = '" rx="' 16.23 + boxSVG[6] = '" ry="'; 16.24 + boxSVG[7] = '" width="' 16.25 + boxSVG[8] = '" height="' 16.26 + boxSVG[9] = '" style="fill:' 16.27 + boxSVG[10] = ';stroke:' 16.28 + boxSVG[11] = ';stroke-width:' 16.29 + boxSVG[12] = ';opacity:' 16.30 + boxSVG[13] = '">'; 16.31 + 16.32 + 16.33 +//Draw a simple syntax graph, with a box of the correct color for each 16.34 +// node, and curvy links with arrows going from text inside one node to 16.35 +// text inside another node. 16.36 +//Approach taken: 16.37 +//Generate the SVG from calculations -- hold strings in an array, and 16.38 +// build up an SVG string by adding string piece, then variable value then 16.39 +// another string piece, and so on. 16.40 +//Make each box a surface holding an SVG 16.41 +//Sizing of the box happens inside the SVG string 16.42 +//Positioning the box happens via a modifier 16.43 + 16.44 +//Make one container surface to hold each element node together with its 16.45 +// properties and ports 16.46 +//Make a separate surface for each SVG element -- one for each box, one for 16.47 +// each text in a box, one for each curvy connector arrow between boxes or 16.48 +// between texts. 16.49 +//For each surface, make a modifier that positions the box relative to the 16.50 +// container surface's origin 16.51 +//At the end, make transforms to move the entire container around 16.52 + 16.53 + //elem1 is the root element from the Gabe Pattern syntax graph 16.54 + // here, make the visual elements that reproduce what see in the .pdf 16.55 + var elem1Container = new ContainerSurface({ 16.56 + size: [600, 600], //size it big for now, trim to contents later 16.57 + properties: { 16.58 + overflow: 'hidden' 16.59 + } 16.60 + }); 16.61 + 16.62 +//== 16.63 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 16.64 +// 11:stroke-width 12:opacity 16.65 + var box1_1width = 66; 16.66 + var box1_1height = 86 16.67 +// var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 16.68 + var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2; 16.69 + var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 16.70 + 16.71 +//== elem1 box 1 --> box1_1 16.72 + var box1_1 = new Surface({ 16.73 + size: [true, true], 16.74 + content: boxSVGFromParts1_1 16.75 + }); 16.76 + var box1_1x = 0; 16.77 + var box1_1y = 2; 16.78 + var boxMod1_1_1 = new StateModifier({ 16.79 + transform: Transform.translate(box1_1x, box1_1y, 0) 16.80 + }); 16.81 + 16.82 +//== elem1 box 1 text 1 --> text1_1_1 16.83 + var text1_1_1 = new Surface({ 16.84 + size: [true, 11], 16.85 + content: "properties", 16.86 + properties: { 16.87 + color: 'black', 16.88 + textAlign: 'left', 16.89 + fontSize: '11px', 16.90 + cursor: 'hand' 16.91 + } 16.92 + }); 16.93 + var text1_1_2 = new Surface({ 16.94 + size: [true, true], 16.95 + content: "portsIn", 16.96 + properties: { 16.97 + color: 'black', 16.98 + textAlign: 'left', 16.99 + fontSize: '11px', 16.100 + cursor: 'pointer' 16.101 + } 16.102 + }); 16.103 + var text1_1_3 = new Surface({ 16.104 + size: [true, true], 16.105 + content: "portsOut", 16.106 + properties: { 16.107 + color: 'black', 16.108 + textAlign: 'left', 16.109 + fontSize: '11px', 16.110 + cursor: 'pointer' 16.111 + } 16.112 + }); 16.113 + var text1_1_4 = new Surface({ 16.114 + size: [true, true], 16.115 + content: "subElems", 16.116 + properties: { 16.117 + color: 'black', 16.118 + textAlign: 'left', 16.119 + fontSize: '11px', 16.120 + cursor: 'pointer' 16.121 + } 16.122 + }); 16.123 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1 16.124 + var text1_1_1x = 8; 16.125 + var text1_1_1y = 8; 16.126 + var textMod1_1_1_1 = new StateModifier({ 16.127 + transform: Transform.translate(text1_1_1x, text1_1_1y, 0) 16.128 + }); 16.129 + var textMod1_1_2_1 = new StateModifier({ 16.130 + transform: Transform.translate(8, 25, 0) 16.131 + }); 16.132 + var textMod1_1_3_1 = new StateModifier({ 16.133 + transform: Transform.translate(8, 42, 0) 16.134 + }); 16.135 + var textMod1_1_4_1 = new StateModifier({ 16.136 + transform: Transform.translate(8, 59, 0) 16.137 + }); 16.138 +//== 16.139 + elem1Container.add(boxMod1_1_1).add(box1_1); 16.140 + elem1Container.add(textMod1_1_1_1).add(text1_1_1); 16.141 + elem1Container.add(textMod1_1_2_1).add(text1_1_2); 16.142 + elem1Container.add(textMod1_1_3_1).add(text1_1_3); 16.143 + elem1Container.add(textMod1_1_4_1).add(text1_1_4); 16.144 + 16.145 +//== elem 1 box 2 --> box1_2 16.146 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 16.147 +// 11:stroke-width 12:opacity 16.148 + var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2; 16.149 + var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 16.150 + var box1_2 = new Surface({ 16.151 + size: [true, true], 16.152 + content: boxSVGFromParts1_2 16.153 + }); 16.154 + var box1_2x = 100; 16.155 + var box1_2y = 2; 16.156 + var boxMod1_2_1 = new StateModifier({ 16.157 + transform: Transform.translate(box1_2x, box1_2y, 0) 16.158 + }); 16.159 +//== elem 1 box 2 text 1 --> text1_2_1 16.160 + var text1_2_1 = new Surface({ 16.161 + size: [true, true], 16.162 + content: "propertyName: TypeOfElement", 16.163 + properties: { 16.164 + color: 'black', 16.165 + textAlign: 'left', 16.166 + fontSize: '11px', 16.167 + cursor: 'pointer' 16.168 + } 16.169 + }); 16.170 + var text1_2_2 = new Surface({ 16.171 + size: [true, true], 16.172 + content: "propertyValue: GabeTransfromRule", 16.173 + properties: { 16.174 + color: 'black', 16.175 + textAlign: 'left', 16.176 + fontSize: '11px', 16.177 + cursor: 'pointer' 16.178 + } 16.179 + }); 16.180 + var text1_2_3 = new Surface({ 16.181 + size: [true, true], 16.182 + content: "subProperties", 16.183 + properties: { 16.184 + color: 'black', 16.185 + textAlign: 'left', 16.186 + fontSize: '11px', 16.187 + cursor: 'pointer' 16.188 + } 16.189 + }); 16.190 +//== 16.191 + var textMod1_2_1_1 = new StateModifier({ 16.192 + transform: Transform.translate(108, 8, 0) 16.193 + }); 16.194 + var textMod1_2_2_1 = new StateModifier({ 16.195 + transform: Transform.translate(108, 25, 0) 16.196 + }); 16.197 + var textMod1_2_3_1 = new StateModifier({ 16.198 + transform: Transform.translate(108, 42, 0) 16.199 + }); 16.200 +//== 16.201 + elem1Container.add(boxMod1_2_1).add(box1_2); 16.202 + elem1Container.add(textMod1_2_1_1).add(text1_2_1); 16.203 + elem1Container.add(textMod1_2_2_1).add(text1_2_2); 16.204 + elem1Container.add(textMod1_2_3_1).add(text1_2_3); 16.205 + 16.206 +//Now, add bezier curve, in SVG.. 16.207 +//One end point is the end of "properties" text surface inside the elem box 16.208 +//Other end point is the middle of side of properties box 16.209 + 16.210 + var bezierSVG1 = '<svg width="106" height="106"> <path d="M3,3 C0,100 100,0 100,100" style="fill:none;stroke:black;stroke-width:4;opacity:1">'; 16.211 + 16.212 + var bezSVG = []; 16.213 + bezSVG[1] = '<svg width="' 16.214 + bezSVG[2] = '" height="' 16.215 + bezSVG[3] = '"><path d="M' //start pt x 16.216 + bezSVG[4] = ',' //start pt y 16.217 + bezSVG[5] = ' C' //control pt 1 x 16.218 + bezSVG[6] = ',' //control pt 1 y 16.219 + bezSVG[7] = ' ' //control pt 2 x 16.220 + bezSVG[8] = ',' //control pt 2 y 16.221 + bezSVG[9] = ' ' //end pt x 16.222 + bezSVG[10] = ',' //end pt y 16.223 + bezSVG[11] = '" style="fill:' 16.224 + bezSVG[12] = ';stroke:' 16.225 + bezSVG[13] = ';stroke-width:' 16.226 + bezSVG[14] = ';opacity:' 16.227 + bezSVG[15] = '">'; 16.228 + 16.229 + //now calculate the end points of the curve -- they connect to the 16.230 + // right edge of the "properties" text in the left box, and to the 16.231 + // middle of the left side of the right box 16.232 + var bezPoints = [{},{}]; 16.233 + var fontSz = 11; 16.234 + bezPoints[0].x = box1_1x + box1_1w; 16.235 + bezPoints[0].y = text1_1_1y + fontSz/2 + 8; 16.236 + bezPoints[1].x = box1_2x; 16.237 + bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2; 16.238 + 16.239 + var controlPoints = []; 16.240 + controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y}; 16.241 + controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y}; 16.242 + 16.243 + 16.244 + // 1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x 16.245 + // 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity 16.246 + var bezSVG1 = ""; 16.247 + bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6); 16.248 + bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6); 16.249 + bezSVG1 += bezSVG[3] + bezPoints[0].x; 16.250 + bezSVG1 += bezSVG[4] + bezPoints[0].y; 16.251 + bezSVG1 += bezSVG[5] + controlPoints[0].x; 16.252 + bezSVG1 += bezSVG[6] + controlPoints[0].y; 16.253 + bezSVG1 += bezSVG[7] + controlPoints[1].x; 16.254 + bezSVG1 += bezSVG[8] + controlPoints[1].y; 16.255 + bezSVG1 += bezSVG[9] + bezPoints[1].x; 16.256 + bezSVG1 += bezSVG[10] + bezPoints[1].y; 16.257 + bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15]; 16.258 + 16.259 +var bezSVG2 = '<svg width="400" height="170"><path d="M66,13.5 C66,2.5 100,13.5 100,2.5" style="fill:none;stroke:black;stroke-width:2;opacity:1">'; 16.260 +var x1 = 59; var x2 = 100; var y1 = 22; var y2 = 40; 16.261 +var bezSVG3 = '<svg width="200" height="200"><path d="M59,21 C100,21 59,38 100,38" style="fill:none;stroke:black;stroke-width:2;opacity:1">'; 16.262 + var bez1_1 = new Surface({ 16.263 + size: [true, true], 16.264 + content: bezSVG1 16.265 + }); 16.266 + 16.267 + elem1Container.add(bez1_1); 16.268 + 16.269 +var el1 = document.createElement("span") 16.270 +var displayStr = bezSVG1.replace(/</g, "<");//make the html display as text 16.271 +el1.innerHTML = (displayStr + "<br>"); 16.272 +document.body.appendChild(el1); 16.273 +el1 = document.createElement("span") 16.274 +displayStr = bezSVG3.replace(/</g, "<");//make the html display as text 16.275 +el1.innerHTML = displayStr; 16.276 +document.body.appendChild(el1); 16.277 + 16.278 + 16.279 +//== elem 1 Modifer 1 --> contMod1_1 16.280 + var contMod1_1 = new StateModifier({ 16.281 + transform: Transform.translate(50, 50, 0) 16.282 + }); 16.283 + var contMod1_2 = new StateModifier({ 16.284 + transform: Transform.scale(1, 1) 16.285 + }); 16.286 +//== 16.287 + 16.288 + mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container); 16.289 + 16.290 + //elem2 is 16.291 + var elem2Container = new ContainerSurface({ 16.292 + size: [200, 200], 16.293 + properties: { 16.294 + overflow: 'hidden' 16.295 + } 16.296 + }); 16.297 + 16.298 + 16.299 + 16.300 +//== elem 2 box 1 --> box2_1 16.301 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 16.302 +// 11:stroke-width 12:opacity 16.303 + var boxSVGFromParts2_1 = boxSVG[1] + '68' + boxSVG[2] + '88' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '66' + boxSVG[8] + '86' + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 16.304 + var box2_1 = new Surface({ 16.305 + size: [100, 100], 16.306 + content: boxSVGFromParts2_1, 16.307 + }); 16.308 + var box2_3 = new Surface({ 16.309 + size: [100, 100], 16.310 + content: boxSVGFromParts2_1, 16.311 + properties: { 16.312 + } 16.313 + }); 16.314 + var box2_4 = new Surface({ 16.315 + size: [100, 100], 16.316 + content: boxSVGFromParts2_1, 16.317 + properties: { 16.318 + } 16.319 + }); 16.320 + 16.321 +//== 16.322 + var boxMod2_1_1 = new StateModifier({ 16.323 + transform: Transform.translate(7, 90, 0) 16.324 + }); 16.325 + var boxMod2_1_2 = new StateModifier({ 16.326 + transform: Transform.scale(.3, .3) 16.327 + }); 16.328 +//== 16.329 + var boxMod2_2_1 = new StateModifier({ 16.330 + transform: Transform.translate(42, 90, 0) 16.331 + }); 16.332 + var boxMod2_2_2 = new StateModifier({ 16.333 + transform: Transform.scale(.3, .3) 16.334 + }); 16.335 +//== 16.336 + var boxMod2_3_1 = new StateModifier({ 16.337 + transform: Transform.translate(42, 2, 0) 16.338 + }); 16.339 + var boxMod2_3_2 = new StateModifier({ 16.340 + transform: Transform.scale(.3, .3) 16.341 + }); 16.342 +//== 16.343 + var boxMod2_4_1 = new StateModifier({ 16.344 + transform: Transform.translate(57, 20, 0) 16.345 + }); 16.346 + var boxMod2_4_2 = new StateModifier({ 16.347 + transform: Transform.scale(1.22, 1.22) 16.348 + }); 16.349 +//== 16.350 + var equalMod = new StateModifier({ 16.351 + transform: Transform.translate(27, 85, 0) 16.352 + }); 16.353 + 16.354 + 16.355 +// summationContainer.add(sigmaMod1).add(sigmaSurf); 16.356 + 16.357 +});
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/startUpApp.js Sun Jul 06 12:02:12 2014 -0700 17.3 @@ -0,0 +1,15 @@ 17.4 +// For any third party dependencies, like jQuery, place them in the lib folder. 17.5 + 17.6 +// Configure loading modules from the lib directory, 17.7 +// except for 'app' ones, which are in a sibling 17.8 +// directory. 17.9 +requirejs.config({ 17.10 +// baseUrl: 'lib', 17.11 + paths: { 17.12 + app: './app' 17.13 + } 17.14 +}); 17.15 + 17.16 +// Start loading the main app file. Put all of 17.17 +// your application logic in there. 17.18 +requirejs(['app/renderPOPSyntaxGraph']); 17.19 \ No newline at end of file
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/POPDisplay.html Sun Jul 06 12:02:12 2014 -0700 18.3 @@ -0,0 +1,48 @@ 18.4 +<!DOCTYPE html> 18.5 +<html> 18.6 + <head> 18.7 + <!--This page is a Display for a POP system. Eventually, a user 18.8 + will simply open this page in their browser, and it will 18.9 + load whatever the last view was for that user. The user will 18.10 + then enter gestures and get responses in the form of new things 18.11 + drawn on the display. For example, they can open worksheets 18.12 + or view srcHolder contents, in either syntactic form or syntax 18.13 + graph form. And they can manipulate the environment, such as 18.14 + make tunnels to other systems, create persistent processors, 18.15 + expand the running processors made from a particular code 18.16 + base (IE, the POP equivalent of running a program) and so on. 18.17 + 18.18 + For now, this page starts up the entire POP system, but in the 18.19 + future it will simply connect to an existing, persistent one.--> 18.20 + <title>POP Display</title> 18.21 + 18.22 + <!-- load the POP system via the requirejs module system --> 18.23 + <script data-main="startUpApp" src="lib/require.js"></script> 18.24 + 18.25 + <!-- helper --> 18.26 + <script src="lib/jquery.min.js"></script> 18.27 + 18.28 + <!-- Declare mobile device compatibilites --> 18.29 + <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" /> 18.30 + <meta name="mobile-web-app-capable" content="yes" /> 18.31 + <meta name="apple-mobile-web-app-capable" content="yes" /> 18.32 + <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 18.33 + 18.34 + <!-- backwards compatibility for famous stuff --> 18.35 + <script type="text/javascript" src="lib/functionPrototypeBind.js"></script> 18.36 + <script type="text/javascript" src="lib/classList.js"></script> 18.37 + <script type="text/javascript" src="lib/requestAnimationFrame.js"></script> 18.38 + 18.39 + <!-- load the famous stuff --> 18.40 + <link rel="stylesheet" type="text/css" href="lib/famous.css" /> 18.41 + <script type="text/javascript" src="lib/famous.js"></script> 18.42 + 18.43 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. --> 18.44 + <link rel="stylesheet" type="text/css" href="lib/famous_styles.css" /> 18.45 + 18.46 + </head> 18.47 + 18.48 +<body> 18.49 + 18.50 +</body> 18.51 +</html>
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/GabePatternSrcHolder.js Sun Jul 06 12:02:12 2014 -0700 19.3 @@ -0,0 +1,15 @@ 19.4 + 19.5 + 19.6 +//Make a SrcHolder object 19.7 +define(function(require, exports, module) { 19.8 + 19.9 + var visualizer = require('./POPSyntaxGraphVisualizer'); 19.10 + var syntaxGraph = require('./buildGabePatternSyntaxGraph'); 19.11 + 19.12 + return{ 19.13 + visualizer: visualizer, 19.14 + syntaxGraph: syntaxGraph 19.15 + }; 19.16 +}); 19.17 + 19.18 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPApp.js Sun Jul 06 12:02:12 2014 -0700 20.3 @@ -0,0 +1,52 @@ 20.4 + 20.5 +//This is testing scaffolding.. 20.6 +//As of July 2, 2014: 20.7 +//instantiate a Display object 20.8 +//instantiate a srcHolder object 20.9 +//invoke the visualizer in the srcHolder object, passing it the Display object 20.10 +//this should cause the visualizer to generate a view hierarchy and 20.11 +// pass that to the Display, which then paints it 20.12 +define(function(require, exports, module) { 20.13 + 20.14 + //get the Display object, which contains a function for passing a view 20.15 + // hierarchy, which the Display then paints onto the screen 20.16 + var POPDisplay = require('./POPDisplay'); 20.17 + 20.18 + //test that have the require system working properly -- logs to console 20.19 + POPDisplay.acceptViewList("testing accept view list"); 20.20 + 20.21 + //invoke the module that paints a canned sub-piece of the gabe pattern 20.22 + // syntax graph.. just so have something to see! (for now.. remove later) 20.23 + require('./renderPOPSyntaxGraph'); 20.24 + 20.25 + //cause the source holder object to be made, which will in turn 20.26 + // cause a graph of syntax objects to be built inside of it 20.27 + // and also cause a visualizer object to be built inside of it 20.28 + var srcHolder = require('./GabePatternSrcHolder'); 20.29 + 20.30 + //connect the srcHolder to the Display 20.31 + //Not sure yet what final form this will take.. for now.. 20.32 + srcHolder.visualizer.connectToDisplay( POPDisplay ); 20.33 + 20.34 + //Trigger the visualizer to build a view hierarchy and pass that 20.35 + // to the Display object, which in turn triggers the Display to build 20.36 + // a famous render tree corresponding to the view hierarchy, which paints 20.37 + // the syntax graph representation into the browser 20.38 + //This isn't the correct final form of how the visualizer determines 20.39 + // the portions of the graph to generate a view hierarchy from, but 20.40 + // it works for now, while developing.. 20.41 + srcHolder.visualizer.setViewSubGraph( srcHolder.visualizer.syntaxGraph ); 20.42 + 20.43 + //Once the system is complete, the view will be initialized to whatever 20.44 + // the last view was before suspend. When first built, the srcHolder 20.45 + // will be empty, so the view will have a null viewSubGraph. 20.46 + //As the MVDM loop gathers gestures, it will build up the syntax graph, 20.47 + // and during the process update the viewSubGraph. 20.48 + //Each gesture that modifies a portion of the graph that is currently 20.49 + // within the view will cause a change in the viewSubGraph.. 20.50 + //Thinking perhaps just have markers inside the normal graph that delimit 20.51 + // the boundaries of the view sub-graph. Implies that the view can only 20.52 + // include connected portions of the graph.. may be overly restrictive.. 20.53 + // might have case where filter the kinds of things that are visible, 20.54 + // which will collect disconnected pieces from the main graph. 20.55 +});
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPDisplay.js Sun Jul 06 12:02:12 2014 -0700 21.3 @@ -0,0 +1,73 @@ 21.4 + 21.5 + 21.6 +//Make a Display object, and a number of functions that operate on it. 21.7 +// One of the functions accepts an array of visual element objects as 21.8 +// input, and turns those visual elements into a famous render tree. 21.9 +//The famous context, and the surfaces, and so on exist inside the Display 21.10 +// object. 21.11 + 21.12 +//This uses require.js to create a module. This module has the name of the 21.13 +// file (POPDisplay). Inside the define, a number of data structures and 21.14 +// functions are created, then returned at the end. The returned things are 21.15 +// what can be accessed by external functions that load this module, via 21.16 +// themselves using the require("POPDisplay") call 21.17 +define(function(require, exports, module) { 21.18 + //Create the famous infrastructure, which is used for rendering on screen 21.19 + var Engine = require("famous/core/Engine"); 21.20 + var Surface = require("famous/core/Surface"); 21.21 + var Modifier = require("famous/core/Modifier"); 21.22 + var Transform = require('famous/core/Transform'); 21.23 + var StateModifier = require('famous/modifiers/StateModifier'); 21.24 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 21.25 + 21.26 + //make the context, which controls rendering to the screen 21.27 + // once add something to this context, that add makes the thing visibly 21.28 + // have effect. 21.29 + //Note, these are available to the render function via the closure 21.30 + // mechanism 21.31 + var mainContext = Engine.createContext(); 21.32 + 21.33 + var handleGesture = function( event ) { 21.34 + //not sure this is the right form, but provide a handler for 21.35 + // gestures made by the programmer/user 21.36 + //This will make an object that pairs the gesture to the view 21.37 + // element that is represented by the surface(s) involved in 21.38 + // the gesture. 21.39 + //It will then send the object to the command generator, which 21.40 + // is part of the source holder 21.41 + console.log("handleGesture"); 21.42 + } 21.43 + function acceptViewList (viewList) { 21.44 + //access Display object and its values here, as a closure 21.45 + console.log("acceptViewList"); 21.46 + } 21.47 + 21.48 + function init() { 21.49 + console.log("init"); 21.50 + // var POPStuffToDraw = 21.51 + var mySurface = new Surface({ 21.52 + size: [100, 100], 21.53 + content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 21.54 + properties: { 21.55 + color: 'white', 21.56 + lineHeight: '200%', 21.57 + textAlign: 'center', 21.58 + fontSize: '36px', 21.59 + cursor: 'pointer' 21.60 + } 21.61 + }); 21.62 + var stateModifier = new StateModifier({ 21.63 + transform: Transform.translate(250, 100, 0) 21.64 + }); 21.65 + mainContext.add(stateModifier).add(mySurface); 21.66 + } 21.67 + 21.68 + 21.69 + return{ 21.70 + init: init, 21.71 + handleGesture: handleGesture, 21.72 + acceptViewList: acceptViewList 21.73 + }; 21.74 +}); 21.75 + 21.76 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPSyntaxGraphVisualizer.js Sun Jul 06 12:02:12 2014 -0700 22.3 @@ -0,0 +1,146 @@ 22.4 + 22.5 + 22.6 +//Make a Visualizer object, and a number of functions that operate on it. 22.7 +// One of the functions accepts 22.8 +define(function(require, exports, module) { 22.9 + //Create the famous infrastructure, which is used for rendering on screen 22.10 + 22.11 + var viewHierarchy = {}; 22.12 + 22.13 + var renderer = require('./renderPOPSyntaxGraph'); 22.14 + 22.15 + function init() { 22.16 + //access Visualizer values here, as a closure 22.17 + console.log("init visualizer"); 22.18 + } 22.19 + 22.20 + function connectToDisplay( POPDisplay ) { 22.21 + //access Visualizer values here, as a closure 22.22 + console.log("connectToDisplay"); 22.23 + } 22.24 + 22.25 + //Calling this function triggers a series of events: 22.26 + //1) it generates a view hierarchy that represents the syntax graph 22.27 + //2) it sends that view hierarchy to the Display 22.28 + //3) the Display creates an internal representation of the hierarchy 22.29 + //4) the Display paints that internal representation to some device 22.30 + function setViewSubGraph( syntaxSubGraph ) { 22.31 + //access Visualizer values here, as a closure 22.32 + console.log("setViewSubGraph"); 22.33 + //for first pass, just build the view hierarchy by hand 22.34 + 22.35 + //A view hierarchy consists of a bounding boxes arranged in a 22.36 + // a hierarchy. Inside each bounding box is either more bounding 22.37 + // boxes or a paintable thing. 22.38 + //For now, paintable things are either SVG or text 22.39 + //Text includes styles such as font, italics, size 22.40 + 22.41 + //In this test, just construct the hierarchy for the two boxes 22.42 + // that already did the by-hand SVG for, with the bezier connecting 22.43 + // them.. for now, just make the data structs and populate with 22.44 + // info gotten from the by-hand rendering 22.45 + //Later, will calculate all the box sizes and positions relative to 22.46 + // parents 22.47 + viewHierarchy.rootBox = { 22.48 + width: 500, 22.49 + height: 500, 22.50 + subBoxes: [] 22.51 + } //note, left out parent-relative position and shape! 22.52 + 22.53 + var children = viewHierarchy.rootBox.subBoxes; 22.54 + //first child is the syntactic element box 22.55 + svgBox = renderer.getElemBox(); 22.56 + children[0] = { 22.57 + width: 68, //match width and height of the SVG shapes inside 22.58 + height: 88, 22.59 + xOffset: 0, 22.60 + yOffset: 2, 22.61 + shape: svgBox, 22.62 + subBoxes: [] 22.63 + } 22.64 + //second child is the properties box attached to the first box 22.65 + svgBox = renderer.getPropertiesBox(); 22.66 + children[1] = { 22.67 + width: 185, //match width and height of the SVG shapes inside 22.68 + height: 71, 22.69 + xOffset: 100, 22.70 + yOffset: 2, 22.71 + shape: svgBox, 22.72 + subBoxes: [] 22.73 + } 22.74 + console.log("box2: " + children[1].shape); 22.75 + 22.76 + //now add the text to the elem box 22.77 + children = children[0].subBoxes; //set to subBoxes of elem box 22.78 + var text1_1_1 = renderer.getText1_1_1; 22.79 + children[0] = { 22.80 + width: text1_1_1.width, 22.81 + height: text1_1_1.height, 22.82 + xOffset: text1_1_1.x, 22.83 + yOffset: text1_1_1.y, 22.84 + shape: text1_1_1.svg 22.85 + } 22.86 + var text1_1_2 = renderer.getText1_1_2; 22.87 + children[1] = { 22.88 + width: text1_1_2.width, 22.89 + height: text1_1_2.height, 22.90 + xOffset: text1_1_2.x, 22.91 + yOffset: text1_1_2.y, 22.92 + shape: text1_1_2.svg 22.93 + } 22.94 + var text1_1_3 = renderer.getText1_1_3; 22.95 + children[2] = { 22.96 + width: text1_1_3.width, 22.97 + height: text1_1_3.height, 22.98 + xOffset: text1_1_3.x, 22.99 + yOffset: text1_1_3.y, 22.100 + shape: text1_1_3.svg 22.101 + } 22.102 + var text1_1_4 = renderer.getText1_1_4; 22.103 + children[3] = { 22.104 + width: text1_1_4.width, 22.105 + height: text1_1_4.height, 22.106 + xOffset: text1_1_4.x, 22.107 + yOffset: text1_1_4.y, 22.108 + shape: text1_1_4.svg 22.109 + } 22.110 + 22.111 + //now add the text to the properties box 22.112 + children = viewHierarchy.rootBox.subBoxes[1].subBoxes; 22.113 + var text1_2_1 = renderer.getText1_2_1; 22.114 + children[0] = { 22.115 + width: text1_2_1.width, 22.116 + height: text1_2_1.height, 22.117 + xOffset: text1_2_1.x, 22.118 + yOffset: text1_2_1.y, 22.119 + shape: text1_2_1.svg 22.120 + } 22.121 + var text1_2_2 = renderer.getText1_2_2; 22.122 + children[1] = { 22.123 + width: text1_2_2.width, 22.124 + height: text1_2_2.height, 22.125 + xOffset: text1_2_2.x, 22.126 + yOffset: text1_2_2.y, 22.127 + shape: text1_2_2.svg 22.128 + } 22.129 + var text1_2_3 = renderer.getText1_2_3; 22.130 + children[2] = { 22.131 + width: text1_2_3.width, 22.132 + height: text1_2_3.height, 22.133 + xOffset: text1_2_3.x, 22.134 + yOffset: text1_2_3.y, 22.135 + shape: text1_2_3.svg 22.136 + } 22.137 + 22.138 + //now add the bezier curve 22.139 + 22.140 + } 22.141 + 22.142 + return{ 22.143 + init: init, 22.144 + connectToDisplay: connectToDisplay, 22.145 + setViewSubGraph: setViewSubGraph 22.146 + }; 22.147 +}); 22.148 + 22.149 +
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/buildGabePatternSyntaxGraph.js Sun Jul 06 12:02:12 2014 -0700 23.3 @@ -0,0 +1,414 @@ 23.4 +//A syntax graph consists of two kinds of nodes: element, port, and property 23.5 +//An element node can have sub-elements, and a property node can have 23.6 +// sub-properties, but a port node may not have sub-ports! 23.7 + 23.8 +//This uses require.js to create a module. This module has the name of the 23.9 +// file (POPDisplay). Inside the define, a number of data structures and 23.10 +// functions are created, then returned at the end. The returned things are 23.11 +// what can be accessed by external functions that load this module, via 23.12 +// themselves using the require("POPDisplay") call 23.13 +define(function(require, exports, module) { 23.14 + 23.15 +//this is the top level handle to the syntax graph of the gabe transform rule 23.16 +var firstGabeTransformRule = {}; 23.17 + 23.18 +//make a variable that holds an empty element struct.. this var will used 23.19 +// to build up an element, and then reused to build up other elements 23.20 +var tempElem = 23.21 + { properties: [], 23.22 + portsIn: [], 23.23 + portsOut: [], 23.24 + subElems: [] 23.25 + }; 23.26 + 23.27 +//the root of the Gabe Transform to the temp elem, then build up a property 23.28 +// to place into the elem. 23.29 +firstGabeTransformRule.root = tempElem; 23.30 + 23.31 +//build the first property 23.32 +var tempProperty = 23.33 + { propertyName: "TypeOfElement", 23.34 + propertyValue: "GabeTransformRule", 23.35 + subProperties: [] 23.36 + } 23.37 + 23.38 +//attach it to the root elem 23.39 +firstGabeTransformRule.root.properties[0] = tempProperty; 23.40 + 23.41 +//build and attach the second property 23.42 +var tempProperty = 23.43 + { propertyName: "TypeOfSyntacticStructure", 23.44 + propertyValue: "syntacticHierarchy", 23.45 + subProperties: [] 23.46 + } 23.47 + 23.48 +firstGabeTransformRule.root.properties[1] = tempProperty; 23.49 + 23.50 +//now reuse tempElem to make the first sub-element of the root elem 23.51 +var tempElem = 23.52 + { properties: [], 23.53 + portsIn: [], 23.54 + portsOut: [], 23.55 + subElems: [] 23.56 + } 23.57 + 23.58 +firstGabeTransformRule.root.subElems[0] = tempElem; 23.59 + 23.60 +var tempProperty = 23.61 + { propertyName: "TypeOfElement", 23.62 + propertyValue: "GabeQueryPattern", 23.63 + subProperties: [] 23.64 + } 23.65 + 23.66 +tempElem.properties[0] = tempProperty; 23.67 + 23.68 +var tempProperty = 23.69 + { propertyName: "TypeOfSyntacticStructure", 23.70 + propertyValue: "syntacticHierarchy", 23.71 + subProperties: [] 23.72 + } 23.73 + 23.74 +tempElem.properties[1] = tempProperty; 23.75 + 23.76 + 23.77 +//Keep going, building up the graph that was drawn 23.78 +//make the second sub-element of the root elem, the replacement pattern 23.79 +var tempElem = 23.80 + { properties: [], 23.81 + portsIn: [], 23.82 + portsOut: [], 23.83 + subElems: [] 23.84 + } 23.85 + 23.86 +firstGabeTransformRule.root.subElems[1] = tempElem; 23.87 + 23.88 +var tempProperty = 23.89 + { propertyName: "TypeOfElement", 23.90 + propertyValue: "GabeReplacePattern", 23.91 + subProperties: [] 23.92 + } 23.93 + 23.94 +tempElem.properties[0] = tempProperty; 23.95 + 23.96 +var tempProperty = 23.97 + { propertyName: "TypeOfSyntacticStructure", 23.98 + propertyValue: "syntacticHierarchy", 23.99 + subProperties: [] 23.100 + } 23.101 + 23.102 +tempElem.properties[1] = tempProperty; 23.103 + 23.104 +//Now, go back and fill in the rest of the query pattern 23.105 +//First, add the sub-elements of the query pattern node 23.106 +var tempElem = 23.107 + { properties: [], 23.108 + portsIn: [], 23.109 + portsOut: [], 23.110 + subElems: [] 23.111 + }; 23.112 + 23.113 +firstGabeTransformRule.root.subElems[0].subElems[0] = tempElem; 23.114 + 23.115 +var tempProperty = 23.116 + { propertyName: "TypeOfElement", 23.117 + propertyValue: "Command", 23.118 + subProperties: [] 23.119 + }; 23.120 + 23.121 +tempElem.properties[0] = tempProperty; 23.122 + 23.123 +var tempProperty = 23.124 + { propertyName: "CommandID", 23.125 + propertyValue: "GabePattPush", 23.126 + subProperties: [] 23.127 + }; 23.128 + 23.129 +tempElem.properties[0].subProperties[0] = tempProperty; 23.130 + 23.131 + 23.132 +var tempProperty = 23.133 + { propertyName: "TypeOfSyntacticStructure", 23.134 + propertyValue: "syntacticPatternRoot", 23.135 + subProperties: [] 23.136 + }; 23.137 + 23.138 +tempElem.properties[1] = tempProperty; 23.139 + 23.140 +//now add the ports to this Command syntactic pattern 23.141 +var tempPort = 23.142 + { element: tempElem, 23.143 + properties: [], 23.144 + pairedPorts: [] 23.145 + }; 23.146 + 23.147 +tempElem.portsIn[0] = tempPort; 23.148 + 23.149 +//add properties to the port 23.150 +tempPort.properties[0] = 23.151 + { propertyName: "TypeOfPort", 23.152 + propertyValue: "dataComm", 23.153 + subProperties: 23.154 + [{ propertyName: "TypeOfCommData", 23.155 + propertyValue: "GabePattStack", 23.156 + subProperties: [] 23.157 + }] 23.158 + }; 23.159 + 23.160 +//check that syntax was done correctly.. 23.161 +fillText = tempPort.properties[0].subProperties[0].propertyName; 23.162 +console.log("propertyName: " + fillText); 23.163 + 23.164 + 23.165 +var tempPort = 23.166 + { element: tempElem, 23.167 + properties: [], 23.168 + pairedPorts: [] 23.169 + }; 23.170 + 23.171 +tempElem.portsIn[1] = tempPort; 23.172 + 23.173 +//add properties to the port 23.174 +tempPort.properties[0] = 23.175 + { propertyName: "TypeOfPort", 23.176 + propertyValue: "dataComm", 23.177 + subProperties: 23.178 + [{ propertyName: "TypeOfCommData", 23.179 + propertyValue: "float", 23.180 + subProperties: [] 23.181 + }] 23.182 + }; 23.183 + 23.184 + 23.185 +var tempPort = 23.186 + { element: tempElem, 23.187 + properties: [], 23.188 + pairedPorts: [] 23.189 + }; 23.190 + 23.191 +tempElem.portsOut[0] = tempPort; 23.192 + 23.193 +//add properties to the port 23.194 +tempPort.properties[0] = 23.195 + { propertyName: "TypeOfPort", 23.196 + propertyValue: "dataComm", 23.197 + subProperties: 23.198 + [{ propertyName: "TypeOfCommData", 23.199 + propertyValue: "GabePattStack", 23.200 + subProperties: [] 23.201 + }] 23.202 + }; 23.203 + 23.204 +//First command (push) done! Now make second command (head) 23.205 +var tempElem = 23.206 + { properties: [], 23.207 + portsIn: [], 23.208 + portsOut: [], 23.209 + subElems: [] 23.210 + }; 23.211 + 23.212 +firstGabeTransformRule.root.subElems[0].subElems[1] = tempElem; 23.213 + 23.214 +//getting tired of the temp this and temp that, just make object directly 23.215 +tempElem.properties[0] = 23.216 + { propertyName: "TypeOfElement", 23.217 + propertyValue: "Command", 23.218 + subProperties: 23.219 + [{ propertyName: "CommandID", 23.220 + propertyValue: "GabePattPop", 23.221 + subProperties: [] 23.222 + }] 23.223 + }; 23.224 + 23.225 +tempElem.properties[1] = 23.226 + { propertyName: "TypeOfSyntacticStructure", 23.227 + propertyValue: "syntacticPatternRoot", 23.228 + subProperties: [] 23.229 + }; 23.230 + 23.231 +//now add the ports to this Command syntactic pattern 23.232 +tempElem.portsIn[0] = 23.233 + { element: tempElem, 23.234 + properties: [], 23.235 + pairedPorts: [] 23.236 + }; 23.237 + 23.238 +//add properties to the port 23.239 +tempElem.portsIn[0].properties[0] = 23.240 + { propertyName: "TypeOfPort", 23.241 + propertyValue: "dataComm", 23.242 + subProperties: 23.243 + [{ propertyName: "TypeOfCommData", 23.244 + propertyValue: "GabePattStack", 23.245 + subProperties: [] 23.246 + }] 23.247 + }; 23.248 + 23.249 +//next port 23.250 +tempElem.portsOut[0] = 23.251 + { element: tempElem, 23.252 + properties: [], 23.253 + pairedPorts: [] 23.254 + }; 23.255 + 23.256 +//add properties to the port 23.257 +tempElem.portsOut[0].properties[0] = 23.258 + { propertyName: "TypeOfPort", 23.259 + propertyValue: "dataComm", 23.260 + subProperties: 23.261 + [{ propertyName: "TypeOfCommData", 23.262 + propertyValue: "GabePattStack", 23.263 + subProperties: [] 23.264 + }] 23.265 + }; 23.266 + 23.267 + 23.268 +//next port 23.269 +tempElem.portsOut[1] = 23.270 + { element: tempElem, 23.271 + properties: [], 23.272 + pairedPorts: [] 23.273 + }; 23.274 + 23.275 +//add properties to the port 23.276 +tempElem.portsOut[1].properties[0] = 23.277 + { propertyName: "TypeOfPort", 23.278 + propertyValue: "dataComm", 23.279 + subProperties: 23.280 + [{ propertyName: "TypeOfCommData", 23.281 + propertyValue: "float", 23.282 + subProperties: [] 23.283 + }] 23.284 + }; 23.285 + 23.286 +//now pair the ports to each other 23.287 +var pushElem = firstGabeTransformRule.root.subElems[0].subElems[0]; 23.288 +var popElem = firstGabeTransformRule.root.subElems[0].subElems[1]; 23.289 + 23.290 +pushElem.portsOut[0].pairedPorts[0] = 23.291 + popElem.portsIn[0]; 23.292 +popElem.portsIn[0].pairedPorts[0] = 23.293 + pushElem.portsOut[0]; 23.294 + 23.295 +//Done with the query pattern! 23.296 + 23.297 +//======================================== 23.298 +//Now do the replace pattern 23.299 +//======================================== 23.300 +var tempElem = 23.301 + { properties: [], 23.302 + portsIn: [], 23.303 + portsOut: [], 23.304 + subElems: [] 23.305 + }; 23.306 + 23.307 +firstGabeTransformRule.root.subElems[1].subElems[0] = tempElem; 23.308 + 23.309 +//This is the pass through command element 23.310 +tempElem.properties[0] = 23.311 + { propertyName: "TypeOfElement", 23.312 + propertyValue: "Command", 23.313 + subProperties: 23.314 + [{ propertyName: "CommandID", 23.315 + propertyValue: "GabePassThrough", 23.316 + subProperties: [] 23.317 + }] 23.318 + }; 23.319 + 23.320 +tempElem.properties[1] = 23.321 + { propertyName: "TypeOfSyntacticStructure", 23.322 + propertyValue: "syntacticPatternRoot", 23.323 + subProperties: [] 23.324 + }; 23.325 + 23.326 +//now add the ports to this Command syntactic pattern 23.327 +tempElem.portsIn[0] = 23.328 + { element: tempElem, 23.329 + properties: [], 23.330 + pairedPorts: [] 23.331 + }; 23.332 + 23.333 +//add properties to the port 23.334 +tempElem.portsIn[0].properties[0] = 23.335 + { propertyName: "TypeOfPort", 23.336 + propertyValue: "dataComm", 23.337 + subProperties: 23.338 + [{ propertyName: "TypeOfCommData", 23.339 + propertyValue: "GabePattStack", 23.340 + subProperties: [] 23.341 + }] 23.342 + }; 23.343 + 23.344 +//next port 23.345 +tempElem.portsIn[1] = 23.346 + { element: tempElem, 23.347 + properties: [], 23.348 + pairedPorts: [] 23.349 + }; 23.350 + 23.351 +//add properties to the port 23.352 +tempElem.portsIn[1].properties[0] = 23.353 + { propertyName: "TypeOfPort", 23.354 + propertyValue: "dataComm", 23.355 + subProperties: 23.356 + [{ propertyName: "TypeOfCommData", 23.357 + propertyValue: "float", 23.358 + subProperties: [] 23.359 + }] 23.360 + }; 23.361 + 23.362 + 23.363 +//next port 23.364 +tempElem.portsOut[0] = 23.365 + { element: tempElem, 23.366 + properties: [], 23.367 + pairedPorts: [] 23.368 + }; 23.369 + 23.370 +//add properties to the port 23.371 +tempElem.portsOut[0].properties[0] = 23.372 + { propertyName: "TypeOfPort", 23.373 + propertyValue: "dataComm", 23.374 + subProperties: 23.375 + [{ propertyName: "TypeOfCommData", 23.376 + propertyValue: "GabePattStack", 23.377 + subProperties: [] 23.378 + }] 23.379 + }; 23.380 + 23.381 + 23.382 +//next port 23.383 +tempElem.portsOut[1] = 23.384 + { element: tempElem, 23.385 + properties: [], 23.386 + pairedPorts: [] 23.387 + }; 23.388 + 23.389 +//add properties to the port 23.390 +tempElem.portsOut[1].properties[0] = 23.391 + { propertyName: "TypeOfPort", 23.392 + propertyValue: "dataComm", 23.393 + subProperties: 23.394 + [{ propertyName: "TypeOfCommData", 23.395 + propertyValue: "float", 23.396 + subProperties: [] 23.397 + }] 23.398 + }; 23.399 + 23.400 +//no paired ports in this one.. done done!! 23.401 + 23.402 +//print a few things, just to make sure the data structs are correctly 23.403 +// created and can be traversed. 23.404 +var passThroughCmd = firstGabeTransformRule.root.subElems[1].subElems[0]; 23.405 +fillText = passThroughCmd.portsOut[1].properties[0].subProperties[0].propertyValue; 23.406 +console.log("propertyValue: " + fillText); 23.407 + 23.408 +//when this module is "required", the require statement will return the 23.409 +// syntax graph data structure 23.410 +return firstGabeTransformRule; 23.411 +}); 23.412 + 23.413 + 23.414 + 23.415 + 23.416 + 23.417 +
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/renderPOPSyntaxGraph.js Sun Jul 06 12:02:12 2014 -0700 24.3 @@ -0,0 +1,422 @@ 24.4 + 24.5 + 24.6 +define(function(require, exports, module) { 24.7 + var Engine = require("famous/core/Engine"); 24.8 + var Surface = require("famous/core/Surface"); 24.9 + var Modifier = require("famous/core/Modifier"); 24.10 + var Transform = require('famous/core/Transform'); 24.11 + var StateModifier = require('famous/modifiers/StateModifier'); 24.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 24.13 + var EventHandler = require('famous/core/EventHandler'); 24.14 + 24.15 + var mainContext = Engine.createContext(); 24.16 + 24.17 + var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">'; 24.18 + var boxSVG = []; 24.19 + boxSVG[1] = '<svg width="'; 24.20 + boxSVG[2] = '" height="'; 24.21 + boxSVG[3] = '"><rect x="'; 24.22 + boxSVG[4] = '" y="'; 24.23 + boxSVG[5] = '" rx="' 24.24 + boxSVG[6] = '" ry="'; 24.25 + boxSVG[7] = '" width="' 24.26 + boxSVG[8] = '" height="' 24.27 + boxSVG[9] = '" style="fill:' 24.28 + boxSVG[10] = ';stroke:' 24.29 + boxSVG[11] = ';stroke-width:' 24.30 + boxSVG[12] = ';opacity:' 24.31 + boxSVG[13] = '" vector-effect="non-scaling-stroke">'; 24.32 + 24.33 + 24.34 +//Draw a simple syntax graph, with a box of the correct color for each 24.35 +// node, and curvy links with arrows going from text inside one node to 24.36 +// text inside another node. 24.37 +//Approach taken: 24.38 +//Generate the SVG from calculations -- hold strings in an array, and 24.39 +// build up an SVG string by adding string piece, then variable value then 24.40 +// another string piece, and so on. 24.41 +//Make each box a surface holding an SVG 24.42 +//Sizing of the box happens inside the SVG string 24.43 +//Positioning the box happens via a modifier 24.44 + 24.45 +//Make one container surface to hold each element node together with its 24.46 +// properties and ports 24.47 +//Make a separate surface for each SVG element -- one for each box, one for 24.48 +// each text in a box, one for each curvy connector arrow between boxes or 24.49 +// between texts. 24.50 +//For each surface, make a modifier that positions the box relative to the 24.51 +// container surface's origin 24.52 +//At the end, make transforms to move the entire container around 24.53 + 24.54 + //elem1 is the root element from the Gabe Pattern syntax graph 24.55 + // here, make the visual elements that reproduce what see in the .pdf 24.56 + var elem1Container = new ContainerSurface({ 24.57 + size: [600, 600], //size it big for now, trim to contents later 24.58 + properties: { 24.59 + overflow: 'hidden' 24.60 + } 24.61 + }); 24.62 + 24.63 +//== 24.64 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 24.65 +// 11:stroke-width 12:opacity 24.66 + var box1_1width = 66; 24.67 + var box1_1height = 86 24.68 +// var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 24.69 + var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2; 24.70 + var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 24.71 + function getElemBox(){ return boxSVGFromParts1_1 }; 24.72 + 24.73 +//== elem1 box 1 --> box1_1 24.74 + var box1_1 = new Surface({ 24.75 + size: [true, true], 24.76 + content: boxSVGFromParts1_1 24.77 + }); 24.78 + var box1_1x = 0; 24.79 + var box1_1y = 2; 24.80 + var boxMod1_1_1 = new StateModifier({ 24.81 + transform: Transform.translate(box1_1x, box1_1y, 0) 24.82 + }); 24.83 + 24.84 + //Below, calculate a bezier curve that is anchored at the end of such 24.85 + // text, so need the bounding box of a text element.. to do so, must 24.86 + // first render the text! That appears to be the only way to calculate 24.87 + // the bounding box.. there doesn't seem to be any other means to predict 24.88 + // it. 24.89 + //So, the famous infrastructure is a bit messed up when it comes to this 24.90 + // instead, will directly manipulate the DOM, by placing the text as 24.91 + // an SVG element with fill and stroke set to none so it is not 24.92 + // visible. Then use the DOM call to get the bounding box. 24.93 + //Unfortunately, there doesn't appear to be any clean way! 24.94 + 24.95 + //Do this part once, the creating a DOM element and adding it to document 24.96 + var el1 = document.createElement("div"); 24.97 + document.body.appendChild(el1); //only need to append once then reuse 24.98 + 24.99 +//== elem1 box 1 text 1 --> text1_1_1 24.100 + var text1_1_1 = new Surface({ 24.101 + size: [true, true], 24.102 + content: "properties", 24.103 + properties: { 24.104 + color: 'black', 24.105 + textAlign: 'left', 24.106 + fontSize: '11px', 24.107 + cursor: 'hand' 24.108 + } 24.109 + }); 24.110 + 24.111 + //now set the SVG text string -- from this point down can be repeated 24.112 + // for multiple strings without removing or re-adding the element, nor 24.113 + // fiddling with the DOM 24.114 + var text1_1_1_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_1.content + '</text> </svg>'; 24.115 + //note that id is inside the text element! Also the fill and stroke are 24.116 + // null so that nothing paints 24.117 + el1.innerHTML = text1_1_1_SVG; 24.118 + 24.119 + //get the element -- this seems to be what triggers the bounding box calc 24.120 + var gottenElem = document.getElementById("svgText"); //use ID of the text elem 24.121 + 24.122 + //get the box, take the values out of it, and display them 24.123 + var rect = gottenElem.getBoundingClientRect(); 24.124 + console.log("svgText width: " + rect.width + " right: " + rect.right); 24.125 + 24.126 + var retText1_1_1 = { 24.127 + width: rect.width, 24.128 + height: rect.height, 24.129 + shape: text1_1_1_SVG 24.130 + } 24.131 + 24.132 + var text1_1_2 = new Surface({ 24.133 + size: [true, true], 24.134 + content: "portsIn", 24.135 + properties: { 24.136 + color: 'black', 24.137 + textAlign: 'left', 24.138 + fontSize: '11px', 24.139 + cursor: 'pointer' 24.140 + } 24.141 + }); 24.142 + //repeat for the next text surface 24.143 + var text1_1_2_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_2.content + '</text> </svg>'; 24.144 + el1.innerHTML = text1_1_2_SVG; 24.145 + var gottenElem = document.getElementById("svgText"); 24.146 + var rect = gottenElem.getBoundingClientRect(); 24.147 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.148 + 24.149 + var retText1_1_2 = { 24.150 + width: rect.width, 24.151 + height: rect.height, 24.152 + shape: text1_1_2_SVG 24.153 + } 24.154 + 24.155 + var text1_1_3 = new Surface({ 24.156 + size: [true, true], 24.157 + content: "portsOut", 24.158 + properties: { 24.159 + color: 'black', 24.160 + textAlign: 'left', 24.161 + fontSize: '11px', 24.162 + cursor: 'pointer' 24.163 + } 24.164 + }); 24.165 + //repeat for the next text surface 24.166 + var text1_1_3_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_3.content + '</text> </svg>'; 24.167 + el1.innerHTML = text1_1_3_SVG; 24.168 + var gottenElem = document.getElementById("svgText"); 24.169 + var rect = gottenElem.getBoundingClientRect(); 24.170 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.171 + 24.172 + var retText1_1_3 = { 24.173 + width: rect.width, 24.174 + height: rect.height, 24.175 + shape: text1_1_3_SVG 24.176 + } 24.177 + 24.178 + var text1_1_4 = new Surface({ 24.179 + size: [true, true], 24.180 + content: "subElems", 24.181 + properties: { 24.182 + color: 'black', 24.183 + textAlign: 'left', 24.184 + fontSize: '11px', 24.185 + cursor: 'pointer' 24.186 + } 24.187 + }); 24.188 + //repeat for the next text surface 24.189 + var text1_1_4_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_4.content + '</text> </svg>'; 24.190 + el1.innerHTML = text1_1_4_SVG; 24.191 + var gottenElem = document.getElementById("svgText"); 24.192 + var rect = gottenElem.getBoundingClientRect(); 24.193 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.194 + 24.195 + var retText1_1_4 = { 24.196 + width: rect.width, 24.197 + height: rect.height, 24.198 + shape: text1_1_4_SVG 24.199 + } 24.200 + 24.201 + 24.202 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1 24.203 + var text1_1_1x = 8; 24.204 + var text1_1_1y = 8; 24.205 + var textMod1_1_1_1 = new StateModifier({ 24.206 + transform: Transform.translate(text1_1_1x, text1_1_1y, 0) 24.207 + }); 24.208 + text1_1_1_SVG.x = 8; text1_1_1_SVG.y = 0; //subtract box x & y 24.209 + var textMod1_1_2_1 = new StateModifier({ 24.210 + transform: Transform.translate(8, 25, 0) 24.211 + }); 24.212 + text1_1_2_SVG.x = 8; text1_1_2_SVG.y = 23; //subtract box x & y 24.213 + var textMod1_1_3_1 = new StateModifier({ 24.214 + transform: Transform.translate(8, 42, 0) 24.215 + }); 24.216 + text1_1_3_SVG.x = 8; text1_1_3_SVG.y = 40; //subtract box x & y 24.217 + var textMod1_1_4_1 = new StateModifier({ 24.218 + transform: Transform.translate(8, 59, 0) 24.219 + }); 24.220 + text1_1_4_SVG.x = 8; text1_1_4_SVG.y = 57; //subtract box x & y 24.221 +//== 24.222 + elem1Container.add(boxMod1_1_1).add(box1_1); 24.223 + elem1Container.add(textMod1_1_1_1).add(text1_1_1); 24.224 + elem1Container.add(textMod1_1_2_1).add(text1_1_2); 24.225 + elem1Container.add(textMod1_1_3_1).add(text1_1_3); 24.226 + elem1Container.add(textMod1_1_4_1).add(text1_1_4); 24.227 + 24.228 +//== elem 1 box 2 --> box1_2 24.229 +// 1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke 24.230 +// 11:stroke-width 12:opacity 24.231 + var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2; 24.232 + var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13]; 24.233 + 24.234 + function getPropertiesBox(){ return boxSVGFromParts1_2 }; 24.235 + 24.236 + var box1_2 = new Surface({ 24.237 + size: [true, true], 24.238 + content: boxSVGFromParts1_2 24.239 + }); 24.240 + var box1_2x = 100; 24.241 + var box1_2y = 2; 24.242 + var boxMod1_2_1 = new StateModifier({ 24.243 + transform: Transform.translate(box1_2x, box1_2y, 0) 24.244 + }); 24.245 +//== elem 1 box 2 text 1 --> text1_2_1 24.246 + var text1_2_1 = new Surface({ 24.247 + size: [true, true], 24.248 + content: "propertyName: TypeOfElement", 24.249 + properties: { 24.250 + color: 'black', 24.251 + textAlign: 'left', 24.252 + fontSize: '11px', 24.253 + cursor: 'pointer' 24.254 + } 24.255 + }); 24.256 + //repeat for the next text surface 24.257 + var text1_2_1_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:blue;stroke:none" id="svgText">' + text1_2_1.content + '</text> </svg>'; 24.258 + el1.innerHTML = text1_2_1_SVG; 24.259 + var gottenElem = document.getElementById("svgText"); 24.260 + var rect = gottenElem.getBoundingClientRect(); 24.261 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.262 + var retText1_2_1 = { 24.263 + width: rect.width, 24.264 + height: rect.height, 24.265 + shape: text1_2_1_SVG 24.266 + } 24.267 + 24.268 + 24.269 + var text1_2_2 = new Surface({ 24.270 + size: [true, true], 24.271 + content: "propertyValue: GabeTransformRule", 24.272 + properties: { 24.273 + color: 'black', 24.274 + textAlign: 'left', 24.275 + fontSize: '11px', 24.276 + cursor: 'pointer' 24.277 + } 24.278 + }); 24.279 + //repeat for the next text surface 24.280 + var text1_2_2_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:red;stroke:none" id="svgText">' + text1_2_2.content + '</text> </svg>'; 24.281 + el1.innerHTML = text1_2_2_SVG; 24.282 + var gottenElem = document.getElementById("svgText"); 24.283 + var rect = gottenElem.getBoundingClientRect(); 24.284 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.285 + var retText1_2_2 = { 24.286 + width: rect.width, 24.287 + height: rect.height, 24.288 + shape: text1_2_2_SVG 24.289 + } 24.290 + 24.291 + var text1_2_3 = new Surface({ 24.292 + size: [true, true], 24.293 + content: "subProperties", 24.294 + properties: { 24.295 + color: 'black', 24.296 + textAlign: 'left', 24.297 + fontSize: '11px', 24.298 + cursor: 'pointer' 24.299 + } 24.300 + }); 24.301 + //repeat for the next text surface 24.302 + var text1_2_3_SVG = '<svg id="svgTextHolder"> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_2_3.content + '</text> </svg>'; 24.303 + el1.innerHTML = text1_2_3_SVG; 24.304 + var gottenElem = document.getElementById("svgText"); 24.305 + var rect = gottenElem.getBoundingClientRect(); 24.306 + console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right); 24.307 + var retText1_2_3 = { 24.308 + width: rect.width, 24.309 + height: rect.height, 24.310 + shape: text1_2_3_SVG 24.311 + } 24.312 + 24.313 +//== 24.314 + var textMod1_2_1_1 = new StateModifier({ 24.315 + transform: Transform.translate(108, 8, 0) 24.316 + }); 24.317 + text1_2_1_SVG.x = 8; text1_2_1_SVG.y = 6; //subtract box x & y 24.318 + var textMod1_2_2_1 = new StateModifier({ 24.319 + transform: Transform.translate(108, 25, 0) 24.320 + }); 24.321 + text1_2_2_SVG.x = 8; text1_2_2_SVG.y = 23; //subtract box x & y 24.322 + var textMod1_2_3_1 = new StateModifier({ 24.323 + transform: Transform.translate(108, 42, 0) 24.324 + }); 24.325 + text1_2_3_SVG.x = 8; text1_2_3_SVG.y = 40; //subtract box x & y 24.326 +//== 24.327 + elem1Container.add(boxMod1_2_1).add(box1_2); 24.328 + elem1Container.add(textMod1_2_1_1).add(text1_2_1); 24.329 + elem1Container.add(textMod1_2_2_1).add(text1_2_2); 24.330 + elem1Container.add(textMod1_2_3_1).add(text1_2_3); 24.331 + 24.332 +//Now, add bezier curve, in SVG.. 24.333 +//One end point is the end of "properties" text surface inside the elem box 24.334 +//Other end point is the middle of side of properties box 24.335 + var bezSVG = []; 24.336 + bezSVG[1] = '<svg width="' 24.337 + bezSVG[2] = '" height="' 24.338 + bezSVG[3] = '"><path d="M' //start pt x 24.339 + bezSVG[4] = ',' //start pt y 24.340 + bezSVG[5] = ' C' //control pt 1 x 24.341 + bezSVG[6] = ',' //control pt 1 y 24.342 + bezSVG[7] = ' ' //control pt 2 x 24.343 + bezSVG[8] = ',' //control pt 2 y 24.344 + bezSVG[9] = ' ' //end pt x 24.345 + bezSVG[10] = ',' //end pt y 24.346 + bezSVG[11] = '" style="fill:' 24.347 + bezSVG[12] = ';stroke:' 24.348 + bezSVG[13] = ';stroke-width:' 24.349 + bezSVG[14] = ';opacity:' 24.350 + bezSVG[15] = '" vector-effect="non-scaling-stroke">'; 24.351 + 24.352 + //now calculate the end points of the curve -- they connect to the 24.353 + // right edge of the "properties" text in the left box, and to the 24.354 + // middle of the left side of the right box 24.355 + var bezPoints = [{},{}]; 24.356 + var fontSz = 11; 24.357 + bezPoints[0].x = box1_1x + box1_1w; 24.358 + bezPoints[0].y = text1_1_1y + fontSz/2 + 8; 24.359 + bezPoints[1].x = box1_2x; 24.360 + bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2; 24.361 + 24.362 + var controlPoints = []; 24.363 + controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y}; 24.364 + controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y}; 24.365 + 24.366 + 24.367 + // 1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x 24.368 + // 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity 24.369 + var bezSVG1 = ""; 24.370 + bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6); 24.371 + bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6); 24.372 + bezSVG1 += bezSVG[3] + bezPoints[0].x; 24.373 + bezSVG1 += bezSVG[4] + bezPoints[0].y; 24.374 + bezSVG1 += bezSVG[5] + controlPoints[0].x; 24.375 + bezSVG1 += bezSVG[6] + controlPoints[0].y; 24.376 + bezSVG1 += bezSVG[7] + controlPoints[1].x; 24.377 + bezSVG1 += bezSVG[8] + controlPoints[1].y; 24.378 + bezSVG1 += bezSVG[9] + bezPoints[1].x; 24.379 + bezSVG1 += bezSVG[10] + bezPoints[1].y; 24.380 + bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15]; 24.381 + 24.382 + var bez1_1 = new Surface({ 24.383 + size: [true, true], 24.384 + content: bezSVG1 24.385 + }); 24.386 + 24.387 + elem1Container.add(bez1_1); 24.388 + 24.389 +//for some reason, the way use el1 above makes the DOM stop rendering 24.390 +// So, in order to get these other elements to render, first remove 24.391 +// the element that have been using to calc bounding box sizes.. 24.392 +var elToRemove = document.getElementById("svgText"); 24.393 +elToRemove.parentNode.parentNode.removeChild(elToRemove.parentNode); 24.394 + 24.395 +//okay, now new DOM elements will render 24.396 +var el2 = document.createElement("span") 24.397 +var displayStr = bezSVG1.replace(/</g, "<");//make the html display as text 24.398 +el2.innerHTML = (displayStr + "<br>"); 24.399 +document.body.appendChild(el2); 24.400 +console.log("bez svg: " + bezSVG1); 24.401 + 24.402 +//== elem 1 Modifer 1 --> contMod1_1 24.403 + var contMod1_1 = new StateModifier({ 24.404 + transform: Transform.translate(50, 50, 0) 24.405 + }); 24.406 + var contMod1_2 = new StateModifier({ 24.407 + transform: Transform.scale(1, 1) 24.408 + }); 24.409 +//== 24.410 + 24.411 + //cause this all to be painted, by adding to the main context 24.412 + mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container); 24.413 + 24.414 + return { 24.415 + getElemBox: getElemBox, 24.416 + getText1_1_1: retText1_1_1, 24.417 + getText1_1_2: retText1_1_2, 24.418 + getText1_1_3: retText1_1_3, 24.419 + getText1_1_4: retText1_1_4, 24.420 + getPropertiesBox: getPropertiesBox, 24.421 + getText1_2_1: retText1_2_1, 24.422 + getText1_2_2: retText1_2_2, 24.423 + getText1_2_3: retText1_2_3 24.424 + } 24.425 +});
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/classList.js Sun Jul 06 12:02:12 2014 -0700 25.3 @@ -0,0 +1,138 @@ 25.4 + 25.5 +/* 25.6 + * classList.js: Cross-browser full element.classList implementation. 25.7 + * 2011-06-15 25.8 + * 25.9 + * By Eli Grey, http://eligrey.com 25.10 + * Public Domain. 25.11 + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 25.12 + */ 25.13 + 25.14 +/*global self, document, DOMException */ 25.15 + 25.16 +/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 25.17 + 25.18 +if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) { 25.19 + 25.20 +(function (view) { 25.21 + 25.22 +"use strict"; 25.23 + 25.24 +var 25.25 + classListProp = "classList" 25.26 + , protoProp = "prototype" 25.27 + , elemCtrProto = (view.HTMLElement || view.Element)[protoProp] 25.28 + , objCtr = Object 25.29 + , strTrim = String[protoProp].trim || function () { 25.30 + return this.replace(/^\s+|\s+$/g, ""); 25.31 + } 25.32 + , arrIndexOf = Array[protoProp].indexOf || function (item) { 25.33 + var 25.34 + i = 0 25.35 + , len = this.length 25.36 + ; 25.37 + for (; i < len; i++) { 25.38 + if (i in this && this[i] === item) { 25.39 + return i; 25.40 + } 25.41 + } 25.42 + return -1; 25.43 + } 25.44 + // Vendors: please allow content code to instantiate DOMExceptions 25.45 + , DOMEx = function (type, message) { 25.46 + this.name = type; 25.47 + this.code = DOMException[type]; 25.48 + this.message = message; 25.49 + } 25.50 + , checkTokenAndGetIndex = function (classList, token) { 25.51 + if (token === "") { 25.52 + throw new DOMEx( 25.53 + "SYNTAX_ERR" 25.54 + , "An invalid or illegal string was specified" 25.55 + ); 25.56 + } 25.57 + if (/\s/.test(token)) { 25.58 + throw new DOMEx( 25.59 + "INVALID_CHARACTER_ERR" 25.60 + , "String contains an invalid character" 25.61 + ); 25.62 + } 25.63 + return arrIndexOf.call(classList, token); 25.64 + } 25.65 + , ClassList = function (elem) { 25.66 + var 25.67 + trimmedClasses = strTrim.call(elem.className) 25.68 + , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] 25.69 + , i = 0 25.70 + , len = classes.length 25.71 + ; 25.72 + for (; i < len; i++) { 25.73 + this.push(classes[i]); 25.74 + } 25.75 + this._updateClassName = function () { 25.76 + elem.className = this.toString(); 25.77 + }; 25.78 + } 25.79 + , classListProto = ClassList[protoProp] = [] 25.80 + , classListGetter = function () { 25.81 + return new ClassList(this); 25.82 + } 25.83 +; 25.84 +// Most DOMException implementations don't allow calling DOMException's toString() 25.85 +// on non-DOMExceptions. Error's toString() is sufficient here. 25.86 +DOMEx[protoProp] = Error[protoProp]; 25.87 +classListProto.item = function (i) { 25.88 + return this[i] || null; 25.89 +}; 25.90 +classListProto.contains = function (token) { 25.91 + token += ""; 25.92 + return checkTokenAndGetIndex(this, token) !== -1; 25.93 +}; 25.94 +classListProto.add = function (token) { 25.95 + token += ""; 25.96 + if (checkTokenAndGetIndex(this, token) === -1) { 25.97 + this.push(token); 25.98 + this._updateClassName(); 25.99 + } 25.100 +}; 25.101 +classListProto.remove = function (token) { 25.102 + token += ""; 25.103 + var index = checkTokenAndGetIndex(this, token); 25.104 + if (index !== -1) { 25.105 + this.splice(index, 1); 25.106 + this._updateClassName(); 25.107 + } 25.108 +}; 25.109 +classListProto.toggle = function (token) { 25.110 + token += ""; 25.111 + if (checkTokenAndGetIndex(this, token) === -1) { 25.112 + this.add(token); 25.113 + } else { 25.114 + this.remove(token); 25.115 + } 25.116 +}; 25.117 +classListProto.toString = function () { 25.118 + return this.join(" "); 25.119 +}; 25.120 + 25.121 +if (objCtr.defineProperty) { 25.122 + var classListPropDesc = { 25.123 + get: classListGetter 25.124 + , enumerable: true 25.125 + , configurable: true 25.126 + }; 25.127 + try { 25.128 + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 25.129 + } catch (ex) { // IE 8 doesn't support enumerable:true 25.130 + if (ex.number === -0x7FF5EC54) { 25.131 + classListPropDesc.enumerable = false; 25.132 + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 25.133 + } 25.134 + } 25.135 +} else if (objCtr[protoProp].__defineGetter__) { 25.136 + elemCtrProto.__defineGetter__(classListProp, classListGetter); 25.137 +} 25.138 + 25.139 +}(self)); 25.140 + 25.141 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.css Sun Jul 06 12:02:12 2014 -0700 26.3 @@ -0,0 +1,77 @@ 26.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 26.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 26.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 26.7 + * 26.8 + * Owner: mark@famo.us 26.9 + * @license MPL 2.0 26.10 + * @copyright Famous Industries, Inc. 2014 26.11 + */ 26.12 + 26.13 + 26.14 +html { 26.15 + width: 100%; 26.16 + height: 100%; 26.17 + margin: 0px; 26.18 + padding: 0px; 26.19 + overflow: hidden; 26.20 + -webkit-transform-style: preserve-3d; 26.21 + transform-style: preserve-3d; 26.22 +} 26.23 + 26.24 +body { 26.25 + position: absolute; 26.26 + width: 100%; 26.27 + height: 100%; 26.28 + margin: 0px; 26.29 + padding: 0px; 26.30 + -webkit-transform-style: preserve-3d; 26.31 + transform-style: preserve-3d; 26.32 + -webkit-font-smoothing: antialiased; 26.33 + -webkit-tap-highlight-color: transparent; 26.34 + -webkit-perspective: 0; 26.35 + perspective: none; 26.36 + overflow: hidden; 26.37 +} 26.38 + 26.39 +.famous-container, .famous-group { 26.40 + position: absolute; 26.41 + top: 0px; 26.42 + left: 0px; 26.43 + bottom: 0px; 26.44 + right: 0px; 26.45 + overflow: visible; 26.46 + -webkit-transform-style: preserve-3d; 26.47 + transform-style: preserve-3d; 26.48 + -webkit-backface-visibility: visible; 26.49 + backface-visibility: visible; 26.50 + pointer-events: none; 26.51 +} 26.52 + 26.53 +.famous-group { 26.54 + width: 0px; 26.55 + height: 0px; 26.56 + margin: 0px; 26.57 + padding: 0px; 26.58 + -webkit-transform-style: preserve-3d; 26.59 + transform-style: preserve-3d; 26.60 +} 26.61 + 26.62 +.famous-surface { 26.63 + position: absolute; 26.64 + -webkit-transform-origin: center center; 26.65 + transform-origin: center center; 26.66 + -webkit-backface-visibility: hidden; 26.67 + backface-visibility: hidden; 26.68 + -webkit-transform-style: flat; 26.69 + transform-style: preserve-3d; /* performance */ 26.70 + -webkit-box-sizing: border-box; 26.71 + -moz-box-sizing: border-box; 26.72 + -webkit-tap-highlight-color: transparent; 26.73 + pointer-events: auto; 26.74 +} 26.75 + 26.76 +.famous-container-group { 26.77 + position: relative; 26.78 + width: 100%; 26.79 + height: 100%; 26.80 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.js Sun Jul 06 12:02:12 2014 -0700 27.3 @@ -0,0 +1,17609 @@ 27.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7 + * 27.8 + * Owner: mark@famo.us 27.9 + * @license MPL 2.0 27.10 + * @copyright Famous Industries, Inc. 2014 27.11 + */ 27.12 + 27.13 +define('famous/core/Entity',['require','exports','module'],function(require, exports, module) { 27.14 + /** 27.15 + * A singleton that maintains a global registry of Surfaces. 27.16 + * Private. 27.17 + * 27.18 + * @private 27.19 + * @static 27.20 + * @class Entity 27.21 + */ 27.22 + 27.23 + var entities = []; 27.24 + 27.25 + /** 27.26 + * Get entity from global index. 27.27 + * 27.28 + * @private 27.29 + * @method get 27.30 + * @param {Number} id entity reigstration id 27.31 + * @return {Surface} entity in the global index 27.32 + */ 27.33 + function get(id) { 27.34 + return entities[id]; 27.35 + } 27.36 + 27.37 + /** 27.38 + * Overwrite entity in the global index 27.39 + * 27.40 + * @private 27.41 + * @method set 27.42 + * @param {Number} id entity reigstration id 27.43 + * @return {Surface} entity to add to the global index 27.44 + */ 27.45 + function set(id, entity) { 27.46 + entities[id] = entity; 27.47 + } 27.48 + 27.49 + /** 27.50 + * Add entity to global index 27.51 + * 27.52 + * @private 27.53 + * @method register 27.54 + * @param {Surface} entity to add to global index 27.55 + * @return {Number} new id 27.56 + */ 27.57 + function register(entity) { 27.58 + var id = entities.length; 27.59 + set(id, entity); 27.60 + return id; 27.61 + } 27.62 + 27.63 + /** 27.64 + * Remove entity from global index 27.65 + * 27.66 + * @private 27.67 + * @method unregister 27.68 + * @param {Number} id entity reigstration id 27.69 + */ 27.70 + function unregister(id) { 27.71 + set(id, null); 27.72 + } 27.73 + 27.74 + module.exports = { 27.75 + register: register, 27.76 + unregister: unregister, 27.77 + get: get, 27.78 + set: set 27.79 + }; 27.80 +}); 27.81 + 27.82 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.83 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.84 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.85 + * 27.86 + * Owner: mark@famo.us 27.87 + * @license MPL 2.0 27.88 + * @copyright Famous Industries, Inc. 2014 27.89 + */ 27.90 + 27.91 +define('famous/core/Transform',['require','exports','module'],function(require, exports, module) { 27.92 + 27.93 + /** 27.94 + * A high-performance static matrix math library used to calculate 27.95 + * affine transforms on surfaces and other renderables. 27.96 + * Famo.us uses 4x4 matrices corresponding directly to 27.97 + * WebKit matrices (column-major order). 27.98 + * 27.99 + * The internal "type" of a Matrix is a 16-long float array in 27.100 + * row-major order, with: 27.101 + * elements [0],[1],[2],[4],[5],[6],[8],[9],[10] forming the 3x3 27.102 + * transformation matrix; 27.103 + * elements [12], [13], [14] corresponding to the t_x, t_y, t_z 27.104 + * translation; 27.105 + * elements [3], [7], [11] set to 0; 27.106 + * element [15] set to 1. 27.107 + * All methods are static. 27.108 + * 27.109 + * @static 27.110 + * 27.111 + * @class Transform 27.112 + */ 27.113 + var Transform = {}; 27.114 + 27.115 + // WARNING: these matrices correspond to WebKit matrices, which are 27.116 + // transposed from their math counterparts 27.117 + Transform.precision = 1e-6; 27.118 + Transform.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 27.119 + 27.120 + /** 27.121 + * Multiply two or more Transform matrix types to return a Transform matrix. 27.122 + * 27.123 + * @method multiply4x4 27.124 + * @static 27.125 + * @param {Transform} a left Transform 27.126 + * @param {Transform} b right Transform 27.127 + * @return {Transform} 27.128 + */ 27.129 + Transform.multiply4x4 = function multiply4x4(a, b) { 27.130 + return [ 27.131 + a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3], 27.132 + a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3], 27.133 + a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3], 27.134 + a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3], 27.135 + a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7], 27.136 + a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7], 27.137 + a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7], 27.138 + a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7], 27.139 + a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11], 27.140 + a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11], 27.141 + a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11], 27.142 + a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11], 27.143 + a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15], 27.144 + a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15], 27.145 + a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15], 27.146 + a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15] 27.147 + ]; 27.148 + }; 27.149 + 27.150 + /** 27.151 + * Fast-multiply two or more Transform matrix types to return a 27.152 + * Matrix, assuming bottom row on each is [0 0 0 1]. 27.153 + * 27.154 + * @method multiply 27.155 + * @static 27.156 + * @param {Transform} a left Transform 27.157 + * @param {Transform} b right Transform 27.158 + * @return {Transform} 27.159 + */ 27.160 + Transform.multiply = function multiply(a, b) { 27.161 + return [ 27.162 + a[0] * b[0] + a[4] * b[1] + a[8] * b[2], 27.163 + a[1] * b[0] + a[5] * b[1] + a[9] * b[2], 27.164 + a[2] * b[0] + a[6] * b[1] + a[10] * b[2], 27.165 + 0, 27.166 + a[0] * b[4] + a[4] * b[5] + a[8] * b[6], 27.167 + a[1] * b[4] + a[5] * b[5] + a[9] * b[6], 27.168 + a[2] * b[4] + a[6] * b[5] + a[10] * b[6], 27.169 + 0, 27.170 + a[0] * b[8] + a[4] * b[9] + a[8] * b[10], 27.171 + a[1] * b[8] + a[5] * b[9] + a[9] * b[10], 27.172 + a[2] * b[8] + a[6] * b[9] + a[10] * b[10], 27.173 + 0, 27.174 + a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12], 27.175 + a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13], 27.176 + a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14], 27.177 + 1 27.178 + ]; 27.179 + }; 27.180 + 27.181 + /** 27.182 + * Return a Transform translated by additional amounts in each 27.183 + * dimension. This is equivalent to the result of 27.184 + * 27.185 + * Transform.multiply(Matrix.translate(t[0], t[1], t[2]), m). 27.186 + * 27.187 + * @method thenMove 27.188 + * @static 27.189 + * @param {Transform} m a Transform 27.190 + * @param {Array.Number} t floats delta vector of length 2 or 3 27.191 + * @return {Transform} 27.192 + */ 27.193 + Transform.thenMove = function thenMove(m, t) { 27.194 + if (!t[2]) t[2] = 0; 27.195 + return [m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, m[12] + t[0], m[13] + t[1], m[14] + t[2], 1]; 27.196 + }; 27.197 + 27.198 + /** 27.199 + * Return a Transform atrix which represents the result of a transform matrix 27.200 + * applied after a move. This is faster than the equivalent multiply. 27.201 + * This is equivalent to the result of: 27.202 + * 27.203 + * Transform.multiply(m, Transform.translate(t[0], t[1], t[2])). 27.204 + * 27.205 + * @method moveThen 27.206 + * @static 27.207 + * @param {Array.Number} v vector representing initial movement 27.208 + * @param {Transform} m matrix to apply afterwards 27.209 + * @return {Transform} the resulting matrix 27.210 + */ 27.211 + Transform.moveThen = function moveThen(v, m) { 27.212 + if (!v[2]) v[2] = 0; 27.213 + var t0 = v[0] * m[0] + v[1] * m[4] + v[2] * m[8]; 27.214 + var t1 = v[0] * m[1] + v[1] * m[5] + v[2] * m[9]; 27.215 + var t2 = v[0] * m[2] + v[1] * m[6] + v[2] * m[10]; 27.216 + return Transform.thenMove(m, [t0, t1, t2]); 27.217 + }; 27.218 + 27.219 + /** 27.220 + * Return a Transform which represents a translation by specified 27.221 + * amounts in each dimension. 27.222 + * 27.223 + * @method translate 27.224 + * @static 27.225 + * @param {Number} x x translation 27.226 + * @param {Number} y y translation 27.227 + * @param {Number} z z translation 27.228 + * @return {Transform} 27.229 + */ 27.230 + Transform.translate = function translate(x, y, z) { 27.231 + if (z === undefined) z = 0; 27.232 + return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]; 27.233 + }; 27.234 + 27.235 + /** 27.236 + * Return a Transform scaled by a vector in each 27.237 + * dimension. This is a more performant equivalent to the result of 27.238 + * 27.239 + * Transform.multiply(Transform.scale(s[0], s[1], s[2]), m). 27.240 + * 27.241 + * @method thenScale 27.242 + * @static 27.243 + * @param {Transform} m a matrix 27.244 + * @param {Array.Number} s delta vector (array of floats && 27.245 + * array.length == 3) 27.246 + * @return {Transform} 27.247 + */ 27.248 + Transform.thenScale = function thenScale(m, s) { 27.249 + return [ 27.250 + s[0] * m[0], s[1] * m[1], s[2] * m[2], 0, 27.251 + s[0] * m[4], s[1] * m[5], s[2] * m[6], 0, 27.252 + s[0] * m[8], s[1] * m[9], s[2] * m[10], 0, 27.253 + s[0] * m[12], s[1] * m[13], s[2] * m[14], 1 27.254 + ]; 27.255 + }; 27.256 + 27.257 + /** 27.258 + * Return a Transform which represents a scale by specified amounts 27.259 + * in each dimension. 27.260 + * 27.261 + * @method scale 27.262 + * @static 27.263 + * @param {Number} x x scale factor 27.264 + * @param {Number} y y scale factor 27.265 + * @param {Number} z z scale factor 27.266 + * @return {Transform} 27.267 + */ 27.268 + Transform.scale = function scale(x, y, z) { 27.269 + if (z === undefined) z = 1; 27.270 + return [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1]; 27.271 + }; 27.272 + 27.273 + /** 27.274 + * Return a Transform which represents a clockwise 27.275 + * rotation around the x axis. 27.276 + * 27.277 + * @method rotateX 27.278 + * @static 27.279 + * @param {Number} theta radians 27.280 + * @return {Transform} 27.281 + */ 27.282 + Transform.rotateX = function rotateX(theta) { 27.283 + var cosTheta = Math.cos(theta); 27.284 + var sinTheta = Math.sin(theta); 27.285 + return [1, 0, 0, 0, 0, cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1]; 27.286 + }; 27.287 + 27.288 + /** 27.289 + * Return a Transform which represents a clockwise 27.290 + * rotation around the y axis. 27.291 + * 27.292 + * @method rotateY 27.293 + * @static 27.294 + * @param {Number} theta radians 27.295 + * @return {Transform} 27.296 + */ 27.297 + Transform.rotateY = function rotateY(theta) { 27.298 + var cosTheta = Math.cos(theta); 27.299 + var sinTheta = Math.sin(theta); 27.300 + return [cosTheta, 0, -sinTheta, 0, 0, 1, 0, 0, sinTheta, 0, cosTheta, 0, 0, 0, 0, 1]; 27.301 + }; 27.302 + 27.303 + /** 27.304 + * Return a Transform which represents a clockwise 27.305 + * rotation around the z axis. 27.306 + * 27.307 + * @method rotateZ 27.308 + * @static 27.309 + * @param {Number} theta radians 27.310 + * @return {Transform} 27.311 + */ 27.312 + Transform.rotateZ = function rotateZ(theta) { 27.313 + var cosTheta = Math.cos(theta); 27.314 + var sinTheta = Math.sin(theta); 27.315 + return [cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 27.316 + }; 27.317 + 27.318 + /** 27.319 + * Return a Transform which represents composed clockwise 27.320 + * rotations along each of the axes. Equivalent to the result of 27.321 + * Matrix.multiply(rotateX(phi), rotateY(theta), rotateZ(psi)). 27.322 + * 27.323 + * @method rotate 27.324 + * @static 27.325 + * @param {Number} phi radians to rotate about the positive x axis 27.326 + * @param {Number} theta radians to rotate about the positive y axis 27.327 + * @param {Number} psi radians to rotate about the positive z axis 27.328 + * @return {Transform} 27.329 + */ 27.330 + Transform.rotate = function rotate(phi, theta, psi) { 27.331 + var cosPhi = Math.cos(phi); 27.332 + var sinPhi = Math.sin(phi); 27.333 + var cosTheta = Math.cos(theta); 27.334 + var sinTheta = Math.sin(theta); 27.335 + var cosPsi = Math.cos(psi); 27.336 + var sinPsi = Math.sin(psi); 27.337 + var result = [ 27.338 + cosTheta * cosPsi, 27.339 + cosPhi * sinPsi + sinPhi * sinTheta * cosPsi, 27.340 + sinPhi * sinPsi - cosPhi * sinTheta * cosPsi, 27.341 + 0, 27.342 + -cosTheta * sinPsi, 27.343 + cosPhi * cosPsi - sinPhi * sinTheta * sinPsi, 27.344 + sinPhi * cosPsi + cosPhi * sinTheta * sinPsi, 27.345 + 0, 27.346 + sinTheta, 27.347 + -sinPhi * cosTheta, 27.348 + cosPhi * cosTheta, 27.349 + 0, 27.350 + 0, 0, 0, 1 27.351 + ]; 27.352 + return result; 27.353 + }; 27.354 + 27.355 + /** 27.356 + * Return a Transform which represents an axis-angle rotation 27.357 + * 27.358 + * @method rotateAxis 27.359 + * @static 27.360 + * @param {Array.Number} v unit vector representing the axis to rotate about 27.361 + * @param {Number} theta radians to rotate clockwise about the axis 27.362 + * @return {Transform} 27.363 + */ 27.364 + Transform.rotateAxis = function rotateAxis(v, theta) { 27.365 + var sinTheta = Math.sin(theta); 27.366 + var cosTheta = Math.cos(theta); 27.367 + var verTheta = 1 - cosTheta; // versine of theta 27.368 + 27.369 + var xxV = v[0] * v[0] * verTheta; 27.370 + var xyV = v[0] * v[1] * verTheta; 27.371 + var xzV = v[0] * v[2] * verTheta; 27.372 + var yyV = v[1] * v[1] * verTheta; 27.373 + var yzV = v[1] * v[2] * verTheta; 27.374 + var zzV = v[2] * v[2] * verTheta; 27.375 + var xs = v[0] * sinTheta; 27.376 + var ys = v[1] * sinTheta; 27.377 + var zs = v[2] * sinTheta; 27.378 + 27.379 + var result = [ 27.380 + xxV + cosTheta, xyV + zs, xzV - ys, 0, 27.381 + xyV - zs, yyV + cosTheta, yzV + xs, 0, 27.382 + xzV + ys, yzV - xs, zzV + cosTheta, 0, 27.383 + 0, 0, 0, 1 27.384 + ]; 27.385 + return result; 27.386 + }; 27.387 + 27.388 + /** 27.389 + * Return a Transform which represents a transform matrix applied about 27.390 + * a separate origin point. 27.391 + * 27.392 + * @method aboutOrigin 27.393 + * @static 27.394 + * @param {Array.Number} v origin point to apply matrix 27.395 + * @param {Transform} m matrix to apply 27.396 + * @return {Transform} 27.397 + */ 27.398 + Transform.aboutOrigin = function aboutOrigin(v, m) { 27.399 + var t0 = v[0] - (v[0] * m[0] + v[1] * m[4] + v[2] * m[8]); 27.400 + var t1 = v[1] - (v[0] * m[1] + v[1] * m[5] + v[2] * m[9]); 27.401 + var t2 = v[2] - (v[0] * m[2] + v[1] * m[6] + v[2] * m[10]); 27.402 + return Transform.thenMove(m, [t0, t1, t2]); 27.403 + }; 27.404 + 27.405 + /** 27.406 + * Return a Transform representation of a skew transformation 27.407 + * 27.408 + * @method skew 27.409 + * @static 27.410 + * @param {Number} phi scale factor skew in the x axis 27.411 + * @param {Number} theta scale factor skew in the y axis 27.412 + * @param {Number} psi scale factor skew in the z axis 27.413 + * @return {Transform} 27.414 + */ 27.415 + Transform.skew = function skew(phi, theta, psi) { 27.416 + return [1, 0, 0, 0, Math.tan(psi), 1, 0, 0, Math.tan(theta), Math.tan(phi), 1, 0, 0, 0, 0, 1]; 27.417 + }; 27.418 + 27.419 + /** 27.420 + * Return a Transform representation of a skew in the x-direction 27.421 + * 27.422 + * @method skewX 27.423 + * @static 27.424 + * @param {Number} angle the angle between the top and left sides 27.425 + * @return {Transform} 27.426 + */ 27.427 + Transform.skewX = function skewX(angle) { 27.428 + return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 27.429 + }; 27.430 + 27.431 + /** 27.432 + * Return a Transform representation of a skew in the y-direction 27.433 + * 27.434 + * @method skewY 27.435 + * @static 27.436 + * @param {Number} angle the angle between the top and right sides 27.437 + * @return {Transform} 27.438 + */ 27.439 + Transform.skewY = function skewY(angle) { 27.440 + return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 27.441 + }; 27.442 + 27.443 + /** 27.444 + * Returns a perspective Transform matrix 27.445 + * 27.446 + * @method perspective 27.447 + * @static 27.448 + * @param {Number} focusZ z position of focal point 27.449 + * @return {Transform} 27.450 + */ 27.451 + Transform.perspective = function perspective(focusZ) { 27.452 + return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1 / focusZ, 0, 0, 0, 1]; 27.453 + }; 27.454 + 27.455 + /** 27.456 + * Return translation vector component of given Transform 27.457 + * 27.458 + * @method getTranslate 27.459 + * @static 27.460 + * @param {Transform} m Transform 27.461 + * @return {Array.Number} the translation vector [t_x, t_y, t_z] 27.462 + */ 27.463 + Transform.getTranslate = function getTranslate(m) { 27.464 + return [m[12], m[13], m[14]]; 27.465 + }; 27.466 + 27.467 + /** 27.468 + * Return inverse affine transform for given Transform. 27.469 + * Note: This assumes m[3] = m[7] = m[11] = 0, and m[15] = 1. 27.470 + * Will provide incorrect results if not invertible or preconditions not met. 27.471 + * 27.472 + * @method inverse 27.473 + * @static 27.474 + * @param {Transform} m Transform 27.475 + * @return {Transform} 27.476 + */ 27.477 + Transform.inverse = function inverse(m) { 27.478 + // only need to consider 3x3 section for affine 27.479 + var c0 = m[5] * m[10] - m[6] * m[9]; 27.480 + var c1 = m[4] * m[10] - m[6] * m[8]; 27.481 + var c2 = m[4] * m[9] - m[5] * m[8]; 27.482 + var c4 = m[1] * m[10] - m[2] * m[9]; 27.483 + var c5 = m[0] * m[10] - m[2] * m[8]; 27.484 + var c6 = m[0] * m[9] - m[1] * m[8]; 27.485 + var c8 = m[1] * m[6] - m[2] * m[5]; 27.486 + var c9 = m[0] * m[6] - m[2] * m[4]; 27.487 + var c10 = m[0] * m[5] - m[1] * m[4]; 27.488 + var detM = m[0] * c0 - m[1] * c1 + m[2] * c2; 27.489 + var invD = 1 / detM; 27.490 + var result = [ 27.491 + invD * c0, -invD * c4, invD * c8, 0, 27.492 + -invD * c1, invD * c5, -invD * c9, 0, 27.493 + invD * c2, -invD * c6, invD * c10, 0, 27.494 + 0, 0, 0, 1 27.495 + ]; 27.496 + result[12] = -m[12] * result[0] - m[13] * result[4] - m[14] * result[8]; 27.497 + result[13] = -m[12] * result[1] - m[13] * result[5] - m[14] * result[9]; 27.498 + result[14] = -m[12] * result[2] - m[13] * result[6] - m[14] * result[10]; 27.499 + return result; 27.500 + }; 27.501 + 27.502 + /** 27.503 + * Returns the transpose of a 4x4 matrix 27.504 + * 27.505 + * @method transpose 27.506 + * @static 27.507 + * @param {Transform} m matrix 27.508 + * @return {Transform} the resulting transposed matrix 27.509 + */ 27.510 + Transform.transpose = function transpose(m) { 27.511 + return [m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]]; 27.512 + }; 27.513 + 27.514 + function _normSquared(v) { 27.515 + return (v.length === 2) ? v[0] * v[0] + v[1] * v[1] : v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; 27.516 + } 27.517 + function _norm(v) { 27.518 + return Math.sqrt(_normSquared(v)); 27.519 + } 27.520 + function _sign(n) { 27.521 + return (n < 0) ? -1 : 1; 27.522 + } 27.523 + 27.524 + /** 27.525 + * Decompose Transform into separate .translate, .rotate, .scale, 27.526 + * and .skew components. 27.527 + * 27.528 + * @method interpret 27.529 + * @static 27.530 + * @param {Transform} M transform matrix 27.531 + * @return {Object} matrix spec object with component matrices .translate, 27.532 + * .rotate, .scale, .skew 27.533 + */ 27.534 + Transform.interpret = function interpret(M) { 27.535 + 27.536 + // QR decomposition via Householder reflections 27.537 + //FIRST ITERATION 27.538 + 27.539 + //default Q1 to the identity matrix; 27.540 + var x = [M[0], M[1], M[2]]; // first column vector 27.541 + var sgn = _sign(x[0]); // sign of first component of x (for stability) 27.542 + var xNorm = _norm(x); // norm of first column vector 27.543 + var v = [x[0] + sgn * xNorm, x[1], x[2]]; // v = x + sign(x[0])|x|e1 27.544 + var mult = 2 / _normSquared(v); // mult = 2/v'v 27.545 + 27.546 + //bail out if our Matrix is singular 27.547 + if (mult >= Infinity) { 27.548 + return {translate: Transform.getTranslate(M), rotate: [0, 0, 0], scale: [0, 0, 0], skew: [0, 0, 0]}; 27.549 + } 27.550 + 27.551 + //evaluate Q1 = I - 2vv'/v'v 27.552 + var Q1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; 27.553 + 27.554 + //diagonals 27.555 + Q1[0] = 1 - mult * v[0] * v[0]; // 0,0 entry 27.556 + Q1[5] = 1 - mult * v[1] * v[1]; // 1,1 entry 27.557 + Q1[10] = 1 - mult * v[2] * v[2]; // 2,2 entry 27.558 + 27.559 + //upper diagonal 27.560 + Q1[1] = -mult * v[0] * v[1]; // 0,1 entry 27.561 + Q1[2] = -mult * v[0] * v[2]; // 0,2 entry 27.562 + Q1[6] = -mult * v[1] * v[2]; // 1,2 entry 27.563 + 27.564 + //lower diagonal 27.565 + Q1[4] = Q1[1]; // 1,0 entry 27.566 + Q1[8] = Q1[2]; // 2,0 entry 27.567 + Q1[9] = Q1[6]; // 2,1 entry 27.568 + 27.569 + //reduce first column of M 27.570 + var MQ1 = Transform.multiply(Q1, M); 27.571 + 27.572 + //SECOND ITERATION on (1,1) minor 27.573 + var x2 = [MQ1[5], MQ1[6]]; 27.574 + var sgn2 = _sign(x2[0]); // sign of first component of x (for stability) 27.575 + var x2Norm = _norm(x2); // norm of first column vector 27.576 + var v2 = [x2[0] + sgn2 * x2Norm, x2[1]]; // v = x + sign(x[0])|x|e1 27.577 + var mult2 = 2 / _normSquared(v2); // mult = 2/v'v 27.578 + 27.579 + //evaluate Q2 = I - 2vv'/v'v 27.580 + var Q2 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; 27.581 + 27.582 + //diagonal 27.583 + Q2[5] = 1 - mult2 * v2[0] * v2[0]; // 1,1 entry 27.584 + Q2[10] = 1 - mult2 * v2[1] * v2[1]; // 2,2 entry 27.585 + 27.586 + //off diagonals 27.587 + Q2[6] = -mult2 * v2[0] * v2[1]; // 2,1 entry 27.588 + Q2[9] = Q2[6]; // 1,2 entry 27.589 + 27.590 + //calc QR decomposition. Q = Q1*Q2, R = Q'*M 27.591 + var Q = Transform.multiply(Q2, Q1); //note: really Q transpose 27.592 + var R = Transform.multiply(Q, M); 27.593 + 27.594 + //remove negative scaling 27.595 + var remover = Transform.scale(R[0] < 0 ? -1 : 1, R[5] < 0 ? -1 : 1, R[10] < 0 ? -1 : 1); 27.596 + R = Transform.multiply(R, remover); 27.597 + Q = Transform.multiply(remover, Q); 27.598 + 27.599 + //decompose into rotate/scale/skew matrices 27.600 + var result = {}; 27.601 + result.translate = Transform.getTranslate(M); 27.602 + result.rotate = [Math.atan2(-Q[6], Q[10]), Math.asin(Q[2]), Math.atan2(-Q[1], Q[0])]; 27.603 + if (!result.rotate[0]) { 27.604 + result.rotate[0] = 0; 27.605 + result.rotate[2] = Math.atan2(Q[4], Q[5]); 27.606 + } 27.607 + result.scale = [R[0], R[5], R[10]]; 27.608 + result.skew = [Math.atan2(R[9], result.scale[2]), Math.atan2(R[8], result.scale[2]), Math.atan2(R[4], result.scale[0])]; 27.609 + 27.610 + //double rotation workaround 27.611 + if (Math.abs(result.rotate[0]) + Math.abs(result.rotate[2]) > 1.5 * Math.PI) { 27.612 + result.rotate[1] = Math.PI - result.rotate[1]; 27.613 + if (result.rotate[1] > Math.PI) result.rotate[1] -= 2 * Math.PI; 27.614 + if (result.rotate[1] < -Math.PI) result.rotate[1] += 2 * Math.PI; 27.615 + if (result.rotate[0] < 0) result.rotate[0] += Math.PI; 27.616 + else result.rotate[0] -= Math.PI; 27.617 + if (result.rotate[2] < 0) result.rotate[2] += Math.PI; 27.618 + else result.rotate[2] -= Math.PI; 27.619 + } 27.620 + 27.621 + return result; 27.622 + }; 27.623 + 27.624 + /** 27.625 + * Weighted average between two matrices by averaging their 27.626 + * translation, rotation, scale, skew components. 27.627 + * f(M1,M2,t) = (1 - t) * M1 + t * M2 27.628 + * 27.629 + * @method average 27.630 + * @static 27.631 + * @param {Transform} M1 f(M1,M2,0) = M1 27.632 + * @param {Transform} M2 f(M1,M2,1) = M2 27.633 + * @param {Number} t 27.634 + * @return {Transform} 27.635 + */ 27.636 + Transform.average = function average(M1, M2, t) { 27.637 + t = (t === undefined) ? 0.5 : t; 27.638 + var specM1 = Transform.interpret(M1); 27.639 + var specM2 = Transform.interpret(M2); 27.640 + 27.641 + var specAvg = { 27.642 + translate: [0, 0, 0], 27.643 + rotate: [0, 0, 0], 27.644 + scale: [0, 0, 0], 27.645 + skew: [0, 0, 0] 27.646 + }; 27.647 + 27.648 + for (var i = 0; i < 3; i++) { 27.649 + specAvg.translate[i] = (1 - t) * specM1.translate[i] + t * specM2.translate[i]; 27.650 + specAvg.rotate[i] = (1 - t) * specM1.rotate[i] + t * specM2.rotate[i]; 27.651 + specAvg.scale[i] = (1 - t) * specM1.scale[i] + t * specM2.scale[i]; 27.652 + specAvg.skew[i] = (1 - t) * specM1.skew[i] + t * specM2.skew[i]; 27.653 + } 27.654 + return Transform.build(specAvg); 27.655 + }; 27.656 + 27.657 + /** 27.658 + * Compose .translate, .rotate, .scale, .skew components into 27.659 + * Transform matrix 27.660 + * 27.661 + * @method build 27.662 + * @static 27.663 + * @param {matrixSpec} spec object with component matrices .translate, 27.664 + * .rotate, .scale, .skew 27.665 + * @return {Transform} composed transform 27.666 + */ 27.667 + Transform.build = function build(spec) { 27.668 + var scaleMatrix = Transform.scale(spec.scale[0], spec.scale[1], spec.scale[2]); 27.669 + var skewMatrix = Transform.skew(spec.skew[0], spec.skew[1], spec.skew[2]); 27.670 + var rotateMatrix = Transform.rotate(spec.rotate[0], spec.rotate[1], spec.rotate[2]); 27.671 + return Transform.thenMove(Transform.multiply(Transform.multiply(rotateMatrix, skewMatrix), scaleMatrix), spec.translate); 27.672 + }; 27.673 + 27.674 + /** 27.675 + * Determine if two Transforms are component-wise equal 27.676 + * Warning: breaks on perspective Transforms 27.677 + * 27.678 + * @method equals 27.679 + * @static 27.680 + * @param {Transform} a matrix 27.681 + * @param {Transform} b matrix 27.682 + * @return {boolean} 27.683 + */ 27.684 + Transform.equals = function equals(a, b) { 27.685 + return !Transform.notEquals(a, b); 27.686 + }; 27.687 + 27.688 + /** 27.689 + * Determine if two Transforms are component-wise unequal 27.690 + * Warning: breaks on perspective Transforms 27.691 + * 27.692 + * @method notEquals 27.693 + * @static 27.694 + * @param {Transform} a matrix 27.695 + * @param {Transform} b matrix 27.696 + * @return {boolean} 27.697 + */ 27.698 + Transform.notEquals = function notEquals(a, b) { 27.699 + if (a === b) return false; 27.700 + 27.701 + // shortci 27.702 + return !(a && b) || 27.703 + a[12] !== b[12] || a[13] !== b[13] || a[14] !== b[14] || 27.704 + a[0] !== b[0] || a[1] !== b[1] || a[2] !== b[2] || 27.705 + a[4] !== b[4] || a[5] !== b[5] || a[6] !== b[6] || 27.706 + a[8] !== b[8] || a[9] !== b[9] || a[10] !== b[10]; 27.707 + }; 27.708 + 27.709 + /** 27.710 + * Constrain angle-trio components to range of [-pi, pi). 27.711 + * 27.712 + * @method normalizeRotation 27.713 + * @static 27.714 + * @param {Array.Number} rotation phi, theta, psi (array of floats 27.715 + * && array.length == 3) 27.716 + * @return {Array.Number} new phi, theta, psi triplet 27.717 + * (array of floats && array.length == 3) 27.718 + */ 27.719 + Transform.normalizeRotation = function normalizeRotation(rotation) { 27.720 + var result = rotation.slice(0); 27.721 + if (result[0] === Math.PI * 0.5 || result[0] === -Math.PI * 0.5) { 27.722 + result[0] = -result[0]; 27.723 + result[1] = Math.PI - result[1]; 27.724 + result[2] -= Math.PI; 27.725 + } 27.726 + if (result[0] > Math.PI * 0.5) { 27.727 + result[0] = result[0] - Math.PI; 27.728 + result[1] = Math.PI - result[1]; 27.729 + result[2] -= Math.PI; 27.730 + } 27.731 + if (result[0] < -Math.PI * 0.5) { 27.732 + result[0] = result[0] + Math.PI; 27.733 + result[1] = -Math.PI - result[1]; 27.734 + result[2] -= Math.PI; 27.735 + } 27.736 + while (result[1] < -Math.PI) result[1] += 2 * Math.PI; 27.737 + while (result[1] >= Math.PI) result[1] -= 2 * Math.PI; 27.738 + while (result[2] < -Math.PI) result[2] += 2 * Math.PI; 27.739 + while (result[2] >= Math.PI) result[2] -= 2 * Math.PI; 27.740 + return result; 27.741 + }; 27.742 + 27.743 + /** 27.744 + * (Property) Array defining a translation forward in z by 1 27.745 + * 27.746 + * @property {array} inFront 27.747 + * @static 27.748 + * @final 27.749 + */ 27.750 + Transform.inFront = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1e-3, 1]; 27.751 + 27.752 + /** 27.753 + * (Property) Array defining a translation backwards in z by 1 27.754 + * 27.755 + * @property {array} behind 27.756 + * @static 27.757 + * @final 27.758 + */ 27.759 + Transform.behind = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1e-3, 1]; 27.760 + 27.761 + module.exports = Transform; 27.762 +}); 27.763 + 27.764 + 27.765 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.766 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.767 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.768 + * 27.769 + * Owner: mark@famo.us 27.770 + * @license MPL 2.0 27.771 + * @copyright Famous Industries, Inc. 2014 27.772 + */ 27.773 + 27.774 +define('famous/core/SpecParser',['require','exports','module','./Transform'],function(require, exports, module) { 27.775 + var Transform = require('./Transform'); 27.776 + 27.777 + /** 27.778 + * 27.779 + * This object translates the rendering instructions ("render specs") 27.780 + * that renderable components generate into document update 27.781 + * instructions ("update specs"). Private. 27.782 + * 27.783 + * @private 27.784 + * @class SpecParser 27.785 + * @constructor 27.786 + */ 27.787 + function SpecParser() { 27.788 + this.result = {}; 27.789 + } 27.790 + SpecParser._instance = new SpecParser(); 27.791 + 27.792 + /** 27.793 + * Convert a render spec coming from the context's render chain to an 27.794 + * update spec for the update chain. This is the only major entry point 27.795 + * for a consumer of this class. 27.796 + * 27.797 + * @method parse 27.798 + * @static 27.799 + * @private 27.800 + * 27.801 + * @param {renderSpec} spec input render spec 27.802 + * @param {Object} context context to do the parse in 27.803 + * @return {Object} the resulting update spec (if no callback 27.804 + * specified, else none) 27.805 + */ 27.806 + SpecParser.parse = function parse(spec, context) { 27.807 + return SpecParser._instance.parse(spec, context); 27.808 + }; 27.809 + 27.810 + /** 27.811 + * Convert a renderSpec coming from the context's render chain to an update 27.812 + * spec for the update chain. This is the only major entrypoint for a 27.813 + * consumer of this class. 27.814 + * 27.815 + * @method parse 27.816 + * 27.817 + * @private 27.818 + * @param {renderSpec} spec input render spec 27.819 + * @param {Context} context 27.820 + * @return {updateSpec} the resulting update spec 27.821 + */ 27.822 + SpecParser.prototype.parse = function parse(spec, context) { 27.823 + this.reset(); 27.824 + this._parseSpec(spec, context, Transform.identity); 27.825 + return this.result; 27.826 + }; 27.827 + 27.828 + /** 27.829 + * Prepare SpecParser for re-use (or first use) by setting internal state 27.830 + * to blank. 27.831 + * 27.832 + * @private 27.833 + * @method reset 27.834 + */ 27.835 + SpecParser.prototype.reset = function reset() { 27.836 + this.result = {}; 27.837 + }; 27.838 + 27.839 + // Multiply matrix M by vector v 27.840 + function _vecInContext(v, m) { 27.841 + return [ 27.842 + v[0] * m[0] + v[1] * m[4] + v[2] * m[8], 27.843 + v[0] * m[1] + v[1] * m[5] + v[2] * m[9], 27.844 + v[0] * m[2] + v[1] * m[6] + v[2] * m[10] 27.845 + ]; 27.846 + } 27.847 + 27.848 + var _originZeroZero = [0, 0]; 27.849 + 27.850 + // From the provided renderSpec tree, recursively compose opacities, 27.851 + // origins, transforms, and sizes corresponding to each surface id from 27.852 + // the provided renderSpec tree structure. On completion, those 27.853 + // properties of 'this' object should be ready to use to build an 27.854 + // updateSpec. 27.855 + SpecParser.prototype._parseSpec = function _parseSpec(spec, parentContext, sizeContext) { 27.856 + var id; 27.857 + var target; 27.858 + var transform; 27.859 + var opacity; 27.860 + var origin; 27.861 + var align; 27.862 + var size; 27.863 + 27.864 + if (typeof spec === 'number') { 27.865 + id = spec; 27.866 + transform = parentContext.transform; 27.867 + align = parentContext.align || parentContext.origin; 27.868 + if (parentContext.size && align && (align[0] || align[1])) { 27.869 + var alignAdjust = [align[0] * parentContext.size[0], align[1] * parentContext.size[1], 0]; 27.870 + transform = Transform.thenMove(transform, _vecInContext(alignAdjust, sizeContext)); 27.871 + } 27.872 + this.result[id] = { 27.873 + transform: transform, 27.874 + opacity: parentContext.opacity, 27.875 + origin: parentContext.origin || _originZeroZero, 27.876 + align: parentContext.align || parentContext.origin || _originZeroZero, 27.877 + size: parentContext.size 27.878 + }; 27.879 + } 27.880 + else if (!spec) { // placed here so 0 will be cached earlier 27.881 + return; 27.882 + } 27.883 + else if (spec instanceof Array) { 27.884 + for (var i = 0; i < spec.length; i++) { 27.885 + this._parseSpec(spec[i], parentContext, sizeContext); 27.886 + } 27.887 + } 27.888 + else { 27.889 + target = spec.target; 27.890 + transform = parentContext.transform; 27.891 + opacity = parentContext.opacity; 27.892 + origin = parentContext.origin; 27.893 + align = parentContext.align; 27.894 + size = parentContext.size; 27.895 + var nextSizeContext = sizeContext; 27.896 + 27.897 + if (spec.opacity !== undefined) opacity = parentContext.opacity * spec.opacity; 27.898 + if (spec.transform) transform = Transform.multiply(parentContext.transform, spec.transform); 27.899 + if (spec.origin) { 27.900 + origin = spec.origin; 27.901 + nextSizeContext = parentContext.transform; 27.902 + } 27.903 + if (spec.align) align = spec.align; 27.904 + if (spec.size) { 27.905 + var parentSize = parentContext.size; 27.906 + size = [ 27.907 + spec.size[0] !== undefined ? spec.size[0] : parentSize[0], 27.908 + spec.size[1] !== undefined ? spec.size[1] : parentSize[1] 27.909 + ]; 27.910 + if (parentSize) { 27.911 + if (!align) align = origin; 27.912 + if (align && (align[0] || align[1])) transform = Transform.thenMove(transform, _vecInContext([align[0] * parentSize[0], align[1] * parentSize[1], 0], sizeContext)); 27.913 + if (origin && (origin[0] || origin[1])) transform = Transform.moveThen([-origin[0] * size[0], -origin[1] * size[1], 0], transform); 27.914 + } 27.915 + nextSizeContext = parentContext.transform; 27.916 + origin = null; 27.917 + align = null; 27.918 + } 27.919 + 27.920 + this._parseSpec(target, { 27.921 + transform: transform, 27.922 + opacity: opacity, 27.923 + origin: origin, 27.924 + align: align, 27.925 + size: size 27.926 + }, nextSizeContext); 27.927 + } 27.928 + }; 27.929 + 27.930 + module.exports = SpecParser; 27.931 +}); 27.932 + 27.933 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.934 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.935 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.936 + * 27.937 + * Owner: mark@famo.us 27.938 + * @license MPL 2.0 27.939 + * @copyright Famous Industries, Inc. 2014 27.940 + */ 27.941 + 27.942 +define('famous/core/RenderNode',['require','exports','module','./Entity','./SpecParser'],function(require, exports, module) { 27.943 + var Entity = require('./Entity'); 27.944 + var SpecParser = require('./SpecParser'); 27.945 + 27.946 + /** 27.947 + * A wrapper for inserting a renderable component (like a Modifer or 27.948 + * Surface) into the render tree. 27.949 + * 27.950 + * @class RenderNode 27.951 + * @constructor 27.952 + * 27.953 + * @param {Object} object Target renderable component 27.954 + */ 27.955 + function RenderNode(object) { 27.956 + this._object = null; 27.957 + this._child = null; 27.958 + this._hasMultipleChildren = false; 27.959 + this._isRenderable = false; 27.960 + this._isModifier = false; 27.961 + 27.962 + this._resultCache = {}; 27.963 + this._prevResults = {}; 27.964 + 27.965 + this._childResult = null; 27.966 + 27.967 + if (object) this.set(object); 27.968 + } 27.969 + 27.970 + /** 27.971 + * Append a renderable to the list of this node's children. 27.972 + * This produces a new RenderNode in the tree. 27.973 + * Note: Does not double-wrap if child is a RenderNode already. 27.974 + * 27.975 + * @method add 27.976 + * @param {Object} child renderable object 27.977 + * @return {RenderNode} new render node wrapping child 27.978 + */ 27.979 + RenderNode.prototype.add = function add(child) { 27.980 + var childNode = (child instanceof RenderNode) ? child : new RenderNode(child); 27.981 + if (this._child instanceof Array) this._child.push(childNode); 27.982 + else if (this._child) { 27.983 + this._child = [this._child, childNode]; 27.984 + this._hasMultipleChildren = true; 27.985 + this._childResult = []; // to be used later 27.986 + } 27.987 + else this._child = childNode; 27.988 + 27.989 + return childNode; 27.990 + }; 27.991 + 27.992 + /** 27.993 + * Return the single wrapped object. Returns null if this node has multiple child nodes. 27.994 + * 27.995 + * @method get 27.996 + * 27.997 + * @return {Ojbect} contained renderable object 27.998 + */ 27.999 + RenderNode.prototype.get = function get() { 27.1000 + return this._object || (this._hasMultipleChildren ? null : (this._child ? this._child.get() : null)); 27.1001 + }; 27.1002 + 27.1003 + /** 27.1004 + * Overwrite the list of children to contain the single provided object 27.1005 + * 27.1006 + * @method set 27.1007 + * @param {Object} child renderable object 27.1008 + * @return {RenderNode} this render node, or child if it is a RenderNode 27.1009 + */ 27.1010 + RenderNode.prototype.set = function set(child) { 27.1011 + this._childResult = null; 27.1012 + this._hasMultipleChildren = false; 27.1013 + this._isRenderable = child.render ? true : false; 27.1014 + this._isModifier = child.modify ? true : false; 27.1015 + this._object = child; 27.1016 + this._child = null; 27.1017 + if (child instanceof RenderNode) return child; 27.1018 + else return this; 27.1019 + }; 27.1020 + 27.1021 + /** 27.1022 + * Get render size of contained object. 27.1023 + * 27.1024 + * @method getSize 27.1025 + * @return {Array.Number} size of this or size of single child. 27.1026 + */ 27.1027 + RenderNode.prototype.getSize = function getSize() { 27.1028 + var result = null; 27.1029 + var target = this.get(); 27.1030 + if (target && target.getSize) result = target.getSize(); 27.1031 + if (!result && this._child && this._child.getSize) result = this._child.getSize(); 27.1032 + return result; 27.1033 + }; 27.1034 + 27.1035 + // apply results of rendering this subtree to the document 27.1036 + function _applyCommit(spec, context, cacheStorage) { 27.1037 + var result = SpecParser.parse(spec, context); 27.1038 + var keys = Object.keys(result); 27.1039 + for (var i = 0; i < keys.length; i++) { 27.1040 + var id = keys[i]; 27.1041 + var childNode = Entity.get(id); 27.1042 + var commitParams = result[id]; 27.1043 + commitParams.allocator = context.allocator; 27.1044 + var commitResult = childNode.commit(commitParams); 27.1045 + if (commitResult) _applyCommit(commitResult, context, cacheStorage); 27.1046 + else cacheStorage[id] = commitParams; 27.1047 + } 27.1048 + } 27.1049 + 27.1050 + /** 27.1051 + * Commit the content change from this node to the document. 27.1052 + * 27.1053 + * @private 27.1054 + * @method commit 27.1055 + * @param {Context} context render context 27.1056 + */ 27.1057 + RenderNode.prototype.commit = function commit(context) { 27.1058 + // free up some divs from the last loop 27.1059 + var prevKeys = Object.keys(this._prevResults); 27.1060 + for (var i = 0; i < prevKeys.length; i++) { 27.1061 + var id = prevKeys[i]; 27.1062 + if (this._resultCache[id] === undefined) { 27.1063 + var object = Entity.get(id); 27.1064 + if (object.cleanup) object.cleanup(context.allocator); 27.1065 + } 27.1066 + } 27.1067 + 27.1068 + this._prevResults = this._resultCache; 27.1069 + this._resultCache = {}; 27.1070 + _applyCommit(this.render(), context, this._resultCache); 27.1071 + }; 27.1072 + 27.1073 + /** 27.1074 + * Generate a render spec from the contents of the wrapped component. 27.1075 + * 27.1076 + * @private 27.1077 + * @method render 27.1078 + * 27.1079 + * @return {Object} render specification for the component subtree 27.1080 + * only under this node. 27.1081 + */ 27.1082 + RenderNode.prototype.render = function render() { 27.1083 + if (this._isRenderable) return this._object.render(); 27.1084 + 27.1085 + var result = null; 27.1086 + if (this._hasMultipleChildren) { 27.1087 + result = this._childResult; 27.1088 + var children = this._child; 27.1089 + for (var i = 0; i < children.length; i++) { 27.1090 + result[i] = children[i].render(); 27.1091 + } 27.1092 + } 27.1093 + else if (this._child) result = this._child.render(); 27.1094 + 27.1095 + return this._isModifier ? this._object.modify(result) : result; 27.1096 + }; 27.1097 + 27.1098 + module.exports = RenderNode; 27.1099 +}); 27.1100 + 27.1101 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1102 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1103 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1104 + * 27.1105 + * Owner: mark@famo.us 27.1106 + * @license MPL 2.0 27.1107 + * @copyright Famous Industries, Inc. 2014 27.1108 + */ 27.1109 + 27.1110 +define('famous/core/EventEmitter',['require','exports','module'],function(require, exports, module) { 27.1111 + /** 27.1112 + * EventEmitter represents a channel for events. 27.1113 + * 27.1114 + * @class EventEmitter 27.1115 + * @constructor 27.1116 + */ 27.1117 + function EventEmitter() { 27.1118 + this.listeners = {}; 27.1119 + this._owner = this; 27.1120 + } 27.1121 + 27.1122 + /** 27.1123 + * Trigger an event, sending to all downstream handlers 27.1124 + * listening for provided 'type' key. 27.1125 + * 27.1126 + * @method emit 27.1127 + * 27.1128 + * @param {string} type event type key (for example, 'click') 27.1129 + * @param {Object} event event data 27.1130 + * @return {EventHandler} this 27.1131 + */ 27.1132 + EventEmitter.prototype.emit = function emit(type, event) { 27.1133 + var handlers = this.listeners[type]; 27.1134 + if (handlers) { 27.1135 + for (var i = 0; i < handlers.length; i++) { 27.1136 + handlers[i].call(this._owner, event); 27.1137 + } 27.1138 + } 27.1139 + return this; 27.1140 + }; 27.1141 + 27.1142 + /** 27.1143 + * Bind a callback function to an event type handled by this object. 27.1144 + * 27.1145 + * @method "on" 27.1146 + * 27.1147 + * @param {string} type event type key (for example, 'click') 27.1148 + * @param {function(string, Object)} handler callback 27.1149 + * @return {EventHandler} this 27.1150 + */ 27.1151 + EventEmitter.prototype.on = function on(type, handler) { 27.1152 + if (!(type in this.listeners)) this.listeners[type] = []; 27.1153 + var index = this.listeners[type].indexOf(handler); 27.1154 + if (index < 0) this.listeners[type].push(handler); 27.1155 + return this; 27.1156 + }; 27.1157 + 27.1158 + /** 27.1159 + * Alias for "on". 27.1160 + * @method addListener 27.1161 + */ 27.1162 + EventEmitter.prototype.addListener = EventEmitter.prototype.on; 27.1163 + 27.1164 + /** 27.1165 + * Unbind an event by type and handler. 27.1166 + * This undoes the work of "on". 27.1167 + * 27.1168 + * @method removeListener 27.1169 + * 27.1170 + * @param {string} type event type key (for example, 'click') 27.1171 + * @param {function} handler function object to remove 27.1172 + * @return {EventEmitter} this 27.1173 + */ 27.1174 + EventEmitter.prototype.removeListener = function removeListener(type, handler) { 27.1175 + var index = this.listeners[type].indexOf(handler); 27.1176 + if (index >= 0) this.listeners[type].splice(index, 1); 27.1177 + return this; 27.1178 + }; 27.1179 + 27.1180 + /** 27.1181 + * Call event handlers with this set to owner. 27.1182 + * 27.1183 + * @method bindThis 27.1184 + * 27.1185 + * @param {Object} owner object this EventEmitter belongs to 27.1186 + */ 27.1187 + EventEmitter.prototype.bindThis = function bindThis(owner) { 27.1188 + this._owner = owner; 27.1189 + }; 27.1190 + 27.1191 + module.exports = EventEmitter; 27.1192 +}); 27.1193 + 27.1194 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1195 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1196 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1197 + * 27.1198 + * Owner: mark@famo.us 27.1199 + * @license MPL 2.0 27.1200 + * @copyright Famous Industries, Inc. 2014 27.1201 + */ 27.1202 + 27.1203 +define('famous/core/EventHandler',['require','exports','module','./EventEmitter'],function(require, exports, module) { 27.1204 + var EventEmitter = require('./EventEmitter'); 27.1205 + 27.1206 + /** 27.1207 + * EventHandler forwards received events to a set of provided callback functions. 27.1208 + * It allows events to be captured, processed, and optionally piped through to other event handlers. 27.1209 + * 27.1210 + * @class EventHandler 27.1211 + * @extends EventEmitter 27.1212 + * @constructor 27.1213 + */ 27.1214 + function EventHandler() { 27.1215 + EventEmitter.apply(this, arguments); 27.1216 + 27.1217 + this.downstream = []; // downstream event handlers 27.1218 + this.downstreamFn = []; // downstream functions 27.1219 + 27.1220 + this.upstream = []; // upstream event handlers 27.1221 + this.upstreamListeners = {}; // upstream listeners 27.1222 + } 27.1223 + EventHandler.prototype = Object.create(EventEmitter.prototype); 27.1224 + EventHandler.prototype.constructor = EventHandler; 27.1225 + 27.1226 + /** 27.1227 + * Assign an event handler to receive an object's input events. 27.1228 + * 27.1229 + * @method setInputHandler 27.1230 + * @static 27.1231 + * 27.1232 + * @param {Object} object object to mix trigger, subscribe, and unsubscribe functions into 27.1233 + * @param {EventHandler} handler assigned event handler 27.1234 + */ 27.1235 + EventHandler.setInputHandler = function setInputHandler(object, handler) { 27.1236 + object.trigger = handler.trigger.bind(handler); 27.1237 + if (handler.subscribe && handler.unsubscribe) { 27.1238 + object.subscribe = handler.subscribe.bind(handler); 27.1239 + object.unsubscribe = handler.unsubscribe.bind(handler); 27.1240 + } 27.1241 + }; 27.1242 + 27.1243 + /** 27.1244 + * Assign an event handler to receive an object's output events. 27.1245 + * 27.1246 + * @method setOutputHandler 27.1247 + * @static 27.1248 + * 27.1249 + * @param {Object} object object to mix pipe, unpipe, on, addListener, and removeListener functions into 27.1250 + * @param {EventHandler} handler assigned event handler 27.1251 + */ 27.1252 + EventHandler.setOutputHandler = function setOutputHandler(object, handler) { 27.1253 + if (handler instanceof EventHandler) handler.bindThis(object); 27.1254 + object.pipe = handler.pipe.bind(handler); 27.1255 + object.unpipe = handler.unpipe.bind(handler); 27.1256 + object.on = handler.on.bind(handler); 27.1257 + object.addListener = object.on; 27.1258 + object.removeListener = handler.removeListener.bind(handler); 27.1259 + }; 27.1260 + 27.1261 + /** 27.1262 + * Trigger an event, sending to all downstream handlers 27.1263 + * listening for provided 'type' key. 27.1264 + * 27.1265 + * @method emit 27.1266 + * 27.1267 + * @param {string} type event type key (for example, 'click') 27.1268 + * @param {Object} event event data 27.1269 + * @return {EventHandler} this 27.1270 + */ 27.1271 + EventHandler.prototype.emit = function emit(type, event) { 27.1272 + EventEmitter.prototype.emit.apply(this, arguments); 27.1273 + var i = 0; 27.1274 + for (i = 0; i < this.downstream.length; i++) { 27.1275 + if (this.downstream[i].trigger) this.downstream[i].trigger(type, event); 27.1276 + } 27.1277 + for (i = 0; i < this.downstreamFn.length; i++) { 27.1278 + this.downstreamFn[i](type, event); 27.1279 + } 27.1280 + return this; 27.1281 + }; 27.1282 + 27.1283 + /** 27.1284 + * Alias for emit 27.1285 + * @method addListener 27.1286 + */ 27.1287 + EventHandler.prototype.trigger = EventHandler.prototype.emit; 27.1288 + 27.1289 + /** 27.1290 + * Add event handler object to set of downstream handlers. 27.1291 + * 27.1292 + * @method pipe 27.1293 + * 27.1294 + * @param {EventHandler} target event handler target object 27.1295 + * @return {EventHandler} passed event handler 27.1296 + */ 27.1297 + EventHandler.prototype.pipe = function pipe(target) { 27.1298 + if (target.subscribe instanceof Function) return target.subscribe(this); 27.1299 + 27.1300 + var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream; 27.1301 + var index = downstreamCtx.indexOf(target); 27.1302 + if (index < 0) downstreamCtx.push(target); 27.1303 + 27.1304 + if (target instanceof Function) target('pipe', null); 27.1305 + else if (target.trigger) target.trigger('pipe', null); 27.1306 + 27.1307 + return target; 27.1308 + }; 27.1309 + 27.1310 + /** 27.1311 + * Remove handler object from set of downstream handlers. 27.1312 + * Undoes work of "pipe". 27.1313 + * 27.1314 + * @method unpipe 27.1315 + * 27.1316 + * @param {EventHandler} target target handler object 27.1317 + * @return {EventHandler} provided target 27.1318 + */ 27.1319 + EventHandler.prototype.unpipe = function unpipe(target) { 27.1320 + if (target.unsubscribe instanceof Function) return target.unsubscribe(this); 27.1321 + 27.1322 + var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream; 27.1323 + var index = downstreamCtx.indexOf(target); 27.1324 + if (index >= 0) { 27.1325 + downstreamCtx.splice(index, 1); 27.1326 + if (target instanceof Function) target('unpipe', null); 27.1327 + else if (target.trigger) target.trigger('unpipe', null); 27.1328 + return target; 27.1329 + } 27.1330 + else return false; 27.1331 + }; 27.1332 + 27.1333 + /** 27.1334 + * Bind a callback function to an event type handled by this object. 27.1335 + * 27.1336 + * @method "on" 27.1337 + * 27.1338 + * @param {string} type event type key (for example, 'click') 27.1339 + * @param {function(string, Object)} handler callback 27.1340 + * @return {EventHandler} this 27.1341 + */ 27.1342 + EventHandler.prototype.on = function on(type, handler) { 27.1343 + EventEmitter.prototype.on.apply(this, arguments); 27.1344 + if (!(type in this.upstreamListeners)) { 27.1345 + var upstreamListener = this.trigger.bind(this, type); 27.1346 + this.upstreamListeners[type] = upstreamListener; 27.1347 + for (var i = 0; i < this.upstream.length; i++) { 27.1348 + this.upstream[i].on(type, upstreamListener); 27.1349 + } 27.1350 + } 27.1351 + return this; 27.1352 + }; 27.1353 + 27.1354 + /** 27.1355 + * Alias for "on" 27.1356 + * @method addListener 27.1357 + */ 27.1358 + EventHandler.prototype.addListener = EventHandler.prototype.on; 27.1359 + 27.1360 + /** 27.1361 + * Listen for events from an upstream event handler. 27.1362 + * 27.1363 + * @method subscribe 27.1364 + * 27.1365 + * @param {EventEmitter} source source emitter object 27.1366 + * @return {EventHandler} this 27.1367 + */ 27.1368 + EventHandler.prototype.subscribe = function subscribe(source) { 27.1369 + var index = this.upstream.indexOf(source); 27.1370 + if (index < 0) { 27.1371 + this.upstream.push(source); 27.1372 + for (var type in this.upstreamListeners) { 27.1373 + source.on(type, this.upstreamListeners[type]); 27.1374 + } 27.1375 + } 27.1376 + return this; 27.1377 + }; 27.1378 + 27.1379 + /** 27.1380 + * Stop listening to events from an upstream event handler. 27.1381 + * 27.1382 + * @method unsubscribe 27.1383 + * 27.1384 + * @param {EventEmitter} source source emitter object 27.1385 + * @return {EventHandler} this 27.1386 + */ 27.1387 + EventHandler.prototype.unsubscribe = function unsubscribe(source) { 27.1388 + var index = this.upstream.indexOf(source); 27.1389 + if (index >= 0) { 27.1390 + this.upstream.splice(index, 1); 27.1391 + for (var type in this.upstreamListeners) { 27.1392 + source.removeListener(type, this.upstreamListeners[type]); 27.1393 + } 27.1394 + } 27.1395 + return this; 27.1396 + }; 27.1397 + 27.1398 + module.exports = EventHandler; 27.1399 +}); 27.1400 + 27.1401 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1402 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1403 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1404 + * 27.1405 + * Owner: mark@famo.us 27.1406 + * @license MPL 2.0 27.1407 + * @copyright Famous Industries, Inc. 2014 27.1408 + */ 27.1409 + 27.1410 +define('famous/core/ElementAllocator',['require','exports','module'],function(require, exports, module) { 27.1411 + 27.1412 + /** 27.1413 + * Internal helper object to Context that handles the process of 27.1414 + * creating and allocating DOM elements within a managed div. 27.1415 + * Private. 27.1416 + * 27.1417 + * @class ElementAllocator 27.1418 + * @constructor 27.1419 + * @private 27.1420 + * @param {Node} container document element in which Famo.us content will be inserted 27.1421 + */ 27.1422 + function ElementAllocator(container) { 27.1423 + if (!container) container = document.createDocumentFragment(); 27.1424 + this.container = container; 27.1425 + this.detachedNodes = {}; 27.1426 + this.nodeCount = 0; 27.1427 + } 27.1428 + 27.1429 + /** 27.1430 + * Move the document elements from their original container to a new one. 27.1431 + * 27.1432 + * @private 27.1433 + * @method migrate 27.1434 + * 27.1435 + * @param {Node} container document element to which Famo.us content will be migrated 27.1436 + */ 27.1437 + ElementAllocator.prototype.migrate = function migrate(container) { 27.1438 + var oldContainer = this.container; 27.1439 + if (container === oldContainer) return; 27.1440 + 27.1441 + if (oldContainer instanceof DocumentFragment) { 27.1442 + container.appendChild(oldContainer); 27.1443 + } 27.1444 + else { 27.1445 + while (oldContainer.hasChildNodes()) { 27.1446 + container.appendChild(oldContainer.removeChild(oldContainer.firstChild)); 27.1447 + } 27.1448 + } 27.1449 + 27.1450 + this.container = container; 27.1451 + }; 27.1452 + 27.1453 + /** 27.1454 + * Allocate an element of specified type from the pool. 27.1455 + * 27.1456 + * @private 27.1457 + * @method allocate 27.1458 + * 27.1459 + * @param {string} type type of element, e.g. 'div' 27.1460 + * @return {Node} allocated document element 27.1461 + */ 27.1462 + ElementAllocator.prototype.allocate = function allocate(type) { 27.1463 + type = type.toLowerCase(); 27.1464 + if (!(type in this.detachedNodes)) this.detachedNodes[type] = []; 27.1465 + var nodeStore = this.detachedNodes[type]; 27.1466 + var result; 27.1467 + if (nodeStore.length > 0) { 27.1468 + result = nodeStore.pop(); 27.1469 + } 27.1470 + else { 27.1471 + result = document.createElement(type); 27.1472 + this.container.appendChild(result); 27.1473 + } 27.1474 + this.nodeCount++; 27.1475 + return result; 27.1476 + }; 27.1477 + 27.1478 + /** 27.1479 + * De-allocate an element of specified type to the pool. 27.1480 + * 27.1481 + * @private 27.1482 + * @method deallocate 27.1483 + * 27.1484 + * @param {Node} element document element to deallocate 27.1485 + */ 27.1486 + ElementAllocator.prototype.deallocate = function deallocate(element) { 27.1487 + var nodeType = element.nodeName.toLowerCase(); 27.1488 + var nodeStore = this.detachedNodes[nodeType]; 27.1489 + nodeStore.push(element); 27.1490 + this.nodeCount--; 27.1491 + }; 27.1492 + 27.1493 + /** 27.1494 + * Get count of total allocated nodes in the document. 27.1495 + * 27.1496 + * @private 27.1497 + * @method getNodeCount 27.1498 + * 27.1499 + * @return {Number} total node count 27.1500 + */ 27.1501 + ElementAllocator.prototype.getNodeCount = function getNodeCount() { 27.1502 + return this.nodeCount; 27.1503 + }; 27.1504 + 27.1505 + module.exports = ElementAllocator; 27.1506 +}); 27.1507 + 27.1508 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1509 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1510 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1511 + * 27.1512 + * Owner: mark@famo.us 27.1513 + * @license MPL 2.0 27.1514 + * @copyright Famous Industries, Inc. 2014 27.1515 + */ 27.1516 + 27.1517 +define('famous/utilities/Utility',['require','exports','module'],function(require, exports, module) { 27.1518 + /** 27.1519 + * This namespace holds standalone functionality. 27.1520 + * Currently includes name mapping for transition curves, 27.1521 + * name mapping for origin pairs, and the after() function. 27.1522 + * 27.1523 + * @class Utility 27.1524 + * @static 27.1525 + */ 27.1526 + var Utility = {}; 27.1527 + 27.1528 + /** 27.1529 + * Table of direction array positions 27.1530 + * 27.1531 + * @property {object} Direction 27.1532 + * @final 27.1533 + */ 27.1534 + Utility.Direction = { 27.1535 + X: 0, 27.1536 + Y: 1, 27.1537 + Z: 2 27.1538 + }; 27.1539 + 27.1540 + /** 27.1541 + * Return wrapper around callback function. Once the wrapper is called N 27.1542 + * times, invoke the callback function. Arguments and scope preserved. 27.1543 + * 27.1544 + * @method after 27.1545 + * 27.1546 + * @param {number} count number of calls before callback function invoked 27.1547 + * @param {Function} callback wrapped callback function 27.1548 + * 27.1549 + * @return {function} wrapped callback with coundown feature 27.1550 + */ 27.1551 + Utility.after = function after(count, callback) { 27.1552 + var counter = count; 27.1553 + return function() { 27.1554 + counter--; 27.1555 + if (counter === 0) callback.apply(this, arguments); 27.1556 + }; 27.1557 + }; 27.1558 + 27.1559 + /** 27.1560 + * Load a URL and return its contents in a callback 27.1561 + * 27.1562 + * @method loadURL 27.1563 + * 27.1564 + * @param {string} url URL of object 27.1565 + * @param {function} callback callback to dispatch with content 27.1566 + */ 27.1567 + Utility.loadURL = function loadURL(url, callback) { 27.1568 + var xhr = new XMLHttpRequest(); 27.1569 + xhr.onreadystatechange = function onreadystatechange() { 27.1570 + if (this.readyState === 4) { 27.1571 + if (callback) callback(this.responseText); 27.1572 + } 27.1573 + }; 27.1574 + xhr.open('GET', url); 27.1575 + xhr.send(); 27.1576 + }; 27.1577 + 27.1578 + /** 27.1579 + * Create a document fragment from a string of HTML 27.1580 + * 27.1581 + * @method createDocumentFragmentFromHTML 27.1582 + * 27.1583 + * @param {string} html HTML to convert to DocumentFragment 27.1584 + * 27.1585 + * @return {DocumentFragment} DocumentFragment representing input HTML 27.1586 + */ 27.1587 + Utility.createDocumentFragmentFromHTML = function createDocumentFragmentFromHTML(html) { 27.1588 + var element = document.createElement('div'); 27.1589 + element.innerHTML = html; 27.1590 + var result = document.createDocumentFragment(); 27.1591 + while (element.hasChildNodes()) result.appendChild(element.firstChild); 27.1592 + return result; 27.1593 + }; 27.1594 + 27.1595 + module.exports = Utility; 27.1596 +}); 27.1597 + 27.1598 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1599 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1600 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1601 + * 27.1602 + * Owner: david@famo.us 27.1603 + * @license MPL 2.0 27.1604 + * @copyright Famous Industries, Inc. 2014 27.1605 + */ 27.1606 + 27.1607 +define('famous/transitions/MultipleTransition',['require','exports','module','famous/utilities/Utility'],function(require, exports, module) { 27.1608 + var Utility = require('famous/utilities/Utility'); 27.1609 + 27.1610 + /** 27.1611 + * Transition meta-method to support transitioning multiple 27.1612 + * values with scalar-only methods. 27.1613 + * 27.1614 + * 27.1615 + * @class MultipleTransition 27.1616 + * @constructor 27.1617 + * 27.1618 + * @param {Object} method Transionable class to multiplex 27.1619 + */ 27.1620 + function MultipleTransition(method) { 27.1621 + this.method = method; 27.1622 + this._instances = []; 27.1623 + this.state = []; 27.1624 + } 27.1625 + 27.1626 + MultipleTransition.SUPPORTS_MULTIPLE = true; 27.1627 + 27.1628 + /** 27.1629 + * Get the state of each transition. 27.1630 + * 27.1631 + * @method get 27.1632 + * 27.1633 + * @return state {Number|Array} state array 27.1634 + */ 27.1635 + MultipleTransition.prototype.get = function get() { 27.1636 + for (var i = 0; i < this._instances.length; i++) { 27.1637 + this.state[i] = this._instances[i].get(); 27.1638 + } 27.1639 + return this.state; 27.1640 + }; 27.1641 + 27.1642 + /** 27.1643 + * Set the end states with a shared transition, with optional callback. 27.1644 + * 27.1645 + * @method set 27.1646 + * 27.1647 + * @param {Number|Array} endState Final State. Use a multi-element argument for multiple transitions. 27.1648 + * @param {Object} transition Transition definition, shared among all instances 27.1649 + * @param {Function} callback called when all endStates have been reached. 27.1650 + */ 27.1651 + MultipleTransition.prototype.set = function set(endState, transition, callback) { 27.1652 + var _allCallback = Utility.after(endState.length, callback); 27.1653 + for (var i = 0; i < endState.length; i++) { 27.1654 + if (!this._instances[i]) this._instances[i] = new (this.method)(); 27.1655 + this._instances[i].set(endState[i], transition, _allCallback); 27.1656 + } 27.1657 + }; 27.1658 + 27.1659 + /** 27.1660 + * Reset all transitions to start state. 27.1661 + * 27.1662 + * @method reset 27.1663 + * 27.1664 + * @param {Number|Array} startState Start state 27.1665 + */ 27.1666 + MultipleTransition.prototype.reset = function reset(startState) { 27.1667 + for (var i = 0; i < startState.length; i++) { 27.1668 + if (!this._instances[i]) this._instances[i] = new (this.method)(); 27.1669 + this._instances[i].reset(startState[i]); 27.1670 + } 27.1671 + }; 27.1672 + 27.1673 + module.exports = MultipleTransition; 27.1674 +}); 27.1675 + 27.1676 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.1677 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.1678 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.1679 + * 27.1680 + * Owner: david@famo.us 27.1681 + * @license MPL 2.0 27.1682 + * @copyright Famous Industries, Inc. 2014 27.1683 + */ 27.1684 + 27.1685 +define('famous/transitions/TweenTransition',['require','exports','module'],function(require, exports, module) { 27.1686 + 27.1687 + /** 27.1688 + * 27.1689 + * A state maintainer for a smooth transition between 27.1690 + * numerically-specified states. Example numeric states include floats or 27.1691 + * Transfornm objects. 27.1692 + * 27.1693 + * An initial state is set with the constructor or set(startValue). A 27.1694 + * corresponding end state and transition are set with set(endValue, 27.1695 + * transition). Subsequent calls to set(endValue, transition) begin at 27.1696 + * the last state. Calls to get(timestamp) provide the _interpolated state 27.1697 + * along the way. 27.1698 + * 27.1699 + * Note that there is no event loop here - calls to get() are the only way 27.1700 + * to find out state projected to the current (or provided) time and are 27.1701 + * the only way to trigger callbacks. Usually this kind of object would 27.1702 + * be part of the render() path of a visible component. 27.1703 + * 27.1704 + * @class TweenTransition 27.1705 + * @constructor 27.1706 + * 27.1707 + * @param {Object} options TODO 27.1708 + * beginning state 27.1709 + */ 27.1710 + function TweenTransition(options) { 27.1711 + this.options = Object.create(TweenTransition.DEFAULT_OPTIONS); 27.1712 + if (options) this.setOptions(options); 27.1713 + 27.1714 + this._startTime = 0; 27.1715 + this._startValue = 0; 27.1716 + this._updateTime = 0; 27.1717 + this._endValue = 0; 27.1718 + this._curve = undefined; 27.1719 + this._duration = 0; 27.1720 + this._active = false; 27.1721 + this._callback = undefined; 27.1722 + this.state = 0; 27.1723 + this.velocity = undefined; 27.1724 + } 27.1725 + 27.1726 + /** 27.1727 + * Transition curves mapping independent variable t from domain [0,1] to a 27.1728 + * range within [0,1]. Includes functions 'linear', 'easeIn', 'easeOut', 27.1729 + * 'easeInOut', 'easeOutBounce', 'spring'. 27.1730 + * 27.1731 + * @property {object} Curve 27.1732 + * @final 27.1733 + */ 27.1734 + TweenTransition.Curves = { 27.1735 + linear: function(t) { 27.1736 + return t; 27.1737 + }, 27.1738 + easeIn: function(t) { 27.1739 + return t*t; 27.1740 + }, 27.1741 + easeOut: function(t) { 27.1742 + return t*(2-t); 27.1743 + }, 27.1744 + easeInOut: function(t) { 27.1745 + if (t <= 0.5) return 2*t*t; 27.1746 + else return -2*t*t + 4*t - 1; 27.1747 + }, 27.1748 + easeOutBounce: function(t) { 27.1749 + return t*(3 - 2*t); 27.1750 + }, 27.1751 + spring: function(t) { 27.1752 + return (1 - t) * Math.sin(6 * Math.PI * t) + t; 27.1753 + } 27.1754 + }; 27.1755 + 27.1756 + TweenTransition.SUPPORTS_MULTIPLE = true; 27.1757 + TweenTransition.DEFAULT_OPTIONS = { 27.1758 + curve: TweenTransition.Curves.linear, 27.1759 + duration: 500, 27.1760 + speed: 0 /* considered only if positive */ 27.1761 + }; 27.1762 + 27.1763 + var registeredCurves = {}; 27.1764 + 27.1765 + /** 27.1766 + * Add "unit" curve to internal dictionary of registered curves. 27.1767 + * 27.1768 + * @method registerCurve 27.1769 + * 27.1770 + * @static 27.1771 + * 27.1772 + * @param {string} curveName dictionary key 27.1773 + * @param {unitCurve} curve function of one numeric variable mapping [0,1] 27.1774 + * to range inside [0,1] 27.1775 + * @return {boolean} false if key is taken, else true 27.1776 + */ 27.1777 + TweenTransition.registerCurve = function registerCurve(curveName, curve) { 27.1778 + if (!registeredCurves[curveName]) { 27.1779 + registeredCurves[curveName] = curve; 27.1780 + return true; 27.1781 + } 27.1782 + else { 27.1783 + return false; 27.1784 + } 27.1785 + }; 27.1786 + 27.1787 + /** 27.1788 + * Remove object with key "curveName" from internal dictionary of registered 27.1789 + * curves. 27.1790 + * 27.1791 + * @method unregisterCurve 27.1792 + * 27.1793 + * @static 27.1794 + * 27.1795 + * @param {string} curveName dictionary key 27.1796 + * @return {boolean} false if key has no dictionary value 27.1797 + */ 27.1798 + TweenTransition.unregisterCurve = function unregisterCurve(curveName) { 27.1799 + if (registeredCurves[curveName]) { 27.1800 + delete registeredCurves[curveName]; 27.1801 + return true; 27.1802 + } 27.1803 + else { 27.1804 + return false; 27.1805 + } 27.1806 + }; 27.1807 + 27.1808 + /** 27.1809 + * Retrieve function with key "curveName" from internal dictionary of 27.1810 + * registered curves. Default curves are defined in the 27.1811 + * TweenTransition.Curves array, where the values represent 27.1812 + * unitCurve functions. 27.1813 + * 27.1814 + * @method getCurve 27.1815 + * 27.1816 + * @static 27.1817 + * 27.1818 + * @param {string} curveName dictionary key 27.1819 + * @return {unitCurve} curve function of one numeric variable mapping [0,1] 27.1820 + * to range inside [0,1] 27.1821 + */ 27.1822 + TweenTransition.getCurve = function getCurve(curveName) { 27.1823 + var curve = registeredCurves[curveName]; 27.1824 + if (curve !== undefined) return curve; 27.1825 + else throw new Error('curve not registered'); 27.1826 + }; 27.1827 + 27.1828 + /** 27.1829 + * Retrieve all available curves. 27.1830 + * 27.1831 + * @method getCurves 27.1832 + * 27.1833 + * @static 27.1834 + * 27.1835 + * @return {object} curve functions of one numeric variable mapping [0,1] 27.1836 + * to range inside [0,1] 27.1837 + */ 27.1838 + TweenTransition.getCurves = function getCurves() { 27.1839 + return registeredCurves; 27.1840 + }; 27.1841 + 27.1842 + // Interpolate: If a linear function f(0) = a, f(1) = b, then return f(t) 27.1843 + function _interpolate(a, b, t) { 27.1844 + return ((1 - t) * a) + (t * b); 27.1845 + } 27.1846 + 27.1847 + function _clone(obj) { 27.1848 + if (obj instanceof Object) { 27.1849 + if (obj instanceof Array) return obj.slice(0); 27.1850 + else return Object.create(obj); 27.1851 + } 27.1852 + else return obj; 27.1853 + } 27.1854 + 27.1855 + // Fill in missing properties in "transition" with those in defaultTransition, and 27.1856 + // convert internal named curve to function object, returning as new 27.1857 + // object. 27.1858 + function _normalize(transition, defaultTransition) { 27.1859 + var result = {curve: defaultTransition.curve}; 27.1860 + if (defaultTransition.duration) result.duration = defaultTransition.duration; 27.1861 + if (defaultTransition.speed) result.speed = defaultTransition.speed; 27.1862 + if (transition instanceof Object) { 27.1863 + if (transition.duration !== undefined) result.duration = transition.duration; 27.1864 + if (transition.curve) result.curve = transition.curve; 27.1865 + if (transition.speed) result.speed = transition.speed; 27.1866 + } 27.1867 + if (typeof result.curve === 'string') result.curve = TweenTransition.getCurve(result.curve); 27.1868 + return result; 27.1869 + } 27.1870 + 27.1871 + /** 27.1872 + * Set internal options, overriding any default options. 27.1873 + * 27.1874 + * @method setOptions 27.1875 + * 27.1876 + * 27.1877 + * @param {Object} options options object 27.1878 + * @param {Object} [options.curve] function mapping [0,1] to [0,1] or identifier 27.1879 + * @param {Number} [options.duration] duration in ms 27.1880 + * @param {Number} [options.speed] speed in pixels per ms 27.1881 + */ 27.1882 + TweenTransition.prototype.setOptions = function setOptions(options) { 27.1883 + if (options.curve !== undefined) this.options.curve = options.curve; 27.1884 + if (options.duration !== undefined) this.options.duration = options.duration; 27.1885 + if (options.speed !== undefined) this.options.speed = options.speed; 27.1886 + }; 27.1887 + 27.1888 + /** 27.1889 + * Add transition to end state to the queue of pending transitions. Special 27.1890 + * Use: calling without a transition resets the object to that state with 27.1891 + * no pending actions 27.1892 + * 27.1893 + * @method set 27.1894 + * 27.1895 + * 27.1896 + * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endValue 27.1897 + * end state to which we _interpolate 27.1898 + * @param {transition=} transition object of type {duration: number, curve: 27.1899 + * f[0,1] -> [0,1] or name}. If transition is omitted, change will be 27.1900 + * instantaneous. 27.1901 + * @param {function()=} callback Zero-argument function to call on observed 27.1902 + * completion (t=1) 27.1903 + */ 27.1904 + TweenTransition.prototype.set = function set(endValue, transition, callback) { 27.1905 + if (!transition) { 27.1906 + this.reset(endValue); 27.1907 + if (callback) callback(); 27.1908 + return; 27.1909 + } 27.1910 + 27.1911 + this._startValue = _clone(this.get()); 27.1912 + transition = _normalize(transition, this.options); 27.1913 + if (transition.speed) { 27.1914 + var startValue = this._startValue; 27.1915 + if (startValue instanceof Object) { 27.1916 + var variance = 0; 27.1917 + for (var i in startValue) variance += (endValue[i] - startValue[i]) * (endValue[i] - startValue[i]); 27.1918 + transition.duration = Math.sqrt(variance) / transition.speed; 27.1919 + } 27.1920 + else { 27.1921 + transition.duration = Math.abs(endValue - startValue) / transition.speed; 27.1922 + } 27.1923 + } 27.1924 + 27.1925 + this._startTime = Date.now(); 27.1926 + this._endValue = _clone(endValue); 27.1927 + this._startVelocity = _clone(transition.velocity); 27.1928 + this._duration = transition.duration; 27.1929 + this._curve = transition.curve; 27.1930 + this._active = true; 27.1931 + this._callback = callback; 27.1932 + }; 27.1933 + 27.1934 + /** 27.1935 + * Cancel all transitions and reset to a stable state 27.1936 + * 27.1937 + * @method reset 27.1938 + * 27.1939 + * @param {number|Array.Number|Object.<number, number>} startValue 27.1940 + * starting state 27.1941 + * @param {number} startVelocity 27.1942 + * starting velocity 27.1943 + */ 27.1944 + TweenTransition.prototype.reset = function reset(startValue, startVelocity) { 27.1945 + if (this._callback) { 27.1946 + var callback = this._callback; 27.1947 + this._callback = undefined; 27.1948 + callback(); 27.1949 + } 27.1950 + this.state = _clone(startValue); 27.1951 + this.velocity = _clone(startVelocity); 27.1952 + this._startTime = 0; 27.1953 + this._duration = 0; 27.1954 + this._updateTime = 0; 27.1955 + this._startValue = this.state; 27.1956 + this._startVelocity = this.velocity; 27.1957 + this._endValue = this.state; 27.1958 + this._active = false; 27.1959 + }; 27.1960 + 27.1961 + /** 27.1962 + * Get current velocity 27.1963 + * 27.1964 + * @method getVelocity 27.1965 + * 27.1966 + * @returns {Number} velocity 27.1967 + */ 27.1968 + TweenTransition.prototype.getVelocity = function getVelocity() { 27.1969 + return this.velocity; 27.1970 + }; 27.1971 + 27.1972 + /** 27.1973 + * Get interpolated state of current action at provided time. If the last 27.1974 + * action has completed, invoke its callback. 27.1975 + * 27.1976 + * @method get 27.1977 + * 27.1978 + * 27.1979 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 27.1980 + * time. If omitted, use current time. (Unix epoch time) 27.1981 + * @return {number|Object.<number|string, number>} beginning state 27.1982 + * _interpolated to this point in time. 27.1983 + */ 27.1984 + TweenTransition.prototype.get = function get(timestamp) { 27.1985 + this.update(timestamp); 27.1986 + return this.state; 27.1987 + }; 27.1988 + 27.1989 + function _calculateVelocity(current, start, curve, duration, t) { 27.1990 + var velocity; 27.1991 + var eps = 1e-7; 27.1992 + var speed = (curve(t) - curve(t - eps)) / eps; 27.1993 + if (current instanceof Array) { 27.1994 + velocity = []; 27.1995 + for (var i = 0; i < current.length; i++){ 27.1996 + if (typeof current[i] === 'number') 27.1997 + velocity[i] = speed * (current[i] - start[i]) / duration; 27.1998 + else 27.1999 + velocity[i] = 0; 27.2000 + } 27.2001 + 27.2002 + } 27.2003 + else velocity = speed * (current - start) / duration; 27.2004 + return velocity; 27.2005 + } 27.2006 + 27.2007 + function _calculateState(start, end, t) { 27.2008 + var state; 27.2009 + if (start instanceof Array) { 27.2010 + state = []; 27.2011 + for (var i = 0; i < start.length; i++) { 27.2012 + if (typeof start[i] === 'number') 27.2013 + state[i] = _interpolate(start[i], end[i], t); 27.2014 + else 27.2015 + state[i] = start[i]; 27.2016 + } 27.2017 + } 27.2018 + else state = _interpolate(start, end, t); 27.2019 + return state; 27.2020 + } 27.2021 + 27.2022 + /** 27.2023 + * Update internal state to the provided timestamp. This may invoke the last 27.2024 + * callback and begin a new action. 27.2025 + * 27.2026 + * @method update 27.2027 + * 27.2028 + * 27.2029 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 27.2030 + * time. If omitted, use current time. (Unix epoch time) 27.2031 + */ 27.2032 + TweenTransition.prototype.update = function update(timestamp) { 27.2033 + if (!this._active) { 27.2034 + if (this._callback) { 27.2035 + var callback = this._callback; 27.2036 + this._callback = undefined; 27.2037 + callback(); 27.2038 + } 27.2039 + return; 27.2040 + } 27.2041 + 27.2042 + if (!timestamp) timestamp = Date.now(); 27.2043 + if (this._updateTime >= timestamp) return; 27.2044 + this._updateTime = timestamp; 27.2045 + 27.2046 + var timeSinceStart = timestamp - this._startTime; 27.2047 + if (timeSinceStart >= this._duration) { 27.2048 + this.state = this._endValue; 27.2049 + this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, 1); 27.2050 + this._active = false; 27.2051 + } 27.2052 + else if (timeSinceStart < 0) { 27.2053 + this.state = this._startValue; 27.2054 + this.velocity = this._startVelocity; 27.2055 + } 27.2056 + else { 27.2057 + var t = timeSinceStart / this._duration; 27.2058 + this.state = _calculateState(this._startValue, this._endValue, this._curve(t)); 27.2059 + this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, t); 27.2060 + } 27.2061 + }; 27.2062 + 27.2063 + /** 27.2064 + * Is there at least one action pending completion? 27.2065 + * 27.2066 + * @method isActive 27.2067 + * 27.2068 + * 27.2069 + * @return {boolean} 27.2070 + */ 27.2071 + TweenTransition.prototype.isActive = function isActive() { 27.2072 + return this._active; 27.2073 + }; 27.2074 + 27.2075 + /** 27.2076 + * Halt transition at current state and erase all pending actions. 27.2077 + * 27.2078 + * @method halt 27.2079 + * 27.2080 + */ 27.2081 + TweenTransition.prototype.halt = function halt() { 27.2082 + this.reset(this.get()); 27.2083 + }; 27.2084 + 27.2085 + // Register all the default curves 27.2086 + TweenTransition.registerCurve('linear', TweenTransition.Curves.linear); 27.2087 + TweenTransition.registerCurve('easeIn', TweenTransition.Curves.easeIn); 27.2088 + TweenTransition.registerCurve('easeOut', TweenTransition.Curves.easeOut); 27.2089 + TweenTransition.registerCurve('easeInOut', TweenTransition.Curves.easeInOut); 27.2090 + TweenTransition.registerCurve('easeOutBounce', TweenTransition.Curves.easeOutBounce); 27.2091 + TweenTransition.registerCurve('spring', TweenTransition.Curves.spring); 27.2092 + 27.2093 + TweenTransition.customCurve = function customCurve(v1, v2) { 27.2094 + v1 = v1 || 0; v2 = v2 || 0; 27.2095 + return function(t) { 27.2096 + return v1*t + (-2*v1 - v2 + 3)*t*t + (v1 + v2 - 2)*t*t*t; 27.2097 + }; 27.2098 + }; 27.2099 + 27.2100 + module.exports = TweenTransition; 27.2101 +}); 27.2102 + 27.2103 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.2104 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.2105 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.2106 + * 27.2107 + * Owner: david@famo.us 27.2108 + * @license MPL 2.0 27.2109 + * @copyright Famous Industries, Inc. 2014 27.2110 + */ 27.2111 + 27.2112 +define('famous/transitions/Transitionable',['require','exports','module','./MultipleTransition','./TweenTransition'],function(require, exports, module) { 27.2113 + var MultipleTransition = require('./MultipleTransition'); 27.2114 + var TweenTransition = require('./TweenTransition'); 27.2115 + 27.2116 + /** 27.2117 + * A state maintainer for a smooth transition between 27.2118 + * numerically-specified states. Example numeric states include floats or 27.2119 + * Transform objects. 27.2120 + * 27.2121 + * An initial state is set with the constructor or set(startState). A 27.2122 + * corresponding end state and transition are set with set(endState, 27.2123 + * transition). Subsequent calls to set(endState, transition) begin at 27.2124 + * the last state. Calls to get(timestamp) provide the interpolated state 27.2125 + * along the way. 27.2126 + * 27.2127 + * Note that there is no event loop here - calls to get() are the only way 27.2128 + * to find state projected to the current (or provided) time and are 27.2129 + * the only way to trigger callbacks. Usually this kind of object would 27.2130 + * be part of the render() path of a visible component. 27.2131 + * 27.2132 + * @class Transitionable 27.2133 + * @constructor 27.2134 + * @param {number|Array.Number|Object.<number|string, number>} start 27.2135 + * beginning state 27.2136 + */ 27.2137 + function Transitionable(start) { 27.2138 + this.currentAction = null; 27.2139 + this.actionQueue = []; 27.2140 + this.callbackQueue = []; 27.2141 + 27.2142 + this.state = 0; 27.2143 + this.velocity = undefined; 27.2144 + this._callback = undefined; 27.2145 + this._engineInstance = null; 27.2146 + this._currentMethod = null; 27.2147 + 27.2148 + this.set(start); 27.2149 + } 27.2150 + 27.2151 + var transitionMethods = {}; 27.2152 + 27.2153 + Transitionable.registerMethod = function registerMethod(name, engineClass) { 27.2154 + if (!(name in transitionMethods)) { 27.2155 + transitionMethods[name] = engineClass; 27.2156 + return true; 27.2157 + } 27.2158 + else return false; 27.2159 + }; 27.2160 + 27.2161 + Transitionable.unregisterMethod = function unregisterMethod(name) { 27.2162 + if (name in transitionMethods) { 27.2163 + delete transitionMethods[name]; 27.2164 + return true; 27.2165 + } 27.2166 + else return false; 27.2167 + }; 27.2168 + 27.2169 + function _loadNext() { 27.2170 + if (this._callback) { 27.2171 + var callback = this._callback; 27.2172 + this._callback = undefined; 27.2173 + callback(); 27.2174 + } 27.2175 + if (this.actionQueue.length <= 0) { 27.2176 + this.set(this.get()); // no update required 27.2177 + return; 27.2178 + } 27.2179 + this.currentAction = this.actionQueue.shift(); 27.2180 + this._callback = this.callbackQueue.shift(); 27.2181 + 27.2182 + var method = null; 27.2183 + var endValue = this.currentAction[0]; 27.2184 + var transition = this.currentAction[1]; 27.2185 + if (transition instanceof Object && transition.method) { 27.2186 + method = transition.method; 27.2187 + if (typeof method === 'string') method = transitionMethods[method]; 27.2188 + } 27.2189 + else { 27.2190 + method = TweenTransition; 27.2191 + } 27.2192 + 27.2193 + if (this._currentMethod !== method) { 27.2194 + if (!(endValue instanceof Object) || method.SUPPORTS_MULTIPLE === true || endValue.length <= method.SUPPORTS_MULTIPLE) { 27.2195 + this._engineInstance = new method(); 27.2196 + } 27.2197 + else { 27.2198 + this._engineInstance = new MultipleTransition(method); 27.2199 + } 27.2200 + this._currentMethod = method; 27.2201 + } 27.2202 + 27.2203 + this._engineInstance.reset(this.state, this.velocity); 27.2204 + if (this.velocity !== undefined) transition.velocity = this.velocity; 27.2205 + this._engineInstance.set(endValue, transition, _loadNext.bind(this)); 27.2206 + } 27.2207 + 27.2208 + /** 27.2209 + * Add transition to end state to the queue of pending transitions. Special 27.2210 + * Use: calling without a transition resets the object to that state with 27.2211 + * no pending actions 27.2212 + * 27.2213 + * @method set 27.2214 + * 27.2215 + * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endState 27.2216 + * end state to which we interpolate 27.2217 + * @param {transition=} transition object of type {duration: number, curve: 27.2218 + * f[0,1] -> [0,1] or name}. If transition is omitted, change will be 27.2219 + * instantaneous. 27.2220 + * @param {function()=} callback Zero-argument function to call on observed 27.2221 + * completion (t=1) 27.2222 + */ 27.2223 + Transitionable.prototype.set = function set(endState, transition, callback) { 27.2224 + if (!transition) { 27.2225 + this.reset(endState); 27.2226 + if (callback) callback(); 27.2227 + return this; 27.2228 + } 27.2229 + 27.2230 + var action = [endState, transition]; 27.2231 + this.actionQueue.push(action); 27.2232 + this.callbackQueue.push(callback); 27.2233 + if (!this.currentAction) _loadNext.call(this); 27.2234 + return this; 27.2235 + }; 27.2236 + 27.2237 + /** 27.2238 + * Cancel all transitions and reset to a stable state 27.2239 + * 27.2240 + * @method reset 27.2241 + * 27.2242 + * @param {number|Array.Number|Object.<number, number>} startState 27.2243 + * stable state to set to 27.2244 + */ 27.2245 + Transitionable.prototype.reset = function reset(startState, startVelocity) { 27.2246 + this._currentMethod = null; 27.2247 + this._engineInstance = null; 27.2248 + this._callback = undefined; 27.2249 + this.state = startState; 27.2250 + this.velocity = startVelocity; 27.2251 + this.currentAction = null; 27.2252 + this.actionQueue = []; 27.2253 + this.callbackQueue = []; 27.2254 + }; 27.2255 + 27.2256 + /** 27.2257 + * Add delay action to the pending action queue queue. 27.2258 + * 27.2259 + * @method delay 27.2260 + * 27.2261 + * @param {number} duration delay time (ms) 27.2262 + * @param {function} callback Zero-argument function to call on observed 27.2263 + * completion (t=1) 27.2264 + */ 27.2265 + Transitionable.prototype.delay = function delay(duration, callback) { 27.2266 + this.set(this.get(), {duration: duration, 27.2267 + curve: function() { 27.2268 + return 0; 27.2269 + }}, 27.2270 + callback 27.2271 + ); 27.2272 + }; 27.2273 + 27.2274 + /** 27.2275 + * Get interpolated state of current action at provided time. If the last 27.2276 + * action has completed, invoke its callback. 27.2277 + * 27.2278 + * @method get 27.2279 + * 27.2280 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 27.2281 + * time. If omitted, use current time. (Unix epoch time) 27.2282 + * @return {number|Object.<number|string, number>} beginning state 27.2283 + * interpolated to this point in time. 27.2284 + */ 27.2285 + Transitionable.prototype.get = function get(timestamp) { 27.2286 + if (this._engineInstance) { 27.2287 + if (this._engineInstance.getVelocity) 27.2288 + this.velocity = this._engineInstance.getVelocity(); 27.2289 + this.state = this._engineInstance.get(timestamp); 27.2290 + } 27.2291 + return this.state; 27.2292 + }; 27.2293 + 27.2294 + /** 27.2295 + * Is there at least one action pending completion? 27.2296 + * 27.2297 + * @method isActive 27.2298 + * 27.2299 + * @return {boolean} 27.2300 + */ 27.2301 + Transitionable.prototype.isActive = function isActive() { 27.2302 + return !!this.currentAction; 27.2303 + }; 27.2304 + 27.2305 + /** 27.2306 + * Halt transition at current state and erase all pending actions. 27.2307 + * 27.2308 + * @method halt 27.2309 + */ 27.2310 + Transitionable.prototype.halt = function halt() { 27.2311 + this.set(this.get()); 27.2312 + }; 27.2313 + 27.2314 + module.exports = Transitionable; 27.2315 +}); 27.2316 + 27.2317 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.2318 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.2319 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.2320 + * 27.2321 + * Owner: mark@famo.us 27.2322 + * @license MPL 2.0 27.2323 + * @copyright Famous Industries, Inc. 2014 27.2324 + */ 27.2325 + 27.2326 +define('famous/core/Context',['require','exports','module','./RenderNode','./EventHandler','./ElementAllocator','./Transform','famous/transitions/Transitionable'],function(require, exports, module) { 27.2327 + var RenderNode = require('./RenderNode'); 27.2328 + var EventHandler = require('./EventHandler'); 27.2329 + var ElementAllocator = require('./ElementAllocator'); 27.2330 + var Transform = require('./Transform'); 27.2331 + var Transitionable = require('famous/transitions/Transitionable'); 27.2332 + 27.2333 + var _originZeroZero = [0, 0]; 27.2334 + 27.2335 + function _getElementSize(element) { 27.2336 + return [element.clientWidth, element.clientHeight]; 27.2337 + } 27.2338 + 27.2339 + /** 27.2340 + * The top-level container for a Famous-renderable piece of the document. 27.2341 + * It is directly updated by the process-wide Engine object, and manages one 27.2342 + * render tree root, which can contain other renderables. 27.2343 + * 27.2344 + * @class Context 27.2345 + * @constructor 27.2346 + * @private 27.2347 + * @param {Node} container Element in which content will be inserted 27.2348 + */ 27.2349 + function Context(container) { 27.2350 + this.container = container; 27.2351 + this._allocator = new ElementAllocator(container); 27.2352 + 27.2353 + this._node = new RenderNode(); 27.2354 + this._eventOutput = new EventHandler(); 27.2355 + this._size = _getElementSize(this.container); 27.2356 + 27.2357 + this._perspectiveState = new Transitionable(0); 27.2358 + this._perspective = undefined; 27.2359 + 27.2360 + this._nodeContext = { 27.2361 + allocator: this._allocator, 27.2362 + transform: Transform.identity, 27.2363 + opacity: 1, 27.2364 + origin: _originZeroZero, 27.2365 + align: null, 27.2366 + size: this._size 27.2367 + }; 27.2368 + 27.2369 + this._eventOutput.on('resize', function() { 27.2370 + this.setSize(_getElementSize(this.container)); 27.2371 + }.bind(this)); 27.2372 + 27.2373 + } 27.2374 + 27.2375 + // Note: Unused 27.2376 + Context.prototype.getAllocator = function getAllocator() { 27.2377 + return this._allocator; 27.2378 + }; 27.2379 + 27.2380 + /** 27.2381 + * Add renderables to this Context's render tree. 27.2382 + * 27.2383 + * @method add 27.2384 + * 27.2385 + * @param {Object} obj renderable object 27.2386 + * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode 27.2387 + */ 27.2388 + Context.prototype.add = function add(obj) { 27.2389 + return this._node.add(obj); 27.2390 + }; 27.2391 + 27.2392 + /** 27.2393 + * Move this Context to another containing document element. 27.2394 + * 27.2395 + * @method migrate 27.2396 + * 27.2397 + * @param {Node} container Element to which content will be migrated 27.2398 + */ 27.2399 + Context.prototype.migrate = function migrate(container) { 27.2400 + if (container === this.container) return; 27.2401 + this.container = container; 27.2402 + this._allocator.migrate(container); 27.2403 + }; 27.2404 + 27.2405 + /** 27.2406 + * Gets viewport size for Context. 27.2407 + * 27.2408 + * @method getSize 27.2409 + * 27.2410 + * @return {Array.Number} viewport size as [width, height] 27.2411 + */ 27.2412 + Context.prototype.getSize = function getSize() { 27.2413 + return this._size; 27.2414 + }; 27.2415 + 27.2416 + /** 27.2417 + * Sets viewport size for Context. 27.2418 + * 27.2419 + * @method setSize 27.2420 + * 27.2421 + * @param {Array.Number} size [width, height]. If unspecified, use size of root document element. 27.2422 + */ 27.2423 + Context.prototype.setSize = function setSize(size) { 27.2424 + if (!size) size = _getElementSize(this.container); 27.2425 + this._size[0] = size[0]; 27.2426 + this._size[1] = size[1]; 27.2427 + }; 27.2428 + 27.2429 + /** 27.2430 + * Commit this Context's content changes to the document. 27.2431 + * 27.2432 + * @private 27.2433 + * @method update 27.2434 + * @param {Object} contextParameters engine commit specification 27.2435 + */ 27.2436 + Context.prototype.update = function update(contextParameters) { 27.2437 + if (contextParameters) { 27.2438 + if (contextParameters.transform) this._nodeContext.transform = contextParameters.transform; 27.2439 + if (contextParameters.opacity) this._nodeContext.opacity = contextParameters.opacity; 27.2440 + if (contextParameters.origin) this._nodeContext.origin = contextParameters.origin; 27.2441 + if (contextParameters.align) this._nodeContext.align = contextParameters.align; 27.2442 + if (contextParameters.size) this._nodeContext.size = contextParameters.size; 27.2443 + } 27.2444 + var perspective = this._perspectiveState.get(); 27.2445 + if (perspective !== this._perspective) { 27.2446 + this.container.style.perspective = perspective ? perspective.toFixed() + 'px' : ''; 27.2447 + this.container.style.webkitPerspective = perspective ? perspective.toFixed() : ''; 27.2448 + this._perspective = perspective; 27.2449 + } 27.2450 + 27.2451 + this._node.commit(this._nodeContext); 27.2452 + }; 27.2453 + 27.2454 + /** 27.2455 + * Get current perspective of this context in pixels. 27.2456 + * 27.2457 + * @method getPerspective 27.2458 + * @return {Number} depth perspective in pixels 27.2459 + */ 27.2460 + Context.prototype.getPerspective = function getPerspective() { 27.2461 + return this._perspectiveState.get(); 27.2462 + }; 27.2463 + 27.2464 + /** 27.2465 + * Set current perspective of this context in pixels. 27.2466 + * 27.2467 + * @method setPerspective 27.2468 + * @param {Number} perspective in pixels 27.2469 + * @param {Object} [transition] Transitionable object for applying the change 27.2470 + * @param {function(Object)} callback function called on completion of transition 27.2471 + */ 27.2472 + Context.prototype.setPerspective = function setPerspective(perspective, transition, callback) { 27.2473 + return this._perspectiveState.set(perspective, transition, callback); 27.2474 + }; 27.2475 + 27.2476 + /** 27.2477 + * Trigger an event, sending to all downstream handlers 27.2478 + * listening for provided 'type' key. 27.2479 + * 27.2480 + * @method emit 27.2481 + * 27.2482 + * @param {string} type event type key (for example, 'click') 27.2483 + * @param {Object} event event data 27.2484 + * @return {EventHandler} this 27.2485 + */ 27.2486 + Context.prototype.emit = function emit(type, event) { 27.2487 + return this._eventOutput.emit(type, event); 27.2488 + }; 27.2489 + 27.2490 + /** 27.2491 + * Bind a callback function to an event type handled by this object. 27.2492 + * 27.2493 + * @method "on" 27.2494 + * 27.2495 + * @param {string} type event type key (for example, 'click') 27.2496 + * @param {function(string, Object)} handler callback 27.2497 + * @return {EventHandler} this 27.2498 + */ 27.2499 + Context.prototype.on = function on(type, handler) { 27.2500 + return this._eventOutput.on(type, handler); 27.2501 + }; 27.2502 + 27.2503 + /** 27.2504 + * Unbind an event by type and handler. 27.2505 + * This undoes the work of "on". 27.2506 + * 27.2507 + * @method removeListener 27.2508 + * 27.2509 + * @param {string} type event type key (for example, 'click') 27.2510 + * @param {function} handler function object to remove 27.2511 + * @return {EventHandler} internal event handler object (for chaining) 27.2512 + */ 27.2513 + Context.prototype.removeListener = function removeListener(type, handler) { 27.2514 + return this._eventOutput.removeListener(type, handler); 27.2515 + }; 27.2516 + 27.2517 + /** 27.2518 + * Add event handler object to set of downstream handlers. 27.2519 + * 27.2520 + * @method pipe 27.2521 + * 27.2522 + * @param {EventHandler} target event handler target object 27.2523 + * @return {EventHandler} passed event handler 27.2524 + */ 27.2525 + Context.prototype.pipe = function pipe(target) { 27.2526 + return this._eventOutput.pipe(target); 27.2527 + }; 27.2528 + 27.2529 + /** 27.2530 + * Remove handler object from set of downstream handlers. 27.2531 + * Undoes work of "pipe". 27.2532 + * 27.2533 + * @method unpipe 27.2534 + * 27.2535 + * @param {EventHandler} target target handler object 27.2536 + * @return {EventHandler} provided target 27.2537 + */ 27.2538 + Context.prototype.unpipe = function unpipe(target) { 27.2539 + return this._eventOutput.unpipe(target); 27.2540 + }; 27.2541 + 27.2542 + module.exports = Context; 27.2543 +}); 27.2544 + 27.2545 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.2546 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.2547 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.2548 + * 27.2549 + * Owner: mark@famo.us 27.2550 + * @license MPL 2.0 27.2551 + * @copyright Famous Industries, Inc. 2014 27.2552 + */ 27.2553 + 27.2554 +define('famous/core/OptionsManager',['require','exports','module','./EventHandler'],function(require, exports, module) { 27.2555 + var EventHandler = require('./EventHandler'); 27.2556 + 27.2557 + /** 27.2558 + * A collection of methods for setting options which can be extended 27.2559 + * onto other classes. 27.2560 + * 27.2561 + * 27.2562 + * **** WARNING **** 27.2563 + * You can only pass through objects that will compile into valid JSON. 27.2564 + * 27.2565 + * Valid options: 27.2566 + * Strings, 27.2567 + * Arrays, 27.2568 + * Objects, 27.2569 + * Numbers, 27.2570 + * Nested Objects, 27.2571 + * Nested Arrays. 27.2572 + * 27.2573 + * This excludes: 27.2574 + * Document Fragments, 27.2575 + * Functions 27.2576 + * @class OptionsManager 27.2577 + * @constructor 27.2578 + * @param {Object} value options dictionary 27.2579 + */ 27.2580 + function OptionsManager(value) { 27.2581 + this._value = value; 27.2582 + this.eventOutput = null; 27.2583 + } 27.2584 + 27.2585 + /** 27.2586 + * Create options manager from source dictionary with arguments overriden by patch dictionary. 27.2587 + * 27.2588 + * @static 27.2589 + * @method OptionsManager.patch 27.2590 + * 27.2591 + * @param {Object} source source arguments 27.2592 + * @param {...Object} data argument additions and overwrites 27.2593 + * @return {Object} source object 27.2594 + */ 27.2595 + OptionsManager.patch = function patchObject(source, data) { 27.2596 + var manager = new OptionsManager(source); 27.2597 + for (var i = 1; i < arguments.length; i++) manager.patch(arguments[i]); 27.2598 + return source; 27.2599 + }; 27.2600 + 27.2601 + function _createEventOutput() { 27.2602 + this.eventOutput = new EventHandler(); 27.2603 + this.eventOutput.bindThis(this); 27.2604 + EventHandler.setOutputHandler(this, this.eventOutput); 27.2605 + } 27.2606 + 27.2607 + /** 27.2608 + * Create OptionsManager from source with arguments overriden by patches. 27.2609 + * Triggers 'change' event on this object's event handler if the state of 27.2610 + * the OptionsManager changes as a result. 27.2611 + * 27.2612 + * @method patch 27.2613 + * 27.2614 + * @param {...Object} arguments list of patch objects 27.2615 + * @return {OptionsManager} this 27.2616 + */ 27.2617 + OptionsManager.prototype.patch = function patch() { 27.2618 + var myState = this._value; 27.2619 + for (var i = 0; i < arguments.length; i++) { 27.2620 + var data = arguments[i]; 27.2621 + for (var k in data) { 27.2622 + if ((k in myState) && (data[k] && data[k].constructor === Object) && (myState[k] && myState[k].constructor === Object)) { 27.2623 + if (!myState.hasOwnProperty(k)) myState[k] = Object.create(myState[k]); 27.2624 + this.key(k).patch(data[k]); 27.2625 + if (this.eventOutput) this.eventOutput.emit('change', {id: k, value: this.key(k).value()}); 27.2626 + } 27.2627 + else this.set(k, data[k]); 27.2628 + } 27.2629 + } 27.2630 + return this; 27.2631 + }; 27.2632 + 27.2633 + /** 27.2634 + * Alias for patch 27.2635 + * 27.2636 + * @method setOptions 27.2637 + * 27.2638 + */ 27.2639 + OptionsManager.prototype.setOptions = OptionsManager.prototype.patch; 27.2640 + 27.2641 + /** 27.2642 + * Return OptionsManager based on sub-object retrieved by key 27.2643 + * 27.2644 + * @method key 27.2645 + * 27.2646 + * @param {string} identifier key 27.2647 + * @return {OptionsManager} new options manager with the value 27.2648 + */ 27.2649 + OptionsManager.prototype.key = function key(identifier) { 27.2650 + var result = new OptionsManager(this._value[identifier]); 27.2651 + if (!(result._value instanceof Object) || result._value instanceof Array) result._value = {}; 27.2652 + return result; 27.2653 + }; 27.2654 + 27.2655 + /** 27.2656 + * Look up value by key 27.2657 + * @method get 27.2658 + * 27.2659 + * @param {string} key key 27.2660 + * @return {Object} associated object 27.2661 + */ 27.2662 + OptionsManager.prototype.get = function get(key) { 27.2663 + return this._value[key]; 27.2664 + }; 27.2665 + 27.2666 + /** 27.2667 + * Alias for get 27.2668 + * @method getOptions 27.2669 + */ 27.2670 + OptionsManager.prototype.getOptions = OptionsManager.prototype.get; 27.2671 + 27.2672 + /** 27.2673 + * Set key to value. Outputs 'change' event if a value is overwritten. 27.2674 + * 27.2675 + * @method set 27.2676 + * 27.2677 + * @param {string} key key string 27.2678 + * @param {Object} value value object 27.2679 + * @return {OptionsManager} new options manager based on the value object 27.2680 + */ 27.2681 + OptionsManager.prototype.set = function set(key, value) { 27.2682 + var originalValue = this.get(key); 27.2683 + this._value[key] = value; 27.2684 + if (this.eventOutput && value !== originalValue) this.eventOutput.emit('change', {id: key, value: value}); 27.2685 + return this; 27.2686 + }; 27.2687 + 27.2688 + /** 27.2689 + * Return entire object contents of this OptionsManager. 27.2690 + * 27.2691 + * @method value 27.2692 + * 27.2693 + * @return {Object} current state of options 27.2694 + */ 27.2695 + OptionsManager.prototype.value = function value() { 27.2696 + return this._value; 27.2697 + }; 27.2698 + 27.2699 + /** 27.2700 + * Bind a callback function to an event type handled by this object. 27.2701 + * 27.2702 + * @method "on" 27.2703 + * 27.2704 + * @param {string} type event type key (for example, 'change') 27.2705 + * @param {function(string, Object)} handler callback 27.2706 + * @return {EventHandler} this 27.2707 + */ 27.2708 + OptionsManager.prototype.on = function on() { 27.2709 + _createEventOutput.call(this); 27.2710 + return this.on.apply(this, arguments); 27.2711 + }; 27.2712 + 27.2713 + /** 27.2714 + * Unbind an event by type and handler. 27.2715 + * This undoes the work of "on". 27.2716 + * 27.2717 + * @method removeListener 27.2718 + * 27.2719 + * @param {string} type event type key (for example, 'change') 27.2720 + * @param {function} handler function object to remove 27.2721 + * @return {EventHandler} internal event handler object (for chaining) 27.2722 + */ 27.2723 + OptionsManager.prototype.removeListener = function removeListener() { 27.2724 + _createEventOutput.call(this); 27.2725 + return this.removeListener.apply(this, arguments); 27.2726 + }; 27.2727 + 27.2728 + /** 27.2729 + * Add event handler object to set of downstream handlers. 27.2730 + * 27.2731 + * @method pipe 27.2732 + * 27.2733 + * @param {EventHandler} target event handler target object 27.2734 + * @return {EventHandler} passed event handler 27.2735 + */ 27.2736 + OptionsManager.prototype.pipe = function pipe() { 27.2737 + _createEventOutput.call(this); 27.2738 + return this.pipe.apply(this, arguments); 27.2739 + }; 27.2740 + 27.2741 + /** 27.2742 + * Remove handler object from set of downstream handlers. 27.2743 + * Undoes work of "pipe" 27.2744 + * 27.2745 + * @method unpipe 27.2746 + * 27.2747 + * @param {EventHandler} target target handler object 27.2748 + * @return {EventHandler} provided target 27.2749 + */ 27.2750 + OptionsManager.prototype.unpipe = function unpipe() { 27.2751 + _createEventOutput.call(this); 27.2752 + return this.unpipe.apply(this, arguments); 27.2753 + }; 27.2754 + 27.2755 + module.exports = OptionsManager; 27.2756 +}); 27.2757 + 27.2758 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.2759 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.2760 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.2761 + * 27.2762 + * Owner: mark@famo.us 27.2763 + * @license MPL 2.0 27.2764 + * @copyright Famous Industries, Inc. 2014 27.2765 + */ 27.2766 + 27.2767 +define('famous/core/Engine',['require','exports','module','./Context','./EventHandler','./OptionsManager'],function(require, exports, module) { 27.2768 + 27.2769 + /** 27.2770 + * The singleton object initiated upon process 27.2771 + * startup which manages all active Context instances, runs 27.2772 + * the render dispatch loop, and acts as a listener and dispatcher 27.2773 + * for events. All methods are therefore static. 27.2774 + * 27.2775 + * On static initialization, window.requestAnimationFrame is called with 27.2776 + * the event loop function. 27.2777 + * 27.2778 + * Note: Any window in which Engine runs will prevent default 27.2779 + * scrolling behavior on the 'touchmove' event. 27.2780 + * 27.2781 + * @static 27.2782 + * @class Engine 27.2783 + */ 27.2784 + var Context = require('./Context'); 27.2785 + var EventHandler = require('./EventHandler'); 27.2786 + var OptionsManager = require('./OptionsManager'); 27.2787 + 27.2788 + var Engine = {}; 27.2789 + 27.2790 + var contexts = []; 27.2791 + var nextTickQueue = []; 27.2792 + var deferQueue = []; 27.2793 + 27.2794 + var lastTime = Date.now(); 27.2795 + var frameTime; 27.2796 + var frameTimeLimit; 27.2797 + var loopEnabled = true; 27.2798 + var eventForwarders = {}; 27.2799 + var eventHandler = new EventHandler(); 27.2800 + 27.2801 + var options = { 27.2802 + containerType: 'div', 27.2803 + containerClass: 'famous-container', 27.2804 + fpsCap: undefined, 27.2805 + runLoop: true 27.2806 + }; 27.2807 + var optionsManager = new OptionsManager(options); 27.2808 + 27.2809 + /** @const */ 27.2810 + var MAX_DEFER_FRAME_TIME = 10; 27.2811 + 27.2812 + /** 27.2813 + * Inside requestAnimationFrame loop, step() is called, which: 27.2814 + * calculates current FPS (throttling loop if it is over limit set in setFPSCap), 27.2815 + * emits dataless 'prerender' event on start of loop, 27.2816 + * calls in order any one-shot functions registered by nextTick on last loop, 27.2817 + * calls Context.update on all Context objects registered, 27.2818 + * and emits dataless 'postrender' event on end of loop. 27.2819 + * 27.2820 + * @static 27.2821 + * @private 27.2822 + * @method step 27.2823 + */ 27.2824 + Engine.step = function step() { 27.2825 + var currentTime = Date.now(); 27.2826 + 27.2827 + // skip frame if we're over our framerate cap 27.2828 + if (frameTimeLimit && currentTime - lastTime < frameTimeLimit) return; 27.2829 + 27.2830 + var i = 0; 27.2831 + 27.2832 + frameTime = currentTime - lastTime; 27.2833 + lastTime = currentTime; 27.2834 + 27.2835 + eventHandler.emit('prerender'); 27.2836 + 27.2837 + // empty the queue 27.2838 + for (i = 0; i < nextTickQueue.length; i++) nextTickQueue[i].call(this); 27.2839 + nextTickQueue.splice(0); 27.2840 + 27.2841 + // limit total execution time for deferrable functions 27.2842 + while (deferQueue.length && (Date.now() - currentTime) < MAX_DEFER_FRAME_TIME) { 27.2843 + deferQueue.shift().call(this); 27.2844 + } 27.2845 + 27.2846 + for (i = 0; i < contexts.length; i++) contexts[i].update(); 27.2847 + 27.2848 + eventHandler.emit('postrender'); 27.2849 + }; 27.2850 + 27.2851 + // engage requestAnimationFrame 27.2852 + function loop() { 27.2853 + if (options.runLoop) { 27.2854 + Engine.step(); 27.2855 + requestAnimationFrame(loop); 27.2856 + } 27.2857 + else loopEnabled = false; 27.2858 + } 27.2859 + requestAnimationFrame(loop); 27.2860 + 27.2861 + // 27.2862 + // Upon main document window resize (unless on an "input" HTML element): 27.2863 + // scroll to the top left corner of the window, 27.2864 + // and for each managed Context: emit the 'resize' event and update its size. 27.2865 + // @param {Object=} event document event 27.2866 + // 27.2867 + function handleResize(event) { 27.2868 + for (var i = 0; i < contexts.length; i++) { 27.2869 + contexts[i].emit('resize'); 27.2870 + } 27.2871 + eventHandler.emit('resize'); 27.2872 + } 27.2873 + window.addEventListener('resize', handleResize, false); 27.2874 + handleResize(); 27.2875 + 27.2876 + // prevent scrolling via browser 27.2877 + window.addEventListener('touchmove', function(event) { 27.2878 + event.preventDefault(); 27.2879 + }, true); 27.2880 + 27.2881 + /** 27.2882 + * Add event handler object to set of downstream handlers. 27.2883 + * 27.2884 + * @method pipe 27.2885 + * 27.2886 + * @param {EventHandler} target event handler target object 27.2887 + * @return {EventHandler} passed event handler 27.2888 + */ 27.2889 + Engine.pipe = function pipe(target) { 27.2890 + if (target.subscribe instanceof Function) return target.subscribe(Engine); 27.2891 + else return eventHandler.pipe(target); 27.2892 + }; 27.2893 + 27.2894 + /** 27.2895 + * Remove handler object from set of downstream handlers. 27.2896 + * Undoes work of "pipe". 27.2897 + * 27.2898 + * @method unpipe 27.2899 + * 27.2900 + * @param {EventHandler} target target handler object 27.2901 + * @return {EventHandler} provided target 27.2902 + */ 27.2903 + Engine.unpipe = function unpipe(target) { 27.2904 + if (target.unsubscribe instanceof Function) return target.unsubscribe(Engine); 27.2905 + else return eventHandler.unpipe(target); 27.2906 + }; 27.2907 + 27.2908 + /** 27.2909 + * Bind a callback function to an event type handled by this object. 27.2910 + * 27.2911 + * @static 27.2912 + * @method "on" 27.2913 + * 27.2914 + * @param {string} type event type key (for example, 'click') 27.2915 + * @param {function(string, Object)} handler callback 27.2916 + * @return {EventHandler} this 27.2917 + */ 27.2918 + Engine.on = function on(type, handler) { 27.2919 + if (!(type in eventForwarders)) { 27.2920 + eventForwarders[type] = eventHandler.emit.bind(eventHandler, type); 27.2921 + if (document.body) { 27.2922 + document.body.addEventListener(type, eventForwarders[type]); 27.2923 + } 27.2924 + else { 27.2925 + Engine.nextTick(function(type, forwarder) { 27.2926 + document.body.addEventListener(type, forwarder); 27.2927 + }.bind(this, type, eventForwarders[type])); 27.2928 + } 27.2929 + } 27.2930 + return eventHandler.on(type, handler); 27.2931 + }; 27.2932 + 27.2933 + /** 27.2934 + * Trigger an event, sending to all downstream handlers 27.2935 + * listening for provided 'type' key. 27.2936 + * 27.2937 + * @method emit 27.2938 + * 27.2939 + * @param {string} type event type key (for example, 'click') 27.2940 + * @param {Object} event event data 27.2941 + * @return {EventHandler} this 27.2942 + */ 27.2943 + Engine.emit = function emit(type, event) { 27.2944 + return eventHandler.emit(type, event); 27.2945 + }; 27.2946 + 27.2947 + /** 27.2948 + * Unbind an event by type and handler. 27.2949 + * This undoes the work of "on". 27.2950 + * 27.2951 + * @static 27.2952 + * @method removeListener 27.2953 + * 27.2954 + * @param {string} type event type key (for example, 'click') 27.2955 + * @param {function} handler function object to remove 27.2956 + * @return {EventHandler} internal event handler object (for chaining) 27.2957 + */ 27.2958 + Engine.removeListener = function removeListener(type, handler) { 27.2959 + return eventHandler.removeListener(type, handler); 27.2960 + }; 27.2961 + 27.2962 + /** 27.2963 + * Return the current calculated frames per second of the Engine. 27.2964 + * 27.2965 + * @static 27.2966 + * @method getFPS 27.2967 + * 27.2968 + * @return {Number} calculated fps 27.2969 + */ 27.2970 + Engine.getFPS = function getFPS() { 27.2971 + return 1000 / frameTime; 27.2972 + }; 27.2973 + 27.2974 + /** 27.2975 + * Set the maximum fps at which the system should run. If internal render 27.2976 + * loop is called at a greater frequency than this FPSCap, Engine will 27.2977 + * throttle render and update until this rate is achieved. 27.2978 + * 27.2979 + * @static 27.2980 + * @method setFPSCap 27.2981 + * 27.2982 + * @param {Number} fps maximum frames per second 27.2983 + */ 27.2984 + Engine.setFPSCap = function setFPSCap(fps) { 27.2985 + frameTimeLimit = Math.floor(1000 / fps); 27.2986 + }; 27.2987 + 27.2988 + /** 27.2989 + * Return engine options. 27.2990 + * 27.2991 + * @static 27.2992 + * @method getOptions 27.2993 + * @param {string} key 27.2994 + * @return {Object} engine options 27.2995 + */ 27.2996 + Engine.getOptions = function getOptions() { 27.2997 + return optionsManager.getOptions.apply(optionsManager, arguments); 27.2998 + }; 27.2999 + 27.3000 + /** 27.3001 + * Set engine options 27.3002 + * 27.3003 + * @static 27.3004 + * @method setOptions 27.3005 + * 27.3006 + * @param {Object} [options] overrides of default options 27.3007 + * @param {Number} [options.fpsCap] maximum fps at which the system should run 27.3008 + * @param {boolean} [options.runLoop=true] whether the run loop should continue 27.3009 + * @param {string} [options.containerType="div"] type of container element. Defaults to 'div'. 27.3010 + * @param {string} [options.containerClass="famous-container"] type of container element. Defaults to 'famous-container'. 27.3011 + */ 27.3012 + Engine.setOptions = function setOptions(options) { 27.3013 + return optionsManager.setOptions.apply(optionsManager, arguments); 27.3014 + }; 27.3015 + 27.3016 + /** 27.3017 + * Creates a new Context for rendering and event handling with 27.3018 + * provided document element as top of each tree. This will be tracked by the 27.3019 + * process-wide Engine. 27.3020 + * 27.3021 + * @static 27.3022 + * @method createContext 27.3023 + * 27.3024 + * @param {Node} el will be top of Famo.us document element tree 27.3025 + * @return {Context} new Context within el 27.3026 + */ 27.3027 + Engine.createContext = function createContext(el) { 27.3028 + var needMountContainer = false; 27.3029 + if (!el) { 27.3030 + el = document.createElement(options.containerType); 27.3031 + el.classList.add(options.containerClass); 27.3032 + needMountContainer = true; 27.3033 + } 27.3034 + var context = new Context(el); 27.3035 + Engine.registerContext(context); 27.3036 + if (needMountContainer) { 27.3037 + Engine.nextTick(function(context, el) { 27.3038 + document.body.appendChild(el); 27.3039 + context.emit('resize'); 27.3040 + }.bind(this, context, el)); 27.3041 + } 27.3042 + return context; 27.3043 + }; 27.3044 + 27.3045 + /** 27.3046 + * Registers an existing context to be updated within the run loop. 27.3047 + * 27.3048 + * @static 27.3049 + * @method registerContext 27.3050 + * 27.3051 + * @param {Context} context Context to register 27.3052 + * @return {FamousContext} provided context 27.3053 + */ 27.3054 + Engine.registerContext = function registerContext(context) { 27.3055 + contexts.push(context); 27.3056 + return context; 27.3057 + }; 27.3058 + 27.3059 + /** 27.3060 + * Queue a function to be executed on the next tick of the 27.3061 + * Engine. 27.3062 + * 27.3063 + * @static 27.3064 + * @method nextTick 27.3065 + * 27.3066 + * @param {function(Object)} fn function accepting window object 27.3067 + */ 27.3068 + Engine.nextTick = function nextTick(fn) { 27.3069 + nextTickQueue.push(fn); 27.3070 + }; 27.3071 + 27.3072 + /** 27.3073 + * Queue a function to be executed sometime soon, at a time that is 27.3074 + * unlikely to affect frame rate. 27.3075 + * 27.3076 + * @static 27.3077 + * @method defer 27.3078 + * 27.3079 + * @param {Function} fn 27.3080 + */ 27.3081 + Engine.defer = function defer(fn) { 27.3082 + deferQueue.push(fn); 27.3083 + }; 27.3084 + 27.3085 + optionsManager.on('change', function(data) { 27.3086 + if (data.id === 'fpsCap') Engine.setFPSCap(data.value); 27.3087 + else if (data.id === 'runLoop') { 27.3088 + // kick off the loop only if it was stopped 27.3089 + if (!loopEnabled && data.value) { 27.3090 + loopEnabled = true; 27.3091 + requestAnimationFrame(loop); 27.3092 + } 27.3093 + } 27.3094 + }); 27.3095 + 27.3096 + module.exports = Engine; 27.3097 +}); 27.3098 + 27.3099 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.3100 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.3101 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.3102 + * 27.3103 + * Owner: mark@famo.us 27.3104 + * @license MPL 2.0 27.3105 + * @copyright Famous Industries, Inc. 2014 27.3106 + */ 27.3107 + 27.3108 +define('famous/core/Surface',['require','exports','module','./Entity','./EventHandler','./Transform'],function(require, exports, module) { 27.3109 + var Entity = require('./Entity'); 27.3110 + var EventHandler = require('./EventHandler'); 27.3111 + var Transform = require('./Transform'); 27.3112 + 27.3113 + var devicePixelRatio = window.devicePixelRatio || 1; 27.3114 + var usePrefix = document.createElement('div').style.webkitTransform !== undefined; 27.3115 + 27.3116 + /** 27.3117 + * A base class for viewable content and event 27.3118 + * targets inside a Famo.us application, containing a renderable document 27.3119 + * fragment. Like an HTML div, it can accept internal markup, 27.3120 + * properties, classes, and handle events. 27.3121 + * 27.3122 + * @class Surface 27.3123 + * @constructor 27.3124 + * 27.3125 + * @param {Object} [options] default option overrides 27.3126 + * @param {Array.Number} [options.size] [width, height] in pixels 27.3127 + * @param {Array.string} [options.classes] CSS classes to set on inner content 27.3128 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 27.3129 + * @param {string} [options.content] inner (HTML) content of surface 27.3130 + */ 27.3131 + function Surface(options) { 27.3132 + this.options = {}; 27.3133 + 27.3134 + this.properties = {}; 27.3135 + this.content = ''; 27.3136 + this.classList = []; 27.3137 + this.size = null; 27.3138 + 27.3139 + this._classesDirty = true; 27.3140 + this._stylesDirty = true; 27.3141 + this._sizeDirty = true; 27.3142 + this._contentDirty = true; 27.3143 + 27.3144 + this._dirtyClasses = []; 27.3145 + 27.3146 + this._matrix = null; 27.3147 + this._opacity = 1; 27.3148 + this._origin = null; 27.3149 + this._size = null; 27.3150 + 27.3151 + /** @ignore */ 27.3152 + this.eventForwarder = function eventForwarder(event) { 27.3153 + this.emit(event.type, event); 27.3154 + }.bind(this); 27.3155 + this.eventHandler = new EventHandler(); 27.3156 + this.eventHandler.bindThis(this); 27.3157 + 27.3158 + this.id = Entity.register(this); 27.3159 + 27.3160 + if (options) this.setOptions(options); 27.3161 + 27.3162 + this._currTarget = null; 27.3163 + } 27.3164 + Surface.prototype.elementType = 'div'; 27.3165 + Surface.prototype.elementClass = 'famous-surface'; 27.3166 + 27.3167 + /** 27.3168 + * Bind a callback function to an event type handled by this object. 27.3169 + * 27.3170 + * @method "on" 27.3171 + * 27.3172 + * @param {string} type event type key (for example, 'click') 27.3173 + * @param {function(string, Object)} fn handler callback 27.3174 + * @return {EventHandler} this 27.3175 + */ 27.3176 + Surface.prototype.on = function on(type, fn) { 27.3177 + if (this._currTarget) this._currTarget.addEventListener(type, this.eventForwarder); 27.3178 + this.eventHandler.on(type, fn); 27.3179 + }; 27.3180 + 27.3181 + /** 27.3182 + * Unbind an event by type and handler. 27.3183 + * This undoes the work of "on" 27.3184 + * 27.3185 + * @method removeListener 27.3186 + * @param {string} type event type key (for example, 'click') 27.3187 + * @param {function(string, Object)} fn handler 27.3188 + */ 27.3189 + Surface.prototype.removeListener = function removeListener(type, fn) { 27.3190 + this.eventHandler.removeListener(type, fn); 27.3191 + }; 27.3192 + 27.3193 + /** 27.3194 + * Trigger an event, sending to all downstream handlers 27.3195 + * listening for provided 'type' key. 27.3196 + * 27.3197 + * @method emit 27.3198 + * 27.3199 + * @param {string} type event type key (for example, 'click') 27.3200 + * @param {Object} [event] event data 27.3201 + * @return {EventHandler} this 27.3202 + */ 27.3203 + Surface.prototype.emit = function emit(type, event) { 27.3204 + if (event && !event.origin) event.origin = this; 27.3205 + var handled = this.eventHandler.emit(type, event); 27.3206 + if (handled && event && event.stopPropagation) event.stopPropagation(); 27.3207 + return handled; 27.3208 + }; 27.3209 + 27.3210 + /** 27.3211 + * Add event handler object to set of downstream handlers. 27.3212 + * 27.3213 + * @method pipe 27.3214 + * 27.3215 + * @param {EventHandler} target event handler target object 27.3216 + * @return {EventHandler} passed event handler 27.3217 + */ 27.3218 + Surface.prototype.pipe = function pipe(target) { 27.3219 + return this.eventHandler.pipe(target); 27.3220 + }; 27.3221 + 27.3222 + /** 27.3223 + * Remove handler object from set of downstream handlers. 27.3224 + * Undoes work of "pipe" 27.3225 + * 27.3226 + * @method unpipe 27.3227 + * 27.3228 + * @param {EventHandler} target target handler object 27.3229 + * @return {EventHandler} provided target 27.3230 + */ 27.3231 + Surface.prototype.unpipe = function unpipe(target) { 27.3232 + return this.eventHandler.unpipe(target); 27.3233 + }; 27.3234 + 27.3235 + /** 27.3236 + * Return spec for this surface. Note that for a base surface, this is 27.3237 + * simply an id. 27.3238 + * 27.3239 + * @method render 27.3240 + * @private 27.3241 + * @return {Object} render spec for this surface (spec id) 27.3242 + */ 27.3243 + Surface.prototype.render = function render() { 27.3244 + return this.id; 27.3245 + }; 27.3246 + 27.3247 + /** 27.3248 + * Set CSS-style properties on this Surface. Note that this will cause 27.3249 + * dirtying and thus re-rendering, even if values do not change. 27.3250 + * 27.3251 + * @method setProperties 27.3252 + * @param {Object} properties property dictionary of "key" => "value" 27.3253 + */ 27.3254 + Surface.prototype.setProperties = function setProperties(properties) { 27.3255 + for (var n in properties) { 27.3256 + this.properties[n] = properties[n]; 27.3257 + } 27.3258 + this._stylesDirty = true; 27.3259 + }; 27.3260 + 27.3261 + /** 27.3262 + * Get CSS-style properties on this Surface. 27.3263 + * 27.3264 + * @method getProperties 27.3265 + * 27.3266 + * @return {Object} Dictionary of this Surface's properties. 27.3267 + */ 27.3268 + Surface.prototype.getProperties = function getProperties() { 27.3269 + return this.properties; 27.3270 + }; 27.3271 + 27.3272 + /** 27.3273 + * Add CSS-style class to the list of classes on this Surface. Note 27.3274 + * this will map directly to the HTML property of the actual 27.3275 + * corresponding rendered <div>. 27.3276 + * 27.3277 + * @method addClass 27.3278 + * @param {string} className name of class to add 27.3279 + */ 27.3280 + Surface.prototype.addClass = function addClass(className) { 27.3281 + if (this.classList.indexOf(className) < 0) { 27.3282 + this.classList.push(className); 27.3283 + this._classesDirty = true; 27.3284 + } 27.3285 + }; 27.3286 + 27.3287 + /** 27.3288 + * Remove CSS-style class from the list of classes on this Surface. 27.3289 + * Note this will map directly to the HTML property of the actual 27.3290 + * corresponding rendered <div>. 27.3291 + * 27.3292 + * @method removeClass 27.3293 + * @param {string} className name of class to remove 27.3294 + */ 27.3295 + Surface.prototype.removeClass = function removeClass(className) { 27.3296 + var i = this.classList.indexOf(className); 27.3297 + if (i >= 0) { 27.3298 + this._dirtyClasses.push(this.classList.splice(i, 1)[0]); 27.3299 + this._classesDirty = true; 27.3300 + } 27.3301 + }; 27.3302 + 27.3303 + /** 27.3304 + * Reset class list to provided dictionary. 27.3305 + * @method setClasses 27.3306 + * @param {Array.string} classList 27.3307 + */ 27.3308 + Surface.prototype.setClasses = function setClasses(classList) { 27.3309 + var i = 0; 27.3310 + var removal = []; 27.3311 + for (i = 0; i < this.classList.length; i++) { 27.3312 + if (classList.indexOf(this.classList[i]) < 0) removal.push(this.classList[i]); 27.3313 + } 27.3314 + for (i = 0; i < removal.length; i++) this.removeClass(removal[i]); 27.3315 + // duplicates are already checked by addClass() 27.3316 + for (i = 0; i < classList.length; i++) this.addClass(classList[i]); 27.3317 + }; 27.3318 + 27.3319 + /** 27.3320 + * Get array of CSS-style classes attached to this div. 27.3321 + * 27.3322 + * @method getClasslist 27.3323 + * @return {Array.string} array of class names 27.3324 + */ 27.3325 + Surface.prototype.getClassList = function getClassList() { 27.3326 + return this.classList; 27.3327 + }; 27.3328 + 27.3329 + /** 27.3330 + * Set or overwrite inner (HTML) content of this surface. Note that this 27.3331 + * causes a re-rendering if the content has changed. 27.3332 + * 27.3333 + * @method setContent 27.3334 + * @param {string|Document Fragment} content HTML content 27.3335 + */ 27.3336 + Surface.prototype.setContent = function setContent(content) { 27.3337 + if (this.content !== content) { 27.3338 + this.content = content; 27.3339 + this._contentDirty = true; 27.3340 + } 27.3341 + }; 27.3342 + 27.3343 + /** 27.3344 + * Return inner (HTML) content of this surface. 27.3345 + * 27.3346 + * @method getContent 27.3347 + * 27.3348 + * @return {string} inner (HTML) content 27.3349 + */ 27.3350 + Surface.prototype.getContent = function getContent() { 27.3351 + return this.content; 27.3352 + }; 27.3353 + 27.3354 + /** 27.3355 + * Set options for this surface 27.3356 + * 27.3357 + * @method setOptions 27.3358 + * @param {Object} [options] overrides for default options. See constructor. 27.3359 + */ 27.3360 + Surface.prototype.setOptions = function setOptions(options) { 27.3361 + if (options.size) this.setSize(options.size); 27.3362 + if (options.classes) this.setClasses(options.classes); 27.3363 + if (options.properties) this.setProperties(options.properties); 27.3364 + if (options.content) this.setContent(options.content); 27.3365 + }; 27.3366 + 27.3367 + // Attach Famous event handling to document events emanating from target 27.3368 + // document element. This occurs just after deployment to the document. 27.3369 + // Calling this enables methods like #on and #pipe. 27.3370 + function _addEventListeners(target) { 27.3371 + for (var i in this.eventHandler.listeners) { 27.3372 + target.addEventListener(i, this.eventForwarder); 27.3373 + } 27.3374 + } 27.3375 + 27.3376 + // Detach Famous event handling from document events emanating from target 27.3377 + // document element. This occurs just before recall from the document. 27.3378 + function _removeEventListeners(target) { 27.3379 + for (var i in this.eventHandler.listeners) { 27.3380 + target.removeEventListener(i, this.eventForwarder); 27.3381 + } 27.3382 + } 27.3383 + 27.3384 + // Apply to document all changes from removeClass() since last setup(). 27.3385 + function _cleanupClasses(target) { 27.3386 + for (var i = 0; i < this._dirtyClasses.length; i++) target.classList.remove(this._dirtyClasses[i]); 27.3387 + this._dirtyClasses = []; 27.3388 + } 27.3389 + 27.3390 + // Apply values of all Famous-managed styles to the document element. 27.3391 + // These will be deployed to the document on call to #setup(). 27.3392 + function _applyStyles(target) { 27.3393 + for (var n in this.properties) { 27.3394 + target.style[n] = this.properties[n]; 27.3395 + } 27.3396 + } 27.3397 + 27.3398 + // Clear all Famous-managed styles from the document element. 27.3399 + // These will be deployed to the document on call to #setup(). 27.3400 + function _cleanupStyles(target) { 27.3401 + for (var n in this.properties) { 27.3402 + target.style[n] = ''; 27.3403 + } 27.3404 + } 27.3405 + 27.3406 + /** 27.3407 + * Return a Matrix's webkit css representation to be used with the 27.3408 + * CSS3 -webkit-transform style. 27.3409 + * Example: -webkit-transform: matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,716,243,0,1) 27.3410 + * 27.3411 + * @method _formatCSSTransform 27.3412 + * @private 27.3413 + * @param {FamousMatrix} m matrix 27.3414 + * @return {string} matrix3d CSS style representation of the transform 27.3415 + */ 27.3416 + function _formatCSSTransform(m) { 27.3417 + m[12] = Math.round(m[12] * devicePixelRatio) / devicePixelRatio; 27.3418 + m[13] = Math.round(m[13] * devicePixelRatio) / devicePixelRatio; 27.3419 + 27.3420 + var result = 'matrix3d('; 27.3421 + for (var i = 0; i < 15; i++) { 27.3422 + result += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; 27.3423 + } 27.3424 + result += m[15] + ')'; 27.3425 + return result; 27.3426 + } 27.3427 + 27.3428 + /** 27.3429 + * Directly apply given FamousMatrix to the document element as the 27.3430 + * appropriate webkit CSS style. 27.3431 + * 27.3432 + * @method setMatrix 27.3433 + * 27.3434 + * @static 27.3435 + * @private 27.3436 + * @param {Element} element document element 27.3437 + * @param {FamousMatrix} matrix 27.3438 + */ 27.3439 + 27.3440 + var _setMatrix; 27.3441 + if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { 27.3442 + _setMatrix = function(element, matrix) { 27.3443 + element.style.zIndex = (matrix[14] * 1000000) | 0; // fix for Firefox z-buffer issues 27.3444 + element.style.transform = _formatCSSTransform(matrix); 27.3445 + }; 27.3446 + } 27.3447 + else if (usePrefix) { 27.3448 + _setMatrix = function(element, matrix) { 27.3449 + element.style.webkitTransform = _formatCSSTransform(matrix); 27.3450 + }; 27.3451 + } 27.3452 + else { 27.3453 + _setMatrix = function(element, matrix) { 27.3454 + element.style.transform = _formatCSSTransform(matrix); 27.3455 + }; 27.3456 + } 27.3457 + 27.3458 + // format origin as CSS percentage string 27.3459 + function _formatCSSOrigin(origin) { 27.3460 + return (100 * origin[0]) + '% ' + (100 * origin[1]) + '%'; 27.3461 + } 27.3462 + 27.3463 + // Directly apply given origin coordinates to the document element as the 27.3464 + // appropriate webkit CSS style. 27.3465 + var _setOrigin = usePrefix ? function(element, origin) { 27.3466 + element.style.webkitTransformOrigin = _formatCSSOrigin(origin); 27.3467 + } : function(element, origin) { 27.3468 + element.style.transformOrigin = _formatCSSOrigin(origin); 27.3469 + }; 27.3470 + 27.3471 + // Shrink given document element until it is effectively invisible. 27.3472 + var _setInvisible = usePrefix ? function(element) { 27.3473 + element.style.webkitTransform = 'scale3d(0.0001,0.0001,1)'; 27.3474 + element.style.opacity = 0; 27.3475 + } : function(element) { 27.3476 + element.style.transform = 'scale3d(0.0001,0.0001,1)'; 27.3477 + element.style.opacity = 0; 27.3478 + }; 27.3479 + 27.3480 + function _xyNotEquals(a, b) { 27.3481 + return (a && b) ? (a[0] !== b[0] || a[1] !== b[1]) : a !== b; 27.3482 + } 27.3483 + 27.3484 + /** 27.3485 + * One-time setup for an element to be ready for commits to document. 27.3486 + * 27.3487 + * @private 27.3488 + * @method setup 27.3489 + * 27.3490 + * @param {ElementAllocator} allocator document element pool for this context 27.3491 + */ 27.3492 + Surface.prototype.setup = function setup(allocator) { 27.3493 + var target = allocator.allocate(this.elementType); 27.3494 + if (this.elementClass) { 27.3495 + if (this.elementClass instanceof Array) { 27.3496 + for (var i = 0; i < this.elementClass.length; i++) { 27.3497 + target.classList.add(this.elementClass[i]); 27.3498 + } 27.3499 + } 27.3500 + else { 27.3501 + target.classList.add(this.elementClass); 27.3502 + } 27.3503 + } 27.3504 + target.style.display = ''; 27.3505 + _addEventListeners.call(this, target); 27.3506 + this._currTarget = target; 27.3507 + this._stylesDirty = true; 27.3508 + this._classesDirty = true; 27.3509 + this._sizeDirty = true; 27.3510 + this._contentDirty = true; 27.3511 + this._matrix = null; 27.3512 + this._opacity = undefined; 27.3513 + this._origin = null; 27.3514 + this._size = null; 27.3515 + }; 27.3516 + 27.3517 + /** 27.3518 + * Apply changes from this component to the corresponding document element. 27.3519 + * This includes changes to classes, styles, size, content, opacity, origin, 27.3520 + * and matrix transforms. 27.3521 + * 27.3522 + * @private 27.3523 + * @method commit 27.3524 + * @param {Context} context commit context 27.3525 + */ 27.3526 + Surface.prototype.commit = function commit(context) { 27.3527 + if (!this._currTarget) this.setup(context.allocator); 27.3528 + var target = this._currTarget; 27.3529 + 27.3530 + var matrix = context.transform; 27.3531 + var opacity = context.opacity; 27.3532 + var origin = context.origin; 27.3533 + var size = context.size; 27.3534 + 27.3535 + if (this._classesDirty) { 27.3536 + _cleanupClasses.call(this, target); 27.3537 + var classList = this.getClassList(); 27.3538 + for (var i = 0; i < classList.length; i++) target.classList.add(classList[i]); 27.3539 + this._classesDirty = false; 27.3540 + } 27.3541 + 27.3542 + if (this._stylesDirty) { 27.3543 + _applyStyles.call(this, target); 27.3544 + this._stylesDirty = false; 27.3545 + } 27.3546 + 27.3547 + if (this._contentDirty) { 27.3548 + this.deploy(target); 27.3549 + this.eventHandler.emit('deploy'); 27.3550 + this._contentDirty = false; 27.3551 + } 27.3552 + 27.3553 + if (this.size) { 27.3554 + var origSize = size; 27.3555 + size = [this.size[0], this.size[1]]; 27.3556 + if (size[0] === undefined && origSize[0]) size[0] = origSize[0]; 27.3557 + if (size[1] === undefined && origSize[1]) size[1] = origSize[1]; 27.3558 + } 27.3559 + 27.3560 + if (size[0] === true) size[0] = target.clientWidth; 27.3561 + if (size[1] === true) size[1] = target.clientHeight; 27.3562 + 27.3563 + if (_xyNotEquals(this._size, size)) { 27.3564 + if (!this._size) this._size = [0, 0]; 27.3565 + this._size[0] = size[0]; 27.3566 + this._size[1] = size[1]; 27.3567 + this._sizeDirty = true; 27.3568 + } 27.3569 + 27.3570 + if (!matrix && this._matrix) { 27.3571 + this._matrix = null; 27.3572 + this._opacity = 0; 27.3573 + _setInvisible(target); 27.3574 + return; 27.3575 + } 27.3576 + 27.3577 + if (this._opacity !== opacity) { 27.3578 + this._opacity = opacity; 27.3579 + target.style.opacity = (opacity >= 1) ? '0.999999' : opacity; 27.3580 + } 27.3581 + 27.3582 + if (_xyNotEquals(this._origin, origin) || Transform.notEquals(this._matrix, matrix) || this._sizeDirty) { 27.3583 + if (!matrix) matrix = Transform.identity; 27.3584 + this._matrix = matrix; 27.3585 + var aaMatrix = matrix; 27.3586 + if (origin) { 27.3587 + if (!this._origin) this._origin = [0, 0]; 27.3588 + this._origin[0] = origin[0]; 27.3589 + this._origin[1] = origin[1]; 27.3590 + aaMatrix = Transform.thenMove(matrix, [-this._size[0] * origin[0], -this._size[1] * origin[1], 0]); 27.3591 + _setOrigin(target, origin); 27.3592 + } 27.3593 + _setMatrix(target, aaMatrix); 27.3594 + } 27.3595 + 27.3596 + if (this._sizeDirty) { 27.3597 + if (this._size) { 27.3598 + target.style.width = (this.size && this.size[0] === true) ? '' : this._size[0] + 'px'; 27.3599 + target.style.height = (this.size && this.size[1] === true) ? '' : this._size[1] + 'px'; 27.3600 + } 27.3601 + this._sizeDirty = false; 27.3602 + } 27.3603 + }; 27.3604 + 27.3605 + /** 27.3606 + * Remove all Famous-relevant attributes from a document element. 27.3607 + * This is called by SurfaceManager's detach(). 27.3608 + * This is in some sense the reverse of .deploy(). 27.3609 + * 27.3610 + * @private 27.3611 + * @method cleanup 27.3612 + * @param {ElementAllocator} allocator 27.3613 + */ 27.3614 + Surface.prototype.cleanup = function cleanup(allocator) { 27.3615 + var i = 0; 27.3616 + var target = this._currTarget; 27.3617 + this.eventHandler.emit('recall'); 27.3618 + this.recall(target); 27.3619 + target.style.display = 'none'; 27.3620 + target.style.width = ''; 27.3621 + target.style.height = ''; 27.3622 + this._size = null; 27.3623 + _cleanupStyles.call(this, target); 27.3624 + var classList = this.getClassList(); 27.3625 + _cleanupClasses.call(this, target); 27.3626 + for (i = 0; i < classList.length; i++) target.classList.remove(classList[i]); 27.3627 + if (this.elementClass) { 27.3628 + if (this.elementClass instanceof Array) { 27.3629 + for (i = 0; i < this.elementClass.length; i++) { 27.3630 + target.classList.remove(this.elementClass[i]); 27.3631 + } 27.3632 + } 27.3633 + else { 27.3634 + target.classList.remove(this.elementClass); 27.3635 + } 27.3636 + } 27.3637 + _removeEventListeners.call(this, target); 27.3638 + this._currTarget = null; 27.3639 + allocator.deallocate(target); 27.3640 + _setInvisible(target); 27.3641 + }; 27.3642 + 27.3643 + /** 27.3644 + * Place the document element that this component manages into the document. 27.3645 + * 27.3646 + * @private 27.3647 + * @method deploy 27.3648 + * @param {Node} target document parent of this container 27.3649 + */ 27.3650 + Surface.prototype.deploy = function deploy(target) { 27.3651 + var content = this.getContent(); 27.3652 + if (content instanceof Node) { 27.3653 + while (target.hasChildNodes()) target.removeChild(target.firstChild); 27.3654 + target.appendChild(content); 27.3655 + } 27.3656 + else target.innerHTML = content; 27.3657 + }; 27.3658 + 27.3659 + /** 27.3660 + * Remove any contained document content associated with this surface 27.3661 + * from the actual document. 27.3662 + * 27.3663 + * @private 27.3664 + * @method recall 27.3665 + */ 27.3666 + Surface.prototype.recall = function recall(target) { 27.3667 + var df = document.createDocumentFragment(); 27.3668 + while (target.hasChildNodes()) df.appendChild(target.firstChild); 27.3669 + this.setContent(df); 27.3670 + }; 27.3671 + 27.3672 + /** 27.3673 + * Get the x and y dimensions of the surface. 27.3674 + * 27.3675 + * @method getSize 27.3676 + * @param {boolean} actual return computed size rather than provided 27.3677 + * @return {Array.Number} [x,y] size of surface 27.3678 + */ 27.3679 + Surface.prototype.getSize = function getSize(actual) { 27.3680 + return actual ? this._size : (this.size || this._size); 27.3681 + }; 27.3682 + 27.3683 + /** 27.3684 + * Set x and y dimensions of the surface. 27.3685 + * 27.3686 + * @method setSize 27.3687 + * @param {Array.Number} size as [width, height] 27.3688 + */ 27.3689 + Surface.prototype.setSize = function setSize(size) { 27.3690 + this.size = size ? [size[0], size[1]] : null; 27.3691 + this._sizeDirty = true; 27.3692 + }; 27.3693 + 27.3694 + module.exports = Surface; 27.3695 +}); 27.3696 + 27.3697 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.3698 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.3699 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.3700 + * 27.3701 + * Owner: mark@famo.us 27.3702 + * @license MPL 2.0 27.3703 + * @copyright Famous Industries, Inc. 2014 27.3704 + */ 27.3705 + 27.3706 +define('famous/core/Group',['require','exports','module','./Context','./Transform','./Surface'],function(require, exports, module) { 27.3707 + var Context = require('./Context'); 27.3708 + var Transform = require('./Transform'); 27.3709 + var Surface = require('./Surface'); 27.3710 + 27.3711 + /** 27.3712 + * A Context designed to contain surfaces and set properties 27.3713 + * to be applied to all of them at once. 27.3714 + * This is primarily used for specific performance improvements in the rendering engine. 27.3715 + * Private. 27.3716 + * 27.3717 + * @private 27.3718 + * @class Group 27.3719 + * @extends Surface 27.3720 + * @constructor 27.3721 + * @param {Object} [options] Surface options array (see Surface}) 27.3722 + */ 27.3723 + function Group(options) { 27.3724 + Surface.call(this, options); 27.3725 + this._shouldRecalculateSize = false; 27.3726 + this._container = document.createDocumentFragment(); 27.3727 + this.context = new Context(this._container); 27.3728 + this.setContent(this._container); 27.3729 + this._groupSize = [undefined, undefined]; 27.3730 + } 27.3731 + 27.3732 + /** @const */ 27.3733 + Group.SIZE_ZERO = [0, 0]; 27.3734 + 27.3735 + Group.prototype = Object.create(Surface.prototype); 27.3736 + Group.prototype.elementType = 'div'; 27.3737 + Group.prototype.elementClass = 'famous-group'; 27.3738 + 27.3739 + /** 27.3740 + * Add renderables to this component's render tree. 27.3741 + * 27.3742 + * @method add 27.3743 + * @private 27.3744 + * @param {Object} obj renderable object 27.3745 + * @return {RenderNode} Render wrapping provided object, if not already a RenderNode 27.3746 + */ 27.3747 + Group.prototype.add = function add() { 27.3748 + return this.context.add.apply(this.context, arguments); 27.3749 + }; 27.3750 + 27.3751 + /** 27.3752 + * Generate a render spec from the contents of this component. 27.3753 + * 27.3754 + * @private 27.3755 + * @method render 27.3756 + * @return {Number} Render spec for this component 27.3757 + */ 27.3758 + Group.prototype.render = function render() { 27.3759 + return Surface.prototype.render.call(this); 27.3760 + }; 27.3761 + 27.3762 + /** 27.3763 + * Place the document element this component manages into the document. 27.3764 + * 27.3765 + * @private 27.3766 + * @method deploy 27.3767 + * @param {Node} target document parent of this container 27.3768 + */ 27.3769 + Group.prototype.deploy = function deploy(target) { 27.3770 + this.context.migrate(target); 27.3771 + }; 27.3772 + 27.3773 + /** 27.3774 + * Remove this component and contained content from the document 27.3775 + * 27.3776 + * @private 27.3777 + * @method recall 27.3778 + * 27.3779 + * @param {Node} target node to which the component was deployed 27.3780 + */ 27.3781 + Group.prototype.recall = function recall(target) { 27.3782 + this._container = document.createDocumentFragment(); 27.3783 + this.context.migrate(this._container); 27.3784 + }; 27.3785 + 27.3786 + /** 27.3787 + * Apply changes from this component to the corresponding document element. 27.3788 + * 27.3789 + * @private 27.3790 + * @method commit 27.3791 + * 27.3792 + * @param {Object} context update spec passed in from above in the render tree. 27.3793 + */ 27.3794 + Group.prototype.commit = function commit(context) { 27.3795 + var transform = context.transform; 27.3796 + var origin = context.origin; 27.3797 + var opacity = context.opacity; 27.3798 + var size = context.size; 27.3799 + var result = Surface.prototype.commit.call(this, { 27.3800 + allocator: context.allocator, 27.3801 + transform: Transform.thenMove(transform, [-origin[0] * size[0], -origin[1] * size[1], 0]), 27.3802 + opacity: opacity, 27.3803 + origin: origin, 27.3804 + size: Group.SIZE_ZERO 27.3805 + }); 27.3806 + if (size[0] !== this._groupSize[0] || size[1] !== this._groupSize[1]) { 27.3807 + this._groupSize[0] = size[0]; 27.3808 + this._groupSize[1] = size[1]; 27.3809 + this.context.setSize(size); 27.3810 + } 27.3811 + this.context.update({ 27.3812 + transform: Transform.translate(-origin[0] * size[0], -origin[1] * size[1], 0), 27.3813 + origin: origin, 27.3814 + size: size 27.3815 + }); 27.3816 + return result; 27.3817 + }; 27.3818 + 27.3819 + module.exports = Group; 27.3820 +}); 27.3821 + 27.3822 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.3823 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.3824 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.3825 + * 27.3826 + * Owner: david@famo.us 27.3827 + * @license MPL 2.0 27.3828 + * @copyright Famous Industries, Inc. 2014 27.3829 + */ 27.3830 + 27.3831 +define('famous/transitions/TransitionableTransform',['require','exports','module','./Transitionable','famous/core/Transform','famous/utilities/Utility'],function(require, exports, module) { 27.3832 + var Transitionable = require('./Transitionable'); 27.3833 + var Transform = require('famous/core/Transform'); 27.3834 + var Utility = require('famous/utilities/Utility'); 27.3835 + 27.3836 + /** 27.3837 + * A class for transitioning the state of a Transform by transitioning 27.3838 + * its translate, scale, skew and rotate components independently. 27.3839 + * 27.3840 + * @class TransitionableTransform 27.3841 + * @constructor 27.3842 + * 27.3843 + * @param [transform=Transform.identity] {Transform} The initial transform state 27.3844 + */ 27.3845 + function TransitionableTransform(transform) { 27.3846 + this._final = Transform.identity.slice(); 27.3847 + this.translate = new Transitionable([0, 0, 0]); 27.3848 + this.rotate = new Transitionable([0, 0, 0]); 27.3849 + this.skew = new Transitionable([0, 0, 0]); 27.3850 + this.scale = new Transitionable([1, 1, 1]); 27.3851 + 27.3852 + if (transform) this.set(transform); 27.3853 + } 27.3854 + 27.3855 + function _build() { 27.3856 + return Transform.build({ 27.3857 + translate: this.translate.get(), 27.3858 + rotate: this.rotate.get(), 27.3859 + skew: this.skew.get(), 27.3860 + scale: this.scale.get() 27.3861 + }); 27.3862 + } 27.3863 + 27.3864 + /** 27.3865 + * An optimized way of setting only the translation component of a Transform 27.3866 + * 27.3867 + * @method setTranslate 27.3868 + * @chainable 27.3869 + * 27.3870 + * @param translate {Array} New translation state 27.3871 + * @param [transition] {Object} Transition definition 27.3872 + * @param [callback] {Function} Callback 27.3873 + * @return {TransitionableTransform} 27.3874 + */ 27.3875 + TransitionableTransform.prototype.setTranslate = function setTranslate(translate, transition, callback) { 27.3876 + this.translate.set(translate, transition, callback); 27.3877 + this._final = this._final.slice(); 27.3878 + this._final[12] = translate[0]; 27.3879 + this._final[13] = translate[1]; 27.3880 + if (translate[2] !== undefined) this._final[14] = translate[2]; 27.3881 + return this; 27.3882 + }; 27.3883 + 27.3884 + /** 27.3885 + * An optimized way of setting only the scale component of a Transform 27.3886 + * 27.3887 + * @method setScale 27.3888 + * @chainable 27.3889 + * 27.3890 + * @param scale {Array} New scale state 27.3891 + * @param [transition] {Object} Transition definition 27.3892 + * @param [callback] {Function} Callback 27.3893 + * @return {TransitionableTransform} 27.3894 + */ 27.3895 + TransitionableTransform.prototype.setScale = function setScale(scale, transition, callback) { 27.3896 + this.scale.set(scale, transition, callback); 27.3897 + this._final = this._final.slice(); 27.3898 + this._final[0] = scale[0]; 27.3899 + this._final[5] = scale[1]; 27.3900 + if (scale[2] !== undefined) this._final[10] = scale[2]; 27.3901 + return this; 27.3902 + }; 27.3903 + 27.3904 + /** 27.3905 + * An optimized way of setting only the rotational component of a Transform 27.3906 + * 27.3907 + * @method setRotate 27.3908 + * @chainable 27.3909 + * 27.3910 + * @param eulerAngles {Array} Euler angles for new rotation state 27.3911 + * @param [transition] {Object} Transition definition 27.3912 + * @param [callback] {Function} Callback 27.3913 + * @return {TransitionableTransform} 27.3914 + */ 27.3915 + TransitionableTransform.prototype.setRotate = function setRotate(eulerAngles, transition, callback) { 27.3916 + this.rotate.set(eulerAngles, transition, callback); 27.3917 + this._final = _build.call(this); 27.3918 + this._final = Transform.build({ 27.3919 + translate: this.translate.get(), 27.3920 + rotate: eulerAngles, 27.3921 + scale: this.scale.get(), 27.3922 + skew: this.skew.get() 27.3923 + }); 27.3924 + return this; 27.3925 + }; 27.3926 + 27.3927 + /** 27.3928 + * An optimized way of setting only the skew component of a Transform 27.3929 + * 27.3930 + * @method setSkew 27.3931 + * @chainable 27.3932 + * 27.3933 + * @param skewAngles {Array} New skew state 27.3934 + * @param [transition] {Object} Transition definition 27.3935 + * @param [callback] {Function} Callback 27.3936 + * @return {TransitionableTransform} 27.3937 + */ 27.3938 + TransitionableTransform.prototype.setSkew = function setSkew(skewAngles, transition, callback) { 27.3939 + this.skew.set(skewAngles, transition, callback); 27.3940 + this._final = Transform.build({ 27.3941 + translate: this.translate.get(), 27.3942 + rotate: this.rotate.get(), 27.3943 + scale: this.scale.get(), 27.3944 + skew: skewAngles 27.3945 + }); 27.3946 + return this; 27.3947 + }; 27.3948 + 27.3949 + /** 27.3950 + * Setter for a TransitionableTransform with optional parameters to transition 27.3951 + * between Transforms 27.3952 + * 27.3953 + * @method set 27.3954 + * @chainable 27.3955 + * 27.3956 + * @param transform {Array} New transform state 27.3957 + * @param [transition] {Object} Transition definition 27.3958 + * @param [callback] {Function} Callback 27.3959 + * @return {TransitionableTransform} 27.3960 + */ 27.3961 + TransitionableTransform.prototype.set = function set(transform, transition, callback) { 27.3962 + this._final = transform; 27.3963 + var components = Transform.interpret(transform); 27.3964 + 27.3965 + var _callback = callback ? Utility.after(4, callback) : null; 27.3966 + this.translate.set(components.translate, transition, _callback); 27.3967 + this.rotate.set(components.rotate, transition, _callback); 27.3968 + this.skew.set(components.skew, transition, _callback); 27.3969 + this.scale.set(components.scale, transition, _callback); 27.3970 + return this; 27.3971 + }; 27.3972 + 27.3973 + /** 27.3974 + * Sets the default transition to use for transitioning betwen Transform states 27.3975 + * 27.3976 + * @method setDefaultTransition 27.3977 + * 27.3978 + * @param transition {Object} Transition definition 27.3979 + */ 27.3980 + TransitionableTransform.prototype.setDefaultTransition = function setDefaultTransition(transition) { 27.3981 + this.translate.setDefault(transition); 27.3982 + this.rotate.setDefault(transition); 27.3983 + this.skew.setDefault(transition); 27.3984 + this.scale.setDefault(transition); 27.3985 + }; 27.3986 + 27.3987 + /** 27.3988 + * Getter. Returns the current state of the Transform 27.3989 + * 27.3990 + * @method get 27.3991 + * 27.3992 + * @return {Transform} 27.3993 + */ 27.3994 + TransitionableTransform.prototype.get = function get() { 27.3995 + if (this.isActive()) { 27.3996 + return _build.call(this); 27.3997 + } 27.3998 + else return this._final; 27.3999 + }; 27.4000 + 27.4001 + /** 27.4002 + * Get the destination state of the Transform 27.4003 + * 27.4004 + * @method getFinal 27.4005 + * 27.4006 + * @return Transform {Transform} 27.4007 + */ 27.4008 + TransitionableTransform.prototype.getFinal = function getFinal() { 27.4009 + return this._final; 27.4010 + }; 27.4011 + 27.4012 + /** 27.4013 + * Determine if the TransitionalTransform is currently transitioning 27.4014 + * 27.4015 + * @method isActive 27.4016 + * 27.4017 + * @return {Boolean} 27.4018 + */ 27.4019 + TransitionableTransform.prototype.isActive = function isActive() { 27.4020 + return this.translate.isActive() || this.rotate.isActive() || this.scale.isActive() || this.skew.isActive(); 27.4021 + }; 27.4022 + 27.4023 + /** 27.4024 + * Halts the transition 27.4025 + * 27.4026 + * @method halt 27.4027 + */ 27.4028 + TransitionableTransform.prototype.halt = function halt() { 27.4029 + this._final = this.get(); 27.4030 + this.translate.halt(); 27.4031 + this.rotate.halt(); 27.4032 + this.skew.halt(); 27.4033 + this.scale.halt(); 27.4034 + }; 27.4035 + 27.4036 + module.exports = TransitionableTransform; 27.4037 +}); 27.4038 + 27.4039 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.4040 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.4041 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.4042 + * 27.4043 + * Owner: mark@famo.us 27.4044 + * @license MPL 2.0 27.4045 + * @copyright Famous Industries, Inc. 2014 27.4046 + */ 27.4047 + 27.4048 +define('famous/core/Modifier',['require','exports','module','./Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 27.4049 + var Transform = require('./Transform'); 27.4050 + 27.4051 + /* TODO: remove these dependencies when deprecation complete */ 27.4052 + var Transitionable = require('famous/transitions/Transitionable'); 27.4053 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 27.4054 + 27.4055 + /** 27.4056 + * 27.4057 + * A collection of visual changes to be 27.4058 + * applied to another renderable component. This collection includes a 27.4059 + * transform matrix, an opacity constant, a size, an origin specifier. 27.4060 + * Modifier objects can be added to any RenderNode or object 27.4061 + * capable of displaying renderables. The Modifier's children and descendants 27.4062 + * are transformed by the amounts specified in the Modifier's properties. 27.4063 + * 27.4064 + * @class Modifier 27.4065 + * @constructor 27.4066 + * @param {Object} [options] overrides of default options 27.4067 + * @param {Transform} [options.transform] affine transformation matrix 27.4068 + * @param {Number} [options.opacity] 27.4069 + * @param {Array.Number} [options.origin] origin adjustment 27.4070 + * @param {Array.Number} [options.size] size to apply to descendants 27.4071 + */ 27.4072 + function Modifier(options) { 27.4073 + this._transformGetter = null; 27.4074 + this._opacityGetter = null; 27.4075 + this._originGetter = null; 27.4076 + this._alignGetter = null; 27.4077 + this._sizeGetter = null; 27.4078 + 27.4079 + /* TODO: remove this when deprecation complete */ 27.4080 + this._legacyStates = {}; 27.4081 + 27.4082 + this._output = { 27.4083 + transform: Transform.identity, 27.4084 + opacity: 1, 27.4085 + origin: null, 27.4086 + align: null, 27.4087 + size: null, 27.4088 + target: null 27.4089 + }; 27.4090 + 27.4091 + if (options) { 27.4092 + if (options.transform) this.transformFrom(options.transform); 27.4093 + if (options.opacity !== undefined) this.opacityFrom(options.opacity); 27.4094 + if (options.origin) this.originFrom(options.origin); 27.4095 + if (options.align) this.alignFrom(options.align); 27.4096 + if (options.size) this.sizeFrom(options.size); 27.4097 + } 27.4098 + } 27.4099 + 27.4100 + /** 27.4101 + * Function, object, or static transform matrix which provides the transform. 27.4102 + * This is evaluated on every tick of the engine. 27.4103 + * 27.4104 + * @method transformFrom 27.4105 + * 27.4106 + * @param {Object} transform transform provider object 27.4107 + * @return {Modifier} this 27.4108 + */ 27.4109 + Modifier.prototype.transformFrom = function transformFrom(transform) { 27.4110 + if (transform instanceof Function) this._transformGetter = transform; 27.4111 + else if (transform instanceof Object && transform.get) this._transformGetter = transform.get.bind(transform); 27.4112 + else { 27.4113 + this._transformGetter = null; 27.4114 + this._output.transform = transform; 27.4115 + } 27.4116 + return this; 27.4117 + }; 27.4118 + 27.4119 + /** 27.4120 + * Set function, object, or number to provide opacity, in range [0,1]. 27.4121 + * 27.4122 + * @method opacityFrom 27.4123 + * 27.4124 + * @param {Object} opacity provider object 27.4125 + * @return {Modifier} this 27.4126 + */ 27.4127 + Modifier.prototype.opacityFrom = function opacityFrom(opacity) { 27.4128 + if (opacity instanceof Function) this._opacityGetter = opacity; 27.4129 + else if (opacity instanceof Object && opacity.get) this._opacityGetter = opacity.get.bind(opacity); 27.4130 + else { 27.4131 + this._opacityGetter = null; 27.4132 + this._output.opacity = opacity; 27.4133 + } 27.4134 + return this; 27.4135 + }; 27.4136 + 27.4137 + /** 27.4138 + * Set function, object, or numerical array to provide origin, as [x,y], 27.4139 + * where x and y are in the range [0,1]. 27.4140 + * 27.4141 + * @method originFrom 27.4142 + * 27.4143 + * @param {Object} origin provider object 27.4144 + * @return {Modifier} this 27.4145 + */ 27.4146 + Modifier.prototype.originFrom = function originFrom(origin) { 27.4147 + if (origin instanceof Function) this._originGetter = origin; 27.4148 + else if (origin instanceof Object && origin.get) this._originGetter = origin.get.bind(origin); 27.4149 + else { 27.4150 + this._originGetter = null; 27.4151 + this._output.origin = origin; 27.4152 + } 27.4153 + return this; 27.4154 + }; 27.4155 + 27.4156 + /** 27.4157 + * Set function, object, or numerical array to provide align, as [x,y], 27.4158 + * where x and y are in the range [0,1]. 27.4159 + * 27.4160 + * @method alignFrom 27.4161 + * 27.4162 + * @param {Object} align provider object 27.4163 + * @return {Modifier} this 27.4164 + */ 27.4165 + Modifier.prototype.alignFrom = function alignFrom(align) { 27.4166 + if (align instanceof Function) this._alignGetter = align; 27.4167 + else if (align instanceof Object && align.get) this._alignGetter = align.get.bind(align); 27.4168 + else { 27.4169 + this._alignGetter = null; 27.4170 + this._output.align = align; 27.4171 + } 27.4172 + return this; 27.4173 + }; 27.4174 + 27.4175 + /** 27.4176 + * Set function, object, or numerical array to provide size, as [width, height]. 27.4177 + * 27.4178 + * @method sizeFrom 27.4179 + * 27.4180 + * @param {Object} size provider object 27.4181 + * @return {Modifier} this 27.4182 + */ 27.4183 + Modifier.prototype.sizeFrom = function sizeFrom(size) { 27.4184 + if (size instanceof Function) this._sizeGetter = size; 27.4185 + else if (size instanceof Object && size.get) this._sizeGetter = size.get.bind(size); 27.4186 + else { 27.4187 + this._sizeGetter = null; 27.4188 + this._output.size = size; 27.4189 + } 27.4190 + return this; 27.4191 + }; 27.4192 + 27.4193 + /** 27.4194 + * Deprecated: Prefer transformFrom with static Transform, or use a TransitionableTransform. 27.4195 + * @deprecated 27.4196 + * @method setTransform 27.4197 + * 27.4198 + * @param {Transform} transform Transform to transition to 27.4199 + * @param {Transitionable} transition Valid transitionable object 27.4200 + * @param {Function} callback callback to call after transition completes 27.4201 + * @return {Modifier} this 27.4202 + */ 27.4203 + Modifier.prototype.setTransform = function setTransform(transform, transition, callback) { 27.4204 + if (transition || this._legacyStates.transform) { 27.4205 + if (!this._legacyStates.transform) { 27.4206 + this._legacyStates.transform = new TransitionableTransform(this._output.transform); 27.4207 + } 27.4208 + if (!this._transformGetter) this.transformFrom(this._legacyStates.transform); 27.4209 + 27.4210 + this._legacyStates.transform.set(transform, transition, callback); 27.4211 + return this; 27.4212 + } 27.4213 + else return this.transformFrom(transform); 27.4214 + }; 27.4215 + 27.4216 + /** 27.4217 + * Deprecated: Prefer opacityFrom with static opacity array, or use a Transitionable with that opacity. 27.4218 + * @deprecated 27.4219 + * @method setOpacity 27.4220 + * 27.4221 + * @param {Number} opacity Opacity value to transition to. 27.4222 + * @param {Transitionable} transition Valid transitionable object 27.4223 + * @param {Function} callback callback to call after transition completes 27.4224 + * @return {Modifier} this 27.4225 + */ 27.4226 + Modifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) { 27.4227 + if (transition || this._legacyStates.opacity) { 27.4228 + if (!this._legacyStates.opacity) { 27.4229 + this._legacyStates.opacity = new Transitionable(this._output.opacity); 27.4230 + } 27.4231 + if (!this._opacityGetter) this.opacityFrom(this._legacyStates.opacity); 27.4232 + 27.4233 + return this._legacyStates.opacity.set(opacity, transition, callback); 27.4234 + } 27.4235 + else return this.opacityFrom(opacity); 27.4236 + }; 27.4237 + 27.4238 + /** 27.4239 + * Deprecated: Prefer originFrom with static origin array, or use a Transitionable with that origin. 27.4240 + * @deprecated 27.4241 + * @method setOrigin 27.4242 + * 27.4243 + * @param {Array.Number} origin two element array with values between 0 and 1. 27.4244 + * @param {Transitionable} transition Valid transitionable object 27.4245 + * @param {Function} callback callback to call after transition completes 27.4246 + * @return {Modifier} this 27.4247 + */ 27.4248 + Modifier.prototype.setOrigin = function setOrigin(origin, transition, callback) { 27.4249 + /* TODO: remove this if statement when deprecation complete */ 27.4250 + if (transition || this._legacyStates.origin) { 27.4251 + 27.4252 + if (!this._legacyStates.origin) { 27.4253 + this._legacyStates.origin = new Transitionable(this._output.origin || [0, 0]); 27.4254 + } 27.4255 + if (!this._originGetter) this.originFrom(this._legacyStates.origin); 27.4256 + 27.4257 + this._legacyStates.origin.set(origin, transition, callback); 27.4258 + return this; 27.4259 + } 27.4260 + else return this.originFrom(origin); 27.4261 + }; 27.4262 + 27.4263 + /** 27.4264 + * Deprecated: Prefer alignFrom with static align array, or use a Transitionable with that align. 27.4265 + * @deprecated 27.4266 + * @method setAlign 27.4267 + * 27.4268 + * @param {Array.Number} align two element array with values between 0 and 1. 27.4269 + * @param {Transitionable} transition Valid transitionable object 27.4270 + * @param {Function} callback callback to call after transition completes 27.4271 + * @return {Modifier} this 27.4272 + */ 27.4273 + Modifier.prototype.setAlign = function setAlign(align, transition, callback) { 27.4274 + /* TODO: remove this if statement when deprecation complete */ 27.4275 + if (transition || this._legacyStates.align) { 27.4276 + 27.4277 + if (!this._legacyStates.align) { 27.4278 + this._legacyStates.align = new Transitionable(this._output.align || [0, 0]); 27.4279 + } 27.4280 + if (!this._alignGetter) this.alignFrom(this._legacyStates.align); 27.4281 + 27.4282 + this._legacyStates.align.set(align, transition, callback); 27.4283 + return this; 27.4284 + } 27.4285 + else return this.alignFrom(align); 27.4286 + }; 27.4287 + 27.4288 + /** 27.4289 + * Deprecated: Prefer sizeFrom with static origin array, or use a Transitionable with that size. 27.4290 + * @deprecated 27.4291 + * @method setSize 27.4292 + * @param {Array.Number} size two element array of [width, height] 27.4293 + * @param {Transitionable} transition Valid transitionable object 27.4294 + * @param {Function} callback callback to call after transition completes 27.4295 + * @return {Modifier} this 27.4296 + */ 27.4297 + Modifier.prototype.setSize = function setSize(size, transition, callback) { 27.4298 + if (size && (transition || this._legacyStates.size)) { 27.4299 + if (!this._legacyStates.size) { 27.4300 + this._legacyStates.size = new Transitionable(this._output.size || [0, 0]); 27.4301 + } 27.4302 + if (!this._sizeGetter) this.sizeFrom(this._legacyStates.size); 27.4303 + 27.4304 + this._legacyStates.size.set(size, transition, callback); 27.4305 + return this; 27.4306 + } 27.4307 + else return this.sizeFrom(size); 27.4308 + }; 27.4309 + 27.4310 + /** 27.4311 + * Deprecated: Prefer to stop transform in your provider object. 27.4312 + * @deprecated 27.4313 + * @method halt 27.4314 + */ 27.4315 + Modifier.prototype.halt = function halt() { 27.4316 + if (this._legacyStates.transform) this._legacyStates.transform.halt(); 27.4317 + if (this._legacyStates.opacity) this._legacyStates.opacity.halt(); 27.4318 + if (this._legacyStates.origin) this._legacyStates.origin.halt(); 27.4319 + if (this._legacyStates.align) this._legacyStates.align.halt(); 27.4320 + if (this._legacyStates.size) this._legacyStates.size.halt(); 27.4321 + this._transformGetter = null; 27.4322 + this._opacityGetter = null; 27.4323 + this._originGetter = null; 27.4324 + this._alignGetter = null; 27.4325 + this._sizeGetter = null; 27.4326 + }; 27.4327 + 27.4328 + /** 27.4329 + * Deprecated: Prefer to use your provided transform or output of your transform provider. 27.4330 + * @deprecated 27.4331 + * @method getTransform 27.4332 + * @return {Object} transform provider object 27.4333 + */ 27.4334 + Modifier.prototype.getTransform = function getTransform() { 27.4335 + return this._transformGetter(); 27.4336 + }; 27.4337 + 27.4338 + /** 27.4339 + * Deprecated: Prefer to determine the end state of your transform from your transform provider 27.4340 + * @deprecated 27.4341 + * @method getFinalTransform 27.4342 + * @return {Transform} transform matrix 27.4343 + */ 27.4344 + Modifier.prototype.getFinalTransform = function getFinalTransform() { 27.4345 + return this._legacyStates.transform ? this._legacyStates.transform.getFinal() : this._output.transform; 27.4346 + }; 27.4347 + 27.4348 + /** 27.4349 + * Deprecated: Prefer to use your provided opacity or output of your opacity provider. 27.4350 + * @deprecated 27.4351 + * @method getOpacity 27.4352 + * @return {Object} opacity provider object 27.4353 + */ 27.4354 + Modifier.prototype.getOpacity = function getOpacity() { 27.4355 + return this._opacityGetter(); 27.4356 + }; 27.4357 + 27.4358 + /** 27.4359 + * Deprecated: Prefer to use your provided origin or output of your origin provider. 27.4360 + * @deprecated 27.4361 + * @method getOrigin 27.4362 + * @return {Object} origin provider object 27.4363 + */ 27.4364 + Modifier.prototype.getOrigin = function getOrigin() { 27.4365 + return this._originGetter(); 27.4366 + }; 27.4367 + 27.4368 + /** 27.4369 + * Deprecated: Prefer to use your provided align or output of your align provider. 27.4370 + * @deprecated 27.4371 + * @method getAlign 27.4372 + * @return {Object} align provider object 27.4373 + */ 27.4374 + Modifier.prototype.getAlign = function getAlign() { 27.4375 + return this._alignGetter(); 27.4376 + }; 27.4377 + 27.4378 + /** 27.4379 + * Deprecated: Prefer to use your provided size or output of your size provider. 27.4380 + * @deprecated 27.4381 + * @method getSize 27.4382 + * @return {Object} size provider object 27.4383 + */ 27.4384 + Modifier.prototype.getSize = function getSize() { 27.4385 + return this._sizeGetter ? this._sizeGetter() : this._output.size; 27.4386 + }; 27.4387 + 27.4388 + // call providers on tick to receive render spec elements to apply 27.4389 + function _update() { 27.4390 + if (this._transformGetter) this._output.transform = this._transformGetter(); 27.4391 + if (this._opacityGetter) this._output.opacity = this._opacityGetter(); 27.4392 + if (this._originGetter) this._output.origin = this._originGetter(); 27.4393 + if (this._alignGetter) this._output.align = this._alignGetter(); 27.4394 + if (this._sizeGetter) this._output.size = this._sizeGetter(); 27.4395 + } 27.4396 + 27.4397 + /** 27.4398 + * Return render spec for this Modifier, applying to the provided 27.4399 + * target component. This is similar to render() for Surfaces. 27.4400 + * 27.4401 + * @private 27.4402 + * @method modify 27.4403 + * 27.4404 + * @param {Object} target (already rendered) render spec to 27.4405 + * which to apply the transform. 27.4406 + * @return {Object} render spec for this Modifier, including the 27.4407 + * provided target 27.4408 + */ 27.4409 + Modifier.prototype.modify = function modify(target) { 27.4410 + _update.call(this); 27.4411 + this._output.target = target; 27.4412 + return this._output; 27.4413 + }; 27.4414 + 27.4415 + module.exports = Modifier; 27.4416 +}); 27.4417 + 27.4418 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.4419 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.4420 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.4421 + * 27.4422 + * Owner: mark@famo.us 27.4423 + * @license MPL 2.0 27.4424 + * @copyright Famous Industries, Inc. 2014 27.4425 + */ 27.4426 + 27.4427 +define('famous/core/Scene',['require','exports','module','./Transform','./Modifier','./RenderNode'],function(require, exports, module) { 27.4428 + var Transform = require('./Transform'); 27.4429 + var Modifier = require('./Modifier'); 27.4430 + var RenderNode = require('./RenderNode'); 27.4431 + 27.4432 + /** 27.4433 + * Builds and renders a scene graph based on a declarative structure definition. 27.4434 + * See the Scene examples in the examples distribution (http://github.com/Famous/examples.git). 27.4435 + * 27.4436 + * @class Scene 27.4437 + * @constructor 27.4438 + * @param {Object} definition in the format of a render spec. 27.4439 + */ 27.4440 + function Scene(definition) { 27.4441 + this.id = null; 27.4442 + this._objects = null; 27.4443 + 27.4444 + this.node = new RenderNode(); 27.4445 + this._definition = null; 27.4446 + 27.4447 + if (definition) this.load(definition); 27.4448 + } 27.4449 + 27.4450 + var _MATRIX_GENERATORS = { 27.4451 + 'translate': Transform.translate, 27.4452 + 'rotate': Transform.rotate, 27.4453 + 'rotateX': Transform.rotateX, 27.4454 + 'rotateY': Transform.rotateY, 27.4455 + 'rotateZ': Transform.rotateZ, 27.4456 + 'rotateAxis': Transform.rotateAxis, 27.4457 + 'scale': Transform.scale, 27.4458 + 'skew': Transform.skew, 27.4459 + 'matrix3d': function() { 27.4460 + return arguments; 27.4461 + } 27.4462 + }; 27.4463 + 27.4464 + /** 27.4465 + * Clone this scene 27.4466 + * 27.4467 + * @method create 27.4468 + * @return {Scene} deep copy of this scene 27.4469 + */ 27.4470 + Scene.prototype.create = function create() { 27.4471 + return new Scene(this._definition); 27.4472 + }; 27.4473 + 27.4474 + function _resolveTransformMatrix(matrixDefinition) { 27.4475 + for (var type in _MATRIX_GENERATORS) { 27.4476 + if (type in matrixDefinition) { 27.4477 + var args = matrixDefinition[type]; 27.4478 + if (!(args instanceof Array)) args = [args]; 27.4479 + return _MATRIX_GENERATORS[type].apply(this, args); 27.4480 + } 27.4481 + } 27.4482 + } 27.4483 + 27.4484 + // parse transform into tree of render nodes, doing matrix multiplication 27.4485 + // when available 27.4486 + function _parseTransform(definition) { 27.4487 + var transformDefinition = definition.transform; 27.4488 + var opacity = definition.opacity; 27.4489 + var origin = definition.origin; 27.4490 + var size = definition.size; 27.4491 + var transform = Transform.identity; 27.4492 + if (transformDefinition instanceof Array) { 27.4493 + if (transformDefinition.length === 16 && typeof transformDefinition[0] === 'number') { 27.4494 + transform = transformDefinition; 27.4495 + } 27.4496 + else { 27.4497 + for (var i = 0; i < transformDefinition.length; i++) { 27.4498 + transform = Transform.multiply(transform, _resolveTransformMatrix(transformDefinition[i])); 27.4499 + } 27.4500 + } 27.4501 + } 27.4502 + else if (transformDefinition instanceof Object) { 27.4503 + transform = _resolveTransformMatrix(transformDefinition); 27.4504 + } 27.4505 + 27.4506 + var result = new Modifier({ 27.4507 + transform: transform, 27.4508 + opacity: opacity, 27.4509 + origin: origin, 27.4510 + size: size 27.4511 + }); 27.4512 + return result; 27.4513 + } 27.4514 + 27.4515 + function _parseArray(definition) { 27.4516 + var result = new RenderNode(); 27.4517 + for (var i = 0; i < definition.length; i++) { 27.4518 + var obj = _parse.call(this, definition[i]); 27.4519 + if (obj) result.add(obj); 27.4520 + } 27.4521 + return result; 27.4522 + } 27.4523 + 27.4524 + // parse object directly into tree of RenderNodes 27.4525 + function _parse(definition) { 27.4526 + var result; 27.4527 + var id; 27.4528 + if (definition instanceof Array) { 27.4529 + result = _parseArray.call(this, definition); 27.4530 + } 27.4531 + else { 27.4532 + id = this._objects.length; 27.4533 + if (definition.render && (definition.render instanceof Function)) { 27.4534 + result = definition; 27.4535 + } 27.4536 + else if (definition.target) { 27.4537 + var targetObj = _parse.call(this, definition.target); 27.4538 + var obj = _parseTransform.call(this, definition); 27.4539 + 27.4540 + result = new RenderNode(obj); 27.4541 + result.add(targetObj); 27.4542 + if (definition.id) this.id[definition.id] = obj; 27.4543 + } 27.4544 + else if (definition.id) { 27.4545 + result = new RenderNode(); 27.4546 + this.id[definition.id] = result; 27.4547 + } 27.4548 + } 27.4549 + this._objects[id] = result; 27.4550 + return result; 27.4551 + } 27.4552 + 27.4553 + /** 27.4554 + * Builds and renders a scene graph based on a canonical declarative scene definition. 27.4555 + * See examples/Scene/example.js. 27.4556 + * 27.4557 + * @method load 27.4558 + * @param {Object} definition definition in the format of a render spec. 27.4559 + */ 27.4560 + Scene.prototype.load = function load(definition) { 27.4561 + this._definition = definition; 27.4562 + this.id = {}; 27.4563 + this._objects = []; 27.4564 + this.node.set(_parse.call(this, definition)); 27.4565 + }; 27.4566 + 27.4567 + /** 27.4568 + * Add renderables to this component's render tree 27.4569 + * 27.4570 + * @method add 27.4571 + * 27.4572 + * @param {Object} obj renderable object 27.4573 + * @return {RenderNode} Render wrapping provided object, if not already a RenderNode 27.4574 + */ 27.4575 + Scene.prototype.add = function add() { 27.4576 + return this.node.add.apply(this.node, arguments); 27.4577 + }; 27.4578 + 27.4579 + /** 27.4580 + * Generate a render spec from the contents of this component. 27.4581 + * 27.4582 + * @private 27.4583 + * @method render 27.4584 + * @return {number} Render spec for this component 27.4585 + */ 27.4586 + Scene.prototype.render = function render() { 27.4587 + return this.node.render.apply(this.node, arguments); 27.4588 + }; 27.4589 + 27.4590 + module.exports = Scene; 27.4591 +}); 27.4592 + 27.4593 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.4594 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.4595 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.4596 + * 27.4597 + * Owner: mark@famo.us 27.4598 + * @license MPL 2.0 27.4599 + * @copyright Famous Industries, Inc. 2014 27.4600 + */ 27.4601 + 27.4602 +define('famous/core/View',['require','exports','module','./EventHandler','./OptionsManager','./RenderNode'],function(require, exports, module) { 27.4603 + var EventHandler = require('./EventHandler'); 27.4604 + var OptionsManager = require('./OptionsManager'); 27.4605 + var RenderNode = require('./RenderNode'); 27.4606 + 27.4607 + /** 27.4608 + * Useful for quickly creating elements within applications 27.4609 + * with large event systems. Consists of a RenderNode paired with 27.4610 + * an input EventHandler and an output EventHandler. 27.4611 + * Meant to be extended by the developer. 27.4612 + * 27.4613 + * @class View 27.4614 + * @uses EventHandler 27.4615 + * @uses OptionsManager 27.4616 + * @uses RenderNode 27.4617 + * @constructor 27.4618 + */ 27.4619 + function View(options) { 27.4620 + this._node = new RenderNode(); 27.4621 + 27.4622 + this._eventInput = new EventHandler(); 27.4623 + this._eventOutput = new EventHandler(); 27.4624 + EventHandler.setInputHandler(this, this._eventInput); 27.4625 + EventHandler.setOutputHandler(this, this._eventOutput); 27.4626 + 27.4627 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS || View.DEFAULT_OPTIONS); 27.4628 + this._optionsManager = new OptionsManager(this.options); 27.4629 + 27.4630 + if (options) this.setOptions(options); 27.4631 + } 27.4632 + 27.4633 + View.DEFAULT_OPTIONS = {}; // no defaults 27.4634 + 27.4635 + /** 27.4636 + * Look up options value by key 27.4637 + * @method getOptions 27.4638 + * 27.4639 + * @param {string} key key 27.4640 + * @return {Object} associated object 27.4641 + */ 27.4642 + View.prototype.getOptions = function getOptions() { 27.4643 + return this._optionsManager.value(); 27.4644 + }; 27.4645 + 27.4646 + /* 27.4647 + * Set internal options. 27.4648 + * No defaults options are set in View. 27.4649 + * 27.4650 + * @method setOptions 27.4651 + * @param {Object} options 27.4652 + */ 27.4653 + View.prototype.setOptions = function setOptions(options) { 27.4654 + this._optionsManager.patch(options); 27.4655 + }; 27.4656 + 27.4657 + /** 27.4658 + * Add a child renderable to the view. 27.4659 + * Note: This is meant to be used by an inheriting class 27.4660 + * rather than from outside the prototype chain. 27.4661 + * 27.4662 + * @method add 27.4663 + * @return {RenderNode} 27.4664 + * @protected 27.4665 + */ 27.4666 + View.prototype.add = function add() { 27.4667 + return this._node.add.apply(this._node, arguments); 27.4668 + }; 27.4669 + 27.4670 + /** 27.4671 + * Alias for add 27.4672 + * @method _add 27.4673 + */ 27.4674 + View.prototype._add = View.prototype.add; 27.4675 + 27.4676 + /** 27.4677 + * Generate a render spec from the contents of this component. 27.4678 + * 27.4679 + * @private 27.4680 + * @method render 27.4681 + * @return {number} Render spec for this component 27.4682 + */ 27.4683 + View.prototype.render = function render() { 27.4684 + return this._node.render(); 27.4685 + }; 27.4686 + 27.4687 + /** 27.4688 + * Return size of contained element. 27.4689 + * 27.4690 + * @method getSize 27.4691 + * @return {Array.Number} [width, height] 27.4692 + */ 27.4693 + View.prototype.getSize = function getSize() { 27.4694 + if (this._node && this._node.getSize) { 27.4695 + return this._node.getSize.apply(this._node, arguments) || this.options.size; 27.4696 + } 27.4697 + else return this.options.size; 27.4698 + }; 27.4699 + 27.4700 + module.exports = View; 27.4701 +}); 27.4702 + 27.4703 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.4704 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.4705 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.4706 + * 27.4707 + * Owner: mark@famo.us 27.4708 + * @license MPL 2.0 27.4709 + * @copyright Famous Industries, Inc. 2014 27.4710 + */ 27.4711 + 27.4712 +define('famous/core/ViewSequence',['require','exports','module'],function(require, exports, module) { 27.4713 + 27.4714 + /** 27.4715 + * Helper object used to iterate through items sequentially. Used in 27.4716 + * views that deal with layout. A ViewSequence object conceptually points 27.4717 + * to a node in a linked list. 27.4718 + * 27.4719 + * @class ViewSequence 27.4720 + * 27.4721 + * @constructor 27.4722 + * @param {Object|Array} options Options object, or content array. 27.4723 + * @param {Number} [options.index] starting index. 27.4724 + * @param {Number} [options.array] Array of elements to populate the ViewSequence 27.4725 + * @param {Object} [options._] Optional backing store (internal 27.4726 + * @param {Boolean} [options.loop] Whether to wrap when accessing elements just past the end 27.4727 + * (or beginning) of the sequence. 27.4728 + */ 27.4729 + function ViewSequence(options) { 27.4730 + if (!options) options = []; 27.4731 + if (options instanceof Array) options = {array: options}; 27.4732 + 27.4733 + this._ = null; 27.4734 + this.index = options.index || 0; 27.4735 + 27.4736 + if (options.array) this._ = new (this.constructor.Backing)(options.array); 27.4737 + else if (options._) this._ = options._; 27.4738 + 27.4739 + if (this.index === this._.firstIndex) this._.firstNode = this; 27.4740 + if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this; 27.4741 + 27.4742 + if (options.loop !== undefined) this._.loop = options.loop; 27.4743 + 27.4744 + this._previousNode = null; 27.4745 + this._nextNode = null; 27.4746 + } 27.4747 + 27.4748 + // constructor for internal storage 27.4749 + ViewSequence.Backing = function Backing(array) { 27.4750 + this.array = array; 27.4751 + this.firstIndex = 0; 27.4752 + this.loop = false; 27.4753 + this.firstNode = null; 27.4754 + this.lastNode = null; 27.4755 + }; 27.4756 + 27.4757 + // Get value "i" slots away from the first index. 27.4758 + ViewSequence.Backing.prototype.getValue = function getValue(i) { 27.4759 + var _i = i - this.firstIndex; 27.4760 + if (_i < 0 || _i >= this.array.length) return null; 27.4761 + return this.array[_i]; 27.4762 + }; 27.4763 + 27.4764 + // Set value "i" slots away from the first index. 27.4765 + ViewSequence.Backing.prototype.setValue = function setValue(i, value) { 27.4766 + this.array[i - this.firstIndex] = value; 27.4767 + }; 27.4768 + 27.4769 + // After splicing into the backing store, restore the indexes of each node correctly. 27.4770 + ViewSequence.Backing.prototype.reindex = function reindex(start, removeCount, insertCount) { 27.4771 + if (!this.array[0]) return; 27.4772 + 27.4773 + var i = 0; 27.4774 + var index = this.firstIndex; 27.4775 + var indexShiftAmount = insertCount - removeCount; 27.4776 + var node = this.firstNode; 27.4777 + 27.4778 + // find node to begin 27.4779 + while (index < start - 1) { 27.4780 + node = node.getNext(); 27.4781 + index++; 27.4782 + } 27.4783 + // skip removed nodes 27.4784 + var spliceStartNode = node; 27.4785 + for (i = 0; i < removeCount; i++) { 27.4786 + node = node.getNext(); 27.4787 + if (node) node._previousNode = spliceStartNode; 27.4788 + } 27.4789 + var spliceResumeNode = node ? node.getNext() : null; 27.4790 + // generate nodes for inserted items 27.4791 + spliceStartNode._nextNode = null; 27.4792 + node = spliceStartNode; 27.4793 + for (i = 0; i < insertCount; i++) node = node.getNext(); 27.4794 + index += insertCount; 27.4795 + // resume the chain 27.4796 + if (node !== spliceResumeNode) { 27.4797 + node._nextNode = spliceResumeNode; 27.4798 + if (spliceResumeNode) spliceResumeNode._previousNode = node; 27.4799 + } 27.4800 + if (spliceResumeNode) { 27.4801 + node = spliceResumeNode; 27.4802 + index++; 27.4803 + while (node && index < this.array.length + this.firstIndex) { 27.4804 + if (node._nextNode) node.index += indexShiftAmount; 27.4805 + else node.index = index; 27.4806 + node = node.getNext(); 27.4807 + index++; 27.4808 + } 27.4809 + } 27.4810 + }; 27.4811 + 27.4812 + /** 27.4813 + * Return ViewSequence node previous to this node in the list, respecting looping if applied. 27.4814 + * 27.4815 + * @method getPrevious 27.4816 + * @return {ViewSequence} previous node. 27.4817 + */ 27.4818 + ViewSequence.prototype.getPrevious = function getPrevious() { 27.4819 + if (this.index === this._.firstIndex) { 27.4820 + if (this._.loop) { 27.4821 + this._previousNode = this._.lastNode || new (this.constructor)({_: this._, index: this._.firstIndex + this._.array.length - 1}); 27.4822 + this._previousNode._nextNode = this; 27.4823 + } 27.4824 + else { 27.4825 + this._previousNode = null; 27.4826 + } 27.4827 + } 27.4828 + else if (!this._previousNode) { 27.4829 + this._previousNode = new (this.constructor)({_: this._, index: this.index - 1}); 27.4830 + this._previousNode._nextNode = this; 27.4831 + } 27.4832 + return this._previousNode; 27.4833 + }; 27.4834 + 27.4835 + /** 27.4836 + * Return ViewSequence node next after this node in the list, respecting looping if applied. 27.4837 + * 27.4838 + * @method getNext 27.4839 + * @return {ViewSequence} previous node. 27.4840 + */ 27.4841 + ViewSequence.prototype.getNext = function getNext() { 27.4842 + if (this.index === this._.firstIndex + this._.array.length - 1) { 27.4843 + if (this._.loop) { 27.4844 + this._nextNode = this._.firstNode || new (this.constructor)({_: this._, index: this._.firstIndex}); 27.4845 + this._nextNode._previousNode = this; 27.4846 + } 27.4847 + else { 27.4848 + this._nextNode = null; 27.4849 + } 27.4850 + } 27.4851 + else if (!this._nextNode) { 27.4852 + this._nextNode = new (this.constructor)({_: this._, index: this.index + 1}); 27.4853 + this._nextNode._previousNode = this; 27.4854 + } 27.4855 + return this._nextNode; 27.4856 + }; 27.4857 + 27.4858 + /** 27.4859 + * Return index of this ViewSequence node. 27.4860 + * 27.4861 + * @method getIndex 27.4862 + * @return {Number} index 27.4863 + */ 27.4864 + ViewSequence.prototype.getIndex = function getIndex() { 27.4865 + return this.index; 27.4866 + }; 27.4867 + 27.4868 + /** 27.4869 + * Return printable version of this ViewSequence node. 27.4870 + * 27.4871 + * @method toString 27.4872 + * @return {string} this index as a string 27.4873 + */ 27.4874 + ViewSequence.prototype.toString = function toString() { 27.4875 + return '' + this.index; 27.4876 + }; 27.4877 + 27.4878 + /** 27.4879 + * Add one or more objects to the beginning of the sequence. 27.4880 + * 27.4881 + * @method unshift 27.4882 + * @param {...Object} value arguments array of objects 27.4883 + */ 27.4884 + ViewSequence.prototype.unshift = function unshift(value) { 27.4885 + this._.array.unshift.apply(this._.array, arguments); 27.4886 + this._.firstIndex -= arguments.length; 27.4887 + }; 27.4888 + 27.4889 + /** 27.4890 + * Add one or more objects to the end of the sequence. 27.4891 + * 27.4892 + * @method push 27.4893 + * @param {...Object} value arguments array of objects 27.4894 + */ 27.4895 + ViewSequence.prototype.push = function push(value) { 27.4896 + this._.array.push.apply(this._.array, arguments); 27.4897 + }; 27.4898 + 27.4899 + /** 27.4900 + * Remove objects from the sequence 27.4901 + * 27.4902 + * @method splice 27.4903 + * @param {Number} index starting index for removal 27.4904 + * @param {Number} howMany how many elements to remove 27.4905 + * @param {...Object} value arguments array of objects 27.4906 + */ 27.4907 + ViewSequence.prototype.splice = function splice(index, howMany) { 27.4908 + var values = Array.prototype.slice.call(arguments, 2); 27.4909 + this._.array.splice.apply(this._.array, [index - this._.firstIndex, howMany].concat(values)); 27.4910 + this._.reindex(index, howMany, values.length); 27.4911 + }; 27.4912 + 27.4913 + /** 27.4914 + * Exchange this element's sequence position with another's. 27.4915 + * 27.4916 + * @method swap 27.4917 + * @param {ViewSequence} other element to swap with. 27.4918 + */ 27.4919 + ViewSequence.prototype.swap = function swap(other) { 27.4920 + var otherValue = other.get(); 27.4921 + var myValue = this.get(); 27.4922 + this._.setValue(this.index, otherValue); 27.4923 + this._.setValue(other.index, myValue); 27.4924 + 27.4925 + var myPrevious = this._previousNode; 27.4926 + var myNext = this._nextNode; 27.4927 + var myIndex = this.index; 27.4928 + var otherPrevious = other._previousNode; 27.4929 + var otherNext = other._nextNode; 27.4930 + var otherIndex = other.index; 27.4931 + 27.4932 + this.index = otherIndex; 27.4933 + this._previousNode = (otherPrevious === this) ? other : otherPrevious; 27.4934 + if (this._previousNode) this._previousNode._nextNode = this; 27.4935 + this._nextNode = (otherNext === this) ? other : otherNext; 27.4936 + if (this._nextNode) this._nextNode._previousNode = this; 27.4937 + 27.4938 + other.index = myIndex; 27.4939 + other._previousNode = (myPrevious === other) ? this : myPrevious; 27.4940 + if (other._previousNode) other._previousNode._nextNode = other; 27.4941 + other._nextNode = (myNext === other) ? this : myNext; 27.4942 + if (other._nextNode) other._nextNode._previousNode = other; 27.4943 + 27.4944 + if (this.index === this._.firstIndex) this._.firstNode = this; 27.4945 + else if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this; 27.4946 + if (other.index === this._.firstIndex) this._.firstNode = other; 27.4947 + else if (other.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = other; 27.4948 + }; 27.4949 + 27.4950 + /** 27.4951 + * Return value of this ViewSequence node. 27.4952 + * 27.4953 + * @method get 27.4954 + * @return {Object} value of thiss 27.4955 + */ 27.4956 + ViewSequence.prototype.get = function get() { 27.4957 + return this._.getValue(this.index); 27.4958 + }; 27.4959 + 27.4960 + /** 27.4961 + * Call getSize() on the contained View. 27.4962 + * 27.4963 + * @method getSize 27.4964 + * @return {Array.Number} [width, height] 27.4965 + */ 27.4966 + ViewSequence.prototype.getSize = function getSize() { 27.4967 + var target = this.get(); 27.4968 + return target ? target.getSize() : null; 27.4969 + }; 27.4970 + 27.4971 + /** 27.4972 + * Generate a render spec from the contents of this component. 27.4973 + * Specifically, this will render the value at the current index. 27.4974 + * @private 27.4975 + * @method render 27.4976 + * @return {number} Render spec for this component 27.4977 + */ 27.4978 + ViewSequence.prototype.render = function render() { 27.4979 + var target = this.get(); 27.4980 + return target ? target.render.apply(target, arguments) : null; 27.4981 + }; 27.4982 + 27.4983 + module.exports = ViewSequence; 27.4984 +}); 27.4985 + 27.4986 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.4987 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.4988 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.4989 + * 27.4990 + * Owner: mark@famo.us 27.4991 + * @license MPL 2.0 27.4992 + * @copyright Famous Industries, Inc. 2014 27.4993 + */ 27.4994 + 27.4995 +define('famous/math/Utilities',['require','exports','module'],function(require, exports, module) { 27.4996 + /** 27.4997 + * A few static methods. 27.4998 + * 27.4999 + * @class Utilities 27.5000 + * @static 27.5001 + */ 27.5002 + var Utilities = {}; 27.5003 + 27.5004 + /** 27.5005 + * Constrain input to range. 27.5006 + * 27.5007 + * @method clamp 27.5008 + * @param {Number} value input 27.5009 + * @param {Array.Number} range [min, max] 27.5010 + * @static 27.5011 + */ 27.5012 + Utilities.clamp = function clamp(value, range) { 27.5013 + return Math.max(Math.min(value, range[1]), range[0]); 27.5014 + }; 27.5015 + 27.5016 + /** 27.5017 + * Euclidean length of numerical array. 27.5018 + * 27.5019 + * @method length 27.5020 + * @param {Array.Number} array array of numbers 27.5021 + * @static 27.5022 + */ 27.5023 + Utilities.length = function length(array) { 27.5024 + var distanceSquared = 0; 27.5025 + for (var i = 0; i < array.length; i++) { 27.5026 + distanceSquared += array[i] * array[i]; 27.5027 + } 27.5028 + return Math.sqrt(distanceSquared); 27.5029 + }; 27.5030 + 27.5031 + module.exports = Utilities; 27.5032 +}); 27.5033 + 27.5034 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5035 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.5036 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.5037 + * 27.5038 + * Owner: mark@famo.us 27.5039 + * @license MPL 2.0 27.5040 + * @copyright Famous Industries, Inc. 2014 27.5041 + */ 27.5042 + 27.5043 +define('famous/inputs/GenericSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.5044 + var EventHandler = require('famous/core/EventHandler'); 27.5045 + 27.5046 + /** 27.5047 + * Combines multiple types of sync classes (e.g. mouse, touch, 27.5048 + * scrolling) into one standardized interface for inclusion in widgets. 27.5049 + * 27.5050 + * Sync classes are first registered with a key, and then can be accessed 27.5051 + * globally by key. 27.5052 + * 27.5053 + * Emits 'start', 'update' and 'end' events as a union of the sync class 27.5054 + * providers. 27.5055 + * 27.5056 + * @class GenericSync 27.5057 + * @constructor 27.5058 + * @param syncs {Object|Array} object with fields {sync key : sync options} 27.5059 + * or an array of registered sync keys 27.5060 + * @param [options] {Object|Array} options object to set on all syncs 27.5061 + */ 27.5062 + function GenericSync(syncs, options) { 27.5063 + this._eventInput = new EventHandler(); 27.5064 + this._eventOutput = new EventHandler(); 27.5065 + 27.5066 + EventHandler.setInputHandler(this, this._eventInput); 27.5067 + EventHandler.setOutputHandler(this, this._eventOutput); 27.5068 + 27.5069 + this._syncs = {}; 27.5070 + if (syncs) this.addSync(syncs); 27.5071 + if (options) this.setOptions(options); 27.5072 + } 27.5073 + 27.5074 + GenericSync.DIRECTION_X = 0; 27.5075 + GenericSync.DIRECTION_Y = 1; 27.5076 + GenericSync.DIRECTION_Z = 2; 27.5077 + 27.5078 + // Global registry of sync classes. Append only. 27.5079 + var registry = {}; 27.5080 + 27.5081 + /** 27.5082 + * Register a global sync class with an identifying key 27.5083 + * 27.5084 + * @static 27.5085 + * @method register 27.5086 + * 27.5087 + * @param syncObject {Object} an object of {sync key : sync options} fields 27.5088 + */ 27.5089 + GenericSync.register = function register(syncObject) { 27.5090 + for (var key in syncObject){ 27.5091 + if (registry[key]){ 27.5092 + if (registry[key] === syncObject[key]) return; // redundant registration 27.5093 + else throw new Error('this key is registered to a different sync class'); 27.5094 + } 27.5095 + else registry[key] = syncObject[key]; 27.5096 + } 27.5097 + }; 27.5098 + 27.5099 + /** 27.5100 + * Helper to set options on all sync instances 27.5101 + * 27.5102 + * @method setOptions 27.5103 + * @param options {Object} options object 27.5104 + */ 27.5105 + GenericSync.prototype.setOptions = function(options) { 27.5106 + for (var key in this._syncs){ 27.5107 + this._syncs[key].setOptions(options); 27.5108 + } 27.5109 + }; 27.5110 + 27.5111 + /** 27.5112 + * Pipe events to a sync class 27.5113 + * 27.5114 + * @method pipeSync 27.5115 + * @param key {String} identifier for sync class 27.5116 + */ 27.5117 + GenericSync.prototype.pipeSync = function pipeToSync(key) { 27.5118 + var sync = this._syncs[key]; 27.5119 + this._eventInput.pipe(sync); 27.5120 + sync.pipe(this._eventOutput); 27.5121 + }; 27.5122 + 27.5123 + /** 27.5124 + * Unpipe events from a sync class 27.5125 + * 27.5126 + * @method unpipeSync 27.5127 + * @param key {String} identifier for sync class 27.5128 + */ 27.5129 + GenericSync.prototype.unpipeSync = function unpipeFromSync(key) { 27.5130 + var sync = this._syncs[key]; 27.5131 + this._eventInput.unpipe(sync); 27.5132 + sync.unpipe(this._eventOutput); 27.5133 + }; 27.5134 + 27.5135 + function _addSingleSync(key, options) { 27.5136 + if (!registry[key]) return; 27.5137 + this._syncs[key] = new (registry[key])(options); 27.5138 + this.pipeSync(key); 27.5139 + } 27.5140 + 27.5141 + /** 27.5142 + * Add a sync class to from the registered classes 27.5143 + * 27.5144 + * @method addSync 27.5145 + * @param syncs {Object|Array.String} an array of registered sync keys 27.5146 + * or an object with fields {sync key : sync options} 27.5147 + */ 27.5148 + GenericSync.prototype.addSync = function addSync(syncs) { 27.5149 + if (syncs instanceof Array) 27.5150 + for (var i = 0; i < syncs.length; i++) 27.5151 + _addSingleSync.call(this, syncs[i]); 27.5152 + else if (syncs instanceof Object) 27.5153 + for (var key in syncs) 27.5154 + _addSingleSync.call(this, key, syncs[key]); 27.5155 + }; 27.5156 + 27.5157 + module.exports = GenericSync; 27.5158 +}); 27.5159 + 27.5160 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5161 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.5162 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.5163 + * 27.5164 + * Owner: mark@famo.us 27.5165 + * @license MPL 2.0 27.5166 + * @copyright Famous Industries, Inc. 2014 27.5167 + */ 27.5168 + 27.5169 +define('famous/inputs/MouseSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.5170 + var EventHandler = require('famous/core/EventHandler'); 27.5171 + 27.5172 + /** 27.5173 + * Handles piped in mouse drag events. Outputs an object with two 27.5174 + * properties, position and velocity. 27.5175 + * Emits 'start', 'update' and 'end' events with DOM event passthroughs, 27.5176 + * with position, velocity, and a delta key. 27.5177 + * 27.5178 + * @class MouseSync 27.5179 + * @constructor 27.5180 + * 27.5181 + * @param [options] {Object} default options overrides 27.5182 + * @param [options.direction] {Number} read from a particular axis 27.5183 + * @param [options.rails] {Boolean} read from axis with greatest differential 27.5184 + * @param [options.propogate] {Boolean} add listened to document on mouseleave 27.5185 + */ 27.5186 + function MouseSync(options) { 27.5187 + this.options = Object.create(MouseSync.DEFAULT_OPTIONS); 27.5188 + if (options) this.setOptions(options); 27.5189 + 27.5190 + this._eventInput = new EventHandler(); 27.5191 + this._eventOutput = new EventHandler(); 27.5192 + 27.5193 + EventHandler.setInputHandler(this, this._eventInput); 27.5194 + EventHandler.setOutputHandler(this, this._eventOutput); 27.5195 + 27.5196 + this._eventInput.on('mousedown', _handleStart.bind(this)); 27.5197 + this._eventInput.on('mousemove', _handleMove.bind(this)); 27.5198 + this._eventInput.on('mouseup', _handleEnd.bind(this)); 27.5199 + 27.5200 + if (this.options.propogate) this._eventInput.on('mouseleave', _handleLeave.bind(this)); 27.5201 + else this._eventInput.on('mouseleave', _handleEnd.bind(this)); 27.5202 + 27.5203 + this._payload = { 27.5204 + delta : null, 27.5205 + position : null, 27.5206 + velocity : null, 27.5207 + clientX : 0, 27.5208 + clientY : 0, 27.5209 + offsetX : 0, 27.5210 + offsetY : 0 27.5211 + }; 27.5212 + 27.5213 + this._position = null; // to be deprecated 27.5214 + this._prevCoord = undefined; 27.5215 + this._prevTime = undefined; 27.5216 + this._down = false; 27.5217 + this._moved = false; 27.5218 + } 27.5219 + 27.5220 + MouseSync.DEFAULT_OPTIONS = { 27.5221 + direction: undefined, 27.5222 + rails: false, 27.5223 + scale: 1, 27.5224 + propogate: true // events piped to document on mouseleave 27.5225 + }; 27.5226 + 27.5227 + MouseSync.DIRECTION_X = 0; 27.5228 + MouseSync.DIRECTION_Y = 1; 27.5229 + 27.5230 + var MINIMUM_TICK_TIME = 8; 27.5231 + 27.5232 + var _now = Date.now; 27.5233 + 27.5234 + function _handleStart(event) { 27.5235 + var delta; 27.5236 + var velocity; 27.5237 + event.preventDefault(); // prevent drag 27.5238 + 27.5239 + var x = event.clientX; 27.5240 + var y = event.clientY; 27.5241 + 27.5242 + this._prevCoord = [x, y]; 27.5243 + this._prevTime = _now(); 27.5244 + this._down = true; 27.5245 + this._move = false; 27.5246 + 27.5247 + if (this.options.direction !== undefined){ 27.5248 + this._position = 0; 27.5249 + delta = 0; 27.5250 + velocity = 0; 27.5251 + } 27.5252 + else { 27.5253 + this._position = [0, 0]; 27.5254 + delta = [0, 0]; 27.5255 + velocity = [0, 0]; 27.5256 + } 27.5257 + 27.5258 + var payload = this._payload; 27.5259 + payload.delta = delta; 27.5260 + payload.position = this._position; 27.5261 + payload.velocity = velocity; 27.5262 + payload.clientX = x; 27.5263 + payload.clientY = y; 27.5264 + payload.offsetX = event.offsetX; 27.5265 + payload.offsetY = event.offsetY; 27.5266 + 27.5267 + this._eventOutput.emit('start', payload); 27.5268 + } 27.5269 + 27.5270 + function _handleMove(event) { 27.5271 + if (!this._prevCoord) return; 27.5272 + 27.5273 + var prevCoord = this._prevCoord; 27.5274 + var prevTime = this._prevTime; 27.5275 + 27.5276 + var x = event.clientX; 27.5277 + var y = event.clientY; 27.5278 + 27.5279 + var currTime = _now(); 27.5280 + 27.5281 + var diffX = x - prevCoord[0]; 27.5282 + var diffY = y - prevCoord[1]; 27.5283 + 27.5284 + if (this.options.rails) { 27.5285 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 27.5286 + else diffX = 0; 27.5287 + } 27.5288 + 27.5289 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time 27.5290 + 27.5291 + var velX = diffX / diffTime; 27.5292 + var velY = diffY / diffTime; 27.5293 + 27.5294 + var scale = this.options.scale; 27.5295 + var nextVel; 27.5296 + var nextDelta; 27.5297 + 27.5298 + if (this.options.direction === MouseSync.DIRECTION_X) { 27.5299 + nextDelta = scale * diffX; 27.5300 + nextVel = scale * velX; 27.5301 + this._position += nextDelta; 27.5302 + } 27.5303 + else if (this.options.direction === MouseSync.DIRECTION_Y) { 27.5304 + nextDelta = scale * diffY; 27.5305 + nextVel = scale * velY; 27.5306 + this._position += nextDelta; 27.5307 + } 27.5308 + else { 27.5309 + nextDelta = [scale * diffX, scale * diffY]; 27.5310 + nextVel = [scale * velX, scale * velY]; 27.5311 + this._position[0] += nextDelta[0]; 27.5312 + this._position[1] += nextDelta[1]; 27.5313 + } 27.5314 + 27.5315 + var payload = this._payload; 27.5316 + payload.delta = nextDelta; 27.5317 + payload.position = this._position; 27.5318 + payload.velocity = nextVel; 27.5319 + payload.clientX = x; 27.5320 + payload.clientY = y; 27.5321 + payload.offsetX = event.offsetX; 27.5322 + payload.offsetY = event.offsetY; 27.5323 + 27.5324 + this._eventOutput.emit('update', payload); 27.5325 + 27.5326 + this._prevCoord = [x, y]; 27.5327 + this._prevTime = currTime; 27.5328 + this._move = true; 27.5329 + } 27.5330 + 27.5331 + function _handleEnd(event) { 27.5332 + if (!this._down) return; 27.5333 + 27.5334 + this._eventOutput.emit('end', this._payload); 27.5335 + this._prevCoord = undefined; 27.5336 + this._prevTime = undefined; 27.5337 + this._down = false; 27.5338 + this._move = false; 27.5339 + } 27.5340 + 27.5341 + function _handleLeave(event) { 27.5342 + if (!this._down || !this._move) return; 27.5343 + 27.5344 + var boundMove = _handleMove.bind(this); 27.5345 + var boundEnd = function(event) { 27.5346 + _handleEnd.call(this, event); 27.5347 + document.removeEventListener('mousemove', boundMove); 27.5348 + document.removeEventListener('mouseup', boundEnd); 27.5349 + }.bind(this, event); 27.5350 + 27.5351 + document.addEventListener('mousemove', boundMove); 27.5352 + document.addEventListener('mouseup', boundEnd); 27.5353 + } 27.5354 + 27.5355 + /** 27.5356 + * Return entire options dictionary, including defaults. 27.5357 + * 27.5358 + * @method getOptions 27.5359 + * @return {Object} configuration options 27.5360 + */ 27.5361 + MouseSync.prototype.getOptions = function getOptions() { 27.5362 + return this.options; 27.5363 + }; 27.5364 + 27.5365 + /** 27.5366 + * Set internal options, overriding any default options 27.5367 + * 27.5368 + * @method setOptions 27.5369 + * 27.5370 + * @param [options] {Object} default options overrides 27.5371 + * @param [options.direction] {Number} read from a particular axis 27.5372 + * @param [options.rails] {Boolean} read from axis with greatest differential 27.5373 + * @param [options.propogate] {Boolean} add listened to document on mouseleave 27.5374 + */ 27.5375 + MouseSync.prototype.setOptions = function setOptions(options) { 27.5376 + if (options.direction !== undefined) this.options.direction = options.direction; 27.5377 + if (options.rails !== undefined) this.options.rails = options.rails; 27.5378 + if (options.scale !== undefined) this.options.scale = options.scale; 27.5379 + if (options.propogate !== undefined) this.options.propogate = options.propogate; 27.5380 + }; 27.5381 + 27.5382 + module.exports = MouseSync; 27.5383 +}); 27.5384 + 27.5385 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5386 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.5387 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.5388 + * 27.5389 + * Owner: mark@famo.us 27.5390 + * @license MPL 2.0 27.5391 + * @copyright Famous Industries, Inc. 2014 27.5392 + */ 27.5393 + 27.5394 +define('famous/inputs/TouchTracker',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.5395 + var EventHandler = require('famous/core/EventHandler'); 27.5396 + 27.5397 + var _now = Date.now; 27.5398 + 27.5399 + function _timestampTouch(touch, event, history) { 27.5400 + return { 27.5401 + x: touch.clientX, 27.5402 + y: touch.clientY, 27.5403 + identifier : touch.identifier, 27.5404 + origin: event.origin, 27.5405 + timestamp: _now(), 27.5406 + count: event.touches.length, 27.5407 + history: history 27.5408 + }; 27.5409 + } 27.5410 + 27.5411 + function _handleStart(event) { 27.5412 + for (var i = 0; i < event.changedTouches.length; i++) { 27.5413 + var touch = event.changedTouches[i]; 27.5414 + var data = _timestampTouch(touch, event, null); 27.5415 + this.eventOutput.emit('trackstart', data); 27.5416 + if (!this.selective && !this.touchHistory[touch.identifier]) this.track(data); 27.5417 + } 27.5418 + } 27.5419 + 27.5420 + function _handleMove(event) { 27.5421 + for (var i = 0; i < event.changedTouches.length; i++) { 27.5422 + var touch = event.changedTouches[i]; 27.5423 + var history = this.touchHistory[touch.identifier]; 27.5424 + if (history) { 27.5425 + var data = _timestampTouch(touch, event, history); 27.5426 + this.touchHistory[touch.identifier].push(data); 27.5427 + this.eventOutput.emit('trackmove', data); 27.5428 + } 27.5429 + } 27.5430 + } 27.5431 + 27.5432 + function _handleEnd(event) { 27.5433 + for (var i = 0; i < event.changedTouches.length; i++) { 27.5434 + var touch = event.changedTouches[i]; 27.5435 + var history = this.touchHistory[touch.identifier]; 27.5436 + if (history) { 27.5437 + var data = _timestampTouch(touch, event, history); 27.5438 + this.eventOutput.emit('trackend', data); 27.5439 + delete this.touchHistory[touch.identifier]; 27.5440 + } 27.5441 + } 27.5442 + } 27.5443 + 27.5444 + function _handleUnpipe() { 27.5445 + for (var i in this.touchHistory) { 27.5446 + var history = this.touchHistory[i]; 27.5447 + this.eventOutput.emit('trackend', { 27.5448 + touch: history[history.length - 1].touch, 27.5449 + timestamp: Date.now(), 27.5450 + count: 0, 27.5451 + history: history 27.5452 + }); 27.5453 + delete this.touchHistory[i]; 27.5454 + } 27.5455 + } 27.5456 + 27.5457 + /** 27.5458 + * Helper to TouchSync – tracks piped in touch events, organizes touch 27.5459 + * events by ID, and emits track events back to TouchSync. 27.5460 + * Emits 'trackstart', 'trackmove', and 'trackend' events upstream. 27.5461 + * 27.5462 + * @class TouchTracker 27.5463 + * @constructor 27.5464 + * @param {Boolean} selective if false, save state for each touch. 27.5465 + */ 27.5466 + function TouchTracker(selective) { 27.5467 + this.selective = selective; 27.5468 + this.touchHistory = {}; 27.5469 + 27.5470 + this.eventInput = new EventHandler(); 27.5471 + this.eventOutput = new EventHandler(); 27.5472 + 27.5473 + EventHandler.setInputHandler(this, this.eventInput); 27.5474 + EventHandler.setOutputHandler(this, this.eventOutput); 27.5475 + 27.5476 + this.eventInput.on('touchstart', _handleStart.bind(this)); 27.5477 + this.eventInput.on('touchmove', _handleMove.bind(this)); 27.5478 + this.eventInput.on('touchend', _handleEnd.bind(this)); 27.5479 + this.eventInput.on('touchcancel', _handleEnd.bind(this)); 27.5480 + this.eventInput.on('unpipe', _handleUnpipe.bind(this)); 27.5481 + } 27.5482 + 27.5483 + /** 27.5484 + * Record touch data, if selective is false. 27.5485 + * @private 27.5486 + * @method track 27.5487 + * @param {Object} data touch data 27.5488 + */ 27.5489 + TouchTracker.prototype.track = function track(data) { 27.5490 + this.touchHistory[data.identifier] = [data]; 27.5491 + }; 27.5492 + 27.5493 + module.exports = TouchTracker; 27.5494 +}); 27.5495 + 27.5496 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5497 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.5498 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.5499 + * 27.5500 + * Owner: mark@famo.us 27.5501 + * @license MPL 2.0 27.5502 + * @copyright Famous Industries, Inc. 2014 27.5503 + */ 27.5504 + 27.5505 +define('famous/inputs/TouchSync',['require','exports','module','./TouchTracker','famous/core/EventHandler'],function(require, exports, module) { 27.5506 + var TouchTracker = require('./TouchTracker'); 27.5507 + var EventHandler = require('famous/core/EventHandler'); 27.5508 + 27.5509 + /** 27.5510 + * Handles piped in touch events. Emits 'start', 'update', and 'events' 27.5511 + * events with position, velocity, acceleration, and touch id. 27.5512 + * Useful for dealing with inputs on touch devices. 27.5513 + * 27.5514 + * 27.5515 + * @class TouchSync 27.5516 + * @constructor 27.5517 + * 27.5518 + * @param [options] {Object} default options overrides 27.5519 + * @param [options.direction] {Number} read from a particular axis 27.5520 + * @param [options.rails] {Boolean} read from axis with greatest differential 27.5521 + * @param [options.scale] {Number} constant factor to scale velocity output 27.5522 + */ 27.5523 + function TouchSync(options) { 27.5524 + this.options = Object.create(TouchSync.DEFAULT_OPTIONS); 27.5525 + if (options) this.setOptions(options); 27.5526 + 27.5527 + this._eventOutput = new EventHandler(); 27.5528 + this._touchTracker = new TouchTracker(); 27.5529 + 27.5530 + EventHandler.setOutputHandler(this, this._eventOutput); 27.5531 + EventHandler.setInputHandler(this, this._touchTracker); 27.5532 + 27.5533 + this._touchTracker.on('trackstart', _handleStart.bind(this)); 27.5534 + this._touchTracker.on('trackmove', _handleMove.bind(this)); 27.5535 + this._touchTracker.on('trackend', _handleEnd.bind(this)); 27.5536 + 27.5537 + this._payload = { 27.5538 + delta : null, 27.5539 + position : null, 27.5540 + velocity : null, 27.5541 + clientX : undefined, 27.5542 + clientY : undefined, 27.5543 + count : 0, 27.5544 + touch : undefined 27.5545 + }; 27.5546 + 27.5547 + this._position = null; // to be deprecated 27.5548 + } 27.5549 + 27.5550 + TouchSync.DEFAULT_OPTIONS = { 27.5551 + direction: undefined, 27.5552 + rails: false, 27.5553 + scale: 1 27.5554 + }; 27.5555 + 27.5556 + TouchSync.DIRECTION_X = 0; 27.5557 + TouchSync.DIRECTION_Y = 1; 27.5558 + 27.5559 + var MINIMUM_TICK_TIME = 8; 27.5560 + 27.5561 + // handle 'trackstart' 27.5562 + function _handleStart(data) { 27.5563 + var velocity; 27.5564 + var delta; 27.5565 + if (this.options.direction !== undefined){ 27.5566 + this._position = 0; 27.5567 + velocity = 0; 27.5568 + delta = 0; 27.5569 + } 27.5570 + else { 27.5571 + this._position = [0, 0]; 27.5572 + velocity = [0, 0]; 27.5573 + delta = [0, 0]; 27.5574 + } 27.5575 + 27.5576 + var payload = this._payload; 27.5577 + payload.delta = delta; 27.5578 + payload.position = this._position; 27.5579 + payload.velocity = velocity; 27.5580 + payload.clientX = data.x; 27.5581 + payload.clientY = data.y; 27.5582 + payload.count = data.count; 27.5583 + payload.touch = data.identifier; 27.5584 + 27.5585 + this._eventOutput.emit('start', payload); 27.5586 + } 27.5587 + 27.5588 + // handle 'trackmove' 27.5589 + function _handleMove(data) { 27.5590 + var history = data.history; 27.5591 + 27.5592 + var currHistory = history[history.length - 1]; 27.5593 + var prevHistory = history[history.length - 2]; 27.5594 + 27.5595 + var prevTime = prevHistory.timestamp; 27.5596 + var currTime = currHistory.timestamp; 27.5597 + 27.5598 + var diffX = currHistory.x - prevHistory.x; 27.5599 + var diffY = currHistory.y - prevHistory.y; 27.5600 + 27.5601 + if (this.options.rails) { 27.5602 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 27.5603 + else diffX = 0; 27.5604 + } 27.5605 + 27.5606 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); 27.5607 + 27.5608 + var velX = diffX / diffTime; 27.5609 + var velY = diffY / diffTime; 27.5610 + 27.5611 + var scale = this.options.scale; 27.5612 + var nextVel; 27.5613 + var nextDelta; 27.5614 + 27.5615 + if (this.options.direction === TouchSync.DIRECTION_X) { 27.5616 + nextDelta = scale * diffX; 27.5617 + nextVel = scale * velX; 27.5618 + this._position += nextDelta; 27.5619 + } 27.5620 + else if (this.options.direction === TouchSync.DIRECTION_Y) { 27.5621 + nextDelta = scale * diffY; 27.5622 + nextVel = scale * velY; 27.5623 + this._position += nextDelta; 27.5624 + } 27.5625 + else { 27.5626 + nextDelta = [scale * diffX, scale * diffY]; 27.5627 + nextVel = [scale * velX, scale * velY]; 27.5628 + this._position[0] += nextDelta[0]; 27.5629 + this._position[1] += nextDelta[1]; 27.5630 + } 27.5631 + 27.5632 + var payload = this._payload; 27.5633 + payload.delta = nextDelta; 27.5634 + payload.velocity = nextVel; 27.5635 + payload.position = this._position; 27.5636 + payload.clientX = data.x; 27.5637 + payload.clientY = data.y; 27.5638 + payload.count = data.count; 27.5639 + payload.touch = data.identifier; 27.5640 + 27.5641 + this._eventOutput.emit('update', payload); 27.5642 + } 27.5643 + 27.5644 + // handle 'trackend' 27.5645 + function _handleEnd(data) { 27.5646 + this._payload.count = data.count; 27.5647 + this._eventOutput.emit('end', this._payload); 27.5648 + } 27.5649 + 27.5650 + /** 27.5651 + * Set internal options, overriding any default options 27.5652 + * 27.5653 + * @method setOptions 27.5654 + * 27.5655 + * @param [options] {Object} default options overrides 27.5656 + * @param [options.direction] {Number} read from a particular axis 27.5657 + * @param [options.rails] {Boolean} read from axis with greatest differential 27.5658 + * @param [options.scale] {Number} constant factor to scale velocity output 27.5659 + */ 27.5660 + TouchSync.prototype.setOptions = function setOptions(options) { 27.5661 + if (options.direction !== undefined) this.options.direction = options.direction; 27.5662 + if (options.rails !== undefined) this.options.rails = options.rails; 27.5663 + if (options.scale !== undefined) this.options.scale = options.scale; 27.5664 + }; 27.5665 + 27.5666 + /** 27.5667 + * Return entire options dictionary, including defaults. 27.5668 + * 27.5669 + * @method getOptions 27.5670 + * @return {Object} configuration options 27.5671 + */ 27.5672 + TouchSync.prototype.getOptions = function getOptions() { 27.5673 + return this.options; 27.5674 + }; 27.5675 + 27.5676 + module.exports = TouchSync; 27.5677 +}); 27.5678 + 27.5679 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.5680 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.5681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.5682 + * 27.5683 + * Owner: david@famo.us 27.5684 + * @license MPL 2.0 27.5685 + * @copyright Famous Industries, Inc. 2014 27.5686 + */ 27.5687 + 27.5688 +define('famous/modifiers/Draggable',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/EventHandler','famous/math/Utilities','famous/inputs/GenericSync','famous/inputs/MouseSync','famous/inputs/TouchSync'],function(require, exports, module) { 27.5689 + var Transform = require('famous/core/Transform'); 27.5690 + var Transitionable = require('famous/transitions/Transitionable'); 27.5691 + var EventHandler = require('famous/core/EventHandler'); 27.5692 + var Utilities = require('famous/math/Utilities'); 27.5693 + 27.5694 + var GenericSync = require('famous/inputs/GenericSync'); 27.5695 + var MouseSync = require('famous/inputs/MouseSync'); 27.5696 + var TouchSync = require('famous/inputs/TouchSync'); 27.5697 + GenericSync.register({'mouse': MouseSync, 'touch': TouchSync}); 27.5698 + 27.5699 + /** 27.5700 + * Makes added render nodes responsive to drag beahvior. 27.5701 + * Emits events 'start', 'update', 'end'. 27.5702 + * @class Draggable 27.5703 + * @constructor 27.5704 + * @param {Object} [options] options configuration object. 27.5705 + * @param {Number} [options.snapX] grid width for snapping during drag 27.5706 + * @param {Number} [options.snapY] grid height for snapping during drag 27.5707 + * @param {Array.Number} [options.xRange] maxmimum [negative, positive] x displacement from start of drag 27.5708 + * @param {Array.Number} [options.yRange] maxmimum [negative, positive] y displacement from start of drag 27.5709 + * @param {Number} [options.scale] one pixel of input motion translates to this many pixels of output drag motion 27.5710 + * @param {Number} [options.projection] User should set to Draggable._direction.x or 27.5711 + * Draggable._direction.y to constrain to one axis. 27.5712 + * 27.5713 + */ 27.5714 + function Draggable(options) { 27.5715 + this.options = Object.create(Draggable.DEFAULT_OPTIONS); 27.5716 + if (options) this.setOptions(options); 27.5717 + 27.5718 + this._positionState = new Transitionable([0,0]); 27.5719 + this._differential = [0,0]; 27.5720 + this._active = true; 27.5721 + 27.5722 + this.sync = new GenericSync(['mouse', 'touch'], {scale : this.options.scale}); 27.5723 + this.eventOutput = new EventHandler(); 27.5724 + EventHandler.setInputHandler(this, this.sync); 27.5725 + EventHandler.setOutputHandler(this, this.eventOutput); 27.5726 + 27.5727 + _bindEvents.call(this); 27.5728 + } 27.5729 + 27.5730 + //binary representation of directions for bitwise operations 27.5731 + var _direction = { 27.5732 + x : 0x01, //001 27.5733 + y : 0x02 //010 27.5734 + }; 27.5735 + 27.5736 + Draggable.DIRECTION_X = _direction.x; 27.5737 + Draggable.DIRECTION_Y = _direction.y; 27.5738 + 27.5739 + var _clamp = Utilities.clamp; 27.5740 + 27.5741 + Draggable.DEFAULT_OPTIONS = { 27.5742 + projection : _direction.x | _direction.y, 27.5743 + scale : 1, 27.5744 + xRange : null, 27.5745 + yRange : null, 27.5746 + snapX : 0, 27.5747 + snapY : 0, 27.5748 + transition : {duration : 0} 27.5749 + }; 27.5750 + 27.5751 + function _mapDifferential(differential) { 27.5752 + var opts = this.options; 27.5753 + var projection = opts.projection; 27.5754 + var snapX = opts.snapX; 27.5755 + var snapY = opts.snapY; 27.5756 + 27.5757 + //axes 27.5758 + var tx = (projection & _direction.x) ? differential[0] : 0; 27.5759 + var ty = (projection & _direction.y) ? differential[1] : 0; 27.5760 + 27.5761 + //snapping 27.5762 + if (snapX > 0) tx -= tx % snapX; 27.5763 + if (snapY > 0) ty -= ty % snapY; 27.5764 + 27.5765 + return [tx, ty]; 27.5766 + } 27.5767 + 27.5768 + function _handleStart() { 27.5769 + if (!this._active) return; 27.5770 + if (this._positionState.isActive()) this._positionState.halt(); 27.5771 + this.eventOutput.emit('start', {position : this.getPosition()}); 27.5772 + } 27.5773 + 27.5774 + function _handleMove(event) { 27.5775 + if (!this._active) return; 27.5776 + 27.5777 + var options = this.options; 27.5778 + this._differential = event.position; 27.5779 + var newDifferential = _mapDifferential.call(this, this._differential); 27.5780 + 27.5781 + //buffer the differential if snapping is set 27.5782 + this._differential[0] -= newDifferential[0]; 27.5783 + this._differential[1] -= newDifferential[1]; 27.5784 + 27.5785 + var pos = this.getPosition(); 27.5786 + 27.5787 + //modify position, retain reference 27.5788 + pos[0] += newDifferential[0]; 27.5789 + pos[1] += newDifferential[1]; 27.5790 + 27.5791 + //handle bounding box 27.5792 + if (options.xRange){ 27.5793 + var xRange = [options.xRange[0] + 0.5 * options.snapX, options.xRange[1] - 0.5 * options.snapX]; 27.5794 + pos[0] = _clamp(pos[0], xRange); 27.5795 + } 27.5796 + 27.5797 + if (options.yRange){ 27.5798 + var yRange = [options.yRange[0] + 0.5 * options.snapY, options.yRange[1] - 0.5 * options.snapY]; 27.5799 + pos[1] = _clamp(pos[1], yRange); 27.5800 + } 27.5801 + 27.5802 + this.eventOutput.emit('update', {position : pos}); 27.5803 + } 27.5804 + 27.5805 + function _handleEnd() { 27.5806 + if (!this._active) return; 27.5807 + this.eventOutput.emit('end', {position : this.getPosition()}); 27.5808 + } 27.5809 + 27.5810 + function _bindEvents() { 27.5811 + this.sync.on('start', _handleStart.bind(this)); 27.5812 + this.sync.on('update', _handleMove.bind(this)); 27.5813 + this.sync.on('end', _handleEnd.bind(this)); 27.5814 + } 27.5815 + 27.5816 + /** 27.5817 + * Set internal options, overriding any default options 27.5818 + * 27.5819 + * @method setOptions 27.5820 + * 27.5821 + * @param {Object} [options] overrides of default options. See constructor. 27.5822 + */ 27.5823 + Draggable.prototype.setOptions = function setOptions(options) { 27.5824 + var currentOptions = this.options; 27.5825 + if (options.projection !== undefined) { 27.5826 + var proj = options.projection; 27.5827 + this.options.projection = 0; 27.5828 + ['x', 'y'].forEach(function(val) { 27.5829 + if (proj.indexOf(val) !== -1) currentOptions.projection |= _direction[val]; 27.5830 + }); 27.5831 + } 27.5832 + if (options.scale !== undefined) { 27.5833 + currentOptions.scale = options.scale; 27.5834 + this.sync.setOptions({ 27.5835 + scale: options.scale 27.5836 + }); 27.5837 + } 27.5838 + if (options.xRange !== undefined) currentOptions.xRange = options.xRange; 27.5839 + if (options.yRange !== undefined) currentOptions.yRange = options.yRange; 27.5840 + if (options.snapX !== undefined) currentOptions.snapX = options.snapX; 27.5841 + if (options.snapY !== undefined) currentOptions.snapY = options.snapY; 27.5842 + }; 27.5843 + 27.5844 + /** 27.5845 + * Get current delta in position from where this draggable started. 27.5846 + * 27.5847 + * @method getPosition 27.5848 + * 27.5849 + * @return {array<number>} [x, y] position delta from start. 27.5850 + */ 27.5851 + Draggable.prototype.getPosition = function getPosition() { 27.5852 + return this._positionState.get(); 27.5853 + }; 27.5854 + 27.5855 + /** 27.5856 + * Transition the element to the desired relative position via provided transition. 27.5857 + * For example, calling this with [0,0] will not change the position. 27.5858 + * Callback will be executed on completion. 27.5859 + * 27.5860 + * @method setRelativePosition 27.5861 + * 27.5862 + * @param {array<number>} position end state to which we interpolate 27.5863 + * @param {transition} transition transition object specifying how object moves to new position 27.5864 + * @param {function} callback zero-argument function to call on observed completion 27.5865 + */ 27.5866 + Draggable.prototype.setRelativePosition = function setRelativePosition(position, transition, callback) { 27.5867 + var currPos = this.getPosition(); 27.5868 + var relativePosition = [currPos[0] + position[0], currPos[1] + position[1]]; 27.5869 + this.setPosition(relativePosition, transition, callback); 27.5870 + }; 27.5871 + 27.5872 + /** 27.5873 + * Transition the element to the desired absolute position via provided transition. 27.5874 + * Callback will be executed on completion. 27.5875 + * 27.5876 + * @method setPosition 27.5877 + * 27.5878 + * @param {array<number>} position end state to which we interpolate 27.5879 + * @param {transition} transition transition object specifying how object moves to new position 27.5880 + * @param {function} callback zero-argument function to call on observed completion 27.5881 + */ 27.5882 + Draggable.prototype.setPosition = function setPosition(position, transition, callback) { 27.5883 + if (this._positionState.isActive()) this._positionState.halt(); 27.5884 + this._positionState.set(position, transition, callback); 27.5885 + }; 27.5886 + 27.5887 + /** 27.5888 + * Set this draggable to respond to user input. 27.5889 + * 27.5890 + * @method activate 27.5891 + * 27.5892 + */ 27.5893 + Draggable.prototype.activate = function activate() { 27.5894 + this._active = true; 27.5895 + }; 27.5896 + 27.5897 + /** 27.5898 + * Set this draggable to ignore user input. 27.5899 + * 27.5900 + * @method deactivate 27.5901 + * 27.5902 + */ 27.5903 + Draggable.prototype.deactivate = function deactivate() { 27.5904 + this._active = false; 27.5905 + }; 27.5906 + 27.5907 + /** 27.5908 + * Switch the input response stage between active and inactive. 27.5909 + * 27.5910 + * @method toggle 27.5911 + * 27.5912 + */ 27.5913 + Draggable.prototype.toggle = function toggle() { 27.5914 + this._active = !this._active; 27.5915 + }; 27.5916 + 27.5917 + /** 27.5918 + * Return render spec for this Modifier, applying to the provided 27.5919 + * target component. This is similar to render() for Surfaces. 27.5920 + * 27.5921 + * @private 27.5922 + * @method modify 27.5923 + * 27.5924 + * @param {Object} target (already rendered) render spec to 27.5925 + * which to apply the transform. 27.5926 + * @return {Object} render spec for this Modifier, including the 27.5927 + * provided target 27.5928 + */ 27.5929 + Draggable.prototype.modify = function modify(target) { 27.5930 + var pos = this.getPosition(); 27.5931 + return { 27.5932 + transform: Transform.translate(pos[0], pos[1]), 27.5933 + target: target 27.5934 + }; 27.5935 + }; 27.5936 + 27.5937 + module.exports = Draggable; 27.5938 +}); 27.5939 + 27.5940 +define('famous/modifiers/Fader',['require','exports','module','famous/transitions/Transitionable','famous/core/OptionsManager'],function(require, exports, module) { 27.5941 + var Transitionable = require('famous/transitions/Transitionable'); 27.5942 + var OptionsManager = require('famous/core/OptionsManager'); 27.5943 + 27.5944 + /** 27.5945 + * Modifier that allows you to fade the opacity of affected renderables in and out. 27.5946 + * @class Fader 27.5947 + * @constructor 27.5948 + * @param {Object} [options] options configuration object. 27.5949 + * @param {Boolean} [options.cull=false] Stops returning affected renderables up the tree when they're fully faded when true. 27.5950 + * @param {Transition} [options.transition=true] The main transition for showing and hiding. 27.5951 + * @param {Transition} [options.pulseInTransition=true] Controls the transition to a pulsed state when the Fader instance's pulse 27.5952 + * method is called. 27.5953 + * @param {Transition} [options.pulseOutTransition=true]Controls the transition back from a pulsed state when the Fader instance's pulse 27.5954 + * method is called. 27.5955 + * 27.5956 + */ 27.5957 + function Fader(options, startState) { 27.5958 + this.options = Object.create(Fader.DEFAULT_OPTIONS); 27.5959 + this._optionsManager = new OptionsManager(this.options); 27.5960 + 27.5961 + if (options) this.setOptions(options); 27.5962 + 27.5963 + if (!startState) startState = 0; 27.5964 + this.transitionHelper = new Transitionable(startState); 27.5965 + } 27.5966 + 27.5967 + Fader.DEFAULT_OPTIONS = { 27.5968 + cull: false, 27.5969 + transition: true, 27.5970 + pulseInTransition: true, 27.5971 + pulseOutTransition: true 27.5972 + }; 27.5973 + 27.5974 + /** 27.5975 + * Set internal options, overriding any default options 27.5976 + * 27.5977 + * @method setOptions 27.5978 + * 27.5979 + * @param {Object} [options] overrides of default options. See constructor. 27.5980 + */ 27.5981 + Fader.prototype.setOptions = function setOptions(options) { 27.5982 + return this._optionsManager.setOptions(options); 27.5983 + }; 27.5984 + 27.5985 + /** 27.5986 + * Fully displays the Fader instance's associated renderables. 27.5987 + * 27.5988 + * @method show 27.5989 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 27.5990 + * @param {Function} [callback] A callback that executes once you've transitioned to the fully shown state. 27.5991 + */ 27.5992 + Fader.prototype.show = function show(transition, callback) { 27.5993 + transition = transition || this.options.transition; 27.5994 + this.set(1, transition, callback); 27.5995 + }; 27.5996 + 27.5997 + /** 27.5998 + * Fully fades the Fader instance's associated renderables. 27.5999 + * 27.6000 + * @method hide 27.6001 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 27.6002 + * @param {Function} [callback] A callback that executes once you've transitioned to the fully faded state. 27.6003 + */ 27.6004 + Fader.prototype.hide = function hide(transition, callback) { 27.6005 + transition = transition || this.options.transition; 27.6006 + this.set(0, transition, callback); 27.6007 + }; 27.6008 + 27.6009 + /** 27.6010 + * Manually sets the opacity state of the fader to the passed-in one. Executes with an optional 27.6011 + * transition and callback. 27.6012 + * 27.6013 + * @method set 27.6014 + * @param {Number} state A number from zero to one: the amount of opacity you want to set to. 27.6015 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 27.6016 + * @param {Function} [callback] A callback that executes once you've finished executing the pulse. 27.6017 + */ 27.6018 + Fader.prototype.set = function set(state, transition, callback) { 27.6019 + this.halt(); 27.6020 + this.transitionHelper.set(state, transition, callback); 27.6021 + }; 27.6022 + 27.6023 + /** 27.6024 + * Halt the transition 27.6025 + * 27.6026 + * @method halt 27.6027 + */ 27.6028 + Fader.prototype.halt = function halt() { 27.6029 + this.transitionHelper.halt(); 27.6030 + }; 27.6031 + 27.6032 + /** 27.6033 + * Tells you if your Fader instance is above its visibility threshold. 27.6034 + * 27.6035 + * @method isVisible 27.6036 + * @return {Boolean} Whether or not your Fader instance is visible. 27.6037 + */ 27.6038 + Fader.prototype.isVisible = function isVisible() { 27.6039 + return (this.transitionHelper.get() > 0); 27.6040 + }; 27.6041 + 27.6042 + /** 27.6043 + * Return render spec for this Modifier, applying to the provided 27.6044 + * target component. This is similar to render() for Surfaces. 27.6045 + * 27.6046 + * @private 27.6047 + * @method modify 27.6048 + * 27.6049 + * @param {Object} target (already rendered) render spec to 27.6050 + * which to apply the transform. 27.6051 + * @return {Object} render spec for this Modifier, including the 27.6052 + * provided target 27.6053 + */ 27.6054 + Fader.prototype.modify = function modify(target) { 27.6055 + var currOpacity = this.transitionHelper.get(); 27.6056 + if (this.options.cull && !currOpacity) return undefined; 27.6057 + else return {opacity: currOpacity, target: target}; 27.6058 + }; 27.6059 + 27.6060 + module.exports = Fader; 27.6061 +}); 27.6062 + 27.6063 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.6064 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6065 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.6066 + * 27.6067 + * Owner: david@famo.us 27.6068 + * @license MPL 2.0 27.6069 + * @copyright Famous Industries, Inc. 2014 27.6070 + */ 27.6071 + 27.6072 +define('famous/modifiers/ModifierChain',['require','exports','module'],function(require, exports, module) { 27.6073 + 27.6074 + /** 27.6075 + * A class to add and remove a chain of modifiers 27.6076 + * at a single point in the render tree 27.6077 + * 27.6078 + * @class ModifierChain 27.6079 + * @constructor 27.6080 + */ 27.6081 + function ModifierChain() { 27.6082 + this._chain = []; 27.6083 + if (arguments.length) this.addModifier.apply(this, arguments); 27.6084 + } 27.6085 + 27.6086 + /** 27.6087 + * Add a modifier, or comma separated modifiers, to the modifier chain. 27.6088 + * 27.6089 + * @method addModifier 27.6090 + * 27.6091 + * @param {...Modifier*} varargs args list of Modifiers 27.6092 + */ 27.6093 + ModifierChain.prototype.addModifier = function addModifier(varargs) { 27.6094 + Array.prototype.push.apply(this._chain, arguments); 27.6095 + }; 27.6096 + 27.6097 + /** 27.6098 + * Remove a modifier from the modifier chain. 27.6099 + * 27.6100 + * @method removeModifier 27.6101 + * 27.6102 + * @param {Modifier} modifier 27.6103 + */ 27.6104 + ModifierChain.prototype.removeModifier = function removeModifier(modifier) { 27.6105 + var index = this._chain.indexOf(modifier); 27.6106 + if (index < 0) return; 27.6107 + this._chain.splice(index, 1); 27.6108 + }; 27.6109 + 27.6110 + /** 27.6111 + * Return render spec for this Modifier, applying to the provided 27.6112 + * target component. This is similar to render() for Surfaces. 27.6113 + * 27.6114 + * @private 27.6115 + * @method modify 27.6116 + * 27.6117 + * @param {Object} input (already rendered) render spec to 27.6118 + * which to apply the transform. 27.6119 + * @return {Object} render spec for this Modifier, including the 27.6120 + * provided target 27.6121 + */ 27.6122 + ModifierChain.prototype.modify = function modify(input) { 27.6123 + var chain = this._chain; 27.6124 + var result = input; 27.6125 + for (var i = 0; i < chain.length; i++) { 27.6126 + result = chain[i].modify(result); 27.6127 + } 27.6128 + return result; 27.6129 + }; 27.6130 + 27.6131 + module.exports = ModifierChain; 27.6132 +}); 27.6133 + 27.6134 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.6135 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6136 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.6137 + * 27.6138 + * Owner: mark@famo.us 27.6139 + * @license MPL 2.0 27.6140 + * @copyright Famous Industries, Inc. 2014 27.6141 + */ 27.6142 + 27.6143 +define('famous/modifiers/StateModifier',['require','exports','module','famous/core/Modifier','famous/core/Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 27.6144 + var Modifier = require('famous/core/Modifier'); 27.6145 + var Transform = require('famous/core/Transform'); 27.6146 + var Transitionable = require('famous/transitions/Transitionable'); 27.6147 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 27.6148 + 27.6149 + /** 27.6150 + * A collection of visual changes to be 27.6151 + * applied to another renderable component, strongly coupled with the state that defines 27.6152 + * those changes. This collection includes a 27.6153 + * transform matrix, an opacity constant, a size, an origin specifier, and an alignment specifier. 27.6154 + * StateModifier objects can be added to any RenderNode or object 27.6155 + * capable of displaying renderables. The StateModifier's children and descendants 27.6156 + * are transformed by the amounts specified in the modifier's properties. 27.6157 + * 27.6158 + * @class StateModifier 27.6159 + * @constructor 27.6160 + * @param {Object} [options] overrides of default options 27.6161 + * @param {Transform} [options.transform] affine transformation matrix 27.6162 + * @param {Number} [options.opacity] 27.6163 + * @param {Array.Number} [options.origin] origin adjustment 27.6164 + * @param {Array.Number} [options.align] align adjustment 27.6165 + * @param {Array.Number} [options.size] size to apply to descendants 27.6166 + */ 27.6167 + function StateModifier(options) { 27.6168 + this._transformState = new TransitionableTransform(Transform.identity); 27.6169 + this._opacityState = new Transitionable(1); 27.6170 + this._originState = new Transitionable([0, 0]); 27.6171 + this._alignState = new Transitionable([0, 0]); 27.6172 + this._sizeState = new Transitionable([0, 0]); 27.6173 + 27.6174 + this._modifier = new Modifier({ 27.6175 + transform: this._transformState, 27.6176 + opacity: this._opacityState, 27.6177 + origin: null, 27.6178 + align: null, 27.6179 + size: null 27.6180 + }); 27.6181 + 27.6182 + this._hasOrigin = false; 27.6183 + this._hasAlign = false; 27.6184 + this._hasSize = false; 27.6185 + 27.6186 + if (options) { 27.6187 + if (options.transform) this.setTransform(options.transform); 27.6188 + if (options.opacity !== undefined) this.setOpacity(options.opacity); 27.6189 + if (options.origin) this.setOrigin(options.origin); 27.6190 + if (options.align) this.setAlign(options.align); 27.6191 + if (options.size) this.setSize(options.size); 27.6192 + } 27.6193 + } 27.6194 + 27.6195 + /** 27.6196 + * Set the transform matrix of this modifier, either statically or 27.6197 + * through a provided Transitionable. 27.6198 + * 27.6199 + * @method setTransform 27.6200 + * 27.6201 + * @param {Transform} transform Transform to transition to. 27.6202 + * @param {Transitionable} [transition] Valid transitionable object 27.6203 + * @param {Function} [callback] callback to call after transition completes 27.6204 + * @return {StateModifier} this 27.6205 + */ 27.6206 + StateModifier.prototype.setTransform = function setTransform(transform, transition, callback) { 27.6207 + this._transformState.set(transform, transition, callback); 27.6208 + return this; 27.6209 + }; 27.6210 + 27.6211 + /** 27.6212 + * Set the opacity of this modifier, either statically or 27.6213 + * through a provided Transitionable. 27.6214 + * 27.6215 + * @method setOpacity 27.6216 + * 27.6217 + * @param {Number} opacity Opacity value to transition to. 27.6218 + * @param {Transitionable} transition Valid transitionable object 27.6219 + * @param {Function} callback callback to call after transition completes 27.6220 + * @return {StateModifier} this 27.6221 + */ 27.6222 + StateModifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) { 27.6223 + this._opacityState.set(opacity, transition, callback); 27.6224 + return this; 27.6225 + }; 27.6226 + 27.6227 + /** 27.6228 + * Set the origin of this modifier, either statically or 27.6229 + * through a provided Transitionable. 27.6230 + * 27.6231 + * @method setOrigin 27.6232 + * 27.6233 + * @param {Array.Number} origin two element array with values between 0 and 1. 27.6234 + * @param {Transitionable} transition Valid transitionable object 27.6235 + * @param {Function} callback callback to call after transition completes 27.6236 + * @return {StateModifier} this 27.6237 + */ 27.6238 + StateModifier.prototype.setOrigin = function setOrigin(origin, transition, callback) { 27.6239 + if (origin === null) { 27.6240 + if (this._hasOrigin) { 27.6241 + this._modifier.originFrom(null); 27.6242 + this._hasOrigin = false; 27.6243 + } 27.6244 + return this; 27.6245 + } 27.6246 + else if (!this._hasOrigin) { 27.6247 + this._hasOrigin = true; 27.6248 + this._modifier.originFrom(this._originState); 27.6249 + } 27.6250 + this._originState.set(origin, transition, callback); 27.6251 + return this; 27.6252 + }; 27.6253 + 27.6254 + /** 27.6255 + * Set the alignment of this modifier, either statically or 27.6256 + * through a provided Transitionable. 27.6257 + * 27.6258 + * @method setAlign 27.6259 + * 27.6260 + * @param {Array.Number} align two element array with values between 0 and 1. 27.6261 + * @param {Transitionable} transition Valid transitionable object 27.6262 + * @param {Function} callback callback to call after transition completes 27.6263 + * @return {StateModifier} this 27.6264 + */ 27.6265 + StateModifier.prototype.setAlign = function setOrigin(align, transition, callback) { 27.6266 + if (align === null) { 27.6267 + if (this._hasAlign) { 27.6268 + this._modifier.alignFrom(null); 27.6269 + this._hasAlign = false; 27.6270 + } 27.6271 + return this; 27.6272 + } 27.6273 + else if (!this._hasAlign) { 27.6274 + this._hasAlign = true; 27.6275 + this._modifier.alignFrom(this._alignState); 27.6276 + } 27.6277 + this._alignState.set(align, transition, callback); 27.6278 + return this; 27.6279 + }; 27.6280 + 27.6281 + /** 27.6282 + * Set the size of this modifier, either statically or 27.6283 + * through a provided Transitionable. 27.6284 + * 27.6285 + * @method setSize 27.6286 + * 27.6287 + * @param {Array.Number} size two element array with values between 0 and 1. 27.6288 + * @param {Transitionable} transition Valid transitionable object 27.6289 + * @param {Function} callback callback to call after transition completes 27.6290 + * @return {StateModifier} this 27.6291 + */ 27.6292 + StateModifier.prototype.setSize = function setSize(size, transition, callback) { 27.6293 + if (size === null) { 27.6294 + if (this._hasSize) { 27.6295 + this._modifier.sizeFrom(null); 27.6296 + this._hasSize = false; 27.6297 + } 27.6298 + return this; 27.6299 + } 27.6300 + else if (!this._hasSize) { 27.6301 + this._hasSize = true; 27.6302 + this._modifier.sizeFrom(this._sizeState); 27.6303 + } 27.6304 + this._sizeState.set(size, transition, callback); 27.6305 + return this; 27.6306 + }; 27.6307 + 27.6308 + /** 27.6309 + * Stop the transition. 27.6310 + * 27.6311 + * @method halt 27.6312 + */ 27.6313 + StateModifier.prototype.halt = function halt() { 27.6314 + this._transformState.halt(); 27.6315 + this._opacityState.halt(); 27.6316 + this._originState.halt(); 27.6317 + this._alignState.halt(); 27.6318 + this._sizeState.halt(); 27.6319 + }; 27.6320 + 27.6321 + /** 27.6322 + * Get the current state of the transform matrix component. 27.6323 + * 27.6324 + * @method getTransform 27.6325 + * @return {Object} transform provider object 27.6326 + */ 27.6327 + StateModifier.prototype.getTransform = function getTransform() { 27.6328 + return this._transformState.get(); 27.6329 + }; 27.6330 + 27.6331 + /** 27.6332 + * Get the destination state of the transform component. 27.6333 + * 27.6334 + * @method getFinalTransform 27.6335 + * @return {Transform} transform matrix 27.6336 + */ 27.6337 + StateModifier.prototype.getFinalTransform = function getFinalTransform() { 27.6338 + return this._transformState.getFinal(); 27.6339 + }; 27.6340 + 27.6341 + /** 27.6342 + * Get the current state of the opacity component. 27.6343 + * 27.6344 + * @method getOpacity 27.6345 + * @return {Object} opacity provider object 27.6346 + */ 27.6347 + StateModifier.prototype.getOpacity = function getOpacity() { 27.6348 + return this._opacityState.get(); 27.6349 + }; 27.6350 + 27.6351 + /** 27.6352 + * Get the current state of the origin component. 27.6353 + * 27.6354 + * @method getOrigin 27.6355 + * @return {Object} origin provider object 27.6356 + */ 27.6357 + StateModifier.prototype.getOrigin = function getOrigin() { 27.6358 + return this._hasOrigin ? this._originState.get() : null; 27.6359 + }; 27.6360 + 27.6361 + /** 27.6362 + * Get the current state of the align component. 27.6363 + * 27.6364 + * @method getAlign 27.6365 + * @return {Object} align provider object 27.6366 + */ 27.6367 + StateModifier.prototype.getAlign = function getAlign() { 27.6368 + return this._hasAlign ? this._alignState.get() : null; 27.6369 + }; 27.6370 + 27.6371 + /** 27.6372 + * Get the current state of the size component. 27.6373 + * 27.6374 + * @method getSize 27.6375 + * @return {Object} size provider object 27.6376 + */ 27.6377 + StateModifier.prototype.getSize = function getSize() { 27.6378 + return this._hasSize ? this._sizeState.get() : null; 27.6379 + }; 27.6380 + 27.6381 + /** 27.6382 + * Return render spec for this StateModifier, applying to the provided 27.6383 + * target component. This is similar to render() for Surfaces. 27.6384 + * 27.6385 + * @private 27.6386 + * @method modify 27.6387 + * 27.6388 + * @param {Object} target (already rendered) render spec to 27.6389 + * which to apply the transform. 27.6390 + * @return {Object} render spec for this StateModifier, including the 27.6391 + * provided target 27.6392 + */ 27.6393 + StateModifier.prototype.modify = function modify(target) { 27.6394 + return this._modifier.modify(target); 27.6395 + }; 27.6396 + 27.6397 + module.exports = StateModifier; 27.6398 +}); 27.6399 + 27.6400 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.6401 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6402 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.6403 + * 27.6404 + * Owner: david@famo.us 27.6405 + * @license MPL 2.0 27.6406 + * @copyright Famous Industries, Inc. 2014 27.6407 + */ 27.6408 + 27.6409 +define('famous/math/Vector',['require','exports','module'],function(require, exports, module) { 27.6410 + 27.6411 + /** 27.6412 + * Three-element floating point vector. 27.6413 + * 27.6414 + * @class Vector 27.6415 + * @constructor 27.6416 + * 27.6417 + * @param {number} x x element value 27.6418 + * @param {number} y y element value 27.6419 + * @param {number} z z element value 27.6420 + */ 27.6421 + function Vector(x,y,z) { 27.6422 + if (arguments.length === 1) this.set(x); 27.6423 + else { 27.6424 + this.x = x || 0; 27.6425 + this.y = y || 0; 27.6426 + this.z = z || 0; 27.6427 + } 27.6428 + return this; 27.6429 + } 27.6430 + 27.6431 + var _register = new Vector(0,0,0); 27.6432 + 27.6433 + /** 27.6434 + * Add this element-wise to another Vector, element-wise. 27.6435 + * Note: This sets the internal result register, so other references to that vector will change. 27.6436 + * 27.6437 + * @method add 27.6438 + * @param {Vector} v addend 27.6439 + * @return {Vector} vector sum 27.6440 + */ 27.6441 + Vector.prototype.add = function add(v) { 27.6442 + return _setXYZ.call(_register, 27.6443 + this.x + v.x, 27.6444 + this.y + v.y, 27.6445 + this.z + v.z 27.6446 + ); 27.6447 + }; 27.6448 + 27.6449 + /** 27.6450 + * Subtract another vector from this vector, element-wise. 27.6451 + * Note: This sets the internal result register, so other references to that vector will change. 27.6452 + * 27.6453 + * @method sub 27.6454 + * @param {Vector} v subtrahend 27.6455 + * @return {Vector} vector difference 27.6456 + */ 27.6457 + Vector.prototype.sub = function sub(v) { 27.6458 + return _setXYZ.call(_register, 27.6459 + this.x - v.x, 27.6460 + this.y - v.y, 27.6461 + this.z - v.z 27.6462 + ); 27.6463 + }; 27.6464 + 27.6465 + /** 27.6466 + * Scale Vector by floating point r. 27.6467 + * Note: This sets the internal result register, so other references to that vector will change. 27.6468 + * 27.6469 + * @method mult 27.6470 + * 27.6471 + * @param {number} r scalar 27.6472 + * @return {Vector} vector result 27.6473 + */ 27.6474 + Vector.prototype.mult = function mult(r) { 27.6475 + return _setXYZ.call(_register, 27.6476 + r * this.x, 27.6477 + r * this.y, 27.6478 + r * this.z 27.6479 + ); 27.6480 + }; 27.6481 + 27.6482 + /** 27.6483 + * Scale Vector by floating point 1/r. 27.6484 + * Note: This sets the internal result register, so other references to that vector will change. 27.6485 + * 27.6486 + * @method div 27.6487 + * 27.6488 + * @param {number} r scalar 27.6489 + * @return {Vector} vector result 27.6490 + */ 27.6491 + Vector.prototype.div = function div(r) { 27.6492 + return this.mult(1 / r); 27.6493 + }; 27.6494 + 27.6495 + /** 27.6496 + * Given another vector v, return cross product (v)x(this). 27.6497 + * Note: This sets the internal result register, so other references to that vector will change. 27.6498 + * 27.6499 + * @method cross 27.6500 + * @param {Vector} v Left Hand Vector 27.6501 + * @return {Vector} vector result 27.6502 + */ 27.6503 + Vector.prototype.cross = function cross(v) { 27.6504 + var x = this.x; 27.6505 + var y = this.y; 27.6506 + var z = this.z; 27.6507 + var vx = v.x; 27.6508 + var vy = v.y; 27.6509 + var vz = v.z; 27.6510 + 27.6511 + return _setXYZ.call(_register, 27.6512 + z * vy - y * vz, 27.6513 + x * vz - z * vx, 27.6514 + y * vx - x * vy 27.6515 + ); 27.6516 + }; 27.6517 + 27.6518 + /** 27.6519 + * Component-wise equality test between this and Vector v. 27.6520 + * @method equals 27.6521 + * @param {Vector} v vector to compare 27.6522 + * @return {boolean} 27.6523 + */ 27.6524 + Vector.prototype.equals = function equals(v) { 27.6525 + return (v.x === this.x && v.y === this.y && v.z === this.z); 27.6526 + }; 27.6527 + 27.6528 + /** 27.6529 + * Rotate clockwise around x-axis by theta radians. 27.6530 + * Note: This sets the internal result register, so other references to that vector will change. 27.6531 + * @method rotateX 27.6532 + * @param {number} theta radians 27.6533 + * @return {Vector} rotated vector 27.6534 + */ 27.6535 + Vector.prototype.rotateX = function rotateX(theta) { 27.6536 + var x = this.x; 27.6537 + var y = this.y; 27.6538 + var z = this.z; 27.6539 + 27.6540 + var cosTheta = Math.cos(theta); 27.6541 + var sinTheta = Math.sin(theta); 27.6542 + 27.6543 + return _setXYZ.call(_register, 27.6544 + x, 27.6545 + y * cosTheta - z * sinTheta, 27.6546 + y * sinTheta + z * cosTheta 27.6547 + ); 27.6548 + }; 27.6549 + 27.6550 + /** 27.6551 + * Rotate clockwise around y-axis by theta radians. 27.6552 + * Note: This sets the internal result register, so other references to that vector will change. 27.6553 + * @method rotateY 27.6554 + * @param {number} theta radians 27.6555 + * @return {Vector} rotated vector 27.6556 + */ 27.6557 + Vector.prototype.rotateY = function rotateY(theta) { 27.6558 + var x = this.x; 27.6559 + var y = this.y; 27.6560 + var z = this.z; 27.6561 + 27.6562 + var cosTheta = Math.cos(theta); 27.6563 + var sinTheta = Math.sin(theta); 27.6564 + 27.6565 + return _setXYZ.call(_register, 27.6566 + z * sinTheta + x * cosTheta, 27.6567 + y, 27.6568 + z * cosTheta - x * sinTheta 27.6569 + ); 27.6570 + }; 27.6571 + 27.6572 + /** 27.6573 + * Rotate clockwise around z-axis by theta radians. 27.6574 + * Note: This sets the internal result register, so other references to that vector will change. 27.6575 + * @method rotateZ 27.6576 + * @param {number} theta radians 27.6577 + * @return {Vector} rotated vector 27.6578 + */ 27.6579 + Vector.prototype.rotateZ = function rotateZ(theta) { 27.6580 + var x = this.x; 27.6581 + var y = this.y; 27.6582 + var z = this.z; 27.6583 + 27.6584 + var cosTheta = Math.cos(theta); 27.6585 + var sinTheta = Math.sin(theta); 27.6586 + 27.6587 + return _setXYZ.call(_register, 27.6588 + x * cosTheta - y * sinTheta, 27.6589 + x * sinTheta + y * cosTheta, 27.6590 + z 27.6591 + ); 27.6592 + }; 27.6593 + 27.6594 + /** 27.6595 + * Return dot product of this with a second Vector 27.6596 + * @method dot 27.6597 + * @param {Vector} v second vector 27.6598 + * @return {number} dot product 27.6599 + */ 27.6600 + Vector.prototype.dot = function dot(v) { 27.6601 + return this.x * v.x + this.y * v.y + this.z * v.z; 27.6602 + }; 27.6603 + 27.6604 + /** 27.6605 + * Return squared length of this vector 27.6606 + * @method normSquared 27.6607 + * @return {number} squared length 27.6608 + */ 27.6609 + Vector.prototype.normSquared = function normSquared() { 27.6610 + return this.dot(this); 27.6611 + }; 27.6612 + 27.6613 + /** 27.6614 + * Return length of this vector 27.6615 + * @method norm 27.6616 + * @return {number} length 27.6617 + */ 27.6618 + Vector.prototype.norm = function norm() { 27.6619 + return Math.sqrt(this.normSquared()); 27.6620 + }; 27.6621 + 27.6622 + /** 27.6623 + * Scale Vector to specified length. 27.6624 + * If length is less than internal tolerance, set vector to [length, 0, 0]. 27.6625 + * Note: This sets the internal result register, so other references to that vector will change. 27.6626 + * @method normalize 27.6627 + * 27.6628 + * @param {number} length target length, default 1.0 27.6629 + * @return {Vector} 27.6630 + */ 27.6631 + Vector.prototype.normalize = function normalize(length) { 27.6632 + if (arguments.length === 0) length = 1; 27.6633 + var norm = this.norm(); 27.6634 + 27.6635 + if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm)); 27.6636 + else return _setXYZ.call(_register, length, 0, 0); 27.6637 + }; 27.6638 + 27.6639 + /** 27.6640 + * Make a separate copy of the Vector. 27.6641 + * 27.6642 + * @method clone 27.6643 + * 27.6644 + * @return {Vector} 27.6645 + */ 27.6646 + Vector.prototype.clone = function clone() { 27.6647 + return new Vector(this); 27.6648 + }; 27.6649 + 27.6650 + /** 27.6651 + * True if and only if every value is 0 (or falsy) 27.6652 + * 27.6653 + * @method isZero 27.6654 + * 27.6655 + * @return {boolean} 27.6656 + */ 27.6657 + Vector.prototype.isZero = function isZero() { 27.6658 + return !(this.x || this.y || this.z); 27.6659 + }; 27.6660 + 27.6661 + function _setXYZ(x,y,z) { 27.6662 + this.x = x; 27.6663 + this.y = y; 27.6664 + this.z = z; 27.6665 + return this; 27.6666 + } 27.6667 + 27.6668 + function _setFromArray(v) { 27.6669 + return _setXYZ.call(this,v[0],v[1],v[2] || 0); 27.6670 + } 27.6671 + 27.6672 + function _setFromVector(v) { 27.6673 + return _setXYZ.call(this, v.x, v.y, v.z); 27.6674 + } 27.6675 + 27.6676 + function _setFromNumber(x) { 27.6677 + return _setXYZ.call(this,x,0,0); 27.6678 + } 27.6679 + 27.6680 + /** 27.6681 + * Set this Vector to the values in the provided Array or Vector. 27.6682 + * 27.6683 + * @method set 27.6684 + * @param {object} v array, Vector, or number 27.6685 + * @return {Vector} this 27.6686 + */ 27.6687 + Vector.prototype.set = function set(v) { 27.6688 + if (v instanceof Array) return _setFromArray.call(this, v); 27.6689 + if (v instanceof Vector) return _setFromVector.call(this, v); 27.6690 + if (typeof v === 'number') return _setFromNumber.call(this, v); 27.6691 + }; 27.6692 + 27.6693 + Vector.prototype.setXYZ = function(x,y,z) { 27.6694 + return _setXYZ.apply(this, arguments); 27.6695 + }; 27.6696 + 27.6697 + Vector.prototype.set1D = function(x) { 27.6698 + return _setFromNumber.call(this, x); 27.6699 + }; 27.6700 + 27.6701 + /** 27.6702 + * Put result of last internal register calculation in specified output vector. 27.6703 + * 27.6704 + * @method put 27.6705 + * @param {Vector} v destination vector 27.6706 + * @return {Vector} destination vector 27.6707 + */ 27.6708 + 27.6709 + Vector.prototype.put = function put(v) { 27.6710 + _setFromVector.call(v, _register); 27.6711 + }; 27.6712 + 27.6713 + /** 27.6714 + * Set this vector to [0,0,0] 27.6715 + * 27.6716 + * @method clear 27.6717 + */ 27.6718 + Vector.prototype.clear = function clear() { 27.6719 + return _setXYZ.call(this,0,0,0); 27.6720 + }; 27.6721 + 27.6722 + /** 27.6723 + * Scale this Vector down to specified "cap" length. 27.6724 + * If Vector shorter than cap, or cap is Infinity, do nothing. 27.6725 + * Note: This sets the internal result register, so other references to that vector will change. 27.6726 + * 27.6727 + * @method cap 27.6728 + * @return {Vector} capped vector 27.6729 + */ 27.6730 + Vector.prototype.cap = function cap(cap) { 27.6731 + if (cap === Infinity) return _setFromVector.call(_register, this); 27.6732 + var norm = this.norm(); 27.6733 + if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm)); 27.6734 + else return _setFromVector.call(_register, this); 27.6735 + }; 27.6736 + 27.6737 + /** 27.6738 + * Return projection of this Vector onto another. 27.6739 + * Note: This sets the internal result register, so other references to that vector will change. 27.6740 + * 27.6741 + * @method project 27.6742 + * @param {Vector} n vector to project upon 27.6743 + * @return {Vector} projected vector 27.6744 + */ 27.6745 + Vector.prototype.project = function project(n) { 27.6746 + return n.mult(this.dot(n)); 27.6747 + }; 27.6748 + 27.6749 + /** 27.6750 + * Reflect this Vector across provided vector. 27.6751 + * Note: This sets the internal result register, so other references to that vector will change. 27.6752 + * 27.6753 + * @method reflectAcross 27.6754 + * @param {Vector} n vector to reflect across 27.6755 + * @return {Vector} reflected vector 27.6756 + */ 27.6757 + Vector.prototype.reflectAcross = function reflectAcross(n) { 27.6758 + n.normalize().put(n); 27.6759 + return _setFromVector(_register, this.sub(this.project(n).mult(2))); 27.6760 + }; 27.6761 + 27.6762 + /** 27.6763 + * Convert Vector to three-element array. 27.6764 + * 27.6765 + * @method get 27.6766 + * @return {array<number>} three-element array 27.6767 + */ 27.6768 + Vector.prototype.get = function get() { 27.6769 + return [this.x, this.y, this.z]; 27.6770 + }; 27.6771 + 27.6772 + Vector.prototype.get1D = function() { 27.6773 + return this.x; 27.6774 + }; 27.6775 + 27.6776 + module.exports = Vector; 27.6777 + 27.6778 +}); 27.6779 + 27.6780 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.6781 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6782 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.6783 + * 27.6784 + * Owner: david@famo.us 27.6785 + * @license MPL 2.0 27.6786 + * @copyright Famous Industries, Inc. 2014 27.6787 + */ 27.6788 + 27.6789 +define('famous/math/Matrix',['require','exports','module','./Vector'],function(require, exports, module) { 27.6790 + var Vector = require('./Vector'); 27.6791 + 27.6792 + /** 27.6793 + * A library for using a 3x3 numerical matrix, represented as a two-level array. 27.6794 + * 27.6795 + * @class Matrix 27.6796 + * @constructor 27.6797 + * 27.6798 + * @param {Array.Array} values array of rows 27.6799 + */ 27.6800 + function Matrix(values) { 27.6801 + this.values = values || 27.6802 + [ 27.6803 + [1,0,0], 27.6804 + [0,1,0], 27.6805 + [0,0,1] 27.6806 + ]; 27.6807 + 27.6808 + return this; 27.6809 + } 27.6810 + 27.6811 + var _register = new Matrix(); 27.6812 + var _vectorRegister = new Vector(); 27.6813 + 27.6814 + /** 27.6815 + * Return the values in the matrix as an array of numerical row arrays 27.6816 + * 27.6817 + * @method get 27.6818 + * 27.6819 + * @return {Array.array} matrix values as array of rows. 27.6820 + */ 27.6821 + Matrix.prototype.get = function get() { 27.6822 + return this.values; 27.6823 + }; 27.6824 + 27.6825 + /** 27.6826 + * Set the nested array of rows in the matrix. 27.6827 + * 27.6828 + * @method set 27.6829 + * 27.6830 + * @param {Array.array} values matrix values as array of rows. 27.6831 + */ 27.6832 + Matrix.prototype.set = function set(values) { 27.6833 + this.values = values; 27.6834 + }; 27.6835 + 27.6836 + /** 27.6837 + * Take this matrix as A, input vector V as a column vector, and return matrix product (A)(V). 27.6838 + * Note: This sets the internal vector register. Current handles to the vector register 27.6839 + * will see values changed. 27.6840 + * 27.6841 + * @method vectorMultiply 27.6842 + * 27.6843 + * @param {Vector} v input vector V 27.6844 + * @return {Vector} result of multiplication, as a handle to the internal vector register 27.6845 + */ 27.6846 + Matrix.prototype.vectorMultiply = function vectorMultiply(v) { 27.6847 + var M = this.get(); 27.6848 + var v0 = v.x; 27.6849 + var v1 = v.y; 27.6850 + var v2 = v.z; 27.6851 + 27.6852 + var M0 = M[0]; 27.6853 + var M1 = M[1]; 27.6854 + var M2 = M[2]; 27.6855 + 27.6856 + var M00 = M0[0]; 27.6857 + var M01 = M0[1]; 27.6858 + var M02 = M0[2]; 27.6859 + var M10 = M1[0]; 27.6860 + var M11 = M1[1]; 27.6861 + var M12 = M1[2]; 27.6862 + var M20 = M2[0]; 27.6863 + var M21 = M2[1]; 27.6864 + var M22 = M2[2]; 27.6865 + 27.6866 + return _vectorRegister.setXYZ( 27.6867 + M00*v0 + M01*v1 + M02*v2, 27.6868 + M10*v0 + M11*v1 + M12*v2, 27.6869 + M20*v0 + M21*v1 + M22*v2 27.6870 + ); 27.6871 + }; 27.6872 + 27.6873 + /** 27.6874 + * Multiply the provided matrix M2 with this matrix. Result is (this) * (M2). 27.6875 + * Note: This sets the internal matrix register. Current handles to the register 27.6876 + * will see values changed. 27.6877 + * 27.6878 + * @method multiply 27.6879 + * 27.6880 + * @param {Matrix} M2 input matrix to multiply on the right 27.6881 + * @return {Matrix} result of multiplication, as a handle to the internal register 27.6882 + */ 27.6883 + Matrix.prototype.multiply = function multiply(M2) { 27.6884 + var M1 = this.get(); 27.6885 + var result = [[]]; 27.6886 + for (var i = 0; i < 3; i++) { 27.6887 + result[i] = []; 27.6888 + for (var j = 0; j < 3; j++) { 27.6889 + var sum = 0; 27.6890 + for (var k = 0; k < 3; k++) { 27.6891 + sum += M1[i][k] * M2[k][j]; 27.6892 + } 27.6893 + result[i][j] = sum; 27.6894 + } 27.6895 + } 27.6896 + return _register.set(result); 27.6897 + }; 27.6898 + 27.6899 + /** 27.6900 + * Creates a Matrix which is the transpose of this matrix. 27.6901 + * Note: This sets the internal matrix register. Current handles to the register 27.6902 + * will see values changed. 27.6903 + * 27.6904 + * @method transpose 27.6905 + * 27.6906 + * @return {Matrix} result of transpose, as a handle to the internal register 27.6907 + */ 27.6908 + Matrix.prototype.transpose = function transpose() { 27.6909 + var result = []; 27.6910 + var M = this.get(); 27.6911 + for (var row = 0; row < 3; row++) { 27.6912 + for (var col = 0; col < 3; col++) { 27.6913 + result[row][col] = M[col][row]; 27.6914 + } 27.6915 + } 27.6916 + return _register.set(result); 27.6917 + }; 27.6918 + 27.6919 + /** 27.6920 + * Clones the matrix 27.6921 + * 27.6922 + * @method clone 27.6923 + * @return {Matrix} New copy of the original matrix 27.6924 + */ 27.6925 + Matrix.prototype.clone = function clone() { 27.6926 + var values = this.get(); 27.6927 + var M = []; 27.6928 + for (var row = 0; row < 3; row++) 27.6929 + M[row] = values[row].slice(); 27.6930 + return new Matrix(M); 27.6931 + }; 27.6932 + 27.6933 + module.exports = Matrix; 27.6934 +}); 27.6935 + 27.6936 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.6937 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.6938 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.6939 + * 27.6940 + * Owner: david@famo.us 27.6941 + * @license MPL 2.0 27.6942 + * @copyright Famous Industries, Inc. 2014 27.6943 + */ 27.6944 + 27.6945 +define('famous/math/Quaternion',['require','exports','module','./Matrix'],function(require, exports, module) { 27.6946 + var Matrix = require('./Matrix'); 27.6947 + 27.6948 + /** 27.6949 + * @class Quaternion 27.6950 + * @constructor 27.6951 + * 27.6952 + * @param {Number} w 27.6953 + * @param {Number} x 27.6954 + * @param {Number} y 27.6955 + * @param {Number} z 27.6956 + */ 27.6957 + function Quaternion(w,x,y,z) { 27.6958 + if (arguments.length === 1) this.set(w); 27.6959 + else { 27.6960 + this.w = (w !== undefined) ? w : 1; //Angle 27.6961 + this.x = (x !== undefined) ? x : 0; //Axis.x 27.6962 + this.y = (y !== undefined) ? y : 0; //Axis.y 27.6963 + this.z = (z !== undefined) ? z : 0; //Axis.z 27.6964 + } 27.6965 + return this; 27.6966 + } 27.6967 + 27.6968 + var register = new Quaternion(1,0,0,0); 27.6969 + 27.6970 + /** 27.6971 + * Doc: TODO 27.6972 + * @method add 27.6973 + * @param {Quaternion} q 27.6974 + * @return {Quaternion} 27.6975 + */ 27.6976 + Quaternion.prototype.add = function add(q) { 27.6977 + return register.setWXYZ( 27.6978 + this.w + q.w, 27.6979 + this.x + q.x, 27.6980 + this.y + q.y, 27.6981 + this.z + q.z 27.6982 + ); 27.6983 + }; 27.6984 + 27.6985 + /* 27.6986 + * Docs: TODO 27.6987 + * 27.6988 + * @method sub 27.6989 + * @param {Quaternion} q 27.6990 + * @return {Quaternion} 27.6991 + */ 27.6992 + Quaternion.prototype.sub = function sub(q) { 27.6993 + return register.setWXYZ( 27.6994 + this.w - q.w, 27.6995 + this.x - q.x, 27.6996 + this.y - q.y, 27.6997 + this.z - q.z 27.6998 + ); 27.6999 + }; 27.7000 + 27.7001 + /** 27.7002 + * Doc: TODO 27.7003 + * 27.7004 + * @method scalarDivide 27.7005 + * @param {Number} s 27.7006 + * @return {Quaternion} 27.7007 + */ 27.7008 + Quaternion.prototype.scalarDivide = function scalarDivide(s) { 27.7009 + return this.scalarMultiply(1/s); 27.7010 + }; 27.7011 + 27.7012 + /* 27.7013 + * Docs: TODO 27.7014 + * 27.7015 + * @method scalarMultiply 27.7016 + * @param {Number} s 27.7017 + * @return {Quaternion} 27.7018 + */ 27.7019 + Quaternion.prototype.scalarMultiply = function scalarMultiply(s) { 27.7020 + return register.setWXYZ( 27.7021 + this.w * s, 27.7022 + this.x * s, 27.7023 + this.y * s, 27.7024 + this.z * s 27.7025 + ); 27.7026 + }; 27.7027 + 27.7028 + /* 27.7029 + * Docs: TODO 27.7030 + * 27.7031 + * @method multiply 27.7032 + * @param {Quaternion} q 27.7033 + * @return {Quaternion} 27.7034 + */ 27.7035 + Quaternion.prototype.multiply = function multiply(q) { 27.7036 + //left-handed coordinate system multiplication 27.7037 + var x1 = this.x; 27.7038 + var y1 = this.y; 27.7039 + var z1 = this.z; 27.7040 + var w1 = this.w; 27.7041 + var x2 = q.x; 27.7042 + var y2 = q.y; 27.7043 + var z2 = q.z; 27.7044 + var w2 = q.w || 0; 27.7045 + 27.7046 + return register.setWXYZ( 27.7047 + w1*w2 - x1*x2 - y1*y2 - z1*z2, 27.7048 + x1*w2 + x2*w1 + y2*z1 - y1*z2, 27.7049 + y1*w2 + y2*w1 + x1*z2 - x2*z1, 27.7050 + z1*w2 + z2*w1 + x2*y1 - x1*y2 27.7051 + ); 27.7052 + }; 27.7053 + 27.7054 + var conj = new Quaternion(1,0,0,0); 27.7055 + 27.7056 + /* 27.7057 + * Docs: TODO 27.7058 + * 27.7059 + * @method rotateVector 27.7060 + * @param {Vector} v 27.7061 + * @return {Quaternion} 27.7062 + */ 27.7063 + Quaternion.prototype.rotateVector = function rotateVector(v) { 27.7064 + conj.set(this.conj()); 27.7065 + return register.set(this.multiply(v).multiply(conj)); 27.7066 + }; 27.7067 + 27.7068 + /* 27.7069 + * Docs: TODO 27.7070 + * 27.7071 + * @method inverse 27.7072 + * @return {Quaternion} 27.7073 + */ 27.7074 + Quaternion.prototype.inverse = function inverse() { 27.7075 + return register.set(this.conj().scalarDivide(this.normSquared())); 27.7076 + }; 27.7077 + 27.7078 + /* 27.7079 + * Docs: TODO 27.7080 + * 27.7081 + * @method negate 27.7082 + * @return {Quaternion} 27.7083 + */ 27.7084 + Quaternion.prototype.negate = function negate() { 27.7085 + return this.scalarMultiply(-1); 27.7086 + }; 27.7087 + 27.7088 + /* 27.7089 + * Docs: TODO 27.7090 + * 27.7091 + * @method conj 27.7092 + * @return {Quaternion} 27.7093 + */ 27.7094 + Quaternion.prototype.conj = function conj() { 27.7095 + return register.setWXYZ( 27.7096 + this.w, 27.7097 + -this.x, 27.7098 + -this.y, 27.7099 + -this.z 27.7100 + ); 27.7101 + }; 27.7102 + 27.7103 + /* 27.7104 + * Docs: TODO 27.7105 + * 27.7106 + * @method normalize 27.7107 + * @param {Number} length 27.7108 + * @return {Quaternion} 27.7109 + */ 27.7110 + Quaternion.prototype.normalize = function normalize(length) { 27.7111 + length = (length === undefined) ? 1 : length; 27.7112 + return this.scalarDivide(length * this.norm()); 27.7113 + }; 27.7114 + 27.7115 + /* 27.7116 + * Docs: TODO 27.7117 + * 27.7118 + * @method makeFromAngleAndAxis 27.7119 + * @param {Number} angle 27.7120 + * @param {Vector} v 27.7121 + * @return {Quaternion} 27.7122 + */ 27.7123 + Quaternion.prototype.makeFromAngleAndAxis = function makeFromAngleAndAxis(angle, v) { 27.7124 + //left handed quaternion creation: theta -> -theta 27.7125 + var n = v.normalize(); 27.7126 + var ha = angle*0.5; 27.7127 + var s = -Math.sin(ha); 27.7128 + this.x = s*n.x; 27.7129 + this.y = s*n.y; 27.7130 + this.z = s*n.z; 27.7131 + this.w = Math.cos(ha); 27.7132 + return this; 27.7133 + }; 27.7134 + 27.7135 + /* 27.7136 + * Docs: TODO 27.7137 + * 27.7138 + * @method setWXYZ 27.7139 + * @param {Number} w 27.7140 + * @param {Number} x 27.7141 + * @param {Number} y 27.7142 + * @param {Number} z 27.7143 + * @return {Quaternion} 27.7144 + */ 27.7145 + Quaternion.prototype.setWXYZ = function setWXYZ(w,x,y,z) { 27.7146 + register.clear(); 27.7147 + this.w = w; 27.7148 + this.x = x; 27.7149 + this.y = y; 27.7150 + this.z = z; 27.7151 + return this; 27.7152 + }; 27.7153 + 27.7154 + /* 27.7155 + * Docs: TODO 27.7156 + * 27.7157 + * @method set 27.7158 + * @param {Array|Quaternion} v 27.7159 + * @return {Quaternion} 27.7160 + */ 27.7161 + Quaternion.prototype.set = function set(v) { 27.7162 + if (v instanceof Array) { 27.7163 + this.w = v[0]; 27.7164 + this.x = v[1]; 27.7165 + this.y = v[2]; 27.7166 + this.z = v[3]; 27.7167 + } 27.7168 + else { 27.7169 + this.w = v.w; 27.7170 + this.x = v.x; 27.7171 + this.y = v.y; 27.7172 + this.z = v.z; 27.7173 + } 27.7174 + if (this !== register) register.clear(); 27.7175 + return this; 27.7176 + }; 27.7177 + 27.7178 + /** 27.7179 + * Docs: TODO 27.7180 + * 27.7181 + * @method put 27.7182 + * @param {Quaternion} q 27.7183 + * @return {Quaternion} 27.7184 + */ 27.7185 + Quaternion.prototype.put = function put(q) { 27.7186 + q.set(register); 27.7187 + }; 27.7188 + 27.7189 + /** 27.7190 + * Doc: TODO 27.7191 + * 27.7192 + * @method clone 27.7193 + * @return {Quaternion} 27.7194 + */ 27.7195 + Quaternion.prototype.clone = function clone() { 27.7196 + return new Quaternion(this); 27.7197 + }; 27.7198 + 27.7199 + /** 27.7200 + * Doc: TODO 27.7201 + * 27.7202 + * @method clear 27.7203 + * @return {Quaternion} 27.7204 + */ 27.7205 + Quaternion.prototype.clear = function clear() { 27.7206 + this.w = 1; 27.7207 + this.x = 0; 27.7208 + this.y = 0; 27.7209 + this.z = 0; 27.7210 + return this; 27.7211 + }; 27.7212 + 27.7213 + /** 27.7214 + * Doc: TODO 27.7215 + * 27.7216 + * @method isEqual 27.7217 + * @param {Quaternion} q 27.7218 + * @return {Boolean} 27.7219 + */ 27.7220 + Quaternion.prototype.isEqual = function isEqual(q) { 27.7221 + return q.w === this.w && q.x === this.x && q.y === this.y && q.z === this.z; 27.7222 + }; 27.7223 + 27.7224 + /** 27.7225 + * Doc: TODO 27.7226 + * 27.7227 + * @method dot 27.7228 + * @param {Quaternion} q 27.7229 + * @return {Number} 27.7230 + */ 27.7231 + Quaternion.prototype.dot = function dot(q) { 27.7232 + return this.w * q.w + this.x * q.x + this.y * q.y + this.z * q.z; 27.7233 + }; 27.7234 + 27.7235 + /** 27.7236 + * Doc: TODO 27.7237 + * 27.7238 + * @method normSquared 27.7239 + * @return {Number} 27.7240 + */ 27.7241 + Quaternion.prototype.normSquared = function normSquared() { 27.7242 + return this.dot(this); 27.7243 + }; 27.7244 + 27.7245 + /** 27.7246 + * Doc: TODO 27.7247 + * 27.7248 + * @method norm 27.7249 + * @return {Number} 27.7250 + */ 27.7251 + Quaternion.prototype.norm = function norm() { 27.7252 + return Math.sqrt(this.normSquared()); 27.7253 + }; 27.7254 + 27.7255 + /** 27.7256 + * Doc: TODO 27.7257 + * 27.7258 + * @method isZero 27.7259 + * @return {Boolean} 27.7260 + */ 27.7261 + Quaternion.prototype.isZero = function isZero() { 27.7262 + return !(this.x || this.y || this.z); 27.7263 + }; 27.7264 + 27.7265 + /** 27.7266 + * Doc: TODO 27.7267 + * 27.7268 + * @method getTransform 27.7269 + * @return {Transform} 27.7270 + */ 27.7271 + Quaternion.prototype.getTransform = function getTransform() { 27.7272 + var temp = this.normalize(1); 27.7273 + var x = temp.x; 27.7274 + var y = temp.y; 27.7275 + var z = temp.z; 27.7276 + var w = temp.w; 27.7277 + 27.7278 + //LHC system flattened to column major = RHC flattened to row major 27.7279 + return [ 27.7280 + 1 - 2*y*y - 2*z*z, 27.7281 + 2*x*y - 2*z*w, 27.7282 + 2*x*z + 2*y*w, 27.7283 + 0, 27.7284 + 2*x*y + 2*z*w, 27.7285 + 1 - 2*x*x - 2*z*z, 27.7286 + 2*y*z - 2*x*w, 27.7287 + 0, 27.7288 + 2*x*z - 2*y*w, 27.7289 + 2*y*z + 2*x*w, 27.7290 + 1 - 2*x*x - 2*y*y, 27.7291 + 0, 27.7292 + 0, 27.7293 + 0, 27.7294 + 0, 27.7295 + 1 27.7296 + ]; 27.7297 + }; 27.7298 + 27.7299 + var matrixRegister = new Matrix(); 27.7300 + 27.7301 + /** 27.7302 + * Doc: TODO 27.7303 + * 27.7304 + * @method getMatrix 27.7305 + * @return {Transform} 27.7306 + */ 27.7307 + Quaternion.prototype.getMatrix = function getMatrix() { 27.7308 + var temp = this.normalize(1); 27.7309 + var x = temp.x; 27.7310 + var y = temp.y; 27.7311 + var z = temp.z; 27.7312 + var w = temp.w; 27.7313 + 27.7314 + //LHC system flattened to row major 27.7315 + return matrixRegister.set([ 27.7316 + [ 27.7317 + 1 - 2*y*y - 2*z*z, 27.7318 + 2*x*y + 2*z*w, 27.7319 + 2*x*z - 2*y*w 27.7320 + ], 27.7321 + [ 27.7322 + 2*x*y - 2*z*w, 27.7323 + 1 - 2*x*x - 2*z*z, 27.7324 + 2*y*z + 2*x*w 27.7325 + ], 27.7326 + [ 27.7327 + 2*x*z + 2*y*w, 27.7328 + 2*y*z - 2*x*w, 27.7329 + 1 - 2*x*x - 2*y*y 27.7330 + ] 27.7331 + ]); 27.7332 + }; 27.7333 + 27.7334 + var epsilon = 1e-5; 27.7335 + 27.7336 + /** 27.7337 + * Doc: TODO 27.7338 + * 27.7339 + * @method slerp 27.7340 + * @param {Quaternion} q 27.7341 + * @param {Number} t 27.7342 + * @return {Transform} 27.7343 + */ 27.7344 + Quaternion.prototype.slerp = function slerp(q, t) { 27.7345 + var omega; 27.7346 + var cosomega; 27.7347 + var sinomega; 27.7348 + var scaleFrom; 27.7349 + var scaleTo; 27.7350 + 27.7351 + cosomega = this.dot(q); 27.7352 + if ((1.0 - cosomega) > epsilon) { 27.7353 + omega = Math.acos(cosomega); 27.7354 + sinomega = Math.sin(omega); 27.7355 + scaleFrom = Math.sin((1.0 - t) * omega) / sinomega; 27.7356 + scaleTo = Math.sin(t * omega) / sinomega; 27.7357 + } 27.7358 + else { 27.7359 + scaleFrom = 1.0 - t; 27.7360 + scaleTo = t; 27.7361 + } 27.7362 + return register.set(this.scalarMultiply(scaleFrom/scaleTo).add(q).multiply(scaleTo)); 27.7363 + }; 27.7364 + 27.7365 + module.exports = Quaternion; 27.7366 + 27.7367 +}); 27.7368 + 27.7369 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.7370 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.7371 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7372 + * 27.7373 + * Owner: david@famo.us 27.7374 + * @license MPL 2.0 27.7375 + * @copyright Famous Industries, Inc. 2014 27.7376 + */ 27.7377 + 27.7378 +define('famous/math/Random',['require','exports','module'],function(require, exports, module) { 27.7379 + 27.7380 + var RAND = Math.random; 27.7381 + 27.7382 + function _randomFloat(min,max) { 27.7383 + return min + RAND() * (max - min); 27.7384 + } 27.7385 + 27.7386 + function _randomInteger(min,max) { 27.7387 + return (min + RAND() * (max - min + 1)) >> 0; 27.7388 + } 27.7389 + 27.7390 + /** 27.7391 + * Very simple uniform random number generator library wrapping Math.random(). 27.7392 + * 27.7393 + * @class Random 27.7394 + * @static 27.7395 + */ 27.7396 + var Random = {}; 27.7397 + 27.7398 + /** 27.7399 + * Get single random integer between min and max (inclusive), or array 27.7400 + * of size dim if specified. 27.7401 + * 27.7402 + * @method integer 27.7403 + * 27.7404 + * @param {Number} min lower bound, default 0 27.7405 + * @param {Number} max upper bound, default 1 27.7406 + * @param {Number} dim (optional) dimension of output array, if specified 27.7407 + * @return {number | array<number>} random integer, or optionally, an array of random integers 27.7408 + */ 27.7409 + Random.integer = function integer(min,max,dim) { 27.7410 + min = (min !== undefined) ? min : 0; 27.7411 + max = (max !== undefined) ? max : 1; 27.7412 + if (dim !== undefined) { 27.7413 + var result = []; 27.7414 + for (var i = 0; i < dim; i++) result.push(_randomInteger(min,max)); 27.7415 + return result; 27.7416 + } 27.7417 + else return _randomInteger(min,max); 27.7418 + }; 27.7419 + 27.7420 + /** 27.7421 + * Get single random float between min and max (inclusive), or array 27.7422 + * of size dim if specified 27.7423 + * 27.7424 + * @method range 27.7425 + * 27.7426 + * @param {Number} min lower bound, default 0 27.7427 + * @param {Number} max upper bound, default 1 27.7428 + * @param {Number} [dim] dimension of output array, if specified 27.7429 + * @return {Number} random float, or optionally an array 27.7430 + */ 27.7431 + Random.range = function range(min,max,dim) { 27.7432 + min = (min !== undefined) ? min : 0; 27.7433 + max = (max !== undefined) ? max : 1; 27.7434 + if (dim !== undefined) { 27.7435 + var result = []; 27.7436 + for (var i = 0; i < dim; i++) result.push(_randomFloat(min,max)); 27.7437 + return result; 27.7438 + } 27.7439 + else return _randomFloat(min,max); 27.7440 + }; 27.7441 + 27.7442 + /** 27.7443 + * Return random number among the set {-1 ,1} 27.7444 + * 27.7445 + * @method sign 27.7446 + * 27.7447 + * @param {Number} prob probability of returning 1, default 0.5 27.7448 + * @return {Number} random sign (-1 or 1) 27.7449 + */ 27.7450 + Random.sign = function sign(prob) { 27.7451 + prob = (prob !== undefined) ? prob : 0.5; 27.7452 + return (RAND() < prob) ? 1 : -1; 27.7453 + }; 27.7454 + 27.7455 + /** 27.7456 + * Return random boolean value, true or false. 27.7457 + * 27.7458 + * @method bool 27.7459 + * 27.7460 + * @param {Number} prob probability of returning true, default 0.5 27.7461 + * @return {Boolean} random boolean 27.7462 + */ 27.7463 + Random.bool = function bool(prob) { 27.7464 + prob = (prob !== undefined) ? prob : 0.5; 27.7465 + return RAND() < prob; 27.7466 + }; 27.7467 + 27.7468 + module.exports = Random; 27.7469 +}); 27.7470 + 27.7471 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.7472 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.7473 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7474 + * 27.7475 + * Owner: david@famo.us 27.7476 + * @license MPL 2.0 27.7477 + * @copyright Famous Industries, Inc. 2014 27.7478 + */ 27.7479 + 27.7480 +define('famous/events/EventArbiter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.7481 + var EventHandler = require('famous/core/EventHandler'); 27.7482 + 27.7483 + /** 27.7484 + * A switch which wraps several event destinations and 27.7485 + * redirects received events to at most one of them. 27.7486 + * Setting the 'mode' of the object dictates which one 27.7487 + * of these destinations will receive events. 27.7488 + * 27.7489 + * @class EventArbiter 27.7490 + * @constructor 27.7491 + * 27.7492 + * @param {Number | string} startMode initial setting of switch, 27.7493 + */ 27.7494 + function EventArbiter(startMode) { 27.7495 + this.dispatchers = {}; 27.7496 + this.currMode = undefined; 27.7497 + this.setMode(startMode); 27.7498 + } 27.7499 + 27.7500 + /** 27.7501 + * Set switch to this mode, passing events to the corresponding 27.7502 + * EventHandler. If mode has changed, emits 'change' event, 27.7503 + * emits 'unpipe' event to the old mode's handler, and emits 'pipe' 27.7504 + * event to the new mode's handler. 27.7505 + * 27.7506 + * @method setMode 27.7507 + * 27.7508 + * @param {string | number} mode indicating which event handler to send to. 27.7509 + */ 27.7510 + EventArbiter.prototype.setMode = function setMode(mode) { 27.7511 + if (mode !== this.currMode) { 27.7512 + var startMode = this.currMode; 27.7513 + 27.7514 + if (this.dispatchers[this.currMode]) this.dispatchers[this.currMode].trigger('unpipe'); 27.7515 + this.currMode = mode; 27.7516 + if (this.dispatchers[mode]) this.dispatchers[mode].emit('pipe'); 27.7517 + this.emit('change', {from: startMode, to: mode}); 27.7518 + } 27.7519 + }; 27.7520 + 27.7521 + /** 27.7522 + * Return the existing EventHandler corresponding to this 27.7523 + * mode, creating one if it doesn't exist. 27.7524 + * 27.7525 + * @method forMode 27.7526 + * 27.7527 + * @param {string | number} mode mode to which this eventHandler corresponds 27.7528 + * 27.7529 + * @return {EventHandler} eventHandler corresponding to this mode 27.7530 + */ 27.7531 + EventArbiter.prototype.forMode = function forMode(mode) { 27.7532 + if (!this.dispatchers[mode]) this.dispatchers[mode] = new EventHandler(); 27.7533 + return this.dispatchers[mode]; 27.7534 + }; 27.7535 + 27.7536 + /** 27.7537 + * Trigger an event, sending to currently selected handler, if 27.7538 + * it is listening for provided 'type' key. 27.7539 + * 27.7540 + * @method emit 27.7541 + * 27.7542 + * @param {string} eventType event type key (for example, 'click') 27.7543 + * @param {Object} event event data 27.7544 + * @return {EventHandler} this 27.7545 + */ 27.7546 + EventArbiter.prototype.emit = function emit(eventType, event) { 27.7547 + if (this.currMode === undefined) return false; 27.7548 + if (!event) event = {}; 27.7549 + var dispatcher = this.dispatchers[this.currMode]; 27.7550 + if (dispatcher) return dispatcher.trigger(eventType, event); 27.7551 + }; 27.7552 + 27.7553 + module.exports = EventArbiter; 27.7554 +}); 27.7555 + 27.7556 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.7557 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.7558 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7559 + * 27.7560 + * Owner: david@famo.us 27.7561 + * @license MPL 2.0 27.7562 + * @copyright Famous Industries, Inc. 2014 27.7563 + */ 27.7564 + 27.7565 +define('famous/events/EventFilter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.7566 + var EventHandler = require('famous/core/EventHandler'); 27.7567 + 27.7568 + /** 27.7569 + * EventFilter regulates the broadcasting of events based on 27.7570 + * a specified condition function of standard event type: function(type, data). 27.7571 + * 27.7572 + * @class EventFilter 27.7573 + * @constructor 27.7574 + * 27.7575 + * @param {function} condition function to determine whether or not 27.7576 + * events are emitted. 27.7577 + */ 27.7578 + function EventFilter(condition) { 27.7579 + EventHandler.call(this); 27.7580 + this._condition = condition; 27.7581 + } 27.7582 + EventFilter.prototype = Object.create(EventHandler.prototype); 27.7583 + EventFilter.prototype.constructor = EventFilter; 27.7584 + 27.7585 + /** 27.7586 + * If filter condition is met, trigger an event, sending to all downstream handlers 27.7587 + * listening for provided 'type' key. 27.7588 + * 27.7589 + * @method emit 27.7590 + * 27.7591 + * @param {string} type event type key (for example, 'click') 27.7592 + * @param {Object} data event data 27.7593 + * @return {EventHandler} this 27.7594 + */ 27.7595 + EventFilter.prototype.emit = function emit(type, data) { 27.7596 + if (this._condition(type, data)) 27.7597 + return EventHandler.prototype.emit.apply(this, arguments); 27.7598 + }; 27.7599 + 27.7600 + /** 27.7601 + * An alias of emit. Trigger determines whether to send 27.7602 + * events based on the return value of it's condition function 27.7603 + * when passed the event type and associated data. 27.7604 + * 27.7605 + * @method trigger 27.7606 + * @param {string} type name of the event 27.7607 + * @param {object} data associated data 27.7608 + */ 27.7609 + EventFilter.prototype.trigger = EventFilter.prototype.emit; 27.7610 + 27.7611 + module.exports = EventFilter; 27.7612 +}); 27.7613 + 27.7614 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.7615 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.7616 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7617 + * 27.7618 + * Owner: david@famo.us 27.7619 + * @license MPL 2.0 27.7620 + * @copyright Famous Industries, Inc. 2014 27.7621 + */ 27.7622 + 27.7623 +define('famous/events/EventMapper',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.7624 + var EventHandler = require('famous/core/EventHandler'); 27.7625 + 27.7626 + /** 27.7627 + * EventMapper routes events to various event destinations 27.7628 + * based on custom logic. The function signature is arbitrary. 27.7629 + * 27.7630 + * @class EventMapper 27.7631 + * @constructor 27.7632 + * 27.7633 + * @param {function} mappingFunction function to determine where 27.7634 + * events are routed to. 27.7635 + */ 27.7636 + function EventMapper(mappingFunction) { 27.7637 + EventHandler.call(this); 27.7638 + this._mappingFunction = mappingFunction; 27.7639 + } 27.7640 + EventMapper.prototype = Object.create(EventHandler.prototype); 27.7641 + EventMapper.prototype.constructor = EventMapper; 27.7642 + 27.7643 + EventMapper.prototype.subscribe = null; 27.7644 + EventMapper.prototype.unsubscribe = null; 27.7645 + 27.7646 + /** 27.7647 + * Trigger an event, sending to all mapped downstream handlers 27.7648 + * listening for provided 'type' key. 27.7649 + * 27.7650 + * @method emit 27.7651 + * 27.7652 + * @param {string} type event type key (for example, 'click') 27.7653 + * @param {Object} data event data 27.7654 + * @return {EventHandler} this 27.7655 + */ 27.7656 + EventMapper.prototype.emit = function emit(type, data) { 27.7657 + var target = this._mappingFunction.apply(this, arguments); 27.7658 + if (target && (target.emit instanceof Function)) target.emit(type, data); 27.7659 + }; 27.7660 + 27.7661 + /** 27.7662 + * Alias of emit. 27.7663 + * @method trigger 27.7664 + */ 27.7665 + EventMapper.prototype.trigger = EventMapper.prototype.emit; 27.7666 + 27.7667 + module.exports = EventMapper; 27.7668 +}); 27.7669 + 27.7670 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.7671 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.7672 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.7673 + * 27.7674 + * @license MPL 2.0 27.7675 + * @copyright Famous Industries, Inc. 2014 27.7676 + */ 27.7677 +define('famous/physics/PhysicsEngine',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.7678 + var EventHandler = require('famous/core/EventHandler'); 27.7679 + 27.7680 + /** 27.7681 + * The Physics Engine is responsible for mediating Bodies and their 27.7682 + * interaction with forces and constraints. The Physics Engine handles the 27.7683 + * logic of adding and removing bodies, updating their state of the over 27.7684 + * time. 27.7685 + * 27.7686 + * @class PhysicsEngine 27.7687 + * @constructor 27.7688 + * @param options {Object} options 27.7689 + */ 27.7690 + function PhysicsEngine(options) { 27.7691 + this.options = Object.create(PhysicsEngine.DEFAULT_OPTIONS); 27.7692 + if (options) this.setOptions(options); 27.7693 + 27.7694 + this._particles = []; //list of managed particles 27.7695 + this._bodies = []; //list of managed bodies 27.7696 + this._agents = {}; //hash of managed agents 27.7697 + this._forces = []; //list of IDs of agents that are forces 27.7698 + this._constraints = []; //list of IDs of agents that are constraints 27.7699 + 27.7700 + this._buffer = 0.0; 27.7701 + this._prevTime = now(); 27.7702 + this._isSleeping = false; 27.7703 + this._eventHandler = null; 27.7704 + this._currAgentId = 0; 27.7705 + this._hasBodies = false; 27.7706 + } 27.7707 + 27.7708 + var TIMESTEP = 17; 27.7709 + var MIN_TIME_STEP = 1000 / 120; 27.7710 + var MAX_TIME_STEP = 17; 27.7711 + 27.7712 + /** 27.7713 + * @property PhysicsEngine.DEFAULT_OPTIONS 27.7714 + * @type Object 27.7715 + * @protected 27.7716 + * @static 27.7717 + */ 27.7718 + PhysicsEngine.DEFAULT_OPTIONS = { 27.7719 + 27.7720 + /** 27.7721 + * The number of iterations the engine takes to resolve constraints 27.7722 + * @attribute constraintSteps 27.7723 + * @type Number 27.7724 + */ 27.7725 + constraintSteps : 1, 27.7726 + 27.7727 + /** 27.7728 + * The energy threshold before the Engine stops updating 27.7729 + * @attribute sleepTolerance 27.7730 + * @type Number 27.7731 + */ 27.7732 + sleepTolerance : 1e-7 27.7733 + }; 27.7734 + 27.7735 + var now = (function() { 27.7736 + return Date.now; 27.7737 + })(); 27.7738 + 27.7739 + /** 27.7740 + * Options setter 27.7741 + * @method setOptions 27.7742 + * @param options {Object} 27.7743 + */ 27.7744 + PhysicsEngine.prototype.setOptions = function setOptions(opts) { 27.7745 + for (var key in opts) if (this.options[key]) this.options[key] = opts[key]; 27.7746 + }; 27.7747 + 27.7748 + /** 27.7749 + * Method to add a physics body to the engine. Necessary to update the 27.7750 + * body over time. 27.7751 + * 27.7752 + * @method addBody 27.7753 + * @param body {Body} 27.7754 + * @return body {Body} 27.7755 + */ 27.7756 + PhysicsEngine.prototype.addBody = function addBody(body) { 27.7757 + body._engine = this; 27.7758 + if (body.isBody) { 27.7759 + this._bodies.push(body); 27.7760 + this._hasBodies = true; 27.7761 + } 27.7762 + else this._particles.push(body); 27.7763 + return body; 27.7764 + }; 27.7765 + 27.7766 + /** 27.7767 + * Remove a body from the engine. Detaches body from all forces and 27.7768 + * constraints. 27.7769 + * 27.7770 + * @method removeBody 27.7771 + * @param body {Body} 27.7772 + */ 27.7773 + PhysicsEngine.prototype.removeBody = function removeBody(body) { 27.7774 + var array = (body.isBody) ? this._bodies : this._particles; 27.7775 + var index = array.indexOf(body); 27.7776 + if (index > -1) { 27.7777 + for (var i = 0; i < Object.keys(this._agents).length; i++) this.detachFrom(i, body); 27.7778 + array.splice(index,1); 27.7779 + } 27.7780 + if (this.getBodies().length === 0) this._hasBodies = false; 27.7781 + }; 27.7782 + 27.7783 + function _mapAgentArray(agent) { 27.7784 + if (agent.applyForce) return this._forces; 27.7785 + if (agent.applyConstraint) return this._constraints; 27.7786 + } 27.7787 + 27.7788 + function _attachOne(agent, targets, source) { 27.7789 + if (targets === undefined) targets = this.getParticlesAndBodies(); 27.7790 + if (!(targets instanceof Array)) targets = [targets]; 27.7791 + 27.7792 + this._agents[this._currAgentId] = { 27.7793 + agent : agent, 27.7794 + targets : targets, 27.7795 + source : source 27.7796 + }; 27.7797 + 27.7798 + _mapAgentArray.call(this, agent).push(this._currAgentId); 27.7799 + return this._currAgentId++; 27.7800 + } 27.7801 + 27.7802 + /** 27.7803 + * Attaches a force or constraint to a Body. Returns an AgentId of the 27.7804 + * attached agent which can be used to detach the agent. 27.7805 + * 27.7806 + * @method attach 27.7807 + * @param agent {Agent|Array.Agent} A force, constraint, or array of them. 27.7808 + * @param [targets=All] {Body|Array.Body} The Body or Bodies affected by the agent 27.7809 + * @param [source] {Body} The source of the agent 27.7810 + * @return AgentId {Number} 27.7811 + */ 27.7812 + PhysicsEngine.prototype.attach = function attach(agents, targets, source) { 27.7813 + if (agents instanceof Array) { 27.7814 + var agentIDs = []; 27.7815 + for (var i = 0; i < agents.length; i++) 27.7816 + agentIDs[i] = _attachOne.call(this, agents[i], targets, source); 27.7817 + return agentIDs; 27.7818 + } 27.7819 + else return _attachOne.call(this, agents, targets, source); 27.7820 + }; 27.7821 + 27.7822 + /** 27.7823 + * Append a body to the targets of a previously defined physics agent. 27.7824 + * 27.7825 + * @method attachTo 27.7826 + * @param agentID {AgentId} The agentId of a previously defined agent 27.7827 + * @param target {Body} The Body affected by the agent 27.7828 + */ 27.7829 + PhysicsEngine.prototype.attachTo = function attachTo(agentID, target) { 27.7830 + _getBoundAgent.call(this, agentID).targets.push(target); 27.7831 + }; 27.7832 + 27.7833 + /** 27.7834 + * Undoes PhysicsEngine.attach. Removes an agent and its associated 27.7835 + * effect on its affected Bodies. 27.7836 + * 27.7837 + * @method detach 27.7838 + * @param agentID {AgentId} The agentId of a previously defined agent 27.7839 + */ 27.7840 + PhysicsEngine.prototype.detach = function detach(id) { 27.7841 + // detach from forces/constraints array 27.7842 + var agent = this.getAgent(id); 27.7843 + var agentArray = _mapAgentArray.call(this, agent); 27.7844 + var index = agentArray.indexOf(id); 27.7845 + agentArray.splice(index,1); 27.7846 + 27.7847 + // detach agents array 27.7848 + delete this._agents[id]; 27.7849 + }; 27.7850 + 27.7851 + /** 27.7852 + * Remove a single Body from a previously defined agent. 27.7853 + * 27.7854 + * @method detach 27.7855 + * @param agentID {AgentId} The agentId of a previously defined agent 27.7856 + * @param target {Body} The body to remove from the agent 27.7857 + */ 27.7858 + PhysicsEngine.prototype.detachFrom = function detachFrom(id, target) { 27.7859 + var boundAgent = _getBoundAgent.call(this, id); 27.7860 + if (boundAgent.source === target) this.detach(id); 27.7861 + else { 27.7862 + var targets = boundAgent.targets; 27.7863 + var index = targets.indexOf(target); 27.7864 + if (index > -1) targets.splice(index,1); 27.7865 + } 27.7866 + }; 27.7867 + 27.7868 + /** 27.7869 + * A convenience method to give the Physics Engine a clean slate of 27.7870 + * agents. Preserves all added Body objects. 27.7871 + * 27.7872 + * @method detachAll 27.7873 + */ 27.7874 + PhysicsEngine.prototype.detachAll = function detachAll() { 27.7875 + this._agents = {}; 27.7876 + this._forces = []; 27.7877 + this._constraints = []; 27.7878 + this._currAgentId = 0; 27.7879 + }; 27.7880 + 27.7881 + function _getBoundAgent(id) { 27.7882 + return this._agents[id]; 27.7883 + } 27.7884 + 27.7885 + /** 27.7886 + * Returns the corresponding agent given its agentId. 27.7887 + * 27.7888 + * @method getAgent 27.7889 + * @param id {AgentId} 27.7890 + */ 27.7891 + PhysicsEngine.prototype.getAgent = function getAgent(id) { 27.7892 + return _getBoundAgent.call(this, id).agent; 27.7893 + }; 27.7894 + 27.7895 + /** 27.7896 + * Returns all particles that are currently managed by the Physics Engine. 27.7897 + * 27.7898 + * @method getParticles 27.7899 + * @return particles {Array.Particles} 27.7900 + */ 27.7901 + PhysicsEngine.prototype.getParticles = function getParticles() { 27.7902 + return this._particles; 27.7903 + }; 27.7904 + 27.7905 + /** 27.7906 + * Returns all bodies, except particles, that are currently managed by the Physics Engine. 27.7907 + * 27.7908 + * @method getBodies 27.7909 + * @return bodies {Array.Bodies} 27.7910 + */ 27.7911 + PhysicsEngine.prototype.getBodies = function getBodies() { 27.7912 + return this._bodies; 27.7913 + }; 27.7914 + 27.7915 + /** 27.7916 + * Returns all bodies that are currently managed by the Physics Engine. 27.7917 + * 27.7918 + * @method getBodies 27.7919 + * @return bodies {Array.Bodies} 27.7920 + */ 27.7921 + PhysicsEngine.prototype.getParticlesAndBodies = function getParticlesAndBodies() { 27.7922 + return this.getParticles().concat(this.getBodies()); 27.7923 + }; 27.7924 + 27.7925 + /** 27.7926 + * Iterates over every Particle and applies a function whose first 27.7927 + * argument is the Particle 27.7928 + * 27.7929 + * @method forEachParticle 27.7930 + * @param fn {Function} Function to iterate over 27.7931 + * @param [dt] {Number} Delta time 27.7932 + */ 27.7933 + PhysicsEngine.prototype.forEachParticle = function forEachParticle(fn, dt) { 27.7934 + var particles = this.getParticles(); 27.7935 + for (var index = 0, len = particles.length; index < len; index++) 27.7936 + fn.call(this, particles[index], dt); 27.7937 + }; 27.7938 + 27.7939 + /** 27.7940 + * Iterates over every Body that isn't a Particle and applies 27.7941 + * a function whose first argument is the Body 27.7942 + * 27.7943 + * @method forEachBody 27.7944 + * @param fn {Function} Function to iterate over 27.7945 + * @param [dt] {Number} Delta time 27.7946 + */ 27.7947 + PhysicsEngine.prototype.forEachBody = function forEachBody(fn, dt) { 27.7948 + if (!this._hasBodies) return; 27.7949 + var bodies = this.getBodies(); 27.7950 + for (var index = 0, len = bodies.length; index < len; index++) 27.7951 + fn.call(this, bodies[index], dt); 27.7952 + }; 27.7953 + 27.7954 + /** 27.7955 + * Iterates over every Body and applies a function whose first 27.7956 + * argument is the Body 27.7957 + * 27.7958 + * @method forEach 27.7959 + * @param fn {Function} Function to iterate over 27.7960 + * @param [dt] {Number} Delta time 27.7961 + */ 27.7962 + PhysicsEngine.prototype.forEach = function forEach(fn, dt) { 27.7963 + this.forEachParticle(fn, dt); 27.7964 + this.forEachBody(fn, dt); 27.7965 + }; 27.7966 + 27.7967 + function _updateForce(index) { 27.7968 + var boundAgent = _getBoundAgent.call(this, this._forces[index]); 27.7969 + boundAgent.agent.applyForce(boundAgent.targets, boundAgent.source); 27.7970 + } 27.7971 + 27.7972 + function _updateForces() { 27.7973 + for (var index = this._forces.length - 1; index > -1; index--) 27.7974 + _updateForce.call(this, index); 27.7975 + } 27.7976 + 27.7977 + function _updateConstraint(index, dt) { 27.7978 + var boundAgent = this._agents[this._constraints[index]]; 27.7979 + return boundAgent.agent.applyConstraint(boundAgent.targets, boundAgent.source, dt); 27.7980 + } 27.7981 + 27.7982 + function _updateConstraints(dt) { 27.7983 + var iteration = 0; 27.7984 + while (iteration < this.options.constraintSteps) { 27.7985 + for (var index = this._constraints.length - 1; index > -1; index--) 27.7986 + _updateConstraint.call(this, index, dt); 27.7987 + iteration++; 27.7988 + } 27.7989 + } 27.7990 + 27.7991 + function _updateVelocities(particle, dt) { 27.7992 + particle.integrateVelocity(dt); 27.7993 + } 27.7994 + 27.7995 + function _updateAngularVelocities(body, dt) { 27.7996 + body.integrateAngularMomentum(dt); 27.7997 + body.updateAngularVelocity(); 27.7998 + } 27.7999 + 27.8000 + function _updateOrientations(body, dt) { 27.8001 + body.integrateOrientation(dt); 27.8002 + } 27.8003 + 27.8004 + function _updatePositions(particle, dt) { 27.8005 + particle.integratePosition(dt); 27.8006 + particle.emit('update', particle); 27.8007 + } 27.8008 + 27.8009 + function _integrate(dt) { 27.8010 + _updateForces.call(this, dt); 27.8011 + this.forEach(_updateVelocities, dt); 27.8012 + this.forEachBody(_updateAngularVelocities, dt); 27.8013 + _updateConstraints.call(this, dt); 27.8014 + this.forEachBody(_updateOrientations, dt); 27.8015 + this.forEach(_updatePositions, dt); 27.8016 + } 27.8017 + 27.8018 + function _getEnergyParticles() { 27.8019 + var energy = 0.0; 27.8020 + var particleEnergy = 0.0; 27.8021 + this.forEach(function(particle) { 27.8022 + particleEnergy = particle.getEnergy(); 27.8023 + energy += particleEnergy; 27.8024 + if (particleEnergy < particle.sleepTolerance) particle.sleep(); 27.8025 + }); 27.8026 + return energy; 27.8027 + } 27.8028 + 27.8029 + function _getEnergyForces() { 27.8030 + var energy = 0; 27.8031 + for (var index = this._forces.length - 1; index > -1; index--) 27.8032 + energy += this._forces[index].getEnergy() || 0.0; 27.8033 + return energy; 27.8034 + } 27.8035 + 27.8036 + function _getEnergyConstraints() { 27.8037 + var energy = 0; 27.8038 + for (var index = this._constraints.length - 1; index > -1; index--) 27.8039 + energy += this._constraints[index].getEnergy() || 0.0; 27.8040 + return energy; 27.8041 + } 27.8042 + 27.8043 + /** 27.8044 + * Calculates the kinetic energy of all Body objects and potential energy 27.8045 + * of all attached agents. 27.8046 + * 27.8047 + * TODO: implement. 27.8048 + * @method getEnergy 27.8049 + * @return energy {Number} 27.8050 + */ 27.8051 + PhysicsEngine.prototype.getEnergy = function getEnergy() { 27.8052 + return _getEnergyParticles.call(this) + _getEnergyForces.call(this) + _getEnergyConstraints.call(this); 27.8053 + }; 27.8054 + 27.8055 + /** 27.8056 + * Updates all Body objects managed by the physics engine over the 27.8057 + * time duration since the last time step was called. 27.8058 + * 27.8059 + * @method step 27.8060 + */ 27.8061 + PhysicsEngine.prototype.step = function step() { 27.8062 +// if (this.getEnergy() < this.options.sleepTolerance) { 27.8063 +// this.sleep(); 27.8064 +// return; 27.8065 +// }; 27.8066 + 27.8067 + //set current frame's time 27.8068 + var currTime = now(); 27.8069 + 27.8070 + //milliseconds elapsed since last frame 27.8071 + var dtFrame = currTime - this._prevTime; 27.8072 + 27.8073 + this._prevTime = currTime; 27.8074 + 27.8075 + if (dtFrame < MIN_TIME_STEP) return; 27.8076 + if (dtFrame > MAX_TIME_STEP) dtFrame = MAX_TIME_STEP; 27.8077 + 27.8078 + //robust integration 27.8079 +// this._buffer += dtFrame; 27.8080 +// while (this._buffer > this._timestep){ 27.8081 +// _integrate.call(this, this._timestep); 27.8082 +// this._buffer -= this._timestep; 27.8083 +// }; 27.8084 +// _integrate.call(this, this._buffer); 27.8085 +// this._buffer = 0.0; 27.8086 + _integrate.call(this, TIMESTEP); 27.8087 + 27.8088 +// this.emit('update', this); 27.8089 + }; 27.8090 + 27.8091 + /** 27.8092 + * Tells whether the Physics Engine is sleeping or awake. 27.8093 + * @method isSleeping 27.8094 + * @return {Boolean} 27.8095 + */ 27.8096 + PhysicsEngine.prototype.isSleeping = function isSleeping() { 27.8097 + return this._isSleeping; 27.8098 + }; 27.8099 + 27.8100 + /** 27.8101 + * Stops the Physics Engine from updating. Emits an 'end' event. 27.8102 + * @method sleep 27.8103 + */ 27.8104 + PhysicsEngine.prototype.sleep = function sleep() { 27.8105 + this.emit('end', this); 27.8106 + this._isSleeping = true; 27.8107 + }; 27.8108 + 27.8109 + /** 27.8110 + * Starts the Physics Engine from updating. Emits an 'start' event. 27.8111 + * @method wake 27.8112 + */ 27.8113 + PhysicsEngine.prototype.wake = function wake() { 27.8114 + this._prevTime = now(); 27.8115 + this.emit('start', this); 27.8116 + this._isSleeping = false; 27.8117 + }; 27.8118 + 27.8119 + PhysicsEngine.prototype.emit = function emit(type, data) { 27.8120 + if (this._eventHandler === null) return; 27.8121 + this._eventHandler.emit(type, data); 27.8122 + }; 27.8123 + 27.8124 + PhysicsEngine.prototype.on = function on(event, fn) { 27.8125 + if (this._eventHandler === null) this._eventHandler = new EventHandler(); 27.8126 + this._eventHandler.on(event, fn); 27.8127 + }; 27.8128 + 27.8129 + module.exports = PhysicsEngine; 27.8130 +}); 27.8131 + 27.8132 +define('famous/inputs/Accumulator',['require','exports','module','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) { 27.8133 + var EventHandler = require('famous/core/EventHandler'); 27.8134 + var Transitionable = require('famous/transitions/Transitionable'); 27.8135 + 27.8136 + /** 27.8137 + * Accumulates differentials of event sources that emit a `delta` 27.8138 + * attribute taking a Number or Array of Number types. The accumulated 27.8139 + * value is stored in a getter/setter. 27.8140 + * 27.8141 + * @class Accumulator 27.8142 + * @constructor 27.8143 + * @param value {Number|Array|Transitionable} Initializing value 27.8144 + * @param [eventName='update'] {String} Name of update event 27.8145 + */ 27.8146 + function Accumulator(value, eventName) { 27.8147 + if (eventName === undefined) eventName = 'update'; 27.8148 + 27.8149 + this._state = (value && value.get && value.set) 27.8150 + ? value 27.8151 + : new Transitionable(value || 0); 27.8152 + 27.8153 + this._eventInput = new EventHandler(); 27.8154 + EventHandler.setInputHandler(this, this._eventInput); 27.8155 + 27.8156 + this._eventInput.on(eventName, _handleUpdate.bind(this)); 27.8157 + } 27.8158 + 27.8159 + function _handleUpdate(data) { 27.8160 + var delta = data.delta; 27.8161 + var state = this.get(); 27.8162 + 27.8163 + if (delta.constructor === state.constructor){ 27.8164 + var newState = (delta instanceof Array) 27.8165 + ? [state[0] + delta[0], state[1] + delta[1]] 27.8166 + : state + delta; 27.8167 + this.set(newState); 27.8168 + } 27.8169 + } 27.8170 + 27.8171 + /** 27.8172 + * Basic getter 27.8173 + * 27.8174 + * @method get 27.8175 + * @return {Number|Array} current value 27.8176 + */ 27.8177 + Accumulator.prototype.get = function get() { 27.8178 + return this._state.get(); 27.8179 + }; 27.8180 + 27.8181 + /** 27.8182 + * Basic setter 27.8183 + * 27.8184 + * @method set 27.8185 + * @param value {Number|Array} new value 27.8186 + */ 27.8187 + Accumulator.prototype.set = function set(value) { 27.8188 + this._state.set(value); 27.8189 + }; 27.8190 + 27.8191 + module.exports = Accumulator; 27.8192 +}); 27.8193 + 27.8194 +define('famous/inputs/DesktopEmulationMode',['require','exports','module'],function(require, exports, module) { 27.8195 + var hasTouch = 'ontouchstart' in window; 27.8196 + 27.8197 + function kill(type) { 27.8198 + window.addEventListener(type, function(event) { 27.8199 + event.stopPropagation(); 27.8200 + return false; 27.8201 + }, true); 27.8202 + } 27.8203 + 27.8204 + if (hasTouch) { 27.8205 + kill('mousedown'); 27.8206 + kill('mousemove'); 27.8207 + kill('mouseup'); 27.8208 + kill('mouseleave'); 27.8209 + } 27.8210 +}); 27.8211 + 27.8212 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8213 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8214 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8215 + * 27.8216 + * Owner: mark@famo.us 27.8217 + * @license MPL 2.0 27.8218 + * @copyright Famous Industries, Inc. 2014 27.8219 + */ 27.8220 + 27.8221 +define('famous/inputs/FastClick',['require','exports','module'],function(require, exports, module) { 27.8222 + /** 27.8223 + * FastClick is an override shim which maps event pairs of 27.8224 + * 'touchstart' and 'touchend' which differ by less than a certain 27.8225 + * threshold to the 'click' event. 27.8226 + * This is used to speed up clicks on some browsers. 27.8227 + */ 27.8228 + if (!window.CustomEvent) return; 27.8229 + var clickThreshold = 300; 27.8230 + var clickWindow = 500; 27.8231 + var potentialClicks = {}; 27.8232 + var recentlyDispatched = {}; 27.8233 + var _now = Date.now; 27.8234 + 27.8235 + window.addEventListener('touchstart', function(event) { 27.8236 + var timestamp = _now(); 27.8237 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8238 + var touch = event.changedTouches[i]; 27.8239 + potentialClicks[touch.identifier] = timestamp; 27.8240 + } 27.8241 + }); 27.8242 + 27.8243 + window.addEventListener('touchmove', function(event) { 27.8244 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8245 + var touch = event.changedTouches[i]; 27.8246 + delete potentialClicks[touch.identifier]; 27.8247 + } 27.8248 + }); 27.8249 + 27.8250 + window.addEventListener('touchend', function(event) { 27.8251 + var currTime = _now(); 27.8252 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8253 + var touch = event.changedTouches[i]; 27.8254 + var startTime = potentialClicks[touch.identifier]; 27.8255 + if (startTime && currTime - startTime < clickThreshold) { 27.8256 + var clickEvt = new window.CustomEvent('click', { 27.8257 + 'bubbles': true, 27.8258 + 'details': touch 27.8259 + }); 27.8260 + recentlyDispatched[currTime] = event; 27.8261 + event.target.dispatchEvent(clickEvt); 27.8262 + } 27.8263 + delete potentialClicks[touch.identifier]; 27.8264 + } 27.8265 + }); 27.8266 + 27.8267 + window.addEventListener('click', function(event) { 27.8268 + var currTime = _now(); 27.8269 + for (var i in recentlyDispatched) { 27.8270 + var previousEvent = recentlyDispatched[i]; 27.8271 + if (currTime - i < clickWindow) { 27.8272 + if (event instanceof window.MouseEvent && event.target === previousEvent.target) event.stopPropagation(); 27.8273 + } 27.8274 + else delete recentlyDispatched[i]; 27.8275 + } 27.8276 + }, true); 27.8277 +}); 27.8278 + 27.8279 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8280 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8281 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8282 + * 27.8283 + * Owner: mark@famo.us 27.8284 + * @license MPL 2.0 27.8285 + * @copyright Famous Industries, Inc. 2014 27.8286 + */ 27.8287 + 27.8288 +define('famous/inputs/TwoFingerSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.8289 + var EventHandler = require('famous/core/EventHandler'); 27.8290 + 27.8291 + /** 27.8292 + * Helper to PinchSync, RotateSync, and ScaleSync. Generalized handling of 27.8293 + * two-finger touch events. 27.8294 + * This class is meant to be overridden and not used directly. 27.8295 + * 27.8296 + * @class TwoFingerSync 27.8297 + * @constructor 27.8298 + */ 27.8299 + function TwoFingerSync() { 27.8300 + this._eventInput = new EventHandler(); 27.8301 + this._eventOutput = new EventHandler(); 27.8302 + 27.8303 + EventHandler.setInputHandler(this, this._eventInput); 27.8304 + EventHandler.setOutputHandler(this, this._eventOutput); 27.8305 + 27.8306 + this.touchAEnabled = false; 27.8307 + this.touchAId = 0; 27.8308 + this.posA = null; 27.8309 + this.timestampA = 0; 27.8310 + this.touchBEnabled = false; 27.8311 + this.touchBId = 0; 27.8312 + this.posB = null; 27.8313 + this.timestampB = 0; 27.8314 + 27.8315 + this._eventInput.on('touchstart', this.handleStart.bind(this)); 27.8316 + this._eventInput.on('touchmove', this.handleMove.bind(this)); 27.8317 + this._eventInput.on('touchend', this.handleEnd.bind(this)); 27.8318 + this._eventInput.on('touchcancel', this.handleEnd.bind(this)); 27.8319 + } 27.8320 + 27.8321 + TwoFingerSync.calculateAngle = function(posA, posB) { 27.8322 + var diffX = posB[0] - posA[0]; 27.8323 + var diffY = posB[1] - posA[1]; 27.8324 + return Math.atan2(diffY, diffX); 27.8325 + }; 27.8326 + 27.8327 + TwoFingerSync.calculateDistance = function(posA, posB) { 27.8328 + var diffX = posB[0] - posA[0]; 27.8329 + var diffY = posB[1] - posA[1]; 27.8330 + return Math.sqrt(diffX * diffX + diffY * diffY); 27.8331 + }; 27.8332 + 27.8333 + TwoFingerSync.calculateCenter = function(posA, posB) { 27.8334 + return [(posA[0] + posB[0]) / 2.0, (posA[1] + posB[1]) / 2.0]; 27.8335 + }; 27.8336 + 27.8337 + var _now = Date.now; 27.8338 + 27.8339 + // private 27.8340 + TwoFingerSync.prototype.handleStart = function handleStart(event) { 27.8341 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8342 + var touch = event.changedTouches[i]; 27.8343 + if (!this.touchAEnabled) { 27.8344 + this.touchAId = touch.identifier; 27.8345 + this.touchAEnabled = true; 27.8346 + this.posA = [touch.pageX, touch.pageY]; 27.8347 + this.timestampA = _now(); 27.8348 + } 27.8349 + else if (!this.touchBEnabled) { 27.8350 + this.touchBId = touch.identifier; 27.8351 + this.touchBEnabled = true; 27.8352 + this.posB = [touch.pageX, touch.pageY]; 27.8353 + this.timestampB = _now(); 27.8354 + this._startUpdate(event); 27.8355 + } 27.8356 + } 27.8357 + }; 27.8358 + 27.8359 + // private 27.8360 + TwoFingerSync.prototype.handleMove = function handleMove(event) { 27.8361 + if (!(this.touchAEnabled && this.touchBEnabled)) return; 27.8362 + var prevTimeA = this.timestampA; 27.8363 + var prevTimeB = this.timestampB; 27.8364 + var diffTime; 27.8365 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8366 + var touch = event.changedTouches[i]; 27.8367 + if (touch.identifier === this.touchAId) { 27.8368 + this.posA = [touch.pageX, touch.pageY]; 27.8369 + this.timestampA = _now(); 27.8370 + diffTime = this.timestampA - prevTimeA; 27.8371 + } 27.8372 + else if (touch.identifier === this.touchBId) { 27.8373 + this.posB = [touch.pageX, touch.pageY]; 27.8374 + this.timestampB = _now(); 27.8375 + diffTime = this.timestampB - prevTimeB; 27.8376 + } 27.8377 + } 27.8378 + if (diffTime) this._moveUpdate(diffTime); 27.8379 + }; 27.8380 + 27.8381 + // private 27.8382 + TwoFingerSync.prototype.handleEnd = function handleEnd(event) { 27.8383 + for (var i = 0; i < event.changedTouches.length; i++) { 27.8384 + var touch = event.changedTouches[i]; 27.8385 + if (touch.identifier === this.touchAId || touch.identifier === this.touchBId) { 27.8386 + if (this.touchAEnabled && this.touchBEnabled) { 27.8387 + this._eventOutput.emit('end', { 27.8388 + touches : [this.touchAId, this.touchBId], 27.8389 + angle : this._angle 27.8390 + }); 27.8391 + } 27.8392 + this.touchAEnabled = false; 27.8393 + this.touchAId = 0; 27.8394 + this.touchBEnabled = false; 27.8395 + this.touchBId = 0; 27.8396 + } 27.8397 + } 27.8398 + }; 27.8399 + 27.8400 + module.exports = TwoFingerSync; 27.8401 +}); 27.8402 + 27.8403 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8404 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8405 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8406 + * 27.8407 + * Owner: mark@famo.us 27.8408 + * @license MPL 2.0 27.8409 + * @copyright Famous Industries, Inc. 2014 27.8410 + */ 27.8411 + 27.8412 +define('famous/inputs/PinchSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 27.8413 + var TwoFingerSync = require('./TwoFingerSync'); 27.8414 + 27.8415 + /** 27.8416 + * Handles piped in two-finger touch events to change position via pinching / expanding. 27.8417 + * Emits 'start', 'update' and 'end' events with 27.8418 + * position, velocity, touch ids, and distance between fingers. 27.8419 + * 27.8420 + * @class PinchSync 27.8421 + * @extends TwoFingerSync 27.8422 + * @constructor 27.8423 + * @param {Object} options default options overrides 27.8424 + * @param {Number} [options.scale] scale velocity by this factor 27.8425 + */ 27.8426 + function PinchSync(options) { 27.8427 + TwoFingerSync.call(this); 27.8428 + 27.8429 + this.options = Object.create(PinchSync.DEFAULT_OPTIONS); 27.8430 + if (options) this.setOptions(options); 27.8431 + 27.8432 + this._displacement = 0; 27.8433 + this._previousDistance = 0; 27.8434 + } 27.8435 + 27.8436 + PinchSync.prototype = Object.create(TwoFingerSync.prototype); 27.8437 + PinchSync.prototype.constructor = PinchSync; 27.8438 + 27.8439 + PinchSync.DEFAULT_OPTIONS = { 27.8440 + scale : 1 27.8441 + }; 27.8442 + 27.8443 + PinchSync.prototype._startUpdate = function _startUpdate(event) { 27.8444 + this._previousDistance = TwoFingerSync.calculateDistance(this.posA, this.posB); 27.8445 + this._displacement = 0; 27.8446 + 27.8447 + this._eventOutput.emit('start', { 27.8448 + count: event.touches.length, 27.8449 + touches: [this.touchAId, this.touchBId], 27.8450 + distance: this._dist, 27.8451 + center: TwoFingerSync.calculateCenter(this.posA, this.posB) 27.8452 + }); 27.8453 + }; 27.8454 + 27.8455 + PinchSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 27.8456 + var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 27.8457 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 27.8458 + 27.8459 + var scale = this.options.scale; 27.8460 + var delta = scale * (currDist - this._previousDistance); 27.8461 + var velocity = delta / diffTime; 27.8462 + 27.8463 + this._previousDistance = currDist; 27.8464 + this._displacement += delta; 27.8465 + 27.8466 + this._eventOutput.emit('update', { 27.8467 + delta : delta, 27.8468 + velocity: velocity, 27.8469 + distance: currDist, 27.8470 + displacement: this._displacement, 27.8471 + center: center, 27.8472 + touches: [this.touchAId, this.touchBId] 27.8473 + }); 27.8474 + }; 27.8475 + 27.8476 + /** 27.8477 + * Return entire options dictionary, including defaults. 27.8478 + * 27.8479 + * @method getOptions 27.8480 + * @return {Object} configuration options 27.8481 + */ 27.8482 + PinchSync.prototype.getOptions = function getOptions() { 27.8483 + return this.options; 27.8484 + }; 27.8485 + 27.8486 + /** 27.8487 + * Set internal options, overriding any default options 27.8488 + * 27.8489 + * @method setOptions 27.8490 + * 27.8491 + * @param {Object} [options] overrides of default options 27.8492 + * @param {Number} [options.scale] scale velocity by this factor 27.8493 + */ 27.8494 + PinchSync.prototype.setOptions = function setOptions(options) { 27.8495 + if (options.scale !== undefined) this.options.scale = options.scale; 27.8496 + }; 27.8497 + 27.8498 + module.exports = PinchSync; 27.8499 +}); 27.8500 + 27.8501 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8502 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8503 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8504 + * 27.8505 + * Owner: mark@famo.us 27.8506 + * @license MPL 2.0 27.8507 + * @copyright Famous Industries, Inc. 2014 27.8508 + */ 27.8509 + 27.8510 +define('famous/inputs/RotateSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 27.8511 + var TwoFingerSync = require('./TwoFingerSync'); 27.8512 + 27.8513 + /** 27.8514 + * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding. 27.8515 + * Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, and angle. 27.8516 + * Useful for determining a rotation factor from initial two-finger touch. 27.8517 + * 27.8518 + * @class RotateSync 27.8519 + * @extends TwoFingerSync 27.8520 + * @constructor 27.8521 + * @param {Object} options default options overrides 27.8522 + * @param {Number} [options.scale] scale velocity by this factor 27.8523 + */ 27.8524 + function RotateSync(options) { 27.8525 + TwoFingerSync.call(this); 27.8526 + 27.8527 + this.options = Object.create(RotateSync.DEFAULT_OPTIONS); 27.8528 + if (options) this.setOptions(options); 27.8529 + 27.8530 + this._angle = 0; 27.8531 + this._previousAngle = 0; 27.8532 + } 27.8533 + 27.8534 + RotateSync.prototype = Object.create(TwoFingerSync.prototype); 27.8535 + RotateSync.prototype.constructor = RotateSync; 27.8536 + 27.8537 + RotateSync.DEFAULT_OPTIONS = { 27.8538 + scale : 1 27.8539 + }; 27.8540 + 27.8541 + RotateSync.prototype._startUpdate = function _startUpdate(event) { 27.8542 + this._angle = 0; 27.8543 + this._previousAngle = TwoFingerSync.calculateAngle(this.posA, this.posB); 27.8544 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 27.8545 + this._eventOutput.emit('start', { 27.8546 + count: event.touches.length, 27.8547 + angle: this._angle, 27.8548 + center: center, 27.8549 + touches: [this.touchAId, this.touchBId] 27.8550 + }); 27.8551 + }; 27.8552 + 27.8553 + RotateSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 27.8554 + var scale = this.options.scale; 27.8555 + 27.8556 + var currAngle = TwoFingerSync.calculateAngle(this.posA, this.posB); 27.8557 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 27.8558 + 27.8559 + var diffTheta = scale * (currAngle - this._previousAngle); 27.8560 + var velTheta = diffTheta / diffTime; 27.8561 + 27.8562 + this._angle += diffTheta; 27.8563 + 27.8564 + this._eventOutput.emit('update', { 27.8565 + delta : diffTheta, 27.8566 + velocity: velTheta, 27.8567 + angle: this._angle, 27.8568 + center: center, 27.8569 + touches: [this.touchAId, this.touchBId] 27.8570 + }); 27.8571 + 27.8572 + this._previousAngle = currAngle; 27.8573 + }; 27.8574 + 27.8575 + /** 27.8576 + * Return entire options dictionary, including defaults. 27.8577 + * 27.8578 + * @method getOptions 27.8579 + * @return {Object} configuration options 27.8580 + */ 27.8581 + RotateSync.prototype.getOptions = function getOptions() { 27.8582 + return this.options; 27.8583 + }; 27.8584 + 27.8585 + /** 27.8586 + * Set internal options, overriding any default options 27.8587 + * 27.8588 + * @method setOptions 27.8589 + * 27.8590 + * @param {Object} [options] overrides of default options 27.8591 + * @param {Number} [options.scale] scale velocity by this factor 27.8592 + */ 27.8593 + RotateSync.prototype.setOptions = function setOptions(options) { 27.8594 + if (options.scale !== undefined) this.options.scale = options.scale; 27.8595 + }; 27.8596 + 27.8597 + module.exports = RotateSync; 27.8598 +}); 27.8599 + 27.8600 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8601 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8602 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8603 + * 27.8604 + * Owner: mark@famo.us 27.8605 + * @license MPL 2.0 27.8606 + * @copyright Famous Industries, Inc. 2014 27.8607 + */ 27.8608 + 27.8609 +define('famous/inputs/ScaleSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 27.8610 + var TwoFingerSync = require('./TwoFingerSync'); 27.8611 + 27.8612 + /** 27.8613 + * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding. 27.8614 + * Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, distance, and scale factor. 27.8615 + * Useful for determining a scaling factor from initial two-finger touch. 27.8616 + * 27.8617 + * @class ScaleSync 27.8618 + * @extends TwoFingerSync 27.8619 + * @constructor 27.8620 + * @param {Object} options default options overrides 27.8621 + * @param {Number} [options.scale] scale velocity by this factor 27.8622 + */ 27.8623 + function ScaleSync(options) { 27.8624 + TwoFingerSync.call(this); 27.8625 + 27.8626 + this.options = Object.create(ScaleSync.DEFAULT_OPTIONS); 27.8627 + if (options) this.setOptions(options); 27.8628 + 27.8629 + this._scaleFactor = 1; 27.8630 + this._startDist = 0; 27.8631 + this._eventInput.on('pipe', _reset.bind(this)); 27.8632 + } 27.8633 + 27.8634 + ScaleSync.prototype = Object.create(TwoFingerSync.prototype); 27.8635 + ScaleSync.prototype.constructor = ScaleSync; 27.8636 + 27.8637 + ScaleSync.DEFAULT_OPTIONS = { 27.8638 + scale : 1 27.8639 + }; 27.8640 + 27.8641 + function _reset() { 27.8642 + this.touchAId = undefined; 27.8643 + this.touchBId = undefined; 27.8644 + } 27.8645 + 27.8646 + // handles initial touch of two fingers 27.8647 + ScaleSync.prototype._startUpdate = function _startUpdate(event) { 27.8648 + this._scaleFactor = 1; 27.8649 + this._startDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 27.8650 + this._eventOutput.emit('start', { 27.8651 + count: event.touches.length, 27.8652 + touches: [this.touchAId, this.touchBId], 27.8653 + distance: this._startDist, 27.8654 + center: TwoFingerSync.calculateCenter(this.posA, this.posB) 27.8655 + }); 27.8656 + }; 27.8657 + 27.8658 + // handles movement of two fingers 27.8659 + ScaleSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 27.8660 + var scale = this.options.scale; 27.8661 + 27.8662 + var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 27.8663 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 27.8664 + 27.8665 + var delta = (currDist - this._startDist) / this._startDist; 27.8666 + var newScaleFactor = Math.max(1 + scale * delta, 0); 27.8667 + var veloScale = (newScaleFactor - this._scaleFactor) / diffTime; 27.8668 + 27.8669 + this._eventOutput.emit('update', { 27.8670 + delta : delta, 27.8671 + scale: newScaleFactor, 27.8672 + velocity: veloScale, 27.8673 + distance: currDist, 27.8674 + center : center, 27.8675 + touches: [this.touchAId, this.touchBId] 27.8676 + }); 27.8677 + 27.8678 + this._scaleFactor = newScaleFactor; 27.8679 + }; 27.8680 + 27.8681 + /** 27.8682 + * Return entire options dictionary, including defaults. 27.8683 + * 27.8684 + * @method getOptions 27.8685 + * @return {Object} configuration options 27.8686 + */ 27.8687 + ScaleSync.prototype.getOptions = function getOptions() { 27.8688 + return this.options; 27.8689 + }; 27.8690 + 27.8691 + /** 27.8692 + * Set internal options, overriding any default options 27.8693 + * 27.8694 + * @method setOptions 27.8695 + * 27.8696 + * @param {Object} [options] overrides of default options 27.8697 + * @param {Number} [options.scale] scale velocity by this factor 27.8698 + */ 27.8699 + ScaleSync.prototype.setOptions = function setOptions(options) { 27.8700 + if (options.scale !== undefined) this.options.scale = options.scale; 27.8701 + }; 27.8702 + 27.8703 + module.exports = ScaleSync; 27.8704 +}); 27.8705 + 27.8706 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8707 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8708 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8709 + * 27.8710 + * Owner: mark@famo.us 27.8711 + * @license MPL 2.0 27.8712 + * @copyright Famous Industries, Inc. 2014 27.8713 + */ 27.8714 + 27.8715 +define('famous/inputs/ScrollSync',['require','exports','module','famous/core/EventHandler','famous/core/Engine'],function(require, exports, module) { 27.8716 + var EventHandler = require('famous/core/EventHandler'); 27.8717 + var Engine = require('famous/core/Engine'); 27.8718 + 27.8719 + /** 27.8720 + * Handles piped in mousewheel events. 27.8721 + * Emits 'start', 'update', and 'end' events with payloads including: 27.8722 + * delta: change since last position, 27.8723 + * position: accumulated deltas, 27.8724 + * velocity: speed of change in pixels per ms, 27.8725 + * slip: true (unused). 27.8726 + * 27.8727 + * Can be used as delegate of GenericSync. 27.8728 + * 27.8729 + * @class ScrollSync 27.8730 + * @constructor 27.8731 + * @param {Object} [options] overrides of default options 27.8732 + * @param {Number} [options.direction] Pay attention to x changes (ScrollSync.DIRECTION_X), 27.8733 + * y changes (ScrollSync.DIRECTION_Y) or both (undefined) 27.8734 + * @param {Number} [options.minimumEndSpeed] End speed calculation floors at this number, in pixels per ms 27.8735 + * @param {boolean} [options.rails] whether to snap position calculations to nearest axis 27.8736 + * @param {Number | Array.Number} [options.scale] scale outputs in by scalar or pair of scalars 27.8737 + * @param {Number} [options.stallTime] reset time for velocity calculation in ms 27.8738 + */ 27.8739 + function ScrollSync(options) { 27.8740 + this.options = Object.create(ScrollSync.DEFAULT_OPTIONS); 27.8741 + if (options) this.setOptions(options); 27.8742 + 27.8743 + this._payload = { 27.8744 + delta : null, 27.8745 + position : null, 27.8746 + velocity : null, 27.8747 + slip : true 27.8748 + }; 27.8749 + 27.8750 + this._eventInput = new EventHandler(); 27.8751 + this._eventOutput = new EventHandler(); 27.8752 + 27.8753 + EventHandler.setInputHandler(this, this._eventInput); 27.8754 + EventHandler.setOutputHandler(this, this._eventOutput); 27.8755 + 27.8756 + this._position = (this.options.direction === undefined) ? [0,0] : 0; 27.8757 + this._prevTime = undefined; 27.8758 + this._prevVel = undefined; 27.8759 + this._eventInput.on('mousewheel', _handleMove.bind(this)); 27.8760 + this._eventInput.on('wheel', _handleMove.bind(this)); 27.8761 + this._inProgress = false; 27.8762 + this._loopBound = false; 27.8763 + } 27.8764 + 27.8765 + ScrollSync.DEFAULT_OPTIONS = { 27.8766 + direction: undefined, 27.8767 + minimumEndSpeed: Infinity, 27.8768 + rails: false, 27.8769 + scale: 1, 27.8770 + stallTime: 50, 27.8771 + lineHeight: 40 27.8772 + }; 27.8773 + 27.8774 + ScrollSync.DIRECTION_X = 0; 27.8775 + ScrollSync.DIRECTION_Y = 1; 27.8776 + 27.8777 + var MINIMUM_TICK_TIME = 8; 27.8778 + 27.8779 + var _now = Date.now; 27.8780 + 27.8781 + function _newFrame() { 27.8782 + if (this._inProgress && (_now() - this._prevTime) > this.options.stallTime) { 27.8783 + this._position = (this.options.direction === undefined) ? [0,0] : 0; 27.8784 + this._inProgress = false; 27.8785 + 27.8786 + var finalVel = (Math.abs(this._prevVel) >= this.options.minimumEndSpeed) 27.8787 + ? this._prevVel 27.8788 + : 0; 27.8789 + 27.8790 + var payload = this._payload; 27.8791 + payload.position = this._position; 27.8792 + payload.velocity = finalVel; 27.8793 + payload.slip = true; 27.8794 + 27.8795 + this._eventOutput.emit('end', payload); 27.8796 + } 27.8797 + } 27.8798 + 27.8799 + function _handleMove(event) { 27.8800 + event.preventDefault(); 27.8801 + 27.8802 + if (!this._inProgress) { 27.8803 + this._inProgress = true; 27.8804 + 27.8805 + payload = this._payload; 27.8806 + payload.slip = true; 27.8807 + payload.position = this._position; 27.8808 + payload.clientX = event.clientX; 27.8809 + payload.clientY = event.clientY; 27.8810 + payload.offsetX = event.offsetX; 27.8811 + payload.offsetY = event.offsetY; 27.8812 + this._eventOutput.emit('start', payload); 27.8813 + if (!this._loopBound) { 27.8814 + Engine.on('prerender', _newFrame.bind(this)); 27.8815 + this._loopBound = true; 27.8816 + } 27.8817 + } 27.8818 + 27.8819 + var currTime = _now(); 27.8820 + var prevTime = this._prevTime || currTime; 27.8821 + 27.8822 + var diffX = (event.wheelDeltaX !== undefined) ? event.wheelDeltaX : -event.deltaX; 27.8823 + var diffY = (event.wheelDeltaY !== undefined) ? event.wheelDeltaY : -event.deltaY; 27.8824 + 27.8825 + if (event.deltaMode === 1) { // units in lines, not pixels 27.8826 + diffX *= this.options.lineHeight; 27.8827 + diffY *= this.options.lineHeight; 27.8828 + } 27.8829 + 27.8830 + if (this.options.rails) { 27.8831 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 27.8832 + else diffX = 0; 27.8833 + } 27.8834 + 27.8835 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time 27.8836 + 27.8837 + var velX = diffX / diffTime; 27.8838 + var velY = diffY / diffTime; 27.8839 + 27.8840 + var scale = this.options.scale; 27.8841 + var nextVel; 27.8842 + var nextDelta; 27.8843 + 27.8844 + if (this.options.direction === ScrollSync.DIRECTION_X) { 27.8845 + nextDelta = scale * diffX; 27.8846 + nextVel = scale * velX; 27.8847 + this._position += nextDelta; 27.8848 + } 27.8849 + else if (this.options.direction === ScrollSync.DIRECTION_Y) { 27.8850 + nextDelta = scale * diffY; 27.8851 + nextVel = scale * velY; 27.8852 + this._position += nextDelta; 27.8853 + } 27.8854 + else { 27.8855 + nextDelta = [scale * diffX, scale * diffY]; 27.8856 + nextVel = [scale * velX, scale * velY]; 27.8857 + this._position[0] += nextDelta[0]; 27.8858 + this._position[1] += nextDelta[1]; 27.8859 + } 27.8860 + 27.8861 + var payload = this._payload; 27.8862 + payload.delta = nextDelta; 27.8863 + payload.velocity = nextVel; 27.8864 + payload.position = this._position; 27.8865 + payload.slip = true; 27.8866 + 27.8867 + this._eventOutput.emit('update', payload); 27.8868 + 27.8869 + this._prevTime = currTime; 27.8870 + this._prevVel = nextVel; 27.8871 + } 27.8872 + 27.8873 + /** 27.8874 + * Return entire options dictionary, including defaults. 27.8875 + * 27.8876 + * @method getOptions 27.8877 + * @return {Object} configuration options 27.8878 + */ 27.8879 + ScrollSync.prototype.getOptions = function getOptions() { 27.8880 + return this.options; 27.8881 + }; 27.8882 + 27.8883 + /** 27.8884 + * Set internal options, overriding any default options 27.8885 + * 27.8886 + * @method setOptions 27.8887 + * 27.8888 + * @param {Object} [options] overrides of default options 27.8889 + * @param {Number} [options.minimimEndSpeed] If final velocity smaller than this, round down to 0. 27.8890 + * @param {Number} [options.stallTime] ms of non-motion before 'end' emitted 27.8891 + * @param {Number} [options.rails] whether to constrain to nearest axis. 27.8892 + * @param {Number} [options.direction] ScrollSync.DIRECTION_X, DIRECTION_Y - 27.8893 + * pay attention to one specific direction. 27.8894 + * @param {Number} [options.scale] constant factor to scale velocity output 27.8895 + */ 27.8896 + ScrollSync.prototype.setOptions = function setOptions(options) { 27.8897 + if (options.direction !== undefined) this.options.direction = options.direction; 27.8898 + if (options.minimumEndSpeed !== undefined) this.options.minimumEndSpeed = options.minimumEndSpeed; 27.8899 + if (options.rails !== undefined) this.options.rails = options.rails; 27.8900 + if (options.scale !== undefined) this.options.scale = options.scale; 27.8901 + if (options.stallTime !== undefined) this.options.stallTime = options.stallTime; 27.8902 + }; 27.8903 + 27.8904 + module.exports = ScrollSync; 27.8905 +}); 27.8906 + 27.8907 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8908 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8909 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8910 + * 27.8911 + * Owner: david@famo.us 27.8912 + * @license MPL 2.0 27.8913 + * @copyright Famous Industries, Inc. 2014 27.8914 + */ 27.8915 + 27.8916 +define('famous/transitions/CachedMap',['require','exports','module'],function(require, exports, module) { 27.8917 + /** 27.8918 + * A simple in-memory object cache. Used as a helper for Views with 27.8919 + * provider functions. 27.8920 + * @class CachedMap 27.8921 + * @constructor 27.8922 + */ 27.8923 + function CachedMap(mappingFunction) { 27.8924 + this._map = mappingFunction || null; 27.8925 + this._cachedOutput = null; 27.8926 + this._cachedInput = Number.NaN; //never valid as input 27.8927 + } 27.8928 + 27.8929 + /** 27.8930 + * Creates a mapping function with a cache. 27.8931 + * This is the main entrypoint for this object. 27.8932 + * @static 27.8933 + * @method create 27.8934 + * @param {function} mappingFunction mapping 27.8935 + * @return {function} memoized mapping function 27.8936 + */ 27.8937 + CachedMap.create = function create(mappingFunction) { 27.8938 + var instance = new CachedMap(mappingFunction); 27.8939 + return instance.get.bind(instance); 27.8940 + }; 27.8941 + 27.8942 + /** 27.8943 + * Retrieve items from cache or from mapping functin. 27.8944 + * 27.8945 + * @method get 27.8946 + * @param {Object} input input key 27.8947 + */ 27.8948 + CachedMap.prototype.get = function get(input) { 27.8949 + if (input !== this._cachedInput) { 27.8950 + this._cachedInput = input; 27.8951 + this._cachedOutput = this._map(input); 27.8952 + } 27.8953 + return this._cachedOutput; 27.8954 + }; 27.8955 + 27.8956 + module.exports = CachedMap; 27.8957 +}); 27.8958 + 27.8959 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.8960 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.8961 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.8962 + * 27.8963 + * Owner: david@famo.us 27.8964 + * @license MPL 2.0 27.8965 + * @copyright Famous Industries, Inc. 2014 27.8966 + */ 27.8967 + 27.8968 +define('famous/transitions/Easing',['require','exports','module'],function(require, exports, module) { 27.8969 + 27.8970 + /* 27.8971 + * A library of curves which map an animation explicitly as a function of time. 27.8972 + * 27.8973 + * @class Easing 27.8974 + */ 27.8975 + var Easing = { 27.8976 + 27.8977 + /** 27.8978 + * @property inQuad 27.8979 + * @static 27.8980 + */ 27.8981 + inQuad: function(t) { 27.8982 + return t*t; 27.8983 + }, 27.8984 + 27.8985 + /** 27.8986 + * @property outQuad 27.8987 + * @static 27.8988 + */ 27.8989 + outQuad: function(t) { 27.8990 + return -(t-=1)*t+1; 27.8991 + }, 27.8992 + 27.8993 + /** 27.8994 + * @property inOutQuad 27.8995 + * @static 27.8996 + */ 27.8997 + inOutQuad: function(t) { 27.8998 + if ((t/=.5) < 1) return .5*t*t; 27.8999 + return -.5*((--t)*(t-2) - 1); 27.9000 + }, 27.9001 + 27.9002 + /** 27.9003 + * @property inCubic 27.9004 + * @static 27.9005 + */ 27.9006 + inCubic: function(t) { 27.9007 + return t*t*t; 27.9008 + }, 27.9009 + 27.9010 + /** 27.9011 + * @property outCubic 27.9012 + * @static 27.9013 + */ 27.9014 + outCubic: function(t) { 27.9015 + return ((--t)*t*t + 1); 27.9016 + }, 27.9017 + 27.9018 + /** 27.9019 + * @property inOutCubic 27.9020 + * @static 27.9021 + */ 27.9022 + inOutCubic: function(t) { 27.9023 + if ((t/=.5) < 1) return .5*t*t*t; 27.9024 + return .5*((t-=2)*t*t + 2); 27.9025 + }, 27.9026 + 27.9027 + /** 27.9028 + * @property inQuart 27.9029 + * @static 27.9030 + */ 27.9031 + inQuart: function(t) { 27.9032 + return t*t*t*t; 27.9033 + }, 27.9034 + 27.9035 + /** 27.9036 + * @property outQuart 27.9037 + * @static 27.9038 + */ 27.9039 + outQuart: function(t) { 27.9040 + return -((--t)*t*t*t - 1); 27.9041 + }, 27.9042 + 27.9043 + /** 27.9044 + * @property inOutQuart 27.9045 + * @static 27.9046 + */ 27.9047 + inOutQuart: function(t) { 27.9048 + if ((t/=.5) < 1) return .5*t*t*t*t; 27.9049 + return -.5 * ((t-=2)*t*t*t - 2); 27.9050 + }, 27.9051 + 27.9052 + /** 27.9053 + * @property inQuint 27.9054 + * @static 27.9055 + */ 27.9056 + inQuint: function(t) { 27.9057 + return t*t*t*t*t; 27.9058 + }, 27.9059 + 27.9060 + /** 27.9061 + * @property outQuint 27.9062 + * @static 27.9063 + */ 27.9064 + outQuint: function(t) { 27.9065 + return ((--t)*t*t*t*t + 1); 27.9066 + }, 27.9067 + 27.9068 + /** 27.9069 + * @property inOutQuint 27.9070 + * @static 27.9071 + */ 27.9072 + inOutQuint: function(t) { 27.9073 + if ((t/=.5) < 1) return .5*t*t*t*t*t; 27.9074 + return .5*((t-=2)*t*t*t*t + 2); 27.9075 + }, 27.9076 + 27.9077 + /** 27.9078 + * @property inSine 27.9079 + * @static 27.9080 + */ 27.9081 + inSine: function(t) { 27.9082 + return -1.0*Math.cos(t * (Math.PI/2)) + 1.0; 27.9083 + }, 27.9084 + 27.9085 + /** 27.9086 + * @property outSine 27.9087 + * @static 27.9088 + */ 27.9089 + outSine: function(t) { 27.9090 + return Math.sin(t * (Math.PI/2)); 27.9091 + }, 27.9092 + 27.9093 + /** 27.9094 + * @property inOutSine 27.9095 + * @static 27.9096 + */ 27.9097 + inOutSine: function(t) { 27.9098 + return -.5*(Math.cos(Math.PI*t) - 1); 27.9099 + }, 27.9100 + 27.9101 + /** 27.9102 + * @property inExpo 27.9103 + * @static 27.9104 + */ 27.9105 + inExpo: function(t) { 27.9106 + return (t===0) ? 0.0 : Math.pow(2, 10 * (t - 1)); 27.9107 + }, 27.9108 + 27.9109 + /** 27.9110 + * @property outExpo 27.9111 + * @static 27.9112 + */ 27.9113 + outExpo: function(t) { 27.9114 + return (t===1.0) ? 1.0 : (-Math.pow(2, -10 * t) + 1); 27.9115 + }, 27.9116 + 27.9117 + /** 27.9118 + * @property inOutExpo 27.9119 + * @static 27.9120 + */ 27.9121 + inOutExpo: function(t) { 27.9122 + if (t===0) return 0.0; 27.9123 + if (t===1.0) return 1.0; 27.9124 + if ((t/=.5) < 1) return .5 * Math.pow(2, 10 * (t - 1)); 27.9125 + return .5 * (-Math.pow(2, -10 * --t) + 2); 27.9126 + }, 27.9127 + 27.9128 + /** 27.9129 + * @property inCirc 27.9130 + * @static 27.9131 + */ 27.9132 + inCirc: function(t) { 27.9133 + return -(Math.sqrt(1 - t*t) - 1); 27.9134 + }, 27.9135 + 27.9136 + /** 27.9137 + * @property outCirc 27.9138 + * @static 27.9139 + */ 27.9140 + outCirc: function(t) { 27.9141 + return Math.sqrt(1 - (--t)*t); 27.9142 + }, 27.9143 + 27.9144 + /** 27.9145 + * @property inOutCirc 27.9146 + * @static 27.9147 + */ 27.9148 + inOutCirc: function(t) { 27.9149 + if ((t/=.5) < 1) return -.5 * (Math.sqrt(1 - t*t) - 1); 27.9150 + return .5 * (Math.sqrt(1 - (t-=2)*t) + 1); 27.9151 + }, 27.9152 + 27.9153 + /** 27.9154 + * @property inElastic 27.9155 + * @static 27.9156 + */ 27.9157 + inElastic: function(t) { 27.9158 + var s=1.70158;var p=0;var a=1.0; 27.9159 + if (t===0) return 0.0; if (t===1) return 1.0; if (!p) p=.3; 27.9160 + s = p/(2*Math.PI) * Math.asin(1.0/a); 27.9161 + return -(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/ p)); 27.9162 + }, 27.9163 + 27.9164 + /** 27.9165 + * @property outElastic 27.9166 + * @static 27.9167 + */ 27.9168 + outElastic: function(t) { 27.9169 + var s=1.70158;var p=0;var a=1.0; 27.9170 + if (t===0) return 0.0; if (t===1) return 1.0; if (!p) p=.3; 27.9171 + s = p/(2*Math.PI) * Math.asin(1.0/a); 27.9172 + return a*Math.pow(2,-10*t) * Math.sin((t-s)*(2*Math.PI)/p) + 1.0; 27.9173 + }, 27.9174 + 27.9175 + /** 27.9176 + * @property inOutElastic 27.9177 + * @static 27.9178 + */ 27.9179 + inOutElastic: function(t) { 27.9180 + var s=1.70158;var p=0;var a=1.0; 27.9181 + if (t===0) return 0.0; if ((t/=.5)===2) return 1.0; if (!p) p=(.3*1.5); 27.9182 + s = p/(2*Math.PI) * Math.asin(1.0/a); 27.9183 + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)); 27.9184 + return a*Math.pow(2,-10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)*.5 + 1.0; 27.9185 + }, 27.9186 + 27.9187 + /** 27.9188 + * @property inBack 27.9189 + * @static 27.9190 + */ 27.9191 + inBack: function(t, s) { 27.9192 + if (s === undefined) s = 1.70158; 27.9193 + return t*t*((s+1)*t - s); 27.9194 + }, 27.9195 + 27.9196 + /** 27.9197 + * @property outBack 27.9198 + * @static 27.9199 + */ 27.9200 + outBack: function(t, s) { 27.9201 + if (s === undefined) s = 1.70158; 27.9202 + return ((--t)*t*((s+1)*t + s) + 1); 27.9203 + }, 27.9204 + 27.9205 + /** 27.9206 + * @property inOutBack 27.9207 + * @static 27.9208 + */ 27.9209 + inOutBack: function(t, s) { 27.9210 + if (s === undefined) s = 1.70158; 27.9211 + if ((t/=.5) < 1) return .5*(t*t*(((s*=(1.525))+1)*t - s)); 27.9212 + return .5*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2); 27.9213 + }, 27.9214 + 27.9215 + /** 27.9216 + * @property inBounce 27.9217 + * @static 27.9218 + */ 27.9219 + inBounce: function(t) { 27.9220 + return 1.0 - Easing.outBounce(1.0-t); 27.9221 + }, 27.9222 + 27.9223 + /** 27.9224 + * @property outBounce 27.9225 + * @static 27.9226 + */ 27.9227 + outBounce: function(t) { 27.9228 + if (t < (1/2.75)) { 27.9229 + return (7.5625*t*t); 27.9230 + } else if (t < (2/2.75)) { 27.9231 + return (7.5625*(t-=(1.5/2.75))*t + .75); 27.9232 + } else if (t < (2.5/2.75)) { 27.9233 + return (7.5625*(t-=(2.25/2.75))*t + .9375); 27.9234 + } else { 27.9235 + return (7.5625*(t-=(2.625/2.75))*t + .984375); 27.9236 + } 27.9237 + }, 27.9238 + 27.9239 + /** 27.9240 + * @property inOutBounce 27.9241 + * @static 27.9242 + */ 27.9243 + inOutBounce: function(t) { 27.9244 + if (t < .5) return Easing.inBounce(t*2) * .5; 27.9245 + return Easing.outBounce(t*2-1.0) * .5 + .5; 27.9246 + } 27.9247 + }; 27.9248 + 27.9249 + module.exports = Easing; 27.9250 +}); 27.9251 + 27.9252 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.9253 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.9254 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.9255 + * 27.9256 + * Owner: david@famo.us 27.9257 + * @license MPL 2.0 27.9258 + * @copyright Famous Industries, Inc. 2014 27.9259 + */ 27.9260 + 27.9261 +define('famous/physics/integrators/SymplecticEuler',['require','exports','module','famous/core/OptionsManager'],function(require, exports, module) { 27.9262 + var OptionsManager = require('famous/core/OptionsManager'); 27.9263 + 27.9264 + /** 27.9265 + * Ordinary Differential Equation (ODE) Integrator. 27.9266 + * Manages updating a physics body's state over time. 27.9267 + * 27.9268 + * p = position, v = velocity, m = mass, f = force, dt = change in time 27.9269 + * 27.9270 + * v <- v + dt * f / m 27.9271 + * p <- p + dt * v 27.9272 + * 27.9273 + * q = orientation, w = angular velocity, L = angular momentum 27.9274 + * 27.9275 + * L <- L + dt * t 27.9276 + * q <- q + dt/2 * q * w 27.9277 + * 27.9278 + * @class SymplecticEuler 27.9279 + * @constructor 27.9280 + * @param {Object} options Options to set 27.9281 + */ 27.9282 + function SymplecticEuler(options) { 27.9283 + this.options = Object.create(SymplecticEuler.DEFAULT_OPTIONS); 27.9284 + this._optionsManager = new OptionsManager(this.options); 27.9285 + 27.9286 + if (options) this.setOptions(options); 27.9287 + } 27.9288 + 27.9289 + /** 27.9290 + * @property SymplecticEuler.DEFAULT_OPTIONS 27.9291 + * @type Object 27.9292 + * @protected 27.9293 + * @static 27.9294 + */ 27.9295 + SymplecticEuler.DEFAULT_OPTIONS = { 27.9296 + 27.9297 + /** 27.9298 + * The maximum velocity of a physics body 27.9299 + * Range : [0, Infinity] 27.9300 + * @attribute velocityCap 27.9301 + * @type Number 27.9302 + */ 27.9303 + 27.9304 + velocityCap : undefined, 27.9305 + 27.9306 + /** 27.9307 + * The maximum angular velocity of a physics body 27.9308 + * Range : [0, Infinity] 27.9309 + * @attribute angularVelocityCap 27.9310 + * @type Number 27.9311 + */ 27.9312 + angularVelocityCap : undefined 27.9313 + }; 27.9314 + 27.9315 + /* 27.9316 + * Setter for options 27.9317 + * 27.9318 + * @method setOptions 27.9319 + * @param {Object} options 27.9320 + */ 27.9321 + SymplecticEuler.prototype.setOptions = function setOptions(options) { 27.9322 + this._optionsManager.patch(options); 27.9323 + }; 27.9324 + 27.9325 + /* 27.9326 + * Getter for options 27.9327 + * 27.9328 + * @method getOptions 27.9329 + * @return {Object} options 27.9330 + */ 27.9331 + SymplecticEuler.prototype.getOptions = function getOptions() { 27.9332 + return this._optionsManager.value(); 27.9333 + }; 27.9334 + 27.9335 + /* 27.9336 + * Updates the velocity of a physics body from its accumulated force. 27.9337 + * v <- v + dt * f / m 27.9338 + * 27.9339 + * @method integrateVelocity 27.9340 + * @param {Body} physics body 27.9341 + * @param {Number} dt delta time 27.9342 + */ 27.9343 + SymplecticEuler.prototype.integrateVelocity = function integrateVelocity(body, dt) { 27.9344 + var v = body.velocity; 27.9345 + var w = body.inverseMass; 27.9346 + var f = body.force; 27.9347 + 27.9348 + if (f.isZero()) return; 27.9349 + 27.9350 + v.add(f.mult(dt * w)).put(v); 27.9351 + f.clear(); 27.9352 + }; 27.9353 + 27.9354 + /* 27.9355 + * Updates the position of a physics body from its velocity. 27.9356 + * p <- p + dt * v 27.9357 + * 27.9358 + * @method integratePosition 27.9359 + * @param {Body} physics body 27.9360 + * @param {Number} dt delta time 27.9361 + */ 27.9362 + SymplecticEuler.prototype.integratePosition = function integratePosition(body, dt) { 27.9363 + var p = body.position; 27.9364 + var v = body.velocity; 27.9365 + 27.9366 + if (this.options.velocityCap) v.cap(this.options.velocityCap).put(v); 27.9367 + p.add(v.mult(dt)).put(p); 27.9368 + }; 27.9369 + 27.9370 + /* 27.9371 + * Updates the angular momentum of a physics body from its accumuled torque. 27.9372 + * L <- L + dt * t 27.9373 + * 27.9374 + * @method integrateAngularMomentum 27.9375 + * @param {Body} physics body (except a particle) 27.9376 + * @param {Number} dt delta time 27.9377 + */ 27.9378 + SymplecticEuler.prototype.integrateAngularMomentum = function integrateAngularMomentum(body, dt) { 27.9379 + var L = body.angularMomentum; 27.9380 + var t = body.torque; 27.9381 + 27.9382 + if (t.isZero()) return; 27.9383 + 27.9384 + if (this.options.angularVelocityCap) t.cap(this.options.angularVelocityCap).put(t); 27.9385 + L.add(t.mult(dt)).put(L); 27.9386 + t.clear(); 27.9387 + }; 27.9388 + 27.9389 + /* 27.9390 + * Updates the orientation of a physics body from its angular velocity. 27.9391 + * q <- q + dt/2 * q * w 27.9392 + * 27.9393 + * @method integrateOrientation 27.9394 + * @param {Body} physics body (except a particle) 27.9395 + * @param {Number} dt delta time 27.9396 + */ 27.9397 + SymplecticEuler.prototype.integrateOrientation = function integrateOrientation(body, dt) { 27.9398 + var q = body.orientation; 27.9399 + var w = body.angularVelocity; 27.9400 + 27.9401 + if (w.isZero()) return; 27.9402 + q.add(q.multiply(w).scalarMultiply(0.5 * dt)).put(q); 27.9403 +// q.normalize.put(q); 27.9404 + }; 27.9405 + 27.9406 + module.exports = SymplecticEuler; 27.9407 +}); 27.9408 + 27.9409 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.9410 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.9411 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.9412 + * 27.9413 + * Owner: david@famo.us 27.9414 + * @license MPL 2.0 27.9415 + * @copyright Famous Industries, Inc. 2014 27.9416 + */ 27.9417 + 27.9418 +define('famous/physics/bodies/Particle',['require','exports','module','famous/math/Vector','famous/core/Transform','famous/core/EventHandler','../integrators/SymplecticEuler'],function(require, exports, module) { 27.9419 + var Vector = require('famous/math/Vector'); 27.9420 + var Transform = require('famous/core/Transform'); 27.9421 + var EventHandler = require('famous/core/EventHandler'); 27.9422 + var Integrator = require('../integrators/SymplecticEuler'); 27.9423 + 27.9424 + /** 27.9425 + * A point body that is controlled by the Physics Engine. A particle has 27.9426 + * position and velocity states that are updated by the Physics Engine. 27.9427 + * Ultimately, a particle is a _special type of modifier, and can be added to 27.9428 + * the Famous render tree like any other modifier. 27.9429 + * 27.9430 + * @constructor 27.9431 + * @class Particle 27.9432 + * @uses EventHandler 27.9433 + * @uses Modifier 27.9434 + * @extensionfor Body 27.9435 + * @param {Options} [options] An object of configurable options. 27.9436 + * @param {Array} [options.position] The position of the particle. 27.9437 + * @param {Array} [options.velocity] The velocity of the particle. 27.9438 + * @param {Number} [options.mass] The mass of the particle. 27.9439 + * @param {Hexadecimal} [options.axis] The axis a particle can move along. Can be bitwise ORed e.g., Particle.AXES.X, Particle.AXES.X | Particle.AXES.Y 27.9440 + * 27.9441 + */ 27.9442 + function Particle(options) { 27.9443 + options = options || {}; 27.9444 + 27.9445 + // registers 27.9446 + this.position = new Vector(); 27.9447 + this.velocity = new Vector(); 27.9448 + this.force = new Vector(); 27.9449 + 27.9450 + var defaults = Particle.DEFAULT_OPTIONS; 27.9451 + 27.9452 + // set vectors 27.9453 + this.setPosition(options.position || defaults.position); 27.9454 + this.setVelocity(options.velocity || defaults.velocity); 27.9455 + this.force.set(options.force || [0,0,0]); 27.9456 + 27.9457 + // set scalars 27.9458 + this.mass = (options.mass !== undefined) 27.9459 + ? options.mass 27.9460 + : defaults.mass; 27.9461 + 27.9462 + this.axis = (options.axis !== undefined) 27.9463 + ? options.axis 27.9464 + : defaults.axis; 27.9465 + 27.9466 + this.inverseMass = 1 / this.mass; 27.9467 + 27.9468 + // state variables 27.9469 + this._isSleeping = false; 27.9470 + this._engine = null; 27.9471 + this._eventOutput = null; 27.9472 + this._positionGetter = null; 27.9473 + 27.9474 + this.transform = Transform.identity.slice(); 27.9475 + 27.9476 + // cached _spec 27.9477 + this._spec = { 27.9478 + transform : this.transform, 27.9479 + target : null 27.9480 + }; 27.9481 + } 27.9482 + 27.9483 + Particle.DEFAULT_OPTIONS = { 27.9484 + position : [0,0,0], 27.9485 + velocity : [0,0,0], 27.9486 + mass : 1, 27.9487 + axis : undefined 27.9488 + }; 27.9489 + 27.9490 + /** 27.9491 + * Kinetic energy threshold needed to update the body 27.9492 + * 27.9493 + * @property SLEEP_TOLERANCE 27.9494 + * @type Number 27.9495 + * @static 27.9496 + * @default 1e-7 27.9497 + */ 27.9498 + Particle.SLEEP_TOLERANCE = 1e-7; 27.9499 + 27.9500 + /** 27.9501 + * Axes by which a body can translate 27.9502 + * 27.9503 + * @property AXES 27.9504 + * @type Hexadecimal 27.9505 + * @static 27.9506 + * @default 1e-7 27.9507 + */ 27.9508 + Particle.AXES = { 27.9509 + X : 0x00, // hexadecimal for 0 27.9510 + Y : 0x01, // hexadecimal for 1 27.9511 + Z : 0x02 // hexadecimal for 2 27.9512 + }; 27.9513 + 27.9514 + // Integrator for updating the particle's state 27.9515 + // TODO: make this a singleton 27.9516 + Particle.INTEGRATOR = new Integrator(); 27.9517 + 27.9518 + //Catalogue of outputted events 27.9519 + var _events = { 27.9520 + start : 'start', 27.9521 + update : 'update', 27.9522 + end : 'end' 27.9523 + }; 27.9524 + 27.9525 + // Cached timing function 27.9526 + var now = (function() { 27.9527 + return Date.now; 27.9528 + })(); 27.9529 + 27.9530 + /** 27.9531 + * Stops the particle from updating 27.9532 + * @method sleep 27.9533 + */ 27.9534 + Particle.prototype.sleep = function sleep() { 27.9535 + if (this._isSleeping) return; 27.9536 + this.emit(_events.end, this); 27.9537 + this._isSleeping = true; 27.9538 + }; 27.9539 + 27.9540 + /** 27.9541 + * Starts the particle update 27.9542 + * @method wake 27.9543 + */ 27.9544 + Particle.prototype.wake = function wake() { 27.9545 + if (!this._isSleeping) return; 27.9546 + this.emit(_events.start, this); 27.9547 + this._isSleeping = false; 27.9548 + this._prevTime = now(); 27.9549 + }; 27.9550 + 27.9551 + /** 27.9552 + * @attribute isBody 27.9553 + * @type Boolean 27.9554 + * @static 27.9555 + */ 27.9556 + Particle.prototype.isBody = false; 27.9557 + 27.9558 + /** 27.9559 + * Basic setter for position 27.9560 + * @method getPosition 27.9561 + * @param position {Array|Vector} 27.9562 + */ 27.9563 + Particle.prototype.setPosition = function setPosition(position) { 27.9564 + this.position.set(position); 27.9565 + }; 27.9566 + 27.9567 + /** 27.9568 + * 1-dimensional setter for position 27.9569 + * @method setPosition1D 27.9570 + * @param value {Number} 27.9571 + */ 27.9572 + Particle.prototype.setPosition1D = function setPosition1D(x) { 27.9573 + this.position.x = x; 27.9574 + }; 27.9575 + 27.9576 + /** 27.9577 + * Basic getter function for position 27.9578 + * @method getPosition 27.9579 + * @return position {Array} 27.9580 + */ 27.9581 + Particle.prototype.getPosition = function getPosition() { 27.9582 + if (this._positionGetter instanceof Function) 27.9583 + this.setPosition(this._positionGetter()); 27.9584 + 27.9585 + this._engine.step(); 27.9586 + 27.9587 + return this.position.get(); 27.9588 + }; 27.9589 + 27.9590 + /** 27.9591 + * 1-dimensional getter for position 27.9592 + * @method getPosition1D 27.9593 + * @return value {Number} 27.9594 + */ 27.9595 + Particle.prototype.getPosition1D = function getPosition1D() { 27.9596 + this._engine.step(); 27.9597 + return this.position.x; 27.9598 + }; 27.9599 + 27.9600 + /** 27.9601 + * Defines the position from outside the Physics Engine 27.9602 + * @method positionFrom 27.9603 + * @param positionGetter {Function} 27.9604 + */ 27.9605 + Particle.prototype.positionFrom = function positionFrom(positionGetter) { 27.9606 + this._positionGetter = positionGetter; 27.9607 + }; 27.9608 + 27.9609 + /** 27.9610 + * Basic setter function for velocity Vector 27.9611 + * @method setVelocity 27.9612 + * @function 27.9613 + */ 27.9614 + Particle.prototype.setVelocity = function setVelocity(velocity) { 27.9615 + this.velocity.set(velocity); 27.9616 + this.wake(); 27.9617 + }; 27.9618 + 27.9619 + /** 27.9620 + * 1-dimensional setter for velocity 27.9621 + * @method setVelocity1D 27.9622 + * @param velocity {Number} 27.9623 + */ 27.9624 + Particle.prototype.setVelocity1D = function setVelocity1D(x) { 27.9625 + this.velocity.x = x; 27.9626 + this.wake(); 27.9627 + }; 27.9628 + 27.9629 + /** 27.9630 + * Basic getter function for velocity Vector 27.9631 + * @method getVelocity 27.9632 + * @return velocity {Array} 27.9633 + */ 27.9634 + Particle.prototype.getVelocity = function getVelocity() { 27.9635 + return this.velocity.get(); 27.9636 + }; 27.9637 + 27.9638 + /** 27.9639 + * 1-dimensional getter for velocity 27.9640 + * @method getVelocity1D 27.9641 + * @return velocity {Number} 27.9642 + */ 27.9643 + Particle.prototype.getVelocity1D = function getVelocity1D() { 27.9644 + return this.velocity.x; 27.9645 + }; 27.9646 + 27.9647 + /** 27.9648 + * Basic setter function for mass quantity 27.9649 + * @method setMass 27.9650 + * @param mass {Number} mass 27.9651 + */ 27.9652 + Particle.prototype.setMass = function setMass(mass) { 27.9653 + this.mass = mass; 27.9654 + this.inverseMass = 1 / mass; 27.9655 + }; 27.9656 + 27.9657 + /** 27.9658 + * Basic getter function for mass quantity 27.9659 + * @method getMass 27.9660 + * @return mass {Number} 27.9661 + */ 27.9662 + Particle.prototype.getMass = function getMass() { 27.9663 + return this.mass; 27.9664 + }; 27.9665 + 27.9666 + /** 27.9667 + * Reset position and velocity 27.9668 + * @method reset 27.9669 + * @param position {Array|Vector} 27.9670 + * @param velocity {Array|Vector} 27.9671 + */ 27.9672 + Particle.prototype.reset = function reset(position, velocity) { 27.9673 + this.setPosition(position || [0,0,0]); 27.9674 + this.setVelocity(velocity || [0,0,0]); 27.9675 + }; 27.9676 + 27.9677 + /** 27.9678 + * Add force vector to existing internal force Vector 27.9679 + * @method applyForce 27.9680 + * @param force {Vector} 27.9681 + */ 27.9682 + Particle.prototype.applyForce = function applyForce(force) { 27.9683 + if (force.isZero()) return; 27.9684 + this.force.add(force).put(this.force); 27.9685 + this.wake(); 27.9686 + }; 27.9687 + 27.9688 + /** 27.9689 + * Add impulse (change in velocity) Vector to this Vector's velocity. 27.9690 + * @method applyImpulse 27.9691 + * @param impulse {Vector} 27.9692 + */ 27.9693 + Particle.prototype.applyImpulse = function applyImpulse(impulse) { 27.9694 + if (impulse.isZero()) return; 27.9695 + var velocity = this.velocity; 27.9696 + velocity.add(impulse.mult(this.inverseMass)).put(velocity); 27.9697 + }; 27.9698 + 27.9699 + /** 27.9700 + * Update a particle's velocity from its force accumulator 27.9701 + * @method integrateVelocity 27.9702 + * @param dt {Number} Time differential 27.9703 + */ 27.9704 + Particle.prototype.integrateVelocity = function integrateVelocity(dt) { 27.9705 + Particle.INTEGRATOR.integrateVelocity(this, dt); 27.9706 + }; 27.9707 + 27.9708 + /** 27.9709 + * Update a particle's position from its velocity 27.9710 + * @method integratePosition 27.9711 + * @param dt {Number} Time differential 27.9712 + */ 27.9713 + Particle.prototype.integratePosition = function integratePosition(dt) { 27.9714 + Particle.INTEGRATOR.integratePosition(this, dt); 27.9715 + }; 27.9716 + 27.9717 + /** 27.9718 + * Update the position and velocity of the particle 27.9719 + * @method _integrate 27.9720 + * @protected 27.9721 + * @param dt {Number} Time differential 27.9722 + */ 27.9723 + Particle.prototype._integrate = function _integrate(dt) { 27.9724 + this.integrateVelocity(dt); 27.9725 + this.integratePosition(dt); 27.9726 + }; 27.9727 + 27.9728 + /** 27.9729 + * Get kinetic energy of the particle. 27.9730 + * @method getEnergy 27.9731 + * @function 27.9732 + */ 27.9733 + Particle.prototype.getEnergy = function getEnergy() { 27.9734 + return 0.5 * this.mass * this.velocity.normSquared(); 27.9735 + }; 27.9736 + 27.9737 + /** 27.9738 + * Generate transform from the current position state 27.9739 + * @method getTransform 27.9740 + * @return Transform {Transform} 27.9741 + */ 27.9742 + Particle.prototype.getTransform = function getTransform() { 27.9743 + this._engine.step(); 27.9744 + 27.9745 + var position = this.position; 27.9746 + var axis = this.axis; 27.9747 + var transform = this.transform; 27.9748 + 27.9749 + if (axis !== undefined) { 27.9750 + if (axis & ~Particle.AXES.X) { 27.9751 + position.x = 0; 27.9752 + } 27.9753 + if (axis & ~Particle.AXES.Y) { 27.9754 + position.y = 0; 27.9755 + } 27.9756 + if (axis & ~Particle.AXES.Z) { 27.9757 + position.z = 0; 27.9758 + } 27.9759 + } 27.9760 + 27.9761 + transform[12] = position.x; 27.9762 + transform[13] = position.y; 27.9763 + transform[14] = position.z; 27.9764 + 27.9765 + return transform; 27.9766 + }; 27.9767 + 27.9768 + /** 27.9769 + * The modify interface of a Modifier 27.9770 + * @method modify 27.9771 + * @param target {Spec} 27.9772 + * @return Spec {Spec} 27.9773 + */ 27.9774 + Particle.prototype.modify = function modify(target) { 27.9775 + var _spec = this._spec; 27.9776 + _spec.transform = this.getTransform(); 27.9777 + _spec.target = target; 27.9778 + return _spec; 27.9779 + }; 27.9780 + 27.9781 + // private 27.9782 + function _createEventOutput() { 27.9783 + this._eventOutput = new EventHandler(); 27.9784 + this._eventOutput.bindThis(this); 27.9785 + //overrides on/removeListener/pipe/unpipe methods 27.9786 + EventHandler.setOutputHandler(this, this._eventOutput); 27.9787 + } 27.9788 + 27.9789 + Particle.prototype.emit = function emit(type, data) { 27.9790 + if (!this._eventOutput) return; 27.9791 + this._eventOutput.emit(type, data); 27.9792 + }; 27.9793 + 27.9794 + Particle.prototype.on = function on() { 27.9795 + _createEventOutput.call(this); 27.9796 + return this.on.apply(this, arguments); 27.9797 + }; 27.9798 + Particle.prototype.removeListener = function removeListener() { 27.9799 + _createEventOutput.call(this); 27.9800 + return this.removeListener.apply(this, arguments); 27.9801 + }; 27.9802 + Particle.prototype.pipe = function pipe() { 27.9803 + _createEventOutput.call(this); 27.9804 + return this.pipe.apply(this, arguments); 27.9805 + }; 27.9806 + Particle.prototype.unpipe = function unpipe() { 27.9807 + _createEventOutput.call(this); 27.9808 + return this.unpipe.apply(this, arguments); 27.9809 + }; 27.9810 + 27.9811 + module.exports = Particle; 27.9812 +}); 27.9813 + 27.9814 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.9815 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.9816 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.9817 + * 27.9818 + * Owner: david@famo.us 27.9819 + * @license MPL 2.0 27.9820 + * @copyright Famous Industries, Inc. 2014 27.9821 + */ 27.9822 + 27.9823 +define('famous/physics/constraints/Constraint',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 27.9824 + var EventHandler = require('famous/core/EventHandler'); 27.9825 + 27.9826 + /** 27.9827 + * Allows for two circular bodies to collide and bounce off each other. 27.9828 + * 27.9829 + * @class Constraint 27.9830 + * @constructor 27.9831 + * @uses EventHandler 27.9832 + * @param options {Object} 27.9833 + */ 27.9834 + function Constraint() { 27.9835 + this.options = this.options || {}; 27.9836 + this._energy = 0.0; 27.9837 + this._eventOutput = null; 27.9838 + } 27.9839 + 27.9840 + /* 27.9841 + * Setter for options. 27.9842 + * 27.9843 + * @method setOptions 27.9844 + * @param options {Objects} 27.9845 + */ 27.9846 + Constraint.prototype.setOptions = function setOptions(options) { 27.9847 + for (var key in options) this.options[key] = options[key]; 27.9848 + }; 27.9849 + 27.9850 + /** 27.9851 + * Adds an impulse to a physics body's velocity due to the constraint 27.9852 + * 27.9853 + * @method applyConstraint 27.9854 + */ 27.9855 + Constraint.prototype.applyConstraint = function applyConstraint() {}; 27.9856 + 27.9857 + /** 27.9858 + * Getter for energy 27.9859 + * 27.9860 + * @method getEnergy 27.9861 + * @return energy {Number} 27.9862 + */ 27.9863 + Constraint.prototype.getEnergy = function getEnergy() { 27.9864 + return this._energy; 27.9865 + }; 27.9866 + 27.9867 + /** 27.9868 + * Setter for energy 27.9869 + * 27.9870 + * @method setEnergy 27.9871 + * @param energy {Number} 27.9872 + */ 27.9873 + Constraint.prototype.setEnergy = function setEnergy(energy) { 27.9874 + this._energy = energy; 27.9875 + }; 27.9876 + 27.9877 + function _createEventOutput() { 27.9878 + this._eventOutput = new EventHandler(); 27.9879 + this._eventOutput.bindThis(this); 27.9880 + EventHandler.setOutputHandler(this, this._eventOutput); 27.9881 + } 27.9882 + 27.9883 + Constraint.prototype.on = function on() { 27.9884 + _createEventOutput.call(this); 27.9885 + return this.on.apply(this, arguments); 27.9886 + }; 27.9887 + Constraint.prototype.addListener = function addListener() { 27.9888 + _createEventOutput.call(this); 27.9889 + return this.addListener.apply(this, arguments); 27.9890 + }; 27.9891 + Constraint.prototype.pipe = function pipe() { 27.9892 + _createEventOutput.call(this); 27.9893 + return this.pipe.apply(this, arguments); 27.9894 + }; 27.9895 + Constraint.prototype.removeListener = function removeListener() { 27.9896 + return this.removeListener.apply(this, arguments); 27.9897 + }; 27.9898 + Constraint.prototype.unpipe = function unpipe() { 27.9899 + return this.unpipe.apply(this, arguments); 27.9900 + }; 27.9901 + 27.9902 + module.exports = Constraint; 27.9903 +}); 27.9904 + 27.9905 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.9906 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.9907 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.9908 + * 27.9909 + * Owner: david@famo.us 27.9910 + * @license MPL 2.0 27.9911 + * @copyright Famous Industries, Inc. 2014 27.9912 + */ 27.9913 + 27.9914 +define('famous/physics/constraints/Snap',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.9915 + var Constraint = require('./Constraint'); 27.9916 + var Vector = require('famous/math/Vector'); 27.9917 + 27.9918 + /** 27.9919 + * A spring constraint is like a spring force, except that it is always 27.9920 + * numerically stable (even for low periods), at the expense of introducing 27.9921 + * damping (even with dampingRatio set to 0). 27.9922 + * 27.9923 + * Use this if you need fast spring-like behavior, e.g., snapping 27.9924 + * 27.9925 + * @class Snap 27.9926 + * @constructor 27.9927 + * @extends Constraint 27.9928 + * @param {Options} [options] An object of configurable options. 27.9929 + * @param {Number} [options.period] The amount of time in milliseconds taken for one complete oscillation when there is no damping. Range : [150, Infinity] 27.9930 + * @param {Number} [options.dampingRatio] Additional damping of the spring. Range : [0, 1]. At 0 this spring will still be damped, at 1 the spring will be critically damped (the spring will never oscillate) 27.9931 + * @param {Number} [options.length] The rest length of the spring. Range: [0, Infinity]. 27.9932 + * @param {Array} [options.anchor] The location of the spring's anchor, if not another physics body. 27.9933 + * 27.9934 + */ 27.9935 + function Snap(options) { 27.9936 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.9937 + if (options) this.setOptions(options); 27.9938 + 27.9939 + //registers 27.9940 + this.pDiff = new Vector(); 27.9941 + this.vDiff = new Vector(); 27.9942 + this.impulse1 = new Vector(); 27.9943 + this.impulse2 = new Vector(); 27.9944 + 27.9945 + Constraint.call(this); 27.9946 + } 27.9947 + 27.9948 + Snap.prototype = Object.create(Constraint.prototype); 27.9949 + Snap.prototype.constructor = Snap; 27.9950 + 27.9951 + Snap.DEFAULT_OPTIONS = { 27.9952 + period : 300, 27.9953 + dampingRatio : 0.1, 27.9954 + length : 0, 27.9955 + anchor : undefined 27.9956 + }; 27.9957 + 27.9958 + /** const */ var pi = Math.PI; 27.9959 + 27.9960 + function _calcEnergy(impulse, disp, dt) { 27.9961 + return Math.abs(impulse.dot(disp)/dt); 27.9962 + } 27.9963 + 27.9964 + /** 27.9965 + * Basic options setter 27.9966 + * 27.9967 + * @method setOptions 27.9968 + * @param options {Objects} options 27.9969 + */ 27.9970 + Snap.prototype.setOptions = function setOptions(options) { 27.9971 + if (options.anchor !== undefined) { 27.9972 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 27.9973 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 27.9974 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 27.9975 + } 27.9976 + if (options.length !== undefined) this.options.length = options.length; 27.9977 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 27.9978 + if (options.period !== undefined) this.options.period = options.period; 27.9979 + }; 27.9980 + 27.9981 + /** 27.9982 + * Set the anchor position 27.9983 + * 27.9984 + * @method setOptions 27.9985 + * @param {Array} v TODO 27.9986 + */ 27.9987 + 27.9988 + Snap.prototype.setAnchor = function setAnchor(v) { 27.9989 + if (this.options.anchor !== undefined) this.options.anchor = new Vector(); 27.9990 + this.options.anchor.set(v); 27.9991 + }; 27.9992 + 27.9993 + /** 27.9994 + * Calculates energy of spring 27.9995 + * 27.9996 + * @method getEnergy 27.9997 + * @param {Object} target TODO 27.9998 + * @param {Object} source TODO 27.9999 + * @return energy {Number} 27.10000 + */ 27.10001 + Snap.prototype.getEnergy = function getEnergy(target, source) { 27.10002 + var options = this.options; 27.10003 + var restLength = options.length; 27.10004 + var anchor = options.anchor || source.position; 27.10005 + var strength = Math.pow(2 * pi / options.period, 2); 27.10006 + 27.10007 + var dist = anchor.sub(target.position).norm() - restLength; 27.10008 + 27.10009 + return 0.5 * strength * dist * dist; 27.10010 + }; 27.10011 + 27.10012 + /** 27.10013 + * Adds a spring impulse to a physics body's velocity due to the constraint 27.10014 + * 27.10015 + * @method applyConstraint 27.10016 + * @param targets {Array.Body} Array of bodies to apply the constraint to 27.10017 + * @param source {Body} The source of the constraint 27.10018 + * @param dt {Number} Delta time 27.10019 + */ 27.10020 + Snap.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.10021 + var options = this.options; 27.10022 + var pDiff = this.pDiff; 27.10023 + var vDiff = this.vDiff; 27.10024 + var impulse1 = this.impulse1; 27.10025 + var impulse2 = this.impulse2; 27.10026 + var length = options.length; 27.10027 + var anchor = options.anchor || source.position; 27.10028 + var period = options.period; 27.10029 + var dampingRatio = options.dampingRatio; 27.10030 + 27.10031 + for (var i = 0; i < targets.length ; i++) { 27.10032 + var target = targets[i]; 27.10033 + 27.10034 + var p1 = target.position; 27.10035 + var v1 = target.velocity; 27.10036 + var m1 = target.mass; 27.10037 + var w1 = target.inverseMass; 27.10038 + 27.10039 + pDiff.set(p1.sub(anchor)); 27.10040 + var dist = pDiff.norm() - length; 27.10041 + var effMass; 27.10042 + 27.10043 + if (source) { 27.10044 + var w2 = source.inverseMass; 27.10045 + var v2 = source.velocity; 27.10046 + vDiff.set(v1.sub(v2)); 27.10047 + effMass = 1/(w1 + w2); 27.10048 + } 27.10049 + else { 27.10050 + vDiff.set(v1); 27.10051 + effMass = m1; 27.10052 + } 27.10053 + 27.10054 + var gamma; 27.10055 + var beta; 27.10056 + 27.10057 + if (this.options.period === 0) { 27.10058 + gamma = 0; 27.10059 + beta = 1; 27.10060 + } 27.10061 + else { 27.10062 + var k = 4 * effMass * pi * pi / (period * period); 27.10063 + var c = 4 * effMass * pi * dampingRatio / period; 27.10064 + 27.10065 + beta = dt * k / (c + dt * k); 27.10066 + gamma = 1 / (c + dt*k); 27.10067 + } 27.10068 + 27.10069 + var antiDrift = beta/dt * dist; 27.10070 + pDiff.normalize(-antiDrift) 27.10071 + .sub(vDiff) 27.10072 + .mult(dt / (gamma + dt/effMass)) 27.10073 + .put(impulse1); 27.10074 + 27.10075 + // var n = new Vector(); 27.10076 + // n.set(pDiff.normalize()); 27.10077 + // var lambda = -(n.dot(vDiff) + antiDrift) / (gamma + dt/effMass); 27.10078 + // impulse2.set(n.mult(dt*lambda)); 27.10079 + 27.10080 + target.applyImpulse(impulse1); 27.10081 + 27.10082 + if (source) { 27.10083 + impulse1.mult(-1).put(impulse2); 27.10084 + source.applyImpulse(impulse2); 27.10085 + } 27.10086 + 27.10087 + this.setEnergy(_calcEnergy(impulse1, pDiff, dt)); 27.10088 + } 27.10089 + }; 27.10090 + 27.10091 + module.exports = Snap; 27.10092 +}); 27.10093 + 27.10094 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.10095 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.10096 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.10097 + * 27.10098 + * Owner: david@famo.us 27.10099 + * @license MPL 2.0 27.10100 + * @copyright Famous Industries, Inc. 2014 27.10101 + */ 27.10102 + 27.10103 +define('famous/transitions/SnapTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/constraints/Snap','famous/math/Vector'],function(require, exports, module) { 27.10104 + var PE = require('famous/physics/PhysicsEngine'); 27.10105 + var Particle = require('famous/physics/bodies/Particle'); 27.10106 + var Spring = require('famous/physics/constraints/Snap'); 27.10107 + var Vector = require('famous/math/Vector'); 27.10108 + 27.10109 + /** 27.10110 + * SnapTransition is a method of transitioning between two values (numbers, 27.10111 + * or arrays of numbers). It is similar to SpringTransition except 27.10112 + * the transition can be much faster and always has a damping effect. 27.10113 + * 27.10114 + * @class SnapTransition 27.10115 + * @constructor 27.10116 + * 27.10117 + * @param [state=0] {Number|Array} Initial state 27.10118 + */ 27.10119 + function SnapTransition(state) { 27.10120 + state = state || 0; 27.10121 + 27.10122 + this.endState = new Vector(state); 27.10123 + this.initState = new Vector(); 27.10124 + 27.10125 + this._dimensions = 1; 27.10126 + this._restTolerance = 1e-10; 27.10127 + this._absRestTolerance = this._restTolerance; 27.10128 + this._callback = undefined; 27.10129 + 27.10130 + this.PE = new PE(); 27.10131 + this.particle = new Particle(); 27.10132 + this.spring = new Spring({anchor : this.endState}); 27.10133 + 27.10134 + this.PE.addBody(this.particle); 27.10135 + this.PE.attach(this.spring, this.particle); 27.10136 + } 27.10137 + 27.10138 + SnapTransition.SUPPORTS_MULTIPLE = 3; 27.10139 + 27.10140 + /** 27.10141 + * @property SnapTransition.DEFAULT_OPTIONS 27.10142 + * @type Object 27.10143 + * @protected 27.10144 + * @static 27.10145 + */ 27.10146 + SnapTransition.DEFAULT_OPTIONS = { 27.10147 + 27.10148 + /** 27.10149 + * The amount of time in milliseconds taken for one complete oscillation 27.10150 + * when there is no damping 27.10151 + * Range : [0, Infinity] 27.10152 + * 27.10153 + * @attribute period 27.10154 + * @type Number 27.10155 + * @default 100 27.10156 + */ 27.10157 + period : 100, 27.10158 + 27.10159 + /** 27.10160 + * The damping of the snap. 27.10161 + * Range : [0, 1] 27.10162 + * 27.10163 + * @attribute dampingRatio 27.10164 + * @type Number 27.10165 + * @default 0.2 27.10166 + */ 27.10167 + dampingRatio : 0.2, 27.10168 + 27.10169 + /** 27.10170 + * The initial velocity of the transition. 27.10171 + * 27.10172 + * @attribute velocity 27.10173 + * @type Number|Array 27.10174 + * @default 0 27.10175 + */ 27.10176 + velocity : 0 27.10177 + }; 27.10178 + 27.10179 + function _getEnergy() { 27.10180 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 27.10181 + } 27.10182 + 27.10183 + function _setAbsoluteRestTolerance() { 27.10184 + var distance = this.endState.sub(this.initState).normSquared(); 27.10185 + this._absRestTolerance = (distance === 0) 27.10186 + ? this._restTolerance 27.10187 + : this._restTolerance * distance; 27.10188 + } 27.10189 + 27.10190 + function _setTarget(target) { 27.10191 + this.endState.set(target); 27.10192 + _setAbsoluteRestTolerance.call(this); 27.10193 + } 27.10194 + 27.10195 + function _wake() { 27.10196 + this.PE.wake(); 27.10197 + } 27.10198 + 27.10199 + function _sleep() { 27.10200 + this.PE.sleep(); 27.10201 + } 27.10202 + 27.10203 + function _setParticlePosition(p) { 27.10204 + this.particle.position.set(p); 27.10205 + } 27.10206 + 27.10207 + function _setParticleVelocity(v) { 27.10208 + this.particle.velocity.set(v); 27.10209 + } 27.10210 + 27.10211 + function _getParticlePosition() { 27.10212 + return (this._dimensions === 0) 27.10213 + ? this.particle.getPosition1D() 27.10214 + : this.particle.getPosition(); 27.10215 + } 27.10216 + 27.10217 + function _getParticleVelocity() { 27.10218 + return (this._dimensions === 0) 27.10219 + ? this.particle.getVelocity1D() 27.10220 + : this.particle.getVelocity(); 27.10221 + } 27.10222 + 27.10223 + function _setCallback(callback) { 27.10224 + this._callback = callback; 27.10225 + } 27.10226 + 27.10227 + function _setupDefinition(definition) { 27.10228 + var defaults = SnapTransition.DEFAULT_OPTIONS; 27.10229 + if (definition.period === undefined) definition.period = defaults.period; 27.10230 + if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio; 27.10231 + if (definition.velocity === undefined) definition.velocity = defaults.velocity; 27.10232 + 27.10233 + //setup spring 27.10234 + this.spring.setOptions({ 27.10235 + period : definition.period, 27.10236 + dampingRatio : definition.dampingRatio 27.10237 + }); 27.10238 + 27.10239 + //setup particle 27.10240 + _setParticleVelocity.call(this, definition.velocity); 27.10241 + } 27.10242 + 27.10243 + function _update() { 27.10244 + if (this.PE.isSleeping()) { 27.10245 + if (this._callback) { 27.10246 + var cb = this._callback; 27.10247 + this._callback = undefined; 27.10248 + cb(); 27.10249 + } 27.10250 + return; 27.10251 + } 27.10252 + 27.10253 + if (_getEnergy.call(this) < this._absRestTolerance) { 27.10254 + _setParticlePosition.call(this, this.endState); 27.10255 + _setParticleVelocity.call(this, [0,0,0]); 27.10256 + _sleep.call(this); 27.10257 + } 27.10258 + } 27.10259 + 27.10260 + /** 27.10261 + * Resets the state and velocity 27.10262 + * 27.10263 + * @method reset 27.10264 + * 27.10265 + * @param state {Number|Array} State 27.10266 + * @param [velocity] {Number|Array} Velocity 27.10267 + */ 27.10268 + SnapTransition.prototype.reset = function reset(state, velocity) { 27.10269 + this._dimensions = (state instanceof Array) 27.10270 + ? state.length 27.10271 + : 0; 27.10272 + 27.10273 + this.initState.set(state); 27.10274 + _setParticlePosition.call(this, state); 27.10275 + _setTarget.call(this, state); 27.10276 + if (velocity) _setParticleVelocity.call(this, velocity); 27.10277 + _setCallback.call(this, undefined); 27.10278 + }; 27.10279 + 27.10280 + /** 27.10281 + * Getter for velocity 27.10282 + * 27.10283 + * @method getVelocity 27.10284 + * 27.10285 + * @return velocity {Number|Array} 27.10286 + */ 27.10287 + SnapTransition.prototype.getVelocity = function getVelocity() { 27.10288 + return _getParticleVelocity.call(this); 27.10289 + }; 27.10290 + 27.10291 + /** 27.10292 + * Setter for velocity 27.10293 + * 27.10294 + * @method setVelocity 27.10295 + * 27.10296 + * @return velocity {Number|Array} 27.10297 + */ 27.10298 + SnapTransition.prototype.setVelocity = function setVelocity(velocity) { 27.10299 + this.call(this, _setParticleVelocity(velocity)); 27.10300 + }; 27.10301 + 27.10302 + /** 27.10303 + * Detects whether a transition is in progress 27.10304 + * 27.10305 + * @method isActive 27.10306 + * 27.10307 + * @return {Boolean} 27.10308 + */ 27.10309 + SnapTransition.prototype.isActive = function isActive() { 27.10310 + return !this.PE.isSleeping(); 27.10311 + }; 27.10312 + 27.10313 + /** 27.10314 + * Halt the transition 27.10315 + * 27.10316 + * @method halt 27.10317 + */ 27.10318 + SnapTransition.prototype.halt = function halt() { 27.10319 + this.set(this.get()); 27.10320 + }; 27.10321 + 27.10322 + /** 27.10323 + * Get the current position of the transition 27.10324 +s * 27.10325 + * @method get 27.10326 + * 27.10327 + * @return state {Number|Array} 27.10328 + */ 27.10329 + SnapTransition.prototype.get = function get() { 27.10330 + _update.call(this); 27.10331 + return _getParticlePosition.call(this); 27.10332 + }; 27.10333 + 27.10334 + /** 27.10335 + * Set the end position and transition, with optional callback on completion. 27.10336 + * 27.10337 + * @method set 27.10338 + * 27.10339 + * @param state {Number|Array} Final state 27.10340 + * @param [definition] {Object} Transition definition 27.10341 + * @param [callback] {Function} Callback 27.10342 + */ 27.10343 + SnapTransition.prototype.set = function set(state, definition, callback) { 27.10344 + if (!definition) { 27.10345 + this.reset(state); 27.10346 + if (callback) callback(); 27.10347 + return; 27.10348 + } 27.10349 + 27.10350 + this._dimensions = (state instanceof Array) 27.10351 + ? state.length 27.10352 + : 0; 27.10353 + 27.10354 + _wake.call(this); 27.10355 + _setupDefinition.call(this, definition); 27.10356 + _setTarget.call(this, state); 27.10357 + _setCallback.call(this, callback); 27.10358 + }; 27.10359 + 27.10360 + module.exports = SnapTransition; 27.10361 +}); 27.10362 + 27.10363 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.10364 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.10365 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.10366 + * 27.10367 + * Owner: david@famo.us 27.10368 + * @license MPL 2.0 27.10369 + * @copyright Famous Industries, Inc. 2014 27.10370 + */ 27.10371 + 27.10372 +define('famous/physics/forces/Force',['require','exports','module','famous/math/Vector','famous/core/EventHandler'],function(require, exports, module) { 27.10373 + var Vector = require('famous/math/Vector'); 27.10374 + var EventHandler = require('famous/core/EventHandler'); 27.10375 + 27.10376 + /** 27.10377 + * Force base class. 27.10378 + * 27.10379 + * @class Force 27.10380 + * @uses EventHandler 27.10381 + * @constructor 27.10382 + */ 27.10383 + function Force(force) { 27.10384 + this.force = new Vector(force); 27.10385 + this._energy = 0.0; 27.10386 + this._eventOutput = null; 27.10387 + } 27.10388 + 27.10389 + /** 27.10390 + * Basic setter for options 27.10391 + * 27.10392 + * @method setOptions 27.10393 + * @param options {Objects} 27.10394 + */ 27.10395 + Force.prototype.setOptions = function setOptions(options) { 27.10396 + for (var key in options) this.options[key] = options[key]; 27.10397 + }; 27.10398 + 27.10399 + /** 27.10400 + * Adds a force to a physics body's force accumulator. 27.10401 + * 27.10402 + * @method applyForce 27.10403 + * @param body {Body} 27.10404 + */ 27.10405 + Force.prototype.applyForce = function applyForce(body) { 27.10406 + body.applyForce(this.force); 27.10407 + }; 27.10408 + 27.10409 + /** 27.10410 + * Getter for a force's potential energy. 27.10411 + * 27.10412 + * @method getEnergy 27.10413 + * @return energy {Number} 27.10414 + */ 27.10415 + Force.prototype.getEnergy = function getEnergy() { 27.10416 + return this._energy; 27.10417 + }; 27.10418 + 27.10419 + /* 27.10420 + * Setter for a force's potential energy. 27.10421 + * 27.10422 + * @method setEnergy 27.10423 + * @param energy {Number} 27.10424 + */ 27.10425 + Force.prototype.setEnergy = function setEnergy(energy) { 27.10426 + this._energy = energy; 27.10427 + }; 27.10428 + 27.10429 + function _createEventOutput() { 27.10430 + this._eventOutput = new EventHandler(); 27.10431 + this._eventOutput.bindThis(this); 27.10432 + EventHandler.setOutputHandler(this, this._eventOutput); 27.10433 + } 27.10434 + 27.10435 + Force.prototype.on = function on() { 27.10436 + _createEventOutput.call(this); 27.10437 + return this.on.apply(this, arguments); 27.10438 + }; 27.10439 + Force.prototype.addListener = function addListener() { 27.10440 + _createEventOutput.call(this); 27.10441 + return this.addListener.apply(this, arguments); 27.10442 + }; 27.10443 + Force.prototype.pipe = function pipe() { 27.10444 + _createEventOutput.call(this); 27.10445 + return this.pipe.apply(this, arguments); 27.10446 + }; 27.10447 + Force.prototype.removeListener = function removeListener() { 27.10448 + return this.removeListener.apply(this, arguments); 27.10449 + }; 27.10450 + Force.prototype.unpipe = function unpipe() { 27.10451 + return this.unpipe.apply(this, arguments); 27.10452 + }; 27.10453 + 27.10454 + module.exports = Force; 27.10455 +}); 27.10456 + 27.10457 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.10458 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.10459 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.10460 + * 27.10461 + * Owner: david@famo.us 27.10462 + * @license MPL 2.0 27.10463 + * @copyright Famous Industries, Inc. 2014 27.10464 + */ 27.10465 + 27.10466 +define('famous/physics/forces/Spring',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 27.10467 + var Force = require('./Force'); 27.10468 + var Vector = require('famous/math/Vector'); 27.10469 + 27.10470 + /** 27.10471 + * A force that moves a physics body to a location with a spring motion. 27.10472 + * The body can be moved to another physics body, or an anchor point. 27.10473 + * 27.10474 + * @class Spring 27.10475 + * @constructor 27.10476 + * @extends Force 27.10477 + * @param {Object} options options to set on drag 27.10478 + */ 27.10479 + function Spring(options) { 27.10480 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.10481 + if (options) this.setOptions(options); 27.10482 + 27.10483 + //registers 27.10484 + this.disp = new Vector(0,0,0); 27.10485 + 27.10486 + _init.call(this); 27.10487 + Force.call(this); 27.10488 + } 27.10489 + 27.10490 + Spring.prototype = Object.create(Force.prototype); 27.10491 + Spring.prototype.constructor = Spring; 27.10492 + 27.10493 + /** @const */ var pi = Math.PI; 27.10494 + 27.10495 + /** 27.10496 + * @property Spring.FORCE_FUNCTIONS 27.10497 + * @type Object 27.10498 + * @protected 27.10499 + * @static 27.10500 + */ 27.10501 + Spring.FORCE_FUNCTIONS = { 27.10502 + 27.10503 + /** 27.10504 + * A FENE (Finitely Extensible Nonlinear Elastic) spring force 27.10505 + * see: http://en.wikipedia.org/wiki/FENE 27.10506 + * @attribute FENE 27.10507 + * @type Function 27.10508 + * @param {Number} dist current distance target is from source body 27.10509 + * @param {Number} rMax maximum range of influence 27.10510 + * @return {Number} unscaled force 27.10511 + */ 27.10512 + FENE : function(dist, rMax) { 27.10513 + var rMaxSmall = rMax * .99; 27.10514 + var r = Math.max(Math.min(dist, rMaxSmall), -rMaxSmall); 27.10515 + return r / (1 - r * r/(rMax * rMax)); 27.10516 + }, 27.10517 + 27.10518 + /** 27.10519 + * A Hookean spring force, linear in the displacement 27.10520 + * see: http://en.wikipedia.org/wiki/FENE 27.10521 + * @attribute FENE 27.10522 + * @type Function 27.10523 + * @param {Number} dist current distance target is from source body 27.10524 + * @return {Number} unscaled force 27.10525 + */ 27.10526 + HOOK : function(dist) { 27.10527 + return dist; 27.10528 + } 27.10529 + }; 27.10530 + 27.10531 + /** 27.10532 + * @property Spring.DEFAULT_OPTIONS 27.10533 + * @type Object 27.10534 + * @protected 27.10535 + * @static 27.10536 + */ 27.10537 + Spring.DEFAULT_OPTIONS = { 27.10538 + 27.10539 + /** 27.10540 + * The amount of time in milliseconds taken for one complete oscillation 27.10541 + * when there is no damping 27.10542 + * Range : [150, Infinity] 27.10543 + * @attribute period 27.10544 + * @type Number 27.10545 + * @default 300 27.10546 + */ 27.10547 + period : 300, 27.10548 + 27.10549 + /** 27.10550 + * The damping of the spring. 27.10551 + * Range : [0, 1] 27.10552 + * 0 = no damping, and the spring will oscillate forever 27.10553 + * 1 = critically damped (the spring will never oscillate) 27.10554 + * @attribute dampingRatio 27.10555 + * @type Number 27.10556 + * @default 0.1 27.10557 + */ 27.10558 + dampingRatio : 0.1, 27.10559 + 27.10560 + /** 27.10561 + * The rest length of the spring 27.10562 + * Range : [0, Infinity] 27.10563 + * @attribute length 27.10564 + * @type Number 27.10565 + * @default 0 27.10566 + */ 27.10567 + length : 0, 27.10568 + 27.10569 + /** 27.10570 + * The maximum length of the spring (for a FENE spring) 27.10571 + * Range : [0, Infinity] 27.10572 + * @attribute length 27.10573 + * @type Number 27.10574 + * @default Infinity 27.10575 + */ 27.10576 + maxLength : Infinity, 27.10577 + 27.10578 + /** 27.10579 + * The location of the spring's anchor, if not another physics body 27.10580 + * 27.10581 + * @attribute anchor 27.10582 + * @type Array 27.10583 + * @optional 27.10584 + */ 27.10585 + anchor : undefined, 27.10586 + 27.10587 + /** 27.10588 + * The type of spring force 27.10589 + * @attribute forceFunction 27.10590 + * @type Function 27.10591 + */ 27.10592 + forceFunction : Spring.FORCE_FUNCTIONS.HOOK 27.10593 + }; 27.10594 + 27.10595 + function _setForceFunction(fn) { 27.10596 + this.forceFunction = fn; 27.10597 + } 27.10598 + 27.10599 + function _calcStiffness() { 27.10600 + var options = this.options; 27.10601 + options.stiffness = Math.pow(2 * pi / options.period, 2); 27.10602 + } 27.10603 + 27.10604 + function _calcDamping() { 27.10605 + var options = this.options; 27.10606 + options.damping = 4 * pi * options.dampingRatio / options.period; 27.10607 + } 27.10608 + 27.10609 + function _calcEnergy(strength, dist) { 27.10610 + return 0.5 * strength * dist * dist; 27.10611 + } 27.10612 + 27.10613 + function _init() { 27.10614 + _setForceFunction.call(this, this.options.forceFunction); 27.10615 + _calcStiffness.call(this); 27.10616 + _calcDamping.call(this); 27.10617 + } 27.10618 + 27.10619 + /** 27.10620 + * Basic options setter 27.10621 + * 27.10622 + * @method setOptions 27.10623 + * @param options {Objects} 27.10624 + */ 27.10625 + Spring.prototype.setOptions = function setOptions(options) { 27.10626 + if (options.anchor !== undefined) { 27.10627 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 27.10628 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 27.10629 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 27.10630 + } 27.10631 + if (options.period !== undefined) this.options.period = options.period; 27.10632 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 27.10633 + if (options.length !== undefined) this.options.length = options.length; 27.10634 + if (options.forceFunction !== undefined) this.options.forceFunction = options.forceFunction; 27.10635 + if (options.maxLength !== undefined) this.options.maxLength = options.maxLength; 27.10636 + 27.10637 + _init.call(this); 27.10638 + }; 27.10639 + 27.10640 + /** 27.10641 + * Adds a spring force to a physics body's force accumulator. 27.10642 + * 27.10643 + * @method applyForce 27.10644 + * @param targets {Array.Body} Array of bodies to apply force to. 27.10645 + */ 27.10646 + Spring.prototype.applyForce = function applyForce(targets, source) { 27.10647 + var force = this.force; 27.10648 + var disp = this.disp; 27.10649 + var options = this.options; 27.10650 + 27.10651 + var stiffness = options.stiffness; 27.10652 + var damping = options.damping; 27.10653 + var restLength = options.length; 27.10654 + var lMax = options.maxLength; 27.10655 + var anchor = options.anchor || source.position; 27.10656 + 27.10657 + for (var i = 0; i < targets.length; i++) { 27.10658 + var target = targets[i]; 27.10659 + var p2 = target.position; 27.10660 + var v2 = target.velocity; 27.10661 + 27.10662 + anchor.sub(p2).put(disp); 27.10663 + var dist = disp.norm() - restLength; 27.10664 + 27.10665 + if (dist === 0) return; 27.10666 + 27.10667 + //if dampingRatio specified, then override strength and damping 27.10668 + var m = target.mass; 27.10669 + stiffness *= m; 27.10670 + damping *= m; 27.10671 + 27.10672 + disp.normalize(stiffness * this.forceFunction(dist, lMax)) 27.10673 + .put(force); 27.10674 + 27.10675 + if (damping) 27.10676 + if (source) force.add(v2.sub(source.velocity).mult(-damping)).put(force); 27.10677 + else force.add(v2.mult(-damping)).put(force); 27.10678 + 27.10679 + target.applyForce(force); 27.10680 + if (source) source.applyForce(force.mult(-1)); 27.10681 + 27.10682 + this.setEnergy(_calcEnergy(stiffness, dist)); 27.10683 + } 27.10684 + }; 27.10685 + 27.10686 + /** 27.10687 + * Calculates the potential energy of the spring. 27.10688 + * 27.10689 + * @method getEnergy 27.10690 + * @param target {Body} The physics body attached to the spring 27.10691 + * @return energy {Number} 27.10692 + */ 27.10693 + Spring.prototype.getEnergy = function getEnergy(target) { 27.10694 + var options = this.options; 27.10695 + var restLength = options.length; 27.10696 + var anchor = options.anchor; 27.10697 + var strength = options.stiffness; 27.10698 + 27.10699 + var dist = anchor.sub(target.position).norm() - restLength; 27.10700 + return 0.5 * strength * dist * dist; 27.10701 + }; 27.10702 + 27.10703 + /** 27.10704 + * Sets the anchor to a new position 27.10705 + * 27.10706 + * @method setAnchor 27.10707 + * @param anchor {Array} New anchor of the spring 27.10708 + */ 27.10709 + Spring.prototype.setAnchor = function setAnchor(anchor) { 27.10710 + if (!this.options.anchor) this.options.anchor = new Vector(); 27.10711 + this.options.anchor.set(anchor); 27.10712 + }; 27.10713 + 27.10714 + module.exports = Spring; 27.10715 +}); 27.10716 + 27.10717 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.10718 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.10719 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.10720 + * 27.10721 + * Owner: david@famo.us 27.10722 + * @license MPL 2.0 27.10723 + * @copyright Famous Industries, Inc. 2014 27.10724 + */ 27.10725 + 27.10726 +/*global console*/ 27.10727 + 27.10728 +define('famous/transitions/SpringTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/math/Vector'],function(require, exports, module) { 27.10729 + var PE = require('famous/physics/PhysicsEngine'); 27.10730 + var Particle = require('famous/physics/bodies/Particle'); 27.10731 + var Spring = require('famous/physics/forces/Spring'); 27.10732 + var Vector = require('famous/math/Vector'); 27.10733 + 27.10734 + /** 27.10735 + * SpringTransition is a method of transitioning between two values (numbers, 27.10736 + * or arrays of numbers) with a bounce. The transition will overshoot the target 27.10737 + * state depending on the parameters of the transition. 27.10738 + * 27.10739 + * @class SpringTransition 27.10740 + * @constructor 27.10741 + * 27.10742 + * @param {Number|Array} [state=0] Initial state 27.10743 + */ 27.10744 + function SpringTransition(state) { 27.10745 + state = state || 0; 27.10746 + this.endState = new Vector(state); 27.10747 + this.initState = new Vector(); 27.10748 + 27.10749 + this._dimensions = undefined; 27.10750 + this._restTolerance = 1e-10; 27.10751 + this._absRestTolerance = this._restTolerance; 27.10752 + this._callback = undefined; 27.10753 + 27.10754 + this.PE = new PE(); 27.10755 + this.spring = new Spring({anchor : this.endState}); 27.10756 + this.particle = new Particle(); 27.10757 + 27.10758 + this.PE.addBody(this.particle); 27.10759 + this.PE.attach(this.spring, this.particle); 27.10760 + } 27.10761 + 27.10762 + SpringTransition.SUPPORTS_MULTIPLE = 3; 27.10763 + 27.10764 + /** 27.10765 + * @property SpringTransition.DEFAULT_OPTIONS 27.10766 + * @type Object 27.10767 + * @protected 27.10768 + * @static 27.10769 + */ 27.10770 + SpringTransition.DEFAULT_OPTIONS = { 27.10771 + 27.10772 + /** 27.10773 + * The amount of time in milliseconds taken for one complete oscillation 27.10774 + * when there is no damping 27.10775 + * Range : [0, Infinity] 27.10776 + * 27.10777 + * @attribute period 27.10778 + * @type Number 27.10779 + * @default 300 27.10780 + */ 27.10781 + period : 300, 27.10782 + 27.10783 + /** 27.10784 + * The damping of the snap. 27.10785 + * Range : [0, 1] 27.10786 + * 0 = no damping, and the spring will oscillate forever 27.10787 + * 1 = critically damped (the spring will never oscillate) 27.10788 + * 27.10789 + * @attribute dampingRatio 27.10790 + * @type Number 27.10791 + * @default 0.5 27.10792 + */ 27.10793 + dampingRatio : 0.5, 27.10794 + 27.10795 + /** 27.10796 + * The initial velocity of the transition. 27.10797 + * 27.10798 + * @attribute velocity 27.10799 + * @type Number|Array 27.10800 + * @default 0 27.10801 + */ 27.10802 + velocity : 0 27.10803 + }; 27.10804 + 27.10805 + function _getEnergy() { 27.10806 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 27.10807 + } 27.10808 + 27.10809 + function _setParticlePosition(p) { 27.10810 + this.particle.setPosition(p); 27.10811 + } 27.10812 + 27.10813 + function _setParticleVelocity(v) { 27.10814 + this.particle.setVelocity(v); 27.10815 + } 27.10816 + 27.10817 + function _getParticlePosition() { 27.10818 + return (this._dimensions === 0) 27.10819 + ? this.particle.getPosition1D() 27.10820 + : this.particle.getPosition(); 27.10821 + } 27.10822 + 27.10823 + function _getParticleVelocity() { 27.10824 + return (this._dimensions === 0) 27.10825 + ? this.particle.getVelocity1D() 27.10826 + : this.particle.getVelocity(); 27.10827 + } 27.10828 + 27.10829 + function _setCallback(callback) { 27.10830 + this._callback = callback; 27.10831 + } 27.10832 + 27.10833 + function _wake() { 27.10834 + this.PE.wake(); 27.10835 + } 27.10836 + 27.10837 + function _sleep() { 27.10838 + this.PE.sleep(); 27.10839 + } 27.10840 + 27.10841 + function _update() { 27.10842 + if (this.PE.isSleeping()) { 27.10843 + if (this._callback) { 27.10844 + var cb = this._callback; 27.10845 + this._callback = undefined; 27.10846 + cb(); 27.10847 + } 27.10848 + return; 27.10849 + } 27.10850 + 27.10851 + if (_getEnergy.call(this) < this._absRestTolerance) { 27.10852 + _setParticlePosition.call(this, this.endState); 27.10853 + _setParticleVelocity.call(this, [0,0,0]); 27.10854 + _sleep.call(this); 27.10855 + } 27.10856 + } 27.10857 + 27.10858 + function _setupDefinition(definition) { 27.10859 + // TODO fix no-console error 27.10860 + /* eslint no-console: 0 */ 27.10861 + var defaults = SpringTransition.DEFAULT_OPTIONS; 27.10862 + if (definition.period === undefined) definition.period = defaults.period; 27.10863 + if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio; 27.10864 + if (definition.velocity === undefined) definition.velocity = defaults.velocity; 27.10865 + 27.10866 + if (definition.period < 150) { 27.10867 + definition.period = 150; 27.10868 + console.warn('The period of a SpringTransition is capped at 150 ms. Use a SnapTransition for faster transitions'); 27.10869 + } 27.10870 + 27.10871 + //setup spring 27.10872 + this.spring.setOptions({ 27.10873 + period : definition.period, 27.10874 + dampingRatio : definition.dampingRatio 27.10875 + }); 27.10876 + 27.10877 + //setup particle 27.10878 + _setParticleVelocity.call(this, definition.velocity); 27.10879 + } 27.10880 + 27.10881 + function _setAbsoluteRestTolerance() { 27.10882 + var distance = this.endState.sub(this.initState).normSquared(); 27.10883 + this._absRestTolerance = (distance === 0) 27.10884 + ? this._restTolerance 27.10885 + : this._restTolerance * distance; 27.10886 + } 27.10887 + 27.10888 + function _setTarget(target) { 27.10889 + this.endState.set(target); 27.10890 + _setAbsoluteRestTolerance.call(this); 27.10891 + } 27.10892 + 27.10893 + /** 27.10894 + * Resets the position and velocity 27.10895 + * 27.10896 + * @method reset 27.10897 + * 27.10898 + * @param {Number|Array.Number} pos positional state 27.10899 + * @param {Number|Array} vel velocity 27.10900 + */ 27.10901 + SpringTransition.prototype.reset = function reset(pos, vel) { 27.10902 + this._dimensions = (pos instanceof Array) 27.10903 + ? pos.length 27.10904 + : 0; 27.10905 + 27.10906 + this.initState.set(pos); 27.10907 + _setParticlePosition.call(this, pos); 27.10908 + _setTarget.call(this, pos); 27.10909 + if (vel) _setParticleVelocity.call(this, vel); 27.10910 + _setCallback.call(this, undefined); 27.10911 + }; 27.10912 + 27.10913 + /** 27.10914 + * Getter for velocity 27.10915 + * 27.10916 + * @method getVelocity 27.10917 + * 27.10918 + * @return {Number|Array} velocity 27.10919 + */ 27.10920 + SpringTransition.prototype.getVelocity = function getVelocity() { 27.10921 + return _getParticleVelocity.call(this); 27.10922 + }; 27.10923 + 27.10924 + /** 27.10925 + * Setter for velocity 27.10926 + * 27.10927 + * @method setVelocity 27.10928 + * 27.10929 + * @return {Number|Array} velocity 27.10930 + */ 27.10931 + SpringTransition.prototype.setVelocity = function setVelocity(v) { 27.10932 + this.call(this, _setParticleVelocity(v)); 27.10933 + }; 27.10934 + 27.10935 + /** 27.10936 + * Detects whether a transition is in progress 27.10937 + * 27.10938 + * @method isActive 27.10939 + * 27.10940 + * @return {Boolean} 27.10941 + */ 27.10942 + SpringTransition.prototype.isActive = function isActive() { 27.10943 + return !this.PE.isSleeping(); 27.10944 + }; 27.10945 + 27.10946 + /** 27.10947 + * Halt the transition 27.10948 + * 27.10949 + * @method halt 27.10950 + */ 27.10951 + SpringTransition.prototype.halt = function halt() { 27.10952 + this.set(this.get()); 27.10953 + }; 27.10954 + 27.10955 + /** 27.10956 + * Get the current position of the transition 27.10957 + * 27.10958 + * @method get 27.10959 + * 27.10960 + * @return {Number|Array} state 27.10961 + */ 27.10962 + SpringTransition.prototype.get = function get() { 27.10963 + _update.call(this); 27.10964 + return _getParticlePosition.call(this); 27.10965 + }; 27.10966 + 27.10967 + /** 27.10968 + * Set the end position and transition, with optional callback on completion. 27.10969 + * 27.10970 + * @method set 27.10971 + * 27.10972 + * @param {Number|Array} endState Final state 27.10973 + * @param {Object} definition Transition definition 27.10974 + * @param {Function} callback Callback 27.10975 + */ 27.10976 + SpringTransition.prototype.set = function set(endState, definition, callback) { 27.10977 + if (!definition) { 27.10978 + this.reset(endState); 27.10979 + if (callback) callback(); 27.10980 + return; 27.10981 + } 27.10982 + 27.10983 + this._dimensions = (endState instanceof Array) 27.10984 + ? endState.length 27.10985 + : 0; 27.10986 + 27.10987 + _wake.call(this); 27.10988 + _setupDefinition.call(this, definition); 27.10989 + _setTarget.call(this, endState); 27.10990 + _setCallback.call(this, callback); 27.10991 + }; 27.10992 + 27.10993 + module.exports = SpringTransition; 27.10994 +}); 27.10995 + 27.10996 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.10997 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.10998 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.10999 + * 27.11000 + * Owner: david@famo.us 27.11001 + * @license MPL 2.0 27.11002 + * @copyright Famous Industries, Inc. 2014 27.11003 + */ 27.11004 + 27.11005 +define('famous/physics/constraints/Wall',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.11006 + var Constraint = require('./Constraint'); 27.11007 + var Vector = require('famous/math/Vector'); 27.11008 + 27.11009 + /** 27.11010 + * A wall describes an infinite two-dimensional plane that physics bodies 27.11011 + * can collide with. To define a wall, you must give it a distance (from 27.11012 + * the center of the physics engine's origin, and a normal defining the plane 27.11013 + * of the wall. 27.11014 + * 27.11015 + * (wall) 27.11016 + * | 27.11017 + * | (normal) (origin) 27.11018 + * | ---> * 27.11019 + * | 27.11020 + * | (distance) 27.11021 + * ................... 27.11022 + * (100px) 27.11023 + * 27.11024 + * e.g., Wall({normal : [1,0,0], distance : 100}) 27.11025 + * would be a wall 100 pixels to the left, whose normal points right 27.11026 + * 27.11027 + * @class Wall 27.11028 + * @constructor 27.11029 + * @extends Constraint 27.11030 + * @param {Options} [options] An object of configurable options. 27.11031 + * @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic). Range : [0, 1] 27.11032 + * @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 27.11033 + * @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers. 27.11034 + * @param {Array} [options.normal] The normal direction to the wall. 27.11035 + * @param {Number} [options.distance] The distance from the origin that the wall is placed. 27.11036 + * @param {onContact} [options.onContact] How to handle collision against the wall. 27.11037 + * 27.11038 + */ 27.11039 + function Wall(options) { 27.11040 + this.options = Object.create(Wall.DEFAULT_OPTIONS); 27.11041 + if (options) this.setOptions(options); 27.11042 + 27.11043 + //registers 27.11044 + this.diff = new Vector(); 27.11045 + this.impulse = new Vector(); 27.11046 + 27.11047 + Constraint.call(this); 27.11048 + } 27.11049 + 27.11050 + Wall.prototype = Object.create(Constraint.prototype); 27.11051 + Wall.prototype.constructor = Wall; 27.11052 + 27.11053 + /** 27.11054 + * @property Wall.ON_CONTACT 27.11055 + * @type Object 27.11056 + * @protected 27.11057 + * @static 27.11058 + */ 27.11059 + Wall.ON_CONTACT = { 27.11060 + 27.11061 + /** 27.11062 + * Physical bodies bounce off the wall 27.11063 + * @attribute REFLECT 27.11064 + */ 27.11065 + REFLECT : 0, 27.11066 + 27.11067 + /** 27.11068 + * Physical bodies are unaffected. Usecase is to fire events on contact. 27.11069 + * @attribute SILENT 27.11070 + */ 27.11071 + SILENT : 1 27.11072 + }; 27.11073 + 27.11074 + Wall.DEFAULT_OPTIONS = { 27.11075 + restitution : 0.5, 27.11076 + drift : 0.5, 27.11077 + slop : 0, 27.11078 + normal : [1, 0, 0], 27.11079 + distance : 0, 27.11080 + onContact : Wall.ON_CONTACT.REFLECT 27.11081 + }; 27.11082 + 27.11083 + /* 27.11084 + * Setter for options. 27.11085 + * 27.11086 + * @method setOptions 27.11087 + * @param options {Objects} 27.11088 + */ 27.11089 + Wall.prototype.setOptions = function setOptions(options) { 27.11090 + if (options.normal !== undefined) { 27.11091 + if (options.normal instanceof Vector) this.options.normal = options.normal.clone(); 27.11092 + if (options.normal instanceof Array) this.options.normal = new Vector(options.normal); 27.11093 + } 27.11094 + if (options.restitution !== undefined) this.options.restitution = options.restitution; 27.11095 + if (options.drift !== undefined) this.options.drift = options.drift; 27.11096 + if (options.slop !== undefined) this.options.slop = options.slop; 27.11097 + if (options.distance !== undefined) this.options.distance = options.distance; 27.11098 + if (options.onContact !== undefined) this.options.onContact = options.onContact; 27.11099 + }; 27.11100 + 27.11101 + function _getNormalVelocity(n, v) { 27.11102 + return v.dot(n); 27.11103 + } 27.11104 + 27.11105 + function _getDistanceFromOrigin(p) { 27.11106 + var n = this.options.normal; 27.11107 + var d = this.options.distance; 27.11108 + return p.dot(n) + d; 27.11109 + } 27.11110 + 27.11111 + function _onEnter(particle, overlap, dt) { 27.11112 + var p = particle.position; 27.11113 + var v = particle.velocity; 27.11114 + var m = particle.mass; 27.11115 + var n = this.options.normal; 27.11116 + var action = this.options.onContact; 27.11117 + var restitution = this.options.restitution; 27.11118 + var impulse = this.impulse; 27.11119 + 27.11120 + var drift = this.options.drift; 27.11121 + var slop = -this.options.slop; 27.11122 + var gamma = 0; 27.11123 + 27.11124 + if (this._eventOutput) { 27.11125 + var data = {particle : particle, wall : this, overlap : overlap, normal : n}; 27.11126 + this._eventOutput.emit('preCollision', data); 27.11127 + this._eventOutput.emit('collision', data); 27.11128 + } 27.11129 + 27.11130 + switch (action) { 27.11131 + case Wall.ON_CONTACT.REFLECT: 27.11132 + var lambda = (overlap < slop) 27.11133 + ? -((1 + restitution) * n.dot(v) + drift / dt * (overlap - slop)) / (m * dt + gamma) 27.11134 + : -((1 + restitution) * n.dot(v)) / (m * dt + gamma); 27.11135 + 27.11136 + impulse.set(n.mult(dt * lambda)); 27.11137 + particle.applyImpulse(impulse); 27.11138 + particle.setPosition(p.add(n.mult(-overlap))); 27.11139 + break; 27.11140 + } 27.11141 + 27.11142 + if (this._eventOutput) this._eventOutput.emit('postCollision', data); 27.11143 + } 27.11144 + 27.11145 + function _onExit(particle, overlap, dt) { 27.11146 + var action = this.options.onContact; 27.11147 + var p = particle.position; 27.11148 + var n = this.options.normal; 27.11149 + 27.11150 + if (action === Wall.ON_CONTACT.REFLECT) { 27.11151 + particle.setPosition(p.add(n.mult(-overlap))); 27.11152 + } 27.11153 + } 27.11154 + 27.11155 + /** 27.11156 + * Adds an impulse to a physics body's velocity due to the wall constraint 27.11157 + * 27.11158 + * @method applyConstraint 27.11159 + * @param targets {Array.Body} Array of bodies to apply the constraint to 27.11160 + * @param source {Body} The source of the constraint 27.11161 + * @param dt {Number} Delta time 27.11162 + */ 27.11163 + Wall.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.11164 + var n = this.options.normal; 27.11165 + 27.11166 + for (var i = 0; i < targets.length; i++) { 27.11167 + var particle = targets[i]; 27.11168 + var p = particle.position; 27.11169 + var v = particle.velocity; 27.11170 + var r = particle.radius || 0; 27.11171 + 27.11172 + var overlap = _getDistanceFromOrigin.call(this, p.add(n.mult(-r))); 27.11173 + var nv = _getNormalVelocity.call(this, n, v); 27.11174 + 27.11175 + if (overlap <= 0) { 27.11176 + if (nv < 0) _onEnter.call(this, particle, overlap, dt); 27.11177 + else _onExit.call(this, particle, overlap, dt); 27.11178 + } 27.11179 + } 27.11180 + }; 27.11181 + 27.11182 + module.exports = Wall; 27.11183 +}); 27.11184 + 27.11185 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11186 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11187 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11188 + * 27.11189 + * Owner: david@famo.us 27.11190 + * @license MPL 2.0 27.11191 + * @copyright Famous Industries, Inc. 2014 27.11192 + */ 27.11193 + 27.11194 +define('famous/transitions/WallTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/physics/constraints/Wall','famous/math/Vector'],function(require, exports, module) { 27.11195 + var PE = require('famous/physics/PhysicsEngine'); 27.11196 + var Particle = require('famous/physics/bodies/Particle'); 27.11197 + var Spring = require('famous/physics/forces/Spring'); 27.11198 + var Wall = require('famous/physics/constraints/Wall'); 27.11199 + var Vector = require('famous/math/Vector'); 27.11200 + 27.11201 + /** 27.11202 + * WallTransition is a method of transitioning between two values (numbers, 27.11203 + * or arrays of numbers) with a bounce. Unlike a SpringTransition 27.11204 + * The transition will not overshoot the target, but bounce back against it. 27.11205 + * The behavior of the bounce is specified by the transition options. 27.11206 + * 27.11207 + * @class WallTransition 27.11208 + * @constructor 27.11209 + * 27.11210 + * @param {Number|Array} [state=0] Initial state 27.11211 + */ 27.11212 + function WallTransition(state) { 27.11213 + state = state || 0; 27.11214 + 27.11215 + this.endState = new Vector(state); 27.11216 + this.initState = new Vector(); 27.11217 + 27.11218 + this.spring = new Spring({anchor : this.endState}); 27.11219 + this.wall = new Wall(); 27.11220 + 27.11221 + this._restTolerance = 1e-10; 27.11222 + this._dimensions = 1; 27.11223 + this._absRestTolerance = this._restTolerance; 27.11224 + this._callback = undefined; 27.11225 + 27.11226 + this.PE = new PE(); 27.11227 + this.particle = new Particle(); 27.11228 + 27.11229 + this.PE.addBody(this.particle); 27.11230 + this.PE.attach([this.wall, this.spring], this.particle); 27.11231 + } 27.11232 + 27.11233 + WallTransition.SUPPORTS_MULTIPLE = 3; 27.11234 + 27.11235 + /** 27.11236 + * @property WallTransition.DEFAULT_OPTIONS 27.11237 + * @type Object 27.11238 + * @protected 27.11239 + * @static 27.11240 + */ 27.11241 + WallTransition.DEFAULT_OPTIONS = { 27.11242 + 27.11243 + /** 27.11244 + * The amount of time in milliseconds taken for one complete oscillation 27.11245 + * when there is no damping 27.11246 + * Range : [0, Infinity] 27.11247 + * 27.11248 + * @attribute period 27.11249 + * @type Number 27.11250 + * @default 300 27.11251 + */ 27.11252 + period : 300, 27.11253 + 27.11254 + /** 27.11255 + * The damping of the snap. 27.11256 + * Range : [0, 1] 27.11257 + * 0 = no damping, and the spring will oscillate forever 27.11258 + * 1 = critically damped (the spring will never oscillate) 27.11259 + * 27.11260 + * @attribute dampingRatio 27.11261 + * @type Number 27.11262 + * @default 0.5 27.11263 + */ 27.11264 + dampingRatio : 0.5, 27.11265 + 27.11266 + /** 27.11267 + * The initial velocity of the transition. 27.11268 + * 27.11269 + * @attribute velocity 27.11270 + * @type Number|Array 27.11271 + * @default 0 27.11272 + */ 27.11273 + velocity : 0, 27.11274 + 27.11275 + /** 27.11276 + * The percentage of momentum transferred to the wall 27.11277 + * 27.11278 + * @attribute restitution 27.11279 + * @type Number 27.11280 + * @default 0.5 27.11281 + */ 27.11282 + resitution : 0.5 27.11283 + }; 27.11284 + 27.11285 + function _getEnergy() { 27.11286 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 27.11287 + } 27.11288 + 27.11289 + function _setAbsoluteRestTolerance() { 27.11290 + var distance = this.endState.sub(this.initState).normSquared(); 27.11291 + this._absRestTolerance = (distance === 0) 27.11292 + ? this._restTolerance 27.11293 + : this._restTolerance * distance; 27.11294 + } 27.11295 + 27.11296 + function _wake() { 27.11297 + this.PE.wake(); 27.11298 + } 27.11299 + 27.11300 + function _sleep() { 27.11301 + this.PE.sleep(); 27.11302 + } 27.11303 + 27.11304 + function _setTarget(target) { 27.11305 + this.endState.set(target); 27.11306 + 27.11307 + var dist = this.endState.sub(this.initState).norm(); 27.11308 + 27.11309 + this.wall.setOptions({ 27.11310 + distance : this.endState.norm(), 27.11311 + normal : (dist === 0) 27.11312 + ? this.particle.velocity.normalize(-1) 27.11313 + : this.endState.sub(this.initState).normalize(-1) 27.11314 + }); 27.11315 + 27.11316 + _setAbsoluteRestTolerance.call(this); 27.11317 + } 27.11318 + 27.11319 + function _setParticlePosition(p) { 27.11320 + this.particle.position.set(p); 27.11321 + } 27.11322 + 27.11323 + function _setParticleVelocity(v) { 27.11324 + this.particle.velocity.set(v); 27.11325 + } 27.11326 + 27.11327 + function _getParticlePosition() { 27.11328 + return (this._dimensions === 0) 27.11329 + ? this.particle.getPosition1D() 27.11330 + : this.particle.getPosition(); 27.11331 + } 27.11332 + 27.11333 + function _getParticleVelocity() { 27.11334 + return (this._dimensions === 0) 27.11335 + ? this.particle.getVelocity1D() 27.11336 + : this.particle.getVelocity(); 27.11337 + } 27.11338 + 27.11339 + function _setCallback(callback) { 27.11340 + this._callback = callback; 27.11341 + } 27.11342 + 27.11343 + function _update() { 27.11344 + if (this.PE.isSleeping()) { 27.11345 + if (this._callback) { 27.11346 + var cb = this._callback; 27.11347 + this._callback = undefined; 27.11348 + cb(); 27.11349 + } 27.11350 + return; 27.11351 + } 27.11352 + var energy = _getEnergy.call(this); 27.11353 + if (energy < this._absRestTolerance) { 27.11354 + _sleep.call(this); 27.11355 + _setParticlePosition.call(this, this.endState); 27.11356 + _setParticleVelocity.call(this, [0,0,0]); 27.11357 + } 27.11358 + } 27.11359 + 27.11360 + function _setupDefinition(def) { 27.11361 + var defaults = WallTransition.DEFAULT_OPTIONS; 27.11362 + if (def.period === undefined) def.period = defaults.period; 27.11363 + if (def.dampingRatio === undefined) def.dampingRatio = defaults.dampingRatio; 27.11364 + if (def.velocity === undefined) def.velocity = defaults.velocity; 27.11365 + if (def.restitution === undefined) def.restitution = defaults.restitution; 27.11366 + 27.11367 + //setup spring 27.11368 + this.spring.setOptions({ 27.11369 + period : def.period, 27.11370 + dampingRatio : def.dampingRatio 27.11371 + }); 27.11372 + 27.11373 + //setup wall 27.11374 + this.wall.setOptions({ 27.11375 + restitution : def.restitution 27.11376 + }); 27.11377 + 27.11378 + //setup particle 27.11379 + _setParticleVelocity.call(this, def.velocity); 27.11380 + } 27.11381 + 27.11382 + /** 27.11383 + * Resets the state and velocity 27.11384 + * 27.11385 + * @method reset 27.11386 + * 27.11387 + * @param {Number|Array} state State 27.11388 + * @param {Number|Array} [velocity] Velocity 27.11389 + */ 27.11390 + WallTransition.prototype.reset = function reset(state, velocity) { 27.11391 + this._dimensions = (state instanceof Array) 27.11392 + ? state.length 27.11393 + : 0; 27.11394 + 27.11395 + this.initState.set(state); 27.11396 + _setParticlePosition.call(this, state); 27.11397 + if (velocity) _setParticleVelocity.call(this, velocity); 27.11398 + _setTarget.call(this, state); 27.11399 + _setCallback.call(this, undefined); 27.11400 + }; 27.11401 + 27.11402 + /** 27.11403 + * Getter for velocity 27.11404 + * 27.11405 + * @method getVelocity 27.11406 + * 27.11407 + * @return velocity {Number|Array} 27.11408 + */ 27.11409 + WallTransition.prototype.getVelocity = function getVelocity() { 27.11410 + return _getParticleVelocity.call(this); 27.11411 + }; 27.11412 + 27.11413 + /** 27.11414 + * Setter for velocity 27.11415 + * 27.11416 + * @method setVelocity 27.11417 + * 27.11418 + * @return velocity {Number|Array} 27.11419 + */ 27.11420 + WallTransition.prototype.setVelocity = function setVelocity(velocity) { 27.11421 + this.call(this, _setParticleVelocity(velocity)); 27.11422 + }; 27.11423 + 27.11424 + /** 27.11425 + * Detects whether a transition is in progress 27.11426 + * 27.11427 + * @method isActive 27.11428 + * 27.11429 + * @return {Boolean} 27.11430 + */ 27.11431 + WallTransition.prototype.isActive = function isActive() { 27.11432 + return !this.PE.isSleeping(); 27.11433 + }; 27.11434 + 27.11435 + /** 27.11436 + * Halt the transition 27.11437 + * 27.11438 + * @method halt 27.11439 + */ 27.11440 + WallTransition.prototype.halt = function halt() { 27.11441 + this.set(this.get()); 27.11442 + }; 27.11443 + 27.11444 + /** 27.11445 + * Getter 27.11446 + * 27.11447 + * @method get 27.11448 + * 27.11449 + * @return state {Number|Array} 27.11450 + */ 27.11451 + WallTransition.prototype.get = function get() { 27.11452 + _update.call(this); 27.11453 + return _getParticlePosition.call(this); 27.11454 + }; 27.11455 + 27.11456 + /** 27.11457 + * Set the end position and transition, with optional callback on completion. 27.11458 + * 27.11459 + * @method set 27.11460 + * 27.11461 + * @param state {Number|Array} Final state 27.11462 + * @param [definition] {Object} Transition definition 27.11463 + * @param [callback] {Function} Callback 27.11464 + */ 27.11465 + WallTransition.prototype.set = function set(state, definition, callback) { 27.11466 + if (!definition) { 27.11467 + this.reset(state); 27.11468 + if (callback) callback(); 27.11469 + return; 27.11470 + } 27.11471 + 27.11472 + this._dimensions = (state instanceof Array) 27.11473 + ? state.length 27.11474 + : 0; 27.11475 + 27.11476 + _wake.call(this); 27.11477 + _setupDefinition.call(this, definition); 27.11478 + _setTarget.call(this, state); 27.11479 + _setCallback.call(this, callback); 27.11480 + }; 27.11481 + 27.11482 + module.exports = WallTransition; 27.11483 +}); 27.11484 + 27.11485 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11486 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11487 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11488 + * 27.11489 + * Owner: mark@famo.us 27.11490 + * @license MPL 2.0 27.11491 + * @copyright Famous Industries, Inc. 2014 27.11492 + */ 27.11493 + 27.11494 +define('famous/surfaces/CanvasSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 27.11495 + var Surface = require('famous/core/Surface'); 27.11496 + 27.11497 + /** 27.11498 + * A surface containing an HTML5 Canvas element. 27.11499 + * This extends the Surface class. 27.11500 + * 27.11501 + * @class CanvasSurface 27.11502 + * @extends Surface 27.11503 + * @constructor 27.11504 + * @param {Object} [options] overrides of default options 27.11505 + * @param {Array.Number} [options.canvasSize] [width, height] for document element 27.11506 + */ 27.11507 + function CanvasSurface(options) { 27.11508 + if (options && options.canvasSize) this._canvasSize = options.canvasSize; 27.11509 + Surface.apply(this, arguments); 27.11510 + if (!this._canvasSize) this._canvasSize = this.getSize(); 27.11511 + this._backBuffer = document.createElement('canvas'); 27.11512 + if (this._canvasSize) { 27.11513 + this._backBuffer.width = this._canvasSize[0]; 27.11514 + this._backBuffer.height = this._canvasSize[1]; 27.11515 + } 27.11516 + this._contextId = undefined; 27.11517 + } 27.11518 + 27.11519 + CanvasSurface.prototype = Object.create(Surface.prototype); 27.11520 + CanvasSurface.prototype.constructor = CanvasSurface; 27.11521 + CanvasSurface.prototype.elementType = 'canvas'; 27.11522 + CanvasSurface.prototype.elementClass = 'famous-surface'; 27.11523 + 27.11524 + /** 27.11525 + * Set inner document content. Note that this is a noop for CanvasSurface. 27.11526 + * 27.11527 + * @method setContent 27.11528 + * 27.11529 + */ 27.11530 + CanvasSurface.prototype.setContent = function setContent() {}; 27.11531 + 27.11532 + /** 27.11533 + * Place the document element this component manages into the document. 27.11534 + * This will draw the content to the document. 27.11535 + * 27.11536 + * @private 27.11537 + * @method deploy 27.11538 + * @param {Node} target document parent of this container 27.11539 + */ 27.11540 + CanvasSurface.prototype.deploy = function deploy(target) { 27.11541 + if (this._canvasSize) { 27.11542 + target.width = this._canvasSize[0]; 27.11543 + target.height = this._canvasSize[1]; 27.11544 + } 27.11545 + if (this._contextId === '2d') { 27.11546 + target.getContext(this._contextId).drawImage(this._backBuffer, 0, 0); 27.11547 + this._backBuffer.width = 0; 27.11548 + this._backBuffer.height = 0; 27.11549 + } 27.11550 + }; 27.11551 + 27.11552 + /** 27.11553 + * Remove this component and contained content from the document 27.11554 + * 27.11555 + * @private 27.11556 + * @method recall 27.11557 + * 27.11558 + * @param {Node} target node to which the component was deployed 27.11559 + */ 27.11560 + CanvasSurface.prototype.recall = function recall(target) { 27.11561 + var size = this.getSize(); 27.11562 + 27.11563 + this._backBuffer.width = target.width; 27.11564 + this._backBuffer.height = target.height; 27.11565 + 27.11566 + if (this._contextId === '2d') { 27.11567 + this._backBuffer.getContext(this._contextId).drawImage(target, 0, 0); 27.11568 + target.width = 0; 27.11569 + target.height = 0; 27.11570 + } 27.11571 + }; 27.11572 + 27.11573 + /** 27.11574 + * Returns the canvas element's context 27.11575 + * 27.11576 + * @method getContext 27.11577 + * @param {string} contextId context identifier 27.11578 + */ 27.11579 + CanvasSurface.prototype.getContext = function getContext(contextId) { 27.11580 + this._contextId = contextId; 27.11581 + return this._currTarget ? this._currTarget.getContext(contextId) : this._backBuffer.getContext(contextId); 27.11582 + }; 27.11583 + 27.11584 + /** 27.11585 + * Set the size of the surface and canvas element. 27.11586 + * 27.11587 + * @method setSize 27.11588 + * @param {Array.number} size [width, height] of surface 27.11589 + * @param {Array.number} canvasSize [width, height] of canvas surface 27.11590 + */ 27.11591 + CanvasSurface.prototype.setSize = function setSize(size, canvasSize) { 27.11592 + Surface.prototype.setSize.apply(this, arguments); 27.11593 + if (canvasSize) this._canvasSize = [canvasSize[0], canvasSize[1]]; 27.11594 + if (this._currTarget) { 27.11595 + this._currTarget.width = this._canvasSize[0]; 27.11596 + this._currTarget.height = this._canvasSize[1]; 27.11597 + } 27.11598 + }; 27.11599 + 27.11600 + module.exports = CanvasSurface; 27.11601 +}); 27.11602 + 27.11603 + 27.11604 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11605 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11606 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11607 + * 27.11608 + * Owner: mark@famo.us 27.11609 + * @license MPL 2.0 27.11610 + * @copyright Famous Industries, Inc. 2014 27.11611 + */ 27.11612 + 27.11613 +define('famous/surfaces/ContainerSurface',['require','exports','module','famous/core/Surface','famous/core/Context'],function(require, exports, module) { 27.11614 + var Surface = require('famous/core/Surface'); 27.11615 + var Context = require('famous/core/Context'); 27.11616 + 27.11617 + /** 27.11618 + * ContainerSurface is an object designed to contain surfaces and 27.11619 + * set properties to be applied to all of them at once. 27.11620 + * This extends the Surface class. 27.11621 + * A container surface will enforce these properties on the 27.11622 + * surfaces it contains: 27.11623 + * 27.11624 + * size (clips contained surfaces to its own width and height); 27.11625 + * 27.11626 + * origin; 27.11627 + * 27.11628 + * its own opacity and transform, which will be automatically 27.11629 + * applied to all Surfaces contained directly and indirectly. 27.11630 + * 27.11631 + * @class ContainerSurface 27.11632 + * @extends Surface 27.11633 + * @constructor 27.11634 + * @param {Array.Number} [options.size] [width, height] in pixels 27.11635 + * @param {Array.string} [options.classes] CSS classes to set on all inner content 27.11636 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 27.11637 + * @param {string} [options.content] inner (HTML) content of surface (should not be used) 27.11638 + */ 27.11639 + function ContainerSurface(options) { 27.11640 + Surface.call(this, options); 27.11641 + this._container = document.createElement('div'); 27.11642 + this._container.classList.add('famous-group'); 27.11643 + this._container.classList.add('famous-container-group'); 27.11644 + this._shouldRecalculateSize = false; 27.11645 + this.context = new Context(this._container); 27.11646 + this.setContent(this._container); 27.11647 + } 27.11648 + 27.11649 + ContainerSurface.prototype = Object.create(Surface.prototype); 27.11650 + ContainerSurface.prototype.constructor = ContainerSurface; 27.11651 + ContainerSurface.prototype.elementType = 'div'; 27.11652 + ContainerSurface.prototype.elementClass = 'famous-surface'; 27.11653 + 27.11654 + /** 27.11655 + * Add renderables to this object's render tree 27.11656 + * 27.11657 + * @method add 27.11658 + * 27.11659 + * @param {Object} obj renderable object 27.11660 + * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode 27.11661 + */ 27.11662 + ContainerSurface.prototype.add = function add() { 27.11663 + return this.context.add.apply(this.context, arguments); 27.11664 + }; 27.11665 + 27.11666 + /** 27.11667 + * Return spec for this surface. Note: Can result in a size recalculation. 27.11668 + * 27.11669 + * @private 27.11670 + * @method render 27.11671 + * 27.11672 + * @return {Object} render spec for this surface (spec id) 27.11673 + */ 27.11674 + ContainerSurface.prototype.render = function render() { 27.11675 + if (this._sizeDirty) this._shouldRecalculateSize = true; 27.11676 + return Surface.prototype.render.apply(this, arguments); 27.11677 + }; 27.11678 + 27.11679 + /** 27.11680 + * Place the document element this component manages into the document. 27.11681 + * 27.11682 + * @private 27.11683 + * @method deploy 27.11684 + * @param {Node} target document parent of this container 27.11685 + */ 27.11686 + ContainerSurface.prototype.deploy = function deploy() { 27.11687 + this._shouldRecalculateSize = true; 27.11688 + return Surface.prototype.deploy.apply(this, arguments); 27.11689 + }; 27.11690 + 27.11691 + /** 27.11692 + * Apply changes from this component to the corresponding document element. 27.11693 + * This includes changes to classes, styles, size, content, opacity, origin, 27.11694 + * and matrix transforms. 27.11695 + * 27.11696 + * @private 27.11697 + * @method commit 27.11698 + * @param {Context} context commit context 27.11699 + * @param {Transform} transform unused TODO 27.11700 + * @param {Number} opacity unused TODO 27.11701 + * @param {Array.Number} origin unused TODO 27.11702 + * @param {Array.Number} size unused TODO 27.11703 + * @return {undefined} TODO returns an undefined value 27.11704 + */ 27.11705 + ContainerSurface.prototype.commit = function commit(context, transform, opacity, origin, size) { 27.11706 + var previousSize = this._size ? [this._size[0], this._size[1]] : null; 27.11707 + var result = Surface.prototype.commit.apply(this, arguments); 27.11708 + if (this._shouldRecalculateSize || (previousSize && (this._size[0] !== previousSize[0] || this._size[1] !== previousSize[1]))) { 27.11709 + this.context.setSize(); 27.11710 + this._shouldRecalculateSize = false; 27.11711 + } 27.11712 + this.context.update(); 27.11713 + return result; 27.11714 + }; 27.11715 + 27.11716 + module.exports = ContainerSurface; 27.11717 +}); 27.11718 + 27.11719 +define('famous/surfaces/FormContainerSurface',['require','exports','module','./ContainerSurface'],function(require, exports, module) { 27.11720 + var ContainerSurface = require('./ContainerSurface'); 27.11721 + 27.11722 + function FormContainerSurface(options) { 27.11723 + if (options) this._method = options.method || ''; 27.11724 + ContainerSurface.apply(this, arguments); 27.11725 + } 27.11726 + 27.11727 + FormContainerSurface.prototype = Object.create(ContainerSurface.prototype); 27.11728 + FormContainerSurface.prototype.constructor = FormContainerSurface; 27.11729 + 27.11730 + FormContainerSurface.prototype.elementType = 'form'; 27.11731 + 27.11732 + FormContainerSurface.prototype.deploy = function deploy(target) { 27.11733 + if (this._method) target.method = this._method; 27.11734 + return ContainerSurface.prototype.deploy.apply(this, arguments); 27.11735 + }; 27.11736 + 27.11737 + module.exports = FormContainerSurface; 27.11738 +}); 27.11739 + 27.11740 + 27.11741 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11742 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11743 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11744 + * 27.11745 + * Owner: mark@famo.us 27.11746 + * @license MPL 2.0 27.11747 + * @copyright Famous Industries, Inc. 2014 27.11748 + */ 27.11749 + 27.11750 +define('famous/surfaces/ImageSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 27.11751 + var Surface = require('famous/core/Surface'); 27.11752 + 27.11753 + /** 27.11754 + * A surface containing image content. 27.11755 + * This extends the Surface class. 27.11756 + * 27.11757 + * @class ImageSurface 27.11758 + * 27.11759 + * @extends Surface 27.11760 + * @constructor 27.11761 + * @param {Object} [options] overrides of default options 27.11762 + */ 27.11763 + function ImageSurface(options) { 27.11764 + this._imageUrl = undefined; 27.11765 + Surface.apply(this, arguments); 27.11766 + } 27.11767 + 27.11768 + ImageSurface.prototype = Object.create(Surface.prototype); 27.11769 + ImageSurface.prototype.constructor = ImageSurface; 27.11770 + ImageSurface.prototype.elementType = 'img'; 27.11771 + ImageSurface.prototype.elementClass = 'famous-surface'; 27.11772 + 27.11773 + /** 27.11774 + * Set content URL. This will cause a re-rendering. 27.11775 + * @method setContent 27.11776 + * @param {string} imageUrl 27.11777 + */ 27.11778 + ImageSurface.prototype.setContent = function setContent(imageUrl) { 27.11779 + this._imageUrl = imageUrl; 27.11780 + this._contentDirty = true; 27.11781 + }; 27.11782 + 27.11783 + /** 27.11784 + * Place the document element that this component manages into the document. 27.11785 + * 27.11786 + * @private 27.11787 + * @method deploy 27.11788 + * @param {Node} target document parent of this container 27.11789 + */ 27.11790 + ImageSurface.prototype.deploy = function deploy(target) { 27.11791 + target.src = this._imageUrl || ''; 27.11792 + }; 27.11793 + 27.11794 + /** 27.11795 + * Remove this component and contained content from the document 27.11796 + * 27.11797 + * @private 27.11798 + * @method recall 27.11799 + * 27.11800 + * @param {Node} target node to which the component was deployed 27.11801 + */ 27.11802 + ImageSurface.prototype.recall = function recall(target) { 27.11803 + target.src = ''; 27.11804 + }; 27.11805 + 27.11806 + module.exports = ImageSurface; 27.11807 +}); 27.11808 + 27.11809 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11810 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11811 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11812 + * 27.11813 + * Owner: mark@famo.us 27.11814 + * @license MPL 2.0 27.11815 + * @copyright Famous Industries, Inc. 2014 27.11816 + */ 27.11817 + 27.11818 +define('famous/surfaces/InputSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 27.11819 + var Surface = require('famous/core/Surface'); 27.11820 + 27.11821 + /** 27.11822 + * A Famo.us surface in the form of an HTML input element. 27.11823 + * This extends the Surface class. 27.11824 + * 27.11825 + * @class InputSurface 27.11826 + * @extends Surface 27.11827 + * @constructor 27.11828 + * @param {Object} [options] overrides of default options 27.11829 + * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an <input> element 27.11830 + * @param {string} [options.type] specifies the type of element to display (e.g. 'datetime', 'text', 'button', etc.) 27.11831 + * @param {string} [options.value] value of text 27.11832 + */ 27.11833 + function InputSurface(options) { 27.11834 + this._placeholder = options.placeholder || ''; 27.11835 + this._value = options.value || ''; 27.11836 + this._type = options.type || 'text'; 27.11837 + this._name = options.name || ''; 27.11838 + 27.11839 + Surface.apply(this, arguments); 27.11840 + 27.11841 + this.on('click', this.focus.bind(this)); 27.11842 + window.addEventListener('click', function(event) { 27.11843 + if (event.target !== this._currTarget) this.blur(); 27.11844 + }.bind(this)); 27.11845 + } 27.11846 + InputSurface.prototype = Object.create(Surface.prototype); 27.11847 + InputSurface.prototype.constructor = InputSurface; 27.11848 + 27.11849 + InputSurface.prototype.elementType = 'input'; 27.11850 + InputSurface.prototype.elementClass = 'famous-surface'; 27.11851 + 27.11852 + /** 27.11853 + * Set placeholder text. Note: Triggers a repaint. 27.11854 + * 27.11855 + * @method setPlaceholder 27.11856 + * @param {string} str Value to set the placeholder to. 27.11857 + * @return {InputSurface} this, allowing method chaining. 27.11858 + */ 27.11859 + InputSurface.prototype.setPlaceholder = function setPlaceholder(str) { 27.11860 + this._placeholder = str; 27.11861 + this._contentDirty = true; 27.11862 + return this; 27.11863 + }; 27.11864 + 27.11865 + /** 27.11866 + * Focus on the current input, pulling up the keyboard on mobile. 27.11867 + * 27.11868 + * @method focus 27.11869 + * @return {InputSurface} this, allowing method chaining. 27.11870 + */ 27.11871 + InputSurface.prototype.focus = function focus() { 27.11872 + if (this._currTarget) this._currTarget.focus(); 27.11873 + return this; 27.11874 + }; 27.11875 + 27.11876 + /** 27.11877 + * Blur the current input, hiding the keyboard on mobile. 27.11878 + * 27.11879 + * @method blur 27.11880 + * @return {InputSurface} this, allowing method chaining. 27.11881 + */ 27.11882 + InputSurface.prototype.blur = function blur() { 27.11883 + if (this._currTarget) this._currTarget.blur(); 27.11884 + return this; 27.11885 + }; 27.11886 + 27.11887 + /** 27.11888 + * Set the placeholder conent. 27.11889 + * Note: Triggers a repaint next tick. 27.11890 + * 27.11891 + * @method setValue 27.11892 + * @param {string} str Value to set the main input value to. 27.11893 + * @return {InputSurface} this, allowing method chaining. 27.11894 + */ 27.11895 + InputSurface.prototype.setValue = function setValue(str) { 27.11896 + this._value = str; 27.11897 + this._contentDirty = true; 27.11898 + return this; 27.11899 + }; 27.11900 + 27.11901 + /** 27.11902 + * Set the type of element to display conent. 27.11903 + * Note: Triggers a repaint next tick. 27.11904 + * 27.11905 + * @method setType 27.11906 + * @param {string} str type of the input surface (e.g. 'button', 'text') 27.11907 + * @return {InputSurface} this, allowing method chaining. 27.11908 + */ 27.11909 + InputSurface.prototype.setType = function setType(str) { 27.11910 + this._type = str; 27.11911 + this._contentDirty = true; 27.11912 + return this; 27.11913 + }; 27.11914 + 27.11915 + /** 27.11916 + * Get the value of the inner content of the element (e.g. the entered text) 27.11917 + * 27.11918 + * @method getValue 27.11919 + * @return {string} value of element 27.11920 + */ 27.11921 + InputSurface.prototype.getValue = function getValue() { 27.11922 + if (this._currTarget) { 27.11923 + return this._currTarget.value; 27.11924 + } 27.11925 + else { 27.11926 + return this._value; 27.11927 + } 27.11928 + }; 27.11929 + 27.11930 + /** 27.11931 + * Set the name attribute of the element. 27.11932 + * Note: Triggers a repaint next tick. 27.11933 + * 27.11934 + * @method setName 27.11935 + * @param {string} str element name 27.11936 + * @return {InputSurface} this, allowing method chaining. 27.11937 + */ 27.11938 + InputSurface.prototype.setName = function setName(str) { 27.11939 + this._name = str; 27.11940 + this._contentDirty = true; 27.11941 + return this; 27.11942 + }; 27.11943 + 27.11944 + /** 27.11945 + * Get the name attribute of the element. 27.11946 + * 27.11947 + * @method getName 27.11948 + * @return {string} name of element 27.11949 + */ 27.11950 + InputSurface.prototype.getName = function getName() { 27.11951 + return this._name; 27.11952 + }; 27.11953 + 27.11954 + /** 27.11955 + * Place the document element this component manages into the document. 27.11956 + * 27.11957 + * @private 27.11958 + * @method deploy 27.11959 + * @param {Node} target document parent of this container 27.11960 + */ 27.11961 + InputSurface.prototype.deploy = function deploy(target) { 27.11962 + if (this._placeholder !== '') target.placeholder = this._placeholder; 27.11963 + target.value = this._value; 27.11964 + target.type = this._type; 27.11965 + target.name = this._name; 27.11966 + }; 27.11967 + 27.11968 + module.exports = InputSurface; 27.11969 +}); 27.11970 + 27.11971 +define('famous/surfaces/SubmitInputSurface',['require','exports','module','./InputSurface'],function(require, exports, module) { 27.11972 + var InputSurface = require('./InputSurface'); 27.11973 + 27.11974 + function SubmitInputSurface(options) { 27.11975 + InputSurface.apply(this, arguments); 27.11976 + this._type = 'submit'; 27.11977 + if (options && options.onClick) this.setOnClick(options.onClick); 27.11978 + } 27.11979 + 27.11980 + SubmitInputSurface.prototype = Object.create(InputSurface.prototype); 27.11981 + SubmitInputSurface.prototype.constructor = SubmitInputSurface; 27.11982 + 27.11983 + SubmitInputSurface.prototype.setOnClick = function(onClick) { 27.11984 + this.onClick = onClick; 27.11985 + }; 27.11986 + 27.11987 + SubmitInputSurface.prototype.deploy = function deploy(target) { 27.11988 + if (this.onclick) target.onClick = this.onClick; 27.11989 + InputSurface.prototype.deploy.apply(this, arguments); 27.11990 + }; 27.11991 + 27.11992 + module.exports = SubmitInputSurface; 27.11993 +}); 27.11994 + 27.11995 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.11996 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.11997 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.11998 + * 27.11999 + * Owner: mark@famo.us 27.12000 + * @license MPL 2.0 27.12001 + * @copyright Famous Industries, Inc. 2014 27.12002 + */ 27.12003 + 27.12004 +define('famous/surfaces/TextareaSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 27.12005 + var Surface = require('famous/core/Surface'); 27.12006 + 27.12007 + /** 27.12008 + * A Famo.us surface in the form of an HTML textarea element. 27.12009 + * This extends the Surface class. 27.12010 + * 27.12011 + * @class TextareaSurface 27.12012 + * @extends Surface 27.12013 + * @constructor 27.12014 + * @param {Object} [options] overrides of default options 27.12015 + * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an textarea element 27.12016 + * @param {string} [options.value] value of text 27.12017 + * @param {string} [options.name] specifies the name of textarea 27.12018 + * @param {string} [options.wrap] specify 'hard' or 'soft' wrap for textarea 27.12019 + * @param {number} [options.cols] number of columns in textarea 27.12020 + * @param {number} [options.rows] number of rows in textarea 27.12021 + */ 27.12022 + function TextareaSurface(options) { 27.12023 + this._placeholder = options.placeholder || ''; 27.12024 + this._value = options.value || ''; 27.12025 + this._name = options.name || ''; 27.12026 + this._wrap = options.wrap || ''; 27.12027 + this._cols = options.cols || ''; 27.12028 + this._rows = options.rows || ''; 27.12029 + 27.12030 + Surface.apply(this, arguments); 27.12031 + this.on('click', this.focus.bind(this)); 27.12032 + } 27.12033 + TextareaSurface.prototype = Object.create(Surface.prototype); 27.12034 + TextareaSurface.prototype.constructor = TextareaSurface; 27.12035 + 27.12036 + TextareaSurface.prototype.elementType = 'textarea'; 27.12037 + TextareaSurface.prototype.elementClass = 'famous-surface'; 27.12038 + 27.12039 + /** 27.12040 + * Set placeholder text. Note: Triggers a repaint. 27.12041 + * 27.12042 + * @method setPlaceholder 27.12043 + * @param {string} str Value to set the placeholder to. 27.12044 + * @return {TextareaSurface} this, allowing method chaining. 27.12045 + */ 27.12046 + TextareaSurface.prototype.setPlaceholder = function setPlaceholder(str) { 27.12047 + this._placeholder = str; 27.12048 + this._contentDirty = true; 27.12049 + return this; 27.12050 + }; 27.12051 + 27.12052 + /** 27.12053 + * Focus on the current input, pulling up the keyboard on mobile. 27.12054 + * 27.12055 + * @method focus 27.12056 + * @return {TextareaSurface} this, allowing method chaining. 27.12057 + */ 27.12058 + TextareaSurface.prototype.focus = function focus() { 27.12059 + if (this._currTarget) this._currTarget.focus(); 27.12060 + return this; 27.12061 + }; 27.12062 + 27.12063 + /** 27.12064 + * Blur the current input, hiding the keyboard on mobile. 27.12065 + * 27.12066 + * @method focus 27.12067 + * @return {TextareaSurface} this, allowing method chaining. 27.12068 + */ 27.12069 + TextareaSurface.prototype.blur = function blur() { 27.12070 + if (this._currTarget) this._currTarget.blur(); 27.12071 + return this; 27.12072 + }; 27.12073 + 27.12074 + /** 27.12075 + * Set the value of textarea. 27.12076 + * Note: Triggers a repaint next tick. 27.12077 + * 27.12078 + * @method setValue 27.12079 + * @param {string} str Value to set the main textarea value to. 27.12080 + * @return {TextareaSurface} this, allowing method chaining. 27.12081 + */ 27.12082 + TextareaSurface.prototype.setValue = function setValue(str) { 27.12083 + this._value = str; 27.12084 + this._contentDirty = true; 27.12085 + return this; 27.12086 + }; 27.12087 + 27.12088 + /** 27.12089 + * Get the value of the inner content of the textarea (e.g. the entered text) 27.12090 + * 27.12091 + * @method getValue 27.12092 + * @return {string} value of element 27.12093 + */ 27.12094 + TextareaSurface.prototype.getValue = function getValue() { 27.12095 + if (this._currTarget) { 27.12096 + return this._currTarget.value; 27.12097 + } 27.12098 + else { 27.12099 + return this._value; 27.12100 + } 27.12101 + }; 27.12102 + 27.12103 + /** 27.12104 + * Set the name attribute of the element. 27.12105 + * Note: Triggers a repaint next tick. 27.12106 + * 27.12107 + * @method setName 27.12108 + * @param {string} str element name 27.12109 + * @return {TextareaSurface} this, allowing method chaining. 27.12110 + */ 27.12111 + TextareaSurface.prototype.setName = function setName(str) { 27.12112 + this._name = str; 27.12113 + this._contentDirty = true; 27.12114 + return this; 27.12115 + }; 27.12116 + 27.12117 + /** 27.12118 + * Get the name attribute of the element. 27.12119 + * 27.12120 + * @method getName 27.12121 + * @return {string} name of element 27.12122 + */ 27.12123 + TextareaSurface.prototype.getName = function getName() { 27.12124 + return this._name; 27.12125 + }; 27.12126 + 27.12127 + /** 27.12128 + * Set the wrap of textarea. 27.12129 + * Note: Triggers a repaint next tick. 27.12130 + * 27.12131 + * @method setWrap 27.12132 + * @param {string} str wrap of the textarea surface (e.g. 'soft', 'hard') 27.12133 + * @return {TextareaSurface} this, allowing method chaining. 27.12134 + */ 27.12135 + TextareaSurface.prototype.setWrap = function setWrap(str) { 27.12136 + this._wrap = str; 27.12137 + this._contentDirty = true; 27.12138 + return this; 27.12139 + }; 27.12140 + 27.12141 + /** 27.12142 + * Set the number of columns visible in the textarea. 27.12143 + * Note: Overridden by surface size; set width to true. (eg. size: [true, *]) 27.12144 + * Triggers a repaint next tick. 27.12145 + * 27.12146 + * @method setColumns 27.12147 + * @param {number} num columns in textarea surface 27.12148 + * @return {TextareaSurface} this, allowing method chaining. 27.12149 + */ 27.12150 + TextareaSurface.prototype.setColumns = function setColumns(num) { 27.12151 + this._cols = num; 27.12152 + this._contentDirty = true; 27.12153 + return this; 27.12154 + }; 27.12155 + 27.12156 + /** 27.12157 + * Set the number of rows visible in the textarea. 27.12158 + * Note: Overridden by surface size; set height to true. (eg. size: [*, true]) 27.12159 + * Triggers a repaint next tick. 27.12160 + * 27.12161 + * @method setRows 27.12162 + * @param {number} num rows in textarea surface 27.12163 + * @return {TextareaSurface} this, allowing method chaining. 27.12164 + */ 27.12165 + TextareaSurface.prototype.setRows = function setRows(num) { 27.12166 + this._rows = num; 27.12167 + this._contentDirty = true; 27.12168 + return this; 27.12169 + }; 27.12170 + 27.12171 + /** 27.12172 + * Place the document element this component manages into the document. 27.12173 + * 27.12174 + * @private 27.12175 + * @method deploy 27.12176 + * @param {Node} target document parent of this container 27.12177 + */ 27.12178 + TextareaSurface.prototype.deploy = function deploy(target) { 27.12179 + if (this._placeholder !== '') target.placeholder = this._placeholder; 27.12180 + if (this._value !== '') target.value = this._value; 27.12181 + if (this._name !== '') target.name = this._name; 27.12182 + if (this._wrap !== '') target.wrap = this._wrap; 27.12183 + if (this._cols !== '') target.cols = this._cols; 27.12184 + if (this._rows !== '') target.rows = this._rows; 27.12185 + }; 27.12186 + 27.12187 + module.exports = TextareaSurface; 27.12188 +}); 27.12189 + 27.12190 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12191 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12192 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12193 + * 27.12194 + * Owner: mark@famo.us 27.12195 + * @license MPL 2.0 27.12196 + * @copyright Famous Industries, Inc. 2014 27.12197 + */ 27.12198 + 27.12199 +define('famous/surfaces/VideoSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 27.12200 + var Surface = require('famous/core/Surface'); 27.12201 + 27.12202 + /** 27.12203 + * Creates a famous surface containing video content. Currently adding 27.12204 + * controls and manipulating the video are not supported through the 27.12205 + * surface interface, but can be accomplished via standard JavaScript 27.12206 + * manipulation of the video DOM element. 27.12207 + * This extends the Surface class. 27.12208 + * 27.12209 + * @class VideoSurface 27.12210 + * @extends Surface 27.12211 + * @constructor 27.12212 + * @param {Object} [options] default option overrides 27.12213 + * @param {Array.Number} [options.size] [width, height] in pixels 27.12214 + * @param {Array.string} [options.classes] CSS classes to set on inner content 27.12215 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 27.12216 + * @param {string} [options.content] inner (HTML) content of surface 27.12217 + * @param {boolean} [options.autoplay] autoplay 27.12218 + */ 27.12219 + function VideoSurface(options) { 27.12220 + this._videoUrl = undefined; 27.12221 + this.options = Object.create(VideoSurface.DEFAULT_OPTIONS); 27.12222 + if (options) this.setOptions(options); 27.12223 + 27.12224 + Surface.apply(this, arguments); 27.12225 + } 27.12226 + VideoSurface.prototype = Object.create(Surface.prototype); 27.12227 + VideoSurface.prototype.constructor = VideoSurface; 27.12228 + 27.12229 + VideoSurface.DEFAULT_OPTIONS = { 27.12230 + autoplay: false 27.12231 + }; 27.12232 + 27.12233 + VideoSurface.prototype.elementType = 'video'; 27.12234 + VideoSurface.prototype.elementClass = 'famous-surface'; 27.12235 + 27.12236 + /** 27.12237 + * Set internal options, overriding any default options 27.12238 + * 27.12239 + * @method setOptions 27.12240 + * 27.12241 + * @param {Object} [options] overrides of default options 27.12242 + * @param {Boolean} [options.autoplay] HTML autoplay 27.12243 + */ 27.12244 + VideoSurface.prototype.setOptions = function setOptions(options) { 27.12245 + for (var key in VideoSurface.DEFAULT_OPTIONS) { 27.12246 + if (options[key] !== undefined) this.options[key] = options[key]; 27.12247 + } 27.12248 + }; 27.12249 + 27.12250 + /** 27.12251 + * Set url of the video. 27.12252 + * 27.12253 + * @method setContent 27.12254 + * @param {string} videoUrl URL 27.12255 + */ 27.12256 + VideoSurface.prototype.setContent = function setContent(videoUrl) { 27.12257 + this._videoUrl = videoUrl; 27.12258 + this._contentDirty = true; 27.12259 + }; 27.12260 + 27.12261 + /** 27.12262 + * Place the document element this component manages into the document. 27.12263 + * Note: In the case of VideoSurface, simply changes the options on the target. 27.12264 + * 27.12265 + * @private 27.12266 + * @method deploy 27.12267 + * @param {Node} target document parent of this container 27.12268 + */ 27.12269 + VideoSurface.prototype.deploy = function deploy(target) { 27.12270 + target.src = this._videoUrl; 27.12271 + target.autoplay = this.options.autoplay; 27.12272 + }; 27.12273 + 27.12274 + /** 27.12275 + * Remove this component and contained content from the document. 27.12276 + * Note: This doesn't actually remove the <video> element from the 27.12277 + * document. 27.12278 + * @private 27.12279 + * @method recall 27.12280 + * 27.12281 + * @param {Node} target node to which the component was deployed 27.12282 + */ 27.12283 + VideoSurface.prototype.recall = function recall(target) { 27.12284 + target.src = ''; 27.12285 + }; 27.12286 + 27.12287 + module.exports = VideoSurface; 27.12288 +}); 27.12289 + 27.12290 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12291 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12292 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12293 + * 27.12294 + * Owner: mark@famo.us 27.12295 + * @license MPL 2.0 27.12296 + * @copyright Famous Industries, Inc. 2014 27.12297 + */ 27.12298 + 27.12299 +define('famous/utilities/KeyCodes',['require','exports','module'],function(require, exports, module) { 27.12300 + 27.12301 + /** 27.12302 + * Collection to map keyboard codes in plain english 27.12303 + * 27.12304 + * @class KeyCodes 27.12305 + * @static 27.12306 + */ 27.12307 + var KeyCodes = { 27.12308 + 0 : 48, 27.12309 + 1 : 49, 27.12310 + 2 : 50, 27.12311 + 3 : 51, 27.12312 + 4 : 52, 27.12313 + 5 : 53, 27.12314 + 6 : 54, 27.12315 + 7 : 55, 27.12316 + 8 : 56, 27.12317 + 9 : 57, 27.12318 + a : 97, 27.12319 + b : 98, 27.12320 + c : 99, 27.12321 + d : 100, 27.12322 + e : 101, 27.12323 + f : 102, 27.12324 + g : 103, 27.12325 + h : 104, 27.12326 + i : 105, 27.12327 + j : 106, 27.12328 + k : 107, 27.12329 + l : 108, 27.12330 + m : 109, 27.12331 + n : 110, 27.12332 + o : 111, 27.12333 + p : 112, 27.12334 + q : 113, 27.12335 + r : 114, 27.12336 + s : 115, 27.12337 + t : 116, 27.12338 + u : 117, 27.12339 + v : 118, 27.12340 + w : 119, 27.12341 + x : 120, 27.12342 + y : 121, 27.12343 + z : 122, 27.12344 + A : 65, 27.12345 + B : 66, 27.12346 + C : 67, 27.12347 + D : 68, 27.12348 + E : 69, 27.12349 + F : 70, 27.12350 + G : 71, 27.12351 + H : 72, 27.12352 + I : 73, 27.12353 + J : 74, 27.12354 + K : 75, 27.12355 + L : 76, 27.12356 + M : 77, 27.12357 + N : 78, 27.12358 + O : 79, 27.12359 + P : 80, 27.12360 + Q : 81, 27.12361 + R : 82, 27.12362 + S : 83, 27.12363 + T : 84, 27.12364 + U : 85, 27.12365 + V : 86, 27.12366 + W : 87, 27.12367 + X : 88, 27.12368 + Y : 89, 27.12369 + Z : 90, 27.12370 + ENTER : 13, 27.12371 + LEFT_ARROW: 37, 27.12372 + RIGHT_ARROW: 39, 27.12373 + UP_ARROW: 38, 27.12374 + DOWN_ARROW: 40, 27.12375 + SPACE: 32, 27.12376 + SHIFT: 16, 27.12377 + TAB: 9 27.12378 + }; 27.12379 + 27.12380 + module.exports = KeyCodes; 27.12381 +}); 27.12382 + 27.12383 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12384 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12385 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12386 + * 27.12387 + * Owner: mark@famo.us 27.12388 + * @license MPL 2.0 27.12389 + * @copyright Famous Industries, Inc. 2014 27.12390 + */ 27.12391 +// TODO fix func-style 27.12392 +/*eslint func-style: [0, "declaration"] */ 27.12393 + 27.12394 +define('famous/utilities/Timer',['require','exports','module','famous/core/Engine'],function(require, exports, module) { 27.12395 + /** 27.12396 + * An internal library to reproduce javascript time-based scheduling. 27.12397 + * Using standard javascript setTimeout methods can have a negative performance impact 27.12398 + * when combined with the Famous rendering process, so instead require Timer and call 27.12399 + * Timer.setTimeout, Timer.setInterval, etc. 27.12400 + * 27.12401 + * @class Timer 27.12402 + * @constructor 27.12403 + */ 27.12404 + var FamousEngine = require('famous/core/Engine'); 27.12405 + 27.12406 + var _event = 'prerender'; 27.12407 + 27.12408 + var getTime = (window.performance) ? 27.12409 + function() { 27.12410 + return window.performance.now(); 27.12411 + } 27.12412 + : function() { 27.12413 + return Date.now(); 27.12414 + }; 27.12415 + 27.12416 + /** 27.12417 + * Add a function to be run on every prerender 27.12418 + * 27.12419 + * @method addTimerFunction 27.12420 + * 27.12421 + * @param {function} fn function to be run every prerender 27.12422 + * 27.12423 + * @return {function} function passed in as parameter 27.12424 + */ 27.12425 + function addTimerFunction(fn) { 27.12426 + FamousEngine.on(_event, fn); 27.12427 + return fn; 27.12428 + } 27.12429 + 27.12430 + /** 27.12431 + * Wraps a function to be invoked after a certain amount of time. 27.12432 + * After a set duration has passed, it executes the function and 27.12433 + * removes it as a listener to 'prerender'. 27.12434 + * 27.12435 + * @method setTimeout 27.12436 + * 27.12437 + * @param {function} fn function to be run after a specified duration 27.12438 + * @param {number} duration milliseconds from now to execute the function 27.12439 + * 27.12440 + * @return {function} function passed in as parameter 27.12441 + */ 27.12442 + function setTimeout(fn, duration) { 27.12443 + var t = getTime(); 27.12444 + var callback = function() { 27.12445 + var t2 = getTime(); 27.12446 + if (t2 - t >= duration) { 27.12447 + fn.apply(this, arguments); 27.12448 + FamousEngine.removeListener(_event, callback); 27.12449 + } 27.12450 + }; 27.12451 + return addTimerFunction(callback); 27.12452 + } 27.12453 + 27.12454 + /** 27.12455 + * Wraps a function to be invoked after a certain amount of time. 27.12456 + * After a set duration has passed, it executes the function and 27.12457 + * resets the execution time. 27.12458 + * 27.12459 + * @method setInterval 27.12460 + * 27.12461 + * @param {function} fn function to be run after a specified duration 27.12462 + * @param {number} duration interval to execute function in milliseconds 27.12463 + * 27.12464 + * @return {function} function passed in as parameter 27.12465 + */ 27.12466 + function setInterval(fn, duration) { 27.12467 + var t = getTime(); 27.12468 + var callback = function() { 27.12469 + var t2 = getTime(); 27.12470 + if (t2 - t >= duration) { 27.12471 + fn.apply(this, arguments); 27.12472 + t = getTime(); 27.12473 + } 27.12474 + }; 27.12475 + return addTimerFunction(callback); 27.12476 + } 27.12477 + 27.12478 + /** 27.12479 + * Wraps a function to be invoked after a certain amount of prerender ticks. 27.12480 + * Similar use to setTimeout but tied to the engine's run speed. 27.12481 + * 27.12482 + * @method after 27.12483 + * 27.12484 + * @param {function} fn function to be run after a specified amount of ticks 27.12485 + * @param {number} numTicks number of prerender frames to wait 27.12486 + * 27.12487 + * @return {function} function passed in as parameter 27.12488 + */ 27.12489 + function after(fn, numTicks) { 27.12490 + if (numTicks === undefined) return undefined; 27.12491 + var callback = function() { 27.12492 + numTicks--; 27.12493 + if (numTicks <= 0) { //in case numTicks is fraction or negative 27.12494 + fn.apply(this, arguments); 27.12495 + clear(callback); 27.12496 + } 27.12497 + }; 27.12498 + return addTimerFunction(callback); 27.12499 + } 27.12500 + 27.12501 + /** 27.12502 + * Wraps a function to be continually invoked after a certain amount of prerender ticks. 27.12503 + * Similar use to setInterval but tied to the engine's run speed. 27.12504 + * 27.12505 + * @method every 27.12506 + * 27.12507 + * @param {function} fn function to be run after a specified amount of ticks 27.12508 + * @param {number} numTicks number of prerender frames to wait 27.12509 + * 27.12510 + * @return {function} function passed in as parameter 27.12511 + */ 27.12512 + function every(fn, numTicks) { 27.12513 + numTicks = numTicks || 1; 27.12514 + var initial = numTicks; 27.12515 + var callback = function() { 27.12516 + numTicks--; 27.12517 + if (numTicks <= 0) { //in case numTicks is fraction or negative 27.12518 + fn.apply(this, arguments); 27.12519 + numTicks = initial; 27.12520 + } 27.12521 + }; 27.12522 + return addTimerFunction(callback); 27.12523 + } 27.12524 + 27.12525 + /** 27.12526 + * Remove a function that gets called every prerender 27.12527 + * 27.12528 + * @method clear 27.12529 + * 27.12530 + * @param {function} fn event linstener 27.12531 + */ 27.12532 + function clear(fn) { 27.12533 + FamousEngine.removeListener(_event, fn); 27.12534 + } 27.12535 + 27.12536 + /** 27.12537 + * Executes a function after a certain amount of time. Makes sure 27.12538 + * the function is not run multiple times. 27.12539 + * 27.12540 + * @method debounce 27.12541 + * 27.12542 + * @param {function} func function to run after certain amount of time 27.12543 + * @param {number} wait amount of time 27.12544 + * 27.12545 + * @return {function} function that is not able to debounce 27.12546 + */ 27.12547 + function debounce(func, wait) { 27.12548 + var timeout; 27.12549 + var ctx; 27.12550 + var timestamp; 27.12551 + var result; 27.12552 + var args; 27.12553 + return function() { 27.12554 + ctx = this; 27.12555 + args = arguments; 27.12556 + timestamp = getTime(); 27.12557 + 27.12558 + var fn = function() { 27.12559 + var last = getTime - timestamp; 27.12560 + 27.12561 + if (last < wait) { 27.12562 + timeout = setTimeout(fn, wait - last); 27.12563 + } else { 27.12564 + timeout = null; 27.12565 + result = func.apply(ctx, args); 27.12566 + } 27.12567 + }; 27.12568 + 27.12569 + clear(timeout); 27.12570 + timeout = setTimeout(fn, wait); 27.12571 + 27.12572 + return result; 27.12573 + }; 27.12574 + } 27.12575 + 27.12576 + module.exports = { 27.12577 + setTimeout : setTimeout, 27.12578 + setInterval : setInterval, 27.12579 + debounce : debounce, 27.12580 + after : after, 27.12581 + every : every, 27.12582 + clear : clear 27.12583 + }; 27.12584 + 27.12585 +}); 27.12586 + 27.12587 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12588 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12589 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12590 + * 27.12591 + * Owner: mike@famo.us 27.12592 + * @license MPL 2.0 27.12593 + * @copyright Famous Industries, Inc. 2014 27.12594 + */ 27.12595 + 27.12596 +define('famous/views/ContextualView',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/EventHandler','famous/core/OptionsManager'],function(require, exports, module) { 27.12597 + var Entity = require('famous/core/Entity'); 27.12598 + var Transform = require('famous/core/Transform'); 27.12599 + var EventHandler = require('famous/core/EventHandler'); 27.12600 + var OptionsManager = require('famous/core/OptionsManager'); 27.12601 + 27.12602 + /** 27.12603 + * ContextualView is an interface for creating views that need to 27.12604 + * be aware of their parent's transform, size, and/or origin. 27.12605 + * Consists of a OptionsManager paired with an input EventHandler 27.12606 + * and an output EventHandler. Meant to be extended by the developer. 27.12607 + * @class ContextualView 27.12608 + * @constructor 27.12609 + * @param {Options} [options] An object of configurable options. 27.12610 + */ 27.12611 + function ContextualView(options) { 27.12612 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS || ContextualView.DEFAULT_OPTIONS); 27.12613 + this._optionsManager = new OptionsManager(this.options); 27.12614 + if (options) this.setOptions(options); 27.12615 + 27.12616 + this._eventInput = new EventHandler(); 27.12617 + this._eventOutput = new EventHandler(); 27.12618 + EventHandler.setInputHandler(this, this._eventInput); 27.12619 + EventHandler.setOutputHandler(this, this._eventOutput); 27.12620 + 27.12621 + this._id = Entity.register(this); 27.12622 + } 27.12623 + 27.12624 + ContextualView.DEFAULT_OPTIONS = {}; 27.12625 + 27.12626 + /** 27.12627 + * Patches the ContextualLayout instance's options with the passed-in ones. 27.12628 + * 27.12629 + * @method setOptions 27.12630 + * @param {Options} options An object of configurable options for the ContextualLayout instance. 27.12631 + */ 27.12632 + ContextualView.prototype.setOptions = function setOptions(options) { 27.12633 + return this._optionsManager.setOptions(options); 27.12634 + }; 27.12635 + 27.12636 + /** 27.12637 + * Returns ContextualLayout instance's options. 27.12638 + * 27.12639 + * @method setOptions 27.12640 + * @return {Options} options The instance's object of configurable options. 27.12641 + */ 27.12642 + ContextualView.prototype.getOptions = function getOptions() { 27.12643 + return this._optionsManager.getOptions(); 27.12644 + }; 27.12645 + 27.12646 + /** 27.12647 + * Return the registers Entity id for the ContextualView. 27.12648 + * 27.12649 + * @private 27.12650 + * @method render 27.12651 + * @return {Number} Registered Entity id 27.12652 + */ 27.12653 + ContextualView.prototype.render = function render() { 27.12654 + return this._id; 27.12655 + }; 27.12656 + 27.12657 + /** 27.12658 + * Apply changes from this component to the corresponding document element. 27.12659 + * This includes changes to classes, styles, size, content, opacity, origin, 27.12660 + * and matrix transforms. 27.12661 + * 27.12662 + * @private 27.12663 + * @method commit 27.12664 + * @param {Context} context commit context 27.12665 + */ 27.12666 + ContextualView.prototype.commit = function commit(context) {}; 27.12667 + 27.12668 + module.exports = ContextualView; 27.12669 +}); 27.12670 + 27.12671 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12672 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12673 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12674 + * 27.12675 + * Owner: felix@famo.us 27.12676 + * @license MPL 2.0 27.12677 + * @copyright Famous Industries, Inc. 2014 27.12678 + */ 27.12679 + 27.12680 +define('famous/views/SequentialLayout',['require','exports','module','famous/core/OptionsManager','famous/core/Transform','famous/core/ViewSequence','famous/utilities/Utility'],function(require, exports, module) { 27.12681 + var OptionsManager = require('famous/core/OptionsManager'); 27.12682 + var Transform = require('famous/core/Transform'); 27.12683 + var ViewSequence = require('famous/core/ViewSequence'); 27.12684 + var Utility = require('famous/utilities/Utility'); 27.12685 + 27.12686 + /** 27.12687 + * SequentialLayout will lay out a collection of renderables sequentially in the specified direction. 27.12688 + * @class SequentialLayout 27.12689 + * @constructor 27.12690 + * @param {Options} [options] An object of configurable options. 27.12691 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 27.12692 + * module, this option will lay out the SequentialLayout instance's renderables either horizontally 27.12693 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 27.12694 + * to just use integers as well. 27.12695 + * @param {Array.Number} [options.defaultItemSize=[50, 50]] In the case where a renderable layed out 27.12696 + * under SequentialLayout's control doesen't have a getSize method, SequentialLayout will assign it 27.12697 + * this default size. (Commonly a case with Views). 27.12698 + */ 27.12699 + function SequentialLayout(options) { 27.12700 + this._items = null; 27.12701 + this._size = null; 27.12702 + this._outputFunction = SequentialLayout.DEFAULT_OUTPUT_FUNCTION; 27.12703 + 27.12704 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.12705 + this.optionsManager = new OptionsManager(this.options); 27.12706 + 27.12707 + this._itemsCache = []; 27.12708 + this._outputCache = { 27.12709 + size: null, 27.12710 + target: this._itemsCache 27.12711 + }; 27.12712 + 27.12713 + if (options) this.setOptions(options); 27.12714 + } 27.12715 + 27.12716 + SequentialLayout.DEFAULT_OPTIONS = { 27.12717 + direction: Utility.Direction.Y, 27.12718 + itemSpacing: 0, 27.12719 + defaultItemSize: [50, 50] 27.12720 + }; 27.12721 + 27.12722 + SequentialLayout.DEFAULT_OUTPUT_FUNCTION = function DEFAULT_OUTPUT_FUNCTION(input, offset, index) { 27.12723 + var transform = (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset); 27.12724 + return { 27.12725 + transform: transform, 27.12726 + target: input.render() 27.12727 + }; 27.12728 + }; 27.12729 + 27.12730 + /** 27.12731 + * Returns the width and the height of the SequentialLayout instance. 27.12732 + * 27.12733 + * @method getSize 27.12734 + * @return {Array} A two value array of the SequentialLayout instance's current width and height (in that order). 27.12735 + */ 27.12736 + SequentialLayout.prototype.getSize = function getSize() { 27.12737 + if (!this._size) this.render(); // hack size in 27.12738 + return this._size; 27.12739 + }; 27.12740 + 27.12741 + /** 27.12742 + * Sets the collection of renderables under the SequentialLayout instance's control. 27.12743 + * 27.12744 + * @method sequenceFrom 27.12745 + * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence. 27.12746 + * @chainable 27.12747 + */ 27.12748 + SequentialLayout.prototype.sequenceFrom = function sequenceFrom(items) { 27.12749 + if (items instanceof Array) items = new ViewSequence(items); 27.12750 + this._items = items; 27.12751 + return this; 27.12752 + }; 27.12753 + 27.12754 + /** 27.12755 + * Patches the SequentialLayout instance's options with the passed-in ones. 27.12756 + * 27.12757 + * @method setOptions 27.12758 + * @param {Options} options An object of configurable options for the SequentialLayout instance. 27.12759 + * @chainable 27.12760 + */ 27.12761 + SequentialLayout.prototype.setOptions = function setOptions(options) { 27.12762 + this.optionsManager.setOptions.apply(this.optionsManager, arguments); 27.12763 + return this; 27.12764 + }; 27.12765 + 27.12766 + /** 27.12767 + * setOutputFunction is used to apply a user-defined output transform on each processed renderable. 27.12768 + * For a good example, check out SequentialLayout's own DEFAULT_OUTPUT_FUNCTION in the code. 27.12769 + * 27.12770 + * @method setOutputFunction 27.12771 + * @param {Function} outputFunction An output processer for each renderable in the SequentialLayout 27.12772 + * instance. 27.12773 + * @chainable 27.12774 + */ 27.12775 + SequentialLayout.prototype.setOutputFunction = function setOutputFunction(outputFunction) { 27.12776 + this._outputFunction = outputFunction; 27.12777 + return this; 27.12778 + }; 27.12779 + 27.12780 + /** 27.12781 + * Generate a render spec from the contents of this component. 27.12782 + * 27.12783 + * @private 27.12784 + * @method render 27.12785 + * @return {number} Render spec for this component 27.12786 + */ 27.12787 + SequentialLayout.prototype.render = function render() { 27.12788 + var length = 0; 27.12789 + var girth = 0; 27.12790 + 27.12791 + var lengthDim = (this.options.direction === Utility.Direction.X) ? 0 : 1; 27.12792 + var girthDim = (this.options.direction === Utility.Direction.X) ? 1 : 0; 27.12793 + 27.12794 + var currentNode = this._items; 27.12795 + var result = this._itemsCache; 27.12796 + var i = 0; 27.12797 + while (currentNode) { 27.12798 + var item = currentNode.get(); 27.12799 + if (!item) break; 27.12800 + 27.12801 + var itemSize; 27.12802 + if (item && item.getSize) itemSize = item.getSize(); 27.12803 + if (!itemSize) itemSize = this.options.defaultItemSize; 27.12804 + if (itemSize[girthDim] !== true) girth = Math.max(girth, itemSize[girthDim]); 27.12805 + 27.12806 + var output = this._outputFunction.call(this, item, length, i); 27.12807 + result[i] = output; 27.12808 + 27.12809 + if (itemSize[lengthDim] && (itemSize[lengthDim] !== true)) length += itemSize[lengthDim] + this.options.itemSpacing; 27.12810 + currentNode = currentNode.getNext(); 27.12811 + i++; 27.12812 + } 27.12813 + this._itemsCache.splice(i); 27.12814 + 27.12815 + if (!girth) girth = undefined; 27.12816 + 27.12817 + if (!this._size) this._size = [0, 0]; 27.12818 + this._size[lengthDim] = length - this.options.itemSpacing; // account for last itemSpacing 27.12819 + this._size[girthDim] = girth; 27.12820 + 27.12821 + this._outputCache.size = this.getSize(); 27.12822 + return this._outputCache; 27.12823 + }; 27.12824 + 27.12825 + module.exports = SequentialLayout; 27.12826 +}); 27.12827 + 27.12828 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12829 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12830 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12831 + * 27.12832 + * Owner: felix@famo.us 27.12833 + * @license MPL 2.0 27.12834 + * @copyright Famous Industries, Inc. 2014 27.12835 + */ 27.12836 + 27.12837 +define('famous/views/Deck',['require','exports','module','famous/core/Transform','famous/core/OptionsManager','famous/transitions/Transitionable','famous/utilities/Utility','./SequentialLayout'],function(require, exports, module) { 27.12838 + var Transform = require('famous/core/Transform'); 27.12839 + var OptionsManager = require('famous/core/OptionsManager'); 27.12840 + var Transitionable = require('famous/transitions/Transitionable'); 27.12841 + var Utility = require('famous/utilities/Utility'); 27.12842 + var SequentialLayout = require('./SequentialLayout'); 27.12843 + 27.12844 + /** 27.12845 + * A Sequential Layout that can be opened and closed with animations. 27.12846 + * 27.12847 + * Takes the same options as SequentialLayout 27.12848 + * as well as options for the open/close transition 27.12849 + * and the rotation you want your Deck instance to layout in. 27.12850 + * 27.12851 + * @class Deck 27.12852 + * @constructor 27.12853 + * @extends SequentialLayout 27.12854 + * 27.12855 + * @param {Options} [options] An object of configurable options 27.12856 + * @param {Transition} [options.transition={duration: 500, curve: 'easeOutBounce'} 27.12857 + * The transition that executes upon opening or closing your deck instance. 27.12858 + * @param {Number} [stackRotation=0] The amount of rotation applied to the propogation 27.12859 + * of the Deck instance's stack of renderables. 27.12860 + * @param {Object} [options.transition] A transition object for changing between states. 27.12861 + * @param {Number} [options.direction] axis of expansion (Utility.Direction.X or .Y) 27.12862 + */ 27.12863 + function Deck(options) { 27.12864 + SequentialLayout.apply(this, arguments); 27.12865 + this.state = new Transitionable(0); 27.12866 + this._isOpen = false; 27.12867 + 27.12868 + this.setOutputFunction(function(input, offset, index) { 27.12869 + var state = _getState.call(this); 27.12870 + var positionMatrix = (this.options.direction === Utility.Direction.X) ? 27.12871 + Transform.translate(state * offset, 0, 0.001 * (state - 1) * offset) : 27.12872 + Transform.translate(0, state * offset, 0.001 * (state - 1) * offset); 27.12873 + var output = input.render(); 27.12874 + if (this.options.stackRotation) { 27.12875 + var amount = this.options.stackRotation * index * (1 - state); 27.12876 + output = { 27.12877 + transform: Transform.rotateZ(amount), 27.12878 + origin: [0.5, 0.5], 27.12879 + target: output 27.12880 + }; 27.12881 + } 27.12882 + return { 27.12883 + transform: positionMatrix, 27.12884 + size: input.getSize(), 27.12885 + target: output 27.12886 + }; 27.12887 + }); 27.12888 + } 27.12889 + Deck.prototype = Object.create(SequentialLayout.prototype); 27.12890 + Deck.prototype.constructor = Deck; 27.12891 + 27.12892 + Deck.DEFAULT_OPTIONS = OptionsManager.patch(SequentialLayout.DEFAULT_OPTIONS, { 27.12893 + transition: { 27.12894 + curve: 'easeOutBounce', 27.12895 + duration: 500 27.12896 + }, 27.12897 + stackRotation: 0 27.12898 + }); 27.12899 + 27.12900 + /** 27.12901 + * Returns the width and the height of the Deck instance. 27.12902 + * 27.12903 + * @method getSize 27.12904 + * @return {Array} A two value array of Deck's current width and height (in that order). 27.12905 + * Scales as Deck opens and closes. 27.12906 + */ 27.12907 + Deck.prototype.getSize = function getSize() { 27.12908 + var originalSize = SequentialLayout.prototype.getSize.apply(this, arguments); 27.12909 + var firstSize = this._items ? this._items.get().getSize() : [0, 0]; 27.12910 + if (!firstSize) firstSize = [0, 0]; 27.12911 + var state = _getState.call(this); 27.12912 + var invState = 1 - state; 27.12913 + return [firstSize[0] * invState + originalSize[0] * state, firstSize[1] * invState + originalSize[1] * state]; 27.12914 + }; 27.12915 + 27.12916 + function _getState(returnFinal) { 27.12917 + if (returnFinal) return this._isOpen ? 1 : 0; 27.12918 + else return this.state.get(); 27.12919 + } 27.12920 + 27.12921 + function _setState(pos, transition, callback) { 27.12922 + this.state.halt(); 27.12923 + this.state.set(pos, transition, callback); 27.12924 + } 27.12925 + 27.12926 + /** 27.12927 + * An accesor method to find out if the messaged Deck instance is open or closed. 27.12928 + * 27.12929 + * @method isOpen 27.12930 + * @return {Boolean} Returns true if the instance is open or false if it's closed. 27.12931 + */ 27.12932 + Deck.prototype.isOpen = function isOpen() { 27.12933 + return this._isOpen; 27.12934 + }; 27.12935 + 27.12936 + /** 27.12937 + * Sets the Deck instance to an open state. 27.12938 + * 27.12939 + * @method open 27.12940 + * @param {function} [callback] Executes after transitioning to a fully open state. 27.12941 + */ 27.12942 + Deck.prototype.open = function open(callback) { 27.12943 + this._isOpen = true; 27.12944 + _setState.call(this, 1, this.options.transition, callback); 27.12945 + }; 27.12946 + 27.12947 + /** 27.12948 + * Sets the Deck instance to an open state. 27.12949 + * 27.12950 + * @method close 27.12951 + * @param {function} [callback] Executes after transitioning to a fully closed state. 27.12952 + */ 27.12953 + Deck.prototype.close = function close(callback) { 27.12954 + this._isOpen = false; 27.12955 + _setState.call(this, 0, this.options.transition, callback); 27.12956 + }; 27.12957 + 27.12958 + /** 27.12959 + * Sets the Deck instance from its current state to the opposite state. 27.12960 + * 27.12961 + * @method close 27.12962 + * @param {function} [callback] Executes after transitioning to the toggled state. 27.12963 + */ 27.12964 + Deck.prototype.toggle = function toggle(callback) { 27.12965 + if (this._isOpen) this.close(callback); 27.12966 + else this.open(callback); 27.12967 + }; 27.12968 + 27.12969 + module.exports = Deck; 27.12970 +}); 27.12971 + 27.12972 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.12973 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.12974 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.12975 + * 27.12976 + * Owner: felix@famo.us 27.12977 + * @license MPL 2.0 27.12978 + * @copyright Famous Industries, Inc. 2014 27.12979 + */ 27.12980 + 27.12981 +define('famous/views/RenderController',['require','exports','module','famous/core/Modifier','famous/core/RenderNode','famous/core/Transform','famous/transitions/Transitionable','famous/core/View'],function(require, exports, module) { 27.12982 + var Modifier = require('famous/core/Modifier'); 27.12983 + var RenderNode = require('famous/core/RenderNode'); 27.12984 + var Transform = require('famous/core/Transform'); 27.12985 + var Transitionable = require('famous/transitions/Transitionable'); 27.12986 + var View = require('famous/core/View'); 27.12987 + 27.12988 + /** 27.12989 + * A dynamic view that can show or hide different renerables with transitions. 27.12990 + * @class RenderController 27.12991 + * @constructor 27.12992 + * @param {Options} [options] An object of configurable options. 27.12993 + * @param {Transition} [inTransition=true] The transition in charge of showing a renderable. 27.12994 + * @param {Transition} [outTransition=true] The transition in charge of removing your previous renderable when 27.12995 + * you show a new one, or hiding your current renderable. 27.12996 + * @param {Boolean} [overlap=true] When showing a new renderable, overlap determines if the 27.12997 + out transition of the old one executes concurrently with the in transition of the new one, 27.12998 + or synchronously beforehand. 27.12999 + */ 27.13000 + function RenderController(options) { 27.13001 + View.apply(this, arguments); 27.13002 + 27.13003 + this._showing = -1; 27.13004 + this._outgoingRenderables = []; 27.13005 + this._nextRenderable = null; 27.13006 + 27.13007 + this._renderables = []; 27.13008 + this._nodes = []; 27.13009 + this._modifiers = []; 27.13010 + this._states = []; 27.13011 + 27.13012 + this.inTransformMap = RenderController.DefaultMap.transform; 27.13013 + this.inOpacityMap = RenderController.DefaultMap.opacity; 27.13014 + this.inOriginMap = RenderController.DefaultMap.origin; 27.13015 + this.outTransformMap = RenderController.DefaultMap.transform; 27.13016 + this.outOpacityMap = RenderController.DefaultMap.opacity; 27.13017 + this.outOriginMap = RenderController.DefaultMap.origin; 27.13018 + 27.13019 + this._output = []; 27.13020 + } 27.13021 + RenderController.prototype = Object.create(View.prototype); 27.13022 + RenderController.prototype.constructor = RenderController; 27.13023 + 27.13024 + RenderController.DEFAULT_OPTIONS = { 27.13025 + inTransition: true, 27.13026 + outTransition: true, 27.13027 + overlap: true 27.13028 + }; 27.13029 + 27.13030 + RenderController.DefaultMap = { 27.13031 + transform: function() { 27.13032 + return Transform.identity; 27.13033 + }, 27.13034 + opacity: function(progress) { 27.13035 + return progress; 27.13036 + }, 27.13037 + origin: null 27.13038 + }; 27.13039 + 27.13040 + function _mappedState(map, state) { 27.13041 + return map(state.get()); 27.13042 + } 27.13043 + 27.13044 + /** 27.13045 + * As your RenderController shows a new renderable, it executes a transition in. This transition in 27.13046 + * will affect a default interior state and modify it as you bring renderables in and out. However, if you want to control 27.13047 + * the transform, opacity, and origin state yourself, you may call certain methods (such as inTransformFrom) to obtain state from an outside source, 27.13048 + * that may either be a function or a Famous transitionable. inTransformFrom sets the accessor for the state of 27.13049 + * the transform used in transitioning in renderables. 27.13050 + * 27.13051 + * @method inTransformFrom 27.13052 + * @param {Function|Transitionable} transform A function that returns a transform from outside closure, or a 27.13053 + * a transitionable that manages a full transform (a sixteen value array). 27.13054 + * @chainable 27.13055 + */ 27.13056 + RenderController.prototype.inTransformFrom = function inTransformFrom(transform) { 27.13057 + if (transform instanceof Function) this.inTransformMap = transform; 27.13058 + else if (transform && transform.get) this.inTransformMap = transform.get.bind(transform); 27.13059 + else throw new Error('inTransformFrom takes only function or getter object'); 27.13060 + //TODO: tween transition 27.13061 + return this; 27.13062 + }; 27.13063 + 27.13064 + /** 27.13065 + * inOpacityFrom sets the accessor for the state of the opacity used in transitioning in renderables. 27.13066 + * @method inOpacityFrom 27.13067 + * @param {Function|Transitionable} opacity A function that returns an opacity from outside closure, or a 27.13068 + * a transitionable that manages opacity (a number between zero and one). 27.13069 + * @chainable 27.13070 + */ 27.13071 + RenderController.prototype.inOpacityFrom = function inOpacityFrom(opacity) { 27.13072 + if (opacity instanceof Function) this.inOpacityMap = opacity; 27.13073 + else if (opacity && opacity.get) this.inOpacityMap = opacity.get.bind(opacity); 27.13074 + else throw new Error('inOpacityFrom takes only function or getter object'); 27.13075 + //TODO: tween opacity 27.13076 + return this; 27.13077 + }; 27.13078 + 27.13079 + /** 27.13080 + * inOriginFrom sets the accessor for the state of the origin used in transitioning in renderables. 27.13081 + * @method inOriginFrom 27.13082 + * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a 27.13083 + * a transitionable that manages origin (a two value array of numbers between zero and one). 27.13084 + * @chainable 27.13085 + */ 27.13086 + RenderController.prototype.inOriginFrom = function inOriginFrom(origin) { 27.13087 + if (origin instanceof Function) this.inOriginMap = origin; 27.13088 + else if (origin && origin.get) this.inOriginMap = origin.get.bind(origin); 27.13089 + else throw new Error('inOriginFrom takes only function or getter object'); 27.13090 + //TODO: tween origin 27.13091 + return this; 27.13092 + }; 27.13093 + 27.13094 + /** 27.13095 + * outTransformFrom sets the accessor for the state of the transform used in transitioning out renderables. 27.13096 + * @method show 27.13097 + * @param {Function|Transitionable} transform A function that returns a transform from outside closure, or a 27.13098 + * a transitionable that manages a full transform (a sixteen value array). 27.13099 + * @chainable 27.13100 + */ 27.13101 + RenderController.prototype.outTransformFrom = function outTransformFrom(transform) { 27.13102 + if (transform instanceof Function) this.outTransformMap = transform; 27.13103 + else if (transform && transform.get) this.outTransformMap = transform.get.bind(transform); 27.13104 + else throw new Error('inTransformFrom takes only function or getter object'); 27.13105 + //TODO: tween transition 27.13106 + return this; 27.13107 + }; 27.13108 + 27.13109 + /** 27.13110 + * outOpacityFrom sets the accessor for the state of the opacity used in transitioning out renderables. 27.13111 + * @method inOpacityFrom 27.13112 + * @param {Function|Transitionable} opacity A function that returns an opacity from outside closure, or a 27.13113 + * a transitionable that manages opacity (a number between zero and one). 27.13114 + * @chainable 27.13115 + */ 27.13116 + RenderController.prototype.outOpacityFrom = function outOpacityFrom(opacity) { 27.13117 + if (opacity instanceof Function) this.outOpacityMap = opacity; 27.13118 + else if (opacity && opacity.get) this.outOpacityMap = opacity.get.bind(opacity); 27.13119 + else throw new Error('inOpacityFrom takes only function or getter object'); 27.13120 + //TODO: tween opacity 27.13121 + return this; 27.13122 + }; 27.13123 + 27.13124 + /** 27.13125 + * outOriginFrom sets the accessor for the state of the origin used in transitioning out renderables. 27.13126 + * @method inOriginFrom 27.13127 + * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a 27.13128 + * a transitionable that manages origin (a two value array of numbers between zero and one). 27.13129 + * @chainable 27.13130 + */ 27.13131 + RenderController.prototype.outOriginFrom = function outOriginFrom(origin) { 27.13132 + if (origin instanceof Function) this.outOriginMap = origin; 27.13133 + else if (origin && origin.get) this.outOriginMap = origin.get.bind(origin); 27.13134 + else throw new Error('inOriginFrom takes only function or getter object'); 27.13135 + //TODO: tween origin 27.13136 + return this; 27.13137 + }; 27.13138 + 27.13139 + /** 27.13140 + * Show displays the targeted renderable with a transition and an optional callback to 27.13141 + * execute afterwards. 27.13142 + * @method show 27.13143 + * @param {Object} renderable The renderable you want to show. 27.13144 + * @param {Transition} [transition] Overwrites the default transition in to display the 27.13145 + * passed-in renderable. 27.13146 + * @param {function} [callback] Executes after transitioning in the renderable. 27.13147 + * @chainable 27.13148 + */ 27.13149 + RenderController.prototype.show = function show(renderable, transition, callback) { 27.13150 + if (!renderable) { 27.13151 + return this.hide(callback); 27.13152 + } 27.13153 + 27.13154 + if (transition instanceof Function) { 27.13155 + callback = transition; 27.13156 + transition = null; 27.13157 + } 27.13158 + 27.13159 + if (this._showing >= 0) { 27.13160 + if (this.options.overlap) this.hide(); 27.13161 + else { 27.13162 + if (this._nextRenderable) { 27.13163 + this._nextRenderable = renderable; 27.13164 + } 27.13165 + else { 27.13166 + this._nextRenderable = renderable; 27.13167 + this.hide(function() { 27.13168 + if (this._nextRenderable === renderable) this.show(this._nextRenderable, callback); 27.13169 + this._nextRenderable = null; 27.13170 + }); 27.13171 + } 27.13172 + return undefined; 27.13173 + } 27.13174 + } 27.13175 + 27.13176 + var state = null; 27.13177 + 27.13178 + // check to see if we should restore 27.13179 + var renderableIndex = this._renderables.indexOf(renderable); 27.13180 + if (renderableIndex >= 0) { 27.13181 + this._showing = renderableIndex; 27.13182 + state = this._states[renderableIndex]; 27.13183 + state.halt(); 27.13184 + 27.13185 + var outgoingIndex = this._outgoingRenderables.indexOf(renderable); 27.13186 + if (outgoingIndex >= 0) this._outgoingRenderables.splice(outgoingIndex, 1); 27.13187 + } 27.13188 + else { 27.13189 + state = new Transitionable(0); 27.13190 + 27.13191 + var modifier = new Modifier({ 27.13192 + transform: this.inTransformMap ? _mappedState.bind(this, this.inTransformMap, state) : null, 27.13193 + opacity: this.inOpacityMap ? _mappedState.bind(this, this.inOpacityMap, state) : null, 27.13194 + origin: this.inOriginMap ? _mappedState.bind(this, this.inOriginMap, state) : null 27.13195 + }); 27.13196 + var node = new RenderNode(); 27.13197 + node.add(modifier).add(renderable); 27.13198 + 27.13199 + this._showing = this._nodes.length; 27.13200 + this._nodes.push(node); 27.13201 + this._modifiers.push(modifier); 27.13202 + this._states.push(state); 27.13203 + this._renderables.push(renderable); 27.13204 + } 27.13205 + 27.13206 + if (!transition) transition = this.options.inTransition; 27.13207 + state.set(1, transition, callback); 27.13208 + }; 27.13209 + 27.13210 + /** 27.13211 + * Hide hides the currently displayed renderable with an out transition. 27.13212 + * @method hide 27.13213 + * @param {Transition} [transition] Overwrites the default transition in to hide the 27.13214 + * currently controlled renderable. 27.13215 + * @param {function} [callback] Executes after transitioning out the renderable. 27.13216 + * @chainable 27.13217 + */ 27.13218 + RenderController.prototype.hide = function hide(transition, callback) { 27.13219 + if (this._showing < 0) return; 27.13220 + var index = this._showing; 27.13221 + this._showing = -1; 27.13222 + 27.13223 + if (transition instanceof Function) { 27.13224 + callback = transition; 27.13225 + transition = undefined; 27.13226 + } 27.13227 + 27.13228 + var node = this._nodes[index]; 27.13229 + var modifier = this._modifiers[index]; 27.13230 + var state = this._states[index]; 27.13231 + var renderable = this._renderables[index]; 27.13232 + 27.13233 + modifier.transformFrom(this.outTransformMap ? _mappedState.bind(this, this.outTransformMap, state) : null); 27.13234 + modifier.opacityFrom(this.outOpacityMap ? _mappedState.bind(this, this.outOpacityMap, state) : null); 27.13235 + modifier.originFrom(this.outOriginMap ? _mappedState.bind(this, this.outOriginMap, state) : null); 27.13236 + 27.13237 + if (this._outgoingRenderables.indexOf(renderable) < 0) this._outgoingRenderables.push(renderable); 27.13238 + 27.13239 + if (!transition) transition = this.options.outTransition; 27.13240 + state.halt(); 27.13241 + state.set(0, transition, function(node, modifier, state, renderable) { 27.13242 + if (this._outgoingRenderables.indexOf(renderable) >= 0) { 27.13243 + var index = this._nodes.indexOf(node); 27.13244 + this._nodes.splice(index, 1); 27.13245 + this._modifiers.splice(index, 1); 27.13246 + this._states.splice(index, 1); 27.13247 + this._renderables.splice(index, 1); 27.13248 + this._outgoingRenderables.splice(this._outgoingRenderables.indexOf(renderable), 1); 27.13249 + 27.13250 + if (this._showing >= index) this._showing--; 27.13251 + } 27.13252 + if (callback) callback.call(this); 27.13253 + }.bind(this, node, modifier, state, renderable)); 27.13254 + }; 27.13255 + 27.13256 + /** 27.13257 + * Generate a render spec from the contents of this component. 27.13258 + * 27.13259 + * @private 27.13260 + * @method render 27.13261 + * @return {number} Render spec for this component 27.13262 + */ 27.13263 + RenderController.prototype.render = function render() { 27.13264 + var result = this._output; 27.13265 + if (result.length > this._nodes.length) result.splice(this._nodes.length); 27.13266 + for (var i = 0; i < this._nodes.length; i++) { 27.13267 + result[i] = this._nodes[i].render(); 27.13268 + } 27.13269 + return result; 27.13270 + }; 27.13271 + 27.13272 + module.exports = RenderController; 27.13273 +}); 27.13274 + 27.13275 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.13276 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.13277 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.13278 + * 27.13279 + * Owner: felix@famo.us 27.13280 + * @license MPL 2.0 27.13281 + * @copyright Famous Industries, Inc. 2014 27.13282 + */ 27.13283 + 27.13284 +define('famous/views/EdgeSwapper',['require','exports','module','famous/transitions/CachedMap','famous/core/Entity','famous/core/EventHandler','famous/core/Transform','./RenderController'],function(require, exports, module) { 27.13285 + var CachedMap = require('famous/transitions/CachedMap'); 27.13286 + var Entity = require('famous/core/Entity'); 27.13287 + var EventHandler = require('famous/core/EventHandler'); 27.13288 + var Transform = require('famous/core/Transform'); 27.13289 + var RenderController = require('./RenderController'); 27.13290 + 27.13291 + /** 27.13292 + * Container which handles swapping renderables from the edge of its parent context. 27.13293 + * @class EdgeSwapper 27.13294 + * @constructor 27.13295 + * @param {Options} [options] An object of configurable options. 27.13296 + * Takes the same options as RenderController. 27.13297 + * @uses RenderController 27.13298 + */ 27.13299 + function EdgeSwapper(options) { 27.13300 + this._currentTarget = null; 27.13301 + this._size = [undefined, undefined]; 27.13302 + 27.13303 + this._controller = new RenderController(options); 27.13304 + this._controller.inTransformFrom(CachedMap.create(_transformMap.bind(this, 0.0001))); 27.13305 + this._controller.outTransformFrom(CachedMap.create(_transformMap.bind(this, -0.0001))); 27.13306 + 27.13307 + this._eventInput = new EventHandler(); 27.13308 + EventHandler.setInputHandler(this, this._eventInput); 27.13309 + 27.13310 + this._entityId = Entity.register(this); 27.13311 + if (options) this.setOptions(options); 27.13312 + } 27.13313 + 27.13314 + function _transformMap(zMax, progress) { 27.13315 + return Transform.translate(this._size[0] * (1 - progress), 0, zMax * (1 - progress)); 27.13316 + } 27.13317 + 27.13318 + /** 27.13319 + * Displays the passed-in content with the EdgeSwapper instance's default transition. 27.13320 + * 27.13321 + * @method show 27.13322 + * @param {Object} content The renderable you want to display. 27.13323 + */ 27.13324 + EdgeSwapper.prototype.show = function show(content) { 27.13325 + // stop sending input to old target 27.13326 + if (this._currentTarget) this._eventInput.unpipe(this._currentTarget); 27.13327 + 27.13328 + this._currentTarget = content; 27.13329 + 27.13330 + // start sending input to new target 27.13331 + if (this._currentTarget && this._currentTarget.trigger) this._eventInput.pipe(this._currentTarget); 27.13332 + 27.13333 + this._controller.show.apply(this._controller, arguments); 27.13334 + }; 27.13335 + 27.13336 + /** 27.13337 + * Patches the EdgeSwapper instance's options with the passed-in ones. 27.13338 + * 27.13339 + * @method setOptions 27.13340 + * @param {Options} options An object of configurable options for the Edgeswapper instance. 27.13341 + */ 27.13342 + EdgeSwapper.prototype.setOptions = function setOptions(options) { 27.13343 + this._controller.setOptions(options); 27.13344 + }; 27.13345 + 27.13346 + /** 27.13347 + * Generate a render spec from the contents of this component. 27.13348 + * 27.13349 + * @private 27.13350 + * @method render 27.13351 + * @return {number} Render spec for this component 27.13352 + */ 27.13353 + EdgeSwapper.prototype.render = function render() { 27.13354 + return this._entityId; 27.13355 + }; 27.13356 + 27.13357 + /** 27.13358 + * Apply changes from this component to the corresponding document element. 27.13359 + * This includes changes to classes, styles, size, content, opacity, origin, 27.13360 + * and matrix transforms. 27.13361 + * 27.13362 + * @private 27.13363 + * @method commit 27.13364 + * @param {Context} context commit context 27.13365 + */ 27.13366 + EdgeSwapper.prototype.commit = function commit(context) { 27.13367 + this._size[0] = context.size[0]; 27.13368 + this._size[1] = context.size[1]; 27.13369 + 27.13370 + return { 27.13371 + transform: context.transform, 27.13372 + opacity: context.opacity, 27.13373 + origin: context.origin, 27.13374 + size: context.size, 27.13375 + target: this._controller.render() 27.13376 + }; 27.13377 + }; 27.13378 + 27.13379 + module.exports = EdgeSwapper; 27.13380 +}); 27.13381 + 27.13382 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.13383 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.13384 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.13385 + * 27.13386 + * Owner: mike@famo.us 27.13387 + * @license MPL 2.0 27.13388 + * @copyright Famous Industries, Inc. 2014 27.13389 + */ 27.13390 + 27.13391 +define('famous/views/FlexibleLayout',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/OptionsManager','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) { 27.13392 + var Entity = require('famous/core/Entity'); 27.13393 + var Transform = require('famous/core/Transform'); 27.13394 + var OptionsManager = require('famous/core/OptionsManager'); 27.13395 + var EventHandler = require('famous/core/EventHandler'); 27.13396 + var Transitionable = require('famous/transitions/Transitionable'); 27.13397 + 27.13398 + /** 27.13399 + * A layout which divides a context into sections based on a proportion 27.13400 + * of the total sum of ratios. FlexibleLayout can either lay renderables 27.13401 + * out vertically or horizontally. 27.13402 + * @class FlexibleLayout 27.13403 + * @constructor 27.13404 + * @param {Options} [options] An object of configurable options. 27.13405 + * @param {Number} [options.direction=0] Direction the FlexibleLayout instance should lay out renderables. 27.13406 + * @param {Transition} [options.transition=false] The transiton that controls the FlexibleLayout instance's reflow. 27.13407 + * @param {Ratios} [options.ratios=[]] The proportions for the renderables to maintain 27.13408 + */ 27.13409 + function FlexibleLayout(options) { 27.13410 + this.options = Object.create(FlexibleLayout.DEFAULT_OPTIONS); 27.13411 + this.optionsManager = new OptionsManager(this.options); 27.13412 + if (options) this.setOptions(options); 27.13413 + 27.13414 + this.id = Entity.register(this); 27.13415 + 27.13416 + this._ratios = new Transitionable(this.options.ratios); 27.13417 + this._nodes = []; 27.13418 + 27.13419 + this._cachedDirection = null; 27.13420 + this._cachedTotalLength = false; 27.13421 + this._cachedLengths = []; 27.13422 + this._cachedTransforms = null; 27.13423 + this._ratiosDirty = false; 27.13424 + 27.13425 + this._eventOutput = new EventHandler(); 27.13426 + EventHandler.setOutputHandler(this, this._eventOutput); 27.13427 + } 27.13428 + 27.13429 + FlexibleLayout.DIRECTION_X = 0; 27.13430 + FlexibleLayout.DIRECTION_Y = 1; 27.13431 + 27.13432 + FlexibleLayout.DEFAULT_OPTIONS = { 27.13433 + direction: FlexibleLayout.DIRECTION_X, 27.13434 + transition: false, 27.13435 + ratios : [] 27.13436 + }; 27.13437 + 27.13438 + function _reflow(ratios, length, direction) { 27.13439 + var currTransform; 27.13440 + var translation = 0; 27.13441 + var flexLength = length; 27.13442 + var ratioSum = 0; 27.13443 + var ratio; 27.13444 + var node; 27.13445 + var i; 27.13446 + 27.13447 + this._cachedLengths = []; 27.13448 + this._cachedTransforms = []; 27.13449 + 27.13450 + for (i = 0; i < ratios.length; i++){ 27.13451 + ratio = ratios[i]; 27.13452 + node = this._nodes[i]; 27.13453 + 27.13454 + if (typeof ratio !== 'number') 27.13455 + flexLength -= node.getSize()[direction] || 0; 27.13456 + else 27.13457 + ratioSum += ratio; 27.13458 + } 27.13459 + 27.13460 + for (i = 0; i < ratios.length; i++) { 27.13461 + node = this._nodes[i]; 27.13462 + ratio = ratios[i]; 27.13463 + 27.13464 + length = (typeof ratio === 'number') 27.13465 + ? flexLength * ratio / ratioSum 27.13466 + : node.getSize()[direction]; 27.13467 + 27.13468 + currTransform = (direction === FlexibleLayout.DIRECTION_X) 27.13469 + ? Transform.translate(translation, 0, 0) 27.13470 + : Transform.translate(0, translation, 0); 27.13471 + 27.13472 + this._cachedTransforms.push(currTransform); 27.13473 + this._cachedLengths.push(length); 27.13474 + 27.13475 + translation += length; 27.13476 + } 27.13477 + } 27.13478 + 27.13479 + /** 27.13480 + * Generate a render spec from the contents of this component. 27.13481 + * 27.13482 + * @private 27.13483 + * @method render 27.13484 + * @return {Object} Render spec for this component 27.13485 + */ 27.13486 + FlexibleLayout.prototype.render = function render() { 27.13487 + return this.id; 27.13488 + }; 27.13489 + 27.13490 + /** 27.13491 + * Patches the FlexibleLayouts instance's options with the passed-in ones. 27.13492 + * 27.13493 + * @method setOptions 27.13494 + * @param {Options} options An object of configurable options for the FlexibleLayout instance. 27.13495 + */ 27.13496 + FlexibleLayout.prototype.setOptions = function setOptions(options) { 27.13497 + this.optionsManager.setOptions(options); 27.13498 + }; 27.13499 + 27.13500 + /** 27.13501 + * Sets the collection of renderables under the FlexibleLayout instance's control. Also sets 27.13502 + * the associated ratio values for sizing the renderables if given. 27.13503 + * 27.13504 + * @method sequenceFrom 27.13505 + * @param {Array} sequence An array of renderables. 27.13506 + */ 27.13507 + FlexibleLayout.prototype.sequenceFrom = function sequenceFrom(sequence) { 27.13508 + this._nodes = sequence; 27.13509 + 27.13510 + if (this._ratios.get().length === 0) { 27.13511 + var ratios = []; 27.13512 + for (var i = 0; i < this._nodes.length; i++) ratios.push(1); 27.13513 + this.setRatios(ratios); 27.13514 + } 27.13515 + }; 27.13516 + 27.13517 + /** 27.13518 + * Sets the associated ratio values for sizing the renderables. 27.13519 + * 27.13520 + * @method setRatios 27.13521 + * @param {Array} ratios Array of ratios corresponding to the percentage sizes each renderable should be 27.13522 + */ 27.13523 + FlexibleLayout.prototype.setRatios = function setRatios(ratios, transition, callback) { 27.13524 + if (transition === undefined) transition = this.options.transition; 27.13525 + var currRatios = this._ratios; 27.13526 + if (currRatios.get().length === 0) transition = undefined; 27.13527 + if (currRatios.isActive()) currRatios.halt(); 27.13528 + currRatios.set(ratios, transition, callback); 27.13529 + this._ratiosDirty = true; 27.13530 + }; 27.13531 + 27.13532 + /** 27.13533 + * Apply changes from this component to the corresponding document element. 27.13534 + * This includes changes to classes, styles, size, content, opacity, origin, 27.13535 + * and matrix transforms. 27.13536 + * 27.13537 + * @private 27.13538 + * @method commit 27.13539 + * @param {Context} context commit context 27.13540 + */ 27.13541 + FlexibleLayout.prototype.commit = function commit(context) { 27.13542 + var parentSize = context.size; 27.13543 + var parentTransform = context.transform; 27.13544 + var parentOrigin = context.origin; 27.13545 + 27.13546 + var ratios = this._ratios.get(); 27.13547 + var direction = this.options.direction; 27.13548 + var length = parentSize[direction]; 27.13549 + var size; 27.13550 + 27.13551 + if (length !== this._cachedTotalLength || this._ratiosDirty || this._ratios.isActive() || direction !== this._cachedDirection) { 27.13552 + _reflow.call(this, ratios, length, direction); 27.13553 + 27.13554 + if (length !== this._cachedTotalLength) this._cachedTotalLength = length; 27.13555 + if (direction !== this._cachedDirection) this._cachedDirection = direction; 27.13556 + if (this._ratiosDirty) this._ratiosDirty = false; 27.13557 + } 27.13558 + 27.13559 + var result = []; 27.13560 + for (var i = 0; i < ratios.length; i++) { 27.13561 + size = [undefined, undefined]; 27.13562 + length = this._cachedLengths[i]; 27.13563 + size[direction] = length; 27.13564 + result.push({ 27.13565 + transform : this._cachedTransforms[i], 27.13566 + size: size, 27.13567 + target : this._nodes[i].render() 27.13568 + }); 27.13569 + } 27.13570 + 27.13571 + if (parentSize && (parentOrigin[0] !== 0 && parentOrigin[1] !== 0)) 27.13572 + parentTransform = Transform.moveThen([-parentSize[0]*parentOrigin[0], -parentSize[1]*parentOrigin[1], 0], parentTransform); 27.13573 + 27.13574 + return { 27.13575 + transform: parentTransform, 27.13576 + size: parentSize, 27.13577 + target: result 27.13578 + }; 27.13579 + }; 27.13580 + 27.13581 + module.exports = FlexibleLayout; 27.13582 +}); 27.13583 + 27.13584 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.13585 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.13586 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.13587 + * 27.13588 + * Owner: felix@famo.us 27.13589 + * @license MPL 2.0 27.13590 + * @copyright Famous Industries, Inc. 2014 27.13591 + */ 27.13592 + 27.13593 +define('famous/views/Flipper',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/RenderNode','famous/core/OptionsManager'],function(require, exports, module) { 27.13594 + var Transform = require('famous/core/Transform'); 27.13595 + var Transitionable = require('famous/transitions/Transitionable'); 27.13596 + var RenderNode = require('famous/core/RenderNode'); 27.13597 + var OptionsManager = require('famous/core/OptionsManager'); 27.13598 + 27.13599 + /** 27.13600 + * Allows you to link two renderables as front and back sides that can be 27.13601 + * 'flipped' back and forth along a chosen axis. Rendering optimizations are 27.13602 + * automatically handled. 27.13603 + * 27.13604 + * @class Flipper 27.13605 + * @constructor 27.13606 + * @param {Options} [options] An object of options. 27.13607 + * @param {Transition} [options.transition=true] The transition executed when flipping your Flipper instance. 27.13608 + */ 27.13609 + function Flipper(options) { 27.13610 + this.options = Object.create(Flipper.DEFAULT_OPTIONS); 27.13611 + this._optionsManager = new OptionsManager(this.options); 27.13612 + if (options) this.setOptions(options); 27.13613 + 27.13614 + this.angle = new Transitionable(0); 27.13615 + 27.13616 + this.frontNode = undefined; 27.13617 + this.backNode = undefined; 27.13618 + 27.13619 + this.flipped = false; 27.13620 + } 27.13621 + 27.13622 + Flipper.DIRECTION_X = 0; 27.13623 + Flipper.DIRECTION_Y = 1; 27.13624 + 27.13625 + var SEPERATION_LENGTH = 1; 27.13626 + 27.13627 + Flipper.DEFAULT_OPTIONS = { 27.13628 + transition: true, 27.13629 + direction: Flipper.DIRECTION_X 27.13630 + }; 27.13631 + 27.13632 + /** 27.13633 + * Toggles the rotation between the front and back renderables 27.13634 + * 27.13635 + * @method flip 27.13636 + * @param {Object} [transition] Transition definition 27.13637 + * @param {Function} [callback] Callback 27.13638 + */ 27.13639 + Flipper.prototype.flip = function flip(transition, callback) { 27.13640 + var angle = this.flipped ? 0 : Math.PI; 27.13641 + this.setAngle(angle, transition, callback); 27.13642 + this.flipped = !this.flipped; 27.13643 + }; 27.13644 + 27.13645 + /** 27.13646 + * Basic setter to the angle 27.13647 + * 27.13648 + * @method setAngle 27.13649 + * @param {Number} angle 27.13650 + * @param {Object} [transition] Transition definition 27.13651 + * @param {Function} [callback] Callback 27.13652 + */ 27.13653 + Flipper.prototype.setAngle = function setAngle(angle, transition, callback) { 27.13654 + if (transition === undefined) transition = this.options.transition; 27.13655 + if (this.angle.isActive()) this.angle.halt(); 27.13656 + this.angle.set(angle, transition, callback); 27.13657 + }; 27.13658 + 27.13659 + /** 27.13660 + * Patches the Flipper instance's options with the passed-in ones. 27.13661 + * 27.13662 + * @method setOptions 27.13663 + * @param {Options} options An object of configurable options for the Flipper instance. 27.13664 + */ 27.13665 + Flipper.prototype.setOptions = function setOptions(options) { 27.13666 + return this._optionsManager.setOptions(options); 27.13667 + }; 27.13668 + 27.13669 + /** 27.13670 + * Adds the passed-in renderable to the view associated with the 'front' of the Flipper instance. 27.13671 + * 27.13672 + * @method setFront 27.13673 + * @chainable 27.13674 + * @param {Object} node The renderable you want to add to the front. 27.13675 + */ 27.13676 + Flipper.prototype.setFront = function setFront(node) { 27.13677 + this.frontNode = node; 27.13678 + }; 27.13679 + 27.13680 + /** 27.13681 + * Adds the passed-in renderable to the view associated with the 'back' of the Flipper instance. 27.13682 + * 27.13683 + * @method setBack 27.13684 + * @chainable 27.13685 + * @param {Object} node The renderable you want to add to the back. 27.13686 + */ 27.13687 + Flipper.prototype.setBack = function setBack(node) { 27.13688 + this.backNode = node; 27.13689 + }; 27.13690 + 27.13691 + /** 27.13692 + * Generate a render spec from the contents of this component. 27.13693 + * 27.13694 + * @private 27.13695 + * @method render 27.13696 + * @return {Number} Render spec for this component 27.13697 + */ 27.13698 + Flipper.prototype.render = function render() { 27.13699 + var angle = this.angle.get(); 27.13700 + 27.13701 + var frontTransform; 27.13702 + var backTransform; 27.13703 + 27.13704 + if (this.options.direction === Flipper.DIRECTION_X) { 27.13705 + frontTransform = Transform.rotateY(angle); 27.13706 + backTransform = Transform.rotateY(angle + Math.PI); 27.13707 + } 27.13708 + else { 27.13709 + frontTransform = Transform.rotateX(angle); 27.13710 + backTransform = Transform.rotateX(angle + Math.PI); 27.13711 + } 27.13712 + 27.13713 + var result = []; 27.13714 + if (this.frontNode){ 27.13715 + result.push({ 27.13716 + transform: frontTransform, 27.13717 + target: this.frontNode.render() 27.13718 + }); 27.13719 + } 27.13720 + 27.13721 + if (this.backNode){ 27.13722 + result.push({ 27.13723 + transform: Transform.moveThen([0, 0, SEPERATION_LENGTH], backTransform), 27.13724 + target: this.backNode.render() 27.13725 + }); 27.13726 + } 27.13727 + 27.13728 + return result; 27.13729 + }; 27.13730 + 27.13731 + module.exports = Flipper; 27.13732 +}); 27.13733 + 27.13734 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.13735 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.13736 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.13737 + * 27.13738 + * Owner: felix@famo.us 27.13739 + * @license MPL 2.0 27.13740 + * @copyright Famous Industries, Inc. 2014 27.13741 + */ 27.13742 + 27.13743 +define('famous/views/GridLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/ViewSequence','famous/core/EventHandler','famous/core/Modifier','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 27.13744 + var Entity = require('famous/core/Entity'); 27.13745 + var RenderNode = require('famous/core/RenderNode'); 27.13746 + var Transform = require('famous/core/Transform'); 27.13747 + var ViewSequence = require('famous/core/ViewSequence'); 27.13748 + var EventHandler = require('famous/core/EventHandler'); 27.13749 + var Modifier = require('famous/core/Modifier'); 27.13750 + var OptionsManager = require('famous/core/OptionsManager'); 27.13751 + var Transitionable = require('famous/transitions/Transitionable'); 27.13752 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 27.13753 + 27.13754 + /** 27.13755 + * A layout which divides a context into several evenly-sized grid cells. 27.13756 + * If dimensions are provided, the grid is evenly subdivided with children 27.13757 + * cells representing their own context, otherwise the cellSize property is used to compute 27.13758 + * dimensions so that items of cellSize will fit. 27.13759 + * @class GridLayout 27.13760 + * @constructor 27.13761 + * @param {Options} [options] An object of configurable options. 27.13762 + * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns 27.13763 + * and rows in your Gridlayout instance. 27.13764 + * @param {Array.Number} [options.cellSize=[250, 250]] A two-value array which specifies the width and height 27.13765 + * of each cell in your Gridlayout instance. 27.13766 + * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow. 27.13767 + */ 27.13768 + function GridLayout(options) { 27.13769 + this.options = Object.create(GridLayout.DEFAULT_OPTIONS); 27.13770 + this.optionsManager = new OptionsManager(this.options); 27.13771 + if (options) this.setOptions(options); 27.13772 + 27.13773 + this.id = Entity.register(this); 27.13774 + 27.13775 + this._modifiers = []; 27.13776 + this._states = []; 27.13777 + this._contextSizeCache = [0, 0]; 27.13778 + this._dimensionsCache = [0, 0]; 27.13779 + this._activeCount = 0; 27.13780 + 27.13781 + this._eventOutput = new EventHandler(); 27.13782 + EventHandler.setOutputHandler(this, this._eventOutput); 27.13783 + } 27.13784 + 27.13785 + function _reflow(size, cols, rows) { 27.13786 + var usableSize = [size[0], size[1]]; 27.13787 + usableSize[0] -= this.options.gutterSize[0] * (cols - 1); 27.13788 + usableSize[1] -= this.options.gutterSize[1] * (rows - 1); 27.13789 + 27.13790 + var rowSize = Math.round(usableSize[1] / rows); 27.13791 + var colSize = Math.round(usableSize[0] / cols); 27.13792 + 27.13793 + var currY = 0; 27.13794 + var currX; 27.13795 + var currIndex = 0; 27.13796 + for (var i = 0; i < rows; i++) { 27.13797 + currX = 0; 27.13798 + for (var j = 0; j < cols; j++) { 27.13799 + if (this._modifiers[currIndex] === undefined) { 27.13800 + _createModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1); 27.13801 + } 27.13802 + else { 27.13803 + _animateModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1); 27.13804 + } 27.13805 + 27.13806 + currIndex++; 27.13807 + currX += colSize + this.options.gutterSize[0]; 27.13808 + } 27.13809 + 27.13810 + currY += rowSize + this.options.gutterSize[1]; 27.13811 + } 27.13812 + 27.13813 + this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]]; 27.13814 + this._contextSizeCache = [size[0], size[1]]; 27.13815 + 27.13816 + this._activeCount = rows * cols; 27.13817 + 27.13818 + for (i = this._activeCount ; i < this._modifiers.length; i++) _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0); 27.13819 + 27.13820 + this._eventOutput.emit('reflow'); 27.13821 + } 27.13822 + 27.13823 + function _createModifier(index, size, position, opacity) { 27.13824 + var transitionItem = { 27.13825 + transform: new TransitionableTransform(Transform.translate.apply(null, position)), 27.13826 + opacity: new Transitionable(opacity), 27.13827 + size: new Transitionable(size) 27.13828 + }; 27.13829 + 27.13830 + var modifier = new Modifier({ 27.13831 + transform: transitionItem.transform, 27.13832 + opacity: transitionItem.opacity, 27.13833 + size: transitionItem.size 27.13834 + }); 27.13835 + 27.13836 + this._states[index] = transitionItem; 27.13837 + this._modifiers[index] = modifier; 27.13838 + 27.13839 + } 27.13840 + 27.13841 + function _animateModifier(index, size, position, opacity) { 27.13842 + var currState = this._states[index]; 27.13843 + 27.13844 + var currSize = currState.size; 27.13845 + var currOpacity = currState.opacity; 27.13846 + var currTransform = currState.transform; 27.13847 + 27.13848 + var transition = this.options.transition; 27.13849 + 27.13850 + currTransform.halt(); 27.13851 + currOpacity.halt(); 27.13852 + currSize.halt(); 27.13853 + 27.13854 + currTransform.setTranslate(position, transition); 27.13855 + currSize.set(size, transition); 27.13856 + currOpacity.set(opacity, transition); 27.13857 + } 27.13858 + 27.13859 + GridLayout.DEFAULT_OPTIONS = { 27.13860 + dimensions: [1, 1], 27.13861 + transition: false, 27.13862 + gutterSize: [0, 0] 27.13863 + }; 27.13864 + 27.13865 + /** 27.13866 + * Generate a render spec from the contents of this component. 27.13867 + * 27.13868 + * @private 27.13869 + * @method render 27.13870 + * @return {Object} Render spec for this component 27.13871 + */ 27.13872 + GridLayout.prototype.render = function render() { 27.13873 + return this.id; 27.13874 + }; 27.13875 + 27.13876 + /** 27.13877 + * Patches the GridLayout instance's options with the passed-in ones. 27.13878 + * 27.13879 + * @method setOptions 27.13880 + * @param {Options} options An object of configurable options for the GridLayout instance. 27.13881 + */ 27.13882 + GridLayout.prototype.setOptions = function setOptions(options) { 27.13883 + return this.optionsManager.setOptions(options); 27.13884 + }; 27.13885 + 27.13886 + /** 27.13887 + * Sets the collection of renderables under the Gridlayout instance's control. 27.13888 + * 27.13889 + * @method sequenceFrom 27.13890 + * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence. 27.13891 + */ 27.13892 + GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) { 27.13893 + if (sequence instanceof Array) sequence = new ViewSequence(sequence); 27.13894 + this.sequence = sequence; 27.13895 + }; 27.13896 + 27.13897 + /** 27.13898 + * Apply changes from this component to the corresponding document element. 27.13899 + * This includes changes to classes, styles, size, content, opacity, origin, 27.13900 + * and matrix transforms. 27.13901 + * 27.13902 + * @private 27.13903 + * @method commit 27.13904 + * @param {Context} context commit context 27.13905 + */ 27.13906 + GridLayout.prototype.commit = function commit(context) { 27.13907 + var transform = context.transform; 27.13908 + var opacity = context.opacity; 27.13909 + var origin = context.origin; 27.13910 + var size = context.size; 27.13911 + 27.13912 + var cols = this.options.dimensions[0]; 27.13913 + var rows = this.options.dimensions[1]; 27.13914 + 27.13915 + if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) { 27.13916 + _reflow.call(this, size, cols, rows); 27.13917 + } 27.13918 + 27.13919 + var sequence = this.sequence; 27.13920 + var result = []; 27.13921 + var currIndex = 0; 27.13922 + while (sequence && (currIndex < this._modifiers.length)) { 27.13923 + var item = sequence.get(); 27.13924 + var modifier = this._modifiers[currIndex]; 27.13925 + if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) { 27.13926 + this._modifiers.splice(currIndex, 1); 27.13927 + this._states.splice(currIndex, 1); 27.13928 + } 27.13929 + if (item) { 27.13930 + result.push( 27.13931 + modifier.modify({ 27.13932 + origin: origin, 27.13933 + target: item.render() 27.13934 + }) 27.13935 + ); 27.13936 + } 27.13937 + sequence = sequence.getNext(); 27.13938 + currIndex++; 27.13939 + } 27.13940 + 27.13941 + if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform); 27.13942 + return { 27.13943 + transform: transform, 27.13944 + opacity: opacity, 27.13945 + size: size, 27.13946 + target: result 27.13947 + }; 27.13948 + }; 27.13949 + 27.13950 + module.exports = GridLayout; 27.13951 +}); 27.13952 + 27.13953 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.13954 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.13955 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.13956 + * 27.13957 + * Owner: felix@famo.us 27.13958 + * @license MPL 2.0 27.13959 + * @copyright Famous Industries, Inc. 2014 27.13960 + */ 27.13961 + 27.13962 +define('famous/views/HeaderFooterLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/OptionsManager'],function(require, exports, module) { 27.13963 + var Entity = require('famous/core/Entity'); 27.13964 + var RenderNode = require('famous/core/RenderNode'); 27.13965 + var Transform = require('famous/core/Transform'); 27.13966 + var OptionsManager = require('famous/core/OptionsManager'); 27.13967 + 27.13968 + /** 27.13969 + * A layout which will arrange three renderables into a header and footer area of defined size, 27.13970 + and a content area of flexible size. 27.13971 + * @class HeaderFooterLayout 27.13972 + * @constructor 27.13973 + * @param {Options} [options] An object of configurable options. 27.13974 + * @param {Number} [options.direction=HeaderFooterLayout.DIRECTION_Y] A direction of HeaderFooterLayout.DIRECTION_X 27.13975 + * lays your HeaderFooterLayout instance horizontally, and a direction of HeaderFooterLayout.DIRECTION_Y 27.13976 + * lays it out vertically. 27.13977 + * @param {Number} [options.headerSize=undefined] The amount of pixels allocated to the header node 27.13978 + * in the HeaderFooterLayout instance's direction. 27.13979 + * @param {Number} [options.footerSize=undefined] The amount of pixels allocated to the footer node 27.13980 + * in the HeaderFooterLayout instance's direction. 27.13981 + */ 27.13982 + function HeaderFooterLayout(options) { 27.13983 + this.options = Object.create(HeaderFooterLayout.DEFAULT_OPTIONS); 27.13984 + this._optionsManager = new OptionsManager(this.options); 27.13985 + if (options) this.setOptions(options); 27.13986 + 27.13987 + this._entityId = Entity.register(this); 27.13988 + 27.13989 + this.header = new RenderNode(); 27.13990 + this.footer = new RenderNode(); 27.13991 + this.content = new RenderNode(); 27.13992 + } 27.13993 + 27.13994 + /** 27.13995 + * When used as a value for your HeaderFooterLayout's direction option, causes it to lay out horizontally. 27.13996 + * 27.13997 + * @attribute DIRECTION_X 27.13998 + * @type Number 27.13999 + * @static 27.14000 + * @default 0 27.14001 + * @protected 27.14002 + */ 27.14003 + HeaderFooterLayout.DIRECTION_X = 0; 27.14004 + 27.14005 + /** 27.14006 + * When used as a value for your HeaderFooterLayout's direction option, causes it to lay out vertically. 27.14007 + * 27.14008 + * @attribute DIRECTION_Y 27.14009 + * @type Number 27.14010 + * @static 27.14011 + * @default 1 27.14012 + * @protected 27.14013 + */ 27.14014 + HeaderFooterLayout.DIRECTION_Y = 1; 27.14015 + 27.14016 + HeaderFooterLayout.DEFAULT_OPTIONS = { 27.14017 + direction: HeaderFooterLayout.DIRECTION_Y, 27.14018 + headerSize: undefined, 27.14019 + footerSize: undefined, 27.14020 + defaultHeaderSize: 0, 27.14021 + defaultFooterSize: 0 27.14022 + }; 27.14023 + 27.14024 + /** 27.14025 + * Generate a render spec from the contents of this component. 27.14026 + * 27.14027 + * @private 27.14028 + * @method render 27.14029 + * @return {Object} Render spec for this component 27.14030 + */ 27.14031 + HeaderFooterLayout.prototype.render = function render() { 27.14032 + return this._entityId; 27.14033 + }; 27.14034 + 27.14035 + /** 27.14036 + * Patches the HeaderFooterLayout instance's options with the passed-in ones. 27.14037 + * 27.14038 + * @method setOptions 27.14039 + * @param {Options} options An object of configurable options for the HeaderFooterLayout instance. 27.14040 + */ 27.14041 + HeaderFooterLayout.prototype.setOptions = function setOptions(options) { 27.14042 + return this._optionsManager.setOptions(options); 27.14043 + }; 27.14044 + 27.14045 + function _resolveNodeSize(node, defaultSize) { 27.14046 + var nodeSize = node.getSize(); 27.14047 + return nodeSize ? nodeSize[this.options.direction] : defaultSize; 27.14048 + } 27.14049 + 27.14050 + function _outputTransform(offset) { 27.14051 + if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return Transform.translate(offset, 0, 0); 27.14052 + else return Transform.translate(0, offset, 0); 27.14053 + } 27.14054 + 27.14055 + function _finalSize(directionSize, size) { 27.14056 + if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return [directionSize, size[1]]; 27.14057 + else return [size[0], directionSize]; 27.14058 + } 27.14059 + 27.14060 + /** 27.14061 + * Apply changes from this component to the corresponding document element. 27.14062 + * This includes changes to classes, styles, size, content, opacity, origin, 27.14063 + * and matrix transforms. 27.14064 + * 27.14065 + * @private 27.14066 + * @method commit 27.14067 + * @param {Context} context commit context 27.14068 + */ 27.14069 + HeaderFooterLayout.prototype.commit = function commit(context) { 27.14070 + var transform = context.transform; 27.14071 + var origin = context.origin; 27.14072 + var size = context.size; 27.14073 + var opacity = context.opacity; 27.14074 + 27.14075 + var headerSize = (this.options.headerSize !== undefined) ? this.options.headerSize : _resolveNodeSize.call(this, this.header, this.options.defaultHeaderSize); 27.14076 + var footerSize = (this.options.footerSize !== undefined) ? this.options.footerSize : _resolveNodeSize.call(this, this.footer, this.options.defaultFooterSize); 27.14077 + var contentSize = size[this.options.direction] - headerSize - footerSize; 27.14078 + 27.14079 + if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform); 27.14080 + 27.14081 + var result = [ 27.14082 + { 27.14083 + size: _finalSize.call(this, headerSize, size), 27.14084 + target: this.header.render() 27.14085 + }, 27.14086 + { 27.14087 + transform: _outputTransform.call(this, headerSize), 27.14088 + size: _finalSize.call(this, contentSize, size), 27.14089 + target: this.content.render() 27.14090 + }, 27.14091 + { 27.14092 + transform: _outputTransform.call(this, headerSize + contentSize), 27.14093 + size: _finalSize.call(this, footerSize, size), 27.14094 + target: this.footer.render() 27.14095 + } 27.14096 + ]; 27.14097 + 27.14098 + return { 27.14099 + transform: transform, 27.14100 + opacity: opacity, 27.14101 + size: size, 27.14102 + target: result 27.14103 + }; 27.14104 + }; 27.14105 + 27.14106 + module.exports = HeaderFooterLayout; 27.14107 +}); 27.14108 + 27.14109 +define('famous/views/Lightbox',['require','exports','module','famous/core/Transform','famous/core/Modifier','famous/core/RenderNode','famous/utilities/Utility','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 27.14110 + var Transform = require('famous/core/Transform'); 27.14111 + var Modifier = require('famous/core/Modifier'); 27.14112 + var RenderNode = require('famous/core/RenderNode'); 27.14113 + var Utility = require('famous/utilities/Utility'); 27.14114 + var OptionsManager = require('famous/core/OptionsManager'); 27.14115 + var Transitionable = require('famous/transitions/Transitionable'); 27.14116 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 27.14117 + 27.14118 + /** 27.14119 + * Lightbox, using transitions, shows and hides different renderables. Lightbox can essentially be 27.14120 + * thought of as RenderController with a stateful implementation and interface. 27.14121 + * 27.14122 + * @class Lightbox 27.14123 + * @constructor 27.14124 + * @param {Options} [options] An object of configurable options. 27.14125 + * @param {Transform} [options.inTransform] The transform at the start of transitioning in a shown renderable. 27.14126 + * @param {Transform} [options.outTransform] The transform at the end of transitioning out a renderable. 27.14127 + * @param {Transform} [options.showTransform] The transform applied to your shown renderable in its state of equilibrium. 27.14128 + * @param {Number} [options.inOpacity] A number between one and zero that defines the state of a shown renderables opacity upon initially 27.14129 + * being transitioned in. 27.14130 + * @param {Number} [options.outOpacity] A number between one and zero that defines the state of a shown renderables opacity upon being 27.14131 + * fully transitioned out. 27.14132 + * @param {Number} [options.showOpacity] A number between one and zero that defines the state of a shown renderables opacity 27.14133 + * once succesfully transitioned in. 27.14134 + * @param {Array<Number>} [options.inOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables 27.14135 + * origin upon intially being transitioned in. 27.14136 + * @param {Array<Number>} [options.outOrigin] A two value array of numbers between one and zero that defines the state of a shown renderable 27.14137 + * once fully hidden. 27.14138 + * @param {Array<Number>} [options.showOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables 27.14139 + * origin upon succesfully being shown. 27.14140 + * @param {Transition} [options.inTransition=true] The transition in charge of showing a renderable. 27.14141 + * @param {Transition} [options.outTransition=true] The transition in charge of removing your previous renderable when 27.14142 + * you show a new one, or hiding your current renderable. 27.14143 + * @param {Boolean} [options.overlap=false] When showing a new renderable, overlap determines if the 27.14144 + * out transition of the old one executes concurrently with the in transition of the new one, 27.14145 + * or synchronously beforehand. 27.14146 + */ 27.14147 + function Lightbox(options) { 27.14148 + this.options = Object.create(Lightbox.DEFAULT_OPTIONS); 27.14149 + this._optionsManager = new OptionsManager(this.options); 27.14150 + 27.14151 + if (options) this.setOptions(options); 27.14152 + 27.14153 + this._showing = false; 27.14154 + this.nodes = []; 27.14155 + this.transforms = []; 27.14156 + this.states = []; 27.14157 + } 27.14158 + 27.14159 + Lightbox.DEFAULT_OPTIONS = { 27.14160 + inTransform: Transform.scale(0.001, 0.001, 0.001), 27.14161 + inOpacity: 0, 27.14162 + inOrigin: [0.5, 0.5], 27.14163 + outTransform: Transform.scale(0.001, 0.001, 0.001), 27.14164 + outOpacity: 0, 27.14165 + outOrigin: [0.5, 0.5], 27.14166 + showTransform: Transform.identity, 27.14167 + showOpacity: 1, 27.14168 + showOrigin: [0.5, 0.5], 27.14169 + inTransition: true, 27.14170 + outTransition: true, 27.14171 + overlap: false 27.14172 + }; 27.14173 + 27.14174 + /** 27.14175 + * Patches the Lightbox instance's options with the passed-in ones. 27.14176 + * 27.14177 + * @method setOptions 27.14178 + * @param {Options} options An object of configurable options for the Lightbox instance. 27.14179 + */ 27.14180 + Lightbox.prototype.setOptions = function setOptions(options) { 27.14181 + return this._optionsManager.setOptions(options); 27.14182 + }; 27.14183 + 27.14184 + /** 27.14185 + * Show displays the targeted renderable with a transition and an optional callback to 27.14186 + * execute afterwards. 27.14187 + * @method show 27.14188 + * @param {Object} renderable The renderable you want to show. 27.14189 + * @param {Transition} [transition] Overwrites the default transition in to display the 27.14190 + * passed-in renderable. 27.14191 + * @param {function} [callback] Executes after transitioning in the renderable. 27.14192 + */ 27.14193 + Lightbox.prototype.show = function show(renderable, transition, callback) { 27.14194 + if (!renderable) { 27.14195 + return this.hide(callback); 27.14196 + } 27.14197 + 27.14198 + if (transition instanceof Function) { 27.14199 + callback = transition; 27.14200 + transition = undefined; 27.14201 + } 27.14202 + 27.14203 + if (this._showing) { 27.14204 + if (this.options.overlap) this.hide(); 27.14205 + else { 27.14206 + return this.hide(this.show.bind(this, renderable, transition, callback)); 27.14207 + } 27.14208 + } 27.14209 + this._showing = true; 27.14210 + 27.14211 + var stateItem = { 27.14212 + transform: new TransitionableTransform(this.options.inTransform), 27.14213 + origin: new Transitionable(this.options.inOrigin), 27.14214 + opacity: new Transitionable(this.options.inOpacity) 27.14215 + }; 27.14216 + 27.14217 + var transform = new Modifier({ 27.14218 + transform: stateItem.transform, 27.14219 + opacity: stateItem.opacity, 27.14220 + origin: stateItem.origin 27.14221 + }); 27.14222 + var node = new RenderNode(); 27.14223 + node.add(transform).add(renderable); 27.14224 + this.nodes.push(node); 27.14225 + this.states.push(stateItem); 27.14226 + this.transforms.push(transform); 27.14227 + 27.14228 + var _cb = callback ? Utility.after(3, callback) : undefined; 27.14229 + 27.14230 + if (!transition) transition = this.options.inTransition; 27.14231 + stateItem.transform.set(this.options.showTransform, transition, _cb); 27.14232 + stateItem.opacity.set(this.options.showOpacity, transition, _cb); 27.14233 + stateItem.origin.set(this.options.showOrigin, transition, _cb); 27.14234 + }; 27.14235 + 27.14236 + /** 27.14237 + * Hide hides the currently displayed renderable with an out transition. 27.14238 + * @method hide 27.14239 + * @param {Transition} [transition] Overwrites the default transition in to hide the 27.14240 + * currently controlled renderable. 27.14241 + * @param {function} [callback] Executes after transitioning out the renderable. 27.14242 + */ 27.14243 + Lightbox.prototype.hide = function hide(transition, callback) { 27.14244 + if (!this._showing) return; 27.14245 + this._showing = false; 27.14246 + 27.14247 + if (transition instanceof Function) { 27.14248 + callback = transition; 27.14249 + transition = undefined; 27.14250 + } 27.14251 + 27.14252 + var node = this.nodes[this.nodes.length - 1]; 27.14253 + var transform = this.transforms[this.transforms.length - 1]; 27.14254 + var stateItem = this.states[this.states.length - 1]; 27.14255 + var _cb = Utility.after(3, function() { 27.14256 + this.nodes.splice(this.nodes.indexOf(node), 1); 27.14257 + this.states.splice(this.states.indexOf(stateItem), 1); 27.14258 + this.transforms.splice(this.transforms.indexOf(transform), 1); 27.14259 + if (callback) callback.call(this); 27.14260 + }.bind(this)); 27.14261 + 27.14262 + if (!transition) transition = this.options.outTransition; 27.14263 + stateItem.transform.set(this.options.outTransform, transition, _cb); 27.14264 + stateItem.opacity.set(this.options.outOpacity, transition, _cb); 27.14265 + stateItem.origin.set(this.options.outOrigin, transition, _cb); 27.14266 + }; 27.14267 + 27.14268 + /** 27.14269 + * Generate a render spec from the contents of this component. 27.14270 + * 27.14271 + * @private 27.14272 + * @method render 27.14273 + * @return {number} Render spec for this component 27.14274 + */ 27.14275 + Lightbox.prototype.render = function render() { 27.14276 + var result = []; 27.14277 + for (var i = 0; i < this.nodes.length; i++) { 27.14278 + result.push(this.nodes[i].render()); 27.14279 + } 27.14280 + return result; 27.14281 + }; 27.14282 + 27.14283 + module.exports = Lightbox; 27.14284 +}); 27.14285 + 27.14286 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.14287 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.14288 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.14289 + * 27.14290 + * Owner: david@famo.us 27.14291 + * @license MPL 2.0 27.14292 + * @copyright Famous Industries, Inc. 2014 27.14293 + */ 27.14294 + 27.14295 +define('famous/physics/forces/Drag',['require','exports','module','./Force'],function(require, exports, module) { 27.14296 + var Force = require('./Force'); 27.14297 + 27.14298 + /** 27.14299 + * Drag is a force that opposes velocity. Attach it to the physics engine 27.14300 + * to slow down a physics body in motion. 27.14301 + * 27.14302 + * @class Drag 27.14303 + * @constructor 27.14304 + * @extends Force 27.14305 + * @param {Object} options options to set on drag 27.14306 + */ 27.14307 + function Drag(options) { 27.14308 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.14309 + if (options) this.setOptions(options); 27.14310 + 27.14311 + Force.call(this); 27.14312 + } 27.14313 + 27.14314 + Drag.prototype = Object.create(Force.prototype); 27.14315 + Drag.prototype.constructor = Drag; 27.14316 + 27.14317 + /** 27.14318 + * @property Drag.FORCE_FUNCTIONS 27.14319 + * @type Object 27.14320 + * @protected 27.14321 + * @static 27.14322 + */ 27.14323 + Drag.FORCE_FUNCTIONS = { 27.14324 + 27.14325 + /** 27.14326 + * A drag force proportional to the velocity 27.14327 + * @attribute LINEAR 27.14328 + * @type Function 27.14329 + * @param {Vector} velocity 27.14330 + * @return {Vector} drag force 27.14331 + */ 27.14332 + LINEAR : function(velocity) { 27.14333 + return velocity; 27.14334 + }, 27.14335 + 27.14336 + /** 27.14337 + * A drag force proportional to the square of the velocity 27.14338 + * @attribute QUADRATIC 27.14339 + * @type Function 27.14340 + * @param {Vector} velocity 27.14341 + * @return {Vector} drag force 27.14342 + */ 27.14343 + QUADRATIC : function(velocity) { 27.14344 + return velocity.mult(velocity.norm()); 27.14345 + } 27.14346 + }; 27.14347 + 27.14348 + /** 27.14349 + * @property Drag.DEFAULT_OPTIONS 27.14350 + * @type Object 27.14351 + * @protected 27.14352 + * @static 27.14353 + */ 27.14354 + Drag.DEFAULT_OPTIONS = { 27.14355 + 27.14356 + /** 27.14357 + * The strength of the force 27.14358 + * Range : [0, 0.1] 27.14359 + * @attribute strength 27.14360 + * @type Number 27.14361 + * @default 0.01 27.14362 + */ 27.14363 + strength : 0.01, 27.14364 + 27.14365 + /** 27.14366 + * The type of opposing force 27.14367 + * @attribute forceFunction 27.14368 + * @type Function 27.14369 + */ 27.14370 + forceFunction : Drag.FORCE_FUNCTIONS.LINEAR 27.14371 + }; 27.14372 + 27.14373 + /** 27.14374 + * Adds a drag force to a physics body's force accumulator. 27.14375 + * 27.14376 + * @method applyForce 27.14377 + * @param targets {Array.Body} Array of bodies to apply drag force to. 27.14378 + */ 27.14379 + Drag.prototype.applyForce = function applyForce(targets) { 27.14380 + var strength = this.options.strength; 27.14381 + var forceFunction = this.options.forceFunction; 27.14382 + var force = this.force; 27.14383 + for (var index = 0; index < targets.length; index++) { 27.14384 + var particle = targets[index]; 27.14385 + forceFunction(particle.velocity).mult(-strength).put(force); 27.14386 + particle.applyForce(force); 27.14387 + } 27.14388 + }; 27.14389 + 27.14390 + /** 27.14391 + * Basic options setter 27.14392 + * 27.14393 + * @method setOptions 27.14394 + * @param {Objects} options 27.14395 + */ 27.14396 + Drag.prototype.setOptions = function setOptions(options) { 27.14397 + for (var key in options) this.options[key] = options[key]; 27.14398 + }; 27.14399 + 27.14400 + module.exports = Drag; 27.14401 +}); 27.14402 + 27.14403 +define('famous/views/Scroller',['require','exports','module','famous/core/Entity','famous/core/Group','famous/core/OptionsManager','famous/core/Transform','famous/utilities/Utility','famous/core/ViewSequence','famous/core/EventHandler'],function(require, exports, module) { 27.14404 + var Entity = require('famous/core/Entity'); 27.14405 + var Group = require('famous/core/Group'); 27.14406 + var OptionsManager = require('famous/core/OptionsManager'); 27.14407 + var Transform = require('famous/core/Transform'); 27.14408 + var Utility = require('famous/utilities/Utility'); 27.14409 + var ViewSequence = require('famous/core/ViewSequence'); 27.14410 + var EventHandler = require('famous/core/EventHandler'); 27.14411 + 27.14412 + /** 27.14413 + * Scroller lays out a collection of renderables, and will browse through them based on 27.14414 + * accessed position. Scroller also broadcasts an 'edgeHit' event, with a position property of the location of the edge, 27.14415 + * when you've hit the 'edges' of it's renderable collection. 27.14416 + * @class Scroller 27.14417 + * @constructor 27.14418 + * @event error 27.14419 + * @param {Options} [options] An object of configurable options. 27.14420 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 27.14421 + * module, this option will lay out the Scroller instance's renderables either horizontally 27.14422 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 27.14423 + * to just use integers as well. 27.14424 + * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scroller will display content in. 27.14425 + * @param {Number} [margin=undefined] The size of the area (in pixels) that Scroller will process renderables' associated calculations in. 27.14426 + */ 27.14427 + function Scroller(options) { 27.14428 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.14429 + this._optionsManager = new OptionsManager(this.options); 27.14430 + if (options) this._optionsManager.setOptions(options); 27.14431 + 27.14432 + this._node = null; 27.14433 + this._position = 0; 27.14434 + 27.14435 + // used for shifting nodes 27.14436 + this._positionOffset = 0; 27.14437 + 27.14438 + this._positionGetter = null; 27.14439 + this._outputFunction = null; 27.14440 + this._masterOutputFunction = null; 27.14441 + this.outputFrom(); 27.14442 + 27.14443 + this._onEdge = 0; // -1 for top, 1 for bottom 27.14444 + 27.14445 + this.group = new Group(); 27.14446 + this.group.add({render: _innerRender.bind(this)}); 27.14447 + 27.14448 + this._entityId = Entity.register(this); 27.14449 + this._size = [undefined, undefined]; 27.14450 + this._contextSize = [undefined, undefined]; 27.14451 + 27.14452 + this._eventInput = new EventHandler(); 27.14453 + this._eventOutput = new EventHandler(); 27.14454 + 27.14455 + EventHandler.setInputHandler(this, this._eventInput); 27.14456 + EventHandler.setOutputHandler(this, this._eventOutput); 27.14457 + } 27.14458 + 27.14459 + Scroller.DEFAULT_OPTIONS = { 27.14460 + direction: Utility.Direction.Y, 27.14461 + margin: 0, 27.14462 + clipSize: undefined, 27.14463 + groupScroll: false 27.14464 + }; 27.14465 + 27.14466 + function _sizeForDir(size) { 27.14467 + if (!size) size = this._contextSize; 27.14468 + var dimension = (this.options.direction === Utility.Direction.X) ? 0 : 1; 27.14469 + return (size[dimension] === undefined) ? this._contextSize[dimension] : size[dimension]; 27.14470 + } 27.14471 + 27.14472 + function _output(node, offset, target) { 27.14473 + var size = node.getSize ? node.getSize() : this._contextSize; 27.14474 + var transform = this._outputFunction(offset); 27.14475 + target.push({transform: transform, target: node.render()}); 27.14476 + return _sizeForDir.call(this, size); 27.14477 + } 27.14478 + 27.14479 + function _getClipSize() { 27.14480 + if (this.options.clipSize) return this.options.clipSize; 27.14481 + else return _sizeForDir.call(this, this._contextSize); 27.14482 + } 27.14483 + 27.14484 + /** 27.14485 + * Patches the Scroller instance's options with the passed-in ones. 27.14486 + * @method setOptions 27.14487 + * @param {Options} options An object of configurable options for the Scroller instance. 27.14488 + */ 27.14489 + Scroller.prototype.setOptions = function setOptions(options) { 27.14490 + this._optionsManager.setOptions(options); 27.14491 + 27.14492 + if (this.options.groupScroll) { 27.14493 + this.group.pipe(this._eventOutput); 27.14494 + } 27.14495 + else { 27.14496 + this.group.unpipe(this._eventOutput); 27.14497 + } 27.14498 + }; 27.14499 + 27.14500 + /** 27.14501 + * Tells you if the Scroller instance is on an edge. 27.14502 + * @method onEdge 27.14503 + * @return {Boolean} Whether the Scroller instance is on an edge or not. 27.14504 + */ 27.14505 + Scroller.prototype.onEdge = function onEdge() { 27.14506 + return this._onEdge; 27.14507 + }; 27.14508 + 27.14509 + /** 27.14510 + * Allows you to overwrite the way Scroller lays out it's renderables. Scroller will 27.14511 + * pass an offset into the function. By default the Scroller instance just translates each node 27.14512 + * in it's direction by the passed-in offset. 27.14513 + * Scroller will translate each renderable down 27.14514 + * @method outputFrom 27.14515 + * @param {Function} fn A function that takes an offset and returns a transform. 27.14516 + * @param {Function} [masterFn] 27.14517 + */ 27.14518 + Scroller.prototype.outputFrom = function outputFrom(fn, masterFn) { 27.14519 + if (!fn) { 27.14520 + fn = function(offset) { 27.14521 + return (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset); 27.14522 + }.bind(this); 27.14523 + if (!masterFn) masterFn = fn; 27.14524 + } 27.14525 + this._outputFunction = fn; 27.14526 + this._masterOutputFunction = masterFn ? masterFn : function(offset) { 27.14527 + return Transform.inverse(fn(-offset)); 27.14528 + }; 27.14529 + }; 27.14530 + 27.14531 + /** 27.14532 + * The Scroller instance's method for reading from an external position. Scroller uses 27.14533 + * the external position to actually scroll through it's renderables. 27.14534 + * @method positionFrom 27.14535 + * @param {Getter} position Can be either a function that returns a position, 27.14536 + * or an object with a get method that returns a position. 27.14537 + */ 27.14538 + Scroller.prototype.positionFrom = function positionFrom(position) { 27.14539 + if (position instanceof Function) this._positionGetter = position; 27.14540 + else if (position && position.get) this._positionGetter = position.get.bind(position); 27.14541 + else { 27.14542 + this._positionGetter = null; 27.14543 + this._position = position; 27.14544 + } 27.14545 + if (this._positionGetter) this._position = this._positionGetter.call(this); 27.14546 + }; 27.14547 + 27.14548 + /** 27.14549 + * Sets the collection of renderables under the Scroller instance's control. 27.14550 + * 27.14551 + * @method sequenceFrom 27.14552 + * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence. 27.14553 + * @chainable 27.14554 + */ 27.14555 + Scroller.prototype.sequenceFrom = function sequenceFrom(node) { 27.14556 + if (node instanceof Array) node = new ViewSequence({array: node}); 27.14557 + this._node = node; 27.14558 + this._positionOffset = 0; 27.14559 + }; 27.14560 + 27.14561 + /** 27.14562 + * Returns the width and the height of the Scroller instance. 27.14563 + * 27.14564 + * @method getSize 27.14565 + * @return {Array} A two value array of the Scroller instance's current width and height (in that order). 27.14566 + */ 27.14567 + Scroller.prototype.getSize = function getSize(actual) { 27.14568 + return actual ? this._contextSize : this._size; 27.14569 + }; 27.14570 + 27.14571 + /** 27.14572 + * Generate a render spec from the contents of this component. 27.14573 + * 27.14574 + * @private 27.14575 + * @method render 27.14576 + * @return {number} Render spec for this component 27.14577 + */ 27.14578 + Scroller.prototype.render = function render() { 27.14579 + if (!this._node) return null; 27.14580 + if (this._positionGetter) this._position = this._positionGetter.call(this); 27.14581 + return this._entityId; 27.14582 + }; 27.14583 + 27.14584 + /** 27.14585 + * Apply changes from this component to the corresponding document element. 27.14586 + * This includes changes to classes, styles, size, content, opacity, origin, 27.14587 + * and matrix transforms. 27.14588 + * 27.14589 + * @private 27.14590 + * @method commit 27.14591 + * @param {Context} context commit context 27.14592 + */ 27.14593 + Scroller.prototype.commit = function commit(context) { 27.14594 + var transform = context.transform; 27.14595 + var opacity = context.opacity; 27.14596 + var origin = context.origin; 27.14597 + var size = context.size; 27.14598 + 27.14599 + // reset edge detection on size change 27.14600 + if (!this.options.clipSize && (size[0] !== this._contextSize[0] || size[1] !== this._contextSize[1])) { 27.14601 + this._onEdge = 0; 27.14602 + this._contextSize[0] = size[0]; 27.14603 + this._contextSize[1] = size[1]; 27.14604 + 27.14605 + if (this.options.direction === Utility.Direction.X) { 27.14606 + this._size[0] = _getClipSize.call(this); 27.14607 + this._size[1] = undefined; 27.14608 + } 27.14609 + else { 27.14610 + this._size[0] = undefined; 27.14611 + this._size[1] = _getClipSize.call(this); 27.14612 + } 27.14613 + } 27.14614 + 27.14615 + var scrollTransform = this._masterOutputFunction(-this._position); 27.14616 + 27.14617 + return { 27.14618 + transform: Transform.multiply(transform, scrollTransform), 27.14619 + size: size, 27.14620 + opacity: opacity, 27.14621 + origin: origin, 27.14622 + target: this.group.render() 27.14623 + }; 27.14624 + }; 27.14625 + 27.14626 + function _normalizeState() { 27.14627 + var nodeSize = _sizeForDir.call(this, this._node.getSize()); 27.14628 + var nextNode = this._node && this._node.getNext ? this._node.getNext() : null; 27.14629 + while (nextNode && this._position + this._positionOffset >= nodeSize) { 27.14630 + this._positionOffset -= nodeSize; 27.14631 + this._node = nextNode; 27.14632 + nodeSize = _sizeForDir.call(this, this._node.getSize()); 27.14633 + nextNode = this._node && this._node.getNext ? this._node.getNext() : null; 27.14634 + } 27.14635 + var prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null; 27.14636 + while (prevNode && this._position + this._positionOffset < 0) { 27.14637 + var prevNodeSize = _sizeForDir.call(this, prevNode.getSize()); 27.14638 + this._positionOffset += prevNodeSize; 27.14639 + this._node = prevNode; 27.14640 + prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null; 27.14641 + } 27.14642 + } 27.14643 + 27.14644 + function _innerRender() { 27.14645 + var size = null; 27.14646 + var position = this._position; 27.14647 + var result = []; 27.14648 + 27.14649 + this._onEdge = 0; 27.14650 + 27.14651 + var offset = -this._positionOffset; 27.14652 + var clipSize = _getClipSize.call(this); 27.14653 + var currNode = this._node; 27.14654 + while (currNode && offset - position < clipSize + this.options.margin) { 27.14655 + offset += _output.call(this, currNode, offset, result); 27.14656 + currNode = currNode.getNext ? currNode.getNext() : null; 27.14657 + } 27.14658 + 27.14659 + var sizeNode = this._node; 27.14660 + var nodesSize = _sizeForDir.call(this, sizeNode.getSize()); 27.14661 + if (offset < clipSize) { 27.14662 + while (sizeNode && nodesSize < clipSize) { 27.14663 + sizeNode = sizeNode.getPrevious(); 27.14664 + if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize()); 27.14665 + } 27.14666 + sizeNode = this._node; 27.14667 + while (sizeNode && nodesSize < clipSize) { 27.14668 + sizeNode = sizeNode.getNext(); 27.14669 + if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize()); 27.14670 + } 27.14671 + } 27.14672 + 27.14673 + var edgeSize = (nodesSize !== undefined && nodesSize < clipSize) ? nodesSize : clipSize; 27.14674 + 27.14675 + if (!currNode && offset - position <= edgeSize) { 27.14676 + this._onEdge = 1; 27.14677 + this._eventOutput.emit('edgeHit', { 27.14678 + position: offset - edgeSize 27.14679 + }); 27.14680 + } 27.14681 + else if (!this._node.getPrevious() && position <= 0) { 27.14682 + this._onEdge = -1; 27.14683 + this._eventOutput.emit('edgeHit', { 27.14684 + position: 0 27.14685 + }); 27.14686 + } 27.14687 + 27.14688 + // backwards 27.14689 + currNode = (this._node && this._node.getPrevious) ? this._node.getPrevious() : null; 27.14690 + offset = -this._positionOffset; 27.14691 + if (currNode) { 27.14692 + size = currNode.getSize ? currNode.getSize() : this._contextSize; 27.14693 + offset -= _sizeForDir.call(this, size); 27.14694 + } 27.14695 + 27.14696 + while (currNode && ((offset - position) > -(_getClipSize.call(this) + this.options.margin))) { 27.14697 + _output.call(this, currNode, offset, result); 27.14698 + currNode = currNode.getPrevious ? currNode.getPrevious() : null; 27.14699 + if (currNode) { 27.14700 + size = currNode.getSize ? currNode.getSize() : this._contextSize; 27.14701 + offset -= _sizeForDir.call(this, size); 27.14702 + } 27.14703 + } 27.14704 + 27.14705 + _normalizeState.call(this); 27.14706 + return result; 27.14707 + } 27.14708 + 27.14709 + module.exports = Scroller; 27.14710 +}); 27.14711 + 27.14712 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.14713 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.14714 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.14715 + * 27.14716 + * Owner: felix@famo.us 27.14717 + * @license MPL 2.0 27.14718 + * @copyright Famous Industries, Inc. 2014 27.14719 + */ 27.14720 + 27.14721 +define('famous/views/Scrollview',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Drag','famous/physics/forces/Spring','famous/core/EventHandler','famous/core/OptionsManager','famous/core/ViewSequence','famous/views/Scroller','famous/utilities/Utility','famous/inputs/GenericSync','famous/inputs/ScrollSync','famous/inputs/TouchSync'],function(require, exports, module) { 27.14722 + var PhysicsEngine = require('famous/physics/PhysicsEngine'); 27.14723 + var Particle = require('famous/physics/bodies/Particle'); 27.14724 + var Drag = require('famous/physics/forces/Drag'); 27.14725 + var Spring = require('famous/physics/forces/Spring'); 27.14726 + 27.14727 + var EventHandler = require('famous/core/EventHandler'); 27.14728 + var OptionsManager = require('famous/core/OptionsManager'); 27.14729 + var ViewSequence = require('famous/core/ViewSequence'); 27.14730 + var Scroller = require('famous/views/Scroller'); 27.14731 + var Utility = require('famous/utilities/Utility'); 27.14732 + 27.14733 + var GenericSync = require('famous/inputs/GenericSync'); 27.14734 + var ScrollSync = require('famous/inputs/ScrollSync'); 27.14735 + var TouchSync = require('famous/inputs/TouchSync'); 27.14736 + GenericSync.register({scroll : ScrollSync, touch : TouchSync}); 27.14737 + 27.14738 + /** 27.14739 + * Scrollview will lay out a collection of renderables sequentially in the specified direction, and will 27.14740 + * allow you to scroll through them with mousewheel or touch events. 27.14741 + * @class Scrollview 27.14742 + * @constructor 27.14743 + * @param {Options} [options] An object of configurable options. 27.14744 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 27.14745 + * module, this option will lay out the Scrollview instance's renderables either horizontally 27.14746 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 27.14747 + * to just use integers as well. 27.14748 + * @param {Boolean} [options.rails=true] When true, Scrollview's genericSync will only process input in it's primary access. 27.14749 + * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scrollview will display content in. 27.14750 + * @param {Number} [margin=undefined] The size of the area (in pixels) that Scrollview will process renderables' associated calculations in. 27.14751 + * @param {Number} [friction=0.001] Input resistance proportional to the velocity of the input. 27.14752 + * Controls the feel of the Scrollview instance at low velocities. 27.14753 + * @param {Number} [drag=0.0001] Input resistance proportional to the square of the velocity of the input. 27.14754 + * Affects Scrollview instance more prominently at high velocities. 27.14755 + * @param {Number} [edgeGrip=0.5] A coefficient for resistance against after-touch momentum. 27.14756 + * @param {Number} [egePeriod=300] Sets the period on the spring that handles the physics associated 27.14757 + * with hitting the end of a scrollview. 27.14758 + * @param {Number} [edgeDamp=1] Sets the damping on the spring that handles the physics associated 27.14759 + * with hitting the end of a scrollview. 27.14760 + * @param {Boolean} [paginated=false] A paginated scrollview will scroll through items discretely 27.14761 + * rather than continously. 27.14762 + * @param {Number} [pagePeriod=500] Sets the period on the spring that handles the physics associated 27.14763 + * with pagination. 27.14764 + * @param {Number} [pageDamp=0.8] Sets the damping on the spring that handles the physics associated 27.14765 + * with pagination. 27.14766 + * @param {Number} [pageStopSpeed=Infinity] The threshold for determining the amount of velocity 27.14767 + * required to trigger pagination. The lower the threshold, the easier it is to scroll continuosly. 27.14768 + * @param {Number} [pageSwitchSpeed=1] The threshold for momentum-based velocity pagination. 27.14769 + * @param {Number} [speedLimit=10] The highest scrolling speed you can reach. 27.14770 + */ 27.14771 + function Scrollview(options) { 27.14772 + this.options = Object.create(Scrollview.DEFAULT_OPTIONS); 27.14773 + this._optionsManager = new OptionsManager(this.options); 27.14774 + 27.14775 + this._node = null; 27.14776 + 27.14777 + this._physicsEngine = new PhysicsEngine(); 27.14778 + this._particle = new Particle(); 27.14779 + this._physicsEngine.addBody(this._particle); 27.14780 + 27.14781 + this.spring = new Spring({anchor: [0, 0, 0]}); 27.14782 + 27.14783 + this.drag = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.QUADRATIC}); 27.14784 + this.friction = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.LINEAR}); 27.14785 + 27.14786 + this.sync = new GenericSync(['scroll', 'touch'], {direction : this.options.direction}); 27.14787 + 27.14788 + this._eventInput = new EventHandler(); 27.14789 + this._eventOutput = new EventHandler(); 27.14790 + 27.14791 + this._eventInput.pipe(this.sync); 27.14792 + this.sync.pipe(this._eventInput); 27.14793 + 27.14794 + EventHandler.setInputHandler(this, this._eventInput); 27.14795 + EventHandler.setOutputHandler(this, this._eventOutput); 27.14796 + 27.14797 + this._touchCount = 0; 27.14798 + this._springState = 0; 27.14799 + this._onEdge = 0; // -1 for top, 1 for bottom 27.14800 + this._pageSpringPosition = 0; 27.14801 + this._edgeSpringPosition = 0; 27.14802 + this._touchVelocity = undefined; 27.14803 + this._earlyEnd = false; 27.14804 + this._needsPaginationCheck = false; 27.14805 + 27.14806 + this._scroller = new Scroller(); 27.14807 + this._scroller.positionFrom(this.getPosition.bind(this)); 27.14808 + 27.14809 + this.setOptions(options); 27.14810 + 27.14811 + _bindEvents.call(this); 27.14812 + } 27.14813 + 27.14814 + /** @const */ 27.14815 + var TOLERANCE = 0.5; 27.14816 + 27.14817 + Scrollview.DEFAULT_OPTIONS = { 27.14818 + direction: Utility.Direction.Y, 27.14819 + rails: true, 27.14820 + friction: 0.001, 27.14821 + drag: 0.0001, 27.14822 + edgeGrip: 0.5, 27.14823 + edgePeriod: 300, 27.14824 + edgeDamp: 1, 27.14825 + margin: 1000, // mostly safe 27.14826 + paginated: false, 27.14827 + pagePeriod: 500, 27.14828 + pageDamp: 0.8, 27.14829 + pageStopSpeed: 10, 27.14830 + pageSwitchSpeed: 0.5, 27.14831 + speedLimit: 10, 27.14832 + groupScroll: false 27.14833 + }; 27.14834 + 27.14835 + /** @enum */ 27.14836 + var SpringStates = { 27.14837 + NONE: 0, 27.14838 + EDGE: 1, 27.14839 + PAGE: 2 27.14840 + }; 27.14841 + 27.14842 + function _handleStart(event) { 27.14843 + this._touchCount = event.count; 27.14844 + if (event.count === undefined) this._touchCount = 1; 27.14845 + 27.14846 + _detachAgents.call(this); 27.14847 + this.setVelocity(0); 27.14848 + this._touchVelocity = 0; 27.14849 + this._earlyEnd = false; 27.14850 + } 27.14851 + 27.14852 + function _handleMove(event) { 27.14853 + var velocity = -event.velocity; 27.14854 + var delta = -event.delta; 27.14855 + 27.14856 + if (this._onEdge && event.slip) { 27.14857 + if ((velocity < 0 && this._onEdge < 0) || (velocity > 0 && this._onEdge > 0)) { 27.14858 + if (!this._earlyEnd) { 27.14859 + _handleEnd.call(this, event); 27.14860 + this._earlyEnd = true; 27.14861 + } 27.14862 + } 27.14863 + else if (this._earlyEnd && (Math.abs(velocity) > Math.abs(this.getVelocity()))) { 27.14864 + _handleStart.call(this, event); 27.14865 + } 27.14866 + } 27.14867 + if (this._earlyEnd) return; 27.14868 + this._touchVelocity = velocity; 27.14869 + 27.14870 + if (event.slip) this.setVelocity(velocity); 27.14871 + else this.setPosition(this.getPosition() + delta); 27.14872 + } 27.14873 + 27.14874 + function _handleEnd(event) { 27.14875 + this._touchCount = event.count || 0; 27.14876 + if (!this._touchCount) { 27.14877 + _detachAgents.call(this); 27.14878 + if (this._onEdge) _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE); 27.14879 + _attachAgents.call(this); 27.14880 + var velocity = -event.velocity; 27.14881 + var speedLimit = this.options.speedLimit; 27.14882 + if (event.slip) speedLimit *= this.options.edgeGrip; 27.14883 + if (velocity < -speedLimit) velocity = -speedLimit; 27.14884 + else if (velocity > speedLimit) velocity = speedLimit; 27.14885 + this.setVelocity(velocity); 27.14886 + this._touchVelocity = undefined; 27.14887 + this._needsPaginationCheck = true; 27.14888 + } 27.14889 + } 27.14890 + 27.14891 + function _bindEvents() { 27.14892 + this._eventInput.bindThis(this); 27.14893 + this._eventInput.on('start', _handleStart); 27.14894 + this._eventInput.on('update', _handleMove); 27.14895 + this._eventInput.on('end', _handleEnd); 27.14896 + 27.14897 + this._scroller.on('edgeHit', function(data) { 27.14898 + this._edgeSpringPosition = data.position; 27.14899 + }.bind(this)); 27.14900 + } 27.14901 + 27.14902 + function _attachAgents() { 27.14903 + if (this._springState) this._physicsEngine.attach([this.spring], this._particle); 27.14904 + else this._physicsEngine.attach([this.drag, this.friction], this._particle); 27.14905 + } 27.14906 + 27.14907 + function _detachAgents() { 27.14908 + this._springState = SpringStates.NONE; 27.14909 + this._physicsEngine.detachAll(); 27.14910 + } 27.14911 + 27.14912 + function _nodeSizeForDirection(node) { 27.14913 + var direction = this.options.direction; 27.14914 + var nodeSize = (node.getSize() || this._scroller.getSize())[direction]; 27.14915 + if (!nodeSize) nodeSize = this._scroller.getSize()[direction]; 27.14916 + return nodeSize; 27.14917 + } 27.14918 + 27.14919 + function _handleEdge(edgeDetected) { 27.14920 + if (!this._onEdge && edgeDetected) { 27.14921 + this.sync.setOptions({scale: this.options.edgeGrip}); 27.14922 + if (!this._touchCount && this._springState !== SpringStates.EDGE) { 27.14923 + _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE); 27.14924 + } 27.14925 + } 27.14926 + else if (this._onEdge && !edgeDetected) { 27.14927 + this.sync.setOptions({scale: 1}); 27.14928 + if (this._springState && Math.abs(this.getVelocity()) < 0.001) { 27.14929 + // reset agents, detaching the spring 27.14930 + _detachAgents.call(this); 27.14931 + _attachAgents.call(this); 27.14932 + } 27.14933 + } 27.14934 + this._onEdge = edgeDetected; 27.14935 + } 27.14936 + 27.14937 + function _handlePagination() { 27.14938 + if (!this._needsPaginationCheck) return; 27.14939 + 27.14940 + if (this._touchCount) return; 27.14941 + if (this._springState === SpringStates.EDGE) return; 27.14942 + 27.14943 + var velocity = this.getVelocity(); 27.14944 + if (Math.abs(velocity) >= this.options.pageStopSpeed) return; 27.14945 + 27.14946 + var position = this.getPosition(); 27.14947 + var velocitySwitch = Math.abs(velocity) > this.options.pageSwitchSpeed; 27.14948 + 27.14949 + // parameters to determine when to switch 27.14950 + var nodeSize = _nodeSizeForDirection.call(this, this._node); 27.14951 + var positionNext = position > 0.5 * nodeSize; 27.14952 + var velocityNext = velocity > 0; 27.14953 + 27.14954 + if ((positionNext && !velocitySwitch) || (velocitySwitch && velocityNext)) this.goToNextPage(); 27.14955 + else _setSpring.call(this, 0, SpringStates.PAGE); 27.14956 + 27.14957 + this._needsPaginationCheck = false; 27.14958 + } 27.14959 + 27.14960 + function _setSpring(position, springState) { 27.14961 + var springOptions; 27.14962 + if (springState === SpringStates.EDGE) { 27.14963 + this._edgeSpringPosition = position; 27.14964 + springOptions = { 27.14965 + anchor: [this._edgeSpringPosition, 0, 0], 27.14966 + period: this.options.edgePeriod, 27.14967 + dampingRatio: this.options.edgeDamp 27.14968 + }; 27.14969 + } 27.14970 + else if (springState === SpringStates.PAGE) { 27.14971 + this._pageSpringPosition = position; 27.14972 + springOptions = { 27.14973 + anchor: [this._pageSpringPosition, 0, 0], 27.14974 + period: this.options.pagePeriod, 27.14975 + dampingRatio: this.options.pageDamp 27.14976 + }; 27.14977 + } 27.14978 + 27.14979 + this.spring.setOptions(springOptions); 27.14980 + if (springState && !this._springState) { 27.14981 + _detachAgents.call(this); 27.14982 + this._springState = springState; 27.14983 + _attachAgents.call(this); 27.14984 + } 27.14985 + this._springState = springState; 27.14986 + } 27.14987 + 27.14988 + function _normalizeState() { 27.14989 + var position = this.getPosition(); 27.14990 + var nodeSize = _nodeSizeForDirection.call(this, this._node); 27.14991 + var nextNode = this._node.getNext(); 27.14992 + 27.14993 + while (position > nodeSize + TOLERANCE && nextNode) { 27.14994 + _shiftOrigin.call(this, -nodeSize); 27.14995 + position -= nodeSize; 27.14996 + this._scroller.sequenceFrom(nextNode); 27.14997 + this._node = nextNode; 27.14998 + nextNode = this._node.getNext(); 27.14999 + nodeSize = _nodeSizeForDirection.call(this, this._node); 27.15000 + } 27.15001 + 27.15002 + var previousNode = this._node.getPrevious(); 27.15003 + var previousNodeSize; 27.15004 + 27.15005 + while (position < -TOLERANCE && previousNode) { 27.15006 + previousNodeSize = _nodeSizeForDirection.call(this, previousNode); 27.15007 + this._scroller.sequenceFrom(previousNode); 27.15008 + this._node = previousNode; 27.15009 + _shiftOrigin.call(this, previousNodeSize); 27.15010 + position += previousNodeSize; 27.15011 + previousNode = this._node.getPrevious(); 27.15012 + } 27.15013 + } 27.15014 + 27.15015 + function _shiftOrigin(amount) { 27.15016 + this._edgeSpringPosition += amount; 27.15017 + this._pageSpringPosition += amount; 27.15018 + this.setPosition(this.getPosition() + amount); 27.15019 + if (this._springState === SpringStates.EDGE) { 27.15020 + this.spring.setOptions({anchor: [this._edgeSpringPosition, 0, 0]}); 27.15021 + } 27.15022 + else if (this._springState === SpringStates.PAGE) { 27.15023 + this.spring.setOptions({anchor: [this._pageSpringPosition, 0, 0]}); 27.15024 + } 27.15025 + } 27.15026 + 27.15027 + Scrollview.prototype.outputFrom = function outputFrom() { 27.15028 + return this._scroller.outputFrom.apply(this._scroller, arguments); 27.15029 + }; 27.15030 + 27.15031 + /** 27.15032 + * Returns the position associated with the Scrollview instance's current node 27.15033 + * (generally the node currently at the top). 27.15034 + * @method getPosition 27.15035 + * @param {number} [node] If specified, returns the position of the node at that index in the 27.15036 + * Scrollview instance's currently managed collection. 27.15037 + * @return {number} The position of either the specified node, or the Scrollview's current Node, 27.15038 + * in pixels translated. 27.15039 + */ 27.15040 + Scrollview.prototype.getPosition = function getPosition() { 27.15041 + return this._particle.getPosition1D(); 27.15042 + }; 27.15043 + 27.15044 + /** 27.15045 + * Sets position of the physics particle that controls Scrollview instance's "position" 27.15046 + * @method setPosition 27.15047 + * @param {number} x The amount of pixels you want your scrollview to progress by. 27.15048 + */ 27.15049 + Scrollview.prototype.setPosition = function setPosition(x) { 27.15050 + this._particle.setPosition1D(x); 27.15051 + }; 27.15052 + 27.15053 + /** 27.15054 + * Returns the Scrollview instance's velocity. 27.15055 + * @method getVelocity 27.15056 + * @return {Number} The velocity. 27.15057 + */ 27.15058 + 27.15059 + Scrollview.prototype.getVelocity = function getVelocity() { 27.15060 + return this._touchCount ? this._touchVelocity : this._particle.getVelocity1D(); 27.15061 + }; 27.15062 + 27.15063 + /** 27.15064 + * Sets the Scrollview instance's velocity. Until affected by input or another call of setVelocity 27.15065 + * the Scrollview instance will scroll at the passed-in velocity. 27.15066 + * @method setVelocity 27.15067 + * @param {number} v The magnitude of the velocity. 27.15068 + */ 27.15069 + Scrollview.prototype.setVelocity = function setVelocity(v) { 27.15070 + this._particle.setVelocity1D(v); 27.15071 + }; 27.15072 + 27.15073 + /** 27.15074 + * Patches the Scrollview instance's options with the passed-in ones. 27.15075 + * @method setOptions 27.15076 + * @param {Options} options An object of configurable options for the Scrollview instance. 27.15077 + */ 27.15078 + Scrollview.prototype.setOptions = function setOptions(options) { 27.15079 + if (options) { 27.15080 + if (options.direction !== undefined) { 27.15081 + if (options.direction === 'x') options.direction = Utility.Direction.X; 27.15082 + else if (options.direction === 'y') options.direction = Utility.Direction.Y; 27.15083 + } 27.15084 + 27.15085 + this._scroller.setOptions(options); 27.15086 + this._optionsManager.setOptions(options); 27.15087 + } 27.15088 + 27.15089 + this._scroller.setOptions(this.options); 27.15090 + if (this.options.groupScroll) 27.15091 + this._scroller.pipe(this._eventInput); 27.15092 + else 27.15093 + this._scroller.unpipe(this._eventInput); 27.15094 + 27.15095 + this.drag.setOptions({strength: this.options.drag}); 27.15096 + this.friction.setOptions({strength: this.options.friction}); 27.15097 + 27.15098 + this.spring.setOptions({ 27.15099 + period: this.options.edgePeriod, 27.15100 + dampingRatio: this.options.edgeDamp 27.15101 + }); 27.15102 + 27.15103 + this.sync.setOptions({ 27.15104 + rails: this.options.rails, 27.15105 + direction: (this.options.direction === Utility.Direction.X) ? GenericSync.DIRECTION_X : GenericSync.DIRECTION_Y 27.15106 + }); 27.15107 + }; 27.15108 + 27.15109 + /** 27.15110 + * goToPreviousPage paginates your Scrollview instance backwards by one item. 27.15111 + * @method goToPreviousPage 27.15112 + * @return {ViewSequence} The previous node. 27.15113 + */ 27.15114 + Scrollview.prototype.goToPreviousPage = function goToPreviousPage() { 27.15115 + if (!this._node) return null; 27.15116 + var previousNode = this._node.getPrevious(); 27.15117 + if (previousNode) { 27.15118 + var currentPosition = this.getPosition(); 27.15119 + var previousNodeSize = _nodeSizeForDirection.call(this, previousNode); 27.15120 + this._scroller.sequenceFrom(previousNode); 27.15121 + this._node = previousNode; 27.15122 + var previousSpringPosition = (currentPosition < TOLERANCE) ? -previousNodeSize : 0; 27.15123 + _setSpring.call(this, previousSpringPosition, SpringStates.PAGE); 27.15124 + _shiftOrigin.call(this, previousNodeSize); 27.15125 + } 27.15126 + this._eventOutput.emit('pageChange', {direction: -1}); 27.15127 + return previousNode; 27.15128 + }; 27.15129 + 27.15130 + /** 27.15131 + * goToNextPage paginates your Scrollview instance forwards by one item. 27.15132 + * @method goToNextPage 27.15133 + * @return {ViewSequence} The next node. 27.15134 + */ 27.15135 + Scrollview.prototype.goToNextPage = function goToNextPage() { 27.15136 + if (!this._node) return null; 27.15137 + var nextNode = this._node.getNext(); 27.15138 + if (nextNode) { 27.15139 + var currentPosition = this.getPosition(); 27.15140 + var currentNodeSize = _nodeSizeForDirection.call(this, this._node); 27.15141 + var nextNodeSize = _nodeSizeForDirection.call(this, nextNode); 27.15142 + this._scroller.sequenceFrom(nextNode); 27.15143 + this._node = nextNode; 27.15144 + var nextSpringPosition = (currentPosition > currentNodeSize - TOLERANCE) ? currentNodeSize + nextNodeSize : currentNodeSize; 27.15145 + _setSpring.call(this, nextSpringPosition, SpringStates.PAGE); 27.15146 + _shiftOrigin.call(this, -currentNodeSize); 27.15147 + } 27.15148 + this._eventOutput.emit('pageChange', {direction: 1}); 27.15149 + return nextNode; 27.15150 + }; 27.15151 + 27.15152 + /** 27.15153 + * Sets the collection of renderables under the Scrollview instance's control, by 27.15154 + * setting its current node to the passed in ViewSequence. If you 27.15155 + * pass in an array, the Scrollview instance will set its node as a ViewSequence instantiated with 27.15156 + * the passed-in array. 27.15157 + * 27.15158 + * @method sequenceFrom 27.15159 + * @param {Array|ViewSequence} node Either an array of renderables or a Famous viewSequence. 27.15160 + */ 27.15161 + Scrollview.prototype.sequenceFrom = function sequenceFrom(node) { 27.15162 + if (node instanceof Array) node = new ViewSequence({array: node}); 27.15163 + this._node = node; 27.15164 + return this._scroller.sequenceFrom(node); 27.15165 + }; 27.15166 + 27.15167 + /** 27.15168 + * Returns the width and the height of the Scrollview instance. 27.15169 + * 27.15170 + * @method getSize 27.15171 + * @return {Array} A two value array of the Scrollview instance's current width and height (in that order). 27.15172 + */ 27.15173 + Scrollview.prototype.getSize = function getSize() { 27.15174 + return this._scroller.getSize.apply(this._scroller, arguments); 27.15175 + }; 27.15176 + 27.15177 + /** 27.15178 + * Generate a render spec from the contents of this component. 27.15179 + * 27.15180 + * @private 27.15181 + * @method render 27.15182 + * @return {number} Render spec for this component 27.15183 + */ 27.15184 + Scrollview.prototype.render = function render() { 27.15185 + if (!this._node) return null; 27.15186 + 27.15187 + _normalizeState.call(this); 27.15188 + _handleEdge.call(this, this._scroller.onEdge()); 27.15189 + if (this.options.paginated) _handlePagination.call(this); 27.15190 + 27.15191 + return this._scroller.render(); 27.15192 + }; 27.15193 + 27.15194 + module.exports = Scrollview; 27.15195 +}); 27.15196 + 27.15197 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15198 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15199 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15200 + * 27.15201 + * Owner: felix@famo.us 27.15202 + * @license MPL 2.0 27.15203 + * @copyright Famous Industries, Inc. 2014 27.15204 + */ 27.15205 + 27.15206 +define('famous/views/ScrollContainer',['require','exports','module','famous/surfaces/ContainerSurface','famous/core/EventHandler','./Scrollview','famous/utilities/Utility','famous/core/OptionsManager'],function(require, exports, module) { 27.15207 + var ContainerSurface = require('famous/surfaces/ContainerSurface'); 27.15208 + var EventHandler = require('famous/core/EventHandler'); 27.15209 + var Scrollview = require('./Scrollview'); 27.15210 + var Utility = require('famous/utilities/Utility'); 27.15211 + var OptionsManager = require('famous/core/OptionsManager'); 27.15212 + 27.15213 + /** 27.15214 + * A Container surface with a scrollview automatically added. The convenience of ScrollContainer lies in 27.15215 + * being able to clip out portions of the associated scrollview that lie outside the bounding surface, 27.15216 + * and in being able to move the scrollview more easily by applying modifiers to the parent container 27.15217 + * surface. 27.15218 + * @class ScrollContainer 27.15219 + * @constructor 27.15220 + * @param {Options} [options] An object of configurable options. 27.15221 + * @param {Options} [options.container=undefined] Options for the ScrollContainer instance's surface. 27.15222 + * @param {Options} [options.scrollview={direction:Utility.Direction.X}] Options for the ScrollContainer instance's scrollview. 27.15223 + */ 27.15224 + function ScrollContainer(options) { 27.15225 + this.options = Object.create(ScrollContainer.DEFAULT_OPTIONS); 27.15226 + this._optionsManager = new OptionsManager(this.options); 27.15227 + 27.15228 + if (options) this.setOptions(options); 27.15229 + 27.15230 + this.container = new ContainerSurface(this.options.container); 27.15231 + this.scrollview = new Scrollview(this.options.scrollview); 27.15232 + 27.15233 + this.container.add(this.scrollview); 27.15234 + 27.15235 + EventHandler.setInputHandler(this, this.scrollview); 27.15236 + EventHandler.setOutputHandler(this, this.scrollview); 27.15237 + this.scrollview.subscribe(this.container); 27.15238 + } 27.15239 + 27.15240 + ScrollContainer.DEFAULT_OPTIONS = { 27.15241 + container: { 27.15242 + properties: {overflow : 'hidden'} 27.15243 + }, 27.15244 + scrollview: {direction: Utility.Direction.X} 27.15245 + }; 27.15246 + 27.15247 + /** 27.15248 + * Patches the ScrollContainer instance's options with the passed-in ones. 27.15249 + * 27.15250 + * @method setOptions 27.15251 + * @param {Options} options An object of configurable options for the ScrollContainer instance. 27.15252 + */ 27.15253 + ScrollContainer.prototype.setOptions = function setOptions(options) { 27.15254 + return this._optionsManager.setOptions(options); 27.15255 + }; 27.15256 + 27.15257 + /** 27.15258 + * Sets the collection of renderables under the ScrollContainer instance scrollview's control. 27.15259 + * 27.15260 + * @method sequenceFrom 27.15261 + * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous ViewSequence. 27.15262 + */ 27.15263 + ScrollContainer.prototype.sequenceFrom = function sequenceFrom() { 27.15264 + return this.scrollview.sequenceFrom.apply(this.scrollview, arguments); 27.15265 + }; 27.15266 + 27.15267 + /** 27.15268 + * Generate a render spec from the contents of this component. 27.15269 + * 27.15270 + * @private 27.15271 + * @method render 27.15272 + * @return {number} Render spec for this component 27.15273 + */ 27.15274 + ScrollContainer.prototype.render = function render() { 27.15275 + return this.container.render.apply(this.container, arguments); 27.15276 + }; 27.15277 + 27.15278 + module.exports = ScrollContainer; 27.15279 +}); 27.15280 + 27.15281 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15282 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15283 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15284 + * 27.15285 + * Owner: mark@famo.us 27.15286 + * @license MPL 2.0 27.15287 + * @copyright Famous Industries, Inc. 2014 27.15288 + */ 27.15289 + 27.15290 +define('famous/widgets/NavigationBar',['require','exports','module','famous/core/Scene','famous/core/Surface','famous/core/Transform','famous/core/View'],function(require, exports, module) { 27.15291 + var Scene = require('famous/core/Scene'); 27.15292 + var Surface = require('famous/core/Surface'); 27.15293 + var Transform = require('famous/core/Transform'); 27.15294 + var View = require('famous/core/View'); 27.15295 + 27.15296 + /** 27.15297 + * A view for displaying the title of the current page 27.15298 + * as well as icons for navigating backwards and opening 27.15299 + * further options 27.15300 + * 27.15301 + * @class NavigationBar 27.15302 + * @extends View 27.15303 + * @constructor 27.15304 + * 27.15305 + * @param {object} [options] overrides of default options 27.15306 + * @param {Array.number} [options.size=(undefined,0.5)] Size of the navigation bar and it's componenets. 27.15307 + * @param {Array.string} [options.backClasses=(back)] CSS Classes attached to back of Navigation. 27.15308 + * @param {String} [options.backContent=(◀)] Content of the back button. 27.15309 + * @param {Array.string} [options.classes=(navigation)] CSS Classes attached to the surfaces. 27.15310 + * @param {String} [options.content] Content to pass into title bar. 27.15311 + * @param {Array.string} [options.classes=(more)] CSS Classes attached to the More surface. 27.15312 + * @param {String} [options.moreContent=(✚)] Content of the more button. 27.15313 + */ 27.15314 + function NavigationBar(options) { 27.15315 + View.apply(this, arguments); 27.15316 + 27.15317 + this.title = new Surface({ 27.15318 + classes: this.options.classes, 27.15319 + content: this.options.content 27.15320 + }); 27.15321 + 27.15322 + this.back = new Surface({ 27.15323 + size: [this.options.size[1], this.options.size[1]], 27.15324 + classes: this.options.classes, 27.15325 + content: this.options.backContent 27.15326 + }); 27.15327 + this.back.on('click', function() { 27.15328 + this._eventOutput.emit('back', {}); 27.15329 + }.bind(this)); 27.15330 + 27.15331 + this.more = new Surface({ 27.15332 + size: [this.options.size[1], this.options.size[1]], 27.15333 + classes: this.options.classes, 27.15334 + content: this.options.moreContent 27.15335 + }); 27.15336 + this.more.on('click', function() { 27.15337 + this._eventOutput.emit('more', {}); 27.15338 + }.bind(this)); 27.15339 + 27.15340 + this.layout = new Scene({ 27.15341 + id: 'master', 27.15342 + size: this.options.size, 27.15343 + target: [ 27.15344 + { 27.15345 + transform: Transform.inFront, 27.15346 + origin: [0, 0.5], 27.15347 + target: this.back 27.15348 + }, 27.15349 + { 27.15350 + origin: [0.5, 0.5], 27.15351 + target: this.title 27.15352 + }, 27.15353 + { 27.15354 + transform: Transform.inFront, 27.15355 + origin: [1, 0.5], 27.15356 + target: this.more 27.15357 + } 27.15358 + ] 27.15359 + }); 27.15360 + 27.15361 + this._add(this.layout); 27.15362 + 27.15363 + this._optionsManager.on('change', function(event) { 27.15364 + var key = event.id; 27.15365 + var data = event.value; 27.15366 + if (key === 'size') { 27.15367 + this.layout.id.master.setSize(data); 27.15368 + this.title.setSize(data); 27.15369 + this.back.setSize([data[1], data[1]]); 27.15370 + this.more.setSize([data[1], data[1]]); 27.15371 + } 27.15372 + else if (key === 'backClasses') { 27.15373 + this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)}); 27.15374 + } 27.15375 + else if (key === 'backContent') { 27.15376 + this.back.setContent(this.options.backContent); 27.15377 + } 27.15378 + else if (key === 'classes') { 27.15379 + this.title.setOptions({classes: this.options.classes}); 27.15380 + this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)}); 27.15381 + this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)}); 27.15382 + } 27.15383 + else if (key === 'content') { 27.15384 + this.setContent(this.options.content); 27.15385 + } 27.15386 + else if (key === 'moreClasses') { 27.15387 + this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)}); 27.15388 + } 27.15389 + else if (key === 'moreContent') { 27.15390 + this.more.setContent(this.options.content); 27.15391 + } 27.15392 + }.bind(this)); 27.15393 + } 27.15394 + 27.15395 + NavigationBar.prototype = Object.create(View.prototype); 27.15396 + NavigationBar.prototype.constructor = NavigationBar; 27.15397 + 27.15398 + NavigationBar.DEFAULT_OPTIONS = { 27.15399 + size: [undefined, 50], 27.15400 + backClasses: ['back'], 27.15401 + backContent: '◀', 27.15402 + classes: ['navigation'], 27.15403 + content: '', 27.15404 + moreClasses: ['more'], 27.15405 + moreContent: '✚' 27.15406 + }; 27.15407 + 27.15408 + /** 27.15409 + * Set the title of the NavigationBar 27.15410 + * 27.15411 + * @method setContent 27.15412 + * 27.15413 + * @param {object} content JSON object containing title information 27.15414 + * 27.15415 + * @return {undefined} 27.15416 + */ 27.15417 + NavigationBar.prototype.setContent = function setContent(content) { 27.15418 + return this.title.setContent(content); 27.15419 + }; 27.15420 + 27.15421 + module.exports = NavigationBar; 27.15422 +}); 27.15423 + 27.15424 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15425 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15426 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15427 + * 27.15428 + * Owner: mark@famo.us 27.15429 + * @license MPL 2.0 27.15430 + * @copyright Famous Industries, Inc. 2014 27.15431 + */ 27.15432 + 27.15433 +define('famous/widgets/Slider',['require','exports','module','famous/core/Surface','famous/surfaces/CanvasSurface','famous/core/Transform','famous/core/EventHandler','famous/math/Utilities','famous/core/OptionsManager','famous/inputs/MouseSync','famous/inputs/TouchSync','famous/inputs/GenericSync'],function(require, exports, module) { 27.15434 + var Surface = require('famous/core/Surface'); 27.15435 + var CanvasSurface = require('famous/surfaces/CanvasSurface'); 27.15436 + var Transform = require('famous/core/Transform'); 27.15437 + var EventHandler = require('famous/core/EventHandler'); 27.15438 + var Utilities = require('famous/math/Utilities'); 27.15439 + var OptionsManager = require('famous/core/OptionsManager'); 27.15440 + 27.15441 + var MouseSync = require('famous/inputs/MouseSync'); 27.15442 + var TouchSync = require('famous/inputs/TouchSync'); 27.15443 + var GenericSync = require('famous/inputs/GenericSync'); 27.15444 + 27.15445 + GenericSync.register({ 27.15446 + mouse : MouseSync, 27.15447 + touch : TouchSync 27.15448 + }); 27.15449 + 27.15450 + /** @constructor */ 27.15451 + function Slider(options) { 27.15452 + this.options = Object.create(Slider.DEFAULT_OPTIONS); 27.15453 + this.optionsManager = new OptionsManager(this.options); 27.15454 + if (options) this.setOptions(options); 27.15455 + 27.15456 + this.indicator = new CanvasSurface({ 27.15457 + size: this.options.indicatorSize, 27.15458 + classes : ['slider-back'] 27.15459 + }); 27.15460 + 27.15461 + this.label = new Surface({ 27.15462 + size: this.options.labelSize, 27.15463 + content: this.options.label, 27.15464 + properties : {pointerEvents : 'none'}, 27.15465 + classes: ['slider-label'] 27.15466 + }); 27.15467 + 27.15468 + this.eventOutput = new EventHandler(); 27.15469 + this.eventInput = new EventHandler(); 27.15470 + EventHandler.setInputHandler(this, this.eventInput); 27.15471 + EventHandler.setOutputHandler(this, this.eventOutput); 27.15472 + 27.15473 + var scale = (this.options.range[1] - this.options.range[0]) / this.options.indicatorSize[0]; 27.15474 + 27.15475 + this.sync = new GenericSync( 27.15476 + ['mouse', 'touch'], 27.15477 + { 27.15478 + scale : scale, 27.15479 + direction : GenericSync.DIRECTION_X 27.15480 + } 27.15481 + ); 27.15482 + 27.15483 + this.indicator.pipe(this.sync); 27.15484 + this.sync.pipe(this); 27.15485 + 27.15486 + this.eventInput.on('update', function(data) { 27.15487 + this.set(data.position); 27.15488 + }.bind(this)); 27.15489 + 27.15490 + this._drawPos = 0; 27.15491 + _updateLabel.call(this); 27.15492 + } 27.15493 + 27.15494 + Slider.DEFAULT_OPTIONS = { 27.15495 + size: [200, 60], 27.15496 + indicatorSize: [200, 30], 27.15497 + labelSize: [200, 30], 27.15498 + range: [0, 1], 27.15499 + precision: 2, 27.15500 + value: 0, 27.15501 + label: '', 27.15502 + fillColor: 'rgba(170, 170, 170, 1)' 27.15503 + }; 27.15504 + 27.15505 + function _updateLabel() { 27.15506 + this.label.setContent(this.options.label + '<span style="float: right">' + this.get().toFixed(this.options.precision) + '</span>'); 27.15507 + } 27.15508 + 27.15509 + Slider.prototype.setOptions = function setOptions(options) { 27.15510 + return this.optionsManager.setOptions(options); 27.15511 + }; 27.15512 + 27.15513 + Slider.prototype.get = function get() { 27.15514 + return this.options.value; 27.15515 + }; 27.15516 + 27.15517 + Slider.prototype.set = function set(value) { 27.15518 + if (value === this.options.value) return; 27.15519 + this.options.value = Utilities.clamp(value, this.options.range); 27.15520 + _updateLabel.call(this); 27.15521 + this.eventOutput.emit('change', {value: value}); 27.15522 + }; 27.15523 + 27.15524 + Slider.prototype.getSize = function getSize() { 27.15525 + return this.options.size; 27.15526 + }; 27.15527 + 27.15528 + Slider.prototype.render = function render() { 27.15529 + var range = this.options.range; 27.15530 + var fillSize = Math.floor(((this.get() - range[0]) / (range[1] - range[0])) * this.options.indicatorSize[0]); 27.15531 + 27.15532 + if (fillSize < this._drawPos) { 27.15533 + this.indicator.getContext('2d').clearRect(fillSize, 0, this._drawPos - fillSize + 1, this.options.indicatorSize[1]); 27.15534 + } 27.15535 + else if (fillSize > this._drawPos) { 27.15536 + var ctx = this.indicator.getContext('2d'); 27.15537 + ctx.fillStyle = this.options.fillColor; 27.15538 + ctx.fillRect(this._drawPos-1, 0, fillSize - this._drawPos+1, this.options.indicatorSize[1]); 27.15539 + } 27.15540 + this._drawPos = fillSize; 27.15541 + 27.15542 + return { 27.15543 + size: this.options.size, 27.15544 + target: [ 27.15545 + { 27.15546 + origin: [0, 0], 27.15547 + target: this.indicator.render() 27.15548 + }, 27.15549 + { 27.15550 + transform: Transform.translate(0, 0, 1), 27.15551 + origin: [0, 0], 27.15552 + target: this.label.render() 27.15553 + } 27.15554 + ] 27.15555 + }; 27.15556 + }; 27.15557 + 27.15558 + module.exports = Slider; 27.15559 +}); 27.15560 + 27.15561 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15562 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15563 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15564 + * 27.15565 + * Owner: mark@famo.us 27.15566 + * @license MPL 2.0 27.15567 + * @copyright Famous Industries, Inc. 2014 27.15568 + */ 27.15569 + 27.15570 +define('famous/widgets/ToggleButton',['require','exports','module','famous/core/Surface','famous/core/EventHandler','famous/views/RenderController'],function(require, exports, module) { 27.15571 + var Surface = require('famous/core/Surface'); 27.15572 + var EventHandler = require('famous/core/EventHandler'); 27.15573 + var RenderController = require('famous/views/RenderController'); 27.15574 + 27.15575 + /** 27.15576 + * A view for transitioning between two surfaces based 27.15577 + * on a 'on' and 'off' state 27.15578 + * 27.15579 + * @class TabBar 27.15580 + * @extends View 27.15581 + * @constructor 27.15582 + * 27.15583 + * @param {object} options overrides of default options 27.15584 + */ 27.15585 + function ToggleButton(options) { 27.15586 + this.options = { 27.15587 + content: '', 27.15588 + offClasses: ['off'], 27.15589 + onClasses: ['on'], 27.15590 + size: undefined, 27.15591 + outTransition: {curve: 'easeInOut', duration: 300}, 27.15592 + inTransition: {curve: 'easeInOut', duration: 300}, 27.15593 + toggleMode: ToggleButton.TOGGLE, 27.15594 + crossfade: true 27.15595 + }; 27.15596 + 27.15597 + this._eventOutput = new EventHandler(); 27.15598 + EventHandler.setOutputHandler(this, this._eventOutput); 27.15599 + 27.15600 + this.offSurface = new Surface(); 27.15601 + this.offSurface.on('click', function() { 27.15602 + if (this.options.toggleMode !== ToggleButton.OFF) this.select(); 27.15603 + }.bind(this)); 27.15604 + this.offSurface.pipe(this._eventOutput); 27.15605 + 27.15606 + this.onSurface = new Surface(); 27.15607 + this.onSurface.on('click', function() { 27.15608 + if (this.options.toggleMode !== ToggleButton.ON) this.deselect(); 27.15609 + }.bind(this)); 27.15610 + this.onSurface.pipe(this._eventOutput); 27.15611 + 27.15612 + this.arbiter = new RenderController({ 27.15613 + overlap : this.options.crossfade 27.15614 + }); 27.15615 + 27.15616 + this.deselect(); 27.15617 + 27.15618 + if (options) this.setOptions(options); 27.15619 + } 27.15620 + 27.15621 + ToggleButton.OFF = 0; 27.15622 + ToggleButton.ON = 1; 27.15623 + ToggleButton.TOGGLE = 2; 27.15624 + 27.15625 + /** 27.15626 + * Transition towards the 'on' state and dispatch an event to 27.15627 + * listeners to announce it was selected 27.15628 + * 27.15629 + * @method select 27.15630 + */ 27.15631 + ToggleButton.prototype.select = function select() { 27.15632 + this.selected = true; 27.15633 + this.arbiter.show(this.onSurface, this.options.inTransition); 27.15634 +// this.arbiter.setMode(ToggleButton.ON, this.options.inTransition); 27.15635 + this._eventOutput.emit('select'); 27.15636 + }; 27.15637 + 27.15638 + /** 27.15639 + * Transition towards the 'off' state and dispatch an event to 27.15640 + * listeners to announce it was deselected 27.15641 + * 27.15642 + * @method deselect 27.15643 + */ 27.15644 + ToggleButton.prototype.deselect = function deselect() { 27.15645 + this.selected = false; 27.15646 + this.arbiter.show(this.offSurface, this.options.outTransition); 27.15647 + this._eventOutput.emit('deselect'); 27.15648 + }; 27.15649 + 27.15650 + /** 27.15651 + * Return the state of the button 27.15652 + * 27.15653 + * @method isSelected 27.15654 + * 27.15655 + * @return {boolean} selected state 27.15656 + */ 27.15657 + ToggleButton.prototype.isSelected = function isSelected() { 27.15658 + return this.selected; 27.15659 + }; 27.15660 + 27.15661 + /** 27.15662 + * Override the current options 27.15663 + * 27.15664 + * @method setOptions 27.15665 + * 27.15666 + * @param {object} options JSON 27.15667 + */ 27.15668 + ToggleButton.prototype.setOptions = function setOptions(options) { 27.15669 + if (options.content !== undefined) { 27.15670 + this.options.content = options.content; 27.15671 + this.offSurface.setContent(this.options.content); 27.15672 + this.onSurface.setContent(this.options.content); 27.15673 + } 27.15674 + if (options.offClasses) { 27.15675 + this.options.offClasses = options.offClasses; 27.15676 + this.offSurface.setClasses(this.options.offClasses); 27.15677 + } 27.15678 + if (options.onClasses) { 27.15679 + this.options.onClasses = options.onClasses; 27.15680 + this.onSurface.setClasses(this.options.onClasses); 27.15681 + } 27.15682 + if (options.size !== undefined) { 27.15683 + this.options.size = options.size; 27.15684 + this.onSurface.setSize(this.options.size); 27.15685 + this.offSurface.setSize(this.options.size); 27.15686 + } 27.15687 + if (options.toggleMode !== undefined) this.options.toggleMode = options.toggleMode; 27.15688 + if (options.outTransition !== undefined) this.options.outTransition = options.outTransition; 27.15689 + if (options.inTransition !== undefined) this.options.inTransition = options.inTransition; 27.15690 + if (options.crossfade !== undefined) { 27.15691 + this.options.crossfade = options.crossfade; 27.15692 + this.arbiter.setOptions({overlap: this.options.crossfade}); 27.15693 + } 27.15694 + }; 27.15695 + 27.15696 + /** 27.15697 + * Return the size defined in the options object 27.15698 + * 27.15699 + * @method getSize 27.15700 + * 27.15701 + * @return {array} two element array [height, width] 27.15702 + */ 27.15703 + ToggleButton.prototype.getSize = function getSize() { 27.15704 + return this.options.size; 27.15705 + }; 27.15706 + 27.15707 + /** 27.15708 + * Generate a render spec from the contents of this component. 27.15709 + * 27.15710 + * @private 27.15711 + * @method render 27.15712 + * @return {number} Render spec for this component 27.15713 + */ 27.15714 + ToggleButton.prototype.render = function render() { 27.15715 + return this.arbiter.render(); 27.15716 + }; 27.15717 + 27.15718 + module.exports = ToggleButton; 27.15719 +}); 27.15720 + 27.15721 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15722 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15723 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15724 + * 27.15725 + * Owner: mark@famo.us 27.15726 + * @license MPL 2.0 27.15727 + * @copyright Famous Industries, Inc. 2014 27.15728 + */ 27.15729 + 27.15730 +define('famous/widgets/TabBar',['require','exports','module','famous/utilities/Utility','famous/core/View','famous/views/GridLayout','./ToggleButton'],function(require, exports, module) { 27.15731 + var Utility = require('famous/utilities/Utility'); 27.15732 + var View = require('famous/core/View'); 27.15733 + var GridLayout = require('famous/views/GridLayout'); 27.15734 + var ToggleButton = require('./ToggleButton'); 27.15735 + 27.15736 + /** 27.15737 + * A view for displaying various tabs that dispatch events 27.15738 + * based on the id of the button that was clicked 27.15739 + * 27.15740 + * @class TabBar 27.15741 + * @extends View 27.15742 + * @constructor 27.15743 + * 27.15744 + * @param {object} options overrides of default options 27.15745 + */ 27.15746 + function TabBar(options) { 27.15747 + View.apply(this, arguments); 27.15748 + 27.15749 + this.layout = new GridLayout(); 27.15750 + this.buttons = []; 27.15751 + this._buttonIds = {}; 27.15752 + this._buttonCallbacks = {}; 27.15753 + 27.15754 + this.layout.sequenceFrom(this.buttons); 27.15755 + this._add(this.layout); 27.15756 + 27.15757 + this._optionsManager.on('change', _updateOptions.bind(this)); 27.15758 + } 27.15759 + 27.15760 + TabBar.prototype = Object.create(View.prototype); 27.15761 + TabBar.prototype.constructor = TabBar; 27.15762 + 27.15763 + TabBar.DEFAULT_OPTIONS = { 27.15764 + sections: [], 27.15765 + widget: ToggleButton, 27.15766 + size: [undefined, 50], 27.15767 + direction: Utility.Direction.X, 27.15768 + buttons: { 27.15769 + toggleMode: ToggleButton.ON 27.15770 + } 27.15771 + }; 27.15772 + 27.15773 + /** 27.15774 + * Update the options for all components of the view 27.15775 + * 27.15776 + * @method _updateOptions 27.15777 + * 27.15778 + * @param {object} data component options 27.15779 + */ 27.15780 + function _updateOptions(data) { 27.15781 + var id = data.id; 27.15782 + var value = data.value; 27.15783 + 27.15784 + if (id === 'direction') { 27.15785 + this.layout.setOptions({dimensions: _resolveGridDimensions.call(this.buttons.length, this.options.direction)}); 27.15786 + } 27.15787 + else if (id === 'buttons') { 27.15788 + for (var i in this.buttons) { 27.15789 + this.buttons[i].setOptions(value); 27.15790 + } 27.15791 + } 27.15792 + else if (id === 'sections') { 27.15793 + for (var sectionId in this.options.sections) { 27.15794 + this.defineSection(sectionId, this.options.sections[sectionId]); 27.15795 + } 27.15796 + } 27.15797 + } 27.15798 + 27.15799 + /** 27.15800 + * Return an array of the proper dimensions for the tabs 27.15801 + * 27.15802 + * @method _resolveGridDimensions 27.15803 + * 27.15804 + * @param {number} count number of buttons 27.15805 + * @param {number} direction direction of the layout 27.15806 + * 27.15807 + * @return {array} the dimensions of the tab section 27.15808 + */ 27.15809 + function _resolveGridDimensions(count, direction) { 27.15810 + if (direction === Utility.Direction.X) return [count, 1]; 27.15811 + else return [1, count]; 27.15812 + } 27.15813 + 27.15814 + /** 27.15815 + * Create a new button with the specified id. If one already exists with 27.15816 + * that id, unbind all listeners. 27.15817 + * 27.15818 + * @method defineSection 27.15819 + * 27.15820 + * @param {string} id name of the button 27.15821 + * @param {object} content data for the creation of a new ToggleButton 27.15822 + */ 27.15823 + TabBar.prototype.defineSection = function defineSection(id, content) { 27.15824 + var button; 27.15825 + var i = this._buttonIds[id]; 27.15826 + 27.15827 + if (i === undefined) { 27.15828 + i = this.buttons.length; 27.15829 + this._buttonIds[id] = i; 27.15830 + var widget = this.options.widget; 27.15831 + button = new widget(); 27.15832 + this.buttons[i] = button; 27.15833 + this.layout.setOptions({dimensions: _resolveGridDimensions(this.buttons.length, this.options.direction)}); 27.15834 + } 27.15835 + else { 27.15836 + button = this.buttons[i]; 27.15837 + button.unbind('select', this._buttonCallbacks[id]); 27.15838 + } 27.15839 + 27.15840 + if (this.options.buttons) button.setOptions(this.options.buttons); 27.15841 + button.setOptions(content); 27.15842 + 27.15843 + this._buttonCallbacks[id] = this.select.bind(this, id); 27.15844 + button.on('select', this._buttonCallbacks[id]); 27.15845 + }; 27.15846 + 27.15847 + /** 27.15848 + * Select a particular button and dispatch the id of the selection 27.15849 + * to any listeners. Deselect all others 27.15850 + * 27.15851 + * @method select 27.15852 + * 27.15853 + * @param {string} id button id 27.15854 + */ 27.15855 + TabBar.prototype.select = function select(id) { 27.15856 + var btn = this._buttonIds[id]; 27.15857 + // this prevents event loop 27.15858 + if (this.buttons[btn] && this.buttons[btn].isSelected()) { 27.15859 + this._eventOutput.emit('select', {id: id}); 27.15860 + } 27.15861 + else if (this.buttons[btn]) { 27.15862 + this.buttons[btn].select(); 27.15863 + } 27.15864 + 27.15865 + for (var i = 0; i < this.buttons.length; i++) { 27.15866 + if (i !== btn) this.buttons[i].deselect(); 27.15867 + } 27.15868 + }; 27.15869 + 27.15870 + module.exports = TabBar; 27.15871 +}); 27.15872 + 27.15873 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.15874 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.15875 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.15876 + * 27.15877 + * Owner: david@famo.us 27.15878 + * @license MPL 2.0 27.15879 + * @copyright Famous Industries, Inc. 2014 27.15880 + */ 27.15881 + 27.15882 +define('famous/physics/bodies/Body',['require','exports','module','./Particle','famous/core/Transform','famous/math/Vector','famous/math/Quaternion','famous/math/Matrix'],function(require, exports, module) { 27.15883 + var Particle = require('./Particle'); 27.15884 + var Transform = require('famous/core/Transform'); 27.15885 + var Vector = require('famous/math/Vector'); 27.15886 + var Quaternion = require('famous/math/Quaternion'); 27.15887 + var Matrix = require('famous/math/Matrix'); 27.15888 + 27.15889 + /** 27.15890 + * A unit controlled by the physics engine which extends the zero-dimensional 27.15891 + * Particle to include geometry. In addition to maintaining the state 27.15892 + * of a Particle its state includes orientation, angular velocity 27.15893 + * and angular momentum and responds to torque forces. 27.15894 + * 27.15895 + * @class Body 27.15896 + * @extends Particle 27.15897 + * @constructor 27.15898 + */ 27.15899 + function Body(options) { 27.15900 + Particle.call(this, options); 27.15901 + options = options || {}; 27.15902 + 27.15903 + this.orientation = new Quaternion(); 27.15904 + this.angularVelocity = new Vector(); 27.15905 + this.angularMomentum = new Vector(); 27.15906 + this.torque = new Vector(); 27.15907 + 27.15908 + if (options.orientation) this.orientation.set(options.orientation); 27.15909 + if (options.angularVelocity) this.angularVelocity.set(options.angularVelocity); 27.15910 + if (options.angularMomentum) this.angularMomentum.set(options.angularMomentum); 27.15911 + if (options.torque) this.torque.set(options.torque); 27.15912 + 27.15913 + this.setMomentsOfInertia(); 27.15914 + 27.15915 + this.angularVelocity.w = 0; //quaternify the angular velocity 27.15916 + 27.15917 + //registers 27.15918 + this.pWorld = new Vector(); //placeholder for world space position 27.15919 + } 27.15920 + 27.15921 + Body.DEFAULT_OPTIONS = Particle.DEFAULT_OPTIONS; 27.15922 + Body.DEFAULT_OPTIONS.orientation = [0,0,0,1]; 27.15923 + Body.DEFAULT_OPTIONS.angularVelocity = [0,0,0]; 27.15924 + 27.15925 + Body.AXES = Particle.AXES; 27.15926 + Body.SLEEP_TOLERANCE = Particle.SLEEP_TOLERANCE; 27.15927 + Body.INTEGRATOR = Particle.INTEGRATOR; 27.15928 + 27.15929 + Body.prototype = Object.create(Particle.prototype); 27.15930 + Body.prototype.constructor = Body; 27.15931 + 27.15932 + Body.prototype.isBody = true; 27.15933 + 27.15934 + Body.prototype.setMass = function setMass() { 27.15935 + Particle.prototype.setMass.apply(this, arguments); 27.15936 + this.setMomentsOfInertia(); 27.15937 + }; 27.15938 + 27.15939 + /** 27.15940 + * Setter for moment of inertia, which is necessary to give proper 27.15941 + * angular inertia depending on the geometry of the body. 27.15942 + * 27.15943 + * @method setMomentsOfInertia 27.15944 + */ 27.15945 + Body.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 27.15946 + this.inertia = new Matrix(); 27.15947 + this.inverseInertia = new Matrix(); 27.15948 + }; 27.15949 + 27.15950 + /** 27.15951 + * Update the angular velocity from the angular momentum state. 27.15952 + * 27.15953 + * @method updateAngularVelocity 27.15954 + */ 27.15955 + Body.prototype.updateAngularVelocity = function updateAngularVelocity() { 27.15956 + this.angularVelocity.set(this.inverseInertia.vectorMultiply(this.angularMomentum)); 27.15957 + }; 27.15958 + 27.15959 + /** 27.15960 + * Determine world coordinates from the local coordinate system. Useful 27.15961 + * if the Body has rotated in space. 27.15962 + * 27.15963 + * @method toWorldCoordinates 27.15964 + * @param localPosition {Vector} local coordinate vector 27.15965 + * @return global coordinate vector {Vector} 27.15966 + */ 27.15967 + Body.prototype.toWorldCoordinates = function toWorldCoordinates(localPosition) { 27.15968 + return this.pWorld.set(this.orientation.rotateVector(localPosition)); 27.15969 + }; 27.15970 + 27.15971 + /** 27.15972 + * Calculates the kinetic and intertial energy of a body. 27.15973 + * 27.15974 + * @method getEnergy 27.15975 + * @return energy {Number} 27.15976 + */ 27.15977 + Body.prototype.getEnergy = function getEnergy() { 27.15978 + return Particle.prototype.getEnergy.call(this) 27.15979 + + 0.5 * this.inertia.vectorMultiply(this.angularVelocity).dot(this.angularVelocity); 27.15980 + }; 27.15981 + 27.15982 + /** 27.15983 + * Extends Particle.reset to reset orientation, angular velocity 27.15984 + * and angular momentum. 27.15985 + * 27.15986 + * @method reset 27.15987 + * @param [p] {Array|Vector} position 27.15988 + * @param [v] {Array|Vector} velocity 27.15989 + * @param [q] {Array|Quaternion} orientation 27.15990 + * @param [L] {Array|Vector} angular momentum 27.15991 + */ 27.15992 + Body.prototype.reset = function reset(p, v, q, L) { 27.15993 + Particle.prototype.reset.call(this, p, v); 27.15994 + this.angularVelocity.clear(); 27.15995 + this.setOrientation(q || [1,0,0,0]); 27.15996 + this.setAngularMomentum(L || [0,0,0]); 27.15997 + }; 27.15998 + 27.15999 + /** 27.16000 + * Setter for orientation 27.16001 + * 27.16002 + * @method setOrientation 27.16003 + * @param q {Array|Quaternion} orientation 27.16004 + */ 27.16005 + Body.prototype.setOrientation = function setOrientation(q) { 27.16006 + this.orientation.set(q); 27.16007 + }; 27.16008 + 27.16009 + /** 27.16010 + * Setter for angular velocity 27.16011 + * 27.16012 + * @method setAngularVelocity 27.16013 + * @param w {Array|Vector} angular velocity 27.16014 + */ 27.16015 + Body.prototype.setAngularVelocity = function setAngularVelocity(w) { 27.16016 + this.wake(); 27.16017 + this.angularVelocity.set(w); 27.16018 + }; 27.16019 + 27.16020 + /** 27.16021 + * Setter for angular momentum 27.16022 + * 27.16023 + * @method setAngularMomentum 27.16024 + * @param L {Array|Vector} angular momentum 27.16025 + */ 27.16026 + Body.prototype.setAngularMomentum = function setAngularMomentum(L) { 27.16027 + this.wake(); 27.16028 + this.angularMomentum.set(L); 27.16029 + }; 27.16030 + 27.16031 + /** 27.16032 + * Extends Particle.applyForce with an optional argument 27.16033 + * to apply the force at an off-centered location, resulting in a torque. 27.16034 + * 27.16035 + * @method applyForce 27.16036 + * @param force {Vector} force 27.16037 + * @param [location] {Vector} off-center location on the body 27.16038 + */ 27.16039 + Body.prototype.applyForce = function applyForce(force, location) { 27.16040 + Particle.prototype.applyForce.call(this, force); 27.16041 + if (location !== undefined) this.applyTorque(location.cross(force)); 27.16042 + }; 27.16043 + 27.16044 + /** 27.16045 + * Applied a torque force to a body, inducing a rotation. 27.16046 + * 27.16047 + * @method applyTorque 27.16048 + * @param torque {Vector} torque 27.16049 + */ 27.16050 + Body.prototype.applyTorque = function applyTorque(torque) { 27.16051 + this.wake(); 27.16052 + this.torque.set(this.torque.add(torque)); 27.16053 + }; 27.16054 + 27.16055 + /** 27.16056 + * Extends Particle.getTransform to include a rotational component 27.16057 + * derived from the particle's orientation. 27.16058 + * 27.16059 + * @method getTransform 27.16060 + * @return transform {Transform} 27.16061 + */ 27.16062 + Body.prototype.getTransform = function getTransform() { 27.16063 + return Transform.thenMove( 27.16064 + this.orientation.getTransform(), 27.16065 + Transform.getTranslate(Particle.prototype.getTransform.call(this)) 27.16066 + ); 27.16067 + }; 27.16068 + 27.16069 + /** 27.16070 + * Extends Particle._integrate to also update the rotational states 27.16071 + * of the body. 27.16072 + * 27.16073 + * @method getTransform 27.16074 + * @protected 27.16075 + * @param dt {Number} delta time 27.16076 + */ 27.16077 + Body.prototype._integrate = function _integrate(dt) { 27.16078 + Particle.prototype._integrate.call(this, dt); 27.16079 + this.integrateAngularMomentum(dt); 27.16080 + this.updateAngularVelocity(dt); 27.16081 + this.integrateOrientation(dt); 27.16082 + }; 27.16083 + 27.16084 + /** 27.16085 + * Updates the angular momentum via the its integrator. 27.16086 + * 27.16087 + * @method integrateAngularMomentum 27.16088 + * @param dt {Number} delta time 27.16089 + */ 27.16090 + Body.prototype.integrateAngularMomentum = function integrateAngularMomentum(dt) { 27.16091 + Body.INTEGRATOR.integrateAngularMomentum(this, dt); 27.16092 + }; 27.16093 + 27.16094 + /** 27.16095 + * Updates the orientation via the its integrator. 27.16096 + * 27.16097 + * @method integrateOrientation 27.16098 + * @param dt {Number} delta time 27.16099 + */ 27.16100 + Body.prototype.integrateOrientation = function integrateOrientation(dt) { 27.16101 + Body.INTEGRATOR.integrateOrientation(this, dt); 27.16102 + }; 27.16103 + 27.16104 + module.exports = Body; 27.16105 +}); 27.16106 + 27.16107 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16108 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16109 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16110 + * 27.16111 + * Owner: david@famo.us 27.16112 + * @license MPL 2.0 27.16113 + * @copyright Famous Industries, Inc. 2014 27.16114 + */ 27.16115 + 27.16116 +define('famous/physics/bodies/Circle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) { 27.16117 + var Body = require('./Body'); 27.16118 + var Matrix = require('famous/math/Matrix'); 27.16119 + 27.16120 + /** 27.16121 + * Implements a circle, or spherical, geometry for an Body with 27.16122 + * radius. 27.16123 + * 27.16124 + * @class Circle 27.16125 + * @extends Body 27.16126 + * @constructor 27.16127 + */ 27.16128 + function Circle(options) { 27.16129 + options = options || {}; 27.16130 + this.setRadius(options.radius || 0); 27.16131 + Body.call(this, options); 27.16132 + } 27.16133 + 27.16134 + Circle.prototype = Object.create(Body.prototype); 27.16135 + Circle.prototype.constructor = Circle; 27.16136 + 27.16137 + /** 27.16138 + * Basic setter for radius. 27.16139 + * @method setRadius 27.16140 + * @param r {Number} radius 27.16141 + */ 27.16142 + Circle.prototype.setRadius = function setRadius(r) { 27.16143 + this.radius = r; 27.16144 + this.size = [2*this.radius, 2*this.radius]; 27.16145 + this.setMomentsOfInertia(); 27.16146 + }; 27.16147 + 27.16148 + Circle.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 27.16149 + var m = this.mass; 27.16150 + var r = this.radius; 27.16151 + 27.16152 + this.inertia = new Matrix([ 27.16153 + [0.25 * m * r * r, 0, 0], 27.16154 + [0, 0.25 * m * r * r, 0], 27.16155 + [0, 0, 0.5 * m * r * r] 27.16156 + ]); 27.16157 + 27.16158 + this.inverseInertia = new Matrix([ 27.16159 + [4 / (m * r * r), 0, 0], 27.16160 + [0, 4 / (m * r * r), 0], 27.16161 + [0, 0, 2 / (m * r * r)] 27.16162 + ]); 27.16163 + }; 27.16164 + 27.16165 + module.exports = Circle; 27.16166 + 27.16167 +}); 27.16168 + 27.16169 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16170 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16171 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16172 + * 27.16173 + * Owner: david@famo.us 27.16174 + * @license MPL 2.0 27.16175 + * @copyright Famous Industries, Inc. 2014 27.16176 + */ 27.16177 + 27.16178 +define('famous/physics/bodies/Rectangle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) { 27.16179 + var Body = require('./Body'); 27.16180 + var Matrix = require('famous/math/Matrix'); 27.16181 + 27.16182 + /** 27.16183 + * Implements a rectangular geometry for an Body with 27.16184 + * size = [width, height]. 27.16185 + * 27.16186 + * @class Rectangle 27.16187 + * @extends Body 27.16188 + * @constructor 27.16189 + */ 27.16190 + function Rectangle(options) { 27.16191 + options = options || {}; 27.16192 + this.size = options.size || [0,0]; 27.16193 + Body.call(this, options); 27.16194 + } 27.16195 + 27.16196 + Rectangle.prototype = Object.create(Body.prototype); 27.16197 + Rectangle.prototype.constructor = Rectangle; 27.16198 + 27.16199 + /** 27.16200 + * Basic setter for size. 27.16201 + * @method setSize 27.16202 + * @param size {Array} size = [width, height] 27.16203 + */ 27.16204 + Rectangle.prototype.setSize = function setSize(size) { 27.16205 + this.size = size; 27.16206 + this.setMomentsOfInertia(); 27.16207 + }; 27.16208 + 27.16209 + Rectangle.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 27.16210 + var m = this.mass; 27.16211 + var w = this.size[0]; 27.16212 + var h = this.size[1]; 27.16213 + 27.16214 + this.inertia = new Matrix([ 27.16215 + [m * h * h / 12, 0, 0], 27.16216 + [0, m * w * w / 12, 0], 27.16217 + [0, 0, m * (w * w + h * h) / 12] 27.16218 + ]); 27.16219 + 27.16220 + this.inverseInertia = new Matrix([ 27.16221 + [12 / (m * h * h), 0, 0], 27.16222 + [0, 12 / (m * w * w), 0], 27.16223 + [0, 0, 12 / (m * (w * w + h * h))] 27.16224 + ]); 27.16225 + }; 27.16226 + 27.16227 + module.exports = Rectangle; 27.16228 + 27.16229 +}); 27.16230 + 27.16231 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16232 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16233 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16234 + * 27.16235 + * Owner: david@famo.us 27.16236 + * @license MPL 2.0 27.16237 + * @copyright Famous Industries, Inc. 2014 27.16238 + */ 27.16239 + 27.16240 +define('famous/physics/constraints/Collision',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.16241 + var Constraint = require('./Constraint'); 27.16242 + var Vector = require('famous/math/Vector'); 27.16243 + 27.16244 + /** 27.16245 + * Allows for two circular bodies to collide and bounce off each other. 27.16246 + * 27.16247 + * @class Collision 27.16248 + * @constructor 27.16249 + * @extends Constraint 27.16250 + * @param {Options} [options] An object of configurable options. 27.16251 + * @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) Range : [0, 1] 27.16252 + * @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 27.16253 + * @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers 27.16254 + * 27.16255 + */ 27.16256 + function Collision(options) { 27.16257 + this.options = Object.create(Collision.DEFAULT_OPTIONS); 27.16258 + if (options) this.setOptions(options); 27.16259 + 27.16260 + //registers 27.16261 + this.normal = new Vector(); 27.16262 + this.pDiff = new Vector(); 27.16263 + this.vDiff = new Vector(); 27.16264 + this.impulse1 = new Vector(); 27.16265 + this.impulse2 = new Vector(); 27.16266 + 27.16267 + Constraint.call(this); 27.16268 + } 27.16269 + 27.16270 + Collision.prototype = Object.create(Constraint.prototype); 27.16271 + Collision.prototype.constructor = Collision; 27.16272 + 27.16273 + Collision.DEFAULT_OPTIONS = { 27.16274 + restitution : 0.5, 27.16275 + drift : 0.5, 27.16276 + slop : 0 27.16277 + }; 27.16278 + 27.16279 + function _normalVelocity(particle1, particle2) { 27.16280 + return particle1.velocity.dot(particle2.velocity); 27.16281 + } 27.16282 + 27.16283 + /* 27.16284 + * Setter for options. 27.16285 + * 27.16286 + * @method setOptions 27.16287 + * @param options {Objects} 27.16288 + */ 27.16289 + Collision.prototype.setOptions = function setOptions(options) { 27.16290 + for (var key in options) this.options[key] = options[key]; 27.16291 + }; 27.16292 + 27.16293 + /** 27.16294 + * Adds an impulse to a physics body's velocity due to the constraint 27.16295 + * 27.16296 + * @method applyConstraint 27.16297 + * @param targets {Array.Body} Array of bodies to apply the constraint to 27.16298 + * @param source {Body} The source of the constraint 27.16299 + * @param dt {Number} Delta time 27.16300 + */ 27.16301 + Collision.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.16302 + if (source === undefined) return; 27.16303 + 27.16304 + var v1 = source.velocity; 27.16305 + var p1 = source.position; 27.16306 + var w1 = source.inverseMass; 27.16307 + var r1 = source.radius; 27.16308 + 27.16309 + var options = this.options; 27.16310 + var drift = options.drift; 27.16311 + var slop = -options.slop; 27.16312 + var restitution = options.restitution; 27.16313 + 27.16314 + var n = this.normal; 27.16315 + var pDiff = this.pDiff; 27.16316 + var vDiff = this.vDiff; 27.16317 + var impulse1 = this.impulse1; 27.16318 + var impulse2 = this.impulse2; 27.16319 + 27.16320 + for (var i = 0; i < targets.length; i++) { 27.16321 + var target = targets[i]; 27.16322 + 27.16323 + if (target === source) continue; 27.16324 + 27.16325 + var v2 = target.velocity; 27.16326 + var p2 = target.position; 27.16327 + var w2 = target.inverseMass; 27.16328 + var r2 = target.radius; 27.16329 + 27.16330 + pDiff.set(p2.sub(p1)); 27.16331 + vDiff.set(v2.sub(v1)); 27.16332 + 27.16333 + var dist = pDiff.norm(); 27.16334 + var overlap = dist - (r1 + r2); 27.16335 + var effMass = 1/(w1 + w2); 27.16336 + var gamma = 0; 27.16337 + 27.16338 + if (overlap < 0) { 27.16339 + 27.16340 + n.set(pDiff.normalize()); 27.16341 + 27.16342 + if (this._eventOutput) { 27.16343 + var collisionData = { 27.16344 + target : target, 27.16345 + source : source, 27.16346 + overlap : overlap, 27.16347 + normal : n 27.16348 + }; 27.16349 + 27.16350 + this._eventOutput.emit('preCollision', collisionData); 27.16351 + this._eventOutput.emit('collision', collisionData); 27.16352 + } 27.16353 + 27.16354 + var lambda = (overlap <= slop) 27.16355 + ? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass) 27.16356 + : ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass); 27.16357 + 27.16358 + n.mult(dt*lambda).put(impulse1); 27.16359 + impulse1.mult(-1).put(impulse2); 27.16360 + 27.16361 + source.applyImpulse(impulse1); 27.16362 + target.applyImpulse(impulse2); 27.16363 + 27.16364 + //source.setPosition(p1.add(n.mult(overlap/2))); 27.16365 + //target.setPosition(p2.sub(n.mult(overlap/2))); 27.16366 + 27.16367 + if (this._eventOutput) this._eventOutput.emit('postCollision', collisionData); 27.16368 + 27.16369 + } 27.16370 + } 27.16371 + }; 27.16372 + 27.16373 + module.exports = Collision; 27.16374 +}); 27.16375 + 27.16376 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16377 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16378 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16379 + * 27.16380 + * Owner: david@famo.us 27.16381 + * @license MPL 2.0 27.16382 + * @copyright Famous Industries, Inc. 2014 27.16383 + */ 27.16384 + 27.16385 +define('famous/physics/constraints/Curve',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.16386 + var Constraint = require('./Constraint'); 27.16387 + var Vector = require('famous/math/Vector'); 27.16388 + 27.16389 + /** 27.16390 + * A constraint that keeps a physics body on a given implicit curve 27.16391 + * regardless of other physical forces are applied to it. 27.16392 + * 27.16393 + * A curve constraint is two surface constraints in disguise, as a curve is 27.16394 + * the intersection of two surfaces, and is essentially constrained to both 27.16395 + * 27.16396 + * @class Curve 27.16397 + * @constructor 27.16398 + * @extends Constraint 27.16399 + * @param {Options} [options] An object of configurable options. 27.16400 + * @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y - r*r } corresponds to a circle of radius r pixels 27.16401 + * @param {Function} [options.plane] An implicitly defined second surface that the body is constrained to 27.16402 + * @param {Number} [options.period] The spring-like reaction when the constraint is violated 27.16403 + * @param {Number} [options.number] The damping-like reaction when the constraint is violated 27.16404 + */ 27.16405 + function Curve(options) { 27.16406 + this.options = Object.create(Curve.DEFAULT_OPTIONS); 27.16407 + if (options) this.setOptions(options); 27.16408 + 27.16409 + //registers 27.16410 + this.J = new Vector(); 27.16411 + this.impulse = new Vector(); 27.16412 + 27.16413 + Constraint.call(this); 27.16414 + } 27.16415 + 27.16416 + Curve.prototype = Object.create(Constraint.prototype); 27.16417 + Curve.prototype.constructor = Curve; 27.16418 + 27.16419 + /** @const */ var epsilon = 1e-7; 27.16420 + /** @const */ var pi = Math.PI; 27.16421 + 27.16422 + Curve.DEFAULT_OPTIONS = { 27.16423 + equation : function(x,y,z) { 27.16424 + return 0; 27.16425 + }, 27.16426 + plane : function(x,y,z) { 27.16427 + return z; 27.16428 + }, 27.16429 + period : 0, 27.16430 + dampingRatio : 0 27.16431 + }; 27.16432 + 27.16433 + /** 27.16434 + * Basic options setter 27.16435 + * 27.16436 + * @method setOptions 27.16437 + * @param options {Objects} 27.16438 + */ 27.16439 + Curve.prototype.setOptions = function setOptions(options) { 27.16440 + for (var key in options) this.options[key] = options[key]; 27.16441 + }; 27.16442 + 27.16443 + /** 27.16444 + * Adds a curve impulse to a physics body. 27.16445 + * 27.16446 + * @method applyConstraint 27.16447 + * @param targets {Array.Body} Array of bodies to apply force to. 27.16448 + * @param source {Body} Not applicable 27.16449 + * @param dt {Number} Delta time 27.16450 + */ 27.16451 + Curve.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.16452 + var options = this.options; 27.16453 + var impulse = this.impulse; 27.16454 + var J = this.J; 27.16455 + 27.16456 + var f = options.equation; 27.16457 + var g = options.plane; 27.16458 + var dampingRatio = options.dampingRatio; 27.16459 + var period = options.period; 27.16460 + 27.16461 + for (var i = 0; i < targets.length; i++) { 27.16462 + var body = targets[i]; 27.16463 + 27.16464 + var v = body.velocity; 27.16465 + var p = body.position; 27.16466 + var m = body.mass; 27.16467 + 27.16468 + var gamma; 27.16469 + var beta; 27.16470 + 27.16471 + if (period === 0) { 27.16472 + gamma = 0; 27.16473 + beta = 1; 27.16474 + } 27.16475 + else { 27.16476 + var c = 4 * m * pi * dampingRatio / period; 27.16477 + var k = 4 * m * pi * pi / (period * period); 27.16478 + 27.16479 + gamma = 1 / (c + dt*k); 27.16480 + beta = dt*k / (c + dt*k); 27.16481 + } 27.16482 + 27.16483 + var x = p.x; 27.16484 + var y = p.y; 27.16485 + var z = p.z; 27.16486 + 27.16487 + var f0 = f(x, y, z); 27.16488 + var dfx = (f(x + epsilon, p, p) - f0) / epsilon; 27.16489 + var dfy = (f(x, y + epsilon, p) - f0) / epsilon; 27.16490 + var dfz = (f(x, y, p + epsilon) - f0) / epsilon; 27.16491 + 27.16492 + var g0 = g(x, y, z); 27.16493 + var dgx = (g(x + epsilon, y, z) - g0) / epsilon; 27.16494 + var dgy = (g(x, y + epsilon, z) - g0) / epsilon; 27.16495 + var dgz = (g(x, y, z + epsilon) - g0) / epsilon; 27.16496 + 27.16497 + J.setXYZ(dfx + dgx, dfy + dgy, dfz + dgz); 27.16498 + 27.16499 + var antiDrift = beta/dt * (f0 + g0); 27.16500 + var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m); 27.16501 + 27.16502 + impulse.set(J.mult(dt*lambda)); 27.16503 + body.applyImpulse(impulse); 27.16504 + } 27.16505 + }; 27.16506 + 27.16507 + module.exports = Curve; 27.16508 +}); 27.16509 + 27.16510 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16511 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16512 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16513 + * 27.16514 + * Owner: david@famo.us 27.16515 + * @license MPL 2.0 27.16516 + * @copyright Famous Industries, Inc. 2014 27.16517 + */ 27.16518 + 27.16519 +define('famous/physics/constraints/Distance',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.16520 + var Constraint = require('./Constraint'); 27.16521 + var Vector = require('famous/math/Vector'); 27.16522 + 27.16523 + /** 27.16524 + * A constraint that keeps a physics body a given distance away from a given 27.16525 + * anchor, or another attached body. 27.16526 + * 27.16527 + * 27.16528 + * @class Distance 27.16529 + * @constructor 27.16530 + * @extends Constraint 27.16531 + * @param {Options} [options] An object of configurable options. 27.16532 + * @param {Array} [options.anchor] The location of the anchor 27.16533 + * @param {Number} [options.length] The amount of distance from the anchor the constraint should enforce 27.16534 + * @param {Number} [options.minLength] The minimum distance before the constraint is activated. Use this property for a "rope" effect. 27.16535 + * @param {Number} [options.period] The spring-like reaction when the constraint is broken. 27.16536 + * @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is broken. 27.16537 + * 27.16538 + */ 27.16539 + function Distance(options) { 27.16540 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 27.16541 + if (options) this.setOptions(options); 27.16542 + 27.16543 + //registers 27.16544 + this.impulse = new Vector(); 27.16545 + this.normal = new Vector(); 27.16546 + this.diffP = new Vector(); 27.16547 + this.diffV = new Vector(); 27.16548 + 27.16549 + Constraint.call(this); 27.16550 + } 27.16551 + 27.16552 + Distance.prototype = Object.create(Constraint.prototype); 27.16553 + Distance.prototype.constructor = Distance; 27.16554 + 27.16555 + Distance.DEFAULT_OPTIONS = { 27.16556 + anchor : null, 27.16557 + length : 0, 27.16558 + minLength : 0, 27.16559 + period : 0, 27.16560 + dampingRatio : 0 27.16561 + }; 27.16562 + 27.16563 + /** @const */ var pi = Math.PI; 27.16564 + 27.16565 + /** 27.16566 + * Basic options setter 27.16567 + * 27.16568 + * @method setOptions 27.16569 + * @param options {Objects} 27.16570 + */ 27.16571 + Distance.prototype.setOptions = function setOptions(options) { 27.16572 + if (options.anchor) { 27.16573 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 27.16574 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 27.16575 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 27.16576 + } 27.16577 + if (options.length !== undefined) this.options.length = options.length; 27.16578 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 27.16579 + if (options.period !== undefined) this.options.period = options.period; 27.16580 + if (options.minLength !== undefined) this.options.minLength = options.minLength; 27.16581 + }; 27.16582 + 27.16583 + function _calcError(impulse, body) { 27.16584 + return body.mass * impulse.norm(); 27.16585 + } 27.16586 + 27.16587 + /** 27.16588 + * Set the anchor position 27.16589 + * 27.16590 + * @method setOptions 27.16591 + * @param anchor {Array} 27.16592 + */ 27.16593 + Distance.prototype.setAnchor = function setAnchor(anchor) { 27.16594 + if (!this.options.anchor) this.options.anchor = new Vector(); 27.16595 + this.options.anchor.set(anchor); 27.16596 + }; 27.16597 + 27.16598 + /** 27.16599 + * Adds an impulse to a physics body's velocity due to the constraint 27.16600 + * 27.16601 + * @method applyConstraint 27.16602 + * @param targets {Array.Body} Array of bodies to apply the constraint to 27.16603 + * @param source {Body} The source of the constraint 27.16604 + * @param dt {Number} Delta time 27.16605 + */ 27.16606 + Distance.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.16607 + var n = this.normal; 27.16608 + var diffP = this.diffP; 27.16609 + var diffV = this.diffV; 27.16610 + var impulse = this.impulse; 27.16611 + var options = this.options; 27.16612 + 27.16613 + var dampingRatio = options.dampingRatio; 27.16614 + var period = options.period; 27.16615 + var minLength = options.minLength; 27.16616 + 27.16617 + var p2; 27.16618 + var w2; 27.16619 + 27.16620 + if (source) { 27.16621 + var v2 = source.velocity; 27.16622 + p2 = source.position; 27.16623 + w2 = source.inverseMass; 27.16624 + } 27.16625 + else { 27.16626 + p2 = this.options.anchor; 27.16627 + w2 = 0; 27.16628 + } 27.16629 + 27.16630 + var length = this.options.length; 27.16631 + 27.16632 + for (var i = 0; i < targets.length; i++) { 27.16633 + var body = targets[i]; 27.16634 + 27.16635 + var v1 = body.velocity; 27.16636 + var p1 = body.position; 27.16637 + var w1 = body.inverseMass; 27.16638 + 27.16639 + diffP.set(p1.sub(p2)); 27.16640 + n.set(diffP.normalize()); 27.16641 + 27.16642 + var dist = diffP.norm() - length; 27.16643 + 27.16644 + //rope effect 27.16645 + if (Math.abs(dist) < minLength) return; 27.16646 + 27.16647 + if (source) diffV.set(v1.sub(v2)); 27.16648 + else diffV.set(v1); 27.16649 + 27.16650 + var effMass = 1 / (w1 + w2); 27.16651 + var gamma; 27.16652 + var beta; 27.16653 + 27.16654 + if (period === 0) { 27.16655 + gamma = 0; 27.16656 + beta = 1; 27.16657 + } 27.16658 + else { 27.16659 + var c = 4 * effMass * pi * dampingRatio / period; 27.16660 + var k = 4 * effMass * pi * pi / (period * period); 27.16661 + 27.16662 + gamma = 1 / (c + dt*k); 27.16663 + beta = dt*k / (c + dt*k); 27.16664 + } 27.16665 + 27.16666 + var antiDrift = beta/dt * dist; 27.16667 + var lambda = -(n.dot(diffV) + antiDrift) / (gamma + dt/effMass); 27.16668 + 27.16669 + impulse.set(n.mult(dt*lambda)); 27.16670 + body.applyImpulse(impulse); 27.16671 + 27.16672 + if (source) source.applyImpulse(impulse.mult(-1)); 27.16673 + } 27.16674 + }; 27.16675 + 27.16676 + module.exports = Distance; 27.16677 +}); 27.16678 + 27.16679 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16680 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16682 + * 27.16683 + * Owner: david@famo.us 27.16684 + * @license MPL 2.0 27.16685 + * @copyright Famous Industries, Inc. 2014 27.16686 + */ 27.16687 + 27.16688 +define('famous/physics/constraints/Surface',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 27.16689 + var Constraint = require('./Constraint'); 27.16690 + var Vector = require('famous/math/Vector'); 27.16691 + 27.16692 + /** 27.16693 + * A constraint that keeps a physics body on a given implicit surface 27.16694 + * regardless of other physical forces are applied to it. 27.16695 + * 27.16696 + * @class Surface 27.16697 + * @constructor 27.16698 + * @extends Constraint 27.16699 + * @param {Options} [options] An object of configurable options. 27.16700 + * @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y + z*z - r*r } corresponds to a sphere of radius r pixels. 27.16701 + * @param {Number} [options.period] The spring-like reaction when the constraint is violated. 27.16702 + * @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is violated. 27.16703 + */ 27.16704 + function Surface(options) { 27.16705 + this.options = Object.create(Surface.DEFAULT_OPTIONS); 27.16706 + if (options) this.setOptions(options); 27.16707 + 27.16708 + this.J = new Vector(); 27.16709 + this.impulse = new Vector(); 27.16710 + 27.16711 + Constraint.call(this); 27.16712 + } 27.16713 + 27.16714 + Surface.prototype = Object.create(Constraint.prototype); 27.16715 + Surface.prototype.constructor = Surface; 27.16716 + 27.16717 + Surface.DEFAULT_OPTIONS = { 27.16718 + equation : undefined, 27.16719 + period : 0, 27.16720 + dampingRatio : 0 27.16721 + }; 27.16722 + 27.16723 + /** @const */ var epsilon = 1e-7; 27.16724 + /** @const */ var pi = Math.PI; 27.16725 + 27.16726 + /** 27.16727 + * Basic options setter 27.16728 + * 27.16729 + * @method setOptions 27.16730 + * @param options {Objects} 27.16731 + */ 27.16732 + Surface.prototype.setOptions = function setOptions(options) { 27.16733 + for (var key in options) this.options[key] = options[key]; 27.16734 + }; 27.16735 + 27.16736 + /** 27.16737 + * Adds a surface impulse to a physics body. 27.16738 + * 27.16739 + * @method applyConstraint 27.16740 + * @param targets {Array.Body} Array of bodies to apply force to. 27.16741 + * @param source {Body} Not applicable 27.16742 + * @param dt {Number} Delta time 27.16743 + */ 27.16744 + Surface.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.16745 + var impulse = this.impulse; 27.16746 + var J = this.J; 27.16747 + var options = this.options; 27.16748 + 27.16749 + var f = options.equation; 27.16750 + var dampingRatio = options.dampingRatio; 27.16751 + var period = options.period; 27.16752 + 27.16753 + for (var i = 0; i < targets.length; i++) { 27.16754 + var particle = targets[i]; 27.16755 + 27.16756 + var v = particle.velocity; 27.16757 + var p = particle.position; 27.16758 + var m = particle.mass; 27.16759 + 27.16760 + var gamma; 27.16761 + var beta; 27.16762 + 27.16763 + if (period === 0) { 27.16764 + gamma = 0; 27.16765 + beta = 1; 27.16766 + } 27.16767 + else { 27.16768 + var c = 4 * m * pi * dampingRatio / period; 27.16769 + var k = 4 * m * pi * pi / (period * period); 27.16770 + 27.16771 + gamma = 1 / (c + dt*k); 27.16772 + beta = dt*k / (c + dt*k); 27.16773 + } 27.16774 + 27.16775 + var x = p.x; 27.16776 + var y = p.y; 27.16777 + var z = p.z; 27.16778 + 27.16779 + var f0 = f(x, y, z); 27.16780 + var dfx = (f(x + epsilon, p, p) - f0) / epsilon; 27.16781 + var dfy = (f(x, y + epsilon, p) - f0) / epsilon; 27.16782 + var dfz = (f(x, y, p + epsilon) - f0) / epsilon; 27.16783 + J.setXYZ(dfx, dfy, dfz); 27.16784 + 27.16785 + var antiDrift = beta/dt * f0; 27.16786 + var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m); 27.16787 + 27.16788 + impulse.set(J.mult(dt*lambda)); 27.16789 + particle.applyImpulse(impulse); 27.16790 + } 27.16791 + }; 27.16792 + 27.16793 + module.exports = Surface; 27.16794 +}); 27.16795 + 27.16796 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.16797 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.16798 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.16799 + * 27.16800 + * Owner: david@famo.us 27.16801 + * @license MPL 2.0 27.16802 + * @copyright Famous Industries, Inc. 2014 27.16803 + */ 27.16804 + 27.16805 +define('famous/physics/constraints/Walls',['require','exports','module','./Constraint','./Wall','famous/math/Vector'],function(require, exports, module) { 27.16806 + var Constraint = require('./Constraint'); 27.16807 + var Wall = require('./Wall'); 27.16808 + var Vector = require('famous/math/Vector'); 27.16809 + 27.16810 + /** 27.16811 + * Walls combines one or more Wall primitives and exposes a simple API to 27.16812 + * interact with several walls at once. A common use case would be to set up 27.16813 + * a bounding box for a physics body, that would collide with each side. 27.16814 + * 27.16815 + * @class Walls 27.16816 + * @constructor 27.16817 + * @extends Constraint 27.16818 + * @uses Wall 27.16819 + * @param {Options} [options] An object of configurable options. 27.16820 + * @param {Array} [options.sides] An array of sides e.g., [Walls.LEFT, Walls.TOP] 27.16821 + * @param {Array} [options.size] The size of the bounding box of the walls. 27.16822 + * @param {Array} [options.origin] The center of the wall relative to the size. 27.16823 + * @param {Array} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 27.16824 + * @param {Array} [options.slop] Amount of penetration in pixels to ignore before collision event triggers. 27.16825 + * @param {Array} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) The energy ratio lost in a collision (0 = stick, 1 = elastic) 27.16826 + * @param {Array} [options.onContact] How to handle collision against the wall. 27.16827 + */ 27.16828 + function Walls(options) { 27.16829 + this.options = Object.create(Walls.DEFAULT_OPTIONS); 27.16830 + if (options) this.setOptions(options); 27.16831 + _createComponents.call(this, options.sides || this.options.sides); 27.16832 + 27.16833 + Constraint.call(this); 27.16834 + } 27.16835 + 27.16836 + Walls.prototype = Object.create(Constraint.prototype); 27.16837 + Walls.prototype.constructor = Walls; 27.16838 + /** 27.16839 + * @property Walls.ON_CONTACT 27.16840 + * @type Object 27.16841 + * @extends Wall.ON_CONTACT 27.16842 + * @static 27.16843 + */ 27.16844 + Walls.ON_CONTACT = Wall.ON_CONTACT; 27.16845 + 27.16846 + /** 27.16847 + * An enumeration of common types of walls 27.16848 + * LEFT, RIGHT, TOP, BOTTOM, FRONT, BACK 27.16849 + * TWO_DIMENSIONAL, THREE_DIMENSIONAL 27.16850 + * 27.16851 + * @property Walls.SIDES 27.16852 + * @type Object 27.16853 + * @final 27.16854 + * @static 27.16855 + */ 27.16856 + Walls.SIDES = { 27.16857 + LEFT : 0, 27.16858 + RIGHT : 1, 27.16859 + TOP : 2, 27.16860 + BOTTOM : 3, 27.16861 + FRONT : 4, 27.16862 + BACK : 5, 27.16863 + TWO_DIMENSIONAL : [0, 1, 2, 3], 27.16864 + THREE_DIMENSIONAL : [0, 1, 2, 3, 4, 5] 27.16865 + }; 27.16866 + 27.16867 + Walls.DEFAULT_OPTIONS = { 27.16868 + sides : Walls.SIDES.TWO_DIMENSIONAL, 27.16869 + size : [window.innerWidth, window.innerHeight, 0], 27.16870 + origin : [.5, .5, .5], 27.16871 + drift : 0.5, 27.16872 + slop : 0, 27.16873 + restitution : 0.5, 27.16874 + onContact : Walls.ON_CONTACT.REFLECT 27.16875 + }; 27.16876 + 27.16877 + var _SIDE_NORMALS = { 27.16878 + 0 : new Vector(1, 0, 0), 27.16879 + 1 : new Vector(-1, 0, 0), 27.16880 + 2 : new Vector(0, 1, 0), 27.16881 + 3 : new Vector(0,-1, 0), 27.16882 + 4 : new Vector(0, 0, 1), 27.16883 + 5 : new Vector(0, 0,-1) 27.16884 + }; 27.16885 + 27.16886 + function _getDistance(side, size, origin) { 27.16887 + var distance; 27.16888 + var SIDES = Walls.SIDES; 27.16889 + switch (parseInt(side)) { 27.16890 + case SIDES.LEFT: 27.16891 + distance = size[0] * origin[0]; 27.16892 + break; 27.16893 + case SIDES.TOP: 27.16894 + distance = size[1] * origin[1]; 27.16895 + break; 27.16896 + case SIDES.FRONT: 27.16897 + distance = size[2] * origin[2]; 27.16898 + break; 27.16899 + case SIDES.RIGHT: 27.16900 + distance = size[0] * (1 - origin[0]); 27.16901 + break; 27.16902 + case SIDES.BOTTOM: 27.16903 + distance = size[1] * (1 - origin[1]); 27.16904 + break; 27.16905 + case SIDES.BACK: 27.16906 + distance = size[2] * (1 - origin[2]); 27.16907 + break; 27.16908 + } 27.16909 + return distance; 27.16910 + } 27.16911 + 27.16912 + /* 27.16913 + * Setter for options. 27.16914 + * 27.16915 + * @method setOptions 27.16916 + * @param options {Objects} 27.16917 + */ 27.16918 + Walls.prototype.setOptions = function setOptions(options) { 27.16919 + var resizeFlag = false; 27.16920 + if (options.restitution !== undefined) _setOptionsForEach.call(this, {restitution : options.restitution}); 27.16921 + if (options.drift !== undefined) _setOptionsForEach.call(this, {drift : options.drift}); 27.16922 + if (options.slop !== undefined) _setOptionsForEach.call(this, {slop : options.slop}); 27.16923 + if (options.onContact !== undefined) _setOptionsForEach.call(this, {onContact : options.onContact}); 27.16924 + if (options.size !== undefined) resizeFlag = true; 27.16925 + if (options.sides !== undefined) this.options.sides = options.sides; 27.16926 + if (options.origin !== undefined) resizeFlag = true; 27.16927 + if (resizeFlag) this.setSize(options.size, options.origin); 27.16928 + }; 27.16929 + 27.16930 + function _createComponents(sides) { 27.16931 + this.components = {}; 27.16932 + var components = this.components; 27.16933 + 27.16934 + for (var i = 0; i < sides.length; i++) { 27.16935 + var side = sides[i]; 27.16936 + components[i] = new Wall({ 27.16937 + normal : _SIDE_NORMALS[side].clone(), 27.16938 + distance : _getDistance(side, this.options.size, this.options.origin) 27.16939 + }); 27.16940 + } 27.16941 + } 27.16942 + 27.16943 + /* 27.16944 + * Setter for size. 27.16945 + * 27.16946 + * @method setOptions 27.16947 + * @param options {Objects} 27.16948 + */ 27.16949 + Walls.prototype.setSize = function setSize(size, origin) { 27.16950 + origin = origin || this.options.origin; 27.16951 + if (origin.length < 3) origin[2] = 0.5; 27.16952 + 27.16953 + this.forEach(function(wall, side) { 27.16954 + var d = _getDistance(side, size, origin); 27.16955 + wall.setOptions({distance : d}); 27.16956 + }); 27.16957 + 27.16958 + this.options.size = size; 27.16959 + this.options.origin = origin; 27.16960 + }; 27.16961 + 27.16962 + function _setOptionsForEach(options) { 27.16963 + this.forEach(function(wall) { 27.16964 + wall.setOptions(options); 27.16965 + }); 27.16966 + for (var key in options) this.options[key] = options[key]; 27.16967 + } 27.16968 + 27.16969 + /** 27.16970 + * Adds an impulse to a physics body's velocity due to the walls constraint 27.16971 + * 27.16972 + * @method applyConstraint 27.16973 + * @param targets {Array.Body} Array of bodies to apply the constraint to 27.16974 + * @param source {Body} The source of the constraint 27.16975 + * @param dt {Number} Delta time 27.16976 + */ 27.16977 + Walls.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 27.16978 + this.forEach(function(wall) { 27.16979 + wall.applyConstraint(targets, source, dt); 27.16980 + }); 27.16981 + }; 27.16982 + 27.16983 + /** 27.16984 + * Apply a method to each wall making up the walls 27.16985 + * 27.16986 + * @method applyConstraint 27.16987 + * @param fn {Function} Function that takes in a wall as its first parameter 27.16988 + */ 27.16989 + Walls.prototype.forEach = function forEach(fn) { 27.16990 + for (var key in this.sides) fn(this.sides[key], key); 27.16991 + }; 27.16992 + 27.16993 + /** 27.16994 + * Rotates the walls by an angle in the XY-plane 27.16995 + * 27.16996 + * @method applyConstraint 27.16997 + * @param angle {Function} 27.16998 + */ 27.16999 + Walls.prototype.rotateZ = function rotateZ(angle) { 27.17000 + this.forEach(function(wall) { 27.17001 + var n = wall.options.normal; 27.17002 + n.rotateZ(angle).put(n); 27.17003 + }); 27.17004 + }; 27.17005 + 27.17006 + /** 27.17007 + * Rotates the walls by an angle in the YZ-plane 27.17008 + * 27.17009 + * @method applyConstraint 27.17010 + * @param angle {Function} 27.17011 + */ 27.17012 + Walls.prototype.rotateX = function rotateX(angle) { 27.17013 + this.forEach(function(wall) { 27.17014 + var n = wall.options.normal; 27.17015 + n.rotateX(angle).put(n); 27.17016 + }); 27.17017 + }; 27.17018 + 27.17019 + /** 27.17020 + * Rotates the walls by an angle in the XZ-plane 27.17021 + * 27.17022 + * @method applyConstraint 27.17023 + * @param angle {Function} 27.17024 + */ 27.17025 + Walls.prototype.rotateY = function rotateY(angle) { 27.17026 + this.forEach(function(wall) { 27.17027 + var n = wall.options.normal; 27.17028 + n.rotateY(angle).put(n); 27.17029 + }); 27.17030 + }; 27.17031 + 27.17032 + module.exports = Walls; 27.17033 +}); 27.17034 + 27.17035 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.17036 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.17037 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.17038 + * 27.17039 + * Owner: david@famo.us 27.17040 + * @license MPL 2.0 27.17041 + * @copyright Famous Industries, Inc. 2014 27.17042 + */ 27.17043 + 27.17044 +//TODO: test options manager 27.17045 +define('famous/physics/forces/Repulsion',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 27.17046 + var Force = require('./Force'); 27.17047 + var Vector = require('famous/math/Vector'); 27.17048 + 27.17049 + /** 27.17050 + * Repulsion is a force that repels (attracts) bodies away (towards) 27.17051 + * each other. A repulsion of negative strength is attractive. 27.17052 + * 27.17053 + * @class Repulsion 27.17054 + * @constructor 27.17055 + * @extends Force 27.17056 + * @param {Object} options overwrites default options 27.17057 + */ 27.17058 + function Repulsion(options) { 27.17059 + this.options = Object.create(Repulsion.DEFAULT_OPTIONS); 27.17060 + if (options) this.setOptions(options); 27.17061 + 27.17062 + //registers 27.17063 + this.disp = new Vector(); 27.17064 + 27.17065 + Force.call(this); 27.17066 + } 27.17067 + 27.17068 + Repulsion.prototype = Object.create(Force.prototype); 27.17069 + Repulsion.prototype.constructor = Repulsion; 27.17070 + /** 27.17071 + * @property Repulsion.DECAY_FUNCTIONS 27.17072 + * @type Object 27.17073 + * @protected 27.17074 + * @static 27.17075 + */ 27.17076 + Repulsion.DECAY_FUNCTIONS = { 27.17077 + 27.17078 + /** 27.17079 + * A linear decay function 27.17080 + * @attribute LINEAR 27.17081 + * @type Function 27.17082 + * @param {Number} r distance from the source body 27.17083 + * @param {Number} cutoff the effective radius of influence 27.17084 + */ 27.17085 + LINEAR : function(r, cutoff) { 27.17086 + return Math.max(1 - (1 / cutoff) * r, 0); 27.17087 + }, 27.17088 + 27.17089 + /** 27.17090 + * A Morse potential decay function (http://en.wikipedia.org/wiki/Morse_potential) 27.17091 + * @attribute MORSE 27.17092 + * @type Function 27.17093 + * @param {Number} r distance from the source body 27.17094 + * @param {Number} cutoff the minimum radius of influence 27.17095 + */ 27.17096 + MORSE : function(r, cutoff) { 27.17097 + var r0 = (cutoff === 0) ? 100 : cutoff; 27.17098 + var rShifted = r + r0 * (1 - Math.log(2)); //shift by x-intercept 27.17099 + return Math.max(1 - Math.pow(1 - Math.exp(rShifted/r0 - 1), 2), 0); 27.17100 + }, 27.17101 + 27.17102 + /** 27.17103 + * An inverse distance decay function 27.17104 + * @attribute INVERSE 27.17105 + * @type Function 27.17106 + * @param {Number} r distance from the source body 27.17107 + * @param {Number} cutoff a distance shift to avoid singularities 27.17108 + */ 27.17109 + INVERSE : function(r, cutoff) { 27.17110 + return 1 / (1 - cutoff + r); 27.17111 + }, 27.17112 + 27.17113 + /** 27.17114 + * An inverse squared distance decay function 27.17115 + * @attribute INVERSE 27.17116 + * @type Function 27.17117 + * @param {Number} r distance from the source body 27.17118 + * @param {Number} cutoff a distance shift to avoid singularities 27.17119 + */ 27.17120 + GRAVITY : function(r, cutoff) { 27.17121 + return 1 / (1 - cutoff + r*r); 27.17122 + } 27.17123 + }; 27.17124 + 27.17125 + /** 27.17126 + * @property Repulsion.DEFAULT_OPTIONS 27.17127 + * @type Object 27.17128 + * @protected 27.17129 + * @static 27.17130 + */ 27.17131 + Repulsion.DEFAULT_OPTIONS = { 27.17132 + 27.17133 + /** 27.17134 + * The strength of the force 27.17135 + * Range : [0, 100] 27.17136 + * @attribute strength 27.17137 + * @type Number 27.17138 + * @default 1 27.17139 + */ 27.17140 + strength : 1, 27.17141 + 27.17142 + /** 27.17143 + * The location of the force, if not another physics body 27.17144 + * 27.17145 + * @attribute anchor 27.17146 + * @type Number 27.17147 + * @default 0.01 27.17148 + * @optional 27.17149 + */ 27.17150 + anchor : undefined, 27.17151 + 27.17152 + /** 27.17153 + * The range of the repulsive force 27.17154 + * @attribute radii 27.17155 + * @type Array 27.17156 + * @default [0, Infinity] 27.17157 + */ 27.17158 + range : [0, Infinity], 27.17159 + 27.17160 + /** 27.17161 + * A normalization for the force to avoid singularities at the origin 27.17162 + * @attribute cutoff 27.17163 + * @type Number 27.17164 + * @default 0 27.17165 + */ 27.17166 + cutoff : 0, 27.17167 + 27.17168 + /** 27.17169 + * The maximum magnitude of the force 27.17170 + * Range : [0, Infinity] 27.17171 + * @attribute cap 27.17172 + * @type Number 27.17173 + * @default Infinity 27.17174 + */ 27.17175 + cap : Infinity, 27.17176 + 27.17177 + /** 27.17178 + * The type of decay the repulsive force should have 27.17179 + * @attribute decayFunction 27.17180 + * @type Function 27.17181 + */ 27.17182 + decayFunction : Repulsion.DECAY_FUNCTIONS.GRAVITY 27.17183 + }; 27.17184 + 27.17185 + /* 27.17186 + * Setter for options. 27.17187 + * 27.17188 + * @method setOptions 27.17189 + * @param {Objects} options 27.17190 + */ 27.17191 + Repulsion.prototype.setOptions = function setOptions(options) { 27.17192 + if (options.anchor !== undefined) { 27.17193 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 27.17194 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 27.17195 + delete options.anchor; 27.17196 + } 27.17197 + for (var key in options) this.options[key] = options[key]; 27.17198 + }; 27.17199 + 27.17200 + /** 27.17201 + * Adds a drag force to a physics body's force accumulator. 27.17202 + * 27.17203 + * @method applyForce 27.17204 + * @param targets {Array.Body} Array of bodies to apply force to 27.17205 + * @param source {Body} The source of the force 27.17206 + */ 27.17207 + Repulsion.prototype.applyForce = function applyForce(targets, source) { 27.17208 + var options = this.options; 27.17209 + var force = this.force; 27.17210 + var disp = this.disp; 27.17211 + 27.17212 + var strength = options.strength; 27.17213 + var anchor = options.anchor || source.position; 27.17214 + var cap = options.cap; 27.17215 + var cutoff = options.cutoff; 27.17216 + var rMin = options.range[0]; 27.17217 + var rMax = options.range[1]; 27.17218 + var decayFn = options.decayFunction; 27.17219 + 27.17220 + if (strength === 0) return; 27.17221 + 27.17222 + for (var index in targets) { 27.17223 + var particle = targets[index]; 27.17224 + 27.17225 + if (particle === source) continue; 27.17226 + 27.17227 + var m1 = particle.mass; 27.17228 + var p1 = particle.position; 27.17229 + 27.17230 + disp.set(p1.sub(anchor)); 27.17231 + var r = disp.norm(); 27.17232 + 27.17233 + if (r < rMax && r > rMin) { 27.17234 + force.set(disp.normalize(strength * m1 * decayFn(r, cutoff)).cap(cap)); 27.17235 + particle.applyForce(force); 27.17236 + } 27.17237 + } 27.17238 + 27.17239 + }; 27.17240 + 27.17241 + module.exports = Repulsion; 27.17242 +}); 27.17243 + 27.17244 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.17245 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.17246 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.17247 + * 27.17248 + * Owner: david@famo.us 27.17249 + * @license MPL 2.0 27.17250 + * @copyright Famous Industries, Inc. 2014 27.17251 + */ 27.17252 + 27.17253 +define('famous/physics/forces/RotationalDrag',['require','exports','module','./Drag'],function(require, exports, module) { 27.17254 + var Drag = require('./Drag'); 27.17255 + 27.17256 + /** 27.17257 + * Rotational drag is a force that opposes angular velocity. 27.17258 + * Attach it to a physics body to slow down its rotation. 27.17259 + * 27.17260 + * @class RotationalDrag 27.17261 + * @constructor 27.17262 + * @extends Force 27.17263 + * @param {Object} options options to set on drag 27.17264 + */ 27.17265 + function RotationalDrag(options) { 27.17266 + Drag.call(this, options); 27.17267 + } 27.17268 + 27.17269 + RotationalDrag.prototype = Object.create(Drag.prototype); 27.17270 + RotationalDrag.prototype.constructor = RotationalDrag; 27.17271 + 27.17272 + RotationalDrag.DEFAULT_OPTIONS = Drag.DEFAULT_OPTIONS; 27.17273 + RotationalDrag.FORCE_FUNCTIONS = Drag.FORCE_FUNCTIONS; 27.17274 + 27.17275 + /** 27.17276 + * @property Repulsion.FORCE_FUNCTIONS 27.17277 + * @type Object 27.17278 + * @protected 27.17279 + * @static 27.17280 + */ 27.17281 + RotationalDrag.FORCE_FUNCTIONS = { 27.17282 + 27.17283 + /** 27.17284 + * A drag force proprtional to the angular velocity 27.17285 + * @attribute LINEAR 27.17286 + * @type Function 27.17287 + * @param {Vector} angularVelocity 27.17288 + * @return {Vector} drag force 27.17289 + */ 27.17290 + LINEAR : function(angularVelocity) { 27.17291 + return angularVelocity; 27.17292 + }, 27.17293 + 27.17294 + /** 27.17295 + * A drag force proprtional to the square of the angular velocity 27.17296 + * @attribute QUADRATIC 27.17297 + * @type Function 27.17298 + * @param {Vector} angularVelocity 27.17299 + * @return {Vector} drag force 27.17300 + */ 27.17301 + QUADRATIC : function(angularVelocity) { 27.17302 + return angularVelocity.mult(angularVelocity.norm()); 27.17303 + } 27.17304 + }; 27.17305 + 27.17306 + /** 27.17307 + * Adds a rotational drag force to a physics body's torque accumulator. 27.17308 + * 27.17309 + * @method applyForce 27.17310 + * @param targets {Array.Body} Array of bodies to apply drag force to. 27.17311 + */ 27.17312 + RotationalDrag.prototype.applyForce = function applyForce(targets) { 27.17313 + var strength = this.options.strength; 27.17314 + var forceFunction = this.options.forceFunction; 27.17315 + var force = this.force; 27.17316 + 27.17317 + //TODO: rotational drag as function of inertia 27.17318 + for (var index = 0; index < targets.length; index++) { 27.17319 + var particle = targets[index]; 27.17320 + forceFunction(particle.angularVelocity).mult(-100*strength).put(force); 27.17321 + particle.applyTorque(force); 27.17322 + } 27.17323 + }; 27.17324 + 27.17325 + /* 27.17326 + * Setter for options. 27.17327 + * 27.17328 + * @method setOptions 27.17329 + * @param {Objects} options 27.17330 + */ 27.17331 + RotationalDrag.prototype.setOptions = function setOptions(options) { 27.17332 + for (var key in options) this.options[key] = options[key]; 27.17333 + }; 27.17334 + 27.17335 + module.exports = RotationalDrag; 27.17336 +}); 27.17337 + 27.17338 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.17339 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.17340 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.17341 + * 27.17342 + * Owner: david@famo.us 27.17343 + * @license MPL 2.0 27.17344 + * @copyright Famous Industries, Inc. 2014 27.17345 + */ 27.17346 + 27.17347 +//TODO: test inheritance 27.17348 +define('famous/physics/forces/RotationalSpring',['require','exports','module','./Spring'],function(require, exports, module) { 27.17349 + var Spring = require('./Spring'); 27.17350 + 27.17351 + /** 27.17352 + * A force that rotates a physics body back to target Euler angles. 27.17353 + * Just as a spring translates a body to a particular X, Y, Z, location, 27.17354 + * a rotational spring rotates a body to a particular X, Y, Z Euler angle. 27.17355 + * Note: there is no physical agent that does this in the "real world" 27.17356 + * 27.17357 + * @class RotationalSpring 27.17358 + * @constructor 27.17359 + * @extends Spring 27.17360 + * @param {Object} options options to set on drag 27.17361 + */ 27.17362 + function RotationalSpring(options) { 27.17363 + Spring.call(this, options); 27.17364 + } 27.17365 + 27.17366 + RotationalSpring.prototype = Object.create(Spring.prototype); 27.17367 + RotationalSpring.prototype.constructor = RotationalSpring; 27.17368 + 27.17369 + RotationalSpring.DEFAULT_OPTIONS = Spring.DEFAULT_OPTIONS; 27.17370 + RotationalSpring.FORCE_FUNCTIONS = Spring.FORCE_FUNCTIONS; 27.17371 + 27.17372 + /** 27.17373 + * Adds a torque force to a physics body's torque accumulator. 27.17374 + * 27.17375 + * @method applyForce 27.17376 + * @param targets {Array.Body} Array of bodies to apply torque to. 27.17377 + */ 27.17378 + RotationalSpring.prototype.applyForce = function applyForce(targets) { 27.17379 + var force = this.force; 27.17380 + var options = this.options; 27.17381 + var disp = this.disp; 27.17382 + 27.17383 + var stiffness = options.stiffness; 27.17384 + var damping = options.damping; 27.17385 + var restLength = options.length; 27.17386 + var anchor = options.anchor; 27.17387 + 27.17388 + for (var i = 0; i < targets.length; i++) { 27.17389 + var target = targets[i]; 27.17390 + 27.17391 + disp.set(anchor.sub(target.orientation)); 27.17392 + var dist = disp.norm() - restLength; 27.17393 + 27.17394 + if (dist === 0) return; 27.17395 + 27.17396 + //if dampingRatio specified, then override strength and damping 27.17397 + var m = target.mass; 27.17398 + stiffness *= m; 27.17399 + damping *= m; 27.17400 + 27.17401 + force.set(disp.normalize(stiffness * this.forceFunction(dist, this.options.lMax))); 27.17402 + 27.17403 + if (damping) force.set(force.add(target.angularVelocity.mult(-damping))); 27.17404 + 27.17405 + target.applyTorque(force); 27.17406 + } 27.17407 + }; 27.17408 + 27.17409 + /** 27.17410 + * Calculates the potential energy of the rotational spring. 27.17411 + * 27.17412 + * @method getEnergy 27.17413 + * @param {Body} target The physics body attached to the spring 27.17414 + */ 27.17415 + RotationalSpring.prototype.getEnergy = function getEnergy(target) { 27.17416 + var options = this.options; 27.17417 + var restLength = options.length; 27.17418 + var anchor = options.anchor; 27.17419 + var strength = options.stiffness; 27.17420 + 27.17421 + var dist = anchor.sub(target.orientation).norm() - restLength; 27.17422 + return 0.5 * strength * dist * dist; 27.17423 + }; 27.17424 + 27.17425 + module.exports = RotationalSpring; 27.17426 +}); 27.17427 + 27.17428 +/* This Source Code Form is subject to the terms of the Mozilla Public 27.17429 + * License, v. 2.0. If a copy of the MPL was not distributed with this 27.17430 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 27.17431 + * 27.17432 + * Owner: david@famo.us 27.17433 + * @license MPL 2.0 27.17434 + * @copyright Famous Industries, Inc. 2014 27.17435 + */ 27.17436 + 27.17437 +define('famous/physics/forces/VectorField',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 27.17438 + var Force = require('./Force'); 27.17439 + var Vector = require('famous/math/Vector'); 27.17440 + 27.17441 + /** 27.17442 + * A force that moves a physics body to a location with a spring motion. 27.17443 + * The body can be moved to another physics body, or an anchor point. 27.17444 + * 27.17445 + * @class VectorField 27.17446 + * @constructor 27.17447 + * @extends Force 27.17448 + * @param {Object} options options to set on drag 27.17449 + */ 27.17450 + function VectorField(options) { 27.17451 + this.options = Object.create(VectorField.DEFAULT_OPTIONS); 27.17452 + if (options) this.setOptions(options); 27.17453 + 27.17454 + _setFieldOptions.call(this, this.options.field); 27.17455 + Force.call(this); 27.17456 + 27.17457 + //registers 27.17458 + this.evaluation = new Vector(0,0,0); 27.17459 + } 27.17460 + 27.17461 + VectorField.prototype = Object.create(Force.prototype); 27.17462 + VectorField.prototype.constructor = VectorField; 27.17463 + 27.17464 + /** 27.17465 + * @property Spring.FORCE_FUNCTIONS 27.17466 + * @type Object 27.17467 + * @protected 27.17468 + * @static 27.17469 + */ 27.17470 + VectorField.FIELDS = { 27.17471 + /** 27.17472 + * Constant force, e.g., gravity 27.17473 + * @attribute CONSTANT 27.17474 + * @type Function 27.17475 + * @param v {Vector} Current position of physics body 27.17476 + * @param options {Object} The direction of the force 27.17477 + * Pass a {direction : Vector} into the VectorField options 27.17478 + * @return {Number} unscaled force 27.17479 + */ 27.17480 + CONSTANT : function(v, options) { 27.17481 + return v.set(options.direction); 27.17482 + }, 27.17483 + 27.17484 + /** 27.17485 + * Linear force 27.17486 + * @attribute LINEAR 27.17487 + * @type Function 27.17488 + * @param v {Vector} Current position of physics body 27.17489 + * @return {Number} unscaled force 27.17490 + */ 27.17491 + LINEAR : function(v) { 27.17492 + return v; 27.17493 + }, 27.17494 + 27.17495 + /** 27.17496 + * Radial force, e.g., Hookean spring 27.17497 + * @attribute RADIAL 27.17498 + * @type Function 27.17499 + * @param v {Vector} Current position of physics body 27.17500 + * @return {Number} unscaled force 27.17501 + */ 27.17502 + RADIAL : function(v) { 27.17503 + return v.set(v.mult(-1, v)); 27.17504 + }, 27.17505 + 27.17506 + /** 27.17507 + * Spherical force 27.17508 + * @attribute SPHERE_ATTRACTOR 27.17509 + * @type Function 27.17510 + * @param v {Vector} Current position of physics body 27.17511 + * @param options {Object} An object with the radius of the sphere 27.17512 + * Pass a {radius : Number} into the VectorField options 27.17513 + * @return {Number} unscaled force 27.17514 + */ 27.17515 + SPHERE_ATTRACTOR : function(v, options) { 27.17516 + return v.set(v.mult((options.radius - v.norm()) / v.norm())); 27.17517 + }, 27.17518 + 27.17519 + /** 27.17520 + * Point attractor force, e.g., Hookean spring with an anchor 27.17521 + * @attribute POINT_ATTRACTOR 27.17522 + * @type Function 27.17523 + * @param v {Vector} Current position of physics body 27.17524 + * @param options {Object} And object with the position of the attractor 27.17525 + * Pass a {position : Vector} into the VectorField options 27.17526 + * @return {Number} unscaled force 27.17527 + */ 27.17528 + POINT_ATTRACTOR : function(v, options) { 27.17529 + return v.set(options.position.sub(v)); 27.17530 + } 27.17531 + }; 27.17532 + 27.17533 + /** 27.17534 + * @property VectorField.DEFAULT_OPTIONS 27.17535 + * @type Object 27.17536 + * @protected 27.17537 + * @static 27.17538 + */ 27.17539 + VectorField.DEFAULT_OPTIONS = { 27.17540 + 27.17541 + /** 27.17542 + * The strength of the force 27.17543 + * Range : [0, 10] 27.17544 + * @attribute strength 27.17545 + * @type Number 27.17546 + * @default 1 27.17547 + */ 27.17548 + strength : 1, 27.17549 + 27.17550 + /** 27.17551 + * Type of vectorfield 27.17552 + * Range : [0, 100] 27.17553 + * @attribute field 27.17554 + * @type Function 27.17555 + */ 27.17556 + field : VectorField.FIELDS.CONSTANT 27.17557 + }; 27.17558 + 27.17559 + /** 27.17560 + * Basic options setter 27.17561 + * 27.17562 + * @method setOptions 27.17563 + * @param {Objects} options 27.17564 + */ 27.17565 + VectorField.prototype.setOptions = function setOptions(options) { 27.17566 + for (var key in options) this.options[key] = options[key]; 27.17567 + }; 27.17568 + 27.17569 + function _setFieldOptions(field) { 27.17570 + var FIELDS = VectorField.FIELDS; 27.17571 + 27.17572 + switch (field) { 27.17573 + case FIELDS.CONSTANT: 27.17574 + if (!this.options.direction) this.options.direction = new Vector(0,1,0); 27.17575 + break; 27.17576 + case FIELDS.POINT_ATTRACTOR: 27.17577 + if (!this.options.position) this.options.position = new Vector(0,0,0); 27.17578 + break; 27.17579 + case FIELDS.SPHERE_ATTRACTOR: 27.17580 + if (!this.options.radius) this.options.radius = 1; 27.17581 + break; 27.17582 + } 27.17583 + } 27.17584 + 27.17585 + function _evaluate(v) { 27.17586 + var evaluation = this.evaluation; 27.17587 + var field = this.options.field; 27.17588 + evaluation.set(v); 27.17589 + return field(evaluation, this.options); 27.17590 + } 27.17591 + 27.17592 + /** 27.17593 + * Adds the vectorfield's force to a physics body's force accumulator. 27.17594 + * 27.17595 + * @method applyForce 27.17596 + * @param targets {Array.body} Array of bodies to apply force to. 27.17597 + */ 27.17598 + VectorField.prototype.applyForce = function applyForce(targets) { 27.17599 + var force = this.force; 27.17600 + for (var i = 0; i < targets.length; i++) { 27.17601 + var particle = targets[i]; 27.17602 + force.set( 27.17603 + _evaluate.call(this, particle.position) 27.17604 + .mult(particle.mass * this.options.strength) 27.17605 + ); 27.17606 + particle.applyForce(force); 27.17607 + } 27.17608 + }; 27.17609 + 27.17610 + module.exports = VectorField; 27.17611 +}); 27.17612 +
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous_styles.css Sun Jul 06 12:02:12 2014 -0700 28.3 @@ -0,0 +1,163 @@ 28.4 +body { 28.5 + color: #404040; 28.6 + background-color: #f2f2f0; 28.7 +} 28.8 + 28.9 +.main { 28.10 + background-color: white; 28.11 +} 28.12 + 28.13 +a { 28.14 + color: #fa5c4f; 28.15 +} 28.16 + 28.17 +.red { 28.18 + color: #fa5c4f; 28.19 +} 28.20 + 28.21 +.light-grey { 28.22 + color: #f2f2f0; 28.23 +} 28.24 + 28.25 +.medium-grey { 28.26 + color: #878785; 28.27 +} 28.28 + 28.29 +.red-bg { 28.30 + color: white; 28.31 + background-color: #fa5c4f; 28.32 +} 28.33 + 28.34 +.red-outline { 28.35 + border: 2px solid #fa5c4f; 28.36 +} 28.37 + 28.38 +.grey-bg { 28.39 + background-color: #404040; 28.40 + color: white; 28.41 +} 28.42 + 28.43 +.spacer-line { 28.44 + border-top: 1px solid #fa5c4f; 28.45 +} 28.46 + 28.47 +.white-bg { 28.48 + background-color: white; 28.49 +} 28.50 + 28.51 +@font-face { 28.52 + font-family: "Avenir Next W04 Demi"; 28.53 + src: url("fonts/7adddd91-84e0-4423-b40e-61945189916d.eot") format("eot"), url("fonts/b0908846-3d5c-4768-af33-5f968b1da156.woff") format("woff"), url("fonts/fe1602be-28ca-467e-9cd3-7bfc586f31bc.ttf") format("truetype"); 28.54 +} 28.55 + 28.56 +@font-face { 28.57 + font-family: "AvenirNextLTW02-Regular"; 28.58 + src: url("fonts/7a1b7ae7-5c29-481f-83ac-652e932c5509.eot") format("eot"), url("fonts/3a42a252-67ff-4186-88cf-762f56719ca1.woff") format("woff"), url("fonts/dbc39ae3-2636-4653-a23e-8938bce2cf51.ttf") format("truetype"); 28.59 +} 28.60 + 28.61 +input:focus { 28.62 + border: 1px solid #fa5c4f; 28.63 +} 28.64 + 28.65 +input:hover { 28.66 + border: 1px solid #404040; 28.67 +} 28.68 + 28.69 +input { 28.70 + outline: 0px; 28.71 + border-radius: 5px; 28.72 + border: 1px solid #f2f2f0; 28.73 + padding: 18px; 28.74 +} 28.75 + 28.76 +body, input { 28.77 + font-family: "AvenirNextLTW02-Regular", sans-serif; 28.78 + font-size: 16px; 28.79 + line-height: 25px; 28.80 +} 28.81 + 28.82 +h1 { 28.83 + font-size: 67px; 28.84 + line-height: 109px; 28.85 + margin-bottom: 67px; 28.86 +} 28.87 + 28.88 +h2 { 28.89 + font-size: 41px; 28.90 + line-height: 67px; 28.91 + margin-bottom: 41px; 28.92 +} 28.93 + 28.94 +h3 { 28.95 + font-size: 25px; 28.96 + line-height: 41px; 28.97 + margin-bottom: 25px; 28.98 +} 28.99 + 28.100 +h4 { 28.101 + font-family: "Avenir Next W04 Demi"; 28.102 +} 28.103 + 28.104 +h4, h5, h6, p, li, a { 28.105 + font-size: 16px; 28.106 + line-height: 25px; 28.107 +} 28.108 + 28.109 +h1, h2, h3, h4, h5, h6 { 28.110 + max-width: 845px; 28.111 +} 28.112 + 28.113 +p { 28.114 + max-width: 522px; 28.115 +} 28.116 + 28.117 +h5 { 28.118 + text-transform: uppercase; 28.119 +} 28.120 + 28.121 +a { 28.122 + text-decoration: none; 28.123 +} 28.124 + 28.125 +a:hover { 28.126 + text-decoration: underline; 28.127 +} 28.128 + 28.129 +pre { 28.130 + font-family: monospace; 28.131 + width: 100%; 28.132 + background-color: #404040; 28.133 + border-radius: 5px; 28.134 + padding: 27px 18px; 28.135 + overflow-x: scroll; 28.136 +} 28.137 + 28.138 +ul { 28.139 + margin-left: 25px; 28.140 +} 28.141 + 28.142 +code { 28.143 + width: 100%; 28.144 +} 28.145 + 28.146 +p, pre, ul { 28.147 + margin-bottom: 25px; 28.148 +} 28.149 + 28.150 +small { 28.151 + font-size: 9px; 28.152 + line-height: 9px; 28.153 +} 28.154 + 28.155 +.button { 28.156 + padding: 18px; 28.157 + border-radius: 3px; 28.158 + margin: 29px 0px; 28.159 +} 28.160 + 28.161 +.backface-visible { 28.162 + backface-visibility: visible; 28.163 + -webkit-backface-visibility: visible; 28.164 + -moz-backface-visibility: visible; 28.165 + -ms-backface-visibility: visible; 28.166 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/functionPrototypeBind.js Sun Jul 06 12:02:12 2014 -0700 29.3 @@ -0,0 +1,23 @@ 29.4 +if (!Function.prototype.bind) { 29.5 + Function.prototype.bind = function (oThis) { 29.6 + if (typeof this !== "function") { 29.7 + // closest thing possible to the ECMAScript 5 internal IsCallable function 29.8 + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 29.9 + } 29.10 + 29.11 + var aArgs = Array.prototype.slice.call(arguments, 1), 29.12 + fToBind = this, 29.13 + fNOP = function () {}, 29.14 + fBound = function () { 29.15 + return fToBind.apply(this instanceof fNOP && oThis 29.16 + ? this 29.17 + : oThis, 29.18 + aArgs.concat(Array.prototype.slice.call(arguments))); 29.19 + }; 29.20 + 29.21 + fNOP.prototype = this.prototype; 29.22 + fBound.prototype = new fNOP(); 29.23 + 29.24 + return fBound; 29.25 + }; 29.26 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/jquery.min.js Sun Jul 06 12:02:12 2014 -0700 30.3 @@ -0,0 +1,4 @@ 30.4 +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ 30.5 +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; 30.6 +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px") 30.7 +},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m}); 30.8 \ No newline at end of file
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/requestAnimationFrame.js Sun Jul 06 12:02:12 2014 -0700 31.3 @@ -0,0 +1,13 @@ 31.4 +// adds requestAnimationFrame functionality 31.5 +// Source: http://strd6.com/2011/05/better-window-requestanimationframe-shim/ 31.6 + 31.7 +window.requestAnimationFrame || (window.requestAnimationFrame = 31.8 + window.webkitRequestAnimationFrame || 31.9 + window.mozRequestAnimationFrame || 31.10 + window.oRequestAnimationFrame || 31.11 + window.msRequestAnimationFrame || 31.12 + function(callback, element) { 31.13 + return window.setTimeout(function() { 31.14 + callback(+new Date()); 31.15 + }, 1000 / 60); 31.16 +});
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/require.js Sun Jul 06 12:02:12 2014 -0700 32.3 @@ -0,0 +1,2076 @@ 32.4 +/** vim: et:ts=4:sw=4:sts=4 32.5 + * @license RequireJS 2.1.14 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 32.6 + * Available via the MIT or new BSD license. 32.7 + * see: http://github.com/jrburke/requirejs for details 32.8 + */ 32.9 +//Not using strict: uneven strict support in browsers, #392, and causes 32.10 +//problems with requirejs.exec()/transpiler plugins that may not be strict. 32.11 +/*jslint regexp: true, nomen: true, sloppy: true */ 32.12 +/*global window, navigator, document, importScripts, setTimeout, opera */ 32.13 + 32.14 +var requirejs, require, define; 32.15 +(function (global) { 32.16 + var req, s, head, baseElement, dataMain, src, 32.17 + interactiveScript, currentlyAddingScript, mainScript, subPath, 32.18 + version = '2.1.14', 32.19 + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, 32.20 + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, 32.21 + jsSuffixRegExp = /\.js$/, 32.22 + currDirRegExp = /^\.\//, 32.23 + op = Object.prototype, 32.24 + ostring = op.toString, 32.25 + hasOwn = op.hasOwnProperty, 32.26 + ap = Array.prototype, 32.27 + apsp = ap.splice, 32.28 + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), 32.29 + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', 32.30 + //PS3 indicates loaded and complete, but need to wait for complete 32.31 + //specifically. Sequence is 'loading', 'loaded', execution, 32.32 + // then 'complete'. The UA check is unfortunate, but not sure how 32.33 + //to feature test w/o causing perf issues. 32.34 + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? 32.35 + /^complete$/ : /^(complete|loaded)$/, 32.36 + defContextName = '_', 32.37 + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. 32.38 + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', 32.39 + contexts = {}, 32.40 + cfg = {}, 32.41 + globalDefQueue = [], 32.42 + useInteractive = false; 32.43 + 32.44 + function isFunction(it) { 32.45 + return ostring.call(it) === '[object Function]'; 32.46 + } 32.47 + 32.48 + function isArray(it) { 32.49 + return ostring.call(it) === '[object Array]'; 32.50 + } 32.51 + 32.52 + /** 32.53 + * Helper function for iterating over an array. If the func returns 32.54 + * a true value, it will break out of the loop. 32.55 + */ 32.56 + function each(ary, func) { 32.57 + if (ary) { 32.58 + var i; 32.59 + for (i = 0; i < ary.length; i += 1) { 32.60 + if (ary[i] && func(ary[i], i, ary)) { 32.61 + break; 32.62 + } 32.63 + } 32.64 + } 32.65 + } 32.66 + 32.67 + /** 32.68 + * Helper function for iterating over an array backwards. If the func 32.69 + * returns a true value, it will break out of the loop. 32.70 + */ 32.71 + function eachReverse(ary, func) { 32.72 + if (ary) { 32.73 + var i; 32.74 + for (i = ary.length - 1; i > -1; i -= 1) { 32.75 + if (ary[i] && func(ary[i], i, ary)) { 32.76 + break; 32.77 + } 32.78 + } 32.79 + } 32.80 + } 32.81 + 32.82 + function hasProp(obj, prop) { 32.83 + return hasOwn.call(obj, prop); 32.84 + } 32.85 + 32.86 + function getOwn(obj, prop) { 32.87 + return hasProp(obj, prop) && obj[prop]; 32.88 + } 32.89 + 32.90 + /** 32.91 + * Cycles over properties in an object and calls a function for each 32.92 + * property value. If the function returns a truthy value, then the 32.93 + * iteration is stopped. 32.94 + */ 32.95 + function eachProp(obj, func) { 32.96 + var prop; 32.97 + for (prop in obj) { 32.98 + if (hasProp(obj, prop)) { 32.99 + if (func(obj[prop], prop)) { 32.100 + break; 32.101 + } 32.102 + } 32.103 + } 32.104 + } 32.105 + 32.106 + /** 32.107 + * Simple function to mix in properties from source into target, 32.108 + * but only if target does not already have a property of the same name. 32.109 + */ 32.110 + function mixin(target, source, force, deepStringMixin) { 32.111 + if (source) { 32.112 + eachProp(source, function (value, prop) { 32.113 + if (force || !hasProp(target, prop)) { 32.114 + if (deepStringMixin && typeof value === 'object' && value && 32.115 + !isArray(value) && !isFunction(value) && 32.116 + !(value instanceof RegExp)) { 32.117 + 32.118 + if (!target[prop]) { 32.119 + target[prop] = {}; 32.120 + } 32.121 + mixin(target[prop], value, force, deepStringMixin); 32.122 + } else { 32.123 + target[prop] = value; 32.124 + } 32.125 + } 32.126 + }); 32.127 + } 32.128 + return target; 32.129 + } 32.130 + 32.131 + //Similar to Function.prototype.bind, but the 'this' object is specified 32.132 + //first, since it is easier to read/figure out what 'this' will be. 32.133 + function bind(obj, fn) { 32.134 + return function () { 32.135 + return fn.apply(obj, arguments); 32.136 + }; 32.137 + } 32.138 + 32.139 + function scripts() { 32.140 + return document.getElementsByTagName('script'); 32.141 + } 32.142 + 32.143 + function defaultOnError(err) { 32.144 + throw err; 32.145 + } 32.146 + 32.147 + //Allow getting a global that is expressed in 32.148 + //dot notation, like 'a.b.c'. 32.149 + function getGlobal(value) { 32.150 + if (!value) { 32.151 + return value; 32.152 + } 32.153 + var g = global; 32.154 + each(value.split('.'), function (part) { 32.155 + g = g[part]; 32.156 + }); 32.157 + return g; 32.158 + } 32.159 + 32.160 + /** 32.161 + * Constructs an error with a pointer to an URL with more information. 32.162 + * @param {String} id the error ID that maps to an ID on a web page. 32.163 + * @param {String} message human readable error. 32.164 + * @param {Error} [err] the original error, if there is one. 32.165 + * 32.166 + * @returns {Error} 32.167 + */ 32.168 + function makeError(id, msg, err, requireModules) { 32.169 + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); 32.170 + e.requireType = id; 32.171 + e.requireModules = requireModules; 32.172 + if (err) { 32.173 + e.originalError = err; 32.174 + } 32.175 + return e; 32.176 + } 32.177 + 32.178 + if (typeof define !== 'undefined') { 32.179 + //If a define is already in play via another AMD loader, 32.180 + //do not overwrite. 32.181 + return; 32.182 + } 32.183 + 32.184 + if (typeof requirejs !== 'undefined') { 32.185 + if (isFunction(requirejs)) { 32.186 + //Do not overwrite an existing requirejs instance. 32.187 + return; 32.188 + } 32.189 + cfg = requirejs; 32.190 + requirejs = undefined; 32.191 + } 32.192 + 32.193 + //Allow for a require config object 32.194 + if (typeof require !== 'undefined' && !isFunction(require)) { 32.195 + //assume it is a config object. 32.196 + cfg = require; 32.197 + require = undefined; 32.198 + } 32.199 + 32.200 + function newContext(contextName) { 32.201 + var inCheckLoaded, Module, context, handlers, 32.202 + checkLoadedTimeoutId, 32.203 + config = { 32.204 + //Defaults. Do not set a default for map 32.205 + //config to speed up normalize(), which 32.206 + //will run faster if there is no default. 32.207 + waitSeconds: 7, 32.208 + baseUrl: './', 32.209 + paths: {}, 32.210 + bundles: {}, 32.211 + pkgs: {}, 32.212 + shim: {}, 32.213 + config: {} 32.214 + }, 32.215 + registry = {}, 32.216 + //registry of just enabled modules, to speed 32.217 + //cycle breaking code when lots of modules 32.218 + //are registered, but not activated. 32.219 + enabledRegistry = {}, 32.220 + undefEvents = {}, 32.221 + defQueue = [], 32.222 + defined = {}, 32.223 + urlFetched = {}, 32.224 + bundlesMap = {}, 32.225 + requireCounter = 1, 32.226 + unnormalizedCounter = 1; 32.227 + 32.228 + /** 32.229 + * Trims the . and .. from an array of path segments. 32.230 + * It will keep a leading path segment if a .. will become 32.231 + * the first path segment, to help with module name lookups, 32.232 + * which act like paths, but can be remapped. But the end result, 32.233 + * all paths that use this function should look normalized. 32.234 + * NOTE: this method MODIFIES the input array. 32.235 + * @param {Array} ary the array of path segments. 32.236 + */ 32.237 + function trimDots(ary) { 32.238 + var i, part; 32.239 + for (i = 0; i < ary.length; i++) { 32.240 + part = ary[i]; 32.241 + if (part === '.') { 32.242 + ary.splice(i, 1); 32.243 + i -= 1; 32.244 + } else if (part === '..') { 32.245 + // If at the start, or previous value is still .., 32.246 + // keep them so that when converted to a path it may 32.247 + // still work when converted to a path, even though 32.248 + // as an ID it is less than ideal. In larger point 32.249 + // releases, may be better to just kick out an error. 32.250 + if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') { 32.251 + continue; 32.252 + } else if (i > 0) { 32.253 + ary.splice(i - 1, 2); 32.254 + i -= 2; 32.255 + } 32.256 + } 32.257 + } 32.258 + } 32.259 + 32.260 + /** 32.261 + * Given a relative module name, like ./something, normalize it to 32.262 + * a real name that can be mapped to a path. 32.263 + * @param {String} name the relative name 32.264 + * @param {String} baseName a real name that the name arg is relative 32.265 + * to. 32.266 + * @param {Boolean} applyMap apply the map config to the value. Should 32.267 + * only be done if this normalization is for a dependency ID. 32.268 + * @returns {String} normalized name 32.269 + */ 32.270 + function normalize(name, baseName, applyMap) { 32.271 + var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, 32.272 + foundMap, foundI, foundStarMap, starI, normalizedBaseParts, 32.273 + baseParts = (baseName && baseName.split('/')), 32.274 + map = config.map, 32.275 + starMap = map && map['*']; 32.276 + 32.277 + //Adjust any relative paths. 32.278 + if (name) { 32.279 + name = name.split('/'); 32.280 + lastIndex = name.length - 1; 32.281 + 32.282 + // If wanting node ID compatibility, strip .js from end 32.283 + // of IDs. Have to do this here, and not in nameToUrl 32.284 + // because node allows either .js or non .js to map 32.285 + // to same file. 32.286 + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { 32.287 + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); 32.288 + } 32.289 + 32.290 + // Starts with a '.' so need the baseName 32.291 + if (name[0].charAt(0) === '.' && baseParts) { 32.292 + //Convert baseName to array, and lop off the last part, 32.293 + //so that . matches that 'directory' and not name of the baseName's 32.294 + //module. For instance, baseName of 'one/two/three', maps to 32.295 + //'one/two/three.js', but we want the directory, 'one/two' for 32.296 + //this normalization. 32.297 + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); 32.298 + name = normalizedBaseParts.concat(name); 32.299 + } 32.300 + 32.301 + trimDots(name); 32.302 + name = name.join('/'); 32.303 + } 32.304 + 32.305 + //Apply map config if available. 32.306 + if (applyMap && map && (baseParts || starMap)) { 32.307 + nameParts = name.split('/'); 32.308 + 32.309 + outerLoop: for (i = nameParts.length; i > 0; i -= 1) { 32.310 + nameSegment = nameParts.slice(0, i).join('/'); 32.311 + 32.312 + if (baseParts) { 32.313 + //Find the longest baseName segment match in the config. 32.314 + //So, do joins on the biggest to smallest lengths of baseParts. 32.315 + for (j = baseParts.length; j > 0; j -= 1) { 32.316 + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); 32.317 + 32.318 + //baseName segment has config, find if it has one for 32.319 + //this name. 32.320 + if (mapValue) { 32.321 + mapValue = getOwn(mapValue, nameSegment); 32.322 + if (mapValue) { 32.323 + //Match, update name to the new value. 32.324 + foundMap = mapValue; 32.325 + foundI = i; 32.326 + break outerLoop; 32.327 + } 32.328 + } 32.329 + } 32.330 + } 32.331 + 32.332 + //Check for a star map match, but just hold on to it, 32.333 + //if there is a shorter segment match later in a matching 32.334 + //config, then favor over this star map. 32.335 + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { 32.336 + foundStarMap = getOwn(starMap, nameSegment); 32.337 + starI = i; 32.338 + } 32.339 + } 32.340 + 32.341 + if (!foundMap && foundStarMap) { 32.342 + foundMap = foundStarMap; 32.343 + foundI = starI; 32.344 + } 32.345 + 32.346 + if (foundMap) { 32.347 + nameParts.splice(0, foundI, foundMap); 32.348 + name = nameParts.join('/'); 32.349 + } 32.350 + } 32.351 + 32.352 + // If the name points to a package's name, use 32.353 + // the package main instead. 32.354 + pkgMain = getOwn(config.pkgs, name); 32.355 + 32.356 + return pkgMain ? pkgMain : name; 32.357 + } 32.358 + 32.359 + function removeScript(name) { 32.360 + if (isBrowser) { 32.361 + each(scripts(), function (scriptNode) { 32.362 + if (scriptNode.getAttribute('data-requiremodule') === name && 32.363 + scriptNode.getAttribute('data-requirecontext') === context.contextName) { 32.364 + scriptNode.parentNode.removeChild(scriptNode); 32.365 + return true; 32.366 + } 32.367 + }); 32.368 + } 32.369 + } 32.370 + 32.371 + function hasPathFallback(id) { 32.372 + var pathConfig = getOwn(config.paths, id); 32.373 + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { 32.374 + //Pop off the first array value, since it failed, and 32.375 + //retry 32.376 + pathConfig.shift(); 32.377 + context.require.undef(id); 32.378 + 32.379 + //Custom require that does not do map translation, since 32.380 + //ID is "absolute", already mapped/resolved. 32.381 + context.makeRequire(null, { 32.382 + skipMap: true 32.383 + })([id]); 32.384 + 32.385 + return true; 32.386 + } 32.387 + } 32.388 + 32.389 + //Turns a plugin!resource to [plugin, resource] 32.390 + //with the plugin being undefined if the name 32.391 + //did not have a plugin prefix. 32.392 + function splitPrefix(name) { 32.393 + var prefix, 32.394 + index = name ? name.indexOf('!') : -1; 32.395 + if (index > -1) { 32.396 + prefix = name.substring(0, index); 32.397 + name = name.substring(index + 1, name.length); 32.398 + } 32.399 + return [prefix, name]; 32.400 + } 32.401 + 32.402 + /** 32.403 + * Creates a module mapping that includes plugin prefix, module 32.404 + * name, and path. If parentModuleMap is provided it will 32.405 + * also normalize the name via require.normalize() 32.406 + * 32.407 + * @param {String} name the module name 32.408 + * @param {String} [parentModuleMap] parent module map 32.409 + * for the module name, used to resolve relative names. 32.410 + * @param {Boolean} isNormalized: is the ID already normalized. 32.411 + * This is true if this call is done for a define() module ID. 32.412 + * @param {Boolean} applyMap: apply the map config to the ID. 32.413 + * Should only be true if this map is for a dependency. 32.414 + * 32.415 + * @returns {Object} 32.416 + */ 32.417 + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { 32.418 + var url, pluginModule, suffix, nameParts, 32.419 + prefix = null, 32.420 + parentName = parentModuleMap ? parentModuleMap.name : null, 32.421 + originalName = name, 32.422 + isDefine = true, 32.423 + normalizedName = ''; 32.424 + 32.425 + //If no name, then it means it is a require call, generate an 32.426 + //internal name. 32.427 + if (!name) { 32.428 + isDefine = false; 32.429 + name = '_@r' + (requireCounter += 1); 32.430 + } 32.431 + 32.432 + nameParts = splitPrefix(name); 32.433 + prefix = nameParts[0]; 32.434 + name = nameParts[1]; 32.435 + 32.436 + if (prefix) { 32.437 + prefix = normalize(prefix, parentName, applyMap); 32.438 + pluginModule = getOwn(defined, prefix); 32.439 + } 32.440 + 32.441 + //Account for relative paths if there is a base name. 32.442 + if (name) { 32.443 + if (prefix) { 32.444 + if (pluginModule && pluginModule.normalize) { 32.445 + //Plugin is loaded, use its normalize method. 32.446 + normalizedName = pluginModule.normalize(name, function (name) { 32.447 + return normalize(name, parentName, applyMap); 32.448 + }); 32.449 + } else { 32.450 + // If nested plugin references, then do not try to 32.451 + // normalize, as it will not normalize correctly. This 32.452 + // places a restriction on resourceIds, and the longer 32.453 + // term solution is not to normalize until plugins are 32.454 + // loaded and all normalizations to allow for async 32.455 + // loading of a loader plugin. But for now, fixes the 32.456 + // common uses. Details in #1131 32.457 + normalizedName = name.indexOf('!') === -1 ? 32.458 + normalize(name, parentName, applyMap) : 32.459 + name; 32.460 + } 32.461 + } else { 32.462 + //A regular module. 32.463 + normalizedName = normalize(name, parentName, applyMap); 32.464 + 32.465 + //Normalized name may be a plugin ID due to map config 32.466 + //application in normalize. The map config values must 32.467 + //already be normalized, so do not need to redo that part. 32.468 + nameParts = splitPrefix(normalizedName); 32.469 + prefix = nameParts[0]; 32.470 + normalizedName = nameParts[1]; 32.471 + isNormalized = true; 32.472 + 32.473 + url = context.nameToUrl(normalizedName); 32.474 + } 32.475 + } 32.476 + 32.477 + //If the id is a plugin id that cannot be determined if it needs 32.478 + //normalization, stamp it with a unique ID so two matching relative 32.479 + //ids that may conflict can be separate. 32.480 + suffix = prefix && !pluginModule && !isNormalized ? 32.481 + '_unnormalized' + (unnormalizedCounter += 1) : 32.482 + ''; 32.483 + 32.484 + return { 32.485 + prefix: prefix, 32.486 + name: normalizedName, 32.487 + parentMap: parentModuleMap, 32.488 + unnormalized: !!suffix, 32.489 + url: url, 32.490 + originalName: originalName, 32.491 + isDefine: isDefine, 32.492 + id: (prefix ? 32.493 + prefix + '!' + normalizedName : 32.494 + normalizedName) + suffix 32.495 + }; 32.496 + } 32.497 + 32.498 + function getModule(depMap) { 32.499 + var id = depMap.id, 32.500 + mod = getOwn(registry, id); 32.501 + 32.502 + if (!mod) { 32.503 + mod = registry[id] = new context.Module(depMap); 32.504 + } 32.505 + 32.506 + return mod; 32.507 + } 32.508 + 32.509 + function on(depMap, name, fn) { 32.510 + var id = depMap.id, 32.511 + mod = getOwn(registry, id); 32.512 + 32.513 + if (hasProp(defined, id) && 32.514 + (!mod || mod.defineEmitComplete)) { 32.515 + if (name === 'defined') { 32.516 + fn(defined[id]); 32.517 + } 32.518 + } else { 32.519 + mod = getModule(depMap); 32.520 + if (mod.error && name === 'error') { 32.521 + fn(mod.error); 32.522 + } else { 32.523 + mod.on(name, fn); 32.524 + } 32.525 + } 32.526 + } 32.527 + 32.528 + function onError(err, errback) { 32.529 + var ids = err.requireModules, 32.530 + notified = false; 32.531 + 32.532 + if (errback) { 32.533 + errback(err); 32.534 + } else { 32.535 + each(ids, function (id) { 32.536 + var mod = getOwn(registry, id); 32.537 + if (mod) { 32.538 + //Set error on module, so it skips timeout checks. 32.539 + mod.error = err; 32.540 + if (mod.events.error) { 32.541 + notified = true; 32.542 + mod.emit('error', err); 32.543 + } 32.544 + } 32.545 + }); 32.546 + 32.547 + if (!notified) { 32.548 + req.onError(err); 32.549 + } 32.550 + } 32.551 + } 32.552 + 32.553 + /** 32.554 + * Internal method to transfer globalQueue items to this context's 32.555 + * defQueue. 32.556 + */ 32.557 + function takeGlobalQueue() { 32.558 + //Push all the globalDefQueue items into the context's defQueue 32.559 + if (globalDefQueue.length) { 32.560 + //Array splice in the values since the context code has a 32.561 + //local var ref to defQueue, so cannot just reassign the one 32.562 + //on context. 32.563 + apsp.apply(defQueue, 32.564 + [defQueue.length, 0].concat(globalDefQueue)); 32.565 + globalDefQueue = []; 32.566 + } 32.567 + } 32.568 + 32.569 + handlers = { 32.570 + 'require': function (mod) { 32.571 + if (mod.require) { 32.572 + return mod.require; 32.573 + } else { 32.574 + return (mod.require = context.makeRequire(mod.map)); 32.575 + } 32.576 + }, 32.577 + 'exports': function (mod) { 32.578 + mod.usingExports = true; 32.579 + if (mod.map.isDefine) { 32.580 + if (mod.exports) { 32.581 + return (defined[mod.map.id] = mod.exports); 32.582 + } else { 32.583 + return (mod.exports = defined[mod.map.id] = {}); 32.584 + } 32.585 + } 32.586 + }, 32.587 + 'module': function (mod) { 32.588 + if (mod.module) { 32.589 + return mod.module; 32.590 + } else { 32.591 + return (mod.module = { 32.592 + id: mod.map.id, 32.593 + uri: mod.map.url, 32.594 + config: function () { 32.595 + return getOwn(config.config, mod.map.id) || {}; 32.596 + }, 32.597 + exports: mod.exports || (mod.exports = {}) 32.598 + }); 32.599 + } 32.600 + } 32.601 + }; 32.602 + 32.603 + function cleanRegistry(id) { 32.604 + //Clean up machinery used for waiting modules. 32.605 + delete registry[id]; 32.606 + delete enabledRegistry[id]; 32.607 + } 32.608 + 32.609 + function breakCycle(mod, traced, processed) { 32.610 + var id = mod.map.id; 32.611 + 32.612 + if (mod.error) { 32.613 + mod.emit('error', mod.error); 32.614 + } else { 32.615 + traced[id] = true; 32.616 + each(mod.depMaps, function (depMap, i) { 32.617 + var depId = depMap.id, 32.618 + dep = getOwn(registry, depId); 32.619 + 32.620 + //Only force things that have not completed 32.621 + //being defined, so still in the registry, 32.622 + //and only if it has not been matched up 32.623 + //in the module already. 32.624 + if (dep && !mod.depMatched[i] && !processed[depId]) { 32.625 + if (getOwn(traced, depId)) { 32.626 + mod.defineDep(i, defined[depId]); 32.627 + mod.check(); //pass false? 32.628 + } else { 32.629 + breakCycle(dep, traced, processed); 32.630 + } 32.631 + } 32.632 + }); 32.633 + processed[id] = true; 32.634 + } 32.635 + } 32.636 + 32.637 + function checkLoaded() { 32.638 + var err, usingPathFallback, 32.639 + waitInterval = config.waitSeconds * 1000, 32.640 + //It is possible to disable the wait interval by using waitSeconds of 0. 32.641 + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), 32.642 + noLoads = [], 32.643 + reqCalls = [], 32.644 + stillLoading = false, 32.645 + needCycleCheck = true; 32.646 + 32.647 + //Do not bother if this call was a result of a cycle break. 32.648 + if (inCheckLoaded) { 32.649 + return; 32.650 + } 32.651 + 32.652 + inCheckLoaded = true; 32.653 + 32.654 + //Figure out the state of all the modules. 32.655 + eachProp(enabledRegistry, function (mod) { 32.656 + var map = mod.map, 32.657 + modId = map.id; 32.658 + 32.659 + //Skip things that are not enabled or in error state. 32.660 + if (!mod.enabled) { 32.661 + return; 32.662 + } 32.663 + 32.664 + if (!map.isDefine) { 32.665 + reqCalls.push(mod); 32.666 + } 32.667 + 32.668 + if (!mod.error) { 32.669 + //If the module should be executed, and it has not 32.670 + //been inited and time is up, remember it. 32.671 + if (!mod.inited && expired) { 32.672 + if (hasPathFallback(modId)) { 32.673 + usingPathFallback = true; 32.674 + stillLoading = true; 32.675 + } else { 32.676 + noLoads.push(modId); 32.677 + removeScript(modId); 32.678 + } 32.679 + } else if (!mod.inited && mod.fetched && map.isDefine) { 32.680 + stillLoading = true; 32.681 + if (!map.prefix) { 32.682 + //No reason to keep looking for unfinished 32.683 + //loading. If the only stillLoading is a 32.684 + //plugin resource though, keep going, 32.685 + //because it may be that a plugin resource 32.686 + //is waiting on a non-plugin cycle. 32.687 + return (needCycleCheck = false); 32.688 + } 32.689 + } 32.690 + } 32.691 + }); 32.692 + 32.693 + if (expired && noLoads.length) { 32.694 + //If wait time expired, throw error of unloaded modules. 32.695 + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); 32.696 + err.contextName = context.contextName; 32.697 + return onError(err); 32.698 + } 32.699 + 32.700 + //Not expired, check for a cycle. 32.701 + if (needCycleCheck) { 32.702 + each(reqCalls, function (mod) { 32.703 + breakCycle(mod, {}, {}); 32.704 + }); 32.705 + } 32.706 + 32.707 + //If still waiting on loads, and the waiting load is something 32.708 + //other than a plugin resource, or there are still outstanding 32.709 + //scripts, then just try back later. 32.710 + if ((!expired || usingPathFallback) && stillLoading) { 32.711 + //Something is still waiting to load. Wait for it, but only 32.712 + //if a timeout is not already in effect. 32.713 + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { 32.714 + checkLoadedTimeoutId = setTimeout(function () { 32.715 + checkLoadedTimeoutId = 0; 32.716 + checkLoaded(); 32.717 + }, 50); 32.718 + } 32.719 + } 32.720 + 32.721 + inCheckLoaded = false; 32.722 + } 32.723 + 32.724 + Module = function (map) { 32.725 + this.events = getOwn(undefEvents, map.id) || {}; 32.726 + this.map = map; 32.727 + this.shim = getOwn(config.shim, map.id); 32.728 + this.depExports = []; 32.729 + this.depMaps = []; 32.730 + this.depMatched = []; 32.731 + this.pluginMaps = {}; 32.732 + this.depCount = 0; 32.733 + 32.734 + /* this.exports this.factory 32.735 + this.depMaps = [], 32.736 + this.enabled, this.fetched 32.737 + */ 32.738 + }; 32.739 + 32.740 + Module.prototype = { 32.741 + init: function (depMaps, factory, errback, options) { 32.742 + options = options || {}; 32.743 + 32.744 + //Do not do more inits if already done. Can happen if there 32.745 + //are multiple define calls for the same module. That is not 32.746 + //a normal, common case, but it is also not unexpected. 32.747 + if (this.inited) { 32.748 + return; 32.749 + } 32.750 + 32.751 + this.factory = factory; 32.752 + 32.753 + if (errback) { 32.754 + //Register for errors on this module. 32.755 + this.on('error', errback); 32.756 + } else if (this.events.error) { 32.757 + //If no errback already, but there are error listeners 32.758 + //on this module, set up an errback to pass to the deps. 32.759 + errback = bind(this, function (err) { 32.760 + this.emit('error', err); 32.761 + }); 32.762 + } 32.763 + 32.764 + //Do a copy of the dependency array, so that 32.765 + //source inputs are not modified. For example 32.766 + //"shim" deps are passed in here directly, and 32.767 + //doing a direct modification of the depMaps array 32.768 + //would affect that config. 32.769 + this.depMaps = depMaps && depMaps.slice(0); 32.770 + 32.771 + this.errback = errback; 32.772 + 32.773 + //Indicate this module has be initialized 32.774 + this.inited = true; 32.775 + 32.776 + this.ignore = options.ignore; 32.777 + 32.778 + //Could have option to init this module in enabled mode, 32.779 + //or could have been previously marked as enabled. However, 32.780 + //the dependencies are not known until init is called. So 32.781 + //if enabled previously, now trigger dependencies as enabled. 32.782 + if (options.enabled || this.enabled) { 32.783 + //Enable this module and dependencies. 32.784 + //Will call this.check() 32.785 + this.enable(); 32.786 + } else { 32.787 + this.check(); 32.788 + } 32.789 + }, 32.790 + 32.791 + defineDep: function (i, depExports) { 32.792 + //Because of cycles, defined callback for a given 32.793 + //export can be called more than once. 32.794 + if (!this.depMatched[i]) { 32.795 + this.depMatched[i] = true; 32.796 + this.depCount -= 1; 32.797 + this.depExports[i] = depExports; 32.798 + } 32.799 + }, 32.800 + 32.801 + fetch: function () { 32.802 + if (this.fetched) { 32.803 + return; 32.804 + } 32.805 + this.fetched = true; 32.806 + 32.807 + context.startTime = (new Date()).getTime(); 32.808 + 32.809 + var map = this.map; 32.810 + 32.811 + //If the manager is for a plugin managed resource, 32.812 + //ask the plugin to load it now. 32.813 + if (this.shim) { 32.814 + context.makeRequire(this.map, { 32.815 + enableBuildCallback: true 32.816 + })(this.shim.deps || [], bind(this, function () { 32.817 + return map.prefix ? this.callPlugin() : this.load(); 32.818 + })); 32.819 + } else { 32.820 + //Regular dependency. 32.821 + return map.prefix ? this.callPlugin() : this.load(); 32.822 + } 32.823 + }, 32.824 + 32.825 + load: function () { 32.826 + var url = this.map.url; 32.827 + 32.828 + //Regular dependency. 32.829 + if (!urlFetched[url]) { 32.830 + urlFetched[url] = true; 32.831 + context.load(this.map.id, url); 32.832 + } 32.833 + }, 32.834 + 32.835 + /** 32.836 + * Checks if the module is ready to define itself, and if so, 32.837 + * define it. 32.838 + */ 32.839 + check: function () { 32.840 + if (!this.enabled || this.enabling) { 32.841 + return; 32.842 + } 32.843 + 32.844 + var err, cjsModule, 32.845 + id = this.map.id, 32.846 + depExports = this.depExports, 32.847 + exports = this.exports, 32.848 + factory = this.factory; 32.849 + 32.850 + if (!this.inited) { 32.851 + this.fetch(); 32.852 + } else if (this.error) { 32.853 + this.emit('error', this.error); 32.854 + } else if (!this.defining) { 32.855 + //The factory could trigger another require call 32.856 + //that would result in checking this module to 32.857 + //define itself again. If already in the process 32.858 + //of doing that, skip this work. 32.859 + this.defining = true; 32.860 + 32.861 + if (this.depCount < 1 && !this.defined) { 32.862 + if (isFunction(factory)) { 32.863 + //If there is an error listener, favor passing 32.864 + //to that instead of throwing an error. However, 32.865 + //only do it for define()'d modules. require 32.866 + //errbacks should not be called for failures in 32.867 + //their callbacks (#699). However if a global 32.868 + //onError is set, use that. 32.869 + if ((this.events.error && this.map.isDefine) || 32.870 + req.onError !== defaultOnError) { 32.871 + try { 32.872 + exports = context.execCb(id, factory, depExports, exports); 32.873 + } catch (e) { 32.874 + err = e; 32.875 + } 32.876 + } else { 32.877 + exports = context.execCb(id, factory, depExports, exports); 32.878 + } 32.879 + 32.880 + // Favor return value over exports. If node/cjs in play, 32.881 + // then will not have a return value anyway. Favor 32.882 + // module.exports assignment over exports object. 32.883 + if (this.map.isDefine && exports === undefined) { 32.884 + cjsModule = this.module; 32.885 + if (cjsModule) { 32.886 + exports = cjsModule.exports; 32.887 + } else if (this.usingExports) { 32.888 + //exports already set the defined value. 32.889 + exports = this.exports; 32.890 + } 32.891 + } 32.892 + 32.893 + if (err) { 32.894 + err.requireMap = this.map; 32.895 + err.requireModules = this.map.isDefine ? [this.map.id] : null; 32.896 + err.requireType = this.map.isDefine ? 'define' : 'require'; 32.897 + return onError((this.error = err)); 32.898 + } 32.899 + 32.900 + } else { 32.901 + //Just a literal value 32.902 + exports = factory; 32.903 + } 32.904 + 32.905 + this.exports = exports; 32.906 + 32.907 + if (this.map.isDefine && !this.ignore) { 32.908 + defined[id] = exports; 32.909 + 32.910 + if (req.onResourceLoad) { 32.911 + req.onResourceLoad(context, this.map, this.depMaps); 32.912 + } 32.913 + } 32.914 + 32.915 + //Clean up 32.916 + cleanRegistry(id); 32.917 + 32.918 + this.defined = true; 32.919 + } 32.920 + 32.921 + //Finished the define stage. Allow calling check again 32.922 + //to allow define notifications below in the case of a 32.923 + //cycle. 32.924 + this.defining = false; 32.925 + 32.926 + if (this.defined && !this.defineEmitted) { 32.927 + this.defineEmitted = true; 32.928 + this.emit('defined', this.exports); 32.929 + this.defineEmitComplete = true; 32.930 + } 32.931 + 32.932 + } 32.933 + }, 32.934 + 32.935 + callPlugin: function () { 32.936 + var map = this.map, 32.937 + id = map.id, 32.938 + //Map already normalized the prefix. 32.939 + pluginMap = makeModuleMap(map.prefix); 32.940 + 32.941 + //Mark this as a dependency for this plugin, so it 32.942 + //can be traced for cycles. 32.943 + this.depMaps.push(pluginMap); 32.944 + 32.945 + on(pluginMap, 'defined', bind(this, function (plugin) { 32.946 + var load, normalizedMap, normalizedMod, 32.947 + bundleId = getOwn(bundlesMap, this.map.id), 32.948 + name = this.map.name, 32.949 + parentName = this.map.parentMap ? this.map.parentMap.name : null, 32.950 + localRequire = context.makeRequire(map.parentMap, { 32.951 + enableBuildCallback: true 32.952 + }); 32.953 + 32.954 + //If current map is not normalized, wait for that 32.955 + //normalized name to load instead of continuing. 32.956 + if (this.map.unnormalized) { 32.957 + //Normalize the ID if the plugin allows it. 32.958 + if (plugin.normalize) { 32.959 + name = plugin.normalize(name, function (name) { 32.960 + return normalize(name, parentName, true); 32.961 + }) || ''; 32.962 + } 32.963 + 32.964 + //prefix and name should already be normalized, no need 32.965 + //for applying map config again either. 32.966 + normalizedMap = makeModuleMap(map.prefix + '!' + name, 32.967 + this.map.parentMap); 32.968 + on(normalizedMap, 32.969 + 'defined', bind(this, function (value) { 32.970 + this.init([], function () { return value; }, null, { 32.971 + enabled: true, 32.972 + ignore: true 32.973 + }); 32.974 + })); 32.975 + 32.976 + normalizedMod = getOwn(registry, normalizedMap.id); 32.977 + if (normalizedMod) { 32.978 + //Mark this as a dependency for this plugin, so it 32.979 + //can be traced for cycles. 32.980 + this.depMaps.push(normalizedMap); 32.981 + 32.982 + if (this.events.error) { 32.983 + normalizedMod.on('error', bind(this, function (err) { 32.984 + this.emit('error', err); 32.985 + })); 32.986 + } 32.987 + normalizedMod.enable(); 32.988 + } 32.989 + 32.990 + return; 32.991 + } 32.992 + 32.993 + //If a paths config, then just load that file instead to 32.994 + //resolve the plugin, as it is built into that paths layer. 32.995 + if (bundleId) { 32.996 + this.map.url = context.nameToUrl(bundleId); 32.997 + this.load(); 32.998 + return; 32.999 + } 32.1000 + 32.1001 + load = bind(this, function (value) { 32.1002 + this.init([], function () { return value; }, null, { 32.1003 + enabled: true 32.1004 + }); 32.1005 + }); 32.1006 + 32.1007 + load.error = bind(this, function (err) { 32.1008 + this.inited = true; 32.1009 + this.error = err; 32.1010 + err.requireModules = [id]; 32.1011 + 32.1012 + //Remove temp unnormalized modules for this module, 32.1013 + //since they will never be resolved otherwise now. 32.1014 + eachProp(registry, function (mod) { 32.1015 + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { 32.1016 + cleanRegistry(mod.map.id); 32.1017 + } 32.1018 + }); 32.1019 + 32.1020 + onError(err); 32.1021 + }); 32.1022 + 32.1023 + //Allow plugins to load other code without having to know the 32.1024 + //context or how to 'complete' the load. 32.1025 + load.fromText = bind(this, function (text, textAlt) { 32.1026 + /*jslint evil: true */ 32.1027 + var moduleName = map.name, 32.1028 + moduleMap = makeModuleMap(moduleName), 32.1029 + hasInteractive = useInteractive; 32.1030 + 32.1031 + //As of 2.1.0, support just passing the text, to reinforce 32.1032 + //fromText only being called once per resource. Still 32.1033 + //support old style of passing moduleName but discard 32.1034 + //that moduleName in favor of the internal ref. 32.1035 + if (textAlt) { 32.1036 + text = textAlt; 32.1037 + } 32.1038 + 32.1039 + //Turn off interactive script matching for IE for any define 32.1040 + //calls in the text, then turn it back on at the end. 32.1041 + if (hasInteractive) { 32.1042 + useInteractive = false; 32.1043 + } 32.1044 + 32.1045 + //Prime the system by creating a module instance for 32.1046 + //it. 32.1047 + getModule(moduleMap); 32.1048 + 32.1049 + //Transfer any config to this other module. 32.1050 + if (hasProp(config.config, id)) { 32.1051 + config.config[moduleName] = config.config[id]; 32.1052 + } 32.1053 + 32.1054 + try { 32.1055 + req.exec(text); 32.1056 + } catch (e) { 32.1057 + return onError(makeError('fromtexteval', 32.1058 + 'fromText eval for ' + id + 32.1059 + ' failed: ' + e, 32.1060 + e, 32.1061 + [id])); 32.1062 + } 32.1063 + 32.1064 + if (hasInteractive) { 32.1065 + useInteractive = true; 32.1066 + } 32.1067 + 32.1068 + //Mark this as a dependency for the plugin 32.1069 + //resource 32.1070 + this.depMaps.push(moduleMap); 32.1071 + 32.1072 + //Support anonymous modules. 32.1073 + context.completeLoad(moduleName); 32.1074 + 32.1075 + //Bind the value of that module to the value for this 32.1076 + //resource ID. 32.1077 + localRequire([moduleName], load); 32.1078 + }); 32.1079 + 32.1080 + //Use parentName here since the plugin's name is not reliable, 32.1081 + //could be some weird string with no path that actually wants to 32.1082 + //reference the parentName's path. 32.1083 + plugin.load(map.name, localRequire, load, config); 32.1084 + })); 32.1085 + 32.1086 + context.enable(pluginMap, this); 32.1087 + this.pluginMaps[pluginMap.id] = pluginMap; 32.1088 + }, 32.1089 + 32.1090 + enable: function () { 32.1091 + enabledRegistry[this.map.id] = this; 32.1092 + this.enabled = true; 32.1093 + 32.1094 + //Set flag mentioning that the module is enabling, 32.1095 + //so that immediate calls to the defined callbacks 32.1096 + //for dependencies do not trigger inadvertent load 32.1097 + //with the depCount still being zero. 32.1098 + this.enabling = true; 32.1099 + 32.1100 + //Enable each dependency 32.1101 + each(this.depMaps, bind(this, function (depMap, i) { 32.1102 + var id, mod, handler; 32.1103 + 32.1104 + if (typeof depMap === 'string') { 32.1105 + //Dependency needs to be converted to a depMap 32.1106 + //and wired up to this module. 32.1107 + depMap = makeModuleMap(depMap, 32.1108 + (this.map.isDefine ? this.map : this.map.parentMap), 32.1109 + false, 32.1110 + !this.skipMap); 32.1111 + this.depMaps[i] = depMap; 32.1112 + 32.1113 + handler = getOwn(handlers, depMap.id); 32.1114 + 32.1115 + if (handler) { 32.1116 + this.depExports[i] = handler(this); 32.1117 + return; 32.1118 + } 32.1119 + 32.1120 + this.depCount += 1; 32.1121 + 32.1122 + on(depMap, 'defined', bind(this, function (depExports) { 32.1123 + this.defineDep(i, depExports); 32.1124 + this.check(); 32.1125 + })); 32.1126 + 32.1127 + if (this.errback) { 32.1128 + on(depMap, 'error', bind(this, this.errback)); 32.1129 + } 32.1130 + } 32.1131 + 32.1132 + id = depMap.id; 32.1133 + mod = registry[id]; 32.1134 + 32.1135 + //Skip special modules like 'require', 'exports', 'module' 32.1136 + //Also, don't call enable if it is already enabled, 32.1137 + //important in circular dependency cases. 32.1138 + if (!hasProp(handlers, id) && mod && !mod.enabled) { 32.1139 + context.enable(depMap, this); 32.1140 + } 32.1141 + })); 32.1142 + 32.1143 + //Enable each plugin that is used in 32.1144 + //a dependency 32.1145 + eachProp(this.pluginMaps, bind(this, function (pluginMap) { 32.1146 + var mod = getOwn(registry, pluginMap.id); 32.1147 + if (mod && !mod.enabled) { 32.1148 + context.enable(pluginMap, this); 32.1149 + } 32.1150 + })); 32.1151 + 32.1152 + this.enabling = false; 32.1153 + 32.1154 + this.check(); 32.1155 + }, 32.1156 + 32.1157 + on: function (name, cb) { 32.1158 + var cbs = this.events[name]; 32.1159 + if (!cbs) { 32.1160 + cbs = this.events[name] = []; 32.1161 + } 32.1162 + cbs.push(cb); 32.1163 + }, 32.1164 + 32.1165 + emit: function (name, evt) { 32.1166 + each(this.events[name], function (cb) { 32.1167 + cb(evt); 32.1168 + }); 32.1169 + if (name === 'error') { 32.1170 + //Now that the error handler was triggered, remove 32.1171 + //the listeners, since this broken Module instance 32.1172 + //can stay around for a while in the registry. 32.1173 + delete this.events[name]; 32.1174 + } 32.1175 + } 32.1176 + }; 32.1177 + 32.1178 + function callGetModule(args) { 32.1179 + //Skip modules already defined. 32.1180 + if (!hasProp(defined, args[0])) { 32.1181 + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); 32.1182 + } 32.1183 + } 32.1184 + 32.1185 + function removeListener(node, func, name, ieName) { 32.1186 + //Favor detachEvent because of IE9 32.1187 + //issue, see attachEvent/addEventListener comment elsewhere 32.1188 + //in this file. 32.1189 + if (node.detachEvent && !isOpera) { 32.1190 + //Probably IE. If not it will throw an error, which will be 32.1191 + //useful to know. 32.1192 + if (ieName) { 32.1193 + node.detachEvent(ieName, func); 32.1194 + } 32.1195 + } else { 32.1196 + node.removeEventListener(name, func, false); 32.1197 + } 32.1198 + } 32.1199 + 32.1200 + /** 32.1201 + * Given an event from a script node, get the requirejs info from it, 32.1202 + * and then removes the event listeners on the node. 32.1203 + * @param {Event} evt 32.1204 + * @returns {Object} 32.1205 + */ 32.1206 + function getScriptData(evt) { 32.1207 + //Using currentTarget instead of target for Firefox 2.0's sake. Not 32.1208 + //all old browsers will be supported, but this one was easy enough 32.1209 + //to support and still makes sense. 32.1210 + var node = evt.currentTarget || evt.srcElement; 32.1211 + 32.1212 + //Remove the listeners once here. 32.1213 + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); 32.1214 + removeListener(node, context.onScriptError, 'error'); 32.1215 + 32.1216 + return { 32.1217 + node: node, 32.1218 + id: node && node.getAttribute('data-requiremodule') 32.1219 + }; 32.1220 + } 32.1221 + 32.1222 + function intakeDefines() { 32.1223 + var args; 32.1224 + 32.1225 + //Any defined modules in the global queue, intake them now. 32.1226 + takeGlobalQueue(); 32.1227 + 32.1228 + //Make sure any remaining defQueue items get properly processed. 32.1229 + while (defQueue.length) { 32.1230 + args = defQueue.shift(); 32.1231 + if (args[0] === null) { 32.1232 + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); 32.1233 + } else { 32.1234 + //args are id, deps, factory. Should be normalized by the 32.1235 + //define() function. 32.1236 + callGetModule(args); 32.1237 + } 32.1238 + } 32.1239 + } 32.1240 + 32.1241 + context = { 32.1242 + config: config, 32.1243 + contextName: contextName, 32.1244 + registry: registry, 32.1245 + defined: defined, 32.1246 + urlFetched: urlFetched, 32.1247 + defQueue: defQueue, 32.1248 + Module: Module, 32.1249 + makeModuleMap: makeModuleMap, 32.1250 + nextTick: req.nextTick, 32.1251 + onError: onError, 32.1252 + 32.1253 + /** 32.1254 + * Set a configuration for the context. 32.1255 + * @param {Object} cfg config object to integrate. 32.1256 + */ 32.1257 + configure: function (cfg) { 32.1258 + //Make sure the baseUrl ends in a slash. 32.1259 + if (cfg.baseUrl) { 32.1260 + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { 32.1261 + cfg.baseUrl += '/'; 32.1262 + } 32.1263 + } 32.1264 + 32.1265 + //Save off the paths since they require special processing, 32.1266 + //they are additive. 32.1267 + var shim = config.shim, 32.1268 + objs = { 32.1269 + paths: true, 32.1270 + bundles: true, 32.1271 + config: true, 32.1272 + map: true 32.1273 + }; 32.1274 + 32.1275 + eachProp(cfg, function (value, prop) { 32.1276 + if (objs[prop]) { 32.1277 + if (!config[prop]) { 32.1278 + config[prop] = {}; 32.1279 + } 32.1280 + mixin(config[prop], value, true, true); 32.1281 + } else { 32.1282 + config[prop] = value; 32.1283 + } 32.1284 + }); 32.1285 + 32.1286 + //Reverse map the bundles 32.1287 + if (cfg.bundles) { 32.1288 + eachProp(cfg.bundles, function (value, prop) { 32.1289 + each(value, function (v) { 32.1290 + if (v !== prop) { 32.1291 + bundlesMap[v] = prop; 32.1292 + } 32.1293 + }); 32.1294 + }); 32.1295 + } 32.1296 + 32.1297 + //Merge shim 32.1298 + if (cfg.shim) { 32.1299 + eachProp(cfg.shim, function (value, id) { 32.1300 + //Normalize the structure 32.1301 + if (isArray(value)) { 32.1302 + value = { 32.1303 + deps: value 32.1304 + }; 32.1305 + } 32.1306 + if ((value.exports || value.init) && !value.exportsFn) { 32.1307 + value.exportsFn = context.makeShimExports(value); 32.1308 + } 32.1309 + shim[id] = value; 32.1310 + }); 32.1311 + config.shim = shim; 32.1312 + } 32.1313 + 32.1314 + //Adjust packages if necessary. 32.1315 + if (cfg.packages) { 32.1316 + each(cfg.packages, function (pkgObj) { 32.1317 + var location, name; 32.1318 + 32.1319 + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; 32.1320 + 32.1321 + name = pkgObj.name; 32.1322 + location = pkgObj.location; 32.1323 + if (location) { 32.1324 + config.paths[name] = pkgObj.location; 32.1325 + } 32.1326 + 32.1327 + //Save pointer to main module ID for pkg name. 32.1328 + //Remove leading dot in main, so main paths are normalized, 32.1329 + //and remove any trailing .js, since different package 32.1330 + //envs have different conventions: some use a module name, 32.1331 + //some use a file name. 32.1332 + config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') 32.1333 + .replace(currDirRegExp, '') 32.1334 + .replace(jsSuffixRegExp, ''); 32.1335 + }); 32.1336 + } 32.1337 + 32.1338 + //If there are any "waiting to execute" modules in the registry, 32.1339 + //update the maps for them, since their info, like URLs to load, 32.1340 + //may have changed. 32.1341 + eachProp(registry, function (mod, id) { 32.1342 + //If module already has init called, since it is too 32.1343 + //late to modify them, and ignore unnormalized ones 32.1344 + //since they are transient. 32.1345 + if (!mod.inited && !mod.map.unnormalized) { 32.1346 + mod.map = makeModuleMap(id); 32.1347 + } 32.1348 + }); 32.1349 + 32.1350 + //If a deps array or a config callback is specified, then call 32.1351 + //require with those args. This is useful when require is defined as a 32.1352 + //config object before require.js is loaded. 32.1353 + if (cfg.deps || cfg.callback) { 32.1354 + context.require(cfg.deps || [], cfg.callback); 32.1355 + } 32.1356 + }, 32.1357 + 32.1358 + makeShimExports: function (value) { 32.1359 + function fn() { 32.1360 + var ret; 32.1361 + if (value.init) { 32.1362 + ret = value.init.apply(global, arguments); 32.1363 + } 32.1364 + return ret || (value.exports && getGlobal(value.exports)); 32.1365 + } 32.1366 + return fn; 32.1367 + }, 32.1368 + 32.1369 + makeRequire: function (relMap, options) { 32.1370 + options = options || {}; 32.1371 + 32.1372 + function localRequire(deps, callback, errback) { 32.1373 + var id, map, requireMod; 32.1374 + 32.1375 + if (options.enableBuildCallback && callback && isFunction(callback)) { 32.1376 + callback.__requireJsBuild = true; 32.1377 + } 32.1378 + 32.1379 + if (typeof deps === 'string') { 32.1380 + if (isFunction(callback)) { 32.1381 + //Invalid call 32.1382 + return onError(makeError('requireargs', 'Invalid require call'), errback); 32.1383 + } 32.1384 + 32.1385 + //If require|exports|module are requested, get the 32.1386 + //value for them from the special handlers. Caveat: 32.1387 + //this only works while module is being defined. 32.1388 + if (relMap && hasProp(handlers, deps)) { 32.1389 + return handlers[deps](registry[relMap.id]); 32.1390 + } 32.1391 + 32.1392 + //Synchronous access to one module. If require.get is 32.1393 + //available (as in the Node adapter), prefer that. 32.1394 + if (req.get) { 32.1395 + return req.get(context, deps, relMap, localRequire); 32.1396 + } 32.1397 + 32.1398 + //Normalize module name, if it contains . or .. 32.1399 + map = makeModuleMap(deps, relMap, false, true); 32.1400 + id = map.id; 32.1401 + 32.1402 + if (!hasProp(defined, id)) { 32.1403 + return onError(makeError('notloaded', 'Module name "' + 32.1404 + id + 32.1405 + '" has not been loaded yet for context: ' + 32.1406 + contextName + 32.1407 + (relMap ? '' : '. Use require([])'))); 32.1408 + } 32.1409 + return defined[id]; 32.1410 + } 32.1411 + 32.1412 + //Grab defines waiting in the global queue. 32.1413 + intakeDefines(); 32.1414 + 32.1415 + //Mark all the dependencies as needing to be loaded. 32.1416 + context.nextTick(function () { 32.1417 + //Some defines could have been added since the 32.1418 + //require call, collect them. 32.1419 + intakeDefines(); 32.1420 + 32.1421 + requireMod = getModule(makeModuleMap(null, relMap)); 32.1422 + 32.1423 + //Store if map config should be applied to this require 32.1424 + //call for dependencies. 32.1425 + requireMod.skipMap = options.skipMap; 32.1426 + 32.1427 + requireMod.init(deps, callback, errback, { 32.1428 + enabled: true 32.1429 + }); 32.1430 + 32.1431 + checkLoaded(); 32.1432 + }); 32.1433 + 32.1434 + return localRequire; 32.1435 + } 32.1436 + 32.1437 + mixin(localRequire, { 32.1438 + isBrowser: isBrowser, 32.1439 + 32.1440 + /** 32.1441 + * Converts a module name + .extension into an URL path. 32.1442 + * *Requires* the use of a module name. It does not support using 32.1443 + * plain URLs like nameToUrl. 32.1444 + */ 32.1445 + toUrl: function (moduleNamePlusExt) { 32.1446 + var ext, 32.1447 + index = moduleNamePlusExt.lastIndexOf('.'), 32.1448 + segment = moduleNamePlusExt.split('/')[0], 32.1449 + isRelative = segment === '.' || segment === '..'; 32.1450 + 32.1451 + //Have a file extension alias, and it is not the 32.1452 + //dots from a relative path. 32.1453 + if (index !== -1 && (!isRelative || index > 1)) { 32.1454 + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); 32.1455 + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); 32.1456 + } 32.1457 + 32.1458 + return context.nameToUrl(normalize(moduleNamePlusExt, 32.1459 + relMap && relMap.id, true), ext, true); 32.1460 + }, 32.1461 + 32.1462 + defined: function (id) { 32.1463 + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); 32.1464 + }, 32.1465 + 32.1466 + specified: function (id) { 32.1467 + id = makeModuleMap(id, relMap, false, true).id; 32.1468 + return hasProp(defined, id) || hasProp(registry, id); 32.1469 + } 32.1470 + }); 32.1471 + 32.1472 + //Only allow undef on top level require calls 32.1473 + if (!relMap) { 32.1474 + localRequire.undef = function (id) { 32.1475 + //Bind any waiting define() calls to this context, 32.1476 + //fix for #408 32.1477 + takeGlobalQueue(); 32.1478 + 32.1479 + var map = makeModuleMap(id, relMap, true), 32.1480 + mod = getOwn(registry, id); 32.1481 + 32.1482 + removeScript(id); 32.1483 + 32.1484 + delete defined[id]; 32.1485 + delete urlFetched[map.url]; 32.1486 + delete undefEvents[id]; 32.1487 + 32.1488 + //Clean queued defines too. Go backwards 32.1489 + //in array so that the splices do not 32.1490 + //mess up the iteration. 32.1491 + eachReverse(defQueue, function(args, i) { 32.1492 + if(args[0] === id) { 32.1493 + defQueue.splice(i, 1); 32.1494 + } 32.1495 + }); 32.1496 + 32.1497 + if (mod) { 32.1498 + //Hold on to listeners in case the 32.1499 + //module will be attempted to be reloaded 32.1500 + //using a different config. 32.1501 + if (mod.events.defined) { 32.1502 + undefEvents[id] = mod.events; 32.1503 + } 32.1504 + 32.1505 + cleanRegistry(id); 32.1506 + } 32.1507 + }; 32.1508 + } 32.1509 + 32.1510 + return localRequire; 32.1511 + }, 32.1512 + 32.1513 + /** 32.1514 + * Called to enable a module if it is still in the registry 32.1515 + * awaiting enablement. A second arg, parent, the parent module, 32.1516 + * is passed in for context, when this method is overridden by 32.1517 + * the optimizer. Not shown here to keep code compact. 32.1518 + */ 32.1519 + enable: function (depMap) { 32.1520 + var mod = getOwn(registry, depMap.id); 32.1521 + if (mod) { 32.1522 + getModule(depMap).enable(); 32.1523 + } 32.1524 + }, 32.1525 + 32.1526 + /** 32.1527 + * Internal method used by environment adapters to complete a load event. 32.1528 + * A load event could be a script load or just a load pass from a synchronous 32.1529 + * load call. 32.1530 + * @param {String} moduleName the name of the module to potentially complete. 32.1531 + */ 32.1532 + completeLoad: function (moduleName) { 32.1533 + var found, args, mod, 32.1534 + shim = getOwn(config.shim, moduleName) || {}, 32.1535 + shExports = shim.exports; 32.1536 + 32.1537 + takeGlobalQueue(); 32.1538 + 32.1539 + while (defQueue.length) { 32.1540 + args = defQueue.shift(); 32.1541 + if (args[0] === null) { 32.1542 + args[0] = moduleName; 32.1543 + //If already found an anonymous module and bound it 32.1544 + //to this name, then this is some other anon module 32.1545 + //waiting for its completeLoad to fire. 32.1546 + if (found) { 32.1547 + break; 32.1548 + } 32.1549 + found = true; 32.1550 + } else if (args[0] === moduleName) { 32.1551 + //Found matching define call for this script! 32.1552 + found = true; 32.1553 + } 32.1554 + 32.1555 + callGetModule(args); 32.1556 + } 32.1557 + 32.1558 + //Do this after the cycle of callGetModule in case the result 32.1559 + //of those calls/init calls changes the registry. 32.1560 + mod = getOwn(registry, moduleName); 32.1561 + 32.1562 + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { 32.1563 + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { 32.1564 + if (hasPathFallback(moduleName)) { 32.1565 + return; 32.1566 + } else { 32.1567 + return onError(makeError('nodefine', 32.1568 + 'No define call for ' + moduleName, 32.1569 + null, 32.1570 + [moduleName])); 32.1571 + } 32.1572 + } else { 32.1573 + //A script that does not call define(), so just simulate 32.1574 + //the call for it. 32.1575 + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); 32.1576 + } 32.1577 + } 32.1578 + 32.1579 + checkLoaded(); 32.1580 + }, 32.1581 + 32.1582 + /** 32.1583 + * Converts a module name to a file path. Supports cases where 32.1584 + * moduleName may actually be just an URL. 32.1585 + * Note that it **does not** call normalize on the moduleName, 32.1586 + * it is assumed to have already been normalized. This is an 32.1587 + * internal API, not a public one. Use toUrl for the public API. 32.1588 + */ 32.1589 + nameToUrl: function (moduleName, ext, skipExt) { 32.1590 + var paths, syms, i, parentModule, url, 32.1591 + parentPath, bundleId, 32.1592 + pkgMain = getOwn(config.pkgs, moduleName); 32.1593 + 32.1594 + if (pkgMain) { 32.1595 + moduleName = pkgMain; 32.1596 + } 32.1597 + 32.1598 + bundleId = getOwn(bundlesMap, moduleName); 32.1599 + 32.1600 + if (bundleId) { 32.1601 + return context.nameToUrl(bundleId, ext, skipExt); 32.1602 + } 32.1603 + 32.1604 + //If a colon is in the URL, it indicates a protocol is used and it is just 32.1605 + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) 32.1606 + //or ends with .js, then assume the user meant to use an url and not a module id. 32.1607 + //The slash is important for protocol-less URLs as well as full paths. 32.1608 + if (req.jsExtRegExp.test(moduleName)) { 32.1609 + //Just a plain path, not module name lookup, so just return it. 32.1610 + //Add extension if it is included. This is a bit wonky, only non-.js things pass 32.1611 + //an extension, this method probably needs to be reworked. 32.1612 + url = moduleName + (ext || ''); 32.1613 + } else { 32.1614 + //A module that needs to be converted to a path. 32.1615 + paths = config.paths; 32.1616 + 32.1617 + syms = moduleName.split('/'); 32.1618 + //For each module name segment, see if there is a path 32.1619 + //registered for it. Start with most specific name 32.1620 + //and work up from it. 32.1621 + for (i = syms.length; i > 0; i -= 1) { 32.1622 + parentModule = syms.slice(0, i).join('/'); 32.1623 + 32.1624 + parentPath = getOwn(paths, parentModule); 32.1625 + if (parentPath) { 32.1626 + //If an array, it means there are a few choices, 32.1627 + //Choose the one that is desired 32.1628 + if (isArray(parentPath)) { 32.1629 + parentPath = parentPath[0]; 32.1630 + } 32.1631 + syms.splice(0, i, parentPath); 32.1632 + break; 32.1633 + } 32.1634 + } 32.1635 + 32.1636 + //Join the path parts together, then figure out if baseUrl is needed. 32.1637 + url = syms.join('/'); 32.1638 + url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); 32.1639 + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; 32.1640 + } 32.1641 + 32.1642 + return config.urlArgs ? url + 32.1643 + ((url.indexOf('?') === -1 ? '?' : '&') + 32.1644 + config.urlArgs) : url; 32.1645 + }, 32.1646 + 32.1647 + //Delegates to req.load. Broken out as a separate function to 32.1648 + //allow overriding in the optimizer. 32.1649 + load: function (id, url) { 32.1650 + req.load(context, id, url); 32.1651 + }, 32.1652 + 32.1653 + /** 32.1654 + * Executes a module callback function. Broken out as a separate function 32.1655 + * solely to allow the build system to sequence the files in the built 32.1656 + * layer in the right sequence. 32.1657 + * 32.1658 + * @private 32.1659 + */ 32.1660 + execCb: function (name, callback, args, exports) { 32.1661 + return callback.apply(exports, args); 32.1662 + }, 32.1663 + 32.1664 + /** 32.1665 + * callback for script loads, used to check status of loading. 32.1666 + * 32.1667 + * @param {Event} evt the event from the browser for the script 32.1668 + * that was loaded. 32.1669 + */ 32.1670 + onScriptLoad: function (evt) { 32.1671 + //Using currentTarget instead of target for Firefox 2.0's sake. Not 32.1672 + //all old browsers will be supported, but this one was easy enough 32.1673 + //to support and still makes sense. 32.1674 + if (evt.type === 'load' || 32.1675 + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { 32.1676 + //Reset interactive script so a script node is not held onto for 32.1677 + //to long. 32.1678 + interactiveScript = null; 32.1679 + 32.1680 + //Pull out the name of the module and the context. 32.1681 + var data = getScriptData(evt); 32.1682 + context.completeLoad(data.id); 32.1683 + } 32.1684 + }, 32.1685 + 32.1686 + /** 32.1687 + * Callback for script errors. 32.1688 + */ 32.1689 + onScriptError: function (evt) { 32.1690 + var data = getScriptData(evt); 32.1691 + if (!hasPathFallback(data.id)) { 32.1692 + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); 32.1693 + } 32.1694 + } 32.1695 + }; 32.1696 + 32.1697 + context.require = context.makeRequire(); 32.1698 + return context; 32.1699 + } 32.1700 + 32.1701 + /** 32.1702 + * Main entry point. 32.1703 + * 32.1704 + * If the only argument to require is a string, then the module that 32.1705 + * is represented by that string is fetched for the appropriate context. 32.1706 + * 32.1707 + * If the first argument is an array, then it will be treated as an array 32.1708 + * of dependency string names to fetch. An optional function callback can 32.1709 + * be specified to execute when all of those dependencies are available. 32.1710 + * 32.1711 + * Make a local req variable to help Caja compliance (it assumes things 32.1712 + * on a require that are not standardized), and to give a short 32.1713 + * name for minification/local scope use. 32.1714 + */ 32.1715 + req = requirejs = function (deps, callback, errback, optional) { 32.1716 + 32.1717 + //Find the right context, use default 32.1718 + var context, config, 32.1719 + contextName = defContextName; 32.1720 + 32.1721 + // Determine if have config object in the call. 32.1722 + if (!isArray(deps) && typeof deps !== 'string') { 32.1723 + // deps is a config object 32.1724 + config = deps; 32.1725 + if (isArray(callback)) { 32.1726 + // Adjust args if there are dependencies 32.1727 + deps = callback; 32.1728 + callback = errback; 32.1729 + errback = optional; 32.1730 + } else { 32.1731 + deps = []; 32.1732 + } 32.1733 + } 32.1734 + 32.1735 + if (config && config.context) { 32.1736 + contextName = config.context; 32.1737 + } 32.1738 + 32.1739 + context = getOwn(contexts, contextName); 32.1740 + if (!context) { 32.1741 + context = contexts[contextName] = req.s.newContext(contextName); 32.1742 + } 32.1743 + 32.1744 + if (config) { 32.1745 + context.configure(config); 32.1746 + } 32.1747 + 32.1748 + return context.require(deps, callback, errback); 32.1749 + }; 32.1750 + 32.1751 + /** 32.1752 + * Support require.config() to make it easier to cooperate with other 32.1753 + * AMD loaders on globally agreed names. 32.1754 + */ 32.1755 + req.config = function (config) { 32.1756 + return req(config); 32.1757 + }; 32.1758 + 32.1759 + /** 32.1760 + * Execute something after the current tick 32.1761 + * of the event loop. Override for other envs 32.1762 + * that have a better solution than setTimeout. 32.1763 + * @param {Function} fn function to execute later. 32.1764 + */ 32.1765 + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { 32.1766 + setTimeout(fn, 4); 32.1767 + } : function (fn) { fn(); }; 32.1768 + 32.1769 + /** 32.1770 + * Export require as a global, but only if it does not already exist. 32.1771 + */ 32.1772 + if (!require) { 32.1773 + require = req; 32.1774 + } 32.1775 + 32.1776 + req.version = version; 32.1777 + 32.1778 + //Used to filter out dependencies that are already paths. 32.1779 + req.jsExtRegExp = /^\/|:|\?|\.js$/; 32.1780 + req.isBrowser = isBrowser; 32.1781 + s = req.s = { 32.1782 + contexts: contexts, 32.1783 + newContext: newContext 32.1784 + }; 32.1785 + 32.1786 + //Create default context. 32.1787 + req({}); 32.1788 + 32.1789 + //Exports some context-sensitive methods on global require. 32.1790 + each([ 32.1791 + 'toUrl', 32.1792 + 'undef', 32.1793 + 'defined', 32.1794 + 'specified' 32.1795 + ], function (prop) { 32.1796 + //Reference from contexts instead of early binding to default context, 32.1797 + //so that during builds, the latest instance of the default context 32.1798 + //with its config gets used. 32.1799 + req[prop] = function () { 32.1800 + var ctx = contexts[defContextName]; 32.1801 + return ctx.require[prop].apply(ctx, arguments); 32.1802 + }; 32.1803 + }); 32.1804 + 32.1805 + if (isBrowser) { 32.1806 + head = s.head = document.getElementsByTagName('head')[0]; 32.1807 + //If BASE tag is in play, using appendChild is a problem for IE6. 32.1808 + //When that browser dies, this can be removed. Details in this jQuery bug: 32.1809 + //http://dev.jquery.com/ticket/2709 32.1810 + baseElement = document.getElementsByTagName('base')[0]; 32.1811 + if (baseElement) { 32.1812 + head = s.head = baseElement.parentNode; 32.1813 + } 32.1814 + } 32.1815 + 32.1816 + /** 32.1817 + * Any errors that require explicitly generates will be passed to this 32.1818 + * function. Intercept/override it if you want custom error handling. 32.1819 + * @param {Error} err the error object. 32.1820 + */ 32.1821 + req.onError = defaultOnError; 32.1822 + 32.1823 + /** 32.1824 + * Creates the node for the load command. Only used in browser envs. 32.1825 + */ 32.1826 + req.createNode = function (config, moduleName, url) { 32.1827 + var node = config.xhtml ? 32.1828 + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : 32.1829 + document.createElement('script'); 32.1830 + node.type = config.scriptType || 'text/javascript'; 32.1831 + node.charset = 'utf-8'; 32.1832 + node.async = true; 32.1833 + return node; 32.1834 + }; 32.1835 + 32.1836 + /** 32.1837 + * Does the request to load a module for the browser case. 32.1838 + * Make this a separate function to allow other environments 32.1839 + * to override it. 32.1840 + * 32.1841 + * @param {Object} context the require context to find state. 32.1842 + * @param {String} moduleName the name of the module. 32.1843 + * @param {Object} url the URL to the module. 32.1844 + */ 32.1845 + req.load = function (context, moduleName, url) { 32.1846 + var config = (context && context.config) || {}, 32.1847 + node; 32.1848 + if (isBrowser) { 32.1849 + //In the browser so use a script tag 32.1850 + node = req.createNode(config, moduleName, url); 32.1851 + 32.1852 + node.setAttribute('data-requirecontext', context.contextName); 32.1853 + node.setAttribute('data-requiremodule', moduleName); 32.1854 + 32.1855 + //Set up load listener. Test attachEvent first because IE9 has 32.1856 + //a subtle issue in its addEventListener and script onload firings 32.1857 + //that do not match the behavior of all other browsers with 32.1858 + //addEventListener support, which fire the onload event for a 32.1859 + //script right after the script execution. See: 32.1860 + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution 32.1861 + //UNFORTUNATELY Opera implements attachEvent but does not follow the script 32.1862 + //script execution mode. 32.1863 + if (node.attachEvent && 32.1864 + //Check if node.attachEvent is artificially added by custom script or 32.1865 + //natively supported by browser 32.1866 + //read https://github.com/jrburke/requirejs/issues/187 32.1867 + //if we can NOT find [native code] then it must NOT natively supported. 32.1868 + //in IE8, node.attachEvent does not have toString() 32.1869 + //Note the test for "[native code" with no closing brace, see: 32.1870 + //https://github.com/jrburke/requirejs/issues/273 32.1871 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && 32.1872 + !isOpera) { 32.1873 + //Probably IE. IE (at least 6-8) do not fire 32.1874 + //script onload right after executing the script, so 32.1875 + //we cannot tie the anonymous define call to a name. 32.1876 + //However, IE reports the script as being in 'interactive' 32.1877 + //readyState at the time of the define call. 32.1878 + useInteractive = true; 32.1879 + 32.1880 + node.attachEvent('onreadystatechange', context.onScriptLoad); 32.1881 + //It would be great to add an error handler here to catch 32.1882 + //404s in IE9+. However, onreadystatechange will fire before 32.1883 + //the error handler, so that does not help. If addEventListener 32.1884 + //is used, then IE will fire error before load, but we cannot 32.1885 + //use that pathway given the connect.microsoft.com issue 32.1886 + //mentioned above about not doing the 'script execute, 32.1887 + //then fire the script load event listener before execute 32.1888 + //next script' that other browsers do. 32.1889 + //Best hope: IE10 fixes the issues, 32.1890 + //and then destroys all installs of IE 6-9. 32.1891 + //node.attachEvent('onerror', context.onScriptError); 32.1892 + } else { 32.1893 + node.addEventListener('load', context.onScriptLoad, false); 32.1894 + node.addEventListener('error', context.onScriptError, false); 32.1895 + } 32.1896 + node.src = url; 32.1897 + 32.1898 + //For some cache cases in IE 6-8, the script executes before the end 32.1899 + //of the appendChild execution, so to tie an anonymous define 32.1900 + //call to the module name (which is stored on the node), hold on 32.1901 + //to a reference to this node, but clear after the DOM insertion. 32.1902 + currentlyAddingScript = node; 32.1903 + if (baseElement) { 32.1904 + head.insertBefore(node, baseElement); 32.1905 + } else { 32.1906 + head.appendChild(node); 32.1907 + } 32.1908 + currentlyAddingScript = null; 32.1909 + 32.1910 + return node; 32.1911 + } else if (isWebWorker) { 32.1912 + try { 32.1913 + //In a web worker, use importScripts. This is not a very 32.1914 + //efficient use of importScripts, importScripts will block until 32.1915 + //its script is downloaded and evaluated. However, if web workers 32.1916 + //are in play, the expectation that a build has been done so that 32.1917 + //only one script needs to be loaded anyway. This may need to be 32.1918 + //reevaluated if other use cases become common. 32.1919 + importScripts(url); 32.1920 + 32.1921 + //Account for anonymous modules 32.1922 + context.completeLoad(moduleName); 32.1923 + } catch (e) { 32.1924 + context.onError(makeError('importscripts', 32.1925 + 'importScripts failed for ' + 32.1926 + moduleName + ' at ' + url, 32.1927 + e, 32.1928 + [moduleName])); 32.1929 + } 32.1930 + } 32.1931 + }; 32.1932 + 32.1933 + function getInteractiveScript() { 32.1934 + if (interactiveScript && interactiveScript.readyState === 'interactive') { 32.1935 + return interactiveScript; 32.1936 + } 32.1937 + 32.1938 + eachReverse(scripts(), function (script) { 32.1939 + if (script.readyState === 'interactive') { 32.1940 + return (interactiveScript = script); 32.1941 + } 32.1942 + }); 32.1943 + return interactiveScript; 32.1944 + } 32.1945 + 32.1946 + //Look for a data-main script attribute, which could also adjust the baseUrl. 32.1947 + if (isBrowser && !cfg.skipDataMain) { 32.1948 + //Figure out baseUrl. Get it from the script tag with require.js in it. 32.1949 + eachReverse(scripts(), function (script) { 32.1950 + //Set the 'head' where we can append children by 32.1951 + //using the script's parent. 32.1952 + if (!head) { 32.1953 + head = script.parentNode; 32.1954 + } 32.1955 + 32.1956 + //Look for a data-main attribute to set main script for the page 32.1957 + //to load. If it is there, the path to data main becomes the 32.1958 + //baseUrl, if it is not already set. 32.1959 + dataMain = script.getAttribute('data-main'); 32.1960 + if (dataMain) { 32.1961 + //Preserve dataMain in case it is a path (i.e. contains '?') 32.1962 + mainScript = dataMain; 32.1963 + 32.1964 + //Set final baseUrl if there is not already an explicit one. 32.1965 + if (!cfg.baseUrl) { 32.1966 + //Pull off the directory of data-main for use as the 32.1967 + //baseUrl. 32.1968 + src = mainScript.split('/'); 32.1969 + mainScript = src.pop(); 32.1970 + subPath = src.length ? src.join('/') + '/' : './'; 32.1971 + 32.1972 + cfg.baseUrl = subPath; 32.1973 + } 32.1974 + 32.1975 + //Strip off any trailing .js since mainScript is now 32.1976 + //like a module name. 32.1977 + mainScript = mainScript.replace(jsSuffixRegExp, ''); 32.1978 + 32.1979 + //If mainScript is still a path, fall back to dataMain 32.1980 + if (req.jsExtRegExp.test(mainScript)) { 32.1981 + mainScript = dataMain; 32.1982 + } 32.1983 + 32.1984 + //Put the data-main script in the files to load. 32.1985 + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; 32.1986 + 32.1987 + return true; 32.1988 + } 32.1989 + }); 32.1990 + } 32.1991 + 32.1992 + /** 32.1993 + * The function that handles definitions of modules. Differs from 32.1994 + * require() in that a string for the module should be the first argument, 32.1995 + * and the function to execute after dependencies are loaded should 32.1996 + * return a value to define the module corresponding to the first argument's 32.1997 + * name. 32.1998 + */ 32.1999 + define = function (name, deps, callback) { 32.2000 + var node, context; 32.2001 + 32.2002 + //Allow for anonymous modules 32.2003 + if (typeof name !== 'string') { 32.2004 + //Adjust args appropriately 32.2005 + callback = deps; 32.2006 + deps = name; 32.2007 + name = null; 32.2008 + } 32.2009 + 32.2010 + //This module may not have dependencies 32.2011 + if (!isArray(deps)) { 32.2012 + callback = deps; 32.2013 + deps = null; 32.2014 + } 32.2015 + 32.2016 + //If no name, and callback is a function, then figure out if it a 32.2017 + //CommonJS thing with dependencies. 32.2018 + if (!deps && isFunction(callback)) { 32.2019 + deps = []; 32.2020 + //Remove comments from the callback string, 32.2021 + //look for require calls, and pull them into the dependencies, 32.2022 + //but only if there are function args. 32.2023 + if (callback.length) { 32.2024 + callback 32.2025 + .toString() 32.2026 + .replace(commentRegExp, '') 32.2027 + .replace(cjsRequireRegExp, function (match, dep) { 32.2028 + deps.push(dep); 32.2029 + }); 32.2030 + 32.2031 + //May be a CommonJS thing even without require calls, but still 32.2032 + //could use exports, and module. Avoid doing exports and module 32.2033 + //work though if it just needs require. 32.2034 + //REQUIRES the function to expect the CommonJS variables in the 32.2035 + //order listed below. 32.2036 + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); 32.2037 + } 32.2038 + } 32.2039 + 32.2040 + //If in IE 6-8 and hit an anonymous define() call, do the interactive 32.2041 + //work. 32.2042 + if (useInteractive) { 32.2043 + node = currentlyAddingScript || getInteractiveScript(); 32.2044 + if (node) { 32.2045 + if (!name) { 32.2046 + name = node.getAttribute('data-requiremodule'); 32.2047 + } 32.2048 + context = contexts[node.getAttribute('data-requirecontext')]; 32.2049 + } 32.2050 + } 32.2051 + 32.2052 + //Always save off evaluating the def call until the script onload handler. 32.2053 + //This allows multiple modules to be in a file without prematurely 32.2054 + //tracing dependencies, and allows for anonymous module support, 32.2055 + //where the module name is not known until the script onload event 32.2056 + //occurs. If no context, use the global queue, and get it processed 32.2057 + //in the onscript load callback. 32.2058 + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); 32.2059 + }; 32.2060 + 32.2061 + define.amd = { 32.2062 + jQuery: true 32.2063 + }; 32.2064 + 32.2065 + 32.2066 + /** 32.2067 + * Executes the text. Normally just uses eval, but can be modified 32.2068 + * to use a better, environment-specific call. Only used for transpiling 32.2069 + * loader plugins, not for plain JS modules. 32.2070 + * @param {String} text the text to execute/evaluate. 32.2071 + */ 32.2072 + req.exec = function (text) { 32.2073 + /*jslint evil: true */ 32.2074 + return eval(text); 32.2075 + }; 32.2076 + 32.2077 + //Set up with config info. 32.2078 + req(cfg); 32.2079 +}(this)); 32.2080 \ No newline at end of file
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/startUpApp.js Sun Jul 06 12:02:12 2014 -0700 33.3 @@ -0,0 +1,16 @@ 33.4 +// For any third party dependencies, like jQuery, place them in the lib folder. 33.5 + 33.6 +// Configure loading modules from the lib directory, 33.7 +// except for 'app' ones, which are in a sibling 33.8 +// directory. 33.9 +requirejs.config({ 33.10 +// baseUrl: 'lib', 33.11 + paths: { 33.12 + app: './app', 33.13 + lib: './lib' 33.14 + } 33.15 +}); 33.16 + 33.17 +// Start loading the main app file. Put all of 33.18 +// your application logic in there. 33.19 +requirejs(['app/POPApp']); 33.20 \ No newline at end of file
34.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.odg has changed
35.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.pdf has changed
36.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.odg has changed
37.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.pdf has changed
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/GabePattern/GabePattern_data_structs.js Sun Jul 06 12:02:12 2014 -0700 38.3 @@ -0,0 +1,438 @@ 38.4 + 38.5 +var c = document.getElementById("POPCanvas"); 38.6 +var ctx = c.getContext("2d"); 38.7 +var foreGroundFill = "#000000"; 38.8 +var backGroundFill = "#FFFFFF"; 38.9 +ctx.font = "14px Arial"; 38.10 +ctx.fillStyle = foreGroundFill; 38.11 +var fillText = "Hello World"; 38.12 +ctx.fillText(fillText,10,50); 38.13 + 38.14 +alert("hello!"); 38.15 + 38.16 +ctx.fillStyle = backGroundFill; 38.17 +ctx.fillText(fillText,10,50); 38.18 + 38.19 +//A syntax graph consists of two kinds of nodes: element, port, and property 38.20 +//An element node can have sub-elements, and a property node can have 38.21 +// sub-properties, but a port node may not have sub-ports! 38.22 + 38.23 +//this is the top level handle to the syntax graph of the gabe transform rule 38.24 +var firstGabeTransformRule = {}; 38.25 + 38.26 +//make a variable that holds an empty element struct.. this var will used 38.27 +// to build up an element, and then reused to build up other elements 38.28 +var tempElem = 38.29 + { properties: [], 38.30 + portsIn: [], 38.31 + portsOut: [], 38.32 + subElems: [] 38.33 + }; 38.34 + 38.35 +//the root of the Gabe Transform to the temp elem, then build up a property 38.36 +// to place into the elem. 38.37 +firstGabeTransformRule.root = tempElem; 38.38 + 38.39 +//build the first property 38.40 +var tempProperty = 38.41 + { propertyName: "TypeOfElement", 38.42 + propertyValue: "GabeTransformRule", 38.43 + subProperties: [] 38.44 + } 38.45 + 38.46 +//attach it to the root elem 38.47 +firstGabeTransformRule.root.properties[0] = tempProperty; 38.48 + 38.49 +//build and attach the second property 38.50 +var tempProperty = 38.51 + { propertyName: "TypeOfSyntacticStructure", 38.52 + propertyValue: "syntacticHierarchy", 38.53 + subProperties: [] 38.54 + } 38.55 + 38.56 +firstGabeTransformRule.root.properties[1] = tempProperty; 38.57 + 38.58 +//now reuse tempElem to make the first sub-element of the root elem 38.59 +var tempElem = 38.60 + { properties: [], 38.61 + portsIn: [], 38.62 + portsOut: [], 38.63 + subElems: [] 38.64 + } 38.65 + 38.66 +firstGabeTransformRule.root.subElems[0] = tempElem; 38.67 + 38.68 +var tempProperty = 38.69 + { propertyName: "TypeOfElement", 38.70 + propertyValue: "GabeQueryPattern", 38.71 + subProperties: [] 38.72 + } 38.73 + 38.74 +tempElem.properties[0] = tempProperty; 38.75 + 38.76 +var tempProperty = 38.77 + { propertyName: "TypeOfSyntacticStructure", 38.78 + propertyValue: "syntacticHierarchy", 38.79 + subProperties: [] 38.80 + } 38.81 + 38.82 +tempElem.properties[1] = tempProperty; 38.83 + 38.84 + 38.85 +//Keep going, building up the graph that was drawn 38.86 +//make the second sub-element of the root elem, the replacement pattern 38.87 +var tempElem = 38.88 + { properties: [], 38.89 + portsIn: [], 38.90 + portsOut: [], 38.91 + subElems: [] 38.92 + } 38.93 + 38.94 +firstGabeTransformRule.root.subElems[1] = tempElem; 38.95 + 38.96 +var tempProperty = 38.97 + { propertyName: "TypeOfElement", 38.98 + propertyValue: "GabeReplacePattern", 38.99 + subProperties: [] 38.100 + } 38.101 + 38.102 +tempElem.properties[0] = tempProperty; 38.103 + 38.104 +var tempProperty = 38.105 + { propertyName: "TypeOfSyntacticStructure", 38.106 + propertyValue: "syntacticHierarchy", 38.107 + subProperties: [] 38.108 + } 38.109 + 38.110 +tempElem.properties[1] = tempProperty; 38.111 + 38.112 +//Now, go back and fill in the rest of the query pattern 38.113 +//First, add the sub-elements of the query pattern node 38.114 +var tempElem = 38.115 + { properties: [], 38.116 + portsIn: [], 38.117 + portsOut: [], 38.118 + subElems: [] 38.119 + }; 38.120 + 38.121 +firstGabeTransformRule.root.subElems[0].subElems[0] = tempElem; 38.122 + 38.123 +var tempProperty = 38.124 + { propertyName: "TypeOfElement", 38.125 + propertyValue: "Command", 38.126 + subProperties: [] 38.127 + }; 38.128 + 38.129 +tempElem.properties[0] = tempProperty; 38.130 + 38.131 +var tempProperty = 38.132 + { propertyName: "CommandID", 38.133 + propertyValue: "GabePattPush", 38.134 + subProperties: [] 38.135 + }; 38.136 + 38.137 +tempElem.properties[0].subProperties[0] = tempProperty; 38.138 + 38.139 + 38.140 +var tempProperty = 38.141 + { propertyName: "TypeOfSyntacticStructure", 38.142 + propertyValue: "syntacticPatternRoot", 38.143 + subProperties: [] 38.144 + }; 38.145 + 38.146 +tempElem.properties[1] = tempProperty; 38.147 + 38.148 +//now add the ports to this Command syntactic pattern 38.149 +var tempPort = 38.150 + { element: tempElem, 38.151 + properties: [], 38.152 + pairedPorts: [] 38.153 + }; 38.154 + 38.155 +tempElem.portsIn[0] = tempPort; 38.156 + 38.157 +//add properties to the port 38.158 +tempPort.properties[0] = 38.159 + { propertyName: "TypeOfPort", 38.160 + propertyValue: "dataComm", 38.161 + subProperties: 38.162 + [{ propertyName: "TypeOfCommData", 38.163 + propertyValue: "GabePattStack", 38.164 + subProperties: [] 38.165 + }] 38.166 + }; 38.167 + 38.168 +//check that syntax was done correctly.. 38.169 +ctx.fillStyle = foreGroundFill; 38.170 +fillText = tempPort.properties[0].subProperties[0].propertyName; 38.171 + 38.172 +ctx.fillText(fillText,10,50); 38.173 + 38.174 +alert("printf!"); 38.175 + 38.176 +ctx.fillStyle = backGroundFill; 38.177 +ctx.fillText(fillText,10,50); 38.178 + 38.179 + 38.180 +var tempPort = 38.181 + { element: tempElem, 38.182 + properties: [], 38.183 + pairedPorts: [] 38.184 + }; 38.185 + 38.186 +tempElem.portsIn[1] = tempPort; 38.187 + 38.188 +//add properties to the port 38.189 +tempPort.properties[0] = 38.190 + { propertyName: "TypeOfPort", 38.191 + propertyValue: "dataComm", 38.192 + subProperties: 38.193 + [{ propertyName: "TypeOfCommData", 38.194 + propertyValue: "float", 38.195 + subProperties: [] 38.196 + }] 38.197 + }; 38.198 + 38.199 + 38.200 +var tempPort = 38.201 + { element: tempElem, 38.202 + properties: [], 38.203 + pairedPorts: [] 38.204 + }; 38.205 + 38.206 +tempElem.portsOut[0] = tempPort; 38.207 + 38.208 +//add properties to the port 38.209 +tempPort.properties[0] = 38.210 + { propertyName: "TypeOfPort", 38.211 + propertyValue: "dataComm", 38.212 + subProperties: 38.213 + [{ propertyName: "TypeOfCommData", 38.214 + propertyValue: "GabePattStack", 38.215 + subProperties: [] 38.216 + }] 38.217 + }; 38.218 + 38.219 +//First command (push) done! Now make second command (head) 38.220 +var tempElem = 38.221 + { properties: [], 38.222 + portsIn: [], 38.223 + portsOut: [], 38.224 + subElems: [] 38.225 + }; 38.226 + 38.227 +firstGabeTransformRule.root.subElems[0].subElems[1] = tempElem; 38.228 + 38.229 +//getting tired of the temp this and temp that, just make object directly 38.230 +tempElem.properties[0] = 38.231 + { propertyName: "TypeOfElement", 38.232 + propertyValue: "Command", 38.233 + subProperties: 38.234 + [{ propertyName: "CommandID", 38.235 + propertyValue: "GabePattPop", 38.236 + subProperties: [] 38.237 + }] 38.238 + }; 38.239 + 38.240 +tempElem.properties[1] = 38.241 + { propertyName: "TypeOfSyntacticStructure", 38.242 + propertyValue: "syntacticPatternRoot", 38.243 + subProperties: [] 38.244 + }; 38.245 + 38.246 +//now add the ports to this Command syntactic pattern 38.247 +tempElem.portsIn[0] = 38.248 + { element: tempElem, 38.249 + properties: [], 38.250 + pairedPorts: [] 38.251 + }; 38.252 + 38.253 +//add properties to the port 38.254 +tempElem.portsIn[0].properties[0] = 38.255 + { propertyName: "TypeOfPort", 38.256 + propertyValue: "dataComm", 38.257 + subProperties: 38.258 + [{ propertyName: "TypeOfCommData", 38.259 + propertyValue: "GabePattStack", 38.260 + subProperties: [] 38.261 + }] 38.262 + }; 38.263 + 38.264 +//next port 38.265 +tempElem.portsOut[0] = 38.266 + { element: tempElem, 38.267 + properties: [], 38.268 + pairedPorts: [] 38.269 + }; 38.270 + 38.271 +//add properties to the port 38.272 +tempElem.portsOut[0].properties[0] = 38.273 + { propertyName: "TypeOfPort", 38.274 + propertyValue: "dataComm", 38.275 + subProperties: 38.276 + [{ propertyName: "TypeOfCommData", 38.277 + propertyValue: "GabePattStack", 38.278 + subProperties: [] 38.279 + }] 38.280 + }; 38.281 + 38.282 + 38.283 +//next port 38.284 +tempElem.portsOut[1] = 38.285 + { element: tempElem, 38.286 + properties: [], 38.287 + pairedPorts: [] 38.288 + }; 38.289 + 38.290 +//add properties to the port 38.291 +tempElem.portsOut[1].properties[0] = 38.292 + { propertyName: "TypeOfPort", 38.293 + propertyValue: "dataComm", 38.294 + subProperties: 38.295 + [{ propertyName: "TypeOfCommData", 38.296 + propertyValue: "float", 38.297 + subProperties: [] 38.298 + }] 38.299 + }; 38.300 + 38.301 +//now pair the ports to each other 38.302 +var pushElem = firstGabeTransformRule.root.subElems[0].subElems[0]; 38.303 +var popElem = firstGabeTransformRule.root.subElems[0].subElems[1]; 38.304 + 38.305 +pushElem.portsOut[0].pairedPorts[0] = 38.306 + popElem.portsIn[0]; 38.307 +popElem.portsIn[0].pairedPorts[0] = 38.308 + pushElem.portsOut[0]; 38.309 + 38.310 +//Done with the query pattern! 38.311 + 38.312 +//======================================== 38.313 +//Now do the replace pattern 38.314 +//======================================== 38.315 +var tempElem = 38.316 + { properties: [], 38.317 + portsIn: [], 38.318 + portsOut: [], 38.319 + subElems: [] 38.320 + }; 38.321 + 38.322 +firstGabeTransformRule.root.subElems[1].subElems[0] = tempElem; 38.323 + 38.324 +//This is the pass through command element 38.325 +tempElem.properties[0] = 38.326 + { propertyName: "TypeOfElement", 38.327 + propertyValue: "Command", 38.328 + subProperties: 38.329 + [{ propertyName: "CommandID", 38.330 + propertyValue: "GabePassThrough", 38.331 + subProperties: [] 38.332 + }] 38.333 + }; 38.334 + 38.335 +tempElem.properties[1] = 38.336 + { propertyName: "TypeOfSyntacticStructure", 38.337 + propertyValue: "syntacticPatternRoot", 38.338 + subProperties: [] 38.339 + }; 38.340 + 38.341 +//now add the ports to this Command syntactic pattern 38.342 +tempElem.portsIn[0] = 38.343 + { element: tempElem, 38.344 + properties: [], 38.345 + pairedPorts: [] 38.346 + }; 38.347 + 38.348 +//add properties to the port 38.349 +tempElem.portsIn[0].properties[0] = 38.350 + { propertyName: "TypeOfPort", 38.351 + propertyValue: "dataComm", 38.352 + subProperties: 38.353 + [{ propertyName: "TypeOfCommData", 38.354 + propertyValue: "GabePattStack", 38.355 + subProperties: [] 38.356 + }] 38.357 + }; 38.358 + 38.359 +//next port 38.360 +tempElem.portsIn[1] = 38.361 + { element: tempElem, 38.362 + properties: [], 38.363 + pairedPorts: [] 38.364 + }; 38.365 + 38.366 +//add properties to the port 38.367 +tempElem.portsIn[1].properties[0] = 38.368 + { propertyName: "TypeOfPort", 38.369 + propertyValue: "dataComm", 38.370 + subProperties: 38.371 + [{ propertyName: "TypeOfCommData", 38.372 + propertyValue: "float", 38.373 + subProperties: [] 38.374 + }] 38.375 + }; 38.376 + 38.377 + 38.378 +//next port 38.379 +tempElem.portsOut[0] = 38.380 + { element: tempElem, 38.381 + properties: [], 38.382 + pairedPorts: [] 38.383 + }; 38.384 + 38.385 +//add properties to the port 38.386 +tempElem.portsOut[0].properties[0] = 38.387 + { propertyName: "TypeOfPort", 38.388 + propertyValue: "dataComm", 38.389 + subProperties: 38.390 + [{ propertyName: "TypeOfCommData", 38.391 + propertyValue: "GabePattStack", 38.392 + subProperties: [] 38.393 + }] 38.394 + }; 38.395 + 38.396 + 38.397 +//next port 38.398 +tempElem.portsOut[1] = 38.399 + { element: tempElem, 38.400 + properties: [], 38.401 + pairedPorts: [] 38.402 + }; 38.403 + 38.404 +//add properties to the port 38.405 +tempElem.portsOut[1].properties[0] = 38.406 + { propertyName: "TypeOfPort", 38.407 + propertyValue: "dataComm", 38.408 + subProperties: 38.409 + [{ propertyName: "TypeOfCommData", 38.410 + propertyValue: "float", 38.411 + subProperties: [] 38.412 + }] 38.413 + }; 38.414 + 38.415 +//no paired ports in this one.. done done!! 38.416 + 38.417 +//print a few things, just to make sure the data structs are correctly 38.418 +// created and can be traversed. 38.419 +ctx.fillStyle = foreGroundFill; 38.420 +var passThroughCmd = firstGabeTransformRule.root.subElems[1].subElems[0]; 38.421 +fillText = passThroughCmd.portsOut[1].properties[0].subProperties[0].propertyValue; 38.422 + 38.423 +ctx.fillText(fillText,10,50); 38.424 + 38.425 +var el2 = document.createElement("printf") 38.426 +el2.style.display="block"; 38.427 +el2.style.width="100%"; 38.428 +el2.innerHTML = fillText; 38.429 +document.body.appendChild(el2); 38.430 + 38.431 +alert("printf!"); 38.432 + 38.433 +ctx.fillStyle = backGroundFill; 38.434 +ctx.fillText(fillText,10,50); 38.435 + 38.436 +document.body.removeChild(el2); 38.437 + 38.438 + 38.439 + 38.440 + 38.441 +
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/GabePattern/loadGabePattern.html Sun Jul 06 12:02:12 2014 -0700 39.3 @@ -0,0 +1,16 @@ 39.4 +<!DOCTYPE html> 39.5 +<html> 39.6 +<body> 39.7 + 39.8 +<canvas id="POPCanvas" width="400" height="400" style="border:1px solid #000000;"> 39.9 +Your browser does not support the HTML5 canvas tag. 39.10 +</canvas> 39.11 + 39.12 + 39.13 +<script src="GabePattern_data_structs.js"> 39.14 +</script> 39.15 + 39.16 +</body> 39.17 +</html> 39.18 + 39.19 +
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/A.svg Sun Jul 06 12:02:12 2014 -0700 40.3 @@ -0,0 +1,7 @@ 40.4 +<?xml version="1.0" standalone="no"?> 40.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 40.6 + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 40.7 +<svg width="100px" height="100px" viewBox="0 0 200 200" 40.8 + xmlns="http://www.w3.org/2000/svg" version="1.1"> 40.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">A</text> 40.10 +</svg>
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/B.svg Sun Jul 06 12:02:12 2014 -0700 41.3 @@ -0,0 +1,7 @@ 41.4 +<?xml version="1.0" standalone="no"?> 41.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 41.6 + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 41.7 +<svg width="100px" height="100px" viewBox="0 0 200 200" 41.8 + xmlns="http://www.w3.org/2000/svg" version="1.1"> 41.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">B</text> 41.10 +</svg>
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/cubic.svg.xml Sun Jul 06 12:02:12 2014 -0700 42.3 @@ -0,0 +1,19 @@ 42.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 42.5 +<?xml-stylesheet href="styles-svg.css" type="text/css"?> 42.6 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 42.7 +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 499" preserveAspectRatio="xMidYMid meet"> 42.8 + <title>SVG curve</title> 42.9 + <desc>example curves in SVG</desc> 42.10 + <g id="main"> 42.11 + <circle id="p1" cx="100" cy="250" r="16" /> 42.12 + <circle id="p2" cx="400" cy="250" r="16" /> 42.13 + 42.14 + <circle id="c1" cx="100" cy="100" r="8" /> 42.15 + <circle id="c2" cx="400" cy="100" r="8" /> 42.16 + 42.17 + <line id="l1" x1="100" y1="250" x2="100" y2="100" /> 42.18 + <line id="l2" x1="400" y1="250" x2="400" y2="100" /> 42.19 + 42.20 + <path id="curve" d="M100,250 C100,100 400,100 400,250" /> 42.21 + </g> 42.22 +</svg> 42.23 \ No newline at end of file
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.html Sun Jul 06 12:02:12 2014 -0700 43.3 @@ -0,0 +1,33 @@ 43.4 +<!DOCTYPE html> 43.5 +<html lang="en"> 43.6 +<head> 43.7 +<meta charset="UTF-8" /> 43.8 +<title>SVG Cubic Bézier Curve Example</title> 43.9 +</head> 43.10 +<link rel="stylesheet" type="text/css" media="all" href="styles.css" /> 43.11 +<body> 43.12 + 43.13 +<h1>SVG Cubic Bézier Curve Example</h1> 43.14 + 43.15 +<object id="svg" type="image/svg+xml" data="cubic.svg.xml" class="C">Your browser does not support SVG</object> 43.16 +<pre id="code">code</pre> 43.17 + 43.18 +<p>This demonstration shows how cubic bézier curves can be drawn on an SVG. </p> 43.19 + 43.20 +<p>Drag the line ends or the control points to change the curve. Click the curve to toggle the fill.</p> 43.21 + 43.22 +<p>For more information, please refer to:<br /> 43.23 +<a href="http://www.sitepoint.com/html5-svg-cubic-curves/">How to Draw Cubic Bezier Curves on HTML5 SVGs</a></p> 43.24 + 43.25 +<p>See also:<br /> 43.26 +<a href="http://blogs.sitepoint.com/html5-svg-quadratic-curves/">How to Draw Quadratic Bézier Curves on HTML5 SVGs</a><br /> 43.27 +<a href="http://blogs.sitepoint.com/svg-path-element/">How to Create Complex Paths in SVGs</a></p> 43.28 + 43.29 +<h2>Disclaimer</h2> 43.30 +<p>The code was developed by <a href="http://twitter.com/craigbuckler">Craig Buckler</a> of <a href="http://optimalworks.net/">OptimalWorks.net</a> for <a href="http://sitepoint.com/">SitePoint.com</a>.</p> 43.31 + 43.32 +<p>This code can be used without any restrictions but please don't expect 24/7 support! A link back to SitePoint.com is appreciated.</p> 43.33 + 43.34 +<script type="text/javascript" src="curves.js"></script> 43.35 +</body> 43.36 +</html> 43.37 \ No newline at end of file
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.js Sun Jul 06 12:02:12 2014 -0700 44.3 @@ -0,0 +1,142 @@ 44.4 +/* 44.5 + * SVG curve example 44.6 + * 44.7 + * By Craig Buckler, http://twitter.com/craigbuckler 44.8 + * of OptimalWorks.net http://optimalworks.net/ 44.9 + * for SitePoint.com http://sitepoint.com/ 44.10 + * 44.11 + * Refer to: 44.12 + * http://www.sitepoint.com/html5-svg-quadratic-curves/ 44.13 + * http://www.sitepoint.com/html5-svg-cubic-curves/ 44.14 + * 44.15 + * This code can be used without restrictions. 44.16 + */ 44.17 + 44.18 +(function() { 44.19 + 44.20 + var container, svg, cType, code, point = {}, line = {}, fill = false, drag = null, dPoint, maxX, maxY; 44.21 + 44.22 + // define initial points 44.23 + function Init() { 44.24 + 44.25 + var c = svg.getElementsByTagName("circle"); 44.26 + for (var i = 0; i < c.length; i++) { 44.27 + point[c[i].getAttributeNS(null,"id")] = { 44.28 + x: parseInt(c[i].getAttributeNS(null,"cx"),10), 44.29 + y: parseInt(c[i].getAttributeNS(null,"cy"),10) 44.30 + }; 44.31 + } 44.32 + 44.33 + // lines 44.34 + line.l1 = svg.getElementById("l1"); 44.35 + line.l2 = svg.getElementById("l2"); 44.36 + line.curve = svg.getElementById("curve"); 44.37 + 44.38 + // code 44.39 + code = document.getElementById("code"); 44.40 + 44.41 + // event handlers 44.42 + svg.onmousedown = svg.onmousemove = svg.onmouseup = Drag; 44.43 + svg.ontouchstart = svg.ontouchmove = svg.ontouchend = Drag; 44.44 + 44.45 + DrawSVG(); 44.46 + } 44.47 + 44.48 + 44.49 + // draw curve 44.50 + function DrawSVG() { 44.51 + 44.52 + // control line 1 44.53 + line.l1.setAttributeNS(null, "x1", point.p1.x); 44.54 + line.l1.setAttributeNS(null, "y1", point.p1.y); 44.55 + line.l1.setAttributeNS(null, "x2", point.c1.x); 44.56 + line.l1.setAttributeNS(null, "y2", point.c1.y); 44.57 + 44.58 + // control line 2 44.59 + var c2 = (point.c2 ? "c2" : "c1"); 44.60 + line.l2.setAttributeNS(null, "x1", point.p2.x); 44.61 + line.l2.setAttributeNS(null, "y1", point.p2.y); 44.62 + line.l2.setAttributeNS(null, "x2", point[c2].x); 44.63 + line.l2.setAttributeNS(null, "y2", point[c2].y); 44.64 + 44.65 + // curve 44.66 + var d = 44.67 + "M"+point.p1.x+","+point.p1.y+" "+cType+ 44.68 + point.c1.x+","+point.c1.y+" "+ 44.69 + (point.c2 ? point.c2.x+","+point.c2.y+" " : "")+ 44.70 + point.p2.x+","+point.p2.y+ 44.71 + (fill ? " Z" : ""); 44.72 + line.curve.setAttributeNS(null, "d", d); 44.73 + 44.74 + // show code 44.75 + if (code) { 44.76 + code.textContent = '<path d="'+d+'" />'; 44.77 + } 44.78 + } 44.79 + 44.80 + 44.81 + // drag event handler 44.82 + function Drag(e) { 44.83 + 44.84 + e.stopPropagation(); 44.85 + var t = e.target, id = t.id, et = e.type, m = MousePos(e); 44.86 + 44.87 + // toggle fill class 44.88 + if (!drag && et == "mousedown" && id == "curve") { 44.89 + fill = !fill; 44.90 + t.setAttributeNS(null, "class", (fill ? "fill" : "")); 44.91 + DrawSVG(); 44.92 + } 44.93 + 44.94 + // start drag 44.95 + if (!drag && typeof(point[id]) != "undefined" && (et == "mousedown" || et == "touchstart")) { 44.96 + drag = t; 44.97 + dPoint = m; 44.98 + } 44.99 + 44.100 + // drag 44.101 + if (drag && (et == "mousemove" || et == "touchmove")) { 44.102 + id = drag.id; 44.103 + point[id].x += m.x - dPoint.x; 44.104 + point[id].y += m.y - dPoint.y; 44.105 + dPoint = m; 44.106 + drag.setAttributeNS(null, "cx", point[id].x); 44.107 + drag.setAttributeNS(null, "cy", point[id].y); 44.108 + DrawSVG(); 44.109 + } 44.110 + 44.111 + // stop drag 44.112 + if (drag && (et == "mouseup" || et == "touchend")) { 44.113 + drag = null; 44.114 + } 44.115 + 44.116 + } 44.117 + 44.118 + 44.119 + // mouse position 44.120 + function MousePos(event) { 44.121 + return { 44.122 + x: Math.max(0, Math.min(maxX, event.pageX)), 44.123 + y: Math.max(0, Math.min(maxY, event.pageY)) 44.124 + } 44.125 + } 44.126 + 44.127 + 44.128 + // start 44.129 + window.onload = function() { 44.130 + container = document.getElementById("svg"); 44.131 + if (container) { 44.132 + cType = container.className; 44.133 + maxX = container.offsetWidth-1; 44.134 + maxY = container.offsetHeight-1; 44.135 + svg = container.contentDocument; 44.136 + Init(); 44.137 + } 44.138 + } 44.139 + 44.140 +})(); 44.141 + 44.142 + 44.143 + 44.144 + 44.145 +
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles-svg.css Sun Jul 06 12:02:12 2014 -0700 45.3 @@ -0,0 +1,34 @@ 45.4 +/* SVG styles */ 45.5 +path 45.6 +{ 45.7 + stroke-width: 8; 45.8 + stroke: #000; 45.9 + stroke-linecap: round; 45.10 + fill: none; 45.11 +} 45.12 + 45.13 +path.fill 45.14 +{ 45.15 + fill: #3ff; 45.16 +} 45.17 + 45.18 +circle 45.19 +{ 45.20 + stroke-width: 2; 45.21 + stroke: #c00; 45.22 + fill: #fff; 45.23 +} 45.24 + 45.25 +circle:hover 45.26 +{ 45.27 + fill: #c00; 45.28 + cursor: move; 45.29 +} 45.30 + 45.31 +line 45.32 +{ 45.33 + stroke-width: 1; 45.34 + stroke: #999; 45.35 + stroke-linecap: round; 45.36 + stroke-dasharray: 5,3; 45.37 +} 45.38 \ No newline at end of file
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles.css Sun Jul 06 12:02:12 2014 -0700 46.3 @@ -0,0 +1,53 @@ 46.4 +/* CSS */ 46.5 +body 46.6 +{ 46.7 + font-family: arial, helvetica, sans-serif; 46.8 + font-size: 85%; 46.9 + margin: 10px 15px; 46.10 + color: #333; 46.11 + background-color: #ddd; 46.12 +} 46.13 + 46.14 +h1 46.15 +{ 46.16 + font-size: 1.6em; 46.17 + font-weight: normal; 46.18 + margin: 0 0 0.3em 0; 46.19 +} 46.20 + 46.21 +h2 46.22 +{ 46.23 + font-size: 1.4em; 46.24 + font-weight: normal; 46.25 + margin: 1.5em 0 0 0; 46.26 +} 46.27 + 46.28 +p 46.29 +{ 46.30 + margin: 1em 0; 46.31 +} 46.32 + 46.33 +#svg 46.34 +{ 46.35 + display: inline; 46.36 + float: left; 46.37 + width: 500px; 46.38 + height: 500px; 46.39 + margin: 0 10px 10px 0; 46.40 + background-color: #fff; 46.41 +} 46.42 + 46.43 +#code 46.44 +{ 46.45 + display: block; 46.46 + width: auto; 46.47 + height: 4em; 46.48 + font-family: monospace; 46.49 + font-size: 1.2em; 46.50 + padding: 2px 4px; 46.51 + margin: 0; 46.52 + color: #555; 46.53 + background-color: #eee; 46.54 + border: 1px solid #999; 46.55 + overflow: auto; 46.56 +} 46.57 \ No newline at end of file
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/box.svg Sun Jul 06 12:02:12 2014 -0700 47.3 @@ -0,0 +1,8 @@ 47.4 +<?xml version="1.0" standalone="no"?> 47.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 47.6 + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 47.7 +<svg width="400" height="400" viewBox="0 0 400 400" 47.8 + xmlns="http://www.w3.org/2000/svg" version="1.1"> 47.9 +<rect x="10" y="10" width="380" height="380" 47.10 +fill="white" stroke="black" stroke-width="10" /> 47.11 +</svg> 47.12 \ No newline at end of file
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/inkscape_sigma.svg Sun Jul 06 12:02:12 2014 -0700 48.3 @@ -0,0 +1,70 @@ 48.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 48.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 48.6 + 48.7 +<svg 48.8 + xmlns:dc="http://purl.org/dc/elements/1.1/" 48.9 + xmlns:cc="http://creativecommons.org/ns#" 48.10 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 48.11 + xmlns:svg="http://www.w3.org/2000/svg" 48.12 + xmlns="http://www.w3.org/2000/svg" 48.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 48.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 48.15 + width="744.09448819" 48.16 + height="1052.3622047" 48.17 + id="svg2" 48.18 + version="1.1" 48.19 + inkscape:version="0.48.2 r9819" 48.20 + sodipodi:docname="New document 1"> 48.21 + <defs 48.22 + id="defs4" /> 48.23 + <sodipodi:namedview 48.24 + id="base" 48.25 + pagecolor="#ffffff" 48.26 + bordercolor="#666666" 48.27 + borderopacity="1.0" 48.28 + inkscape:pageopacity="0.0" 48.29 + inkscape:pageshadow="2" 48.30 + inkscape:zoom="0.82" 48.31 + inkscape:cx="375" 48.32 + inkscape:cy="878.31441" 48.33 + inkscape:document-units="px" 48.34 + inkscape:current-layer="layer1" 48.35 + showgrid="false" 48.36 + inkscape:window-width="1063" 48.37 + inkscape:window-height="832" 48.38 + inkscape:window-x="125" 48.39 + inkscape:window-y="0" 48.40 + inkscape:window-maximized="0" /> 48.41 + <metadata 48.42 + id="metadata7"> 48.43 + <rdf:RDF> 48.44 + <cc:Work 48.45 + rdf:about=""> 48.46 + <dc:format>image/svg+xml</dc:format> 48.47 + <dc:type 48.48 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 48.49 + <dc:title></dc:title> 48.50 + </cc:Work> 48.51 + </rdf:RDF> 48.52 + </metadata> 48.53 + <g 48.54 + inkscape:label="Layer 1" 48.55 + inkscape:groupmode="layer" 48.56 + id="layer1"> 48.57 + <g 48.58 + id="g3759"> 48.59 + <path 48.60 + sodipodi:nodetypes="ccc" 48.61 + inkscape:connector-curvature="0" 48.62 + id="path2985" 48.63 + d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" 48.64 + style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 48.65 + <path 48.66 + style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" 48.67 + d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" 48.68 + id="path3757" 48.69 + inkscape:connector-curvature="0" 48.70 + sodipodi:nodetypes="ccc" /> 48.71 + </g> 48.72 + </g> 48.73 +</svg>
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/plus.svg Sun Jul 06 12:02:12 2014 -0700 49.3 @@ -0,0 +1,7 @@ 49.4 +<?xml version="1.0" standalone="no"?> 49.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 49.6 + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 49.7 +<svg width="100px" height="100px" viewBox="0 0 200 200" 49.8 + xmlns="http://www.w3.org/2000/svg" version="1.1"> 49.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">+</text> 49.10 +</svg>
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/sigma.svg Sun Jul 06 12:02:12 2014 -0700 50.3 @@ -0,0 +1,42 @@ 50.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 50.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 50.6 + 50.7 +<svg 50.8 + xmlns:dc="http://purl.org/dc/elements/1.1/" 50.9 + xmlns:cc="http://creativecommons.org/ns#" 50.10 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 50.11 + xmlns:svg="http://www.w3.org/2000/svg" 50.12 + xmlns="http://www.w3.org/2000/svg" 50.13 + version="1.1" 50.14 + width="744.09448" 50.15 + height="1052.3622" 50.16 + id="svg2"> 50.17 + <defs 50.18 + id="defs4" /> 50.19 + <metadata 50.20 + id="metadata7"> 50.21 + <rdf:RDF> 50.22 + <cc:Work 50.23 + rdf:about=""> 50.24 + <dc:format>image/svg+xml</dc:format> 50.25 + <dc:type 50.26 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 50.27 + <dc:title></dc:title> 50.28 + </cc:Work> 50.29 + </rdf:RDF> 50.30 + </metadata> 50.31 + <g 50.32 + id="layer1"> 50.33 + <g 50.34 + id="g3759"> 50.35 + <path 50.36 + d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" 50.37 + id="path2985" 50.38 + style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 50.39 + <path 50.40 + d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" 50.41 + id="path3757" 50.42 + style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 50.43 + </g> 50.44 + </g> 50.45 +</svg>
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/ToDos__14_Jy_02.txt Sun Jul 06 12:02:12 2014 -0700 51.3 @@ -0,0 +1,173 @@ 51.4 + 51.5 +#-] Create skeleton of system 51.6 +#- -] create an app module that acts as test scaffolding 51.7 +#- -] create a Display module and a visualizer module 51.8 +#- -] in the app, create the display and visualizer and connect them 51.9 +#- -] in the app, create the GabePattern syntax graph inside the srcHolder, and set that to be what gets visualized. 51.10 +#- -] in app, trigger the visualizer to generate a view hierarchy and send it to the display, which in turn triggers display to generate famous render tree. 51.11 + 51.12 +//====== Visualizer ====== 51.13 +//= 51.14 +//======================== 51.15 +-] make a function that accepts a native syntax graph and builds a view hierarchy from it, then hands that view hierarchy data structure to the Display 51.16 +#- -] First, make the prototype, with skeleton of internal structure 51.17 +- -] second, do by-hand code that creates the view hierarchy of the two-box visualization of part of the syntax graph of the GabePattern example 51.18 + 51.19 + 51.20 +//====== Display ====== 51.21 +//= 51.22 +//======================== 51.23 +-] make a function that accepts a view hierarchy data structure and builds a famous render tree from that 51.24 +#- -] first, make the prototype and skeleton of internal structure 51.25 + 51.26 + 51.27 +===================== 51.28 +# -] So, the task at hand is to draw a single syntax graph element, by using famous. After that, add transforms that change the size.. then ones that shift positions.. and so on, go from there.. until have a syntax graph drawn. 51.29 +# - -] Try taking an SVG representation of the round-cornered box and converting that to whatever famous takes as its native vector graphic/drawing format. Saw a googled thing about a converter from svg to something famous understood, like some form of opengl or something. 51.30 + 51.31 +# -] Get SVG working with famous -- draw the sigma example, hard-coding it, with SVG copied from inkscape output. 51.32 + 51.33 +#-] Q: how to remove a node from the render tree? Or from a context surface? 51.34 +-[] A: CAN'T!!!!! Have to regenerate the whole damn thing! 51.35 + 51.36 +#-] Get famous working without a net connection -- download whatever URLs that the page references, so are local files. 51.37 + 51.38 +-] Get famous fonts -- download to local somehow.. 51.39 + 51.40 +#-] Figure out how that other graph drawing thing made the curvy arrow-lines between nodes.. 51.41 + 51.42 +#-] Get bezier curves in SVG working on syntax graph page, going between text surface and middle of target box side, with control points set to mix x of one end point with y of other end point 51.43 + 51.44 +XXX -] Next, draw two element nodes, complete with properties and ports, with linked ports -- so know correct code, that is known to work. [-] don't need to go this far, all the essential elements have been hit. 51.45 + 51.46 +#-] Look back at Java stuff, see what were doing for structure sent from visualizer to Display 51.47 +[-] Were also doing a hierarchy of bounding boxes 51.48 +[-] Were parsing the syntax graph -- generate a bounding box and visual contents for each kind of element in the syntax graph 51.49 + 51.50 +-] Next, define a data structure for the visual elements. 51.51 +- -] within it is the information needed to construct the graph that have drawn 51.52 +- -] see below for visual element design.. and #look back over java version.. 51.53 + 51.54 +-] Next, take the syntax graph for the GabePatterns, create the visual elements to represent that. 51.55 + 51.56 +-] Next, write the Display object to receive the visual elements, and then create the famous objects from it, which end up painting the syntax graph elements as seen in the PDF. 51.57 + 51.58 +-] Next, create the visual element objects for the rest of the syntax graph, and have them all draw to the screen, using famous. 51.59 + 51.60 +-] Make a Display object, which contains the code wrote above. 51.61 + 51.62 +-] Have the Display object receive the visual element object, and proceed to draw it to the screen using famous. Choose a protocol for handing visual element objects to the Display and triggering the Display to render them via famous. 51.63 + 51.64 +-] Make the visual elements for a graph of 5 nodes. hand them to the display. 51.65 + 51.66 +-] Make a "change" visual element. Have the display modify its famous structure according to the change visual element. 51.67 + 51.68 + 51.69 +-] Separately, the task is to construct a visual hierarchy structure inside the visualizer.. then to convert that into visual elements.. then to receive those elements in the famous display, and reconstruct a famous structure from the stream of visual elements. 51.70 + 51.71 +-] Create a source holder object.. just a simple thing, as a place holder 51.72 + 51.73 +-] dump the syntax graph wrote for Gabe out to a JSON file 51.74 + 51.75 +-] have the source holder object load the JSON in, and convert to the javascript objects wrote for Gabe 51.76 + 51.77 +-] Then, make a new object, just one syntax graph element, as above. Send it to a JSON file. Have the source holder read it in and convert to javascript object. 51.78 + 51.79 +-] make a visualizer object inside the source holder 51.80 + 51.81 +-] give the visualizer access to the data structure inside the holder, which is the syntax graph 51.82 + 51.83 +-] have the visualizer build its own data structure? Or augment the existing one with new stuff? Add a visualizer field to all of the syntax graph nodes? Make it an array, one spot for each visualizer added to the source holder? 51.84 + 51.85 +-] Go with augment for now, even though feels like it's mixing things dangerously.. it, on the other hand, puts the visualization right into the data visualized, so keeps the two in sync -- no danger of something modifying the data behind the back of the visualizer.. 51.86 + 51.87 +-] make the augmentation for the one syntax graph element created above. 51.88 + 51.89 +-] have the visualizer generate a visual element object from that simple graph. 51.90 + 51.91 +-] have the visualizer send that visual element to the display created above, which 51.92 + 51.93 +-] Draw the visual hierarchy structure, which is separate from the syntax graph data. Perhaps make them both the same data structures, just add visual objects as properties (which are ignored by everything thing else, like the compiler) 51.94 + 51.95 +-] The javascript structure of linked objects will be internal to the source holder. The visualizer will take that and construct stream of visual elements from it. The modifier will directly modify it. The holder will also have a serialized version of the data structure -- which is JSON format. The data structure will be made such that can use the JSON tools to directly turn it into JSON, save that to a file, then later read the file back, and use the JSON tool to parse the JSON back into the javascript linked objects. 51.96 + 51.97 +-] The modifier will attach additional objects and properties, which are used to manage interaction with something that is editing the source.. for example, an insertion point is maintained, and highlight markings, and selection markings. (maybe multiple selections, and even browse through previous selections, and fork off one) 51.98 + 51.99 +-] The modifier will notify the visualizer of what changed, each time it does a change. The visualizer can then decide what needs to be re-sent to the display, and can decide new visual placements of things, if needed.. 51.100 + 51.101 + 51.102 +============================================== 51.103 += 51.104 += 51.105 +============================================== 51.106 +So, question.. what do display list elements look like? Does visualizer produce the layout, for example, specify a bounding box and position for each element, including text, lines, etc? Does it produce the bezier curves in SVG that connect syntax graph elements? 51.107 + 51.108 +Or, does it send something with fewer details? Let the Display calculate exact placement of visual elements? 51.109 + 51.110 +What about pan and zoom? Does Visualizer handle that, or Display.. pan means moving some elements out of the painted canvas and moving others in.. zoom does too, in addition to calculating new transforms for each element painted.. So, if Display does this, then it must either have all the visual elements in it, or else it much send a request to Visualizer that triggers sending what's needed.. 51.111 + 51.112 +Soooo.. make a two-way path between Display and Visualizer, in order to handle pan, zoom, 3D rotates, and so forth? 51.113 + 51.114 +Orrrr.. leave that to the MVDM loop.. the pan/zoom/rotate gestures go into the command-maker, and thence into the visualizer, which then sends view update.. 51.115 + 51.116 +sooo.. this view update stuff.. does Display keep a full representation of the visual elements, and then translate that into Famo.us elements? Or, does it keep, say, a current visualizer list.. where visualizer updates simply modify the previous list sent.. then Display translates the updated list into Famo.us elements.. given that Famo.us doesn't support removing render tree elements, that might be a good approach.. and it simplifies the thing about how to figure out what a visualizer update is and what to do with it inside the Display. 51.117 + 51.118 +Okay.. now.. just need to figure out what the Visualizer actually sends.. how much detail.. 51.119 + 51.120 +You know what? I don't want to think about it! Just going to do something, see what happens, and then can modify later.. probably will never get modified, these choices have a way of sticking, due to momentum of volume of work and low improvement in changing.. but, don't want to stall myself, need to keep moving.. 51.121 + 51.122 +sooooo... something has to calculate placement of bounding boxes, and calculate translations and sizing.. and move things in and out based on zoom, pan, rotate.. and trigger redraws and resends of display data for graphs and calculation results.. seems like if put placement and transform calcs inside Display then are making the Display an active thing, giving it intelligence and control.. then, run into problems when have a view that is composed of pieces from many different holders and different processors.. for example, displaying a worksheet, where the worksheet itself is in a holder that generates a view, and locations on the worksheet are calculated by live processors, and locations are graphs which are generated by graphing processors that take calculations from other processors.. want the worksheet holder to handle generating the view, and collecting the data from the other processors.. don't want the Display to have any kind of intelligence related to this! 51.123 + 51.124 +Hmmm.. so, if the worksheet holder is doing all of the collecting of data and triggering re-calcs, and melding together into a view.. then Display is simply passively painting that and collecting gestures that it sends back.. the holder then knows what to do with the gestures performed upon view elements.. 51.125 + 51.126 +So that means that the Display should not be calculating pan and zoom and rotate!! Those are responses to gestures, and those trigger behaviors from the visualizer (which may, in turn, have to trigger behaviors from other processors in order to get updated calcs to put into the view) 51.127 + 51.128 +Got it, so as tempting as it is to peel off such gestures in the Display and build intelligence into there.. it will cause problems.. so best to have all the visual related processing be done inside the visualizers.. 51.129 + 51.130 +so.. means the visualizer should send out things pretty close to renderable.. 51.131 + 51.132 +Now. The question comes up.. what format? Does the visualizer send out SVG? Is that universal enough? Will that cause problems with non-browser based approaches? If not SVG, then what? Will need to represent paths.. does visualizer calculate Bezier curves and send those? Or does it just say "here are end points, connect these with a smooth path"? Does the visualizer calculate how to route arcs within a graph around the other nodes in an optimal way? If the user supplies helpers by moving things, does the Display remember that, or the Visualizer? 51.133 + 51.134 +Ahhhh.. okay.. if what the user to be able to affect the visual arrangement, then need to remember the gestures they give that are related to visual arrangement.. for example, they grab bezier control points and move them, in order to affect a curve, or add new points within a path in order to route it.. those things have to be remembered! The Display has no place to store such things!! 51.135 + 51.136 +Right.. that means that the holder must store info related to viewing the holder contents! sooooo.. the visualizer must be the thing that generates any details that a person may want to adjust. 51.137 + 51.138 +Right. Any visual arrangement that a person might want to adjust must be stored inside the holder, and so the visualizer must be the thing that generates that level of detail. Right. Got it. 51.139 + 51.140 +So. Yes. That means that the visualizer must send out bounding boxes, translations, sizing, path points, control points, and so forth. So. Yes. SVG is looking like a good way to go.. has to be something! Can invent my own equivalent, which specifies paths, shapes, widths, and so forth.. but what is the gain? The only potential is sending in binary, to save the overhead of SVG's text embodiment. The savings worth the effort? NO! 51.141 + 51.142 +Okay then. SVG. That is the visualizer's format for POP. Or perhaps it just sends the values that go into the SVG? The Display does the final conversion to text-based SVG format? Hmmmm, what about custom syntax, which is SVG from the programmer? Just send indication of SVG elements, together with the values? Maybe enums for the SVG indicators, or something.. 51.143 + 51.144 +Now. Question is, how much effort? Is it more effort to send a representation, then construct text-repr inside Display? Or more effort to construct SVG text in visualizer and send it ready-made? 51.145 + 51.146 +Seems easier to just construct SVG text inside visualizer and send that.. 51.147 + 51.148 +Heck, if send representation, then are already forcing SVG! It doesn't constrain the Display if send the text form.. the display is just as free to convert the binary form to something else as it is to convert the text form to something else.. so if Display is not browser, and doesn't have SVG drawing primitives, it has to do the extra step of parsing SVG in order to extract the values from the text, and then generate whatever internal form it has, such as calculating paths or even pixels itself.. the extraction from text does not seem like a terribly large burden compared to the rest. 51.149 + 51.150 +Buuuut.. don't really care! Going to generate text form inside visualizer, because, why not? Then the Display only translates displayList elements into its internal thing that paints. In the case of browser, Display translates display list into famo.us elements, placing the SVG verbatim onto famous surfaces, and makes the SVG bounding box the same as the famous surface size. 51.151 + 51.152 +In fact, display list is going to represent almost verbatim what a Famo.us render tree will look like! It is a fairly universal declaration.. hierarchy of local visual contexts, with relationship among those contexts, including relative placement in 3D space and relative sizing from one to another. 51.153 + 51.154 +Alright, getting to it now.. display list will be a serialization of a hierarchy.. The top of the hierarchy is the view painted onto. The Display tells the visualizer what the pixel dimensions are of the view. The visualizer makes that the top level bounding box. It then inserts bounding boxes within that, and inserts bounding boxes within those, and so forth down. Each bounding box is either a hierarchy element, relationship element, or a painted element. Hierarchy elements simply state what elements are included, and give their own bounding box. Relationship elements are attached by the parent hierarchy element. For example, it is the job of the parent to make sure all the children fit inside its bounding box. The bounding box may be 2D or 3D. A parent ensures the fit by attaching relationships to the children elements. The relationships can be translations or scalings or rotations.. or actually any arbitrary 3D transform. A hierarchy element knows nothing of the context in which it fits, so it has no way of attaching relationships to itself! Each hierarchy element is responsible for ensuring that all descendants fit within its bounding box. Any relationship attached to a hierarchy element is transitively applied to all descendants of the hierarchy element. For example, if one is rotated in 3D, then it, together with all its contents, is rotated as a unit. Each descendant maintains the same relationship to its parent as before.. but the entire bundle has been rotated as a unit! 51.155 + 51.156 +Great.. so that is the display list.. it is a serialization of that hierarchy. A display update then assumes a given hierarchy, and says "change this relationship between this parent and this child" or "remove this parent and all descendants" etc.. in effect, it specifies a change to the hierarchical structure.. 51.157 + 51.158 +Sooooo.. means that have two copies of the view hierarchy.. one inside the visualizer, which is serialized, and another inside the Display, which is translated into Display-local elements that are then painted. 51.159 + 51.160 +Not the most efficient.. hurts me.. but, well, what are you going to do? What's better? Need the flexibility of having the visualizer control all changes to the view hierarchy.. and need the visualizer to calculate all placement and path details so that user changes can be remembered inside the holder (without something clunky like "save this view modification info as a black box and hand it to the Display, which knows what it means" yuck, just begging for loss of sync when move from one Display to another or even upgrade the Display!).. 51.161 + 51.162 +so, then, there's no way around having the visualizer internally represent the bounding box hierarchy as it constructs the details. Thennnnn.. something must translate that representation into the internal Display representation! The Display could have any native form internally.. canvas with paths drawn upon it, Java 2D, even just pixels, with all the code in between.. well, in effect, every Display ends up being everything between that hierarchy and on down to pixels!! 51.163 + 51.164 +So, could just hand the data structure from visualizer to the Display..? This is fine if both are inside same hardware, sharing memory.. but need a serialization if Display has separate memory.. which it will if the src holder is on a server and the display is a browser on a client! 51.165 + 51.166 +Hmmm.. what about just handing the data structure to the Display for now.. can always add the serialization later, it's not functional! :-) Ahhh, yes.. less work. Good. Okay, will do that. save serialization for later. For now, in javascript, will build a src holder that saves syntax graph natively in JSON, as an internal data structure of the form made for GabePatterns. The visualizer in the src holder will generate a view hierarchy from that data structure. It will save any view related data within the syntax graph data structure as extra properties added to the nodes. The visualizer will then hand a reference to the view hierarchy directly to the display object. The display object will then generate famous elements from the view hierarcy elements. View updates will simply be the visualizer changing the view hierarchy then calling the display with a reference to the changed hierarchy. 51.167 + 51.168 +Done. Make it so. 51.169 + 51.170 +BTW, thinking to introduce another component, which is a helper, that maybe takes some higher level view form and generates the view hierarchy from that.. this will ease the burden on developers who make custom syntax.. it will act as a library for them, essentially.. (and, of course, there will be a serializer that turns a view hierarchy into a stream of visual objects sent to the Display, which will reconstruct the view hierarchy then translate that into into elements that it paints.. for now, that serializer is just JSON! It has provision to translate javascript objects into text form, and then on the other side parse that text form to reproduce the javascript objects.. might need extra logic in order to recreate the links among parents and children.. not sure whether JSON can go deep that way..). 51.171 + 51.172 + 51.173 + 51.174 + 51.175 + 51.176 +
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/copy_of_famous_univ_example_code.js Sun Jul 06 12:02:12 2014 -0700 52.3 @@ -0,0 +1,94 @@ 52.4 +var Engine = require('famous/core/Engine'); 52.5 +var Surface = require('famous/core/Surface'); 52.6 +var Transform = require('famous/core/Transform'); 52.7 +var StateModifier = require('famous/modifiers/StateModifier'); 52.8 +var Easing = require('famous/transitions/Easing'); 52.9 +var Lightbox = require('famous/views/Lightbox'); 52.10 +var ImageSurface = require('famous/surfaces/ImageSurface'); 52.11 +var DeviceView = require('./DeviceView'); 52.12 + 52.13 +var mainContext = Engine.createContext(); 52.14 + 52.15 +var device, lightbox; 52.16 +var slides = []; 52.17 +var index = 0; 52.18 +var arrowMod; 52.19 + 52.20 +var lightboxOptions = { 52.21 + inOpacity: 1, 52.22 + outOpacity: 1, 52.23 + inTransform: Transform.translate(320,0, 0), 52.24 + outTransform: Transform.translate(-320, 0, 1), 52.25 + inTransition: { duration: 400, curve: Easing.outBack }, 52.26 + outTransition: { duration: 150, curve: Easing.easeOut } 52.27 +}; 52.28 + 52.29 +createDevice(); 52.30 +createSlides(); 52.31 +createLightbox(); 52.32 + 52.33 +function createDevice() { 52.34 + var deviceOptions = { 52.35 + type: 'iphone', 52.36 + height: window.innerHeight - 100 52.37 + }; 52.38 + 52.39 + device = new DeviceView(deviceOptions); 52.40 + 52.41 + var deviceModifier = new StateModifier({ 52.42 + size: device.getSize(), 52.43 + origin: [0.5, 0.5] 52.44 + }); 52.45 + 52.46 + mainContext.add(deviceModifier).add(device); 52.47 +} 52.48 + 52.49 +function createSlides() { 52.50 + var slideContent = [ 52.51 + '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">', 52.52 + '<img src="http://launch.famo.us/fu-assets/hello/slide1.png" width="100%">', 52.53 + '<img src="http://launch.famo.us/fu-assets/hello/slide2.png" width="100%">', 52.54 + '<img src="http://launch.famo.us/fu-assets/hello/slide3.png" width="100%">']; 52.55 + 52.56 + var background = new Surface({ 52.57 + properties: { 52.58 + backgroundColor: '#FA5C4F' 52.59 + } 52.60 + }); 52.61 + 52.62 + device.add(background); 52.63 + 52.64 + for (var i = 0; i < slideContent.length; i++) { 52.65 + var slide = new Surface({ 52.66 + content: slideContent[i], 52.67 + properties: { 52.68 + color: 'white', 52.69 + lineHeight: '200%', 52.70 + textAlign: 'center', 52.71 + fontSize: '36px', 52.72 + cursor: 'pointer' 52.73 + } 52.74 + }); 52.75 + 52.76 + slide.on('click', showNextSlide); 52.77 + 52.78 + slides.push(slide); 52.79 + } 52.80 +} 52.81 + 52.82 +function createLightbox() { 52.83 + lightbox = new Lightbox(lightboxOptions); 52.84 + device.add(lightbox); 52.85 + lightbox.show(slides[0]); 52.86 +} 52.87 + 52.88 +function showNextSlide() { 52.89 + index++; 52.90 + if(slides[index]) lightbox.show(slides[index]); 52.91 + 52.92 + if(index === 1) { 52.93 + GlobalEvents.trigger('pointToButton', 'fullscreen'); 52.94 + } 52.95 +} 52.96 + 52.97 +GlobalEvents.trigger('hideArrowOnToggle') 52.98 \ No newline at end of file
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/famous_learning.js Sun Jul 06 12:02:12 2014 -0700 53.3 @@ -0,0 +1,143 @@ 53.4 + 53.5 + 53.6 +define(function(require, exports, module) { 53.7 + var Engine = require("famous/core/Engine"); 53.8 + var Surface = require("famous/core/Surface"); 53.9 + var Modifier = require("famous/core/Modifier"); 53.10 + var Transform = require('famous/core/Transform'); 53.11 + var StateModifier = require('famous/modifiers/StateModifier'); 53.12 + var ContainerSurface = require("famous/surfaces/ContainerSurface"); 53.13 + var Scrollview = require("famous/views/Scrollview"); 53.14 + 53.15 + var mainContext = Engine.createContext(); 53.16 + 53.17 + var boxSVG = '<svg width="100" height="80"> <rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">'; 53.18 + var mySurface = new Surface({ 53.19 + size: [100, 100], 53.20 + content: boxSVG, 53.21 + properties: { 53.22 + color: 'white', 53.23 + lineHeight: '200%', 53.24 + textAlign: 'center', 53.25 + fontSize: '36px', 53.26 + cursor: 'pointer' 53.27 + } 53.28 + }); 53.29 + var mySurface2 = new Surface({ 53.30 + size: [100, 100], 53.31 + content: boxSVG, 53.32 + properties: { 53.33 + color: 'white', 53.34 + lineHeight: '200%', 53.35 + textAlign: 'center', 53.36 + fontSize: '36px', 53.37 + cursor: 'pointer' 53.38 + } 53.39 + }); 53.40 + var sigmaSVG = '<svg width="744.09448" height="1052.3622" id="svg2"> <g id="g3759"> <path d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" id="path2985" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" id="path3757" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> </g> </svg>'; 53.41 + var sigmaSurf = new Surface({ 53.42 + size: [100, 100], 53.43 + content: sigmaSVG, 53.44 + properties: { 53.45 + color: 'black', 53.46 + lineHeight: '200%', 53.47 + textAlign: 'center', 53.48 + fontSize: '36px', 53.49 + cursor: 'pointer' 53.50 + } 53.51 + }); 53.52 + 53.53 + var moveModifier1 = new StateModifier({ 53.54 + transform: Transform.translate(250, 100, 0) 53.55 + }); 53.56 + var moveModifier2 = new StateModifier({ 53.57 + transform: Transform.translate(350, 150, 0) 53.58 + }); 53.59 + var rotateModifier = new StateModifier({ 53.60 + transform: Transform.rotateZ(Math.PI/4) 53.61 + }); 53.62 + 53.63 +//the origin is the point inside the child, relative to the child's 53.64 +// internal axes, at which the child will be pinned inside its parent. 53.65 +//The align is the point inside the parent, relative to the parent's axes, 53.66 +// at which the origins of children will be pinned. 53.67 +//The origin is also the point about which rotations are performed 53.68 + var moveRelativeModifier = new StateModifier({ 53.69 + size: [20, 20], 53.70 + align: [0.5,0], 53.71 + origin: [0.5,0] 53.72 + }); 53.73 + var moveRelativeModifier2 = new StateModifier({ 53.74 + size: [20, 20], 53.75 + align: [0.5,0], 53.76 + origin: [0.5,0] 53.77 + }); 53.78 + 53.79 + var moveModifier2 = new StateModifier({ 53.80 + transform: Transform.translate(350, 150, 0) 53.81 + }); 53.82 + 53.83 + var scaleMod = new StateModifier({ 53.84 + transform: Transform.scale(0.5, 0.5, 1) 53.85 + }); 53.86 + 53.87 + 53.88 +//can make a tree inside the context -- so, can have a transform applied 53.89 +// to multiple children.. do so by making a var that holds the transform 53.90 +// node, then add to that variable multiple times. 53.91 +//Note, though that a given surface object will only render once! Have to 53.92 +// clone it if want multiple versions to be drawn. 53.93 +//Same goes for modifiers -- cannot put same modifier object at multiple 53.94 +// places within tree -- it will only render children of ONE of those places! 53.95 + var node = mainContext.add(rotateModifier); 53.96 + node.add(moveModifier2).add(moveRelativeModifier).add(mySurface); 53.97 + node.add(moveModifier1).add(scaleMod).add(mySurface2); 53.98 + mainContext.add(moveRelativeModifier2).add(sigmaSurf); 53.99 + 53.100 + //========== copy-pasted scrollview example stuff below this ========== 53.101 + var container = new ContainerSurface( 53.102 + { 53.103 + size: [400, 400], 53.104 + properties: 53.105 + { 53.106 + overflow: 'hidden' 53.107 + } 53.108 + }); 53.109 + 53.110 + var surfaces = []; 53.111 + //create a thing that is able to transition between surfaces.. the 53.112 + // surface that transitions in is the new one that is seeable on screen. 53.113 + var scrollview = new Scrollview(); 53.114 + 53.115 + //create the renderable surfaces, each is capable of being seeable on screen 53.116 + var temp; 53.117 + for (var i = 0; i < 5; i++) { 53.118 + temp = new Surface({ 53.119 + size: [undefined, 50], 53.120 + content: 'I am surface: ' + (i + 1), 53.121 + classes: ['red-bg'], 53.122 + properties: { 53.123 + textAlign: 'center', 53.124 + lineHeight: '50px' 53.125 + } 53.126 + }); 53.127 + 53.128 + //put the surface into the scrollview management element 53.129 + temp.pipe(scrollview); 53.130 + //put the surface into an array of surfaces, for bookkeeping 53.131 + surfaces.push(temp); 53.132 + } 53.133 + 53.134 + //The scrollview is now loaded up with all the surfaces, so tell it how 53.135 + // want it to transition between the different surfaces 53.136 + scrollview.sequenceFrom(surfaces); 53.137 + 53.138 + //add the scrollview to the container.. the container defines size and 53.139 + // some other properties.. 53.140 + container.add(scrollview); 53.141 + 53.142 + //make the container viewable, and hence the scrollview, hence whatever 53.143 + // surface is loaded as the top in the scrollview 53.144 + mainContext.add(new Modifier({origin: [.5, .5]})).add(container); 53.145 + 53.146 +});
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning.js Sun Jul 06 12:02:12 2014 -0700 54.3 @@ -0,0 +1,144 @@ 54.4 + 54.5 +//load in the famous stuff -- so far only figured out how to do it via html tag.. 54.6 + 54.7 +document.write('<script type="text/javascript"> require(["famous_learning"]);</script>'); 54.8 +//document.write('<script type="text/javascript"> require(["draw_svg_example"]);</script>'); 54.9 +//========================= 54.10 + 54.11 +var el = document.createElement("h1") 54.12 +el.id="title"; 54.13 +el.innerHTML = "Some title"; 54.14 +document.body.appendChild(el); 54.15 + 54.16 +var el2 = document.createElement("span") 54.17 +el2.style.display="block"; 54.18 +el2.style.width="100%"; 54.19 +el2.innerHTML = "Some arb text"; 54.20 +document.body.appendChild(el2); 54.21 + 54.22 +function appendHtml(el, str) { 54.23 + var div = document.createElement('div'); 54.24 + div.innerHTML = str; 54.25 + while (div.children.length > 0) { 54.26 + if ( div.children[0].tagName == 'LINK' ) { 54.27 + // Create an actual link element to append later 54.28 + style = document.createElement('link'); 54.29 + style.href = div.children[0].href; 54.30 + // append your other things like rel, type, etc 54.31 + el.appendChild(style); 54.32 + } 54.33 + el.appendChild(div.children[0]); 54.34 + } 54.35 +} 54.36 + 54.37 +var c = document.getElementById("myCanvas"); 54.38 +var ctx = c.getContext("2d"); 54.39 +ctx.fillStyle = "#FF0000"; 54.40 +ctx.fillRect(0,0,150,75); 54.41 + 54.42 +var c = document.getElementById("myCanvas"); 54.43 +var ctx = c.getContext("2d"); 54.44 +ctx.moveTo(0,0); 54.45 +ctx.lineTo(200,100); 54.46 +ctx.stroke(); 54.47 + 54.48 +var c = document.getElementById("myCanvas"); 54.49 +var ctx = c.getContext("2d"); 54.50 +ctx.beginPath(); 54.51 +ctx.arc(95,50,40,0,Math.PI); 54.52 +ctx.stroke(); 54.53 + 54.54 +var c = document.getElementById("myCanvas"); 54.55 +var ctx = c.getContext("2d"); 54.56 +ctx.font = "30px Arial"; 54.57 +ctx.fillStyle = "#000000"; 54.58 +ctx.fillText("Hello World",10,50); 54.59 + 54.60 +ctx.fillStyle = "#FF0000"; 54.61 +ctx.fillText("Hello World",10,50); 54.62 + 54.63 +var c = document.getElementById("myCanvas"); 54.64 +var ctx = c.getContext("2d"); 54.65 +ctx.font = "30px Arial"; 54.66 +ctx.fillStyle = "#000000"; 54.67 +ctx.strokeText("Hello World",10,90); 54.68 + 54.69 +var c = document.getElementById("POPCanvas"); 54.70 +var ctx = c.getContext("2d"); 54.71 +ctx.font = "30px Arial"; 54.72 +ctx.fillStyle = "#000000"; 54.73 +ctx.strokeText("Hello POP!",10,90); 54.74 + 54.75 +//A syntax graph consists of two kinds of elements, plus a list of properties attached to each element 54.76 + 54.77 +//var surname = prompt('Greetings friend, may I enquire as to your surname?'); 54.78 + 54.79 +var i = 1; 54.80 +while (i < 2) { 54.81 +// alert(i); 54.82 + i = i + 1; 54.83 +} 54.84 + 54.85 +for (var i = 1; i < 2; i++) { 54.86 +// alert(i); 54.87 +} 54.88 + 54.89 +var add = function (a, b) { 54.90 + return a + b; 54.91 +}; 54.92 + 54.93 + 54.94 +var result = add(1, 2); // result is now 3 54.95 + 54.96 + 54.97 +var jedi = { 54.98 + name: "Yoda", 54.99 + age: 899, 54.100 + talk: function () { alert("another... Sky... walker..."); } 54.101 +}; 54.102 + 54.103 +var dog = {}; 54.104 + 54.105 +dog.bark = function () { alert("Woof!"); }; 54.106 + 54.107 +var helloFrom = function (personName) { 54.108 + return "Hello from " + personName; 54.109 +} 54.110 + 54.111 +var people = ['Tom', 'Yoda', 'Ron']; 54.112 + 54.113 +people.push('Bob'); 54.114 +people.push('Dr Evil'); 54.115 + 54.116 +people.pop(); 54.117 + 54.118 +for (var i=0; i < people.length; i++) { 54.119 + var greeting = helloFrom(people[i]); 54.120 +// alert(greeting); 54.121 +} 54.122 + 54.123 +var person = { 54.124 + age: 122 54.125 +}; 54.126 + 54.127 +person.name = { 54.128 + first: "Jeanne", 54.129 + last: "Calment" 54.130 +}; 54.131 + 54.132 +var properties = []; 54.133 + 54.134 +var exampleSyntaxGraph = {}; 54.135 + 54.136 +exampleSyntaxGraph.root = 54.137 + { properties: {}, 54.138 + linksIn: {}, 54.139 + linksOut: {}, 54.140 + subElems: {} 54.141 + }; 54.142 + 54.143 +exampleSyntaxGraph.root.properties.propertyName = "ElementType";exampleSyntaxGraph.root.properties.propertyValue = "Command"; 54.144 +exampleSyntaxGraph.root.properties.propertyName = "ElementType"; 54.145 + 54.146 + 54.147 +
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learningLoadPage.html Sun Jul 06 12:02:12 2014 -0700 55.3 @@ -0,0 +1,53 @@ 55.4 +<!DOCTYPE html> 55.5 +<html> 55.6 + <head> 55.7 + <title>famo.us App</title> 55.8 + <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" /> 55.9 + <meta name="mobile-web-app-capable" content="yes" /> 55.10 + <meta name="apple-mobile-web-app-capable" content="yes" /> 55.11 + <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 55.12 + 55.13 + <!-- shims for backwards compatibility --> 55.14 + <script type="text/javascript" src="http://code.famo.us/lib/functionPrototypeBind.js"></script> 55.15 + <script type="text/javascript" src="http://code.famo.us/lib/classList.js"></script> 55.16 + <script type="text/javascript" src="http://code.famo.us/lib/requestAnimationFrame.js"></script> 55.17 + 55.18 + <!-- module loader --> 55.19 + <script type="text/javascript" src="http://code.famo.us/lib/require.js"></script> 55.20 + 55.21 + <!-- famous --> 55.22 + <link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.2/famous.css" /> 55.23 + <script type="text/javascript" src="http://code.famo.us/famous/0.2/famous.js"></script> 55.24 + 55.25 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. --> 55.26 + <link rel="stylesheet" type="text/css" href="http://code.famo.us/assets/famous_styles.css" /> 55.27 + 55.28 + <!-- load D3, to play around with also! --> 55.29 + <!--script type="text/javascript" src="d3/d3.v3.js"></script--> 55.30 + 55.31 + </head> 55.32 + 55.33 +<!-- 55.34 +<script src="terminal.js"> 55.35 +</script> 55.36 +<body onload="window.start('terminal');"> 55.37 + 55.38 +<div id="loader">...</div> 55.39 +--> 55.40 +<body> 55.41 +<canvas id="myCanvas" width="200" height="200" style="border:1px solid #000000;"> 55.42 +Your browser does not support the HTML5 canvas tag. 55.43 +</canvas> 55.44 + 55.45 +<canvas id="POPCanvas" width="200" height="100" style="border:1px solid #000000;"> 55.46 +</canvas> 55.47 + 55.48 +<!--script type="text/javascript">require(['famous_surface_example']);</script--> 55.49 + 55.50 +<script src="epocritesPuzzle.js"> 55.51 +</script> 55.52 + 55.53 +</body> 55.54 +</html> 55.55 + 55.56 +
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning_text_bounding_box.js Sun Jul 06 12:02:12 2014 -0700 56.3 @@ -0,0 +1,83 @@ 56.4 + 56.5 + //Do this part once, of creating a DOM element and adding it to document 56.6 + var el1 = document.createElement("div"); 56.7 + document.body.appendChild(el1); //only need to append once then reuse 56.8 + 56.9 + //now set the SVG text string -- from this point down can be repeated 56.10 + // for multiple strings without removing or re-adding the element, nor 56.11 + // fiddling with the DOM 56.12 + var text1_1_1_SVG = '<svg> <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText1">' + text1_1_1.content + '</text> </svg>'; 56.13 + //note the id is inside the text element! Also the fill and stroke are 56.14 + // null so nothing paints 56.15 + el1.innerHTML = text1_1_1_SVG; 56.16 + 56.17 + //get the element -- this seems to be what triggers the bounding box calc 56.18 + var test = document.getElementById("svgText1"); //use ID of the text elem 56.19 + 56.20 + //get the box, take the values out of it, and display them 56.21 + var rect = test.getBoundingClientRect(); 56.22 + var str = ""; 56.23 + for (i in rect) { //a trick for getting all the attributes of the object 56.24 + str += i + " = " + rect[i] + " "; 56.25 + } 56.26 + console.log("svgText1: " + str); 56.27 + 56.28 + var el2 = document.createElement("span"); 56.29 + el2.style.display="block"; 56.30 + el2.id="testing123"; 56.31 + el2.style.width="10%"; 56.32 + el2.innerHTML = text1_1_1.content; 56.33 + document.body.appendChild(el2); 56.34 + console.log("testing123 class " + el2.className); 56.35 + 56.36 + 56.37 + var test = document.getElementById("test12"); 56.38 + var rect = test.getBoundingClientRect(); 56.39 + var str = ""; 56.40 + for (i in rect) { 56.41 + str += i + " = " + rect[i] + "<br>"; 56.42 + } 56.43 + console.log("test12: " + str); 56.44 + 56.45 +// var svgTextElem = new SVGTextElement(); 56.46 + 56.47 + var elem = document.getElementById("svg_text"); 56.48 + var foo = elem.getBBox(); 56.49 + console.log("svg_text getBBox: " + foo.width); 56.50 +// console.log("svg_text computed: " + elem.getComputedTextLength()); 56.51 + console.log("svg_text foo: " + elem.childNodes[1].className); 56.52 + console.log("svg_text class: " + elem.className); 56.53 + 56.54 + 56.55 + var f = document.getElementById("svg_text").getClientRects(); 56.56 + console.log("svg_text getClientRects: " + f[0].width); 56.57 + 56.58 + var rect = document.getElementById("testing123").getBoundingClientRect(); 56.59 + console.log("getBoundingClientRect: " + rect.width); 56.60 + 56.61 + function getText1_1_1() { 56.62 + } 56.63 + var text1_1_2 = new Surface({ 56.64 + size: [true, true], 56.65 + content: "portsIn", 56.66 + properties: { 56.67 + color: 'black', 56.68 + textAlign: 'left', 56.69 + fontSize: '11px', 56.70 + cursor: 'pointer' 56.71 + } 56.72 + }); 56.73 +// document.body.removeChild(el1); 56.74 + var text1_1_2_SVG = '<svg> <text id="svgText2" x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none">' + text1_1_2.content + '</text> </svg>'; 56.75 + el1.innerHTML = text1_1_2_SVG; 56.76 +// document.body.appendChild(el1); 56.77 + 56.78 + var test = document.getElementById("svgText2"); 56.79 + var rect = test.getBoundingClientRect(); 56.80 + var str = ""; 56.81 + for (i in rect) { 56.82 + str += i + " = " + rect[i] + "<br>"; 56.83 + } 56.84 + console.log("svgText2: " + str); 56.85 + console.log("svgText2: " + test.getComputedTextLength()); 56.86 +
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/classList.js Sun Jul 06 12:02:12 2014 -0700 57.3 @@ -0,0 +1,138 @@ 57.4 + 57.5 +/* 57.6 + * classList.js: Cross-browser full element.classList implementation. 57.7 + * 2011-06-15 57.8 + * 57.9 + * By Eli Grey, http://eligrey.com 57.10 + * Public Domain. 57.11 + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 57.12 + */ 57.13 + 57.14 +/*global self, document, DOMException */ 57.15 + 57.16 +/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 57.17 + 57.18 +if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) { 57.19 + 57.20 +(function (view) { 57.21 + 57.22 +"use strict"; 57.23 + 57.24 +var 57.25 + classListProp = "classList" 57.26 + , protoProp = "prototype" 57.27 + , elemCtrProto = (view.HTMLElement || view.Element)[protoProp] 57.28 + , objCtr = Object 57.29 + , strTrim = String[protoProp].trim || function () { 57.30 + return this.replace(/^\s+|\s+$/g, ""); 57.31 + } 57.32 + , arrIndexOf = Array[protoProp].indexOf || function (item) { 57.33 + var 57.34 + i = 0 57.35 + , len = this.length 57.36 + ; 57.37 + for (; i < len; i++) { 57.38 + if (i in this && this[i] === item) { 57.39 + return i; 57.40 + } 57.41 + } 57.42 + return -1; 57.43 + } 57.44 + // Vendors: please allow content code to instantiate DOMExceptions 57.45 + , DOMEx = function (type, message) { 57.46 + this.name = type; 57.47 + this.code = DOMException[type]; 57.48 + this.message = message; 57.49 + } 57.50 + , checkTokenAndGetIndex = function (classList, token) { 57.51 + if (token === "") { 57.52 + throw new DOMEx( 57.53 + "SYNTAX_ERR" 57.54 + , "An invalid or illegal string was specified" 57.55 + ); 57.56 + } 57.57 + if (/\s/.test(token)) { 57.58 + throw new DOMEx( 57.59 + "INVALID_CHARACTER_ERR" 57.60 + , "String contains an invalid character" 57.61 + ); 57.62 + } 57.63 + return arrIndexOf.call(classList, token); 57.64 + } 57.65 + , ClassList = function (elem) { 57.66 + var 57.67 + trimmedClasses = strTrim.call(elem.className) 57.68 + , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] 57.69 + , i = 0 57.70 + , len = classes.length 57.71 + ; 57.72 + for (; i < len; i++) { 57.73 + this.push(classes[i]); 57.74 + } 57.75 + this._updateClassName = function () { 57.76 + elem.className = this.toString(); 57.77 + }; 57.78 + } 57.79 + , classListProto = ClassList[protoProp] = [] 57.80 + , classListGetter = function () { 57.81 + return new ClassList(this); 57.82 + } 57.83 +; 57.84 +// Most DOMException implementations don't allow calling DOMException's toString() 57.85 +// on non-DOMExceptions. Error's toString() is sufficient here. 57.86 +DOMEx[protoProp] = Error[protoProp]; 57.87 +classListProto.item = function (i) { 57.88 + return this[i] || null; 57.89 +}; 57.90 +classListProto.contains = function (token) { 57.91 + token += ""; 57.92 + return checkTokenAndGetIndex(this, token) !== -1; 57.93 +}; 57.94 +classListProto.add = function (token) { 57.95 + token += ""; 57.96 + if (checkTokenAndGetIndex(this, token) === -1) { 57.97 + this.push(token); 57.98 + this._updateClassName(); 57.99 + } 57.100 +}; 57.101 +classListProto.remove = function (token) { 57.102 + token += ""; 57.103 + var index = checkTokenAndGetIndex(this, token); 57.104 + if (index !== -1) { 57.105 + this.splice(index, 1); 57.106 + this._updateClassName(); 57.107 + } 57.108 +}; 57.109 +classListProto.toggle = function (token) { 57.110 + token += ""; 57.111 + if (checkTokenAndGetIndex(this, token) === -1) { 57.112 + this.add(token); 57.113 + } else { 57.114 + this.remove(token); 57.115 + } 57.116 +}; 57.117 +classListProto.toString = function () { 57.118 + return this.join(" "); 57.119 +}; 57.120 + 57.121 +if (objCtr.defineProperty) { 57.122 + var classListPropDesc = { 57.123 + get: classListGetter 57.124 + , enumerable: true 57.125 + , configurable: true 57.126 + }; 57.127 + try { 57.128 + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 57.129 + } catch (ex) { // IE 8 doesn't support enumerable:true 57.130 + if (ex.number === -0x7FF5EC54) { 57.131 + classListPropDesc.enumerable = false; 57.132 + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 57.133 + } 57.134 + } 57.135 +} else if (objCtr[protoProp].__defineGetter__) { 57.136 + elemCtrProto.__defineGetter__(classListProp, classListGetter); 57.137 +} 57.138 + 57.139 +}(self)); 57.140 + 57.141 +}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous.css Sun Jul 06 12:02:12 2014 -0700 58.3 @@ -0,0 +1,77 @@ 58.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 58.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 58.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 58.7 + * 58.8 + * Owner: mark@famo.us 58.9 + * @license MPL 2.0 58.10 + * @copyright Famous Industries, Inc. 2014 58.11 + */ 58.12 + 58.13 + 58.14 +html { 58.15 + width: 100%; 58.16 + height: 100%; 58.17 + margin: 0px; 58.18 + padding: 0px; 58.19 + overflow: hidden; 58.20 + -webkit-transform-style: preserve-3d; 58.21 + transform-style: preserve-3d; 58.22 +} 58.23 + 58.24 +body { 58.25 + position: absolute; 58.26 + width: 100%; 58.27 + height: 100%; 58.28 + margin: 0px; 58.29 + padding: 0px; 58.30 + -webkit-transform-style: preserve-3d; 58.31 + transform-style: preserve-3d; 58.32 + -webkit-font-smoothing: antialiased; 58.33 + -webkit-tap-highlight-color: transparent; 58.34 + -webkit-perspective: 0; 58.35 + perspective: none; 58.36 + overflow: hidden; 58.37 +} 58.38 + 58.39 +.famous-container, .famous-group { 58.40 + position: absolute; 58.41 + top: 0px; 58.42 + left: 0px; 58.43 + bottom: 0px; 58.44 + right: 0px; 58.45 + overflow: visible; 58.46 + -webkit-transform-style: preserve-3d; 58.47 + transform-style: preserve-3d; 58.48 + -webkit-backface-visibility: visible; 58.49 + backface-visibility: visible; 58.50 + pointer-events: none; 58.51 +} 58.52 + 58.53 +.famous-group { 58.54 + width: 0px; 58.55 + height: 0px; 58.56 + margin: 0px; 58.57 + padding: 0px; 58.58 + -webkit-transform-style: preserve-3d; 58.59 + transform-style: preserve-3d; 58.60 +} 58.61 + 58.62 +.famous-surface { 58.63 + position: absolute; 58.64 + -webkit-transform-origin: center center; 58.65 + transform-origin: center center; 58.66 + -webkit-backface-visibility: hidden; 58.67 + backface-visibility: hidden; 58.68 + -webkit-transform-style: flat; 58.69 + transform-style: preserve-3d; /* performance */ 58.70 + -webkit-box-sizing: border-box; 58.71 + -moz-box-sizing: border-box; 58.72 + -webkit-tap-highlight-color: transparent; 58.73 + pointer-events: auto; 58.74 +} 58.75 + 58.76 +.famous-container-group { 58.77 + position: relative; 58.78 + width: 100%; 58.79 + height: 100%; 58.80 +}
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous.js Sun Jul 06 12:02:12 2014 -0700 59.3 @@ -0,0 +1,17609 @@ 59.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7 + * 59.8 + * Owner: mark@famo.us 59.9 + * @license MPL 2.0 59.10 + * @copyright Famous Industries, Inc. 2014 59.11 + */ 59.12 + 59.13 +define('famous/core/Entity',['require','exports','module'],function(require, exports, module) { 59.14 + /** 59.15 + * A singleton that maintains a global registry of Surfaces. 59.16 + * Private. 59.17 + * 59.18 + * @private 59.19 + * @static 59.20 + * @class Entity 59.21 + */ 59.22 + 59.23 + var entities = []; 59.24 + 59.25 + /** 59.26 + * Get entity from global index. 59.27 + * 59.28 + * @private 59.29 + * @method get 59.30 + * @param {Number} id entity reigstration id 59.31 + * @return {Surface} entity in the global index 59.32 + */ 59.33 + function get(id) { 59.34 + return entities[id]; 59.35 + } 59.36 + 59.37 + /** 59.38 + * Overwrite entity in the global index 59.39 + * 59.40 + * @private 59.41 + * @method set 59.42 + * @param {Number} id entity reigstration id 59.43 + * @return {Surface} entity to add to the global index 59.44 + */ 59.45 + function set(id, entity) { 59.46 + entities[id] = entity; 59.47 + } 59.48 + 59.49 + /** 59.50 + * Add entity to global index 59.51 + * 59.52 + * @private 59.53 + * @method register 59.54 + * @param {Surface} entity to add to global index 59.55 + * @return {Number} new id 59.56 + */ 59.57 + function register(entity) { 59.58 + var id = entities.length; 59.59 + set(id, entity); 59.60 + return id; 59.61 + } 59.62 + 59.63 + /** 59.64 + * Remove entity from global index 59.65 + * 59.66 + * @private 59.67 + * @method unregister 59.68 + * @param {Number} id entity reigstration id 59.69 + */ 59.70 + function unregister(id) { 59.71 + set(id, null); 59.72 + } 59.73 + 59.74 + module.exports = { 59.75 + register: register, 59.76 + unregister: unregister, 59.77 + get: get, 59.78 + set: set 59.79 + }; 59.80 +}); 59.81 + 59.82 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.83 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.84 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.85 + * 59.86 + * Owner: mark@famo.us 59.87 + * @license MPL 2.0 59.88 + * @copyright Famous Industries, Inc. 2014 59.89 + */ 59.90 + 59.91 +define('famous/core/Transform',['require','exports','module'],function(require, exports, module) { 59.92 + 59.93 + /** 59.94 + * A high-performance static matrix math library used to calculate 59.95 + * affine transforms on surfaces and other renderables. 59.96 + * Famo.us uses 4x4 matrices corresponding directly to 59.97 + * WebKit matrices (column-major order). 59.98 + * 59.99 + * The internal "type" of a Matrix is a 16-long float array in 59.100 + * row-major order, with: 59.101 + * elements [0],[1],[2],[4],[5],[6],[8],[9],[10] forming the 3x3 59.102 + * transformation matrix; 59.103 + * elements [12], [13], [14] corresponding to the t_x, t_y, t_z 59.104 + * translation; 59.105 + * elements [3], [7], [11] set to 0; 59.106 + * element [15] set to 1. 59.107 + * All methods are static. 59.108 + * 59.109 + * @static 59.110 + * 59.111 + * @class Transform 59.112 + */ 59.113 + var Transform = {}; 59.114 + 59.115 + // WARNING: these matrices correspond to WebKit matrices, which are 59.116 + // transposed from their math counterparts 59.117 + Transform.precision = 1e-6; 59.118 + Transform.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 59.119 + 59.120 + /** 59.121 + * Multiply two or more Transform matrix types to return a Transform matrix. 59.122 + * 59.123 + * @method multiply4x4 59.124 + * @static 59.125 + * @param {Transform} a left Transform 59.126 + * @param {Transform} b right Transform 59.127 + * @return {Transform} 59.128 + */ 59.129 + Transform.multiply4x4 = function multiply4x4(a, b) { 59.130 + return [ 59.131 + a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3], 59.132 + a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3], 59.133 + a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3], 59.134 + a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3], 59.135 + a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7], 59.136 + a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7], 59.137 + a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7], 59.138 + a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7], 59.139 + a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11], 59.140 + a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11], 59.141 + a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11], 59.142 + a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11], 59.143 + a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15], 59.144 + a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15], 59.145 + a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15], 59.146 + a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15] 59.147 + ]; 59.148 + }; 59.149 + 59.150 + /** 59.151 + * Fast-multiply two or more Transform matrix types to return a 59.152 + * Matrix, assuming bottom row on each is [0 0 0 1]. 59.153 + * 59.154 + * @method multiply 59.155 + * @static 59.156 + * @param {Transform} a left Transform 59.157 + * @param {Transform} b right Transform 59.158 + * @return {Transform} 59.159 + */ 59.160 + Transform.multiply = function multiply(a, b) { 59.161 + return [ 59.162 + a[0] * b[0] + a[4] * b[1] + a[8] * b[2], 59.163 + a[1] * b[0] + a[5] * b[1] + a[9] * b[2], 59.164 + a[2] * b[0] + a[6] * b[1] + a[10] * b[2], 59.165 + 0, 59.166 + a[0] * b[4] + a[4] * b[5] + a[8] * b[6], 59.167 + a[1] * b[4] + a[5] * b[5] + a[9] * b[6], 59.168 + a[2] * b[4] + a[6] * b[5] + a[10] * b[6], 59.169 + 0, 59.170 + a[0] * b[8] + a[4] * b[9] + a[8] * b[10], 59.171 + a[1] * b[8] + a[5] * b[9] + a[9] * b[10], 59.172 + a[2] * b[8] + a[6] * b[9] + a[10] * b[10], 59.173 + 0, 59.174 + a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12], 59.175 + a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13], 59.176 + a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14], 59.177 + 1 59.178 + ]; 59.179 + }; 59.180 + 59.181 + /** 59.182 + * Return a Transform translated by additional amounts in each 59.183 + * dimension. This is equivalent to the result of 59.184 + * 59.185 + * Transform.multiply(Matrix.translate(t[0], t[1], t[2]), m). 59.186 + * 59.187 + * @method thenMove 59.188 + * @static 59.189 + * @param {Transform} m a Transform 59.190 + * @param {Array.Number} t floats delta vector of length 2 or 3 59.191 + * @return {Transform} 59.192 + */ 59.193 + Transform.thenMove = function thenMove(m, t) { 59.194 + if (!t[2]) t[2] = 0; 59.195 + return [m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, m[12] + t[0], m[13] + t[1], m[14] + t[2], 1]; 59.196 + }; 59.197 + 59.198 + /** 59.199 + * Return a Transform atrix which represents the result of a transform matrix 59.200 + * applied after a move. This is faster than the equivalent multiply. 59.201 + * This is equivalent to the result of: 59.202 + * 59.203 + * Transform.multiply(m, Transform.translate(t[0], t[1], t[2])). 59.204 + * 59.205 + * @method moveThen 59.206 + * @static 59.207 + * @param {Array.Number} v vector representing initial movement 59.208 + * @param {Transform} m matrix to apply afterwards 59.209 + * @return {Transform} the resulting matrix 59.210 + */ 59.211 + Transform.moveThen = function moveThen(v, m) { 59.212 + if (!v[2]) v[2] = 0; 59.213 + var t0 = v[0] * m[0] + v[1] * m[4] + v[2] * m[8]; 59.214 + var t1 = v[0] * m[1] + v[1] * m[5] + v[2] * m[9]; 59.215 + var t2 = v[0] * m[2] + v[1] * m[6] + v[2] * m[10]; 59.216 + return Transform.thenMove(m, [t0, t1, t2]); 59.217 + }; 59.218 + 59.219 + /** 59.220 + * Return a Transform which represents a translation by specified 59.221 + * amounts in each dimension. 59.222 + * 59.223 + * @method translate 59.224 + * @static 59.225 + * @param {Number} x x translation 59.226 + * @param {Number} y y translation 59.227 + * @param {Number} z z translation 59.228 + * @return {Transform} 59.229 + */ 59.230 + Transform.translate = function translate(x, y, z) { 59.231 + if (z === undefined) z = 0; 59.232 + return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]; 59.233 + }; 59.234 + 59.235 + /** 59.236 + * Return a Transform scaled by a vector in each 59.237 + * dimension. This is a more performant equivalent to the result of 59.238 + * 59.239 + * Transform.multiply(Transform.scale(s[0], s[1], s[2]), m). 59.240 + * 59.241 + * @method thenScale 59.242 + * @static 59.243 + * @param {Transform} m a matrix 59.244 + * @param {Array.Number} s delta vector (array of floats && 59.245 + * array.length == 3) 59.246 + * @return {Transform} 59.247 + */ 59.248 + Transform.thenScale = function thenScale(m, s) { 59.249 + return [ 59.250 + s[0] * m[0], s[1] * m[1], s[2] * m[2], 0, 59.251 + s[0] * m[4], s[1] * m[5], s[2] * m[6], 0, 59.252 + s[0] * m[8], s[1] * m[9], s[2] * m[10], 0, 59.253 + s[0] * m[12], s[1] * m[13], s[2] * m[14], 1 59.254 + ]; 59.255 + }; 59.256 + 59.257 + /** 59.258 + * Return a Transform which represents a scale by specified amounts 59.259 + * in each dimension. 59.260 + * 59.261 + * @method scale 59.262 + * @static 59.263 + * @param {Number} x x scale factor 59.264 + * @param {Number} y y scale factor 59.265 + * @param {Number} z z scale factor 59.266 + * @return {Transform} 59.267 + */ 59.268 + Transform.scale = function scale(x, y, z) { 59.269 + if (z === undefined) z = 1; 59.270 + return [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1]; 59.271 + }; 59.272 + 59.273 + /** 59.274 + * Return a Transform which represents a clockwise 59.275 + * rotation around the x axis. 59.276 + * 59.277 + * @method rotateX 59.278 + * @static 59.279 + * @param {Number} theta radians 59.280 + * @return {Transform} 59.281 + */ 59.282 + Transform.rotateX = function rotateX(theta) { 59.283 + var cosTheta = Math.cos(theta); 59.284 + var sinTheta = Math.sin(theta); 59.285 + return [1, 0, 0, 0, 0, cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1]; 59.286 + }; 59.287 + 59.288 + /** 59.289 + * Return a Transform which represents a clockwise 59.290 + * rotation around the y axis. 59.291 + * 59.292 + * @method rotateY 59.293 + * @static 59.294 + * @param {Number} theta radians 59.295 + * @return {Transform} 59.296 + */ 59.297 + Transform.rotateY = function rotateY(theta) { 59.298 + var cosTheta = Math.cos(theta); 59.299 + var sinTheta = Math.sin(theta); 59.300 + return [cosTheta, 0, -sinTheta, 0, 0, 1, 0, 0, sinTheta, 0, cosTheta, 0, 0, 0, 0, 1]; 59.301 + }; 59.302 + 59.303 + /** 59.304 + * Return a Transform which represents a clockwise 59.305 + * rotation around the z axis. 59.306 + * 59.307 + * @method rotateZ 59.308 + * @static 59.309 + * @param {Number} theta radians 59.310 + * @return {Transform} 59.311 + */ 59.312 + Transform.rotateZ = function rotateZ(theta) { 59.313 + var cosTheta = Math.cos(theta); 59.314 + var sinTheta = Math.sin(theta); 59.315 + return [cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 59.316 + }; 59.317 + 59.318 + /** 59.319 + * Return a Transform which represents composed clockwise 59.320 + * rotations along each of the axes. Equivalent to the result of 59.321 + * Matrix.multiply(rotateX(phi), rotateY(theta), rotateZ(psi)). 59.322 + * 59.323 + * @method rotate 59.324 + * @static 59.325 + * @param {Number} phi radians to rotate about the positive x axis 59.326 + * @param {Number} theta radians to rotate about the positive y axis 59.327 + * @param {Number} psi radians to rotate about the positive z axis 59.328 + * @return {Transform} 59.329 + */ 59.330 + Transform.rotate = function rotate(phi, theta, psi) { 59.331 + var cosPhi = Math.cos(phi); 59.332 + var sinPhi = Math.sin(phi); 59.333 + var cosTheta = Math.cos(theta); 59.334 + var sinTheta = Math.sin(theta); 59.335 + var cosPsi = Math.cos(psi); 59.336 + var sinPsi = Math.sin(psi); 59.337 + var result = [ 59.338 + cosTheta * cosPsi, 59.339 + cosPhi * sinPsi + sinPhi * sinTheta * cosPsi, 59.340 + sinPhi * sinPsi - cosPhi * sinTheta * cosPsi, 59.341 + 0, 59.342 + -cosTheta * sinPsi, 59.343 + cosPhi * cosPsi - sinPhi * sinTheta * sinPsi, 59.344 + sinPhi * cosPsi + cosPhi * sinTheta * sinPsi, 59.345 + 0, 59.346 + sinTheta, 59.347 + -sinPhi * cosTheta, 59.348 + cosPhi * cosTheta, 59.349 + 0, 59.350 + 0, 0, 0, 1 59.351 + ]; 59.352 + return result; 59.353 + }; 59.354 + 59.355 + /** 59.356 + * Return a Transform which represents an axis-angle rotation 59.357 + * 59.358 + * @method rotateAxis 59.359 + * @static 59.360 + * @param {Array.Number} v unit vector representing the axis to rotate about 59.361 + * @param {Number} theta radians to rotate clockwise about the axis 59.362 + * @return {Transform} 59.363 + */ 59.364 + Transform.rotateAxis = function rotateAxis(v, theta) { 59.365 + var sinTheta = Math.sin(theta); 59.366 + var cosTheta = Math.cos(theta); 59.367 + var verTheta = 1 - cosTheta; // versine of theta 59.368 + 59.369 + var xxV = v[0] * v[0] * verTheta; 59.370 + var xyV = v[0] * v[1] * verTheta; 59.371 + var xzV = v[0] * v[2] * verTheta; 59.372 + var yyV = v[1] * v[1] * verTheta; 59.373 + var yzV = v[1] * v[2] * verTheta; 59.374 + var zzV = v[2] * v[2] * verTheta; 59.375 + var xs = v[0] * sinTheta; 59.376 + var ys = v[1] * sinTheta; 59.377 + var zs = v[2] * sinTheta; 59.378 + 59.379 + var result = [ 59.380 + xxV + cosTheta, xyV + zs, xzV - ys, 0, 59.381 + xyV - zs, yyV + cosTheta, yzV + xs, 0, 59.382 + xzV + ys, yzV - xs, zzV + cosTheta, 0, 59.383 + 0, 0, 0, 1 59.384 + ]; 59.385 + return result; 59.386 + }; 59.387 + 59.388 + /** 59.389 + * Return a Transform which represents a transform matrix applied about 59.390 + * a separate origin point. 59.391 + * 59.392 + * @method aboutOrigin 59.393 + * @static 59.394 + * @param {Array.Number} v origin point to apply matrix 59.395 + * @param {Transform} m matrix to apply 59.396 + * @return {Transform} 59.397 + */ 59.398 + Transform.aboutOrigin = function aboutOrigin(v, m) { 59.399 + var t0 = v[0] - (v[0] * m[0] + v[1] * m[4] + v[2] * m[8]); 59.400 + var t1 = v[1] - (v[0] * m[1] + v[1] * m[5] + v[2] * m[9]); 59.401 + var t2 = v[2] - (v[0] * m[2] + v[1] * m[6] + v[2] * m[10]); 59.402 + return Transform.thenMove(m, [t0, t1, t2]); 59.403 + }; 59.404 + 59.405 + /** 59.406 + * Return a Transform representation of a skew transformation 59.407 + * 59.408 + * @method skew 59.409 + * @static 59.410 + * @param {Number} phi scale factor skew in the x axis 59.411 + * @param {Number} theta scale factor skew in the y axis 59.412 + * @param {Number} psi scale factor skew in the z axis 59.413 + * @return {Transform} 59.414 + */ 59.415 + Transform.skew = function skew(phi, theta, psi) { 59.416 + return [1, 0, 0, 0, Math.tan(psi), 1, 0, 0, Math.tan(theta), Math.tan(phi), 1, 0, 0, 0, 0, 1]; 59.417 + }; 59.418 + 59.419 + /** 59.420 + * Return a Transform representation of a skew in the x-direction 59.421 + * 59.422 + * @method skewX 59.423 + * @static 59.424 + * @param {Number} angle the angle between the top and left sides 59.425 + * @return {Transform} 59.426 + */ 59.427 + Transform.skewX = function skewX(angle) { 59.428 + return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 59.429 + }; 59.430 + 59.431 + /** 59.432 + * Return a Transform representation of a skew in the y-direction 59.433 + * 59.434 + * @method skewY 59.435 + * @static 59.436 + * @param {Number} angle the angle between the top and right sides 59.437 + * @return {Transform} 59.438 + */ 59.439 + Transform.skewY = function skewY(angle) { 59.440 + return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 59.441 + }; 59.442 + 59.443 + /** 59.444 + * Returns a perspective Transform matrix 59.445 + * 59.446 + * @method perspective 59.447 + * @static 59.448 + * @param {Number} focusZ z position of focal point 59.449 + * @return {Transform} 59.450 + */ 59.451 + Transform.perspective = function perspective(focusZ) { 59.452 + return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1 / focusZ, 0, 0, 0, 1]; 59.453 + }; 59.454 + 59.455 + /** 59.456 + * Return translation vector component of given Transform 59.457 + * 59.458 + * @method getTranslate 59.459 + * @static 59.460 + * @param {Transform} m Transform 59.461 + * @return {Array.Number} the translation vector [t_x, t_y, t_z] 59.462 + */ 59.463 + Transform.getTranslate = function getTranslate(m) { 59.464 + return [m[12], m[13], m[14]]; 59.465 + }; 59.466 + 59.467 + /** 59.468 + * Return inverse affine transform for given Transform. 59.469 + * Note: This assumes m[3] = m[7] = m[11] = 0, and m[15] = 1. 59.470 + * Will provide incorrect results if not invertible or preconditions not met. 59.471 + * 59.472 + * @method inverse 59.473 + * @static 59.474 + * @param {Transform} m Transform 59.475 + * @return {Transform} 59.476 + */ 59.477 + Transform.inverse = function inverse(m) { 59.478 + // only need to consider 3x3 section for affine 59.479 + var c0 = m[5] * m[10] - m[6] * m[9]; 59.480 + var c1 = m[4] * m[10] - m[6] * m[8]; 59.481 + var c2 = m[4] * m[9] - m[5] * m[8]; 59.482 + var c4 = m[1] * m[10] - m[2] * m[9]; 59.483 + var c5 = m[0] * m[10] - m[2] * m[8]; 59.484 + var c6 = m[0] * m[9] - m[1] * m[8]; 59.485 + var c8 = m[1] * m[6] - m[2] * m[5]; 59.486 + var c9 = m[0] * m[6] - m[2] * m[4]; 59.487 + var c10 = m[0] * m[5] - m[1] * m[4]; 59.488 + var detM = m[0] * c0 - m[1] * c1 + m[2] * c2; 59.489 + var invD = 1 / detM; 59.490 + var result = [ 59.491 + invD * c0, -invD * c4, invD * c8, 0, 59.492 + -invD * c1, invD * c5, -invD * c9, 0, 59.493 + invD * c2, -invD * c6, invD * c10, 0, 59.494 + 0, 0, 0, 1 59.495 + ]; 59.496 + result[12] = -m[12] * result[0] - m[13] * result[4] - m[14] * result[8]; 59.497 + result[13] = -m[12] * result[1] - m[13] * result[5] - m[14] * result[9]; 59.498 + result[14] = -m[12] * result[2] - m[13] * result[6] - m[14] * result[10]; 59.499 + return result; 59.500 + }; 59.501 + 59.502 + /** 59.503 + * Returns the transpose of a 4x4 matrix 59.504 + * 59.505 + * @method transpose 59.506 + * @static 59.507 + * @param {Transform} m matrix 59.508 + * @return {Transform} the resulting transposed matrix 59.509 + */ 59.510 + Transform.transpose = function transpose(m) { 59.511 + return [m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]]; 59.512 + }; 59.513 + 59.514 + function _normSquared(v) { 59.515 + return (v.length === 2) ? v[0] * v[0] + v[1] * v[1] : v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; 59.516 + } 59.517 + function _norm(v) { 59.518 + return Math.sqrt(_normSquared(v)); 59.519 + } 59.520 + function _sign(n) { 59.521 + return (n < 0) ? -1 : 1; 59.522 + } 59.523 + 59.524 + /** 59.525 + * Decompose Transform into separate .translate, .rotate, .scale, 59.526 + * and .skew components. 59.527 + * 59.528 + * @method interpret 59.529 + * @static 59.530 + * @param {Transform} M transform matrix 59.531 + * @return {Object} matrix spec object with component matrices .translate, 59.532 + * .rotate, .scale, .skew 59.533 + */ 59.534 + Transform.interpret = function interpret(M) { 59.535 + 59.536 + // QR decomposition via Householder reflections 59.537 + //FIRST ITERATION 59.538 + 59.539 + //default Q1 to the identity matrix; 59.540 + var x = [M[0], M[1], M[2]]; // first column vector 59.541 + var sgn = _sign(x[0]); // sign of first component of x (for stability) 59.542 + var xNorm = _norm(x); // norm of first column vector 59.543 + var v = [x[0] + sgn * xNorm, x[1], x[2]]; // v = x + sign(x[0])|x|e1 59.544 + var mult = 2 / _normSquared(v); // mult = 2/v'v 59.545 + 59.546 + //bail out if our Matrix is singular 59.547 + if (mult >= Infinity) { 59.548 + return {translate: Transform.getTranslate(M), rotate: [0, 0, 0], scale: [0, 0, 0], skew: [0, 0, 0]}; 59.549 + } 59.550 + 59.551 + //evaluate Q1 = I - 2vv'/v'v 59.552 + var Q1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; 59.553 + 59.554 + //diagonals 59.555 + Q1[0] = 1 - mult * v[0] * v[0]; // 0,0 entry 59.556 + Q1[5] = 1 - mult * v[1] * v[1]; // 1,1 entry 59.557 + Q1[10] = 1 - mult * v[2] * v[2]; // 2,2 entry 59.558 + 59.559 + //upper diagonal 59.560 + Q1[1] = -mult * v[0] * v[1]; // 0,1 entry 59.561 + Q1[2] = -mult * v[0] * v[2]; // 0,2 entry 59.562 + Q1[6] = -mult * v[1] * v[2]; // 1,2 entry 59.563 + 59.564 + //lower diagonal 59.565 + Q1[4] = Q1[1]; // 1,0 entry 59.566 + Q1[8] = Q1[2]; // 2,0 entry 59.567 + Q1[9] = Q1[6]; // 2,1 entry 59.568 + 59.569 + //reduce first column of M 59.570 + var MQ1 = Transform.multiply(Q1, M); 59.571 + 59.572 + //SECOND ITERATION on (1,1) minor 59.573 + var x2 = [MQ1[5], MQ1[6]]; 59.574 + var sgn2 = _sign(x2[0]); // sign of first component of x (for stability) 59.575 + var x2Norm = _norm(x2); // norm of first column vector 59.576 + var v2 = [x2[0] + sgn2 * x2Norm, x2[1]]; // v = x + sign(x[0])|x|e1 59.577 + var mult2 = 2 / _normSquared(v2); // mult = 2/v'v 59.578 + 59.579 + //evaluate Q2 = I - 2vv'/v'v 59.580 + var Q2 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; 59.581 + 59.582 + //diagonal 59.583 + Q2[5] = 1 - mult2 * v2[0] * v2[0]; // 1,1 entry 59.584 + Q2[10] = 1 - mult2 * v2[1] * v2[1]; // 2,2 entry 59.585 + 59.586 + //off diagonals 59.587 + Q2[6] = -mult2 * v2[0] * v2[1]; // 2,1 entry 59.588 + Q2[9] = Q2[6]; // 1,2 entry 59.589 + 59.590 + //calc QR decomposition. Q = Q1*Q2, R = Q'*M 59.591 + var Q = Transform.multiply(Q2, Q1); //note: really Q transpose 59.592 + var R = Transform.multiply(Q, M); 59.593 + 59.594 + //remove negative scaling 59.595 + var remover = Transform.scale(R[0] < 0 ? -1 : 1, R[5] < 0 ? -1 : 1, R[10] < 0 ? -1 : 1); 59.596 + R = Transform.multiply(R, remover); 59.597 + Q = Transform.multiply(remover, Q); 59.598 + 59.599 + //decompose into rotate/scale/skew matrices 59.600 + var result = {}; 59.601 + result.translate = Transform.getTranslate(M); 59.602 + result.rotate = [Math.atan2(-Q[6], Q[10]), Math.asin(Q[2]), Math.atan2(-Q[1], Q[0])]; 59.603 + if (!result.rotate[0]) { 59.604 + result.rotate[0] = 0; 59.605 + result.rotate[2] = Math.atan2(Q[4], Q[5]); 59.606 + } 59.607 + result.scale = [R[0], R[5], R[10]]; 59.608 + result.skew = [Math.atan2(R[9], result.scale[2]), Math.atan2(R[8], result.scale[2]), Math.atan2(R[4], result.scale[0])]; 59.609 + 59.610 + //double rotation workaround 59.611 + if (Math.abs(result.rotate[0]) + Math.abs(result.rotate[2]) > 1.5 * Math.PI) { 59.612 + result.rotate[1] = Math.PI - result.rotate[1]; 59.613 + if (result.rotate[1] > Math.PI) result.rotate[1] -= 2 * Math.PI; 59.614 + if (result.rotate[1] < -Math.PI) result.rotate[1] += 2 * Math.PI; 59.615 + if (result.rotate[0] < 0) result.rotate[0] += Math.PI; 59.616 + else result.rotate[0] -= Math.PI; 59.617 + if (result.rotate[2] < 0) result.rotate[2] += Math.PI; 59.618 + else result.rotate[2] -= Math.PI; 59.619 + } 59.620 + 59.621 + return result; 59.622 + }; 59.623 + 59.624 + /** 59.625 + * Weighted average between two matrices by averaging their 59.626 + * translation, rotation, scale, skew components. 59.627 + * f(M1,M2,t) = (1 - t) * M1 + t * M2 59.628 + * 59.629 + * @method average 59.630 + * @static 59.631 + * @param {Transform} M1 f(M1,M2,0) = M1 59.632 + * @param {Transform} M2 f(M1,M2,1) = M2 59.633 + * @param {Number} t 59.634 + * @return {Transform} 59.635 + */ 59.636 + Transform.average = function average(M1, M2, t) { 59.637 + t = (t === undefined) ? 0.5 : t; 59.638 + var specM1 = Transform.interpret(M1); 59.639 + var specM2 = Transform.interpret(M2); 59.640 + 59.641 + var specAvg = { 59.642 + translate: [0, 0, 0], 59.643 + rotate: [0, 0, 0], 59.644 + scale: [0, 0, 0], 59.645 + skew: [0, 0, 0] 59.646 + }; 59.647 + 59.648 + for (var i = 0; i < 3; i++) { 59.649 + specAvg.translate[i] = (1 - t) * specM1.translate[i] + t * specM2.translate[i]; 59.650 + specAvg.rotate[i] = (1 - t) * specM1.rotate[i] + t * specM2.rotate[i]; 59.651 + specAvg.scale[i] = (1 - t) * specM1.scale[i] + t * specM2.scale[i]; 59.652 + specAvg.skew[i] = (1 - t) * specM1.skew[i] + t * specM2.skew[i]; 59.653 + } 59.654 + return Transform.build(specAvg); 59.655 + }; 59.656 + 59.657 + /** 59.658 + * Compose .translate, .rotate, .scale, .skew components into 59.659 + * Transform matrix 59.660 + * 59.661 + * @method build 59.662 + * @static 59.663 + * @param {matrixSpec} spec object with component matrices .translate, 59.664 + * .rotate, .scale, .skew 59.665 + * @return {Transform} composed transform 59.666 + */ 59.667 + Transform.build = function build(spec) { 59.668 + var scaleMatrix = Transform.scale(spec.scale[0], spec.scale[1], spec.scale[2]); 59.669 + var skewMatrix = Transform.skew(spec.skew[0], spec.skew[1], spec.skew[2]); 59.670 + var rotateMatrix = Transform.rotate(spec.rotate[0], spec.rotate[1], spec.rotate[2]); 59.671 + return Transform.thenMove(Transform.multiply(Transform.multiply(rotateMatrix, skewMatrix), scaleMatrix), spec.translate); 59.672 + }; 59.673 + 59.674 + /** 59.675 + * Determine if two Transforms are component-wise equal 59.676 + * Warning: breaks on perspective Transforms 59.677 + * 59.678 + * @method equals 59.679 + * @static 59.680 + * @param {Transform} a matrix 59.681 + * @param {Transform} b matrix 59.682 + * @return {boolean} 59.683 + */ 59.684 + Transform.equals = function equals(a, b) { 59.685 + return !Transform.notEquals(a, b); 59.686 + }; 59.687 + 59.688 + /** 59.689 + * Determine if two Transforms are component-wise unequal 59.690 + * Warning: breaks on perspective Transforms 59.691 + * 59.692 + * @method notEquals 59.693 + * @static 59.694 + * @param {Transform} a matrix 59.695 + * @param {Transform} b matrix 59.696 + * @return {boolean} 59.697 + */ 59.698 + Transform.notEquals = function notEquals(a, b) { 59.699 + if (a === b) return false; 59.700 + 59.701 + // shortci 59.702 + return !(a && b) || 59.703 + a[12] !== b[12] || a[13] !== b[13] || a[14] !== b[14] || 59.704 + a[0] !== b[0] || a[1] !== b[1] || a[2] !== b[2] || 59.705 + a[4] !== b[4] || a[5] !== b[5] || a[6] !== b[6] || 59.706 + a[8] !== b[8] || a[9] !== b[9] || a[10] !== b[10]; 59.707 + }; 59.708 + 59.709 + /** 59.710 + * Constrain angle-trio components to range of [-pi, pi). 59.711 + * 59.712 + * @method normalizeRotation 59.713 + * @static 59.714 + * @param {Array.Number} rotation phi, theta, psi (array of floats 59.715 + * && array.length == 3) 59.716 + * @return {Array.Number} new phi, theta, psi triplet 59.717 + * (array of floats && array.length == 3) 59.718 + */ 59.719 + Transform.normalizeRotation = function normalizeRotation(rotation) { 59.720 + var result = rotation.slice(0); 59.721 + if (result[0] === Math.PI * 0.5 || result[0] === -Math.PI * 0.5) { 59.722 + result[0] = -result[0]; 59.723 + result[1] = Math.PI - result[1]; 59.724 + result[2] -= Math.PI; 59.725 + } 59.726 + if (result[0] > Math.PI * 0.5) { 59.727 + result[0] = result[0] - Math.PI; 59.728 + result[1] = Math.PI - result[1]; 59.729 + result[2] -= Math.PI; 59.730 + } 59.731 + if (result[0] < -Math.PI * 0.5) { 59.732 + result[0] = result[0] + Math.PI; 59.733 + result[1] = -Math.PI - result[1]; 59.734 + result[2] -= Math.PI; 59.735 + } 59.736 + while (result[1] < -Math.PI) result[1] += 2 * Math.PI; 59.737 + while (result[1] >= Math.PI) result[1] -= 2 * Math.PI; 59.738 + while (result[2] < -Math.PI) result[2] += 2 * Math.PI; 59.739 + while (result[2] >= Math.PI) result[2] -= 2 * Math.PI; 59.740 + return result; 59.741 + }; 59.742 + 59.743 + /** 59.744 + * (Property) Array defining a translation forward in z by 1 59.745 + * 59.746 + * @property {array} inFront 59.747 + * @static 59.748 + * @final 59.749 + */ 59.750 + Transform.inFront = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1e-3, 1]; 59.751 + 59.752 + /** 59.753 + * (Property) Array defining a translation backwards in z by 1 59.754 + * 59.755 + * @property {array} behind 59.756 + * @static 59.757 + * @final 59.758 + */ 59.759 + Transform.behind = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1e-3, 1]; 59.760 + 59.761 + module.exports = Transform; 59.762 +}); 59.763 + 59.764 + 59.765 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.766 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.767 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.768 + * 59.769 + * Owner: mark@famo.us 59.770 + * @license MPL 2.0 59.771 + * @copyright Famous Industries, Inc. 2014 59.772 + */ 59.773 + 59.774 +define('famous/core/SpecParser',['require','exports','module','./Transform'],function(require, exports, module) { 59.775 + var Transform = require('./Transform'); 59.776 + 59.777 + /** 59.778 + * 59.779 + * This object translates the rendering instructions ("render specs") 59.780 + * that renderable components generate into document update 59.781 + * instructions ("update specs"). Private. 59.782 + * 59.783 + * @private 59.784 + * @class SpecParser 59.785 + * @constructor 59.786 + */ 59.787 + function SpecParser() { 59.788 + this.result = {}; 59.789 + } 59.790 + SpecParser._instance = new SpecParser(); 59.791 + 59.792 + /** 59.793 + * Convert a render spec coming from the context's render chain to an 59.794 + * update spec for the update chain. This is the only major entry point 59.795 + * for a consumer of this class. 59.796 + * 59.797 + * @method parse 59.798 + * @static 59.799 + * @private 59.800 + * 59.801 + * @param {renderSpec} spec input render spec 59.802 + * @param {Object} context context to do the parse in 59.803 + * @return {Object} the resulting update spec (if no callback 59.804 + * specified, else none) 59.805 + */ 59.806 + SpecParser.parse = function parse(spec, context) { 59.807 + return SpecParser._instance.parse(spec, context); 59.808 + }; 59.809 + 59.810 + /** 59.811 + * Convert a renderSpec coming from the context's render chain to an update 59.812 + * spec for the update chain. This is the only major entrypoint for a 59.813 + * consumer of this class. 59.814 + * 59.815 + * @method parse 59.816 + * 59.817 + * @private 59.818 + * @param {renderSpec} spec input render spec 59.819 + * @param {Context} context 59.820 + * @return {updateSpec} the resulting update spec 59.821 + */ 59.822 + SpecParser.prototype.parse = function parse(spec, context) { 59.823 + this.reset(); 59.824 + this._parseSpec(spec, context, Transform.identity); 59.825 + return this.result; 59.826 + }; 59.827 + 59.828 + /** 59.829 + * Prepare SpecParser for re-use (or first use) by setting internal state 59.830 + * to blank. 59.831 + * 59.832 + * @private 59.833 + * @method reset 59.834 + */ 59.835 + SpecParser.prototype.reset = function reset() { 59.836 + this.result = {}; 59.837 + }; 59.838 + 59.839 + // Multiply matrix M by vector v 59.840 + function _vecInContext(v, m) { 59.841 + return [ 59.842 + v[0] * m[0] + v[1] * m[4] + v[2] * m[8], 59.843 + v[0] * m[1] + v[1] * m[5] + v[2] * m[9], 59.844 + v[0] * m[2] + v[1] * m[6] + v[2] * m[10] 59.845 + ]; 59.846 + } 59.847 + 59.848 + var _originZeroZero = [0, 0]; 59.849 + 59.850 + // From the provided renderSpec tree, recursively compose opacities, 59.851 + // origins, transforms, and sizes corresponding to each surface id from 59.852 + // the provided renderSpec tree structure. On completion, those 59.853 + // properties of 'this' object should be ready to use to build an 59.854 + // updateSpec. 59.855 + SpecParser.prototype._parseSpec = function _parseSpec(spec, parentContext, sizeContext) { 59.856 + var id; 59.857 + var target; 59.858 + var transform; 59.859 + var opacity; 59.860 + var origin; 59.861 + var align; 59.862 + var size; 59.863 + 59.864 + if (typeof spec === 'number') { 59.865 + id = spec; 59.866 + transform = parentContext.transform; 59.867 + align = parentContext.align || parentContext.origin; 59.868 + if (parentContext.size && align && (align[0] || align[1])) { 59.869 + var alignAdjust = [align[0] * parentContext.size[0], align[1] * parentContext.size[1], 0]; 59.870 + transform = Transform.thenMove(transform, _vecInContext(alignAdjust, sizeContext)); 59.871 + } 59.872 + this.result[id] = { 59.873 + transform: transform, 59.874 + opacity: parentContext.opacity, 59.875 + origin: parentContext.origin || _originZeroZero, 59.876 + align: parentContext.align || parentContext.origin || _originZeroZero, 59.877 + size: parentContext.size 59.878 + }; 59.879 + } 59.880 + else if (!spec) { // placed here so 0 will be cached earlier 59.881 + return; 59.882 + } 59.883 + else if (spec instanceof Array) { 59.884 + for (var i = 0; i < spec.length; i++) { 59.885 + this._parseSpec(spec[i], parentContext, sizeContext); 59.886 + } 59.887 + } 59.888 + else { 59.889 + target = spec.target; 59.890 + transform = parentContext.transform; 59.891 + opacity = parentContext.opacity; 59.892 + origin = parentContext.origin; 59.893 + align = parentContext.align; 59.894 + size = parentContext.size; 59.895 + var nextSizeContext = sizeContext; 59.896 + 59.897 + if (spec.opacity !== undefined) opacity = parentContext.opacity * spec.opacity; 59.898 + if (spec.transform) transform = Transform.multiply(parentContext.transform, spec.transform); 59.899 + if (spec.origin) { 59.900 + origin = spec.origin; 59.901 + nextSizeContext = parentContext.transform; 59.902 + } 59.903 + if (spec.align) align = spec.align; 59.904 + if (spec.size) { 59.905 + var parentSize = parentContext.size; 59.906 + size = [ 59.907 + spec.size[0] !== undefined ? spec.size[0] : parentSize[0], 59.908 + spec.size[1] !== undefined ? spec.size[1] : parentSize[1] 59.909 + ]; 59.910 + if (parentSize) { 59.911 + if (!align) align = origin; 59.912 + if (align && (align[0] || align[1])) transform = Transform.thenMove(transform, _vecInContext([align[0] * parentSize[0], align[1] * parentSize[1], 0], sizeContext)); 59.913 + if (origin && (origin[0] || origin[1])) transform = Transform.moveThen([-origin[0] * size[0], -origin[1] * size[1], 0], transform); 59.914 + } 59.915 + nextSizeContext = parentContext.transform; 59.916 + origin = null; 59.917 + align = null; 59.918 + } 59.919 + 59.920 + this._parseSpec(target, { 59.921 + transform: transform, 59.922 + opacity: opacity, 59.923 + origin: origin, 59.924 + align: align, 59.925 + size: size 59.926 + }, nextSizeContext); 59.927 + } 59.928 + }; 59.929 + 59.930 + module.exports = SpecParser; 59.931 +}); 59.932 + 59.933 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.934 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.935 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.936 + * 59.937 + * Owner: mark@famo.us 59.938 + * @license MPL 2.0 59.939 + * @copyright Famous Industries, Inc. 2014 59.940 + */ 59.941 + 59.942 +define('famous/core/RenderNode',['require','exports','module','./Entity','./SpecParser'],function(require, exports, module) { 59.943 + var Entity = require('./Entity'); 59.944 + var SpecParser = require('./SpecParser'); 59.945 + 59.946 + /** 59.947 + * A wrapper for inserting a renderable component (like a Modifer or 59.948 + * Surface) into the render tree. 59.949 + * 59.950 + * @class RenderNode 59.951 + * @constructor 59.952 + * 59.953 + * @param {Object} object Target renderable component 59.954 + */ 59.955 + function RenderNode(object) { 59.956 + this._object = null; 59.957 + this._child = null; 59.958 + this._hasMultipleChildren = false; 59.959 + this._isRenderable = false; 59.960 + this._isModifier = false; 59.961 + 59.962 + this._resultCache = {}; 59.963 + this._prevResults = {}; 59.964 + 59.965 + this._childResult = null; 59.966 + 59.967 + if (object) this.set(object); 59.968 + } 59.969 + 59.970 + /** 59.971 + * Append a renderable to the list of this node's children. 59.972 + * This produces a new RenderNode in the tree. 59.973 + * Note: Does not double-wrap if child is a RenderNode already. 59.974 + * 59.975 + * @method add 59.976 + * @param {Object} child renderable object 59.977 + * @return {RenderNode} new render node wrapping child 59.978 + */ 59.979 + RenderNode.prototype.add = function add(child) { 59.980 + var childNode = (child instanceof RenderNode) ? child : new RenderNode(child); 59.981 + if (this._child instanceof Array) this._child.push(childNode); 59.982 + else if (this._child) { 59.983 + this._child = [this._child, childNode]; 59.984 + this._hasMultipleChildren = true; 59.985 + this._childResult = []; // to be used later 59.986 + } 59.987 + else this._child = childNode; 59.988 + 59.989 + return childNode; 59.990 + }; 59.991 + 59.992 + /** 59.993 + * Return the single wrapped object. Returns null if this node has multiple child nodes. 59.994 + * 59.995 + * @method get 59.996 + * 59.997 + * @return {Ojbect} contained renderable object 59.998 + */ 59.999 + RenderNode.prototype.get = function get() { 59.1000 + return this._object || (this._hasMultipleChildren ? null : (this._child ? this._child.get() : null)); 59.1001 + }; 59.1002 + 59.1003 + /** 59.1004 + * Overwrite the list of children to contain the single provided object 59.1005 + * 59.1006 + * @method set 59.1007 + * @param {Object} child renderable object 59.1008 + * @return {RenderNode} this render node, or child if it is a RenderNode 59.1009 + */ 59.1010 + RenderNode.prototype.set = function set(child) { 59.1011 + this._childResult = null; 59.1012 + this._hasMultipleChildren = false; 59.1013 + this._isRenderable = child.render ? true : false; 59.1014 + this._isModifier = child.modify ? true : false; 59.1015 + this._object = child; 59.1016 + this._child = null; 59.1017 + if (child instanceof RenderNode) return child; 59.1018 + else return this; 59.1019 + }; 59.1020 + 59.1021 + /** 59.1022 + * Get render size of contained object. 59.1023 + * 59.1024 + * @method getSize 59.1025 + * @return {Array.Number} size of this or size of single child. 59.1026 + */ 59.1027 + RenderNode.prototype.getSize = function getSize() { 59.1028 + var result = null; 59.1029 + var target = this.get(); 59.1030 + if (target && target.getSize) result = target.getSize(); 59.1031 + if (!result && this._child && this._child.getSize) result = this._child.getSize(); 59.1032 + return result; 59.1033 + }; 59.1034 + 59.1035 + // apply results of rendering this subtree to the document 59.1036 + function _applyCommit(spec, context, cacheStorage) { 59.1037 + var result = SpecParser.parse(spec, context); 59.1038 + var keys = Object.keys(result); 59.1039 + for (var i = 0; i < keys.length; i++) { 59.1040 + var id = keys[i]; 59.1041 + var childNode = Entity.get(id); 59.1042 + var commitParams = result[id]; 59.1043 + commitParams.allocator = context.allocator; 59.1044 + var commitResult = childNode.commit(commitParams); 59.1045 + if (commitResult) _applyCommit(commitResult, context, cacheStorage); 59.1046 + else cacheStorage[id] = commitParams; 59.1047 + } 59.1048 + } 59.1049 + 59.1050 + /** 59.1051 + * Commit the content change from this node to the document. 59.1052 + * 59.1053 + * @private 59.1054 + * @method commit 59.1055 + * @param {Context} context render context 59.1056 + */ 59.1057 + RenderNode.prototype.commit = function commit(context) { 59.1058 + // free up some divs from the last loop 59.1059 + var prevKeys = Object.keys(this._prevResults); 59.1060 + for (var i = 0; i < prevKeys.length; i++) { 59.1061 + var id = prevKeys[i]; 59.1062 + if (this._resultCache[id] === undefined) { 59.1063 + var object = Entity.get(id); 59.1064 + if (object.cleanup) object.cleanup(context.allocator); 59.1065 + } 59.1066 + } 59.1067 + 59.1068 + this._prevResults = this._resultCache; 59.1069 + this._resultCache = {}; 59.1070 + _applyCommit(this.render(), context, this._resultCache); 59.1071 + }; 59.1072 + 59.1073 + /** 59.1074 + * Generate a render spec from the contents of the wrapped component. 59.1075 + * 59.1076 + * @private 59.1077 + * @method render 59.1078 + * 59.1079 + * @return {Object} render specification for the component subtree 59.1080 + * only under this node. 59.1081 + */ 59.1082 + RenderNode.prototype.render = function render() { 59.1083 + if (this._isRenderable) return this._object.render(); 59.1084 + 59.1085 + var result = null; 59.1086 + if (this._hasMultipleChildren) { 59.1087 + result = this._childResult; 59.1088 + var children = this._child; 59.1089 + for (var i = 0; i < children.length; i++) { 59.1090 + result[i] = children[i].render(); 59.1091 + } 59.1092 + } 59.1093 + else if (this._child) result = this._child.render(); 59.1094 + 59.1095 + return this._isModifier ? this._object.modify(result) : result; 59.1096 + }; 59.1097 + 59.1098 + module.exports = RenderNode; 59.1099 +}); 59.1100 + 59.1101 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1102 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1103 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1104 + * 59.1105 + * Owner: mark@famo.us 59.1106 + * @license MPL 2.0 59.1107 + * @copyright Famous Industries, Inc. 2014 59.1108 + */ 59.1109 + 59.1110 +define('famous/core/EventEmitter',['require','exports','module'],function(require, exports, module) { 59.1111 + /** 59.1112 + * EventEmitter represents a channel for events. 59.1113 + * 59.1114 + * @class EventEmitter 59.1115 + * @constructor 59.1116 + */ 59.1117 + function EventEmitter() { 59.1118 + this.listeners = {}; 59.1119 + this._owner = this; 59.1120 + } 59.1121 + 59.1122 + /** 59.1123 + * Trigger an event, sending to all downstream handlers 59.1124 + * listening for provided 'type' key. 59.1125 + * 59.1126 + * @method emit 59.1127 + * 59.1128 + * @param {string} type event type key (for example, 'click') 59.1129 + * @param {Object} event event data 59.1130 + * @return {EventHandler} this 59.1131 + */ 59.1132 + EventEmitter.prototype.emit = function emit(type, event) { 59.1133 + var handlers = this.listeners[type]; 59.1134 + if (handlers) { 59.1135 + for (var i = 0; i < handlers.length; i++) { 59.1136 + handlers[i].call(this._owner, event); 59.1137 + } 59.1138 + } 59.1139 + return this; 59.1140 + }; 59.1141 + 59.1142 + /** 59.1143 + * Bind a callback function to an event type handled by this object. 59.1144 + * 59.1145 + * @method "on" 59.1146 + * 59.1147 + * @param {string} type event type key (for example, 'click') 59.1148 + * @param {function(string, Object)} handler callback 59.1149 + * @return {EventHandler} this 59.1150 + */ 59.1151 + EventEmitter.prototype.on = function on(type, handler) { 59.1152 + if (!(type in this.listeners)) this.listeners[type] = []; 59.1153 + var index = this.listeners[type].indexOf(handler); 59.1154 + if (index < 0) this.listeners[type].push(handler); 59.1155 + return this; 59.1156 + }; 59.1157 + 59.1158 + /** 59.1159 + * Alias for "on". 59.1160 + * @method addListener 59.1161 + */ 59.1162 + EventEmitter.prototype.addListener = EventEmitter.prototype.on; 59.1163 + 59.1164 + /** 59.1165 + * Unbind an event by type and handler. 59.1166 + * This undoes the work of "on". 59.1167 + * 59.1168 + * @method removeListener 59.1169 + * 59.1170 + * @param {string} type event type key (for example, 'click') 59.1171 + * @param {function} handler function object to remove 59.1172 + * @return {EventEmitter} this 59.1173 + */ 59.1174 + EventEmitter.prototype.removeListener = function removeListener(type, handler) { 59.1175 + var index = this.listeners[type].indexOf(handler); 59.1176 + if (index >= 0) this.listeners[type].splice(index, 1); 59.1177 + return this; 59.1178 + }; 59.1179 + 59.1180 + /** 59.1181 + * Call event handlers with this set to owner. 59.1182 + * 59.1183 + * @method bindThis 59.1184 + * 59.1185 + * @param {Object} owner object this EventEmitter belongs to 59.1186 + */ 59.1187 + EventEmitter.prototype.bindThis = function bindThis(owner) { 59.1188 + this._owner = owner; 59.1189 + }; 59.1190 + 59.1191 + module.exports = EventEmitter; 59.1192 +}); 59.1193 + 59.1194 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1195 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1196 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1197 + * 59.1198 + * Owner: mark@famo.us 59.1199 + * @license MPL 2.0 59.1200 + * @copyright Famous Industries, Inc. 2014 59.1201 + */ 59.1202 + 59.1203 +define('famous/core/EventHandler',['require','exports','module','./EventEmitter'],function(require, exports, module) { 59.1204 + var EventEmitter = require('./EventEmitter'); 59.1205 + 59.1206 + /** 59.1207 + * EventHandler forwards received events to a set of provided callback functions. 59.1208 + * It allows events to be captured, processed, and optionally piped through to other event handlers. 59.1209 + * 59.1210 + * @class EventHandler 59.1211 + * @extends EventEmitter 59.1212 + * @constructor 59.1213 + */ 59.1214 + function EventHandler() { 59.1215 + EventEmitter.apply(this, arguments); 59.1216 + 59.1217 + this.downstream = []; // downstream event handlers 59.1218 + this.downstreamFn = []; // downstream functions 59.1219 + 59.1220 + this.upstream = []; // upstream event handlers 59.1221 + this.upstreamListeners = {}; // upstream listeners 59.1222 + } 59.1223 + EventHandler.prototype = Object.create(EventEmitter.prototype); 59.1224 + EventHandler.prototype.constructor = EventHandler; 59.1225 + 59.1226 + /** 59.1227 + * Assign an event handler to receive an object's input events. 59.1228 + * 59.1229 + * @method setInputHandler 59.1230 + * @static 59.1231 + * 59.1232 + * @param {Object} object object to mix trigger, subscribe, and unsubscribe functions into 59.1233 + * @param {EventHandler} handler assigned event handler 59.1234 + */ 59.1235 + EventHandler.setInputHandler = function setInputHandler(object, handler) { 59.1236 + object.trigger = handler.trigger.bind(handler); 59.1237 + if (handler.subscribe && handler.unsubscribe) { 59.1238 + object.subscribe = handler.subscribe.bind(handler); 59.1239 + object.unsubscribe = handler.unsubscribe.bind(handler); 59.1240 + } 59.1241 + }; 59.1242 + 59.1243 + /** 59.1244 + * Assign an event handler to receive an object's output events. 59.1245 + * 59.1246 + * @method setOutputHandler 59.1247 + * @static 59.1248 + * 59.1249 + * @param {Object} object object to mix pipe, unpipe, on, addListener, and removeListener functions into 59.1250 + * @param {EventHandler} handler assigned event handler 59.1251 + */ 59.1252 + EventHandler.setOutputHandler = function setOutputHandler(object, handler) { 59.1253 + if (handler instanceof EventHandler) handler.bindThis(object); 59.1254 + object.pipe = handler.pipe.bind(handler); 59.1255 + object.unpipe = handler.unpipe.bind(handler); 59.1256 + object.on = handler.on.bind(handler); 59.1257 + object.addListener = object.on; 59.1258 + object.removeListener = handler.removeListener.bind(handler); 59.1259 + }; 59.1260 + 59.1261 + /** 59.1262 + * Trigger an event, sending to all downstream handlers 59.1263 + * listening for provided 'type' key. 59.1264 + * 59.1265 + * @method emit 59.1266 + * 59.1267 + * @param {string} type event type key (for example, 'click') 59.1268 + * @param {Object} event event data 59.1269 + * @return {EventHandler} this 59.1270 + */ 59.1271 + EventHandler.prototype.emit = function emit(type, event) { 59.1272 + EventEmitter.prototype.emit.apply(this, arguments); 59.1273 + var i = 0; 59.1274 + for (i = 0; i < this.downstream.length; i++) { 59.1275 + if (this.downstream[i].trigger) this.downstream[i].trigger(type, event); 59.1276 + } 59.1277 + for (i = 0; i < this.downstreamFn.length; i++) { 59.1278 + this.downstreamFn[i](type, event); 59.1279 + } 59.1280 + return this; 59.1281 + }; 59.1282 + 59.1283 + /** 59.1284 + * Alias for emit 59.1285 + * @method addListener 59.1286 + */ 59.1287 + EventHandler.prototype.trigger = EventHandler.prototype.emit; 59.1288 + 59.1289 + /** 59.1290 + * Add event handler object to set of downstream handlers. 59.1291 + * 59.1292 + * @method pipe 59.1293 + * 59.1294 + * @param {EventHandler} target event handler target object 59.1295 + * @return {EventHandler} passed event handler 59.1296 + */ 59.1297 + EventHandler.prototype.pipe = function pipe(target) { 59.1298 + if (target.subscribe instanceof Function) return target.subscribe(this); 59.1299 + 59.1300 + var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream; 59.1301 + var index = downstreamCtx.indexOf(target); 59.1302 + if (index < 0) downstreamCtx.push(target); 59.1303 + 59.1304 + if (target instanceof Function) target('pipe', null); 59.1305 + else if (target.trigger) target.trigger('pipe', null); 59.1306 + 59.1307 + return target; 59.1308 + }; 59.1309 + 59.1310 + /** 59.1311 + * Remove handler object from set of downstream handlers. 59.1312 + * Undoes work of "pipe". 59.1313 + * 59.1314 + * @method unpipe 59.1315 + * 59.1316 + * @param {EventHandler} target target handler object 59.1317 + * @return {EventHandler} provided target 59.1318 + */ 59.1319 + EventHandler.prototype.unpipe = function unpipe(target) { 59.1320 + if (target.unsubscribe instanceof Function) return target.unsubscribe(this); 59.1321 + 59.1322 + var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream; 59.1323 + var index = downstreamCtx.indexOf(target); 59.1324 + if (index >= 0) { 59.1325 + downstreamCtx.splice(index, 1); 59.1326 + if (target instanceof Function) target('unpipe', null); 59.1327 + else if (target.trigger) target.trigger('unpipe', null); 59.1328 + return target; 59.1329 + } 59.1330 + else return false; 59.1331 + }; 59.1332 + 59.1333 + /** 59.1334 + * Bind a callback function to an event type handled by this object. 59.1335 + * 59.1336 + * @method "on" 59.1337 + * 59.1338 + * @param {string} type event type key (for example, 'click') 59.1339 + * @param {function(string, Object)} handler callback 59.1340 + * @return {EventHandler} this 59.1341 + */ 59.1342 + EventHandler.prototype.on = function on(type, handler) { 59.1343 + EventEmitter.prototype.on.apply(this, arguments); 59.1344 + if (!(type in this.upstreamListeners)) { 59.1345 + var upstreamListener = this.trigger.bind(this, type); 59.1346 + this.upstreamListeners[type] = upstreamListener; 59.1347 + for (var i = 0; i < this.upstream.length; i++) { 59.1348 + this.upstream[i].on(type, upstreamListener); 59.1349 + } 59.1350 + } 59.1351 + return this; 59.1352 + }; 59.1353 + 59.1354 + /** 59.1355 + * Alias for "on" 59.1356 + * @method addListener 59.1357 + */ 59.1358 + EventHandler.prototype.addListener = EventHandler.prototype.on; 59.1359 + 59.1360 + /** 59.1361 + * Listen for events from an upstream event handler. 59.1362 + * 59.1363 + * @method subscribe 59.1364 + * 59.1365 + * @param {EventEmitter} source source emitter object 59.1366 + * @return {EventHandler} this 59.1367 + */ 59.1368 + EventHandler.prototype.subscribe = function subscribe(source) { 59.1369 + var index = this.upstream.indexOf(source); 59.1370 + if (index < 0) { 59.1371 + this.upstream.push(source); 59.1372 + for (var type in this.upstreamListeners) { 59.1373 + source.on(type, this.upstreamListeners[type]); 59.1374 + } 59.1375 + } 59.1376 + return this; 59.1377 + }; 59.1378 + 59.1379 + /** 59.1380 + * Stop listening to events from an upstream event handler. 59.1381 + * 59.1382 + * @method unsubscribe 59.1383 + * 59.1384 + * @param {EventEmitter} source source emitter object 59.1385 + * @return {EventHandler} this 59.1386 + */ 59.1387 + EventHandler.prototype.unsubscribe = function unsubscribe(source) { 59.1388 + var index = this.upstream.indexOf(source); 59.1389 + if (index >= 0) { 59.1390 + this.upstream.splice(index, 1); 59.1391 + for (var type in this.upstreamListeners) { 59.1392 + source.removeListener(type, this.upstreamListeners[type]); 59.1393 + } 59.1394 + } 59.1395 + return this; 59.1396 + }; 59.1397 + 59.1398 + module.exports = EventHandler; 59.1399 +}); 59.1400 + 59.1401 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1402 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1403 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1404 + * 59.1405 + * Owner: mark@famo.us 59.1406 + * @license MPL 2.0 59.1407 + * @copyright Famous Industries, Inc. 2014 59.1408 + */ 59.1409 + 59.1410 +define('famous/core/ElementAllocator',['require','exports','module'],function(require, exports, module) { 59.1411 + 59.1412 + /** 59.1413 + * Internal helper object to Context that handles the process of 59.1414 + * creating and allocating DOM elements within a managed div. 59.1415 + * Private. 59.1416 + * 59.1417 + * @class ElementAllocator 59.1418 + * @constructor 59.1419 + * @private 59.1420 + * @param {Node} container document element in which Famo.us content will be inserted 59.1421 + */ 59.1422 + function ElementAllocator(container) { 59.1423 + if (!container) container = document.createDocumentFragment(); 59.1424 + this.container = container; 59.1425 + this.detachedNodes = {}; 59.1426 + this.nodeCount = 0; 59.1427 + } 59.1428 + 59.1429 + /** 59.1430 + * Move the document elements from their original container to a new one. 59.1431 + * 59.1432 + * @private 59.1433 + * @method migrate 59.1434 + * 59.1435 + * @param {Node} container document element to which Famo.us content will be migrated 59.1436 + */ 59.1437 + ElementAllocator.prototype.migrate = function migrate(container) { 59.1438 + var oldContainer = this.container; 59.1439 + if (container === oldContainer) return; 59.1440 + 59.1441 + if (oldContainer instanceof DocumentFragment) { 59.1442 + container.appendChild(oldContainer); 59.1443 + } 59.1444 + else { 59.1445 + while (oldContainer.hasChildNodes()) { 59.1446 + container.appendChild(oldContainer.removeChild(oldContainer.firstChild)); 59.1447 + } 59.1448 + } 59.1449 + 59.1450 + this.container = container; 59.1451 + }; 59.1452 + 59.1453 + /** 59.1454 + * Allocate an element of specified type from the pool. 59.1455 + * 59.1456 + * @private 59.1457 + * @method allocate 59.1458 + * 59.1459 + * @param {string} type type of element, e.g. 'div' 59.1460 + * @return {Node} allocated document element 59.1461 + */ 59.1462 + ElementAllocator.prototype.allocate = function allocate(type) { 59.1463 + type = type.toLowerCase(); 59.1464 + if (!(type in this.detachedNodes)) this.detachedNodes[type] = []; 59.1465 + var nodeStore = this.detachedNodes[type]; 59.1466 + var result; 59.1467 + if (nodeStore.length > 0) { 59.1468 + result = nodeStore.pop(); 59.1469 + } 59.1470 + else { 59.1471 + result = document.createElement(type); 59.1472 + this.container.appendChild(result); 59.1473 + } 59.1474 + this.nodeCount++; 59.1475 + return result; 59.1476 + }; 59.1477 + 59.1478 + /** 59.1479 + * De-allocate an element of specified type to the pool. 59.1480 + * 59.1481 + * @private 59.1482 + * @method deallocate 59.1483 + * 59.1484 + * @param {Node} element document element to deallocate 59.1485 + */ 59.1486 + ElementAllocator.prototype.deallocate = function deallocate(element) { 59.1487 + var nodeType = element.nodeName.toLowerCase(); 59.1488 + var nodeStore = this.detachedNodes[nodeType]; 59.1489 + nodeStore.push(element); 59.1490 + this.nodeCount--; 59.1491 + }; 59.1492 + 59.1493 + /** 59.1494 + * Get count of total allocated nodes in the document. 59.1495 + * 59.1496 + * @private 59.1497 + * @method getNodeCount 59.1498 + * 59.1499 + * @return {Number} total node count 59.1500 + */ 59.1501 + ElementAllocator.prototype.getNodeCount = function getNodeCount() { 59.1502 + return this.nodeCount; 59.1503 + }; 59.1504 + 59.1505 + module.exports = ElementAllocator; 59.1506 +}); 59.1507 + 59.1508 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1509 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1510 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1511 + * 59.1512 + * Owner: mark@famo.us 59.1513 + * @license MPL 2.0 59.1514 + * @copyright Famous Industries, Inc. 2014 59.1515 + */ 59.1516 + 59.1517 +define('famous/utilities/Utility',['require','exports','module'],function(require, exports, module) { 59.1518 + /** 59.1519 + * This namespace holds standalone functionality. 59.1520 + * Currently includes name mapping for transition curves, 59.1521 + * name mapping for origin pairs, and the after() function. 59.1522 + * 59.1523 + * @class Utility 59.1524 + * @static 59.1525 + */ 59.1526 + var Utility = {}; 59.1527 + 59.1528 + /** 59.1529 + * Table of direction array positions 59.1530 + * 59.1531 + * @property {object} Direction 59.1532 + * @final 59.1533 + */ 59.1534 + Utility.Direction = { 59.1535 + X: 0, 59.1536 + Y: 1, 59.1537 + Z: 2 59.1538 + }; 59.1539 + 59.1540 + /** 59.1541 + * Return wrapper around callback function. Once the wrapper is called N 59.1542 + * times, invoke the callback function. Arguments and scope preserved. 59.1543 + * 59.1544 + * @method after 59.1545 + * 59.1546 + * @param {number} count number of calls before callback function invoked 59.1547 + * @param {Function} callback wrapped callback function 59.1548 + * 59.1549 + * @return {function} wrapped callback with coundown feature 59.1550 + */ 59.1551 + Utility.after = function after(count, callback) { 59.1552 + var counter = count; 59.1553 + return function() { 59.1554 + counter--; 59.1555 + if (counter === 0) callback.apply(this, arguments); 59.1556 + }; 59.1557 + }; 59.1558 + 59.1559 + /** 59.1560 + * Load a URL and return its contents in a callback 59.1561 + * 59.1562 + * @method loadURL 59.1563 + * 59.1564 + * @param {string} url URL of object 59.1565 + * @param {function} callback callback to dispatch with content 59.1566 + */ 59.1567 + Utility.loadURL = function loadURL(url, callback) { 59.1568 + var xhr = new XMLHttpRequest(); 59.1569 + xhr.onreadystatechange = function onreadystatechange() { 59.1570 + if (this.readyState === 4) { 59.1571 + if (callback) callback(this.responseText); 59.1572 + } 59.1573 + }; 59.1574 + xhr.open('GET', url); 59.1575 + xhr.send(); 59.1576 + }; 59.1577 + 59.1578 + /** 59.1579 + * Create a document fragment from a string of HTML 59.1580 + * 59.1581 + * @method createDocumentFragmentFromHTML 59.1582 + * 59.1583 + * @param {string} html HTML to convert to DocumentFragment 59.1584 + * 59.1585 + * @return {DocumentFragment} DocumentFragment representing input HTML 59.1586 + */ 59.1587 + Utility.createDocumentFragmentFromHTML = function createDocumentFragmentFromHTML(html) { 59.1588 + var element = document.createElement('div'); 59.1589 + element.innerHTML = html; 59.1590 + var result = document.createDocumentFragment(); 59.1591 + while (element.hasChildNodes()) result.appendChild(element.firstChild); 59.1592 + return result; 59.1593 + }; 59.1594 + 59.1595 + module.exports = Utility; 59.1596 +}); 59.1597 + 59.1598 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1599 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1600 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1601 + * 59.1602 + * Owner: david@famo.us 59.1603 + * @license MPL 2.0 59.1604 + * @copyright Famous Industries, Inc. 2014 59.1605 + */ 59.1606 + 59.1607 +define('famous/transitions/MultipleTransition',['require','exports','module','famous/utilities/Utility'],function(require, exports, module) { 59.1608 + var Utility = require('famous/utilities/Utility'); 59.1609 + 59.1610 + /** 59.1611 + * Transition meta-method to support transitioning multiple 59.1612 + * values with scalar-only methods. 59.1613 + * 59.1614 + * 59.1615 + * @class MultipleTransition 59.1616 + * @constructor 59.1617 + * 59.1618 + * @param {Object} method Transionable class to multiplex 59.1619 + */ 59.1620 + function MultipleTransition(method) { 59.1621 + this.method = method; 59.1622 + this._instances = []; 59.1623 + this.state = []; 59.1624 + } 59.1625 + 59.1626 + MultipleTransition.SUPPORTS_MULTIPLE = true; 59.1627 + 59.1628 + /** 59.1629 + * Get the state of each transition. 59.1630 + * 59.1631 + * @method get 59.1632 + * 59.1633 + * @return state {Number|Array} state array 59.1634 + */ 59.1635 + MultipleTransition.prototype.get = function get() { 59.1636 + for (var i = 0; i < this._instances.length; i++) { 59.1637 + this.state[i] = this._instances[i].get(); 59.1638 + } 59.1639 + return this.state; 59.1640 + }; 59.1641 + 59.1642 + /** 59.1643 + * Set the end states with a shared transition, with optional callback. 59.1644 + * 59.1645 + * @method set 59.1646 + * 59.1647 + * @param {Number|Array} endState Final State. Use a multi-element argument for multiple transitions. 59.1648 + * @param {Object} transition Transition definition, shared among all instances 59.1649 + * @param {Function} callback called when all endStates have been reached. 59.1650 + */ 59.1651 + MultipleTransition.prototype.set = function set(endState, transition, callback) { 59.1652 + var _allCallback = Utility.after(endState.length, callback); 59.1653 + for (var i = 0; i < endState.length; i++) { 59.1654 + if (!this._instances[i]) this._instances[i] = new (this.method)(); 59.1655 + this._instances[i].set(endState[i], transition, _allCallback); 59.1656 + } 59.1657 + }; 59.1658 + 59.1659 + /** 59.1660 + * Reset all transitions to start state. 59.1661 + * 59.1662 + * @method reset 59.1663 + * 59.1664 + * @param {Number|Array} startState Start state 59.1665 + */ 59.1666 + MultipleTransition.prototype.reset = function reset(startState) { 59.1667 + for (var i = 0; i < startState.length; i++) { 59.1668 + if (!this._instances[i]) this._instances[i] = new (this.method)(); 59.1669 + this._instances[i].reset(startState[i]); 59.1670 + } 59.1671 + }; 59.1672 + 59.1673 + module.exports = MultipleTransition; 59.1674 +}); 59.1675 + 59.1676 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.1677 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.1678 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.1679 + * 59.1680 + * Owner: david@famo.us 59.1681 + * @license MPL 2.0 59.1682 + * @copyright Famous Industries, Inc. 2014 59.1683 + */ 59.1684 + 59.1685 +define('famous/transitions/TweenTransition',['require','exports','module'],function(require, exports, module) { 59.1686 + 59.1687 + /** 59.1688 + * 59.1689 + * A state maintainer for a smooth transition between 59.1690 + * numerically-specified states. Example numeric states include floats or 59.1691 + * Transfornm objects. 59.1692 + * 59.1693 + * An initial state is set with the constructor or set(startValue). A 59.1694 + * corresponding end state and transition are set with set(endValue, 59.1695 + * transition). Subsequent calls to set(endValue, transition) begin at 59.1696 + * the last state. Calls to get(timestamp) provide the _interpolated state 59.1697 + * along the way. 59.1698 + * 59.1699 + * Note that there is no event loop here - calls to get() are the only way 59.1700 + * to find out state projected to the current (or provided) time and are 59.1701 + * the only way to trigger callbacks. Usually this kind of object would 59.1702 + * be part of the render() path of a visible component. 59.1703 + * 59.1704 + * @class TweenTransition 59.1705 + * @constructor 59.1706 + * 59.1707 + * @param {Object} options TODO 59.1708 + * beginning state 59.1709 + */ 59.1710 + function TweenTransition(options) { 59.1711 + this.options = Object.create(TweenTransition.DEFAULT_OPTIONS); 59.1712 + if (options) this.setOptions(options); 59.1713 + 59.1714 + this._startTime = 0; 59.1715 + this._startValue = 0; 59.1716 + this._updateTime = 0; 59.1717 + this._endValue = 0; 59.1718 + this._curve = undefined; 59.1719 + this._duration = 0; 59.1720 + this._active = false; 59.1721 + this._callback = undefined; 59.1722 + this.state = 0; 59.1723 + this.velocity = undefined; 59.1724 + } 59.1725 + 59.1726 + /** 59.1727 + * Transition curves mapping independent variable t from domain [0,1] to a 59.1728 + * range within [0,1]. Includes functions 'linear', 'easeIn', 'easeOut', 59.1729 + * 'easeInOut', 'easeOutBounce', 'spring'. 59.1730 + * 59.1731 + * @property {object} Curve 59.1732 + * @final 59.1733 + */ 59.1734 + TweenTransition.Curves = { 59.1735 + linear: function(t) { 59.1736 + return t; 59.1737 + }, 59.1738 + easeIn: function(t) { 59.1739 + return t*t; 59.1740 + }, 59.1741 + easeOut: function(t) { 59.1742 + return t*(2-t); 59.1743 + }, 59.1744 + easeInOut: function(t) { 59.1745 + if (t <= 0.5) return 2*t*t; 59.1746 + else return -2*t*t + 4*t - 1; 59.1747 + }, 59.1748 + easeOutBounce: function(t) { 59.1749 + return t*(3 - 2*t); 59.1750 + }, 59.1751 + spring: function(t) { 59.1752 + return (1 - t) * Math.sin(6 * Math.PI * t) + t; 59.1753 + } 59.1754 + }; 59.1755 + 59.1756 + TweenTransition.SUPPORTS_MULTIPLE = true; 59.1757 + TweenTransition.DEFAULT_OPTIONS = { 59.1758 + curve: TweenTransition.Curves.linear, 59.1759 + duration: 500, 59.1760 + speed: 0 /* considered only if positive */ 59.1761 + }; 59.1762 + 59.1763 + var registeredCurves = {}; 59.1764 + 59.1765 + /** 59.1766 + * Add "unit" curve to internal dictionary of registered curves. 59.1767 + * 59.1768 + * @method registerCurve 59.1769 + * 59.1770 + * @static 59.1771 + * 59.1772 + * @param {string} curveName dictionary key 59.1773 + * @param {unitCurve} curve function of one numeric variable mapping [0,1] 59.1774 + * to range inside [0,1] 59.1775 + * @return {boolean} false if key is taken, else true 59.1776 + */ 59.1777 + TweenTransition.registerCurve = function registerCurve(curveName, curve) { 59.1778 + if (!registeredCurves[curveName]) { 59.1779 + registeredCurves[curveName] = curve; 59.1780 + return true; 59.1781 + } 59.1782 + else { 59.1783 + return false; 59.1784 + } 59.1785 + }; 59.1786 + 59.1787 + /** 59.1788 + * Remove object with key "curveName" from internal dictionary of registered 59.1789 + * curves. 59.1790 + * 59.1791 + * @method unregisterCurve 59.1792 + * 59.1793 + * @static 59.1794 + * 59.1795 + * @param {string} curveName dictionary key 59.1796 + * @return {boolean} false if key has no dictionary value 59.1797 + */ 59.1798 + TweenTransition.unregisterCurve = function unregisterCurve(curveName) { 59.1799 + if (registeredCurves[curveName]) { 59.1800 + delete registeredCurves[curveName]; 59.1801 + return true; 59.1802 + } 59.1803 + else { 59.1804 + return false; 59.1805 + } 59.1806 + }; 59.1807 + 59.1808 + /** 59.1809 + * Retrieve function with key "curveName" from internal dictionary of 59.1810 + * registered curves. Default curves are defined in the 59.1811 + * TweenTransition.Curves array, where the values represent 59.1812 + * unitCurve functions. 59.1813 + * 59.1814 + * @method getCurve 59.1815 + * 59.1816 + * @static 59.1817 + * 59.1818 + * @param {string} curveName dictionary key 59.1819 + * @return {unitCurve} curve function of one numeric variable mapping [0,1] 59.1820 + * to range inside [0,1] 59.1821 + */ 59.1822 + TweenTransition.getCurve = function getCurve(curveName) { 59.1823 + var curve = registeredCurves[curveName]; 59.1824 + if (curve !== undefined) return curve; 59.1825 + else throw new Error('curve not registered'); 59.1826 + }; 59.1827 + 59.1828 + /** 59.1829 + * Retrieve all available curves. 59.1830 + * 59.1831 + * @method getCurves 59.1832 + * 59.1833 + * @static 59.1834 + * 59.1835 + * @return {object} curve functions of one numeric variable mapping [0,1] 59.1836 + * to range inside [0,1] 59.1837 + */ 59.1838 + TweenTransition.getCurves = function getCurves() { 59.1839 + return registeredCurves; 59.1840 + }; 59.1841 + 59.1842 + // Interpolate: If a linear function f(0) = a, f(1) = b, then return f(t) 59.1843 + function _interpolate(a, b, t) { 59.1844 + return ((1 - t) * a) + (t * b); 59.1845 + } 59.1846 + 59.1847 + function _clone(obj) { 59.1848 + if (obj instanceof Object) { 59.1849 + if (obj instanceof Array) return obj.slice(0); 59.1850 + else return Object.create(obj); 59.1851 + } 59.1852 + else return obj; 59.1853 + } 59.1854 + 59.1855 + // Fill in missing properties in "transition" with those in defaultTransition, and 59.1856 + // convert internal named curve to function object, returning as new 59.1857 + // object. 59.1858 + function _normalize(transition, defaultTransition) { 59.1859 + var result = {curve: defaultTransition.curve}; 59.1860 + if (defaultTransition.duration) result.duration = defaultTransition.duration; 59.1861 + if (defaultTransition.speed) result.speed = defaultTransition.speed; 59.1862 + if (transition instanceof Object) { 59.1863 + if (transition.duration !== undefined) result.duration = transition.duration; 59.1864 + if (transition.curve) result.curve = transition.curve; 59.1865 + if (transition.speed) result.speed = transition.speed; 59.1866 + } 59.1867 + if (typeof result.curve === 'string') result.curve = TweenTransition.getCurve(result.curve); 59.1868 + return result; 59.1869 + } 59.1870 + 59.1871 + /** 59.1872 + * Set internal options, overriding any default options. 59.1873 + * 59.1874 + * @method setOptions 59.1875 + * 59.1876 + * 59.1877 + * @param {Object} options options object 59.1878 + * @param {Object} [options.curve] function mapping [0,1] to [0,1] or identifier 59.1879 + * @param {Number} [options.duration] duration in ms 59.1880 + * @param {Number} [options.speed] speed in pixels per ms 59.1881 + */ 59.1882 + TweenTransition.prototype.setOptions = function setOptions(options) { 59.1883 + if (options.curve !== undefined) this.options.curve = options.curve; 59.1884 + if (options.duration !== undefined) this.options.duration = options.duration; 59.1885 + if (options.speed !== undefined) this.options.speed = options.speed; 59.1886 + }; 59.1887 + 59.1888 + /** 59.1889 + * Add transition to end state to the queue of pending transitions. Special 59.1890 + * Use: calling without a transition resets the object to that state with 59.1891 + * no pending actions 59.1892 + * 59.1893 + * @method set 59.1894 + * 59.1895 + * 59.1896 + * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endValue 59.1897 + * end state to which we _interpolate 59.1898 + * @param {transition=} transition object of type {duration: number, curve: 59.1899 + * f[0,1] -> [0,1] or name}. If transition is omitted, change will be 59.1900 + * instantaneous. 59.1901 + * @param {function()=} callback Zero-argument function to call on observed 59.1902 + * completion (t=1) 59.1903 + */ 59.1904 + TweenTransition.prototype.set = function set(endValue, transition, callback) { 59.1905 + if (!transition) { 59.1906 + this.reset(endValue); 59.1907 + if (callback) callback(); 59.1908 + return; 59.1909 + } 59.1910 + 59.1911 + this._startValue = _clone(this.get()); 59.1912 + transition = _normalize(transition, this.options); 59.1913 + if (transition.speed) { 59.1914 + var startValue = this._startValue; 59.1915 + if (startValue instanceof Object) { 59.1916 + var variance = 0; 59.1917 + for (var i in startValue) variance += (endValue[i] - startValue[i]) * (endValue[i] - startValue[i]); 59.1918 + transition.duration = Math.sqrt(variance) / transition.speed; 59.1919 + } 59.1920 + else { 59.1921 + transition.duration = Math.abs(endValue - startValue) / transition.speed; 59.1922 + } 59.1923 + } 59.1924 + 59.1925 + this._startTime = Date.now(); 59.1926 + this._endValue = _clone(endValue); 59.1927 + this._startVelocity = _clone(transition.velocity); 59.1928 + this._duration = transition.duration; 59.1929 + this._curve = transition.curve; 59.1930 + this._active = true; 59.1931 + this._callback = callback; 59.1932 + }; 59.1933 + 59.1934 + /** 59.1935 + * Cancel all transitions and reset to a stable state 59.1936 + * 59.1937 + * @method reset 59.1938 + * 59.1939 + * @param {number|Array.Number|Object.<number, number>} startValue 59.1940 + * starting state 59.1941 + * @param {number} startVelocity 59.1942 + * starting velocity 59.1943 + */ 59.1944 + TweenTransition.prototype.reset = function reset(startValue, startVelocity) { 59.1945 + if (this._callback) { 59.1946 + var callback = this._callback; 59.1947 + this._callback = undefined; 59.1948 + callback(); 59.1949 + } 59.1950 + this.state = _clone(startValue); 59.1951 + this.velocity = _clone(startVelocity); 59.1952 + this._startTime = 0; 59.1953 + this._duration = 0; 59.1954 + this._updateTime = 0; 59.1955 + this._startValue = this.state; 59.1956 + this._startVelocity = this.velocity; 59.1957 + this._endValue = this.state; 59.1958 + this._active = false; 59.1959 + }; 59.1960 + 59.1961 + /** 59.1962 + * Get current velocity 59.1963 + * 59.1964 + * @method getVelocity 59.1965 + * 59.1966 + * @returns {Number} velocity 59.1967 + */ 59.1968 + TweenTransition.prototype.getVelocity = function getVelocity() { 59.1969 + return this.velocity; 59.1970 + }; 59.1971 + 59.1972 + /** 59.1973 + * Get interpolated state of current action at provided time. If the last 59.1974 + * action has completed, invoke its callback. 59.1975 + * 59.1976 + * @method get 59.1977 + * 59.1978 + * 59.1979 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 59.1980 + * time. If omitted, use current time. (Unix epoch time) 59.1981 + * @return {number|Object.<number|string, number>} beginning state 59.1982 + * _interpolated to this point in time. 59.1983 + */ 59.1984 + TweenTransition.prototype.get = function get(timestamp) { 59.1985 + this.update(timestamp); 59.1986 + return this.state; 59.1987 + }; 59.1988 + 59.1989 + function _calculateVelocity(current, start, curve, duration, t) { 59.1990 + var velocity; 59.1991 + var eps = 1e-7; 59.1992 + var speed = (curve(t) - curve(t - eps)) / eps; 59.1993 + if (current instanceof Array) { 59.1994 + velocity = []; 59.1995 + for (var i = 0; i < current.length; i++){ 59.1996 + if (typeof current[i] === 'number') 59.1997 + velocity[i] = speed * (current[i] - start[i]) / duration; 59.1998 + else 59.1999 + velocity[i] = 0; 59.2000 + } 59.2001 + 59.2002 + } 59.2003 + else velocity = speed * (current - start) / duration; 59.2004 + return velocity; 59.2005 + } 59.2006 + 59.2007 + function _calculateState(start, end, t) { 59.2008 + var state; 59.2009 + if (start instanceof Array) { 59.2010 + state = []; 59.2011 + for (var i = 0; i < start.length; i++) { 59.2012 + if (typeof start[i] === 'number') 59.2013 + state[i] = _interpolate(start[i], end[i], t); 59.2014 + else 59.2015 + state[i] = start[i]; 59.2016 + } 59.2017 + } 59.2018 + else state = _interpolate(start, end, t); 59.2019 + return state; 59.2020 + } 59.2021 + 59.2022 + /** 59.2023 + * Update internal state to the provided timestamp. This may invoke the last 59.2024 + * callback and begin a new action. 59.2025 + * 59.2026 + * @method update 59.2027 + * 59.2028 + * 59.2029 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 59.2030 + * time. If omitted, use current time. (Unix epoch time) 59.2031 + */ 59.2032 + TweenTransition.prototype.update = function update(timestamp) { 59.2033 + if (!this._active) { 59.2034 + if (this._callback) { 59.2035 + var callback = this._callback; 59.2036 + this._callback = undefined; 59.2037 + callback(); 59.2038 + } 59.2039 + return; 59.2040 + } 59.2041 + 59.2042 + if (!timestamp) timestamp = Date.now(); 59.2043 + if (this._updateTime >= timestamp) return; 59.2044 + this._updateTime = timestamp; 59.2045 + 59.2046 + var timeSinceStart = timestamp - this._startTime; 59.2047 + if (timeSinceStart >= this._duration) { 59.2048 + this.state = this._endValue; 59.2049 + this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, 1); 59.2050 + this._active = false; 59.2051 + } 59.2052 + else if (timeSinceStart < 0) { 59.2053 + this.state = this._startValue; 59.2054 + this.velocity = this._startVelocity; 59.2055 + } 59.2056 + else { 59.2057 + var t = timeSinceStart / this._duration; 59.2058 + this.state = _calculateState(this._startValue, this._endValue, this._curve(t)); 59.2059 + this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, t); 59.2060 + } 59.2061 + }; 59.2062 + 59.2063 + /** 59.2064 + * Is there at least one action pending completion? 59.2065 + * 59.2066 + * @method isActive 59.2067 + * 59.2068 + * 59.2069 + * @return {boolean} 59.2070 + */ 59.2071 + TweenTransition.prototype.isActive = function isActive() { 59.2072 + return this._active; 59.2073 + }; 59.2074 + 59.2075 + /** 59.2076 + * Halt transition at current state and erase all pending actions. 59.2077 + * 59.2078 + * @method halt 59.2079 + * 59.2080 + */ 59.2081 + TweenTransition.prototype.halt = function halt() { 59.2082 + this.reset(this.get()); 59.2083 + }; 59.2084 + 59.2085 + // Register all the default curves 59.2086 + TweenTransition.registerCurve('linear', TweenTransition.Curves.linear); 59.2087 + TweenTransition.registerCurve('easeIn', TweenTransition.Curves.easeIn); 59.2088 + TweenTransition.registerCurve('easeOut', TweenTransition.Curves.easeOut); 59.2089 + TweenTransition.registerCurve('easeInOut', TweenTransition.Curves.easeInOut); 59.2090 + TweenTransition.registerCurve('easeOutBounce', TweenTransition.Curves.easeOutBounce); 59.2091 + TweenTransition.registerCurve('spring', TweenTransition.Curves.spring); 59.2092 + 59.2093 + TweenTransition.customCurve = function customCurve(v1, v2) { 59.2094 + v1 = v1 || 0; v2 = v2 || 0; 59.2095 + return function(t) { 59.2096 + return v1*t + (-2*v1 - v2 + 3)*t*t + (v1 + v2 - 2)*t*t*t; 59.2097 + }; 59.2098 + }; 59.2099 + 59.2100 + module.exports = TweenTransition; 59.2101 +}); 59.2102 + 59.2103 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.2104 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.2105 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.2106 + * 59.2107 + * Owner: david@famo.us 59.2108 + * @license MPL 2.0 59.2109 + * @copyright Famous Industries, Inc. 2014 59.2110 + */ 59.2111 + 59.2112 +define('famous/transitions/Transitionable',['require','exports','module','./MultipleTransition','./TweenTransition'],function(require, exports, module) { 59.2113 + var MultipleTransition = require('./MultipleTransition'); 59.2114 + var TweenTransition = require('./TweenTransition'); 59.2115 + 59.2116 + /** 59.2117 + * A state maintainer for a smooth transition between 59.2118 + * numerically-specified states. Example numeric states include floats or 59.2119 + * Transform objects. 59.2120 + * 59.2121 + * An initial state is set with the constructor or set(startState). A 59.2122 + * corresponding end state and transition are set with set(endState, 59.2123 + * transition). Subsequent calls to set(endState, transition) begin at 59.2124 + * the last state. Calls to get(timestamp) provide the interpolated state 59.2125 + * along the way. 59.2126 + * 59.2127 + * Note that there is no event loop here - calls to get() are the only way 59.2128 + * to find state projected to the current (or provided) time and are 59.2129 + * the only way to trigger callbacks. Usually this kind of object would 59.2130 + * be part of the render() path of a visible component. 59.2131 + * 59.2132 + * @class Transitionable 59.2133 + * @constructor 59.2134 + * @param {number|Array.Number|Object.<number|string, number>} start 59.2135 + * beginning state 59.2136 + */ 59.2137 + function Transitionable(start) { 59.2138 + this.currentAction = null; 59.2139 + this.actionQueue = []; 59.2140 + this.callbackQueue = []; 59.2141 + 59.2142 + this.state = 0; 59.2143 + this.velocity = undefined; 59.2144 + this._callback = undefined; 59.2145 + this._engineInstance = null; 59.2146 + this._currentMethod = null; 59.2147 + 59.2148 + this.set(start); 59.2149 + } 59.2150 + 59.2151 + var transitionMethods = {}; 59.2152 + 59.2153 + Transitionable.registerMethod = function registerMethod(name, engineClass) { 59.2154 + if (!(name in transitionMethods)) { 59.2155 + transitionMethods[name] = engineClass; 59.2156 + return true; 59.2157 + } 59.2158 + else return false; 59.2159 + }; 59.2160 + 59.2161 + Transitionable.unregisterMethod = function unregisterMethod(name) { 59.2162 + if (name in transitionMethods) { 59.2163 + delete transitionMethods[name]; 59.2164 + return true; 59.2165 + } 59.2166 + else return false; 59.2167 + }; 59.2168 + 59.2169 + function _loadNext() { 59.2170 + if (this._callback) { 59.2171 + var callback = this._callback; 59.2172 + this._callback = undefined; 59.2173 + callback(); 59.2174 + } 59.2175 + if (this.actionQueue.length <= 0) { 59.2176 + this.set(this.get()); // no update required 59.2177 + return; 59.2178 + } 59.2179 + this.currentAction = this.actionQueue.shift(); 59.2180 + this._callback = this.callbackQueue.shift(); 59.2181 + 59.2182 + var method = null; 59.2183 + var endValue = this.currentAction[0]; 59.2184 + var transition = this.currentAction[1]; 59.2185 + if (transition instanceof Object && transition.method) { 59.2186 + method = transition.method; 59.2187 + if (typeof method === 'string') method = transitionMethods[method]; 59.2188 + } 59.2189 + else { 59.2190 + method = TweenTransition; 59.2191 + } 59.2192 + 59.2193 + if (this._currentMethod !== method) { 59.2194 + if (!(endValue instanceof Object) || method.SUPPORTS_MULTIPLE === true || endValue.length <= method.SUPPORTS_MULTIPLE) { 59.2195 + this._engineInstance = new method(); 59.2196 + } 59.2197 + else { 59.2198 + this._engineInstance = new MultipleTransition(method); 59.2199 + } 59.2200 + this._currentMethod = method; 59.2201 + } 59.2202 + 59.2203 + this._engineInstance.reset(this.state, this.velocity); 59.2204 + if (this.velocity !== undefined) transition.velocity = this.velocity; 59.2205 + this._engineInstance.set(endValue, transition, _loadNext.bind(this)); 59.2206 + } 59.2207 + 59.2208 + /** 59.2209 + * Add transition to end state to the queue of pending transitions. Special 59.2210 + * Use: calling without a transition resets the object to that state with 59.2211 + * no pending actions 59.2212 + * 59.2213 + * @method set 59.2214 + * 59.2215 + * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endState 59.2216 + * end state to which we interpolate 59.2217 + * @param {transition=} transition object of type {duration: number, curve: 59.2218 + * f[0,1] -> [0,1] or name}. If transition is omitted, change will be 59.2219 + * instantaneous. 59.2220 + * @param {function()=} callback Zero-argument function to call on observed 59.2221 + * completion (t=1) 59.2222 + */ 59.2223 + Transitionable.prototype.set = function set(endState, transition, callback) { 59.2224 + if (!transition) { 59.2225 + this.reset(endState); 59.2226 + if (callback) callback(); 59.2227 + return this; 59.2228 + } 59.2229 + 59.2230 + var action = [endState, transition]; 59.2231 + this.actionQueue.push(action); 59.2232 + this.callbackQueue.push(callback); 59.2233 + if (!this.currentAction) _loadNext.call(this); 59.2234 + return this; 59.2235 + }; 59.2236 + 59.2237 + /** 59.2238 + * Cancel all transitions and reset to a stable state 59.2239 + * 59.2240 + * @method reset 59.2241 + * 59.2242 + * @param {number|Array.Number|Object.<number, number>} startState 59.2243 + * stable state to set to 59.2244 + */ 59.2245 + Transitionable.prototype.reset = function reset(startState, startVelocity) { 59.2246 + this._currentMethod = null; 59.2247 + this._engineInstance = null; 59.2248 + this._callback = undefined; 59.2249 + this.state = startState; 59.2250 + this.velocity = startVelocity; 59.2251 + this.currentAction = null; 59.2252 + this.actionQueue = []; 59.2253 + this.callbackQueue = []; 59.2254 + }; 59.2255 + 59.2256 + /** 59.2257 + * Add delay action to the pending action queue queue. 59.2258 + * 59.2259 + * @method delay 59.2260 + * 59.2261 + * @param {number} duration delay time (ms) 59.2262 + * @param {function} callback Zero-argument function to call on observed 59.2263 + * completion (t=1) 59.2264 + */ 59.2265 + Transitionable.prototype.delay = function delay(duration, callback) { 59.2266 + this.set(this.get(), {duration: duration, 59.2267 + curve: function() { 59.2268 + return 0; 59.2269 + }}, 59.2270 + callback 59.2271 + ); 59.2272 + }; 59.2273 + 59.2274 + /** 59.2275 + * Get interpolated state of current action at provided time. If the last 59.2276 + * action has completed, invoke its callback. 59.2277 + * 59.2278 + * @method get 59.2279 + * 59.2280 + * @param {number=} timestamp Evaluate the curve at a normalized version of this 59.2281 + * time. If omitted, use current time. (Unix epoch time) 59.2282 + * @return {number|Object.<number|string, number>} beginning state 59.2283 + * interpolated to this point in time. 59.2284 + */ 59.2285 + Transitionable.prototype.get = function get(timestamp) { 59.2286 + if (this._engineInstance) { 59.2287 + if (this._engineInstance.getVelocity) 59.2288 + this.velocity = this._engineInstance.getVelocity(); 59.2289 + this.state = this._engineInstance.get(timestamp); 59.2290 + } 59.2291 + return this.state; 59.2292 + }; 59.2293 + 59.2294 + /** 59.2295 + * Is there at least one action pending completion? 59.2296 + * 59.2297 + * @method isActive 59.2298 + * 59.2299 + * @return {boolean} 59.2300 + */ 59.2301 + Transitionable.prototype.isActive = function isActive() { 59.2302 + return !!this.currentAction; 59.2303 + }; 59.2304 + 59.2305 + /** 59.2306 + * Halt transition at current state and erase all pending actions. 59.2307 + * 59.2308 + * @method halt 59.2309 + */ 59.2310 + Transitionable.prototype.halt = function halt() { 59.2311 + this.set(this.get()); 59.2312 + }; 59.2313 + 59.2314 + module.exports = Transitionable; 59.2315 +}); 59.2316 + 59.2317 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.2318 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.2319 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.2320 + * 59.2321 + * Owner: mark@famo.us 59.2322 + * @license MPL 2.0 59.2323 + * @copyright Famous Industries, Inc. 2014 59.2324 + */ 59.2325 + 59.2326 +define('famous/core/Context',['require','exports','module','./RenderNode','./EventHandler','./ElementAllocator','./Transform','famous/transitions/Transitionable'],function(require, exports, module) { 59.2327 + var RenderNode = require('./RenderNode'); 59.2328 + var EventHandler = require('./EventHandler'); 59.2329 + var ElementAllocator = require('./ElementAllocator'); 59.2330 + var Transform = require('./Transform'); 59.2331 + var Transitionable = require('famous/transitions/Transitionable'); 59.2332 + 59.2333 + var _originZeroZero = [0, 0]; 59.2334 + 59.2335 + function _getElementSize(element) { 59.2336 + return [element.clientWidth, element.clientHeight]; 59.2337 + } 59.2338 + 59.2339 + /** 59.2340 + * The top-level container for a Famous-renderable piece of the document. 59.2341 + * It is directly updated by the process-wide Engine object, and manages one 59.2342 + * render tree root, which can contain other renderables. 59.2343 + * 59.2344 + * @class Context 59.2345 + * @constructor 59.2346 + * @private 59.2347 + * @param {Node} container Element in which content will be inserted 59.2348 + */ 59.2349 + function Context(container) { 59.2350 + this.container = container; 59.2351 + this._allocator = new ElementAllocator(container); 59.2352 + 59.2353 + this._node = new RenderNode(); 59.2354 + this._eventOutput = new EventHandler(); 59.2355 + this._size = _getElementSize(this.container); 59.2356 + 59.2357 + this._perspectiveState = new Transitionable(0); 59.2358 + this._perspective = undefined; 59.2359 + 59.2360 + this._nodeContext = { 59.2361 + allocator: this._allocator, 59.2362 + transform: Transform.identity, 59.2363 + opacity: 1, 59.2364 + origin: _originZeroZero, 59.2365 + align: null, 59.2366 + size: this._size 59.2367 + }; 59.2368 + 59.2369 + this._eventOutput.on('resize', function() { 59.2370 + this.setSize(_getElementSize(this.container)); 59.2371 + }.bind(this)); 59.2372 + 59.2373 + } 59.2374 + 59.2375 + // Note: Unused 59.2376 + Context.prototype.getAllocator = function getAllocator() { 59.2377 + return this._allocator; 59.2378 + }; 59.2379 + 59.2380 + /** 59.2381 + * Add renderables to this Context's render tree. 59.2382 + * 59.2383 + * @method add 59.2384 + * 59.2385 + * @param {Object} obj renderable object 59.2386 + * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode 59.2387 + */ 59.2388 + Context.prototype.add = function add(obj) { 59.2389 + return this._node.add(obj); 59.2390 + }; 59.2391 + 59.2392 + /** 59.2393 + * Move this Context to another containing document element. 59.2394 + * 59.2395 + * @method migrate 59.2396 + * 59.2397 + * @param {Node} container Element to which content will be migrated 59.2398 + */ 59.2399 + Context.prototype.migrate = function migrate(container) { 59.2400 + if (container === this.container) return; 59.2401 + this.container = container; 59.2402 + this._allocator.migrate(container); 59.2403 + }; 59.2404 + 59.2405 + /** 59.2406 + * Gets viewport size for Context. 59.2407 + * 59.2408 + * @method getSize 59.2409 + * 59.2410 + * @return {Array.Number} viewport size as [width, height] 59.2411 + */ 59.2412 + Context.prototype.getSize = function getSize() { 59.2413 + return this._size; 59.2414 + }; 59.2415 + 59.2416 + /** 59.2417 + * Sets viewport size for Context. 59.2418 + * 59.2419 + * @method setSize 59.2420 + * 59.2421 + * @param {Array.Number} size [width, height]. If unspecified, use size of root document element. 59.2422 + */ 59.2423 + Context.prototype.setSize = function setSize(size) { 59.2424 + if (!size) size = _getElementSize(this.container); 59.2425 + this._size[0] = size[0]; 59.2426 + this._size[1] = size[1]; 59.2427 + }; 59.2428 + 59.2429 + /** 59.2430 + * Commit this Context's content changes to the document. 59.2431 + * 59.2432 + * @private 59.2433 + * @method update 59.2434 + * @param {Object} contextParameters engine commit specification 59.2435 + */ 59.2436 + Context.prototype.update = function update(contextParameters) { 59.2437 + if (contextParameters) { 59.2438 + if (contextParameters.transform) this._nodeContext.transform = contextParameters.transform; 59.2439 + if (contextParameters.opacity) this._nodeContext.opacity = contextParameters.opacity; 59.2440 + if (contextParameters.origin) this._nodeContext.origin = contextParameters.origin; 59.2441 + if (contextParameters.align) this._nodeContext.align = contextParameters.align; 59.2442 + if (contextParameters.size) this._nodeContext.size = contextParameters.size; 59.2443 + } 59.2444 + var perspective = this._perspectiveState.get(); 59.2445 + if (perspective !== this._perspective) { 59.2446 + this.container.style.perspective = perspective ? perspective.toFixed() + 'px' : ''; 59.2447 + this.container.style.webkitPerspective = perspective ? perspective.toFixed() : ''; 59.2448 + this._perspective = perspective; 59.2449 + } 59.2450 + 59.2451 + this._node.commit(this._nodeContext); 59.2452 + }; 59.2453 + 59.2454 + /** 59.2455 + * Get current perspective of this context in pixels. 59.2456 + * 59.2457 + * @method getPerspective 59.2458 + * @return {Number} depth perspective in pixels 59.2459 + */ 59.2460 + Context.prototype.getPerspective = function getPerspective() { 59.2461 + return this._perspectiveState.get(); 59.2462 + }; 59.2463 + 59.2464 + /** 59.2465 + * Set current perspective of this context in pixels. 59.2466 + * 59.2467 + * @method setPerspective 59.2468 + * @param {Number} perspective in pixels 59.2469 + * @param {Object} [transition] Transitionable object for applying the change 59.2470 + * @param {function(Object)} callback function called on completion of transition 59.2471 + */ 59.2472 + Context.prototype.setPerspective = function setPerspective(perspective, transition, callback) { 59.2473 + return this._perspectiveState.set(perspective, transition, callback); 59.2474 + }; 59.2475 + 59.2476 + /** 59.2477 + * Trigger an event, sending to all downstream handlers 59.2478 + * listening for provided 'type' key. 59.2479 + * 59.2480 + * @method emit 59.2481 + * 59.2482 + * @param {string} type event type key (for example, 'click') 59.2483 + * @param {Object} event event data 59.2484 + * @return {EventHandler} this 59.2485 + */ 59.2486 + Context.prototype.emit = function emit(type, event) { 59.2487 + return this._eventOutput.emit(type, event); 59.2488 + }; 59.2489 + 59.2490 + /** 59.2491 + * Bind a callback function to an event type handled by this object. 59.2492 + * 59.2493 + * @method "on" 59.2494 + * 59.2495 + * @param {string} type event type key (for example, 'click') 59.2496 + * @param {function(string, Object)} handler callback 59.2497 + * @return {EventHandler} this 59.2498 + */ 59.2499 + Context.prototype.on = function on(type, handler) { 59.2500 + return this._eventOutput.on(type, handler); 59.2501 + }; 59.2502 + 59.2503 + /** 59.2504 + * Unbind an event by type and handler. 59.2505 + * This undoes the work of "on". 59.2506 + * 59.2507 + * @method removeListener 59.2508 + * 59.2509 + * @param {string} type event type key (for example, 'click') 59.2510 + * @param {function} handler function object to remove 59.2511 + * @return {EventHandler} internal event handler object (for chaining) 59.2512 + */ 59.2513 + Context.prototype.removeListener = function removeListener(type, handler) { 59.2514 + return this._eventOutput.removeListener(type, handler); 59.2515 + }; 59.2516 + 59.2517 + /** 59.2518 + * Add event handler object to set of downstream handlers. 59.2519 + * 59.2520 + * @method pipe 59.2521 + * 59.2522 + * @param {EventHandler} target event handler target object 59.2523 + * @return {EventHandler} passed event handler 59.2524 + */ 59.2525 + Context.prototype.pipe = function pipe(target) { 59.2526 + return this._eventOutput.pipe(target); 59.2527 + }; 59.2528 + 59.2529 + /** 59.2530 + * Remove handler object from set of downstream handlers. 59.2531 + * Undoes work of "pipe". 59.2532 + * 59.2533 + * @method unpipe 59.2534 + * 59.2535 + * @param {EventHandler} target target handler object 59.2536 + * @return {EventHandler} provided target 59.2537 + */ 59.2538 + Context.prototype.unpipe = function unpipe(target) { 59.2539 + return this._eventOutput.unpipe(target); 59.2540 + }; 59.2541 + 59.2542 + module.exports = Context; 59.2543 +}); 59.2544 + 59.2545 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.2546 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.2547 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.2548 + * 59.2549 + * Owner: mark@famo.us 59.2550 + * @license MPL 2.0 59.2551 + * @copyright Famous Industries, Inc. 2014 59.2552 + */ 59.2553 + 59.2554 +define('famous/core/OptionsManager',['require','exports','module','./EventHandler'],function(require, exports, module) { 59.2555 + var EventHandler = require('./EventHandler'); 59.2556 + 59.2557 + /** 59.2558 + * A collection of methods for setting options which can be extended 59.2559 + * onto other classes. 59.2560 + * 59.2561 + * 59.2562 + * **** WARNING **** 59.2563 + * You can only pass through objects that will compile into valid JSON. 59.2564 + * 59.2565 + * Valid options: 59.2566 + * Strings, 59.2567 + * Arrays, 59.2568 + * Objects, 59.2569 + * Numbers, 59.2570 + * Nested Objects, 59.2571 + * Nested Arrays. 59.2572 + * 59.2573 + * This excludes: 59.2574 + * Document Fragments, 59.2575 + * Functions 59.2576 + * @class OptionsManager 59.2577 + * @constructor 59.2578 + * @param {Object} value options dictionary 59.2579 + */ 59.2580 + function OptionsManager(value) { 59.2581 + this._value = value; 59.2582 + this.eventOutput = null; 59.2583 + } 59.2584 + 59.2585 + /** 59.2586 + * Create options manager from source dictionary with arguments overriden by patch dictionary. 59.2587 + * 59.2588 + * @static 59.2589 + * @method OptionsManager.patch 59.2590 + * 59.2591 + * @param {Object} source source arguments 59.2592 + * @param {...Object} data argument additions and overwrites 59.2593 + * @return {Object} source object 59.2594 + */ 59.2595 + OptionsManager.patch = function patchObject(source, data) { 59.2596 + var manager = new OptionsManager(source); 59.2597 + for (var i = 1; i < arguments.length; i++) manager.patch(arguments[i]); 59.2598 + return source; 59.2599 + }; 59.2600 + 59.2601 + function _createEventOutput() { 59.2602 + this.eventOutput = new EventHandler(); 59.2603 + this.eventOutput.bindThis(this); 59.2604 + EventHandler.setOutputHandler(this, this.eventOutput); 59.2605 + } 59.2606 + 59.2607 + /** 59.2608 + * Create OptionsManager from source with arguments overriden by patches. 59.2609 + * Triggers 'change' event on this object's event handler if the state of 59.2610 + * the OptionsManager changes as a result. 59.2611 + * 59.2612 + * @method patch 59.2613 + * 59.2614 + * @param {...Object} arguments list of patch objects 59.2615 + * @return {OptionsManager} this 59.2616 + */ 59.2617 + OptionsManager.prototype.patch = function patch() { 59.2618 + var myState = this._value; 59.2619 + for (var i = 0; i < arguments.length; i++) { 59.2620 + var data = arguments[i]; 59.2621 + for (var k in data) { 59.2622 + if ((k in myState) && (data[k] && data[k].constructor === Object) && (myState[k] && myState[k].constructor === Object)) { 59.2623 + if (!myState.hasOwnProperty(k)) myState[k] = Object.create(myState[k]); 59.2624 + this.key(k).patch(data[k]); 59.2625 + if (this.eventOutput) this.eventOutput.emit('change', {id: k, value: this.key(k).value()}); 59.2626 + } 59.2627 + else this.set(k, data[k]); 59.2628 + } 59.2629 + } 59.2630 + return this; 59.2631 + }; 59.2632 + 59.2633 + /** 59.2634 + * Alias for patch 59.2635 + * 59.2636 + * @method setOptions 59.2637 + * 59.2638 + */ 59.2639 + OptionsManager.prototype.setOptions = OptionsManager.prototype.patch; 59.2640 + 59.2641 + /** 59.2642 + * Return OptionsManager based on sub-object retrieved by key 59.2643 + * 59.2644 + * @method key 59.2645 + * 59.2646 + * @param {string} identifier key 59.2647 + * @return {OptionsManager} new options manager with the value 59.2648 + */ 59.2649 + OptionsManager.prototype.key = function key(identifier) { 59.2650 + var result = new OptionsManager(this._value[identifier]); 59.2651 + if (!(result._value instanceof Object) || result._value instanceof Array) result._value = {}; 59.2652 + return result; 59.2653 + }; 59.2654 + 59.2655 + /** 59.2656 + * Look up value by key 59.2657 + * @method get 59.2658 + * 59.2659 + * @param {string} key key 59.2660 + * @return {Object} associated object 59.2661 + */ 59.2662 + OptionsManager.prototype.get = function get(key) { 59.2663 + return this._value[key]; 59.2664 + }; 59.2665 + 59.2666 + /** 59.2667 + * Alias for get 59.2668 + * @method getOptions 59.2669 + */ 59.2670 + OptionsManager.prototype.getOptions = OptionsManager.prototype.get; 59.2671 + 59.2672 + /** 59.2673 + * Set key to value. Outputs 'change' event if a value is overwritten. 59.2674 + * 59.2675 + * @method set 59.2676 + * 59.2677 + * @param {string} key key string 59.2678 + * @param {Object} value value object 59.2679 + * @return {OptionsManager} new options manager based on the value object 59.2680 + */ 59.2681 + OptionsManager.prototype.set = function set(key, value) { 59.2682 + var originalValue = this.get(key); 59.2683 + this._value[key] = value; 59.2684 + if (this.eventOutput && value !== originalValue) this.eventOutput.emit('change', {id: key, value: value}); 59.2685 + return this; 59.2686 + }; 59.2687 + 59.2688 + /** 59.2689 + * Return entire object contents of this OptionsManager. 59.2690 + * 59.2691 + * @method value 59.2692 + * 59.2693 + * @return {Object} current state of options 59.2694 + */ 59.2695 + OptionsManager.prototype.value = function value() { 59.2696 + return this._value; 59.2697 + }; 59.2698 + 59.2699 + /** 59.2700 + * Bind a callback function to an event type handled by this object. 59.2701 + * 59.2702 + * @method "on" 59.2703 + * 59.2704 + * @param {string} type event type key (for example, 'change') 59.2705 + * @param {function(string, Object)} handler callback 59.2706 + * @return {EventHandler} this 59.2707 + */ 59.2708 + OptionsManager.prototype.on = function on() { 59.2709 + _createEventOutput.call(this); 59.2710 + return this.on.apply(this, arguments); 59.2711 + }; 59.2712 + 59.2713 + /** 59.2714 + * Unbind an event by type and handler. 59.2715 + * This undoes the work of "on". 59.2716 + * 59.2717 + * @method removeListener 59.2718 + * 59.2719 + * @param {string} type event type key (for example, 'change') 59.2720 + * @param {function} handler function object to remove 59.2721 + * @return {EventHandler} internal event handler object (for chaining) 59.2722 + */ 59.2723 + OptionsManager.prototype.removeListener = function removeListener() { 59.2724 + _createEventOutput.call(this); 59.2725 + return this.removeListener.apply(this, arguments); 59.2726 + }; 59.2727 + 59.2728 + /** 59.2729 + * Add event handler object to set of downstream handlers. 59.2730 + * 59.2731 + * @method pipe 59.2732 + * 59.2733 + * @param {EventHandler} target event handler target object 59.2734 + * @return {EventHandler} passed event handler 59.2735 + */ 59.2736 + OptionsManager.prototype.pipe = function pipe() { 59.2737 + _createEventOutput.call(this); 59.2738 + return this.pipe.apply(this, arguments); 59.2739 + }; 59.2740 + 59.2741 + /** 59.2742 + * Remove handler object from set of downstream handlers. 59.2743 + * Undoes work of "pipe" 59.2744 + * 59.2745 + * @method unpipe 59.2746 + * 59.2747 + * @param {EventHandler} target target handler object 59.2748 + * @return {EventHandler} provided target 59.2749 + */ 59.2750 + OptionsManager.prototype.unpipe = function unpipe() { 59.2751 + _createEventOutput.call(this); 59.2752 + return this.unpipe.apply(this, arguments); 59.2753 + }; 59.2754 + 59.2755 + module.exports = OptionsManager; 59.2756 +}); 59.2757 + 59.2758 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.2759 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.2760 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.2761 + * 59.2762 + * Owner: mark@famo.us 59.2763 + * @license MPL 2.0 59.2764 + * @copyright Famous Industries, Inc. 2014 59.2765 + */ 59.2766 + 59.2767 +define('famous/core/Engine',['require','exports','module','./Context','./EventHandler','./OptionsManager'],function(require, exports, module) { 59.2768 + 59.2769 + /** 59.2770 + * The singleton object initiated upon process 59.2771 + * startup which manages all active Context instances, runs 59.2772 + * the render dispatch loop, and acts as a listener and dispatcher 59.2773 + * for events. All methods are therefore static. 59.2774 + * 59.2775 + * On static initialization, window.requestAnimationFrame is called with 59.2776 + * the event loop function. 59.2777 + * 59.2778 + * Note: Any window in which Engine runs will prevent default 59.2779 + * scrolling behavior on the 'touchmove' event. 59.2780 + * 59.2781 + * @static 59.2782 + * @class Engine 59.2783 + */ 59.2784 + var Context = require('./Context'); 59.2785 + var EventHandler = require('./EventHandler'); 59.2786 + var OptionsManager = require('./OptionsManager'); 59.2787 + 59.2788 + var Engine = {}; 59.2789 + 59.2790 + var contexts = []; 59.2791 + var nextTickQueue = []; 59.2792 + var deferQueue = []; 59.2793 + 59.2794 + var lastTime = Date.now(); 59.2795 + var frameTime; 59.2796 + var frameTimeLimit; 59.2797 + var loopEnabled = true; 59.2798 + var eventForwarders = {}; 59.2799 + var eventHandler = new EventHandler(); 59.2800 + 59.2801 + var options = { 59.2802 + containerType: 'div', 59.2803 + containerClass: 'famous-container', 59.2804 + fpsCap: undefined, 59.2805 + runLoop: true 59.2806 + }; 59.2807 + var optionsManager = new OptionsManager(options); 59.2808 + 59.2809 + /** @const */ 59.2810 + var MAX_DEFER_FRAME_TIME = 10; 59.2811 + 59.2812 + /** 59.2813 + * Inside requestAnimationFrame loop, step() is called, which: 59.2814 + * calculates current FPS (throttling loop if it is over limit set in setFPSCap), 59.2815 + * emits dataless 'prerender' event on start of loop, 59.2816 + * calls in order any one-shot functions registered by nextTick on last loop, 59.2817 + * calls Context.update on all Context objects registered, 59.2818 + * and emits dataless 'postrender' event on end of loop. 59.2819 + * 59.2820 + * @static 59.2821 + * @private 59.2822 + * @method step 59.2823 + */ 59.2824 + Engine.step = function step() { 59.2825 + var currentTime = Date.now(); 59.2826 + 59.2827 + // skip frame if we're over our framerate cap 59.2828 + if (frameTimeLimit && currentTime - lastTime < frameTimeLimit) return; 59.2829 + 59.2830 + var i = 0; 59.2831 + 59.2832 + frameTime = currentTime - lastTime; 59.2833 + lastTime = currentTime; 59.2834 + 59.2835 + eventHandler.emit('prerender'); 59.2836 + 59.2837 + // empty the queue 59.2838 + for (i = 0; i < nextTickQueue.length; i++) nextTickQueue[i].call(this); 59.2839 + nextTickQueue.splice(0); 59.2840 + 59.2841 + // limit total execution time for deferrable functions 59.2842 + while (deferQueue.length && (Date.now() - currentTime) < MAX_DEFER_FRAME_TIME) { 59.2843 + deferQueue.shift().call(this); 59.2844 + } 59.2845 + 59.2846 + for (i = 0; i < contexts.length; i++) contexts[i].update(); 59.2847 + 59.2848 + eventHandler.emit('postrender'); 59.2849 + }; 59.2850 + 59.2851 + // engage requestAnimationFrame 59.2852 + function loop() { 59.2853 + if (options.runLoop) { 59.2854 + Engine.step(); 59.2855 + requestAnimationFrame(loop); 59.2856 + } 59.2857 + else loopEnabled = false; 59.2858 + } 59.2859 + requestAnimationFrame(loop); 59.2860 + 59.2861 + // 59.2862 + // Upon main document window resize (unless on an "input" HTML element): 59.2863 + // scroll to the top left corner of the window, 59.2864 + // and for each managed Context: emit the 'resize' event and update its size. 59.2865 + // @param {Object=} event document event 59.2866 + // 59.2867 + function handleResize(event) { 59.2868 + for (var i = 0; i < contexts.length; i++) { 59.2869 + contexts[i].emit('resize'); 59.2870 + } 59.2871 + eventHandler.emit('resize'); 59.2872 + } 59.2873 + window.addEventListener('resize', handleResize, false); 59.2874 + handleResize(); 59.2875 + 59.2876 + // prevent scrolling via browser 59.2877 + window.addEventListener('touchmove', function(event) { 59.2878 + event.preventDefault(); 59.2879 + }, true); 59.2880 + 59.2881 + /** 59.2882 + * Add event handler object to set of downstream handlers. 59.2883 + * 59.2884 + * @method pipe 59.2885 + * 59.2886 + * @param {EventHandler} target event handler target object 59.2887 + * @return {EventHandler} passed event handler 59.2888 + */ 59.2889 + Engine.pipe = function pipe(target) { 59.2890 + if (target.subscribe instanceof Function) return target.subscribe(Engine); 59.2891 + else return eventHandler.pipe(target); 59.2892 + }; 59.2893 + 59.2894 + /** 59.2895 + * Remove handler object from set of downstream handlers. 59.2896 + * Undoes work of "pipe". 59.2897 + * 59.2898 + * @method unpipe 59.2899 + * 59.2900 + * @param {EventHandler} target target handler object 59.2901 + * @return {EventHandler} provided target 59.2902 + */ 59.2903 + Engine.unpipe = function unpipe(target) { 59.2904 + if (target.unsubscribe instanceof Function) return target.unsubscribe(Engine); 59.2905 + else return eventHandler.unpipe(target); 59.2906 + }; 59.2907 + 59.2908 + /** 59.2909 + * Bind a callback function to an event type handled by this object. 59.2910 + * 59.2911 + * @static 59.2912 + * @method "on" 59.2913 + * 59.2914 + * @param {string} type event type key (for example, 'click') 59.2915 + * @param {function(string, Object)} handler callback 59.2916 + * @return {EventHandler} this 59.2917 + */ 59.2918 + Engine.on = function on(type, handler) { 59.2919 + if (!(type in eventForwarders)) { 59.2920 + eventForwarders[type] = eventHandler.emit.bind(eventHandler, type); 59.2921 + if (document.body) { 59.2922 + document.body.addEventListener(type, eventForwarders[type]); 59.2923 + } 59.2924 + else { 59.2925 + Engine.nextTick(function(type, forwarder) { 59.2926 + document.body.addEventListener(type, forwarder); 59.2927 + }.bind(this, type, eventForwarders[type])); 59.2928 + } 59.2929 + } 59.2930 + return eventHandler.on(type, handler); 59.2931 + }; 59.2932 + 59.2933 + /** 59.2934 + * Trigger an event, sending to all downstream handlers 59.2935 + * listening for provided 'type' key. 59.2936 + * 59.2937 + * @method emit 59.2938 + * 59.2939 + * @param {string} type event type key (for example, 'click') 59.2940 + * @param {Object} event event data 59.2941 + * @return {EventHandler} this 59.2942 + */ 59.2943 + Engine.emit = function emit(type, event) { 59.2944 + return eventHandler.emit(type, event); 59.2945 + }; 59.2946 + 59.2947 + /** 59.2948 + * Unbind an event by type and handler. 59.2949 + * This undoes the work of "on". 59.2950 + * 59.2951 + * @static 59.2952 + * @method removeListener 59.2953 + * 59.2954 + * @param {string} type event type key (for example, 'click') 59.2955 + * @param {function} handler function object to remove 59.2956 + * @return {EventHandler} internal event handler object (for chaining) 59.2957 + */ 59.2958 + Engine.removeListener = function removeListener(type, handler) { 59.2959 + return eventHandler.removeListener(type, handler); 59.2960 + }; 59.2961 + 59.2962 + /** 59.2963 + * Return the current calculated frames per second of the Engine. 59.2964 + * 59.2965 + * @static 59.2966 + * @method getFPS 59.2967 + * 59.2968 + * @return {Number} calculated fps 59.2969 + */ 59.2970 + Engine.getFPS = function getFPS() { 59.2971 + return 1000 / frameTime; 59.2972 + }; 59.2973 + 59.2974 + /** 59.2975 + * Set the maximum fps at which the system should run. If internal render 59.2976 + * loop is called at a greater frequency than this FPSCap, Engine will 59.2977 + * throttle render and update until this rate is achieved. 59.2978 + * 59.2979 + * @static 59.2980 + * @method setFPSCap 59.2981 + * 59.2982 + * @param {Number} fps maximum frames per second 59.2983 + */ 59.2984 + Engine.setFPSCap = function setFPSCap(fps) { 59.2985 + frameTimeLimit = Math.floor(1000 / fps); 59.2986 + }; 59.2987 + 59.2988 + /** 59.2989 + * Return engine options. 59.2990 + * 59.2991 + * @static 59.2992 + * @method getOptions 59.2993 + * @param {string} key 59.2994 + * @return {Object} engine options 59.2995 + */ 59.2996 + Engine.getOptions = function getOptions() { 59.2997 + return optionsManager.getOptions.apply(optionsManager, arguments); 59.2998 + }; 59.2999 + 59.3000 + /** 59.3001 + * Set engine options 59.3002 + * 59.3003 + * @static 59.3004 + * @method setOptions 59.3005 + * 59.3006 + * @param {Object} [options] overrides of default options 59.3007 + * @param {Number} [options.fpsCap] maximum fps at which the system should run 59.3008 + * @param {boolean} [options.runLoop=true] whether the run loop should continue 59.3009 + * @param {string} [options.containerType="div"] type of container element. Defaults to 'div'. 59.3010 + * @param {string} [options.containerClass="famous-container"] type of container element. Defaults to 'famous-container'. 59.3011 + */ 59.3012 + Engine.setOptions = function setOptions(options) { 59.3013 + return optionsManager.setOptions.apply(optionsManager, arguments); 59.3014 + }; 59.3015 + 59.3016 + /** 59.3017 + * Creates a new Context for rendering and event handling with 59.3018 + * provided document element as top of each tree. This will be tracked by the 59.3019 + * process-wide Engine. 59.3020 + * 59.3021 + * @static 59.3022 + * @method createContext 59.3023 + * 59.3024 + * @param {Node} el will be top of Famo.us document element tree 59.3025 + * @return {Context} new Context within el 59.3026 + */ 59.3027 + Engine.createContext = function createContext(el) { 59.3028 + var needMountContainer = false; 59.3029 + if (!el) { 59.3030 + el = document.createElement(options.containerType); 59.3031 + el.classList.add(options.containerClass); 59.3032 + needMountContainer = true; 59.3033 + } 59.3034 + var context = new Context(el); 59.3035 + Engine.registerContext(context); 59.3036 + if (needMountContainer) { 59.3037 + Engine.nextTick(function(context, el) { 59.3038 + document.body.appendChild(el); 59.3039 + context.emit('resize'); 59.3040 + }.bind(this, context, el)); 59.3041 + } 59.3042 + return context; 59.3043 + }; 59.3044 + 59.3045 + /** 59.3046 + * Registers an existing context to be updated within the run loop. 59.3047 + * 59.3048 + * @static 59.3049 + * @method registerContext 59.3050 + * 59.3051 + * @param {Context} context Context to register 59.3052 + * @return {FamousContext} provided context 59.3053 + */ 59.3054 + Engine.registerContext = function registerContext(context) { 59.3055 + contexts.push(context); 59.3056 + return context; 59.3057 + }; 59.3058 + 59.3059 + /** 59.3060 + * Queue a function to be executed on the next tick of the 59.3061 + * Engine. 59.3062 + * 59.3063 + * @static 59.3064 + * @method nextTick 59.3065 + * 59.3066 + * @param {function(Object)} fn function accepting window object 59.3067 + */ 59.3068 + Engine.nextTick = function nextTick(fn) { 59.3069 + nextTickQueue.push(fn); 59.3070 + }; 59.3071 + 59.3072 + /** 59.3073 + * Queue a function to be executed sometime soon, at a time that is 59.3074 + * unlikely to affect frame rate. 59.3075 + * 59.3076 + * @static 59.3077 + * @method defer 59.3078 + * 59.3079 + * @param {Function} fn 59.3080 + */ 59.3081 + Engine.defer = function defer(fn) { 59.3082 + deferQueue.push(fn); 59.3083 + }; 59.3084 + 59.3085 + optionsManager.on('change', function(data) { 59.3086 + if (data.id === 'fpsCap') Engine.setFPSCap(data.value); 59.3087 + else if (data.id === 'runLoop') { 59.3088 + // kick off the loop only if it was stopped 59.3089 + if (!loopEnabled && data.value) { 59.3090 + loopEnabled = true; 59.3091 + requestAnimationFrame(loop); 59.3092 + } 59.3093 + } 59.3094 + }); 59.3095 + 59.3096 + module.exports = Engine; 59.3097 +}); 59.3098 + 59.3099 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.3100 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.3101 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.3102 + * 59.3103 + * Owner: mark@famo.us 59.3104 + * @license MPL 2.0 59.3105 + * @copyright Famous Industries, Inc. 2014 59.3106 + */ 59.3107 + 59.3108 +define('famous/core/Surface',['require','exports','module','./Entity','./EventHandler','./Transform'],function(require, exports, module) { 59.3109 + var Entity = require('./Entity'); 59.3110 + var EventHandler = require('./EventHandler'); 59.3111 + var Transform = require('./Transform'); 59.3112 + 59.3113 + var devicePixelRatio = window.devicePixelRatio || 1; 59.3114 + var usePrefix = document.createElement('div').style.webkitTransform !== undefined; 59.3115 + 59.3116 + /** 59.3117 + * A base class for viewable content and event 59.3118 + * targets inside a Famo.us application, containing a renderable document 59.3119 + * fragment. Like an HTML div, it can accept internal markup, 59.3120 + * properties, classes, and handle events. 59.3121 + * 59.3122 + * @class Surface 59.3123 + * @constructor 59.3124 + * 59.3125 + * @param {Object} [options] default option overrides 59.3126 + * @param {Array.Number} [options.size] [width, height] in pixels 59.3127 + * @param {Array.string} [options.classes] CSS classes to set on inner content 59.3128 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 59.3129 + * @param {string} [options.content] inner (HTML) content of surface 59.3130 + */ 59.3131 + function Surface(options) { 59.3132 + this.options = {}; 59.3133 + 59.3134 + this.properties = {}; 59.3135 + this.content = ''; 59.3136 + this.classList = []; 59.3137 + this.size = null; 59.3138 + 59.3139 + this._classesDirty = true; 59.3140 + this._stylesDirty = true; 59.3141 + this._sizeDirty = true; 59.3142 + this._contentDirty = true; 59.3143 + 59.3144 + this._dirtyClasses = []; 59.3145 + 59.3146 + this._matrix = null; 59.3147 + this._opacity = 1; 59.3148 + this._origin = null; 59.3149 + this._size = null; 59.3150 + 59.3151 + /** @ignore */ 59.3152 + this.eventForwarder = function eventForwarder(event) { 59.3153 + this.emit(event.type, event); 59.3154 + }.bind(this); 59.3155 + this.eventHandler = new EventHandler(); 59.3156 + this.eventHandler.bindThis(this); 59.3157 + 59.3158 + this.id = Entity.register(this); 59.3159 + 59.3160 + if (options) this.setOptions(options); 59.3161 + 59.3162 + this._currTarget = null; 59.3163 + } 59.3164 + Surface.prototype.elementType = 'div'; 59.3165 + Surface.prototype.elementClass = 'famous-surface'; 59.3166 + 59.3167 + /** 59.3168 + * Bind a callback function to an event type handled by this object. 59.3169 + * 59.3170 + * @method "on" 59.3171 + * 59.3172 + * @param {string} type event type key (for example, 'click') 59.3173 + * @param {function(string, Object)} fn handler callback 59.3174 + * @return {EventHandler} this 59.3175 + */ 59.3176 + Surface.prototype.on = function on(type, fn) { 59.3177 + if (this._currTarget) this._currTarget.addEventListener(type, this.eventForwarder); 59.3178 + this.eventHandler.on(type, fn); 59.3179 + }; 59.3180 + 59.3181 + /** 59.3182 + * Unbind an event by type and handler. 59.3183 + * This undoes the work of "on" 59.3184 + * 59.3185 + * @method removeListener 59.3186 + * @param {string} type event type key (for example, 'click') 59.3187 + * @param {function(string, Object)} fn handler 59.3188 + */ 59.3189 + Surface.prototype.removeListener = function removeListener(type, fn) { 59.3190 + this.eventHandler.removeListener(type, fn); 59.3191 + }; 59.3192 + 59.3193 + /** 59.3194 + * Trigger an event, sending to all downstream handlers 59.3195 + * listening for provided 'type' key. 59.3196 + * 59.3197 + * @method emit 59.3198 + * 59.3199 + * @param {string} type event type key (for example, 'click') 59.3200 + * @param {Object} [event] event data 59.3201 + * @return {EventHandler} this 59.3202 + */ 59.3203 + Surface.prototype.emit = function emit(type, event) { 59.3204 + if (event && !event.origin) event.origin = this; 59.3205 + var handled = this.eventHandler.emit(type, event); 59.3206 + if (handled && event && event.stopPropagation) event.stopPropagation(); 59.3207 + return handled; 59.3208 + }; 59.3209 + 59.3210 + /** 59.3211 + * Add event handler object to set of downstream handlers. 59.3212 + * 59.3213 + * @method pipe 59.3214 + * 59.3215 + * @param {EventHandler} target event handler target object 59.3216 + * @return {EventHandler} passed event handler 59.3217 + */ 59.3218 + Surface.prototype.pipe = function pipe(target) { 59.3219 + return this.eventHandler.pipe(target); 59.3220 + }; 59.3221 + 59.3222 + /** 59.3223 + * Remove handler object from set of downstream handlers. 59.3224 + * Undoes work of "pipe" 59.3225 + * 59.3226 + * @method unpipe 59.3227 + * 59.3228 + * @param {EventHandler} target target handler object 59.3229 + * @return {EventHandler} provided target 59.3230 + */ 59.3231 + Surface.prototype.unpipe = function unpipe(target) { 59.3232 + return this.eventHandler.unpipe(target); 59.3233 + }; 59.3234 + 59.3235 + /** 59.3236 + * Return spec for this surface. Note that for a base surface, this is 59.3237 + * simply an id. 59.3238 + * 59.3239 + * @method render 59.3240 + * @private 59.3241 + * @return {Object} render spec for this surface (spec id) 59.3242 + */ 59.3243 + Surface.prototype.render = function render() { 59.3244 + return this.id; 59.3245 + }; 59.3246 + 59.3247 + /** 59.3248 + * Set CSS-style properties on this Surface. Note that this will cause 59.3249 + * dirtying and thus re-rendering, even if values do not change. 59.3250 + * 59.3251 + * @method setProperties 59.3252 + * @param {Object} properties property dictionary of "key" => "value" 59.3253 + */ 59.3254 + Surface.prototype.setProperties = function setProperties(properties) { 59.3255 + for (var n in properties) { 59.3256 + this.properties[n] = properties[n]; 59.3257 + } 59.3258 + this._stylesDirty = true; 59.3259 + }; 59.3260 + 59.3261 + /** 59.3262 + * Get CSS-style properties on this Surface. 59.3263 + * 59.3264 + * @method getProperties 59.3265 + * 59.3266 + * @return {Object} Dictionary of this Surface's properties. 59.3267 + */ 59.3268 + Surface.prototype.getProperties = function getProperties() { 59.3269 + return this.properties; 59.3270 + }; 59.3271 + 59.3272 + /** 59.3273 + * Add CSS-style class to the list of classes on this Surface. Note 59.3274 + * this will map directly to the HTML property of the actual 59.3275 + * corresponding rendered <div>. 59.3276 + * 59.3277 + * @method addClass 59.3278 + * @param {string} className name of class to add 59.3279 + */ 59.3280 + Surface.prototype.addClass = function addClass(className) { 59.3281 + if (this.classList.indexOf(className) < 0) { 59.3282 + this.classList.push(className); 59.3283 + this._classesDirty = true; 59.3284 + } 59.3285 + }; 59.3286 + 59.3287 + /** 59.3288 + * Remove CSS-style class from the list of classes on this Surface. 59.3289 + * Note this will map directly to the HTML property of the actual 59.3290 + * corresponding rendered <div>. 59.3291 + * 59.3292 + * @method removeClass 59.3293 + * @param {string} className name of class to remove 59.3294 + */ 59.3295 + Surface.prototype.removeClass = function removeClass(className) { 59.3296 + var i = this.classList.indexOf(className); 59.3297 + if (i >= 0) { 59.3298 + this._dirtyClasses.push(this.classList.splice(i, 1)[0]); 59.3299 + this._classesDirty = true; 59.3300 + } 59.3301 + }; 59.3302 + 59.3303 + /** 59.3304 + * Reset class list to provided dictionary. 59.3305 + * @method setClasses 59.3306 + * @param {Array.string} classList 59.3307 + */ 59.3308 + Surface.prototype.setClasses = function setClasses(classList) { 59.3309 + var i = 0; 59.3310 + var removal = []; 59.3311 + for (i = 0; i < this.classList.length; i++) { 59.3312 + if (classList.indexOf(this.classList[i]) < 0) removal.push(this.classList[i]); 59.3313 + } 59.3314 + for (i = 0; i < removal.length; i++) this.removeClass(removal[i]); 59.3315 + // duplicates are already checked by addClass() 59.3316 + for (i = 0; i < classList.length; i++) this.addClass(classList[i]); 59.3317 + }; 59.3318 + 59.3319 + /** 59.3320 + * Get array of CSS-style classes attached to this div. 59.3321 + * 59.3322 + * @method getClasslist 59.3323 + * @return {Array.string} array of class names 59.3324 + */ 59.3325 + Surface.prototype.getClassList = function getClassList() { 59.3326 + return this.classList; 59.3327 + }; 59.3328 + 59.3329 + /** 59.3330 + * Set or overwrite inner (HTML) content of this surface. Note that this 59.3331 + * causes a re-rendering if the content has changed. 59.3332 + * 59.3333 + * @method setContent 59.3334 + * @param {string|Document Fragment} content HTML content 59.3335 + */ 59.3336 + Surface.prototype.setContent = function setContent(content) { 59.3337 + if (this.content !== content) { 59.3338 + this.content = content; 59.3339 + this._contentDirty = true; 59.3340 + } 59.3341 + }; 59.3342 + 59.3343 + /** 59.3344 + * Return inner (HTML) content of this surface. 59.3345 + * 59.3346 + * @method getContent 59.3347 + * 59.3348 + * @return {string} inner (HTML) content 59.3349 + */ 59.3350 + Surface.prototype.getContent = function getContent() { 59.3351 + return this.content; 59.3352 + }; 59.3353 + 59.3354 + /** 59.3355 + * Set options for this surface 59.3356 + * 59.3357 + * @method setOptions 59.3358 + * @param {Object} [options] overrides for default options. See constructor. 59.3359 + */ 59.3360 + Surface.prototype.setOptions = function setOptions(options) { 59.3361 + if (options.size) this.setSize(options.size); 59.3362 + if (options.classes) this.setClasses(options.classes); 59.3363 + if (options.properties) this.setProperties(options.properties); 59.3364 + if (options.content) this.setContent(options.content); 59.3365 + }; 59.3366 + 59.3367 + // Attach Famous event handling to document events emanating from target 59.3368 + // document element. This occurs just after deployment to the document. 59.3369 + // Calling this enables methods like #on and #pipe. 59.3370 + function _addEventListeners(target) { 59.3371 + for (var i in this.eventHandler.listeners) { 59.3372 + target.addEventListener(i, this.eventForwarder); 59.3373 + } 59.3374 + } 59.3375 + 59.3376 + // Detach Famous event handling from document events emanating from target 59.3377 + // document element. This occurs just before recall from the document. 59.3378 + function _removeEventListeners(target) { 59.3379 + for (var i in this.eventHandler.listeners) { 59.3380 + target.removeEventListener(i, this.eventForwarder); 59.3381 + } 59.3382 + } 59.3383 + 59.3384 + // Apply to document all changes from removeClass() since last setup(). 59.3385 + function _cleanupClasses(target) { 59.3386 + for (var i = 0; i < this._dirtyClasses.length; i++) target.classList.remove(this._dirtyClasses[i]); 59.3387 + this._dirtyClasses = []; 59.3388 + } 59.3389 + 59.3390 + // Apply values of all Famous-managed styles to the document element. 59.3391 + // These will be deployed to the document on call to #setup(). 59.3392 + function _applyStyles(target) { 59.3393 + for (var n in this.properties) { 59.3394 + target.style[n] = this.properties[n]; 59.3395 + } 59.3396 + } 59.3397 + 59.3398 + // Clear all Famous-managed styles from the document element. 59.3399 + // These will be deployed to the document on call to #setup(). 59.3400 + function _cleanupStyles(target) { 59.3401 + for (var n in this.properties) { 59.3402 + target.style[n] = ''; 59.3403 + } 59.3404 + } 59.3405 + 59.3406 + /** 59.3407 + * Return a Matrix's webkit css representation to be used with the 59.3408 + * CSS3 -webkit-transform style. 59.3409 + * Example: -webkit-transform: matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,716,243,0,1) 59.3410 + * 59.3411 + * @method _formatCSSTransform 59.3412 + * @private 59.3413 + * @param {FamousMatrix} m matrix 59.3414 + * @return {string} matrix3d CSS style representation of the transform 59.3415 + */ 59.3416 + function _formatCSSTransform(m) { 59.3417 + m[12] = Math.round(m[12] * devicePixelRatio) / devicePixelRatio; 59.3418 + m[13] = Math.round(m[13] * devicePixelRatio) / devicePixelRatio; 59.3419 + 59.3420 + var result = 'matrix3d('; 59.3421 + for (var i = 0; i < 15; i++) { 59.3422 + result += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; 59.3423 + } 59.3424 + result += m[15] + ')'; 59.3425 + return result; 59.3426 + } 59.3427 + 59.3428 + /** 59.3429 + * Directly apply given FamousMatrix to the document element as the 59.3430 + * appropriate webkit CSS style. 59.3431 + * 59.3432 + * @method setMatrix 59.3433 + * 59.3434 + * @static 59.3435 + * @private 59.3436 + * @param {Element} element document element 59.3437 + * @param {FamousMatrix} matrix 59.3438 + */ 59.3439 + 59.3440 + var _setMatrix; 59.3441 + if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { 59.3442 + _setMatrix = function(element, matrix) { 59.3443 + element.style.zIndex = (matrix[14] * 1000000) | 0; // fix for Firefox z-buffer issues 59.3444 + element.style.transform = _formatCSSTransform(matrix); 59.3445 + }; 59.3446 + } 59.3447 + else if (usePrefix) { 59.3448 + _setMatrix = function(element, matrix) { 59.3449 + element.style.webkitTransform = _formatCSSTransform(matrix); 59.3450 + }; 59.3451 + } 59.3452 + else { 59.3453 + _setMatrix = function(element, matrix) { 59.3454 + element.style.transform = _formatCSSTransform(matrix); 59.3455 + }; 59.3456 + } 59.3457 + 59.3458 + // format origin as CSS percentage string 59.3459 + function _formatCSSOrigin(origin) { 59.3460 + return (100 * origin[0]) + '% ' + (100 * origin[1]) + '%'; 59.3461 + } 59.3462 + 59.3463 + // Directly apply given origin coordinates to the document element as the 59.3464 + // appropriate webkit CSS style. 59.3465 + var _setOrigin = usePrefix ? function(element, origin) { 59.3466 + element.style.webkitTransformOrigin = _formatCSSOrigin(origin); 59.3467 + } : function(element, origin) { 59.3468 + element.style.transformOrigin = _formatCSSOrigin(origin); 59.3469 + }; 59.3470 + 59.3471 + // Shrink given document element until it is effectively invisible. 59.3472 + var _setInvisible = usePrefix ? function(element) { 59.3473 + element.style.webkitTransform = 'scale3d(0.0001,0.0001,1)'; 59.3474 + element.style.opacity = 0; 59.3475 + } : function(element) { 59.3476 + element.style.transform = 'scale3d(0.0001,0.0001,1)'; 59.3477 + element.style.opacity = 0; 59.3478 + }; 59.3479 + 59.3480 + function _xyNotEquals(a, b) { 59.3481 + return (a && b) ? (a[0] !== b[0] || a[1] !== b[1]) : a !== b; 59.3482 + } 59.3483 + 59.3484 + /** 59.3485 + * One-time setup for an element to be ready for commits to document. 59.3486 + * 59.3487 + * @private 59.3488 + * @method setup 59.3489 + * 59.3490 + * @param {ElementAllocator} allocator document element pool for this context 59.3491 + */ 59.3492 + Surface.prototype.setup = function setup(allocator) { 59.3493 + var target = allocator.allocate(this.elementType); 59.3494 + if (this.elementClass) { 59.3495 + if (this.elementClass instanceof Array) { 59.3496 + for (var i = 0; i < this.elementClass.length; i++) { 59.3497 + target.classList.add(this.elementClass[i]); 59.3498 + } 59.3499 + } 59.3500 + else { 59.3501 + target.classList.add(this.elementClass); 59.3502 + } 59.3503 + } 59.3504 + target.style.display = ''; 59.3505 + _addEventListeners.call(this, target); 59.3506 + this._currTarget = target; 59.3507 + this._stylesDirty = true; 59.3508 + this._classesDirty = true; 59.3509 + this._sizeDirty = true; 59.3510 + this._contentDirty = true; 59.3511 + this._matrix = null; 59.3512 + this._opacity = undefined; 59.3513 + this._origin = null; 59.3514 + this._size = null; 59.3515 + }; 59.3516 + 59.3517 + /** 59.3518 + * Apply changes from this component to the corresponding document element. 59.3519 + * This includes changes to classes, styles, size, content, opacity, origin, 59.3520 + * and matrix transforms. 59.3521 + * 59.3522 + * @private 59.3523 + * @method commit 59.3524 + * @param {Context} context commit context 59.3525 + */ 59.3526 + Surface.prototype.commit = function commit(context) { 59.3527 + if (!this._currTarget) this.setup(context.allocator); 59.3528 + var target = this._currTarget; 59.3529 + 59.3530 + var matrix = context.transform; 59.3531 + var opacity = context.opacity; 59.3532 + var origin = context.origin; 59.3533 + var size = context.size; 59.3534 + 59.3535 + if (this._classesDirty) { 59.3536 + _cleanupClasses.call(this, target); 59.3537 + var classList = this.getClassList(); 59.3538 + for (var i = 0; i < classList.length; i++) target.classList.add(classList[i]); 59.3539 + this._classesDirty = false; 59.3540 + } 59.3541 + 59.3542 + if (this._stylesDirty) { 59.3543 + _applyStyles.call(this, target); 59.3544 + this._stylesDirty = false; 59.3545 + } 59.3546 + 59.3547 + if (this._contentDirty) { 59.3548 + this.deploy(target); 59.3549 + this.eventHandler.emit('deploy'); 59.3550 + this._contentDirty = false; 59.3551 + } 59.3552 + 59.3553 + if (this.size) { 59.3554 + var origSize = size; 59.3555 + size = [this.size[0], this.size[1]]; 59.3556 + if (size[0] === undefined && origSize[0]) size[0] = origSize[0]; 59.3557 + if (size[1] === undefined && origSize[1]) size[1] = origSize[1]; 59.3558 + } 59.3559 + 59.3560 + if (size[0] === true) size[0] = target.clientWidth; 59.3561 + if (size[1] === true) size[1] = target.clientHeight; 59.3562 + 59.3563 + if (_xyNotEquals(this._size, size)) { 59.3564 + if (!this._size) this._size = [0, 0]; 59.3565 + this._size[0] = size[0]; 59.3566 + this._size[1] = size[1]; 59.3567 + this._sizeDirty = true; 59.3568 + } 59.3569 + 59.3570 + if (!matrix && this._matrix) { 59.3571 + this._matrix = null; 59.3572 + this._opacity = 0; 59.3573 + _setInvisible(target); 59.3574 + return; 59.3575 + } 59.3576 + 59.3577 + if (this._opacity !== opacity) { 59.3578 + this._opacity = opacity; 59.3579 + target.style.opacity = (opacity >= 1) ? '0.999999' : opacity; 59.3580 + } 59.3581 + 59.3582 + if (_xyNotEquals(this._origin, origin) || Transform.notEquals(this._matrix, matrix) || this._sizeDirty) { 59.3583 + if (!matrix) matrix = Transform.identity; 59.3584 + this._matrix = matrix; 59.3585 + var aaMatrix = matrix; 59.3586 + if (origin) { 59.3587 + if (!this._origin) this._origin = [0, 0]; 59.3588 + this._origin[0] = origin[0]; 59.3589 + this._origin[1] = origin[1]; 59.3590 + aaMatrix = Transform.thenMove(matrix, [-this._size[0] * origin[0], -this._size[1] * origin[1], 0]); 59.3591 + _setOrigin(target, origin); 59.3592 + } 59.3593 + _setMatrix(target, aaMatrix); 59.3594 + } 59.3595 + 59.3596 + if (this._sizeDirty) { 59.3597 + if (this._size) { 59.3598 + target.style.width = (this.size && this.size[0] === true) ? '' : this._size[0] + 'px'; 59.3599 + target.style.height = (this.size && this.size[1] === true) ? '' : this._size[1] + 'px'; 59.3600 + } 59.3601 + this._sizeDirty = false; 59.3602 + } 59.3603 + }; 59.3604 + 59.3605 + /** 59.3606 + * Remove all Famous-relevant attributes from a document element. 59.3607 + * This is called by SurfaceManager's detach(). 59.3608 + * This is in some sense the reverse of .deploy(). 59.3609 + * 59.3610 + * @private 59.3611 + * @method cleanup 59.3612 + * @param {ElementAllocator} allocator 59.3613 + */ 59.3614 + Surface.prototype.cleanup = function cleanup(allocator) { 59.3615 + var i = 0; 59.3616 + var target = this._currTarget; 59.3617 + this.eventHandler.emit('recall'); 59.3618 + this.recall(target); 59.3619 + target.style.display = 'none'; 59.3620 + target.style.width = ''; 59.3621 + target.style.height = ''; 59.3622 + this._size = null; 59.3623 + _cleanupStyles.call(this, target); 59.3624 + var classList = this.getClassList(); 59.3625 + _cleanupClasses.call(this, target); 59.3626 + for (i = 0; i < classList.length; i++) target.classList.remove(classList[i]); 59.3627 + if (this.elementClass) { 59.3628 + if (this.elementClass instanceof Array) { 59.3629 + for (i = 0; i < this.elementClass.length; i++) { 59.3630 + target.classList.remove(this.elementClass[i]); 59.3631 + } 59.3632 + } 59.3633 + else { 59.3634 + target.classList.remove(this.elementClass); 59.3635 + } 59.3636 + } 59.3637 + _removeEventListeners.call(this, target); 59.3638 + this._currTarget = null; 59.3639 + allocator.deallocate(target); 59.3640 + _setInvisible(target); 59.3641 + }; 59.3642 + 59.3643 + /** 59.3644 + * Place the document element that this component manages into the document. 59.3645 + * 59.3646 + * @private 59.3647 + * @method deploy 59.3648 + * @param {Node} target document parent of this container 59.3649 + */ 59.3650 + Surface.prototype.deploy = function deploy(target) { 59.3651 + var content = this.getContent(); 59.3652 + if (content instanceof Node) { 59.3653 + while (target.hasChildNodes()) target.removeChild(target.firstChild); 59.3654 + target.appendChild(content); 59.3655 + } 59.3656 + else target.innerHTML = content; 59.3657 + }; 59.3658 + 59.3659 + /** 59.3660 + * Remove any contained document content associated with this surface 59.3661 + * from the actual document. 59.3662 + * 59.3663 + * @private 59.3664 + * @method recall 59.3665 + */ 59.3666 + Surface.prototype.recall = function recall(target) { 59.3667 + var df = document.createDocumentFragment(); 59.3668 + while (target.hasChildNodes()) df.appendChild(target.firstChild); 59.3669 + this.setContent(df); 59.3670 + }; 59.3671 + 59.3672 + /** 59.3673 + * Get the x and y dimensions of the surface. 59.3674 + * 59.3675 + * @method getSize 59.3676 + * @param {boolean} actual return computed size rather than provided 59.3677 + * @return {Array.Number} [x,y] size of surface 59.3678 + */ 59.3679 + Surface.prototype.getSize = function getSize(actual) { 59.3680 + return actual ? this._size : (this.size || this._size); 59.3681 + }; 59.3682 + 59.3683 + /** 59.3684 + * Set x and y dimensions of the surface. 59.3685 + * 59.3686 + * @method setSize 59.3687 + * @param {Array.Number} size as [width, height] 59.3688 + */ 59.3689 + Surface.prototype.setSize = function setSize(size) { 59.3690 + this.size = size ? [size[0], size[1]] : null; 59.3691 + this._sizeDirty = true; 59.3692 + }; 59.3693 + 59.3694 + module.exports = Surface; 59.3695 +}); 59.3696 + 59.3697 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.3698 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.3699 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.3700 + * 59.3701 + * Owner: mark@famo.us 59.3702 + * @license MPL 2.0 59.3703 + * @copyright Famous Industries, Inc. 2014 59.3704 + */ 59.3705 + 59.3706 +define('famous/core/Group',['require','exports','module','./Context','./Transform','./Surface'],function(require, exports, module) { 59.3707 + var Context = require('./Context'); 59.3708 + var Transform = require('./Transform'); 59.3709 + var Surface = require('./Surface'); 59.3710 + 59.3711 + /** 59.3712 + * A Context designed to contain surfaces and set properties 59.3713 + * to be applied to all of them at once. 59.3714 + * This is primarily used for specific performance improvements in the rendering engine. 59.3715 + * Private. 59.3716 + * 59.3717 + * @private 59.3718 + * @class Group 59.3719 + * @extends Surface 59.3720 + * @constructor 59.3721 + * @param {Object} [options] Surface options array (see Surface}) 59.3722 + */ 59.3723 + function Group(options) { 59.3724 + Surface.call(this, options); 59.3725 + this._shouldRecalculateSize = false; 59.3726 + this._container = document.createDocumentFragment(); 59.3727 + this.context = new Context(this._container); 59.3728 + this.setContent(this._container); 59.3729 + this._groupSize = [undefined, undefined]; 59.3730 + } 59.3731 + 59.3732 + /** @const */ 59.3733 + Group.SIZE_ZERO = [0, 0]; 59.3734 + 59.3735 + Group.prototype = Object.create(Surface.prototype); 59.3736 + Group.prototype.elementType = 'div'; 59.3737 + Group.prototype.elementClass = 'famous-group'; 59.3738 + 59.3739 + /** 59.3740 + * Add renderables to this component's render tree. 59.3741 + * 59.3742 + * @method add 59.3743 + * @private 59.3744 + * @param {Object} obj renderable object 59.3745 + * @return {RenderNode} Render wrapping provided object, if not already a RenderNode 59.3746 + */ 59.3747 + Group.prototype.add = function add() { 59.3748 + return this.context.add.apply(this.context, arguments); 59.3749 + }; 59.3750 + 59.3751 + /** 59.3752 + * Generate a render spec from the contents of this component. 59.3753 + * 59.3754 + * @private 59.3755 + * @method render 59.3756 + * @return {Number} Render spec for this component 59.3757 + */ 59.3758 + Group.prototype.render = function render() { 59.3759 + return Surface.prototype.render.call(this); 59.3760 + }; 59.3761 + 59.3762 + /** 59.3763 + * Place the document element this component manages into the document. 59.3764 + * 59.3765 + * @private 59.3766 + * @method deploy 59.3767 + * @param {Node} target document parent of this container 59.3768 + */ 59.3769 + Group.prototype.deploy = function deploy(target) { 59.3770 + this.context.migrate(target); 59.3771 + }; 59.3772 + 59.3773 + /** 59.3774 + * Remove this component and contained content from the document 59.3775 + * 59.3776 + * @private 59.3777 + * @method recall 59.3778 + * 59.3779 + * @param {Node} target node to which the component was deployed 59.3780 + */ 59.3781 + Group.prototype.recall = function recall(target) { 59.3782 + this._container = document.createDocumentFragment(); 59.3783 + this.context.migrate(this._container); 59.3784 + }; 59.3785 + 59.3786 + /** 59.3787 + * Apply changes from this component to the corresponding document element. 59.3788 + * 59.3789 + * @private 59.3790 + * @method commit 59.3791 + * 59.3792 + * @param {Object} context update spec passed in from above in the render tree. 59.3793 + */ 59.3794 + Group.prototype.commit = function commit(context) { 59.3795 + var transform = context.transform; 59.3796 + var origin = context.origin; 59.3797 + var opacity = context.opacity; 59.3798 + var size = context.size; 59.3799 + var result = Surface.prototype.commit.call(this, { 59.3800 + allocator: context.allocator, 59.3801 + transform: Transform.thenMove(transform, [-origin[0] * size[0], -origin[1] * size[1], 0]), 59.3802 + opacity: opacity, 59.3803 + origin: origin, 59.3804 + size: Group.SIZE_ZERO 59.3805 + }); 59.3806 + if (size[0] !== this._groupSize[0] || size[1] !== this._groupSize[1]) { 59.3807 + this._groupSize[0] = size[0]; 59.3808 + this._groupSize[1] = size[1]; 59.3809 + this.context.setSize(size); 59.3810 + } 59.3811 + this.context.update({ 59.3812 + transform: Transform.translate(-origin[0] * size[0], -origin[1] * size[1], 0), 59.3813 + origin: origin, 59.3814 + size: size 59.3815 + }); 59.3816 + return result; 59.3817 + }; 59.3818 + 59.3819 + module.exports = Group; 59.3820 +}); 59.3821 + 59.3822 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.3823 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.3824 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.3825 + * 59.3826 + * Owner: david@famo.us 59.3827 + * @license MPL 2.0 59.3828 + * @copyright Famous Industries, Inc. 2014 59.3829 + */ 59.3830 + 59.3831 +define('famous/transitions/TransitionableTransform',['require','exports','module','./Transitionable','famous/core/Transform','famous/utilities/Utility'],function(require, exports, module) { 59.3832 + var Transitionable = require('./Transitionable'); 59.3833 + var Transform = require('famous/core/Transform'); 59.3834 + var Utility = require('famous/utilities/Utility'); 59.3835 + 59.3836 + /** 59.3837 + * A class for transitioning the state of a Transform by transitioning 59.3838 + * its translate, scale, skew and rotate components independently. 59.3839 + * 59.3840 + * @class TransitionableTransform 59.3841 + * @constructor 59.3842 + * 59.3843 + * @param [transform=Transform.identity] {Transform} The initial transform state 59.3844 + */ 59.3845 + function TransitionableTransform(transform) { 59.3846 + this._final = Transform.identity.slice(); 59.3847 + this.translate = new Transitionable([0, 0, 0]); 59.3848 + this.rotate = new Transitionable([0, 0, 0]); 59.3849 + this.skew = new Transitionable([0, 0, 0]); 59.3850 + this.scale = new Transitionable([1, 1, 1]); 59.3851 + 59.3852 + if (transform) this.set(transform); 59.3853 + } 59.3854 + 59.3855 + function _build() { 59.3856 + return Transform.build({ 59.3857 + translate: this.translate.get(), 59.3858 + rotate: this.rotate.get(), 59.3859 + skew: this.skew.get(), 59.3860 + scale: this.scale.get() 59.3861 + }); 59.3862 + } 59.3863 + 59.3864 + /** 59.3865 + * An optimized way of setting only the translation component of a Transform 59.3866 + * 59.3867 + * @method setTranslate 59.3868 + * @chainable 59.3869 + * 59.3870 + * @param translate {Array} New translation state 59.3871 + * @param [transition] {Object} Transition definition 59.3872 + * @param [callback] {Function} Callback 59.3873 + * @return {TransitionableTransform} 59.3874 + */ 59.3875 + TransitionableTransform.prototype.setTranslate = function setTranslate(translate, transition, callback) { 59.3876 + this.translate.set(translate, transition, callback); 59.3877 + this._final = this._final.slice(); 59.3878 + this._final[12] = translate[0]; 59.3879 + this._final[13] = translate[1]; 59.3880 + if (translate[2] !== undefined) this._final[14] = translate[2]; 59.3881 + return this; 59.3882 + }; 59.3883 + 59.3884 + /** 59.3885 + * An optimized way of setting only the scale component of a Transform 59.3886 + * 59.3887 + * @method setScale 59.3888 + * @chainable 59.3889 + * 59.3890 + * @param scale {Array} New scale state 59.3891 + * @param [transition] {Object} Transition definition 59.3892 + * @param [callback] {Function} Callback 59.3893 + * @return {TransitionableTransform} 59.3894 + */ 59.3895 + TransitionableTransform.prototype.setScale = function setScale(scale, transition, callback) { 59.3896 + this.scale.set(scale, transition, callback); 59.3897 + this._final = this._final.slice(); 59.3898 + this._final[0] = scale[0]; 59.3899 + this._final[5] = scale[1]; 59.3900 + if (scale[2] !== undefined) this._final[10] = scale[2]; 59.3901 + return this; 59.3902 + }; 59.3903 + 59.3904 + /** 59.3905 + * An optimized way of setting only the rotational component of a Transform 59.3906 + * 59.3907 + * @method setRotate 59.3908 + * @chainable 59.3909 + * 59.3910 + * @param eulerAngles {Array} Euler angles for new rotation state 59.3911 + * @param [transition] {Object} Transition definition 59.3912 + * @param [callback] {Function} Callback 59.3913 + * @return {TransitionableTransform} 59.3914 + */ 59.3915 + TransitionableTransform.prototype.setRotate = function setRotate(eulerAngles, transition, callback) { 59.3916 + this.rotate.set(eulerAngles, transition, callback); 59.3917 + this._final = _build.call(this); 59.3918 + this._final = Transform.build({ 59.3919 + translate: this.translate.get(), 59.3920 + rotate: eulerAngles, 59.3921 + scale: this.scale.get(), 59.3922 + skew: this.skew.get() 59.3923 + }); 59.3924 + return this; 59.3925 + }; 59.3926 + 59.3927 + /** 59.3928 + * An optimized way of setting only the skew component of a Transform 59.3929 + * 59.3930 + * @method setSkew 59.3931 + * @chainable 59.3932 + * 59.3933 + * @param skewAngles {Array} New skew state 59.3934 + * @param [transition] {Object} Transition definition 59.3935 + * @param [callback] {Function} Callback 59.3936 + * @return {TransitionableTransform} 59.3937 + */ 59.3938 + TransitionableTransform.prototype.setSkew = function setSkew(skewAngles, transition, callback) { 59.3939 + this.skew.set(skewAngles, transition, callback); 59.3940 + this._final = Transform.build({ 59.3941 + translate: this.translate.get(), 59.3942 + rotate: this.rotate.get(), 59.3943 + scale: this.scale.get(), 59.3944 + skew: skewAngles 59.3945 + }); 59.3946 + return this; 59.3947 + }; 59.3948 + 59.3949 + /** 59.3950 + * Setter for a TransitionableTransform with optional parameters to transition 59.3951 + * between Transforms 59.3952 + * 59.3953 + * @method set 59.3954 + * @chainable 59.3955 + * 59.3956 + * @param transform {Array} New transform state 59.3957 + * @param [transition] {Object} Transition definition 59.3958 + * @param [callback] {Function} Callback 59.3959 + * @return {TransitionableTransform} 59.3960 + */ 59.3961 + TransitionableTransform.prototype.set = function set(transform, transition, callback) { 59.3962 + this._final = transform; 59.3963 + var components = Transform.interpret(transform); 59.3964 + 59.3965 + var _callback = callback ? Utility.after(4, callback) : null; 59.3966 + this.translate.set(components.translate, transition, _callback); 59.3967 + this.rotate.set(components.rotate, transition, _callback); 59.3968 + this.skew.set(components.skew, transition, _callback); 59.3969 + this.scale.set(components.scale, transition, _callback); 59.3970 + return this; 59.3971 + }; 59.3972 + 59.3973 + /** 59.3974 + * Sets the default transition to use for transitioning betwen Transform states 59.3975 + * 59.3976 + * @method setDefaultTransition 59.3977 + * 59.3978 + * @param transition {Object} Transition definition 59.3979 + */ 59.3980 + TransitionableTransform.prototype.setDefaultTransition = function setDefaultTransition(transition) { 59.3981 + this.translate.setDefault(transition); 59.3982 + this.rotate.setDefault(transition); 59.3983 + this.skew.setDefault(transition); 59.3984 + this.scale.setDefault(transition); 59.3985 + }; 59.3986 + 59.3987 + /** 59.3988 + * Getter. Returns the current state of the Transform 59.3989 + * 59.3990 + * @method get 59.3991 + * 59.3992 + * @return {Transform} 59.3993 + */ 59.3994 + TransitionableTransform.prototype.get = function get() { 59.3995 + if (this.isActive()) { 59.3996 + return _build.call(this); 59.3997 + } 59.3998 + else return this._final; 59.3999 + }; 59.4000 + 59.4001 + /** 59.4002 + * Get the destination state of the Transform 59.4003 + * 59.4004 + * @method getFinal 59.4005 + * 59.4006 + * @return Transform {Transform} 59.4007 + */ 59.4008 + TransitionableTransform.prototype.getFinal = function getFinal() { 59.4009 + return this._final; 59.4010 + }; 59.4011 + 59.4012 + /** 59.4013 + * Determine if the TransitionalTransform is currently transitioning 59.4014 + * 59.4015 + * @method isActive 59.4016 + * 59.4017 + * @return {Boolean} 59.4018 + */ 59.4019 + TransitionableTransform.prototype.isActive = function isActive() { 59.4020 + return this.translate.isActive() || this.rotate.isActive() || this.scale.isActive() || this.skew.isActive(); 59.4021 + }; 59.4022 + 59.4023 + /** 59.4024 + * Halts the transition 59.4025 + * 59.4026 + * @method halt 59.4027 + */ 59.4028 + TransitionableTransform.prototype.halt = function halt() { 59.4029 + this._final = this.get(); 59.4030 + this.translate.halt(); 59.4031 + this.rotate.halt(); 59.4032 + this.skew.halt(); 59.4033 + this.scale.halt(); 59.4034 + }; 59.4035 + 59.4036 + module.exports = TransitionableTransform; 59.4037 +}); 59.4038 + 59.4039 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.4040 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.4041 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.4042 + * 59.4043 + * Owner: mark@famo.us 59.4044 + * @license MPL 2.0 59.4045 + * @copyright Famous Industries, Inc. 2014 59.4046 + */ 59.4047 + 59.4048 +define('famous/core/Modifier',['require','exports','module','./Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 59.4049 + var Transform = require('./Transform'); 59.4050 + 59.4051 + /* TODO: remove these dependencies when deprecation complete */ 59.4052 + var Transitionable = require('famous/transitions/Transitionable'); 59.4053 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 59.4054 + 59.4055 + /** 59.4056 + * 59.4057 + * A collection of visual changes to be 59.4058 + * applied to another renderable component. This collection includes a 59.4059 + * transform matrix, an opacity constant, a size, an origin specifier. 59.4060 + * Modifier objects can be added to any RenderNode or object 59.4061 + * capable of displaying renderables. The Modifier's children and descendants 59.4062 + * are transformed by the amounts specified in the Modifier's properties. 59.4063 + * 59.4064 + * @class Modifier 59.4065 + * @constructor 59.4066 + * @param {Object} [options] overrides of default options 59.4067 + * @param {Transform} [options.transform] affine transformation matrix 59.4068 + * @param {Number} [options.opacity] 59.4069 + * @param {Array.Number} [options.origin] origin adjustment 59.4070 + * @param {Array.Number} [options.size] size to apply to descendants 59.4071 + */ 59.4072 + function Modifier(options) { 59.4073 + this._transformGetter = null; 59.4074 + this._opacityGetter = null; 59.4075 + this._originGetter = null; 59.4076 + this._alignGetter = null; 59.4077 + this._sizeGetter = null; 59.4078 + 59.4079 + /* TODO: remove this when deprecation complete */ 59.4080 + this._legacyStates = {}; 59.4081 + 59.4082 + this._output = { 59.4083 + transform: Transform.identity, 59.4084 + opacity: 1, 59.4085 + origin: null, 59.4086 + align: null, 59.4087 + size: null, 59.4088 + target: null 59.4089 + }; 59.4090 + 59.4091 + if (options) { 59.4092 + if (options.transform) this.transformFrom(options.transform); 59.4093 + if (options.opacity !== undefined) this.opacityFrom(options.opacity); 59.4094 + if (options.origin) this.originFrom(options.origin); 59.4095 + if (options.align) this.alignFrom(options.align); 59.4096 + if (options.size) this.sizeFrom(options.size); 59.4097 + } 59.4098 + } 59.4099 + 59.4100 + /** 59.4101 + * Function, object, or static transform matrix which provides the transform. 59.4102 + * This is evaluated on every tick of the engine. 59.4103 + * 59.4104 + * @method transformFrom 59.4105 + * 59.4106 + * @param {Object} transform transform provider object 59.4107 + * @return {Modifier} this 59.4108 + */ 59.4109 + Modifier.prototype.transformFrom = function transformFrom(transform) { 59.4110 + if (transform instanceof Function) this._transformGetter = transform; 59.4111 + else if (transform instanceof Object && transform.get) this._transformGetter = transform.get.bind(transform); 59.4112 + else { 59.4113 + this._transformGetter = null; 59.4114 + this._output.transform = transform; 59.4115 + } 59.4116 + return this; 59.4117 + }; 59.4118 + 59.4119 + /** 59.4120 + * Set function, object, or number to provide opacity, in range [0,1]. 59.4121 + * 59.4122 + * @method opacityFrom 59.4123 + * 59.4124 + * @param {Object} opacity provider object 59.4125 + * @return {Modifier} this 59.4126 + */ 59.4127 + Modifier.prototype.opacityFrom = function opacityFrom(opacity) { 59.4128 + if (opacity instanceof Function) this._opacityGetter = opacity; 59.4129 + else if (opacity instanceof Object && opacity.get) this._opacityGetter = opacity.get.bind(opacity); 59.4130 + else { 59.4131 + this._opacityGetter = null; 59.4132 + this._output.opacity = opacity; 59.4133 + } 59.4134 + return this; 59.4135 + }; 59.4136 + 59.4137 + /** 59.4138 + * Set function, object, or numerical array to provide origin, as [x,y], 59.4139 + * where x and y are in the range [0,1]. 59.4140 + * 59.4141 + * @method originFrom 59.4142 + * 59.4143 + * @param {Object} origin provider object 59.4144 + * @return {Modifier} this 59.4145 + */ 59.4146 + Modifier.prototype.originFrom = function originFrom(origin) { 59.4147 + if (origin instanceof Function) this._originGetter = origin; 59.4148 + else if (origin instanceof Object && origin.get) this._originGetter = origin.get.bind(origin); 59.4149 + else { 59.4150 + this._originGetter = null; 59.4151 + this._output.origin = origin; 59.4152 + } 59.4153 + return this; 59.4154 + }; 59.4155 + 59.4156 + /** 59.4157 + * Set function, object, or numerical array to provide align, as [x,y], 59.4158 + * where x and y are in the range [0,1]. 59.4159 + * 59.4160 + * @method alignFrom 59.4161 + * 59.4162 + * @param {Object} align provider object 59.4163 + * @return {Modifier} this 59.4164 + */ 59.4165 + Modifier.prototype.alignFrom = function alignFrom(align) { 59.4166 + if (align instanceof Function) this._alignGetter = align; 59.4167 + else if (align instanceof Object && align.get) this._alignGetter = align.get.bind(align); 59.4168 + else { 59.4169 + this._alignGetter = null; 59.4170 + this._output.align = align; 59.4171 + } 59.4172 + return this; 59.4173 + }; 59.4174 + 59.4175 + /** 59.4176 + * Set function, object, or numerical array to provide size, as [width, height]. 59.4177 + * 59.4178 + * @method sizeFrom 59.4179 + * 59.4180 + * @param {Object} size provider object 59.4181 + * @return {Modifier} this 59.4182 + */ 59.4183 + Modifier.prototype.sizeFrom = function sizeFrom(size) { 59.4184 + if (size instanceof Function) this._sizeGetter = size; 59.4185 + else if (size instanceof Object && size.get) this._sizeGetter = size.get.bind(size); 59.4186 + else { 59.4187 + this._sizeGetter = null; 59.4188 + this._output.size = size; 59.4189 + } 59.4190 + return this; 59.4191 + }; 59.4192 + 59.4193 + /** 59.4194 + * Deprecated: Prefer transformFrom with static Transform, or use a TransitionableTransform. 59.4195 + * @deprecated 59.4196 + * @method setTransform 59.4197 + * 59.4198 + * @param {Transform} transform Transform to transition to 59.4199 + * @param {Transitionable} transition Valid transitionable object 59.4200 + * @param {Function} callback callback to call after transition completes 59.4201 + * @return {Modifier} this 59.4202 + */ 59.4203 + Modifier.prototype.setTransform = function setTransform(transform, transition, callback) { 59.4204 + if (transition || this._legacyStates.transform) { 59.4205 + if (!this._legacyStates.transform) { 59.4206 + this._legacyStates.transform = new TransitionableTransform(this._output.transform); 59.4207 + } 59.4208 + if (!this._transformGetter) this.transformFrom(this._legacyStates.transform); 59.4209 + 59.4210 + this._legacyStates.transform.set(transform, transition, callback); 59.4211 + return this; 59.4212 + } 59.4213 + else return this.transformFrom(transform); 59.4214 + }; 59.4215 + 59.4216 + /** 59.4217 + * Deprecated: Prefer opacityFrom with static opacity array, or use a Transitionable with that opacity. 59.4218 + * @deprecated 59.4219 + * @method setOpacity 59.4220 + * 59.4221 + * @param {Number} opacity Opacity value to transition to. 59.4222 + * @param {Transitionable} transition Valid transitionable object 59.4223 + * @param {Function} callback callback to call after transition completes 59.4224 + * @return {Modifier} this 59.4225 + */ 59.4226 + Modifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) { 59.4227 + if (transition || this._legacyStates.opacity) { 59.4228 + if (!this._legacyStates.opacity) { 59.4229 + this._legacyStates.opacity = new Transitionable(this._output.opacity); 59.4230 + } 59.4231 + if (!this._opacityGetter) this.opacityFrom(this._legacyStates.opacity); 59.4232 + 59.4233 + return this._legacyStates.opacity.set(opacity, transition, callback); 59.4234 + } 59.4235 + else return this.opacityFrom(opacity); 59.4236 + }; 59.4237 + 59.4238 + /** 59.4239 + * Deprecated: Prefer originFrom with static origin array, or use a Transitionable with that origin. 59.4240 + * @deprecated 59.4241 + * @method setOrigin 59.4242 + * 59.4243 + * @param {Array.Number} origin two element array with values between 0 and 1. 59.4244 + * @param {Transitionable} transition Valid transitionable object 59.4245 + * @param {Function} callback callback to call after transition completes 59.4246 + * @return {Modifier} this 59.4247 + */ 59.4248 + Modifier.prototype.setOrigin = function setOrigin(origin, transition, callback) { 59.4249 + /* TODO: remove this if statement when deprecation complete */ 59.4250 + if (transition || this._legacyStates.origin) { 59.4251 + 59.4252 + if (!this._legacyStates.origin) { 59.4253 + this._legacyStates.origin = new Transitionable(this._output.origin || [0, 0]); 59.4254 + } 59.4255 + if (!this._originGetter) this.originFrom(this._legacyStates.origin); 59.4256 + 59.4257 + this._legacyStates.origin.set(origin, transition, callback); 59.4258 + return this; 59.4259 + } 59.4260 + else return this.originFrom(origin); 59.4261 + }; 59.4262 + 59.4263 + /** 59.4264 + * Deprecated: Prefer alignFrom with static align array, or use a Transitionable with that align. 59.4265 + * @deprecated 59.4266 + * @method setAlign 59.4267 + * 59.4268 + * @param {Array.Number} align two element array with values between 0 and 1. 59.4269 + * @param {Transitionable} transition Valid transitionable object 59.4270 + * @param {Function} callback callback to call after transition completes 59.4271 + * @return {Modifier} this 59.4272 + */ 59.4273 + Modifier.prototype.setAlign = function setAlign(align, transition, callback) { 59.4274 + /* TODO: remove this if statement when deprecation complete */ 59.4275 + if (transition || this._legacyStates.align) { 59.4276 + 59.4277 + if (!this._legacyStates.align) { 59.4278 + this._legacyStates.align = new Transitionable(this._output.align || [0, 0]); 59.4279 + } 59.4280 + if (!this._alignGetter) this.alignFrom(this._legacyStates.align); 59.4281 + 59.4282 + this._legacyStates.align.set(align, transition, callback); 59.4283 + return this; 59.4284 + } 59.4285 + else return this.alignFrom(align); 59.4286 + }; 59.4287 + 59.4288 + /** 59.4289 + * Deprecated: Prefer sizeFrom with static origin array, or use a Transitionable with that size. 59.4290 + * @deprecated 59.4291 + * @method setSize 59.4292 + * @param {Array.Number} size two element array of [width, height] 59.4293 + * @param {Transitionable} transition Valid transitionable object 59.4294 + * @param {Function} callback callback to call after transition completes 59.4295 + * @return {Modifier} this 59.4296 + */ 59.4297 + Modifier.prototype.setSize = function setSize(size, transition, callback) { 59.4298 + if (size && (transition || this._legacyStates.size)) { 59.4299 + if (!this._legacyStates.size) { 59.4300 + this._legacyStates.size = new Transitionable(this._output.size || [0, 0]); 59.4301 + } 59.4302 + if (!this._sizeGetter) this.sizeFrom(this._legacyStates.size); 59.4303 + 59.4304 + this._legacyStates.size.set(size, transition, callback); 59.4305 + return this; 59.4306 + } 59.4307 + else return this.sizeFrom(size); 59.4308 + }; 59.4309 + 59.4310 + /** 59.4311 + * Deprecated: Prefer to stop transform in your provider object. 59.4312 + * @deprecated 59.4313 + * @method halt 59.4314 + */ 59.4315 + Modifier.prototype.halt = function halt() { 59.4316 + if (this._legacyStates.transform) this._legacyStates.transform.halt(); 59.4317 + if (this._legacyStates.opacity) this._legacyStates.opacity.halt(); 59.4318 + if (this._legacyStates.origin) this._legacyStates.origin.halt(); 59.4319 + if (this._legacyStates.align) this._legacyStates.align.halt(); 59.4320 + if (this._legacyStates.size) this._legacyStates.size.halt(); 59.4321 + this._transformGetter = null; 59.4322 + this._opacityGetter = null; 59.4323 + this._originGetter = null; 59.4324 + this._alignGetter = null; 59.4325 + this._sizeGetter = null; 59.4326 + }; 59.4327 + 59.4328 + /** 59.4329 + * Deprecated: Prefer to use your provided transform or output of your transform provider. 59.4330 + * @deprecated 59.4331 + * @method getTransform 59.4332 + * @return {Object} transform provider object 59.4333 + */ 59.4334 + Modifier.prototype.getTransform = function getTransform() { 59.4335 + return this._transformGetter(); 59.4336 + }; 59.4337 + 59.4338 + /** 59.4339 + * Deprecated: Prefer to determine the end state of your transform from your transform provider 59.4340 + * @deprecated 59.4341 + * @method getFinalTransform 59.4342 + * @return {Transform} transform matrix 59.4343 + */ 59.4344 + Modifier.prototype.getFinalTransform = function getFinalTransform() { 59.4345 + return this._legacyStates.transform ? this._legacyStates.transform.getFinal() : this._output.transform; 59.4346 + }; 59.4347 + 59.4348 + /** 59.4349 + * Deprecated: Prefer to use your provided opacity or output of your opacity provider. 59.4350 + * @deprecated 59.4351 + * @method getOpacity 59.4352 + * @return {Object} opacity provider object 59.4353 + */ 59.4354 + Modifier.prototype.getOpacity = function getOpacity() { 59.4355 + return this._opacityGetter(); 59.4356 + }; 59.4357 + 59.4358 + /** 59.4359 + * Deprecated: Prefer to use your provided origin or output of your origin provider. 59.4360 + * @deprecated 59.4361 + * @method getOrigin 59.4362 + * @return {Object} origin provider object 59.4363 + */ 59.4364 + Modifier.prototype.getOrigin = function getOrigin() { 59.4365 + return this._originGetter(); 59.4366 + }; 59.4367 + 59.4368 + /** 59.4369 + * Deprecated: Prefer to use your provided align or output of your align provider. 59.4370 + * @deprecated 59.4371 + * @method getAlign 59.4372 + * @return {Object} align provider object 59.4373 + */ 59.4374 + Modifier.prototype.getAlign = function getAlign() { 59.4375 + return this._alignGetter(); 59.4376 + }; 59.4377 + 59.4378 + /** 59.4379 + * Deprecated: Prefer to use your provided size or output of your size provider. 59.4380 + * @deprecated 59.4381 + * @method getSize 59.4382 + * @return {Object} size provider object 59.4383 + */ 59.4384 + Modifier.prototype.getSize = function getSize() { 59.4385 + return this._sizeGetter ? this._sizeGetter() : this._output.size; 59.4386 + }; 59.4387 + 59.4388 + // call providers on tick to receive render spec elements to apply 59.4389 + function _update() { 59.4390 + if (this._transformGetter) this._output.transform = this._transformGetter(); 59.4391 + if (this._opacityGetter) this._output.opacity = this._opacityGetter(); 59.4392 + if (this._originGetter) this._output.origin = this._originGetter(); 59.4393 + if (this._alignGetter) this._output.align = this._alignGetter(); 59.4394 + if (this._sizeGetter) this._output.size = this._sizeGetter(); 59.4395 + } 59.4396 + 59.4397 + /** 59.4398 + * Return render spec for this Modifier, applying to the provided 59.4399 + * target component. This is similar to render() for Surfaces. 59.4400 + * 59.4401 + * @private 59.4402 + * @method modify 59.4403 + * 59.4404 + * @param {Object} target (already rendered) render spec to 59.4405 + * which to apply the transform. 59.4406 + * @return {Object} render spec for this Modifier, including the 59.4407 + * provided target 59.4408 + */ 59.4409 + Modifier.prototype.modify = function modify(target) { 59.4410 + _update.call(this); 59.4411 + this._output.target = target; 59.4412 + return this._output; 59.4413 + }; 59.4414 + 59.4415 + module.exports = Modifier; 59.4416 +}); 59.4417 + 59.4418 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.4419 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.4420 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.4421 + * 59.4422 + * Owner: mark@famo.us 59.4423 + * @license MPL 2.0 59.4424 + * @copyright Famous Industries, Inc. 2014 59.4425 + */ 59.4426 + 59.4427 +define('famous/core/Scene',['require','exports','module','./Transform','./Modifier','./RenderNode'],function(require, exports, module) { 59.4428 + var Transform = require('./Transform'); 59.4429 + var Modifier = require('./Modifier'); 59.4430 + var RenderNode = require('./RenderNode'); 59.4431 + 59.4432 + /** 59.4433 + * Builds and renders a scene graph based on a declarative structure definition. 59.4434 + * See the Scene examples in the examples distribution (http://github.com/Famous/examples.git). 59.4435 + * 59.4436 + * @class Scene 59.4437 + * @constructor 59.4438 + * @param {Object} definition in the format of a render spec. 59.4439 + */ 59.4440 + function Scene(definition) { 59.4441 + this.id = null; 59.4442 + this._objects = null; 59.4443 + 59.4444 + this.node = new RenderNode(); 59.4445 + this._definition = null; 59.4446 + 59.4447 + if (definition) this.load(definition); 59.4448 + } 59.4449 + 59.4450 + var _MATRIX_GENERATORS = { 59.4451 + 'translate': Transform.translate, 59.4452 + 'rotate': Transform.rotate, 59.4453 + 'rotateX': Transform.rotateX, 59.4454 + 'rotateY': Transform.rotateY, 59.4455 + 'rotateZ': Transform.rotateZ, 59.4456 + 'rotateAxis': Transform.rotateAxis, 59.4457 + 'scale': Transform.scale, 59.4458 + 'skew': Transform.skew, 59.4459 + 'matrix3d': function() { 59.4460 + return arguments; 59.4461 + } 59.4462 + }; 59.4463 + 59.4464 + /** 59.4465 + * Clone this scene 59.4466 + * 59.4467 + * @method create 59.4468 + * @return {Scene} deep copy of this scene 59.4469 + */ 59.4470 + Scene.prototype.create = function create() { 59.4471 + return new Scene(this._definition); 59.4472 + }; 59.4473 + 59.4474 + function _resolveTransformMatrix(matrixDefinition) { 59.4475 + for (var type in _MATRIX_GENERATORS) { 59.4476 + if (type in matrixDefinition) { 59.4477 + var args = matrixDefinition[type]; 59.4478 + if (!(args instanceof Array)) args = [args]; 59.4479 + return _MATRIX_GENERATORS[type].apply(this, args); 59.4480 + } 59.4481 + } 59.4482 + } 59.4483 + 59.4484 + // parse transform into tree of render nodes, doing matrix multiplication 59.4485 + // when available 59.4486 + function _parseTransform(definition) { 59.4487 + var transformDefinition = definition.transform; 59.4488 + var opacity = definition.opacity; 59.4489 + var origin = definition.origin; 59.4490 + var size = definition.size; 59.4491 + var transform = Transform.identity; 59.4492 + if (transformDefinition instanceof Array) { 59.4493 + if (transformDefinition.length === 16 && typeof transformDefinition[0] === 'number') { 59.4494 + transform = transformDefinition; 59.4495 + } 59.4496 + else { 59.4497 + for (var i = 0; i < transformDefinition.length; i++) { 59.4498 + transform = Transform.multiply(transform, _resolveTransformMatrix(transformDefinition[i])); 59.4499 + } 59.4500 + } 59.4501 + } 59.4502 + else if (transformDefinition instanceof Object) { 59.4503 + transform = _resolveTransformMatrix(transformDefinition); 59.4504 + } 59.4505 + 59.4506 + var result = new Modifier({ 59.4507 + transform: transform, 59.4508 + opacity: opacity, 59.4509 + origin: origin, 59.4510 + size: size 59.4511 + }); 59.4512 + return result; 59.4513 + } 59.4514 + 59.4515 + function _parseArray(definition) { 59.4516 + var result = new RenderNode(); 59.4517 + for (var i = 0; i < definition.length; i++) { 59.4518 + var obj = _parse.call(this, definition[i]); 59.4519 + if (obj) result.add(obj); 59.4520 + } 59.4521 + return result; 59.4522 + } 59.4523 + 59.4524 + // parse object directly into tree of RenderNodes 59.4525 + function _parse(definition) { 59.4526 + var result; 59.4527 + var id; 59.4528 + if (definition instanceof Array) { 59.4529 + result = _parseArray.call(this, definition); 59.4530 + } 59.4531 + else { 59.4532 + id = this._objects.length; 59.4533 + if (definition.render && (definition.render instanceof Function)) { 59.4534 + result = definition; 59.4535 + } 59.4536 + else if (definition.target) { 59.4537 + var targetObj = _parse.call(this, definition.target); 59.4538 + var obj = _parseTransform.call(this, definition); 59.4539 + 59.4540 + result = new RenderNode(obj); 59.4541 + result.add(targetObj); 59.4542 + if (definition.id) this.id[definition.id] = obj; 59.4543 + } 59.4544 + else if (definition.id) { 59.4545 + result = new RenderNode(); 59.4546 + this.id[definition.id] = result; 59.4547 + } 59.4548 + } 59.4549 + this._objects[id] = result; 59.4550 + return result; 59.4551 + } 59.4552 + 59.4553 + /** 59.4554 + * Builds and renders a scene graph based on a canonical declarative scene definition. 59.4555 + * See examples/Scene/example.js. 59.4556 + * 59.4557 + * @method load 59.4558 + * @param {Object} definition definition in the format of a render spec. 59.4559 + */ 59.4560 + Scene.prototype.load = function load(definition) { 59.4561 + this._definition = definition; 59.4562 + this.id = {}; 59.4563 + this._objects = []; 59.4564 + this.node.set(_parse.call(this, definition)); 59.4565 + }; 59.4566 + 59.4567 + /** 59.4568 + * Add renderables to this component's render tree 59.4569 + * 59.4570 + * @method add 59.4571 + * 59.4572 + * @param {Object} obj renderable object 59.4573 + * @return {RenderNode} Render wrapping provided object, if not already a RenderNode 59.4574 + */ 59.4575 + Scene.prototype.add = function add() { 59.4576 + return this.node.add.apply(this.node, arguments); 59.4577 + }; 59.4578 + 59.4579 + /** 59.4580 + * Generate a render spec from the contents of this component. 59.4581 + * 59.4582 + * @private 59.4583 + * @method render 59.4584 + * @return {number} Render spec for this component 59.4585 + */ 59.4586 + Scene.prototype.render = function render() { 59.4587 + return this.node.render.apply(this.node, arguments); 59.4588 + }; 59.4589 + 59.4590 + module.exports = Scene; 59.4591 +}); 59.4592 + 59.4593 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.4594 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.4595 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.4596 + * 59.4597 + * Owner: mark@famo.us 59.4598 + * @license MPL 2.0 59.4599 + * @copyright Famous Industries, Inc. 2014 59.4600 + */ 59.4601 + 59.4602 +define('famous/core/View',['require','exports','module','./EventHandler','./OptionsManager','./RenderNode'],function(require, exports, module) { 59.4603 + var EventHandler = require('./EventHandler'); 59.4604 + var OptionsManager = require('./OptionsManager'); 59.4605 + var RenderNode = require('./RenderNode'); 59.4606 + 59.4607 + /** 59.4608 + * Useful for quickly creating elements within applications 59.4609 + * with large event systems. Consists of a RenderNode paired with 59.4610 + * an input EventHandler and an output EventHandler. 59.4611 + * Meant to be extended by the developer. 59.4612 + * 59.4613 + * @class View 59.4614 + * @uses EventHandler 59.4615 + * @uses OptionsManager 59.4616 + * @uses RenderNode 59.4617 + * @constructor 59.4618 + */ 59.4619 + function View(options) { 59.4620 + this._node = new RenderNode(); 59.4621 + 59.4622 + this._eventInput = new EventHandler(); 59.4623 + this._eventOutput = new EventHandler(); 59.4624 + EventHandler.setInputHandler(this, this._eventInput); 59.4625 + EventHandler.setOutputHandler(this, this._eventOutput); 59.4626 + 59.4627 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS || View.DEFAULT_OPTIONS); 59.4628 + this._optionsManager = new OptionsManager(this.options); 59.4629 + 59.4630 + if (options) this.setOptions(options); 59.4631 + } 59.4632 + 59.4633 + View.DEFAULT_OPTIONS = {}; // no defaults 59.4634 + 59.4635 + /** 59.4636 + * Look up options value by key 59.4637 + * @method getOptions 59.4638 + * 59.4639 + * @param {string} key key 59.4640 + * @return {Object} associated object 59.4641 + */ 59.4642 + View.prototype.getOptions = function getOptions() { 59.4643 + return this._optionsManager.value(); 59.4644 + }; 59.4645 + 59.4646 + /* 59.4647 + * Set internal options. 59.4648 + * No defaults options are set in View. 59.4649 + * 59.4650 + * @method setOptions 59.4651 + * @param {Object} options 59.4652 + */ 59.4653 + View.prototype.setOptions = function setOptions(options) { 59.4654 + this._optionsManager.patch(options); 59.4655 + }; 59.4656 + 59.4657 + /** 59.4658 + * Add a child renderable to the view. 59.4659 + * Note: This is meant to be used by an inheriting class 59.4660 + * rather than from outside the prototype chain. 59.4661 + * 59.4662 + * @method add 59.4663 + * @return {RenderNode} 59.4664 + * @protected 59.4665 + */ 59.4666 + View.prototype.add = function add() { 59.4667 + return this._node.add.apply(this._node, arguments); 59.4668 + }; 59.4669 + 59.4670 + /** 59.4671 + * Alias for add 59.4672 + * @method _add 59.4673 + */ 59.4674 + View.prototype._add = View.prototype.add; 59.4675 + 59.4676 + /** 59.4677 + * Generate a render spec from the contents of this component. 59.4678 + * 59.4679 + * @private 59.4680 + * @method render 59.4681 + * @return {number} Render spec for this component 59.4682 + */ 59.4683 + View.prototype.render = function render() { 59.4684 + return this._node.render(); 59.4685 + }; 59.4686 + 59.4687 + /** 59.4688 + * Return size of contained element. 59.4689 + * 59.4690 + * @method getSize 59.4691 + * @return {Array.Number} [width, height] 59.4692 + */ 59.4693 + View.prototype.getSize = function getSize() { 59.4694 + if (this._node && this._node.getSize) { 59.4695 + return this._node.getSize.apply(this._node, arguments) || this.options.size; 59.4696 + } 59.4697 + else return this.options.size; 59.4698 + }; 59.4699 + 59.4700 + module.exports = View; 59.4701 +}); 59.4702 + 59.4703 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.4704 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.4705 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.4706 + * 59.4707 + * Owner: mark@famo.us 59.4708 + * @license MPL 2.0 59.4709 + * @copyright Famous Industries, Inc. 2014 59.4710 + */ 59.4711 + 59.4712 +define('famous/core/ViewSequence',['require','exports','module'],function(require, exports, module) { 59.4713 + 59.4714 + /** 59.4715 + * Helper object used to iterate through items sequentially. Used in 59.4716 + * views that deal with layout. A ViewSequence object conceptually points 59.4717 + * to a node in a linked list. 59.4718 + * 59.4719 + * @class ViewSequence 59.4720 + * 59.4721 + * @constructor 59.4722 + * @param {Object|Array} options Options object, or content array. 59.4723 + * @param {Number} [options.index] starting index. 59.4724 + * @param {Number} [options.array] Array of elements to populate the ViewSequence 59.4725 + * @param {Object} [options._] Optional backing store (internal 59.4726 + * @param {Boolean} [options.loop] Whether to wrap when accessing elements just past the end 59.4727 + * (or beginning) of the sequence. 59.4728 + */ 59.4729 + function ViewSequence(options) { 59.4730 + if (!options) options = []; 59.4731 + if (options instanceof Array) options = {array: options}; 59.4732 + 59.4733 + this._ = null; 59.4734 + this.index = options.index || 0; 59.4735 + 59.4736 + if (options.array) this._ = new (this.constructor.Backing)(options.array); 59.4737 + else if (options._) this._ = options._; 59.4738 + 59.4739 + if (this.index === this._.firstIndex) this._.firstNode = this; 59.4740 + if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this; 59.4741 + 59.4742 + if (options.loop !== undefined) this._.loop = options.loop; 59.4743 + 59.4744 + this._previousNode = null; 59.4745 + this._nextNode = null; 59.4746 + } 59.4747 + 59.4748 + // constructor for internal storage 59.4749 + ViewSequence.Backing = function Backing(array) { 59.4750 + this.array = array; 59.4751 + this.firstIndex = 0; 59.4752 + this.loop = false; 59.4753 + this.firstNode = null; 59.4754 + this.lastNode = null; 59.4755 + }; 59.4756 + 59.4757 + // Get value "i" slots away from the first index. 59.4758 + ViewSequence.Backing.prototype.getValue = function getValue(i) { 59.4759 + var _i = i - this.firstIndex; 59.4760 + if (_i < 0 || _i >= this.array.length) return null; 59.4761 + return this.array[_i]; 59.4762 + }; 59.4763 + 59.4764 + // Set value "i" slots away from the first index. 59.4765 + ViewSequence.Backing.prototype.setValue = function setValue(i, value) { 59.4766 + this.array[i - this.firstIndex] = value; 59.4767 + }; 59.4768 + 59.4769 + // After splicing into the backing store, restore the indexes of each node correctly. 59.4770 + ViewSequence.Backing.prototype.reindex = function reindex(start, removeCount, insertCount) { 59.4771 + if (!this.array[0]) return; 59.4772 + 59.4773 + var i = 0; 59.4774 + var index = this.firstIndex; 59.4775 + var indexShiftAmount = insertCount - removeCount; 59.4776 + var node = this.firstNode; 59.4777 + 59.4778 + // find node to begin 59.4779 + while (index < start - 1) { 59.4780 + node = node.getNext(); 59.4781 + index++; 59.4782 + } 59.4783 + // skip removed nodes 59.4784 + var spliceStartNode = node; 59.4785 + for (i = 0; i < removeCount; i++) { 59.4786 + node = node.getNext(); 59.4787 + if (node) node._previousNode = spliceStartNode; 59.4788 + } 59.4789 + var spliceResumeNode = node ? node.getNext() : null; 59.4790 + // generate nodes for inserted items 59.4791 + spliceStartNode._nextNode = null; 59.4792 + node = spliceStartNode; 59.4793 + for (i = 0; i < insertCount; i++) node = node.getNext(); 59.4794 + index += insertCount; 59.4795 + // resume the chain 59.4796 + if (node !== spliceResumeNode) { 59.4797 + node._nextNode = spliceResumeNode; 59.4798 + if (spliceResumeNode) spliceResumeNode._previousNode = node; 59.4799 + } 59.4800 + if (spliceResumeNode) { 59.4801 + node = spliceResumeNode; 59.4802 + index++; 59.4803 + while (node && index < this.array.length + this.firstIndex) { 59.4804 + if (node._nextNode) node.index += indexShiftAmount; 59.4805 + else node.index = index; 59.4806 + node = node.getNext(); 59.4807 + index++; 59.4808 + } 59.4809 + } 59.4810 + }; 59.4811 + 59.4812 + /** 59.4813 + * Return ViewSequence node previous to this node in the list, respecting looping if applied. 59.4814 + * 59.4815 + * @method getPrevious 59.4816 + * @return {ViewSequence} previous node. 59.4817 + */ 59.4818 + ViewSequence.prototype.getPrevious = function getPrevious() { 59.4819 + if (this.index === this._.firstIndex) { 59.4820 + if (this._.loop) { 59.4821 + this._previousNode = this._.lastNode || new (this.constructor)({_: this._, index: this._.firstIndex + this._.array.length - 1}); 59.4822 + this._previousNode._nextNode = this; 59.4823 + } 59.4824 + else { 59.4825 + this._previousNode = null; 59.4826 + } 59.4827 + } 59.4828 + else if (!this._previousNode) { 59.4829 + this._previousNode = new (this.constructor)({_: this._, index: this.index - 1}); 59.4830 + this._previousNode._nextNode = this; 59.4831 + } 59.4832 + return this._previousNode; 59.4833 + }; 59.4834 + 59.4835 + /** 59.4836 + * Return ViewSequence node next after this node in the list, respecting looping if applied. 59.4837 + * 59.4838 + * @method getNext 59.4839 + * @return {ViewSequence} previous node. 59.4840 + */ 59.4841 + ViewSequence.prototype.getNext = function getNext() { 59.4842 + if (this.index === this._.firstIndex + this._.array.length - 1) { 59.4843 + if (this._.loop) { 59.4844 + this._nextNode = this._.firstNode || new (this.constructor)({_: this._, index: this._.firstIndex}); 59.4845 + this._nextNode._previousNode = this; 59.4846 + } 59.4847 + else { 59.4848 + this._nextNode = null; 59.4849 + } 59.4850 + } 59.4851 + else if (!this._nextNode) { 59.4852 + this._nextNode = new (this.constructor)({_: this._, index: this.index + 1}); 59.4853 + this._nextNode._previousNode = this; 59.4854 + } 59.4855 + return this._nextNode; 59.4856 + }; 59.4857 + 59.4858 + /** 59.4859 + * Return index of this ViewSequence node. 59.4860 + * 59.4861 + * @method getIndex 59.4862 + * @return {Number} index 59.4863 + */ 59.4864 + ViewSequence.prototype.getIndex = function getIndex() { 59.4865 + return this.index; 59.4866 + }; 59.4867 + 59.4868 + /** 59.4869 + * Return printable version of this ViewSequence node. 59.4870 + * 59.4871 + * @method toString 59.4872 + * @return {string} this index as a string 59.4873 + */ 59.4874 + ViewSequence.prototype.toString = function toString() { 59.4875 + return '' + this.index; 59.4876 + }; 59.4877 + 59.4878 + /** 59.4879 + * Add one or more objects to the beginning of the sequence. 59.4880 + * 59.4881 + * @method unshift 59.4882 + * @param {...Object} value arguments array of objects 59.4883 + */ 59.4884 + ViewSequence.prototype.unshift = function unshift(value) { 59.4885 + this._.array.unshift.apply(this._.array, arguments); 59.4886 + this._.firstIndex -= arguments.length; 59.4887 + }; 59.4888 + 59.4889 + /** 59.4890 + * Add one or more objects to the end of the sequence. 59.4891 + * 59.4892 + * @method push 59.4893 + * @param {...Object} value arguments array of objects 59.4894 + */ 59.4895 + ViewSequence.prototype.push = function push(value) { 59.4896 + this._.array.push.apply(this._.array, arguments); 59.4897 + }; 59.4898 + 59.4899 + /** 59.4900 + * Remove objects from the sequence 59.4901 + * 59.4902 + * @method splice 59.4903 + * @param {Number} index starting index for removal 59.4904 + * @param {Number} howMany how many elements to remove 59.4905 + * @param {...Object} value arguments array of objects 59.4906 + */ 59.4907 + ViewSequence.prototype.splice = function splice(index, howMany) { 59.4908 + var values = Array.prototype.slice.call(arguments, 2); 59.4909 + this._.array.splice.apply(this._.array, [index - this._.firstIndex, howMany].concat(values)); 59.4910 + this._.reindex(index, howMany, values.length); 59.4911 + }; 59.4912 + 59.4913 + /** 59.4914 + * Exchange this element's sequence position with another's. 59.4915 + * 59.4916 + * @method swap 59.4917 + * @param {ViewSequence} other element to swap with. 59.4918 + */ 59.4919 + ViewSequence.prototype.swap = function swap(other) { 59.4920 + var otherValue = other.get(); 59.4921 + var myValue = this.get(); 59.4922 + this._.setValue(this.index, otherValue); 59.4923 + this._.setValue(other.index, myValue); 59.4924 + 59.4925 + var myPrevious = this._previousNode; 59.4926 + var myNext = this._nextNode; 59.4927 + var myIndex = this.index; 59.4928 + var otherPrevious = other._previousNode; 59.4929 + var otherNext = other._nextNode; 59.4930 + var otherIndex = other.index; 59.4931 + 59.4932 + this.index = otherIndex; 59.4933 + this._previousNode = (otherPrevious === this) ? other : otherPrevious; 59.4934 + if (this._previousNode) this._previousNode._nextNode = this; 59.4935 + this._nextNode = (otherNext === this) ? other : otherNext; 59.4936 + if (this._nextNode) this._nextNode._previousNode = this; 59.4937 + 59.4938 + other.index = myIndex; 59.4939 + other._previousNode = (myPrevious === other) ? this : myPrevious; 59.4940 + if (other._previousNode) other._previousNode._nextNode = other; 59.4941 + other._nextNode = (myNext === other) ? this : myNext; 59.4942 + if (other._nextNode) other._nextNode._previousNode = other; 59.4943 + 59.4944 + if (this.index === this._.firstIndex) this._.firstNode = this; 59.4945 + else if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this; 59.4946 + if (other.index === this._.firstIndex) this._.firstNode = other; 59.4947 + else if (other.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = other; 59.4948 + }; 59.4949 + 59.4950 + /** 59.4951 + * Return value of this ViewSequence node. 59.4952 + * 59.4953 + * @method get 59.4954 + * @return {Object} value of thiss 59.4955 + */ 59.4956 + ViewSequence.prototype.get = function get() { 59.4957 + return this._.getValue(this.index); 59.4958 + }; 59.4959 + 59.4960 + /** 59.4961 + * Call getSize() on the contained View. 59.4962 + * 59.4963 + * @method getSize 59.4964 + * @return {Array.Number} [width, height] 59.4965 + */ 59.4966 + ViewSequence.prototype.getSize = function getSize() { 59.4967 + var target = this.get(); 59.4968 + return target ? target.getSize() : null; 59.4969 + }; 59.4970 + 59.4971 + /** 59.4972 + * Generate a render spec from the contents of this component. 59.4973 + * Specifically, this will render the value at the current index. 59.4974 + * @private 59.4975 + * @method render 59.4976 + * @return {number} Render spec for this component 59.4977 + */ 59.4978 + ViewSequence.prototype.render = function render() { 59.4979 + var target = this.get(); 59.4980 + return target ? target.render.apply(target, arguments) : null; 59.4981 + }; 59.4982 + 59.4983 + module.exports = ViewSequence; 59.4984 +}); 59.4985 + 59.4986 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.4987 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.4988 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.4989 + * 59.4990 + * Owner: mark@famo.us 59.4991 + * @license MPL 2.0 59.4992 + * @copyright Famous Industries, Inc. 2014 59.4993 + */ 59.4994 + 59.4995 +define('famous/math/Utilities',['require','exports','module'],function(require, exports, module) { 59.4996 + /** 59.4997 + * A few static methods. 59.4998 + * 59.4999 + * @class Utilities 59.5000 + * @static 59.5001 + */ 59.5002 + var Utilities = {}; 59.5003 + 59.5004 + /** 59.5005 + * Constrain input to range. 59.5006 + * 59.5007 + * @method clamp 59.5008 + * @param {Number} value input 59.5009 + * @param {Array.Number} range [min, max] 59.5010 + * @static 59.5011 + */ 59.5012 + Utilities.clamp = function clamp(value, range) { 59.5013 + return Math.max(Math.min(value, range[1]), range[0]); 59.5014 + }; 59.5015 + 59.5016 + /** 59.5017 + * Euclidean length of numerical array. 59.5018 + * 59.5019 + * @method length 59.5020 + * @param {Array.Number} array array of numbers 59.5021 + * @static 59.5022 + */ 59.5023 + Utilities.length = function length(array) { 59.5024 + var distanceSquared = 0; 59.5025 + for (var i = 0; i < array.length; i++) { 59.5026 + distanceSquared += array[i] * array[i]; 59.5027 + } 59.5028 + return Math.sqrt(distanceSquared); 59.5029 + }; 59.5030 + 59.5031 + module.exports = Utilities; 59.5032 +}); 59.5033 + 59.5034 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5035 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.5036 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.5037 + * 59.5038 + * Owner: mark@famo.us 59.5039 + * @license MPL 2.0 59.5040 + * @copyright Famous Industries, Inc. 2014 59.5041 + */ 59.5042 + 59.5043 +define('famous/inputs/GenericSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.5044 + var EventHandler = require('famous/core/EventHandler'); 59.5045 + 59.5046 + /** 59.5047 + * Combines multiple types of sync classes (e.g. mouse, touch, 59.5048 + * scrolling) into one standardized interface for inclusion in widgets. 59.5049 + * 59.5050 + * Sync classes are first registered with a key, and then can be accessed 59.5051 + * globally by key. 59.5052 + * 59.5053 + * Emits 'start', 'update' and 'end' events as a union of the sync class 59.5054 + * providers. 59.5055 + * 59.5056 + * @class GenericSync 59.5057 + * @constructor 59.5058 + * @param syncs {Object|Array} object with fields {sync key : sync options} 59.5059 + * or an array of registered sync keys 59.5060 + * @param [options] {Object|Array} options object to set on all syncs 59.5061 + */ 59.5062 + function GenericSync(syncs, options) { 59.5063 + this._eventInput = new EventHandler(); 59.5064 + this._eventOutput = new EventHandler(); 59.5065 + 59.5066 + EventHandler.setInputHandler(this, this._eventInput); 59.5067 + EventHandler.setOutputHandler(this, this._eventOutput); 59.5068 + 59.5069 + this._syncs = {}; 59.5070 + if (syncs) this.addSync(syncs); 59.5071 + if (options) this.setOptions(options); 59.5072 + } 59.5073 + 59.5074 + GenericSync.DIRECTION_X = 0; 59.5075 + GenericSync.DIRECTION_Y = 1; 59.5076 + GenericSync.DIRECTION_Z = 2; 59.5077 + 59.5078 + // Global registry of sync classes. Append only. 59.5079 + var registry = {}; 59.5080 + 59.5081 + /** 59.5082 + * Register a global sync class with an identifying key 59.5083 + * 59.5084 + * @static 59.5085 + * @method register 59.5086 + * 59.5087 + * @param syncObject {Object} an object of {sync key : sync options} fields 59.5088 + */ 59.5089 + GenericSync.register = function register(syncObject) { 59.5090 + for (var key in syncObject){ 59.5091 + if (registry[key]){ 59.5092 + if (registry[key] === syncObject[key]) return; // redundant registration 59.5093 + else throw new Error('this key is registered to a different sync class'); 59.5094 + } 59.5095 + else registry[key] = syncObject[key]; 59.5096 + } 59.5097 + }; 59.5098 + 59.5099 + /** 59.5100 + * Helper to set options on all sync instances 59.5101 + * 59.5102 + * @method setOptions 59.5103 + * @param options {Object} options object 59.5104 + */ 59.5105 + GenericSync.prototype.setOptions = function(options) { 59.5106 + for (var key in this._syncs){ 59.5107 + this._syncs[key].setOptions(options); 59.5108 + } 59.5109 + }; 59.5110 + 59.5111 + /** 59.5112 + * Pipe events to a sync class 59.5113 + * 59.5114 + * @method pipeSync 59.5115 + * @param key {String} identifier for sync class 59.5116 + */ 59.5117 + GenericSync.prototype.pipeSync = function pipeToSync(key) { 59.5118 + var sync = this._syncs[key]; 59.5119 + this._eventInput.pipe(sync); 59.5120 + sync.pipe(this._eventOutput); 59.5121 + }; 59.5122 + 59.5123 + /** 59.5124 + * Unpipe events from a sync class 59.5125 + * 59.5126 + * @method unpipeSync 59.5127 + * @param key {String} identifier for sync class 59.5128 + */ 59.5129 + GenericSync.prototype.unpipeSync = function unpipeFromSync(key) { 59.5130 + var sync = this._syncs[key]; 59.5131 + this._eventInput.unpipe(sync); 59.5132 + sync.unpipe(this._eventOutput); 59.5133 + }; 59.5134 + 59.5135 + function _addSingleSync(key, options) { 59.5136 + if (!registry[key]) return; 59.5137 + this._syncs[key] = new (registry[key])(options); 59.5138 + this.pipeSync(key); 59.5139 + } 59.5140 + 59.5141 + /** 59.5142 + * Add a sync class to from the registered classes 59.5143 + * 59.5144 + * @method addSync 59.5145 + * @param syncs {Object|Array.String} an array of registered sync keys 59.5146 + * or an object with fields {sync key : sync options} 59.5147 + */ 59.5148 + GenericSync.prototype.addSync = function addSync(syncs) { 59.5149 + if (syncs instanceof Array) 59.5150 + for (var i = 0; i < syncs.length; i++) 59.5151 + _addSingleSync.call(this, syncs[i]); 59.5152 + else if (syncs instanceof Object) 59.5153 + for (var key in syncs) 59.5154 + _addSingleSync.call(this, key, syncs[key]); 59.5155 + }; 59.5156 + 59.5157 + module.exports = GenericSync; 59.5158 +}); 59.5159 + 59.5160 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5161 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.5162 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.5163 + * 59.5164 + * Owner: mark@famo.us 59.5165 + * @license MPL 2.0 59.5166 + * @copyright Famous Industries, Inc. 2014 59.5167 + */ 59.5168 + 59.5169 +define('famous/inputs/MouseSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.5170 + var EventHandler = require('famous/core/EventHandler'); 59.5171 + 59.5172 + /** 59.5173 + * Handles piped in mouse drag events. Outputs an object with two 59.5174 + * properties, position and velocity. 59.5175 + * Emits 'start', 'update' and 'end' events with DOM event passthroughs, 59.5176 + * with position, velocity, and a delta key. 59.5177 + * 59.5178 + * @class MouseSync 59.5179 + * @constructor 59.5180 + * 59.5181 + * @param [options] {Object} default options overrides 59.5182 + * @param [options.direction] {Number} read from a particular axis 59.5183 + * @param [options.rails] {Boolean} read from axis with greatest differential 59.5184 + * @param [options.propogate] {Boolean} add listened to document on mouseleave 59.5185 + */ 59.5186 + function MouseSync(options) { 59.5187 + this.options = Object.create(MouseSync.DEFAULT_OPTIONS); 59.5188 + if (options) this.setOptions(options); 59.5189 + 59.5190 + this._eventInput = new EventHandler(); 59.5191 + this._eventOutput = new EventHandler(); 59.5192 + 59.5193 + EventHandler.setInputHandler(this, this._eventInput); 59.5194 + EventHandler.setOutputHandler(this, this._eventOutput); 59.5195 + 59.5196 + this._eventInput.on('mousedown', _handleStart.bind(this)); 59.5197 + this._eventInput.on('mousemove', _handleMove.bind(this)); 59.5198 + this._eventInput.on('mouseup', _handleEnd.bind(this)); 59.5199 + 59.5200 + if (this.options.propogate) this._eventInput.on('mouseleave', _handleLeave.bind(this)); 59.5201 + else this._eventInput.on('mouseleave', _handleEnd.bind(this)); 59.5202 + 59.5203 + this._payload = { 59.5204 + delta : null, 59.5205 + position : null, 59.5206 + velocity : null, 59.5207 + clientX : 0, 59.5208 + clientY : 0, 59.5209 + offsetX : 0, 59.5210 + offsetY : 0 59.5211 + }; 59.5212 + 59.5213 + this._position = null; // to be deprecated 59.5214 + this._prevCoord = undefined; 59.5215 + this._prevTime = undefined; 59.5216 + this._down = false; 59.5217 + this._moved = false; 59.5218 + } 59.5219 + 59.5220 + MouseSync.DEFAULT_OPTIONS = { 59.5221 + direction: undefined, 59.5222 + rails: false, 59.5223 + scale: 1, 59.5224 + propogate: true // events piped to document on mouseleave 59.5225 + }; 59.5226 + 59.5227 + MouseSync.DIRECTION_X = 0; 59.5228 + MouseSync.DIRECTION_Y = 1; 59.5229 + 59.5230 + var MINIMUM_TICK_TIME = 8; 59.5231 + 59.5232 + var _now = Date.now; 59.5233 + 59.5234 + function _handleStart(event) { 59.5235 + var delta; 59.5236 + var velocity; 59.5237 + event.preventDefault(); // prevent drag 59.5238 + 59.5239 + var x = event.clientX; 59.5240 + var y = event.clientY; 59.5241 + 59.5242 + this._prevCoord = [x, y]; 59.5243 + this._prevTime = _now(); 59.5244 + this._down = true; 59.5245 + this._move = false; 59.5246 + 59.5247 + if (this.options.direction !== undefined){ 59.5248 + this._position = 0; 59.5249 + delta = 0; 59.5250 + velocity = 0; 59.5251 + } 59.5252 + else { 59.5253 + this._position = [0, 0]; 59.5254 + delta = [0, 0]; 59.5255 + velocity = [0, 0]; 59.5256 + } 59.5257 + 59.5258 + var payload = this._payload; 59.5259 + payload.delta = delta; 59.5260 + payload.position = this._position; 59.5261 + payload.velocity = velocity; 59.5262 + payload.clientX = x; 59.5263 + payload.clientY = y; 59.5264 + payload.offsetX = event.offsetX; 59.5265 + payload.offsetY = event.offsetY; 59.5266 + 59.5267 + this._eventOutput.emit('start', payload); 59.5268 + } 59.5269 + 59.5270 + function _handleMove(event) { 59.5271 + if (!this._prevCoord) return; 59.5272 + 59.5273 + var prevCoord = this._prevCoord; 59.5274 + var prevTime = this._prevTime; 59.5275 + 59.5276 + var x = event.clientX; 59.5277 + var y = event.clientY; 59.5278 + 59.5279 + var currTime = _now(); 59.5280 + 59.5281 + var diffX = x - prevCoord[0]; 59.5282 + var diffY = y - prevCoord[1]; 59.5283 + 59.5284 + if (this.options.rails) { 59.5285 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 59.5286 + else diffX = 0; 59.5287 + } 59.5288 + 59.5289 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time 59.5290 + 59.5291 + var velX = diffX / diffTime; 59.5292 + var velY = diffY / diffTime; 59.5293 + 59.5294 + var scale = this.options.scale; 59.5295 + var nextVel; 59.5296 + var nextDelta; 59.5297 + 59.5298 + if (this.options.direction === MouseSync.DIRECTION_X) { 59.5299 + nextDelta = scale * diffX; 59.5300 + nextVel = scale * velX; 59.5301 + this._position += nextDelta; 59.5302 + } 59.5303 + else if (this.options.direction === MouseSync.DIRECTION_Y) { 59.5304 + nextDelta = scale * diffY; 59.5305 + nextVel = scale * velY; 59.5306 + this._position += nextDelta; 59.5307 + } 59.5308 + else { 59.5309 + nextDelta = [scale * diffX, scale * diffY]; 59.5310 + nextVel = [scale * velX, scale * velY]; 59.5311 + this._position[0] += nextDelta[0]; 59.5312 + this._position[1] += nextDelta[1]; 59.5313 + } 59.5314 + 59.5315 + var payload = this._payload; 59.5316 + payload.delta = nextDelta; 59.5317 + payload.position = this._position; 59.5318 + payload.velocity = nextVel; 59.5319 + payload.clientX = x; 59.5320 + payload.clientY = y; 59.5321 + payload.offsetX = event.offsetX; 59.5322 + payload.offsetY = event.offsetY; 59.5323 + 59.5324 + this._eventOutput.emit('update', payload); 59.5325 + 59.5326 + this._prevCoord = [x, y]; 59.5327 + this._prevTime = currTime; 59.5328 + this._move = true; 59.5329 + } 59.5330 + 59.5331 + function _handleEnd(event) { 59.5332 + if (!this._down) return; 59.5333 + 59.5334 + this._eventOutput.emit('end', this._payload); 59.5335 + this._prevCoord = undefined; 59.5336 + this._prevTime = undefined; 59.5337 + this._down = false; 59.5338 + this._move = false; 59.5339 + } 59.5340 + 59.5341 + function _handleLeave(event) { 59.5342 + if (!this._down || !this._move) return; 59.5343 + 59.5344 + var boundMove = _handleMove.bind(this); 59.5345 + var boundEnd = function(event) { 59.5346 + _handleEnd.call(this, event); 59.5347 + document.removeEventListener('mousemove', boundMove); 59.5348 + document.removeEventListener('mouseup', boundEnd); 59.5349 + }.bind(this, event); 59.5350 + 59.5351 + document.addEventListener('mousemove', boundMove); 59.5352 + document.addEventListener('mouseup', boundEnd); 59.5353 + } 59.5354 + 59.5355 + /** 59.5356 + * Return entire options dictionary, including defaults. 59.5357 + * 59.5358 + * @method getOptions 59.5359 + * @return {Object} configuration options 59.5360 + */ 59.5361 + MouseSync.prototype.getOptions = function getOptions() { 59.5362 + return this.options; 59.5363 + }; 59.5364 + 59.5365 + /** 59.5366 + * Set internal options, overriding any default options 59.5367 + * 59.5368 + * @method setOptions 59.5369 + * 59.5370 + * @param [options] {Object} default options overrides 59.5371 + * @param [options.direction] {Number} read from a particular axis 59.5372 + * @param [options.rails] {Boolean} read from axis with greatest differential 59.5373 + * @param [options.propogate] {Boolean} add listened to document on mouseleave 59.5374 + */ 59.5375 + MouseSync.prototype.setOptions = function setOptions(options) { 59.5376 + if (options.direction !== undefined) this.options.direction = options.direction; 59.5377 + if (options.rails !== undefined) this.options.rails = options.rails; 59.5378 + if (options.scale !== undefined) this.options.scale = options.scale; 59.5379 + if (options.propogate !== undefined) this.options.propogate = options.propogate; 59.5380 + }; 59.5381 + 59.5382 + module.exports = MouseSync; 59.5383 +}); 59.5384 + 59.5385 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5386 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.5387 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.5388 + * 59.5389 + * Owner: mark@famo.us 59.5390 + * @license MPL 2.0 59.5391 + * @copyright Famous Industries, Inc. 2014 59.5392 + */ 59.5393 + 59.5394 +define('famous/inputs/TouchTracker',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.5395 + var EventHandler = require('famous/core/EventHandler'); 59.5396 + 59.5397 + var _now = Date.now; 59.5398 + 59.5399 + function _timestampTouch(touch, event, history) { 59.5400 + return { 59.5401 + x: touch.clientX, 59.5402 + y: touch.clientY, 59.5403 + identifier : touch.identifier, 59.5404 + origin: event.origin, 59.5405 + timestamp: _now(), 59.5406 + count: event.touches.length, 59.5407 + history: history 59.5408 + }; 59.5409 + } 59.5410 + 59.5411 + function _handleStart(event) { 59.5412 + for (var i = 0; i < event.changedTouches.length; i++) { 59.5413 + var touch = event.changedTouches[i]; 59.5414 + var data = _timestampTouch(touch, event, null); 59.5415 + this.eventOutput.emit('trackstart', data); 59.5416 + if (!this.selective && !this.touchHistory[touch.identifier]) this.track(data); 59.5417 + } 59.5418 + } 59.5419 + 59.5420 + function _handleMove(event) { 59.5421 + for (var i = 0; i < event.changedTouches.length; i++) { 59.5422 + var touch = event.changedTouches[i]; 59.5423 + var history = this.touchHistory[touch.identifier]; 59.5424 + if (history) { 59.5425 + var data = _timestampTouch(touch, event, history); 59.5426 + this.touchHistory[touch.identifier].push(data); 59.5427 + this.eventOutput.emit('trackmove', data); 59.5428 + } 59.5429 + } 59.5430 + } 59.5431 + 59.5432 + function _handleEnd(event) { 59.5433 + for (var i = 0; i < event.changedTouches.length; i++) { 59.5434 + var touch = event.changedTouches[i]; 59.5435 + var history = this.touchHistory[touch.identifier]; 59.5436 + if (history) { 59.5437 + var data = _timestampTouch(touch, event, history); 59.5438 + this.eventOutput.emit('trackend', data); 59.5439 + delete this.touchHistory[touch.identifier]; 59.5440 + } 59.5441 + } 59.5442 + } 59.5443 + 59.5444 + function _handleUnpipe() { 59.5445 + for (var i in this.touchHistory) { 59.5446 + var history = this.touchHistory[i]; 59.5447 + this.eventOutput.emit('trackend', { 59.5448 + touch: history[history.length - 1].touch, 59.5449 + timestamp: Date.now(), 59.5450 + count: 0, 59.5451 + history: history 59.5452 + }); 59.5453 + delete this.touchHistory[i]; 59.5454 + } 59.5455 + } 59.5456 + 59.5457 + /** 59.5458 + * Helper to TouchSync – tracks piped in touch events, organizes touch 59.5459 + * events by ID, and emits track events back to TouchSync. 59.5460 + * Emits 'trackstart', 'trackmove', and 'trackend' events upstream. 59.5461 + * 59.5462 + * @class TouchTracker 59.5463 + * @constructor 59.5464 + * @param {Boolean} selective if false, save state for each touch. 59.5465 + */ 59.5466 + function TouchTracker(selective) { 59.5467 + this.selective = selective; 59.5468 + this.touchHistory = {}; 59.5469 + 59.5470 + this.eventInput = new EventHandler(); 59.5471 + this.eventOutput = new EventHandler(); 59.5472 + 59.5473 + EventHandler.setInputHandler(this, this.eventInput); 59.5474 + EventHandler.setOutputHandler(this, this.eventOutput); 59.5475 + 59.5476 + this.eventInput.on('touchstart', _handleStart.bind(this)); 59.5477 + this.eventInput.on('touchmove', _handleMove.bind(this)); 59.5478 + this.eventInput.on('touchend', _handleEnd.bind(this)); 59.5479 + this.eventInput.on('touchcancel', _handleEnd.bind(this)); 59.5480 + this.eventInput.on('unpipe', _handleUnpipe.bind(this)); 59.5481 + } 59.5482 + 59.5483 + /** 59.5484 + * Record touch data, if selective is false. 59.5485 + * @private 59.5486 + * @method track 59.5487 + * @param {Object} data touch data 59.5488 + */ 59.5489 + TouchTracker.prototype.track = function track(data) { 59.5490 + this.touchHistory[data.identifier] = [data]; 59.5491 + }; 59.5492 + 59.5493 + module.exports = TouchTracker; 59.5494 +}); 59.5495 + 59.5496 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5497 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.5498 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.5499 + * 59.5500 + * Owner: mark@famo.us 59.5501 + * @license MPL 2.0 59.5502 + * @copyright Famous Industries, Inc. 2014 59.5503 + */ 59.5504 + 59.5505 +define('famous/inputs/TouchSync',['require','exports','module','./TouchTracker','famous/core/EventHandler'],function(require, exports, module) { 59.5506 + var TouchTracker = require('./TouchTracker'); 59.5507 + var EventHandler = require('famous/core/EventHandler'); 59.5508 + 59.5509 + /** 59.5510 + * Handles piped in touch events. Emits 'start', 'update', and 'events' 59.5511 + * events with position, velocity, acceleration, and touch id. 59.5512 + * Useful for dealing with inputs on touch devices. 59.5513 + * 59.5514 + * 59.5515 + * @class TouchSync 59.5516 + * @constructor 59.5517 + * 59.5518 + * @param [options] {Object} default options overrides 59.5519 + * @param [options.direction] {Number} read from a particular axis 59.5520 + * @param [options.rails] {Boolean} read from axis with greatest differential 59.5521 + * @param [options.scale] {Number} constant factor to scale velocity output 59.5522 + */ 59.5523 + function TouchSync(options) { 59.5524 + this.options = Object.create(TouchSync.DEFAULT_OPTIONS); 59.5525 + if (options) this.setOptions(options); 59.5526 + 59.5527 + this._eventOutput = new EventHandler(); 59.5528 + this._touchTracker = new TouchTracker(); 59.5529 + 59.5530 + EventHandler.setOutputHandler(this, this._eventOutput); 59.5531 + EventHandler.setInputHandler(this, this._touchTracker); 59.5532 + 59.5533 + this._touchTracker.on('trackstart', _handleStart.bind(this)); 59.5534 + this._touchTracker.on('trackmove', _handleMove.bind(this)); 59.5535 + this._touchTracker.on('trackend', _handleEnd.bind(this)); 59.5536 + 59.5537 + this._payload = { 59.5538 + delta : null, 59.5539 + position : null, 59.5540 + velocity : null, 59.5541 + clientX : undefined, 59.5542 + clientY : undefined, 59.5543 + count : 0, 59.5544 + touch : undefined 59.5545 + }; 59.5546 + 59.5547 + this._position = null; // to be deprecated 59.5548 + } 59.5549 + 59.5550 + TouchSync.DEFAULT_OPTIONS = { 59.5551 + direction: undefined, 59.5552 + rails: false, 59.5553 + scale: 1 59.5554 + }; 59.5555 + 59.5556 + TouchSync.DIRECTION_X = 0; 59.5557 + TouchSync.DIRECTION_Y = 1; 59.5558 + 59.5559 + var MINIMUM_TICK_TIME = 8; 59.5560 + 59.5561 + // handle 'trackstart' 59.5562 + function _handleStart(data) { 59.5563 + var velocity; 59.5564 + var delta; 59.5565 + if (this.options.direction !== undefined){ 59.5566 + this._position = 0; 59.5567 + velocity = 0; 59.5568 + delta = 0; 59.5569 + } 59.5570 + else { 59.5571 + this._position = [0, 0]; 59.5572 + velocity = [0, 0]; 59.5573 + delta = [0, 0]; 59.5574 + } 59.5575 + 59.5576 + var payload = this._payload; 59.5577 + payload.delta = delta; 59.5578 + payload.position = this._position; 59.5579 + payload.velocity = velocity; 59.5580 + payload.clientX = data.x; 59.5581 + payload.clientY = data.y; 59.5582 + payload.count = data.count; 59.5583 + payload.touch = data.identifier; 59.5584 + 59.5585 + this._eventOutput.emit('start', payload); 59.5586 + } 59.5587 + 59.5588 + // handle 'trackmove' 59.5589 + function _handleMove(data) { 59.5590 + var history = data.history; 59.5591 + 59.5592 + var currHistory = history[history.length - 1]; 59.5593 + var prevHistory = history[history.length - 2]; 59.5594 + 59.5595 + var prevTime = prevHistory.timestamp; 59.5596 + var currTime = currHistory.timestamp; 59.5597 + 59.5598 + var diffX = currHistory.x - prevHistory.x; 59.5599 + var diffY = currHistory.y - prevHistory.y; 59.5600 + 59.5601 + if (this.options.rails) { 59.5602 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 59.5603 + else diffX = 0; 59.5604 + } 59.5605 + 59.5606 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); 59.5607 + 59.5608 + var velX = diffX / diffTime; 59.5609 + var velY = diffY / diffTime; 59.5610 + 59.5611 + var scale = this.options.scale; 59.5612 + var nextVel; 59.5613 + var nextDelta; 59.5614 + 59.5615 + if (this.options.direction === TouchSync.DIRECTION_X) { 59.5616 + nextDelta = scale * diffX; 59.5617 + nextVel = scale * velX; 59.5618 + this._position += nextDelta; 59.5619 + } 59.5620 + else if (this.options.direction === TouchSync.DIRECTION_Y) { 59.5621 + nextDelta = scale * diffY; 59.5622 + nextVel = scale * velY; 59.5623 + this._position += nextDelta; 59.5624 + } 59.5625 + else { 59.5626 + nextDelta = [scale * diffX, scale * diffY]; 59.5627 + nextVel = [scale * velX, scale * velY]; 59.5628 + this._position[0] += nextDelta[0]; 59.5629 + this._position[1] += nextDelta[1]; 59.5630 + } 59.5631 + 59.5632 + var payload = this._payload; 59.5633 + payload.delta = nextDelta; 59.5634 + payload.velocity = nextVel; 59.5635 + payload.position = this._position; 59.5636 + payload.clientX = data.x; 59.5637 + payload.clientY = data.y; 59.5638 + payload.count = data.count; 59.5639 + payload.touch = data.identifier; 59.5640 + 59.5641 + this._eventOutput.emit('update', payload); 59.5642 + } 59.5643 + 59.5644 + // handle 'trackend' 59.5645 + function _handleEnd(data) { 59.5646 + this._payload.count = data.count; 59.5647 + this._eventOutput.emit('end', this._payload); 59.5648 + } 59.5649 + 59.5650 + /** 59.5651 + * Set internal options, overriding any default options 59.5652 + * 59.5653 + * @method setOptions 59.5654 + * 59.5655 + * @param [options] {Object} default options overrides 59.5656 + * @param [options.direction] {Number} read from a particular axis 59.5657 + * @param [options.rails] {Boolean} read from axis with greatest differential 59.5658 + * @param [options.scale] {Number} constant factor to scale velocity output 59.5659 + */ 59.5660 + TouchSync.prototype.setOptions = function setOptions(options) { 59.5661 + if (options.direction !== undefined) this.options.direction = options.direction; 59.5662 + if (options.rails !== undefined) this.options.rails = options.rails; 59.5663 + if (options.scale !== undefined) this.options.scale = options.scale; 59.5664 + }; 59.5665 + 59.5666 + /** 59.5667 + * Return entire options dictionary, including defaults. 59.5668 + * 59.5669 + * @method getOptions 59.5670 + * @return {Object} configuration options 59.5671 + */ 59.5672 + TouchSync.prototype.getOptions = function getOptions() { 59.5673 + return this.options; 59.5674 + }; 59.5675 + 59.5676 + module.exports = TouchSync; 59.5677 +}); 59.5678 + 59.5679 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.5680 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.5681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.5682 + * 59.5683 + * Owner: david@famo.us 59.5684 + * @license MPL 2.0 59.5685 + * @copyright Famous Industries, Inc. 2014 59.5686 + */ 59.5687 + 59.5688 +define('famous/modifiers/Draggable',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/EventHandler','famous/math/Utilities','famous/inputs/GenericSync','famous/inputs/MouseSync','famous/inputs/TouchSync'],function(require, exports, module) { 59.5689 + var Transform = require('famous/core/Transform'); 59.5690 + var Transitionable = require('famous/transitions/Transitionable'); 59.5691 + var EventHandler = require('famous/core/EventHandler'); 59.5692 + var Utilities = require('famous/math/Utilities'); 59.5693 + 59.5694 + var GenericSync = require('famous/inputs/GenericSync'); 59.5695 + var MouseSync = require('famous/inputs/MouseSync'); 59.5696 + var TouchSync = require('famous/inputs/TouchSync'); 59.5697 + GenericSync.register({'mouse': MouseSync, 'touch': TouchSync}); 59.5698 + 59.5699 + /** 59.5700 + * Makes added render nodes responsive to drag beahvior. 59.5701 + * Emits events 'start', 'update', 'end'. 59.5702 + * @class Draggable 59.5703 + * @constructor 59.5704 + * @param {Object} [options] options configuration object. 59.5705 + * @param {Number} [options.snapX] grid width for snapping during drag 59.5706 + * @param {Number} [options.snapY] grid height for snapping during drag 59.5707 + * @param {Array.Number} [options.xRange] maxmimum [negative, positive] x displacement from start of drag 59.5708 + * @param {Array.Number} [options.yRange] maxmimum [negative, positive] y displacement from start of drag 59.5709 + * @param {Number} [options.scale] one pixel of input motion translates to this many pixels of output drag motion 59.5710 + * @param {Number} [options.projection] User should set to Draggable._direction.x or 59.5711 + * Draggable._direction.y to constrain to one axis. 59.5712 + * 59.5713 + */ 59.5714 + function Draggable(options) { 59.5715 + this.options = Object.create(Draggable.DEFAULT_OPTIONS); 59.5716 + if (options) this.setOptions(options); 59.5717 + 59.5718 + this._positionState = new Transitionable([0,0]); 59.5719 + this._differential = [0,0]; 59.5720 + this._active = true; 59.5721 + 59.5722 + this.sync = new GenericSync(['mouse', 'touch'], {scale : this.options.scale}); 59.5723 + this.eventOutput = new EventHandler(); 59.5724 + EventHandler.setInputHandler(this, this.sync); 59.5725 + EventHandler.setOutputHandler(this, this.eventOutput); 59.5726 + 59.5727 + _bindEvents.call(this); 59.5728 + } 59.5729 + 59.5730 + //binary representation of directions for bitwise operations 59.5731 + var _direction = { 59.5732 + x : 0x01, //001 59.5733 + y : 0x02 //010 59.5734 + }; 59.5735 + 59.5736 + Draggable.DIRECTION_X = _direction.x; 59.5737 + Draggable.DIRECTION_Y = _direction.y; 59.5738 + 59.5739 + var _clamp = Utilities.clamp; 59.5740 + 59.5741 + Draggable.DEFAULT_OPTIONS = { 59.5742 + projection : _direction.x | _direction.y, 59.5743 + scale : 1, 59.5744 + xRange : null, 59.5745 + yRange : null, 59.5746 + snapX : 0, 59.5747 + snapY : 0, 59.5748 + transition : {duration : 0} 59.5749 + }; 59.5750 + 59.5751 + function _mapDifferential(differential) { 59.5752 + var opts = this.options; 59.5753 + var projection = opts.projection; 59.5754 + var snapX = opts.snapX; 59.5755 + var snapY = opts.snapY; 59.5756 + 59.5757 + //axes 59.5758 + var tx = (projection & _direction.x) ? differential[0] : 0; 59.5759 + var ty = (projection & _direction.y) ? differential[1] : 0; 59.5760 + 59.5761 + //snapping 59.5762 + if (snapX > 0) tx -= tx % snapX; 59.5763 + if (snapY > 0) ty -= ty % snapY; 59.5764 + 59.5765 + return [tx, ty]; 59.5766 + } 59.5767 + 59.5768 + function _handleStart() { 59.5769 + if (!this._active) return; 59.5770 + if (this._positionState.isActive()) this._positionState.halt(); 59.5771 + this.eventOutput.emit('start', {position : this.getPosition()}); 59.5772 + } 59.5773 + 59.5774 + function _handleMove(event) { 59.5775 + if (!this._active) return; 59.5776 + 59.5777 + var options = this.options; 59.5778 + this._differential = event.position; 59.5779 + var newDifferential = _mapDifferential.call(this, this._differential); 59.5780 + 59.5781 + //buffer the differential if snapping is set 59.5782 + this._differential[0] -= newDifferential[0]; 59.5783 + this._differential[1] -= newDifferential[1]; 59.5784 + 59.5785 + var pos = this.getPosition(); 59.5786 + 59.5787 + //modify position, retain reference 59.5788 + pos[0] += newDifferential[0]; 59.5789 + pos[1] += newDifferential[1]; 59.5790 + 59.5791 + //handle bounding box 59.5792 + if (options.xRange){ 59.5793 + var xRange = [options.xRange[0] + 0.5 * options.snapX, options.xRange[1] - 0.5 * options.snapX]; 59.5794 + pos[0] = _clamp(pos[0], xRange); 59.5795 + } 59.5796 + 59.5797 + if (options.yRange){ 59.5798 + var yRange = [options.yRange[0] + 0.5 * options.snapY, options.yRange[1] - 0.5 * options.snapY]; 59.5799 + pos[1] = _clamp(pos[1], yRange); 59.5800 + } 59.5801 + 59.5802 + this.eventOutput.emit('update', {position : pos}); 59.5803 + } 59.5804 + 59.5805 + function _handleEnd() { 59.5806 + if (!this._active) return; 59.5807 + this.eventOutput.emit('end', {position : this.getPosition()}); 59.5808 + } 59.5809 + 59.5810 + function _bindEvents() { 59.5811 + this.sync.on('start', _handleStart.bind(this)); 59.5812 + this.sync.on('update', _handleMove.bind(this)); 59.5813 + this.sync.on('end', _handleEnd.bind(this)); 59.5814 + } 59.5815 + 59.5816 + /** 59.5817 + * Set internal options, overriding any default options 59.5818 + * 59.5819 + * @method setOptions 59.5820 + * 59.5821 + * @param {Object} [options] overrides of default options. See constructor. 59.5822 + */ 59.5823 + Draggable.prototype.setOptions = function setOptions(options) { 59.5824 + var currentOptions = this.options; 59.5825 + if (options.projection !== undefined) { 59.5826 + var proj = options.projection; 59.5827 + this.options.projection = 0; 59.5828 + ['x', 'y'].forEach(function(val) { 59.5829 + if (proj.indexOf(val) !== -1) currentOptions.projection |= _direction[val]; 59.5830 + }); 59.5831 + } 59.5832 + if (options.scale !== undefined) { 59.5833 + currentOptions.scale = options.scale; 59.5834 + this.sync.setOptions({ 59.5835 + scale: options.scale 59.5836 + }); 59.5837 + } 59.5838 + if (options.xRange !== undefined) currentOptions.xRange = options.xRange; 59.5839 + if (options.yRange !== undefined) currentOptions.yRange = options.yRange; 59.5840 + if (options.snapX !== undefined) currentOptions.snapX = options.snapX; 59.5841 + if (options.snapY !== undefined) currentOptions.snapY = options.snapY; 59.5842 + }; 59.5843 + 59.5844 + /** 59.5845 + * Get current delta in position from where this draggable started. 59.5846 + * 59.5847 + * @method getPosition 59.5848 + * 59.5849 + * @return {array<number>} [x, y] position delta from start. 59.5850 + */ 59.5851 + Draggable.prototype.getPosition = function getPosition() { 59.5852 + return this._positionState.get(); 59.5853 + }; 59.5854 + 59.5855 + /** 59.5856 + * Transition the element to the desired relative position via provided transition. 59.5857 + * For example, calling this with [0,0] will not change the position. 59.5858 + * Callback will be executed on completion. 59.5859 + * 59.5860 + * @method setRelativePosition 59.5861 + * 59.5862 + * @param {array<number>} position end state to which we interpolate 59.5863 + * @param {transition} transition transition object specifying how object moves to new position 59.5864 + * @param {function} callback zero-argument function to call on observed completion 59.5865 + */ 59.5866 + Draggable.prototype.setRelativePosition = function setRelativePosition(position, transition, callback) { 59.5867 + var currPos = this.getPosition(); 59.5868 + var relativePosition = [currPos[0] + position[0], currPos[1] + position[1]]; 59.5869 + this.setPosition(relativePosition, transition, callback); 59.5870 + }; 59.5871 + 59.5872 + /** 59.5873 + * Transition the element to the desired absolute position via provided transition. 59.5874 + * Callback will be executed on completion. 59.5875 + * 59.5876 + * @method setPosition 59.5877 + * 59.5878 + * @param {array<number>} position end state to which we interpolate 59.5879 + * @param {transition} transition transition object specifying how object moves to new position 59.5880 + * @param {function} callback zero-argument function to call on observed completion 59.5881 + */ 59.5882 + Draggable.prototype.setPosition = function setPosition(position, transition, callback) { 59.5883 + if (this._positionState.isActive()) this._positionState.halt(); 59.5884 + this._positionState.set(position, transition, callback); 59.5885 + }; 59.5886 + 59.5887 + /** 59.5888 + * Set this draggable to respond to user input. 59.5889 + * 59.5890 + * @method activate 59.5891 + * 59.5892 + */ 59.5893 + Draggable.prototype.activate = function activate() { 59.5894 + this._active = true; 59.5895 + }; 59.5896 + 59.5897 + /** 59.5898 + * Set this draggable to ignore user input. 59.5899 + * 59.5900 + * @method deactivate 59.5901 + * 59.5902 + */ 59.5903 + Draggable.prototype.deactivate = function deactivate() { 59.5904 + this._active = false; 59.5905 + }; 59.5906 + 59.5907 + /** 59.5908 + * Switch the input response stage between active and inactive. 59.5909 + * 59.5910 + * @method toggle 59.5911 + * 59.5912 + */ 59.5913 + Draggable.prototype.toggle = function toggle() { 59.5914 + this._active = !this._active; 59.5915 + }; 59.5916 + 59.5917 + /** 59.5918 + * Return render spec for this Modifier, applying to the provided 59.5919 + * target component. This is similar to render() for Surfaces. 59.5920 + * 59.5921 + * @private 59.5922 + * @method modify 59.5923 + * 59.5924 + * @param {Object} target (already rendered) render spec to 59.5925 + * which to apply the transform. 59.5926 + * @return {Object} render spec for this Modifier, including the 59.5927 + * provided target 59.5928 + */ 59.5929 + Draggable.prototype.modify = function modify(target) { 59.5930 + var pos = this.getPosition(); 59.5931 + return { 59.5932 + transform: Transform.translate(pos[0], pos[1]), 59.5933 + target: target 59.5934 + }; 59.5935 + }; 59.5936 + 59.5937 + module.exports = Draggable; 59.5938 +}); 59.5939 + 59.5940 +define('famous/modifiers/Fader',['require','exports','module','famous/transitions/Transitionable','famous/core/OptionsManager'],function(require, exports, module) { 59.5941 + var Transitionable = require('famous/transitions/Transitionable'); 59.5942 + var OptionsManager = require('famous/core/OptionsManager'); 59.5943 + 59.5944 + /** 59.5945 + * Modifier that allows you to fade the opacity of affected renderables in and out. 59.5946 + * @class Fader 59.5947 + * @constructor 59.5948 + * @param {Object} [options] options configuration object. 59.5949 + * @param {Boolean} [options.cull=false] Stops returning affected renderables up the tree when they're fully faded when true. 59.5950 + * @param {Transition} [options.transition=true] The main transition for showing and hiding. 59.5951 + * @param {Transition} [options.pulseInTransition=true] Controls the transition to a pulsed state when the Fader instance's pulse 59.5952 + * method is called. 59.5953 + * @param {Transition} [options.pulseOutTransition=true]Controls the transition back from a pulsed state when the Fader instance's pulse 59.5954 + * method is called. 59.5955 + * 59.5956 + */ 59.5957 + function Fader(options, startState) { 59.5958 + this.options = Object.create(Fader.DEFAULT_OPTIONS); 59.5959 + this._optionsManager = new OptionsManager(this.options); 59.5960 + 59.5961 + if (options) this.setOptions(options); 59.5962 + 59.5963 + if (!startState) startState = 0; 59.5964 + this.transitionHelper = new Transitionable(startState); 59.5965 + } 59.5966 + 59.5967 + Fader.DEFAULT_OPTIONS = { 59.5968 + cull: false, 59.5969 + transition: true, 59.5970 + pulseInTransition: true, 59.5971 + pulseOutTransition: true 59.5972 + }; 59.5973 + 59.5974 + /** 59.5975 + * Set internal options, overriding any default options 59.5976 + * 59.5977 + * @method setOptions 59.5978 + * 59.5979 + * @param {Object} [options] overrides of default options. See constructor. 59.5980 + */ 59.5981 + Fader.prototype.setOptions = function setOptions(options) { 59.5982 + return this._optionsManager.setOptions(options); 59.5983 + }; 59.5984 + 59.5985 + /** 59.5986 + * Fully displays the Fader instance's associated renderables. 59.5987 + * 59.5988 + * @method show 59.5989 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 59.5990 + * @param {Function} [callback] A callback that executes once you've transitioned to the fully shown state. 59.5991 + */ 59.5992 + Fader.prototype.show = function show(transition, callback) { 59.5993 + transition = transition || this.options.transition; 59.5994 + this.set(1, transition, callback); 59.5995 + }; 59.5996 + 59.5997 + /** 59.5998 + * Fully fades the Fader instance's associated renderables. 59.5999 + * 59.6000 + * @method hide 59.6001 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 59.6002 + * @param {Function} [callback] A callback that executes once you've transitioned to the fully faded state. 59.6003 + */ 59.6004 + Fader.prototype.hide = function hide(transition, callback) { 59.6005 + transition = transition || this.options.transition; 59.6006 + this.set(0, transition, callback); 59.6007 + }; 59.6008 + 59.6009 + /** 59.6010 + * Manually sets the opacity state of the fader to the passed-in one. Executes with an optional 59.6011 + * transition and callback. 59.6012 + * 59.6013 + * @method set 59.6014 + * @param {Number} state A number from zero to one: the amount of opacity you want to set to. 59.6015 + * @param {Transition} [transition] The transition that coordinates setting to the new state. 59.6016 + * @param {Function} [callback] A callback that executes once you've finished executing the pulse. 59.6017 + */ 59.6018 + Fader.prototype.set = function set(state, transition, callback) { 59.6019 + this.halt(); 59.6020 + this.transitionHelper.set(state, transition, callback); 59.6021 + }; 59.6022 + 59.6023 + /** 59.6024 + * Halt the transition 59.6025 + * 59.6026 + * @method halt 59.6027 + */ 59.6028 + Fader.prototype.halt = function halt() { 59.6029 + this.transitionHelper.halt(); 59.6030 + }; 59.6031 + 59.6032 + /** 59.6033 + * Tells you if your Fader instance is above its visibility threshold. 59.6034 + * 59.6035 + * @method isVisible 59.6036 + * @return {Boolean} Whether or not your Fader instance is visible. 59.6037 + */ 59.6038 + Fader.prototype.isVisible = function isVisible() { 59.6039 + return (this.transitionHelper.get() > 0); 59.6040 + }; 59.6041 + 59.6042 + /** 59.6043 + * Return render spec for this Modifier, applying to the provided 59.6044 + * target component. This is similar to render() for Surfaces. 59.6045 + * 59.6046 + * @private 59.6047 + * @method modify 59.6048 + * 59.6049 + * @param {Object} target (already rendered) render spec to 59.6050 + * which to apply the transform. 59.6051 + * @return {Object} render spec for this Modifier, including the 59.6052 + * provided target 59.6053 + */ 59.6054 + Fader.prototype.modify = function modify(target) { 59.6055 + var currOpacity = this.transitionHelper.get(); 59.6056 + if (this.options.cull && !currOpacity) return undefined; 59.6057 + else return {opacity: currOpacity, target: target}; 59.6058 + }; 59.6059 + 59.6060 + module.exports = Fader; 59.6061 +}); 59.6062 + 59.6063 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.6064 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6065 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.6066 + * 59.6067 + * Owner: david@famo.us 59.6068 + * @license MPL 2.0 59.6069 + * @copyright Famous Industries, Inc. 2014 59.6070 + */ 59.6071 + 59.6072 +define('famous/modifiers/ModifierChain',['require','exports','module'],function(require, exports, module) { 59.6073 + 59.6074 + /** 59.6075 + * A class to add and remove a chain of modifiers 59.6076 + * at a single point in the render tree 59.6077 + * 59.6078 + * @class ModifierChain 59.6079 + * @constructor 59.6080 + */ 59.6081 + function ModifierChain() { 59.6082 + this._chain = []; 59.6083 + if (arguments.length) this.addModifier.apply(this, arguments); 59.6084 + } 59.6085 + 59.6086 + /** 59.6087 + * Add a modifier, or comma separated modifiers, to the modifier chain. 59.6088 + * 59.6089 + * @method addModifier 59.6090 + * 59.6091 + * @param {...Modifier*} varargs args list of Modifiers 59.6092 + */ 59.6093 + ModifierChain.prototype.addModifier = function addModifier(varargs) { 59.6094 + Array.prototype.push.apply(this._chain, arguments); 59.6095 + }; 59.6096 + 59.6097 + /** 59.6098 + * Remove a modifier from the modifier chain. 59.6099 + * 59.6100 + * @method removeModifier 59.6101 + * 59.6102 + * @param {Modifier} modifier 59.6103 + */ 59.6104 + ModifierChain.prototype.removeModifier = function removeModifier(modifier) { 59.6105 + var index = this._chain.indexOf(modifier); 59.6106 + if (index < 0) return; 59.6107 + this._chain.splice(index, 1); 59.6108 + }; 59.6109 + 59.6110 + /** 59.6111 + * Return render spec for this Modifier, applying to the provided 59.6112 + * target component. This is similar to render() for Surfaces. 59.6113 + * 59.6114 + * @private 59.6115 + * @method modify 59.6116 + * 59.6117 + * @param {Object} input (already rendered) render spec to 59.6118 + * which to apply the transform. 59.6119 + * @return {Object} render spec for this Modifier, including the 59.6120 + * provided target 59.6121 + */ 59.6122 + ModifierChain.prototype.modify = function modify(input) { 59.6123 + var chain = this._chain; 59.6124 + var result = input; 59.6125 + for (var i = 0; i < chain.length; i++) { 59.6126 + result = chain[i].modify(result); 59.6127 + } 59.6128 + return result; 59.6129 + }; 59.6130 + 59.6131 + module.exports = ModifierChain; 59.6132 +}); 59.6133 + 59.6134 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.6135 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6136 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.6137 + * 59.6138 + * Owner: mark@famo.us 59.6139 + * @license MPL 2.0 59.6140 + * @copyright Famous Industries, Inc. 2014 59.6141 + */ 59.6142 + 59.6143 +define('famous/modifiers/StateModifier',['require','exports','module','famous/core/Modifier','famous/core/Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 59.6144 + var Modifier = require('famous/core/Modifier'); 59.6145 + var Transform = require('famous/core/Transform'); 59.6146 + var Transitionable = require('famous/transitions/Transitionable'); 59.6147 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 59.6148 + 59.6149 + /** 59.6150 + * A collection of visual changes to be 59.6151 + * applied to another renderable component, strongly coupled with the state that defines 59.6152 + * those changes. This collection includes a 59.6153 + * transform matrix, an opacity constant, a size, an origin specifier, and an alignment specifier. 59.6154 + * StateModifier objects can be added to any RenderNode or object 59.6155 + * capable of displaying renderables. The StateModifier's children and descendants 59.6156 + * are transformed by the amounts specified in the modifier's properties. 59.6157 + * 59.6158 + * @class StateModifier 59.6159 + * @constructor 59.6160 + * @param {Object} [options] overrides of default options 59.6161 + * @param {Transform} [options.transform] affine transformation matrix 59.6162 + * @param {Number} [options.opacity] 59.6163 + * @param {Array.Number} [options.origin] origin adjustment 59.6164 + * @param {Array.Number} [options.align] align adjustment 59.6165 + * @param {Array.Number} [options.size] size to apply to descendants 59.6166 + */ 59.6167 + function StateModifier(options) { 59.6168 + this._transformState = new TransitionableTransform(Transform.identity); 59.6169 + this._opacityState = new Transitionable(1); 59.6170 + this._originState = new Transitionable([0, 0]); 59.6171 + this._alignState = new Transitionable([0, 0]); 59.6172 + this._sizeState = new Transitionable([0, 0]); 59.6173 + 59.6174 + this._modifier = new Modifier({ 59.6175 + transform: this._transformState, 59.6176 + opacity: this._opacityState, 59.6177 + origin: null, 59.6178 + align: null, 59.6179 + size: null 59.6180 + }); 59.6181 + 59.6182 + this._hasOrigin = false; 59.6183 + this._hasAlign = false; 59.6184 + this._hasSize = false; 59.6185 + 59.6186 + if (options) { 59.6187 + if (options.transform) this.setTransform(options.transform); 59.6188 + if (options.opacity !== undefined) this.setOpacity(options.opacity); 59.6189 + if (options.origin) this.setOrigin(options.origin); 59.6190 + if (options.align) this.setAlign(options.align); 59.6191 + if (options.size) this.setSize(options.size); 59.6192 + } 59.6193 + } 59.6194 + 59.6195 + /** 59.6196 + * Set the transform matrix of this modifier, either statically or 59.6197 + * through a provided Transitionable. 59.6198 + * 59.6199 + * @method setTransform 59.6200 + * 59.6201 + * @param {Transform} transform Transform to transition to. 59.6202 + * @param {Transitionable} [transition] Valid transitionable object 59.6203 + * @param {Function} [callback] callback to call after transition completes 59.6204 + * @return {StateModifier} this 59.6205 + */ 59.6206 + StateModifier.prototype.setTransform = function setTransform(transform, transition, callback) { 59.6207 + this._transformState.set(transform, transition, callback); 59.6208 + return this; 59.6209 + }; 59.6210 + 59.6211 + /** 59.6212 + * Set the opacity of this modifier, either statically or 59.6213 + * through a provided Transitionable. 59.6214 + * 59.6215 + * @method setOpacity 59.6216 + * 59.6217 + * @param {Number} opacity Opacity value to transition to. 59.6218 + * @param {Transitionable} transition Valid transitionable object 59.6219 + * @param {Function} callback callback to call after transition completes 59.6220 + * @return {StateModifier} this 59.6221 + */ 59.6222 + StateModifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) { 59.6223 + this._opacityState.set(opacity, transition, callback); 59.6224 + return this; 59.6225 + }; 59.6226 + 59.6227 + /** 59.6228 + * Set the origin of this modifier, either statically or 59.6229 + * through a provided Transitionable. 59.6230 + * 59.6231 + * @method setOrigin 59.6232 + * 59.6233 + * @param {Array.Number} origin two element array with values between 0 and 1. 59.6234 + * @param {Transitionable} transition Valid transitionable object 59.6235 + * @param {Function} callback callback to call after transition completes 59.6236 + * @return {StateModifier} this 59.6237 + */ 59.6238 + StateModifier.prototype.setOrigin = function setOrigin(origin, transition, callback) { 59.6239 + if (origin === null) { 59.6240 + if (this._hasOrigin) { 59.6241 + this._modifier.originFrom(null); 59.6242 + this._hasOrigin = false; 59.6243 + } 59.6244 + return this; 59.6245 + } 59.6246 + else if (!this._hasOrigin) { 59.6247 + this._hasOrigin = true; 59.6248 + this._modifier.originFrom(this._originState); 59.6249 + } 59.6250 + this._originState.set(origin, transition, callback); 59.6251 + return this; 59.6252 + }; 59.6253 + 59.6254 + /** 59.6255 + * Set the alignment of this modifier, either statically or 59.6256 + * through a provided Transitionable. 59.6257 + * 59.6258 + * @method setAlign 59.6259 + * 59.6260 + * @param {Array.Number} align two element array with values between 0 and 1. 59.6261 + * @param {Transitionable} transition Valid transitionable object 59.6262 + * @param {Function} callback callback to call after transition completes 59.6263 + * @return {StateModifier} this 59.6264 + */ 59.6265 + StateModifier.prototype.setAlign = function setOrigin(align, transition, callback) { 59.6266 + if (align === null) { 59.6267 + if (this._hasAlign) { 59.6268 + this._modifier.alignFrom(null); 59.6269 + this._hasAlign = false; 59.6270 + } 59.6271 + return this; 59.6272 + } 59.6273 + else if (!this._hasAlign) { 59.6274 + this._hasAlign = true; 59.6275 + this._modifier.alignFrom(this._alignState); 59.6276 + } 59.6277 + this._alignState.set(align, transition, callback); 59.6278 + return this; 59.6279 + }; 59.6280 + 59.6281 + /** 59.6282 + * Set the size of this modifier, either statically or 59.6283 + * through a provided Transitionable. 59.6284 + * 59.6285 + * @method setSize 59.6286 + * 59.6287 + * @param {Array.Number} size two element array with values between 0 and 1. 59.6288 + * @param {Transitionable} transition Valid transitionable object 59.6289 + * @param {Function} callback callback to call after transition completes 59.6290 + * @return {StateModifier} this 59.6291 + */ 59.6292 + StateModifier.prototype.setSize = function setSize(size, transition, callback) { 59.6293 + if (size === null) { 59.6294 + if (this._hasSize) { 59.6295 + this._modifier.sizeFrom(null); 59.6296 + this._hasSize = false; 59.6297 + } 59.6298 + return this; 59.6299 + } 59.6300 + else if (!this._hasSize) { 59.6301 + this._hasSize = true; 59.6302 + this._modifier.sizeFrom(this._sizeState); 59.6303 + } 59.6304 + this._sizeState.set(size, transition, callback); 59.6305 + return this; 59.6306 + }; 59.6307 + 59.6308 + /** 59.6309 + * Stop the transition. 59.6310 + * 59.6311 + * @method halt 59.6312 + */ 59.6313 + StateModifier.prototype.halt = function halt() { 59.6314 + this._transformState.halt(); 59.6315 + this._opacityState.halt(); 59.6316 + this._originState.halt(); 59.6317 + this._alignState.halt(); 59.6318 + this._sizeState.halt(); 59.6319 + }; 59.6320 + 59.6321 + /** 59.6322 + * Get the current state of the transform matrix component. 59.6323 + * 59.6324 + * @method getTransform 59.6325 + * @return {Object} transform provider object 59.6326 + */ 59.6327 + StateModifier.prototype.getTransform = function getTransform() { 59.6328 + return this._transformState.get(); 59.6329 + }; 59.6330 + 59.6331 + /** 59.6332 + * Get the destination state of the transform component. 59.6333 + * 59.6334 + * @method getFinalTransform 59.6335 + * @return {Transform} transform matrix 59.6336 + */ 59.6337 + StateModifier.prototype.getFinalTransform = function getFinalTransform() { 59.6338 + return this._transformState.getFinal(); 59.6339 + }; 59.6340 + 59.6341 + /** 59.6342 + * Get the current state of the opacity component. 59.6343 + * 59.6344 + * @method getOpacity 59.6345 + * @return {Object} opacity provider object 59.6346 + */ 59.6347 + StateModifier.prototype.getOpacity = function getOpacity() { 59.6348 + return this._opacityState.get(); 59.6349 + }; 59.6350 + 59.6351 + /** 59.6352 + * Get the current state of the origin component. 59.6353 + * 59.6354 + * @method getOrigin 59.6355 + * @return {Object} origin provider object 59.6356 + */ 59.6357 + StateModifier.prototype.getOrigin = function getOrigin() { 59.6358 + return this._hasOrigin ? this._originState.get() : null; 59.6359 + }; 59.6360 + 59.6361 + /** 59.6362 + * Get the current state of the align component. 59.6363 + * 59.6364 + * @method getAlign 59.6365 + * @return {Object} align provider object 59.6366 + */ 59.6367 + StateModifier.prototype.getAlign = function getAlign() { 59.6368 + return this._hasAlign ? this._alignState.get() : null; 59.6369 + }; 59.6370 + 59.6371 + /** 59.6372 + * Get the current state of the size component. 59.6373 + * 59.6374 + * @method getSize 59.6375 + * @return {Object} size provider object 59.6376 + */ 59.6377 + StateModifier.prototype.getSize = function getSize() { 59.6378 + return this._hasSize ? this._sizeState.get() : null; 59.6379 + }; 59.6380 + 59.6381 + /** 59.6382 + * Return render spec for this StateModifier, applying to the provided 59.6383 + * target component. This is similar to render() for Surfaces. 59.6384 + * 59.6385 + * @private 59.6386 + * @method modify 59.6387 + * 59.6388 + * @param {Object} target (already rendered) render spec to 59.6389 + * which to apply the transform. 59.6390 + * @return {Object} render spec for this StateModifier, including the 59.6391 + * provided target 59.6392 + */ 59.6393 + StateModifier.prototype.modify = function modify(target) { 59.6394 + return this._modifier.modify(target); 59.6395 + }; 59.6396 + 59.6397 + module.exports = StateModifier; 59.6398 +}); 59.6399 + 59.6400 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.6401 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6402 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.6403 + * 59.6404 + * Owner: david@famo.us 59.6405 + * @license MPL 2.0 59.6406 + * @copyright Famous Industries, Inc. 2014 59.6407 + */ 59.6408 + 59.6409 +define('famous/math/Vector',['require','exports','module'],function(require, exports, module) { 59.6410 + 59.6411 + /** 59.6412 + * Three-element floating point vector. 59.6413 + * 59.6414 + * @class Vector 59.6415 + * @constructor 59.6416 + * 59.6417 + * @param {number} x x element value 59.6418 + * @param {number} y y element value 59.6419 + * @param {number} z z element value 59.6420 + */ 59.6421 + function Vector(x,y,z) { 59.6422 + if (arguments.length === 1) this.set(x); 59.6423 + else { 59.6424 + this.x = x || 0; 59.6425 + this.y = y || 0; 59.6426 + this.z = z || 0; 59.6427 + } 59.6428 + return this; 59.6429 + } 59.6430 + 59.6431 + var _register = new Vector(0,0,0); 59.6432 + 59.6433 + /** 59.6434 + * Add this element-wise to another Vector, element-wise. 59.6435 + * Note: This sets the internal result register, so other references to that vector will change. 59.6436 + * 59.6437 + * @method add 59.6438 + * @param {Vector} v addend 59.6439 + * @return {Vector} vector sum 59.6440 + */ 59.6441 + Vector.prototype.add = function add(v) { 59.6442 + return _setXYZ.call(_register, 59.6443 + this.x + v.x, 59.6444 + this.y + v.y, 59.6445 + this.z + v.z 59.6446 + ); 59.6447 + }; 59.6448 + 59.6449 + /** 59.6450 + * Subtract another vector from this vector, element-wise. 59.6451 + * Note: This sets the internal result register, so other references to that vector will change. 59.6452 + * 59.6453 + * @method sub 59.6454 + * @param {Vector} v subtrahend 59.6455 + * @return {Vector} vector difference 59.6456 + */ 59.6457 + Vector.prototype.sub = function sub(v) { 59.6458 + return _setXYZ.call(_register, 59.6459 + this.x - v.x, 59.6460 + this.y - v.y, 59.6461 + this.z - v.z 59.6462 + ); 59.6463 + }; 59.6464 + 59.6465 + /** 59.6466 + * Scale Vector by floating point r. 59.6467 + * Note: This sets the internal result register, so other references to that vector will change. 59.6468 + * 59.6469 + * @method mult 59.6470 + * 59.6471 + * @param {number} r scalar 59.6472 + * @return {Vector} vector result 59.6473 + */ 59.6474 + Vector.prototype.mult = function mult(r) { 59.6475 + return _setXYZ.call(_register, 59.6476 + r * this.x, 59.6477 + r * this.y, 59.6478 + r * this.z 59.6479 + ); 59.6480 + }; 59.6481 + 59.6482 + /** 59.6483 + * Scale Vector by floating point 1/r. 59.6484 + * Note: This sets the internal result register, so other references to that vector will change. 59.6485 + * 59.6486 + * @method div 59.6487 + * 59.6488 + * @param {number} r scalar 59.6489 + * @return {Vector} vector result 59.6490 + */ 59.6491 + Vector.prototype.div = function div(r) { 59.6492 + return this.mult(1 / r); 59.6493 + }; 59.6494 + 59.6495 + /** 59.6496 + * Given another vector v, return cross product (v)x(this). 59.6497 + * Note: This sets the internal result register, so other references to that vector will change. 59.6498 + * 59.6499 + * @method cross 59.6500 + * @param {Vector} v Left Hand Vector 59.6501 + * @return {Vector} vector result 59.6502 + */ 59.6503 + Vector.prototype.cross = function cross(v) { 59.6504 + var x = this.x; 59.6505 + var y = this.y; 59.6506 + var z = this.z; 59.6507 + var vx = v.x; 59.6508 + var vy = v.y; 59.6509 + var vz = v.z; 59.6510 + 59.6511 + return _setXYZ.call(_register, 59.6512 + z * vy - y * vz, 59.6513 + x * vz - z * vx, 59.6514 + y * vx - x * vy 59.6515 + ); 59.6516 + }; 59.6517 + 59.6518 + /** 59.6519 + * Component-wise equality test between this and Vector v. 59.6520 + * @method equals 59.6521 + * @param {Vector} v vector to compare 59.6522 + * @return {boolean} 59.6523 + */ 59.6524 + Vector.prototype.equals = function equals(v) { 59.6525 + return (v.x === this.x && v.y === this.y && v.z === this.z); 59.6526 + }; 59.6527 + 59.6528 + /** 59.6529 + * Rotate clockwise around x-axis by theta radians. 59.6530 + * Note: This sets the internal result register, so other references to that vector will change. 59.6531 + * @method rotateX 59.6532 + * @param {number} theta radians 59.6533 + * @return {Vector} rotated vector 59.6534 + */ 59.6535 + Vector.prototype.rotateX = function rotateX(theta) { 59.6536 + var x = this.x; 59.6537 + var y = this.y; 59.6538 + var z = this.z; 59.6539 + 59.6540 + var cosTheta = Math.cos(theta); 59.6541 + var sinTheta = Math.sin(theta); 59.6542 + 59.6543 + return _setXYZ.call(_register, 59.6544 + x, 59.6545 + y * cosTheta - z * sinTheta, 59.6546 + y * sinTheta + z * cosTheta 59.6547 + ); 59.6548 + }; 59.6549 + 59.6550 + /** 59.6551 + * Rotate clockwise around y-axis by theta radians. 59.6552 + * Note: This sets the internal result register, so other references to that vector will change. 59.6553 + * @method rotateY 59.6554 + * @param {number} theta radians 59.6555 + * @return {Vector} rotated vector 59.6556 + */ 59.6557 + Vector.prototype.rotateY = function rotateY(theta) { 59.6558 + var x = this.x; 59.6559 + var y = this.y; 59.6560 + var z = this.z; 59.6561 + 59.6562 + var cosTheta = Math.cos(theta); 59.6563 + var sinTheta = Math.sin(theta); 59.6564 + 59.6565 + return _setXYZ.call(_register, 59.6566 + z * sinTheta + x * cosTheta, 59.6567 + y, 59.6568 + z * cosTheta - x * sinTheta 59.6569 + ); 59.6570 + }; 59.6571 + 59.6572 + /** 59.6573 + * Rotate clockwise around z-axis by theta radians. 59.6574 + * Note: This sets the internal result register, so other references to that vector will change. 59.6575 + * @method rotateZ 59.6576 + * @param {number} theta radians 59.6577 + * @return {Vector} rotated vector 59.6578 + */ 59.6579 + Vector.prototype.rotateZ = function rotateZ(theta) { 59.6580 + var x = this.x; 59.6581 + var y = this.y; 59.6582 + var z = this.z; 59.6583 + 59.6584 + var cosTheta = Math.cos(theta); 59.6585 + var sinTheta = Math.sin(theta); 59.6586 + 59.6587 + return _setXYZ.call(_register, 59.6588 + x * cosTheta - y * sinTheta, 59.6589 + x * sinTheta + y * cosTheta, 59.6590 + z 59.6591 + ); 59.6592 + }; 59.6593 + 59.6594 + /** 59.6595 + * Return dot product of this with a second Vector 59.6596 + * @method dot 59.6597 + * @param {Vector} v second vector 59.6598 + * @return {number} dot product 59.6599 + */ 59.6600 + Vector.prototype.dot = function dot(v) { 59.6601 + return this.x * v.x + this.y * v.y + this.z * v.z; 59.6602 + }; 59.6603 + 59.6604 + /** 59.6605 + * Return squared length of this vector 59.6606 + * @method normSquared 59.6607 + * @return {number} squared length 59.6608 + */ 59.6609 + Vector.prototype.normSquared = function normSquared() { 59.6610 + return this.dot(this); 59.6611 + }; 59.6612 + 59.6613 + /** 59.6614 + * Return length of this vector 59.6615 + * @method norm 59.6616 + * @return {number} length 59.6617 + */ 59.6618 + Vector.prototype.norm = function norm() { 59.6619 + return Math.sqrt(this.normSquared()); 59.6620 + }; 59.6621 + 59.6622 + /** 59.6623 + * Scale Vector to specified length. 59.6624 + * If length is less than internal tolerance, set vector to [length, 0, 0]. 59.6625 + * Note: This sets the internal result register, so other references to that vector will change. 59.6626 + * @method normalize 59.6627 + * 59.6628 + * @param {number} length target length, default 1.0 59.6629 + * @return {Vector} 59.6630 + */ 59.6631 + Vector.prototype.normalize = function normalize(length) { 59.6632 + if (arguments.length === 0) length = 1; 59.6633 + var norm = this.norm(); 59.6634 + 59.6635 + if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm)); 59.6636 + else return _setXYZ.call(_register, length, 0, 0); 59.6637 + }; 59.6638 + 59.6639 + /** 59.6640 + * Make a separate copy of the Vector. 59.6641 + * 59.6642 + * @method clone 59.6643 + * 59.6644 + * @return {Vector} 59.6645 + */ 59.6646 + Vector.prototype.clone = function clone() { 59.6647 + return new Vector(this); 59.6648 + }; 59.6649 + 59.6650 + /** 59.6651 + * True if and only if every value is 0 (or falsy) 59.6652 + * 59.6653 + * @method isZero 59.6654 + * 59.6655 + * @return {boolean} 59.6656 + */ 59.6657 + Vector.prototype.isZero = function isZero() { 59.6658 + return !(this.x || this.y || this.z); 59.6659 + }; 59.6660 + 59.6661 + function _setXYZ(x,y,z) { 59.6662 + this.x = x; 59.6663 + this.y = y; 59.6664 + this.z = z; 59.6665 + return this; 59.6666 + } 59.6667 + 59.6668 + function _setFromArray(v) { 59.6669 + return _setXYZ.call(this,v[0],v[1],v[2] || 0); 59.6670 + } 59.6671 + 59.6672 + function _setFromVector(v) { 59.6673 + return _setXYZ.call(this, v.x, v.y, v.z); 59.6674 + } 59.6675 + 59.6676 + function _setFromNumber(x) { 59.6677 + return _setXYZ.call(this,x,0,0); 59.6678 + } 59.6679 + 59.6680 + /** 59.6681 + * Set this Vector to the values in the provided Array or Vector. 59.6682 + * 59.6683 + * @method set 59.6684 + * @param {object} v array, Vector, or number 59.6685 + * @return {Vector} this 59.6686 + */ 59.6687 + Vector.prototype.set = function set(v) { 59.6688 + if (v instanceof Array) return _setFromArray.call(this, v); 59.6689 + if (v instanceof Vector) return _setFromVector.call(this, v); 59.6690 + if (typeof v === 'number') return _setFromNumber.call(this, v); 59.6691 + }; 59.6692 + 59.6693 + Vector.prototype.setXYZ = function(x,y,z) { 59.6694 + return _setXYZ.apply(this, arguments); 59.6695 + }; 59.6696 + 59.6697 + Vector.prototype.set1D = function(x) { 59.6698 + return _setFromNumber.call(this, x); 59.6699 + }; 59.6700 + 59.6701 + /** 59.6702 + * Put result of last internal register calculation in specified output vector. 59.6703 + * 59.6704 + * @method put 59.6705 + * @param {Vector} v destination vector 59.6706 + * @return {Vector} destination vector 59.6707 + */ 59.6708 + 59.6709 + Vector.prototype.put = function put(v) { 59.6710 + _setFromVector.call(v, _register); 59.6711 + }; 59.6712 + 59.6713 + /** 59.6714 + * Set this vector to [0,0,0] 59.6715 + * 59.6716 + * @method clear 59.6717 + */ 59.6718 + Vector.prototype.clear = function clear() { 59.6719 + return _setXYZ.call(this,0,0,0); 59.6720 + }; 59.6721 + 59.6722 + /** 59.6723 + * Scale this Vector down to specified "cap" length. 59.6724 + * If Vector shorter than cap, or cap is Infinity, do nothing. 59.6725 + * Note: This sets the internal result register, so other references to that vector will change. 59.6726 + * 59.6727 + * @method cap 59.6728 + * @return {Vector} capped vector 59.6729 + */ 59.6730 + Vector.prototype.cap = function cap(cap) { 59.6731 + if (cap === Infinity) return _setFromVector.call(_register, this); 59.6732 + var norm = this.norm(); 59.6733 + if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm)); 59.6734 + else return _setFromVector.call(_register, this); 59.6735 + }; 59.6736 + 59.6737 + /** 59.6738 + * Return projection of this Vector onto another. 59.6739 + * Note: This sets the internal result register, so other references to that vector will change. 59.6740 + * 59.6741 + * @method project 59.6742 + * @param {Vector} n vector to project upon 59.6743 + * @return {Vector} projected vector 59.6744 + */ 59.6745 + Vector.prototype.project = function project(n) { 59.6746 + return n.mult(this.dot(n)); 59.6747 + }; 59.6748 + 59.6749 + /** 59.6750 + * Reflect this Vector across provided vector. 59.6751 + * Note: This sets the internal result register, so other references to that vector will change. 59.6752 + * 59.6753 + * @method reflectAcross 59.6754 + * @param {Vector} n vector to reflect across 59.6755 + * @return {Vector} reflected vector 59.6756 + */ 59.6757 + Vector.prototype.reflectAcross = function reflectAcross(n) { 59.6758 + n.normalize().put(n); 59.6759 + return _setFromVector(_register, this.sub(this.project(n).mult(2))); 59.6760 + }; 59.6761 + 59.6762 + /** 59.6763 + * Convert Vector to three-element array. 59.6764 + * 59.6765 + * @method get 59.6766 + * @return {array<number>} three-element array 59.6767 + */ 59.6768 + Vector.prototype.get = function get() { 59.6769 + return [this.x, this.y, this.z]; 59.6770 + }; 59.6771 + 59.6772 + Vector.prototype.get1D = function() { 59.6773 + return this.x; 59.6774 + }; 59.6775 + 59.6776 + module.exports = Vector; 59.6777 + 59.6778 +}); 59.6779 + 59.6780 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.6781 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6782 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.6783 + * 59.6784 + * Owner: david@famo.us 59.6785 + * @license MPL 2.0 59.6786 + * @copyright Famous Industries, Inc. 2014 59.6787 + */ 59.6788 + 59.6789 +define('famous/math/Matrix',['require','exports','module','./Vector'],function(require, exports, module) { 59.6790 + var Vector = require('./Vector'); 59.6791 + 59.6792 + /** 59.6793 + * A library for using a 3x3 numerical matrix, represented as a two-level array. 59.6794 + * 59.6795 + * @class Matrix 59.6796 + * @constructor 59.6797 + * 59.6798 + * @param {Array.Array} values array of rows 59.6799 + */ 59.6800 + function Matrix(values) { 59.6801 + this.values = values || 59.6802 + [ 59.6803 + [1,0,0], 59.6804 + [0,1,0], 59.6805 + [0,0,1] 59.6806 + ]; 59.6807 + 59.6808 + return this; 59.6809 + } 59.6810 + 59.6811 + var _register = new Matrix(); 59.6812 + var _vectorRegister = new Vector(); 59.6813 + 59.6814 + /** 59.6815 + * Return the values in the matrix as an array of numerical row arrays 59.6816 + * 59.6817 + * @method get 59.6818 + * 59.6819 + * @return {Array.array} matrix values as array of rows. 59.6820 + */ 59.6821 + Matrix.prototype.get = function get() { 59.6822 + return this.values; 59.6823 + }; 59.6824 + 59.6825 + /** 59.6826 + * Set the nested array of rows in the matrix. 59.6827 + * 59.6828 + * @method set 59.6829 + * 59.6830 + * @param {Array.array} values matrix values as array of rows. 59.6831 + */ 59.6832 + Matrix.prototype.set = function set(values) { 59.6833 + this.values = values; 59.6834 + }; 59.6835 + 59.6836 + /** 59.6837 + * Take this matrix as A, input vector V as a column vector, and return matrix product (A)(V). 59.6838 + * Note: This sets the internal vector register. Current handles to the vector register 59.6839 + * will see values changed. 59.6840 + * 59.6841 + * @method vectorMultiply 59.6842 + * 59.6843 + * @param {Vector} v input vector V 59.6844 + * @return {Vector} result of multiplication, as a handle to the internal vector register 59.6845 + */ 59.6846 + Matrix.prototype.vectorMultiply = function vectorMultiply(v) { 59.6847 + var M = this.get(); 59.6848 + var v0 = v.x; 59.6849 + var v1 = v.y; 59.6850 + var v2 = v.z; 59.6851 + 59.6852 + var M0 = M[0]; 59.6853 + var M1 = M[1]; 59.6854 + var M2 = M[2]; 59.6855 + 59.6856 + var M00 = M0[0]; 59.6857 + var M01 = M0[1]; 59.6858 + var M02 = M0[2]; 59.6859 + var M10 = M1[0]; 59.6860 + var M11 = M1[1]; 59.6861 + var M12 = M1[2]; 59.6862 + var M20 = M2[0]; 59.6863 + var M21 = M2[1]; 59.6864 + var M22 = M2[2]; 59.6865 + 59.6866 + return _vectorRegister.setXYZ( 59.6867 + M00*v0 + M01*v1 + M02*v2, 59.6868 + M10*v0 + M11*v1 + M12*v2, 59.6869 + M20*v0 + M21*v1 + M22*v2 59.6870 + ); 59.6871 + }; 59.6872 + 59.6873 + /** 59.6874 + * Multiply the provided matrix M2 with this matrix. Result is (this) * (M2). 59.6875 + * Note: This sets the internal matrix register. Current handles to the register 59.6876 + * will see values changed. 59.6877 + * 59.6878 + * @method multiply 59.6879 + * 59.6880 + * @param {Matrix} M2 input matrix to multiply on the right 59.6881 + * @return {Matrix} result of multiplication, as a handle to the internal register 59.6882 + */ 59.6883 + Matrix.prototype.multiply = function multiply(M2) { 59.6884 + var M1 = this.get(); 59.6885 + var result = [[]]; 59.6886 + for (var i = 0; i < 3; i++) { 59.6887 + result[i] = []; 59.6888 + for (var j = 0; j < 3; j++) { 59.6889 + var sum = 0; 59.6890 + for (var k = 0; k < 3; k++) { 59.6891 + sum += M1[i][k] * M2[k][j]; 59.6892 + } 59.6893 + result[i][j] = sum; 59.6894 + } 59.6895 + } 59.6896 + return _register.set(result); 59.6897 + }; 59.6898 + 59.6899 + /** 59.6900 + * Creates a Matrix which is the transpose of this matrix. 59.6901 + * Note: This sets the internal matrix register. Current handles to the register 59.6902 + * will see values changed. 59.6903 + * 59.6904 + * @method transpose 59.6905 + * 59.6906 + * @return {Matrix} result of transpose, as a handle to the internal register 59.6907 + */ 59.6908 + Matrix.prototype.transpose = function transpose() { 59.6909 + var result = []; 59.6910 + var M = this.get(); 59.6911 + for (var row = 0; row < 3; row++) { 59.6912 + for (var col = 0; col < 3; col++) { 59.6913 + result[row][col] = M[col][row]; 59.6914 + } 59.6915 + } 59.6916 + return _register.set(result); 59.6917 + }; 59.6918 + 59.6919 + /** 59.6920 + * Clones the matrix 59.6921 + * 59.6922 + * @method clone 59.6923 + * @return {Matrix} New copy of the original matrix 59.6924 + */ 59.6925 + Matrix.prototype.clone = function clone() { 59.6926 + var values = this.get(); 59.6927 + var M = []; 59.6928 + for (var row = 0; row < 3; row++) 59.6929 + M[row] = values[row].slice(); 59.6930 + return new Matrix(M); 59.6931 + }; 59.6932 + 59.6933 + module.exports = Matrix; 59.6934 +}); 59.6935 + 59.6936 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.6937 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.6938 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.6939 + * 59.6940 + * Owner: david@famo.us 59.6941 + * @license MPL 2.0 59.6942 + * @copyright Famous Industries, Inc. 2014 59.6943 + */ 59.6944 + 59.6945 +define('famous/math/Quaternion',['require','exports','module','./Matrix'],function(require, exports, module) { 59.6946 + var Matrix = require('./Matrix'); 59.6947 + 59.6948 + /** 59.6949 + * @class Quaternion 59.6950 + * @constructor 59.6951 + * 59.6952 + * @param {Number} w 59.6953 + * @param {Number} x 59.6954 + * @param {Number} y 59.6955 + * @param {Number} z 59.6956 + */ 59.6957 + function Quaternion(w,x,y,z) { 59.6958 + if (arguments.length === 1) this.set(w); 59.6959 + else { 59.6960 + this.w = (w !== undefined) ? w : 1; //Angle 59.6961 + this.x = (x !== undefined) ? x : 0; //Axis.x 59.6962 + this.y = (y !== undefined) ? y : 0; //Axis.y 59.6963 + this.z = (z !== undefined) ? z : 0; //Axis.z 59.6964 + } 59.6965 + return this; 59.6966 + } 59.6967 + 59.6968 + var register = new Quaternion(1,0,0,0); 59.6969 + 59.6970 + /** 59.6971 + * Doc: TODO 59.6972 + * @method add 59.6973 + * @param {Quaternion} q 59.6974 + * @return {Quaternion} 59.6975 + */ 59.6976 + Quaternion.prototype.add = function add(q) { 59.6977 + return register.setWXYZ( 59.6978 + this.w + q.w, 59.6979 + this.x + q.x, 59.6980 + this.y + q.y, 59.6981 + this.z + q.z 59.6982 + ); 59.6983 + }; 59.6984 + 59.6985 + /* 59.6986 + * Docs: TODO 59.6987 + * 59.6988 + * @method sub 59.6989 + * @param {Quaternion} q 59.6990 + * @return {Quaternion} 59.6991 + */ 59.6992 + Quaternion.prototype.sub = function sub(q) { 59.6993 + return register.setWXYZ( 59.6994 + this.w - q.w, 59.6995 + this.x - q.x, 59.6996 + this.y - q.y, 59.6997 + this.z - q.z 59.6998 + ); 59.6999 + }; 59.7000 + 59.7001 + /** 59.7002 + * Doc: TODO 59.7003 + * 59.7004 + * @method scalarDivide 59.7005 + * @param {Number} s 59.7006 + * @return {Quaternion} 59.7007 + */ 59.7008 + Quaternion.prototype.scalarDivide = function scalarDivide(s) { 59.7009 + return this.scalarMultiply(1/s); 59.7010 + }; 59.7011 + 59.7012 + /* 59.7013 + * Docs: TODO 59.7014 + * 59.7015 + * @method scalarMultiply 59.7016 + * @param {Number} s 59.7017 + * @return {Quaternion} 59.7018 + */ 59.7019 + Quaternion.prototype.scalarMultiply = function scalarMultiply(s) { 59.7020 + return register.setWXYZ( 59.7021 + this.w * s, 59.7022 + this.x * s, 59.7023 + this.y * s, 59.7024 + this.z * s 59.7025 + ); 59.7026 + }; 59.7027 + 59.7028 + /* 59.7029 + * Docs: TODO 59.7030 + * 59.7031 + * @method multiply 59.7032 + * @param {Quaternion} q 59.7033 + * @return {Quaternion} 59.7034 + */ 59.7035 + Quaternion.prototype.multiply = function multiply(q) { 59.7036 + //left-handed coordinate system multiplication 59.7037 + var x1 = this.x; 59.7038 + var y1 = this.y; 59.7039 + var z1 = this.z; 59.7040 + var w1 = this.w; 59.7041 + var x2 = q.x; 59.7042 + var y2 = q.y; 59.7043 + var z2 = q.z; 59.7044 + var w2 = q.w || 0; 59.7045 + 59.7046 + return register.setWXYZ( 59.7047 + w1*w2 - x1*x2 - y1*y2 - z1*z2, 59.7048 + x1*w2 + x2*w1 + y2*z1 - y1*z2, 59.7049 + y1*w2 + y2*w1 + x1*z2 - x2*z1, 59.7050 + z1*w2 + z2*w1 + x2*y1 - x1*y2 59.7051 + ); 59.7052 + }; 59.7053 + 59.7054 + var conj = new Quaternion(1,0,0,0); 59.7055 + 59.7056 + /* 59.7057 + * Docs: TODO 59.7058 + * 59.7059 + * @method rotateVector 59.7060 + * @param {Vector} v 59.7061 + * @return {Quaternion} 59.7062 + */ 59.7063 + Quaternion.prototype.rotateVector = function rotateVector(v) { 59.7064 + conj.set(this.conj()); 59.7065 + return register.set(this.multiply(v).multiply(conj)); 59.7066 + }; 59.7067 + 59.7068 + /* 59.7069 + * Docs: TODO 59.7070 + * 59.7071 + * @method inverse 59.7072 + * @return {Quaternion} 59.7073 + */ 59.7074 + Quaternion.prototype.inverse = function inverse() { 59.7075 + return register.set(this.conj().scalarDivide(this.normSquared())); 59.7076 + }; 59.7077 + 59.7078 + /* 59.7079 + * Docs: TODO 59.7080 + * 59.7081 + * @method negate 59.7082 + * @return {Quaternion} 59.7083 + */ 59.7084 + Quaternion.prototype.negate = function negate() { 59.7085 + return this.scalarMultiply(-1); 59.7086 + }; 59.7087 + 59.7088 + /* 59.7089 + * Docs: TODO 59.7090 + * 59.7091 + * @method conj 59.7092 + * @return {Quaternion} 59.7093 + */ 59.7094 + Quaternion.prototype.conj = function conj() { 59.7095 + return register.setWXYZ( 59.7096 + this.w, 59.7097 + -this.x, 59.7098 + -this.y, 59.7099 + -this.z 59.7100 + ); 59.7101 + }; 59.7102 + 59.7103 + /* 59.7104 + * Docs: TODO 59.7105 + * 59.7106 + * @method normalize 59.7107 + * @param {Number} length 59.7108 + * @return {Quaternion} 59.7109 + */ 59.7110 + Quaternion.prototype.normalize = function normalize(length) { 59.7111 + length = (length === undefined) ? 1 : length; 59.7112 + return this.scalarDivide(length * this.norm()); 59.7113 + }; 59.7114 + 59.7115 + /* 59.7116 + * Docs: TODO 59.7117 + * 59.7118 + * @method makeFromAngleAndAxis 59.7119 + * @param {Number} angle 59.7120 + * @param {Vector} v 59.7121 + * @return {Quaternion} 59.7122 + */ 59.7123 + Quaternion.prototype.makeFromAngleAndAxis = function makeFromAngleAndAxis(angle, v) { 59.7124 + //left handed quaternion creation: theta -> -theta 59.7125 + var n = v.normalize(); 59.7126 + var ha = angle*0.5; 59.7127 + var s = -Math.sin(ha); 59.7128 + this.x = s*n.x; 59.7129 + this.y = s*n.y; 59.7130 + this.z = s*n.z; 59.7131 + this.w = Math.cos(ha); 59.7132 + return this; 59.7133 + }; 59.7134 + 59.7135 + /* 59.7136 + * Docs: TODO 59.7137 + * 59.7138 + * @method setWXYZ 59.7139 + * @param {Number} w 59.7140 + * @param {Number} x 59.7141 + * @param {Number} y 59.7142 + * @param {Number} z 59.7143 + * @return {Quaternion} 59.7144 + */ 59.7145 + Quaternion.prototype.setWXYZ = function setWXYZ(w,x,y,z) { 59.7146 + register.clear(); 59.7147 + this.w = w; 59.7148 + this.x = x; 59.7149 + this.y = y; 59.7150 + this.z = z; 59.7151 + return this; 59.7152 + }; 59.7153 + 59.7154 + /* 59.7155 + * Docs: TODO 59.7156 + * 59.7157 + * @method set 59.7158 + * @param {Array|Quaternion} v 59.7159 + * @return {Quaternion} 59.7160 + */ 59.7161 + Quaternion.prototype.set = function set(v) { 59.7162 + if (v instanceof Array) { 59.7163 + this.w = v[0]; 59.7164 + this.x = v[1]; 59.7165 + this.y = v[2]; 59.7166 + this.z = v[3]; 59.7167 + } 59.7168 + else { 59.7169 + this.w = v.w; 59.7170 + this.x = v.x; 59.7171 + this.y = v.y; 59.7172 + this.z = v.z; 59.7173 + } 59.7174 + if (this !== register) register.clear(); 59.7175 + return this; 59.7176 + }; 59.7177 + 59.7178 + /** 59.7179 + * Docs: TODO 59.7180 + * 59.7181 + * @method put 59.7182 + * @param {Quaternion} q 59.7183 + * @return {Quaternion} 59.7184 + */ 59.7185 + Quaternion.prototype.put = function put(q) { 59.7186 + q.set(register); 59.7187 + }; 59.7188 + 59.7189 + /** 59.7190 + * Doc: TODO 59.7191 + * 59.7192 + * @method clone 59.7193 + * @return {Quaternion} 59.7194 + */ 59.7195 + Quaternion.prototype.clone = function clone() { 59.7196 + return new Quaternion(this); 59.7197 + }; 59.7198 + 59.7199 + /** 59.7200 + * Doc: TODO 59.7201 + * 59.7202 + * @method clear 59.7203 + * @return {Quaternion} 59.7204 + */ 59.7205 + Quaternion.prototype.clear = function clear() { 59.7206 + this.w = 1; 59.7207 + this.x = 0; 59.7208 + this.y = 0; 59.7209 + this.z = 0; 59.7210 + return this; 59.7211 + }; 59.7212 + 59.7213 + /** 59.7214 + * Doc: TODO 59.7215 + * 59.7216 + * @method isEqual 59.7217 + * @param {Quaternion} q 59.7218 + * @return {Boolean} 59.7219 + */ 59.7220 + Quaternion.prototype.isEqual = function isEqual(q) { 59.7221 + return q.w === this.w && q.x === this.x && q.y === this.y && q.z === this.z; 59.7222 + }; 59.7223 + 59.7224 + /** 59.7225 + * Doc: TODO 59.7226 + * 59.7227 + * @method dot 59.7228 + * @param {Quaternion} q 59.7229 + * @return {Number} 59.7230 + */ 59.7231 + Quaternion.prototype.dot = function dot(q) { 59.7232 + return this.w * q.w + this.x * q.x + this.y * q.y + this.z * q.z; 59.7233 + }; 59.7234 + 59.7235 + /** 59.7236 + * Doc: TODO 59.7237 + * 59.7238 + * @method normSquared 59.7239 + * @return {Number} 59.7240 + */ 59.7241 + Quaternion.prototype.normSquared = function normSquared() { 59.7242 + return this.dot(this); 59.7243 + }; 59.7244 + 59.7245 + /** 59.7246 + * Doc: TODO 59.7247 + * 59.7248 + * @method norm 59.7249 + * @return {Number} 59.7250 + */ 59.7251 + Quaternion.prototype.norm = function norm() { 59.7252 + return Math.sqrt(this.normSquared()); 59.7253 + }; 59.7254 + 59.7255 + /** 59.7256 + * Doc: TODO 59.7257 + * 59.7258 + * @method isZero 59.7259 + * @return {Boolean} 59.7260 + */ 59.7261 + Quaternion.prototype.isZero = function isZero() { 59.7262 + return !(this.x || this.y || this.z); 59.7263 + }; 59.7264 + 59.7265 + /** 59.7266 + * Doc: TODO 59.7267 + * 59.7268 + * @method getTransform 59.7269 + * @return {Transform} 59.7270 + */ 59.7271 + Quaternion.prototype.getTransform = function getTransform() { 59.7272 + var temp = this.normalize(1); 59.7273 + var x = temp.x; 59.7274 + var y = temp.y; 59.7275 + var z = temp.z; 59.7276 + var w = temp.w; 59.7277 + 59.7278 + //LHC system flattened to column major = RHC flattened to row major 59.7279 + return [ 59.7280 + 1 - 2*y*y - 2*z*z, 59.7281 + 2*x*y - 2*z*w, 59.7282 + 2*x*z + 2*y*w, 59.7283 + 0, 59.7284 + 2*x*y + 2*z*w, 59.7285 + 1 - 2*x*x - 2*z*z, 59.7286 + 2*y*z - 2*x*w, 59.7287 + 0, 59.7288 + 2*x*z - 2*y*w, 59.7289 + 2*y*z + 2*x*w, 59.7290 + 1 - 2*x*x - 2*y*y, 59.7291 + 0, 59.7292 + 0, 59.7293 + 0, 59.7294 + 0, 59.7295 + 1 59.7296 + ]; 59.7297 + }; 59.7298 + 59.7299 + var matrixRegister = new Matrix(); 59.7300 + 59.7301 + /** 59.7302 + * Doc: TODO 59.7303 + * 59.7304 + * @method getMatrix 59.7305 + * @return {Transform} 59.7306 + */ 59.7307 + Quaternion.prototype.getMatrix = function getMatrix() { 59.7308 + var temp = this.normalize(1); 59.7309 + var x = temp.x; 59.7310 + var y = temp.y; 59.7311 + var z = temp.z; 59.7312 + var w = temp.w; 59.7313 + 59.7314 + //LHC system flattened to row major 59.7315 + return matrixRegister.set([ 59.7316 + [ 59.7317 + 1 - 2*y*y - 2*z*z, 59.7318 + 2*x*y + 2*z*w, 59.7319 + 2*x*z - 2*y*w 59.7320 + ], 59.7321 + [ 59.7322 + 2*x*y - 2*z*w, 59.7323 + 1 - 2*x*x - 2*z*z, 59.7324 + 2*y*z + 2*x*w 59.7325 + ], 59.7326 + [ 59.7327 + 2*x*z + 2*y*w, 59.7328 + 2*y*z - 2*x*w, 59.7329 + 1 - 2*x*x - 2*y*y 59.7330 + ] 59.7331 + ]); 59.7332 + }; 59.7333 + 59.7334 + var epsilon = 1e-5; 59.7335 + 59.7336 + /** 59.7337 + * Doc: TODO 59.7338 + * 59.7339 + * @method slerp 59.7340 + * @param {Quaternion} q 59.7341 + * @param {Number} t 59.7342 + * @return {Transform} 59.7343 + */ 59.7344 + Quaternion.prototype.slerp = function slerp(q, t) { 59.7345 + var omega; 59.7346 + var cosomega; 59.7347 + var sinomega; 59.7348 + var scaleFrom; 59.7349 + var scaleTo; 59.7350 + 59.7351 + cosomega = this.dot(q); 59.7352 + if ((1.0 - cosomega) > epsilon) { 59.7353 + omega = Math.acos(cosomega); 59.7354 + sinomega = Math.sin(omega); 59.7355 + scaleFrom = Math.sin((1.0 - t) * omega) / sinomega; 59.7356 + scaleTo = Math.sin(t * omega) / sinomega; 59.7357 + } 59.7358 + else { 59.7359 + scaleFrom = 1.0 - t; 59.7360 + scaleTo = t; 59.7361 + } 59.7362 + return register.set(this.scalarMultiply(scaleFrom/scaleTo).add(q).multiply(scaleTo)); 59.7363 + }; 59.7364 + 59.7365 + module.exports = Quaternion; 59.7366 + 59.7367 +}); 59.7368 + 59.7369 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.7370 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.7371 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7372 + * 59.7373 + * Owner: david@famo.us 59.7374 + * @license MPL 2.0 59.7375 + * @copyright Famous Industries, Inc. 2014 59.7376 + */ 59.7377 + 59.7378 +define('famous/math/Random',['require','exports','module'],function(require, exports, module) { 59.7379 + 59.7380 + var RAND = Math.random; 59.7381 + 59.7382 + function _randomFloat(min,max) { 59.7383 + return min + RAND() * (max - min); 59.7384 + } 59.7385 + 59.7386 + function _randomInteger(min,max) { 59.7387 + return (min + RAND() * (max - min + 1)) >> 0; 59.7388 + } 59.7389 + 59.7390 + /** 59.7391 + * Very simple uniform random number generator library wrapping Math.random(). 59.7392 + * 59.7393 + * @class Random 59.7394 + * @static 59.7395 + */ 59.7396 + var Random = {}; 59.7397 + 59.7398 + /** 59.7399 + * Get single random integer between min and max (inclusive), or array 59.7400 + * of size dim if specified. 59.7401 + * 59.7402 + * @method integer 59.7403 + * 59.7404 + * @param {Number} min lower bound, default 0 59.7405 + * @param {Number} max upper bound, default 1 59.7406 + * @param {Number} dim (optional) dimension of output array, if specified 59.7407 + * @return {number | array<number>} random integer, or optionally, an array of random integers 59.7408 + */ 59.7409 + Random.integer = function integer(min,max,dim) { 59.7410 + min = (min !== undefined) ? min : 0; 59.7411 + max = (max !== undefined) ? max : 1; 59.7412 + if (dim !== undefined) { 59.7413 + var result = []; 59.7414 + for (var i = 0; i < dim; i++) result.push(_randomInteger(min,max)); 59.7415 + return result; 59.7416 + } 59.7417 + else return _randomInteger(min,max); 59.7418 + }; 59.7419 + 59.7420 + /** 59.7421 + * Get single random float between min and max (inclusive), or array 59.7422 + * of size dim if specified 59.7423 + * 59.7424 + * @method range 59.7425 + * 59.7426 + * @param {Number} min lower bound, default 0 59.7427 + * @param {Number} max upper bound, default 1 59.7428 + * @param {Number} [dim] dimension of output array, if specified 59.7429 + * @return {Number} random float, or optionally an array 59.7430 + */ 59.7431 + Random.range = function range(min,max,dim) { 59.7432 + min = (min !== undefined) ? min : 0; 59.7433 + max = (max !== undefined) ? max : 1; 59.7434 + if (dim !== undefined) { 59.7435 + var result = []; 59.7436 + for (var i = 0; i < dim; i++) result.push(_randomFloat(min,max)); 59.7437 + return result; 59.7438 + } 59.7439 + else return _randomFloat(min,max); 59.7440 + }; 59.7441 + 59.7442 + /** 59.7443 + * Return random number among the set {-1 ,1} 59.7444 + * 59.7445 + * @method sign 59.7446 + * 59.7447 + * @param {Number} prob probability of returning 1, default 0.5 59.7448 + * @return {Number} random sign (-1 or 1) 59.7449 + */ 59.7450 + Random.sign = function sign(prob) { 59.7451 + prob = (prob !== undefined) ? prob : 0.5; 59.7452 + return (RAND() < prob) ? 1 : -1; 59.7453 + }; 59.7454 + 59.7455 + /** 59.7456 + * Return random boolean value, true or false. 59.7457 + * 59.7458 + * @method bool 59.7459 + * 59.7460 + * @param {Number} prob probability of returning true, default 0.5 59.7461 + * @return {Boolean} random boolean 59.7462 + */ 59.7463 + Random.bool = function bool(prob) { 59.7464 + prob = (prob !== undefined) ? prob : 0.5; 59.7465 + return RAND() < prob; 59.7466 + }; 59.7467 + 59.7468 + module.exports = Random; 59.7469 +}); 59.7470 + 59.7471 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.7472 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.7473 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7474 + * 59.7475 + * Owner: david@famo.us 59.7476 + * @license MPL 2.0 59.7477 + * @copyright Famous Industries, Inc. 2014 59.7478 + */ 59.7479 + 59.7480 +define('famous/events/EventArbiter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.7481 + var EventHandler = require('famous/core/EventHandler'); 59.7482 + 59.7483 + /** 59.7484 + * A switch which wraps several event destinations and 59.7485 + * redirects received events to at most one of them. 59.7486 + * Setting the 'mode' of the object dictates which one 59.7487 + * of these destinations will receive events. 59.7488 + * 59.7489 + * @class EventArbiter 59.7490 + * @constructor 59.7491 + * 59.7492 + * @param {Number | string} startMode initial setting of switch, 59.7493 + */ 59.7494 + function EventArbiter(startMode) { 59.7495 + this.dispatchers = {}; 59.7496 + this.currMode = undefined; 59.7497 + this.setMode(startMode); 59.7498 + } 59.7499 + 59.7500 + /** 59.7501 + * Set switch to this mode, passing events to the corresponding 59.7502 + * EventHandler. If mode has changed, emits 'change' event, 59.7503 + * emits 'unpipe' event to the old mode's handler, and emits 'pipe' 59.7504 + * event to the new mode's handler. 59.7505 + * 59.7506 + * @method setMode 59.7507 + * 59.7508 + * @param {string | number} mode indicating which event handler to send to. 59.7509 + */ 59.7510 + EventArbiter.prototype.setMode = function setMode(mode) { 59.7511 + if (mode !== this.currMode) { 59.7512 + var startMode = this.currMode; 59.7513 + 59.7514 + if (this.dispatchers[this.currMode]) this.dispatchers[this.currMode].trigger('unpipe'); 59.7515 + this.currMode = mode; 59.7516 + if (this.dispatchers[mode]) this.dispatchers[mode].emit('pipe'); 59.7517 + this.emit('change', {from: startMode, to: mode}); 59.7518 + } 59.7519 + }; 59.7520 + 59.7521 + /** 59.7522 + * Return the existing EventHandler corresponding to this 59.7523 + * mode, creating one if it doesn't exist. 59.7524 + * 59.7525 + * @method forMode 59.7526 + * 59.7527 + * @param {string | number} mode mode to which this eventHandler corresponds 59.7528 + * 59.7529 + * @return {EventHandler} eventHandler corresponding to this mode 59.7530 + */ 59.7531 + EventArbiter.prototype.forMode = function forMode(mode) { 59.7532 + if (!this.dispatchers[mode]) this.dispatchers[mode] = new EventHandler(); 59.7533 + return this.dispatchers[mode]; 59.7534 + }; 59.7535 + 59.7536 + /** 59.7537 + * Trigger an event, sending to currently selected handler, if 59.7538 + * it is listening for provided 'type' key. 59.7539 + * 59.7540 + * @method emit 59.7541 + * 59.7542 + * @param {string} eventType event type key (for example, 'click') 59.7543 + * @param {Object} event event data 59.7544 + * @return {EventHandler} this 59.7545 + */ 59.7546 + EventArbiter.prototype.emit = function emit(eventType, event) { 59.7547 + if (this.currMode === undefined) return false; 59.7548 + if (!event) event = {}; 59.7549 + var dispatcher = this.dispatchers[this.currMode]; 59.7550 + if (dispatcher) return dispatcher.trigger(eventType, event); 59.7551 + }; 59.7552 + 59.7553 + module.exports = EventArbiter; 59.7554 +}); 59.7555 + 59.7556 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.7557 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.7558 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7559 + * 59.7560 + * Owner: david@famo.us 59.7561 + * @license MPL 2.0 59.7562 + * @copyright Famous Industries, Inc. 2014 59.7563 + */ 59.7564 + 59.7565 +define('famous/events/EventFilter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.7566 + var EventHandler = require('famous/core/EventHandler'); 59.7567 + 59.7568 + /** 59.7569 + * EventFilter regulates the broadcasting of events based on 59.7570 + * a specified condition function of standard event type: function(type, data). 59.7571 + * 59.7572 + * @class EventFilter 59.7573 + * @constructor 59.7574 + * 59.7575 + * @param {function} condition function to determine whether or not 59.7576 + * events are emitted. 59.7577 + */ 59.7578 + function EventFilter(condition) { 59.7579 + EventHandler.call(this); 59.7580 + this._condition = condition; 59.7581 + } 59.7582 + EventFilter.prototype = Object.create(EventHandler.prototype); 59.7583 + EventFilter.prototype.constructor = EventFilter; 59.7584 + 59.7585 + /** 59.7586 + * If filter condition is met, trigger an event, sending to all downstream handlers 59.7587 + * listening for provided 'type' key. 59.7588 + * 59.7589 + * @method emit 59.7590 + * 59.7591 + * @param {string} type event type key (for example, 'click') 59.7592 + * @param {Object} data event data 59.7593 + * @return {EventHandler} this 59.7594 + */ 59.7595 + EventFilter.prototype.emit = function emit(type, data) { 59.7596 + if (this._condition(type, data)) 59.7597 + return EventHandler.prototype.emit.apply(this, arguments); 59.7598 + }; 59.7599 + 59.7600 + /** 59.7601 + * An alias of emit. Trigger determines whether to send 59.7602 + * events based on the return value of it's condition function 59.7603 + * when passed the event type and associated data. 59.7604 + * 59.7605 + * @method trigger 59.7606 + * @param {string} type name of the event 59.7607 + * @param {object} data associated data 59.7608 + */ 59.7609 + EventFilter.prototype.trigger = EventFilter.prototype.emit; 59.7610 + 59.7611 + module.exports = EventFilter; 59.7612 +}); 59.7613 + 59.7614 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.7615 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.7616 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7617 + * 59.7618 + * Owner: david@famo.us 59.7619 + * @license MPL 2.0 59.7620 + * @copyright Famous Industries, Inc. 2014 59.7621 + */ 59.7622 + 59.7623 +define('famous/events/EventMapper',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.7624 + var EventHandler = require('famous/core/EventHandler'); 59.7625 + 59.7626 + /** 59.7627 + * EventMapper routes events to various event destinations 59.7628 + * based on custom logic. The function signature is arbitrary. 59.7629 + * 59.7630 + * @class EventMapper 59.7631 + * @constructor 59.7632 + * 59.7633 + * @param {function} mappingFunction function to determine where 59.7634 + * events are routed to. 59.7635 + */ 59.7636 + function EventMapper(mappingFunction) { 59.7637 + EventHandler.call(this); 59.7638 + this._mappingFunction = mappingFunction; 59.7639 + } 59.7640 + EventMapper.prototype = Object.create(EventHandler.prototype); 59.7641 + EventMapper.prototype.constructor = EventMapper; 59.7642 + 59.7643 + EventMapper.prototype.subscribe = null; 59.7644 + EventMapper.prototype.unsubscribe = null; 59.7645 + 59.7646 + /** 59.7647 + * Trigger an event, sending to all mapped downstream handlers 59.7648 + * listening for provided 'type' key. 59.7649 + * 59.7650 + * @method emit 59.7651 + * 59.7652 + * @param {string} type event type key (for example, 'click') 59.7653 + * @param {Object} data event data 59.7654 + * @return {EventHandler} this 59.7655 + */ 59.7656 + EventMapper.prototype.emit = function emit(type, data) { 59.7657 + var target = this._mappingFunction.apply(this, arguments); 59.7658 + if (target && (target.emit instanceof Function)) target.emit(type, data); 59.7659 + }; 59.7660 + 59.7661 + /** 59.7662 + * Alias of emit. 59.7663 + * @method trigger 59.7664 + */ 59.7665 + EventMapper.prototype.trigger = EventMapper.prototype.emit; 59.7666 + 59.7667 + module.exports = EventMapper; 59.7668 +}); 59.7669 + 59.7670 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.7671 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.7672 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.7673 + * 59.7674 + * @license MPL 2.0 59.7675 + * @copyright Famous Industries, Inc. 2014 59.7676 + */ 59.7677 +define('famous/physics/PhysicsEngine',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.7678 + var EventHandler = require('famous/core/EventHandler'); 59.7679 + 59.7680 + /** 59.7681 + * The Physics Engine is responsible for mediating Bodies and their 59.7682 + * interaction with forces and constraints. The Physics Engine handles the 59.7683 + * logic of adding and removing bodies, updating their state of the over 59.7684 + * time. 59.7685 + * 59.7686 + * @class PhysicsEngine 59.7687 + * @constructor 59.7688 + * @param options {Object} options 59.7689 + */ 59.7690 + function PhysicsEngine(options) { 59.7691 + this.options = Object.create(PhysicsEngine.DEFAULT_OPTIONS); 59.7692 + if (options) this.setOptions(options); 59.7693 + 59.7694 + this._particles = []; //list of managed particles 59.7695 + this._bodies = []; //list of managed bodies 59.7696 + this._agents = {}; //hash of managed agents 59.7697 + this._forces = []; //list of IDs of agents that are forces 59.7698 + this._constraints = []; //list of IDs of agents that are constraints 59.7699 + 59.7700 + this._buffer = 0.0; 59.7701 + this._prevTime = now(); 59.7702 + this._isSleeping = false; 59.7703 + this._eventHandler = null; 59.7704 + this._currAgentId = 0; 59.7705 + this._hasBodies = false; 59.7706 + } 59.7707 + 59.7708 + var TIMESTEP = 17; 59.7709 + var MIN_TIME_STEP = 1000 / 120; 59.7710 + var MAX_TIME_STEP = 17; 59.7711 + 59.7712 + /** 59.7713 + * @property PhysicsEngine.DEFAULT_OPTIONS 59.7714 + * @type Object 59.7715 + * @protected 59.7716 + * @static 59.7717 + */ 59.7718 + PhysicsEngine.DEFAULT_OPTIONS = { 59.7719 + 59.7720 + /** 59.7721 + * The number of iterations the engine takes to resolve constraints 59.7722 + * @attribute constraintSteps 59.7723 + * @type Number 59.7724 + */ 59.7725 + constraintSteps : 1, 59.7726 + 59.7727 + /** 59.7728 + * The energy threshold before the Engine stops updating 59.7729 + * @attribute sleepTolerance 59.7730 + * @type Number 59.7731 + */ 59.7732 + sleepTolerance : 1e-7 59.7733 + }; 59.7734 + 59.7735 + var now = (function() { 59.7736 + return Date.now; 59.7737 + })(); 59.7738 + 59.7739 + /** 59.7740 + * Options setter 59.7741 + * @method setOptions 59.7742 + * @param options {Object} 59.7743 + */ 59.7744 + PhysicsEngine.prototype.setOptions = function setOptions(opts) { 59.7745 + for (var key in opts) if (this.options[key]) this.options[key] = opts[key]; 59.7746 + }; 59.7747 + 59.7748 + /** 59.7749 + * Method to add a physics body to the engine. Necessary to update the 59.7750 + * body over time. 59.7751 + * 59.7752 + * @method addBody 59.7753 + * @param body {Body} 59.7754 + * @return body {Body} 59.7755 + */ 59.7756 + PhysicsEngine.prototype.addBody = function addBody(body) { 59.7757 + body._engine = this; 59.7758 + if (body.isBody) { 59.7759 + this._bodies.push(body); 59.7760 + this._hasBodies = true; 59.7761 + } 59.7762 + else this._particles.push(body); 59.7763 + return body; 59.7764 + }; 59.7765 + 59.7766 + /** 59.7767 + * Remove a body from the engine. Detaches body from all forces and 59.7768 + * constraints. 59.7769 + * 59.7770 + * @method removeBody 59.7771 + * @param body {Body} 59.7772 + */ 59.7773 + PhysicsEngine.prototype.removeBody = function removeBody(body) { 59.7774 + var array = (body.isBody) ? this._bodies : this._particles; 59.7775 + var index = array.indexOf(body); 59.7776 + if (index > -1) { 59.7777 + for (var i = 0; i < Object.keys(this._agents).length; i++) this.detachFrom(i, body); 59.7778 + array.splice(index,1); 59.7779 + } 59.7780 + if (this.getBodies().length === 0) this._hasBodies = false; 59.7781 + }; 59.7782 + 59.7783 + function _mapAgentArray(agent) { 59.7784 + if (agent.applyForce) return this._forces; 59.7785 + if (agent.applyConstraint) return this._constraints; 59.7786 + } 59.7787 + 59.7788 + function _attachOne(agent, targets, source) { 59.7789 + if (targets === undefined) targets = this.getParticlesAndBodies(); 59.7790 + if (!(targets instanceof Array)) targets = [targets]; 59.7791 + 59.7792 + this._agents[this._currAgentId] = { 59.7793 + agent : agent, 59.7794 + targets : targets, 59.7795 + source : source 59.7796 + }; 59.7797 + 59.7798 + _mapAgentArray.call(this, agent).push(this._currAgentId); 59.7799 + return this._currAgentId++; 59.7800 + } 59.7801 + 59.7802 + /** 59.7803 + * Attaches a force or constraint to a Body. Returns an AgentId of the 59.7804 + * attached agent which can be used to detach the agent. 59.7805 + * 59.7806 + * @method attach 59.7807 + * @param agent {Agent|Array.Agent} A force, constraint, or array of them. 59.7808 + * @param [targets=All] {Body|Array.Body} The Body or Bodies affected by the agent 59.7809 + * @param [source] {Body} The source of the agent 59.7810 + * @return AgentId {Number} 59.7811 + */ 59.7812 + PhysicsEngine.prototype.attach = function attach(agents, targets, source) { 59.7813 + if (agents instanceof Array) { 59.7814 + var agentIDs = []; 59.7815 + for (var i = 0; i < agents.length; i++) 59.7816 + agentIDs[i] = _attachOne.call(this, agents[i], targets, source); 59.7817 + return agentIDs; 59.7818 + } 59.7819 + else return _attachOne.call(this, agents, targets, source); 59.7820 + }; 59.7821 + 59.7822 + /** 59.7823 + * Append a body to the targets of a previously defined physics agent. 59.7824 + * 59.7825 + * @method attachTo 59.7826 + * @param agentID {AgentId} The agentId of a previously defined agent 59.7827 + * @param target {Body} The Body affected by the agent 59.7828 + */ 59.7829 + PhysicsEngine.prototype.attachTo = function attachTo(agentID, target) { 59.7830 + _getBoundAgent.call(this, agentID).targets.push(target); 59.7831 + }; 59.7832 + 59.7833 + /** 59.7834 + * Undoes PhysicsEngine.attach. Removes an agent and its associated 59.7835 + * effect on its affected Bodies. 59.7836 + * 59.7837 + * @method detach 59.7838 + * @param agentID {AgentId} The agentId of a previously defined agent 59.7839 + */ 59.7840 + PhysicsEngine.prototype.detach = function detach(id) { 59.7841 + // detach from forces/constraints array 59.7842 + var agent = this.getAgent(id); 59.7843 + var agentArray = _mapAgentArray.call(this, agent); 59.7844 + var index = agentArray.indexOf(id); 59.7845 + agentArray.splice(index,1); 59.7846 + 59.7847 + // detach agents array 59.7848 + delete this._agents[id]; 59.7849 + }; 59.7850 + 59.7851 + /** 59.7852 + * Remove a single Body from a previously defined agent. 59.7853 + * 59.7854 + * @method detach 59.7855 + * @param agentID {AgentId} The agentId of a previously defined agent 59.7856 + * @param target {Body} The body to remove from the agent 59.7857 + */ 59.7858 + PhysicsEngine.prototype.detachFrom = function detachFrom(id, target) { 59.7859 + var boundAgent = _getBoundAgent.call(this, id); 59.7860 + if (boundAgent.source === target) this.detach(id); 59.7861 + else { 59.7862 + var targets = boundAgent.targets; 59.7863 + var index = targets.indexOf(target); 59.7864 + if (index > -1) targets.splice(index,1); 59.7865 + } 59.7866 + }; 59.7867 + 59.7868 + /** 59.7869 + * A convenience method to give the Physics Engine a clean slate of 59.7870 + * agents. Preserves all added Body objects. 59.7871 + * 59.7872 + * @method detachAll 59.7873 + */ 59.7874 + PhysicsEngine.prototype.detachAll = function detachAll() { 59.7875 + this._agents = {}; 59.7876 + this._forces = []; 59.7877 + this._constraints = []; 59.7878 + this._currAgentId = 0; 59.7879 + }; 59.7880 + 59.7881 + function _getBoundAgent(id) { 59.7882 + return this._agents[id]; 59.7883 + } 59.7884 + 59.7885 + /** 59.7886 + * Returns the corresponding agent given its agentId. 59.7887 + * 59.7888 + * @method getAgent 59.7889 + * @param id {AgentId} 59.7890 + */ 59.7891 + PhysicsEngine.prototype.getAgent = function getAgent(id) { 59.7892 + return _getBoundAgent.call(this, id).agent; 59.7893 + }; 59.7894 + 59.7895 + /** 59.7896 + * Returns all particles that are currently managed by the Physics Engine. 59.7897 + * 59.7898 + * @method getParticles 59.7899 + * @return particles {Array.Particles} 59.7900 + */ 59.7901 + PhysicsEngine.prototype.getParticles = function getParticles() { 59.7902 + return this._particles; 59.7903 + }; 59.7904 + 59.7905 + /** 59.7906 + * Returns all bodies, except particles, that are currently managed by the Physics Engine. 59.7907 + * 59.7908 + * @method getBodies 59.7909 + * @return bodies {Array.Bodies} 59.7910 + */ 59.7911 + PhysicsEngine.prototype.getBodies = function getBodies() { 59.7912 + return this._bodies; 59.7913 + }; 59.7914 + 59.7915 + /** 59.7916 + * Returns all bodies that are currently managed by the Physics Engine. 59.7917 + * 59.7918 + * @method getBodies 59.7919 + * @return bodies {Array.Bodies} 59.7920 + */ 59.7921 + PhysicsEngine.prototype.getParticlesAndBodies = function getParticlesAndBodies() { 59.7922 + return this.getParticles().concat(this.getBodies()); 59.7923 + }; 59.7924 + 59.7925 + /** 59.7926 + * Iterates over every Particle and applies a function whose first 59.7927 + * argument is the Particle 59.7928 + * 59.7929 + * @method forEachParticle 59.7930 + * @param fn {Function} Function to iterate over 59.7931 + * @param [dt] {Number} Delta time 59.7932 + */ 59.7933 + PhysicsEngine.prototype.forEachParticle = function forEachParticle(fn, dt) { 59.7934 + var particles = this.getParticles(); 59.7935 + for (var index = 0, len = particles.length; index < len; index++) 59.7936 + fn.call(this, particles[index], dt); 59.7937 + }; 59.7938 + 59.7939 + /** 59.7940 + * Iterates over every Body that isn't a Particle and applies 59.7941 + * a function whose first argument is the Body 59.7942 + * 59.7943 + * @method forEachBody 59.7944 + * @param fn {Function} Function to iterate over 59.7945 + * @param [dt] {Number} Delta time 59.7946 + */ 59.7947 + PhysicsEngine.prototype.forEachBody = function forEachBody(fn, dt) { 59.7948 + if (!this._hasBodies) return; 59.7949 + var bodies = this.getBodies(); 59.7950 + for (var index = 0, len = bodies.length; index < len; index++) 59.7951 + fn.call(this, bodies[index], dt); 59.7952 + }; 59.7953 + 59.7954 + /** 59.7955 + * Iterates over every Body and applies a function whose first 59.7956 + * argument is the Body 59.7957 + * 59.7958 + * @method forEach 59.7959 + * @param fn {Function} Function to iterate over 59.7960 + * @param [dt] {Number} Delta time 59.7961 + */ 59.7962 + PhysicsEngine.prototype.forEach = function forEach(fn, dt) { 59.7963 + this.forEachParticle(fn, dt); 59.7964 + this.forEachBody(fn, dt); 59.7965 + }; 59.7966 + 59.7967 + function _updateForce(index) { 59.7968 + var boundAgent = _getBoundAgent.call(this, this._forces[index]); 59.7969 + boundAgent.agent.applyForce(boundAgent.targets, boundAgent.source); 59.7970 + } 59.7971 + 59.7972 + function _updateForces() { 59.7973 + for (var index = this._forces.length - 1; index > -1; index--) 59.7974 + _updateForce.call(this, index); 59.7975 + } 59.7976 + 59.7977 + function _updateConstraint(index, dt) { 59.7978 + var boundAgent = this._agents[this._constraints[index]]; 59.7979 + return boundAgent.agent.applyConstraint(boundAgent.targets, boundAgent.source, dt); 59.7980 + } 59.7981 + 59.7982 + function _updateConstraints(dt) { 59.7983 + var iteration = 0; 59.7984 + while (iteration < this.options.constraintSteps) { 59.7985 + for (var index = this._constraints.length - 1; index > -1; index--) 59.7986 + _updateConstraint.call(this, index, dt); 59.7987 + iteration++; 59.7988 + } 59.7989 + } 59.7990 + 59.7991 + function _updateVelocities(particle, dt) { 59.7992 + particle.integrateVelocity(dt); 59.7993 + } 59.7994 + 59.7995 + function _updateAngularVelocities(body, dt) { 59.7996 + body.integrateAngularMomentum(dt); 59.7997 + body.updateAngularVelocity(); 59.7998 + } 59.7999 + 59.8000 + function _updateOrientations(body, dt) { 59.8001 + body.integrateOrientation(dt); 59.8002 + } 59.8003 + 59.8004 + function _updatePositions(particle, dt) { 59.8005 + particle.integratePosition(dt); 59.8006 + particle.emit('update', particle); 59.8007 + } 59.8008 + 59.8009 + function _integrate(dt) { 59.8010 + _updateForces.call(this, dt); 59.8011 + this.forEach(_updateVelocities, dt); 59.8012 + this.forEachBody(_updateAngularVelocities, dt); 59.8013 + _updateConstraints.call(this, dt); 59.8014 + this.forEachBody(_updateOrientations, dt); 59.8015 + this.forEach(_updatePositions, dt); 59.8016 + } 59.8017 + 59.8018 + function _getEnergyParticles() { 59.8019 + var energy = 0.0; 59.8020 + var particleEnergy = 0.0; 59.8021 + this.forEach(function(particle) { 59.8022 + particleEnergy = particle.getEnergy(); 59.8023 + energy += particleEnergy; 59.8024 + if (particleEnergy < particle.sleepTolerance) particle.sleep(); 59.8025 + }); 59.8026 + return energy; 59.8027 + } 59.8028 + 59.8029 + function _getEnergyForces() { 59.8030 + var energy = 0; 59.8031 + for (var index = this._forces.length - 1; index > -1; index--) 59.8032 + energy += this._forces[index].getEnergy() || 0.0; 59.8033 + return energy; 59.8034 + } 59.8035 + 59.8036 + function _getEnergyConstraints() { 59.8037 + var energy = 0; 59.8038 + for (var index = this._constraints.length - 1; index > -1; index--) 59.8039 + energy += this._constraints[index].getEnergy() || 0.0; 59.8040 + return energy; 59.8041 + } 59.8042 + 59.8043 + /** 59.8044 + * Calculates the kinetic energy of all Body objects and potential energy 59.8045 + * of all attached agents. 59.8046 + * 59.8047 + * TODO: implement. 59.8048 + * @method getEnergy 59.8049 + * @return energy {Number} 59.8050 + */ 59.8051 + PhysicsEngine.prototype.getEnergy = function getEnergy() { 59.8052 + return _getEnergyParticles.call(this) + _getEnergyForces.call(this) + _getEnergyConstraints.call(this); 59.8053 + }; 59.8054 + 59.8055 + /** 59.8056 + * Updates all Body objects managed by the physics engine over the 59.8057 + * time duration since the last time step was called. 59.8058 + * 59.8059 + * @method step 59.8060 + */ 59.8061 + PhysicsEngine.prototype.step = function step() { 59.8062 +// if (this.getEnergy() < this.options.sleepTolerance) { 59.8063 +// this.sleep(); 59.8064 +// return; 59.8065 +// }; 59.8066 + 59.8067 + //set current frame's time 59.8068 + var currTime = now(); 59.8069 + 59.8070 + //milliseconds elapsed since last frame 59.8071 + var dtFrame = currTime - this._prevTime; 59.8072 + 59.8073 + this._prevTime = currTime; 59.8074 + 59.8075 + if (dtFrame < MIN_TIME_STEP) return; 59.8076 + if (dtFrame > MAX_TIME_STEP) dtFrame = MAX_TIME_STEP; 59.8077 + 59.8078 + //robust integration 59.8079 +// this._buffer += dtFrame; 59.8080 +// while (this._buffer > this._timestep){ 59.8081 +// _integrate.call(this, this._timestep); 59.8082 +// this._buffer -= this._timestep; 59.8083 +// }; 59.8084 +// _integrate.call(this, this._buffer); 59.8085 +// this._buffer = 0.0; 59.8086 + _integrate.call(this, TIMESTEP); 59.8087 + 59.8088 +// this.emit('update', this); 59.8089 + }; 59.8090 + 59.8091 + /** 59.8092 + * Tells whether the Physics Engine is sleeping or awake. 59.8093 + * @method isSleeping 59.8094 + * @return {Boolean} 59.8095 + */ 59.8096 + PhysicsEngine.prototype.isSleeping = function isSleeping() { 59.8097 + return this._isSleeping; 59.8098 + }; 59.8099 + 59.8100 + /** 59.8101 + * Stops the Physics Engine from updating. Emits an 'end' event. 59.8102 + * @method sleep 59.8103 + */ 59.8104 + PhysicsEngine.prototype.sleep = function sleep() { 59.8105 + this.emit('end', this); 59.8106 + this._isSleeping = true; 59.8107 + }; 59.8108 + 59.8109 + /** 59.8110 + * Starts the Physics Engine from updating. Emits an 'start' event. 59.8111 + * @method wake 59.8112 + */ 59.8113 + PhysicsEngine.prototype.wake = function wake() { 59.8114 + this._prevTime = now(); 59.8115 + this.emit('start', this); 59.8116 + this._isSleeping = false; 59.8117 + }; 59.8118 + 59.8119 + PhysicsEngine.prototype.emit = function emit(type, data) { 59.8120 + if (this._eventHandler === null) return; 59.8121 + this._eventHandler.emit(type, data); 59.8122 + }; 59.8123 + 59.8124 + PhysicsEngine.prototype.on = function on(event, fn) { 59.8125 + if (this._eventHandler === null) this._eventHandler = new EventHandler(); 59.8126 + this._eventHandler.on(event, fn); 59.8127 + }; 59.8128 + 59.8129 + module.exports = PhysicsEngine; 59.8130 +}); 59.8131 + 59.8132 +define('famous/inputs/Accumulator',['require','exports','module','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) { 59.8133 + var EventHandler = require('famous/core/EventHandler'); 59.8134 + var Transitionable = require('famous/transitions/Transitionable'); 59.8135 + 59.8136 + /** 59.8137 + * Accumulates differentials of event sources that emit a `delta` 59.8138 + * attribute taking a Number or Array of Number types. The accumulated 59.8139 + * value is stored in a getter/setter. 59.8140 + * 59.8141 + * @class Accumulator 59.8142 + * @constructor 59.8143 + * @param value {Number|Array|Transitionable} Initializing value 59.8144 + * @param [eventName='update'] {String} Name of update event 59.8145 + */ 59.8146 + function Accumulator(value, eventName) { 59.8147 + if (eventName === undefined) eventName = 'update'; 59.8148 + 59.8149 + this._state = (value && value.get && value.set) 59.8150 + ? value 59.8151 + : new Transitionable(value || 0); 59.8152 + 59.8153 + this._eventInput = new EventHandler(); 59.8154 + EventHandler.setInputHandler(this, this._eventInput); 59.8155 + 59.8156 + this._eventInput.on(eventName, _handleUpdate.bind(this)); 59.8157 + } 59.8158 + 59.8159 + function _handleUpdate(data) { 59.8160 + var delta = data.delta; 59.8161 + var state = this.get(); 59.8162 + 59.8163 + if (delta.constructor === state.constructor){ 59.8164 + var newState = (delta instanceof Array) 59.8165 + ? [state[0] + delta[0], state[1] + delta[1]] 59.8166 + : state + delta; 59.8167 + this.set(newState); 59.8168 + } 59.8169 + } 59.8170 + 59.8171 + /** 59.8172 + * Basic getter 59.8173 + * 59.8174 + * @method get 59.8175 + * @return {Number|Array} current value 59.8176 + */ 59.8177 + Accumulator.prototype.get = function get() { 59.8178 + return this._state.get(); 59.8179 + }; 59.8180 + 59.8181 + /** 59.8182 + * Basic setter 59.8183 + * 59.8184 + * @method set 59.8185 + * @param value {Number|Array} new value 59.8186 + */ 59.8187 + Accumulator.prototype.set = function set(value) { 59.8188 + this._state.set(value); 59.8189 + }; 59.8190 + 59.8191 + module.exports = Accumulator; 59.8192 +}); 59.8193 + 59.8194 +define('famous/inputs/DesktopEmulationMode',['require','exports','module'],function(require, exports, module) { 59.8195 + var hasTouch = 'ontouchstart' in window; 59.8196 + 59.8197 + function kill(type) { 59.8198 + window.addEventListener(type, function(event) { 59.8199 + event.stopPropagation(); 59.8200 + return false; 59.8201 + }, true); 59.8202 + } 59.8203 + 59.8204 + if (hasTouch) { 59.8205 + kill('mousedown'); 59.8206 + kill('mousemove'); 59.8207 + kill('mouseup'); 59.8208 + kill('mouseleave'); 59.8209 + } 59.8210 +}); 59.8211 + 59.8212 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8213 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8214 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8215 + * 59.8216 + * Owner: mark@famo.us 59.8217 + * @license MPL 2.0 59.8218 + * @copyright Famous Industries, Inc. 2014 59.8219 + */ 59.8220 + 59.8221 +define('famous/inputs/FastClick',['require','exports','module'],function(require, exports, module) { 59.8222 + /** 59.8223 + * FastClick is an override shim which maps event pairs of 59.8224 + * 'touchstart' and 'touchend' which differ by less than a certain 59.8225 + * threshold to the 'click' event. 59.8226 + * This is used to speed up clicks on some browsers. 59.8227 + */ 59.8228 + if (!window.CustomEvent) return; 59.8229 + var clickThreshold = 300; 59.8230 + var clickWindow = 500; 59.8231 + var potentialClicks = {}; 59.8232 + var recentlyDispatched = {}; 59.8233 + var _now = Date.now; 59.8234 + 59.8235 + window.addEventListener('touchstart', function(event) { 59.8236 + var timestamp = _now(); 59.8237 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8238 + var touch = event.changedTouches[i]; 59.8239 + potentialClicks[touch.identifier] = timestamp; 59.8240 + } 59.8241 + }); 59.8242 + 59.8243 + window.addEventListener('touchmove', function(event) { 59.8244 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8245 + var touch = event.changedTouches[i]; 59.8246 + delete potentialClicks[touch.identifier]; 59.8247 + } 59.8248 + }); 59.8249 + 59.8250 + window.addEventListener('touchend', function(event) { 59.8251 + var currTime = _now(); 59.8252 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8253 + var touch = event.changedTouches[i]; 59.8254 + var startTime = potentialClicks[touch.identifier]; 59.8255 + if (startTime && currTime - startTime < clickThreshold) { 59.8256 + var clickEvt = new window.CustomEvent('click', { 59.8257 + 'bubbles': true, 59.8258 + 'details': touch 59.8259 + }); 59.8260 + recentlyDispatched[currTime] = event; 59.8261 + event.target.dispatchEvent(clickEvt); 59.8262 + } 59.8263 + delete potentialClicks[touch.identifier]; 59.8264 + } 59.8265 + }); 59.8266 + 59.8267 + window.addEventListener('click', function(event) { 59.8268 + var currTime = _now(); 59.8269 + for (var i in recentlyDispatched) { 59.8270 + var previousEvent = recentlyDispatched[i]; 59.8271 + if (currTime - i < clickWindow) { 59.8272 + if (event instanceof window.MouseEvent && event.target === previousEvent.target) event.stopPropagation(); 59.8273 + } 59.8274 + else delete recentlyDispatched[i]; 59.8275 + } 59.8276 + }, true); 59.8277 +}); 59.8278 + 59.8279 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8280 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8281 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8282 + * 59.8283 + * Owner: mark@famo.us 59.8284 + * @license MPL 2.0 59.8285 + * @copyright Famous Industries, Inc. 2014 59.8286 + */ 59.8287 + 59.8288 +define('famous/inputs/TwoFingerSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.8289 + var EventHandler = require('famous/core/EventHandler'); 59.8290 + 59.8291 + /** 59.8292 + * Helper to PinchSync, RotateSync, and ScaleSync. Generalized handling of 59.8293 + * two-finger touch events. 59.8294 + * This class is meant to be overridden and not used directly. 59.8295 + * 59.8296 + * @class TwoFingerSync 59.8297 + * @constructor 59.8298 + */ 59.8299 + function TwoFingerSync() { 59.8300 + this._eventInput = new EventHandler(); 59.8301 + this._eventOutput = new EventHandler(); 59.8302 + 59.8303 + EventHandler.setInputHandler(this, this._eventInput); 59.8304 + EventHandler.setOutputHandler(this, this._eventOutput); 59.8305 + 59.8306 + this.touchAEnabled = false; 59.8307 + this.touchAId = 0; 59.8308 + this.posA = null; 59.8309 + this.timestampA = 0; 59.8310 + this.touchBEnabled = false; 59.8311 + this.touchBId = 0; 59.8312 + this.posB = null; 59.8313 + this.timestampB = 0; 59.8314 + 59.8315 + this._eventInput.on('touchstart', this.handleStart.bind(this)); 59.8316 + this._eventInput.on('touchmove', this.handleMove.bind(this)); 59.8317 + this._eventInput.on('touchend', this.handleEnd.bind(this)); 59.8318 + this._eventInput.on('touchcancel', this.handleEnd.bind(this)); 59.8319 + } 59.8320 + 59.8321 + TwoFingerSync.calculateAngle = function(posA, posB) { 59.8322 + var diffX = posB[0] - posA[0]; 59.8323 + var diffY = posB[1] - posA[1]; 59.8324 + return Math.atan2(diffY, diffX); 59.8325 + }; 59.8326 + 59.8327 + TwoFingerSync.calculateDistance = function(posA, posB) { 59.8328 + var diffX = posB[0] - posA[0]; 59.8329 + var diffY = posB[1] - posA[1]; 59.8330 + return Math.sqrt(diffX * diffX + diffY * diffY); 59.8331 + }; 59.8332 + 59.8333 + TwoFingerSync.calculateCenter = function(posA, posB) { 59.8334 + return [(posA[0] + posB[0]) / 2.0, (posA[1] + posB[1]) / 2.0]; 59.8335 + }; 59.8336 + 59.8337 + var _now = Date.now; 59.8338 + 59.8339 + // private 59.8340 + TwoFingerSync.prototype.handleStart = function handleStart(event) { 59.8341 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8342 + var touch = event.changedTouches[i]; 59.8343 + if (!this.touchAEnabled) { 59.8344 + this.touchAId = touch.identifier; 59.8345 + this.touchAEnabled = true; 59.8346 + this.posA = [touch.pageX, touch.pageY]; 59.8347 + this.timestampA = _now(); 59.8348 + } 59.8349 + else if (!this.touchBEnabled) { 59.8350 + this.touchBId = touch.identifier; 59.8351 + this.touchBEnabled = true; 59.8352 + this.posB = [touch.pageX, touch.pageY]; 59.8353 + this.timestampB = _now(); 59.8354 + this._startUpdate(event); 59.8355 + } 59.8356 + } 59.8357 + }; 59.8358 + 59.8359 + // private 59.8360 + TwoFingerSync.prototype.handleMove = function handleMove(event) { 59.8361 + if (!(this.touchAEnabled && this.touchBEnabled)) return; 59.8362 + var prevTimeA = this.timestampA; 59.8363 + var prevTimeB = this.timestampB; 59.8364 + var diffTime; 59.8365 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8366 + var touch = event.changedTouches[i]; 59.8367 + if (touch.identifier === this.touchAId) { 59.8368 + this.posA = [touch.pageX, touch.pageY]; 59.8369 + this.timestampA = _now(); 59.8370 + diffTime = this.timestampA - prevTimeA; 59.8371 + } 59.8372 + else if (touch.identifier === this.touchBId) { 59.8373 + this.posB = [touch.pageX, touch.pageY]; 59.8374 + this.timestampB = _now(); 59.8375 + diffTime = this.timestampB - prevTimeB; 59.8376 + } 59.8377 + } 59.8378 + if (diffTime) this._moveUpdate(diffTime); 59.8379 + }; 59.8380 + 59.8381 + // private 59.8382 + TwoFingerSync.prototype.handleEnd = function handleEnd(event) { 59.8383 + for (var i = 0; i < event.changedTouches.length; i++) { 59.8384 + var touch = event.changedTouches[i]; 59.8385 + if (touch.identifier === this.touchAId || touch.identifier === this.touchBId) { 59.8386 + if (this.touchAEnabled && this.touchBEnabled) { 59.8387 + this._eventOutput.emit('end', { 59.8388 + touches : [this.touchAId, this.touchBId], 59.8389 + angle : this._angle 59.8390 + }); 59.8391 + } 59.8392 + this.touchAEnabled = false; 59.8393 + this.touchAId = 0; 59.8394 + this.touchBEnabled = false; 59.8395 + this.touchBId = 0; 59.8396 + } 59.8397 + } 59.8398 + }; 59.8399 + 59.8400 + module.exports = TwoFingerSync; 59.8401 +}); 59.8402 + 59.8403 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8404 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8405 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8406 + * 59.8407 + * Owner: mark@famo.us 59.8408 + * @license MPL 2.0 59.8409 + * @copyright Famous Industries, Inc. 2014 59.8410 + */ 59.8411 + 59.8412 +define('famous/inputs/PinchSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 59.8413 + var TwoFingerSync = require('./TwoFingerSync'); 59.8414 + 59.8415 + /** 59.8416 + * Handles piped in two-finger touch events to change position via pinching / expanding. 59.8417 + * Emits 'start', 'update' and 'end' events with 59.8418 + * position, velocity, touch ids, and distance between fingers. 59.8419 + * 59.8420 + * @class PinchSync 59.8421 + * @extends TwoFingerSync 59.8422 + * @constructor 59.8423 + * @param {Object} options default options overrides 59.8424 + * @param {Number} [options.scale] scale velocity by this factor 59.8425 + */ 59.8426 + function PinchSync(options) { 59.8427 + TwoFingerSync.call(this); 59.8428 + 59.8429 + this.options = Object.create(PinchSync.DEFAULT_OPTIONS); 59.8430 + if (options) this.setOptions(options); 59.8431 + 59.8432 + this._displacement = 0; 59.8433 + this._previousDistance = 0; 59.8434 + } 59.8435 + 59.8436 + PinchSync.prototype = Object.create(TwoFingerSync.prototype); 59.8437 + PinchSync.prototype.constructor = PinchSync; 59.8438 + 59.8439 + PinchSync.DEFAULT_OPTIONS = { 59.8440 + scale : 1 59.8441 + }; 59.8442 + 59.8443 + PinchSync.prototype._startUpdate = function _startUpdate(event) { 59.8444 + this._previousDistance = TwoFingerSync.calculateDistance(this.posA, this.posB); 59.8445 + this._displacement = 0; 59.8446 + 59.8447 + this._eventOutput.emit('start', { 59.8448 + count: event.touches.length, 59.8449 + touches: [this.touchAId, this.touchBId], 59.8450 + distance: this._dist, 59.8451 + center: TwoFingerSync.calculateCenter(this.posA, this.posB) 59.8452 + }); 59.8453 + }; 59.8454 + 59.8455 + PinchSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 59.8456 + var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 59.8457 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 59.8458 + 59.8459 + var scale = this.options.scale; 59.8460 + var delta = scale * (currDist - this._previousDistance); 59.8461 + var velocity = delta / diffTime; 59.8462 + 59.8463 + this._previousDistance = currDist; 59.8464 + this._displacement += delta; 59.8465 + 59.8466 + this._eventOutput.emit('update', { 59.8467 + delta : delta, 59.8468 + velocity: velocity, 59.8469 + distance: currDist, 59.8470 + displacement: this._displacement, 59.8471 + center: center, 59.8472 + touches: [this.touchAId, this.touchBId] 59.8473 + }); 59.8474 + }; 59.8475 + 59.8476 + /** 59.8477 + * Return entire options dictionary, including defaults. 59.8478 + * 59.8479 + * @method getOptions 59.8480 + * @return {Object} configuration options 59.8481 + */ 59.8482 + PinchSync.prototype.getOptions = function getOptions() { 59.8483 + return this.options; 59.8484 + }; 59.8485 + 59.8486 + /** 59.8487 + * Set internal options, overriding any default options 59.8488 + * 59.8489 + * @method setOptions 59.8490 + * 59.8491 + * @param {Object} [options] overrides of default options 59.8492 + * @param {Number} [options.scale] scale velocity by this factor 59.8493 + */ 59.8494 + PinchSync.prototype.setOptions = function setOptions(options) { 59.8495 + if (options.scale !== undefined) this.options.scale = options.scale; 59.8496 + }; 59.8497 + 59.8498 + module.exports = PinchSync; 59.8499 +}); 59.8500 + 59.8501 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8502 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8503 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8504 + * 59.8505 + * Owner: mark@famo.us 59.8506 + * @license MPL 2.0 59.8507 + * @copyright Famous Industries, Inc. 2014 59.8508 + */ 59.8509 + 59.8510 +define('famous/inputs/RotateSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 59.8511 + var TwoFingerSync = require('./TwoFingerSync'); 59.8512 + 59.8513 + /** 59.8514 + * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding. 59.8515 + * Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, and angle. 59.8516 + * Useful for determining a rotation factor from initial two-finger touch. 59.8517 + * 59.8518 + * @class RotateSync 59.8519 + * @extends TwoFingerSync 59.8520 + * @constructor 59.8521 + * @param {Object} options default options overrides 59.8522 + * @param {Number} [options.scale] scale velocity by this factor 59.8523 + */ 59.8524 + function RotateSync(options) { 59.8525 + TwoFingerSync.call(this); 59.8526 + 59.8527 + this.options = Object.create(RotateSync.DEFAULT_OPTIONS); 59.8528 + if (options) this.setOptions(options); 59.8529 + 59.8530 + this._angle = 0; 59.8531 + this._previousAngle = 0; 59.8532 + } 59.8533 + 59.8534 + RotateSync.prototype = Object.create(TwoFingerSync.prototype); 59.8535 + RotateSync.prototype.constructor = RotateSync; 59.8536 + 59.8537 + RotateSync.DEFAULT_OPTIONS = { 59.8538 + scale : 1 59.8539 + }; 59.8540 + 59.8541 + RotateSync.prototype._startUpdate = function _startUpdate(event) { 59.8542 + this._angle = 0; 59.8543 + this._previousAngle = TwoFingerSync.calculateAngle(this.posA, this.posB); 59.8544 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 59.8545 + this._eventOutput.emit('start', { 59.8546 + count: event.touches.length, 59.8547 + angle: this._angle, 59.8548 + center: center, 59.8549 + touches: [this.touchAId, this.touchBId] 59.8550 + }); 59.8551 + }; 59.8552 + 59.8553 + RotateSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 59.8554 + var scale = this.options.scale; 59.8555 + 59.8556 + var currAngle = TwoFingerSync.calculateAngle(this.posA, this.posB); 59.8557 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 59.8558 + 59.8559 + var diffTheta = scale * (currAngle - this._previousAngle); 59.8560 + var velTheta = diffTheta / diffTime; 59.8561 + 59.8562 + this._angle += diffTheta; 59.8563 + 59.8564 + this._eventOutput.emit('update', { 59.8565 + delta : diffTheta, 59.8566 + velocity: velTheta, 59.8567 + angle: this._angle, 59.8568 + center: center, 59.8569 + touches: [this.touchAId, this.touchBId] 59.8570 + }); 59.8571 + 59.8572 + this._previousAngle = currAngle; 59.8573 + }; 59.8574 + 59.8575 + /** 59.8576 + * Return entire options dictionary, including defaults. 59.8577 + * 59.8578 + * @method getOptions 59.8579 + * @return {Object} configuration options 59.8580 + */ 59.8581 + RotateSync.prototype.getOptions = function getOptions() { 59.8582 + return this.options; 59.8583 + }; 59.8584 + 59.8585 + /** 59.8586 + * Set internal options, overriding any default options 59.8587 + * 59.8588 + * @method setOptions 59.8589 + * 59.8590 + * @param {Object} [options] overrides of default options 59.8591 + * @param {Number} [options.scale] scale velocity by this factor 59.8592 + */ 59.8593 + RotateSync.prototype.setOptions = function setOptions(options) { 59.8594 + if (options.scale !== undefined) this.options.scale = options.scale; 59.8595 + }; 59.8596 + 59.8597 + module.exports = RotateSync; 59.8598 +}); 59.8599 + 59.8600 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8601 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8602 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8603 + * 59.8604 + * Owner: mark@famo.us 59.8605 + * @license MPL 2.0 59.8606 + * @copyright Famous Industries, Inc. 2014 59.8607 + */ 59.8608 + 59.8609 +define('famous/inputs/ScaleSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) { 59.8610 + var TwoFingerSync = require('./TwoFingerSync'); 59.8611 + 59.8612 + /** 59.8613 + * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding. 59.8614 + * Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, distance, and scale factor. 59.8615 + * Useful for determining a scaling factor from initial two-finger touch. 59.8616 + * 59.8617 + * @class ScaleSync 59.8618 + * @extends TwoFingerSync 59.8619 + * @constructor 59.8620 + * @param {Object} options default options overrides 59.8621 + * @param {Number} [options.scale] scale velocity by this factor 59.8622 + */ 59.8623 + function ScaleSync(options) { 59.8624 + TwoFingerSync.call(this); 59.8625 + 59.8626 + this.options = Object.create(ScaleSync.DEFAULT_OPTIONS); 59.8627 + if (options) this.setOptions(options); 59.8628 + 59.8629 + this._scaleFactor = 1; 59.8630 + this._startDist = 0; 59.8631 + this._eventInput.on('pipe', _reset.bind(this)); 59.8632 + } 59.8633 + 59.8634 + ScaleSync.prototype = Object.create(TwoFingerSync.prototype); 59.8635 + ScaleSync.prototype.constructor = ScaleSync; 59.8636 + 59.8637 + ScaleSync.DEFAULT_OPTIONS = { 59.8638 + scale : 1 59.8639 + }; 59.8640 + 59.8641 + function _reset() { 59.8642 + this.touchAId = undefined; 59.8643 + this.touchBId = undefined; 59.8644 + } 59.8645 + 59.8646 + // handles initial touch of two fingers 59.8647 + ScaleSync.prototype._startUpdate = function _startUpdate(event) { 59.8648 + this._scaleFactor = 1; 59.8649 + this._startDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 59.8650 + this._eventOutput.emit('start', { 59.8651 + count: event.touches.length, 59.8652 + touches: [this.touchAId, this.touchBId], 59.8653 + distance: this._startDist, 59.8654 + center: TwoFingerSync.calculateCenter(this.posA, this.posB) 59.8655 + }); 59.8656 + }; 59.8657 + 59.8658 + // handles movement of two fingers 59.8659 + ScaleSync.prototype._moveUpdate = function _moveUpdate(diffTime) { 59.8660 + var scale = this.options.scale; 59.8661 + 59.8662 + var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB); 59.8663 + var center = TwoFingerSync.calculateCenter(this.posA, this.posB); 59.8664 + 59.8665 + var delta = (currDist - this._startDist) / this._startDist; 59.8666 + var newScaleFactor = Math.max(1 + scale * delta, 0); 59.8667 + var veloScale = (newScaleFactor - this._scaleFactor) / diffTime; 59.8668 + 59.8669 + this._eventOutput.emit('update', { 59.8670 + delta : delta, 59.8671 + scale: newScaleFactor, 59.8672 + velocity: veloScale, 59.8673 + distance: currDist, 59.8674 + center : center, 59.8675 + touches: [this.touchAId, this.touchBId] 59.8676 + }); 59.8677 + 59.8678 + this._scaleFactor = newScaleFactor; 59.8679 + }; 59.8680 + 59.8681 + /** 59.8682 + * Return entire options dictionary, including defaults. 59.8683 + * 59.8684 + * @method getOptions 59.8685 + * @return {Object} configuration options 59.8686 + */ 59.8687 + ScaleSync.prototype.getOptions = function getOptions() { 59.8688 + return this.options; 59.8689 + }; 59.8690 + 59.8691 + /** 59.8692 + * Set internal options, overriding any default options 59.8693 + * 59.8694 + * @method setOptions 59.8695 + * 59.8696 + * @param {Object} [options] overrides of default options 59.8697 + * @param {Number} [options.scale] scale velocity by this factor 59.8698 + */ 59.8699 + ScaleSync.prototype.setOptions = function setOptions(options) { 59.8700 + if (options.scale !== undefined) this.options.scale = options.scale; 59.8701 + }; 59.8702 + 59.8703 + module.exports = ScaleSync; 59.8704 +}); 59.8705 + 59.8706 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8707 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8708 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8709 + * 59.8710 + * Owner: mark@famo.us 59.8711 + * @license MPL 2.0 59.8712 + * @copyright Famous Industries, Inc. 2014 59.8713 + */ 59.8714 + 59.8715 +define('famous/inputs/ScrollSync',['require','exports','module','famous/core/EventHandler','famous/core/Engine'],function(require, exports, module) { 59.8716 + var EventHandler = require('famous/core/EventHandler'); 59.8717 + var Engine = require('famous/core/Engine'); 59.8718 + 59.8719 + /** 59.8720 + * Handles piped in mousewheel events. 59.8721 + * Emits 'start', 'update', and 'end' events with payloads including: 59.8722 + * delta: change since last position, 59.8723 + * position: accumulated deltas, 59.8724 + * velocity: speed of change in pixels per ms, 59.8725 + * slip: true (unused). 59.8726 + * 59.8727 + * Can be used as delegate of GenericSync. 59.8728 + * 59.8729 + * @class ScrollSync 59.8730 + * @constructor 59.8731 + * @param {Object} [options] overrides of default options 59.8732 + * @param {Number} [options.direction] Pay attention to x changes (ScrollSync.DIRECTION_X), 59.8733 + * y changes (ScrollSync.DIRECTION_Y) or both (undefined) 59.8734 + * @param {Number} [options.minimumEndSpeed] End speed calculation floors at this number, in pixels per ms 59.8735 + * @param {boolean} [options.rails] whether to snap position calculations to nearest axis 59.8736 + * @param {Number | Array.Number} [options.scale] scale outputs in by scalar or pair of scalars 59.8737 + * @param {Number} [options.stallTime] reset time for velocity calculation in ms 59.8738 + */ 59.8739 + function ScrollSync(options) { 59.8740 + this.options = Object.create(ScrollSync.DEFAULT_OPTIONS); 59.8741 + if (options) this.setOptions(options); 59.8742 + 59.8743 + this._payload = { 59.8744 + delta : null, 59.8745 + position : null, 59.8746 + velocity : null, 59.8747 + slip : true 59.8748 + }; 59.8749 + 59.8750 + this._eventInput = new EventHandler(); 59.8751 + this._eventOutput = new EventHandler(); 59.8752 + 59.8753 + EventHandler.setInputHandler(this, this._eventInput); 59.8754 + EventHandler.setOutputHandler(this, this._eventOutput); 59.8755 + 59.8756 + this._position = (this.options.direction === undefined) ? [0,0] : 0; 59.8757 + this._prevTime = undefined; 59.8758 + this._prevVel = undefined; 59.8759 + this._eventInput.on('mousewheel', _handleMove.bind(this)); 59.8760 + this._eventInput.on('wheel', _handleMove.bind(this)); 59.8761 + this._inProgress = false; 59.8762 + this._loopBound = false; 59.8763 + } 59.8764 + 59.8765 + ScrollSync.DEFAULT_OPTIONS = { 59.8766 + direction: undefined, 59.8767 + minimumEndSpeed: Infinity, 59.8768 + rails: false, 59.8769 + scale: 1, 59.8770 + stallTime: 50, 59.8771 + lineHeight: 40 59.8772 + }; 59.8773 + 59.8774 + ScrollSync.DIRECTION_X = 0; 59.8775 + ScrollSync.DIRECTION_Y = 1; 59.8776 + 59.8777 + var MINIMUM_TICK_TIME = 8; 59.8778 + 59.8779 + var _now = Date.now; 59.8780 + 59.8781 + function _newFrame() { 59.8782 + if (this._inProgress && (_now() - this._prevTime) > this.options.stallTime) { 59.8783 + this._position = (this.options.direction === undefined) ? [0,0] : 0; 59.8784 + this._inProgress = false; 59.8785 + 59.8786 + var finalVel = (Math.abs(this._prevVel) >= this.options.minimumEndSpeed) 59.8787 + ? this._prevVel 59.8788 + : 0; 59.8789 + 59.8790 + var payload = this._payload; 59.8791 + payload.position = this._position; 59.8792 + payload.velocity = finalVel; 59.8793 + payload.slip = true; 59.8794 + 59.8795 + this._eventOutput.emit('end', payload); 59.8796 + } 59.8797 + } 59.8798 + 59.8799 + function _handleMove(event) { 59.8800 + event.preventDefault(); 59.8801 + 59.8802 + if (!this._inProgress) { 59.8803 + this._inProgress = true; 59.8804 + 59.8805 + payload = this._payload; 59.8806 + payload.slip = true; 59.8807 + payload.position = this._position; 59.8808 + payload.clientX = event.clientX; 59.8809 + payload.clientY = event.clientY; 59.8810 + payload.offsetX = event.offsetX; 59.8811 + payload.offsetY = event.offsetY; 59.8812 + this._eventOutput.emit('start', payload); 59.8813 + if (!this._loopBound) { 59.8814 + Engine.on('prerender', _newFrame.bind(this)); 59.8815 + this._loopBound = true; 59.8816 + } 59.8817 + } 59.8818 + 59.8819 + var currTime = _now(); 59.8820 + var prevTime = this._prevTime || currTime; 59.8821 + 59.8822 + var diffX = (event.wheelDeltaX !== undefined) ? event.wheelDeltaX : -event.deltaX; 59.8823 + var diffY = (event.wheelDeltaY !== undefined) ? event.wheelDeltaY : -event.deltaY; 59.8824 + 59.8825 + if (event.deltaMode === 1) { // units in lines, not pixels 59.8826 + diffX *= this.options.lineHeight; 59.8827 + diffY *= this.options.lineHeight; 59.8828 + } 59.8829 + 59.8830 + if (this.options.rails) { 59.8831 + if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0; 59.8832 + else diffX = 0; 59.8833 + } 59.8834 + 59.8835 + var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time 59.8836 + 59.8837 + var velX = diffX / diffTime; 59.8838 + var velY = diffY / diffTime; 59.8839 + 59.8840 + var scale = this.options.scale; 59.8841 + var nextVel; 59.8842 + var nextDelta; 59.8843 + 59.8844 + if (this.options.direction === ScrollSync.DIRECTION_X) { 59.8845 + nextDelta = scale * diffX; 59.8846 + nextVel = scale * velX; 59.8847 + this._position += nextDelta; 59.8848 + } 59.8849 + else if (this.options.direction === ScrollSync.DIRECTION_Y) { 59.8850 + nextDelta = scale * diffY; 59.8851 + nextVel = scale * velY; 59.8852 + this._position += nextDelta; 59.8853 + } 59.8854 + else { 59.8855 + nextDelta = [scale * diffX, scale * diffY]; 59.8856 + nextVel = [scale * velX, scale * velY]; 59.8857 + this._position[0] += nextDelta[0]; 59.8858 + this._position[1] += nextDelta[1]; 59.8859 + } 59.8860 + 59.8861 + var payload = this._payload; 59.8862 + payload.delta = nextDelta; 59.8863 + payload.velocity = nextVel; 59.8864 + payload.position = this._position; 59.8865 + payload.slip = true; 59.8866 + 59.8867 + this._eventOutput.emit('update', payload); 59.8868 + 59.8869 + this._prevTime = currTime; 59.8870 + this._prevVel = nextVel; 59.8871 + } 59.8872 + 59.8873 + /** 59.8874 + * Return entire options dictionary, including defaults. 59.8875 + * 59.8876 + * @method getOptions 59.8877 + * @return {Object} configuration options 59.8878 + */ 59.8879 + ScrollSync.prototype.getOptions = function getOptions() { 59.8880 + return this.options; 59.8881 + }; 59.8882 + 59.8883 + /** 59.8884 + * Set internal options, overriding any default options 59.8885 + * 59.8886 + * @method setOptions 59.8887 + * 59.8888 + * @param {Object} [options] overrides of default options 59.8889 + * @param {Number} [options.minimimEndSpeed] If final velocity smaller than this, round down to 0. 59.8890 + * @param {Number} [options.stallTime] ms of non-motion before 'end' emitted 59.8891 + * @param {Number} [options.rails] whether to constrain to nearest axis. 59.8892 + * @param {Number} [options.direction] ScrollSync.DIRECTION_X, DIRECTION_Y - 59.8893 + * pay attention to one specific direction. 59.8894 + * @param {Number} [options.scale] constant factor to scale velocity output 59.8895 + */ 59.8896 + ScrollSync.prototype.setOptions = function setOptions(options) { 59.8897 + if (options.direction !== undefined) this.options.direction = options.direction; 59.8898 + if (options.minimumEndSpeed !== undefined) this.options.minimumEndSpeed = options.minimumEndSpeed; 59.8899 + if (options.rails !== undefined) this.options.rails = options.rails; 59.8900 + if (options.scale !== undefined) this.options.scale = options.scale; 59.8901 + if (options.stallTime !== undefined) this.options.stallTime = options.stallTime; 59.8902 + }; 59.8903 + 59.8904 + module.exports = ScrollSync; 59.8905 +}); 59.8906 + 59.8907 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8908 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8909 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8910 + * 59.8911 + * Owner: david@famo.us 59.8912 + * @license MPL 2.0 59.8913 + * @copyright Famous Industries, Inc. 2014 59.8914 + */ 59.8915 + 59.8916 +define('famous/transitions/CachedMap',['require','exports','module'],function(require, exports, module) { 59.8917 + /** 59.8918 + * A simple in-memory object cache. Used as a helper for Views with 59.8919 + * provider functions. 59.8920 + * @class CachedMap 59.8921 + * @constructor 59.8922 + */ 59.8923 + function CachedMap(mappingFunction) { 59.8924 + this._map = mappingFunction || null; 59.8925 + this._cachedOutput = null; 59.8926 + this._cachedInput = Number.NaN; //never valid as input 59.8927 + } 59.8928 + 59.8929 + /** 59.8930 + * Creates a mapping function with a cache. 59.8931 + * This is the main entrypoint for this object. 59.8932 + * @static 59.8933 + * @method create 59.8934 + * @param {function} mappingFunction mapping 59.8935 + * @return {function} memoized mapping function 59.8936 + */ 59.8937 + CachedMap.create = function create(mappingFunction) { 59.8938 + var instance = new CachedMap(mappingFunction); 59.8939 + return instance.get.bind(instance); 59.8940 + }; 59.8941 + 59.8942 + /** 59.8943 + * Retrieve items from cache or from mapping functin. 59.8944 + * 59.8945 + * @method get 59.8946 + * @param {Object} input input key 59.8947 + */ 59.8948 + CachedMap.prototype.get = function get(input) { 59.8949 + if (input !== this._cachedInput) { 59.8950 + this._cachedInput = input; 59.8951 + this._cachedOutput = this._map(input); 59.8952 + } 59.8953 + return this._cachedOutput; 59.8954 + }; 59.8955 + 59.8956 + module.exports = CachedMap; 59.8957 +}); 59.8958 + 59.8959 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.8960 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.8961 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.8962 + * 59.8963 + * Owner: david@famo.us 59.8964 + * @license MPL 2.0 59.8965 + * @copyright Famous Industries, Inc. 2014 59.8966 + */ 59.8967 + 59.8968 +define('famous/transitions/Easing',['require','exports','module'],function(require, exports, module) { 59.8969 + 59.8970 + /* 59.8971 + * A library of curves which map an animation explicitly as a function of time. 59.8972 + * 59.8973 + * @class Easing 59.8974 + */ 59.8975 + var Easing = { 59.8976 + 59.8977 + /** 59.8978 + * @property inQuad 59.8979 + * @static 59.8980 + */ 59.8981 + inQuad: function(t) { 59.8982 + return t*t; 59.8983 + }, 59.8984 + 59.8985 + /** 59.8986 + * @property outQuad 59.8987 + * @static 59.8988 + */ 59.8989 + outQuad: function(t) { 59.8990 + return -(t-=1)*t+1; 59.8991 + }, 59.8992 + 59.8993 + /** 59.8994 + * @property inOutQuad 59.8995 + * @static 59.8996 + */ 59.8997 + inOutQuad: function(t) { 59.8998 + if ((t/=.5) < 1) return .5*t*t; 59.8999 + return -.5*((--t)*(t-2) - 1); 59.9000 + }, 59.9001 + 59.9002 + /** 59.9003 + * @property inCubic 59.9004 + * @static 59.9005 + */ 59.9006 + inCubic: function(t) { 59.9007 + return t*t*t; 59.9008 + }, 59.9009 + 59.9010 + /** 59.9011 + * @property outCubic 59.9012 + * @static 59.9013 + */ 59.9014 + outCubic: function(t) { 59.9015 + return ((--t)*t*t + 1); 59.9016 + }, 59.9017 + 59.9018 + /** 59.9019 + * @property inOutCubic 59.9020 + * @static 59.9021 + */ 59.9022 + inOutCubic: function(t) { 59.9023 + if ((t/=.5) < 1) return .5*t*t*t; 59.9024 + return .5*((t-=2)*t*t + 2); 59.9025 + }, 59.9026 + 59.9027 + /** 59.9028 + * @property inQuart 59.9029 + * @static 59.9030 + */ 59.9031 + inQuart: function(t) { 59.9032 + return t*t*t*t; 59.9033 + }, 59.9034 + 59.9035 + /** 59.9036 + * @property outQuart 59.9037 + * @static 59.9038 + */ 59.9039 + outQuart: function(t) { 59.9040 + return -((--t)*t*t*t - 1); 59.9041 + }, 59.9042 + 59.9043 + /** 59.9044 + * @property inOutQuart 59.9045 + * @static 59.9046 + */ 59.9047 + inOutQuart: function(t) { 59.9048 + if ((t/=.5) < 1) return .5*t*t*t*t; 59.9049 + return -.5 * ((t-=2)*t*t*t - 2); 59.9050 + }, 59.9051 + 59.9052 + /** 59.9053 + * @property inQuint 59.9054 + * @static 59.9055 + */ 59.9056 + inQuint: function(t) { 59.9057 + return t*t*t*t*t; 59.9058 + }, 59.9059 + 59.9060 + /** 59.9061 + * @property outQuint 59.9062 + * @static 59.9063 + */ 59.9064 + outQuint: function(t) { 59.9065 + return ((--t)*t*t*t*t + 1); 59.9066 + }, 59.9067 + 59.9068 + /** 59.9069 + * @property inOutQuint 59.9070 + * @static 59.9071 + */ 59.9072 + inOutQuint: function(t) { 59.9073 + if ((t/=.5) < 1) return .5*t*t*t*t*t; 59.9074 + return .5*((t-=2)*t*t*t*t + 2); 59.9075 + }, 59.9076 + 59.9077 + /** 59.9078 + * @property inSine 59.9079 + * @static 59.9080 + */ 59.9081 + inSine: function(t) { 59.9082 + return -1.0*Math.cos(t * (Math.PI/2)) + 1.0; 59.9083 + }, 59.9084 + 59.9085 + /** 59.9086 + * @property outSine 59.9087 + * @static 59.9088 + */ 59.9089 + outSine: function(t) { 59.9090 + return Math.sin(t * (Math.PI/2)); 59.9091 + }, 59.9092 + 59.9093 + /** 59.9094 + * @property inOutSine 59.9095 + * @static 59.9096 + */ 59.9097 + inOutSine: function(t) { 59.9098 + return -.5*(Math.cos(Math.PI*t) - 1); 59.9099 + }, 59.9100 + 59.9101 + /** 59.9102 + * @property inExpo 59.9103 + * @static 59.9104 + */ 59.9105 + inExpo: function(t) { 59.9106 + return (t===0) ? 0.0 : Math.pow(2, 10 * (t - 1)); 59.9107 + }, 59.9108 + 59.9109 + /** 59.9110 + * @property outExpo 59.9111 + * @static 59.9112 + */ 59.9113 + outExpo: function(t) { 59.9114 + return (t===1.0) ? 1.0 : (-Math.pow(2, -10 * t) + 1); 59.9115 + }, 59.9116 + 59.9117 + /** 59.9118 + * @property inOutExpo 59.9119 + * @static 59.9120 + */ 59.9121 + inOutExpo: function(t) { 59.9122 + if (t===0) return 0.0; 59.9123 + if (t===1.0) return 1.0; 59.9124 + if ((t/=.5) < 1) return .5 * Math.pow(2, 10 * (t - 1)); 59.9125 + return .5 * (-Math.pow(2, -10 * --t) + 2); 59.9126 + }, 59.9127 + 59.9128 + /** 59.9129 + * @property inCirc 59.9130 + * @static 59.9131 + */ 59.9132 + inCirc: function(t) { 59.9133 + return -(Math.sqrt(1 - t*t) - 1); 59.9134 + }, 59.9135 + 59.9136 + /** 59.9137 + * @property outCirc 59.9138 + * @static 59.9139 + */ 59.9140 + outCirc: function(t) { 59.9141 + return Math.sqrt(1 - (--t)*t); 59.9142 + }, 59.9143 + 59.9144 + /** 59.9145 + * @property inOutCirc 59.9146 + * @static 59.9147 + */ 59.9148 + inOutCirc: function(t) { 59.9149 + if ((t/=.5) < 1) return -.5 * (Math.sqrt(1 - t*t) - 1); 59.9150 + return .5 * (Math.sqrt(1 - (t-=2)*t) + 1); 59.9151 + }, 59.9152 + 59.9153 + /** 59.9154 + * @property inElastic 59.9155 + * @static 59.9156 + */ 59.9157 + inElastic: function(t) { 59.9158 + var s=1.70158;var p=0;var a=1.0; 59.9159 + if (t===0) return 0.0; if (t===1) return 1.0; if (!p) p=.3; 59.9160 + s = p/(2*Math.PI) * Math.asin(1.0/a); 59.9161 + return -(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/ p)); 59.9162 + }, 59.9163 + 59.9164 + /** 59.9165 + * @property outElastic 59.9166 + * @static 59.9167 + */ 59.9168 + outElastic: function(t) { 59.9169 + var s=1.70158;var p=0;var a=1.0; 59.9170 + if (t===0) return 0.0; if (t===1) return 1.0; if (!p) p=.3; 59.9171 + s = p/(2*Math.PI) * Math.asin(1.0/a); 59.9172 + return a*Math.pow(2,-10*t) * Math.sin((t-s)*(2*Math.PI)/p) + 1.0; 59.9173 + }, 59.9174 + 59.9175 + /** 59.9176 + * @property inOutElastic 59.9177 + * @static 59.9178 + */ 59.9179 + inOutElastic: function(t) { 59.9180 + var s=1.70158;var p=0;var a=1.0; 59.9181 + if (t===0) return 0.0; if ((t/=.5)===2) return 1.0; if (!p) p=(.3*1.5); 59.9182 + s = p/(2*Math.PI) * Math.asin(1.0/a); 59.9183 + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)); 59.9184 + return a*Math.pow(2,-10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)*.5 + 1.0; 59.9185 + }, 59.9186 + 59.9187 + /** 59.9188 + * @property inBack 59.9189 + * @static 59.9190 + */ 59.9191 + inBack: function(t, s) { 59.9192 + if (s === undefined) s = 1.70158; 59.9193 + return t*t*((s+1)*t - s); 59.9194 + }, 59.9195 + 59.9196 + /** 59.9197 + * @property outBack 59.9198 + * @static 59.9199 + */ 59.9200 + outBack: function(t, s) { 59.9201 + if (s === undefined) s = 1.70158; 59.9202 + return ((--t)*t*((s+1)*t + s) + 1); 59.9203 + }, 59.9204 + 59.9205 + /** 59.9206 + * @property inOutBack 59.9207 + * @static 59.9208 + */ 59.9209 + inOutBack: function(t, s) { 59.9210 + if (s === undefined) s = 1.70158; 59.9211 + if ((t/=.5) < 1) return .5*(t*t*(((s*=(1.525))+1)*t - s)); 59.9212 + return .5*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2); 59.9213 + }, 59.9214 + 59.9215 + /** 59.9216 + * @property inBounce 59.9217 + * @static 59.9218 + */ 59.9219 + inBounce: function(t) { 59.9220 + return 1.0 - Easing.outBounce(1.0-t); 59.9221 + }, 59.9222 + 59.9223 + /** 59.9224 + * @property outBounce 59.9225 + * @static 59.9226 + */ 59.9227 + outBounce: function(t) { 59.9228 + if (t < (1/2.75)) { 59.9229 + return (7.5625*t*t); 59.9230 + } else if (t < (2/2.75)) { 59.9231 + return (7.5625*(t-=(1.5/2.75))*t + .75); 59.9232 + } else if (t < (2.5/2.75)) { 59.9233 + return (7.5625*(t-=(2.25/2.75))*t + .9375); 59.9234 + } else { 59.9235 + return (7.5625*(t-=(2.625/2.75))*t + .984375); 59.9236 + } 59.9237 + }, 59.9238 + 59.9239 + /** 59.9240 + * @property inOutBounce 59.9241 + * @static 59.9242 + */ 59.9243 + inOutBounce: function(t) { 59.9244 + if (t < .5) return Easing.inBounce(t*2) * .5; 59.9245 + return Easing.outBounce(t*2-1.0) * .5 + .5; 59.9246 + } 59.9247 + }; 59.9248 + 59.9249 + module.exports = Easing; 59.9250 +}); 59.9251 + 59.9252 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.9253 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.9254 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.9255 + * 59.9256 + * Owner: david@famo.us 59.9257 + * @license MPL 2.0 59.9258 + * @copyright Famous Industries, Inc. 2014 59.9259 + */ 59.9260 + 59.9261 +define('famous/physics/integrators/SymplecticEuler',['require','exports','module','famous/core/OptionsManager'],function(require, exports, module) { 59.9262 + var OptionsManager = require('famous/core/OptionsManager'); 59.9263 + 59.9264 + /** 59.9265 + * Ordinary Differential Equation (ODE) Integrator. 59.9266 + * Manages updating a physics body's state over time. 59.9267 + * 59.9268 + * p = position, v = velocity, m = mass, f = force, dt = change in time 59.9269 + * 59.9270 + * v <- v + dt * f / m 59.9271 + * p <- p + dt * v 59.9272 + * 59.9273 + * q = orientation, w = angular velocity, L = angular momentum 59.9274 + * 59.9275 + * L <- L + dt * t 59.9276 + * q <- q + dt/2 * q * w 59.9277 + * 59.9278 + * @class SymplecticEuler 59.9279 + * @constructor 59.9280 + * @param {Object} options Options to set 59.9281 + */ 59.9282 + function SymplecticEuler(options) { 59.9283 + this.options = Object.create(SymplecticEuler.DEFAULT_OPTIONS); 59.9284 + this._optionsManager = new OptionsManager(this.options); 59.9285 + 59.9286 + if (options) this.setOptions(options); 59.9287 + } 59.9288 + 59.9289 + /** 59.9290 + * @property SymplecticEuler.DEFAULT_OPTIONS 59.9291 + * @type Object 59.9292 + * @protected 59.9293 + * @static 59.9294 + */ 59.9295 + SymplecticEuler.DEFAULT_OPTIONS = { 59.9296 + 59.9297 + /** 59.9298 + * The maximum velocity of a physics body 59.9299 + * Range : [0, Infinity] 59.9300 + * @attribute velocityCap 59.9301 + * @type Number 59.9302 + */ 59.9303 + 59.9304 + velocityCap : undefined, 59.9305 + 59.9306 + /** 59.9307 + * The maximum angular velocity of a physics body 59.9308 + * Range : [0, Infinity] 59.9309 + * @attribute angularVelocityCap 59.9310 + * @type Number 59.9311 + */ 59.9312 + angularVelocityCap : undefined 59.9313 + }; 59.9314 + 59.9315 + /* 59.9316 + * Setter for options 59.9317 + * 59.9318 + * @method setOptions 59.9319 + * @param {Object} options 59.9320 + */ 59.9321 + SymplecticEuler.prototype.setOptions = function setOptions(options) { 59.9322 + this._optionsManager.patch(options); 59.9323 + }; 59.9324 + 59.9325 + /* 59.9326 + * Getter for options 59.9327 + * 59.9328 + * @method getOptions 59.9329 + * @return {Object} options 59.9330 + */ 59.9331 + SymplecticEuler.prototype.getOptions = function getOptions() { 59.9332 + return this._optionsManager.value(); 59.9333 + }; 59.9334 + 59.9335 + /* 59.9336 + * Updates the velocity of a physics body from its accumulated force. 59.9337 + * v <- v + dt * f / m 59.9338 + * 59.9339 + * @method integrateVelocity 59.9340 + * @param {Body} physics body 59.9341 + * @param {Number} dt delta time 59.9342 + */ 59.9343 + SymplecticEuler.prototype.integrateVelocity = function integrateVelocity(body, dt) { 59.9344 + var v = body.velocity; 59.9345 + var w = body.inverseMass; 59.9346 + var f = body.force; 59.9347 + 59.9348 + if (f.isZero()) return; 59.9349 + 59.9350 + v.add(f.mult(dt * w)).put(v); 59.9351 + f.clear(); 59.9352 + }; 59.9353 + 59.9354 + /* 59.9355 + * Updates the position of a physics body from its velocity. 59.9356 + * p <- p + dt * v 59.9357 + * 59.9358 + * @method integratePosition 59.9359 + * @param {Body} physics body 59.9360 + * @param {Number} dt delta time 59.9361 + */ 59.9362 + SymplecticEuler.prototype.integratePosition = function integratePosition(body, dt) { 59.9363 + var p = body.position; 59.9364 + var v = body.velocity; 59.9365 + 59.9366 + if (this.options.velocityCap) v.cap(this.options.velocityCap).put(v); 59.9367 + p.add(v.mult(dt)).put(p); 59.9368 + }; 59.9369 + 59.9370 + /* 59.9371 + * Updates the angular momentum of a physics body from its accumuled torque. 59.9372 + * L <- L + dt * t 59.9373 + * 59.9374 + * @method integrateAngularMomentum 59.9375 + * @param {Body} physics body (except a particle) 59.9376 + * @param {Number} dt delta time 59.9377 + */ 59.9378 + SymplecticEuler.prototype.integrateAngularMomentum = function integrateAngularMomentum(body, dt) { 59.9379 + var L = body.angularMomentum; 59.9380 + var t = body.torque; 59.9381 + 59.9382 + if (t.isZero()) return; 59.9383 + 59.9384 + if (this.options.angularVelocityCap) t.cap(this.options.angularVelocityCap).put(t); 59.9385 + L.add(t.mult(dt)).put(L); 59.9386 + t.clear(); 59.9387 + }; 59.9388 + 59.9389 + /* 59.9390 + * Updates the orientation of a physics body from its angular velocity. 59.9391 + * q <- q + dt/2 * q * w 59.9392 + * 59.9393 + * @method integrateOrientation 59.9394 + * @param {Body} physics body (except a particle) 59.9395 + * @param {Number} dt delta time 59.9396 + */ 59.9397 + SymplecticEuler.prototype.integrateOrientation = function integrateOrientation(body, dt) { 59.9398 + var q = body.orientation; 59.9399 + var w = body.angularVelocity; 59.9400 + 59.9401 + if (w.isZero()) return; 59.9402 + q.add(q.multiply(w).scalarMultiply(0.5 * dt)).put(q); 59.9403 +// q.normalize.put(q); 59.9404 + }; 59.9405 + 59.9406 + module.exports = SymplecticEuler; 59.9407 +}); 59.9408 + 59.9409 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.9410 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.9411 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.9412 + * 59.9413 + * Owner: david@famo.us 59.9414 + * @license MPL 2.0 59.9415 + * @copyright Famous Industries, Inc. 2014 59.9416 + */ 59.9417 + 59.9418 +define('famous/physics/bodies/Particle',['require','exports','module','famous/math/Vector','famous/core/Transform','famous/core/EventHandler','../integrators/SymplecticEuler'],function(require, exports, module) { 59.9419 + var Vector = require('famous/math/Vector'); 59.9420 + var Transform = require('famous/core/Transform'); 59.9421 + var EventHandler = require('famous/core/EventHandler'); 59.9422 + var Integrator = require('../integrators/SymplecticEuler'); 59.9423 + 59.9424 + /** 59.9425 + * A point body that is controlled by the Physics Engine. A particle has 59.9426 + * position and velocity states that are updated by the Physics Engine. 59.9427 + * Ultimately, a particle is a _special type of modifier, and can be added to 59.9428 + * the Famous render tree like any other modifier. 59.9429 + * 59.9430 + * @constructor 59.9431 + * @class Particle 59.9432 + * @uses EventHandler 59.9433 + * @uses Modifier 59.9434 + * @extensionfor Body 59.9435 + * @param {Options} [options] An object of configurable options. 59.9436 + * @param {Array} [options.position] The position of the particle. 59.9437 + * @param {Array} [options.velocity] The velocity of the particle. 59.9438 + * @param {Number} [options.mass] The mass of the particle. 59.9439 + * @param {Hexadecimal} [options.axis] The axis a particle can move along. Can be bitwise ORed e.g., Particle.AXES.X, Particle.AXES.X | Particle.AXES.Y 59.9440 + * 59.9441 + */ 59.9442 + function Particle(options) { 59.9443 + options = options || {}; 59.9444 + 59.9445 + // registers 59.9446 + this.position = new Vector(); 59.9447 + this.velocity = new Vector(); 59.9448 + this.force = new Vector(); 59.9449 + 59.9450 + var defaults = Particle.DEFAULT_OPTIONS; 59.9451 + 59.9452 + // set vectors 59.9453 + this.setPosition(options.position || defaults.position); 59.9454 + this.setVelocity(options.velocity || defaults.velocity); 59.9455 + this.force.set(options.force || [0,0,0]); 59.9456 + 59.9457 + // set scalars 59.9458 + this.mass = (options.mass !== undefined) 59.9459 + ? options.mass 59.9460 + : defaults.mass; 59.9461 + 59.9462 + this.axis = (options.axis !== undefined) 59.9463 + ? options.axis 59.9464 + : defaults.axis; 59.9465 + 59.9466 + this.inverseMass = 1 / this.mass; 59.9467 + 59.9468 + // state variables 59.9469 + this._isSleeping = false; 59.9470 + this._engine = null; 59.9471 + this._eventOutput = null; 59.9472 + this._positionGetter = null; 59.9473 + 59.9474 + this.transform = Transform.identity.slice(); 59.9475 + 59.9476 + // cached _spec 59.9477 + this._spec = { 59.9478 + transform : this.transform, 59.9479 + target : null 59.9480 + }; 59.9481 + } 59.9482 + 59.9483 + Particle.DEFAULT_OPTIONS = { 59.9484 + position : [0,0,0], 59.9485 + velocity : [0,0,0], 59.9486 + mass : 1, 59.9487 + axis : undefined 59.9488 + }; 59.9489 + 59.9490 + /** 59.9491 + * Kinetic energy threshold needed to update the body 59.9492 + * 59.9493 + * @property SLEEP_TOLERANCE 59.9494 + * @type Number 59.9495 + * @static 59.9496 + * @default 1e-7 59.9497 + */ 59.9498 + Particle.SLEEP_TOLERANCE = 1e-7; 59.9499 + 59.9500 + /** 59.9501 + * Axes by which a body can translate 59.9502 + * 59.9503 + * @property AXES 59.9504 + * @type Hexadecimal 59.9505 + * @static 59.9506 + * @default 1e-7 59.9507 + */ 59.9508 + Particle.AXES = { 59.9509 + X : 0x00, // hexadecimal for 0 59.9510 + Y : 0x01, // hexadecimal for 1 59.9511 + Z : 0x02 // hexadecimal for 2 59.9512 + }; 59.9513 + 59.9514 + // Integrator for updating the particle's state 59.9515 + // TODO: make this a singleton 59.9516 + Particle.INTEGRATOR = new Integrator(); 59.9517 + 59.9518 + //Catalogue of outputted events 59.9519 + var _events = { 59.9520 + start : 'start', 59.9521 + update : 'update', 59.9522 + end : 'end' 59.9523 + }; 59.9524 + 59.9525 + // Cached timing function 59.9526 + var now = (function() { 59.9527 + return Date.now; 59.9528 + })(); 59.9529 + 59.9530 + /** 59.9531 + * Stops the particle from updating 59.9532 + * @method sleep 59.9533 + */ 59.9534 + Particle.prototype.sleep = function sleep() { 59.9535 + if (this._isSleeping) return; 59.9536 + this.emit(_events.end, this); 59.9537 + this._isSleeping = true; 59.9538 + }; 59.9539 + 59.9540 + /** 59.9541 + * Starts the particle update 59.9542 + * @method wake 59.9543 + */ 59.9544 + Particle.prototype.wake = function wake() { 59.9545 + if (!this._isSleeping) return; 59.9546 + this.emit(_events.start, this); 59.9547 + this._isSleeping = false; 59.9548 + this._prevTime = now(); 59.9549 + }; 59.9550 + 59.9551 + /** 59.9552 + * @attribute isBody 59.9553 + * @type Boolean 59.9554 + * @static 59.9555 + */ 59.9556 + Particle.prototype.isBody = false; 59.9557 + 59.9558 + /** 59.9559 + * Basic setter for position 59.9560 + * @method getPosition 59.9561 + * @param position {Array|Vector} 59.9562 + */ 59.9563 + Particle.prototype.setPosition = function setPosition(position) { 59.9564 + this.position.set(position); 59.9565 + }; 59.9566 + 59.9567 + /** 59.9568 + * 1-dimensional setter for position 59.9569 + * @method setPosition1D 59.9570 + * @param value {Number} 59.9571 + */ 59.9572 + Particle.prototype.setPosition1D = function setPosition1D(x) { 59.9573 + this.position.x = x; 59.9574 + }; 59.9575 + 59.9576 + /** 59.9577 + * Basic getter function for position 59.9578 + * @method getPosition 59.9579 + * @return position {Array} 59.9580 + */ 59.9581 + Particle.prototype.getPosition = function getPosition() { 59.9582 + if (this._positionGetter instanceof Function) 59.9583 + this.setPosition(this._positionGetter()); 59.9584 + 59.9585 + this._engine.step(); 59.9586 + 59.9587 + return this.position.get(); 59.9588 + }; 59.9589 + 59.9590 + /** 59.9591 + * 1-dimensional getter for position 59.9592 + * @method getPosition1D 59.9593 + * @return value {Number} 59.9594 + */ 59.9595 + Particle.prototype.getPosition1D = function getPosition1D() { 59.9596 + this._engine.step(); 59.9597 + return this.position.x; 59.9598 + }; 59.9599 + 59.9600 + /** 59.9601 + * Defines the position from outside the Physics Engine 59.9602 + * @method positionFrom 59.9603 + * @param positionGetter {Function} 59.9604 + */ 59.9605 + Particle.prototype.positionFrom = function positionFrom(positionGetter) { 59.9606 + this._positionGetter = positionGetter; 59.9607 + }; 59.9608 + 59.9609 + /** 59.9610 + * Basic setter function for velocity Vector 59.9611 + * @method setVelocity 59.9612 + * @function 59.9613 + */ 59.9614 + Particle.prototype.setVelocity = function setVelocity(velocity) { 59.9615 + this.velocity.set(velocity); 59.9616 + this.wake(); 59.9617 + }; 59.9618 + 59.9619 + /** 59.9620 + * 1-dimensional setter for velocity 59.9621 + * @method setVelocity1D 59.9622 + * @param velocity {Number} 59.9623 + */ 59.9624 + Particle.prototype.setVelocity1D = function setVelocity1D(x) { 59.9625 + this.velocity.x = x; 59.9626 + this.wake(); 59.9627 + }; 59.9628 + 59.9629 + /** 59.9630 + * Basic getter function for velocity Vector 59.9631 + * @method getVelocity 59.9632 + * @return velocity {Array} 59.9633 + */ 59.9634 + Particle.prototype.getVelocity = function getVelocity() { 59.9635 + return this.velocity.get(); 59.9636 + }; 59.9637 + 59.9638 + /** 59.9639 + * 1-dimensional getter for velocity 59.9640 + * @method getVelocity1D 59.9641 + * @return velocity {Number} 59.9642 + */ 59.9643 + Particle.prototype.getVelocity1D = function getVelocity1D() { 59.9644 + return this.velocity.x; 59.9645 + }; 59.9646 + 59.9647 + /** 59.9648 + * Basic setter function for mass quantity 59.9649 + * @method setMass 59.9650 + * @param mass {Number} mass 59.9651 + */ 59.9652 + Particle.prototype.setMass = function setMass(mass) { 59.9653 + this.mass = mass; 59.9654 + this.inverseMass = 1 / mass; 59.9655 + }; 59.9656 + 59.9657 + /** 59.9658 + * Basic getter function for mass quantity 59.9659 + * @method getMass 59.9660 + * @return mass {Number} 59.9661 + */ 59.9662 + Particle.prototype.getMass = function getMass() { 59.9663 + return this.mass; 59.9664 + }; 59.9665 + 59.9666 + /** 59.9667 + * Reset position and velocity 59.9668 + * @method reset 59.9669 + * @param position {Array|Vector} 59.9670 + * @param velocity {Array|Vector} 59.9671 + */ 59.9672 + Particle.prototype.reset = function reset(position, velocity) { 59.9673 + this.setPosition(position || [0,0,0]); 59.9674 + this.setVelocity(velocity || [0,0,0]); 59.9675 + }; 59.9676 + 59.9677 + /** 59.9678 + * Add force vector to existing internal force Vector 59.9679 + * @method applyForce 59.9680 + * @param force {Vector} 59.9681 + */ 59.9682 + Particle.prototype.applyForce = function applyForce(force) { 59.9683 + if (force.isZero()) return; 59.9684 + this.force.add(force).put(this.force); 59.9685 + this.wake(); 59.9686 + }; 59.9687 + 59.9688 + /** 59.9689 + * Add impulse (change in velocity) Vector to this Vector's velocity. 59.9690 + * @method applyImpulse 59.9691 + * @param impulse {Vector} 59.9692 + */ 59.9693 + Particle.prototype.applyImpulse = function applyImpulse(impulse) { 59.9694 + if (impulse.isZero()) return; 59.9695 + var velocity = this.velocity; 59.9696 + velocity.add(impulse.mult(this.inverseMass)).put(velocity); 59.9697 + }; 59.9698 + 59.9699 + /** 59.9700 + * Update a particle's velocity from its force accumulator 59.9701 + * @method integrateVelocity 59.9702 + * @param dt {Number} Time differential 59.9703 + */ 59.9704 + Particle.prototype.integrateVelocity = function integrateVelocity(dt) { 59.9705 + Particle.INTEGRATOR.integrateVelocity(this, dt); 59.9706 + }; 59.9707 + 59.9708 + /** 59.9709 + * Update a particle's position from its velocity 59.9710 + * @method integratePosition 59.9711 + * @param dt {Number} Time differential 59.9712 + */ 59.9713 + Particle.prototype.integratePosition = function integratePosition(dt) { 59.9714 + Particle.INTEGRATOR.integratePosition(this, dt); 59.9715 + }; 59.9716 + 59.9717 + /** 59.9718 + * Update the position and velocity of the particle 59.9719 + * @method _integrate 59.9720 + * @protected 59.9721 + * @param dt {Number} Time differential 59.9722 + */ 59.9723 + Particle.prototype._integrate = function _integrate(dt) { 59.9724 + this.integrateVelocity(dt); 59.9725 + this.integratePosition(dt); 59.9726 + }; 59.9727 + 59.9728 + /** 59.9729 + * Get kinetic energy of the particle. 59.9730 + * @method getEnergy 59.9731 + * @function 59.9732 + */ 59.9733 + Particle.prototype.getEnergy = function getEnergy() { 59.9734 + return 0.5 * this.mass * this.velocity.normSquared(); 59.9735 + }; 59.9736 + 59.9737 + /** 59.9738 + * Generate transform from the current position state 59.9739 + * @method getTransform 59.9740 + * @return Transform {Transform} 59.9741 + */ 59.9742 + Particle.prototype.getTransform = function getTransform() { 59.9743 + this._engine.step(); 59.9744 + 59.9745 + var position = this.position; 59.9746 + var axis = this.axis; 59.9747 + var transform = this.transform; 59.9748 + 59.9749 + if (axis !== undefined) { 59.9750 + if (axis & ~Particle.AXES.X) { 59.9751 + position.x = 0; 59.9752 + } 59.9753 + if (axis & ~Particle.AXES.Y) { 59.9754 + position.y = 0; 59.9755 + } 59.9756 + if (axis & ~Particle.AXES.Z) { 59.9757 + position.z = 0; 59.9758 + } 59.9759 + } 59.9760 + 59.9761 + transform[12] = position.x; 59.9762 + transform[13] = position.y; 59.9763 + transform[14] = position.z; 59.9764 + 59.9765 + return transform; 59.9766 + }; 59.9767 + 59.9768 + /** 59.9769 + * The modify interface of a Modifier 59.9770 + * @method modify 59.9771 + * @param target {Spec} 59.9772 + * @return Spec {Spec} 59.9773 + */ 59.9774 + Particle.prototype.modify = function modify(target) { 59.9775 + var _spec = this._spec; 59.9776 + _spec.transform = this.getTransform(); 59.9777 + _spec.target = target; 59.9778 + return _spec; 59.9779 + }; 59.9780 + 59.9781 + // private 59.9782 + function _createEventOutput() { 59.9783 + this._eventOutput = new EventHandler(); 59.9784 + this._eventOutput.bindThis(this); 59.9785 + //overrides on/removeListener/pipe/unpipe methods 59.9786 + EventHandler.setOutputHandler(this, this._eventOutput); 59.9787 + } 59.9788 + 59.9789 + Particle.prototype.emit = function emit(type, data) { 59.9790 + if (!this._eventOutput) return; 59.9791 + this._eventOutput.emit(type, data); 59.9792 + }; 59.9793 + 59.9794 + Particle.prototype.on = function on() { 59.9795 + _createEventOutput.call(this); 59.9796 + return this.on.apply(this, arguments); 59.9797 + }; 59.9798 + Particle.prototype.removeListener = function removeListener() { 59.9799 + _createEventOutput.call(this); 59.9800 + return this.removeListener.apply(this, arguments); 59.9801 + }; 59.9802 + Particle.prototype.pipe = function pipe() { 59.9803 + _createEventOutput.call(this); 59.9804 + return this.pipe.apply(this, arguments); 59.9805 + }; 59.9806 + Particle.prototype.unpipe = function unpipe() { 59.9807 + _createEventOutput.call(this); 59.9808 + return this.unpipe.apply(this, arguments); 59.9809 + }; 59.9810 + 59.9811 + module.exports = Particle; 59.9812 +}); 59.9813 + 59.9814 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.9815 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.9816 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.9817 + * 59.9818 + * Owner: david@famo.us 59.9819 + * @license MPL 2.0 59.9820 + * @copyright Famous Industries, Inc. 2014 59.9821 + */ 59.9822 + 59.9823 +define('famous/physics/constraints/Constraint',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) { 59.9824 + var EventHandler = require('famous/core/EventHandler'); 59.9825 + 59.9826 + /** 59.9827 + * Allows for two circular bodies to collide and bounce off each other. 59.9828 + * 59.9829 + * @class Constraint 59.9830 + * @constructor 59.9831 + * @uses EventHandler 59.9832 + * @param options {Object} 59.9833 + */ 59.9834 + function Constraint() { 59.9835 + this.options = this.options || {}; 59.9836 + this._energy = 0.0; 59.9837 + this._eventOutput = null; 59.9838 + } 59.9839 + 59.9840 + /* 59.9841 + * Setter for options. 59.9842 + * 59.9843 + * @method setOptions 59.9844 + * @param options {Objects} 59.9845 + */ 59.9846 + Constraint.prototype.setOptions = function setOptions(options) { 59.9847 + for (var key in options) this.options[key] = options[key]; 59.9848 + }; 59.9849 + 59.9850 + /** 59.9851 + * Adds an impulse to a physics body's velocity due to the constraint 59.9852 + * 59.9853 + * @method applyConstraint 59.9854 + */ 59.9855 + Constraint.prototype.applyConstraint = function applyConstraint() {}; 59.9856 + 59.9857 + /** 59.9858 + * Getter for energy 59.9859 + * 59.9860 + * @method getEnergy 59.9861 + * @return energy {Number} 59.9862 + */ 59.9863 + Constraint.prototype.getEnergy = function getEnergy() { 59.9864 + return this._energy; 59.9865 + }; 59.9866 + 59.9867 + /** 59.9868 + * Setter for energy 59.9869 + * 59.9870 + * @method setEnergy 59.9871 + * @param energy {Number} 59.9872 + */ 59.9873 + Constraint.prototype.setEnergy = function setEnergy(energy) { 59.9874 + this._energy = energy; 59.9875 + }; 59.9876 + 59.9877 + function _createEventOutput() { 59.9878 + this._eventOutput = new EventHandler(); 59.9879 + this._eventOutput.bindThis(this); 59.9880 + EventHandler.setOutputHandler(this, this._eventOutput); 59.9881 + } 59.9882 + 59.9883 + Constraint.prototype.on = function on() { 59.9884 + _createEventOutput.call(this); 59.9885 + return this.on.apply(this, arguments); 59.9886 + }; 59.9887 + Constraint.prototype.addListener = function addListener() { 59.9888 + _createEventOutput.call(this); 59.9889 + return this.addListener.apply(this, arguments); 59.9890 + }; 59.9891 + Constraint.prototype.pipe = function pipe() { 59.9892 + _createEventOutput.call(this); 59.9893 + return this.pipe.apply(this, arguments); 59.9894 + }; 59.9895 + Constraint.prototype.removeListener = function removeListener() { 59.9896 + return this.removeListener.apply(this, arguments); 59.9897 + }; 59.9898 + Constraint.prototype.unpipe = function unpipe() { 59.9899 + return this.unpipe.apply(this, arguments); 59.9900 + }; 59.9901 + 59.9902 + module.exports = Constraint; 59.9903 +}); 59.9904 + 59.9905 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.9906 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.9907 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.9908 + * 59.9909 + * Owner: david@famo.us 59.9910 + * @license MPL 2.0 59.9911 + * @copyright Famous Industries, Inc. 2014 59.9912 + */ 59.9913 + 59.9914 +define('famous/physics/constraints/Snap',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.9915 + var Constraint = require('./Constraint'); 59.9916 + var Vector = require('famous/math/Vector'); 59.9917 + 59.9918 + /** 59.9919 + * A spring constraint is like a spring force, except that it is always 59.9920 + * numerically stable (even for low periods), at the expense of introducing 59.9921 + * damping (even with dampingRatio set to 0). 59.9922 + * 59.9923 + * Use this if you need fast spring-like behavior, e.g., snapping 59.9924 + * 59.9925 + * @class Snap 59.9926 + * @constructor 59.9927 + * @extends Constraint 59.9928 + * @param {Options} [options] An object of configurable options. 59.9929 + * @param {Number} [options.period] The amount of time in milliseconds taken for one complete oscillation when there is no damping. Range : [150, Infinity] 59.9930 + * @param {Number} [options.dampingRatio] Additional damping of the spring. Range : [0, 1]. At 0 this spring will still be damped, at 1 the spring will be critically damped (the spring will never oscillate) 59.9931 + * @param {Number} [options.length] The rest length of the spring. Range: [0, Infinity]. 59.9932 + * @param {Array} [options.anchor] The location of the spring's anchor, if not another physics body. 59.9933 + * 59.9934 + */ 59.9935 + function Snap(options) { 59.9936 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.9937 + if (options) this.setOptions(options); 59.9938 + 59.9939 + //registers 59.9940 + this.pDiff = new Vector(); 59.9941 + this.vDiff = new Vector(); 59.9942 + this.impulse1 = new Vector(); 59.9943 + this.impulse2 = new Vector(); 59.9944 + 59.9945 + Constraint.call(this); 59.9946 + } 59.9947 + 59.9948 + Snap.prototype = Object.create(Constraint.prototype); 59.9949 + Snap.prototype.constructor = Snap; 59.9950 + 59.9951 + Snap.DEFAULT_OPTIONS = { 59.9952 + period : 300, 59.9953 + dampingRatio : 0.1, 59.9954 + length : 0, 59.9955 + anchor : undefined 59.9956 + }; 59.9957 + 59.9958 + /** const */ var pi = Math.PI; 59.9959 + 59.9960 + function _calcEnergy(impulse, disp, dt) { 59.9961 + return Math.abs(impulse.dot(disp)/dt); 59.9962 + } 59.9963 + 59.9964 + /** 59.9965 + * Basic options setter 59.9966 + * 59.9967 + * @method setOptions 59.9968 + * @param options {Objects} options 59.9969 + */ 59.9970 + Snap.prototype.setOptions = function setOptions(options) { 59.9971 + if (options.anchor !== undefined) { 59.9972 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 59.9973 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 59.9974 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 59.9975 + } 59.9976 + if (options.length !== undefined) this.options.length = options.length; 59.9977 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 59.9978 + if (options.period !== undefined) this.options.period = options.period; 59.9979 + }; 59.9980 + 59.9981 + /** 59.9982 + * Set the anchor position 59.9983 + * 59.9984 + * @method setOptions 59.9985 + * @param {Array} v TODO 59.9986 + */ 59.9987 + 59.9988 + Snap.prototype.setAnchor = function setAnchor(v) { 59.9989 + if (this.options.anchor !== undefined) this.options.anchor = new Vector(); 59.9990 + this.options.anchor.set(v); 59.9991 + }; 59.9992 + 59.9993 + /** 59.9994 + * Calculates energy of spring 59.9995 + * 59.9996 + * @method getEnergy 59.9997 + * @param {Object} target TODO 59.9998 + * @param {Object} source TODO 59.9999 + * @return energy {Number} 59.10000 + */ 59.10001 + Snap.prototype.getEnergy = function getEnergy(target, source) { 59.10002 + var options = this.options; 59.10003 + var restLength = options.length; 59.10004 + var anchor = options.anchor || source.position; 59.10005 + var strength = Math.pow(2 * pi / options.period, 2); 59.10006 + 59.10007 + var dist = anchor.sub(target.position).norm() - restLength; 59.10008 + 59.10009 + return 0.5 * strength * dist * dist; 59.10010 + }; 59.10011 + 59.10012 + /** 59.10013 + * Adds a spring impulse to a physics body's velocity due to the constraint 59.10014 + * 59.10015 + * @method applyConstraint 59.10016 + * @param targets {Array.Body} Array of bodies to apply the constraint to 59.10017 + * @param source {Body} The source of the constraint 59.10018 + * @param dt {Number} Delta time 59.10019 + */ 59.10020 + Snap.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.10021 + var options = this.options; 59.10022 + var pDiff = this.pDiff; 59.10023 + var vDiff = this.vDiff; 59.10024 + var impulse1 = this.impulse1; 59.10025 + var impulse2 = this.impulse2; 59.10026 + var length = options.length; 59.10027 + var anchor = options.anchor || source.position; 59.10028 + var period = options.period; 59.10029 + var dampingRatio = options.dampingRatio; 59.10030 + 59.10031 + for (var i = 0; i < targets.length ; i++) { 59.10032 + var target = targets[i]; 59.10033 + 59.10034 + var p1 = target.position; 59.10035 + var v1 = target.velocity; 59.10036 + var m1 = target.mass; 59.10037 + var w1 = target.inverseMass; 59.10038 + 59.10039 + pDiff.set(p1.sub(anchor)); 59.10040 + var dist = pDiff.norm() - length; 59.10041 + var effMass; 59.10042 + 59.10043 + if (source) { 59.10044 + var w2 = source.inverseMass; 59.10045 + var v2 = source.velocity; 59.10046 + vDiff.set(v1.sub(v2)); 59.10047 + effMass = 1/(w1 + w2); 59.10048 + } 59.10049 + else { 59.10050 + vDiff.set(v1); 59.10051 + effMass = m1; 59.10052 + } 59.10053 + 59.10054 + var gamma; 59.10055 + var beta; 59.10056 + 59.10057 + if (this.options.period === 0) { 59.10058 + gamma = 0; 59.10059 + beta = 1; 59.10060 + } 59.10061 + else { 59.10062 + var k = 4 * effMass * pi * pi / (period * period); 59.10063 + var c = 4 * effMass * pi * dampingRatio / period; 59.10064 + 59.10065 + beta = dt * k / (c + dt * k); 59.10066 + gamma = 1 / (c + dt*k); 59.10067 + } 59.10068 + 59.10069 + var antiDrift = beta/dt * dist; 59.10070 + pDiff.normalize(-antiDrift) 59.10071 + .sub(vDiff) 59.10072 + .mult(dt / (gamma + dt/effMass)) 59.10073 + .put(impulse1); 59.10074 + 59.10075 + // var n = new Vector(); 59.10076 + // n.set(pDiff.normalize()); 59.10077 + // var lambda = -(n.dot(vDiff) + antiDrift) / (gamma + dt/effMass); 59.10078 + // impulse2.set(n.mult(dt*lambda)); 59.10079 + 59.10080 + target.applyImpulse(impulse1); 59.10081 + 59.10082 + if (source) { 59.10083 + impulse1.mult(-1).put(impulse2); 59.10084 + source.applyImpulse(impulse2); 59.10085 + } 59.10086 + 59.10087 + this.setEnergy(_calcEnergy(impulse1, pDiff, dt)); 59.10088 + } 59.10089 + }; 59.10090 + 59.10091 + module.exports = Snap; 59.10092 +}); 59.10093 + 59.10094 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.10095 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.10096 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.10097 + * 59.10098 + * Owner: david@famo.us 59.10099 + * @license MPL 2.0 59.10100 + * @copyright Famous Industries, Inc. 2014 59.10101 + */ 59.10102 + 59.10103 +define('famous/transitions/SnapTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/constraints/Snap','famous/math/Vector'],function(require, exports, module) { 59.10104 + var PE = require('famous/physics/PhysicsEngine'); 59.10105 + var Particle = require('famous/physics/bodies/Particle'); 59.10106 + var Spring = require('famous/physics/constraints/Snap'); 59.10107 + var Vector = require('famous/math/Vector'); 59.10108 + 59.10109 + /** 59.10110 + * SnapTransition is a method of transitioning between two values (numbers, 59.10111 + * or arrays of numbers). It is similar to SpringTransition except 59.10112 + * the transition can be much faster and always has a damping effect. 59.10113 + * 59.10114 + * @class SnapTransition 59.10115 + * @constructor 59.10116 + * 59.10117 + * @param [state=0] {Number|Array} Initial state 59.10118 + */ 59.10119 + function SnapTransition(state) { 59.10120 + state = state || 0; 59.10121 + 59.10122 + this.endState = new Vector(state); 59.10123 + this.initState = new Vector(); 59.10124 + 59.10125 + this._dimensions = 1; 59.10126 + this._restTolerance = 1e-10; 59.10127 + this._absRestTolerance = this._restTolerance; 59.10128 + this._callback = undefined; 59.10129 + 59.10130 + this.PE = new PE(); 59.10131 + this.particle = new Particle(); 59.10132 + this.spring = new Spring({anchor : this.endState}); 59.10133 + 59.10134 + this.PE.addBody(this.particle); 59.10135 + this.PE.attach(this.spring, this.particle); 59.10136 + } 59.10137 + 59.10138 + SnapTransition.SUPPORTS_MULTIPLE = 3; 59.10139 + 59.10140 + /** 59.10141 + * @property SnapTransition.DEFAULT_OPTIONS 59.10142 + * @type Object 59.10143 + * @protected 59.10144 + * @static 59.10145 + */ 59.10146 + SnapTransition.DEFAULT_OPTIONS = { 59.10147 + 59.10148 + /** 59.10149 + * The amount of time in milliseconds taken for one complete oscillation 59.10150 + * when there is no damping 59.10151 + * Range : [0, Infinity] 59.10152 + * 59.10153 + * @attribute period 59.10154 + * @type Number 59.10155 + * @default 100 59.10156 + */ 59.10157 + period : 100, 59.10158 + 59.10159 + /** 59.10160 + * The damping of the snap. 59.10161 + * Range : [0, 1] 59.10162 + * 59.10163 + * @attribute dampingRatio 59.10164 + * @type Number 59.10165 + * @default 0.2 59.10166 + */ 59.10167 + dampingRatio : 0.2, 59.10168 + 59.10169 + /** 59.10170 + * The initial velocity of the transition. 59.10171 + * 59.10172 + * @attribute velocity 59.10173 + * @type Number|Array 59.10174 + * @default 0 59.10175 + */ 59.10176 + velocity : 0 59.10177 + }; 59.10178 + 59.10179 + function _getEnergy() { 59.10180 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 59.10181 + } 59.10182 + 59.10183 + function _setAbsoluteRestTolerance() { 59.10184 + var distance = this.endState.sub(this.initState).normSquared(); 59.10185 + this._absRestTolerance = (distance === 0) 59.10186 + ? this._restTolerance 59.10187 + : this._restTolerance * distance; 59.10188 + } 59.10189 + 59.10190 + function _setTarget(target) { 59.10191 + this.endState.set(target); 59.10192 + _setAbsoluteRestTolerance.call(this); 59.10193 + } 59.10194 + 59.10195 + function _wake() { 59.10196 + this.PE.wake(); 59.10197 + } 59.10198 + 59.10199 + function _sleep() { 59.10200 + this.PE.sleep(); 59.10201 + } 59.10202 + 59.10203 + function _setParticlePosition(p) { 59.10204 + this.particle.position.set(p); 59.10205 + } 59.10206 + 59.10207 + function _setParticleVelocity(v) { 59.10208 + this.particle.velocity.set(v); 59.10209 + } 59.10210 + 59.10211 + function _getParticlePosition() { 59.10212 + return (this._dimensions === 0) 59.10213 + ? this.particle.getPosition1D() 59.10214 + : this.particle.getPosition(); 59.10215 + } 59.10216 + 59.10217 + function _getParticleVelocity() { 59.10218 + return (this._dimensions === 0) 59.10219 + ? this.particle.getVelocity1D() 59.10220 + : this.particle.getVelocity(); 59.10221 + } 59.10222 + 59.10223 + function _setCallback(callback) { 59.10224 + this._callback = callback; 59.10225 + } 59.10226 + 59.10227 + function _setupDefinition(definition) { 59.10228 + var defaults = SnapTransition.DEFAULT_OPTIONS; 59.10229 + if (definition.period === undefined) definition.period = defaults.period; 59.10230 + if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio; 59.10231 + if (definition.velocity === undefined) definition.velocity = defaults.velocity; 59.10232 + 59.10233 + //setup spring 59.10234 + this.spring.setOptions({ 59.10235 + period : definition.period, 59.10236 + dampingRatio : definition.dampingRatio 59.10237 + }); 59.10238 + 59.10239 + //setup particle 59.10240 + _setParticleVelocity.call(this, definition.velocity); 59.10241 + } 59.10242 + 59.10243 + function _update() { 59.10244 + if (this.PE.isSleeping()) { 59.10245 + if (this._callback) { 59.10246 + var cb = this._callback; 59.10247 + this._callback = undefined; 59.10248 + cb(); 59.10249 + } 59.10250 + return; 59.10251 + } 59.10252 + 59.10253 + if (_getEnergy.call(this) < this._absRestTolerance) { 59.10254 + _setParticlePosition.call(this, this.endState); 59.10255 + _setParticleVelocity.call(this, [0,0,0]); 59.10256 + _sleep.call(this); 59.10257 + } 59.10258 + } 59.10259 + 59.10260 + /** 59.10261 + * Resets the state and velocity 59.10262 + * 59.10263 + * @method reset 59.10264 + * 59.10265 + * @param state {Number|Array} State 59.10266 + * @param [velocity] {Number|Array} Velocity 59.10267 + */ 59.10268 + SnapTransition.prototype.reset = function reset(state, velocity) { 59.10269 + this._dimensions = (state instanceof Array) 59.10270 + ? state.length 59.10271 + : 0; 59.10272 + 59.10273 + this.initState.set(state); 59.10274 + _setParticlePosition.call(this, state); 59.10275 + _setTarget.call(this, state); 59.10276 + if (velocity) _setParticleVelocity.call(this, velocity); 59.10277 + _setCallback.call(this, undefined); 59.10278 + }; 59.10279 + 59.10280 + /** 59.10281 + * Getter for velocity 59.10282 + * 59.10283 + * @method getVelocity 59.10284 + * 59.10285 + * @return velocity {Number|Array} 59.10286 + */ 59.10287 + SnapTransition.prototype.getVelocity = function getVelocity() { 59.10288 + return _getParticleVelocity.call(this); 59.10289 + }; 59.10290 + 59.10291 + /** 59.10292 + * Setter for velocity 59.10293 + * 59.10294 + * @method setVelocity 59.10295 + * 59.10296 + * @return velocity {Number|Array} 59.10297 + */ 59.10298 + SnapTransition.prototype.setVelocity = function setVelocity(velocity) { 59.10299 + this.call(this, _setParticleVelocity(velocity)); 59.10300 + }; 59.10301 + 59.10302 + /** 59.10303 + * Detects whether a transition is in progress 59.10304 + * 59.10305 + * @method isActive 59.10306 + * 59.10307 + * @return {Boolean} 59.10308 + */ 59.10309 + SnapTransition.prototype.isActive = function isActive() { 59.10310 + return !this.PE.isSleeping(); 59.10311 + }; 59.10312 + 59.10313 + /** 59.10314 + * Halt the transition 59.10315 + * 59.10316 + * @method halt 59.10317 + */ 59.10318 + SnapTransition.prototype.halt = function halt() { 59.10319 + this.set(this.get()); 59.10320 + }; 59.10321 + 59.10322 + /** 59.10323 + * Get the current position of the transition 59.10324 +s * 59.10325 + * @method get 59.10326 + * 59.10327 + * @return state {Number|Array} 59.10328 + */ 59.10329 + SnapTransition.prototype.get = function get() { 59.10330 + _update.call(this); 59.10331 + return _getParticlePosition.call(this); 59.10332 + }; 59.10333 + 59.10334 + /** 59.10335 + * Set the end position and transition, with optional callback on completion. 59.10336 + * 59.10337 + * @method set 59.10338 + * 59.10339 + * @param state {Number|Array} Final state 59.10340 + * @param [definition] {Object} Transition definition 59.10341 + * @param [callback] {Function} Callback 59.10342 + */ 59.10343 + SnapTransition.prototype.set = function set(state, definition, callback) { 59.10344 + if (!definition) { 59.10345 + this.reset(state); 59.10346 + if (callback) callback(); 59.10347 + return; 59.10348 + } 59.10349 + 59.10350 + this._dimensions = (state instanceof Array) 59.10351 + ? state.length 59.10352 + : 0; 59.10353 + 59.10354 + _wake.call(this); 59.10355 + _setupDefinition.call(this, definition); 59.10356 + _setTarget.call(this, state); 59.10357 + _setCallback.call(this, callback); 59.10358 + }; 59.10359 + 59.10360 + module.exports = SnapTransition; 59.10361 +}); 59.10362 + 59.10363 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.10364 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.10365 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.10366 + * 59.10367 + * Owner: david@famo.us 59.10368 + * @license MPL 2.0 59.10369 + * @copyright Famous Industries, Inc. 2014 59.10370 + */ 59.10371 + 59.10372 +define('famous/physics/forces/Force',['require','exports','module','famous/math/Vector','famous/core/EventHandler'],function(require, exports, module) { 59.10373 + var Vector = require('famous/math/Vector'); 59.10374 + var EventHandler = require('famous/core/EventHandler'); 59.10375 + 59.10376 + /** 59.10377 + * Force base class. 59.10378 + * 59.10379 + * @class Force 59.10380 + * @uses EventHandler 59.10381 + * @constructor 59.10382 + */ 59.10383 + function Force(force) { 59.10384 + this.force = new Vector(force); 59.10385 + this._energy = 0.0; 59.10386 + this._eventOutput = null; 59.10387 + } 59.10388 + 59.10389 + /** 59.10390 + * Basic setter for options 59.10391 + * 59.10392 + * @method setOptions 59.10393 + * @param options {Objects} 59.10394 + */ 59.10395 + Force.prototype.setOptions = function setOptions(options) { 59.10396 + for (var key in options) this.options[key] = options[key]; 59.10397 + }; 59.10398 + 59.10399 + /** 59.10400 + * Adds a force to a physics body's force accumulator. 59.10401 + * 59.10402 + * @method applyForce 59.10403 + * @param body {Body} 59.10404 + */ 59.10405 + Force.prototype.applyForce = function applyForce(body) { 59.10406 + body.applyForce(this.force); 59.10407 + }; 59.10408 + 59.10409 + /** 59.10410 + * Getter for a force's potential energy. 59.10411 + * 59.10412 + * @method getEnergy 59.10413 + * @return energy {Number} 59.10414 + */ 59.10415 + Force.prototype.getEnergy = function getEnergy() { 59.10416 + return this._energy; 59.10417 + }; 59.10418 + 59.10419 + /* 59.10420 + * Setter for a force's potential energy. 59.10421 + * 59.10422 + * @method setEnergy 59.10423 + * @param energy {Number} 59.10424 + */ 59.10425 + Force.prototype.setEnergy = function setEnergy(energy) { 59.10426 + this._energy = energy; 59.10427 + }; 59.10428 + 59.10429 + function _createEventOutput() { 59.10430 + this._eventOutput = new EventHandler(); 59.10431 + this._eventOutput.bindThis(this); 59.10432 + EventHandler.setOutputHandler(this, this._eventOutput); 59.10433 + } 59.10434 + 59.10435 + Force.prototype.on = function on() { 59.10436 + _createEventOutput.call(this); 59.10437 + return this.on.apply(this, arguments); 59.10438 + }; 59.10439 + Force.prototype.addListener = function addListener() { 59.10440 + _createEventOutput.call(this); 59.10441 + return this.addListener.apply(this, arguments); 59.10442 + }; 59.10443 + Force.prototype.pipe = function pipe() { 59.10444 + _createEventOutput.call(this); 59.10445 + return this.pipe.apply(this, arguments); 59.10446 + }; 59.10447 + Force.prototype.removeListener = function removeListener() { 59.10448 + return this.removeListener.apply(this, arguments); 59.10449 + }; 59.10450 + Force.prototype.unpipe = function unpipe() { 59.10451 + return this.unpipe.apply(this, arguments); 59.10452 + }; 59.10453 + 59.10454 + module.exports = Force; 59.10455 +}); 59.10456 + 59.10457 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.10458 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.10459 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.10460 + * 59.10461 + * Owner: david@famo.us 59.10462 + * @license MPL 2.0 59.10463 + * @copyright Famous Industries, Inc. 2014 59.10464 + */ 59.10465 + 59.10466 +define('famous/physics/forces/Spring',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 59.10467 + var Force = require('./Force'); 59.10468 + var Vector = require('famous/math/Vector'); 59.10469 + 59.10470 + /** 59.10471 + * A force that moves a physics body to a location with a spring motion. 59.10472 + * The body can be moved to another physics body, or an anchor point. 59.10473 + * 59.10474 + * @class Spring 59.10475 + * @constructor 59.10476 + * @extends Force 59.10477 + * @param {Object} options options to set on drag 59.10478 + */ 59.10479 + function Spring(options) { 59.10480 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.10481 + if (options) this.setOptions(options); 59.10482 + 59.10483 + //registers 59.10484 + this.disp = new Vector(0,0,0); 59.10485 + 59.10486 + _init.call(this); 59.10487 + Force.call(this); 59.10488 + } 59.10489 + 59.10490 + Spring.prototype = Object.create(Force.prototype); 59.10491 + Spring.prototype.constructor = Spring; 59.10492 + 59.10493 + /** @const */ var pi = Math.PI; 59.10494 + 59.10495 + /** 59.10496 + * @property Spring.FORCE_FUNCTIONS 59.10497 + * @type Object 59.10498 + * @protected 59.10499 + * @static 59.10500 + */ 59.10501 + Spring.FORCE_FUNCTIONS = { 59.10502 + 59.10503 + /** 59.10504 + * A FENE (Finitely Extensible Nonlinear Elastic) spring force 59.10505 + * see: http://en.wikipedia.org/wiki/FENE 59.10506 + * @attribute FENE 59.10507 + * @type Function 59.10508 + * @param {Number} dist current distance target is from source body 59.10509 + * @param {Number} rMax maximum range of influence 59.10510 + * @return {Number} unscaled force 59.10511 + */ 59.10512 + FENE : function(dist, rMax) { 59.10513 + var rMaxSmall = rMax * .99; 59.10514 + var r = Math.max(Math.min(dist, rMaxSmall), -rMaxSmall); 59.10515 + return r / (1 - r * r/(rMax * rMax)); 59.10516 + }, 59.10517 + 59.10518 + /** 59.10519 + * A Hookean spring force, linear in the displacement 59.10520 + * see: http://en.wikipedia.org/wiki/FENE 59.10521 + * @attribute FENE 59.10522 + * @type Function 59.10523 + * @param {Number} dist current distance target is from source body 59.10524 + * @return {Number} unscaled force 59.10525 + */ 59.10526 + HOOK : function(dist) { 59.10527 + return dist; 59.10528 + } 59.10529 + }; 59.10530 + 59.10531 + /** 59.10532 + * @property Spring.DEFAULT_OPTIONS 59.10533 + * @type Object 59.10534 + * @protected 59.10535 + * @static 59.10536 + */ 59.10537 + Spring.DEFAULT_OPTIONS = { 59.10538 + 59.10539 + /** 59.10540 + * The amount of time in milliseconds taken for one complete oscillation 59.10541 + * when there is no damping 59.10542 + * Range : [150, Infinity] 59.10543 + * @attribute period 59.10544 + * @type Number 59.10545 + * @default 300 59.10546 + */ 59.10547 + period : 300, 59.10548 + 59.10549 + /** 59.10550 + * The damping of the spring. 59.10551 + * Range : [0, 1] 59.10552 + * 0 = no damping, and the spring will oscillate forever 59.10553 + * 1 = critically damped (the spring will never oscillate) 59.10554 + * @attribute dampingRatio 59.10555 + * @type Number 59.10556 + * @default 0.1 59.10557 + */ 59.10558 + dampingRatio : 0.1, 59.10559 + 59.10560 + /** 59.10561 + * The rest length of the spring 59.10562 + * Range : [0, Infinity] 59.10563 + * @attribute length 59.10564 + * @type Number 59.10565 + * @default 0 59.10566 + */ 59.10567 + length : 0, 59.10568 + 59.10569 + /** 59.10570 + * The maximum length of the spring (for a FENE spring) 59.10571 + * Range : [0, Infinity] 59.10572 + * @attribute length 59.10573 + * @type Number 59.10574 + * @default Infinity 59.10575 + */ 59.10576 + maxLength : Infinity, 59.10577 + 59.10578 + /** 59.10579 + * The location of the spring's anchor, if not another physics body 59.10580 + * 59.10581 + * @attribute anchor 59.10582 + * @type Array 59.10583 + * @optional 59.10584 + */ 59.10585 + anchor : undefined, 59.10586 + 59.10587 + /** 59.10588 + * The type of spring force 59.10589 + * @attribute forceFunction 59.10590 + * @type Function 59.10591 + */ 59.10592 + forceFunction : Spring.FORCE_FUNCTIONS.HOOK 59.10593 + }; 59.10594 + 59.10595 + function _setForceFunction(fn) { 59.10596 + this.forceFunction = fn; 59.10597 + } 59.10598 + 59.10599 + function _calcStiffness() { 59.10600 + var options = this.options; 59.10601 + options.stiffness = Math.pow(2 * pi / options.period, 2); 59.10602 + } 59.10603 + 59.10604 + function _calcDamping() { 59.10605 + var options = this.options; 59.10606 + options.damping = 4 * pi * options.dampingRatio / options.period; 59.10607 + } 59.10608 + 59.10609 + function _calcEnergy(strength, dist) { 59.10610 + return 0.5 * strength * dist * dist; 59.10611 + } 59.10612 + 59.10613 + function _init() { 59.10614 + _setForceFunction.call(this, this.options.forceFunction); 59.10615 + _calcStiffness.call(this); 59.10616 + _calcDamping.call(this); 59.10617 + } 59.10618 + 59.10619 + /** 59.10620 + * Basic options setter 59.10621 + * 59.10622 + * @method setOptions 59.10623 + * @param options {Objects} 59.10624 + */ 59.10625 + Spring.prototype.setOptions = function setOptions(options) { 59.10626 + if (options.anchor !== undefined) { 59.10627 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 59.10628 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 59.10629 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 59.10630 + } 59.10631 + if (options.period !== undefined) this.options.period = options.period; 59.10632 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 59.10633 + if (options.length !== undefined) this.options.length = options.length; 59.10634 + if (options.forceFunction !== undefined) this.options.forceFunction = options.forceFunction; 59.10635 + if (options.maxLength !== undefined) this.options.maxLength = options.maxLength; 59.10636 + 59.10637 + _init.call(this); 59.10638 + }; 59.10639 + 59.10640 + /** 59.10641 + * Adds a spring force to a physics body's force accumulator. 59.10642 + * 59.10643 + * @method applyForce 59.10644 + * @param targets {Array.Body} Array of bodies to apply force to. 59.10645 + */ 59.10646 + Spring.prototype.applyForce = function applyForce(targets, source) { 59.10647 + var force = this.force; 59.10648 + var disp = this.disp; 59.10649 + var options = this.options; 59.10650 + 59.10651 + var stiffness = options.stiffness; 59.10652 + var damping = options.damping; 59.10653 + var restLength = options.length; 59.10654 + var lMax = options.maxLength; 59.10655 + var anchor = options.anchor || source.position; 59.10656 + 59.10657 + for (var i = 0; i < targets.length; i++) { 59.10658 + var target = targets[i]; 59.10659 + var p2 = target.position; 59.10660 + var v2 = target.velocity; 59.10661 + 59.10662 + anchor.sub(p2).put(disp); 59.10663 + var dist = disp.norm() - restLength; 59.10664 + 59.10665 + if (dist === 0) return; 59.10666 + 59.10667 + //if dampingRatio specified, then override strength and damping 59.10668 + var m = target.mass; 59.10669 + stiffness *= m; 59.10670 + damping *= m; 59.10671 + 59.10672 + disp.normalize(stiffness * this.forceFunction(dist, lMax)) 59.10673 + .put(force); 59.10674 + 59.10675 + if (damping) 59.10676 + if (source) force.add(v2.sub(source.velocity).mult(-damping)).put(force); 59.10677 + else force.add(v2.mult(-damping)).put(force); 59.10678 + 59.10679 + target.applyForce(force); 59.10680 + if (source) source.applyForce(force.mult(-1)); 59.10681 + 59.10682 + this.setEnergy(_calcEnergy(stiffness, dist)); 59.10683 + } 59.10684 + }; 59.10685 + 59.10686 + /** 59.10687 + * Calculates the potential energy of the spring. 59.10688 + * 59.10689 + * @method getEnergy 59.10690 + * @param target {Body} The physics body attached to the spring 59.10691 + * @return energy {Number} 59.10692 + */ 59.10693 + Spring.prototype.getEnergy = function getEnergy(target) { 59.10694 + var options = this.options; 59.10695 + var restLength = options.length; 59.10696 + var anchor = options.anchor; 59.10697 + var strength = options.stiffness; 59.10698 + 59.10699 + var dist = anchor.sub(target.position).norm() - restLength; 59.10700 + return 0.5 * strength * dist * dist; 59.10701 + }; 59.10702 + 59.10703 + /** 59.10704 + * Sets the anchor to a new position 59.10705 + * 59.10706 + * @method setAnchor 59.10707 + * @param anchor {Array} New anchor of the spring 59.10708 + */ 59.10709 + Spring.prototype.setAnchor = function setAnchor(anchor) { 59.10710 + if (!this.options.anchor) this.options.anchor = new Vector(); 59.10711 + this.options.anchor.set(anchor); 59.10712 + }; 59.10713 + 59.10714 + module.exports = Spring; 59.10715 +}); 59.10716 + 59.10717 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.10718 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.10719 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.10720 + * 59.10721 + * Owner: david@famo.us 59.10722 + * @license MPL 2.0 59.10723 + * @copyright Famous Industries, Inc. 2014 59.10724 + */ 59.10725 + 59.10726 +/*global console*/ 59.10727 + 59.10728 +define('famous/transitions/SpringTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/math/Vector'],function(require, exports, module) { 59.10729 + var PE = require('famous/physics/PhysicsEngine'); 59.10730 + var Particle = require('famous/physics/bodies/Particle'); 59.10731 + var Spring = require('famous/physics/forces/Spring'); 59.10732 + var Vector = require('famous/math/Vector'); 59.10733 + 59.10734 + /** 59.10735 + * SpringTransition is a method of transitioning between two values (numbers, 59.10736 + * or arrays of numbers) with a bounce. The transition will overshoot the target 59.10737 + * state depending on the parameters of the transition. 59.10738 + * 59.10739 + * @class SpringTransition 59.10740 + * @constructor 59.10741 + * 59.10742 + * @param {Number|Array} [state=0] Initial state 59.10743 + */ 59.10744 + function SpringTransition(state) { 59.10745 + state = state || 0; 59.10746 + this.endState = new Vector(state); 59.10747 + this.initState = new Vector(); 59.10748 + 59.10749 + this._dimensions = undefined; 59.10750 + this._restTolerance = 1e-10; 59.10751 + this._absRestTolerance = this._restTolerance; 59.10752 + this._callback = undefined; 59.10753 + 59.10754 + this.PE = new PE(); 59.10755 + this.spring = new Spring({anchor : this.endState}); 59.10756 + this.particle = new Particle(); 59.10757 + 59.10758 + this.PE.addBody(this.particle); 59.10759 + this.PE.attach(this.spring, this.particle); 59.10760 + } 59.10761 + 59.10762 + SpringTransition.SUPPORTS_MULTIPLE = 3; 59.10763 + 59.10764 + /** 59.10765 + * @property SpringTransition.DEFAULT_OPTIONS 59.10766 + * @type Object 59.10767 + * @protected 59.10768 + * @static 59.10769 + */ 59.10770 + SpringTransition.DEFAULT_OPTIONS = { 59.10771 + 59.10772 + /** 59.10773 + * The amount of time in milliseconds taken for one complete oscillation 59.10774 + * when there is no damping 59.10775 + * Range : [0, Infinity] 59.10776 + * 59.10777 + * @attribute period 59.10778 + * @type Number 59.10779 + * @default 300 59.10780 + */ 59.10781 + period : 300, 59.10782 + 59.10783 + /** 59.10784 + * The damping of the snap. 59.10785 + * Range : [0, 1] 59.10786 + * 0 = no damping, and the spring will oscillate forever 59.10787 + * 1 = critically damped (the spring will never oscillate) 59.10788 + * 59.10789 + * @attribute dampingRatio 59.10790 + * @type Number 59.10791 + * @default 0.5 59.10792 + */ 59.10793 + dampingRatio : 0.5, 59.10794 + 59.10795 + /** 59.10796 + * The initial velocity of the transition. 59.10797 + * 59.10798 + * @attribute velocity 59.10799 + * @type Number|Array 59.10800 + * @default 0 59.10801 + */ 59.10802 + velocity : 0 59.10803 + }; 59.10804 + 59.10805 + function _getEnergy() { 59.10806 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 59.10807 + } 59.10808 + 59.10809 + function _setParticlePosition(p) { 59.10810 + this.particle.setPosition(p); 59.10811 + } 59.10812 + 59.10813 + function _setParticleVelocity(v) { 59.10814 + this.particle.setVelocity(v); 59.10815 + } 59.10816 + 59.10817 + function _getParticlePosition() { 59.10818 + return (this._dimensions === 0) 59.10819 + ? this.particle.getPosition1D() 59.10820 + : this.particle.getPosition(); 59.10821 + } 59.10822 + 59.10823 + function _getParticleVelocity() { 59.10824 + return (this._dimensions === 0) 59.10825 + ? this.particle.getVelocity1D() 59.10826 + : this.particle.getVelocity(); 59.10827 + } 59.10828 + 59.10829 + function _setCallback(callback) { 59.10830 + this._callback = callback; 59.10831 + } 59.10832 + 59.10833 + function _wake() { 59.10834 + this.PE.wake(); 59.10835 + } 59.10836 + 59.10837 + function _sleep() { 59.10838 + this.PE.sleep(); 59.10839 + } 59.10840 + 59.10841 + function _update() { 59.10842 + if (this.PE.isSleeping()) { 59.10843 + if (this._callback) { 59.10844 + var cb = this._callback; 59.10845 + this._callback = undefined; 59.10846 + cb(); 59.10847 + } 59.10848 + return; 59.10849 + } 59.10850 + 59.10851 + if (_getEnergy.call(this) < this._absRestTolerance) { 59.10852 + _setParticlePosition.call(this, this.endState); 59.10853 + _setParticleVelocity.call(this, [0,0,0]); 59.10854 + _sleep.call(this); 59.10855 + } 59.10856 + } 59.10857 + 59.10858 + function _setupDefinition(definition) { 59.10859 + // TODO fix no-console error 59.10860 + /* eslint no-console: 0 */ 59.10861 + var defaults = SpringTransition.DEFAULT_OPTIONS; 59.10862 + if (definition.period === undefined) definition.period = defaults.period; 59.10863 + if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio; 59.10864 + if (definition.velocity === undefined) definition.velocity = defaults.velocity; 59.10865 + 59.10866 + if (definition.period < 150) { 59.10867 + definition.period = 150; 59.10868 + console.warn('The period of a SpringTransition is capped at 150 ms. Use a SnapTransition for faster transitions'); 59.10869 + } 59.10870 + 59.10871 + //setup spring 59.10872 + this.spring.setOptions({ 59.10873 + period : definition.period, 59.10874 + dampingRatio : definition.dampingRatio 59.10875 + }); 59.10876 + 59.10877 + //setup particle 59.10878 + _setParticleVelocity.call(this, definition.velocity); 59.10879 + } 59.10880 + 59.10881 + function _setAbsoluteRestTolerance() { 59.10882 + var distance = this.endState.sub(this.initState).normSquared(); 59.10883 + this._absRestTolerance = (distance === 0) 59.10884 + ? this._restTolerance 59.10885 + : this._restTolerance * distance; 59.10886 + } 59.10887 + 59.10888 + function _setTarget(target) { 59.10889 + this.endState.set(target); 59.10890 + _setAbsoluteRestTolerance.call(this); 59.10891 + } 59.10892 + 59.10893 + /** 59.10894 + * Resets the position and velocity 59.10895 + * 59.10896 + * @method reset 59.10897 + * 59.10898 + * @param {Number|Array.Number} pos positional state 59.10899 + * @param {Number|Array} vel velocity 59.10900 + */ 59.10901 + SpringTransition.prototype.reset = function reset(pos, vel) { 59.10902 + this._dimensions = (pos instanceof Array) 59.10903 + ? pos.length 59.10904 + : 0; 59.10905 + 59.10906 + this.initState.set(pos); 59.10907 + _setParticlePosition.call(this, pos); 59.10908 + _setTarget.call(this, pos); 59.10909 + if (vel) _setParticleVelocity.call(this, vel); 59.10910 + _setCallback.call(this, undefined); 59.10911 + }; 59.10912 + 59.10913 + /** 59.10914 + * Getter for velocity 59.10915 + * 59.10916 + * @method getVelocity 59.10917 + * 59.10918 + * @return {Number|Array} velocity 59.10919 + */ 59.10920 + SpringTransition.prototype.getVelocity = function getVelocity() { 59.10921 + return _getParticleVelocity.call(this); 59.10922 + }; 59.10923 + 59.10924 + /** 59.10925 + * Setter for velocity 59.10926 + * 59.10927 + * @method setVelocity 59.10928 + * 59.10929 + * @return {Number|Array} velocity 59.10930 + */ 59.10931 + SpringTransition.prototype.setVelocity = function setVelocity(v) { 59.10932 + this.call(this, _setParticleVelocity(v)); 59.10933 + }; 59.10934 + 59.10935 + /** 59.10936 + * Detects whether a transition is in progress 59.10937 + * 59.10938 + * @method isActive 59.10939 + * 59.10940 + * @return {Boolean} 59.10941 + */ 59.10942 + SpringTransition.prototype.isActive = function isActive() { 59.10943 + return !this.PE.isSleeping(); 59.10944 + }; 59.10945 + 59.10946 + /** 59.10947 + * Halt the transition 59.10948 + * 59.10949 + * @method halt 59.10950 + */ 59.10951 + SpringTransition.prototype.halt = function halt() { 59.10952 + this.set(this.get()); 59.10953 + }; 59.10954 + 59.10955 + /** 59.10956 + * Get the current position of the transition 59.10957 + * 59.10958 + * @method get 59.10959 + * 59.10960 + * @return {Number|Array} state 59.10961 + */ 59.10962 + SpringTransition.prototype.get = function get() { 59.10963 + _update.call(this); 59.10964 + return _getParticlePosition.call(this); 59.10965 + }; 59.10966 + 59.10967 + /** 59.10968 + * Set the end position and transition, with optional callback on completion. 59.10969 + * 59.10970 + * @method set 59.10971 + * 59.10972 + * @param {Number|Array} endState Final state 59.10973 + * @param {Object} definition Transition definition 59.10974 + * @param {Function} callback Callback 59.10975 + */ 59.10976 + SpringTransition.prototype.set = function set(endState, definition, callback) { 59.10977 + if (!definition) { 59.10978 + this.reset(endState); 59.10979 + if (callback) callback(); 59.10980 + return; 59.10981 + } 59.10982 + 59.10983 + this._dimensions = (endState instanceof Array) 59.10984 + ? endState.length 59.10985 + : 0; 59.10986 + 59.10987 + _wake.call(this); 59.10988 + _setupDefinition.call(this, definition); 59.10989 + _setTarget.call(this, endState); 59.10990 + _setCallback.call(this, callback); 59.10991 + }; 59.10992 + 59.10993 + module.exports = SpringTransition; 59.10994 +}); 59.10995 + 59.10996 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.10997 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.10998 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.10999 + * 59.11000 + * Owner: david@famo.us 59.11001 + * @license MPL 2.0 59.11002 + * @copyright Famous Industries, Inc. 2014 59.11003 + */ 59.11004 + 59.11005 +define('famous/physics/constraints/Wall',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.11006 + var Constraint = require('./Constraint'); 59.11007 + var Vector = require('famous/math/Vector'); 59.11008 + 59.11009 + /** 59.11010 + * A wall describes an infinite two-dimensional plane that physics bodies 59.11011 + * can collide with. To define a wall, you must give it a distance (from 59.11012 + * the center of the physics engine's origin, and a normal defining the plane 59.11013 + * of the wall. 59.11014 + * 59.11015 + * (wall) 59.11016 + * | 59.11017 + * | (normal) (origin) 59.11018 + * | ---> * 59.11019 + * | 59.11020 + * | (distance) 59.11021 + * ................... 59.11022 + * (100px) 59.11023 + * 59.11024 + * e.g., Wall({normal : [1,0,0], distance : 100}) 59.11025 + * would be a wall 100 pixels to the left, whose normal points right 59.11026 + * 59.11027 + * @class Wall 59.11028 + * @constructor 59.11029 + * @extends Constraint 59.11030 + * @param {Options} [options] An object of configurable options. 59.11031 + * @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic). Range : [0, 1] 59.11032 + * @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 59.11033 + * @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers. 59.11034 + * @param {Array} [options.normal] The normal direction to the wall. 59.11035 + * @param {Number} [options.distance] The distance from the origin that the wall is placed. 59.11036 + * @param {onContact} [options.onContact] How to handle collision against the wall. 59.11037 + * 59.11038 + */ 59.11039 + function Wall(options) { 59.11040 + this.options = Object.create(Wall.DEFAULT_OPTIONS); 59.11041 + if (options) this.setOptions(options); 59.11042 + 59.11043 + //registers 59.11044 + this.diff = new Vector(); 59.11045 + this.impulse = new Vector(); 59.11046 + 59.11047 + Constraint.call(this); 59.11048 + } 59.11049 + 59.11050 + Wall.prototype = Object.create(Constraint.prototype); 59.11051 + Wall.prototype.constructor = Wall; 59.11052 + 59.11053 + /** 59.11054 + * @property Wall.ON_CONTACT 59.11055 + * @type Object 59.11056 + * @protected 59.11057 + * @static 59.11058 + */ 59.11059 + Wall.ON_CONTACT = { 59.11060 + 59.11061 + /** 59.11062 + * Physical bodies bounce off the wall 59.11063 + * @attribute REFLECT 59.11064 + */ 59.11065 + REFLECT : 0, 59.11066 + 59.11067 + /** 59.11068 + * Physical bodies are unaffected. Usecase is to fire events on contact. 59.11069 + * @attribute SILENT 59.11070 + */ 59.11071 + SILENT : 1 59.11072 + }; 59.11073 + 59.11074 + Wall.DEFAULT_OPTIONS = { 59.11075 + restitution : 0.5, 59.11076 + drift : 0.5, 59.11077 + slop : 0, 59.11078 + normal : [1, 0, 0], 59.11079 + distance : 0, 59.11080 + onContact : Wall.ON_CONTACT.REFLECT 59.11081 + }; 59.11082 + 59.11083 + /* 59.11084 + * Setter for options. 59.11085 + * 59.11086 + * @method setOptions 59.11087 + * @param options {Objects} 59.11088 + */ 59.11089 + Wall.prototype.setOptions = function setOptions(options) { 59.11090 + if (options.normal !== undefined) { 59.11091 + if (options.normal instanceof Vector) this.options.normal = options.normal.clone(); 59.11092 + if (options.normal instanceof Array) this.options.normal = new Vector(options.normal); 59.11093 + } 59.11094 + if (options.restitution !== undefined) this.options.restitution = options.restitution; 59.11095 + if (options.drift !== undefined) this.options.drift = options.drift; 59.11096 + if (options.slop !== undefined) this.options.slop = options.slop; 59.11097 + if (options.distance !== undefined) this.options.distance = options.distance; 59.11098 + if (options.onContact !== undefined) this.options.onContact = options.onContact; 59.11099 + }; 59.11100 + 59.11101 + function _getNormalVelocity(n, v) { 59.11102 + return v.dot(n); 59.11103 + } 59.11104 + 59.11105 + function _getDistanceFromOrigin(p) { 59.11106 + var n = this.options.normal; 59.11107 + var d = this.options.distance; 59.11108 + return p.dot(n) + d; 59.11109 + } 59.11110 + 59.11111 + function _onEnter(particle, overlap, dt) { 59.11112 + var p = particle.position; 59.11113 + var v = particle.velocity; 59.11114 + var m = particle.mass; 59.11115 + var n = this.options.normal; 59.11116 + var action = this.options.onContact; 59.11117 + var restitution = this.options.restitution; 59.11118 + var impulse = this.impulse; 59.11119 + 59.11120 + var drift = this.options.drift; 59.11121 + var slop = -this.options.slop; 59.11122 + var gamma = 0; 59.11123 + 59.11124 + if (this._eventOutput) { 59.11125 + var data = {particle : particle, wall : this, overlap : overlap, normal : n}; 59.11126 + this._eventOutput.emit('preCollision', data); 59.11127 + this._eventOutput.emit('collision', data); 59.11128 + } 59.11129 + 59.11130 + switch (action) { 59.11131 + case Wall.ON_CONTACT.REFLECT: 59.11132 + var lambda = (overlap < slop) 59.11133 + ? -((1 + restitution) * n.dot(v) + drift / dt * (overlap - slop)) / (m * dt + gamma) 59.11134 + : -((1 + restitution) * n.dot(v)) / (m * dt + gamma); 59.11135 + 59.11136 + impulse.set(n.mult(dt * lambda)); 59.11137 + particle.applyImpulse(impulse); 59.11138 + particle.setPosition(p.add(n.mult(-overlap))); 59.11139 + break; 59.11140 + } 59.11141 + 59.11142 + if (this._eventOutput) this._eventOutput.emit('postCollision', data); 59.11143 + } 59.11144 + 59.11145 + function _onExit(particle, overlap, dt) { 59.11146 + var action = this.options.onContact; 59.11147 + var p = particle.position; 59.11148 + var n = this.options.normal; 59.11149 + 59.11150 + if (action === Wall.ON_CONTACT.REFLECT) { 59.11151 + particle.setPosition(p.add(n.mult(-overlap))); 59.11152 + } 59.11153 + } 59.11154 + 59.11155 + /** 59.11156 + * Adds an impulse to a physics body's velocity due to the wall constraint 59.11157 + * 59.11158 + * @method applyConstraint 59.11159 + * @param targets {Array.Body} Array of bodies to apply the constraint to 59.11160 + * @param source {Body} The source of the constraint 59.11161 + * @param dt {Number} Delta time 59.11162 + */ 59.11163 + Wall.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.11164 + var n = this.options.normal; 59.11165 + 59.11166 + for (var i = 0; i < targets.length; i++) { 59.11167 + var particle = targets[i]; 59.11168 + var p = particle.position; 59.11169 + var v = particle.velocity; 59.11170 + var r = particle.radius || 0; 59.11171 + 59.11172 + var overlap = _getDistanceFromOrigin.call(this, p.add(n.mult(-r))); 59.11173 + var nv = _getNormalVelocity.call(this, n, v); 59.11174 + 59.11175 + if (overlap <= 0) { 59.11176 + if (nv < 0) _onEnter.call(this, particle, overlap, dt); 59.11177 + else _onExit.call(this, particle, overlap, dt); 59.11178 + } 59.11179 + } 59.11180 + }; 59.11181 + 59.11182 + module.exports = Wall; 59.11183 +}); 59.11184 + 59.11185 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11186 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11187 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11188 + * 59.11189 + * Owner: david@famo.us 59.11190 + * @license MPL 2.0 59.11191 + * @copyright Famous Industries, Inc. 2014 59.11192 + */ 59.11193 + 59.11194 +define('famous/transitions/WallTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/physics/constraints/Wall','famous/math/Vector'],function(require, exports, module) { 59.11195 + var PE = require('famous/physics/PhysicsEngine'); 59.11196 + var Particle = require('famous/physics/bodies/Particle'); 59.11197 + var Spring = require('famous/physics/forces/Spring'); 59.11198 + var Wall = require('famous/physics/constraints/Wall'); 59.11199 + var Vector = require('famous/math/Vector'); 59.11200 + 59.11201 + /** 59.11202 + * WallTransition is a method of transitioning between two values (numbers, 59.11203 + * or arrays of numbers) with a bounce. Unlike a SpringTransition 59.11204 + * The transition will not overshoot the target, but bounce back against it. 59.11205 + * The behavior of the bounce is specified by the transition options. 59.11206 + * 59.11207 + * @class WallTransition 59.11208 + * @constructor 59.11209 + * 59.11210 + * @param {Number|Array} [state=0] Initial state 59.11211 + */ 59.11212 + function WallTransition(state) { 59.11213 + state = state || 0; 59.11214 + 59.11215 + this.endState = new Vector(state); 59.11216 + this.initState = new Vector(); 59.11217 + 59.11218 + this.spring = new Spring({anchor : this.endState}); 59.11219 + this.wall = new Wall(); 59.11220 + 59.11221 + this._restTolerance = 1e-10; 59.11222 + this._dimensions = 1; 59.11223 + this._absRestTolerance = this._restTolerance; 59.11224 + this._callback = undefined; 59.11225 + 59.11226 + this.PE = new PE(); 59.11227 + this.particle = new Particle(); 59.11228 + 59.11229 + this.PE.addBody(this.particle); 59.11230 + this.PE.attach([this.wall, this.spring], this.particle); 59.11231 + } 59.11232 + 59.11233 + WallTransition.SUPPORTS_MULTIPLE = 3; 59.11234 + 59.11235 + /** 59.11236 + * @property WallTransition.DEFAULT_OPTIONS 59.11237 + * @type Object 59.11238 + * @protected 59.11239 + * @static 59.11240 + */ 59.11241 + WallTransition.DEFAULT_OPTIONS = { 59.11242 + 59.11243 + /** 59.11244 + * The amount of time in milliseconds taken for one complete oscillation 59.11245 + * when there is no damping 59.11246 + * Range : [0, Infinity] 59.11247 + * 59.11248 + * @attribute period 59.11249 + * @type Number 59.11250 + * @default 300 59.11251 + */ 59.11252 + period : 300, 59.11253 + 59.11254 + /** 59.11255 + * The damping of the snap. 59.11256 + * Range : [0, 1] 59.11257 + * 0 = no damping, and the spring will oscillate forever 59.11258 + * 1 = critically damped (the spring will never oscillate) 59.11259 + * 59.11260 + * @attribute dampingRatio 59.11261 + * @type Number 59.11262 + * @default 0.5 59.11263 + */ 59.11264 + dampingRatio : 0.5, 59.11265 + 59.11266 + /** 59.11267 + * The initial velocity of the transition. 59.11268 + * 59.11269 + * @attribute velocity 59.11270 + * @type Number|Array 59.11271 + * @default 0 59.11272 + */ 59.11273 + velocity : 0, 59.11274 + 59.11275 + /** 59.11276 + * The percentage of momentum transferred to the wall 59.11277 + * 59.11278 + * @attribute restitution 59.11279 + * @type Number 59.11280 + * @default 0.5 59.11281 + */ 59.11282 + resitution : 0.5 59.11283 + }; 59.11284 + 59.11285 + function _getEnergy() { 59.11286 + return this.particle.getEnergy() + this.spring.getEnergy(this.particle); 59.11287 + } 59.11288 + 59.11289 + function _setAbsoluteRestTolerance() { 59.11290 + var distance = this.endState.sub(this.initState).normSquared(); 59.11291 + this._absRestTolerance = (distance === 0) 59.11292 + ? this._restTolerance 59.11293 + : this._restTolerance * distance; 59.11294 + } 59.11295 + 59.11296 + function _wake() { 59.11297 + this.PE.wake(); 59.11298 + } 59.11299 + 59.11300 + function _sleep() { 59.11301 + this.PE.sleep(); 59.11302 + } 59.11303 + 59.11304 + function _setTarget(target) { 59.11305 + this.endState.set(target); 59.11306 + 59.11307 + var dist = this.endState.sub(this.initState).norm(); 59.11308 + 59.11309 + this.wall.setOptions({ 59.11310 + distance : this.endState.norm(), 59.11311 + normal : (dist === 0) 59.11312 + ? this.particle.velocity.normalize(-1) 59.11313 + : this.endState.sub(this.initState).normalize(-1) 59.11314 + }); 59.11315 + 59.11316 + _setAbsoluteRestTolerance.call(this); 59.11317 + } 59.11318 + 59.11319 + function _setParticlePosition(p) { 59.11320 + this.particle.position.set(p); 59.11321 + } 59.11322 + 59.11323 + function _setParticleVelocity(v) { 59.11324 + this.particle.velocity.set(v); 59.11325 + } 59.11326 + 59.11327 + function _getParticlePosition() { 59.11328 + return (this._dimensions === 0) 59.11329 + ? this.particle.getPosition1D() 59.11330 + : this.particle.getPosition(); 59.11331 + } 59.11332 + 59.11333 + function _getParticleVelocity() { 59.11334 + return (this._dimensions === 0) 59.11335 + ? this.particle.getVelocity1D() 59.11336 + : this.particle.getVelocity(); 59.11337 + } 59.11338 + 59.11339 + function _setCallback(callback) { 59.11340 + this._callback = callback; 59.11341 + } 59.11342 + 59.11343 + function _update() { 59.11344 + if (this.PE.isSleeping()) { 59.11345 + if (this._callback) { 59.11346 + var cb = this._callback; 59.11347 + this._callback = undefined; 59.11348 + cb(); 59.11349 + } 59.11350 + return; 59.11351 + } 59.11352 + var energy = _getEnergy.call(this); 59.11353 + if (energy < this._absRestTolerance) { 59.11354 + _sleep.call(this); 59.11355 + _setParticlePosition.call(this, this.endState); 59.11356 + _setParticleVelocity.call(this, [0,0,0]); 59.11357 + } 59.11358 + } 59.11359 + 59.11360 + function _setupDefinition(def) { 59.11361 + var defaults = WallTransition.DEFAULT_OPTIONS; 59.11362 + if (def.period === undefined) def.period = defaults.period; 59.11363 + if (def.dampingRatio === undefined) def.dampingRatio = defaults.dampingRatio; 59.11364 + if (def.velocity === undefined) def.velocity = defaults.velocity; 59.11365 + if (def.restitution === undefined) def.restitution = defaults.restitution; 59.11366 + 59.11367 + //setup spring 59.11368 + this.spring.setOptions({ 59.11369 + period : def.period, 59.11370 + dampingRatio : def.dampingRatio 59.11371 + }); 59.11372 + 59.11373 + //setup wall 59.11374 + this.wall.setOptions({ 59.11375 + restitution : def.restitution 59.11376 + }); 59.11377 + 59.11378 + //setup particle 59.11379 + _setParticleVelocity.call(this, def.velocity); 59.11380 + } 59.11381 + 59.11382 + /** 59.11383 + * Resets the state and velocity 59.11384 + * 59.11385 + * @method reset 59.11386 + * 59.11387 + * @param {Number|Array} state State 59.11388 + * @param {Number|Array} [velocity] Velocity 59.11389 + */ 59.11390 + WallTransition.prototype.reset = function reset(state, velocity) { 59.11391 + this._dimensions = (state instanceof Array) 59.11392 + ? state.length 59.11393 + : 0; 59.11394 + 59.11395 + this.initState.set(state); 59.11396 + _setParticlePosition.call(this, state); 59.11397 + if (velocity) _setParticleVelocity.call(this, velocity); 59.11398 + _setTarget.call(this, state); 59.11399 + _setCallback.call(this, undefined); 59.11400 + }; 59.11401 + 59.11402 + /** 59.11403 + * Getter for velocity 59.11404 + * 59.11405 + * @method getVelocity 59.11406 + * 59.11407 + * @return velocity {Number|Array} 59.11408 + */ 59.11409 + WallTransition.prototype.getVelocity = function getVelocity() { 59.11410 + return _getParticleVelocity.call(this); 59.11411 + }; 59.11412 + 59.11413 + /** 59.11414 + * Setter for velocity 59.11415 + * 59.11416 + * @method setVelocity 59.11417 + * 59.11418 + * @return velocity {Number|Array} 59.11419 + */ 59.11420 + WallTransition.prototype.setVelocity = function setVelocity(velocity) { 59.11421 + this.call(this, _setParticleVelocity(velocity)); 59.11422 + }; 59.11423 + 59.11424 + /** 59.11425 + * Detects whether a transition is in progress 59.11426 + * 59.11427 + * @method isActive 59.11428 + * 59.11429 + * @return {Boolean} 59.11430 + */ 59.11431 + WallTransition.prototype.isActive = function isActive() { 59.11432 + return !this.PE.isSleeping(); 59.11433 + }; 59.11434 + 59.11435 + /** 59.11436 + * Halt the transition 59.11437 + * 59.11438 + * @method halt 59.11439 + */ 59.11440 + WallTransition.prototype.halt = function halt() { 59.11441 + this.set(this.get()); 59.11442 + }; 59.11443 + 59.11444 + /** 59.11445 + * Getter 59.11446 + * 59.11447 + * @method get 59.11448 + * 59.11449 + * @return state {Number|Array} 59.11450 + */ 59.11451 + WallTransition.prototype.get = function get() { 59.11452 + _update.call(this); 59.11453 + return _getParticlePosition.call(this); 59.11454 + }; 59.11455 + 59.11456 + /** 59.11457 + * Set the end position and transition, with optional callback on completion. 59.11458 + * 59.11459 + * @method set 59.11460 + * 59.11461 + * @param state {Number|Array} Final state 59.11462 + * @param [definition] {Object} Transition definition 59.11463 + * @param [callback] {Function} Callback 59.11464 + */ 59.11465 + WallTransition.prototype.set = function set(state, definition, callback) { 59.11466 + if (!definition) { 59.11467 + this.reset(state); 59.11468 + if (callback) callback(); 59.11469 + return; 59.11470 + } 59.11471 + 59.11472 + this._dimensions = (state instanceof Array) 59.11473 + ? state.length 59.11474 + : 0; 59.11475 + 59.11476 + _wake.call(this); 59.11477 + _setupDefinition.call(this, definition); 59.11478 + _setTarget.call(this, state); 59.11479 + _setCallback.call(this, callback); 59.11480 + }; 59.11481 + 59.11482 + module.exports = WallTransition; 59.11483 +}); 59.11484 + 59.11485 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11486 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11487 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11488 + * 59.11489 + * Owner: mark@famo.us 59.11490 + * @license MPL 2.0 59.11491 + * @copyright Famous Industries, Inc. 2014 59.11492 + */ 59.11493 + 59.11494 +define('famous/surfaces/CanvasSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 59.11495 + var Surface = require('famous/core/Surface'); 59.11496 + 59.11497 + /** 59.11498 + * A surface containing an HTML5 Canvas element. 59.11499 + * This extends the Surface class. 59.11500 + * 59.11501 + * @class CanvasSurface 59.11502 + * @extends Surface 59.11503 + * @constructor 59.11504 + * @param {Object} [options] overrides of default options 59.11505 + * @param {Array.Number} [options.canvasSize] [width, height] for document element 59.11506 + */ 59.11507 + function CanvasSurface(options) { 59.11508 + if (options && options.canvasSize) this._canvasSize = options.canvasSize; 59.11509 + Surface.apply(this, arguments); 59.11510 + if (!this._canvasSize) this._canvasSize = this.getSize(); 59.11511 + this._backBuffer = document.createElement('canvas'); 59.11512 + if (this._canvasSize) { 59.11513 + this._backBuffer.width = this._canvasSize[0]; 59.11514 + this._backBuffer.height = this._canvasSize[1]; 59.11515 + } 59.11516 + this._contextId = undefined; 59.11517 + } 59.11518 + 59.11519 + CanvasSurface.prototype = Object.create(Surface.prototype); 59.11520 + CanvasSurface.prototype.constructor = CanvasSurface; 59.11521 + CanvasSurface.prototype.elementType = 'canvas'; 59.11522 + CanvasSurface.prototype.elementClass = 'famous-surface'; 59.11523 + 59.11524 + /** 59.11525 + * Set inner document content. Note that this is a noop for CanvasSurface. 59.11526 + * 59.11527 + * @method setContent 59.11528 + * 59.11529 + */ 59.11530 + CanvasSurface.prototype.setContent = function setContent() {}; 59.11531 + 59.11532 + /** 59.11533 + * Place the document element this component manages into the document. 59.11534 + * This will draw the content to the document. 59.11535 + * 59.11536 + * @private 59.11537 + * @method deploy 59.11538 + * @param {Node} target document parent of this container 59.11539 + */ 59.11540 + CanvasSurface.prototype.deploy = function deploy(target) { 59.11541 + if (this._canvasSize) { 59.11542 + target.width = this._canvasSize[0]; 59.11543 + target.height = this._canvasSize[1]; 59.11544 + } 59.11545 + if (this._contextId === '2d') { 59.11546 + target.getContext(this._contextId).drawImage(this._backBuffer, 0, 0); 59.11547 + this._backBuffer.width = 0; 59.11548 + this._backBuffer.height = 0; 59.11549 + } 59.11550 + }; 59.11551 + 59.11552 + /** 59.11553 + * Remove this component and contained content from the document 59.11554 + * 59.11555 + * @private 59.11556 + * @method recall 59.11557 + * 59.11558 + * @param {Node} target node to which the component was deployed 59.11559 + */ 59.11560 + CanvasSurface.prototype.recall = function recall(target) { 59.11561 + var size = this.getSize(); 59.11562 + 59.11563 + this._backBuffer.width = target.width; 59.11564 + this._backBuffer.height = target.height; 59.11565 + 59.11566 + if (this._contextId === '2d') { 59.11567 + this._backBuffer.getContext(this._contextId).drawImage(target, 0, 0); 59.11568 + target.width = 0; 59.11569 + target.height = 0; 59.11570 + } 59.11571 + }; 59.11572 + 59.11573 + /** 59.11574 + * Returns the canvas element's context 59.11575 + * 59.11576 + * @method getContext 59.11577 + * @param {string} contextId context identifier 59.11578 + */ 59.11579 + CanvasSurface.prototype.getContext = function getContext(contextId) { 59.11580 + this._contextId = contextId; 59.11581 + return this._currTarget ? this._currTarget.getContext(contextId) : this._backBuffer.getContext(contextId); 59.11582 + }; 59.11583 + 59.11584 + /** 59.11585 + * Set the size of the surface and canvas element. 59.11586 + * 59.11587 + * @method setSize 59.11588 + * @param {Array.number} size [width, height] of surface 59.11589 + * @param {Array.number} canvasSize [width, height] of canvas surface 59.11590 + */ 59.11591 + CanvasSurface.prototype.setSize = function setSize(size, canvasSize) { 59.11592 + Surface.prototype.setSize.apply(this, arguments); 59.11593 + if (canvasSize) this._canvasSize = [canvasSize[0], canvasSize[1]]; 59.11594 + if (this._currTarget) { 59.11595 + this._currTarget.width = this._canvasSize[0]; 59.11596 + this._currTarget.height = this._canvasSize[1]; 59.11597 + } 59.11598 + }; 59.11599 + 59.11600 + module.exports = CanvasSurface; 59.11601 +}); 59.11602 + 59.11603 + 59.11604 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11605 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11606 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11607 + * 59.11608 + * Owner: mark@famo.us 59.11609 + * @license MPL 2.0 59.11610 + * @copyright Famous Industries, Inc. 2014 59.11611 + */ 59.11612 + 59.11613 +define('famous/surfaces/ContainerSurface',['require','exports','module','famous/core/Surface','famous/core/Context'],function(require, exports, module) { 59.11614 + var Surface = require('famous/core/Surface'); 59.11615 + var Context = require('famous/core/Context'); 59.11616 + 59.11617 + /** 59.11618 + * ContainerSurface is an object designed to contain surfaces and 59.11619 + * set properties to be applied to all of them at once. 59.11620 + * This extends the Surface class. 59.11621 + * A container surface will enforce these properties on the 59.11622 + * surfaces it contains: 59.11623 + * 59.11624 + * size (clips contained surfaces to its own width and height); 59.11625 + * 59.11626 + * origin; 59.11627 + * 59.11628 + * its own opacity and transform, which will be automatically 59.11629 + * applied to all Surfaces contained directly and indirectly. 59.11630 + * 59.11631 + * @class ContainerSurface 59.11632 + * @extends Surface 59.11633 + * @constructor 59.11634 + * @param {Array.Number} [options.size] [width, height] in pixels 59.11635 + * @param {Array.string} [options.classes] CSS classes to set on all inner content 59.11636 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 59.11637 + * @param {string} [options.content] inner (HTML) content of surface (should not be used) 59.11638 + */ 59.11639 + function ContainerSurface(options) { 59.11640 + Surface.call(this, options); 59.11641 + this._container = document.createElement('div'); 59.11642 + this._container.classList.add('famous-group'); 59.11643 + this._container.classList.add('famous-container-group'); 59.11644 + this._shouldRecalculateSize = false; 59.11645 + this.context = new Context(this._container); 59.11646 + this.setContent(this._container); 59.11647 + } 59.11648 + 59.11649 + ContainerSurface.prototype = Object.create(Surface.prototype); 59.11650 + ContainerSurface.prototype.constructor = ContainerSurface; 59.11651 + ContainerSurface.prototype.elementType = 'div'; 59.11652 + ContainerSurface.prototype.elementClass = 'famous-surface'; 59.11653 + 59.11654 + /** 59.11655 + * Add renderables to this object's render tree 59.11656 + * 59.11657 + * @method add 59.11658 + * 59.11659 + * @param {Object} obj renderable object 59.11660 + * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode 59.11661 + */ 59.11662 + ContainerSurface.prototype.add = function add() { 59.11663 + return this.context.add.apply(this.context, arguments); 59.11664 + }; 59.11665 + 59.11666 + /** 59.11667 + * Return spec for this surface. Note: Can result in a size recalculation. 59.11668 + * 59.11669 + * @private 59.11670 + * @method render 59.11671 + * 59.11672 + * @return {Object} render spec for this surface (spec id) 59.11673 + */ 59.11674 + ContainerSurface.prototype.render = function render() { 59.11675 + if (this._sizeDirty) this._shouldRecalculateSize = true; 59.11676 + return Surface.prototype.render.apply(this, arguments); 59.11677 + }; 59.11678 + 59.11679 + /** 59.11680 + * Place the document element this component manages into the document. 59.11681 + * 59.11682 + * @private 59.11683 + * @method deploy 59.11684 + * @param {Node} target document parent of this container 59.11685 + */ 59.11686 + ContainerSurface.prototype.deploy = function deploy() { 59.11687 + this._shouldRecalculateSize = true; 59.11688 + return Surface.prototype.deploy.apply(this, arguments); 59.11689 + }; 59.11690 + 59.11691 + /** 59.11692 + * Apply changes from this component to the corresponding document element. 59.11693 + * This includes changes to classes, styles, size, content, opacity, origin, 59.11694 + * and matrix transforms. 59.11695 + * 59.11696 + * @private 59.11697 + * @method commit 59.11698 + * @param {Context} context commit context 59.11699 + * @param {Transform} transform unused TODO 59.11700 + * @param {Number} opacity unused TODO 59.11701 + * @param {Array.Number} origin unused TODO 59.11702 + * @param {Array.Number} size unused TODO 59.11703 + * @return {undefined} TODO returns an undefined value 59.11704 + */ 59.11705 + ContainerSurface.prototype.commit = function commit(context, transform, opacity, origin, size) { 59.11706 + var previousSize = this._size ? [this._size[0], this._size[1]] : null; 59.11707 + var result = Surface.prototype.commit.apply(this, arguments); 59.11708 + if (this._shouldRecalculateSize || (previousSize && (this._size[0] !== previousSize[0] || this._size[1] !== previousSize[1]))) { 59.11709 + this.context.setSize(); 59.11710 + this._shouldRecalculateSize = false; 59.11711 + } 59.11712 + this.context.update(); 59.11713 + return result; 59.11714 + }; 59.11715 + 59.11716 + module.exports = ContainerSurface; 59.11717 +}); 59.11718 + 59.11719 +define('famous/surfaces/FormContainerSurface',['require','exports','module','./ContainerSurface'],function(require, exports, module) { 59.11720 + var ContainerSurface = require('./ContainerSurface'); 59.11721 + 59.11722 + function FormContainerSurface(options) { 59.11723 + if (options) this._method = options.method || ''; 59.11724 + ContainerSurface.apply(this, arguments); 59.11725 + } 59.11726 + 59.11727 + FormContainerSurface.prototype = Object.create(ContainerSurface.prototype); 59.11728 + FormContainerSurface.prototype.constructor = FormContainerSurface; 59.11729 + 59.11730 + FormContainerSurface.prototype.elementType = 'form'; 59.11731 + 59.11732 + FormContainerSurface.prototype.deploy = function deploy(target) { 59.11733 + if (this._method) target.method = this._method; 59.11734 + return ContainerSurface.prototype.deploy.apply(this, arguments); 59.11735 + }; 59.11736 + 59.11737 + module.exports = FormContainerSurface; 59.11738 +}); 59.11739 + 59.11740 + 59.11741 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11742 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11743 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11744 + * 59.11745 + * Owner: mark@famo.us 59.11746 + * @license MPL 2.0 59.11747 + * @copyright Famous Industries, Inc. 2014 59.11748 + */ 59.11749 + 59.11750 +define('famous/surfaces/ImageSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 59.11751 + var Surface = require('famous/core/Surface'); 59.11752 + 59.11753 + /** 59.11754 + * A surface containing image content. 59.11755 + * This extends the Surface class. 59.11756 + * 59.11757 + * @class ImageSurface 59.11758 + * 59.11759 + * @extends Surface 59.11760 + * @constructor 59.11761 + * @param {Object} [options] overrides of default options 59.11762 + */ 59.11763 + function ImageSurface(options) { 59.11764 + this._imageUrl = undefined; 59.11765 + Surface.apply(this, arguments); 59.11766 + } 59.11767 + 59.11768 + ImageSurface.prototype = Object.create(Surface.prototype); 59.11769 + ImageSurface.prototype.constructor = ImageSurface; 59.11770 + ImageSurface.prototype.elementType = 'img'; 59.11771 + ImageSurface.prototype.elementClass = 'famous-surface'; 59.11772 + 59.11773 + /** 59.11774 + * Set content URL. This will cause a re-rendering. 59.11775 + * @method setContent 59.11776 + * @param {string} imageUrl 59.11777 + */ 59.11778 + ImageSurface.prototype.setContent = function setContent(imageUrl) { 59.11779 + this._imageUrl = imageUrl; 59.11780 + this._contentDirty = true; 59.11781 + }; 59.11782 + 59.11783 + /** 59.11784 + * Place the document element that this component manages into the document. 59.11785 + * 59.11786 + * @private 59.11787 + * @method deploy 59.11788 + * @param {Node} target document parent of this container 59.11789 + */ 59.11790 + ImageSurface.prototype.deploy = function deploy(target) { 59.11791 + target.src = this._imageUrl || ''; 59.11792 + }; 59.11793 + 59.11794 + /** 59.11795 + * Remove this component and contained content from the document 59.11796 + * 59.11797 + * @private 59.11798 + * @method recall 59.11799 + * 59.11800 + * @param {Node} target node to which the component was deployed 59.11801 + */ 59.11802 + ImageSurface.prototype.recall = function recall(target) { 59.11803 + target.src = ''; 59.11804 + }; 59.11805 + 59.11806 + module.exports = ImageSurface; 59.11807 +}); 59.11808 + 59.11809 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11810 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11811 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11812 + * 59.11813 + * Owner: mark@famo.us 59.11814 + * @license MPL 2.0 59.11815 + * @copyright Famous Industries, Inc. 2014 59.11816 + */ 59.11817 + 59.11818 +define('famous/surfaces/InputSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 59.11819 + var Surface = require('famous/core/Surface'); 59.11820 + 59.11821 + /** 59.11822 + * A Famo.us surface in the form of an HTML input element. 59.11823 + * This extends the Surface class. 59.11824 + * 59.11825 + * @class InputSurface 59.11826 + * @extends Surface 59.11827 + * @constructor 59.11828 + * @param {Object} [options] overrides of default options 59.11829 + * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an <input> element 59.11830 + * @param {string} [options.type] specifies the type of element to display (e.g. 'datetime', 'text', 'button', etc.) 59.11831 + * @param {string} [options.value] value of text 59.11832 + */ 59.11833 + function InputSurface(options) { 59.11834 + this._placeholder = options.placeholder || ''; 59.11835 + this._value = options.value || ''; 59.11836 + this._type = options.type || 'text'; 59.11837 + this._name = options.name || ''; 59.11838 + 59.11839 + Surface.apply(this, arguments); 59.11840 + 59.11841 + this.on('click', this.focus.bind(this)); 59.11842 + window.addEventListener('click', function(event) { 59.11843 + if (event.target !== this._currTarget) this.blur(); 59.11844 + }.bind(this)); 59.11845 + } 59.11846 + InputSurface.prototype = Object.create(Surface.prototype); 59.11847 + InputSurface.prototype.constructor = InputSurface; 59.11848 + 59.11849 + InputSurface.prototype.elementType = 'input'; 59.11850 + InputSurface.prototype.elementClass = 'famous-surface'; 59.11851 + 59.11852 + /** 59.11853 + * Set placeholder text. Note: Triggers a repaint. 59.11854 + * 59.11855 + * @method setPlaceholder 59.11856 + * @param {string} str Value to set the placeholder to. 59.11857 + * @return {InputSurface} this, allowing method chaining. 59.11858 + */ 59.11859 + InputSurface.prototype.setPlaceholder = function setPlaceholder(str) { 59.11860 + this._placeholder = str; 59.11861 + this._contentDirty = true; 59.11862 + return this; 59.11863 + }; 59.11864 + 59.11865 + /** 59.11866 + * Focus on the current input, pulling up the keyboard on mobile. 59.11867 + * 59.11868 + * @method focus 59.11869 + * @return {InputSurface} this, allowing method chaining. 59.11870 + */ 59.11871 + InputSurface.prototype.focus = function focus() { 59.11872 + if (this._currTarget) this._currTarget.focus(); 59.11873 + return this; 59.11874 + }; 59.11875 + 59.11876 + /** 59.11877 + * Blur the current input, hiding the keyboard on mobile. 59.11878 + * 59.11879 + * @method blur 59.11880 + * @return {InputSurface} this, allowing method chaining. 59.11881 + */ 59.11882 + InputSurface.prototype.blur = function blur() { 59.11883 + if (this._currTarget) this._currTarget.blur(); 59.11884 + return this; 59.11885 + }; 59.11886 + 59.11887 + /** 59.11888 + * Set the placeholder conent. 59.11889 + * Note: Triggers a repaint next tick. 59.11890 + * 59.11891 + * @method setValue 59.11892 + * @param {string} str Value to set the main input value to. 59.11893 + * @return {InputSurface} this, allowing method chaining. 59.11894 + */ 59.11895 + InputSurface.prototype.setValue = function setValue(str) { 59.11896 + this._value = str; 59.11897 + this._contentDirty = true; 59.11898 + return this; 59.11899 + }; 59.11900 + 59.11901 + /** 59.11902 + * Set the type of element to display conent. 59.11903 + * Note: Triggers a repaint next tick. 59.11904 + * 59.11905 + * @method setType 59.11906 + * @param {string} str type of the input surface (e.g. 'button', 'text') 59.11907 + * @return {InputSurface} this, allowing method chaining. 59.11908 + */ 59.11909 + InputSurface.prototype.setType = function setType(str) { 59.11910 + this._type = str; 59.11911 + this._contentDirty = true; 59.11912 + return this; 59.11913 + }; 59.11914 + 59.11915 + /** 59.11916 + * Get the value of the inner content of the element (e.g. the entered text) 59.11917 + * 59.11918 + * @method getValue 59.11919 + * @return {string} value of element 59.11920 + */ 59.11921 + InputSurface.prototype.getValue = function getValue() { 59.11922 + if (this._currTarget) { 59.11923 + return this._currTarget.value; 59.11924 + } 59.11925 + else { 59.11926 + return this._value; 59.11927 + } 59.11928 + }; 59.11929 + 59.11930 + /** 59.11931 + * Set the name attribute of the element. 59.11932 + * Note: Triggers a repaint next tick. 59.11933 + * 59.11934 + * @method setName 59.11935 + * @param {string} str element name 59.11936 + * @return {InputSurface} this, allowing method chaining. 59.11937 + */ 59.11938 + InputSurface.prototype.setName = function setName(str) { 59.11939 + this._name = str; 59.11940 + this._contentDirty = true; 59.11941 + return this; 59.11942 + }; 59.11943 + 59.11944 + /** 59.11945 + * Get the name attribute of the element. 59.11946 + * 59.11947 + * @method getName 59.11948 + * @return {string} name of element 59.11949 + */ 59.11950 + InputSurface.prototype.getName = function getName() { 59.11951 + return this._name; 59.11952 + }; 59.11953 + 59.11954 + /** 59.11955 + * Place the document element this component manages into the document. 59.11956 + * 59.11957 + * @private 59.11958 + * @method deploy 59.11959 + * @param {Node} target document parent of this container 59.11960 + */ 59.11961 + InputSurface.prototype.deploy = function deploy(target) { 59.11962 + if (this._placeholder !== '') target.placeholder = this._placeholder; 59.11963 + target.value = this._value; 59.11964 + target.type = this._type; 59.11965 + target.name = this._name; 59.11966 + }; 59.11967 + 59.11968 + module.exports = InputSurface; 59.11969 +}); 59.11970 + 59.11971 +define('famous/surfaces/SubmitInputSurface',['require','exports','module','./InputSurface'],function(require, exports, module) { 59.11972 + var InputSurface = require('./InputSurface'); 59.11973 + 59.11974 + function SubmitInputSurface(options) { 59.11975 + InputSurface.apply(this, arguments); 59.11976 + this._type = 'submit'; 59.11977 + if (options && options.onClick) this.setOnClick(options.onClick); 59.11978 + } 59.11979 + 59.11980 + SubmitInputSurface.prototype = Object.create(InputSurface.prototype); 59.11981 + SubmitInputSurface.prototype.constructor = SubmitInputSurface; 59.11982 + 59.11983 + SubmitInputSurface.prototype.setOnClick = function(onClick) { 59.11984 + this.onClick = onClick; 59.11985 + }; 59.11986 + 59.11987 + SubmitInputSurface.prototype.deploy = function deploy(target) { 59.11988 + if (this.onclick) target.onClick = this.onClick; 59.11989 + InputSurface.prototype.deploy.apply(this, arguments); 59.11990 + }; 59.11991 + 59.11992 + module.exports = SubmitInputSurface; 59.11993 +}); 59.11994 + 59.11995 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.11996 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.11997 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.11998 + * 59.11999 + * Owner: mark@famo.us 59.12000 + * @license MPL 2.0 59.12001 + * @copyright Famous Industries, Inc. 2014 59.12002 + */ 59.12003 + 59.12004 +define('famous/surfaces/TextareaSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 59.12005 + var Surface = require('famous/core/Surface'); 59.12006 + 59.12007 + /** 59.12008 + * A Famo.us surface in the form of an HTML textarea element. 59.12009 + * This extends the Surface class. 59.12010 + * 59.12011 + * @class TextareaSurface 59.12012 + * @extends Surface 59.12013 + * @constructor 59.12014 + * @param {Object} [options] overrides of default options 59.12015 + * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an textarea element 59.12016 + * @param {string} [options.value] value of text 59.12017 + * @param {string} [options.name] specifies the name of textarea 59.12018 + * @param {string} [options.wrap] specify 'hard' or 'soft' wrap for textarea 59.12019 + * @param {number} [options.cols] number of columns in textarea 59.12020 + * @param {number} [options.rows] number of rows in textarea 59.12021 + */ 59.12022 + function TextareaSurface(options) { 59.12023 + this._placeholder = options.placeholder || ''; 59.12024 + this._value = options.value || ''; 59.12025 + this._name = options.name || ''; 59.12026 + this._wrap = options.wrap || ''; 59.12027 + this._cols = options.cols || ''; 59.12028 + this._rows = options.rows || ''; 59.12029 + 59.12030 + Surface.apply(this, arguments); 59.12031 + this.on('click', this.focus.bind(this)); 59.12032 + } 59.12033 + TextareaSurface.prototype = Object.create(Surface.prototype); 59.12034 + TextareaSurface.prototype.constructor = TextareaSurface; 59.12035 + 59.12036 + TextareaSurface.prototype.elementType = 'textarea'; 59.12037 + TextareaSurface.prototype.elementClass = 'famous-surface'; 59.12038 + 59.12039 + /** 59.12040 + * Set placeholder text. Note: Triggers a repaint. 59.12041 + * 59.12042 + * @method setPlaceholder 59.12043 + * @param {string} str Value to set the placeholder to. 59.12044 + * @return {TextareaSurface} this, allowing method chaining. 59.12045 + */ 59.12046 + TextareaSurface.prototype.setPlaceholder = function setPlaceholder(str) { 59.12047 + this._placeholder = str; 59.12048 + this._contentDirty = true; 59.12049 + return this; 59.12050 + }; 59.12051 + 59.12052 + /** 59.12053 + * Focus on the current input, pulling up the keyboard on mobile. 59.12054 + * 59.12055 + * @method focus 59.12056 + * @return {TextareaSurface} this, allowing method chaining. 59.12057 + */ 59.12058 + TextareaSurface.prototype.focus = function focus() { 59.12059 + if (this._currTarget) this._currTarget.focus(); 59.12060 + return this; 59.12061 + }; 59.12062 + 59.12063 + /** 59.12064 + * Blur the current input, hiding the keyboard on mobile. 59.12065 + * 59.12066 + * @method focus 59.12067 + * @return {TextareaSurface} this, allowing method chaining. 59.12068 + */ 59.12069 + TextareaSurface.prototype.blur = function blur() { 59.12070 + if (this._currTarget) this._currTarget.blur(); 59.12071 + return this; 59.12072 + }; 59.12073 + 59.12074 + /** 59.12075 + * Set the value of textarea. 59.12076 + * Note: Triggers a repaint next tick. 59.12077 + * 59.12078 + * @method setValue 59.12079 + * @param {string} str Value to set the main textarea value to. 59.12080 + * @return {TextareaSurface} this, allowing method chaining. 59.12081 + */ 59.12082 + TextareaSurface.prototype.setValue = function setValue(str) { 59.12083 + this._value = str; 59.12084 + this._contentDirty = true; 59.12085 + return this; 59.12086 + }; 59.12087 + 59.12088 + /** 59.12089 + * Get the value of the inner content of the textarea (e.g. the entered text) 59.12090 + * 59.12091 + * @method getValue 59.12092 + * @return {string} value of element 59.12093 + */ 59.12094 + TextareaSurface.prototype.getValue = function getValue() { 59.12095 + if (this._currTarget) { 59.12096 + return this._currTarget.value; 59.12097 + } 59.12098 + else { 59.12099 + return this._value; 59.12100 + } 59.12101 + }; 59.12102 + 59.12103 + /** 59.12104 + * Set the name attribute of the element. 59.12105 + * Note: Triggers a repaint next tick. 59.12106 + * 59.12107 + * @method setName 59.12108 + * @param {string} str element name 59.12109 + * @return {TextareaSurface} this, allowing method chaining. 59.12110 + */ 59.12111 + TextareaSurface.prototype.setName = function setName(str) { 59.12112 + this._name = str; 59.12113 + this._contentDirty = true; 59.12114 + return this; 59.12115 + }; 59.12116 + 59.12117 + /** 59.12118 + * Get the name attribute of the element. 59.12119 + * 59.12120 + * @method getName 59.12121 + * @return {string} name of element 59.12122 + */ 59.12123 + TextareaSurface.prototype.getName = function getName() { 59.12124 + return this._name; 59.12125 + }; 59.12126 + 59.12127 + /** 59.12128 + * Set the wrap of textarea. 59.12129 + * Note: Triggers a repaint next tick. 59.12130 + * 59.12131 + * @method setWrap 59.12132 + * @param {string} str wrap of the textarea surface (e.g. 'soft', 'hard') 59.12133 + * @return {TextareaSurface} this, allowing method chaining. 59.12134 + */ 59.12135 + TextareaSurface.prototype.setWrap = function setWrap(str) { 59.12136 + this._wrap = str; 59.12137 + this._contentDirty = true; 59.12138 + return this; 59.12139 + }; 59.12140 + 59.12141 + /** 59.12142 + * Set the number of columns visible in the textarea. 59.12143 + * Note: Overridden by surface size; set width to true. (eg. size: [true, *]) 59.12144 + * Triggers a repaint next tick. 59.12145 + * 59.12146 + * @method setColumns 59.12147 + * @param {number} num columns in textarea surface 59.12148 + * @return {TextareaSurface} this, allowing method chaining. 59.12149 + */ 59.12150 + TextareaSurface.prototype.setColumns = function setColumns(num) { 59.12151 + this._cols = num; 59.12152 + this._contentDirty = true; 59.12153 + return this; 59.12154 + }; 59.12155 + 59.12156 + /** 59.12157 + * Set the number of rows visible in the textarea. 59.12158 + * Note: Overridden by surface size; set height to true. (eg. size: [*, true]) 59.12159 + * Triggers a repaint next tick. 59.12160 + * 59.12161 + * @method setRows 59.12162 + * @param {number} num rows in textarea surface 59.12163 + * @return {TextareaSurface} this, allowing method chaining. 59.12164 + */ 59.12165 + TextareaSurface.prototype.setRows = function setRows(num) { 59.12166 + this._rows = num; 59.12167 + this._contentDirty = true; 59.12168 + return this; 59.12169 + }; 59.12170 + 59.12171 + /** 59.12172 + * Place the document element this component manages into the document. 59.12173 + * 59.12174 + * @private 59.12175 + * @method deploy 59.12176 + * @param {Node} target document parent of this container 59.12177 + */ 59.12178 + TextareaSurface.prototype.deploy = function deploy(target) { 59.12179 + if (this._placeholder !== '') target.placeholder = this._placeholder; 59.12180 + if (this._value !== '') target.value = this._value; 59.12181 + if (this._name !== '') target.name = this._name; 59.12182 + if (this._wrap !== '') target.wrap = this._wrap; 59.12183 + if (this._cols !== '') target.cols = this._cols; 59.12184 + if (this._rows !== '') target.rows = this._rows; 59.12185 + }; 59.12186 + 59.12187 + module.exports = TextareaSurface; 59.12188 +}); 59.12189 + 59.12190 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12191 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12192 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12193 + * 59.12194 + * Owner: mark@famo.us 59.12195 + * @license MPL 2.0 59.12196 + * @copyright Famous Industries, Inc. 2014 59.12197 + */ 59.12198 + 59.12199 +define('famous/surfaces/VideoSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) { 59.12200 + var Surface = require('famous/core/Surface'); 59.12201 + 59.12202 + /** 59.12203 + * Creates a famous surface containing video content. Currently adding 59.12204 + * controls and manipulating the video are not supported through the 59.12205 + * surface interface, but can be accomplished via standard JavaScript 59.12206 + * manipulation of the video DOM element. 59.12207 + * This extends the Surface class. 59.12208 + * 59.12209 + * @class VideoSurface 59.12210 + * @extends Surface 59.12211 + * @constructor 59.12212 + * @param {Object} [options] default option overrides 59.12213 + * @param {Array.Number} [options.size] [width, height] in pixels 59.12214 + * @param {Array.string} [options.classes] CSS classes to set on inner content 59.12215 + * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div 59.12216 + * @param {string} [options.content] inner (HTML) content of surface 59.12217 + * @param {boolean} [options.autoplay] autoplay 59.12218 + */ 59.12219 + function VideoSurface(options) { 59.12220 + this._videoUrl = undefined; 59.12221 + this.options = Object.create(VideoSurface.DEFAULT_OPTIONS); 59.12222 + if (options) this.setOptions(options); 59.12223 + 59.12224 + Surface.apply(this, arguments); 59.12225 + } 59.12226 + VideoSurface.prototype = Object.create(Surface.prototype); 59.12227 + VideoSurface.prototype.constructor = VideoSurface; 59.12228 + 59.12229 + VideoSurface.DEFAULT_OPTIONS = { 59.12230 + autoplay: false 59.12231 + }; 59.12232 + 59.12233 + VideoSurface.prototype.elementType = 'video'; 59.12234 + VideoSurface.prototype.elementClass = 'famous-surface'; 59.12235 + 59.12236 + /** 59.12237 + * Set internal options, overriding any default options 59.12238 + * 59.12239 + * @method setOptions 59.12240 + * 59.12241 + * @param {Object} [options] overrides of default options 59.12242 + * @param {Boolean} [options.autoplay] HTML autoplay 59.12243 + */ 59.12244 + VideoSurface.prototype.setOptions = function setOptions(options) { 59.12245 + for (var key in VideoSurface.DEFAULT_OPTIONS) { 59.12246 + if (options[key] !== undefined) this.options[key] = options[key]; 59.12247 + } 59.12248 + }; 59.12249 + 59.12250 + /** 59.12251 + * Set url of the video. 59.12252 + * 59.12253 + * @method setContent 59.12254 + * @param {string} videoUrl URL 59.12255 + */ 59.12256 + VideoSurface.prototype.setContent = function setContent(videoUrl) { 59.12257 + this._videoUrl = videoUrl; 59.12258 + this._contentDirty = true; 59.12259 + }; 59.12260 + 59.12261 + /** 59.12262 + * Place the document element this component manages into the document. 59.12263 + * Note: In the case of VideoSurface, simply changes the options on the target. 59.12264 + * 59.12265 + * @private 59.12266 + * @method deploy 59.12267 + * @param {Node} target document parent of this container 59.12268 + */ 59.12269 + VideoSurface.prototype.deploy = function deploy(target) { 59.12270 + target.src = this._videoUrl; 59.12271 + target.autoplay = this.options.autoplay; 59.12272 + }; 59.12273 + 59.12274 + /** 59.12275 + * Remove this component and contained content from the document. 59.12276 + * Note: This doesn't actually remove the <video> element from the 59.12277 + * document. 59.12278 + * @private 59.12279 + * @method recall 59.12280 + * 59.12281 + * @param {Node} target node to which the component was deployed 59.12282 + */ 59.12283 + VideoSurface.prototype.recall = function recall(target) { 59.12284 + target.src = ''; 59.12285 + }; 59.12286 + 59.12287 + module.exports = VideoSurface; 59.12288 +}); 59.12289 + 59.12290 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12291 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12292 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12293 + * 59.12294 + * Owner: mark@famo.us 59.12295 + * @license MPL 2.0 59.12296 + * @copyright Famous Industries, Inc. 2014 59.12297 + */ 59.12298 + 59.12299 +define('famous/utilities/KeyCodes',['require','exports','module'],function(require, exports, module) { 59.12300 + 59.12301 + /** 59.12302 + * Collection to map keyboard codes in plain english 59.12303 + * 59.12304 + * @class KeyCodes 59.12305 + * @static 59.12306 + */ 59.12307 + var KeyCodes = { 59.12308 + 0 : 48, 59.12309 + 1 : 49, 59.12310 + 2 : 50, 59.12311 + 3 : 51, 59.12312 + 4 : 52, 59.12313 + 5 : 53, 59.12314 + 6 : 54, 59.12315 + 7 : 55, 59.12316 + 8 : 56, 59.12317 + 9 : 57, 59.12318 + a : 97, 59.12319 + b : 98, 59.12320 + c : 99, 59.12321 + d : 100, 59.12322 + e : 101, 59.12323 + f : 102, 59.12324 + g : 103, 59.12325 + h : 104, 59.12326 + i : 105, 59.12327 + j : 106, 59.12328 + k : 107, 59.12329 + l : 108, 59.12330 + m : 109, 59.12331 + n : 110, 59.12332 + o : 111, 59.12333 + p : 112, 59.12334 + q : 113, 59.12335 + r : 114, 59.12336 + s : 115, 59.12337 + t : 116, 59.12338 + u : 117, 59.12339 + v : 118, 59.12340 + w : 119, 59.12341 + x : 120, 59.12342 + y : 121, 59.12343 + z : 122, 59.12344 + A : 65, 59.12345 + B : 66, 59.12346 + C : 67, 59.12347 + D : 68, 59.12348 + E : 69, 59.12349 + F : 70, 59.12350 + G : 71, 59.12351 + H : 72, 59.12352 + I : 73, 59.12353 + J : 74, 59.12354 + K : 75, 59.12355 + L : 76, 59.12356 + M : 77, 59.12357 + N : 78, 59.12358 + O : 79, 59.12359 + P : 80, 59.12360 + Q : 81, 59.12361 + R : 82, 59.12362 + S : 83, 59.12363 + T : 84, 59.12364 + U : 85, 59.12365 + V : 86, 59.12366 + W : 87, 59.12367 + X : 88, 59.12368 + Y : 89, 59.12369 + Z : 90, 59.12370 + ENTER : 13, 59.12371 + LEFT_ARROW: 37, 59.12372 + RIGHT_ARROW: 39, 59.12373 + UP_ARROW: 38, 59.12374 + DOWN_ARROW: 40, 59.12375 + SPACE: 32, 59.12376 + SHIFT: 16, 59.12377 + TAB: 9 59.12378 + }; 59.12379 + 59.12380 + module.exports = KeyCodes; 59.12381 +}); 59.12382 + 59.12383 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12384 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12385 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12386 + * 59.12387 + * Owner: mark@famo.us 59.12388 + * @license MPL 2.0 59.12389 + * @copyright Famous Industries, Inc. 2014 59.12390 + */ 59.12391 +// TODO fix func-style 59.12392 +/*eslint func-style: [0, "declaration"] */ 59.12393 + 59.12394 +define('famous/utilities/Timer',['require','exports','module','famous/core/Engine'],function(require, exports, module) { 59.12395 + /** 59.12396 + * An internal library to reproduce javascript time-based scheduling. 59.12397 + * Using standard javascript setTimeout methods can have a negative performance impact 59.12398 + * when combined with the Famous rendering process, so instead require Timer and call 59.12399 + * Timer.setTimeout, Timer.setInterval, etc. 59.12400 + * 59.12401 + * @class Timer 59.12402 + * @constructor 59.12403 + */ 59.12404 + var FamousEngine = require('famous/core/Engine'); 59.12405 + 59.12406 + var _event = 'prerender'; 59.12407 + 59.12408 + var getTime = (window.performance) ? 59.12409 + function() { 59.12410 + return window.performance.now(); 59.12411 + } 59.12412 + : function() { 59.12413 + return Date.now(); 59.12414 + }; 59.12415 + 59.12416 + /** 59.12417 + * Add a function to be run on every prerender 59.12418 + * 59.12419 + * @method addTimerFunction 59.12420 + * 59.12421 + * @param {function} fn function to be run every prerender 59.12422 + * 59.12423 + * @return {function} function passed in as parameter 59.12424 + */ 59.12425 + function addTimerFunction(fn) { 59.12426 + FamousEngine.on(_event, fn); 59.12427 + return fn; 59.12428 + } 59.12429 + 59.12430 + /** 59.12431 + * Wraps a function to be invoked after a certain amount of time. 59.12432 + * After a set duration has passed, it executes the function and 59.12433 + * removes it as a listener to 'prerender'. 59.12434 + * 59.12435 + * @method setTimeout 59.12436 + * 59.12437 + * @param {function} fn function to be run after a specified duration 59.12438 + * @param {number} duration milliseconds from now to execute the function 59.12439 + * 59.12440 + * @return {function} function passed in as parameter 59.12441 + */ 59.12442 + function setTimeout(fn, duration) { 59.12443 + var t = getTime(); 59.12444 + var callback = function() { 59.12445 + var t2 = getTime(); 59.12446 + if (t2 - t >= duration) { 59.12447 + fn.apply(this, arguments); 59.12448 + FamousEngine.removeListener(_event, callback); 59.12449 + } 59.12450 + }; 59.12451 + return addTimerFunction(callback); 59.12452 + } 59.12453 + 59.12454 + /** 59.12455 + * Wraps a function to be invoked after a certain amount of time. 59.12456 + * After a set duration has passed, it executes the function and 59.12457 + * resets the execution time. 59.12458 + * 59.12459 + * @method setInterval 59.12460 + * 59.12461 + * @param {function} fn function to be run after a specified duration 59.12462 + * @param {number} duration interval to execute function in milliseconds 59.12463 + * 59.12464 + * @return {function} function passed in as parameter 59.12465 + */ 59.12466 + function setInterval(fn, duration) { 59.12467 + var t = getTime(); 59.12468 + var callback = function() { 59.12469 + var t2 = getTime(); 59.12470 + if (t2 - t >= duration) { 59.12471 + fn.apply(this, arguments); 59.12472 + t = getTime(); 59.12473 + } 59.12474 + }; 59.12475 + return addTimerFunction(callback); 59.12476 + } 59.12477 + 59.12478 + /** 59.12479 + * Wraps a function to be invoked after a certain amount of prerender ticks. 59.12480 + * Similar use to setTimeout but tied to the engine's run speed. 59.12481 + * 59.12482 + * @method after 59.12483 + * 59.12484 + * @param {function} fn function to be run after a specified amount of ticks 59.12485 + * @param {number} numTicks number of prerender frames to wait 59.12486 + * 59.12487 + * @return {function} function passed in as parameter 59.12488 + */ 59.12489 + function after(fn, numTicks) { 59.12490 + if (numTicks === undefined) return undefined; 59.12491 + var callback = function() { 59.12492 + numTicks--; 59.12493 + if (numTicks <= 0) { //in case numTicks is fraction or negative 59.12494 + fn.apply(this, arguments); 59.12495 + clear(callback); 59.12496 + } 59.12497 + }; 59.12498 + return addTimerFunction(callback); 59.12499 + } 59.12500 + 59.12501 + /** 59.12502 + * Wraps a function to be continually invoked after a certain amount of prerender ticks. 59.12503 + * Similar use to setInterval but tied to the engine's run speed. 59.12504 + * 59.12505 + * @method every 59.12506 + * 59.12507 + * @param {function} fn function to be run after a specified amount of ticks 59.12508 + * @param {number} numTicks number of prerender frames to wait 59.12509 + * 59.12510 + * @return {function} function passed in as parameter 59.12511 + */ 59.12512 + function every(fn, numTicks) { 59.12513 + numTicks = numTicks || 1; 59.12514 + var initial = numTicks; 59.12515 + var callback = function() { 59.12516 + numTicks--; 59.12517 + if (numTicks <= 0) { //in case numTicks is fraction or negative 59.12518 + fn.apply(this, arguments); 59.12519 + numTicks = initial; 59.12520 + } 59.12521 + }; 59.12522 + return addTimerFunction(callback); 59.12523 + } 59.12524 + 59.12525 + /** 59.12526 + * Remove a function that gets called every prerender 59.12527 + * 59.12528 + * @method clear 59.12529 + * 59.12530 + * @param {function} fn event linstener 59.12531 + */ 59.12532 + function clear(fn) { 59.12533 + FamousEngine.removeListener(_event, fn); 59.12534 + } 59.12535 + 59.12536 + /** 59.12537 + * Executes a function after a certain amount of time. Makes sure 59.12538 + * the function is not run multiple times. 59.12539 + * 59.12540 + * @method debounce 59.12541 + * 59.12542 + * @param {function} func function to run after certain amount of time 59.12543 + * @param {number} wait amount of time 59.12544 + * 59.12545 + * @return {function} function that is not able to debounce 59.12546 + */ 59.12547 + function debounce(func, wait) { 59.12548 + var timeout; 59.12549 + var ctx; 59.12550 + var timestamp; 59.12551 + var result; 59.12552 + var args; 59.12553 + return function() { 59.12554 + ctx = this; 59.12555 + args = arguments; 59.12556 + timestamp = getTime(); 59.12557 + 59.12558 + var fn = function() { 59.12559 + var last = getTime - timestamp; 59.12560 + 59.12561 + if (last < wait) { 59.12562 + timeout = setTimeout(fn, wait - last); 59.12563 + } else { 59.12564 + timeout = null; 59.12565 + result = func.apply(ctx, args); 59.12566 + } 59.12567 + }; 59.12568 + 59.12569 + clear(timeout); 59.12570 + timeout = setTimeout(fn, wait); 59.12571 + 59.12572 + return result; 59.12573 + }; 59.12574 + } 59.12575 + 59.12576 + module.exports = { 59.12577 + setTimeout : setTimeout, 59.12578 + setInterval : setInterval, 59.12579 + debounce : debounce, 59.12580 + after : after, 59.12581 + every : every, 59.12582 + clear : clear 59.12583 + }; 59.12584 + 59.12585 +}); 59.12586 + 59.12587 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12588 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12589 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12590 + * 59.12591 + * Owner: mike@famo.us 59.12592 + * @license MPL 2.0 59.12593 + * @copyright Famous Industries, Inc. 2014 59.12594 + */ 59.12595 + 59.12596 +define('famous/views/ContextualView',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/EventHandler','famous/core/OptionsManager'],function(require, exports, module) { 59.12597 + var Entity = require('famous/core/Entity'); 59.12598 + var Transform = require('famous/core/Transform'); 59.12599 + var EventHandler = require('famous/core/EventHandler'); 59.12600 + var OptionsManager = require('famous/core/OptionsManager'); 59.12601 + 59.12602 + /** 59.12603 + * ContextualView is an interface for creating views that need to 59.12604 + * be aware of their parent's transform, size, and/or origin. 59.12605 + * Consists of a OptionsManager paired with an input EventHandler 59.12606 + * and an output EventHandler. Meant to be extended by the developer. 59.12607 + * @class ContextualView 59.12608 + * @constructor 59.12609 + * @param {Options} [options] An object of configurable options. 59.12610 + */ 59.12611 + function ContextualView(options) { 59.12612 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS || ContextualView.DEFAULT_OPTIONS); 59.12613 + this._optionsManager = new OptionsManager(this.options); 59.12614 + if (options) this.setOptions(options); 59.12615 + 59.12616 + this._eventInput = new EventHandler(); 59.12617 + this._eventOutput = new EventHandler(); 59.12618 + EventHandler.setInputHandler(this, this._eventInput); 59.12619 + EventHandler.setOutputHandler(this, this._eventOutput); 59.12620 + 59.12621 + this._id = Entity.register(this); 59.12622 + } 59.12623 + 59.12624 + ContextualView.DEFAULT_OPTIONS = {}; 59.12625 + 59.12626 + /** 59.12627 + * Patches the ContextualLayout instance's options with the passed-in ones. 59.12628 + * 59.12629 + * @method setOptions 59.12630 + * @param {Options} options An object of configurable options for the ContextualLayout instance. 59.12631 + */ 59.12632 + ContextualView.prototype.setOptions = function setOptions(options) { 59.12633 + return this._optionsManager.setOptions(options); 59.12634 + }; 59.12635 + 59.12636 + /** 59.12637 + * Returns ContextualLayout instance's options. 59.12638 + * 59.12639 + * @method setOptions 59.12640 + * @return {Options} options The instance's object of configurable options. 59.12641 + */ 59.12642 + ContextualView.prototype.getOptions = function getOptions() { 59.12643 + return this._optionsManager.getOptions(); 59.12644 + }; 59.12645 + 59.12646 + /** 59.12647 + * Return the registers Entity id for the ContextualView. 59.12648 + * 59.12649 + * @private 59.12650 + * @method render 59.12651 + * @return {Number} Registered Entity id 59.12652 + */ 59.12653 + ContextualView.prototype.render = function render() { 59.12654 + return this._id; 59.12655 + }; 59.12656 + 59.12657 + /** 59.12658 + * Apply changes from this component to the corresponding document element. 59.12659 + * This includes changes to classes, styles, size, content, opacity, origin, 59.12660 + * and matrix transforms. 59.12661 + * 59.12662 + * @private 59.12663 + * @method commit 59.12664 + * @param {Context} context commit context 59.12665 + */ 59.12666 + ContextualView.prototype.commit = function commit(context) {}; 59.12667 + 59.12668 + module.exports = ContextualView; 59.12669 +}); 59.12670 + 59.12671 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12672 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12673 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12674 + * 59.12675 + * Owner: felix@famo.us 59.12676 + * @license MPL 2.0 59.12677 + * @copyright Famous Industries, Inc. 2014 59.12678 + */ 59.12679 + 59.12680 +define('famous/views/SequentialLayout',['require','exports','module','famous/core/OptionsManager','famous/core/Transform','famous/core/ViewSequence','famous/utilities/Utility'],function(require, exports, module) { 59.12681 + var OptionsManager = require('famous/core/OptionsManager'); 59.12682 + var Transform = require('famous/core/Transform'); 59.12683 + var ViewSequence = require('famous/core/ViewSequence'); 59.12684 + var Utility = require('famous/utilities/Utility'); 59.12685 + 59.12686 + /** 59.12687 + * SequentialLayout will lay out a collection of renderables sequentially in the specified direction. 59.12688 + * @class SequentialLayout 59.12689 + * @constructor 59.12690 + * @param {Options} [options] An object of configurable options. 59.12691 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 59.12692 + * module, this option will lay out the SequentialLayout instance's renderables either horizontally 59.12693 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 59.12694 + * to just use integers as well. 59.12695 + * @param {Array.Number} [options.defaultItemSize=[50, 50]] In the case where a renderable layed out 59.12696 + * under SequentialLayout's control doesen't have a getSize method, SequentialLayout will assign it 59.12697 + * this default size. (Commonly a case with Views). 59.12698 + */ 59.12699 + function SequentialLayout(options) { 59.12700 + this._items = null; 59.12701 + this._size = null; 59.12702 + this._outputFunction = SequentialLayout.DEFAULT_OUTPUT_FUNCTION; 59.12703 + 59.12704 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.12705 + this.optionsManager = new OptionsManager(this.options); 59.12706 + 59.12707 + this._itemsCache = []; 59.12708 + this._outputCache = { 59.12709 + size: null, 59.12710 + target: this._itemsCache 59.12711 + }; 59.12712 + 59.12713 + if (options) this.setOptions(options); 59.12714 + } 59.12715 + 59.12716 + SequentialLayout.DEFAULT_OPTIONS = { 59.12717 + direction: Utility.Direction.Y, 59.12718 + itemSpacing: 0, 59.12719 + defaultItemSize: [50, 50] 59.12720 + }; 59.12721 + 59.12722 + SequentialLayout.DEFAULT_OUTPUT_FUNCTION = function DEFAULT_OUTPUT_FUNCTION(input, offset, index) { 59.12723 + var transform = (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset); 59.12724 + return { 59.12725 + transform: transform, 59.12726 + target: input.render() 59.12727 + }; 59.12728 + }; 59.12729 + 59.12730 + /** 59.12731 + * Returns the width and the height of the SequentialLayout instance. 59.12732 + * 59.12733 + * @method getSize 59.12734 + * @return {Array} A two value array of the SequentialLayout instance's current width and height (in that order). 59.12735 + */ 59.12736 + SequentialLayout.prototype.getSize = function getSize() { 59.12737 + if (!this._size) this.render(); // hack size in 59.12738 + return this._size; 59.12739 + }; 59.12740 + 59.12741 + /** 59.12742 + * Sets the collection of renderables under the SequentialLayout instance's control. 59.12743 + * 59.12744 + * @method sequenceFrom 59.12745 + * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence. 59.12746 + * @chainable 59.12747 + */ 59.12748 + SequentialLayout.prototype.sequenceFrom = function sequenceFrom(items) { 59.12749 + if (items instanceof Array) items = new ViewSequence(items); 59.12750 + this._items = items; 59.12751 + return this; 59.12752 + }; 59.12753 + 59.12754 + /** 59.12755 + * Patches the SequentialLayout instance's options with the passed-in ones. 59.12756 + * 59.12757 + * @method setOptions 59.12758 + * @param {Options} options An object of configurable options for the SequentialLayout instance. 59.12759 + * @chainable 59.12760 + */ 59.12761 + SequentialLayout.prototype.setOptions = function setOptions(options) { 59.12762 + this.optionsManager.setOptions.apply(this.optionsManager, arguments); 59.12763 + return this; 59.12764 + }; 59.12765 + 59.12766 + /** 59.12767 + * setOutputFunction is used to apply a user-defined output transform on each processed renderable. 59.12768 + * For a good example, check out SequentialLayout's own DEFAULT_OUTPUT_FUNCTION in the code. 59.12769 + * 59.12770 + * @method setOutputFunction 59.12771 + * @param {Function} outputFunction An output processer for each renderable in the SequentialLayout 59.12772 + * instance. 59.12773 + * @chainable 59.12774 + */ 59.12775 + SequentialLayout.prototype.setOutputFunction = function setOutputFunction(outputFunction) { 59.12776 + this._outputFunction = outputFunction; 59.12777 + return this; 59.12778 + }; 59.12779 + 59.12780 + /** 59.12781 + * Generate a render spec from the contents of this component. 59.12782 + * 59.12783 + * @private 59.12784 + * @method render 59.12785 + * @return {number} Render spec for this component 59.12786 + */ 59.12787 + SequentialLayout.prototype.render = function render() { 59.12788 + var length = 0; 59.12789 + var girth = 0; 59.12790 + 59.12791 + var lengthDim = (this.options.direction === Utility.Direction.X) ? 0 : 1; 59.12792 + var girthDim = (this.options.direction === Utility.Direction.X) ? 1 : 0; 59.12793 + 59.12794 + var currentNode = this._items; 59.12795 + var result = this._itemsCache; 59.12796 + var i = 0; 59.12797 + while (currentNode) { 59.12798 + var item = currentNode.get(); 59.12799 + if (!item) break; 59.12800 + 59.12801 + var itemSize; 59.12802 + if (item && item.getSize) itemSize = item.getSize(); 59.12803 + if (!itemSize) itemSize = this.options.defaultItemSize; 59.12804 + if (itemSize[girthDim] !== true) girth = Math.max(girth, itemSize[girthDim]); 59.12805 + 59.12806 + var output = this._outputFunction.call(this, item, length, i); 59.12807 + result[i] = output; 59.12808 + 59.12809 + if (itemSize[lengthDim] && (itemSize[lengthDim] !== true)) length += itemSize[lengthDim] + this.options.itemSpacing; 59.12810 + currentNode = currentNode.getNext(); 59.12811 + i++; 59.12812 + } 59.12813 + this._itemsCache.splice(i); 59.12814 + 59.12815 + if (!girth) girth = undefined; 59.12816 + 59.12817 + if (!this._size) this._size = [0, 0]; 59.12818 + this._size[lengthDim] = length - this.options.itemSpacing; // account for last itemSpacing 59.12819 + this._size[girthDim] = girth; 59.12820 + 59.12821 + this._outputCache.size = this.getSize(); 59.12822 + return this._outputCache; 59.12823 + }; 59.12824 + 59.12825 + module.exports = SequentialLayout; 59.12826 +}); 59.12827 + 59.12828 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12829 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12830 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12831 + * 59.12832 + * Owner: felix@famo.us 59.12833 + * @license MPL 2.0 59.12834 + * @copyright Famous Industries, Inc. 2014 59.12835 + */ 59.12836 + 59.12837 +define('famous/views/Deck',['require','exports','module','famous/core/Transform','famous/core/OptionsManager','famous/transitions/Transitionable','famous/utilities/Utility','./SequentialLayout'],function(require, exports, module) { 59.12838 + var Transform = require('famous/core/Transform'); 59.12839 + var OptionsManager = require('famous/core/OptionsManager'); 59.12840 + var Transitionable = require('famous/transitions/Transitionable'); 59.12841 + var Utility = require('famous/utilities/Utility'); 59.12842 + var SequentialLayout = require('./SequentialLayout'); 59.12843 + 59.12844 + /** 59.12845 + * A Sequential Layout that can be opened and closed with animations. 59.12846 + * 59.12847 + * Takes the same options as SequentialLayout 59.12848 + * as well as options for the open/close transition 59.12849 + * and the rotation you want your Deck instance to layout in. 59.12850 + * 59.12851 + * @class Deck 59.12852 + * @constructor 59.12853 + * @extends SequentialLayout 59.12854 + * 59.12855 + * @param {Options} [options] An object of configurable options 59.12856 + * @param {Transition} [options.transition={duration: 500, curve: 'easeOutBounce'} 59.12857 + * The transition that executes upon opening or closing your deck instance. 59.12858 + * @param {Number} [stackRotation=0] The amount of rotation applied to the propogation 59.12859 + * of the Deck instance's stack of renderables. 59.12860 + * @param {Object} [options.transition] A transition object for changing between states. 59.12861 + * @param {Number} [options.direction] axis of expansion (Utility.Direction.X or .Y) 59.12862 + */ 59.12863 + function Deck(options) { 59.12864 + SequentialLayout.apply(this, arguments); 59.12865 + this.state = new Transitionable(0); 59.12866 + this._isOpen = false; 59.12867 + 59.12868 + this.setOutputFunction(function(input, offset, index) { 59.12869 + var state = _getState.call(this); 59.12870 + var positionMatrix = (this.options.direction === Utility.Direction.X) ? 59.12871 + Transform.translate(state * offset, 0, 0.001 * (state - 1) * offset) : 59.12872 + Transform.translate(0, state * offset, 0.001 * (state - 1) * offset); 59.12873 + var output = input.render(); 59.12874 + if (this.options.stackRotation) { 59.12875 + var amount = this.options.stackRotation * index * (1 - state); 59.12876 + output = { 59.12877 + transform: Transform.rotateZ(amount), 59.12878 + origin: [0.5, 0.5], 59.12879 + target: output 59.12880 + }; 59.12881 + } 59.12882 + return { 59.12883 + transform: positionMatrix, 59.12884 + size: input.getSize(), 59.12885 + target: output 59.12886 + }; 59.12887 + }); 59.12888 + } 59.12889 + Deck.prototype = Object.create(SequentialLayout.prototype); 59.12890 + Deck.prototype.constructor = Deck; 59.12891 + 59.12892 + Deck.DEFAULT_OPTIONS = OptionsManager.patch(SequentialLayout.DEFAULT_OPTIONS, { 59.12893 + transition: { 59.12894 + curve: 'easeOutBounce', 59.12895 + duration: 500 59.12896 + }, 59.12897 + stackRotation: 0 59.12898 + }); 59.12899 + 59.12900 + /** 59.12901 + * Returns the width and the height of the Deck instance. 59.12902 + * 59.12903 + * @method getSize 59.12904 + * @return {Array} A two value array of Deck's current width and height (in that order). 59.12905 + * Scales as Deck opens and closes. 59.12906 + */ 59.12907 + Deck.prototype.getSize = function getSize() { 59.12908 + var originalSize = SequentialLayout.prototype.getSize.apply(this, arguments); 59.12909 + var firstSize = this._items ? this._items.get().getSize() : [0, 0]; 59.12910 + if (!firstSize) firstSize = [0, 0]; 59.12911 + var state = _getState.call(this); 59.12912 + var invState = 1 - state; 59.12913 + return [firstSize[0] * invState + originalSize[0] * state, firstSize[1] * invState + originalSize[1] * state]; 59.12914 + }; 59.12915 + 59.12916 + function _getState(returnFinal) { 59.12917 + if (returnFinal) return this._isOpen ? 1 : 0; 59.12918 + else return this.state.get(); 59.12919 + } 59.12920 + 59.12921 + function _setState(pos, transition, callback) { 59.12922 + this.state.halt(); 59.12923 + this.state.set(pos, transition, callback); 59.12924 + } 59.12925 + 59.12926 + /** 59.12927 + * An accesor method to find out if the messaged Deck instance is open or closed. 59.12928 + * 59.12929 + * @method isOpen 59.12930 + * @return {Boolean} Returns true if the instance is open or false if it's closed. 59.12931 + */ 59.12932 + Deck.prototype.isOpen = function isOpen() { 59.12933 + return this._isOpen; 59.12934 + }; 59.12935 + 59.12936 + /** 59.12937 + * Sets the Deck instance to an open state. 59.12938 + * 59.12939 + * @method open 59.12940 + * @param {function} [callback] Executes after transitioning to a fully open state. 59.12941 + */ 59.12942 + Deck.prototype.open = function open(callback) { 59.12943 + this._isOpen = true; 59.12944 + _setState.call(this, 1, this.options.transition, callback); 59.12945 + }; 59.12946 + 59.12947 + /** 59.12948 + * Sets the Deck instance to an open state. 59.12949 + * 59.12950 + * @method close 59.12951 + * @param {function} [callback] Executes after transitioning to a fully closed state. 59.12952 + */ 59.12953 + Deck.prototype.close = function close(callback) { 59.12954 + this._isOpen = false; 59.12955 + _setState.call(this, 0, this.options.transition, callback); 59.12956 + }; 59.12957 + 59.12958 + /** 59.12959 + * Sets the Deck instance from its current state to the opposite state. 59.12960 + * 59.12961 + * @method close 59.12962 + * @param {function} [callback] Executes after transitioning to the toggled state. 59.12963 + */ 59.12964 + Deck.prototype.toggle = function toggle(callback) { 59.12965 + if (this._isOpen) this.close(callback); 59.12966 + else this.open(callback); 59.12967 + }; 59.12968 + 59.12969 + module.exports = Deck; 59.12970 +}); 59.12971 + 59.12972 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.12973 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.12974 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.12975 + * 59.12976 + * Owner: felix@famo.us 59.12977 + * @license MPL 2.0 59.12978 + * @copyright Famous Industries, Inc. 2014 59.12979 + */ 59.12980 + 59.12981 +define('famous/views/RenderController',['require','exports','module','famous/core/Modifier','famous/core/RenderNode','famous/core/Transform','famous/transitions/Transitionable','famous/core/View'],function(require, exports, module) { 59.12982 + var Modifier = require('famous/core/Modifier'); 59.12983 + var RenderNode = require('famous/core/RenderNode'); 59.12984 + var Transform = require('famous/core/Transform'); 59.12985 + var Transitionable = require('famous/transitions/Transitionable'); 59.12986 + var View = require('famous/core/View'); 59.12987 + 59.12988 + /** 59.12989 + * A dynamic view that can show or hide different renerables with transitions. 59.12990 + * @class RenderController 59.12991 + * @constructor 59.12992 + * @param {Options} [options] An object of configurable options. 59.12993 + * @param {Transition} [inTransition=true] The transition in charge of showing a renderable. 59.12994 + * @param {Transition} [outTransition=true] The transition in charge of removing your previous renderable when 59.12995 + * you show a new one, or hiding your current renderable. 59.12996 + * @param {Boolean} [overlap=true] When showing a new renderable, overlap determines if the 59.12997 + out transition of the old one executes concurrently with the in transition of the new one, 59.12998 + or synchronously beforehand. 59.12999 + */ 59.13000 + function RenderController(options) { 59.13001 + View.apply(this, arguments); 59.13002 + 59.13003 + this._showing = -1; 59.13004 + this._outgoingRenderables = []; 59.13005 + this._nextRenderable = null; 59.13006 + 59.13007 + this._renderables = []; 59.13008 + this._nodes = []; 59.13009 + this._modifiers = []; 59.13010 + this._states = []; 59.13011 + 59.13012 + this.inTransformMap = RenderController.DefaultMap.transform; 59.13013 + this.inOpacityMap = RenderController.DefaultMap.opacity; 59.13014 + this.inOriginMap = RenderController.DefaultMap.origin; 59.13015 + this.outTransformMap = RenderController.DefaultMap.transform; 59.13016 + this.outOpacityMap = RenderController.DefaultMap.opacity; 59.13017 + this.outOriginMap = RenderController.DefaultMap.origin; 59.13018 + 59.13019 + this._output = []; 59.13020 + } 59.13021 + RenderController.prototype = Object.create(View.prototype); 59.13022 + RenderController.prototype.constructor = RenderController; 59.13023 + 59.13024 + RenderController.DEFAULT_OPTIONS = { 59.13025 + inTransition: true, 59.13026 + outTransition: true, 59.13027 + overlap: true 59.13028 + }; 59.13029 + 59.13030 + RenderController.DefaultMap = { 59.13031 + transform: function() { 59.13032 + return Transform.identity; 59.13033 + }, 59.13034 + opacity: function(progress) { 59.13035 + return progress; 59.13036 + }, 59.13037 + origin: null 59.13038 + }; 59.13039 + 59.13040 + function _mappedState(map, state) { 59.13041 + return map(state.get()); 59.13042 + } 59.13043 + 59.13044 + /** 59.13045 + * As your RenderController shows a new renderable, it executes a transition in. This transition in 59.13046 + * will affect a default interior state and modify it as you bring renderables in and out. However, if you want to control 59.13047 + * the transform, opacity, and origin state yourself, you may call certain methods (such as inTransformFrom) to obtain state from an outside source, 59.13048 + * that may either be a function or a Famous transitionable. inTransformFrom sets the accessor for the state of 59.13049 + * the transform used in transitioning in renderables. 59.13050 + * 59.13051 + * @method inTransformFrom 59.13052 + * @param {Function|Transitionable} transform A function that returns a transform from outside closure, or a 59.13053 + * a transitionable that manages a full transform (a sixteen value array). 59.13054 + * @chainable 59.13055 + */ 59.13056 + RenderController.prototype.inTransformFrom = function inTransformFrom(transform) { 59.13057 + if (transform instanceof Function) this.inTransformMap = transform; 59.13058 + else if (transform && transform.get) this.inTransformMap = transform.get.bind(transform); 59.13059 + else throw new Error('inTransformFrom takes only function or getter object'); 59.13060 + //TODO: tween transition 59.13061 + return this; 59.13062 + }; 59.13063 + 59.13064 + /** 59.13065 + * inOpacityFrom sets the accessor for the state of the opacity used in transitioning in renderables. 59.13066 + * @method inOpacityFrom 59.13067 + * @param {Function|Transitionable} opacity A function that returns an opacity from outside closure, or a 59.13068 + * a transitionable that manages opacity (a number between zero and one). 59.13069 + * @chainable 59.13070 + */ 59.13071 + RenderController.prototype.inOpacityFrom = function inOpacityFrom(opacity) { 59.13072 + if (opacity instanceof Function) this.inOpacityMap = opacity; 59.13073 + else if (opacity && opacity.get) this.inOpacityMap = opacity.get.bind(opacity); 59.13074 + else throw new Error('inOpacityFrom takes only function or getter object'); 59.13075 + //TODO: tween opacity 59.13076 + return this; 59.13077 + }; 59.13078 + 59.13079 + /** 59.13080 + * inOriginFrom sets the accessor for the state of the origin used in transitioning in renderables. 59.13081 + * @method inOriginFrom 59.13082 + * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a 59.13083 + * a transitionable that manages origin (a two value array of numbers between zero and one). 59.13084 + * @chainable 59.13085 + */ 59.13086 + RenderController.prototype.inOriginFrom = function inOriginFrom(origin) { 59.13087 + if (origin instanceof Function) this.inOriginMap = origin; 59.13088 + else if (origin && origin.get) this.inOriginMap = origin.get.bind(origin); 59.13089 + else throw new Error('inOriginFrom takes only function or getter object'); 59.13090 + //TODO: tween origin 59.13091 + return this; 59.13092 + }; 59.13093 + 59.13094 + /** 59.13095 + * outTransformFrom sets the accessor for the state of the transform used in transitioning out renderables. 59.13096 + * @method show 59.13097 + * @param {Function|Transitionable} transform A function that returns a transform from outside closure, or a 59.13098 + * a transitionable that manages a full transform (a sixteen value array). 59.13099 + * @chainable 59.13100 + */ 59.13101 + RenderController.prototype.outTransformFrom = function outTransformFrom(transform) { 59.13102 + if (transform instanceof Function) this.outTransformMap = transform; 59.13103 + else if (transform && transform.get) this.outTransformMap = transform.get.bind(transform); 59.13104 + else throw new Error('inTransformFrom takes only function or getter object'); 59.13105 + //TODO: tween transition 59.13106 + return this; 59.13107 + }; 59.13108 + 59.13109 + /** 59.13110 + * outOpacityFrom sets the accessor for the state of the opacity used in transitioning out renderables. 59.13111 + * @method inOpacityFrom 59.13112 + * @param {Function|Transitionable} opacity A function that returns an opacity from outside closure, or a 59.13113 + * a transitionable that manages opacity (a number between zero and one). 59.13114 + * @chainable 59.13115 + */ 59.13116 + RenderController.prototype.outOpacityFrom = function outOpacityFrom(opacity) { 59.13117 + if (opacity instanceof Function) this.outOpacityMap = opacity; 59.13118 + else if (opacity && opacity.get) this.outOpacityMap = opacity.get.bind(opacity); 59.13119 + else throw new Error('inOpacityFrom takes only function or getter object'); 59.13120 + //TODO: tween opacity 59.13121 + return this; 59.13122 + }; 59.13123 + 59.13124 + /** 59.13125 + * outOriginFrom sets the accessor for the state of the origin used in transitioning out renderables. 59.13126 + * @method inOriginFrom 59.13127 + * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a 59.13128 + * a transitionable that manages origin (a two value array of numbers between zero and one). 59.13129 + * @chainable 59.13130 + */ 59.13131 + RenderController.prototype.outOriginFrom = function outOriginFrom(origin) { 59.13132 + if (origin instanceof Function) this.outOriginMap = origin; 59.13133 + else if (origin && origin.get) this.outOriginMap = origin.get.bind(origin); 59.13134 + else throw new Error('inOriginFrom takes only function or getter object'); 59.13135 + //TODO: tween origin 59.13136 + return this; 59.13137 + }; 59.13138 + 59.13139 + /** 59.13140 + * Show displays the targeted renderable with a transition and an optional callback to 59.13141 + * execute afterwards. 59.13142 + * @method show 59.13143 + * @param {Object} renderable The renderable you want to show. 59.13144 + * @param {Transition} [transition] Overwrites the default transition in to display the 59.13145 + * passed-in renderable. 59.13146 + * @param {function} [callback] Executes after transitioning in the renderable. 59.13147 + * @chainable 59.13148 + */ 59.13149 + RenderController.prototype.show = function show(renderable, transition, callback) { 59.13150 + if (!renderable) { 59.13151 + return this.hide(callback); 59.13152 + } 59.13153 + 59.13154 + if (transition instanceof Function) { 59.13155 + callback = transition; 59.13156 + transition = null; 59.13157 + } 59.13158 + 59.13159 + if (this._showing >= 0) { 59.13160 + if (this.options.overlap) this.hide(); 59.13161 + else { 59.13162 + if (this._nextRenderable) { 59.13163 + this._nextRenderable = renderable; 59.13164 + } 59.13165 + else { 59.13166 + this._nextRenderable = renderable; 59.13167 + this.hide(function() { 59.13168 + if (this._nextRenderable === renderable) this.show(this._nextRenderable, callback); 59.13169 + this._nextRenderable = null; 59.13170 + }); 59.13171 + } 59.13172 + return undefined; 59.13173 + } 59.13174 + } 59.13175 + 59.13176 + var state = null; 59.13177 + 59.13178 + // check to see if we should restore 59.13179 + var renderableIndex = this._renderables.indexOf(renderable); 59.13180 + if (renderableIndex >= 0) { 59.13181 + this._showing = renderableIndex; 59.13182 + state = this._states[renderableIndex]; 59.13183 + state.halt(); 59.13184 + 59.13185 + var outgoingIndex = this._outgoingRenderables.indexOf(renderable); 59.13186 + if (outgoingIndex >= 0) this._outgoingRenderables.splice(outgoingIndex, 1); 59.13187 + } 59.13188 + else { 59.13189 + state = new Transitionable(0); 59.13190 + 59.13191 + var modifier = new Modifier({ 59.13192 + transform: this.inTransformMap ? _mappedState.bind(this, this.inTransformMap, state) : null, 59.13193 + opacity: this.inOpacityMap ? _mappedState.bind(this, this.inOpacityMap, state) : null, 59.13194 + origin: this.inOriginMap ? _mappedState.bind(this, this.inOriginMap, state) : null 59.13195 + }); 59.13196 + var node = new RenderNode(); 59.13197 + node.add(modifier).add(renderable); 59.13198 + 59.13199 + this._showing = this._nodes.length; 59.13200 + this._nodes.push(node); 59.13201 + this._modifiers.push(modifier); 59.13202 + this._states.push(state); 59.13203 + this._renderables.push(renderable); 59.13204 + } 59.13205 + 59.13206 + if (!transition) transition = this.options.inTransition; 59.13207 + state.set(1, transition, callback); 59.13208 + }; 59.13209 + 59.13210 + /** 59.13211 + * Hide hides the currently displayed renderable with an out transition. 59.13212 + * @method hide 59.13213 + * @param {Transition} [transition] Overwrites the default transition in to hide the 59.13214 + * currently controlled renderable. 59.13215 + * @param {function} [callback] Executes after transitioning out the renderable. 59.13216 + * @chainable 59.13217 + */ 59.13218 + RenderController.prototype.hide = function hide(transition, callback) { 59.13219 + if (this._showing < 0) return; 59.13220 + var index = this._showing; 59.13221 + this._showing = -1; 59.13222 + 59.13223 + if (transition instanceof Function) { 59.13224 + callback = transition; 59.13225 + transition = undefined; 59.13226 + } 59.13227 + 59.13228 + var node = this._nodes[index]; 59.13229 + var modifier = this._modifiers[index]; 59.13230 + var state = this._states[index]; 59.13231 + var renderable = this._renderables[index]; 59.13232 + 59.13233 + modifier.transformFrom(this.outTransformMap ? _mappedState.bind(this, this.outTransformMap, state) : null); 59.13234 + modifier.opacityFrom(this.outOpacityMap ? _mappedState.bind(this, this.outOpacityMap, state) : null); 59.13235 + modifier.originFrom(this.outOriginMap ? _mappedState.bind(this, this.outOriginMap, state) : null); 59.13236 + 59.13237 + if (this._outgoingRenderables.indexOf(renderable) < 0) this._outgoingRenderables.push(renderable); 59.13238 + 59.13239 + if (!transition) transition = this.options.outTransition; 59.13240 + state.halt(); 59.13241 + state.set(0, transition, function(node, modifier, state, renderable) { 59.13242 + if (this._outgoingRenderables.indexOf(renderable) >= 0) { 59.13243 + var index = this._nodes.indexOf(node); 59.13244 + this._nodes.splice(index, 1); 59.13245 + this._modifiers.splice(index, 1); 59.13246 + this._states.splice(index, 1); 59.13247 + this._renderables.splice(index, 1); 59.13248 + this._outgoingRenderables.splice(this._outgoingRenderables.indexOf(renderable), 1); 59.13249 + 59.13250 + if (this._showing >= index) this._showing--; 59.13251 + } 59.13252 + if (callback) callback.call(this); 59.13253 + }.bind(this, node, modifier, state, renderable)); 59.13254 + }; 59.13255 + 59.13256 + /** 59.13257 + * Generate a render spec from the contents of this component. 59.13258 + * 59.13259 + * @private 59.13260 + * @method render 59.13261 + * @return {number} Render spec for this component 59.13262 + */ 59.13263 + RenderController.prototype.render = function render() { 59.13264 + var result = this._output; 59.13265 + if (result.length > this._nodes.length) result.splice(this._nodes.length); 59.13266 + for (var i = 0; i < this._nodes.length; i++) { 59.13267 + result[i] = this._nodes[i].render(); 59.13268 + } 59.13269 + return result; 59.13270 + }; 59.13271 + 59.13272 + module.exports = RenderController; 59.13273 +}); 59.13274 + 59.13275 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.13276 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.13277 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.13278 + * 59.13279 + * Owner: felix@famo.us 59.13280 + * @license MPL 2.0 59.13281 + * @copyright Famous Industries, Inc. 2014 59.13282 + */ 59.13283 + 59.13284 +define('famous/views/EdgeSwapper',['require','exports','module','famous/transitions/CachedMap','famous/core/Entity','famous/core/EventHandler','famous/core/Transform','./RenderController'],function(require, exports, module) { 59.13285 + var CachedMap = require('famous/transitions/CachedMap'); 59.13286 + var Entity = require('famous/core/Entity'); 59.13287 + var EventHandler = require('famous/core/EventHandler'); 59.13288 + var Transform = require('famous/core/Transform'); 59.13289 + var RenderController = require('./RenderController'); 59.13290 + 59.13291 + /** 59.13292 + * Container which handles swapping renderables from the edge of its parent context. 59.13293 + * @class EdgeSwapper 59.13294 + * @constructor 59.13295 + * @param {Options} [options] An object of configurable options. 59.13296 + * Takes the same options as RenderController. 59.13297 + * @uses RenderController 59.13298 + */ 59.13299 + function EdgeSwapper(options) { 59.13300 + this._currentTarget = null; 59.13301 + this._size = [undefined, undefined]; 59.13302 + 59.13303 + this._controller = new RenderController(options); 59.13304 + this._controller.inTransformFrom(CachedMap.create(_transformMap.bind(this, 0.0001))); 59.13305 + this._controller.outTransformFrom(CachedMap.create(_transformMap.bind(this, -0.0001))); 59.13306 + 59.13307 + this._eventInput = new EventHandler(); 59.13308 + EventHandler.setInputHandler(this, this._eventInput); 59.13309 + 59.13310 + this._entityId = Entity.register(this); 59.13311 + if (options) this.setOptions(options); 59.13312 + } 59.13313 + 59.13314 + function _transformMap(zMax, progress) { 59.13315 + return Transform.translate(this._size[0] * (1 - progress), 0, zMax * (1 - progress)); 59.13316 + } 59.13317 + 59.13318 + /** 59.13319 + * Displays the passed-in content with the EdgeSwapper instance's default transition. 59.13320 + * 59.13321 + * @method show 59.13322 + * @param {Object} content The renderable you want to display. 59.13323 + */ 59.13324 + EdgeSwapper.prototype.show = function show(content) { 59.13325 + // stop sending input to old target 59.13326 + if (this._currentTarget) this._eventInput.unpipe(this._currentTarget); 59.13327 + 59.13328 + this._currentTarget = content; 59.13329 + 59.13330 + // start sending input to new target 59.13331 + if (this._currentTarget && this._currentTarget.trigger) this._eventInput.pipe(this._currentTarget); 59.13332 + 59.13333 + this._controller.show.apply(this._controller, arguments); 59.13334 + }; 59.13335 + 59.13336 + /** 59.13337 + * Patches the EdgeSwapper instance's options with the passed-in ones. 59.13338 + * 59.13339 + * @method setOptions 59.13340 + * @param {Options} options An object of configurable options for the Edgeswapper instance. 59.13341 + */ 59.13342 + EdgeSwapper.prototype.setOptions = function setOptions(options) { 59.13343 + this._controller.setOptions(options); 59.13344 + }; 59.13345 + 59.13346 + /** 59.13347 + * Generate a render spec from the contents of this component. 59.13348 + * 59.13349 + * @private 59.13350 + * @method render 59.13351 + * @return {number} Render spec for this component 59.13352 + */ 59.13353 + EdgeSwapper.prototype.render = function render() { 59.13354 + return this._entityId; 59.13355 + }; 59.13356 + 59.13357 + /** 59.13358 + * Apply changes from this component to the corresponding document element. 59.13359 + * This includes changes to classes, styles, size, content, opacity, origin, 59.13360 + * and matrix transforms. 59.13361 + * 59.13362 + * @private 59.13363 + * @method commit 59.13364 + * @param {Context} context commit context 59.13365 + */ 59.13366 + EdgeSwapper.prototype.commit = function commit(context) { 59.13367 + this._size[0] = context.size[0]; 59.13368 + this._size[1] = context.size[1]; 59.13369 + 59.13370 + return { 59.13371 + transform: context.transform, 59.13372 + opacity: context.opacity, 59.13373 + origin: context.origin, 59.13374 + size: context.size, 59.13375 + target: this._controller.render() 59.13376 + }; 59.13377 + }; 59.13378 + 59.13379 + module.exports = EdgeSwapper; 59.13380 +}); 59.13381 + 59.13382 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.13383 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.13384 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.13385 + * 59.13386 + * Owner: mike@famo.us 59.13387 + * @license MPL 2.0 59.13388 + * @copyright Famous Industries, Inc. 2014 59.13389 + */ 59.13390 + 59.13391 +define('famous/views/FlexibleLayout',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/OptionsManager','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) { 59.13392 + var Entity = require('famous/core/Entity'); 59.13393 + var Transform = require('famous/core/Transform'); 59.13394 + var OptionsManager = require('famous/core/OptionsManager'); 59.13395 + var EventHandler = require('famous/core/EventHandler'); 59.13396 + var Transitionable = require('famous/transitions/Transitionable'); 59.13397 + 59.13398 + /** 59.13399 + * A layout which divides a context into sections based on a proportion 59.13400 + * of the total sum of ratios. FlexibleLayout can either lay renderables 59.13401 + * out vertically or horizontally. 59.13402 + * @class FlexibleLayout 59.13403 + * @constructor 59.13404 + * @param {Options} [options] An object of configurable options. 59.13405 + * @param {Number} [options.direction=0] Direction the FlexibleLayout instance should lay out renderables. 59.13406 + * @param {Transition} [options.transition=false] The transiton that controls the FlexibleLayout instance's reflow. 59.13407 + * @param {Ratios} [options.ratios=[]] The proportions for the renderables to maintain 59.13408 + */ 59.13409 + function FlexibleLayout(options) { 59.13410 + this.options = Object.create(FlexibleLayout.DEFAULT_OPTIONS); 59.13411 + this.optionsManager = new OptionsManager(this.options); 59.13412 + if (options) this.setOptions(options); 59.13413 + 59.13414 + this.id = Entity.register(this); 59.13415 + 59.13416 + this._ratios = new Transitionable(this.options.ratios); 59.13417 + this._nodes = []; 59.13418 + 59.13419 + this._cachedDirection = null; 59.13420 + this._cachedTotalLength = false; 59.13421 + this._cachedLengths = []; 59.13422 + this._cachedTransforms = null; 59.13423 + this._ratiosDirty = false; 59.13424 + 59.13425 + this._eventOutput = new EventHandler(); 59.13426 + EventHandler.setOutputHandler(this, this._eventOutput); 59.13427 + } 59.13428 + 59.13429 + FlexibleLayout.DIRECTION_X = 0; 59.13430 + FlexibleLayout.DIRECTION_Y = 1; 59.13431 + 59.13432 + FlexibleLayout.DEFAULT_OPTIONS = { 59.13433 + direction: FlexibleLayout.DIRECTION_X, 59.13434 + transition: false, 59.13435 + ratios : [] 59.13436 + }; 59.13437 + 59.13438 + function _reflow(ratios, length, direction) { 59.13439 + var currTransform; 59.13440 + var translation = 0; 59.13441 + var flexLength = length; 59.13442 + var ratioSum = 0; 59.13443 + var ratio; 59.13444 + var node; 59.13445 + var i; 59.13446 + 59.13447 + this._cachedLengths = []; 59.13448 + this._cachedTransforms = []; 59.13449 + 59.13450 + for (i = 0; i < ratios.length; i++){ 59.13451 + ratio = ratios[i]; 59.13452 + node = this._nodes[i]; 59.13453 + 59.13454 + if (typeof ratio !== 'number') 59.13455 + flexLength -= node.getSize()[direction] || 0; 59.13456 + else 59.13457 + ratioSum += ratio; 59.13458 + } 59.13459 + 59.13460 + for (i = 0; i < ratios.length; i++) { 59.13461 + node = this._nodes[i]; 59.13462 + ratio = ratios[i]; 59.13463 + 59.13464 + length = (typeof ratio === 'number') 59.13465 + ? flexLength * ratio / ratioSum 59.13466 + : node.getSize()[direction]; 59.13467 + 59.13468 + currTransform = (direction === FlexibleLayout.DIRECTION_X) 59.13469 + ? Transform.translate(translation, 0, 0) 59.13470 + : Transform.translate(0, translation, 0); 59.13471 + 59.13472 + this._cachedTransforms.push(currTransform); 59.13473 + this._cachedLengths.push(length); 59.13474 + 59.13475 + translation += length; 59.13476 + } 59.13477 + } 59.13478 + 59.13479 + /** 59.13480 + * Generate a render spec from the contents of this component. 59.13481 + * 59.13482 + * @private 59.13483 + * @method render 59.13484 + * @return {Object} Render spec for this component 59.13485 + */ 59.13486 + FlexibleLayout.prototype.render = function render() { 59.13487 + return this.id; 59.13488 + }; 59.13489 + 59.13490 + /** 59.13491 + * Patches the FlexibleLayouts instance's options with the passed-in ones. 59.13492 + * 59.13493 + * @method setOptions 59.13494 + * @param {Options} options An object of configurable options for the FlexibleLayout instance. 59.13495 + */ 59.13496 + FlexibleLayout.prototype.setOptions = function setOptions(options) { 59.13497 + this.optionsManager.setOptions(options); 59.13498 + }; 59.13499 + 59.13500 + /** 59.13501 + * Sets the collection of renderables under the FlexibleLayout instance's control. Also sets 59.13502 + * the associated ratio values for sizing the renderables if given. 59.13503 + * 59.13504 + * @method sequenceFrom 59.13505 + * @param {Array} sequence An array of renderables. 59.13506 + */ 59.13507 + FlexibleLayout.prototype.sequenceFrom = function sequenceFrom(sequence) { 59.13508 + this._nodes = sequence; 59.13509 + 59.13510 + if (this._ratios.get().length === 0) { 59.13511 + var ratios = []; 59.13512 + for (var i = 0; i < this._nodes.length; i++) ratios.push(1); 59.13513 + this.setRatios(ratios); 59.13514 + } 59.13515 + }; 59.13516 + 59.13517 + /** 59.13518 + * Sets the associated ratio values for sizing the renderables. 59.13519 + * 59.13520 + * @method setRatios 59.13521 + * @param {Array} ratios Array of ratios corresponding to the percentage sizes each renderable should be 59.13522 + */ 59.13523 + FlexibleLayout.prototype.setRatios = function setRatios(ratios, transition, callback) { 59.13524 + if (transition === undefined) transition = this.options.transition; 59.13525 + var currRatios = this._ratios; 59.13526 + if (currRatios.get().length === 0) transition = undefined; 59.13527 + if (currRatios.isActive()) currRatios.halt(); 59.13528 + currRatios.set(ratios, transition, callback); 59.13529 + this._ratiosDirty = true; 59.13530 + }; 59.13531 + 59.13532 + /** 59.13533 + * Apply changes from this component to the corresponding document element. 59.13534 + * This includes changes to classes, styles, size, content, opacity, origin, 59.13535 + * and matrix transforms. 59.13536 + * 59.13537 + * @private 59.13538 + * @method commit 59.13539 + * @param {Context} context commit context 59.13540 + */ 59.13541 + FlexibleLayout.prototype.commit = function commit(context) { 59.13542 + var parentSize = context.size; 59.13543 + var parentTransform = context.transform; 59.13544 + var parentOrigin = context.origin; 59.13545 + 59.13546 + var ratios = this._ratios.get(); 59.13547 + var direction = this.options.direction; 59.13548 + var length = parentSize[direction]; 59.13549 + var size; 59.13550 + 59.13551 + if (length !== this._cachedTotalLength || this._ratiosDirty || this._ratios.isActive() || direction !== this._cachedDirection) { 59.13552 + _reflow.call(this, ratios, length, direction); 59.13553 + 59.13554 + if (length !== this._cachedTotalLength) this._cachedTotalLength = length; 59.13555 + if (direction !== this._cachedDirection) this._cachedDirection = direction; 59.13556 + if (this._ratiosDirty) this._ratiosDirty = false; 59.13557 + } 59.13558 + 59.13559 + var result = []; 59.13560 + for (var i = 0; i < ratios.length; i++) { 59.13561 + size = [undefined, undefined]; 59.13562 + length = this._cachedLengths[i]; 59.13563 + size[direction] = length; 59.13564 + result.push({ 59.13565 + transform : this._cachedTransforms[i], 59.13566 + size: size, 59.13567 + target : this._nodes[i].render() 59.13568 + }); 59.13569 + } 59.13570 + 59.13571 + if (parentSize && (parentOrigin[0] !== 0 && parentOrigin[1] !== 0)) 59.13572 + parentTransform = Transform.moveThen([-parentSize[0]*parentOrigin[0], -parentSize[1]*parentOrigin[1], 0], parentTransform); 59.13573 + 59.13574 + return { 59.13575 + transform: parentTransform, 59.13576 + size: parentSize, 59.13577 + target: result 59.13578 + }; 59.13579 + }; 59.13580 + 59.13581 + module.exports = FlexibleLayout; 59.13582 +}); 59.13583 + 59.13584 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.13585 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.13586 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.13587 + * 59.13588 + * Owner: felix@famo.us 59.13589 + * @license MPL 2.0 59.13590 + * @copyright Famous Industries, Inc. 2014 59.13591 + */ 59.13592 + 59.13593 +define('famous/views/Flipper',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/RenderNode','famous/core/OptionsManager'],function(require, exports, module) { 59.13594 + var Transform = require('famous/core/Transform'); 59.13595 + var Transitionable = require('famous/transitions/Transitionable'); 59.13596 + var RenderNode = require('famous/core/RenderNode'); 59.13597 + var OptionsManager = require('famous/core/OptionsManager'); 59.13598 + 59.13599 + /** 59.13600 + * Allows you to link two renderables as front and back sides that can be 59.13601 + * 'flipped' back and forth along a chosen axis. Rendering optimizations are 59.13602 + * automatically handled. 59.13603 + * 59.13604 + * @class Flipper 59.13605 + * @constructor 59.13606 + * @param {Options} [options] An object of options. 59.13607 + * @param {Transition} [options.transition=true] The transition executed when flipping your Flipper instance. 59.13608 + */ 59.13609 + function Flipper(options) { 59.13610 + this.options = Object.create(Flipper.DEFAULT_OPTIONS); 59.13611 + this._optionsManager = new OptionsManager(this.options); 59.13612 + if (options) this.setOptions(options); 59.13613 + 59.13614 + this.angle = new Transitionable(0); 59.13615 + 59.13616 + this.frontNode = undefined; 59.13617 + this.backNode = undefined; 59.13618 + 59.13619 + this.flipped = false; 59.13620 + } 59.13621 + 59.13622 + Flipper.DIRECTION_X = 0; 59.13623 + Flipper.DIRECTION_Y = 1; 59.13624 + 59.13625 + var SEPERATION_LENGTH = 1; 59.13626 + 59.13627 + Flipper.DEFAULT_OPTIONS = { 59.13628 + transition: true, 59.13629 + direction: Flipper.DIRECTION_X 59.13630 + }; 59.13631 + 59.13632 + /** 59.13633 + * Toggles the rotation between the front and back renderables 59.13634 + * 59.13635 + * @method flip 59.13636 + * @param {Object} [transition] Transition definition 59.13637 + * @param {Function} [callback] Callback 59.13638 + */ 59.13639 + Flipper.prototype.flip = function flip(transition, callback) { 59.13640 + var angle = this.flipped ? 0 : Math.PI; 59.13641 + this.setAngle(angle, transition, callback); 59.13642 + this.flipped = !this.flipped; 59.13643 + }; 59.13644 + 59.13645 + /** 59.13646 + * Basic setter to the angle 59.13647 + * 59.13648 + * @method setAngle 59.13649 + * @param {Number} angle 59.13650 + * @param {Object} [transition] Transition definition 59.13651 + * @param {Function} [callback] Callback 59.13652 + */ 59.13653 + Flipper.prototype.setAngle = function setAngle(angle, transition, callback) { 59.13654 + if (transition === undefined) transition = this.options.transition; 59.13655 + if (this.angle.isActive()) this.angle.halt(); 59.13656 + this.angle.set(angle, transition, callback); 59.13657 + }; 59.13658 + 59.13659 + /** 59.13660 + * Patches the Flipper instance's options with the passed-in ones. 59.13661 + * 59.13662 + * @method setOptions 59.13663 + * @param {Options} options An object of configurable options for the Flipper instance. 59.13664 + */ 59.13665 + Flipper.prototype.setOptions = function setOptions(options) { 59.13666 + return this._optionsManager.setOptions(options); 59.13667 + }; 59.13668 + 59.13669 + /** 59.13670 + * Adds the passed-in renderable to the view associated with the 'front' of the Flipper instance. 59.13671 + * 59.13672 + * @method setFront 59.13673 + * @chainable 59.13674 + * @param {Object} node The renderable you want to add to the front. 59.13675 + */ 59.13676 + Flipper.prototype.setFront = function setFront(node) { 59.13677 + this.frontNode = node; 59.13678 + }; 59.13679 + 59.13680 + /** 59.13681 + * Adds the passed-in renderable to the view associated with the 'back' of the Flipper instance. 59.13682 + * 59.13683 + * @method setBack 59.13684 + * @chainable 59.13685 + * @param {Object} node The renderable you want to add to the back. 59.13686 + */ 59.13687 + Flipper.prototype.setBack = function setBack(node) { 59.13688 + this.backNode = node; 59.13689 + }; 59.13690 + 59.13691 + /** 59.13692 + * Generate a render spec from the contents of this component. 59.13693 + * 59.13694 + * @private 59.13695 + * @method render 59.13696 + * @return {Number} Render spec for this component 59.13697 + */ 59.13698 + Flipper.prototype.render = function render() { 59.13699 + var angle = this.angle.get(); 59.13700 + 59.13701 + var frontTransform; 59.13702 + var backTransform; 59.13703 + 59.13704 + if (this.options.direction === Flipper.DIRECTION_X) { 59.13705 + frontTransform = Transform.rotateY(angle); 59.13706 + backTransform = Transform.rotateY(angle + Math.PI); 59.13707 + } 59.13708 + else { 59.13709 + frontTransform = Transform.rotateX(angle); 59.13710 + backTransform = Transform.rotateX(angle + Math.PI); 59.13711 + } 59.13712 + 59.13713 + var result = []; 59.13714 + if (this.frontNode){ 59.13715 + result.push({ 59.13716 + transform: frontTransform, 59.13717 + target: this.frontNode.render() 59.13718 + }); 59.13719 + } 59.13720 + 59.13721 + if (this.backNode){ 59.13722 + result.push({ 59.13723 + transform: Transform.moveThen([0, 0, SEPERATION_LENGTH], backTransform), 59.13724 + target: this.backNode.render() 59.13725 + }); 59.13726 + } 59.13727 + 59.13728 + return result; 59.13729 + }; 59.13730 + 59.13731 + module.exports = Flipper; 59.13732 +}); 59.13733 + 59.13734 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.13735 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.13736 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.13737 + * 59.13738 + * Owner: felix@famo.us 59.13739 + * @license MPL 2.0 59.13740 + * @copyright Famous Industries, Inc. 2014 59.13741 + */ 59.13742 + 59.13743 +define('famous/views/GridLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/ViewSequence','famous/core/EventHandler','famous/core/Modifier','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 59.13744 + var Entity = require('famous/core/Entity'); 59.13745 + var RenderNode = require('famous/core/RenderNode'); 59.13746 + var Transform = require('famous/core/Transform'); 59.13747 + var ViewSequence = require('famous/core/ViewSequence'); 59.13748 + var EventHandler = require('famous/core/EventHandler'); 59.13749 + var Modifier = require('famous/core/Modifier'); 59.13750 + var OptionsManager = require('famous/core/OptionsManager'); 59.13751 + var Transitionable = require('famous/transitions/Transitionable'); 59.13752 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 59.13753 + 59.13754 + /** 59.13755 + * A layout which divides a context into several evenly-sized grid cells. 59.13756 + * If dimensions are provided, the grid is evenly subdivided with children 59.13757 + * cells representing their own context, otherwise the cellSize property is used to compute 59.13758 + * dimensions so that items of cellSize will fit. 59.13759 + * @class GridLayout 59.13760 + * @constructor 59.13761 + * @param {Options} [options] An object of configurable options. 59.13762 + * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns 59.13763 + * and rows in your Gridlayout instance. 59.13764 + * @param {Array.Number} [options.cellSize=[250, 250]] A two-value array which specifies the width and height 59.13765 + * of each cell in your Gridlayout instance. 59.13766 + * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow. 59.13767 + */ 59.13768 + function GridLayout(options) { 59.13769 + this.options = Object.create(GridLayout.DEFAULT_OPTIONS); 59.13770 + this.optionsManager = new OptionsManager(this.options); 59.13771 + if (options) this.setOptions(options); 59.13772 + 59.13773 + this.id = Entity.register(this); 59.13774 + 59.13775 + this._modifiers = []; 59.13776 + this._states = []; 59.13777 + this._contextSizeCache = [0, 0]; 59.13778 + this._dimensionsCache = [0, 0]; 59.13779 + this._activeCount = 0; 59.13780 + 59.13781 + this._eventOutput = new EventHandler(); 59.13782 + EventHandler.setOutputHandler(this, this._eventOutput); 59.13783 + } 59.13784 + 59.13785 + function _reflow(size, cols, rows) { 59.13786 + var usableSize = [size[0], size[1]]; 59.13787 + usableSize[0] -= this.options.gutterSize[0] * (cols - 1); 59.13788 + usableSize[1] -= this.options.gutterSize[1] * (rows - 1); 59.13789 + 59.13790 + var rowSize = Math.round(usableSize[1] / rows); 59.13791 + var colSize = Math.round(usableSize[0] / cols); 59.13792 + 59.13793 + var currY = 0; 59.13794 + var currX; 59.13795 + var currIndex = 0; 59.13796 + for (var i = 0; i < rows; i++) { 59.13797 + currX = 0; 59.13798 + for (var j = 0; j < cols; j++) { 59.13799 + if (this._modifiers[currIndex] === undefined) { 59.13800 + _createModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1); 59.13801 + } 59.13802 + else { 59.13803 + _animateModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1); 59.13804 + } 59.13805 + 59.13806 + currIndex++; 59.13807 + currX += colSize + this.options.gutterSize[0]; 59.13808 + } 59.13809 + 59.13810 + currY += rowSize + this.options.gutterSize[1]; 59.13811 + } 59.13812 + 59.13813 + this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]]; 59.13814 + this._contextSizeCache = [size[0], size[1]]; 59.13815 + 59.13816 + this._activeCount = rows * cols; 59.13817 + 59.13818 + for (i = this._activeCount ; i < this._modifiers.length; i++) _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0); 59.13819 + 59.13820 + this._eventOutput.emit('reflow'); 59.13821 + } 59.13822 + 59.13823 + function _createModifier(index, size, position, opacity) { 59.13824 + var transitionItem = { 59.13825 + transform: new TransitionableTransform(Transform.translate.apply(null, position)), 59.13826 + opacity: new Transitionable(opacity), 59.13827 + size: new Transitionable(size) 59.13828 + }; 59.13829 + 59.13830 + var modifier = new Modifier({ 59.13831 + transform: transitionItem.transform, 59.13832 + opacity: transitionItem.opacity, 59.13833 + size: transitionItem.size 59.13834 + }); 59.13835 + 59.13836 + this._states[index] = transitionItem; 59.13837 + this._modifiers[index] = modifier; 59.13838 + 59.13839 + } 59.13840 + 59.13841 + function _animateModifier(index, size, position, opacity) { 59.13842 + var currState = this._states[index]; 59.13843 + 59.13844 + var currSize = currState.size; 59.13845 + var currOpacity = currState.opacity; 59.13846 + var currTransform = currState.transform; 59.13847 + 59.13848 + var transition = this.options.transition; 59.13849 + 59.13850 + currTransform.halt(); 59.13851 + currOpacity.halt(); 59.13852 + currSize.halt(); 59.13853 + 59.13854 + currTransform.setTranslate(position, transition); 59.13855 + currSize.set(size, transition); 59.13856 + currOpacity.set(opacity, transition); 59.13857 + } 59.13858 + 59.13859 + GridLayout.DEFAULT_OPTIONS = { 59.13860 + dimensions: [1, 1], 59.13861 + transition: false, 59.13862 + gutterSize: [0, 0] 59.13863 + }; 59.13864 + 59.13865 + /** 59.13866 + * Generate a render spec from the contents of this component. 59.13867 + * 59.13868 + * @private 59.13869 + * @method render 59.13870 + * @return {Object} Render spec for this component 59.13871 + */ 59.13872 + GridLayout.prototype.render = function render() { 59.13873 + return this.id; 59.13874 + }; 59.13875 + 59.13876 + /** 59.13877 + * Patches the GridLayout instance's options with the passed-in ones. 59.13878 + * 59.13879 + * @method setOptions 59.13880 + * @param {Options} options An object of configurable options for the GridLayout instance. 59.13881 + */ 59.13882 + GridLayout.prototype.setOptions = function setOptions(options) { 59.13883 + return this.optionsManager.setOptions(options); 59.13884 + }; 59.13885 + 59.13886 + /** 59.13887 + * Sets the collection of renderables under the Gridlayout instance's control. 59.13888 + * 59.13889 + * @method sequenceFrom 59.13890 + * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence. 59.13891 + */ 59.13892 + GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) { 59.13893 + if (sequence instanceof Array) sequence = new ViewSequence(sequence); 59.13894 + this.sequence = sequence; 59.13895 + }; 59.13896 + 59.13897 + /** 59.13898 + * Apply changes from this component to the corresponding document element. 59.13899 + * This includes changes to classes, styles, size, content, opacity, origin, 59.13900 + * and matrix transforms. 59.13901 + * 59.13902 + * @private 59.13903 + * @method commit 59.13904 + * @param {Context} context commit context 59.13905 + */ 59.13906 + GridLayout.prototype.commit = function commit(context) { 59.13907 + var transform = context.transform; 59.13908 + var opacity = context.opacity; 59.13909 + var origin = context.origin; 59.13910 + var size = context.size; 59.13911 + 59.13912 + var cols = this.options.dimensions[0]; 59.13913 + var rows = this.options.dimensions[1]; 59.13914 + 59.13915 + if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) { 59.13916 + _reflow.call(this, size, cols, rows); 59.13917 + } 59.13918 + 59.13919 + var sequence = this.sequence; 59.13920 + var result = []; 59.13921 + var currIndex = 0; 59.13922 + while (sequence && (currIndex < this._modifiers.length)) { 59.13923 + var item = sequence.get(); 59.13924 + var modifier = this._modifiers[currIndex]; 59.13925 + if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) { 59.13926 + this._modifiers.splice(currIndex, 1); 59.13927 + this._states.splice(currIndex, 1); 59.13928 + } 59.13929 + if (item) { 59.13930 + result.push( 59.13931 + modifier.modify({ 59.13932 + origin: origin, 59.13933 + target: item.render() 59.13934 + }) 59.13935 + ); 59.13936 + } 59.13937 + sequence = sequence.getNext(); 59.13938 + currIndex++; 59.13939 + } 59.13940 + 59.13941 + if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform); 59.13942 + return { 59.13943 + transform: transform, 59.13944 + opacity: opacity, 59.13945 + size: size, 59.13946 + target: result 59.13947 + }; 59.13948 + }; 59.13949 + 59.13950 + module.exports = GridLayout; 59.13951 +}); 59.13952 + 59.13953 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.13954 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.13955 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.13956 + * 59.13957 + * Owner: felix@famo.us 59.13958 + * @license MPL 2.0 59.13959 + * @copyright Famous Industries, Inc. 2014 59.13960 + */ 59.13961 + 59.13962 +define('famous/views/HeaderFooterLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/OptionsManager'],function(require, exports, module) { 59.13963 + var Entity = require('famous/core/Entity'); 59.13964 + var RenderNode = require('famous/core/RenderNode'); 59.13965 + var Transform = require('famous/core/Transform'); 59.13966 + var OptionsManager = require('famous/core/OptionsManager'); 59.13967 + 59.13968 + /** 59.13969 + * A layout which will arrange three renderables into a header and footer area of defined size, 59.13970 + and a content area of flexible size. 59.13971 + * @class HeaderFooterLayout 59.13972 + * @constructor 59.13973 + * @param {Options} [options] An object of configurable options. 59.13974 + * @param {Number} [options.direction=HeaderFooterLayout.DIRECTION_Y] A direction of HeaderFooterLayout.DIRECTION_X 59.13975 + * lays your HeaderFooterLayout instance horizontally, and a direction of HeaderFooterLayout.DIRECTION_Y 59.13976 + * lays it out vertically. 59.13977 + * @param {Number} [options.headerSize=undefined] The amount of pixels allocated to the header node 59.13978 + * in the HeaderFooterLayout instance's direction. 59.13979 + * @param {Number} [options.footerSize=undefined] The amount of pixels allocated to the footer node 59.13980 + * in the HeaderFooterLayout instance's direction. 59.13981 + */ 59.13982 + function HeaderFooterLayout(options) { 59.13983 + this.options = Object.create(HeaderFooterLayout.DEFAULT_OPTIONS); 59.13984 + this._optionsManager = new OptionsManager(this.options); 59.13985 + if (options) this.setOptions(options); 59.13986 + 59.13987 + this._entityId = Entity.register(this); 59.13988 + 59.13989 + this.header = new RenderNode(); 59.13990 + this.footer = new RenderNode(); 59.13991 + this.content = new RenderNode(); 59.13992 + } 59.13993 + 59.13994 + /** 59.13995 + * When used as a value for your HeaderFooterLayout's direction option, causes it to lay out horizontally. 59.13996 + * 59.13997 + * @attribute DIRECTION_X 59.13998 + * @type Number 59.13999 + * @static 59.14000 + * @default 0 59.14001 + * @protected 59.14002 + */ 59.14003 + HeaderFooterLayout.DIRECTION_X = 0; 59.14004 + 59.14005 + /** 59.14006 + * When used as a value for your HeaderFooterLayout's direction option, causes it to lay out vertically. 59.14007 + * 59.14008 + * @attribute DIRECTION_Y 59.14009 + * @type Number 59.14010 + * @static 59.14011 + * @default 1 59.14012 + * @protected 59.14013 + */ 59.14014 + HeaderFooterLayout.DIRECTION_Y = 1; 59.14015 + 59.14016 + HeaderFooterLayout.DEFAULT_OPTIONS = { 59.14017 + direction: HeaderFooterLayout.DIRECTION_Y, 59.14018 + headerSize: undefined, 59.14019 + footerSize: undefined, 59.14020 + defaultHeaderSize: 0, 59.14021 + defaultFooterSize: 0 59.14022 + }; 59.14023 + 59.14024 + /** 59.14025 + * Generate a render spec from the contents of this component. 59.14026 + * 59.14027 + * @private 59.14028 + * @method render 59.14029 + * @return {Object} Render spec for this component 59.14030 + */ 59.14031 + HeaderFooterLayout.prototype.render = function render() { 59.14032 + return this._entityId; 59.14033 + }; 59.14034 + 59.14035 + /** 59.14036 + * Patches the HeaderFooterLayout instance's options with the passed-in ones. 59.14037 + * 59.14038 + * @method setOptions 59.14039 + * @param {Options} options An object of configurable options for the HeaderFooterLayout instance. 59.14040 + */ 59.14041 + HeaderFooterLayout.prototype.setOptions = function setOptions(options) { 59.14042 + return this._optionsManager.setOptions(options); 59.14043 + }; 59.14044 + 59.14045 + function _resolveNodeSize(node, defaultSize) { 59.14046 + var nodeSize = node.getSize(); 59.14047 + return nodeSize ? nodeSize[this.options.direction] : defaultSize; 59.14048 + } 59.14049 + 59.14050 + function _outputTransform(offset) { 59.14051 + if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return Transform.translate(offset, 0, 0); 59.14052 + else return Transform.translate(0, offset, 0); 59.14053 + } 59.14054 + 59.14055 + function _finalSize(directionSize, size) { 59.14056 + if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return [directionSize, size[1]]; 59.14057 + else return [size[0], directionSize]; 59.14058 + } 59.14059 + 59.14060 + /** 59.14061 + * Apply changes from this component to the corresponding document element. 59.14062 + * This includes changes to classes, styles, size, content, opacity, origin, 59.14063 + * and matrix transforms. 59.14064 + * 59.14065 + * @private 59.14066 + * @method commit 59.14067 + * @param {Context} context commit context 59.14068 + */ 59.14069 + HeaderFooterLayout.prototype.commit = function commit(context) { 59.14070 + var transform = context.transform; 59.14071 + var origin = context.origin; 59.14072 + var size = context.size; 59.14073 + var opacity = context.opacity; 59.14074 + 59.14075 + var headerSize = (this.options.headerSize !== undefined) ? this.options.headerSize : _resolveNodeSize.call(this, this.header, this.options.defaultHeaderSize); 59.14076 + var footerSize = (this.options.footerSize !== undefined) ? this.options.footerSize : _resolveNodeSize.call(this, this.footer, this.options.defaultFooterSize); 59.14077 + var contentSize = size[this.options.direction] - headerSize - footerSize; 59.14078 + 59.14079 + if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform); 59.14080 + 59.14081 + var result = [ 59.14082 + { 59.14083 + size: _finalSize.call(this, headerSize, size), 59.14084 + target: this.header.render() 59.14085 + }, 59.14086 + { 59.14087 + transform: _outputTransform.call(this, headerSize), 59.14088 + size: _finalSize.call(this, contentSize, size), 59.14089 + target: this.content.render() 59.14090 + }, 59.14091 + { 59.14092 + transform: _outputTransform.call(this, headerSize + contentSize), 59.14093 + size: _finalSize.call(this, footerSize, size), 59.14094 + target: this.footer.render() 59.14095 + } 59.14096 + ]; 59.14097 + 59.14098 + return { 59.14099 + transform: transform, 59.14100 + opacity: opacity, 59.14101 + size: size, 59.14102 + target: result 59.14103 + }; 59.14104 + }; 59.14105 + 59.14106 + module.exports = HeaderFooterLayout; 59.14107 +}); 59.14108 + 59.14109 +define('famous/views/Lightbox',['require','exports','module','famous/core/Transform','famous/core/Modifier','famous/core/RenderNode','famous/utilities/Utility','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) { 59.14110 + var Transform = require('famous/core/Transform'); 59.14111 + var Modifier = require('famous/core/Modifier'); 59.14112 + var RenderNode = require('famous/core/RenderNode'); 59.14113 + var Utility = require('famous/utilities/Utility'); 59.14114 + var OptionsManager = require('famous/core/OptionsManager'); 59.14115 + var Transitionable = require('famous/transitions/Transitionable'); 59.14116 + var TransitionableTransform = require('famous/transitions/TransitionableTransform'); 59.14117 + 59.14118 + /** 59.14119 + * Lightbox, using transitions, shows and hides different renderables. Lightbox can essentially be 59.14120 + * thought of as RenderController with a stateful implementation and interface. 59.14121 + * 59.14122 + * @class Lightbox 59.14123 + * @constructor 59.14124 + * @param {Options} [options] An object of configurable options. 59.14125 + * @param {Transform} [options.inTransform] The transform at the start of transitioning in a shown renderable. 59.14126 + * @param {Transform} [options.outTransform] The transform at the end of transitioning out a renderable. 59.14127 + * @param {Transform} [options.showTransform] The transform applied to your shown renderable in its state of equilibrium. 59.14128 + * @param {Number} [options.inOpacity] A number between one and zero that defines the state of a shown renderables opacity upon initially 59.14129 + * being transitioned in. 59.14130 + * @param {Number} [options.outOpacity] A number between one and zero that defines the state of a shown renderables opacity upon being 59.14131 + * fully transitioned out. 59.14132 + * @param {Number} [options.showOpacity] A number between one and zero that defines the state of a shown renderables opacity 59.14133 + * once succesfully transitioned in. 59.14134 + * @param {Array<Number>} [options.inOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables 59.14135 + * origin upon intially being transitioned in. 59.14136 + * @param {Array<Number>} [options.outOrigin] A two value array of numbers between one and zero that defines the state of a shown renderable 59.14137 + * once fully hidden. 59.14138 + * @param {Array<Number>} [options.showOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables 59.14139 + * origin upon succesfully being shown. 59.14140 + * @param {Transition} [options.inTransition=true] The transition in charge of showing a renderable. 59.14141 + * @param {Transition} [options.outTransition=true] The transition in charge of removing your previous renderable when 59.14142 + * you show a new one, or hiding your current renderable. 59.14143 + * @param {Boolean} [options.overlap=false] When showing a new renderable, overlap determines if the 59.14144 + * out transition of the old one executes concurrently with the in transition of the new one, 59.14145 + * or synchronously beforehand. 59.14146 + */ 59.14147 + function Lightbox(options) { 59.14148 + this.options = Object.create(Lightbox.DEFAULT_OPTIONS); 59.14149 + this._optionsManager = new OptionsManager(this.options); 59.14150 + 59.14151 + if (options) this.setOptions(options); 59.14152 + 59.14153 + this._showing = false; 59.14154 + this.nodes = []; 59.14155 + this.transforms = []; 59.14156 + this.states = []; 59.14157 + } 59.14158 + 59.14159 + Lightbox.DEFAULT_OPTIONS = { 59.14160 + inTransform: Transform.scale(0.001, 0.001, 0.001), 59.14161 + inOpacity: 0, 59.14162 + inOrigin: [0.5, 0.5], 59.14163 + outTransform: Transform.scale(0.001, 0.001, 0.001), 59.14164 + outOpacity: 0, 59.14165 + outOrigin: [0.5, 0.5], 59.14166 + showTransform: Transform.identity, 59.14167 + showOpacity: 1, 59.14168 + showOrigin: [0.5, 0.5], 59.14169 + inTransition: true, 59.14170 + outTransition: true, 59.14171 + overlap: false 59.14172 + }; 59.14173 + 59.14174 + /** 59.14175 + * Patches the Lightbox instance's options with the passed-in ones. 59.14176 + * 59.14177 + * @method setOptions 59.14178 + * @param {Options} options An object of configurable options for the Lightbox instance. 59.14179 + */ 59.14180 + Lightbox.prototype.setOptions = function setOptions(options) { 59.14181 + return this._optionsManager.setOptions(options); 59.14182 + }; 59.14183 + 59.14184 + /** 59.14185 + * Show displays the targeted renderable with a transition and an optional callback to 59.14186 + * execute afterwards. 59.14187 + * @method show 59.14188 + * @param {Object} renderable The renderable you want to show. 59.14189 + * @param {Transition} [transition] Overwrites the default transition in to display the 59.14190 + * passed-in renderable. 59.14191 + * @param {function} [callback] Executes after transitioning in the renderable. 59.14192 + */ 59.14193 + Lightbox.prototype.show = function show(renderable, transition, callback) { 59.14194 + if (!renderable) { 59.14195 + return this.hide(callback); 59.14196 + } 59.14197 + 59.14198 + if (transition instanceof Function) { 59.14199 + callback = transition; 59.14200 + transition = undefined; 59.14201 + } 59.14202 + 59.14203 + if (this._showing) { 59.14204 + if (this.options.overlap) this.hide(); 59.14205 + else { 59.14206 + return this.hide(this.show.bind(this, renderable, transition, callback)); 59.14207 + } 59.14208 + } 59.14209 + this._showing = true; 59.14210 + 59.14211 + var stateItem = { 59.14212 + transform: new TransitionableTransform(this.options.inTransform), 59.14213 + origin: new Transitionable(this.options.inOrigin), 59.14214 + opacity: new Transitionable(this.options.inOpacity) 59.14215 + }; 59.14216 + 59.14217 + var transform = new Modifier({ 59.14218 + transform: stateItem.transform, 59.14219 + opacity: stateItem.opacity, 59.14220 + origin: stateItem.origin 59.14221 + }); 59.14222 + var node = new RenderNode(); 59.14223 + node.add(transform).add(renderable); 59.14224 + this.nodes.push(node); 59.14225 + this.states.push(stateItem); 59.14226 + this.transforms.push(transform); 59.14227 + 59.14228 + var _cb = callback ? Utility.after(3, callback) : undefined; 59.14229 + 59.14230 + if (!transition) transition = this.options.inTransition; 59.14231 + stateItem.transform.set(this.options.showTransform, transition, _cb); 59.14232 + stateItem.opacity.set(this.options.showOpacity, transition, _cb); 59.14233 + stateItem.origin.set(this.options.showOrigin, transition, _cb); 59.14234 + }; 59.14235 + 59.14236 + /** 59.14237 + * Hide hides the currently displayed renderable with an out transition. 59.14238 + * @method hide 59.14239 + * @param {Transition} [transition] Overwrites the default transition in to hide the 59.14240 + * currently controlled renderable. 59.14241 + * @param {function} [callback] Executes after transitioning out the renderable. 59.14242 + */ 59.14243 + Lightbox.prototype.hide = function hide(transition, callback) { 59.14244 + if (!this._showing) return; 59.14245 + this._showing = false; 59.14246 + 59.14247 + if (transition instanceof Function) { 59.14248 + callback = transition; 59.14249 + transition = undefined; 59.14250 + } 59.14251 + 59.14252 + var node = this.nodes[this.nodes.length - 1]; 59.14253 + var transform = this.transforms[this.transforms.length - 1]; 59.14254 + var stateItem = this.states[this.states.length - 1]; 59.14255 + var _cb = Utility.after(3, function() { 59.14256 + this.nodes.splice(this.nodes.indexOf(node), 1); 59.14257 + this.states.splice(this.states.indexOf(stateItem), 1); 59.14258 + this.transforms.splice(this.transforms.indexOf(transform), 1); 59.14259 + if (callback) callback.call(this); 59.14260 + }.bind(this)); 59.14261 + 59.14262 + if (!transition) transition = this.options.outTransition; 59.14263 + stateItem.transform.set(this.options.outTransform, transition, _cb); 59.14264 + stateItem.opacity.set(this.options.outOpacity, transition, _cb); 59.14265 + stateItem.origin.set(this.options.outOrigin, transition, _cb); 59.14266 + }; 59.14267 + 59.14268 + /** 59.14269 + * Generate a render spec from the contents of this component. 59.14270 + * 59.14271 + * @private 59.14272 + * @method render 59.14273 + * @return {number} Render spec for this component 59.14274 + */ 59.14275 + Lightbox.prototype.render = function render() { 59.14276 + var result = []; 59.14277 + for (var i = 0; i < this.nodes.length; i++) { 59.14278 + result.push(this.nodes[i].render()); 59.14279 + } 59.14280 + return result; 59.14281 + }; 59.14282 + 59.14283 + module.exports = Lightbox; 59.14284 +}); 59.14285 + 59.14286 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.14287 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.14288 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.14289 + * 59.14290 + * Owner: david@famo.us 59.14291 + * @license MPL 2.0 59.14292 + * @copyright Famous Industries, Inc. 2014 59.14293 + */ 59.14294 + 59.14295 +define('famous/physics/forces/Drag',['require','exports','module','./Force'],function(require, exports, module) { 59.14296 + var Force = require('./Force'); 59.14297 + 59.14298 + /** 59.14299 + * Drag is a force that opposes velocity. Attach it to the physics engine 59.14300 + * to slow down a physics body in motion. 59.14301 + * 59.14302 + * @class Drag 59.14303 + * @constructor 59.14304 + * @extends Force 59.14305 + * @param {Object} options options to set on drag 59.14306 + */ 59.14307 + function Drag(options) { 59.14308 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.14309 + if (options) this.setOptions(options); 59.14310 + 59.14311 + Force.call(this); 59.14312 + } 59.14313 + 59.14314 + Drag.prototype = Object.create(Force.prototype); 59.14315 + Drag.prototype.constructor = Drag; 59.14316 + 59.14317 + /** 59.14318 + * @property Drag.FORCE_FUNCTIONS 59.14319 + * @type Object 59.14320 + * @protected 59.14321 + * @static 59.14322 + */ 59.14323 + Drag.FORCE_FUNCTIONS = { 59.14324 + 59.14325 + /** 59.14326 + * A drag force proportional to the velocity 59.14327 + * @attribute LINEAR 59.14328 + * @type Function 59.14329 + * @param {Vector} velocity 59.14330 + * @return {Vector} drag force 59.14331 + */ 59.14332 + LINEAR : function(velocity) { 59.14333 + return velocity; 59.14334 + }, 59.14335 + 59.14336 + /** 59.14337 + * A drag force proportional to the square of the velocity 59.14338 + * @attribute QUADRATIC 59.14339 + * @type Function 59.14340 + * @param {Vector} velocity 59.14341 + * @return {Vector} drag force 59.14342 + */ 59.14343 + QUADRATIC : function(velocity) { 59.14344 + return velocity.mult(velocity.norm()); 59.14345 + } 59.14346 + }; 59.14347 + 59.14348 + /** 59.14349 + * @property Drag.DEFAULT_OPTIONS 59.14350 + * @type Object 59.14351 + * @protected 59.14352 + * @static 59.14353 + */ 59.14354 + Drag.DEFAULT_OPTIONS = { 59.14355 + 59.14356 + /** 59.14357 + * The strength of the force 59.14358 + * Range : [0, 0.1] 59.14359 + * @attribute strength 59.14360 + * @type Number 59.14361 + * @default 0.01 59.14362 + */ 59.14363 + strength : 0.01, 59.14364 + 59.14365 + /** 59.14366 + * The type of opposing force 59.14367 + * @attribute forceFunction 59.14368 + * @type Function 59.14369 + */ 59.14370 + forceFunction : Drag.FORCE_FUNCTIONS.LINEAR 59.14371 + }; 59.14372 + 59.14373 + /** 59.14374 + * Adds a drag force to a physics body's force accumulator. 59.14375 + * 59.14376 + * @method applyForce 59.14377 + * @param targets {Array.Body} Array of bodies to apply drag force to. 59.14378 + */ 59.14379 + Drag.prototype.applyForce = function applyForce(targets) { 59.14380 + var strength = this.options.strength; 59.14381 + var forceFunction = this.options.forceFunction; 59.14382 + var force = this.force; 59.14383 + for (var index = 0; index < targets.length; index++) { 59.14384 + var particle = targets[index]; 59.14385 + forceFunction(particle.velocity).mult(-strength).put(force); 59.14386 + particle.applyForce(force); 59.14387 + } 59.14388 + }; 59.14389 + 59.14390 + /** 59.14391 + * Basic options setter 59.14392 + * 59.14393 + * @method setOptions 59.14394 + * @param {Objects} options 59.14395 + */ 59.14396 + Drag.prototype.setOptions = function setOptions(options) { 59.14397 + for (var key in options) this.options[key] = options[key]; 59.14398 + }; 59.14399 + 59.14400 + module.exports = Drag; 59.14401 +}); 59.14402 + 59.14403 +define('famous/views/Scroller',['require','exports','module','famous/core/Entity','famous/core/Group','famous/core/OptionsManager','famous/core/Transform','famous/utilities/Utility','famous/core/ViewSequence','famous/core/EventHandler'],function(require, exports, module) { 59.14404 + var Entity = require('famous/core/Entity'); 59.14405 + var Group = require('famous/core/Group'); 59.14406 + var OptionsManager = require('famous/core/OptionsManager'); 59.14407 + var Transform = require('famous/core/Transform'); 59.14408 + var Utility = require('famous/utilities/Utility'); 59.14409 + var ViewSequence = require('famous/core/ViewSequence'); 59.14410 + var EventHandler = require('famous/core/EventHandler'); 59.14411 + 59.14412 + /** 59.14413 + * Scroller lays out a collection of renderables, and will browse through them based on 59.14414 + * accessed position. Scroller also broadcasts an 'edgeHit' event, with a position property of the location of the edge, 59.14415 + * when you've hit the 'edges' of it's renderable collection. 59.14416 + * @class Scroller 59.14417 + * @constructor 59.14418 + * @event error 59.14419 + * @param {Options} [options] An object of configurable options. 59.14420 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 59.14421 + * module, this option will lay out the Scroller instance's renderables either horizontally 59.14422 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 59.14423 + * to just use integers as well. 59.14424 + * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scroller will display content in. 59.14425 + * @param {Number} [margin=undefined] The size of the area (in pixels) that Scroller will process renderables' associated calculations in. 59.14426 + */ 59.14427 + function Scroller(options) { 59.14428 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.14429 + this._optionsManager = new OptionsManager(this.options); 59.14430 + if (options) this._optionsManager.setOptions(options); 59.14431 + 59.14432 + this._node = null; 59.14433 + this._position = 0; 59.14434 + 59.14435 + // used for shifting nodes 59.14436 + this._positionOffset = 0; 59.14437 + 59.14438 + this._positionGetter = null; 59.14439 + this._outputFunction = null; 59.14440 + this._masterOutputFunction = null; 59.14441 + this.outputFrom(); 59.14442 + 59.14443 + this._onEdge = 0; // -1 for top, 1 for bottom 59.14444 + 59.14445 + this.group = new Group(); 59.14446 + this.group.add({render: _innerRender.bind(this)}); 59.14447 + 59.14448 + this._entityId = Entity.register(this); 59.14449 + this._size = [undefined, undefined]; 59.14450 + this._contextSize = [undefined, undefined]; 59.14451 + 59.14452 + this._eventInput = new EventHandler(); 59.14453 + this._eventOutput = new EventHandler(); 59.14454 + 59.14455 + EventHandler.setInputHandler(this, this._eventInput); 59.14456 + EventHandler.setOutputHandler(this, this._eventOutput); 59.14457 + } 59.14458 + 59.14459 + Scroller.DEFAULT_OPTIONS = { 59.14460 + direction: Utility.Direction.Y, 59.14461 + margin: 0, 59.14462 + clipSize: undefined, 59.14463 + groupScroll: false 59.14464 + }; 59.14465 + 59.14466 + function _sizeForDir(size) { 59.14467 + if (!size) size = this._contextSize; 59.14468 + var dimension = (this.options.direction === Utility.Direction.X) ? 0 : 1; 59.14469 + return (size[dimension] === undefined) ? this._contextSize[dimension] : size[dimension]; 59.14470 + } 59.14471 + 59.14472 + function _output(node, offset, target) { 59.14473 + var size = node.getSize ? node.getSize() : this._contextSize; 59.14474 + var transform = this._outputFunction(offset); 59.14475 + target.push({transform: transform, target: node.render()}); 59.14476 + return _sizeForDir.call(this, size); 59.14477 + } 59.14478 + 59.14479 + function _getClipSize() { 59.14480 + if (this.options.clipSize) return this.options.clipSize; 59.14481 + else return _sizeForDir.call(this, this._contextSize); 59.14482 + } 59.14483 + 59.14484 + /** 59.14485 + * Patches the Scroller instance's options with the passed-in ones. 59.14486 + * @method setOptions 59.14487 + * @param {Options} options An object of configurable options for the Scroller instance. 59.14488 + */ 59.14489 + Scroller.prototype.setOptions = function setOptions(options) { 59.14490 + this._optionsManager.setOptions(options); 59.14491 + 59.14492 + if (this.options.groupScroll) { 59.14493 + this.group.pipe(this._eventOutput); 59.14494 + } 59.14495 + else { 59.14496 + this.group.unpipe(this._eventOutput); 59.14497 + } 59.14498 + }; 59.14499 + 59.14500 + /** 59.14501 + * Tells you if the Scroller instance is on an edge. 59.14502 + * @method onEdge 59.14503 + * @return {Boolean} Whether the Scroller instance is on an edge or not. 59.14504 + */ 59.14505 + Scroller.prototype.onEdge = function onEdge() { 59.14506 + return this._onEdge; 59.14507 + }; 59.14508 + 59.14509 + /** 59.14510 + * Allows you to overwrite the way Scroller lays out it's renderables. Scroller will 59.14511 + * pass an offset into the function. By default the Scroller instance just translates each node 59.14512 + * in it's direction by the passed-in offset. 59.14513 + * Scroller will translate each renderable down 59.14514 + * @method outputFrom 59.14515 + * @param {Function} fn A function that takes an offset and returns a transform. 59.14516 + * @param {Function} [masterFn] 59.14517 + */ 59.14518 + Scroller.prototype.outputFrom = function outputFrom(fn, masterFn) { 59.14519 + if (!fn) { 59.14520 + fn = function(offset) { 59.14521 + return (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset); 59.14522 + }.bind(this); 59.14523 + if (!masterFn) masterFn = fn; 59.14524 + } 59.14525 + this._outputFunction = fn; 59.14526 + this._masterOutputFunction = masterFn ? masterFn : function(offset) { 59.14527 + return Transform.inverse(fn(-offset)); 59.14528 + }; 59.14529 + }; 59.14530 + 59.14531 + /** 59.14532 + * The Scroller instance's method for reading from an external position. Scroller uses 59.14533 + * the external position to actually scroll through it's renderables. 59.14534 + * @method positionFrom 59.14535 + * @param {Getter} position Can be either a function that returns a position, 59.14536 + * or an object with a get method that returns a position. 59.14537 + */ 59.14538 + Scroller.prototype.positionFrom = function positionFrom(position) { 59.14539 + if (position instanceof Function) this._positionGetter = position; 59.14540 + else if (position && position.get) this._positionGetter = position.get.bind(position); 59.14541 + else { 59.14542 + this._positionGetter = null; 59.14543 + this._position = position; 59.14544 + } 59.14545 + if (this._positionGetter) this._position = this._positionGetter.call(this); 59.14546 + }; 59.14547 + 59.14548 + /** 59.14549 + * Sets the collection of renderables under the Scroller instance's control. 59.14550 + * 59.14551 + * @method sequenceFrom 59.14552 + * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence. 59.14553 + * @chainable 59.14554 + */ 59.14555 + Scroller.prototype.sequenceFrom = function sequenceFrom(node) { 59.14556 + if (node instanceof Array) node = new ViewSequence({array: node}); 59.14557 + this._node = node; 59.14558 + this._positionOffset = 0; 59.14559 + }; 59.14560 + 59.14561 + /** 59.14562 + * Returns the width and the height of the Scroller instance. 59.14563 + * 59.14564 + * @method getSize 59.14565 + * @return {Array} A two value array of the Scroller instance's current width and height (in that order). 59.14566 + */ 59.14567 + Scroller.prototype.getSize = function getSize(actual) { 59.14568 + return actual ? this._contextSize : this._size; 59.14569 + }; 59.14570 + 59.14571 + /** 59.14572 + * Generate a render spec from the contents of this component. 59.14573 + * 59.14574 + * @private 59.14575 + * @method render 59.14576 + * @return {number} Render spec for this component 59.14577 + */ 59.14578 + Scroller.prototype.render = function render() { 59.14579 + if (!this._node) return null; 59.14580 + if (this._positionGetter) this._position = this._positionGetter.call(this); 59.14581 + return this._entityId; 59.14582 + }; 59.14583 + 59.14584 + /** 59.14585 + * Apply changes from this component to the corresponding document element. 59.14586 + * This includes changes to classes, styles, size, content, opacity, origin, 59.14587 + * and matrix transforms. 59.14588 + * 59.14589 + * @private 59.14590 + * @method commit 59.14591 + * @param {Context} context commit context 59.14592 + */ 59.14593 + Scroller.prototype.commit = function commit(context) { 59.14594 + var transform = context.transform; 59.14595 + var opacity = context.opacity; 59.14596 + var origin = context.origin; 59.14597 + var size = context.size; 59.14598 + 59.14599 + // reset edge detection on size change 59.14600 + if (!this.options.clipSize && (size[0] !== this._contextSize[0] || size[1] !== this._contextSize[1])) { 59.14601 + this._onEdge = 0; 59.14602 + this._contextSize[0] = size[0]; 59.14603 + this._contextSize[1] = size[1]; 59.14604 + 59.14605 + if (this.options.direction === Utility.Direction.X) { 59.14606 + this._size[0] = _getClipSize.call(this); 59.14607 + this._size[1] = undefined; 59.14608 + } 59.14609 + else { 59.14610 + this._size[0] = undefined; 59.14611 + this._size[1] = _getClipSize.call(this); 59.14612 + } 59.14613 + } 59.14614 + 59.14615 + var scrollTransform = this._masterOutputFunction(-this._position); 59.14616 + 59.14617 + return { 59.14618 + transform: Transform.multiply(transform, scrollTransform), 59.14619 + size: size, 59.14620 + opacity: opacity, 59.14621 + origin: origin, 59.14622 + target: this.group.render() 59.14623 + }; 59.14624 + }; 59.14625 + 59.14626 + function _normalizeState() { 59.14627 + var nodeSize = _sizeForDir.call(this, this._node.getSize()); 59.14628 + var nextNode = this._node && this._node.getNext ? this._node.getNext() : null; 59.14629 + while (nextNode && this._position + this._positionOffset >= nodeSize) { 59.14630 + this._positionOffset -= nodeSize; 59.14631 + this._node = nextNode; 59.14632 + nodeSize = _sizeForDir.call(this, this._node.getSize()); 59.14633 + nextNode = this._node && this._node.getNext ? this._node.getNext() : null; 59.14634 + } 59.14635 + var prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null; 59.14636 + while (prevNode && this._position + this._positionOffset < 0) { 59.14637 + var prevNodeSize = _sizeForDir.call(this, prevNode.getSize()); 59.14638 + this._positionOffset += prevNodeSize; 59.14639 + this._node = prevNode; 59.14640 + prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null; 59.14641 + } 59.14642 + } 59.14643 + 59.14644 + function _innerRender() { 59.14645 + var size = null; 59.14646 + var position = this._position; 59.14647 + var result = []; 59.14648 + 59.14649 + this._onEdge = 0; 59.14650 + 59.14651 + var offset = -this._positionOffset; 59.14652 + var clipSize = _getClipSize.call(this); 59.14653 + var currNode = this._node; 59.14654 + while (currNode && offset - position < clipSize + this.options.margin) { 59.14655 + offset += _output.call(this, currNode, offset, result); 59.14656 + currNode = currNode.getNext ? currNode.getNext() : null; 59.14657 + } 59.14658 + 59.14659 + var sizeNode = this._node; 59.14660 + var nodesSize = _sizeForDir.call(this, sizeNode.getSize()); 59.14661 + if (offset < clipSize) { 59.14662 + while (sizeNode && nodesSize < clipSize) { 59.14663 + sizeNode = sizeNode.getPrevious(); 59.14664 + if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize()); 59.14665 + } 59.14666 + sizeNode = this._node; 59.14667 + while (sizeNode && nodesSize < clipSize) { 59.14668 + sizeNode = sizeNode.getNext(); 59.14669 + if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize()); 59.14670 + } 59.14671 + } 59.14672 + 59.14673 + var edgeSize = (nodesSize !== undefined && nodesSize < clipSize) ? nodesSize : clipSize; 59.14674 + 59.14675 + if (!currNode && offset - position <= edgeSize) { 59.14676 + this._onEdge = 1; 59.14677 + this._eventOutput.emit('edgeHit', { 59.14678 + position: offset - edgeSize 59.14679 + }); 59.14680 + } 59.14681 + else if (!this._node.getPrevious() && position <= 0) { 59.14682 + this._onEdge = -1; 59.14683 + this._eventOutput.emit('edgeHit', { 59.14684 + position: 0 59.14685 + }); 59.14686 + } 59.14687 + 59.14688 + // backwards 59.14689 + currNode = (this._node && this._node.getPrevious) ? this._node.getPrevious() : null; 59.14690 + offset = -this._positionOffset; 59.14691 + if (currNode) { 59.14692 + size = currNode.getSize ? currNode.getSize() : this._contextSize; 59.14693 + offset -= _sizeForDir.call(this, size); 59.14694 + } 59.14695 + 59.14696 + while (currNode && ((offset - position) > -(_getClipSize.call(this) + this.options.margin))) { 59.14697 + _output.call(this, currNode, offset, result); 59.14698 + currNode = currNode.getPrevious ? currNode.getPrevious() : null; 59.14699 + if (currNode) { 59.14700 + size = currNode.getSize ? currNode.getSize() : this._contextSize; 59.14701 + offset -= _sizeForDir.call(this, size); 59.14702 + } 59.14703 + } 59.14704 + 59.14705 + _normalizeState.call(this); 59.14706 + return result; 59.14707 + } 59.14708 + 59.14709 + module.exports = Scroller; 59.14710 +}); 59.14711 + 59.14712 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.14713 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.14714 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.14715 + * 59.14716 + * Owner: felix@famo.us 59.14717 + * @license MPL 2.0 59.14718 + * @copyright Famous Industries, Inc. 2014 59.14719 + */ 59.14720 + 59.14721 +define('famous/views/Scrollview',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Drag','famous/physics/forces/Spring','famous/core/EventHandler','famous/core/OptionsManager','famous/core/ViewSequence','famous/views/Scroller','famous/utilities/Utility','famous/inputs/GenericSync','famous/inputs/ScrollSync','famous/inputs/TouchSync'],function(require, exports, module) { 59.14722 + var PhysicsEngine = require('famous/physics/PhysicsEngine'); 59.14723 + var Particle = require('famous/physics/bodies/Particle'); 59.14724 + var Drag = require('famous/physics/forces/Drag'); 59.14725 + var Spring = require('famous/physics/forces/Spring'); 59.14726 + 59.14727 + var EventHandler = require('famous/core/EventHandler'); 59.14728 + var OptionsManager = require('famous/core/OptionsManager'); 59.14729 + var ViewSequence = require('famous/core/ViewSequence'); 59.14730 + var Scroller = require('famous/views/Scroller'); 59.14731 + var Utility = require('famous/utilities/Utility'); 59.14732 + 59.14733 + var GenericSync = require('famous/inputs/GenericSync'); 59.14734 + var ScrollSync = require('famous/inputs/ScrollSync'); 59.14735 + var TouchSync = require('famous/inputs/TouchSync'); 59.14736 + GenericSync.register({scroll : ScrollSync, touch : TouchSync}); 59.14737 + 59.14738 + /** 59.14739 + * Scrollview will lay out a collection of renderables sequentially in the specified direction, and will 59.14740 + * allow you to scroll through them with mousewheel or touch events. 59.14741 + * @class Scrollview 59.14742 + * @constructor 59.14743 + * @param {Options} [options] An object of configurable options. 59.14744 + * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility 59.14745 + * module, this option will lay out the Scrollview instance's renderables either horizontally 59.14746 + * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free 59.14747 + * to just use integers as well. 59.14748 + * @param {Boolean} [options.rails=true] When true, Scrollview's genericSync will only process input in it's primary access. 59.14749 + * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scrollview will display content in. 59.14750 + * @param {Number} [margin=undefined] The size of the area (in pixels) that Scrollview will process renderables' associated calculations in. 59.14751 + * @param {Number} [friction=0.001] Input resistance proportional to the velocity of the input. 59.14752 + * Controls the feel of the Scrollview instance at low velocities. 59.14753 + * @param {Number} [drag=0.0001] Input resistance proportional to the square of the velocity of the input. 59.14754 + * Affects Scrollview instance more prominently at high velocities. 59.14755 + * @param {Number} [edgeGrip=0.5] A coefficient for resistance against after-touch momentum. 59.14756 + * @param {Number} [egePeriod=300] Sets the period on the spring that handles the physics associated 59.14757 + * with hitting the end of a scrollview. 59.14758 + * @param {Number} [edgeDamp=1] Sets the damping on the spring that handles the physics associated 59.14759 + * with hitting the end of a scrollview. 59.14760 + * @param {Boolean} [paginated=false] A paginated scrollview will scroll through items discretely 59.14761 + * rather than continously. 59.14762 + * @param {Number} [pagePeriod=500] Sets the period on the spring that handles the physics associated 59.14763 + * with pagination. 59.14764 + * @param {Number} [pageDamp=0.8] Sets the damping on the spring that handles the physics associated 59.14765 + * with pagination. 59.14766 + * @param {Number} [pageStopSpeed=Infinity] The threshold for determining the amount of velocity 59.14767 + * required to trigger pagination. The lower the threshold, the easier it is to scroll continuosly. 59.14768 + * @param {Number} [pageSwitchSpeed=1] The threshold for momentum-based velocity pagination. 59.14769 + * @param {Number} [speedLimit=10] The highest scrolling speed you can reach. 59.14770 + */ 59.14771 + function Scrollview(options) { 59.14772 + this.options = Object.create(Scrollview.DEFAULT_OPTIONS); 59.14773 + this._optionsManager = new OptionsManager(this.options); 59.14774 + 59.14775 + this._node = null; 59.14776 + 59.14777 + this._physicsEngine = new PhysicsEngine(); 59.14778 + this._particle = new Particle(); 59.14779 + this._physicsEngine.addBody(this._particle); 59.14780 + 59.14781 + this.spring = new Spring({anchor: [0, 0, 0]}); 59.14782 + 59.14783 + this.drag = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.QUADRATIC}); 59.14784 + this.friction = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.LINEAR}); 59.14785 + 59.14786 + this.sync = new GenericSync(['scroll', 'touch'], {direction : this.options.direction}); 59.14787 + 59.14788 + this._eventInput = new EventHandler(); 59.14789 + this._eventOutput = new EventHandler(); 59.14790 + 59.14791 + this._eventInput.pipe(this.sync); 59.14792 + this.sync.pipe(this._eventInput); 59.14793 + 59.14794 + EventHandler.setInputHandler(this, this._eventInput); 59.14795 + EventHandler.setOutputHandler(this, this._eventOutput); 59.14796 + 59.14797 + this._touchCount = 0; 59.14798 + this._springState = 0; 59.14799 + this._onEdge = 0; // -1 for top, 1 for bottom 59.14800 + this._pageSpringPosition = 0; 59.14801 + this._edgeSpringPosition = 0; 59.14802 + this._touchVelocity = undefined; 59.14803 + this._earlyEnd = false; 59.14804 + this._needsPaginationCheck = false; 59.14805 + 59.14806 + this._scroller = new Scroller(); 59.14807 + this._scroller.positionFrom(this.getPosition.bind(this)); 59.14808 + 59.14809 + this.setOptions(options); 59.14810 + 59.14811 + _bindEvents.call(this); 59.14812 + } 59.14813 + 59.14814 + /** @const */ 59.14815 + var TOLERANCE = 0.5; 59.14816 + 59.14817 + Scrollview.DEFAULT_OPTIONS = { 59.14818 + direction: Utility.Direction.Y, 59.14819 + rails: true, 59.14820 + friction: 0.001, 59.14821 + drag: 0.0001, 59.14822 + edgeGrip: 0.5, 59.14823 + edgePeriod: 300, 59.14824 + edgeDamp: 1, 59.14825 + margin: 1000, // mostly safe 59.14826 + paginated: false, 59.14827 + pagePeriod: 500, 59.14828 + pageDamp: 0.8, 59.14829 + pageStopSpeed: 10, 59.14830 + pageSwitchSpeed: 0.5, 59.14831 + speedLimit: 10, 59.14832 + groupScroll: false 59.14833 + }; 59.14834 + 59.14835 + /** @enum */ 59.14836 + var SpringStates = { 59.14837 + NONE: 0, 59.14838 + EDGE: 1, 59.14839 + PAGE: 2 59.14840 + }; 59.14841 + 59.14842 + function _handleStart(event) { 59.14843 + this._touchCount = event.count; 59.14844 + if (event.count === undefined) this._touchCount = 1; 59.14845 + 59.14846 + _detachAgents.call(this); 59.14847 + this.setVelocity(0); 59.14848 + this._touchVelocity = 0; 59.14849 + this._earlyEnd = false; 59.14850 + } 59.14851 + 59.14852 + function _handleMove(event) { 59.14853 + var velocity = -event.velocity; 59.14854 + var delta = -event.delta; 59.14855 + 59.14856 + if (this._onEdge && event.slip) { 59.14857 + if ((velocity < 0 && this._onEdge < 0) || (velocity > 0 && this._onEdge > 0)) { 59.14858 + if (!this._earlyEnd) { 59.14859 + _handleEnd.call(this, event); 59.14860 + this._earlyEnd = true; 59.14861 + } 59.14862 + } 59.14863 + else if (this._earlyEnd && (Math.abs(velocity) > Math.abs(this.getVelocity()))) { 59.14864 + _handleStart.call(this, event); 59.14865 + } 59.14866 + } 59.14867 + if (this._earlyEnd) return; 59.14868 + this._touchVelocity = velocity; 59.14869 + 59.14870 + if (event.slip) this.setVelocity(velocity); 59.14871 + else this.setPosition(this.getPosition() + delta); 59.14872 + } 59.14873 + 59.14874 + function _handleEnd(event) { 59.14875 + this._touchCount = event.count || 0; 59.14876 + if (!this._touchCount) { 59.14877 + _detachAgents.call(this); 59.14878 + if (this._onEdge) _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE); 59.14879 + _attachAgents.call(this); 59.14880 + var velocity = -event.velocity; 59.14881 + var speedLimit = this.options.speedLimit; 59.14882 + if (event.slip) speedLimit *= this.options.edgeGrip; 59.14883 + if (velocity < -speedLimit) velocity = -speedLimit; 59.14884 + else if (velocity > speedLimit) velocity = speedLimit; 59.14885 + this.setVelocity(velocity); 59.14886 + this._touchVelocity = undefined; 59.14887 + this._needsPaginationCheck = true; 59.14888 + } 59.14889 + } 59.14890 + 59.14891 + function _bindEvents() { 59.14892 + this._eventInput.bindThis(this); 59.14893 + this._eventInput.on('start', _handleStart); 59.14894 + this._eventInput.on('update', _handleMove); 59.14895 + this._eventInput.on('end', _handleEnd); 59.14896 + 59.14897 + this._scroller.on('edgeHit', function(data) { 59.14898 + this._edgeSpringPosition = data.position; 59.14899 + }.bind(this)); 59.14900 + } 59.14901 + 59.14902 + function _attachAgents() { 59.14903 + if (this._springState) this._physicsEngine.attach([this.spring], this._particle); 59.14904 + else this._physicsEngine.attach([this.drag, this.friction], this._particle); 59.14905 + } 59.14906 + 59.14907 + function _detachAgents() { 59.14908 + this._springState = SpringStates.NONE; 59.14909 + this._physicsEngine.detachAll(); 59.14910 + } 59.14911 + 59.14912 + function _nodeSizeForDirection(node) { 59.14913 + var direction = this.options.direction; 59.14914 + var nodeSize = (node.getSize() || this._scroller.getSize())[direction]; 59.14915 + if (!nodeSize) nodeSize = this._scroller.getSize()[direction]; 59.14916 + return nodeSize; 59.14917 + } 59.14918 + 59.14919 + function _handleEdge(edgeDetected) { 59.14920 + if (!this._onEdge && edgeDetected) { 59.14921 + this.sync.setOptions({scale: this.options.edgeGrip}); 59.14922 + if (!this._touchCount && this._springState !== SpringStates.EDGE) { 59.14923 + _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE); 59.14924 + } 59.14925 + } 59.14926 + else if (this._onEdge && !edgeDetected) { 59.14927 + this.sync.setOptions({scale: 1}); 59.14928 + if (this._springState && Math.abs(this.getVelocity()) < 0.001) { 59.14929 + // reset agents, detaching the spring 59.14930 + _detachAgents.call(this); 59.14931 + _attachAgents.call(this); 59.14932 + } 59.14933 + } 59.14934 + this._onEdge = edgeDetected; 59.14935 + } 59.14936 + 59.14937 + function _handlePagination() { 59.14938 + if (!this._needsPaginationCheck) return; 59.14939 + 59.14940 + if (this._touchCount) return; 59.14941 + if (this._springState === SpringStates.EDGE) return; 59.14942 + 59.14943 + var velocity = this.getVelocity(); 59.14944 + if (Math.abs(velocity) >= this.options.pageStopSpeed) return; 59.14945 + 59.14946 + var position = this.getPosition(); 59.14947 + var velocitySwitch = Math.abs(velocity) > this.options.pageSwitchSpeed; 59.14948 + 59.14949 + // parameters to determine when to switch 59.14950 + var nodeSize = _nodeSizeForDirection.call(this, this._node); 59.14951 + var positionNext = position > 0.5 * nodeSize; 59.14952 + var velocityNext = velocity > 0; 59.14953 + 59.14954 + if ((positionNext && !velocitySwitch) || (velocitySwitch && velocityNext)) this.goToNextPage(); 59.14955 + else _setSpring.call(this, 0, SpringStates.PAGE); 59.14956 + 59.14957 + this._needsPaginationCheck = false; 59.14958 + } 59.14959 + 59.14960 + function _setSpring(position, springState) { 59.14961 + var springOptions; 59.14962 + if (springState === SpringStates.EDGE) { 59.14963 + this._edgeSpringPosition = position; 59.14964 + springOptions = { 59.14965 + anchor: [this._edgeSpringPosition, 0, 0], 59.14966 + period: this.options.edgePeriod, 59.14967 + dampingRatio: this.options.edgeDamp 59.14968 + }; 59.14969 + } 59.14970 + else if (springState === SpringStates.PAGE) { 59.14971 + this._pageSpringPosition = position; 59.14972 + springOptions = { 59.14973 + anchor: [this._pageSpringPosition, 0, 0], 59.14974 + period: this.options.pagePeriod, 59.14975 + dampingRatio: this.options.pageDamp 59.14976 + }; 59.14977 + } 59.14978 + 59.14979 + this.spring.setOptions(springOptions); 59.14980 + if (springState && !this._springState) { 59.14981 + _detachAgents.call(this); 59.14982 + this._springState = springState; 59.14983 + _attachAgents.call(this); 59.14984 + } 59.14985 + this._springState = springState; 59.14986 + } 59.14987 + 59.14988 + function _normalizeState() { 59.14989 + var position = this.getPosition(); 59.14990 + var nodeSize = _nodeSizeForDirection.call(this, this._node); 59.14991 + var nextNode = this._node.getNext(); 59.14992 + 59.14993 + while (position > nodeSize + TOLERANCE && nextNode) { 59.14994 + _shiftOrigin.call(this, -nodeSize); 59.14995 + position -= nodeSize; 59.14996 + this._scroller.sequenceFrom(nextNode); 59.14997 + this._node = nextNode; 59.14998 + nextNode = this._node.getNext(); 59.14999 + nodeSize = _nodeSizeForDirection.call(this, this._node); 59.15000 + } 59.15001 + 59.15002 + var previousNode = this._node.getPrevious(); 59.15003 + var previousNodeSize; 59.15004 + 59.15005 + while (position < -TOLERANCE && previousNode) { 59.15006 + previousNodeSize = _nodeSizeForDirection.call(this, previousNode); 59.15007 + this._scroller.sequenceFrom(previousNode); 59.15008 + this._node = previousNode; 59.15009 + _shiftOrigin.call(this, previousNodeSize); 59.15010 + position += previousNodeSize; 59.15011 + previousNode = this._node.getPrevious(); 59.15012 + } 59.15013 + } 59.15014 + 59.15015 + function _shiftOrigin(amount) { 59.15016 + this._edgeSpringPosition += amount; 59.15017 + this._pageSpringPosition += amount; 59.15018 + this.setPosition(this.getPosition() + amount); 59.15019 + if (this._springState === SpringStates.EDGE) { 59.15020 + this.spring.setOptions({anchor: [this._edgeSpringPosition, 0, 0]}); 59.15021 + } 59.15022 + else if (this._springState === SpringStates.PAGE) { 59.15023 + this.spring.setOptions({anchor: [this._pageSpringPosition, 0, 0]}); 59.15024 + } 59.15025 + } 59.15026 + 59.15027 + Scrollview.prototype.outputFrom = function outputFrom() { 59.15028 + return this._scroller.outputFrom.apply(this._scroller, arguments); 59.15029 + }; 59.15030 + 59.15031 + /** 59.15032 + * Returns the position associated with the Scrollview instance's current node 59.15033 + * (generally the node currently at the top). 59.15034 + * @method getPosition 59.15035 + * @param {number} [node] If specified, returns the position of the node at that index in the 59.15036 + * Scrollview instance's currently managed collection. 59.15037 + * @return {number} The position of either the specified node, or the Scrollview's current Node, 59.15038 + * in pixels translated. 59.15039 + */ 59.15040 + Scrollview.prototype.getPosition = function getPosition() { 59.15041 + return this._particle.getPosition1D(); 59.15042 + }; 59.15043 + 59.15044 + /** 59.15045 + * Sets position of the physics particle that controls Scrollview instance's "position" 59.15046 + * @method setPosition 59.15047 + * @param {number} x The amount of pixels you want your scrollview to progress by. 59.15048 + */ 59.15049 + Scrollview.prototype.setPosition = function setPosition(x) { 59.15050 + this._particle.setPosition1D(x); 59.15051 + }; 59.15052 + 59.15053 + /** 59.15054 + * Returns the Scrollview instance's velocity. 59.15055 + * @method getVelocity 59.15056 + * @return {Number} The velocity. 59.15057 + */ 59.15058 + 59.15059 + Scrollview.prototype.getVelocity = function getVelocity() { 59.15060 + return this._touchCount ? this._touchVelocity : this._particle.getVelocity1D(); 59.15061 + }; 59.15062 + 59.15063 + /** 59.15064 + * Sets the Scrollview instance's velocity. Until affected by input or another call of setVelocity 59.15065 + * the Scrollview instance will scroll at the passed-in velocity. 59.15066 + * @method setVelocity 59.15067 + * @param {number} v The magnitude of the velocity. 59.15068 + */ 59.15069 + Scrollview.prototype.setVelocity = function setVelocity(v) { 59.15070 + this._particle.setVelocity1D(v); 59.15071 + }; 59.15072 + 59.15073 + /** 59.15074 + * Patches the Scrollview instance's options with the passed-in ones. 59.15075 + * @method setOptions 59.15076 + * @param {Options} options An object of configurable options for the Scrollview instance. 59.15077 + */ 59.15078 + Scrollview.prototype.setOptions = function setOptions(options) { 59.15079 + if (options) { 59.15080 + if (options.direction !== undefined) { 59.15081 + if (options.direction === 'x') options.direction = Utility.Direction.X; 59.15082 + else if (options.direction === 'y') options.direction = Utility.Direction.Y; 59.15083 + } 59.15084 + 59.15085 + this._scroller.setOptions(options); 59.15086 + this._optionsManager.setOptions(options); 59.15087 + } 59.15088 + 59.15089 + this._scroller.setOptions(this.options); 59.15090 + if (this.options.groupScroll) 59.15091 + this._scroller.pipe(this._eventInput); 59.15092 + else 59.15093 + this._scroller.unpipe(this._eventInput); 59.15094 + 59.15095 + this.drag.setOptions({strength: this.options.drag}); 59.15096 + this.friction.setOptions({strength: this.options.friction}); 59.15097 + 59.15098 + this.spring.setOptions({ 59.15099 + period: this.options.edgePeriod, 59.15100 + dampingRatio: this.options.edgeDamp 59.15101 + }); 59.15102 + 59.15103 + this.sync.setOptions({ 59.15104 + rails: this.options.rails, 59.15105 + direction: (this.options.direction === Utility.Direction.X) ? GenericSync.DIRECTION_X : GenericSync.DIRECTION_Y 59.15106 + }); 59.15107 + }; 59.15108 + 59.15109 + /** 59.15110 + * goToPreviousPage paginates your Scrollview instance backwards by one item. 59.15111 + * @method goToPreviousPage 59.15112 + * @return {ViewSequence} The previous node. 59.15113 + */ 59.15114 + Scrollview.prototype.goToPreviousPage = function goToPreviousPage() { 59.15115 + if (!this._node) return null; 59.15116 + var previousNode = this._node.getPrevious(); 59.15117 + if (previousNode) { 59.15118 + var currentPosition = this.getPosition(); 59.15119 + var previousNodeSize = _nodeSizeForDirection.call(this, previousNode); 59.15120 + this._scroller.sequenceFrom(previousNode); 59.15121 + this._node = previousNode; 59.15122 + var previousSpringPosition = (currentPosition < TOLERANCE) ? -previousNodeSize : 0; 59.15123 + _setSpring.call(this, previousSpringPosition, SpringStates.PAGE); 59.15124 + _shiftOrigin.call(this, previousNodeSize); 59.15125 + } 59.15126 + this._eventOutput.emit('pageChange', {direction: -1}); 59.15127 + return previousNode; 59.15128 + }; 59.15129 + 59.15130 + /** 59.15131 + * goToNextPage paginates your Scrollview instance forwards by one item. 59.15132 + * @method goToNextPage 59.15133 + * @return {ViewSequence} The next node. 59.15134 + */ 59.15135 + Scrollview.prototype.goToNextPage = function goToNextPage() { 59.15136 + if (!this._node) return null; 59.15137 + var nextNode = this._node.getNext(); 59.15138 + if (nextNode) { 59.15139 + var currentPosition = this.getPosition(); 59.15140 + var currentNodeSize = _nodeSizeForDirection.call(this, this._node); 59.15141 + var nextNodeSize = _nodeSizeForDirection.call(this, nextNode); 59.15142 + this._scroller.sequenceFrom(nextNode); 59.15143 + this._node = nextNode; 59.15144 + var nextSpringPosition = (currentPosition > currentNodeSize - TOLERANCE) ? currentNodeSize + nextNodeSize : currentNodeSize; 59.15145 + _setSpring.call(this, nextSpringPosition, SpringStates.PAGE); 59.15146 + _shiftOrigin.call(this, -currentNodeSize); 59.15147 + } 59.15148 + this._eventOutput.emit('pageChange', {direction: 1}); 59.15149 + return nextNode; 59.15150 + }; 59.15151 + 59.15152 + /** 59.15153 + * Sets the collection of renderables under the Scrollview instance's control, by 59.15154 + * setting its current node to the passed in ViewSequence. If you 59.15155 + * pass in an array, the Scrollview instance will set its node as a ViewSequence instantiated with 59.15156 + * the passed-in array. 59.15157 + * 59.15158 + * @method sequenceFrom 59.15159 + * @param {Array|ViewSequence} node Either an array of renderables or a Famous viewSequence. 59.15160 + */ 59.15161 + Scrollview.prototype.sequenceFrom = function sequenceFrom(node) { 59.15162 + if (node instanceof Array) node = new ViewSequence({array: node}); 59.15163 + this._node = node; 59.15164 + return this._scroller.sequenceFrom(node); 59.15165 + }; 59.15166 + 59.15167 + /** 59.15168 + * Returns the width and the height of the Scrollview instance. 59.15169 + * 59.15170 + * @method getSize 59.15171 + * @return {Array} A two value array of the Scrollview instance's current width and height (in that order). 59.15172 + */ 59.15173 + Scrollview.prototype.getSize = function getSize() { 59.15174 + return this._scroller.getSize.apply(this._scroller, arguments); 59.15175 + }; 59.15176 + 59.15177 + /** 59.15178 + * Generate a render spec from the contents of this component. 59.15179 + * 59.15180 + * @private 59.15181 + * @method render 59.15182 + * @return {number} Render spec for this component 59.15183 + */ 59.15184 + Scrollview.prototype.render = function render() { 59.15185 + if (!this._node) return null; 59.15186 + 59.15187 + _normalizeState.call(this); 59.15188 + _handleEdge.call(this, this._scroller.onEdge()); 59.15189 + if (this.options.paginated) _handlePagination.call(this); 59.15190 + 59.15191 + return this._scroller.render(); 59.15192 + }; 59.15193 + 59.15194 + module.exports = Scrollview; 59.15195 +}); 59.15196 + 59.15197 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15198 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15199 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15200 + * 59.15201 + * Owner: felix@famo.us 59.15202 + * @license MPL 2.0 59.15203 + * @copyright Famous Industries, Inc. 2014 59.15204 + */ 59.15205 + 59.15206 +define('famous/views/ScrollContainer',['require','exports','module','famous/surfaces/ContainerSurface','famous/core/EventHandler','./Scrollview','famous/utilities/Utility','famous/core/OptionsManager'],function(require, exports, module) { 59.15207 + var ContainerSurface = require('famous/surfaces/ContainerSurface'); 59.15208 + var EventHandler = require('famous/core/EventHandler'); 59.15209 + var Scrollview = require('./Scrollview'); 59.15210 + var Utility = require('famous/utilities/Utility'); 59.15211 + var OptionsManager = require('famous/core/OptionsManager'); 59.15212 + 59.15213 + /** 59.15214 + * A Container surface with a scrollview automatically added. The convenience of ScrollContainer lies in 59.15215 + * being able to clip out portions of the associated scrollview that lie outside the bounding surface, 59.15216 + * and in being able to move the scrollview more easily by applying modifiers to the parent container 59.15217 + * surface. 59.15218 + * @class ScrollContainer 59.15219 + * @constructor 59.15220 + * @param {Options} [options] An object of configurable options. 59.15221 + * @param {Options} [options.container=undefined] Options for the ScrollContainer instance's surface. 59.15222 + * @param {Options} [options.scrollview={direction:Utility.Direction.X}] Options for the ScrollContainer instance's scrollview. 59.15223 + */ 59.15224 + function ScrollContainer(options) { 59.15225 + this.options = Object.create(ScrollContainer.DEFAULT_OPTIONS); 59.15226 + this._optionsManager = new OptionsManager(this.options); 59.15227 + 59.15228 + if (options) this.setOptions(options); 59.15229 + 59.15230 + this.container = new ContainerSurface(this.options.container); 59.15231 + this.scrollview = new Scrollview(this.options.scrollview); 59.15232 + 59.15233 + this.container.add(this.scrollview); 59.15234 + 59.15235 + EventHandler.setInputHandler(this, this.scrollview); 59.15236 + EventHandler.setOutputHandler(this, this.scrollview); 59.15237 + this.scrollview.subscribe(this.container); 59.15238 + } 59.15239 + 59.15240 + ScrollContainer.DEFAULT_OPTIONS = { 59.15241 + container: { 59.15242 + properties: {overflow : 'hidden'} 59.15243 + }, 59.15244 + scrollview: {direction: Utility.Direction.X} 59.15245 + }; 59.15246 + 59.15247 + /** 59.15248 + * Patches the ScrollContainer instance's options with the passed-in ones. 59.15249 + * 59.15250 + * @method setOptions 59.15251 + * @param {Options} options An object of configurable options for the ScrollContainer instance. 59.15252 + */ 59.15253 + ScrollContainer.prototype.setOptions = function setOptions(options) { 59.15254 + return this._optionsManager.setOptions(options); 59.15255 + }; 59.15256 + 59.15257 + /** 59.15258 + * Sets the collection of renderables under the ScrollContainer instance scrollview's control. 59.15259 + * 59.15260 + * @method sequenceFrom 59.15261 + * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous ViewSequence. 59.15262 + */ 59.15263 + ScrollContainer.prototype.sequenceFrom = function sequenceFrom() { 59.15264 + return this.scrollview.sequenceFrom.apply(this.scrollview, arguments); 59.15265 + }; 59.15266 + 59.15267 + /** 59.15268 + * Generate a render spec from the contents of this component. 59.15269 + * 59.15270 + * @private 59.15271 + * @method render 59.15272 + * @return {number} Render spec for this component 59.15273 + */ 59.15274 + ScrollContainer.prototype.render = function render() { 59.15275 + return this.container.render.apply(this.container, arguments); 59.15276 + }; 59.15277 + 59.15278 + module.exports = ScrollContainer; 59.15279 +}); 59.15280 + 59.15281 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15282 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15283 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15284 + * 59.15285 + * Owner: mark@famo.us 59.15286 + * @license MPL 2.0 59.15287 + * @copyright Famous Industries, Inc. 2014 59.15288 + */ 59.15289 + 59.15290 +define('famous/widgets/NavigationBar',['require','exports','module','famous/core/Scene','famous/core/Surface','famous/core/Transform','famous/core/View'],function(require, exports, module) { 59.15291 + var Scene = require('famous/core/Scene'); 59.15292 + var Surface = require('famous/core/Surface'); 59.15293 + var Transform = require('famous/core/Transform'); 59.15294 + var View = require('famous/core/View'); 59.15295 + 59.15296 + /** 59.15297 + * A view for displaying the title of the current page 59.15298 + * as well as icons for navigating backwards and opening 59.15299 + * further options 59.15300 + * 59.15301 + * @class NavigationBar 59.15302 + * @extends View 59.15303 + * @constructor 59.15304 + * 59.15305 + * @param {object} [options] overrides of default options 59.15306 + * @param {Array.number} [options.size=(undefined,0.5)] Size of the navigation bar and it's componenets. 59.15307 + * @param {Array.string} [options.backClasses=(back)] CSS Classes attached to back of Navigation. 59.15308 + * @param {String} [options.backContent=(◀)] Content of the back button. 59.15309 + * @param {Array.string} [options.classes=(navigation)] CSS Classes attached to the surfaces. 59.15310 + * @param {String} [options.content] Content to pass into title bar. 59.15311 + * @param {Array.string} [options.classes=(more)] CSS Classes attached to the More surface. 59.15312 + * @param {String} [options.moreContent=(✚)] Content of the more button. 59.15313 + */ 59.15314 + function NavigationBar(options) { 59.15315 + View.apply(this, arguments); 59.15316 + 59.15317 + this.title = new Surface({ 59.15318 + classes: this.options.classes, 59.15319 + content: this.options.content 59.15320 + }); 59.15321 + 59.15322 + this.back = new Surface({ 59.15323 + size: [this.options.size[1], this.options.size[1]], 59.15324 + classes: this.options.classes, 59.15325 + content: this.options.backContent 59.15326 + }); 59.15327 + this.back.on('click', function() { 59.15328 + this._eventOutput.emit('back', {}); 59.15329 + }.bind(this)); 59.15330 + 59.15331 + this.more = new Surface({ 59.15332 + size: [this.options.size[1], this.options.size[1]], 59.15333 + classes: this.options.classes, 59.15334 + content: this.options.moreContent 59.15335 + }); 59.15336 + this.more.on('click', function() { 59.15337 + this._eventOutput.emit('more', {}); 59.15338 + }.bind(this)); 59.15339 + 59.15340 + this.layout = new Scene({ 59.15341 + id: 'master', 59.15342 + size: this.options.size, 59.15343 + target: [ 59.15344 + { 59.15345 + transform: Transform.inFront, 59.15346 + origin: [0, 0.5], 59.15347 + target: this.back 59.15348 + }, 59.15349 + { 59.15350 + origin: [0.5, 0.5], 59.15351 + target: this.title 59.15352 + }, 59.15353 + { 59.15354 + transform: Transform.inFront, 59.15355 + origin: [1, 0.5], 59.15356 + target: this.more 59.15357 + } 59.15358 + ] 59.15359 + }); 59.15360 + 59.15361 + this._add(this.layout); 59.15362 + 59.15363 + this._optionsManager.on('change', function(event) { 59.15364 + var key = event.id; 59.15365 + var data = event.value; 59.15366 + if (key === 'size') { 59.15367 + this.layout.id.master.setSize(data); 59.15368 + this.title.setSize(data); 59.15369 + this.back.setSize([data[1], data[1]]); 59.15370 + this.more.setSize([data[1], data[1]]); 59.15371 + } 59.15372 + else if (key === 'backClasses') { 59.15373 + this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)}); 59.15374 + } 59.15375 + else if (key === 'backContent') { 59.15376 + this.back.setContent(this.options.backContent); 59.15377 + } 59.15378 + else if (key === 'classes') { 59.15379 + this.title.setOptions({classes: this.options.classes}); 59.15380 + this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)}); 59.15381 + this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)}); 59.15382 + } 59.15383 + else if (key === 'content') { 59.15384 + this.setContent(this.options.content); 59.15385 + } 59.15386 + else if (key === 'moreClasses') { 59.15387 + this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)}); 59.15388 + } 59.15389 + else if (key === 'moreContent') { 59.15390 + this.more.setContent(this.options.content); 59.15391 + } 59.15392 + }.bind(this)); 59.15393 + } 59.15394 + 59.15395 + NavigationBar.prototype = Object.create(View.prototype); 59.15396 + NavigationBar.prototype.constructor = NavigationBar; 59.15397 + 59.15398 + NavigationBar.DEFAULT_OPTIONS = { 59.15399 + size: [undefined, 50], 59.15400 + backClasses: ['back'], 59.15401 + backContent: '◀', 59.15402 + classes: ['navigation'], 59.15403 + content: '', 59.15404 + moreClasses: ['more'], 59.15405 + moreContent: '✚' 59.15406 + }; 59.15407 + 59.15408 + /** 59.15409 + * Set the title of the NavigationBar 59.15410 + * 59.15411 + * @method setContent 59.15412 + * 59.15413 + * @param {object} content JSON object containing title information 59.15414 + * 59.15415 + * @return {undefined} 59.15416 + */ 59.15417 + NavigationBar.prototype.setContent = function setContent(content) { 59.15418 + return this.title.setContent(content); 59.15419 + }; 59.15420 + 59.15421 + module.exports = NavigationBar; 59.15422 +}); 59.15423 + 59.15424 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15425 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15426 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15427 + * 59.15428 + * Owner: mark@famo.us 59.15429 + * @license MPL 2.0 59.15430 + * @copyright Famous Industries, Inc. 2014 59.15431 + */ 59.15432 + 59.15433 +define('famous/widgets/Slider',['require','exports','module','famous/core/Surface','famous/surfaces/CanvasSurface','famous/core/Transform','famous/core/EventHandler','famous/math/Utilities','famous/core/OptionsManager','famous/inputs/MouseSync','famous/inputs/TouchSync','famous/inputs/GenericSync'],function(require, exports, module) { 59.15434 + var Surface = require('famous/core/Surface'); 59.15435 + var CanvasSurface = require('famous/surfaces/CanvasSurface'); 59.15436 + var Transform = require('famous/core/Transform'); 59.15437 + var EventHandler = require('famous/core/EventHandler'); 59.15438 + var Utilities = require('famous/math/Utilities'); 59.15439 + var OptionsManager = require('famous/core/OptionsManager'); 59.15440 + 59.15441 + var MouseSync = require('famous/inputs/MouseSync'); 59.15442 + var TouchSync = require('famous/inputs/TouchSync'); 59.15443 + var GenericSync = require('famous/inputs/GenericSync'); 59.15444 + 59.15445 + GenericSync.register({ 59.15446 + mouse : MouseSync, 59.15447 + touch : TouchSync 59.15448 + }); 59.15449 + 59.15450 + /** @constructor */ 59.15451 + function Slider(options) { 59.15452 + this.options = Object.create(Slider.DEFAULT_OPTIONS); 59.15453 + this.optionsManager = new OptionsManager(this.options); 59.15454 + if (options) this.setOptions(options); 59.15455 + 59.15456 + this.indicator = new CanvasSurface({ 59.15457 + size: this.options.indicatorSize, 59.15458 + classes : ['slider-back'] 59.15459 + }); 59.15460 + 59.15461 + this.label = new Surface({ 59.15462 + size: this.options.labelSize, 59.15463 + content: this.options.label, 59.15464 + properties : {pointerEvents : 'none'}, 59.15465 + classes: ['slider-label'] 59.15466 + }); 59.15467 + 59.15468 + this.eventOutput = new EventHandler(); 59.15469 + this.eventInput = new EventHandler(); 59.15470 + EventHandler.setInputHandler(this, this.eventInput); 59.15471 + EventHandler.setOutputHandler(this, this.eventOutput); 59.15472 + 59.15473 + var scale = (this.options.range[1] - this.options.range[0]) / this.options.indicatorSize[0]; 59.15474 + 59.15475 + this.sync = new GenericSync( 59.15476 + ['mouse', 'touch'], 59.15477 + { 59.15478 + scale : scale, 59.15479 + direction : GenericSync.DIRECTION_X 59.15480 + } 59.15481 + ); 59.15482 + 59.15483 + this.indicator.pipe(this.sync); 59.15484 + this.sync.pipe(this); 59.15485 + 59.15486 + this.eventInput.on('update', function(data) { 59.15487 + this.set(data.position); 59.15488 + }.bind(this)); 59.15489 + 59.15490 + this._drawPos = 0; 59.15491 + _updateLabel.call(this); 59.15492 + } 59.15493 + 59.15494 + Slider.DEFAULT_OPTIONS = { 59.15495 + size: [200, 60], 59.15496 + indicatorSize: [200, 30], 59.15497 + labelSize: [200, 30], 59.15498 + range: [0, 1], 59.15499 + precision: 2, 59.15500 + value: 0, 59.15501 + label: '', 59.15502 + fillColor: 'rgba(170, 170, 170, 1)' 59.15503 + }; 59.15504 + 59.15505 + function _updateLabel() { 59.15506 + this.label.setContent(this.options.label + '<span style="float: right">' + this.get().toFixed(this.options.precision) + '</span>'); 59.15507 + } 59.15508 + 59.15509 + Slider.prototype.setOptions = function setOptions(options) { 59.15510 + return this.optionsManager.setOptions(options); 59.15511 + }; 59.15512 + 59.15513 + Slider.prototype.get = function get() { 59.15514 + return this.options.value; 59.15515 + }; 59.15516 + 59.15517 + Slider.prototype.set = function set(value) { 59.15518 + if (value === this.options.value) return; 59.15519 + this.options.value = Utilities.clamp(value, this.options.range); 59.15520 + _updateLabel.call(this); 59.15521 + this.eventOutput.emit('change', {value: value}); 59.15522 + }; 59.15523 + 59.15524 + Slider.prototype.getSize = function getSize() { 59.15525 + return this.options.size; 59.15526 + }; 59.15527 + 59.15528 + Slider.prototype.render = function render() { 59.15529 + var range = this.options.range; 59.15530 + var fillSize = Math.floor(((this.get() - range[0]) / (range[1] - range[0])) * this.options.indicatorSize[0]); 59.15531 + 59.15532 + if (fillSize < this._drawPos) { 59.15533 + this.indicator.getContext('2d').clearRect(fillSize, 0, this._drawPos - fillSize + 1, this.options.indicatorSize[1]); 59.15534 + } 59.15535 + else if (fillSize > this._drawPos) { 59.15536 + var ctx = this.indicator.getContext('2d'); 59.15537 + ctx.fillStyle = this.options.fillColor; 59.15538 + ctx.fillRect(this._drawPos-1, 0, fillSize - this._drawPos+1, this.options.indicatorSize[1]); 59.15539 + } 59.15540 + this._drawPos = fillSize; 59.15541 + 59.15542 + return { 59.15543 + size: this.options.size, 59.15544 + target: [ 59.15545 + { 59.15546 + origin: [0, 0], 59.15547 + target: this.indicator.render() 59.15548 + }, 59.15549 + { 59.15550 + transform: Transform.translate(0, 0, 1), 59.15551 + origin: [0, 0], 59.15552 + target: this.label.render() 59.15553 + } 59.15554 + ] 59.15555 + }; 59.15556 + }; 59.15557 + 59.15558 + module.exports = Slider; 59.15559 +}); 59.15560 + 59.15561 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15562 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15563 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15564 + * 59.15565 + * Owner: mark@famo.us 59.15566 + * @license MPL 2.0 59.15567 + * @copyright Famous Industries, Inc. 2014 59.15568 + */ 59.15569 + 59.15570 +define('famous/widgets/ToggleButton',['require','exports','module','famous/core/Surface','famous/core/EventHandler','famous/views/RenderController'],function(require, exports, module) { 59.15571 + var Surface = require('famous/core/Surface'); 59.15572 + var EventHandler = require('famous/core/EventHandler'); 59.15573 + var RenderController = require('famous/views/RenderController'); 59.15574 + 59.15575 + /** 59.15576 + * A view for transitioning between two surfaces based 59.15577 + * on a 'on' and 'off' state 59.15578 + * 59.15579 + * @class TabBar 59.15580 + * @extends View 59.15581 + * @constructor 59.15582 + * 59.15583 + * @param {object} options overrides of default options 59.15584 + */ 59.15585 + function ToggleButton(options) { 59.15586 + this.options = { 59.15587 + content: '', 59.15588 + offClasses: ['off'], 59.15589 + onClasses: ['on'], 59.15590 + size: undefined, 59.15591 + outTransition: {curve: 'easeInOut', duration: 300}, 59.15592 + inTransition: {curve: 'easeInOut', duration: 300}, 59.15593 + toggleMode: ToggleButton.TOGGLE, 59.15594 + crossfade: true 59.15595 + }; 59.15596 + 59.15597 + this._eventOutput = new EventHandler(); 59.15598 + EventHandler.setOutputHandler(this, this._eventOutput); 59.15599 + 59.15600 + this.offSurface = new Surface(); 59.15601 + this.offSurface.on('click', function() { 59.15602 + if (this.options.toggleMode !== ToggleButton.OFF) this.select(); 59.15603 + }.bind(this)); 59.15604 + this.offSurface.pipe(this._eventOutput); 59.15605 + 59.15606 + this.onSurface = new Surface(); 59.15607 + this.onSurface.on('click', function() { 59.15608 + if (this.options.toggleMode !== ToggleButton.ON) this.deselect(); 59.15609 + }.bind(this)); 59.15610 + this.onSurface.pipe(this._eventOutput); 59.15611 + 59.15612 + this.arbiter = new RenderController({ 59.15613 + overlap : this.options.crossfade 59.15614 + }); 59.15615 + 59.15616 + this.deselect(); 59.15617 + 59.15618 + if (options) this.setOptions(options); 59.15619 + } 59.15620 + 59.15621 + ToggleButton.OFF = 0; 59.15622 + ToggleButton.ON = 1; 59.15623 + ToggleButton.TOGGLE = 2; 59.15624 + 59.15625 + /** 59.15626 + * Transition towards the 'on' state and dispatch an event to 59.15627 + * listeners to announce it was selected 59.15628 + * 59.15629 + * @method select 59.15630 + */ 59.15631 + ToggleButton.prototype.select = function select() { 59.15632 + this.selected = true; 59.15633 + this.arbiter.show(this.onSurface, this.options.inTransition); 59.15634 +// this.arbiter.setMode(ToggleButton.ON, this.options.inTransition); 59.15635 + this._eventOutput.emit('select'); 59.15636 + }; 59.15637 + 59.15638 + /** 59.15639 + * Transition towards the 'off' state and dispatch an event to 59.15640 + * listeners to announce it was deselected 59.15641 + * 59.15642 + * @method deselect 59.15643 + */ 59.15644 + ToggleButton.prototype.deselect = function deselect() { 59.15645 + this.selected = false; 59.15646 + this.arbiter.show(this.offSurface, this.options.outTransition); 59.15647 + this._eventOutput.emit('deselect'); 59.15648 + }; 59.15649 + 59.15650 + /** 59.15651 + * Return the state of the button 59.15652 + * 59.15653 + * @method isSelected 59.15654 + * 59.15655 + * @return {boolean} selected state 59.15656 + */ 59.15657 + ToggleButton.prototype.isSelected = function isSelected() { 59.15658 + return this.selected; 59.15659 + }; 59.15660 + 59.15661 + /** 59.15662 + * Override the current options 59.15663 + * 59.15664 + * @method setOptions 59.15665 + * 59.15666 + * @param {object} options JSON 59.15667 + */ 59.15668 + ToggleButton.prototype.setOptions = function setOptions(options) { 59.15669 + if (options.content !== undefined) { 59.15670 + this.options.content = options.content; 59.15671 + this.offSurface.setContent(this.options.content); 59.15672 + this.onSurface.setContent(this.options.content); 59.15673 + } 59.15674 + if (options.offClasses) { 59.15675 + this.options.offClasses = options.offClasses; 59.15676 + this.offSurface.setClasses(this.options.offClasses); 59.15677 + } 59.15678 + if (options.onClasses) { 59.15679 + this.options.onClasses = options.onClasses; 59.15680 + this.onSurface.setClasses(this.options.onClasses); 59.15681 + } 59.15682 + if (options.size !== undefined) { 59.15683 + this.options.size = options.size; 59.15684 + this.onSurface.setSize(this.options.size); 59.15685 + this.offSurface.setSize(this.options.size); 59.15686 + } 59.15687 + if (options.toggleMode !== undefined) this.options.toggleMode = options.toggleMode; 59.15688 + if (options.outTransition !== undefined) this.options.outTransition = options.outTransition; 59.15689 + if (options.inTransition !== undefined) this.options.inTransition = options.inTransition; 59.15690 + if (options.crossfade !== undefined) { 59.15691 + this.options.crossfade = options.crossfade; 59.15692 + this.arbiter.setOptions({overlap: this.options.crossfade}); 59.15693 + } 59.15694 + }; 59.15695 + 59.15696 + /** 59.15697 + * Return the size defined in the options object 59.15698 + * 59.15699 + * @method getSize 59.15700 + * 59.15701 + * @return {array} two element array [height, width] 59.15702 + */ 59.15703 + ToggleButton.prototype.getSize = function getSize() { 59.15704 + return this.options.size; 59.15705 + }; 59.15706 + 59.15707 + /** 59.15708 + * Generate a render spec from the contents of this component. 59.15709 + * 59.15710 + * @private 59.15711 + * @method render 59.15712 + * @return {number} Render spec for this component 59.15713 + */ 59.15714 + ToggleButton.prototype.render = function render() { 59.15715 + return this.arbiter.render(); 59.15716 + }; 59.15717 + 59.15718 + module.exports = ToggleButton; 59.15719 +}); 59.15720 + 59.15721 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15722 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15723 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15724 + * 59.15725 + * Owner: mark@famo.us 59.15726 + * @license MPL 2.0 59.15727 + * @copyright Famous Industries, Inc. 2014 59.15728 + */ 59.15729 + 59.15730 +define('famous/widgets/TabBar',['require','exports','module','famous/utilities/Utility','famous/core/View','famous/views/GridLayout','./ToggleButton'],function(require, exports, module) { 59.15731 + var Utility = require('famous/utilities/Utility'); 59.15732 + var View = require('famous/core/View'); 59.15733 + var GridLayout = require('famous/views/GridLayout'); 59.15734 + var ToggleButton = require('./ToggleButton'); 59.15735 + 59.15736 + /** 59.15737 + * A view for displaying various tabs that dispatch events 59.15738 + * based on the id of the button that was clicked 59.15739 + * 59.15740 + * @class TabBar 59.15741 + * @extends View 59.15742 + * @constructor 59.15743 + * 59.15744 + * @param {object} options overrides of default options 59.15745 + */ 59.15746 + function TabBar(options) { 59.15747 + View.apply(this, arguments); 59.15748 + 59.15749 + this.layout = new GridLayout(); 59.15750 + this.buttons = []; 59.15751 + this._buttonIds = {}; 59.15752 + this._buttonCallbacks = {}; 59.15753 + 59.15754 + this.layout.sequenceFrom(this.buttons); 59.15755 + this._add(this.layout); 59.15756 + 59.15757 + this._optionsManager.on('change', _updateOptions.bind(this)); 59.15758 + } 59.15759 + 59.15760 + TabBar.prototype = Object.create(View.prototype); 59.15761 + TabBar.prototype.constructor = TabBar; 59.15762 + 59.15763 + TabBar.DEFAULT_OPTIONS = { 59.15764 + sections: [], 59.15765 + widget: ToggleButton, 59.15766 + size: [undefined, 50], 59.15767 + direction: Utility.Direction.X, 59.15768 + buttons: { 59.15769 + toggleMode: ToggleButton.ON 59.15770 + } 59.15771 + }; 59.15772 + 59.15773 + /** 59.15774 + * Update the options for all components of the view 59.15775 + * 59.15776 + * @method _updateOptions 59.15777 + * 59.15778 + * @param {object} data component options 59.15779 + */ 59.15780 + function _updateOptions(data) { 59.15781 + var id = data.id; 59.15782 + var value = data.value; 59.15783 + 59.15784 + if (id === 'direction') { 59.15785 + this.layout.setOptions({dimensions: _resolveGridDimensions.call(this.buttons.length, this.options.direction)}); 59.15786 + } 59.15787 + else if (id === 'buttons') { 59.15788 + for (var i in this.buttons) { 59.15789 + this.buttons[i].setOptions(value); 59.15790 + } 59.15791 + } 59.15792 + else if (id === 'sections') { 59.15793 + for (var sectionId in this.options.sections) { 59.15794 + this.defineSection(sectionId, this.options.sections[sectionId]); 59.15795 + } 59.15796 + } 59.15797 + } 59.15798 + 59.15799 + /** 59.15800 + * Return an array of the proper dimensions for the tabs 59.15801 + * 59.15802 + * @method _resolveGridDimensions 59.15803 + * 59.15804 + * @param {number} count number of buttons 59.15805 + * @param {number} direction direction of the layout 59.15806 + * 59.15807 + * @return {array} the dimensions of the tab section 59.15808 + */ 59.15809 + function _resolveGridDimensions(count, direction) { 59.15810 + if (direction === Utility.Direction.X) return [count, 1]; 59.15811 + else return [1, count]; 59.15812 + } 59.15813 + 59.15814 + /** 59.15815 + * Create a new button with the specified id. If one already exists with 59.15816 + * that id, unbind all listeners. 59.15817 + * 59.15818 + * @method defineSection 59.15819 + * 59.15820 + * @param {string} id name of the button 59.15821 + * @param {object} content data for the creation of a new ToggleButton 59.15822 + */ 59.15823 + TabBar.prototype.defineSection = function defineSection(id, content) { 59.15824 + var button; 59.15825 + var i = this._buttonIds[id]; 59.15826 + 59.15827 + if (i === undefined) { 59.15828 + i = this.buttons.length; 59.15829 + this._buttonIds[id] = i; 59.15830 + var widget = this.options.widget; 59.15831 + button = new widget(); 59.15832 + this.buttons[i] = button; 59.15833 + this.layout.setOptions({dimensions: _resolveGridDimensions(this.buttons.length, this.options.direction)}); 59.15834 + } 59.15835 + else { 59.15836 + button = this.buttons[i]; 59.15837 + button.unbind('select', this._buttonCallbacks[id]); 59.15838 + } 59.15839 + 59.15840 + if (this.options.buttons) button.setOptions(this.options.buttons); 59.15841 + button.setOptions(content); 59.15842 + 59.15843 + this._buttonCallbacks[id] = this.select.bind(this, id); 59.15844 + button.on('select', this._buttonCallbacks[id]); 59.15845 + }; 59.15846 + 59.15847 + /** 59.15848 + * Select a particular button and dispatch the id of the selection 59.15849 + * to any listeners. Deselect all others 59.15850 + * 59.15851 + * @method select 59.15852 + * 59.15853 + * @param {string} id button id 59.15854 + */ 59.15855 + TabBar.prototype.select = function select(id) { 59.15856 + var btn = this._buttonIds[id]; 59.15857 + // this prevents event loop 59.15858 + if (this.buttons[btn] && this.buttons[btn].isSelected()) { 59.15859 + this._eventOutput.emit('select', {id: id}); 59.15860 + } 59.15861 + else if (this.buttons[btn]) { 59.15862 + this.buttons[btn].select(); 59.15863 + } 59.15864 + 59.15865 + for (var i = 0; i < this.buttons.length; i++) { 59.15866 + if (i !== btn) this.buttons[i].deselect(); 59.15867 + } 59.15868 + }; 59.15869 + 59.15870 + module.exports = TabBar; 59.15871 +}); 59.15872 + 59.15873 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.15874 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.15875 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.15876 + * 59.15877 + * Owner: david@famo.us 59.15878 + * @license MPL 2.0 59.15879 + * @copyright Famous Industries, Inc. 2014 59.15880 + */ 59.15881 + 59.15882 +define('famous/physics/bodies/Body',['require','exports','module','./Particle','famous/core/Transform','famous/math/Vector','famous/math/Quaternion','famous/math/Matrix'],function(require, exports, module) { 59.15883 + var Particle = require('./Particle'); 59.15884 + var Transform = require('famous/core/Transform'); 59.15885 + var Vector = require('famous/math/Vector'); 59.15886 + var Quaternion = require('famous/math/Quaternion'); 59.15887 + var Matrix = require('famous/math/Matrix'); 59.15888 + 59.15889 + /** 59.15890 + * A unit controlled by the physics engine which extends the zero-dimensional 59.15891 + * Particle to include geometry. In addition to maintaining the state 59.15892 + * of a Particle its state includes orientation, angular velocity 59.15893 + * and angular momentum and responds to torque forces. 59.15894 + * 59.15895 + * @class Body 59.15896 + * @extends Particle 59.15897 + * @constructor 59.15898 + */ 59.15899 + function Body(options) { 59.15900 + Particle.call(this, options); 59.15901 + options = options || {}; 59.15902 + 59.15903 + this.orientation = new Quaternion(); 59.15904 + this.angularVelocity = new Vector(); 59.15905 + this.angularMomentum = new Vector(); 59.15906 + this.torque = new Vector(); 59.15907 + 59.15908 + if (options.orientation) this.orientation.set(options.orientation); 59.15909 + if (options.angularVelocity) this.angularVelocity.set(options.angularVelocity); 59.15910 + if (options.angularMomentum) this.angularMomentum.set(options.angularMomentum); 59.15911 + if (options.torque) this.torque.set(options.torque); 59.15912 + 59.15913 + this.setMomentsOfInertia(); 59.15914 + 59.15915 + this.angularVelocity.w = 0; //quaternify the angular velocity 59.15916 + 59.15917 + //registers 59.15918 + this.pWorld = new Vector(); //placeholder for world space position 59.15919 + } 59.15920 + 59.15921 + Body.DEFAULT_OPTIONS = Particle.DEFAULT_OPTIONS; 59.15922 + Body.DEFAULT_OPTIONS.orientation = [0,0,0,1]; 59.15923 + Body.DEFAULT_OPTIONS.angularVelocity = [0,0,0]; 59.15924 + 59.15925 + Body.AXES = Particle.AXES; 59.15926 + Body.SLEEP_TOLERANCE = Particle.SLEEP_TOLERANCE; 59.15927 + Body.INTEGRATOR = Particle.INTEGRATOR; 59.15928 + 59.15929 + Body.prototype = Object.create(Particle.prototype); 59.15930 + Body.prototype.constructor = Body; 59.15931 + 59.15932 + Body.prototype.isBody = true; 59.15933 + 59.15934 + Body.prototype.setMass = function setMass() { 59.15935 + Particle.prototype.setMass.apply(this, arguments); 59.15936 + this.setMomentsOfInertia(); 59.15937 + }; 59.15938 + 59.15939 + /** 59.15940 + * Setter for moment of inertia, which is necessary to give proper 59.15941 + * angular inertia depending on the geometry of the body. 59.15942 + * 59.15943 + * @method setMomentsOfInertia 59.15944 + */ 59.15945 + Body.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 59.15946 + this.inertia = new Matrix(); 59.15947 + this.inverseInertia = new Matrix(); 59.15948 + }; 59.15949 + 59.15950 + /** 59.15951 + * Update the angular velocity from the angular momentum state. 59.15952 + * 59.15953 + * @method updateAngularVelocity 59.15954 + */ 59.15955 + Body.prototype.updateAngularVelocity = function updateAngularVelocity() { 59.15956 + this.angularVelocity.set(this.inverseInertia.vectorMultiply(this.angularMomentum)); 59.15957 + }; 59.15958 + 59.15959 + /** 59.15960 + * Determine world coordinates from the local coordinate system. Useful 59.15961 + * if the Body has rotated in space. 59.15962 + * 59.15963 + * @method toWorldCoordinates 59.15964 + * @param localPosition {Vector} local coordinate vector 59.15965 + * @return global coordinate vector {Vector} 59.15966 + */ 59.15967 + Body.prototype.toWorldCoordinates = function toWorldCoordinates(localPosition) { 59.15968 + return this.pWorld.set(this.orientation.rotateVector(localPosition)); 59.15969 + }; 59.15970 + 59.15971 + /** 59.15972 + * Calculates the kinetic and intertial energy of a body. 59.15973 + * 59.15974 + * @method getEnergy 59.15975 + * @return energy {Number} 59.15976 + */ 59.15977 + Body.prototype.getEnergy = function getEnergy() { 59.15978 + return Particle.prototype.getEnergy.call(this) 59.15979 + + 0.5 * this.inertia.vectorMultiply(this.angularVelocity).dot(this.angularVelocity); 59.15980 + }; 59.15981 + 59.15982 + /** 59.15983 + * Extends Particle.reset to reset orientation, angular velocity 59.15984 + * and angular momentum. 59.15985 + * 59.15986 + * @method reset 59.15987 + * @param [p] {Array|Vector} position 59.15988 + * @param [v] {Array|Vector} velocity 59.15989 + * @param [q] {Array|Quaternion} orientation 59.15990 + * @param [L] {Array|Vector} angular momentum 59.15991 + */ 59.15992 + Body.prototype.reset = function reset(p, v, q, L) { 59.15993 + Particle.prototype.reset.call(this, p, v); 59.15994 + this.angularVelocity.clear(); 59.15995 + this.setOrientation(q || [1,0,0,0]); 59.15996 + this.setAngularMomentum(L || [0,0,0]); 59.15997 + }; 59.15998 + 59.15999 + /** 59.16000 + * Setter for orientation 59.16001 + * 59.16002 + * @method setOrientation 59.16003 + * @param q {Array|Quaternion} orientation 59.16004 + */ 59.16005 + Body.prototype.setOrientation = function setOrientation(q) { 59.16006 + this.orientation.set(q); 59.16007 + }; 59.16008 + 59.16009 + /** 59.16010 + * Setter for angular velocity 59.16011 + * 59.16012 + * @method setAngularVelocity 59.16013 + * @param w {Array|Vector} angular velocity 59.16014 + */ 59.16015 + Body.prototype.setAngularVelocity = function setAngularVelocity(w) { 59.16016 + this.wake(); 59.16017 + this.angularVelocity.set(w); 59.16018 + }; 59.16019 + 59.16020 + /** 59.16021 + * Setter for angular momentum 59.16022 + * 59.16023 + * @method setAngularMomentum 59.16024 + * @param L {Array|Vector} angular momentum 59.16025 + */ 59.16026 + Body.prototype.setAngularMomentum = function setAngularMomentum(L) { 59.16027 + this.wake(); 59.16028 + this.angularMomentum.set(L); 59.16029 + }; 59.16030 + 59.16031 + /** 59.16032 + * Extends Particle.applyForce with an optional argument 59.16033 + * to apply the force at an off-centered location, resulting in a torque. 59.16034 + * 59.16035 + * @method applyForce 59.16036 + * @param force {Vector} force 59.16037 + * @param [location] {Vector} off-center location on the body 59.16038 + */ 59.16039 + Body.prototype.applyForce = function applyForce(force, location) { 59.16040 + Particle.prototype.applyForce.call(this, force); 59.16041 + if (location !== undefined) this.applyTorque(location.cross(force)); 59.16042 + }; 59.16043 + 59.16044 + /** 59.16045 + * Applied a torque force to a body, inducing a rotation. 59.16046 + * 59.16047 + * @method applyTorque 59.16048 + * @param torque {Vector} torque 59.16049 + */ 59.16050 + Body.prototype.applyTorque = function applyTorque(torque) { 59.16051 + this.wake(); 59.16052 + this.torque.set(this.torque.add(torque)); 59.16053 + }; 59.16054 + 59.16055 + /** 59.16056 + * Extends Particle.getTransform to include a rotational component 59.16057 + * derived from the particle's orientation. 59.16058 + * 59.16059 + * @method getTransform 59.16060 + * @return transform {Transform} 59.16061 + */ 59.16062 + Body.prototype.getTransform = function getTransform() { 59.16063 + return Transform.thenMove( 59.16064 + this.orientation.getTransform(), 59.16065 + Transform.getTranslate(Particle.prototype.getTransform.call(this)) 59.16066 + ); 59.16067 + }; 59.16068 + 59.16069 + /** 59.16070 + * Extends Particle._integrate to also update the rotational states 59.16071 + * of the body. 59.16072 + * 59.16073 + * @method getTransform 59.16074 + * @protected 59.16075 + * @param dt {Number} delta time 59.16076 + */ 59.16077 + Body.prototype._integrate = function _integrate(dt) { 59.16078 + Particle.prototype._integrate.call(this, dt); 59.16079 + this.integrateAngularMomentum(dt); 59.16080 + this.updateAngularVelocity(dt); 59.16081 + this.integrateOrientation(dt); 59.16082 + }; 59.16083 + 59.16084 + /** 59.16085 + * Updates the angular momentum via the its integrator. 59.16086 + * 59.16087 + * @method integrateAngularMomentum 59.16088 + * @param dt {Number} delta time 59.16089 + */ 59.16090 + Body.prototype.integrateAngularMomentum = function integrateAngularMomentum(dt) { 59.16091 + Body.INTEGRATOR.integrateAngularMomentum(this, dt); 59.16092 + }; 59.16093 + 59.16094 + /** 59.16095 + * Updates the orientation via the its integrator. 59.16096 + * 59.16097 + * @method integrateOrientation 59.16098 + * @param dt {Number} delta time 59.16099 + */ 59.16100 + Body.prototype.integrateOrientation = function integrateOrientation(dt) { 59.16101 + Body.INTEGRATOR.integrateOrientation(this, dt); 59.16102 + }; 59.16103 + 59.16104 + module.exports = Body; 59.16105 +}); 59.16106 + 59.16107 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16108 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16109 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16110 + * 59.16111 + * Owner: david@famo.us 59.16112 + * @license MPL 2.0 59.16113 + * @copyright Famous Industries, Inc. 2014 59.16114 + */ 59.16115 + 59.16116 +define('famous/physics/bodies/Circle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) { 59.16117 + var Body = require('./Body'); 59.16118 + var Matrix = require('famous/math/Matrix'); 59.16119 + 59.16120 + /** 59.16121 + * Implements a circle, or spherical, geometry for an Body with 59.16122 + * radius. 59.16123 + * 59.16124 + * @class Circle 59.16125 + * @extends Body 59.16126 + * @constructor 59.16127 + */ 59.16128 + function Circle(options) { 59.16129 + options = options || {}; 59.16130 + this.setRadius(options.radius || 0); 59.16131 + Body.call(this, options); 59.16132 + } 59.16133 + 59.16134 + Circle.prototype = Object.create(Body.prototype); 59.16135 + Circle.prototype.constructor = Circle; 59.16136 + 59.16137 + /** 59.16138 + * Basic setter for radius. 59.16139 + * @method setRadius 59.16140 + * @param r {Number} radius 59.16141 + */ 59.16142 + Circle.prototype.setRadius = function setRadius(r) { 59.16143 + this.radius = r; 59.16144 + this.size = [2*this.radius, 2*this.radius]; 59.16145 + this.setMomentsOfInertia(); 59.16146 + }; 59.16147 + 59.16148 + Circle.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 59.16149 + var m = this.mass; 59.16150 + var r = this.radius; 59.16151 + 59.16152 + this.inertia = new Matrix([ 59.16153 + [0.25 * m * r * r, 0, 0], 59.16154 + [0, 0.25 * m * r * r, 0], 59.16155 + [0, 0, 0.5 * m * r * r] 59.16156 + ]); 59.16157 + 59.16158 + this.inverseInertia = new Matrix([ 59.16159 + [4 / (m * r * r), 0, 0], 59.16160 + [0, 4 / (m * r * r), 0], 59.16161 + [0, 0, 2 / (m * r * r)] 59.16162 + ]); 59.16163 + }; 59.16164 + 59.16165 + module.exports = Circle; 59.16166 + 59.16167 +}); 59.16168 + 59.16169 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16170 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16171 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16172 + * 59.16173 + * Owner: david@famo.us 59.16174 + * @license MPL 2.0 59.16175 + * @copyright Famous Industries, Inc. 2014 59.16176 + */ 59.16177 + 59.16178 +define('famous/physics/bodies/Rectangle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) { 59.16179 + var Body = require('./Body'); 59.16180 + var Matrix = require('famous/math/Matrix'); 59.16181 + 59.16182 + /** 59.16183 + * Implements a rectangular geometry for an Body with 59.16184 + * size = [width, height]. 59.16185 + * 59.16186 + * @class Rectangle 59.16187 + * @extends Body 59.16188 + * @constructor 59.16189 + */ 59.16190 + function Rectangle(options) { 59.16191 + options = options || {}; 59.16192 + this.size = options.size || [0,0]; 59.16193 + Body.call(this, options); 59.16194 + } 59.16195 + 59.16196 + Rectangle.prototype = Object.create(Body.prototype); 59.16197 + Rectangle.prototype.constructor = Rectangle; 59.16198 + 59.16199 + /** 59.16200 + * Basic setter for size. 59.16201 + * @method setSize 59.16202 + * @param size {Array} size = [width, height] 59.16203 + */ 59.16204 + Rectangle.prototype.setSize = function setSize(size) { 59.16205 + this.size = size; 59.16206 + this.setMomentsOfInertia(); 59.16207 + }; 59.16208 + 59.16209 + Rectangle.prototype.setMomentsOfInertia = function setMomentsOfInertia() { 59.16210 + var m = this.mass; 59.16211 + var w = this.size[0]; 59.16212 + var h = this.size[1]; 59.16213 + 59.16214 + this.inertia = new Matrix([ 59.16215 + [m * h * h / 12, 0, 0], 59.16216 + [0, m * w * w / 12, 0], 59.16217 + [0, 0, m * (w * w + h * h) / 12] 59.16218 + ]); 59.16219 + 59.16220 + this.inverseInertia = new Matrix([ 59.16221 + [12 / (m * h * h), 0, 0], 59.16222 + [0, 12 / (m * w * w), 0], 59.16223 + [0, 0, 12 / (m * (w * w + h * h))] 59.16224 + ]); 59.16225 + }; 59.16226 + 59.16227 + module.exports = Rectangle; 59.16228 + 59.16229 +}); 59.16230 + 59.16231 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16232 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16233 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16234 + * 59.16235 + * Owner: david@famo.us 59.16236 + * @license MPL 2.0 59.16237 + * @copyright Famous Industries, Inc. 2014 59.16238 + */ 59.16239 + 59.16240 +define('famous/physics/constraints/Collision',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.16241 + var Constraint = require('./Constraint'); 59.16242 + var Vector = require('famous/math/Vector'); 59.16243 + 59.16244 + /** 59.16245 + * Allows for two circular bodies to collide and bounce off each other. 59.16246 + * 59.16247 + * @class Collision 59.16248 + * @constructor 59.16249 + * @extends Constraint 59.16250 + * @param {Options} [options] An object of configurable options. 59.16251 + * @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) Range : [0, 1] 59.16252 + * @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 59.16253 + * @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers 59.16254 + * 59.16255 + */ 59.16256 + function Collision(options) { 59.16257 + this.options = Object.create(Collision.DEFAULT_OPTIONS); 59.16258 + if (options) this.setOptions(options); 59.16259 + 59.16260 + //registers 59.16261 + this.normal = new Vector(); 59.16262 + this.pDiff = new Vector(); 59.16263 + this.vDiff = new Vector(); 59.16264 + this.impulse1 = new Vector(); 59.16265 + this.impulse2 = new Vector(); 59.16266 + 59.16267 + Constraint.call(this); 59.16268 + } 59.16269 + 59.16270 + Collision.prototype = Object.create(Constraint.prototype); 59.16271 + Collision.prototype.constructor = Collision; 59.16272 + 59.16273 + Collision.DEFAULT_OPTIONS = { 59.16274 + restitution : 0.5, 59.16275 + drift : 0.5, 59.16276 + slop : 0 59.16277 + }; 59.16278 + 59.16279 + function _normalVelocity(particle1, particle2) { 59.16280 + return particle1.velocity.dot(particle2.velocity); 59.16281 + } 59.16282 + 59.16283 + /* 59.16284 + * Setter for options. 59.16285 + * 59.16286 + * @method setOptions 59.16287 + * @param options {Objects} 59.16288 + */ 59.16289 + Collision.prototype.setOptions = function setOptions(options) { 59.16290 + for (var key in options) this.options[key] = options[key]; 59.16291 + }; 59.16292 + 59.16293 + /** 59.16294 + * Adds an impulse to a physics body's velocity due to the constraint 59.16295 + * 59.16296 + * @method applyConstraint 59.16297 + * @param targets {Array.Body} Array of bodies to apply the constraint to 59.16298 + * @param source {Body} The source of the constraint 59.16299 + * @param dt {Number} Delta time 59.16300 + */ 59.16301 + Collision.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.16302 + if (source === undefined) return; 59.16303 + 59.16304 + var v1 = source.velocity; 59.16305 + var p1 = source.position; 59.16306 + var w1 = source.inverseMass; 59.16307 + var r1 = source.radius; 59.16308 + 59.16309 + var options = this.options; 59.16310 + var drift = options.drift; 59.16311 + var slop = -options.slop; 59.16312 + var restitution = options.restitution; 59.16313 + 59.16314 + var n = this.normal; 59.16315 + var pDiff = this.pDiff; 59.16316 + var vDiff = this.vDiff; 59.16317 + var impulse1 = this.impulse1; 59.16318 + var impulse2 = this.impulse2; 59.16319 + 59.16320 + for (var i = 0; i < targets.length; i++) { 59.16321 + var target = targets[i]; 59.16322 + 59.16323 + if (target === source) continue; 59.16324 + 59.16325 + var v2 = target.velocity; 59.16326 + var p2 = target.position; 59.16327 + var w2 = target.inverseMass; 59.16328 + var r2 = target.radius; 59.16329 + 59.16330 + pDiff.set(p2.sub(p1)); 59.16331 + vDiff.set(v2.sub(v1)); 59.16332 + 59.16333 + var dist = pDiff.norm(); 59.16334 + var overlap = dist - (r1 + r2); 59.16335 + var effMass = 1/(w1 + w2); 59.16336 + var gamma = 0; 59.16337 + 59.16338 + if (overlap < 0) { 59.16339 + 59.16340 + n.set(pDiff.normalize()); 59.16341 + 59.16342 + if (this._eventOutput) { 59.16343 + var collisionData = { 59.16344 + target : target, 59.16345 + source : source, 59.16346 + overlap : overlap, 59.16347 + normal : n 59.16348 + }; 59.16349 + 59.16350 + this._eventOutput.emit('preCollision', collisionData); 59.16351 + this._eventOutput.emit('collision', collisionData); 59.16352 + } 59.16353 + 59.16354 + var lambda = (overlap <= slop) 59.16355 + ? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass) 59.16356 + : ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass); 59.16357 + 59.16358 + n.mult(dt*lambda).put(impulse1); 59.16359 + impulse1.mult(-1).put(impulse2); 59.16360 + 59.16361 + source.applyImpulse(impulse1); 59.16362 + target.applyImpulse(impulse2); 59.16363 + 59.16364 + //source.setPosition(p1.add(n.mult(overlap/2))); 59.16365 + //target.setPosition(p2.sub(n.mult(overlap/2))); 59.16366 + 59.16367 + if (this._eventOutput) this._eventOutput.emit('postCollision', collisionData); 59.16368 + 59.16369 + } 59.16370 + } 59.16371 + }; 59.16372 + 59.16373 + module.exports = Collision; 59.16374 +}); 59.16375 + 59.16376 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16377 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16378 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16379 + * 59.16380 + * Owner: david@famo.us 59.16381 + * @license MPL 2.0 59.16382 + * @copyright Famous Industries, Inc. 2014 59.16383 + */ 59.16384 + 59.16385 +define('famous/physics/constraints/Curve',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.16386 + var Constraint = require('./Constraint'); 59.16387 + var Vector = require('famous/math/Vector'); 59.16388 + 59.16389 + /** 59.16390 + * A constraint that keeps a physics body on a given implicit curve 59.16391 + * regardless of other physical forces are applied to it. 59.16392 + * 59.16393 + * A curve constraint is two surface constraints in disguise, as a curve is 59.16394 + * the intersection of two surfaces, and is essentially constrained to both 59.16395 + * 59.16396 + * @class Curve 59.16397 + * @constructor 59.16398 + * @extends Constraint 59.16399 + * @param {Options} [options] An object of configurable options. 59.16400 + * @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y - r*r } corresponds to a circle of radius r pixels 59.16401 + * @param {Function} [options.plane] An implicitly defined second surface that the body is constrained to 59.16402 + * @param {Number} [options.period] The spring-like reaction when the constraint is violated 59.16403 + * @param {Number} [options.number] The damping-like reaction when the constraint is violated 59.16404 + */ 59.16405 + function Curve(options) { 59.16406 + this.options = Object.create(Curve.DEFAULT_OPTIONS); 59.16407 + if (options) this.setOptions(options); 59.16408 + 59.16409 + //registers 59.16410 + this.J = new Vector(); 59.16411 + this.impulse = new Vector(); 59.16412 + 59.16413 + Constraint.call(this); 59.16414 + } 59.16415 + 59.16416 + Curve.prototype = Object.create(Constraint.prototype); 59.16417 + Curve.prototype.constructor = Curve; 59.16418 + 59.16419 + /** @const */ var epsilon = 1e-7; 59.16420 + /** @const */ var pi = Math.PI; 59.16421 + 59.16422 + Curve.DEFAULT_OPTIONS = { 59.16423 + equation : function(x,y,z) { 59.16424 + return 0; 59.16425 + }, 59.16426 + plane : function(x,y,z) { 59.16427 + return z; 59.16428 + }, 59.16429 + period : 0, 59.16430 + dampingRatio : 0 59.16431 + }; 59.16432 + 59.16433 + /** 59.16434 + * Basic options setter 59.16435 + * 59.16436 + * @method setOptions 59.16437 + * @param options {Objects} 59.16438 + */ 59.16439 + Curve.prototype.setOptions = function setOptions(options) { 59.16440 + for (var key in options) this.options[key] = options[key]; 59.16441 + }; 59.16442 + 59.16443 + /** 59.16444 + * Adds a curve impulse to a physics body. 59.16445 + * 59.16446 + * @method applyConstraint 59.16447 + * @param targets {Array.Body} Array of bodies to apply force to. 59.16448 + * @param source {Body} Not applicable 59.16449 + * @param dt {Number} Delta time 59.16450 + */ 59.16451 + Curve.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.16452 + var options = this.options; 59.16453 + var impulse = this.impulse; 59.16454 + var J = this.J; 59.16455 + 59.16456 + var f = options.equation; 59.16457 + var g = options.plane; 59.16458 + var dampingRatio = options.dampingRatio; 59.16459 + var period = options.period; 59.16460 + 59.16461 + for (var i = 0; i < targets.length; i++) { 59.16462 + var body = targets[i]; 59.16463 + 59.16464 + var v = body.velocity; 59.16465 + var p = body.position; 59.16466 + var m = body.mass; 59.16467 + 59.16468 + var gamma; 59.16469 + var beta; 59.16470 + 59.16471 + if (period === 0) { 59.16472 + gamma = 0; 59.16473 + beta = 1; 59.16474 + } 59.16475 + else { 59.16476 + var c = 4 * m * pi * dampingRatio / period; 59.16477 + var k = 4 * m * pi * pi / (period * period); 59.16478 + 59.16479 + gamma = 1 / (c + dt*k); 59.16480 + beta = dt*k / (c + dt*k); 59.16481 + } 59.16482 + 59.16483 + var x = p.x; 59.16484 + var y = p.y; 59.16485 + var z = p.z; 59.16486 + 59.16487 + var f0 = f(x, y, z); 59.16488 + var dfx = (f(x + epsilon, p, p) - f0) / epsilon; 59.16489 + var dfy = (f(x, y + epsilon, p) - f0) / epsilon; 59.16490 + var dfz = (f(x, y, p + epsilon) - f0) / epsilon; 59.16491 + 59.16492 + var g0 = g(x, y, z); 59.16493 + var dgx = (g(x + epsilon, y, z) - g0) / epsilon; 59.16494 + var dgy = (g(x, y + epsilon, z) - g0) / epsilon; 59.16495 + var dgz = (g(x, y, z + epsilon) - g0) / epsilon; 59.16496 + 59.16497 + J.setXYZ(dfx + dgx, dfy + dgy, dfz + dgz); 59.16498 + 59.16499 + var antiDrift = beta/dt * (f0 + g0); 59.16500 + var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m); 59.16501 + 59.16502 + impulse.set(J.mult(dt*lambda)); 59.16503 + body.applyImpulse(impulse); 59.16504 + } 59.16505 + }; 59.16506 + 59.16507 + module.exports = Curve; 59.16508 +}); 59.16509 + 59.16510 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16511 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16512 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16513 + * 59.16514 + * Owner: david@famo.us 59.16515 + * @license MPL 2.0 59.16516 + * @copyright Famous Industries, Inc. 2014 59.16517 + */ 59.16518 + 59.16519 +define('famous/physics/constraints/Distance',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.16520 + var Constraint = require('./Constraint'); 59.16521 + var Vector = require('famous/math/Vector'); 59.16522 + 59.16523 + /** 59.16524 + * A constraint that keeps a physics body a given distance away from a given 59.16525 + * anchor, or another attached body. 59.16526 + * 59.16527 + * 59.16528 + * @class Distance 59.16529 + * @constructor 59.16530 + * @extends Constraint 59.16531 + * @param {Options} [options] An object of configurable options. 59.16532 + * @param {Array} [options.anchor] The location of the anchor 59.16533 + * @param {Number} [options.length] The amount of distance from the anchor the constraint should enforce 59.16534 + * @param {Number} [options.minLength] The minimum distance before the constraint is activated. Use this property for a "rope" effect. 59.16535 + * @param {Number} [options.period] The spring-like reaction when the constraint is broken. 59.16536 + * @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is broken. 59.16537 + * 59.16538 + */ 59.16539 + function Distance(options) { 59.16540 + this.options = Object.create(this.constructor.DEFAULT_OPTIONS); 59.16541 + if (options) this.setOptions(options); 59.16542 + 59.16543 + //registers 59.16544 + this.impulse = new Vector(); 59.16545 + this.normal = new Vector(); 59.16546 + this.diffP = new Vector(); 59.16547 + this.diffV = new Vector(); 59.16548 + 59.16549 + Constraint.call(this); 59.16550 + } 59.16551 + 59.16552 + Distance.prototype = Object.create(Constraint.prototype); 59.16553 + Distance.prototype.constructor = Distance; 59.16554 + 59.16555 + Distance.DEFAULT_OPTIONS = { 59.16556 + anchor : null, 59.16557 + length : 0, 59.16558 + minLength : 0, 59.16559 + period : 0, 59.16560 + dampingRatio : 0 59.16561 + }; 59.16562 + 59.16563 + /** @const */ var pi = Math.PI; 59.16564 + 59.16565 + /** 59.16566 + * Basic options setter 59.16567 + * 59.16568 + * @method setOptions 59.16569 + * @param options {Objects} 59.16570 + */ 59.16571 + Distance.prototype.setOptions = function setOptions(options) { 59.16572 + if (options.anchor) { 59.16573 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 59.16574 + if (options.anchor instanceof Vector) this.options.anchor = options.anchor; 59.16575 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 59.16576 + } 59.16577 + if (options.length !== undefined) this.options.length = options.length; 59.16578 + if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio; 59.16579 + if (options.period !== undefined) this.options.period = options.period; 59.16580 + if (options.minLength !== undefined) this.options.minLength = options.minLength; 59.16581 + }; 59.16582 + 59.16583 + function _calcError(impulse, body) { 59.16584 + return body.mass * impulse.norm(); 59.16585 + } 59.16586 + 59.16587 + /** 59.16588 + * Set the anchor position 59.16589 + * 59.16590 + * @method setOptions 59.16591 + * @param anchor {Array} 59.16592 + */ 59.16593 + Distance.prototype.setAnchor = function setAnchor(anchor) { 59.16594 + if (!this.options.anchor) this.options.anchor = new Vector(); 59.16595 + this.options.anchor.set(anchor); 59.16596 + }; 59.16597 + 59.16598 + /** 59.16599 + * Adds an impulse to a physics body's velocity due to the constraint 59.16600 + * 59.16601 + * @method applyConstraint 59.16602 + * @param targets {Array.Body} Array of bodies to apply the constraint to 59.16603 + * @param source {Body} The source of the constraint 59.16604 + * @param dt {Number} Delta time 59.16605 + */ 59.16606 + Distance.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.16607 + var n = this.normal; 59.16608 + var diffP = this.diffP; 59.16609 + var diffV = this.diffV; 59.16610 + var impulse = this.impulse; 59.16611 + var options = this.options; 59.16612 + 59.16613 + var dampingRatio = options.dampingRatio; 59.16614 + var period = options.period; 59.16615 + var minLength = options.minLength; 59.16616 + 59.16617 + var p2; 59.16618 + var w2; 59.16619 + 59.16620 + if (source) { 59.16621 + var v2 = source.velocity; 59.16622 + p2 = source.position; 59.16623 + w2 = source.inverseMass; 59.16624 + } 59.16625 + else { 59.16626 + p2 = this.options.anchor; 59.16627 + w2 = 0; 59.16628 + } 59.16629 + 59.16630 + var length = this.options.length; 59.16631 + 59.16632 + for (var i = 0; i < targets.length; i++) { 59.16633 + var body = targets[i]; 59.16634 + 59.16635 + var v1 = body.velocity; 59.16636 + var p1 = body.position; 59.16637 + var w1 = body.inverseMass; 59.16638 + 59.16639 + diffP.set(p1.sub(p2)); 59.16640 + n.set(diffP.normalize()); 59.16641 + 59.16642 + var dist = diffP.norm() - length; 59.16643 + 59.16644 + //rope effect 59.16645 + if (Math.abs(dist) < minLength) return; 59.16646 + 59.16647 + if (source) diffV.set(v1.sub(v2)); 59.16648 + else diffV.set(v1); 59.16649 + 59.16650 + var effMass = 1 / (w1 + w2); 59.16651 + var gamma; 59.16652 + var beta; 59.16653 + 59.16654 + if (period === 0) { 59.16655 + gamma = 0; 59.16656 + beta = 1; 59.16657 + } 59.16658 + else { 59.16659 + var c = 4 * effMass * pi * dampingRatio / period; 59.16660 + var k = 4 * effMass * pi * pi / (period * period); 59.16661 + 59.16662 + gamma = 1 / (c + dt*k); 59.16663 + beta = dt*k / (c + dt*k); 59.16664 + } 59.16665 + 59.16666 + var antiDrift = beta/dt * dist; 59.16667 + var lambda = -(n.dot(diffV) + antiDrift) / (gamma + dt/effMass); 59.16668 + 59.16669 + impulse.set(n.mult(dt*lambda)); 59.16670 + body.applyImpulse(impulse); 59.16671 + 59.16672 + if (source) source.applyImpulse(impulse.mult(-1)); 59.16673 + } 59.16674 + }; 59.16675 + 59.16676 + module.exports = Distance; 59.16677 +}); 59.16678 + 59.16679 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16680 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16682 + * 59.16683 + * Owner: david@famo.us 59.16684 + * @license MPL 2.0 59.16685 + * @copyright Famous Industries, Inc. 2014 59.16686 + */ 59.16687 + 59.16688 +define('famous/physics/constraints/Surface',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) { 59.16689 + var Constraint = require('./Constraint'); 59.16690 + var Vector = require('famous/math/Vector'); 59.16691 + 59.16692 + /** 59.16693 + * A constraint that keeps a physics body on a given implicit surface 59.16694 + * regardless of other physical forces are applied to it. 59.16695 + * 59.16696 + * @class Surface 59.16697 + * @constructor 59.16698 + * @extends Constraint 59.16699 + * @param {Options} [options] An object of configurable options. 59.16700 + * @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y + z*z - r*r } corresponds to a sphere of radius r pixels. 59.16701 + * @param {Number} [options.period] The spring-like reaction when the constraint is violated. 59.16702 + * @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is violated. 59.16703 + */ 59.16704 + function Surface(options) { 59.16705 + this.options = Object.create(Surface.DEFAULT_OPTIONS); 59.16706 + if (options) this.setOptions(options); 59.16707 + 59.16708 + this.J = new Vector(); 59.16709 + this.impulse = new Vector(); 59.16710 + 59.16711 + Constraint.call(this); 59.16712 + } 59.16713 + 59.16714 + Surface.prototype = Object.create(Constraint.prototype); 59.16715 + Surface.prototype.constructor = Surface; 59.16716 + 59.16717 + Surface.DEFAULT_OPTIONS = { 59.16718 + equation : undefined, 59.16719 + period : 0, 59.16720 + dampingRatio : 0 59.16721 + }; 59.16722 + 59.16723 + /** @const */ var epsilon = 1e-7; 59.16724 + /** @const */ var pi = Math.PI; 59.16725 + 59.16726 + /** 59.16727 + * Basic options setter 59.16728 + * 59.16729 + * @method setOptions 59.16730 + * @param options {Objects} 59.16731 + */ 59.16732 + Surface.prototype.setOptions = function setOptions(options) { 59.16733 + for (var key in options) this.options[key] = options[key]; 59.16734 + }; 59.16735 + 59.16736 + /** 59.16737 + * Adds a surface impulse to a physics body. 59.16738 + * 59.16739 + * @method applyConstraint 59.16740 + * @param targets {Array.Body} Array of bodies to apply force to. 59.16741 + * @param source {Body} Not applicable 59.16742 + * @param dt {Number} Delta time 59.16743 + */ 59.16744 + Surface.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.16745 + var impulse = this.impulse; 59.16746 + var J = this.J; 59.16747 + var options = this.options; 59.16748 + 59.16749 + var f = options.equation; 59.16750 + var dampingRatio = options.dampingRatio; 59.16751 + var period = options.period; 59.16752 + 59.16753 + for (var i = 0; i < targets.length; i++) { 59.16754 + var particle = targets[i]; 59.16755 + 59.16756 + var v = particle.velocity; 59.16757 + var p = particle.position; 59.16758 + var m = particle.mass; 59.16759 + 59.16760 + var gamma; 59.16761 + var beta; 59.16762 + 59.16763 + if (period === 0) { 59.16764 + gamma = 0; 59.16765 + beta = 1; 59.16766 + } 59.16767 + else { 59.16768 + var c = 4 * m * pi * dampingRatio / period; 59.16769 + var k = 4 * m * pi * pi / (period * period); 59.16770 + 59.16771 + gamma = 1 / (c + dt*k); 59.16772 + beta = dt*k / (c + dt*k); 59.16773 + } 59.16774 + 59.16775 + var x = p.x; 59.16776 + var y = p.y; 59.16777 + var z = p.z; 59.16778 + 59.16779 + var f0 = f(x, y, z); 59.16780 + var dfx = (f(x + epsilon, p, p) - f0) / epsilon; 59.16781 + var dfy = (f(x, y + epsilon, p) - f0) / epsilon; 59.16782 + var dfz = (f(x, y, p + epsilon) - f0) / epsilon; 59.16783 + J.setXYZ(dfx, dfy, dfz); 59.16784 + 59.16785 + var antiDrift = beta/dt * f0; 59.16786 + var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m); 59.16787 + 59.16788 + impulse.set(J.mult(dt*lambda)); 59.16789 + particle.applyImpulse(impulse); 59.16790 + } 59.16791 + }; 59.16792 + 59.16793 + module.exports = Surface; 59.16794 +}); 59.16795 + 59.16796 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.16797 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.16798 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.16799 + * 59.16800 + * Owner: david@famo.us 59.16801 + * @license MPL 2.0 59.16802 + * @copyright Famous Industries, Inc. 2014 59.16803 + */ 59.16804 + 59.16805 +define('famous/physics/constraints/Walls',['require','exports','module','./Constraint','./Wall','famous/math/Vector'],function(require, exports, module) { 59.16806 + var Constraint = require('./Constraint'); 59.16807 + var Wall = require('./Wall'); 59.16808 + var Vector = require('famous/math/Vector'); 59.16809 + 59.16810 + /** 59.16811 + * Walls combines one or more Wall primitives and exposes a simple API to 59.16812 + * interact with several walls at once. A common use case would be to set up 59.16813 + * a bounding box for a physics body, that would collide with each side. 59.16814 + * 59.16815 + * @class Walls 59.16816 + * @constructor 59.16817 + * @extends Constraint 59.16818 + * @uses Wall 59.16819 + * @param {Options} [options] An object of configurable options. 59.16820 + * @param {Array} [options.sides] An array of sides e.g., [Walls.LEFT, Walls.TOP] 59.16821 + * @param {Array} [options.size] The size of the bounding box of the walls. 59.16822 + * @param {Array} [options.origin] The center of the wall relative to the size. 59.16823 + * @param {Array} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1] 59.16824 + * @param {Array} [options.slop] Amount of penetration in pixels to ignore before collision event triggers. 59.16825 + * @param {Array} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) The energy ratio lost in a collision (0 = stick, 1 = elastic) 59.16826 + * @param {Array} [options.onContact] How to handle collision against the wall. 59.16827 + */ 59.16828 + function Walls(options) { 59.16829 + this.options = Object.create(Walls.DEFAULT_OPTIONS); 59.16830 + if (options) this.setOptions(options); 59.16831 + _createComponents.call(this, options.sides || this.options.sides); 59.16832 + 59.16833 + Constraint.call(this); 59.16834 + } 59.16835 + 59.16836 + Walls.prototype = Object.create(Constraint.prototype); 59.16837 + Walls.prototype.constructor = Walls; 59.16838 + /** 59.16839 + * @property Walls.ON_CONTACT 59.16840 + * @type Object 59.16841 + * @extends Wall.ON_CONTACT 59.16842 + * @static 59.16843 + */ 59.16844 + Walls.ON_CONTACT = Wall.ON_CONTACT; 59.16845 + 59.16846 + /** 59.16847 + * An enumeration of common types of walls 59.16848 + * LEFT, RIGHT, TOP, BOTTOM, FRONT, BACK 59.16849 + * TWO_DIMENSIONAL, THREE_DIMENSIONAL 59.16850 + * 59.16851 + * @property Walls.SIDES 59.16852 + * @type Object 59.16853 + * @final 59.16854 + * @static 59.16855 + */ 59.16856 + Walls.SIDES = { 59.16857 + LEFT : 0, 59.16858 + RIGHT : 1, 59.16859 + TOP : 2, 59.16860 + BOTTOM : 3, 59.16861 + FRONT : 4, 59.16862 + BACK : 5, 59.16863 + TWO_DIMENSIONAL : [0, 1, 2, 3], 59.16864 + THREE_DIMENSIONAL : [0, 1, 2, 3, 4, 5] 59.16865 + }; 59.16866 + 59.16867 + Walls.DEFAULT_OPTIONS = { 59.16868 + sides : Walls.SIDES.TWO_DIMENSIONAL, 59.16869 + size : [window.innerWidth, window.innerHeight, 0], 59.16870 + origin : [.5, .5, .5], 59.16871 + drift : 0.5, 59.16872 + slop : 0, 59.16873 + restitution : 0.5, 59.16874 + onContact : Walls.ON_CONTACT.REFLECT 59.16875 + }; 59.16876 + 59.16877 + var _SIDE_NORMALS = { 59.16878 + 0 : new Vector(1, 0, 0), 59.16879 + 1 : new Vector(-1, 0, 0), 59.16880 + 2 : new Vector(0, 1, 0), 59.16881 + 3 : new Vector(0,-1, 0), 59.16882 + 4 : new Vector(0, 0, 1), 59.16883 + 5 : new Vector(0, 0,-1) 59.16884 + }; 59.16885 + 59.16886 + function _getDistance(side, size, origin) { 59.16887 + var distance; 59.16888 + var SIDES = Walls.SIDES; 59.16889 + switch (parseInt(side)) { 59.16890 + case SIDES.LEFT: 59.16891 + distance = size[0] * origin[0]; 59.16892 + break; 59.16893 + case SIDES.TOP: 59.16894 + distance = size[1] * origin[1]; 59.16895 + break; 59.16896 + case SIDES.FRONT: 59.16897 + distance = size[2] * origin[2]; 59.16898 + break; 59.16899 + case SIDES.RIGHT: 59.16900 + distance = size[0] * (1 - origin[0]); 59.16901 + break; 59.16902 + case SIDES.BOTTOM: 59.16903 + distance = size[1] * (1 - origin[1]); 59.16904 + break; 59.16905 + case SIDES.BACK: 59.16906 + distance = size[2] * (1 - origin[2]); 59.16907 + break; 59.16908 + } 59.16909 + return distance; 59.16910 + } 59.16911 + 59.16912 + /* 59.16913 + * Setter for options. 59.16914 + * 59.16915 + * @method setOptions 59.16916 + * @param options {Objects} 59.16917 + */ 59.16918 + Walls.prototype.setOptions = function setOptions(options) { 59.16919 + var resizeFlag = false; 59.16920 + if (options.restitution !== undefined) _setOptionsForEach.call(this, {restitution : options.restitution}); 59.16921 + if (options.drift !== undefined) _setOptionsForEach.call(this, {drift : options.drift}); 59.16922 + if (options.slop !== undefined) _setOptionsForEach.call(this, {slop : options.slop}); 59.16923 + if (options.onContact !== undefined) _setOptionsForEach.call(this, {onContact : options.onContact}); 59.16924 + if (options.size !== undefined) resizeFlag = true; 59.16925 + if (options.sides !== undefined) this.options.sides = options.sides; 59.16926 + if (options.origin !== undefined) resizeFlag = true; 59.16927 + if (resizeFlag) this.setSize(options.size, options.origin); 59.16928 + }; 59.16929 + 59.16930 + function _createComponents(sides) { 59.16931 + this.components = {}; 59.16932 + var components = this.components; 59.16933 + 59.16934 + for (var i = 0; i < sides.length; i++) { 59.16935 + var side = sides[i]; 59.16936 + components[i] = new Wall({ 59.16937 + normal : _SIDE_NORMALS[side].clone(), 59.16938 + distance : _getDistance(side, this.options.size, this.options.origin) 59.16939 + }); 59.16940 + } 59.16941 + } 59.16942 + 59.16943 + /* 59.16944 + * Setter for size. 59.16945 + * 59.16946 + * @method setOptions 59.16947 + * @param options {Objects} 59.16948 + */ 59.16949 + Walls.prototype.setSize = function setSize(size, origin) { 59.16950 + origin = origin || this.options.origin; 59.16951 + if (origin.length < 3) origin[2] = 0.5; 59.16952 + 59.16953 + this.forEach(function(wall, side) { 59.16954 + var d = _getDistance(side, size, origin); 59.16955 + wall.setOptions({distance : d}); 59.16956 + }); 59.16957 + 59.16958 + this.options.size = size; 59.16959 + this.options.origin = origin; 59.16960 + }; 59.16961 + 59.16962 + function _setOptionsForEach(options) { 59.16963 + this.forEach(function(wall) { 59.16964 + wall.setOptions(options); 59.16965 + }); 59.16966 + for (var key in options) this.options[key] = options[key]; 59.16967 + } 59.16968 + 59.16969 + /** 59.16970 + * Adds an impulse to a physics body's velocity due to the walls constraint 59.16971 + * 59.16972 + * @method applyConstraint 59.16973 + * @param targets {Array.Body} Array of bodies to apply the constraint to 59.16974 + * @param source {Body} The source of the constraint 59.16975 + * @param dt {Number} Delta time 59.16976 + */ 59.16977 + Walls.prototype.applyConstraint = function applyConstraint(targets, source, dt) { 59.16978 + this.forEach(function(wall) { 59.16979 + wall.applyConstraint(targets, source, dt); 59.16980 + }); 59.16981 + }; 59.16982 + 59.16983 + /** 59.16984 + * Apply a method to each wall making up the walls 59.16985 + * 59.16986 + * @method applyConstraint 59.16987 + * @param fn {Function} Function that takes in a wall as its first parameter 59.16988 + */ 59.16989 + Walls.prototype.forEach = function forEach(fn) { 59.16990 + for (var key in this.sides) fn(this.sides[key], key); 59.16991 + }; 59.16992 + 59.16993 + /** 59.16994 + * Rotates the walls by an angle in the XY-plane 59.16995 + * 59.16996 + * @method applyConstraint 59.16997 + * @param angle {Function} 59.16998 + */ 59.16999 + Walls.prototype.rotateZ = function rotateZ(angle) { 59.17000 + this.forEach(function(wall) { 59.17001 + var n = wall.options.normal; 59.17002 + n.rotateZ(angle).put(n); 59.17003 + }); 59.17004 + }; 59.17005 + 59.17006 + /** 59.17007 + * Rotates the walls by an angle in the YZ-plane 59.17008 + * 59.17009 + * @method applyConstraint 59.17010 + * @param angle {Function} 59.17011 + */ 59.17012 + Walls.prototype.rotateX = function rotateX(angle) { 59.17013 + this.forEach(function(wall) { 59.17014 + var n = wall.options.normal; 59.17015 + n.rotateX(angle).put(n); 59.17016 + }); 59.17017 + }; 59.17018 + 59.17019 + /** 59.17020 + * Rotates the walls by an angle in the XZ-plane 59.17021 + * 59.17022 + * @method applyConstraint 59.17023 + * @param angle {Function} 59.17024 + */ 59.17025 + Walls.prototype.rotateY = function rotateY(angle) { 59.17026 + this.forEach(function(wall) { 59.17027 + var n = wall.options.normal; 59.17028 + n.rotateY(angle).put(n); 59.17029 + }); 59.17030 + }; 59.17031 + 59.17032 + module.exports = Walls; 59.17033 +}); 59.17034 + 59.17035 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.17036 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.17037 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.17038 + * 59.17039 + * Owner: david@famo.us 59.17040 + * @license MPL 2.0 59.17041 + * @copyright Famous Industries, Inc. 2014 59.17042 + */ 59.17043 + 59.17044 +//TODO: test options manager 59.17045 +define('famous/physics/forces/Repulsion',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 59.17046 + var Force = require('./Force'); 59.17047 + var Vector = require('famous/math/Vector'); 59.17048 + 59.17049 + /** 59.17050 + * Repulsion is a force that repels (attracts) bodies away (towards) 59.17051 + * each other. A repulsion of negative strength is attractive. 59.17052 + * 59.17053 + * @class Repulsion 59.17054 + * @constructor 59.17055 + * @extends Force 59.17056 + * @param {Object} options overwrites default options 59.17057 + */ 59.17058 + function Repulsion(options) { 59.17059 + this.options = Object.create(Repulsion.DEFAULT_OPTIONS); 59.17060 + if (options) this.setOptions(options); 59.17061 + 59.17062 + //registers 59.17063 + this.disp = new Vector(); 59.17064 + 59.17065 + Force.call(this); 59.17066 + } 59.17067 + 59.17068 + Repulsion.prototype = Object.create(Force.prototype); 59.17069 + Repulsion.prototype.constructor = Repulsion; 59.17070 + /** 59.17071 + * @property Repulsion.DECAY_FUNCTIONS 59.17072 + * @type Object 59.17073 + * @protected 59.17074 + * @static 59.17075 + */ 59.17076 + Repulsion.DECAY_FUNCTIONS = { 59.17077 + 59.17078 + /** 59.17079 + * A linear decay function 59.17080 + * @attribute LINEAR 59.17081 + * @type Function 59.17082 + * @param {Number} r distance from the source body 59.17083 + * @param {Number} cutoff the effective radius of influence 59.17084 + */ 59.17085 + LINEAR : function(r, cutoff) { 59.17086 + return Math.max(1 - (1 / cutoff) * r, 0); 59.17087 + }, 59.17088 + 59.17089 + /** 59.17090 + * A Morse potential decay function (http://en.wikipedia.org/wiki/Morse_potential) 59.17091 + * @attribute MORSE 59.17092 + * @type Function 59.17093 + * @param {Number} r distance from the source body 59.17094 + * @param {Number} cutoff the minimum radius of influence 59.17095 + */ 59.17096 + MORSE : function(r, cutoff) { 59.17097 + var r0 = (cutoff === 0) ? 100 : cutoff; 59.17098 + var rShifted = r + r0 * (1 - Math.log(2)); //shift by x-intercept 59.17099 + return Math.max(1 - Math.pow(1 - Math.exp(rShifted/r0 - 1), 2), 0); 59.17100 + }, 59.17101 + 59.17102 + /** 59.17103 + * An inverse distance decay function 59.17104 + * @attribute INVERSE 59.17105 + * @type Function 59.17106 + * @param {Number} r distance from the source body 59.17107 + * @param {Number} cutoff a distance shift to avoid singularities 59.17108 + */ 59.17109 + INVERSE : function(r, cutoff) { 59.17110 + return 1 / (1 - cutoff + r); 59.17111 + }, 59.17112 + 59.17113 + /** 59.17114 + * An inverse squared distance decay function 59.17115 + * @attribute INVERSE 59.17116 + * @type Function 59.17117 + * @param {Number} r distance from the source body 59.17118 + * @param {Number} cutoff a distance shift to avoid singularities 59.17119 + */ 59.17120 + GRAVITY : function(r, cutoff) { 59.17121 + return 1 / (1 - cutoff + r*r); 59.17122 + } 59.17123 + }; 59.17124 + 59.17125 + /** 59.17126 + * @property Repulsion.DEFAULT_OPTIONS 59.17127 + * @type Object 59.17128 + * @protected 59.17129 + * @static 59.17130 + */ 59.17131 + Repulsion.DEFAULT_OPTIONS = { 59.17132 + 59.17133 + /** 59.17134 + * The strength of the force 59.17135 + * Range : [0, 100] 59.17136 + * @attribute strength 59.17137 + * @type Number 59.17138 + * @default 1 59.17139 + */ 59.17140 + strength : 1, 59.17141 + 59.17142 + /** 59.17143 + * The location of the force, if not another physics body 59.17144 + * 59.17145 + * @attribute anchor 59.17146 + * @type Number 59.17147 + * @default 0.01 59.17148 + * @optional 59.17149 + */ 59.17150 + anchor : undefined, 59.17151 + 59.17152 + /** 59.17153 + * The range of the repulsive force 59.17154 + * @attribute radii 59.17155 + * @type Array 59.17156 + * @default [0, Infinity] 59.17157 + */ 59.17158 + range : [0, Infinity], 59.17159 + 59.17160 + /** 59.17161 + * A normalization for the force to avoid singularities at the origin 59.17162 + * @attribute cutoff 59.17163 + * @type Number 59.17164 + * @default 0 59.17165 + */ 59.17166 + cutoff : 0, 59.17167 + 59.17168 + /** 59.17169 + * The maximum magnitude of the force 59.17170 + * Range : [0, Infinity] 59.17171 + * @attribute cap 59.17172 + * @type Number 59.17173 + * @default Infinity 59.17174 + */ 59.17175 + cap : Infinity, 59.17176 + 59.17177 + /** 59.17178 + * The type of decay the repulsive force should have 59.17179 + * @attribute decayFunction 59.17180 + * @type Function 59.17181 + */ 59.17182 + decayFunction : Repulsion.DECAY_FUNCTIONS.GRAVITY 59.17183 + }; 59.17184 + 59.17185 + /* 59.17186 + * Setter for options. 59.17187 + * 59.17188 + * @method setOptions 59.17189 + * @param {Objects} options 59.17190 + */ 59.17191 + Repulsion.prototype.setOptions = function setOptions(options) { 59.17192 + if (options.anchor !== undefined) { 59.17193 + if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position; 59.17194 + if (options.anchor instanceof Array) this.options.anchor = new Vector(options.anchor); 59.17195 + delete options.anchor; 59.17196 + } 59.17197 + for (var key in options) this.options[key] = options[key]; 59.17198 + }; 59.17199 + 59.17200 + /** 59.17201 + * Adds a drag force to a physics body's force accumulator. 59.17202 + * 59.17203 + * @method applyForce 59.17204 + * @param targets {Array.Body} Array of bodies to apply force to 59.17205 + * @param source {Body} The source of the force 59.17206 + */ 59.17207 + Repulsion.prototype.applyForce = function applyForce(targets, source) { 59.17208 + var options = this.options; 59.17209 + var force = this.force; 59.17210 + var disp = this.disp; 59.17211 + 59.17212 + var strength = options.strength; 59.17213 + var anchor = options.anchor || source.position; 59.17214 + var cap = options.cap; 59.17215 + var cutoff = options.cutoff; 59.17216 + var rMin = options.range[0]; 59.17217 + var rMax = options.range[1]; 59.17218 + var decayFn = options.decayFunction; 59.17219 + 59.17220 + if (strength === 0) return; 59.17221 + 59.17222 + for (var index in targets) { 59.17223 + var particle = targets[index]; 59.17224 + 59.17225 + if (particle === source) continue; 59.17226 + 59.17227 + var m1 = particle.mass; 59.17228 + var p1 = particle.position; 59.17229 + 59.17230 + disp.set(p1.sub(anchor)); 59.17231 + var r = disp.norm(); 59.17232 + 59.17233 + if (r < rMax && r > rMin) { 59.17234 + force.set(disp.normalize(strength * m1 * decayFn(r, cutoff)).cap(cap)); 59.17235 + particle.applyForce(force); 59.17236 + } 59.17237 + } 59.17238 + 59.17239 + }; 59.17240 + 59.17241 + module.exports = Repulsion; 59.17242 +}); 59.17243 + 59.17244 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.17245 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.17246 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.17247 + * 59.17248 + * Owner: david@famo.us 59.17249 + * @license MPL 2.0 59.17250 + * @copyright Famous Industries, Inc. 2014 59.17251 + */ 59.17252 + 59.17253 +define('famous/physics/forces/RotationalDrag',['require','exports','module','./Drag'],function(require, exports, module) { 59.17254 + var Drag = require('./Drag'); 59.17255 + 59.17256 + /** 59.17257 + * Rotational drag is a force that opposes angular velocity. 59.17258 + * Attach it to a physics body to slow down its rotation. 59.17259 + * 59.17260 + * @class RotationalDrag 59.17261 + * @constructor 59.17262 + * @extends Force 59.17263 + * @param {Object} options options to set on drag 59.17264 + */ 59.17265 + function RotationalDrag(options) { 59.17266 + Drag.call(this, options); 59.17267 + } 59.17268 + 59.17269 + RotationalDrag.prototype = Object.create(Drag.prototype); 59.17270 + RotationalDrag.prototype.constructor = RotationalDrag; 59.17271 + 59.17272 + RotationalDrag.DEFAULT_OPTIONS = Drag.DEFAULT_OPTIONS; 59.17273 + RotationalDrag.FORCE_FUNCTIONS = Drag.FORCE_FUNCTIONS; 59.17274 + 59.17275 + /** 59.17276 + * @property Repulsion.FORCE_FUNCTIONS 59.17277 + * @type Object 59.17278 + * @protected 59.17279 + * @static 59.17280 + */ 59.17281 + RotationalDrag.FORCE_FUNCTIONS = { 59.17282 + 59.17283 + /** 59.17284 + * A drag force proprtional to the angular velocity 59.17285 + * @attribute LINEAR 59.17286 + * @type Function 59.17287 + * @param {Vector} angularVelocity 59.17288 + * @return {Vector} drag force 59.17289 + */ 59.17290 + LINEAR : function(angularVelocity) { 59.17291 + return angularVelocity; 59.17292 + }, 59.17293 + 59.17294 + /** 59.17295 + * A drag force proprtional to the square of the angular velocity 59.17296 + * @attribute QUADRATIC 59.17297 + * @type Function 59.17298 + * @param {Vector} angularVelocity 59.17299 + * @return {Vector} drag force 59.17300 + */ 59.17301 + QUADRATIC : function(angularVelocity) { 59.17302 + return angularVelocity.mult(angularVelocity.norm()); 59.17303 + } 59.17304 + }; 59.17305 + 59.17306 + /** 59.17307 + * Adds a rotational drag force to a physics body's torque accumulator. 59.17308 + * 59.17309 + * @method applyForce 59.17310 + * @param targets {Array.Body} Array of bodies to apply drag force to. 59.17311 + */ 59.17312 + RotationalDrag.prototype.applyForce = function applyForce(targets) { 59.17313 + var strength = this.options.strength; 59.17314 + var forceFunction = this.options.forceFunction; 59.17315 + var force = this.force; 59.17316 + 59.17317 + //TODO: rotational drag as function of inertia 59.17318 + for (var index = 0; index < targets.length; index++) { 59.17319 + var particle = targets[index]; 59.17320 + forceFunction(particle.angularVelocity).mult(-100*strength).put(force); 59.17321 + particle.applyTorque(force); 59.17322 + } 59.17323 + }; 59.17324 + 59.17325 + /* 59.17326 + * Setter for options. 59.17327 + * 59.17328 + * @method setOptions 59.17329 + * @param {Objects} options 59.17330 + */ 59.17331 + RotationalDrag.prototype.setOptions = function setOptions(options) { 59.17332 + for (var key in options) this.options[key] = options[key]; 59.17333 + }; 59.17334 + 59.17335 + module.exports = RotationalDrag; 59.17336 +}); 59.17337 + 59.17338 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.17339 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.17340 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.17341 + * 59.17342 + * Owner: david@famo.us 59.17343 + * @license MPL 2.0 59.17344 + * @copyright Famous Industries, Inc. 2014 59.17345 + */ 59.17346 + 59.17347 +//TODO: test inheritance 59.17348 +define('famous/physics/forces/RotationalSpring',['require','exports','module','./Spring'],function(require, exports, module) { 59.17349 + var Spring = require('./Spring'); 59.17350 + 59.17351 + /** 59.17352 + * A force that rotates a physics body back to target Euler angles. 59.17353 + * Just as a spring translates a body to a particular X, Y, Z, location, 59.17354 + * a rotational spring rotates a body to a particular X, Y, Z Euler angle. 59.17355 + * Note: there is no physical agent that does this in the "real world" 59.17356 + * 59.17357 + * @class RotationalSpring 59.17358 + * @constructor 59.17359 + * @extends Spring 59.17360 + * @param {Object} options options to set on drag 59.17361 + */ 59.17362 + function RotationalSpring(options) { 59.17363 + Spring.call(this, options); 59.17364 + } 59.17365 + 59.17366 + RotationalSpring.prototype = Object.create(Spring.prototype); 59.17367 + RotationalSpring.prototype.constructor = RotationalSpring; 59.17368 + 59.17369 + RotationalSpring.DEFAULT_OPTIONS = Spring.DEFAULT_OPTIONS; 59.17370 + RotationalSpring.FORCE_FUNCTIONS = Spring.FORCE_FUNCTIONS; 59.17371 + 59.17372 + /** 59.17373 + * Adds a torque force to a physics body's torque accumulator. 59.17374 + * 59.17375 + * @method applyForce 59.17376 + * @param targets {Array.Body} Array of bodies to apply torque to. 59.17377 + */ 59.17378 + RotationalSpring.prototype.applyForce = function applyForce(targets) { 59.17379 + var force = this.force; 59.17380 + var options = this.options; 59.17381 + var disp = this.disp; 59.17382 + 59.17383 + var stiffness = options.stiffness; 59.17384 + var damping = options.damping; 59.17385 + var restLength = options.length; 59.17386 + var anchor = options.anchor; 59.17387 + 59.17388 + for (var i = 0; i < targets.length; i++) { 59.17389 + var target = targets[i]; 59.17390 + 59.17391 + disp.set(anchor.sub(target.orientation)); 59.17392 + var dist = disp.norm() - restLength; 59.17393 + 59.17394 + if (dist === 0) return; 59.17395 + 59.17396 + //if dampingRatio specified, then override strength and damping 59.17397 + var m = target.mass; 59.17398 + stiffness *= m; 59.17399 + damping *= m; 59.17400 + 59.17401 + force.set(disp.normalize(stiffness * this.forceFunction(dist, this.options.lMax))); 59.17402 + 59.17403 + if (damping) force.set(force.add(target.angularVelocity.mult(-damping))); 59.17404 + 59.17405 + target.applyTorque(force); 59.17406 + } 59.17407 + }; 59.17408 + 59.17409 + /** 59.17410 + * Calculates the potential energy of the rotational spring. 59.17411 + * 59.17412 + * @method getEnergy 59.17413 + * @param {Body} target The physics body attached to the spring 59.17414 + */ 59.17415 + RotationalSpring.prototype.getEnergy = function getEnergy(target) { 59.17416 + var options = this.options; 59.17417 + var restLength = options.length; 59.17418 + var anchor = options.anchor; 59.17419 + var strength = options.stiffness; 59.17420 + 59.17421 + var dist = anchor.sub(target.orientation).norm() - restLength; 59.17422 + return 0.5 * strength * dist * dist; 59.17423 + }; 59.17424 + 59.17425 + module.exports = RotationalSpring; 59.17426 +}); 59.17427 + 59.17428 +/* This Source Code Form is subject to the terms of the Mozilla Public 59.17429 + * License, v. 2.0. If a copy of the MPL was not distributed with this 59.17430 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 59.17431 + * 59.17432 + * Owner: david@famo.us 59.17433 + * @license MPL 2.0 59.17434 + * @copyright Famous Industries, Inc. 2014 59.17435 + */ 59.17436 + 59.17437 +define('famous/physics/forces/VectorField',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) { 59.17438 + var Force = require('./Force'); 59.17439 + var Vector = require('famous/math/Vector'); 59.17440 + 59.17441 + /** 59.17442 + * A force that moves a physics body to a location with a spring motion. 59.17443 + * The body can be moved to another physics body, or an anchor point. 59.17444 + * 59.17445 + * @class VectorField 59.17446 + * @constructor 59.17447 + * @extends Force 59.17448 + * @param {Object} options options to set on drag 59.17449 + */ 59.17450 + function VectorField(options) { 59.17451 + this.options = Object.create(VectorField.DEFAULT_OPTIONS); 59.17452 + if (options) this.setOptions(options); 59.17453 + 59.17454 + _setFieldOptions.call(this, this.options.field); 59.17455 + Force.call(this); 59.17456 + 59.17457 + //registers 59.17458 + this.evaluation = new Vector(0,0,0); 59.17459 + } 59.17460 + 59.17461 + VectorField.prototype = Object.create(Force.prototype); 59.17462 + VectorField.prototype.constructor = VectorField; 59.17463 + 59.17464 + /** 59.17465 + * @property Spring.FORCE_FUNCTIONS 59.17466 + * @type Object 59.17467 + * @protected 59.17468 + * @static 59.17469 + */ 59.17470 + VectorField.FIELDS = { 59.17471 + /** 59.17472 + * Constant force, e.g., gravity 59.17473 + * @attribute CONSTANT 59.17474 + * @type Function 59.17475 + * @param v {Vector} Current position of physics body 59.17476 + * @param options {Object} The direction of the force 59.17477 + * Pass a {direction : Vector} into the VectorField options 59.17478 + * @return {Number} unscaled force 59.17479 + */ 59.17480 + CONSTANT : function(v, options) { 59.17481 + return v.set(options.direction); 59.17482 + }, 59.17483 + 59.17484 + /** 59.17485 + * Linear force 59.17486 + * @attribute LINEAR 59.17487 + * @type Function 59.17488 + * @param v {Vector} Current position of physics body 59.17489 + * @return {Number} unscaled force 59.17490 + */ 59.17491 + LINEAR : function(v) { 59.17492 + return v; 59.17493 + }, 59.17494 + 59.17495 + /** 59.17496 + * Radial force, e.g., Hookean spring 59.17497 + * @attribute RADIAL 59.17498 + * @type Function 59.17499 + * @param v {Vector} Current position of physics body 59.17500 + * @return {Number} unscaled force 59.17501 + */ 59.17502 + RADIAL : function(v) { 59.17503 + return v.set(v.mult(-1, v)); 59.17504 + }, 59.17505 + 59.17506 + /** 59.17507 + * Spherical force 59.17508 + * @attribute SPHERE_ATTRACTOR 59.17509 + * @type Function 59.17510 + * @param v {Vector} Current position of physics body 59.17511 + * @param options {Object} An object with the radius of the sphere 59.17512 + * Pass a {radius : Number} into the VectorField options 59.17513 + * @return {Number} unscaled force 59.17514 + */ 59.17515 + SPHERE_ATTRACTOR : function(v, options) { 59.17516 + return v.set(v.mult((options.radius - v.norm()) / v.norm())); 59.17517 + }, 59.17518 + 59.17519 + /** 59.17520 + * Point attractor force, e.g., Hookean spring with an anchor 59.17521 + * @attribute POINT_ATTRACTOR 59.17522 + * @type Function 59.17523 + * @param v {Vector} Current position of physics body 59.17524 + * @param options {Object} And object with the position of the attractor 59.17525 + * Pass a {position : Vector} into the VectorField options 59.17526 + * @return {Number} unscaled force 59.17527 + */ 59.17528 + POINT_ATTRACTOR : function(v, options) { 59.17529 + return v.set(options.position.sub(v)); 59.17530 + } 59.17531 + }; 59.17532 + 59.17533 + /** 59.17534 + * @property VectorField.DEFAULT_OPTIONS 59.17535 + * @type Object 59.17536 + * @protected 59.17537 + * @static 59.17538 + */ 59.17539 + VectorField.DEFAULT_OPTIONS = { 59.17540 + 59.17541 + /** 59.17542 + * The strength of the force 59.17543 + * Range : [0, 10] 59.17544 + * @attribute strength 59.17545 + * @type Number 59.17546 + * @default 1 59.17547 + */ 59.17548 + strength : 1, 59.17549 + 59.17550 + /** 59.17551 + * Type of vectorfield 59.17552 + * Range : [0, 100] 59.17553 + * @attribute field 59.17554 + * @type Function 59.17555 + */ 59.17556 + field : VectorField.FIELDS.CONSTANT 59.17557 + }; 59.17558 + 59.17559 + /** 59.17560 + * Basic options setter 59.17561 + * 59.17562 + * @method setOptions 59.17563 + * @param {Objects} options 59.17564 + */ 59.17565 + VectorField.prototype.setOptions = function setOptions(options) { 59.17566 + for (var key in options) this.options[key] = options[key]; 59.17567 + }; 59.17568 + 59.17569 + function _setFieldOptions(field) { 59.17570 + var FIELDS = VectorField.FIELDS; 59.17571 + 59.17572 + switch (field) { 59.17573 + case FIELDS.CONSTANT: 59.17574 + if (!this.options.direction) this.options.direction = new Vector(0,1,0); 59.17575 + break; 59.17576 + case FIELDS.POINT_ATTRACTOR: 59.17577 + if (!this.options.position) this.options.position = new Vector(0,0,0); 59.17578 + break; 59.17579 + case FIELDS.SPHERE_ATTRACTOR: 59.17580 + if (!this.options.radius) this.options.radius = 1; 59.17581 + break; 59.17582 + } 59.17583 + } 59.17584 + 59.17585 + function _evaluate(v) { 59.17586 + var evaluation = this.evaluation; 59.17587 + var field = this.options.field; 59.17588 + evaluation.set(v); 59.17589 + return field(evaluation, this.options); 59.17590 + } 59.17591 + 59.17592 + /** 59.17593 + * Adds the vectorfield's force to a physics body's force accumulator. 59.17594 + * 59.17595 + * @method applyForce 59.17596 + * @param targets {Array.body} Array of bodies to apply force to. 59.17597 + */ 59.17598 + VectorField.prototype.applyForce = function applyForce(targets) { 59.17599 + var force = this.force; 59.17600 + for (var i = 0; i < targets.length; i++) { 59.17601 + var particle = targets[i]; 59.17602 + force.set( 59.17603 + _evaluate.call(this, particle.position) 59.17604 + .mult(particle.mass * this.options.strength) 59.17605 + ); 59.17606 + particle.applyForce(force); 59.17607 + } 59.17608 + }; 59.17609 + 59.17610 + module.exports = VectorField; 59.17611 +}); 59.17612 +
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous_styles.css Sun Jul 06 12:02:12 2014 -0700 60.3 @@ -0,0 +1,163 @@ 60.4 +body { 60.5 + color: #404040; 60.6 + background-color: #f2f2f0; 60.7 +} 60.8 + 60.9 +.main { 60.10 + background-color: white; 60.11 +} 60.12 + 60.13 +a { 60.14 + color: #fa5c4f; 60.15 +} 60.16 + 60.17 +.red { 60.18 + color: #fa5c4f; 60.19 +} 60.20 + 60.21 +.light-grey { 60.22 + color: #f2f2f0; 60.23 +} 60.24 + 60.25 +.medium-grey { 60.26 + color: #878785; 60.27 +} 60.28 + 60.29 +.red-bg { 60.30 + color: white; 60.31 + background-color: #fa5c4f; 60.32 +} 60.33 + 60.34 +.red-outline { 60.35 + border: 2px solid #fa5c4f; 60.36 +} 60.37 + 60.38 +.grey-bg { 60.39 + background-color: #404040; 60.40 + color: white; 60.41 +} 60.42 + 60.43 +.spacer-line { 60.44 + border-top: 1px solid #fa5c4f; 60.45 +} 60.46 + 60.47 +.white-bg { 60.48 + background-color: white; 60.49 +} 60.50 + 60.51 +@font-face { 60.52 + font-family: "Avenir Next W04 Demi"; 60.53 + src: url("fonts/7adddd91-84e0-4423-b40e-61945189916d.eot") format("eot"), url("fonts/b0908846-3d5c-4768-af33-5f968b1da156.woff") format("woff"), url("fonts/fe1602be-28ca-467e-9cd3-7bfc586f31bc.ttf") format("truetype"); 60.54 +} 60.55 + 60.56 +@font-face { 60.57 + font-family: "AvenirNextLTW02-Regular"; 60.58 + src: url("fonts/7a1b7ae7-5c29-481f-83ac-652e932c5509.eot") format("eot"), url("fonts/3a42a252-67ff-4186-88cf-762f56719ca1.woff") format("woff"), url("fonts/dbc39ae3-2636-4653-a23e-8938bce2cf51.ttf") format("truetype"); 60.59 +} 60.60 + 60.61 +input:focus { 60.62 + border: 1px solid #fa5c4f; 60.63 +} 60.64 + 60.65 +input:hover { 60.66 + border: 1px solid #404040; 60.67 +} 60.68 + 60.69 +input { 60.70 + outline: 0px; 60.71 + border-radius: 5px; 60.72 + border: 1px solid #f2f2f0; 60.73 + padding: 18px; 60.74 +} 60.75 + 60.76 +body, input { 60.77 + font-family: "AvenirNextLTW02-Regular", sans-serif; 60.78 + font-size: 16px; 60.79 + line-height: 25px; 60.80 +} 60.81 + 60.82 +h1 { 60.83 + font-size: 67px; 60.84 + line-height: 109px; 60.85 + margin-bottom: 67px; 60.86 +} 60.87 + 60.88 +h2 { 60.89 + font-size: 41px; 60.90 + line-height: 67px; 60.91 + margin-bottom: 41px; 60.92 +} 60.93 + 60.94 +h3 { 60.95 + font-size: 25px; 60.96 + line-height: 41px; 60.97 + margin-bottom: 25px; 60.98 +} 60.99 + 60.100 +h4 { 60.101 + font-family: "Avenir Next W04 Demi"; 60.102 +} 60.103 + 60.104 +h4, h5, h6, p, li, a { 60.105 + font-size: 16px; 60.106 + line-height: 25px; 60.107 +} 60.108 + 60.109 +h1, h2, h3, h4, h5, h6 { 60.110 + max-width: 845px; 60.111 +} 60.112 + 60.113 +p { 60.114 + max-width: 522px; 60.115 +} 60.116 + 60.117 +h5 { 60.118 + text-transform: uppercase; 60.119 +} 60.120 + 60.121 +a { 60.122 + text-decoration: none; 60.123 +} 60.124 + 60.125 +a:hover { 60.126 + text-decoration: underline; 60.127 +} 60.128 + 60.129 +pre { 60.130 + font-family: monospace; 60.131 + width: 100%; 60.132 + background-color: #404040; 60.133 + border-radius: 5px; 60.134 + padding: 27px 18px; 60.135 + overflow-x: scroll; 60.136 +} 60.137 + 60.138 +ul { 60.139 + margin-left: 25px; 60.140 +} 60.141 + 60.142 +code { 60.143 + width: 100%; 60.144 +} 60.145 + 60.146 +p, pre, ul { 60.147 + margin-bottom: 25px; 60.148 +} 60.149 + 60.150 +small { 60.151 + font-size: 9px; 60.152 + line-height: 9px; 60.153 +} 60.154 + 60.155 +.button { 60.156 + padding: 18px; 60.157 + border-radius: 3px; 60.158 + margin: 29px 0px; 60.159 +} 60.160 + 60.161 +.backface-visible { 60.162 + backface-visibility: visible; 60.163 + -webkit-backface-visibility: visible; 60.164 + -moz-backface-visibility: visible; 60.165 + -ms-backface-visibility: visible; 60.166 +}
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/functionPrototypeBind.js Sun Jul 06 12:02:12 2014 -0700 61.3 @@ -0,0 +1,23 @@ 61.4 +if (!Function.prototype.bind) { 61.5 + Function.prototype.bind = function (oThis) { 61.6 + if (typeof this !== "function") { 61.7 + // closest thing possible to the ECMAScript 5 internal IsCallable function 61.8 + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 61.9 + } 61.10 + 61.11 + var aArgs = Array.prototype.slice.call(arguments, 1), 61.12 + fToBind = this, 61.13 + fNOP = function () {}, 61.14 + fBound = function () { 61.15 + return fToBind.apply(this instanceof fNOP && oThis 61.16 + ? this 61.17 + : oThis, 61.18 + aArgs.concat(Array.prototype.slice.call(arguments))); 61.19 + }; 61.20 + 61.21 + fNOP.prototype = this.prototype; 61.22 + fBound.prototype = new fNOP(); 61.23 + 61.24 + return fBound; 61.25 + }; 61.26 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/requestAnimationFrame.js Sun Jul 06 12:02:12 2014 -0700 62.3 @@ -0,0 +1,13 @@ 62.4 +// adds requestAnimationFrame functionality 62.5 +// Source: http://strd6.com/2011/05/better-window-requestanimationframe-shim/ 62.6 + 62.7 +window.requestAnimationFrame || (window.requestAnimationFrame = 62.8 + window.webkitRequestAnimationFrame || 62.9 + window.mozRequestAnimationFrame || 62.10 + window.oRequestAnimationFrame || 62.11 + window.msRequestAnimationFrame || 62.12 + function(callback, element) { 62.13 + return window.setTimeout(function() { 62.14 + callback(+new Date()); 62.15 + }, 1000 / 60); 62.16 +});
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/require.js Sun Jul 06 12:02:12 2014 -0700 63.3 @@ -0,0 +1,36 @@ 63.4 +/* 63.5 + RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 63.6 + Available via the MIT or new BSD license. 63.7 + see: http://github.com/jrburke/requirejs for details 63.8 +*/ 63.9 +var requirejs,require,define; 63.10 +(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof 63.11 +RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n= 63.12 +I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b; 63.13 +g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0, 63.14 +b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a)); 63.15 +return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]= 63.16 +!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+ 63.17 +f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a; 63.18 +for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module? 63.19 +a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback= 63.20 +b;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a= 63.21 +this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&& 63.22 +(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= 63.23 +this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f); 63.24 +if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval", 63.25 +"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b, 63.26 +a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m, 63.27 +nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b, 63.28 +a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild= 63.29 +!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!== 63.30 +d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b, 63.31 +c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0, 63.32 +d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C("scripterror", 63.33 +"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/, 63.34 +Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)}; 63.35 +h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.11";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c= 63.36 +b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)): 63.37 +(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl= 63.38 +Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b|| 63.39 +(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);
64.1 Binary file 1__Development/9__Design_documents/0__figures__on_which_work_out_fundamentals_of_EQNLang/09_My_26___HamiltonianPath_and_Taylor_series.pdf has changed
