OSDN Git Service

Client is version 0.5.44, fetch pettanR resourcies working!
[pettanr/pettanr.git] / app / assets / javascripts / system.js
1 /*
2  * pettanR system.js
3  *   version 0.5.44
4  *
5  * gadgetOS
6  *   author:
7  *     itozyun
8  *   licence:
9  *     3-clause BSD
10  */
11
12 ( function( window, document, undefined ){
13         
14         var body           = document.getElementsByTagName( 'body' )[ 0 ]; //( document.compatMode || '' ) !== 'CSS1Compat' ? document.body : document.documentElement;// 
15         var SERVICE_LIST   = [];
16         var SUPER_USER_KEY = { getUID: function(){ return 0; }};
17         var API_USER_LIST  = [ SUPER_USER_KEY ];
18         var numApiUser     = 1;
19         
20         function EMPTY_FUNCTION(){};
21         
22         function isApiUser( _user ){
23                 return _user === SUPER_USER_KEY ||
24                         File.isDriver( _user ) === true ||
25                         Application.isApplicationInstance( _user ) === true;
26         };
27         
28         var Const = {
29                 FILE: {
30                         TYPE: {
31                                 UNKNOWN:        0,
32                                 FOLDER:         1,
33                                 IMAGE:          2,
34                                 TEXT:           3,
35                                 HTML:           4,
36                                 CSV:            5,
37                                 JSON:           6,
38                                 XML:            7
39                         },
40                         STATE: {
41                                 UNKNOWN:        0,
42                                 OK:                     1,
43                                 LOADING:        2,
44                                 ERROR:          3,
45                                 BROKEN:         4
46                         },
47                         UPDATE_POLICY: {
48                                 _____:          parseInt( '00000', 2 ),
49                                 ____C:          parseInt( '00001', 2 ), // hasCreateMenu
50                                 ___W_:          parseInt( '00010', 2 ), // isWritable
51                                 ___WC:          parseInt( '00011', 2 ), // isWritable
52                                 __R__:          parseInt( '00100', 2 ), // isRenamable
53                                 __R_C:          parseInt( '00101', 2 ), // hasCreateMenu
54                                 __RW_:          parseInt( '00110', 2 ), // isWritable
55                                 __RWC:          parseInt( '00111', 2 ), // isWritable
56                                 _S___:          parseInt( '01000', 2 ), // childrenIsSortable
57                                 _S__C:          parseInt( '01001', 2 ),
58                                 _S_W_:          parseInt( '01010', 2 ),
59                                 _S_WC:          parseInt( '01011', 2 ),
60                                 _SR__:          parseInt( '01100', 2 ),
61                                 _SR_C:          parseInt( '01101', 2 ),
62                                 _SRW_:          parseInt( '01110', 2 ),
63                                 _SRWC:          parseInt( '01111', 2 ),
64                                 D____:          parseInt( '10000', 2 ),
65                                 D___C:          parseInt( '10001', 2 ), // hasCreateMenu
66                                 D__W_:          parseInt( '10010', 2 ), // isWritable
67                                 D__WC:          parseInt( '10011', 2 ), // isWritable
68                                 D_R__:          parseInt( '10100', 2 ), // isRenamable
69                                 D_R_C:          parseInt( '10101', 2 ), // hasCreateMenu
70                                 D_RW_:          parseInt( '10110', 2 ), // isWritable
71                                 D_RWC:          parseInt( '10111', 2 ), // isWritable
72                                 DS___:          parseInt( '11000', 2 ), // childrenIsSortable
73                                 DS__C:          parseInt( '11001', 2 ),
74                                 DS_W_:          parseInt( '11010', 2 ),
75                                 DS_WC:          parseInt( '11011', 2 ),
76                                 DSR__:          parseInt( '11100', 2 ),
77                                 DSR_C:          parseInt( '11101', 2 ),
78                                 DSRW_:          parseInt( '11110', 2 ),
79                                 DSRWC:          parseInt( '11111', 2 ),
80                                 CREATE:         1,
81                                 WRAITE:         2,
82                                 RENAME:         4,
83                                 SORT:           8,
84                                 DELETE:         16
85                         },
86                         EVENT: {
87                                 UPDATE_ATTRIVUTE:       'onFileUpdate',
88                                 GET_SEQENTIAL_FILES:'gotSeqentilFiles'
89                         },
90                         DATA_PROPERTY_RESERVED: [
91                                 'children', 'driver', 'state', 'type'
92                         ]                       
93                 },
94                 TREE: {
95                         EVENT: {
96                                 UPDATE:                         'onTreeUpdate'
97                         }
98                 },
99                 KEY: {
100                         EVENT: {
101                                 KEY_DOWN:                       'keydown',
102                                 KEY_UP:                         'keyup',
103                                 KEY_CHANGE:                     'keychange',
104                                 CURSOL:                         'cursol'
105                         }
106                 },
107                 APP: {
108                         TYPE: {
109                                 GENERAL : 0,
110                                 OVERLAY : 1,
111                                 PAGE    : 2
112                         }
113                 }
114         };
115
116 /**
117  * Class を定義し システムの管理下に置く.
118  * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される.
119  *  1. Class.create( def, opt_final, opt_pool, opt_abstract ) でクラスを登録.
120  *  2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く.
121  *  3. 通常通り new で インスタンス生成
122  *  4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.
123  *  5. pool が有効の場合、new で pool されたインスタンスが返される.
124  *  6. 
125  * 
126  */
127 var Class = ( function(){
128         var CLASS_LIST         = [],
129                 DEF_LIST           = [],
130                 PRIVATE_CLASS_LIST = [],
131                 PRIVATE_DEF_LIST   = [],
132                 CONSTRUCTOR        = 'Constructor',
133                 GET_INDEX          = Util.getIndex,
134                 killPrivateFlag    = false,
135                 dataUser           = null,
136                 traits             = null,
137                 f                  = true,
138                 c                  = Util.copyArray,
139                 a; /* arguments */
140         
141         function getClass( instance ){
142                 var cList    = CLASS_LIST,
143                         i        = cList.length,
144                         klass;
145                 for( ; i; ){
146                         klass = cList[ --i ];
147                         if( instance instanceof klass ) return klass;
148                 };
149                 cList = PRIVATE_CLASS_LIST;
150                 i     = cList.length;
151                 for( ; i; ){
152                         klass = cList[ --i ];
153                         if( instance instanceof klass ) return klass;
154                 };
155                 
156                 if( GET_INDEX( cList, instance ) !== -1 ) return instance;
157                 if( GET_INDEX( CLASS_LIST, instance ) !== -1 ) return instance;
158         };
159         
160         function getClassDef( KlassOrInstance ){
161                 var getIndex = GET_INDEX,
162                         i        = getIndex( CLASS_LIST, KlassOrInstance );
163                 if( i === -1 ) i = getIndex( CLASS_LIST, getClass( KlassOrInstance ) );
164                 if( i !== -1 ) return DEF_LIST[ i ];
165                 
166                 i = getIndex( PRIVATE_CLASS_LIST, KlassOrInstance );
167                 if( i === -1 ) i = getIndex( PRIVATE_CLASS_LIST, getClass( KlassOrInstance ) );
168                 if( i !== -1 ) return PRIVATE_DEF_LIST[ i ];
169                 
170                 if( GET_INDEX( DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance;
171                 if( GET_INDEX( PRIVATE_DEF_LIST, KlassOrInstance ) !== -1 ) return KlassOrInstance;
172         };
173         
174         /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */
175         function override( target, over, force ){
176                 for( var p in over ){
177                         if( force === true || typeof target[ p ] === 'undefined' ){
178                                 target[ p ] = over[ p ];
179                         };
180                 };
181                 return target;
182         };
183         
184         /* サブクラスを作るメソッド  
185          * var subClass = superClass.inherits( ... ) 
186          * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002
187          */
188         function inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){
189                 var args        = c( arguments ),
190                         params      = [],
191                         Super       = this,
192                         superDef    = getClassDef( Super ),
193                         displayName = args[ 0 ],
194                         classSetting,
195                         opt_super,
196                         klass;
197                 if( superDef.Final === true ) throw new Error( 'Class is final!' );
198                 
199                 if( Type.isString( displayName ) === true ){
200                         args.shift();
201                 } else {
202                         displayName = 'SubClass of ' + superDef.displayName;
203                 };
204                 params.push( displayName );
205                 
206                 classSetting = args[ 0 ];
207                 if( Type.isNumber( classSetting ) === true ){
208                         if( superDef.isPrivate === true ) classSetting = classSetting | Class.PRIVATE_DATA;
209                         opt_super = !!( classSetting & Class.SUPER_ACCESS );
210                         params.push( classSetting );
211                         args.shift();
212                 };
213                 if( getClass( args[ 0 ] ) ){
214                         params.push( args.shift() );
215                 } else
216                 if( superDef.privateClass ){
217                         params.push( superDef.privateClass );
218                 };
219                 params.push( args[ 0 ] ); /* props */
220                 f      = false;
221                 traits = new Super();
222                 f      = true;
223                 klass  = Class.create.apply( Class, params );
224                 traits = null;
225                 if( opt_super === true ) getClassDef( klass ).Super = Super.prototype;
226                 return klass;
227         };
228         
229         /* Class.create で作られたクラスのインスタンスが共通で備えるメソッド */
230         var CommonProps = {
231                 kill : function(){
232                         var instance = this,
233                                 klass    = getClass( instance ),
234                                 def      = getClassDef( klass ),
235                                 data, p, i;
236                         if( def.isPrivate === true && killPrivateFlag === false ){
237                                 throw new Error( 'PrivateInstance.kill() work in PrivateUser.kill().' );
238                         };
239                         Type.isFunction( instance.onKill ) === true && instance.onKill();
240                         for( p in instance ){
241                                 if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue;
242                                 delete instance[ p ];
243                         };
244                         if( def.pool ){
245                                 def.live && def.live.splice( GET_INDEX( def.live, instance ), 1 );
246                                 def.pool.push( instance );
247                         };
248                         if( def.privateClass ){
249                                 i = GET_INDEX( def.userList, instance );
250                                 if( i !== -1 ){
251                                         data            = klass.getPrivateData( instance );
252                                         killPrivateFlag = true;
253                                         data.kill();
254                                         killPrivateFlag = false;
255                                         def.dataList.splice( i, 1 );
256                                         def.userList.splice( i, 1 );
257                                 };
258                         };
259                         // myCallback の削除
260                         // myCallback を受け取った API への通知
261                 },
262                 getMyCallback : function( callback ){
263                         var def       = getClassDef( this ),
264                                 iList     = def.callbackInstanceList,
265                                 rList     = def.callbackRegisterList,
266                                 i, cList, myCallback;
267                         if( !iList ){
268                                 iList = def.callbackInstanceList = [];
269                                 rList = def.callbackRegisterList = [];
270                         };
271                         i = GET_INDEX( iList, this );
272                         if( i === -1 ){
273                                 cList = [];
274                                 iList.push( this );
275                                 rList.push( cList );
276                         } else {
277                                 cList = rList[ i ];
278                                 for( i = cList.length; i; ){
279                                         if( cList[ --i ].callback === callback ) return cList[ i ];
280                                 };
281                         };
282                         myCallback = new Callback( this, callback );
283                         cList.push( myCallback );
284                         return myCallback;
285                 },
286                 releaseMyCallback : function( callback ){
287                         var def   = getClassDef( this ),
288                                 iList = def.callbackInstanceList,
289                                 rList = def.callbackRegisterList,
290                                 i, _i, cList;
291                         if( !iList ) return;
292                         i = GET_INDEX( iList, this );
293                         if( i === -1 ) return;
294                         cList = rList[ i ];
295                         _i    = GET_INDEX( cList, callback );
296                         if( _i === -1 ) return;
297                         cList.splice( _i, 1 );
298                         callback.kill();
299                         if( cList.length !== 0 ) return;
300                         iList.splice( i, 1 );
301                         rList.splice( i, 1 );
302                         if( iList.length !== 0 ) return;
303                         delete def.callbackInstanceList;
304                         delete def.callbackRegisterList;
305                 }
306         };
307
308         /* privateDataclass をもつクラスに追加されるメソッド */
309         function newPrivateData( /* instance, args */ ){
310                 var args         = c( arguments ),
311                         user         = args.shift(),
312                         def          = getClassDef( user ),
313                         privateClass = def.privateClass,
314                         privateDef   = getClassDef( privateClass ),
315                         i            = -1,
316                         data;
317                 if( def.userList ){
318                         i = GET_INDEX( def.userList, user );
319                 } else {
320                         def.userList = [];
321                         def.dataList = [];
322                 };
323                 if( i !== -1 ){
324                         throw new Error( 'PrivateData already exist!' );
325                 };
326                 dataUser  = user;
327                 data      = new privateClass( args );
328                 data.User = user;
329                 dataUser  = null;       
330                 return data;
331         };
332         function getPrivateData( instance ){
333                 var def = getClassDef( instance ),
334                         i   = GET_INDEX( def.userList, instance );
335                 if( i !== -1 ) return def.dataList[ i ];
336         };
337         
338         /*
339          * new の実体.コンストラクタの機能は instance.Constructor に書く.
340          * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる
341          */
342         /* Constructor Real for GeneralClass */
343         function C( args ){
344                 var klass = this,
345                         def   = getClassDef( klass ),   
346                         instance,
347                         userDef;
348                 if( def.Abstract === true ){
349                         throw new Error( 'AbstractClass!' );
350                 };
351                 if( def.isPrivate === true && dataUser === null ){
352                         throw new Error( 'use myClass.newPrivateData( instance, ...args )!' );
353                 };
354                 f = false;
355                 instance = def.pool && def.pool.length > 0 ? def.pool.shift() : instance = new klass();
356                 f = true;
357                 if( def.Super && !instance.Super ) instance.Super = def.Super;
358                 if( def.isPrivate === true ){
359                         userDef = getClassDef( dataUser );
360                         userDef.dataList.push( instance );
361                         userDef.userList.push( dataUser );
362                 } else {
363                         def.live && def.live.push( instance );
364                         args = c( arguments );
365                 };
366                 def[ CONSTRUCTOR ] && def[ CONSTRUCTOR ].apply( instance, args );
367                 return instance;
368         };
369         
370         return {
371                 POOL_OBJECT  : 1,
372                 ABSTRACT     : 2,
373                 FINAL        : 4,
374                 SUPER_ACCESS : 8,
375                 PRIVATE_DATA : 16,
376                 create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){
377                         var args        = c( arguments ),
378                                 displayName = args[ 0 ],
379                                 classSetting,
380                                 opt_pool, opt_abstract, opt_final, opt_private,
381                                 privateDef,
382                                 props,
383                                 klass,
384                                 classDef = {};
385                         if( Type.isString( displayName ) === true ){
386                                 classDef.displayName = displayName;
387                                 args.shift();
388                         };
389                         classSetting = args[ 0 ];
390                         if( Type.isNumber( classSetting ) === true ){
391                                 opt_pool     = !!( classSetting & Class.POOL_OBJECT  );
392                                 opt_abstract = !!( classSetting & Class.ABSTRACT     );
393                                 opt_final    = !!( classSetting & Class.FINAL        );
394                                 opt_private  = !!( classSetting & Class.PRIVATE_DATA );
395                                 if( opt_final === true && opt_abstract === true ){
396                                         throw new Error( 'final & Abstract!' );
397                                 };                              
398                                 args.shift();
399                         };
400                         
401                         if( GET_INDEX( PRIVATE_CLASS_LIST, args[ 0 ] ) !== -1 ){
402                                 privateDef = getClassDef( args[ 0 ] );
403                                 if( privateDef.isPrivate !== true ){
404                                         throw new Error( 'PrivateClass not found! please, Class.create( Class.PRIVATE, {...} ).' );
405                                 } else
406                                 if( privateDef.Abstract === true ){
407                                         throw new Error( 'PrivateClass is Abstract!' );
408                                 };
409                                 classDef.privateClass = args.shift();
410                         };
411                         props = args[ 0 ];
412                         if( props === null || Type.isObject( props ) === false ){
413                                 throw new Error( 'No Class Def!' );
414                         };
415                         
416                         if( Type.isFunction( props[ CONSTRUCTOR ] ) === true ){
417                                 classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ];
418                         };
419                         
420                         klass = function(){ a = arguments; if( f ) return C.apply( a.callee, c( a ) )};
421                         klass.prototype = override( override( traits || {}, props, true ), CommonProps, false );
422                         
423                         if( opt_abstract === true ){
424                                 classDef.Abstract = true;
425                         } else
426                         if( opt_pool === true ){
427                                 classDef.pool = [];
428                                 if( opt_private === false )classDef.live = [];
429                         };                      
430                         if( opt_final === true ){
431                                 classDef.Final = true;
432                         } else {
433                                 klass.inherits = inherits;
434                         };                      
435                         if( opt_private === true ){
436                                 if( classDef.privateClass ){
437                                         throw new Error( 'Private Data Class has no PrivateClass!' );
438                                 };
439                                 classDef.isPrivate = true;
440                                 PRIVATE_CLASS_LIST.push( klass );
441                                 PRIVATE_DEF_LIST.push( classDef );
442                         } else {
443                                 if( classDef.privateClass ){
444                                         klass.newPrivateData = newPrivateData;
445                                         klass.getPrivateData = getPrivateData;  
446                                 };
447                                 CLASS_LIST.push( klass );
448                                 DEF_LIST.push( classDef );                              
449                         };
450                         return klass;
451                 },
452                 onShutdown : function(){
453                         
454                 },
455                 getClass : function( instance ){
456                         return getClass( instance );
457                 },
458                 getClassDef : function(){
459                         
460                 }
461         };
462 })();
463
464 /**
465  * Callback 時に thisObject や args を指定したい場合に使用. 
466  */
467 var Callback = Class.create(
468         Class.POOL_OBJECT | Class.FINAL, {
469         Constructor : function( thisObject, callback, opt_args ){
470                 if( Type.isFunction( callback ) === false ){
471                         throw new Error( 'Not function!' );
472                 };
473                 this.callback = callback;
474                 if( thisObject ) this.thisObject = thisObject;
475                 if( Type.isArray( opt_args ) === true ){
476                         this.args = opt_args;
477                 } else
478                 if( opt_args !== undefined ){
479                         this.arg = opt_args;
480                 };
481         },
482         fire : function( /* args */ ){
483                 var thisObject = this.thisObject || window,
484                         args       = Util.copyArray( arguments );
485                 if( 0 < args.length ){
486                         if( this.args !== undefined ){
487                                 args.push.apply( args, this.args );
488                         } else
489                         if( this.arg !== undefined ){
490                                 args.push( this.arg );
491                         };
492                         this.callback.apply( thisObject, args );
493                 } else {
494                         if( this.args !== undefined ){
495                                 this.callback.apply( thisObject, this.args );
496                         } else
497                         if( this.arg !== undefined ){
498                                 this.callback.call( thisObject, this.arg );
499                         } else {
500                                 this.callback.call( thisObject );
501                         };
502                 };
503         },
504         registerUser : function( user ){
505                 if( !this.userList ){
506                         this.userList = [ user ];
507                 } else {
508                         Util.getIndex( this.userList, user ) === -1 && this.userList.push( user );
509                 };
510         },
511         onKill : function(){
512                 var instance = this.thisObject;
513                 this.userList && Class.getClass( instance ) && instance.releaseMyCalllback( this );
514         }
515 });
516
517
518 /* --------------------------------------------------------------
519  * System Timer
520  * 
521  */
522
523 var SystemTimer = ( function(){
524         var setTimeout    = window.setTimeout;
525         var clearTimeout  = window.clearTimeout;
526         var INTERVAL_TIME = 16;
527         var TICKET_LIST   = [];
528         var timerId       = undefined;
529         var next          = 0;
530         
531         function loop(){
532                 var i    = 0,
533                         list = TICKET_LIST;
534             for( i = 0; i < list.length; ){
535                 if( list[ i ].fire( next ) !== false ) ++i;
536             };
537             timerId = undefined;
538             update();
539         };
540         function update(){
541                 var list = TICKET_LIST,
542                         l    = list.length,
543                         n    = 99999999,
544                         c;
545                 if( l === 0 ){
546                         timerId !== undefined && clearTimeout( timerId );
547                         timerId = undefined;
548                         return;
549                 };
550             for( ; l; ){
551                 c = list[ --l ].count;
552                 if( n > c ) n = c;
553             };
554             if( next > n || timerId === undefined ){
555                 timerId !== undefined && clearTimeout( timerId );
556                 timerId = setTimeout( loop, INTERVAL_TIME * n );
557                 next = n;
558             };
559         };
560         
561         var TimerTicket = Class.create(
562                 Class.POOL_OBJECT, {
563                         Constructor : function( apiuser, callback, time, once, opt_thisObject ){
564                                 this.apiuser  = apiuser;
565                                 this.callback = callback;
566                                 this.time     = time;
567                                 this.count    = time;
568                                 if( once ) this.once = once;
569                                 this.thisObj  = opt_thisObject || apiuser;
570                         },
571                         fire : function( c ){
572                                 this.count -= c;
573                                 if( 0 < this.count ) return;
574                                 this.callback.call( this.thisObj );
575                                 if( this.once === true ){
576                                         this.destroy();
577                                         TICKET_LIST.splice( Util.getIndex( TICKET_LIST, this ), 1 );
578                                         return false;
579                                 } else {
580                                         this.count = this.time;
581                                 };
582                         },
583                         destroy : function( apiuser, callback ){
584                                 if( apiuser  && apiuser  !== this.apiuser )  return false;
585                                 if( callback && callback !== this.callback ) return false;
586                                 
587                                 this.kill();
588                                 return true;
589                         }
590                 }
591         );
592         
593         return {
594                 add: function( _apiuser, _handler, _time, _once, opt_thisObject ){
595                         if( Type.isNumber( _time ) === false || _time < INTERVAL_TIME ) _time = INTERVAL_TIME;
596                         
597                     var _ticket = new TimerTicket( _apiuser, _handler, Math.ceil( _time / INTERVAL_TIME ), _once, opt_thisObject );
598                     TICKET_LIST.push( _ticket );
599                     
600                     update();
601                 },
602                 remove: function( _apiuser, _handler ){
603                         var _ticket,
604                                 i = 0;
605                         while( _ticket = TICKET_LIST[ i ] ){
606                                 if( _ticket.destroy( _apiuser, _handler ) === true ){
607                                         TICKET_LIST.splice( i, 1 );
608                                 } else {
609                                         ++i;
610                                 };
611                         };
612                     update();
613                 }
614         };
615 })();
616
617 /* --------------------------------------------------------------
618  * Async Callback
619  * 
620  */
621 var AsyncCall = ( function(){
622         var CALLBACK_LIST = [];
623         
624         var CallbackTicket = Class.create(
625                 Class.POOL_OBJECT, {
626                 Constructor : function( apiuser, callback, args, thisObject ){
627                         this.apiuser  = apiuser;
628                         this.callback = callback;
629                         this.args     = args;
630                         this.thisObj  = thisObject || apiuser;
631                 },
632                 fire : function(){
633                         var f = this.callback,
634                                 a = this.args,
635                                 t = this.thisObj;
636                         this.destroy();
637                         if( Type.isArray( a ) === true ){
638                                 f.apply( t, a );
639                         } else {
640                                 f.call( t, a );
641                         };
642                 },
643                 destroy : function( apiuser, callback ){
644                         if( apiuser  && apiuser  !== this.apiuser ) return false;
645                         if( callback && callback !== this.callback ) return false;
646                         
647                         this.kill();
648                         return true;
649                 }
650         });
651
652         function dispatch(){
653                 var _ticket = CALLBACK_LIST.shift();
654                 if( _ticket ){
655                         _ticket.fire();
656                         CALLBACK_LIST.length !== 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
657                 };
658         };
659
660         return {
661                 add: function( _apiuser, _callback, _argments, _thisObject ){
662                         CALLBACK_LIST.length === 0 && SystemTimer.add( SUPER_USER_KEY, dispatch, 1, true );
663                         CALLBACK_LIST.push( new CallbackTicket( _apiuser, _callback, _argments, _thisObject ) );
664                 },
665                 remove: function( _apiuser, _callback ){
666                         var _ticket,
667                                 i = 0;
668                         while( _ticket = CALLBACK_LIST[ i ] ){
669                                 if( _ticket.destroy( _apiuser, _callback ) === true ){
670                                         CALLBACK_LIST.splice( i, 1 );
671                                 } else {
672                                         ++i;
673                                 };
674                         };
675                 }
676         };
677 })();
678
679 /* -----------------------------------------------------------
680  * 画像一覧は
681  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
682  *  最近アップロードされた画像 > images
683  *  最近使われた画像 > images
684  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
685  *  風景画像庫 >
686  *  効果画像庫 >
687  *  アイテム画像庫 >
688  *  
689  * 画像一覧を読み込むタイミング
690  */
691 var File = ( function(){
692         var DRIVER_LIST             = [];
693         
694         var FILE_TYPE_IS_FOLDER     = Const.FILE.TYPE.FOLDER,
695                 numFileType             = Const.FILE.TYPE.XML,
696                 FILEDATA_RESITER        = [],                   // store all of fileData( json object )
697                 FILEDATA_ACCESS         = [],                   // file operations for Kernel only ! hide from Out of File
698                 FILE_OBJECT_POOL        = [],
699                 EVENT_LISTENER_REGISTER = [],
700                 TREE_ARRAY              = [],
701                 TREE_ACCESS_ARRAY       = [];
702         
703         var REQUEST_CONTROLER = ( function(){
704                 var REQUEST_TICKET_RESISTER = [],
705                         currentTicket           = null,
706                         currentData             = null,
707                         DATA_TYPE_ARRAY         = 'json,xml,html,text'.split( ',' ),
708                         DATA_IS_JSON            = 0,
709                         DATA_IS_XML             = 1,
710                         DATA_IS_HTML            = 2,
711                         DATA_IS_TEXT            = 3,
712                         numError                = 0;
713                 
714                 var RequestTicket = Class.create(
715                         Class.POOL_OBJECT, {
716                         Constructor : function( apiuser, type, data, url, onLoad, onError ){
717                                 this.apiuser = apiuser;
718                                 this.type    = type;
719                                 this.data    = data;
720                                 this.url     = url;
721                                 this.onLoad  = onLoad;
722                                 this.onError = onError;
723                                 this.state   = 0;
724                         },
725                         load : function( data ){
726                                 AsyncCall.add( this.apiuser, this.onLoad, [ this.data, data ] );
727                         },
728                         error : function(){
729                                 AsyncCall.add( this.apiuser, this.onError, this.data );
730                         }
731                 });
732                 
733                 function request(){
734                         if( currentTicket !== null || REQUEST_TICKET_RESISTER.length === 0 ) return;
735                         currentTicket = REQUEST_TICKET_RESISTER.shift();
736                         $.ajax({
737                                 url:            currentTicket.url,
738                                 dataType:       DATA_TYPE_ARRAY[ currentTicket.type ],
739                                 success:        onSuccess,
740                                 error:          onError
741                         });
742                 };
743                 function onSuccess( _data ){
744                         currentTicket.load( _data );
745                         currentTicket.kill();
746                         currentTicket = null;
747                         request();
748                 };
749                 function onError(){
750                         ++numError;
751                         currentTicket.error();
752                         currentTicket.kill(); // retry
753                         currentTicket = null;
754                         request();
755                 };
756
757                 return {
758                         getNumTask: function(){
759                                 return REQUEST_TICKET_RESISTER.length;
760                         },
761                         getNumError: function(){
762                                 return numError;
763                         },
764                         getJson: function( _apiuser, _data, _url, _onLoad, _onError ){
765                                 REQUEST_TICKET_RESISTER.push( new RequestTicket( _apiuser, DATA_IS_JSON, _data, _url, _onLoad, _onError ));
766                                 currentTicket === null && request();
767                         }
768                 };
769         })();
770
771         var FILE_CONTROLER = {
772                 createTree: function( _apiuser, _rootFileData ){
773                         var _tree = new TreeClass( _apiuser, _rootFileData );
774                         TREE_ARRAY.push( _tree );
775                         return _tree;
776                 },
777                 getFileUID: function( FILEDATAorFILE ){
778                         if( FILEDATAorFILE instanceof FileClass ){
779                                 return FILEDATAorFILE.getUID();
780                         };
781                         
782                         var uid = Util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
783                         if( uid === -1 ){
784                                 uid = FILEDATA_RESITER.length;
785                                 FILEDATA_RESITER.push( FILEDATAorFILE );
786                         };
787                         return uid;
788                 },
789                 getFileDataAccess: function( UIDorFILEorFILEDATA ){
790                         var _uid, _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA ), _access;
791
792                         if( _data === null || typeof _data !== 'object' ) return null;
793                         for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i ){
794                                 _access = FILEDATA_ACCESS[ i ];
795                                 if( _access.DATA === _data ) return _access;
796                         };
797                         return null;
798                 },      
799                 getFileData: function( UIDorFILEorFILEDATA ){
800                         if( typeof UIDorFILEorFILEDATA === 'number' ){
801                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;
802                         } else
803                         if( UIDorFILEorFILEDATA instanceof FileClass ){
804                                 return FILEDATA_RESITER[ UIDorFILEorFILEDATA.getUID() ] || null;
805                         } else
806                         if( Util.getIndex( FILEDATA_RESITER, UIDorFILEorFILEDATA ) !== -1 ){
807                                 return UIDorFILEorFILEDATA;
808                         };
809                         return null;
810                 },
811                 getChildren: function( UIDorFILEorFILEDATA ){
812                         var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA );
813                         return _data !== null ? _data.children || null : null;
814                 },
815                 getDriver: function( _file ){
816                         var _data = FILE_CONTROLER.getFileData( _file );
817                         return _data !== null && _data.driver ? _data.driver : BASE_DRIVER;
818                 },
819                 getUpdateFlag: function( _file, _bit ){
820                         var _driver = FILE_CONTROLER.getDriver( _file ),
821                                 _policy;
822                         if( typeof _driver.getUpdatePolicy === 'function' ){
823                                 _policy = _driver.getUpdatePolicy( _file );
824                                 
825                         }
826                         if( typeof _policy !== 'number' ) {
827                                 _policy = BASE_DRIVER.getUpdatePolicy( _file )
828                         }
829                         return _policy % ( _bit * 2 ) >= _bit;
830                 },
831                 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback ){
832                         var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID ),
833                                 _parentType = _parentData.TYPE,
834                                 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile ),
835                                 _targetType = _targetData.TYPE;
836                 },
837                 replace: function( _uid, _file, _newIndex ){
838                         
839                 },
840                 addEventListener: function( FILEorNULL, _eventType, _callback, opt_thisObject ){
841                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
842                         EVENT_LISTENER_REGISTER.push( new FileEventTicket( _uid, _eventType, _callback, opt_thisObject ));
843                 },
844                 removeEventListener: function( FILEorNULL, eventType, callback ){
845                         var uid  = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
846                                 list = EVENT_LISTENER_REGISTER,
847                                 i    = 0,
848                                 ticket;
849                         for( ; i < list.length; ){
850                                 ticket = list[ i ];
851                                 if( ticket.fileUID === uid && ticket.eventType === eventType && ticket.callBack === callback ){
852                                         list.splice( i, 1 );
853                                         ticket.kill();
854                                 } else {
855                                         ++i;
856                                 };
857                         };
858                 },
859                 getTreeAccess: function(){
860                         
861                 },
862                 fileEventRellay: function( _uid, _event ){
863                         var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
864                         if( _fileAccess === null ) return;
865                         var _treeUID    =  _fileAccess.TREE.getUID(),
866                                 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
867                                 _data       = _fileAccess.DATA,
868                                 _tree;
869                         if( !_treeAccess ) return;
870                         _treeAccess.dispatchFileEvent( _event );
871                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i ){
872                                 if( i !== _treeUID ){
873                                         _tree = TREE_ARRAY[ i ];
874                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
875                                                 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
876                                                 _treeAccess && _treeAccess.dispatchFileEvent( _event );
877                                         };
878                                 };
879                         };
880                 }
881         };
882         
883         var TreeClass = function( apiuser, rootFileData ){
884                 var PARENT_FILE_RESITER = [],
885                         ACCESS = {
886                                 apiuser          : apiuser,
887                                 dispatchFileEvent: dispatchFileEvent
888                         },
889                         EVENT_LISTENER_ARRAY = [],
890                         instance             = this,
891                         rootFile             = new FileClass( instance, null, rootFileData ),
892                         currentFile          = rootFile;
893                 
894                 currentFile.getSeqentialFiles();
895                 TREE_ACCESS_ARRAY.push( ACCESS );
896                 
897                 function dispatchFileEvent( e ){
898                         var _eventType  = e.eventType,
899                                 _targetFile = e.targetFile,
900                                 _uid        = _targetFile.getUID(),
901                                 _ticket, _type, _callback;
902                         for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
903                                 _ticket   = EVENT_LISTENER_REGISTER[ i ];
904                                 _type     = _ticket.eventType;
905                                 _callback = _ticket.callBack;
906                                 if( _eventType === _type && _uid === _ticket.fileUID ){
907                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile, e.key, e.value ], _ticket.thisObject || _targetFile );
908                                 } else
909                                 if( _type === Const.TREE.EVENT.UPDATE && _eventType === Const.FILE.EVENT.GET_SEQENTIAL_FILES ){
910                                         //_callback( _eventType, _targetFile );
911                                         AsyncCall.add( apiuser, _callback, [ _eventType, _targetFile ], _ticket.thisObject || instance );
912                                 };
913                         };
914                 };
915                 
916                 this.getUID = function(){
917                         return Util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
918                 };
919                 this.getRootFile = function(){
920                         return rootFile;
921                 };
922                 this.getCurrentFile = function(){
923                         return currentFile;
924                 };
925                 this.hierarchy = function(){
926                         return PARENT_FILE_RESITER.length;
927                 };
928                 this.getParentFileAt = function( _index ){
929                         var l = PARENT_FILE_RESITER.length;
930                         if( typeof _index !== 'number' || _index < 0 || _index >= l ) return null;
931                         return PARENT_FILE_RESITER[ l -1 -_index ];
932                 };
933                 this.down = function( _index ){
934                         if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
935                         PARENT_FILE_RESITER.unshift( currentFile );
936                         currentFile = currentFile.getChildFileAt( _index );
937                         currentFile.getSeqentialFiles();
938                         return currentFile;
939                 };
940                 this.up = function( _index ){
941                         var l = PARENT_FILE_RESITER.length;
942                         if( l === 0 ) return null;
943                         
944                         if( currentFile ){
945                                 var _currentFile = currentFile;
946                                 currentFile = null;
947                                 _currentFile.destroy();
948                         };
949                         if( typeof _index === 'number' ){
950                                 if( _index >= l ) return null;
951                                 currentFile = this.getParentFileAt( _index );
952                                 PARENT_FILE_RESITER.splice( 0, l -_index);
953                         } else {
954                                 currentFile = PARENT_FILE_RESITER.shift();
955                         };
956                         currentFile.getSeqentialFiles();
957                         return currentFile;     
958                 };
959                 this.addTreeEventListener = function( _eventType, _callback, opt_thisObject ){
960                         FILE_CONTROLER.addEventListener( null, _eventType, _callback, opt_thisObject );
961                 };
962                 this.removeTreeEventListener = function( _eventType, _callback ){
963                         FILE_CONTROLER.removeEventListener( null, _eventType, _callback );
964                 };
965                 this.destroy = function( _apiuser ){
966                         if( _apiuser && apiuser !== _apiuser ) return false;
967                         // removeEvent
968                         var _currentFile = currentFile;
969                         currentFile = rootFile = rootFileData = null;
970                         // currentFile, rootFile を null にしないと .File.destroy() ができない.
971                         _currentFile.destroy();
972                         while( PARENT_FILE_RESITER.length > 0 ){
973                                 _currentFile = PARENT_FILE_RESITER.shift();
974                                 _currentFile.destroy();
975                         };
976                         
977                         AsyncCall.remove( apiuser );
978                         instance = apiuser = null;
979                         return true;
980                 };
981         };
982         
983         var FileEventTicket = Class.create(
984                 Class.POOL_OBJECT, {
985                 Constructor : function( uid, eventType, callback, opt_thisObject ){
986                         this.fileUID    = uid;
987                         this.eventType  = eventType;
988                         this.callBack   = callback;
989                         this.thisObject = opt_thisObject;
990                 }       
991         });
992         
993         var FileEventClass = function( eventType, file, key, value ){
994                 this.eventType        = eventType;
995                 this.targetFile       = file;
996                 this.updatedAttribute = key;
997                 this.updatedValue     = value;
998         };
999
1000 /*
1001  * file の data は object で保持している。
1002  * File の外からファイルをみるときは、FileClassを通して操作する。
1003  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
1004  * treeがdestryされると、fileのイベントリスナーも全て削除される。
1005  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
1006  * 
1007  */
1008         
1009         var FileClass = function( tree, parentData, data ){
1010                 var uid = FILE_CONTROLER.getFileUID( data );
1011                 
1012                 FILEDATA_ACCESS.push( {
1013                         TREE:                           tree,
1014                         parentData:                     parentData,
1015                         DATA:                           data
1016                 } );
1017                 
1018                 tree = parentData = data = null;
1019
1020                 this.getUID = function(){
1021                         return uid;
1022                 };
1023         };
1024         
1025         FileClass.prototype = {
1026                 isChildFile: function( _FILEorFILEDATA ){
1027                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
1028                 },
1029                 getSeqentialFiles: function(){
1030                         var _driver = FILE_CONTROLER.getDriver( this );
1031                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
1032                                 _driver.getSeqentialFiles( this );
1033                         }
1034                 },
1035                 addEventListener: function( _eventType, _callback ){
1036                         FILE_CONTROLER.addEventListener( this, _eventType, _callback );
1037                 },
1038                 removeEventListener: function( _eventType, _callback ){
1039                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
1040                 },
1041                 dispatchEvent: function( e ){
1042                         e instanceof FileEventClass && FILE_CONTROLER.fileEventRellay( this.getUID(), e );
1043                 },
1044                 getChildFileLength: function(){
1045                         var children = FILE_CONTROLER.getChildren( this );
1046                         return Type.isArray( children ) === true ? children.length : -1;
1047                 },
1048                 getChildFileIndex: function( _FILEorFILEDATA ){
1049                         var children = FILE_CONTROLER.getChildren( this );
1050                         if( Type.isArray( children ) === false ) return -1;
1051                         var l = children.length,
1052                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
1053                         if( _fileData === null ) return -1;
1054                         for( var i=0; i<l; ++i ){
1055                                 if( children[ i ] === _fileData ) return i;
1056                         }
1057                         return -1;
1058                 },
1059                 getChildFileAt: function( _index ){
1060                         var _access = FILE_CONTROLER.getFileDataAccess( this ),
1061                                 _children = FILE_CONTROLER.getChildren( this );
1062                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length ) return null;
1063                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
1064                         // _file.init();
1065                         return _file;
1066                 },
1067                 getName: function(){
1068                         var driver = FILE_CONTROLER.getDriver( this );
1069                         if( typeof driver.getName === 'function'){
1070                                 return driver.getName( this );
1071                         }
1072                         return BASE_DRIVER.getName( this );
1073                 },
1074                 getThumbnail: function(){
1075                         var driver = FILE_CONTROLER.getDriver( this );
1076                         if( typeof driver.getThumbnail === 'function'){
1077                                 return driver.getThumbnail( this );
1078                         }
1079                         return BASE_DRIVER.getThumbnail( this );
1080                 },
1081                 getType: function(){
1082                         var _data = FILE_CONTROLER.getFileData( this );
1083                         return typeof _data.type === 'number' ? _data.type : Const.FILE.TYPE.UNKNOWN;
1084                 },
1085                 getState: function(){
1086                         var _data = FILE_CONTROLER.getFileData( this );
1087                         return typeof _data.state === 'number' ? _data.state : Const.FILE.STATE.OK;
1088                 },
1089                 getSummary: function(){
1090                         var driver = FILE_CONTROLER.getDriver( this );
1091                         if( typeof driver.getSummary === 'function'){
1092                                 return driver.getSummary( this );
1093                         }
1094                         return BASE_DRIVER.getSummary( this );
1095                 },
1096                 isWritable: function(){
1097                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.WRITE );
1098                 },
1099                 isSortable: function(){
1100                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.SORT );
1101                 },              
1102                 isCreatable: function(){
1103                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.CREATE );
1104                 },
1105                 isRenamable: function(){
1106                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.RENAME );
1107                 },
1108                 isDeletable: function(){
1109                         return FILE_CONTROLER.getUpdateFlag( this, Const.FILE.UPDATE_POLICY.DELETE );
1110                 },
1111                 read: function(){
1112                         // simpleDeepCopy
1113                         var driver = FILE_CONTROLER.getDriver( this ),
1114                                 data;
1115                         if( Type.isFunction( driver.read ) === true ){
1116                                  data = driver.read( this );
1117                         };
1118                         return BASE_DRIVER.read( data || this );
1119                 },
1120                 write: function( _newData, _onUpdateFunction ){
1121                         var driver = FILE_CONTROLER.getDriver( this );
1122                         if( typeof driver.write === 'function'){
1123                                 return driver.write( this, _newData, _onUpdateFunction );
1124                         }
1125                         return BASE_DRIVER.write( this, _newData, _onUpdateFunction );
1126                 },
1127                 viewerApplicationList: function(){
1128                         var driver = FILE_CONTROLER.getDriver( this );
1129                         if( typeof driver.viewerApplicationList === 'function'){
1130                                 return driver.viewerApplicationList( this );
1131                         }
1132                         return BASE_DRIVER.viewerApplicationList( this );
1133                 },
1134                 editorApplicationList: function(){
1135                         var driver = FILE_CONTROLER.getDriver( this );
1136                         if( typeof driver.editorApplicationList === 'function'){
1137                                 return driver.editorApplicationList( this );
1138                         }
1139                         return BASE_DRIVER.viwerApps( this );
1140                 },
1141                 create: function(){
1142                         
1143                 },
1144                 sort: function(){
1145                         
1146                 },
1147                 onCopy: function(){
1148                         
1149                 },
1150                 onDelete: function(){
1151                         
1152                 },
1153                 move: function( _newFolder, _newIndex, opt_callback ){
1154                         var _access = FILE_CONTROLER.getFileDataAccess( this );
1155                         _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
1156                 },
1157                 replace: function( _newIndex, opt_callback ){
1158                         var _access = FILE_CONTROLER.getFileDataAccess( this );
1159                         _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
1160                 },
1161                 /**
1162                  * サーチ
1163                  * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
1164                  */
1165                 search: function( obj, rule ){
1166                         var _children = FILE_CONTROLER.getChildren( this ),
1167                                 _child,
1168                                 ret = [], k, c;
1169                         for( var i=0, l=_children.length; i<l; ++i ){
1170                                 _child = _children[ i ];
1171                                 c = true;
1172                                 for( k in obj ){
1173                                         if( obj[ k ] !== _child[ k ] ){
1174                                                 c = false;
1175                                                 break;
1176                                         }
1177                                 }
1178                                 c === true && ret.push( i );
1179                         }
1180                         return ret;
1181                 },
1182                 destroy: function(){
1183                         var _access = FILE_CONTROLER.getFileDataAccess( this );
1184                         var _tree = _access.TREE;
1185                         if( _tree.getCurrentFile() === this ) return;
1186                         if( _tree.getRootFile() === this ) return;
1187                         for( var i=0, l = _tree.hierarchy(); i<l; ++i ){
1188                                 if( _tree.getParentFileAt( i ) === this ){
1189                                         return;
1190                                 }
1191                         }
1192                         var _index = Util.getIndex( FILEDATA_ACCESS, _access );
1193                         if( _index === -1 ) return;
1194                         // event の 削除
1195                         FILEDATA_ACCESS.splice( _index, 1 );
1196                         delete _access.DATA;
1197                         delete _access.TREE;
1198                         delete _access.parentData;
1199                 }
1200         };
1201
1202         /*
1203          * FileDriverBase
1204          */
1205         var FileDriverBase = function( driverClass ){
1206                 this.getUID = function(){
1207                         return Util.getIndex( API_USER_LIST, driverClass );
1208                 };
1209                 this.getSeqentialFiles = function( _file ){
1210                 };
1211                 this.getName = function( _file ){
1212                         var _data = FILE_CONTROLER.getFileData( _file );
1213                         return _data.name || 'No Name';
1214                 };
1215                 this.getThumbnail = function( _file ){
1216                         var _data = FILE_CONTROLER.getFileData( _file ),
1217                                 _type = _data.type,
1218                                 _className = '';
1219                         if( _type === Const.FILE.TYPE.FOLDER ){
1220                                 _className = 'folder';
1221                         } else
1222                         if( _type === Const.FILE.TYPE.IMAGE ){
1223                                 
1224                         } else
1225                         if( _type === Const.FILE.TYPE.TEXT ){
1226                                 
1227                         } else
1228                         if( _type === Const.FILE.TYPE.HTML ){
1229                                 
1230                         } else
1231                         if( _type === Const.FILE.TYPE.CSV ){
1232                                 
1233                         } else
1234                         if( _type === Const.FILE.TYPE.JSON ){
1235                                 
1236                         } else
1237                         if( _type === Const.FILE.TYPE.XML ){
1238                                 
1239                         };
1240                         return {
1241                                 image:          null,
1242                                 className:      ' file-type-' + _className
1243                         };
1244                 };
1245                 this.getSummary = function( _file ){
1246                         var _data = FILE_CONTROLER.getFileData( _file ),
1247                                 _type = _data.type;
1248                         if( _type === Const.FILE.TYPE.FOLDER ){
1249                                 return 'folder';
1250                         } else
1251                         if( _type === Const.FILE.TYPE.IMAGE ){
1252                                 return 'image file';
1253                         } else
1254                         if( _type === Const.FILE.TYPE.TEXT ){
1255                                 return 'text file';
1256                         } else
1257                         if( _type === Const.FILE.TYPE.HTML ){
1258                                 return 'html document file';
1259                         } else
1260                         if( _type === Const.FILE.TYPE.CSV ){
1261                                 return 'csv daat file';
1262                         } else
1263                         if( _type === Const.FILE.TYPE.JSON ){
1264                                 return 'json data file';
1265                         } else
1266                         if( _type === Const.FILE.TYPE.XML ){
1267                                 return 'xml data file';
1268                         }
1269                         return '';
1270                 };
1271                 this.getUpdatePolicy = function( _file ){
1272                         // debug用 全てのメニューを許可
1273                         return Const.FILE.UPDATE_POLICY.DSRWC;
1274                 };
1275                 this.read = function( FILEorDATA ){
1276                         var data,
1277                                 protects = Const.FILE.DATA_PROPERTY_RESERVED,
1278                                 objSrc   = [],
1279                                 objCopy  = [],
1280                                 getIndex = Util.getIndex;                       
1281                         if( FILEorDATA instanceof FileClass ){
1282                                 data = FILE_CONTROLER.getFileData( FILEorDATA )
1283                         } else {
1284                                 data = FILEorDATA;
1285                         };
1286                         
1287                         function clone( src ) {
1288                                 var ret, i, key;
1289                                 if( Type.isArray( src ) === true ){
1290                                         i = getIndex( objSrc, src );
1291                                         if( i !== -1 ) return objCopy[ i ];
1292                                         ret = [];
1293                                         objSrc[ objSrc.length ]   = src;
1294                                         objCopy[ objCopy.length ] = ret;
1295                                 } else
1296                                 if( Type.isObject( src ) === true ){
1297                                         i = getIndex( objSrc, src );
1298                                         if( i !== -1 ) return objCopy[ i ];
1299                                         ret = {};
1300                                         objSrc[ objSrc.length ]   = src;
1301                                         objCopy[ objCopy.length ] = ret;
1302                                 } else
1303                                 if( Type.isNumber( src ) === true || Type.isString( src ) === true || Type.isBoolean( src ) === true ){
1304                                         return src;
1305                                 } else {
1306                                         return src;
1307                                 };
1308                                 for( key in src ){
1309                                         if( getIndex( protects, key ) === -1 ){
1310                                                 ret[ key ] = clone( src[ key ]);
1311                                         };
1312                                 };
1313                                 return ret;
1314                         };                              
1315                         return clone( data );
1316                 };
1317                 this.write = function( _file, _newData, _onUpdateFunction ){
1318                         var _data = FILE_CONTROLER.getFileData( _file ),
1319                                 _type = _data.type;
1320                         return false;
1321                 };
1322                 this.viewerApplicationList = function(){
1323                         return [];
1324                 };
1325                 this.editorApplicationList = function(){
1326                         return [];
1327                 };
1328                 this.onCreate = function(){
1329                         
1330                 };
1331                 this.onSort = function(){
1332                         
1333                 };
1334                 this.onCopy = function(){
1335                         
1336                 };
1337                 this.onDelete = function(){
1338                         
1339                 };
1340         };
1341         
1342         var BASE_DRIVER   = new FileDriverBase();
1343         
1344         var ROOT_FILEDATA = {
1345                         name:           'system root',
1346                         type:           FILE_TYPE_IS_FOLDER,
1347                         children:       []
1348                 },
1349                 SYSTEM_TREE = FILE_CONTROLER.createTree( SUPER_USER_KEY, ROOT_FILEDATA ),
1350                 ROOT_FILE   = SYSTEM_TREE.getRootFile();
1351
1352         function createFileTypeID(){
1353                 return ++numFileType;
1354         };
1355         
1356         var FileAPIClass = function( driver ){
1357                 var constObject;
1358                 this.createFolderUnderRoot = function( _fileData ){
1359                         if( _fileData !== null && Type.isObject( _fileData ) === true ){
1360                                 ROOT_FILEDATA.children.push( _fileData );
1361                                 ROOT_FILE.dispatchEvent( new FileEventClass( Const.FILE.EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null ));
1362                         }
1363                 };
1364                 this.createFileEvent   = function( _eventType, _file, _key, _value ){
1365                         return new FileEventClass( _eventType, _file, _key, _value );
1366                 };
1367                 this.createFileTypeID  = createFileTypeID;
1368                 this.getFileDataAccess = FILE_CONTROLER.getFileDataAccess;
1369                 this.getFileData       = FILE_CONTROLER.getFileData;
1370                 this.getJson           = function( _data, _url, _onLoad, _onError ){
1371                         REQUEST_CONTROLER.getJson( driver, _data, _url, _onLoad, _onError );
1372                 };
1373                 this.createTree        = function( _rootFile ){
1374                         return FILE_CONTROLER.createTree( driver, _rootFile );
1375                 };
1376                 this.isTreeInstance    = function( _tree ){
1377                         return _tree instanceof TreeClass;
1378                 };
1379                 this.isFileInstance    = function( _file ){
1380                         return _file instanceof FileClass;
1381                 };
1382                 this.isFileEvent       = function( _event ){
1383                         return _event instanceof FileEventClass;
1384                 };
1385                 this.getConst          = function(){
1386                         return Const; // constObject = constObject || clone( Const )
1387                 };
1388         };
1389         
1390         return {
1391                 registerDriver: function( _class ){
1392                         _class.prototype = new FileDriverBase( _class );
1393                         var _driver = new _class();
1394                         
1395                         DRIVER_LIST.push( _driver );
1396                         API_USER_LIST.push( _class );
1397
1398                         return new FileAPIClass( _driver );
1399                 },
1400                 isDriver: function( _driver ){
1401                         return _driver instanceof FileDriverBase;
1402                 },
1403                 isTreeInstance: function( _tree ){
1404                         return _tree instanceof TreeClass;
1405                 },
1406                 isFileInstance: function( _file ){
1407                         return _file instanceof FileClass;
1408                 }
1409         }
1410 })();
1411
1412
1413 /* ----------------------------------------------------
1414  * ApplicationManager
1415  * window resize event, overlayApplication currentAplication に流す
1416  */     
1417
1418 var APPLICATION_LIST = [];
1419
1420 var ApplicationPrivateData = function(){};
1421 ApplicationPrivateData.prototype = {
1422         appClass      : null,
1423         application   : null,
1424         displayName   : null,
1425         isOverlay     : false,
1426         rootElement   : null,
1427         bgColor       : '#C1CACF',
1428         uiList        : null,
1429         formList      : null,
1430         finderList    : null,
1431         styleCursor   : null,
1432         eventRoot     : null,
1433         fetchResource : 0,
1434         bootParams    : null,
1435         phase         : 0,
1436         cursor        : '',
1437         w             : 0,
1438         h             : 0,
1439         init          : function( appClass, displayName, isOverlay ){
1440                 this.appClass    = appClass;
1441                 // this.application = app;
1442                 this.displayName = displayName;
1443                 this.isOverlay   = isOverlay;
1444                 this.rootElement = document.createElement( 'div' );
1445                 this.styleCursor = this.rootElement.style;
1446                 ApplicationPrivateData.list.push( this );
1447         },
1448         detect : function(){
1449                 if( this.rootElement.firstChild && this.fetchResource === 0 ){
1450                         SystemTimer.remove( this.application, this.detect );
1451                         this.onOpen();
1452                 };
1453         },
1454         onOpen : function(){
1455                 this.rootElement.style.display = '';
1456                 
1457                 // this.layer !== null && this.layer.onResize( this.w, this.h );
1458                 
1459                 if( this.application.MIN_WIDTH > this.w || this.application.MIN_HEIGHT > this.h ){
1460                         if( Type.isHTMLElement( this.rootElement ) === true ){
1461                                 // 小さすぎる!、と表示
1462                         };
1463                 };
1464                 if( this.bootParams.length > 2 ){
1465                         this.application.onOpen.apply( this.application, this.bootParams );
1466                 } else {
1467                         this.application.onOpen( this.w, this.h );
1468                 };
1469                 this.phase = 4; 
1470         },
1471         fetchResourceComplete : function(){
1472                 --this.fetchResource;
1473         }
1474 };
1475 ApplicationPrivateData.list = [];
1476 ApplicationPrivateData.get = function( app ){
1477         var list = ApplicationPrivateData.list,
1478                 i    = list.length;
1479         for( ; i; ){
1480                 if( app instanceof list[ --i ].appClass ) return list[ i ];
1481         };
1482         return null;
1483 };
1484
1485 var AbstractApplication = function( appClass, displayName, isOverlay ){
1486         ( new ApplicationPrivateData() ).init( appClass, displayName, isOverlay );
1487 };
1488 AbstractApplication.prototype = {
1489         getUID : function(){
1490                 var data = ApplicationPrivateData.get( this );
1491                 return Util.getIndex( API_USER_LIST, data.appClass );
1492         },
1493         init : function(){
1494                 var data = ApplicationPrivateData.get( this );
1495                 // this.rootElement = data.rootElement;
1496                 // data.application = this;
1497                 data.phase = 1;
1498                 data.appClass === Page.appClass && Page.show();
1499                 this.onInit();
1500                 data.phase = 2;
1501         },
1502         open : function( w, h /*, _option */ ){
1503                 var data = ApplicationPrivateData.get( this );
1504                 data.phase      = 3;
1505                 data.bootParams = Util.copyArray( arguments );
1506                 data.w          = w;
1507                 data.h          = h;
1508                 if( data.rootElement.innerHTML && data.rootElement.innerHTML.length > 0 ){
1509                         SystemTimer.add( this, data.detect, 16, false, data );
1510                 } else {
1511                         data.onOpen();
1512                 };
1513         },
1514         resize : function( w, h ){
1515                 var data = ApplicationPrivateData.get( this );
1516                 if( data.phase !== 4 ) return;
1517                 if( this.MIN_WIDTH > w || this.MIN_HEIGHT > h ){
1518                         if( Type.isHTMLElement( this.rootElement ) === true ){
1519                                 // 小さすぎる!、と表示
1520                         };
1521                         return;
1522                 };
1523                 this.onPaneResize( w, h );
1524         },
1525         close : function(){
1526                 var data = ApplicationPrivateData.get( this );
1527                 data.phase = 5;
1528                 if( this.onClose() === false ){
1529                         return false;
1530                 };
1531                 if( data.uiList ){ 
1532                         while( data.uiList.length > 0 ) data.uiList.shift().destroy();
1533                 };
1534                 if( data.finderList ){
1535                         while( data.finderList.length > 0 ) data.finderList.shift().destroy();
1536                 };              
1537                 
1538                 data.eventRoot && PointingDeviceEventTree.destroyTree( data.eventRoot );
1539                 MouseEvent.remove( this );
1540                 KeyEvent.remove( this );
1541                 SystemTimer.remove( this );
1542                 AsyncCall.remove( this );
1543                 StyleSheet.unload( this );
1544
1545                 var elm = this.rootElement;
1546                 Util.removeAllChildren( elm );
1547                 elm.parentNode.removeChild( elm );
1548                 
1549                 Application.shutdown( this, data.isOverlay );
1550                 
1551                 data.appClass === Page.appClass && Page.hide();
1552
1553                 data.phase = 6;
1554                 
1555                 var list = ApplicationPrivateData.list;
1556                 list.splice( Util.getIndex( list, data ), 1 );
1557         },
1558         createUIGroup : function( node ){
1559                 var data = ApplicationPrivateData.get( this ),
1560                         ui = UI.createUIGroup( this, node );
1561                 if( data.uiList === null ) data.uiList = [];
1562                 data.uiList.push( ui );
1563                 return ui;
1564         },
1565         createUIForm : function( nodeOrElm, opt_elmForm ){
1566                 var data = ApplicationPrivateData.get( this ),
1567                         form = UIForm.createForm( this, nodeOrElm, opt_elmForm );
1568                 if( data.formList === null ) data.formList = [];
1569                 data.formList.push( form );
1570                 return form;
1571         },
1572         createFinder : function( _elmTarget, _tree, _onSelect, _viewerOption, _editorOption ){
1573                 var data   = ApplicationPrivateData.get( this ),
1574                         finder = Finder.create( this, _elmTarget, _tree, _onSelect, _viewerOption, _editorOption );
1575                 if( data.finderList === null ) data.finderList = [];
1576                 data.finderList.push( finder );
1577                 return finder;
1578         },
1579         createDHTML : function( _elm ){
1580                 return DHTML.create( this, _elm );
1581         },
1582         addEventListener : function( element, eventType, handler, opt_thisObject ){
1583                 MouseEvent.add( this, element, eventType, handler, opt_thisObject );
1584         },
1585         removeEventListener : function( element, eventType, handler ){
1586                 MouseEvent.remove( this, element, eventType, handler );
1587         },
1588         getPointingDeviceEventTreeRoot : function(){
1589                 var data = ApplicationPrivateData.get( this );
1590                 if( data.phase === 1 ){
1591                         data.eventRoot   = PointingDeviceEventTree.create( this );
1592                         data.styleCursor = PointingDeviceEventTree._getNodePrivateData( data.eventRoot ).elmMouseCatch.style;
1593                 };              
1594                 return data.eventRoot;
1595         },
1596         updateCoursor : function( _cursor ){
1597                 var data = ApplicationPrivateData.get( this );
1598                 if( data.cursor !== _cursor ){
1599                         data.styleCursor.cursor = data.cursor = _cursor;
1600                 };
1601         },
1602         fetchCSS : function( url, opt_onload, opt_onerror ){
1603                 var data = ApplicationPrivateData.get( this );
1604                 if( data.phase === 1 ){
1605                         ++data.fetchResource;
1606                         StyleSheet.load( this, url, data.fetchResourceComplete, data.fetchResourceComplete, data );
1607                 };
1608         },
1609         onInit : function(){},
1610         onOpen : function(){},
1611         onClose : function(){ return true; },
1612         onPaneResize : function( w, h ){},
1613         addKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){
1614                 KeyEvent.add( this, _eventType, _handler, _keyCode, _shift, _ctrl );
1615         },
1616         removeKeyEventListener : function( _eventType, _handler, _keyCode, _shift, _ctrl ){
1617                 KeyEvent.remove( this, _eventType, _handler, _keyCode, _shift, _ctrl );
1618         },
1619         shiftEnabled : function(){
1620                 return KeyEvent.shiftEnabled;
1621         },
1622         ctrlEnabled : function(){
1623                 return KeyEvent.ctrlEnabled;
1624         },
1625         addTimer : function( handler, time, once ){
1626                 SystemTimer.add( this, handler, time, !!once );
1627         },
1628         removeTimer : function( handler ){
1629                 SystemTimer.remove( this, handler );
1630         },
1631         addAsyncCall : function( _callback, _argments, _thisObject ){
1632                 AsyncCall.add( this, _callback, _argments, _thisObject );
1633         },
1634         removeAsyncCall : function( _callback ){
1635                 AsyncCall.remove( this, _callback );
1636         },
1637         fetchHTMLElement : function( id ){
1638                 var elm = document.getElementById( id );
1639                 if( elm ){
1640                         elm.removeAttribute( 'id' );
1641                         elm.parentNode.removeChild( elm );
1642                         return elm;
1643                 };
1644         }
1645 };
1646
1647 var PointingDeviceEventTree = ( function(){
1648         var ROOT_LIST       = [],
1649                 currentRootData = null,
1650                 targetNodeData  = null,
1651                 forceNodeData   = null,
1652                 hoverList       = [];
1653         
1654         function eventRellay( e ){
1655                 var data = forceNodeData, // || targetNodeData,
1656                         x    = e.clientX,
1657                         y    = e.clientY,
1658                         type = e.type,
1659                         list = hoverList,
1660                         i    = 0,
1661                         ret, systemOnly = false, addClass, removeClass,
1662                         parent;
1663                 if( data && data.dispatchEvent( e, type, true ) === true ) return false;
1664                 if( currentRootData === null ) return;
1665                 targetNodeData = currentRootData;
1666                 currentRootData._capcher( x, y );
1667                 targetNodeData.apiuser.updateCoursor( targetNodeData._cursor );
1668                 data = targetNodeData;
1669                 while( data ){
1670                         ret = data.dispatchEvent( e, type, true, systemOnly );
1671                         if( ret === true || ret === false ) break; // systemOnly = true;
1672                         data = data.parentData;
1673                 };
1674                 
1675                 addClass    = Util.addClass;
1676                 removeClass = Util.removeClass;
1677                 for( ; i < list.length; ){
1678                         parent = data = list[ i ];
1679                         while( parent.parentData && parent === parent.parentData.hitChild ){
1680                                 parent = parent.parentData;
1681                         };
1682                         if( parent !== currentRootData ){
1683                                 data.hover === true && removeClass( data.elm, data.hoverClass );
1684                                 delete data.isHover;
1685                                 data.events && data.events.mouseout && data.fire( e, 'mouseout', false );
1686                                 delete data.hitSelf;
1687                                 list.splice( i, 1 );
1688                                 continue;
1689                         };
1690                         if( data.hover === true && data.isHover === false ){
1691                                 addClass( data.elm, data.hoverClass );
1692                                 data.isHover = true;
1693                         };
1694                         if( data.hitSelf === false ){
1695                                 data.events && data.events.mouseover && data.fire( e, 'mouseover', true );
1696                                 data.hitSelf = true;
1697                         };
1698                         ++i;
1699                 };
1700                 return false;
1701         };      
1702         
1703         var NodeClass = function( apiuser, rootData, /*parentLayer,*/ parentData, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){
1704                 ( new NodePrivateData() ).init( apiuser, rootData, /*parentLayer,*/ parentData, this, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop );
1705         };
1706         NodeClass.prototype = {
1707                 createNode : function( rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ){
1708                         var data = NodePrivateData.get( this ),
1709                                 elm;
1710                         if( Type.isHTMLElement( rangeOrElmData ) === true ){
1711                                 elm = rangeOrElmData;
1712                         } else
1713                         if( Type.isString( rangeOrElmData ) === true ){
1714                                 elm = document.getElementById( rangeOrElmData );
1715                                 if( !elm ){
1716                                         elm = Util.pullHtmlAsTemplete( rangeOrElmData );
1717                                 };
1718                                 if( !elm || Type.isHTMLElement( elm ) === false || elm.nodeType !== 1 ){
1719                                         throw new Error( "invalid HTMLElement." );
1720                                 };
1721                         } else
1722                         if( Type.isObject( rangeOrElmData ) === false || Type.isFinite( rangeOrElmData.x ) === false || Type.isFinite( rangeOrElmData.y ) === false ){
1723                                 throw new Error( "No range" );
1724                         };
1725                         
1726                         if( elm && data.elm === null ){
1727                                 throw new Error( "MetaLayer don't containe HTMLElement-Layer." );
1728                         };
1729                         if( data.elm && data.elm.style.hasLayout === false ){
1730                                 throw new Error( "[ie] OffsetParent is hasLayout === false." );
1731                         };
1732                         
1733                         var newNode = new NodeClass( data.apiuser, data.rootData, data, elm || rangeOrElmData, through, clip, hover, cursor, scroll, dragdrop ),
1734                                 newData = NodePrivateData.get( newNode );
1735                         
1736                         if( data.childData === null ) data.childData = [];
1737                         data.childData.push( newData );
1738                         return newNode;
1739                 },
1740                 createNodeAt : function(){
1741                 },
1742                 remove : function(){
1743                         NodePrivateData.get( this ).remove();
1744                 },
1745                 nodeIndex : function( v ){
1746                         return NodePrivateData.get( this ).nodeIndex( v );
1747                 },
1748                 numNode : function(){
1749                         return NodePrivateData.get( this ).numNode();
1750                 },
1751                 disabled : function( v ){
1752                         return NodePrivateData.get( this ).disabled( v );
1753                 },
1754                 childrenDisabled : function( v ){
1755                         return NodePrivateData.get( this ).disabled( v );
1756                 },
1757                 mesure : function(){
1758                         NodePrivateData.get( this ).mesure();
1759                 },
1760                 mesureChildren : function(){
1761                         NodePrivateData.get( this ).mesureChildren();
1762                 },
1763                 update : function( x, y, w, h ){
1764                         NodePrivateData.get( this ).update( x, y, w, h );
1765                 },
1766                 setPosition : function( x, y ){
1767                         NodePrivateData.get( this ).setPosition( x, y );
1768                 },
1769                 setSize : function( w, h ){
1770                         NodePrivateData.get( this ).setSize( w, h );
1771                 },
1772                 cursor : function( v ){
1773                         return NodePrivateData.get( this ).cursor( v );
1774                 },
1775                 x : function( x ){
1776                         return NodePrivateData.get( this ).positionX( x );
1777                 },
1778                 y : function( y ){
1779                         return NodePrivateData.get( this ).positionY( y );
1780                 },
1781                 width : function( w ){
1782                         return NodePrivateData.get( this ).width( w );
1783                 },
1784                 height : function( h ){
1785                         return NodePrivateData.get( this ).height( h );
1786                 },
1787                 getAbsolutePositionX : function(){
1788                         return NodePrivateData.get( this ).getAbsolutePositionX();
1789                 },
1790                 getAbsolutePositionY : function(){
1791                         return NodePrivateData.get( this ).getAbsolutePositionY();
1792                 },
1793                 addEventListener : function( type, handler, opt_thisObject ){
1794                         NodePrivateData.get( this ).addEventListener( type, handler, opt_thisObject );
1795                 },
1796                 removeEventListener : function( type, handler ){
1797                         NodePrivateData.get( this ).removeEventListener( type, handler );
1798                 },
1799                 scrollTo : function( x, y ){
1800                         NodePrivateData.get( this ).scrollTo( x, y );
1801                 },
1802                 scrollX : function( v ){
1803                         return NodePrivateData.get( this ).scrollX( v );
1804                 },
1805                 scrollY : function( v ){
1806                         return NodePrivateData.get( this ).scrollY( v );
1807                 },
1808                 invalidateScrollbar : function(){
1809                         ScrollBarManager.update( NodePrivateData.get( this ) );
1810                 }
1811         };
1812
1813         /**
1814          * clip : true の場合、子ノードの変更によってヒットエリアを変化させない.elm には overflow:hidden としておくのが通常.
1815          */
1816         var NodePrivateData = function(){};
1817         NodePrivateData.prototype = {
1818                 elmMouseCatch : null, // rootData only
1819                 eventCounter  : null, // rootData only
1820                 cursorStyle   : null, // rootData only
1821                 node          : null,
1822                 apiuser       : null,
1823                 rootData      : null,
1824                 elm           : null, // resizeTarget
1825                 elmScroll     : null,
1826                 elmScroller   : null,
1827                 elmScrollbar  : null,
1828                 x             : 0,
1829                 y             : 0,
1830                 w             : 0,
1831                 h             : 0,
1832                 t             : 0, // top
1833                 l             : 0, // left
1834                 b             : 0, // bottom
1835                 r             : 0, // right
1836                 absoluteX     : 0,
1837                 absoluteY     : 0,
1838                 _scrollX      : 0,
1839                 _scrollY      : 0,
1840                 scrollingX    : 0,
1841                 scrollingY    : 0,
1842                 _cursor       : '',
1843                 // parentLayer   : null,
1844                 parentData    : null,
1845                 childData     : null,
1846                 events        : null,
1847                 hitChild      : null,
1848                 hitSelf       : false,
1849                 _disabled     : false,
1850                 _childDisabled: false,
1851                 layoutManager : null,
1852                 through       : false,
1853                 clip          : false,
1854                 hover         : false,
1855                 hoverClass    : null,
1856                 isHover       : false,
1857                 scroll        : false,
1858                 dragdrop      : false,
1859                 tooltip       : null,
1860                 init: function( apiuser, rootData, /*parentLayer,*/ parentData, node, rangeOrElm, through, clip, hover, cursor, scroll, dragdrop ){
1861                         this.apiuser     = apiuser;
1862                         this.rootData    = rootData || this;
1863                         // this.parentLayer = parentLayer;
1864                         this.parentData  = parentData;
1865                         this.node        = node;
1866                         this.through     = through;
1867                         this.clip        = !!clip;
1868                         if( cursor ) this._cursor = cursor;   
1869
1870                         if( Type.isHTMLElement( rangeOrElm ) === true ){
1871                                 this.elm        = rangeOrElm;
1872                                 this.hover      = !!hover;
1873                                 this.hoverClass = hover;
1874                                 this.scroll     = clip && scroll;                               
1875                                 this.mesure();
1876                                 this.scroll === true && ScrollBarManager.register( this );
1877                         } else {
1878                                 this.update( rangeOrElm.x, rangeOrElm.y, rangeOrElm.w, rangeOrElm.h );
1879                         };
1880                         
1881                         NodePrivateData.dataList.push( this );
1882                 },
1883                 mesure : function(){
1884                         var x, y, w, h, parent, _this, _parent;
1885                         if( this.elm ){
1886                                 w = this.elm.offsetWidth;
1887                                 h = this.elm.offsetHeight;
1888                                 _this   = Position.cumulativeOffset( this.elm );
1889                                 _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ];
1890                                 x  = _this[ 0 ] - _parent[ 0 ];
1891                                 y  = _this[ 1 ] - _parent[ 1 ];                         
1892                                 if( this.x !== x || this.y !== y || this.w !== w || this.h !== h ){
1893                                         this.x = x;
1894                                         this.y = y;
1895                                         this.w = w;
1896                                         this.h = h;
1897                                         parent = this.parentData;
1898                                         parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY );
1899                                         this._updateRectangle();
1900                                 };                      
1901                         } else {
1902                                 this._updateRectangle();
1903                         };
1904                 },
1905                 mesureChildren : function(){
1906                         var nodes, i;
1907                         if( nodes = this.childData ){
1908                                 for( i = nodes.length; i; ){
1909                                         nodes[ --i ].mesure();
1910                                 };
1911                         };
1912                 },
1913                 update : function( x, y, w, h ){
1914                         var updateXY = false,
1915                                 _this, _parent,
1916                                 parent;
1917                         
1918                         if( this.elm ){
1919                                 // width
1920                                 if( Type.isFinite( w ) === true ){
1921                                         this.elm.style.width = w + 'px';
1922                                 } else
1923                                 if( Type.isString( w ) === true ){
1924                                         this.elm.style.width = w;
1925                                         w = this.elm.offsetWidth;
1926                                 };
1927                                 //update = this.w !== w;
1928         
1929                                 // height
1930                                 if( Type.isFinite( h ) === true ){
1931                                         this.elm.style.height = h + 'px';
1932                                 } else
1933                                 if( Type.isString( h ) === true ){
1934                                         this.elm.style.height = w;
1935                                         h = this.elm.offsetHeight;
1936                                 };
1937                                 //update = update || this.h !== h;
1938                                 
1939                                 // x
1940                                 if( Type.isFinite( x ) === true ){
1941                                         this.elm.style.left = x + 'px';
1942                                 } else
1943                                 if( Type.isString( x ) === true ){
1944                                         this.elm.style.left = x;
1945                                         updateXY = true;
1946                                 } else {
1947                                         updateXY = true;
1948                                 };
1949                                 
1950                                 // y
1951                                 if( Type.isFinite( y ) === true ){
1952                                         this.elm.style.top = y + 'px';
1953                                 } else
1954                                 if( Type.isString( y ) === true ){
1955                                         this.elm.style.top = y;
1956                                         updateXY = true;
1957                                 } else {
1958                                         updateXY = true;
1959                                 };
1960                                 if( updateXY === true ){
1961                                         _this   = Position.cumulativeOffset( this.elm );
1962                                         _parent = this.parentData ? Position.cumulativeOffset( this.parentData.elm ) : [ 0, 0 ];
1963                                         x       = _this[ 0 ] - _parent[ 0 ];
1964                                         y       = _this[ 1 ] - _parent[ 1 ];
1965                                 };
1966                                 //update = update || this.x !== x;
1967                                 //update = update || this.y !== y;
1968                                 
1969                                 //update === true && this._updateRectangle();
1970                                 // return;
1971                         };
1972                         x = Type.isFinite( x ) === true ? x : this.x;
1973                         y = Type.isFinite( y ) === true ? y : this.y;
1974                         w = Type.isFinite( w ) === true ? w : this.w;
1975                         h = Type.isFinite( h ) === true ? h : this.h;
1976                         if( this.x !== x || this.y !== y ){
1977                                 this.x = x;
1978                                 this.y = y;
1979                                 //console.log( 'xy  ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h + ' absX:' + this.parentData.absoluteX )
1980                                 parent = this.parentData;
1981                                 parent && this._updateAbsoluteXY( parent.absoluteX, parent.absoluteY, parent.scrollingX, parent.scrollingY );
1982                                 this.w === w && this.h === h && this._updateRectangle();
1983                         };
1984                         if( this.w !== w || this.h !== h ){
1985                                 this.w = w;
1986                                 this.h = h;
1987                                 //console.log( 'wh  ' + ( this.elm ? this.elm.id : '' ) + ' x:' + x + ' y:' + y + ' w:' + w + ' h:' + h )
1988                                 this._updateRectangle();
1989                         };
1990                         
1991                         ScrollBarManager.update( this );
1992                 },
1993                 _updateAbsoluteXY : function( x, y, sX, sY ){
1994                         var nodes, i;
1995                         this.absoluteX = x = this.x + x;
1996                         this.absoluteY = y = this.y + y;
1997                         if( nodes = this.childData ){
1998                                 for( i = nodes.length; i; ){
1999                                         nodes[ --i ]._updateAbsoluteXY( x, y, this.scrollingX, this.scrollingY );
2000                                 };
2001                         };
2002                 },
2003                 _updateRectangle : function(){
2004                         var w = this.w,
2005                                 h = this.h,
2006                                 x = this.x,
2007                                 y = this.y,
2008                                 l = x,
2009                                 t = y,
2010                                 r = x + w,
2011                                 b = y + h,
2012                                 nodes = this.childData,
2013                                 i, node;
2014                         // self;
2015                         // childnodes
2016                         if( this.clip === false && nodes ){
2017                                 for( i = nodes.length; i; ){
2018                                         node = nodes[ --i ];
2019                                         if( node.l + x < l ) l = x + node.l;
2020                                         if( node.t + y < t ) t = y + node.t;
2021                                         if( r < node.r + x ) r = x + node.r;
2022                                         if( b < node.b + y ) b = y + node.b;
2023                                 };
2024                         };
2025                         // update
2026                         if( b !== this.b || r !== this.r || t !== this.t || l !== this.l ){
2027                                 this.l = l;
2028                                 this.t = t;
2029                                 this.r = r;
2030                                 this.b = b;
2031                                 // this.w = r - x;
2032                                 // this.h = b - y;
2033                                 this.parentData && this.parentData.clip === false && this.parentData._updateRectangle();
2034                                 return true;
2035                         };
2036                 },
2037                 setPosition : function( x, y ){
2038                         this.update( x, y );
2039                 },
2040                 setSize : function( w, h ){
2041                         this.update( undefined, undefined, w, h );
2042                 },
2043                 positionX : function( x ){
2044                         x !== undefined && this.update( x );
2045                         return this.x;
2046                 },
2047                 positionY : function( y ){
2048                         y !== undefined && this.update( undefined, y );
2049                         return this.y;
2050                 },
2051                 width : function( w ){
2052                         w !== undefined && this.update( undefined, undefined, w );
2053                         return this.w;
2054                 },
2055                 height : function( h ){
2056                         h !== undefined && this.update( undefined, undefined, undefined, h );
2057                         return this.h;
2058                 },
2059                 getAbsolutePositionX : function(){
2060                         return this.absoluteX;
2061                 },
2062                 getAbsolutePositionY : function(){
2063                         return this.absoluteY;
2064                 },
2065                 cursor : function( v ){
2066                         if( Type.isString( v ) === true ){
2067                                 this._cursor = v;
2068                                 this === targetNodeData && this.apiuser.updateCoursor( v );
2069                         };
2070                         return this._cursor;
2071                 },
2072                 addEventListener : function( eventType, handler, opt_thisObject ){
2073                         var node    = this.node,
2074                                 counter = this.rootData.eventCounter,
2075                                 list, i;
2076                         if( this.events === null ) this.events = {};
2077                         list = this.events[ eventType ];
2078                         if( !list ){
2079                                 list = this.events[ eventType ] = [];
2080                         } else {
2081                                 for( i = list.length; i; ){
2082                                         if( list[ --i ].match( eventType, handler ) === true ){
2083                                                 return;
2084                                         };
2085                                 };                              
2086                         };
2087                         list.push( new EventTicketClass( this.node, eventType, handler, opt_thisObject ) );
2088                         if( eventType !== 'mouseout' && eventType !== 'mouseover' ){
2089                                 if( counter[ eventType ] ){
2090                                         ++counter[ eventType ];
2091                                 } else {
2092                                         //console.log( eventType );
2093                                         counter[ eventType ] = 1;
2094                                         MouseEvent.add( this.apiuser, this.rootData.elmMouseCatch, eventType, eventRellay );
2095                                 };                              
2096                         };
2097                 },
2098                 removeEventListener : function( eventType, handler ){
2099                         var events  = this.events,
2100                                 counter = this.rootData.eventCounter,
2101                                 type, list, i = 0;
2102                         if( events === null ) return;
2103                         console.log( ' *** remove ' + eventType );
2104                         for( type in events ){
2105                                 list = events[ type ];
2106                                 if( eventType && eventType !== type ) continue;
2107                                 for( ; i < list.length; ){
2108                                         if( list[ i ].destroy( type, handler ) === true ){
2109                                                 console.log( ' *** removed! ' + type );
2110                                                 list.splice( i, 1 );
2111                                         } else {
2112                                                 ++i;
2113                                         };
2114                                 };
2115                                 if( list.length === 0 ){
2116                                         // delete this[ type ];
2117                                         delete events[ type ];
2118                                 };
2119                                 if( counter[ type ] ){
2120                                         --counter[ type ];
2121                                         if( counter[ type ] === 0 ){
2122                                                 MouseEvent.remove( this.apiuser, this.rootData.elmMouseCatch, type, eventRellay );
2123                                                 delete counter[ type ];
2124                                         };
2125                                 };
2126                         };
2127                 },
2128                 _capcher : function( x, y ){
2129                         var t = this, nodes, child, _x, _y, hit, i;
2130                         if( t._disabled === true ) return false;
2131                         delete t.hitChild;
2132                         x -= t.x;
2133                         y -= t.y;
2134                         if( nodes = t.childData ){
2135                                 _x = x - t.scrollingX;
2136                                 _y = y - t.scrollingY;
2137                                 for( i = nodes.length; i; ){
2138                                         child = nodes[ --i ];
2139                                         if( child._disabled === false && child.l <= _x && _x < child.r && child.t <= _y && _y < child.b && child._capcher( _x, _y ) === true ){
2140                                                 t.hitChild = child;
2141                                                 break;
2142                                         };
2143                                 };
2144                         };
2145                         if( t.through === true ){
2146                                 t.hitChild && t.hitSelf === false && hoverList.push( t );
2147                                 return !!t.hitChild;
2148                         };
2149                         hit = 0 <= x && x < t.w && 0 <= y && y < t.h;
2150                         ( t.hitChild || hit ) && t.hitSelf === false && hoverList.push( t );
2151                         if( hit === true && t.hitChild === null ) targetNodeData = t;
2152                         return hit || !!t.hitChild;
2153                 },
2154                 fire : function( e, eventType, hit ){
2155                         var list = this.events[ eventType ],
2156                                 i    = list.length;
2157                         e = NodePrivateData.createEvent( e, eventType, this, hit );
2158                         for( ; i; ) list[ --i ].fire( e );
2159                         // console.log( eventType + ' x:' + x + ' y:' + y );
2160                 },
2161                 dispatchEvent : function( e, eventType, hit ){
2162                         var ret, list, i, p, child;
2163                         if( !this.events || !( list = this.events[ eventType ] ) ) return;
2164                         
2165                         child = !!this.hitChild;
2166                         e = NodePrivateData.createEvent( e, eventType, this, hit );
2167                         for( i = list.length; i; ){
2168                                 ret = list[ --i ].fire( e );
2169                                 if( ret === true && child === false ){
2170                                         forceNodeData = this;
2171                                         return true;
2172                                 };
2173                                 if( ret === false ) return false;
2174                         };
2175                         forceNodeData  = null;
2176                 },
2177                 scrollTo : function( x, y ){
2178                         this._scrollX = x;
2179                         this._scrollY = y;
2180                         ScrollBarManager.update( this );
2181                 },
2182                 scrollX : function( v ){
2183                         if( Type.isFinite( v ) === true ){
2184                                 this._scrillX = v;
2185                                 ScrollBarManager.update( this );
2186                         };
2187                         return this.scrollingX; // this._scrollX;
2188                 },
2189                 scrollY : function( v ){
2190                         if( Type.isFinite( v ) === true ){
2191                                 this._scrillY = v;
2192                                 ScrollBarManager.update( this );
2193                         };
2194                         return this.scrollingY; // this._scrollY;
2195                 },
2196                 nodeIndex : function( v ){
2197                         var list, i;
2198                         if( !this.parentData ) return 0;
2199                         
2200                         list = this.parentData.childData;
2201                         i    = Util.getIndex( list, this );
2202                         if( Type.isFinite( v ) === false || i === v && v < 0 && list.length <= v ) return i;
2203                         
2204                         list.splice( i, 1 );
2205                         list.length === v ? list.push( this ) : list.splice( v, 0, this );
2206                         this._free();
2207                         return v;
2208                 },
2209                 _free : function(){
2210                         if( this.parentData.hitChild === this ){
2211                                 this.parentData.hitChild = null;
2212                                 this.isHover === true && hoverList.splice( Util.getIndex( hoverList, this ), 1 ) && Util.removeClass( this.elm, this.hoverClass );
2213                                 this.isHover = false;
2214                                 if( forceNodeData === this ) forceNodeData = null;
2215                                 if( targetNodeData  === this ) targetNodeData  = null;
2216                         };                      
2217                 },
2218                 numNode : function(){
2219                         return this.childData ? this.childData.length : 0;
2220                 },
2221                 disabled : function( v ){
2222                         if( Type.isBoolean( v ) === true ){
2223                                 this._disabled = v;
2224                                 if( v === false ){
2225                                         this._free();
2226                                 };
2227                         };
2228                         return this._disabled;
2229                 },
2230                 childrenDisabled : function( v ){
2231                         if( Type.isBoolean( v ) === true ){
2232                                 this._childDisabled = v;
2233                         };
2234                         return this._childDisabled;
2235                 },
2236                 remove : function(){
2237                         if( this === this.rootData ) return;
2238                         var parent = this.parentData,
2239                                 nodes  = parent.childData;
2240                         this._destroy();
2241                         if( parent.hitChild === this ) delete parent.hitChild;
2242                         nodes.splice( Util.getIndex( nodes, this ), 1 );
2243                         if( nodes.length === 0 ) delete parent.childData;       
2244                         parent.clip === false && parent._updateRectangle();
2245                 },
2246                 _destroy : function(){
2247                         var nodes = this.childData,
2248                                 list  = NodePrivateData.dataList,
2249                                 node;
2250                         this.removeEventListener();
2251                         ScrollBarManager.remove( this );
2252                         if( nodes ){
2253                                 while( node = nodes.shift() ) node._destroy();
2254                                 delete this.childData;
2255                         };
2256                         list.splice( Util.getIndex( list, this ), 1 );
2257                 }
2258         };
2259         NodePrivateData.dataList = [];
2260         NodePrivateData.get = function( node ){
2261                 // if( node instanceof NodePrivateData ) return node;
2262                 // return NodePrivateData.dataList[ layer._getUID() ];
2263                 var list = NodePrivateData.dataList;
2264                 for( var i = list.length; i; ){
2265                         if( list[ --i ].node === node ) return list[ i ];
2266                 };
2267                 return null;
2268         };
2269         NodePrivateData.createEvent = function( e, eventType, data, hit ){
2270                 var _e = {
2271                         layerX      : e.clientX - data.absoluteX,
2272                         layerY      : e.clientY - data.absoluteY,
2273                         clientX     : e.clientX,
2274                         clientY     : e.clientY,
2275                         dragOffsetX : e.dragOffsetX,
2276                         dragOffsetY : e.dragOffsetY,
2277                         dragPhase   : e.dragPhase,                                      
2278                         eventType   : eventType,
2279                         hit         : hit,
2280                         node        : data.node,
2281                         wheelDelta  : e.wheelDelta,
2282                         target      : forceNodeData ? forceNodeData.node : targetNodeData ? targetNodeData.node : null
2283                 };
2284                 return _e;
2285         };
2286         
2287         var EventTicketClass = function( node, eventType, handler, opt_thisObject ){
2288                 this.node    = node;
2289                 this.type    = eventType;
2290                 this.handler = handler;
2291                 this.thisObj = opt_thisObject || node;
2292         };
2293         EventTicketClass.prototype = {
2294                 match : function( eventType, handler ){
2295                         if( handler && this.handler !== handler ) return false;
2296                         if( eventType && this.type !== eventType ) return false;
2297                         return true;
2298                 },
2299                 destroy : function( eventType, handler ){
2300                         if( this.match( eventType, handler ) === false ) return false;
2301                         delete this.node;
2302                         delete this.type;
2303                         delete this.handler;
2304                         delete this.thisObj;
2305                         return true;
2306                 },
2307                 fire : ( function(){
2308                         if( Function.prototype.call ){
2309                                 return function( e ){
2310                                         return this.handler.call( this.thisObj, e );
2311                                 };                              
2312                         };
2313                         return function( e ){
2314                                 var ret;
2315                                 this.thisObj._currentHandler = this.handler;
2316                                 ret = this.thisObj._currentHandler( e );
2317                                 delete this.thisObj._currentHandler;
2318                                 return ret;                                     
2319                         };
2320                 })()
2321         };
2322         
2323 /*-------------------------------------
2324  *  StayHelper
2325  */
2326         var StayEventTicketClass = function( node, data, stayhandler, opt_thisObject ){
2327                 node.addEventListener( 'mouseover', this.mouseoverHandler, this );
2328                 this.node       = node;
2329                 this.data       = data;
2330                 this.handler    = stayhandler;
2331                 this.thisObject = opt_thisObject;
2332         };
2333         StayEventTicketClass.prototype = Util.extend( new EventTicketClass( null, 'mousestay' ), {
2334                 // type : 'mousestay',
2335                 e    : null,
2336                 mouseoverHandler : function( e ){
2337                         this.e = NodePrivateData.createEvent( e, this.type, this.data, true );
2338                         this.node.addEventListener( 'mouseout',  this.mousestayHandler, this );
2339                         this.node.addEventListener( 'mousemove', this.mousemoveHandler, this );
2340                         SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this );
2341                 },
2342                 timeoutHandler : function(){
2343                         this.mouseoutHandler();
2344                         return this.fire( this.e );
2345                 },
2346                 mousemoveHandler : function( e ){
2347                         this.e = NodePrivateData.createEvent( e, this.type, this.data, true );
2348                         SystemTimer.remove( this.data.apiuser, this.timeoutHandler );
2349                         SystemTimer.add( this.data.apiuser, this.timeoutHandler, null, this );
2350                 },
2351                 mouseoutHandler : function( e ){
2352                         this.node.removeEventListener( 'mouseout', this.mousestayHandler );
2353                         this.node.removeEventListener( 'mousemove', this.mousemoveHandler );
2354                         SystemTimer.remove( this.data.apiuser, this.timeoutHandler );
2355                         delete this.e;
2356                 }
2357         });
2358         
2359         var ScrollBarManager = ( function(){
2360                 var elmScroller     = document.createElement( 'div' ),
2361                         elmBar          = document.createElement( 'div' ),
2362                         smoothList      = [],
2363                         dragPhase       = 2,
2364                         dragOut         = false,
2365                         currentNodeData = null,
2366                         dragStartY      = 0,
2367                         currentEvent;
2368                 
2369                 function tick(){
2370                         var list = smoothList,
2371                                 i, data, y;
2372                         for( i = 0; i < list.length; ){
2373                                 data = list[ i ];
2374                                 if( data.scrollingY !== data._scrollY ){
2375                                         y = data.scrollingY += data.smoothY;
2376                                         if( data.smoothY < 0 ){
2377                                                 y = y < data._scrollY ? data._scrollY : y;
2378                                         } else {
2379                                                 y = data._scrollY < y ? data._scrollY : y;
2380                                         };
2381                                         data.scrollingY    = y;
2382                                         data.elm.scrollTop = -y;
2383                                         data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true );
2384                                 };
2385                                 if( data.scrollingY === data._scrollY ){
2386                                         list.splice( i, 1 );
2387                                         // data.events && data.events.scroll && data.fire( currentEvent, 'scroll', true );
2388                                 } else {
2389                                         ++i;
2390                                 };
2391                         };
2392                         list.length === 0 && SystemTimer.remove( SUPER_USER_KEY, tick );
2393                         currentEvent.type = 'updateAfterScroll';
2394                         AsyncCall.add( data.apiuser, eventRellay, currentEvent ); // スクロール後の更新        
2395                 };
2396                 
2397                 function scrollReady( e ){
2398                         var data = this;
2399                         
2400                         dragOut = false;
2401                         if( data === currentNodeData || dragPhase !== 2 ) return; // Drag中の場合は 他にスクロールを作らない
2402                         currentNodeData && scrollRelease();
2403
2404                         dragPhase = 2;
2405                         data.elm.parentNode.appendChild( elmScroller );
2406                         elmScroller.appendChild( data.elm );
2407                         
2408                         elmScroller.style.cssText = 'position:absolute;left:0;top:0;';
2409                         elmScroller.appendChild( elmBar );      
2410                         
2411                         data.elm.scrollTop = -data.scrollingY;
2412                         data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data );
2413                         data.rootData.addEventListener( 'mousedrag',  onMouseDragScroll, data );
2414                         data.addEventListener( 'mouseout',   onMouseOut, data );
2415                         currentNodeData = data;
2416                         ScrollBarManager.update( data );
2417                 };
2418                 function scrollRelease(){
2419                         var data   = currentNodeData;
2420                         var parent = elmScroller.parentNode;
2421                         parent.appendChild( currentNodeData.elm );
2422                         parent.removeChild( elmScroller );
2423                         currentNodeData.elm.scrollTop = -data.scrollingY;
2424                         
2425                         data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data );
2426                         data.rootData.removeEventListener( 'mousedrag',  onMouseDragScroll, data );
2427                         data.removeEventListener( 'mouseout',   onMouseOut, data );
2428                         currentNodeData = null;
2429                 };
2430                 function onMouseOut( e ){
2431                         dragOut = true;
2432                         console.log( 'mouseOut ' + dragPhase );
2433                         dragPhase === 2 && scrollRelease(); // Dragしてのアウトの場合, scroll をリリースしない
2434                 };
2435                 function onMouseWheelScroll( e ){
2436                         var data = this;
2437                         this._scrollY += e.wheelDelta;
2438                         ScrollBarManager.update( this );
2439                         currentEvent = e;
2440                         return true;
2441                 };
2442                 function onMouseDragScroll( e ){
2443                         var data = this;
2444                         //e.dragOffsetY;
2445                         currentEvent = e;
2446                         dragPhase = e.dragPhase;
2447                         switch( dragPhase ){
2448                                 case 0:
2449                                         dragStartY = this.scrollingY;
2450                                         data.rootData.removeEventListener( 'mousewheel', onMouseWheelScroll, data );
2451                                 case 1:
2452                                         this._scrollY = dragStartY + e.dragOffsetY;
2453                                         ScrollBarManager.update( this );                                
2454                                         return true;
2455                                 case 2:
2456                                         dragOut === true ? scrollRelease() : data.rootData.addEventListener( 'mousewheel', onMouseWheelScroll, data );
2457                                         return false;
2458                         };
2459                 };
2460                 
2461                 return {
2462                         register : function( data ){
2463                                 data.addEventListener( 'mouseover', scrollReady, data );
2464                         },
2465                         update : function( data ){
2466                                 // if( data !== currentNodeData ) return;
2467                                 var isCurrent = data === currentNodeData;
2468                                 
2469                                 var contentH = data._scrollH = data.elm.scrollHeight,
2470                                         clipH    = data.h,
2471                                         offsetH  = contentH - clipH,
2472                                         scrollY  = data._scrollY = 0 < data._scrollY ? 0 : ( data._scrollY < -offsetH ? -offsetH : data._scrollY ),
2473                                         barH, barY;
2474                                 if( isCurrent === true ){
2475                                         elmScroller.style.width  = data.w + 'px';
2476                                         elmScroller.style.height = clipH + 'px';                                        
2477                                 };
2478                                 
2479                                 if( offsetH < 1 ){
2480                                         data._scrollY = scrollY = 0;
2481                                         if( isCurrent === true ) elmBar.style.display = 'none';
2482                                 } else
2483                                 if( isCurrent === true ){
2484                                         barH     = Math.floor( clipH * ( clipH / contentH ) );
2485                                         barY     = Math.floor( ( clipH - barH ) * - scrollY / offsetH );
2486                                         elmBar.style.cssText = [
2487                                                 'position:absolute;',
2488                                                 'width:10px;',
2489                                                 'background-color:#333;',
2490                                                 'right:2px;',
2491                                                 'font-size:0;line-height:0;',
2492                                                 'height:', barH, 'px;',
2493                                                 'top:', data.y + barY, 'px;'
2494                                         ].join( '' );                                   
2495                                 };
2496                                 data.smoothY = ( scrollY - data.scrollingY ) / 10;
2497                                 if( data.scrollingY !== scrollY && Util.getIndex( smoothList, data ) === -1 ){
2498                                         smoothList.length === 0 && SystemTimer.add( SUPER_USER_KEY, tick, 16 );
2499                                         smoothList.push( data );
2500                                 };
2501                         },
2502                         remove : function( data ){
2503                                 var list = smoothList,
2504                                         i    = Util.getIndex( list, data );
2505                                 data === currentNodeData && scrollRelease();
2506                                 i !== -1 && list.splice( i, 1 );
2507                         }
2508                 };
2509         })();
2510         
2511         return {
2512                 create : function( apiuser ){
2513                         var     elm  = document.createElement( 'div' ),
2514                                 root, data;
2515                         body.appendChild( elm );
2516                         
2517                         root = new NodeClass( apiuser, null, null, elm );
2518                         data = NodePrivateData.get( root );
2519                         
2520                         // elm.style.cssText = 'position:absolute;top:0;left:0;height:100%;';
2521                         elm.className      = 'mouse-operation-catcher';
2522                         elm.unselectable   = 'on';
2523                         data.elmMouseCatch = elm;
2524                         
2525                         data.eventCounter  = {};
2526                         ROOT_LIST.push( data );
2527                         currentRootData    = data;
2528                         targetNodeData     = null;
2529                         forceNodeData      = null;
2530                         
2531                         MouseEvent.add( apiuser, elm, 'mousemove', eventRellay );
2532                         return root;
2533                 },
2534                 onCurrentApplicationChange : function( _application ){
2535                         currentRootData    = null;
2536                         targetNodeData     = null;
2537                         forceNodeData      = null;
2538                         for( var i = ROOT_LIST.length; i; ){
2539                                 if( ROOT_LIST[ --i ].apiuser === _application ){
2540                                         currentRootData = ROOT_LIST[ i ];
2541                                         return;
2542                                 };
2543                         };
2544                 },
2545                 destroyTree : function( root ){
2546                         var data = NodePrivateData.get( root );
2547                         MouseEvent.remove( data.apiuser, data.elmMouseCatch, 'mousemove', eventRellay );
2548                         body.removeChild( data.elmMouseCatch );
2549                         data._destroy();
2550                         ROOT_LIST.splice( Util.getIndex( ROOT_LIST, data ), 1 );
2551                         if( currentRootData === data ){
2552                                 currentRootData    = null;
2553                                 targetNodeData     = null;
2554                                 forceNodeData      = null;      
2555                         };
2556                 },
2557                 onSystemShutdown : function(){
2558                         
2559                 },
2560                 isNodeInstance : function( node ){
2561                         return node instanceof NodeClass;
2562                 },
2563                 _getNodePrivateData : function( node ){ // system only
2564                         return NodePrivateData.get( node );
2565                 }
2566         };
2567 })();
2568
2569 var Application = ( function(){
2570         
2571         var LIVE_APPLICATION_LIST = [];
2572         
2573         var currentApplication    = null,
2574                 coveredApplication    = null,
2575                 winW                  = 0,
2576                 winH                  = 0;
2577         
2578         var ApplicationReference = function( appClass, isOverlay, displayName, id, thumbnailUrl, tailColor ){
2579                 var self          = this;
2580                 var application   = null;
2581                 this.id           = id;
2582                 this.displayName  = displayName;
2583                 this.thumbnailUrl = thumbnailUrl;
2584                 this.tailColor    = tailColor;
2585                 
2586                 function asyncBoot(){
2587                         application = Application.boot( appClass, displayName, self.getUID(), isOverlay, Util.copyArray( arguments ) );
2588                 };
2589                 this.getUID = function(){
2590                         return Util.getIndex( API_USER_LIST, appClass );
2591                 };
2592                 this.getDisplayName = function(){
2593                         return this.displayName;
2594                 };
2595                 this.boot = function( /* _option */ ){
2596                         AsyncCall.add( this, asyncBoot, Util.copyArray( arguments ) );
2597                 };
2598                 this.shutdown = function(){
2599                         if( !application ) return false;
2600                         
2601                         AsyncCall.add( application, ( isOverlay === true ? Overlay.hide : application.close ) );
2602                 };
2603         };
2604         
2605         function asyncBootHome(){
2606                 currentApplication === null && Home.boot();
2607         };
2608         function asyncOpen( /* arguments */ ){
2609                 var _arg = Util.copyArray( arguments );
2610                 _arg.unshift( winW, winH );
2611                 currentApplication.open.apply( currentApplication, _arg );
2612         };
2613         return {
2614                 register: function( _class, _overlay, _tail, _displayName, _id, _thumbnailUrl, _tailColor ){
2615                         APPLICATION_LIST.push( _class );
2616                         API_USER_LIST.push( _class );
2617                         var _ref = new ApplicationReference( _class, _overlay, _displayName, _id, _thumbnailUrl, _tailColor );
2618                         _tail === true && Home.add( _ref );
2619                         return _ref;
2620                 },
2621                 isApplicationInstance: function( app ){
2622                         return ApplicationPrivateData.get( app ) !== null;
2623                 },
2624                 isApplicationReference: function( _reference ){
2625                         return _reference instanceof ApplicationReference;
2626                 },
2627                 isCurrentAppplication: function( app ){
2628                         return app === currentApplication;
2629                 },
2630                 boot: function( appClass, displayName, uid, isOverlay, arg ){
2631                         if( currentApplication ){
2632                                 if( currentApplication.getUID() === uid ) return null;
2633                                 if( isOverlay === false && currentApplication.close() === false ) return null;
2634                         };
2635
2636                         appClass.prototype = new AbstractApplication( appClass, displayName, isOverlay );
2637                         
2638                         var application = new appClass(),
2639                                 data = ApplicationPrivateData.get( application );
2640                         
2641                         application.rootElement = data.rootElement;
2642                         data.application = application;
2643                         
2644                         coveredApplication = isOverlay === true ? currentApplication : null;
2645                         
2646                         Application.onCurrentApplicationChange( application );
2647                         
2648                         if( isOverlay === false ){
2649                                 body.style.backgroundColor = application.bgColor;
2650                                 
2651                                 body.appendChild( data.rootElement );
2652                                 data.rootElement.style.display = 'none';
2653                                 application.init();
2654
2655                                 application.addAsyncCall( asyncOpen, arg );
2656                         } else {
2657                                 Overlay.show( application, arg );
2658                         };
2659                         
2660                         return application;
2661                 },
2662                 shutdown: function( _application, isOverlay ){
2663                         if( isOverlay === false ){
2664                                 currentApplication = null;
2665                                 AsyncCall.add( SUPER_USER_KEY, asyncBootHome );
2666                         } else {
2667                                 Application.onCurrentApplicationChange( coveredApplication );
2668                                 coveredApplication = null;
2669                         };
2670                 },
2671                 onCurrentApplicationChange: function( _application ){
2672                         if( Application.isApplicationInstance( _application ) === false ) return;
2673                         if( currentApplication === _application ) return;
2674                         currentApplication = _application;
2675                         MouseEvent.onCurrentApplicationChange( _application );
2676                         PointingDeviceEventTree.onCurrentApplicationChange( _application );
2677                         KeyEvent.updateCurrentListener( _application );
2678                         // InteractiveLayer.onCurrentApplicationChange( _application );
2679                 },
2680                 onApplicationShutdown: function( _application ){
2681                         LIVE_APPLICATION_LIST.splice( Util.getIndex(  LIVE_APPLICATION_LIST, _application ) );
2682                 },
2683                 onWindowResize: function( w, h ){
2684                         winW = w;
2685                         winH = h;
2686                         currentApplication && currentApplication.resize( w, h );
2687                         Overlay.onWindowResize( w, h );
2688                         UI.onWindowResize( w, h );
2689                 },
2690                 onSystemShutdown: function(){
2691                         
2692                 }
2693         }
2694 })();
2695
2696 /* --------------------------------------------------------------
2697  * Home
2698  * 
2699  */
2700         var Home = ( function(){
2701                 var APP_REF_LIST    = [];
2702                 var ELM_TAIL_ORIGIN = ( function(){
2703                         var ret = document.createElement( 'div' ),
2704                                 h2  = document.createElement( 'h2' );
2705                         ret.className = 'tail-wrapper';
2706                         ret.appendChild( h2 );
2707                         h2.appendChild( document.createTextNode( 'appName' ) );
2708                         return ret;
2709                 })();
2710                 
2711                 var TailClass = function( appRef ){
2712                         this.elm = ELM_TAIL_ORIGIN.cloneNode( true );
2713                         this.destroy = function(){
2714                                 appRef = self = elmName = null;
2715                         };                      
2716                         
2717                         var self    = this,
2718                                 elmName = this.elm.getElementsByTagName( 'h2' )[ 0 ].firstChild;
2719                         
2720                         this.elm.style.backgroundColor = appRef.tailColor;
2721                         elmName.data = appRef.displayName;
2722                 };
2723                 
2724                 var ref = Application.register( function(){
2725                         var self     = this,
2726                                 winW     = 0,
2727                                 winH     = 0,
2728                                 tailList = [],
2729                                 elmContainer, elmHeader;
2730                         
2731                         function draw(){
2732                                 var tail, elm;
2733                                 for( var i=0, l=APP_REF_LIST.length; i<l; ++i ){
2734                                         tail = new TailClass( APP_REF_LIST[ i ] );
2735                                         tailList.push( tail );
2736                                         elm  = tail.elm;
2737                                         elmContainer.appendChild( elm );
2738                                         self.addEventListener( elm, 'click', onTailClick );
2739                                 };
2740                         };
2741                         
2742                         function onTailClick( e ){
2743                                 var _children = elmContainer.getElementsByTagName( 'div' );
2744                                 for( var i=0, l=_children.length; i<l; ++i ){
2745                                         if( this === _children[ i ] ){
2746                                                 APP_REF_LIST[ i ].boot();
2747                                                 break;
2748                                         };
2749                                 };
2750                         };
2751                         
2752                         this.bgColor     = '#0F6D39';
2753                         this.MIN_WIDTH   = 320;
2754                         this.MIN_HEIGHT  = 320;
2755                         this.onInit = function(){
2756                                 self.rootElement.id = 'home-root';
2757                                 
2758                                 elmContainer        = document.createElement( 'div' );
2759                                 self.rootElement.appendChild( elmContainer );
2760                                 elmContainer.id     = 'home-tail-container';
2761                                 
2762                                 elmHeader           = document.createElement( 'div' );
2763                                 self.rootElement.appendChild( elmHeader );
2764                                 elmHeader.id        = 'home-header';
2765                         };
2766                         this.onOpen = function( _w, _h ){
2767                                 winW = _w;
2768                                 winH = _h;
2769                                 draw();
2770                         };
2771                         this.onPaneResize = function( _w, _h ){
2772                                 
2773                         };
2774                         this.onClose = function(){
2775                                 self.removeEventListener();
2776                                 while( tailList.length > 0 ){
2777                                         tailList.shift().destroy();
2778                                 }
2779                                 self = tailList = elmContainer = null;
2780                         };
2781                 }, false, false, 'home', 'home', null );
2782                 
2783                 return {
2784                         add: function( _appRef ){
2785                                 if( Application.isApplicationReference( _appRef ) === false ) return;
2786                                 Util.getIndex( APP_REF_LIST, _appRef ) === -1 && APP_REF_LIST.push( _appRef );
2787                         },
2788                         boot: function(){
2789                                 ref.boot();
2790                         }
2791                 }
2792         })();
2793
2794         var Page = ( function(){
2795                 var pageNodes = [],
2796                         appClass, ref,
2797                         ignoreTagList = [ 'script', 'noscript', 'style' ];
2798                 
2799                 var MemoryClass = function( node ){
2800                         this.node = node;
2801                 };
2802                 MemoryClass.prototype = {
2803                         init: function(){
2804                                 var node      = this.node,
2805                                         _nodeType = node.nodeType;
2806                                 if( _nodeType === 1 && Util.getIndex( ignoreTagList, node.tagName.toLowerCase() ) === -1 ){
2807                                         this.type    = _nodeType;
2808                                         this.display = node.style.display;
2809                                 } else
2810                                 if( _nodeType === 3 ){
2811                                         if( node.data.replace( /\s/g, '' ).length !== 0 ){
2812                                                 this.type    = _nodeType;
2813                                                 this.before  = pageNodes.length === 0 ? null : pageNodes[ pageNodes.length - 1 ].node;
2814                                         } else {
2815                                                 body.removeChild( node );
2816                                                 return false;
2817                                         }
2818                                 } else {
2819                                         // body.removeChild( node );
2820                                         return false;
2821                                 };
2822                         },
2823                         show: function(){
2824                                 if( this.type === 1 ){
2825                                         if( this.display ){
2826                                                 this.node.style.display = this.display;
2827                                         } else {
2828                                                 this.node.style.display = '';
2829                                         }
2830                                 } else {
2831                                         if( this.before ){
2832                                                 body.insertBefore( this.node, this.before );
2833                                         } else {
2834                                                 body.appendChild( this.node );
2835                                         };
2836                                 };
2837                         },
2838                         hide: function(){
2839                                 if( !this.node.parentNode ){
2840                                         return;
2841                                 };
2842                                 if( this.type === 1 ){
2843                                         this.node.style.display = 'none';
2844                                 } else {
2845                                         body.removeChild( this.node );
2846                                 };
2847                         }
2848                 };
2849                 
2850                 return {
2851                         onReady: function(){
2852                                 var _children = Util.copyArray( body.childNodes ),
2853                                         _mem;
2854                                 for( var i = 0, l = _children.length; i<l; ++i ){
2855                                         _mem = new MemoryClass( _children[ i ] );
2856                                         _mem.init() !== false && pageNodes.push( _mem );
2857                                 };
2858                                 if( pageNodes.length !== 0 ){
2859                                         if( Type.isFunction( gOS.PageApplicationClass ) === true ){
2860                                                 Page.appClass = gOS.PageApplicationClass;
2861                                                 Page.appClass.bgColor    = Page.appClass.bgColor;
2862                                                 Page.appClass.MIN_WIDTH  = Page.appClass.MIN_WIDTH  || 240;
2863                                                 Page.appClass.MIN_HEIGHT = Page.appClass.MIN_HEIGHT || 240;
2864                                         } else {
2865                                                 Page.appClass = function(){
2866                                                         var self     = this;
2867                                                         
2868                                                         this.bgColor      = '#ffffff';
2869                                                         this.MIN_WIDTH    = 200;
2870                                                         this.MIN_HEIGHT   = 200;
2871                                                         this.onInit       = function(){};
2872                                                         this.onOpen       = function( _w, _h ){
2873                                                                 KeyEvent.add( self, Const.KEY.EVENT.KEY_DOWN, ref.shutdown, 27 ); // 27.esc
2874                                                         };
2875                                                         this.onPaneResize = function( _w, _h ){};
2876                                                         this.onClose      = function(){};
2877                                                 };
2878                                         };
2879                                         ref = Application.register( Page.appClass, false, true, document.title, 'page', null, Page.appClass.tailColor || '#999999' );
2880                                         if( Type.isFunction( gOS.PageApplicationClass ) === true ){
2881                                                 gOS.PageApplicationRef = ref;
2882                                         }; 
2883                                 };
2884                                 delete Page.onReady;
2885                         },
2886                         show: function(){
2887                                 for( var i = pageNodes.length; i; ){
2888                                         pageNodes[ --i ].show();
2889                                 };
2890                         },
2891                         hide: function(){
2892                                 for( var i = pageNodes.length; i; ){
2893                                         pageNodes[ --i ].hide();
2894                                 };                              
2895                         },
2896                         boot: function(){
2897                                 ref && ref.boot();
2898                         },
2899                         registered: function(){
2900                                 return !!ref;
2901                         },
2902                         appClass: null
2903                 }
2904         })();
2905
2906 /* --------------------------------------------------------------
2907  * Event
2908  * 
2909  *  screenX
2910  *  スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系である。screenX, screenY属性で取得できる。Javascritpでは、同名のプロパティとして実装されている。
2911  *  しかし、これは、現実的には、何の役に立たない。ブラウザ自体がディスプレイのどの位置にいるのかがわからないので、画面上の位置を知ったところで、何にもならないからだ。 
2912  * 
2913  *  clientX
2914  *  ウインドウ座標とは、現在のブラウザのウインドウの、ドキュメントを表示している部分の左上原点とした座標である。
2915  *  問題は、ウインドウは、必ずしもドキュメント全体を表示するとは限らない。スクロールと呼ばれるUIによって、ドキュメントの一部だけを表示しているかもしれない。
2916  */
2917         var XBrowserEvent = ( function(){
2918                 var wrappedHandlerClass,
2919                         wrappedEventClass,
2920                         tmp;
2921                 
2922                 if( window.addEventListener ){
2923                         wrappedHandlerClass = function( ticket ){
2924                                 this.handler = function( e ){
2925                                         if( ticket.fire( e ) !== false ) return;
2926                                         e.preventDefault();
2927                                         e.stopPropagation();
2928                                         return false;
2929                                 };
2930                                 this.destroy = function(){
2931                                         ticket = null;
2932                                         delete this.handler;
2933                                         delete this.destroy;
2934                                 };
2935                         };
2936                 } else {
2937                         wrappedEventClass = function( e, element ){
2938                                 this._event        = e;
2939                                 this.type          = e.type;
2940                                 this.target        = e.srcElement;
2941                                 this.currentTarget = element;
2942                                 this.relatedTarget = e.formElement ? e.formElement : e.toElement;
2943                                 this.eventPhase    = e.srcElement === element ? 2: 3;
2944                                 
2945                                 this.clientX       = e.clientX;
2946                                 this.clientY       = e.clientY;
2947                                 this.screenX       = e.screenX;
2948                                 this.screenY       = e.screenY;
2949                                 
2950                                 this.keyCode       = e.keyCode;
2951                                 this.altKey        = e.altKey;
2952                                 this.ctrlKey       = e.ctrlKey;
2953                                 this.shiftKey      = e.shiftKey;
2954                                 
2955                                 this.wheelDelta    = e.wheelDelta;
2956                         };
2957                         wrappedEventClass.prototype.stopPropagation = function(){
2958                                 this._event.cancelBubble = true;
2959                         };
2960                         wrappedEventClass.prototype.preventDefault  = function(){
2961                                 this._event.returnValue = false;
2962                         };
2963
2964                         if( document.attachEvent ){
2965                                 wrappedHandlerClass = function( ticket ){
2966                                         this.handler = function(){
2967                                                 if( ticket === null ) alert( window.event.type )
2968                                                 if( ticket.fire( new wrappedEventClass( window.event, ticket.element ) ) !== false ) return;
2969                                                 // e.preventDefault();
2970                                                 // e.stopPropagation();
2971                                                 window.event.cancelBubble = true;
2972                                                 window.event.returnValue  = false;
2973                                                 return false;
2974                                         };
2975                                         this.destroy = function(){
2976                                                 ticket = null;
2977                                                 delete this.handler;
2978                                                 delete this.destroy;
2979                                         };
2980                                 };
2981                         } else {
2982                                 tmp = {
2983                                         list: [],
2984                                         find: function( _ticket ){
2985                                                 for( var i=0, l= tmp.list.length, _item; i<l; ++i ){
2986                                                         _item = tmp.list[ i ];
2987                                                         if( _item.element === _ticket.element && _item.eventType === _ticket.eventType ){
2988                                                                 return _item;
2989                                                         };
2990                                                 };
2991                                                 return null;
2992                                         }
2993                                 };
2994                                 tmp.TicketClass = function( _ticket ){
2995                                         var self = this;
2996                                         this.element   = _ticket.element;
2997                                         this.eventType = _ticket.eventType;
2998                                         this.tickets   = [ _ticket ];
2999                                         this.onDestroy = function(){ self = null; };
3000                                         
3001                                         this.element[ 'on' + this.eventType ] = function( e ){ return self.fire( e );};
3002                                         _ticket = null;
3003                                 };
3004                                 tmp.TicketClass.prototype = {
3005                                         add: function( _ticket ){
3006                                                 Util.getIndex( this.tickets, ticket ) === -1 && this.tickets.push( _ticket );
3007                                         },
3008                                         remove: function( _ticket ){
3009                                                 var i = Util.getIndex( this.tickets, _ticket );
3010                                                 i !== -1 && this.tickets.splice( i, 1 );
3011                                                 this.tickets.length === 0 && this.destroy();
3012                                         },
3013                                         fire: function( e ){
3014                                                 e = e || new wrappedEventClass( window.event, this.element );
3015                                                 var i = this.tickets.length,
3016                                                         cancel;
3017                                                 for( ; i; ){
3018                                                         if( this.tickets[ --i ].fire( e ) === false ) cancel = false;
3019                                                 };
3020                                                 return cancel;
3021                                         },
3022                                         destroy: function(){
3023                                                 this.onDestroy();
3024                                                 this.element[ 'on' + this.eventType ] = '';
3025                                                 tmp.list.splice( Util.getIndex( tmp.list, this ), 1 );
3026                                                 delete this.element;
3027                                                 delete this.eventType;
3028                                                 delete this.tickets;
3029                                                 delete this.onDestroy;
3030                                         }
3031                                 };
3032                         };
3033                 };
3034
3035                 return {
3036                         add: function( _ticket ){
3037                                 if( document.addEventListener ){
3038                                         XBrowserEvent.add = function( _ticket ){
3039                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket );
3040                                                 _ticket.element.addEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
3041                                         };
3042                                 } else
3043                                 if( document.attachEvent ){
3044                                         XBrowserEvent.add = function( _ticket ){
3045                                                 _ticket.wrappedHandler = new wrappedHandlerClass( _ticket );
3046                                                 _ticket.element.attachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
3047                                         };
3048                                 } else {
3049                                         XBrowserEvent.add = function( _ticket ){
3050                                                 var t = tmp.find( _ticket );
3051                                                 if( t !== null ){
3052                                                         t.add( _ticket );
3053                                                 } else {
3054                                                         tmp.list.push( new tmp.TicketClass( _ticket ) );
3055                                                 };
3056                                         };
3057                                 };
3058                                 
3059                                 XBrowserEvent.add( _ticket );
3060                         },
3061                         remove: function( _ticket ){
3062                                 if( document.removeEventListener ){
3063                                         XBrowserEvent.remove = function( _ticket ){
3064                                                 _ticket.element.removeEventListener( _ticket.eventType, _ticket.wrappedHandler.handler, false );
3065                                                 _ticket.wrappedHandler.destroy();
3066                                         };
3067                                 } else
3068                                 if( document.detachEvent ){
3069                                         XBrowserEvent.remove = function( _ticket ){
3070                                                 _ticket.element.detachEvent( 'on' + _ticket.eventType, _ticket.wrappedHandler.handler );
3071                                                 _ticket.wrappedHandler.destroy();
3072                                         };
3073                                 } else {
3074                                         XBrowserEvent.remove = function( _ticket ){
3075                                                 var t = tmp.find( _ticket );
3076                                                 if( t !== null ){
3077                                                         t.remove( _ticket );
3078                                                 };
3079                                         };
3080                                 };
3081                                 
3082                                 XBrowserEvent.remove( _ticket );
3083                         }
3084                 }
3085         })();
3086
3087 /*
3088  * EventTicketClass
3089  */
3090         var EventTicketClass = function( _element, _eventType, _handler, opt_thisObject ){
3091                 this.element        = _element;
3092                 this.eventType      = _eventType;
3093                 this.handler        = _handler;
3094                 this.wrappedHandler = null;
3095                 this.thisObject     = opt_thisObject;
3096                 XBrowserEvent.add( this );
3097         };
3098         EventTicketClass.prototype = {
3099                 fire : ( function(){
3100                         if( Function.prototype.call ){
3101                                 return function( e ){
3102                                         return this.handler.call( this.thisObject || this.element, e );
3103                                 };                              
3104                         };
3105                         return function( e ){
3106                                 var thisObj = this.thisObject || this.element,
3107                                         ret;
3108                                 thisObj._currentHandler = this.handler;
3109                                 ret = thisObj._currentHandler( e );
3110                                 delete thisObj._currentHandler;
3111                                 return ret;                                     
3112                         };
3113                 })(),
3114                 match: function( _element, _eventType, _handler ){
3115                         if( _handler   && _handler   !== this.handler )   return false;
3116                         if( _eventType && _eventType !== this.eventType ) return false;
3117                         if( _element   && _element   !== this.element )   return false;
3118                         
3119                         return true;
3120                 },
3121                 destroy: function( _element, _eventType, _handler ){
3122                         if( this.match( _element, _eventType, _handler ) === false ) return false;
3123                         
3124                         XBrowserEvent.remove( this );
3125                         
3126                         delete this.element;
3127                         delete this.eventType;
3128                         delete this.handler;
3129                         delete this.wrappedHandler;
3130                         delete this.thisObject;
3131                         return true;
3132                 }
3133         };
3134
3135 var ReadyEvent = ( function(){
3136         var ticketReady,
3137                 ticketLoad;
3138
3139         function webkitDetect(){
3140                 var state = document.readyState;
3141                 if( state === 'loaded' || state === 'complete' ){
3142                         SystemTimer.remove( SUPER_USER_KEY, webkitDetect );
3143                         timer = null;
3144                         onReady();
3145                 };
3146         };
3147         function ieDetect(){
3148                 if( this.readyState === 'complete' ){ // this.readyState === 'loaded' || 
3149                         this.onreadystatechange = new Function();
3150                         this.onreadystatechange = null;
3151                         AsyncCall.remove( SUPER_USER_KEY, ieScroll );
3152                         onReady();
3153                 };
3154         };
3155         function ieScroll(){
3156                 try {
3157                         document.documentElement.doScroll( 'left' );
3158                 } catch( e ){
3159                         AsyncCall.add( SUPER_USER_KEY, ieScroll );
3160                         return;
3161                 };
3162                 // no errors, fire
3163                 document.onreadystatechange = new Function();
3164                 document.onreadystatechange = null;
3165                 onReady();              
3166         };
3167                 
3168         function onReady(){
3169                 ticketReady && ticketReady.destroy();
3170                 ticketLoad  && ticketLoad.destroy();
3171                 ticketReady = ticketLoad = null;
3172                 Page.onReady();
3173                 if( Page.registered() === true ){
3174                         Page.boot();
3175                 } else {
3176                         Home.boot();
3177                 };
3178         };
3179         
3180         // Apple WebKit (Safari, OmniWeb, ...)
3181         if( document.readyState && !!UA.WEBKIT ){
3182                 SystemTimer.add( SUPER_USER_KEY, webkitDetect, 50 );
3183         /* } else
3184                 if( document.readyState && UA.isIE && UA.ieVersion < 9 ){
3185                 ieScroll();
3186                 document.onreadystatechange = ieDetect; */
3187         } else {
3188                 ticketReady = new EventTicketClass( document, 'DOMContentLoaded', onReady );
3189                 ticketLoad  = new EventTicketClass( window, 'load', onReady );
3190         };
3191 })();
3192
3193
3194
3195
3196 /* =====================================================
3197  *  ResizeEvent
3198  * 
3199  */
3200
3201 var ResizeEvent = ( function(){
3202         var _globalLock = 0;
3203         var _resize;
3204         var root = window;
3205         var w = 0, h = 0;
3206         
3207         function getInnerSize(){
3208                 return {
3209                         w : root.innerWidth || root.clientWidth,
3210                         h : root.innerHeight || root.clientHeight
3211                 };
3212         }
3213         function unlock(){
3214                 _globalLock = 0;
3215         }
3216         
3217         if( document.uniqueID ){
3218                 _resize = function(){
3219                         root = (document.compatMode || "") !== "CSS1Compat" ? document.body : document.documentElement;
3220
3221                         // resize agent
3222                         function loop(){
3223                                 if( !_globalLock++ ){
3224                                         var size = getInnerSize();
3225                                         if( w !== size.w || h !== size.h ){// resized
3226                                                 w = size.w;
3227                                                 h = size.h;
3228                                                 // update
3229                                                 Application.onWindowResize( w, h );
3230                                         }
3231                                         window.setTimeout( unlock, 0 );
3232                                         // delay unlock
3233                                 }
3234                                 window.setTimeout( loop, 100 );
3235                         }
3236                         loop();
3237                 };
3238         } else {
3239                 _resize = function(){
3240                         new EventTicketClass( window, 'resize', onResize );
3241                         
3242                         function onResize(){
3243                                 if( !_globalLock++ ) {
3244                                         var size = getInnerSize();
3245                                         if( w !== size.w || h !== size.h ){// resized
3246                                                 w = size.w;
3247                                                 h = size.h;
3248                                                 // update
3249                                                 Application.onWindowResize( w, h );
3250                                         }
3251                                         window.setTimeout( unlock, 0 );
3252                                 }
3253                         }
3254                         onResize();
3255                 };
3256         }
3257         AsyncCall.add( SUPER_USER_KEY, _resize );
3258         
3259         return {
3260                 getSize: getInnerSize,
3261                 onSystemShutdown: function(){
3262                         
3263                 }
3264         }
3265 })();
3266
3267
3268 /* =====================================================
3269  *  MouseEvent
3270  * 
3271  */
3272         var MouseEvent = ( function(){
3273                 var CLICK_OFFSET   = 2 * 2,
3274                         DRAG_OFFSET    = 4 * 4;         
3275                 
3276                 var EVENT_LIST_MAP = [],
3277                         TMP = {},
3278                         currentEventList;
3279         /*-------------------------------------
3280          * ClickHelper
3281          * mousedown, mouseup, の移動距離を調べて clickハンドラ を呼ぶ
3282          */
3283                 var ClickEventTicketClass = function( element, clickhandler, opt_thisObject ){
3284                         this.mousedownTicket = new EventTicketClass( element, 'mousedown', this.mousedownHandler, this );
3285                         this.element         = element;
3286                         this.handler         = clickhandler;
3287                         this.thisObject      = opt_thisObject;
3288                 };
3289                 ClickEventTicketClass.prototype = {
3290                         element          : null,
3291                         handler          : null,
3292                         thisObject       : null,
3293                         startX           : 0,
3294                         startY           : 0,
3295                         mousedownTicket  : null,
3296                         mousemoveTicket  : null,
3297                         mouseupTicket    : null,
3298                         mouseoutTicket   : null,
3299                         eventType        : 'click',
3300                         fire             : EventTicketClass.prototype.fire,
3301                         match            : EventTicketClass.prototype.match,
3302                         mousedownHandler : function( e ){
3303                                 this.startX = e.clientX;
3304                                 this.startY = e.clientY;
3305                                 
3306                                 this.mousemoveTicket = new EventTicketClass( this.element, 'mousemove', this.mousemoveHandler, this );
3307                                 this.mouseupTicket   = new EventTicketClass( this.element, 'mouseup',   this.mouseupHandler,   this );
3308                                 this.mouseoutTicket  = new EventTicketClass( this.element, 'mouseout',  this.mouseoutHandler,  this );
3309                                 return false;                   
3310                         },
3311                         mousemoveHandler : function( e ){
3312                                 var offsetX = e.clientX - this.startX,
3313                                         offsetY = e.clientY - this.startY;                              
3314                                 offsetX * offsetX + offsetY * offsetY >= CLICK_OFFSET && this.mouseoutHandler();
3315                                 return false;
3316                         },
3317                         mouseupHandler : function( e ){
3318                                 this.mouseoutHandler();
3319                                 return this.fire( ClickEventTicketClass.createEvent( e ) );
3320                         },
3321                         mouseoutHandler : function( e ){
3322                                 this.mousemoveTicket && this.mousemoveTicket.destroy();
3323                                 this.mouseupTicket   && this.mouseupTicket.destroy();
3324                                 this.mouseoutTicket  && this.mouseoutTicket.destroy();
3325                                 if( this.mousemoveTicket ) delete this.mousemoveTicket;
3326                                 if( this.mouseupTicket  )  delete this.mouseupTicket;
3327                                 if( this.mouseoutTicket )  delete this.mouseoutTicket;
3328                                 return false;
3329                         },
3330                         destroy : function( _element, _eventType, _handler ){
3331                                 if( this.match( _element, _eventType, _handler ) === false ) return false;
3332                                 
3333                                 this.mouseoutHandler();
3334                                 this.mousedownTicket.destroy();
3335
3336                                 delete this.element;
3337                                 delete this.handler;
3338                                 delete this.thisObject;
3339                                 delete this.mousedownTicket;    
3340                                 return true;
3341                         }
3342                 };
3343                 if( document.createEvent ){
3344                         ClickEventTicketClass.createEvent = function( e ){
3345                                 var _e = document.createEvent( 'MouseEvents' );
3346                                 _e.initMouseEvent(
3347                                         'click' , false, true, e.view, 
3348                                         e.detail, e.screenX, e.screenY, e.clientX, e.clientY, 
3349                                         e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 
3350                                         e.button, e.relatedTarget
3351                                 );
3352                                 return _e;
3353                         };                                      
3354                 } else
3355                 if( document.attachEvent ){
3356                         ClickEventTicketClass.createEvent = function( e ){
3357                                 e.type = 'click';
3358                                 return e;
3359                         };
3360                 } else {
3361                         
3362                 };
3363                 
3364         /*-------------------------------------
3365          *  WheelHelper
3366          */
3367                 var WheelEventTicketClass = ( function(){
3368                         if( UA.GECKO ){
3369                                 return function( element, wheelhandler, opt_thisObject ){
3370                                         this.wheelTicket = new EventTicketClass( element, 'DOMMouseScroll', this.onGeckoWheel, this );
3371                                         this.element     = element;
3372                                         this.handler     = wheelhandler;
3373                                         this.thisObject  = opt_thisObject;
3374                                 };
3375                         } else
3376                         if( true || UA.isIE ){
3377                                 return function( element, wheelhandler, opt_thisObject ){
3378                                         this.wheelTicket = new EventTicketClass( element, this.eventType, wheelhandler );
3379                                         this.element     = element;
3380                                         this.handler     = wheelhandler;
3381                                         this.thisObject  = opt_thisObject;
3382                                 };
3383                         } else {
3384                                 TMP.wheelHandlerList = [];
3385                                 TMP.wheelThisObjList = [];
3386                                 //TMP.wheelLegacy = undefined;
3387                                 TMP.onWheel   = function( e ){
3388                                         e = e || window.event;
3389                                         var cancel = true,
3390                                                 f = TMP.wheelLegacy;
3391                                         if( f ) cancel = f.call( this, e );
3392                                         
3393                                         for( i = TMP.wheelHandlerList.length; i; ){
3394                                                 if( TMP.wheelHandlerList[ --i ].call( TMP.wheelThisObjList[ i ] || this, e ) === false ) cancel = false;
3395                                         };
3396                                         return cancel;
3397                                 };
3398                                 return function( element, wheelhandler, opt_thisObject ){
3399                                         this.element     = element;
3400                                         this.handler     = wheelhandler;
3401                                         this.thisObject  = opt_thisObject;
3402                                         
3403                                         if( TMP.wheelHandlerList.length === 0 ){
3404                                                 //TMP.wheelLegacy     = Type.isFunction( window.onmousewheel ) === true ? window.onmousewheel : undefined;
3405                                                 element.onmousewheel = TMP.onWheel;
3406                                         };
3407                                         TMP.wheelHandlerList.push( wheelhandler );
3408                                         TMP.wheelThisObjList.push( opt_thisObject )
3409                                 };
3410                         };
3411                 })();
3412                 WheelEventTicketClass.prototype = {
3413                         eventType : 'mousewheel',
3414                         match     : EventTicketClass.prototype.match,
3415                         destroy   : function( _element, _eventType, _handler ){
3416                                 if( this.match( _element, _eventType, _handler ) === false ) return false;
3417                                 
3418                                 this.wheelTicket && this.wheelTicket.destroy();
3419                                 
3420                                 delete this.wheelTicket;
3421                                 delete this.element;
3422                                 delete this.handler;
3423                                 delete this.thisObject;
3424                                 
3425                                 this.onDestroy && this.onDestroy();
3426                                 return true;
3427                         }
3428                 };
3429                 if( UA.GECKO ){
3430                         WheelEventTicketClass.prototype.onGeckoWheel = function( e ){
3431                                 var _e = document.createEvent( 'MouseEvents' );
3432                                 _e.initMouseEvent(
3433                                         'mousewheel' , false, true, e.view, 
3434                                         e.detail, e.screenX, e.screenY, e.clientX, e.clientY, 
3435                                         e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 
3436                                         e.button, e.relatedTarget
3437                                 );
3438                                 _e.wheelDelta = e.detail * -40;
3439                                 return this.handler.call( this.thisObject || this.element, _e );
3440                         };
3441                 } else
3442                 if( true || UA.isIE ){
3443
3444                 } else {
3445                         WheelEventTicketClass.prototype.onDestroy = function(){
3446                                 TMP.wheelHandlerList.splice( Util.getIndex( TMP.wheelHandlerList, this.handler ), 1 );
3447                                 TMP.wheelThisObjList.splice( Util.getIndex( TMP.wheelThisObjList, this.handler ), 1 );
3448                                 if( TMP.wheelHandlerList.length === 0 ) this.element.onmousewheel = '';
3449                         };                      
3450                 };
3451                 
3452         /*-------------------------------------
3453          *  DragHelper
3454          */
3455                 var DragEventTicketClass = function( element, draghandler, opt_thisObject ){
3456                         this.mousedownTicket = new EventTicketClass( element, 'mousedown', this.mousedownHandler, this );
3457                         this.element         = element;
3458                         this.handler         = draghandler;
3459                         this.thisObject      = opt_thisObject;
3460                 };
3461                 DragEventTicketClass.prototype = {
3462                         element         : null,
3463                         handler         : null,
3464                         thisObject      : null,
3465                         startX          : 0,
3466                         startY          : 0,
3467                         dragging        : false,
3468                         mousedownTicket : null,
3469                         mousemoveTicket : null,
3470                         mouseupTicket   : null,
3471                         mouseoutTicket  : null,
3472                         eventType       : 'mousedrag',
3473                         fire            : EventTicketClass.prototype.fire,
3474                         match           : EventTicketClass.prototype.match,
3475                         mousedownHandler: function( e ){
3476                                 this.startX = e.clientX;
3477                                 this.startY = e.clientY;
3478                                 
3479                                 this.mousemoveTicket = new EventTicketClass( this.element, 'mousemove', this.dragMoveHandler, this );
3480                                 this.mouseupTicket   = new EventTicketClass( this.element, 'mouseup',   this.dragEndHandler,  this );
3481                                 this.mouseoutTicket  = new EventTicketClass( this.element, 'mouseout',  this.dragEndHandler,  this );                                   
3482                         
3483                                 return false;
3484                         },
3485                         dragMoveHandler : function( e ){
3486                                 var offsetX = e.clientX - this.startX,
3487                                         offsetY = e.clientY - this.startY;
3488                                 if( this.dragging === false ){
3489                                         if( offsetX * offsetX + offsetY * offsetY < DRAG_OFFSET ) return;
3490                                         console.log( 'Drag start' );
3491                                         // dragStart
3492                                         this.dragging = true;
3493                                         return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 0 ) );
3494                                 };
3495                                 return this.fire( DragEventTicketClass.createEvent( e, offsetX, offsetY, 1 ) );
3496                         },
3497                         dragEndHandler  : function( e ){
3498                                 if( this.dragging === true ){
3499                                         console.log( 'Drag End ' + e.type );
3500                                         this.removeEvents();
3501                                         // dragEnd
3502                                         return this.fire( DragEventTicketClass.createEvent( e, e.clientX - this.startX, e.clientY - this.startY, 2 ) );
3503                                 };
3504                                 this.removeEvents();
3505                                 return false;
3506                         },
3507                         removeEvents : function(){
3508                                 this.dragging = false;
3509                                 if( this.mousemoveTicket ){
3510                                         this.mousemoveTicket.destroy();
3511                                         delete this.mousemoveTicket;
3512                                 };
3513                                 if( this.mouseupTicket ){
3514                                         this.mouseupTicket.destroy();
3515                                         delete this.mouseupTicket;
3516                                 };
3517                                 if( this.mouseoutTicke ){
3518                                         this.mouseoutTicket.destroy();
3519                                         delete this.mouseoutTicket;
3520                                 };                              
3521                         },
3522                         destroy : function( _element, _eventType, _handler ){
3523                                 if( this.match( _element, _eventType, _handler ) === false ) return false;
3524                                 
3525                                 this.removeEvents();
3526                                 this.mousedownTicket.destroy();
3527
3528                                 delete this.element;
3529                                 delete this.handler;
3530                                 delete this.thisObject;
3531                                 delete this.mousedownTicket;    
3532                                 return true;
3533                         }
3534                 };
3535                 if( document.createEvent ){
3536                         DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){
3537                                 var _e = document.createEvent( 'MouseEvents' );
3538                                 _e.initMouseEvent(
3539                                         DragEventTicketClass.prototype.eventType , false, true, e.view, 
3540                                         e.detail, e.screenX, e.screenY, e.clientX, e.clientY, 
3541                                         e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 
3542                                         e.button, e.relatedTarget
3543                                 );
3544                                 _e.dragPhase   = dragPhase;
3545                                 _e.dragOffsetX = offsetX;
3546                                 _e.dragOffsetY = offsetY;
3547                                 return _e;
3548                         };                                      
3549                 } else
3550                 if( document.attachEvent ){
3551                         DragEventTicketClass.createEvent = function( e, offsetX, offsetY, dragPhase ){
3552                                 e.type        = DragEventTicketClass.prototype.eventType;
3553                                 e.dragPhase   = dragPhase;
3554                                 e.dragOffsetX = offsetX;
3555                                 e.dragOffsetY = offsetY;
3556                                 return e;
3557                         };
3558                 } else {
3559                         
3560                 };
3561
3562                 return {
3563                         add: function( _apiuser, _element, _eventType, _handler, opt_thisObject ){
3564                                 if( isApiUser( _apiuser ) === true &&
3565                                         ( Type.isHTMLElement( _element ) === true || _element === window || _element === document ) &&
3566                                         Type.isString( _eventType ) === true &&
3567                                         Type.isFunction( _handler ) === true
3568                                 ){
3569                                         var _uid    = _apiuser.getUID(),
3570                                                 _events = EVENT_LIST_MAP[ _uid ];
3571                                         if( Type.isArray( _events ) === false ){
3572                                                 _events = EVENT_LIST_MAP[ _uid ] = [];
3573                                         } else {
3574                                                 // 2重登録の禁止
3575                                                 for( var i=0, l=_events.length; i<l; ++i ){
3576                                                         if( _events[ i ].match( _element, _eventType, _handler ) === true ) return;
3577                                                 };
3578                                         };
3579                                         switch( _eventType ){
3580                                                 case 'click':
3581                                                         _events.push( new ClickEventTicketClass( _element, _handler, opt_thisObject ) );
3582                                                         break;
3583                                                 case 'mousewheel':
3584                                                         _events.push( new WheelEventTicketClass( _element, _handler, opt_thisObject ) );
3585                                                         break;
3586                                                 case 'mousedrag':
3587                                                         _events.push( new DragEventTicketClass( _element, _handler, opt_thisObject ) );
3588                                                         break;
3589                                                 default:
3590                                                         _events.push( new EventTicketClass( _element, _eventType, _handler, opt_thisObject ) );
3591                                         };
3592                                 };
3593                         },
3594                         remove: function( apiuser, element, eventType, handler ){
3595                                 if( isApiUser( apiuser ) === true ){
3596                                         var uid  = apiuser.getUID(),
3597                                                 list = EVENT_LIST_MAP[ uid ],
3598                                                 i    = 0;
3599                                         if( Type.isArray( list ) === false ) return;
3600                                         for( ;i < list.length; ){
3601                                                 if( list[ i ].destroy( element, eventType, handler ) === true ){
3602                                                         list.splice( i, 1 );
3603                                                 } else {
3604                                                         ++i;
3605                                                 };
3606                                         };
3607                                         if( list.length === 0 ){
3608                                                 EVENT_LIST_MAP[ uid ] = null;
3609                                         };
3610                                 };
3611                         },
3612                         onCurrentApplicationChange: function(){
3613                                 
3614                         },
3615                         onApplicationShutdown: function(){
3616                                 
3617                         },
3618                         onSystemShutdown: function(){
3619                                 
3620                         }
3621                 }
3622         })();
3623
3624 /* ----------------------------------------
3625  * KEY
3626  * 
3627  *  - EDITABLE_TEXT_CONTROL
3628  * 
3629  *    .SHIFT_DOWN_EVENT:        'shiftDown',
3630  *    .SHIFT_UP_EVENT:          'shiftUp',
3631  *    .CTRL_DOWN_EVENT:         'ctrlDown',
3632  *    .CTRL_UP_EVENT:           'ctrlUp',
3633  *    .SPACE_DOWN_EVENT:        'spaceDown',
3634  *    .SPACE_UP_EVENT:          'spaceUp',
3635  *    .init:                            function,
3636  *    .addKeyDownEvent:         function,
3637  *    .keyEventDispatcher:      function,
3638  * 
3639  * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。
3640  * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。
3641  * 
3642  */
3643 var KeyEvent = ( function(){
3644         var EVENT_LIST_MAP = [],
3645                 LOCK_UP        = [],
3646                 LOCK_DOWN      = [],
3647                 application    = null,
3648                 currentList    = null;
3649
3650         window.focus();
3651         
3652         var focusTicket    = null,
3653                 keydownTicket  = null,
3654                 keyupTicket    = null,
3655                 keyPress       = null,
3656                 keypressTicket = null;
3657         
3658         function unlock( lock, key ){
3659                 lock.splice( Util.getIndex( lock, key ), 1 );
3660         };
3661         
3662         function onKeyChange( e ){
3663                 var cancel         = false,
3664                         type           = e.type,
3665                         key            = e.keyCode, // || e.which,
3666                         shift          = Type.isBoolean( e.shiftKey ) === true ? e.shiftKey : ( e.modifiers & Event.SHIFT_MASK ),
3667                         ctrl           = Type.isBoolean( e.ctrlKey  ) === true ? e.ctrlKey  : ( e.modifiers & Event.CONTROL_MASK ),
3668                         lock           = type === 'keyup' ? LOCK_UP : LOCK_DOWN,
3669                         i, t;
3670                         
3671                 // block chattering
3672                 if( Util.getIndex( lock, key ) !== -1 ) return;
3673                 lock.push( key );
3674                 AsyncCall.add( SUPER_USER_KEY, unlock, [ lock, key ] );
3675                 
3676                 if( key === 16 || shift === true ){
3677                         KeyEvent.shiftEnabled = type !== 'keyup';
3678                 };
3679                 if( key === 17 || ctrl === true ){
3680                         KeyEvent.ctrlEnabled  = type !== 'keyup';
3681                 };
3682                 for( i = currentList.length; i; ){
3683                         t = currentList[ --i ];
3684                         if( Type.isFunction( t[ type ] ) === true && t.keyCode === key && ( t.shift === undefined || t.shift === shift ) && ( t.ctrl === undefined || t.ctrl === ctrl )){
3685                                 if( t[ type ].call( t.apiuser, e ) === false ){
3686                                         cancel = true;
3687                                         break;
3688                                 };
3689                         };
3690                 };
3691                 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true ){ // 13.enter 18.esc 9.tab 27.esc   || ( key === 13 && overlayEnabled === false)
3692                         return false;
3693                 };
3694         };
3695         
3696         if( UA.isIE === true && UA.ieRenderingVersion < 9 ){
3697                 keyPress = function( e ){
3698                         var key = e.keyCode;
3699                         if( key === 13 || key === 27 ){
3700                                 e.type = 'keydown';
3701                                 return onKeyChange( e );
3702                         };
3703                 };
3704         };
3705         
3706         var KeyEventTicketClass = function( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
3707                 this.apiuser = _apiuser;
3708                 this.type    = _type;
3709                 this.keydown = _onKeydown;
3710                 this.keyup   = _onKeyup;                
3711                 this.keyCode = _keyCode;
3712                 this.shift   = _shift;
3713                 this.ctrl    = _ctrl;
3714                 _apiuser = _onKeydown = _onKeyup = null;
3715         }
3716         KeyEventTicketClass.prototype = {
3717                 match: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
3718                         if( _apiuser  && _apiuser  !== this.apiuser ) return false;
3719                         if( _type     && _type     !== this.type )    return false;
3720                         if( _handler ){
3721                                 if( this.type === 'keydown' ){
3722                                         if( _handler !== this.keydown ) return false;
3723                                 } else {
3724                                         if( _handler !== this.keyup )   return false;
3725                                 };
3726                         };
3727                         if( _keyCode  && _keyCode  !== this.keyCode ) return false;
3728                         if( _shift    && _shift    !== this.shift )   return false;
3729                         if( _ctrl     && _ctrl     !== this.ctrl )    return false;
3730                         return true;
3731                 },
3732                 destroy: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
3733                         if( this.match( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === false ) return false;
3734                         
3735                         delete this.apiuser;
3736                         delete this.keydown;
3737                         delete this.keyup;
3738                         
3739                         return true;
3740                 }
3741         };
3742         
3743         function registerEvent( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ){
3744                 var _uid  = _apiuser.getUID(),
3745                         _list = EVENT_LIST_MAP[ _uid ];
3746                 if( Type.isArray( _list ) === false ){
3747                         _list = EVENT_LIST_MAP[ _uid ] = [];
3748                 }
3749                 for( var i=0, l=_list.length; i<l; ++i ){
3750                         if( _list[ i ].match( _apiuser, _type, _onKeydown || _onKeyup, _keyCode, _shift, _ctrl ) === true ) return;
3751                 }
3752                 _list.push( new KeyEventTicketClass( _apiuser, _type, _onKeydown, _onKeyup, _keyCode, _shift, _ctrl ));
3753                 
3754                 if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
3755         };
3756         
3757         return {
3758                 add: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
3759                         if( _type === 'keydown' ){
3760                                 registerEvent( _apiuser, _type, _handler, null, _keyCode, _shift, _ctrl );
3761                         } else
3762                         if( _type === 'keyup' ){
3763                                 registerEvent( _apiuser, _type, null, _handler, _keyCode, _shift, _ctrl );
3764                         } else
3765                         if( _type === 'keychange' ){
3766                                 registerEvent( _apiuser, _type, _handler, _handler, _keyCode, _shift, _ctrl );
3767                         } else
3768                         if( _type === 'cursol' ){
3769                                 
3770                         };
3771                 },
3772                 remove: function( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ){
3773                         var _list = EVENT_LIST_MAP[ _apiuser.getUID() ],
3774                                 i = 0;
3775                         if( Type.isArray( _list ) === true ){
3776                                 while( i < _list.length ){
3777                                         if( _list[ i ].destroy( _apiuser, _type, _handler, _keyCode, _shift, _ctrl ) === true ){
3778                                                 _list.splice( i, 1 );
3779                                         } else {
3780                                                 ++i;
3781                                         }
3782                                 }
3783                         }
3784                         if( _apiuser === application ) KeyEvent.updateCurrentListener( _apiuser );
3785                 },
3786                 shiftEnabled: false,
3787                 ctrlEnabled:  false,
3788                 /*
3789                  * currentListener
3790                  *  currrentApplication ( overlay Application ) or
3791                  *  superuser ( UI )
3792                  */
3793                 updateCurrentListener: function( _apiuser ){
3794                         application = _apiuser;
3795                         var _uid    = _apiuser.getUID();
3796                         currentList = EVENT_LIST_MAP[ _uid ] || ( EVENT_LIST_MAP[ _uid ] = [] );
3797                         
3798                         var _ticket,
3799                                 _down = false,
3800                                 _up   = false;
3801                         for( var i=currentList.length; _ticket = currentList[ --i ]; ){
3802                                 if( _down === false ) _down = !!_ticket.keydown;
3803                                 if( _up   === false ) _up   = !!_ticket.keyup;
3804                                 if( _down && _up ) break;
3805                         }
3806                         if( _down === true ){
3807                                 keydownTicket = new EventTicketClass( document, 'keydown', onKeyChange );
3808                                 keypressTicket = keyPress !== null ? new EventTicketClass( document, 'keypress', keyPress ) : null;
3809                         } else {
3810                                 keydownTicket && keydownTicket.destroy();
3811                                 keypressTicket && keypressTicket.destroy();
3812                                 keydownTicket = keypressTicket = null;
3813                         }
3814                         if( _up === true ){
3815                                 keyupTicket   = new EventTicketClass( document, 'keyup', onKeyChange );
3816                         } else {
3817                                 keyupTicket && keyupTicket.destroy();
3818                                 keyupTicket = null;
3819                         }
3820                         
3821                         if( _down === true || _up === true ){
3822                                 focusTicket   = new EventTicketClass( document, 'mouseenter', window.focus );
3823                         } else {
3824                                 focusTicket && focusTicket.destroy();
3825                                 focusTicket = null;
3826                         }
3827                 },
3828                 onApplicationShutdown: function( _apiuser ){
3829                         KeyEvent.remove( _apiuser );
3830                 },
3831                 onSystemShutdown: function(){
3832                         
3833                 }
3834         }
3835 })();
3836
3837 /**
3838  * 
3839  * http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof
3840  */
3841
3842 var StyleSheet = ( function(){
3843         var head = document.getElementsByTagName( 'head' )[ 0 ];
3844         
3845         var TICKET_LIST = [];
3846         var STATE_LIST  = 'loaded,complete,uninitialized'.split( ',' );
3847         
3848         var cssRules, sheet;
3849         
3850         var FetchCssTicketClass = function( _apiuser, _url, _elm, _onload, _onerror, opt_thisObject ){
3851                 this.apiusers = [ _apiuser ];
3852                 this.url      = _url;
3853                 this.elm      = _elm;
3854                 this.onload   = [ _onload ];
3855                 this.onerror  = [ _onerror ];
3856                 this.thisObj  = [ opt_thisObject ];
3857                 this.time     = 0;
3858         };
3859         FetchCssTicketClass.prototype = {
3860                 match: function( _apiuser, _url ){
3861                         if( _apiuser  && Util.getIndex( this.apiusers, _apiuser ) === -1 ) return false;
3862                         if( _url      && _url      !== this.url     ) return false;
3863                         return true;
3864                 },
3865                 destroy: function( _apiuser, _url ){
3866                         if( this.match( _apiuser, _url ) === false ) return false;
3867                         
3868                         var i = Util.getIndex( this.apiusers, _apiuser );
3869                         
3870                         this.apiusers.splice( i, 1 );
3871                         this.onload.splice( i, 1 );
3872                         this.onerror.splice( i, 1 );
3873                         this.thisObj.splice( i, 1 );
3874                         
3875                         if( this.apiusers.length !== 0 ) return false;
3876                         
3877                         head.removeChild( this.elm );
3878                         this.elm.onreadystatechange = new Function();
3879                         this.elm.onload = null;
3880                         
3881                         delete this.apiusers;
3882                         delete this.url;
3883                         delete this.elm;
3884                         delete this.onload;
3885                         delete this.onerror;
3886                         delete this.thisObj;
3887                         delete this.time;
3888                         
3889                         return true;
3890                 },
3891                 loaded: function(){
3892                 for( var i = this.onload.length, f; i; ){
3893                         f = this.onload[ --i ];
3894                         Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url, this.thisObj[ i ] || this.apiusers[ i ] );
3895                         this.onload[ i ] = this.onerror[ i ] = null;
3896                 };
3897                 },
3898                 error: function(){
3899                 for( var i = this.onerror.length, f; i; ){
3900                         f = this.onerror[ --i ];
3901                         Type.isFunction( f ) === true && AsyncCall.add( this.apiusers[ i ], f, this.url, this.thisObj[ i ] || this.apiusers[ i ] );
3902                         this.onload[ i ] = this.onerror[ i ] = null;
3903                 };
3904                 },
3905                 check: function(){
3906                         var el = this.elm;
3907                         try {
3908                                 return el[ sheet ] && el[ sheet ][ cssRules ].length > 0;
3909                         } catch( e ){
3910                                 return false;
3911                         };
3912                 },
3913                 done: false
3914         };
3915         
3916         function getTicket( elm ){
3917                 for( var i = TICKET_LIST.length, t; i; ){
3918                         t = TICKET_LIST[ --i ];
3919                         if( t.elm === elm ) return t;
3920                 };
3921         };
3922         
3923         function detect(){
3924                 var t = getTicket( this ), rs = this.readyState, c;
3925                 if( t && t.done === false && ( !rs || Util.getIndex( STATE_LIST, rs ) !== -1 ) ){
3926                         t.done = true;
3927                 t.loaded();
3928                 this.onreadystatechange = new Function();
3929                 this.onload = null;
3930                 };
3931         };
3932         
3933         function checkTimer(){
3934                 var l = TICKET_LIST.length,
3935                         n = 0;
3936                 for( var i = 0; i < l; ++i ){
3937                         t = TICKET_LIST[ i ];
3938                         ++t.time;
3939                         if( t.check() === true ){
3940                                 t.loaded();
3941                                 ++n;
3942                         } else
3943                         if( t.time > 99 ){
3944                                 t.error();
3945                         } else {
3946                                 
3947                         };
3948                 };
3949                 l === n && SystemTimer.remove( SUPER_USER_KEY, checkTimer );
3950         };
3951         
3952         return {
3953                 load: function( _apiuser, _url, opt_onload, opt_onerror, opt_thisObject ){
3954                         _url = Util.getAbsolutePath( _url );
3955                         var t;
3956                         for( var i=TICKET_LIST.length; i; ){
3957                                 t = TICKET_LIST[ --i ];
3958                                 if( t.match( null, _url ) === true ){
3959                                         if( t.match( _apiuser, _url ) === false ){
3960                                                 t.apiusers.push( _apiuser );
3961                                                 t.onload.push( opt_onload );
3962                                                 t.onerror.push( opt_onerror );
3963                                                 t.thisObj.push( opt_thisObject );
3964                                         };
3965                                         SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );
3966                                         return;
3967                                 };
3968                         };
3969                         var elm = document.createElement( 'link' );
3970                         head.appendChild( elm );
3971                         elm.rel  = 'stylesheet';
3972                         elm.type = 'text\/css';
3973                         elm.onreadystatechange = elm.onload = detect;
3974                         elm.href = _url;
3975                         
3976                         if( !sheet ){ // only assign these once
3977                                 cssRules = 'cssRules';
3978                                 sheet    = 'sheet';
3979                                 if ( !( sheet in elm ) ) { // MSIE uses non-standard property names
3980                                         cssRules = 'rules';
3981                                         sheet    = 'styleSheet';
3982                                 };
3983                         };
3984                         
3985                         TICKET_LIST.push( new FetchCssTicketClass( _apiuser, _url, elm, opt_onload, opt_onerror, opt_thisObject ) );
3986                         
3987                         SystemTimer.add( SUPER_USER_KEY, checkTimer, 333 );
3988                 },
3989                 unload: function( _apiuser, _url ){
3990                         _url = _url ? Util.getAbsolutePath( _url ) : null;
3991                         for( var i = 0; i < TICKET_LIST.length; ){
3992                                 t = TICKET_LIST[ i ];
3993                                 if( t.destroy( _apiuser, _url ) === true ){
3994                                         TICKET_LIST.splice( i, 1 );
3995                                 } else {
3996                                         ++i;
3997                                 }
3998                         };
3999                         if( TICKET_LIST.length === 0 ){
4000                                 SystemTimer.remove( SUPER_USER_KEY, checkTimer );
4001                         }
4002                 }
4003         }
4004 })();
4005
4006 /*
4007  * AssetLoader
4008  * fetchCSS
4009  * fetchJson
4010  * fetchHtml
4011  * fetchImage
4012  * fetchLocalFile
4013  * fetchLocalStorage
4014  */
4015
4016 var Image = ( function(){
4017         var TASK_LIST = [];
4018         /* 
4019          * FetchClass original is
4020          * 
4021          * LICENSE: MIT?
4022          *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631
4023          *  AUTHOR: uupaa.js@gmail.com
4024          * 
4025          */
4026         function detect(){
4027                 for( var i=0, t; i < TASK_LIST.length; ){
4028                         t = TASK_LIST[ i ];
4029                         if( t.complete() === true ){
4030                                 TASK_LIST.splice( i, 1 );
4031                         } else {
4032                                 ++i;
4033                         };
4034                 };
4035                 TASK_LIST.length === 0 && SystemTimer.remove( SUPER_USER_KEY, detect );
4036         };
4037         function getTask( img ){
4038                 for( var i = TASK_LIST.length; i; ){
4039                         if( TASK_LIST[ --i ].img === img ) return TASK_LIST[ i ];
4040                 };
4041         };
4042         function onError(){
4043                 var task = getTask( this );
4044                 if( task.finish === true ) return;
4045                 task.finish = true;
4046                 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
4047         };
4048         function onLoad(){
4049                 // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、
4050                 // if( timer ) return; // これがあると safari3.2 で駄目、、、
4051                 var task = getTask( this );
4052                 task.finish = true;
4053                 TASK_LIST.splice( Util.getIndex( TASK_LIST, task ), 1 );
4054                 if( window.opera && !task.img.complete ){
4055                         AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
4056                         return;
4057                 };
4058                 task.size = Util.getImageSize( this );
4059                 AsyncCall.add( task.apiuser, task.asyncCallback, null, task );
4060         };
4061
4062
4063         var FetchClass = function( apiuser, abspath, onLoadCallback, onErrorCallback, timeout ){
4064                 this.apiuser         = apiuser;
4065                 this.abspath         = abspath;
4066                 this.onLoadCallback  = onLoadCallback;
4067                 this.onErrorCallback = onErrorCallback;
4068                 this.timeout         = timeout;
4069                 this.tick            = 0;
4070         };
4071         FetchClass.prototype = {
4072                 img: null,
4073                 size: null,
4074                 tick: 0,
4075                 finish: false,
4076                 load: function(){
4077                         var img     = this.img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る
4078                         img.onabort = img.onerror = onError;
4079                         img.onload  = onLoad;
4080                         img.src     = this.abspath;
4081                 },
4082                 complete: function(){
4083                         if( this.finish === true ) return true;
4084                         if( this.img.complete ){
4085                                 this.finish = true;
4086                                 if( this.img.width ) return true;
4087                                 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );
4088                                 return true;
4089                         };
4090                         if( ( this.tick += 250 ) > this.timeout ){
4091                                 this.finish = true;
4092                                 AsyncCall.add( this.apiuser, this.asyncCallback, null, this );
4093                                 return true;
4094                         };
4095                 },
4096                 asyncCallback: function(){
4097                         this.size ? this.onLoadCallback( this.abspath, this.size.width, this.size.height ) : this.onErrorCallback( this.abspath );
4098                         this.destroy();
4099                 },
4100                 destroy: function(){
4101                         this.finish  = true;
4102                         this.img.src = this.img.onload = this.img.onabort = this.img.onerror = '';
4103                         delete this.img;
4104                         delete this.size;
4105                         delete this.onLoadCallback;
4106                         delete this.onErrorCallback;
4107                 },
4108                 stop: function(){
4109                         timer !== null && window.clearTimeout( timer );
4110                         destroy();
4111                 }
4112         };
4113         
4114         return {
4115                 load: function( URLorELM, onLoad, onError, opt_timeout ){
4116                         var src, fetch;
4117                         if( Type.isString( URLorELM ) === true ){
4118                                 src = URLorELM;
4119                         } else
4120                         if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){
4121                                 src = URLorELM.src;
4122                         } else {
4123                                 return;
4124                         };
4125                         
4126                         fetch = new FetchClass(
4127                                 Util.getAbsolutePath( src ),
4128                                 onLoad, onError,
4129                                 Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined
4130                         );
4131                         TASK_LIST.push( fetch );
4132                         
4133                         SystemTimer.add( SUPER_USER_KEY, detect, 250 );
4134                 },
4135                 unload: function(  ){
4136                         
4137                 }
4138         };
4139 })();
4140
4141
4142 /* ----------------------------------------
4143  * 
4144  */
4145
4146 var Overlay = ( function(){
4147         var elmContainer, elmShadow, elmCloseButton,
4148                 bootParams,
4149                 application    = null,
4150                 visible        = false,
4151                 bodyOverflow   = '',
4152                 windowW, windowH;
4153
4154         function onCloseClick( e ){
4155                 Overlay.hide();
4156                 return false;
4157         };
4158         function asyncInit( /* arguments */ ){
4159                 application.init();
4160                 //application.rootElement.style.display = 'none';
4161                 
4162                 elmContainer.style.cssText = "top:" + body.scrollTop + 'px;display:none;';
4163                 $( elmContainer ).stop().fadeIn( onFadeInComplete );            
4164         };
4165         function asyncOpen( /* arguments */ ){
4166
4167                 
4168                 
4169         };
4170         function onFadeInComplete(){
4171                 KeyEvent.add( application, Const.KEY.EVENT.KEY_DOWN, Overlay.hide, 27 ); // 27.esc
4172                 MouseEvent.add( application, elmCloseButton, 'click', onCloseClick );
4173                 
4174                 var _arg = bootParams; //Util.copyArray( arguments );
4175                 _arg.unshift( windowW, windowH );
4176                 application.open.apply( application, _arg );            
4177         };
4178         function onFadeOutComplete(){   
4179                 Util.removeAllChildren( elmContainer );
4180                 body.removeChild( elmContainer );
4181                 elmContainer = elmShadow = elmCloseButton = null;
4182         };
4183         return {
4184                 show: function( _application, _bootParams ){
4185                         if( visible === true && application === _application ) return;
4186                         if( Application.isApplicationInstance( _application ) === false ) return;
4187                         
4188                         elmContainer = document.createElement( 'div' );
4189                         body.appendChild( elmContainer );
4190                         
4191                         elmContainer.id = 'overlay-container';
4192                         
4193                         bodyOverflow        = body.style.overflow;
4194                         body.style.overflow = 'hidden';
4195                         
4196                         elmShadow = document.createElement( 'div' );
4197                         elmContainer.appendChild( elmShadow );
4198                         elmShadow.id = 'overlay-shadow';
4199                         
4200                         elmCloseButton  = document.createElement( 'div' );
4201                         elmContainer.appendChild( elmCloseButton );
4202                         elmCloseButton.id = 'overlay-close-button';
4203                         elmCloseButton.appendChild( document.createTextNode( 'x' ) );
4204                         
4205                         elmContainer.style.display = 'none'; // hide for fadeIn
4206                         
4207                         visible     = true;
4208                         application = _application;
4209                         
4210                         //asyncInit();
4211                         elmContainer.insertBefore( application.rootElement, elmCloseButton );
4212                         _application.addAsyncCall( asyncInit );
4213                         // _application.addAsyncCall( asyncOpen,  );
4214                         
4215                         bootParams = _bootParams;                       
4216                 },
4217                 hide: function(){
4218                         if( visible === false ) return;
4219                         if( application.close() === false ) return false;
4220                         
4221                         body.style.overflow = bodyOverflow;
4222                         
4223                         $( elmContainer ).stop().css( {
4224                                 filter:         '',
4225                                 opacity:        ''
4226                         }).fadeOut( onFadeOutComplete );
4227                         visible = false;
4228                         
4229                         application = null;
4230                 },
4231                 onWindowResize: function( _windowW, _windowH ){
4232                         windowW = _windowW;
4233                         windowH = _windowH;                     
4234                         
4235                         if( application === null ) return;
4236                         
4237                         elmContainer.style.height = _windowH + 'px';
4238                         elmContainer.style.top    = body.scrollTop + 'px';
4239
4240                         elmShadow.style.height = _windowH + 'px';
4241
4242                         AsyncCall.add( application, application.resize, [ _windowW, _windowH ] );
4243                 }
4244         }
4245 })();
4246
4247 /* ----------------------------------------
4248  * UI
4249  * 
4250  * keyEventRellay
4251  *  form -> overlay -> view
4252  * 
4253  */
4254
4255 var UI = ( function(){
4256         var UI_LIST     = [],
4257                 currentUser = null,
4258                 currentList = null,
4259                 currentUi   = null,
4260                 currentItem = null,
4261                 windowW     = 0,
4262                 windowH     = 0;
4263
4264         var CLASSNAME_COMBOBOX_OPTION = 'combobox-option',
4265                 CLASSNAME_COMBOBOX_OPTION_CURRENT = CLASSNAME_COMBOBOX_OPTION + ' combobox-option-current',
4266                 ELM_COMBOBOX = ( function(){
4267                         var ret       = document.createElement( 'a' ),
4268                                 elmToggle = document.createElement( 'span' ),
4269                                 elmValue  = document.createElement( 'span' );
4270                         ret.href = '#';
4271                         ret.appendChild( elmToggle );
4272                         ret.appendChild( elmValue );
4273                         elmToggle.className = 'combobox-toggle';
4274                         elmValue.className  = 'combobox-value';
4275                         
4276                         elmToggle.appendChild( document.createTextNode( '▼' ));
4277                         elmValue.appendChild( document.createTextNode( 'null' ));
4278                         return ret;
4279                 })();
4280         
4281         var UIItemPrivateData = function(){};
4282         UIItemPrivateData.prototype = {
4283                 groupData   : null,
4284                 item        : null,
4285                 elm         : null,
4286                 node        : null,
4287                 focus       : false,
4288                 visible     : true,
4289                 enabled     : true,
4290                 value       : null,
4291                 onUpdate    : null,
4292                 validator   : null,
4293                 elmValue    : null,
4294                 elmBox      : null,
4295                 elmA        : null,
4296                 elmToggle   : null,
4297                 elmValue    : null,
4298                 selectIndex : 0,
4299                 optionList  : null,
4300                 init    : function( groupData, item, elm, value, onUpdate, validator, focus, visible, enabled ){
4301                         this.groupData = groupData;
4302                         this.item      = item;
4303                         this.elm       = elm;
4304                         this.value     = value;
4305                         this.onUpdate  = onUpdate;
4306                         this.validator = validator;                     
4307                         this.focus     = !!focus;
4308                         this.visible   = !!visible;
4309                         this.enabled   = !!enabled;
4310                         UIItemPrivateData.list.push( this );
4311                 },
4312                 destroy : function(){
4313                         var list = UIItemPrivateData.list;
4314                         list.splice( Util.getIndex( list, this ), 1 );
4315                         
4316                         list = this.groupData.itemList;
4317                         var i = Util.getIndex( list, this.item );
4318                         i !== -1 && list.splice( i, 1 );
4319                         
4320                         this.node && this.node.remove();
4321                 }
4322         };
4323         UIItemPrivateData.list = [];
4324         UIItemPrivateData.get = function( item ){
4325                 var list = UIItemPrivateData.list;
4326                 for( i = list.length; i; ){
4327                         if( list[ --i ].item === item ) return list[ i ];
4328                 };
4329                 return null;
4330         };
4331         
4332 /* --------------------------------
4333  * TextInputManager
4334  */
4335         var TextInputManager = ( function(){
4336                 var elmInput = ( function(){
4337                         var ret  = document.createElement( 'input' );
4338                         ret.type = 'text';
4339                         ret.id   = 'ui-textinput';
4340                         return ret;
4341                 })();
4342                 var currentData;
4343                 
4344                 function updateWrapperPosition(){
4345                         var p = Position.cumulativeOffset( currentData.elmValue ),
4346                                 w = currentData.elmValue.offsetWidth - 2,
4347                                 _w;             
4348                         elmInput.style.cssText = [
4349                                 'left:',   p[ 0 ], 'px;',
4350                                 'top:',    p[ 1 ], 'px;',//,
4351                                 'width:',  w, 'px;'//,
4352                                 //'height:', data.elmValue.offsetHeight, 'px;',
4353                                 //'position:absolute;'
4354                         ].join( '' );
4355                         
4356                         //_w = elmInput.offsetWidth;
4357                         //if( w !== _w ) elmInput.style.width = ( w - ( _w - w ) ) + 'px;';     
4358                 };
4359                 
4360                 return {
4361                         show: function( data ){
4362                                 // this.groupData.node.addEventListener( 'mouseout' );
4363                                 currentData = data;
4364
4365                                 body.appendChild( elmInput );
4366                                 elmInput.value = data.value;
4367                                 updateWrapperPosition();
4368                                 
4369                                 elmInput.focus();
4370                                 elmInput.select();
4371                                 
4372                                 SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 );
4373                         },
4374                         hide : function( data ){
4375                                 if( currentData !== data ) return;
4376                                 currentData = null;
4377                                 body.removeChild( elmInput );
4378                                 var ret = elmInput.value;
4379                                 elmInput.value = '';
4380                                 SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition );
4381                                 return ret;
4382                         },
4383                         update : function( data ){
4384                                 elmInput.value = data.value;
4385                         },
4386                         onWindowResize: function( _w, _h ){
4387                                 AsyncCall.add( currentUser, updateWrapperPosition );
4388                         }
4389                 };
4390         })();
4391         
4392         var TextInputClass = function( groupData, elmWrapper, elmValue, onUpdate, validater ){
4393                 var data = new UIItemPrivateData();
4394                 data.init( groupData, this, elmWrapper, elmValue.innerHTML, onUpdate, validater, false, true, true );
4395                 Util.addClass( elmValue, 'editable-text' );
4396                 data.elmValue = elmValue;
4397                 this.value( data.value );
4398                 data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-inpittext-hover', 'pointer' );
4399                 data.node.addEventListener( 'click', this.focus, this );
4400                 //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', instance.focus );
4401         };
4402         TextInputClass.prototype = {
4403                 value : function( value ){
4404                         var data = UIItemPrivateData.get( this );
4405                         if( Type.isString( value ) === true || Type.isNumber( value ) === true ){
4406                                 data.elmValue.innerHTML = data.value = '' + value;
4407                                 data.focus === true && TextInputManager.update( data );
4408                         };
4409                         data.focus === true && this.blur();
4410                         return data.value;
4411                 },
4412                 focus : function( e ){
4413                         var data = UIItemPrivateData.get( this );
4414                         data.focus = true;
4415                         start( data );
4416                         TextInputManager.show( data );
4417                         return false;
4418                 },
4419                 blur : function( keep ){
4420                         var data = UIItemPrivateData.get( this ),
4421                                 newValue;
4422                         if( data.focus === false ) return;
4423                         newValue = TextInputManager.hide( data );
4424                         newValue = keep !== 27 ? ( data.validater ? '' + data.validater( newValue ) : newValue ) : data.value; // 27:ESC
4425
4426                         data.elmValue.innerHTML = newValue;
4427                         
4428                         data.onUpdate && newValue !== data.value && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ newValue, data.value ], this );
4429                         
4430                         data.value = newValue;
4431                         data.focus = false;
4432                         finish( data );
4433                 },
4434                 enabled : function( v ){
4435                         var data = UIItemPrivateData.get( this );
4436                         if( Type.isBoolean( v ) === true && data.enabled !== v ){
4437                                 Util.toggleClass( data.elm, 'ui-textinput-disabled', !v );
4438                                 if( data.focus === true && v === false ) this.blur();
4439                                 data.enabled = v;
4440                                 data.node.disabled( !( data.visible && v ) );
4441                         };
4442                         return data.enabled;
4443                 },
4444                 visible : function( v ){
4445                         var data = UIItemPrivateData.get( this );
4446                         if( Type.isBoolean( v ) === true && data.visible !== v ){
4447                                 data.elm.style.display = v ? '' : 'none';
4448                                 if( data.focus === true && v === false ) this.blur();
4449                                 data.visible = v;
4450                                 data.node.disabled( !( data.enabled && v ) );
4451                         };
4452                         return data.visible;
4453                 },
4454                 destroy : function(){
4455                         var data = UIItemPrivateData.get( this );
4456                         data.focus === true && TextInputManager.hide( data );
4457                         data.destroy();
4458                 }
4459         };
4460
4461 /* --------------------------------
4462  * TextInputManager
4463  */
4464         var FileInputManager = ( function(){
4465                 var currentData,
4466                         elmForm,
4467                         elmFileInput,
4468                         elmWrap,
4469                         evt;
4470                 
4471                 function updateWrapperPosition(){
4472                         var p = Position.cumulativeOffset( currentData.elmValue ),
4473                                 w = currentData.elmValue.offsetWidth,
4474                                 _w;             
4475                         elmWrap.style.cssText = [
4476                                 'left:',   p[ 0 ], 'px;',
4477                                 'top:',    p[ 1 ], 'px;',//,
4478                                 'width:',  w, 'px;'//,
4479                                 //'height:', data.elmValue.offsetHeight, 'px;',
4480                                 //'position:absolute;'
4481                         ].join( '' );
4482                         
4483                         _w = elmWrap.offsetWidth;
4484                         if( w !== _w ) elmWrap.style.width = ( w - ( _w - w ) ) + 'px'; 
4485                 };
4486                 
4487                 function change( e ){
4488                         var data = currentData,
4489                                 file = data.elmFileInputReal.value;
4490                         file = file.split( '\\' );
4491                         file = file[ file.length - 1 ];
4492                         if( data.value !== file ){
4493                                 data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, [ file, data.value ], this );
4494                                 data.elmValue.innerHTML = data.value = file;
4495                         };
4496                         currentData.item.blur();
4497                 };
4498                 function asyncMouseout(){
4499                         currentData && currentData.item.blur();
4500                 };
4501                 function onClick(){
4502                         MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout );
4503                         MouseEvent.remove( currentUser, elmFileInput, 'click', onClick );       
4504                 };
4505                 return {
4506                         show : function( data ){
4507                                 currentData = data;
4508                                 
4509                                 elmFileInput = data.elmFileInputReal;
4510                                 elmWrap      = elmFileInput.parentNode;
4511                                 // 
4512                                 
4513                                 updateWrapperPosition();
4514                                 elmFileInput.focus();
4515                                 //data.node.addEventListener( 'change', change, data );
4516                                 evt = new EventTicketClass( elmFileInput, 'change', change );
4517                                 MouseEvent.add( currentUser, elmFileInput, 'mouseout', asyncMouseout );
4518                                 MouseEvent.add( currentUser, elmFileInput, 'click', onClick );
4519                                 // currentData.elmFileInputReal.onchange = change;
4520                                 SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 );
4521                         },
4522                         hide : function( data ){
4523                                 if( currentData !== data ) return;
4524                                 // data.node.removeEventListener( 'change', change );
4525                                 evt.destroy();
4526                                 // MouseEvent.remove( currentUser, elmFileInput, 'mouseout', asyncMouseout );
4527                                 onClick();
4528                                 //currentData.elmFileInputReal.onchange = null;
4529                                 elmWrap.style.display = 'none';
4530                                 currentData = elmFileInput = null;
4531                                 SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition );
4532                         },
4533                         onWindowResize: function( _w, _h ){
4534                                 AsyncCall.add( currentUser, updateWrapperPosition );
4535                         }
4536                 };
4537         })();
4538         
4539         var FileInputClass = function( groupData, elmWrapper, onUpdate, validater, elmFileInputReal, elmValue ){
4540                 var data = new UIItemPrivateData();
4541                 data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true );
4542                 data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-fileinput-hover', 'pointer' );
4543                 data.elmValue = elmValue;
4544                 data.elmFileInputReal = elmFileInputReal;
4545                 data.node.addEventListener( 'mouseover', this.focus, this );
4546         };
4547         FileInputClass.prototype = {
4548                 value : function(){
4549                         return data.value;
4550                 },
4551                 focus : function(){
4552                         var data = UIItemPrivateData.get( this );
4553                         data.focus = true;
4554                         Util.addClass( data.elm, 'fileinput-has-focus' );
4555                         start( data );
4556                         FileInputManager.show( data );
4557                 },
4558                 blur : function( keyCode ){
4559                         var data = UIItemPrivateData.get( this );
4560                         Util.removeClass( data.elm, 'fileinput-has-focus' );
4561                         data.focus = false;
4562                         FileInputManager.hide( data );
4563                         finish( data );
4564                 },
4565                 enabled : function( v ){
4566                         var data = UIItemPrivateData.get( this );
4567                         if( Type.isBoolean( v ) === true && data.enabled !== v ){
4568                                 if( data.focus === true && v === false ) this.blur();
4569                                 Util.toggleClass( data.elm, 'fileinput-disabled', !v );
4570                                 data.enabled = v;
4571                                 data.node.disabled( !( data.visible && v ) );
4572                         };
4573                         return data.enabled;
4574                 },
4575                 visible : function( v ){
4576                         var data = UIItemPrivateData.get( this );
4577                         if( Type.isBoolean( v ) === true && data.visible !== v ){
4578                                 if( data.focus === true && v === false ) this.blur();
4579                                 data.elm.style.display = v ? '' : 'none';
4580                                 data.visible = v;
4581                                 data.node.disabled( !( data.enabled && v ) );
4582                         };
4583                         return data.visible;
4584                 },
4585                 destroy : function(){
4586                         var data = UIItemPrivateData.get( this );
4587                         data.focus === true && FileInputManager.hide( data );
4588                         data.destroy();
4589                 }
4590         };
4591         
4592         var ButtonClass = function( groupData, elmWrapper, onUpdate ){
4593                 var data = new UIItemPrivateData();
4594                 data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true );
4595                 data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-button-hover', 'pointer' );
4596                 data.node.addEventListener( 'click', onUpdate );
4597                 //MouseEvent.add( groupData.apiuser, elmWrapper, 'click', onUpdate );
4598         };
4599         ButtonClass.prototype = {
4600                 focus : function(){
4601                         var data = UIItemPrivateData.get( this );
4602                         data.focus = true;
4603                         Util.addClass( data.elm, 'button-has-focus' );
4604                         start( data );
4605                 },
4606                 blur : function( keyCode ){
4607                         var data = UIItemPrivateData.get( this );
4608                         keyCode === 13 && data.onUpdate && data.onUpdate();
4609                         Util.removeClass( data.elm, 'button-has-focus' );
4610                         data.focus = false;
4611                         finish( data );
4612                 },
4613                 enabled : function( v ){
4614                         var data = UIItemPrivateData.get( this );
4615                         if( Type.isBoolean( v ) === true && data.enabled !== v ){
4616                                 Util.toggleClass( data.elm, 'button-disabled', !v );
4617                                 data.enabled = v;
4618                                 data.node.disabled( !( data.visible && v ) );
4619                         };
4620                         return data.enabled;
4621                 },
4622                 visible : function( v ){
4623                         var data = UIItemPrivateData.get( this );
4624                         if( Type.isBoolean( v ) === true && data.visible !== v ){
4625                                 data.elm.style.display = v ? '' : 'none';
4626                                 data.visible = v;
4627                                 data.node.disabled( !( data.enabled && v ) );
4628                         };
4629                         return data.visible;
4630                 },
4631                 destroy : function(){
4632                         var data = UIItemPrivateData.get( this );
4633                         // MouseEvent.remove( data.groupData.apiuser, data.elm );
4634                         data.destroy();
4635                 }
4636         };
4637
4638         var ComboBoxClass = function( groupData, elmWrapper, onUpdate ){
4639                 var elmA   = ELM_COMBOBOX.cloneNode( true ),
4640                         data   = new UIItemPrivateData();
4641                 data.init( groupData, this, elmWrapper, null, onUpdate, null, false, true, true );
4642                 
4643                 data.elmBox      = Util.getElementsByClassName( elmWrapper, 'combobox' )[ 0 ];
4644                 data.elmBox.appendChild( elmA );
4645                 data.elmA        = elmA;
4646                 data.elmToggle   = Util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ];
4647                 data.elmValue    = Util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild;
4648                 data.selectIndex = 0;
4649                 data.optionList  = [];
4650
4651                 data.node = groupData.node.createNode( elmWrapper, false, true, 'ui-combobox-hover', 'pointer' );
4652                 data.node.addEventListener( 'click', this.focus, this );
4653         };
4654         ComboBoxClass.prototype = {
4655                 focus : function( e ){
4656                         var data = UIItemPrivateData.get( this );
4657                         data.node.removeEventListener( 'click', this.focus );
4658                         data.focus = true;
4659                         data.elmA.className = 'combobox-has-focus';
4660                         start( data );
4661                         OptionControl.show( data );
4662                         return false;
4663                 },
4664                 blur : function( keyCode ){
4665                         var data = UIItemPrivateData.get( this );
4666                         OptionControl.hide( this );
4667                         data.focus = false;
4668                         data.elmA.className = '';
4669                         finish( data );
4670                         data.node.addEventListener( 'click', this.focus, this );
4671                 },
4672                 enabled : function( v ){
4673                         var data = UIItemPrivateData.get( this );
4674                         if( Type.isBoolean( v ) === true && data.enabled !== v ){
4675                                 Util.toggleClass( data.elm, 'ui-combobox-disabled', !v );
4676                                 if( data.focus === true && v === false ) this.blur();
4677                                 data.enabled = v;
4678                                 data.node.disabled( !( data.visible && v ) );
4679                         };
4680                         return data.enabled;
4681                 },
4682                 visible : function( v ){
4683                         var data = UIItemPrivateData.get( this );
4684                         if( Type.isBoolean( v ) === true && data.visible !== v ){
4685                                 data.elm.style.display = v ? '' : 'none';
4686                                 if( data.focus === true && v === false ) this.blur();
4687                                 data.visible = v;
4688                                 data.node.disabled( !( data.enabled && v ) );
4689                         };
4690                         return data.visible;
4691                 },
4692                 value : function( _value ){
4693                         var data = UIItemPrivateData.get( this ),
4694                                 i    = 0,
4695                                 list = data.optionList,
4696                                 l    = list.length,
4697                                 _option;
4698                         if( Type.isString( _value ) === true && data.value !== _value ){
4699                                 for( ; i < l; ++i ){
4700                                         _option = list[ i ];
4701                                         if( _value === _option.value ){
4702                                                 data.value = _value;
4703                                                 data.index = i;
4704                                                 data.elmValue.data = _option.displayValue;
4705                                                 if( data.focus === true ){
4706                                                         OptionControl.update( this, _value );
4707                                                 };
4708                                                 data.onUpdate && AsyncCall.add( data.groupData.apiuser, data.onUpdate, _value, this );
4709                                                 break;
4710                                         };
4711                                 };
4712                         };
4713                         return data.value;
4714                 },
4715                 selectIndex : function(){
4716                         var data = UIItemPrivateData.get( this );
4717                         return data.selectIndex;
4718                 },
4719                 createOption : function( _displayValue, _value, _isSelected ){
4720                         var data   = UIItemPrivateData.get( this ),
4721                                 option = null,
4722                                 list   = data.optionList,
4723                                 i      = list.length,
4724                                 _option, i;
4725                         _value      = _value || _displayValue;
4726                         _isSelected = !!_isSelected;
4727                         for( ; i; ){
4728                                 _option = list[ --i ];
4729                                 if( _value === _option.value ){
4730                                         option = _option;
4731                                         break;
4732                                 };
4733                         };
4734                         if( _isSelected === true ){
4735                                 data.selectIndex   = list.length;
4736                                 data.elmValue.data = _displayValue;
4737                         };                      
4738                         option === null && list.push( new OptionDataClass( _displayValue, _value, _isSelected ) );
4739                 },
4740                 destroy : function(){
4741                         var data   = UIItemPrivateData.get( this );
4742                         data.focus === true && OptionControl.hide( this );
4743                         // this.blur();
4744                         // MouseEvent.remove( data.groupData.apiuser, data.elm );
4745                         data.optionList.length = 0;
4746                         data.destroy();
4747                 }
4748         };
4749         var OptionDataClass = function( displayValue, value, isCurrent ){
4750                 this.displayValue = displayValue;
4751                 this.value        = value || displayValue;
4752                 this.current      = isCurrent;
4753                 displayValue = value = null;
4754         };
4755
4756         var OptionControl = ( function(){
4757                 var ELM_OPTION_WRAPPER = ( function(){
4758                                 var ret = document.createElement( 'div' );
4759                                 ret.className = 'option-container';
4760                                 return ret;
4761                         })(),
4762                         ELM_OPTION_ORIGIN = ( function(){
4763                                 var ret = document.createElement( 'a' );
4764                                 ret.appendChild( document.createTextNode( 'option' ) );
4765                                 ret.href = '#';
4766                                 return ret;
4767                         })();
4768
4769                 var OptionClass = function( option ){
4770                         this.elm     = ELM_OPTION_ORIGIN.cloneNode( true );
4771                         this.data    = option;
4772                         this.init();
4773                 };
4774                 OptionClass.prototype = {
4775                         init: function(){
4776                                 ELM_OPTION_WRAPPER.appendChild( this.elm );
4777                                 this.elm.firstChild.data = this.data.displayValue;
4778                                 this.current( this.data.current );
4779                                 MouseEvent.add( SUPER_USER_KEY, this.elm, 'mousedown', onOptionSelect );// onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!
4780                         },
4781                         current: function( _current ){
4782                                 this.elm.className = _current === true ? CLASSNAME_COMBOBOX_OPTION_CURRENT : CLASSNAME_COMBOBOX_OPTION;
4783                                 this.data.current  = _current;
4784                                 currentOption      = _current === true ? this : currentOption;
4785                         },
4786                         destroy: function(){
4787                                 MouseEvent.remove( SUPER_USER_KEY, this.elm );
4788                                 Util.removeAllChildren( this.elm );
4789                                 ELM_OPTION_WRAPPER.removeChild( this.elm );
4790                                 delete this.elm;
4791                                 delete this.data;
4792                         }
4793                 };
4794                 
4795                 function onOptionSelect( e ){
4796                         var i = 0,
4797                                 l = OPTION_LIST.length,
4798                                 _option;
4799                         for( ; i < l; ++i ){
4800                                 _option = OPTION_LIST[ i ];
4801                                 if( this === _option.elm ){
4802                                         updateCurrrentOption( _option.data.value, true );
4803                                         currentCombobox.blur();
4804                                         break;
4805                                 };
4806                         };
4807                         return false;
4808                 };
4809                 
4810                 var OPTION_LIST     = [],
4811                         currentCombobox = null,
4812                         apiuser,
4813                         elm,
4814                         currentOption,
4815                         currentIndex;
4816                 
4817                 function updateCurrrentOption( _value, _updateCombobox ){
4818                         var _option,
4819                                 i = OPTION_LIST.length;
4820                         for( ; i; ){
4821                                 _option = OPTION_LIST[ --i ];
4822                                 if( _value === _option.data.value ){
4823                                         currentOption && currentOption.current( false );
4824                                         _option.current( true );
4825                                         currentOption = _option;
4826                                         currentIndex  = i;
4827                                         _updateCombobox === true && currentCombobox.value( _value );
4828                                         break;
4829                                 };
4830                         };
4831                 };
4832                 function bodyMouseupHandler(){
4833                         currentCombobox.blur();
4834                         OptionControl.hide( currentCombobox );
4835                 };
4836                 function updateWrapperPosition(){
4837                         var position = Util.getAbsolutePosition( elm );
4838
4839                         ELM_OPTION_WRAPPER.style.cssText = [
4840                                 'width:', elm.offsetWidth - 2, 'px;',
4841                                 'left:',  position.x, 'px;',
4842                                 'top:',   position.y + elm.offsetHeight, 'px;'
4843                         ].join( '' );
4844                 };
4845                 function change( e ){
4846                         var l   = OPTION_LIST.length,
4847                                 i   = currentIndex + ( e.keyCode === 40 ? -1 : 1 );
4848                         if( currentCombobox === null || l < 2 ) return;
4849                         i = i < 0 ?
4850                                         l - 1 :
4851                                         i < l ? i : 0;
4852                         updateCurrrentOption( OPTION_LIST[ i ].data.value, true );
4853                         return false;
4854                 };
4855                 return {
4856                         show: function( data ){
4857                                 var combobox = data.item,
4858                                         list     = data.optionList,
4859                                         i        = 0,
4860                                         l        = list.length;
4861                                 if( currentItem !== combobox || currentCombobox === combobox ) return;
4862                                 currentCombobox && currentCombobox.blur();
4863                                 
4864                                 apiuser         = data.groupData.apiuser;
4865                                 currentCombobox = combobox;
4866                                 elm             = data.elmBox;
4867                                 
4868                                 for( ; i < l; ++i ){
4869                                         OPTION_LIST.unshift( new OptionClass( list[ i ] ) );
4870                                 };
4871                                 MouseEvent.add( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler );
4872                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 38 );
4873                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change, 40 );
4874                                 //KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter, 13 );
4875                                 //KeyEvent.updateCurrentListener( SUPER_USER_KEY );
4876                                 
4877                                 body.appendChild( ELM_OPTION_WRAPPER );
4878                                 
4879                                 updateCurrrentOption( combobox.value(), false );
4880                                 updateWrapperPosition();
4881                                 
4882                                 SystemTimer.add( SUPER_USER_KEY, updateWrapperPosition, 500 );
4883                         },
4884                         hide: function( _combobox ){
4885                                 if( currentCombobox !== _combobox || currentCombobox === null ) return;
4886
4887                                 var _option;
4888                                 while( _option = OPTION_LIST.shift() ){
4889                                         _option.destroy();
4890                                 };
4891                                 
4892                                 body.removeChild( ELM_OPTION_WRAPPER );
4893                                 
4894                                 MouseEvent.remove( SUPER_USER_KEY, document, 'mouseup', bodyMouseupHandler );
4895                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
4896                                 KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, change );
4897                                 //KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onEnter );
4898                                 //KeyEvent.updateCurrentListener( apiuser );
4899                                 
4900                                 SystemTimer.remove( SUPER_USER_KEY, updateWrapperPosition, 500 );
4901                                 
4902                                 apiuser         = null;
4903                                 currentCombobox = null;
4904                                 currentOption   = null;
4905                                 currentIndex    = 0;                            
4906                         },
4907                         onEnter: function(){
4908                                 currentCombobox.value( currentOption.data.value );
4909                                 //currentCombobox.blur();
4910                                 //OptionControl.hide( currentCombobox );
4911                         },
4912                         update: function( data, _value ){
4913                                 if( currentCombobox !== data.item || currentItem !== data.item ) return;
4914                                 if( currentOption.data.value === _value ) return;
4915                                 updateCurrrentOption( _value, true );
4916                         },
4917                         onWindowResize: function( _w, _h ){
4918                                 currentCombobox && AsyncCall.add( apiuser, updateWrapperPosition );
4919                         }
4920                 };
4921         })();
4922         
4923         var UIGroupPrivateData = function(){};
4924         UIGroupPrivateData.prototype = {
4925                 apiuser  : null,
4926                 node     : null,
4927                 uigroup  : null,
4928                 itemList : null,
4929                 visible  : true,
4930                 enabled  : true,
4931                 init     : function( apiuser, node, uigroup ){
4932                         this.apiuser  = apiuser;
4933                         this.node     = node;
4934                         this.uigroup  = uigroup;
4935                         this.itemList = [];
4936                         UIGroupPrivateData.list.push( this );
4937                 },
4938                 destroy  : function(){
4939                         
4940                 }
4941         };
4942         UIGroupPrivateData.list = [];
4943         UIGroupPrivateData.get  = function( uigroup ){
4944                 var list = UIGroupPrivateData.list,
4945                         i    = list.length;
4946                 for( ; i; ){
4947                         if( list[ --i ].uigroup === uigroup ) return list[ i ];
4948                 };
4949                 return null;
4950         };
4951         
4952         var UIGroupClass = function( apiuser, node ){
4953                 ( new UIGroupPrivateData() ).init( apiuser, node, this );
4954         };
4955         UIGroupClass.prototype = {
4956                 focus : function( _value ){
4957                         var data = UIGroupPrivateData.get( this );
4958                         /*
4959                         if( _value === true ){
4960                                 if( currentItem ){
4961                                         start( apiuser, self, currentItem );
4962                                 } else
4963                                 if( itemList.length > 0 ){
4964                                         start( apiuser, self, itemList[ 0 ] );
4965                                 };
4966                         } else
4967                         if( _value === false ){
4968                                 finish( apiuser, self, currentItem );
4969                         } else
4970                         */
4971                         if( _value && Util.getIndex( data.itemList, _value ) !== -1 ){
4972                                 // currentItem = _value;
4973                                 currentList = data.itemList;
4974                         };
4975                         return currentUi === this; 
4976                 },
4977                 blur : function(){
4978                         var data = UIGroupPrivateData.get( this );
4979                         if( currentList === data.itemList ){
4980                                 currentList = null;
4981                         };
4982                 },
4983                 createInputText : function( elmWrapper, onUpdate, validater ){
4984                         var data     = UIGroupPrivateData.get( this ),
4985                                 elmValue = Util.getElementsByClassName( elmWrapper, 'editable-value' )[ 0 ],
4986                                 ret;
4987                         if( elmValue ){
4988                                 ret = new TextInputClass( data, elmWrapper, elmValue, onUpdate, validater );
4989                                 data.itemList.push( ret );
4990                                 return ret;
4991                         };
4992                         alert( 'error createInputText' );
4993                 },
4994                 createButton : function( elm, onClick ){
4995                         var data = UIGroupPrivateData.get( this ),
4996                                 ret  = new ButtonClass( data, elm, onClick );
4997                         data.itemList.push( ret );
4998                         return ret;
4999                 },
5000                 createFileInput : function( elm, onUpdate, validater, elmFileInputReal ){
5001                         var data     = UIGroupPrivateData.get( this ),
5002                                 elmValue = Util.getElementsByClassName( elm, 'fileinput-value' )[ 0 ],
5003                                 ret;
5004                         if( elmValue ){
5005                                 ret = new FileInputClass( data, elm, onUpdate, validater, elmFileInputReal, elmValue );
5006                                 data.itemList.push( ret );
5007                                 return ret;
5008                         };
5009                         return ret;
5010                 },
5011                 createCombobox : function( elm, onUpdate, optionList ){
5012                         var data = UIGroupPrivateData.get( this ),
5013                                 ret  = new ComboBoxClass( data, elm, onUpdate, optionList );
5014                         data.itemList.push( ret );
5015                         return ret;
5016                 },
5017                 createCheckBox : function(){
5018                         
5019                 },
5020                 createRadio : function(){
5021                         
5022                 },
5023                 createSlider : function(){
5024                         
5025                 },
5026                 visible : function( v ){
5027                         var data = UIGroupPrivateData.get( this );
5028                         if( Type.isBoolean( v ) === true && data.visible !== v ){
5029                                 for( var i = data.itemList.length; i; ){
5030                                         data.itemList[ --i ].visible( v );
5031                                 };
5032                                 data.visible = v;
5033                                 data.node.disabled( !( data.enabled && v ) );
5034                         };
5035                         return data.visible;
5036                 },
5037                 enabled : function( v ){
5038                         var data = UIGroupPrivateData.get( this );
5039                         if( Type.isBoolean( v ) === true && data.enabled !== v ){
5040                                 for( var i = data.itemList.length; i; ){
5041                                         data.itemList[ --i ].enabled( v );
5042                                 };
5043                                 data.enabled = v;
5044                                 data.node.disabled( !( data.visible && v ) );
5045                         };
5046                         return data.enabled;
5047                 },
5048                 destroy : function(){
5049                         var data = UIGroupPrivateData.get( this ),
5050                                 _item;
5051                         if( currentUi === this ){
5052                                 currentItem.blur();
5053                                 // finish( UIItemPrivateData.get( currentItem ) );
5054                         };                      
5055                         while( _item = data.itemList.shift() ){
5056                                 _item.destroy();
5057                         };
5058                         data.destroy();
5059                 }
5060         };
5061         
5062         function start( data ){
5063                 if( currentItem !== data.item ){
5064                         currentUi !== data.groupData.uigroup && currentUi && currentUi.blur();
5065                         
5066                         currentItem !== null && currentItem.blur();
5067                         
5068                         currentUser = data.groupData.apiuser;
5069                         currentUi   = data.groupData.uigroup;
5070                         currentItem = data.item;
5071                         
5072                         currentUi.focus( currentItem );
5073                         
5074                         // if( currentUser !== _apiuser ) {
5075                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
5076                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
5077                                 KeyEvent.add( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );
5078                                 KeyEvent.updateCurrentListener( SUPER_USER_KEY );
5079                         // };
5080                 };
5081         }
5082         function finish( data ){
5083                 if( currentItem === data.item ){
5084                         currentUi.blur();
5085                         
5086                         currentUser = null;
5087                         currentUi   = null;
5088                         currentItem = null;
5089                         currentList = null;
5090                         
5091                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 13 );
5092                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown, 27 );
5093                         KeyEvent.remove( SUPER_USER_KEY, Const.KEY.EVENT.KEY_DOWN, onKeyDown,  9 );
5094                         KeyEvent.updateCurrentListener( data.groupData.apiuser );
5095                 };
5096         };
5097
5098         function onKeyDown( e ){
5099                 if( currentItem === null ) return true;
5100                 var keyCode = e.keyCode,
5101                         index   = Util.getIndex( currentList, currentItem );
5102                 if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt
5103                         keyCode === 9  && tabShift( index, e.shiftKey === true ? -1 : 1 );
5104                         keyCode === 13 && currentItem instanceof ComboBoxClass && OptionControl.onEnter();
5105                         keyCode === 13 && tabShift( index, 1 );                 
5106                         currentItem && currentItem.blur( keyCode );
5107                         return false;
5108                 };
5109         };
5110
5111         function tabShift( index, way ){
5112                 var l = currentList.length,
5113                         i = index + way,
5114                         item;
5115                 if( l < 2 ) return;
5116                 while( i !== index ){
5117                         i = i < 0 ?
5118                                 l - 1 :
5119                                 i < l ? i : 0; // 0 < i < l
5120                         item = currentList[ i ];
5121                         if( item.enabled() === true && item.visible() === true ){
5122                                 AsyncCall.add( currentUser, item.focus, null, item );
5123                                 return;
5124                         };
5125                         i += way;
5126                 };
5127         };
5128         
5129         return {
5130                 createUIGroup: function( apiuser, node ){
5131                         var uid  = apiuser.getUID(),
5132                                 list = UI_LIST[ uid ],
5133                                 ui   = new UIGroupClass( apiuser, node );
5134                         if( Type.isArray( list ) === false ){
5135                                 list = UI_LIST[ uid ] = [];
5136                         };
5137                         list.push( ui );
5138                         return ui;
5139                 },
5140                 onWindowResize: function( w, h ){
5141                         windowW = w;
5142                         windowH = h;
5143                         currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );
5144                         currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h );
5145                         currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h );
5146                 },
5147                 onCurrentApplicationChange: function( _apiuser ){
5148                         currentList = UI_LIST[ _apiuser.getUID() ];
5149                 },
5150                 onApplicationShutdown: function( _apiuser ){
5151                         KeyEvent.remove( _apiuser );
5152                 },
5153                 onSystemShutdown: function(){
5154                         
5155                 }
5156         };
5157 })();
5158
5159 var UIForm = ( function(){
5160         var FORM_LIST           = [];
5161         var CLASSNAME_FORM      = 'uiform-invisible';
5162         var CLASSNAME_FILE_WRAP = 'ui-fileinput-wrapper';
5163         var FormItemData = function(){};
5164         FormItemData.prototype = {
5165                 formData : null,
5166                 uiItem   : null,
5167                 init : function( formData, uiItem ){
5168                         this.formData = formData;
5169                         this.uiItem   = uiItem;
5170                 },
5171                 onUpdate : function( v ){
5172                         // var index = Util.getIndex( this.formData.itemList, this );
5173                 }
5174         };
5175         
5176         var FormPrivateData = function(){};
5177         FormPrivateData.prototype = {
5178                 apiuser  : null,
5179                 node     : null,
5180                 form     : null,
5181                 elmForm  : null,
5182                 itemList : null,
5183                 visible  : true,
5184                 enabled  : true,
5185                 init     : function( apiuser, from, node, elm, elmForm ){
5186                         this.apiuser      = apiuser;
5187                         this.form         = form;
5188                         this.ui           = apiuser.createUIGroup( node );
5189                         this.node         = node;
5190                         this.elm          = elm;
5191                         this.elmForm      = elmForm;
5192                         this.itemList     = [];
5193                         elmForm.className = CLASSNAME_FORM;
5194                         FormPrivateData.list.push( this );
5195                         
5196                         var forms = Util.copyArray( elmForm.getElementsByTagName( '*' ) ),
5197                                 l     = forms.length,
5198                                 i     = 0,
5199                                 items = 'input,select,textarea,button',
5200                                 form, data, el, wrap;
5201                         for( ; i<l; ++i ){
5202                                 form = forms[ i ];
5203                                 if( form.nodeType !== 1 ) continue;
5204                                 switch( form.tagName.toLowerCase() ){
5205                                         case 'input':
5206                                                 switch( form.type.toLowerCase() ){
5207                                                         case 'text':
5208                                                                 break;
5209                                                         case 'file':
5210                                                                 el = document.createElement( 'div' );
5211                                                                 el.className = 'uiform-file-container';
5212                                                                 el.appendChild( document.createElement( 'div' ) );
5213                                                                 el.appendChild( document.createElement( 'div' ) );
5214                                                                 el.firstChild.className = 'uiform-label';
5215                                                                 el.lastChild.className  = 'uiform-file fileinput-value';
5216                                                                 // opera9 don't work for opera9;
5217                                                                 //el = Util.pullHtmlAsTemplete( '<div class="uiform-file-container"><div class="uiform-label"></div><div class="uiform-file fileinput-value"></div></div>' );
5218                                                                 elm.appendChild( el );
5219                                                                 data = new FormItemData();
5220                                                                 wrap = document.createElement( 'div' );
5221                                                                 form.parentNode.insertBefore( wrap, form );
5222                                                                 wrap.className = CLASSNAME_FILE_WRAP;
5223                                                                 wrap.appendChild( form );
5224                                                                 data.init( this, this.ui.createFileInput( el, data.onUpdate, null, form ) );
5225                                                                 this.itemList.push( data );
5226                                                                 break;
5227                                                         case 'button':
5228                                                                 break;
5229                                                         default:
5230                                                                 continue;
5231                                                 };
5232                                                 break;
5233                                         case 'select':
5234                                                 break;
5235                                         case 'button':
5236                                                 break;
5237                                         case 'textarea':
5238                                                 break;
5239                                         default:
5240                                                 continue;
5241                                 };
5242                         };
5243                 },
5244                 destroy  : function(){
5245                         
5246                 }
5247         };
5248         FormPrivateData.list = [];
5249         FormPrivateData.get  = function( from ){
5250                 var list = FormPrivateData.list,
5251                         i    = list.length;
5252                 for( ; i; ){
5253                         if( list[ --i ].form === form ) return list[ i ];
5254                 };
5255                 return null;
5256         };
5257         
5258         var FormClass = function( apiuser, node, elm, elmForm ){
5259                 ( new FormPrivateData() ).init( apiuser, this, node, elm, elmForm );
5260         };
5261         FormClass.prototype = {
5262                 createTextInput : function(){
5263                         
5264                 },
5265                 createMultiLineInput : function(){
5266                         
5267                 },
5268                 createFileInput : function(){
5269                         
5270                 },
5271                 createButton : function(){
5272                         
5273                 },
5274                 createComboBox : function(){
5275                         
5276                 },
5277                 submit : function(){
5278                         
5279                 }
5280         };
5281         
5282         return {
5283                 createForm: function( apiuser, nodeOrElm, opt_elmForm ){
5284                         var uid  = apiuser.getUID(),
5285                                 list = FORM_LIST[ uid ],
5286                                 node, elm, form;
5287                         if( PointingDeviceEventTree.isNodeInstance( nodeOrElm ) === true ){
5288                                 node = nodeOrElm;
5289                                 elm  = PointingDeviceEventTree._getNodePrivateData( nodeOrElm ).elm;
5290                         } else {
5291                                 // App が eventTree を持っている?
5292                                 // App が eventTree を持っていない
5293                                 elm  = nodeOrElm;
5294                         };  
5295                         form = new FormClass( apiuser, node, elm, opt_elmForm );
5296                         if( Type.isArray( list ) === false ){
5297                                 list = FORM_LIST[ uid ] = [];
5298                         };
5299                         list.push( form );
5300                         return form;
5301                 },
5302                 onWindowResize: function( w, h ){
5303                         windowW = w;
5304                         windowH = h;
5305                         currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );
5306                         currentItem instanceof TextInputClass && TextInputManager.onWindowResize( w, h );
5307                         currentItem instanceof FileInputClass && FileInputManager.onWindowResize( w, h );
5308                 },
5309                 onCurrentApplicationChange: function( _apiuser ){
5310                 },
5311                 onApplicationShutdown: function( _apiuser ){
5312                 },
5313                 onSystemShutdown: function(){
5314                         
5315                 }
5316         };
5317 })();
5318
5319 var Finder = ( function(){
5320         var FINDER_LIST              = [],
5321                 ELM_ORIGIN_LOCATION_ITEM = Util.pullHtmlAsTemplete( '<div class="finder-location-item"></div>' ),
5322                 HTML_FINDER_ICON = ( function(){
5323                         return ( UA.isIE === true && UA.ieVersion < 8 ?
5324                         [
5325                                 '<div class="finder-icon fnder-icon-ie7">',
5326                                         '<div class="finder-icon-handle"></div>',
5327                                         '<div class="file-icon"><div></div></div>',
5328                                         '<span class="finder-icon-cell finder-icon-ie-filename">',
5329                                                 '<span class="finder-icon-vertical-middle-outer">',
5330                                                         '<span class="finder-icon-vertical-middle-inner">',
5331                                                                 '<span class="finder-icon-filename break-word">file name</span>',
5332                                                         '</span>',
5333                                                 '</span>',
5334                                         '</span>',
5335                                         '<span class="finder-icon-cell finder-icon-ie-summary">',
5336                                                 '<span class="finder-icon-vertical-middle-outer">',
5337                                                         '<span class="finder-icon-vertical-middle-inner">',
5338                                                                 '<span class="finder-icon-summary break-word">file descriptiion</span>',
5339                                                         '</span>',
5340                                                 '</span>',
5341                                         '</span>',
5342                                         '<div class="finder-icon-down"></div>',
5343                                 '</div>'
5344                         ] :
5345                         [
5346                                 '<div class="finder-icon fnder-icon-modern">',
5347                                         '<div class="finder-icon-handle"></div>',
5348                                         '<div class="file-icon"><div></div></div>',
5349                                         '<div class="finder-icon-filename break-word">file name</div>',
5350                                         '<div class="finder-icon-summary break-word">file descriptiion</div>',
5351                                         '<div class="finder-icon-down">&gt;</div>',
5352                                 '</div>'
5353                         ] ).join( '' );
5354                 })(),
5355                 ELM_ORIGIN_FINDER_ICON = Util.pullHtmlAsTemplete( HTML_FINDER_ICON ),
5356                 ICON_HEIGHT            = Util.getElementSize( ELM_ORIGIN_FINDER_ICON ).height;
5357         
5358         // t : 時間
5359     // b : 開始の値(開始時の座標やスケールなど)
5360     // c : 開始と終了の値の差分
5361     // d : Tween(トゥイーン)の合計時間
5362
5363         function easeOutQuad( t, b, c, d ){
5364                 t /= d;
5365                 return -c * t*( t-2 ) + b;
5366         };
5367         
5368 /**
5369  * FinderIconClass
5370  */
5371         var FinderIconClass = function(){};
5372         FinderIconClass.prototype = {
5373                 finderData       : null,
5374                 file             : null,
5375                 elm              : null,
5376                 node             : null,
5377                 _index           : -1,
5378                 _style           : -1,
5379                 init : function( page, file, w, index, style ){
5380                         if( !this.elm ) this.elm  = ELM_ORIGIN_FINDER_ICON.cloneNode( true );
5381
5382                         if( this.page !== page ){
5383                                 this.page = page;
5384                                 page.elm.appendChild( this.elm );
5385                                 this.node && this.node.remove();
5386                                 this.node = page.node.createNode( this.elm, false, true, 'finder-icon-hover', '' );
5387                         };
5388                         if( this.file !== file ){
5389                                 this.file && this.file.destroy();
5390                                 this.file   = file;
5391                                 this._index = index;
5392                                 this.draw( w );
5393                                 return;
5394                         };
5395                         if( this._index !== index ){
5396                                 this._index = index;
5397                                 this.resize( w );
5398                         };
5399                 },
5400                 index : function( _index ){     
5401                         return this._index;
5402                 },
5403                 style : function( _style ){
5404                         return this._style;
5405                 },
5406                 draw : function( w ){
5407                         var file       = this.file,
5408                                 elm        = this.elm,
5409                                 thumb      = file.getThumbnail(),
5410                                 elmThumb   = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild,
5411                                 elmName    = Util.getElementsByClassName( elm, 'finder-icon-filename' )[ 0 ],
5412                                 elmDesc    = Util.getElementsByClassName( elm, 'finder-icon-summary' )[ 0 ];
5413                         if( thumb.image ){
5414                                 elmThumb.className = 'has-thumbnail';
5415                                 elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' );
5416                         } else {
5417                                 elmThumb.className = thumb.className;
5418                                 elmThumb.style.backgroundImage = '';
5419                         };
5420                         
5421                         elmName.firstChild.data = file.getName();
5422                         elmDesc.firstChild.data = file.getSummary();
5423                         
5424                         this.resize( w );
5425                 },
5426                 resize : function( w ){
5427                         this.node.update( 0, this._index * ICON_HEIGHT, w );
5428                 },
5429                 onEditorClick : function( e ){
5430                         this.onEditorCallback && this.onEditorCallback( this.file, this.file.editorApplicationList()[ 0 ] );
5431                         return false;
5432                 },
5433                 onViwerClick : function( e ){
5434                         this.onViewerCallback && this.onViewerCallback( this.file, this.file.viewerApplicationList()[ 0 ] );
5435                         return false;
5436                 },
5437                 onActionClick : function( e ){
5438                         this.onActionCallback && this.onActionCallback( this.file );
5439                         return false;
5440                 },
5441                 destroy : function(){
5442                         this.elm && this.elm.parentNode.removeChild( this.elm );
5443                         this.file && this.file.destroy();
5444                         this.node && this.node.remove();
5445                         delete this.page;
5446                         delete this.file;
5447                         delete this.node;
5448                         delete this._index;
5449                         delete this._style;
5450                         FinderIconClass.pool.push( this );
5451                 }       
5452         };
5453         FinderIconClass.pool = [];
5454         FinderIconClass.get = function( page, file, w, index, style ){
5455                 var _icon = FinderIconClass.pool.length > 0 ? FinderIconClass.pool.shift() : new FinderIconClass();
5456                 _icon.init( page, file, w, index, style );
5457                 return _icon;
5458         };
5459
5460 /**
5461  * PathClass
5462  */
5463         var PathClass = function(){};
5464         PathClass.prototype = {
5465                 finderData : null,
5466                 elm        : null,
5467                 node       : null,
5468                 file       : null,
5469                 _index     : null,
5470                 w          : 0,
5471                 init : function( finderData, file, index ){
5472                         if( !this.elm ) this.elm  = ELM_ORIGIN_LOCATION_ITEM.cloneNode( true );
5473                         
5474                         if( this.finderData !== finderData ){
5475                                 this.finderData = finderData;
5476                                 finderData.elmPath.appendChild( this.elm );
5477                                 this.node && this.node.remove();
5478                                 delete this.node;
5479                         };
5480                         if( this.file !== file ){
5481                                 this.file = file;
5482                                 this.draw();
5483                         };
5484                         this._index = index;
5485                         if( !this.node ) this.node = finderData.nodePath.createNode( this.elm, false, true, 'finder-path-hover', 'pointer' );
5486                 },
5487                 draw  : function(){
5488                         this.elm.className = 'file-icon-' + this.file.getType();
5489                         this.elm.innerHTML = this.file.getName();                       
5490                 },
5491                 textWidth : function(){
5492                         this.elm.style.width = 'auto';
5493                         var ret = this.elm.offsetWidth;
5494                         this.elm.style.width = '';
5495                         return ret + 15;
5496                 },
5497                 update : function( x, w ){
5498                         this.node.update( x - 15, undefined, w );
5499                 },
5500                 index : function( _index ){
5501                         return this._index;
5502                 },
5503                 destroy : function(){
5504                         this.finderData.elmPath.removeChild( this.elm );
5505                         this.node && this.node.remove();
5506                         
5507                         delete this.finderData;
5508                         delete this.elm;
5509                         delete this.node;
5510                         delete this.file;
5511                         delete this._index;
5512                         PathClass.pool.push( this );
5513                 }
5514         };
5515         PathClass.pool = [];
5516         PathClass.get  = function( finderData, file, index ){
5517                 var _bread = PathClass.pool.length > 0 ? PathClass.pool.shift() : new PathClass();
5518                 _bread.init( finderData, file, index );
5519                 return _bread;
5520         };
5521         
5522         
5523         /**
5524          * Page
5525          */
5526         var PageClass = function(){};
5527         PageClass.prototype = {
5528                 nodeRoot     : null,
5529                 elmRoot      : null,
5530                 elmScroll    : null,
5531                 elm          : null,
5532                 node         : null,
5533                 folder       : null,
5534                 iconList     : null,
5535                 sliding      : false,
5536                 currentX     : 0,
5537                 panTime      : 0,
5538                 startX       : 0,
5539                 offsetX      : 0,
5540                 panTotalTime : 0,
5541                 isPanOut     : false,
5542                 init : function( nodeRoot, elmRoot, elmScroll ){
5543                         this.nodeRoot  = nodeRoot;
5544                         this.elmRoot   = elmRoot;
5545                         this.elmScroll = elmScroll;
5546                         
5547                         if( this.elm === null ){
5548                                 this.elm = document.createElement( 'div' );
5549                         };
5550                         elmScroll.appendChild( this.elm );
5551                         this.elm.style.cssText = 'position:absolute;top:0;';
5552                         // this.elm.style.display = 'none';
5553                         this.node = this.nodeRoot.createNode( this.elm, true, false );
5554                         if( this.iconList === null ){
5555                                 this.iconList = [];
5556                         };
5557                 },
5558                 panInReady : function( way ){
5559                         this.elm.style.display = '';
5560                         var x = this.sliding === true ? this.currentX : way * this.nodeRoot.width();
5561                         this.startX       = this.currentX = x;
5562                         this.targetX      = 0;
5563                         this.offsetX      = -x;
5564                         this.panTime      = 0;
5565                         this.panTotalTime = 20;
5566                         this.sliding      = true;
5567                         this.isPanOut     = false;
5568                         // this.elm.style.left = x + 'px';
5569                         this.node.x( x );
5570                 },
5571                 panOutReady : function( way ){
5572                         var x = -way * this.nodeRoot.width();
5573                         this.startX       = this.currentX || 0;
5574                         this.targetX      = x;
5575                         this.offsetX      = x - this.startX;
5576                         this.panTime      = 0;
5577                         this.panTotalTime = 20;
5578                         this.sliding      = true;
5579                         this.isPanOut     = true;
5580                 },
5581                 pan : function(){
5582                         var page = this,
5583                                 x    = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime );
5584                         // page.elm.style.left = x + 'px';
5585                         this.node.x( x );
5586                         if( page.panTotalTime < ++page.panTime ){
5587                                 delete page.panTime;
5588                                 delete page.startX;
5589                                 delete page.offsetX;                                    
5590                                 delete page.panTotalTime;
5591                                 delete page.sliding;
5592                                 if( this.isPanOut === true ) this.elm.style.display = 'none';
5593                         };
5594                 },
5595                 draw : function( folder ){
5596                         _w = this.nodeRoot.width();
5597                         this.folder = folder;
5598                         var data     = this,
5599                                 iconList = data.iconList,
5600                                 i        = 0,
5601                                 j        = 0,
5602                                 l        = folder.getChildFileLength(),
5603                                 m        = iconList.length,
5604                                 scrollY  = -this.nodeRoot.scrollY(),
5605                                 rootH    = scrollY + this.nodeRoot.height(),
5606                                 icon;
5607
5608                         for( ; i < l; ++i ){
5609                                 if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ) continue;
5610                                 if( j < m ){
5611                                         iconList[ j ].init( this, folder.getChildFileAt( i ), _w, i, data.style );
5612                                 } else {
5613                                         iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) );
5614                                 };
5615                                 j++;
5616                         };
5617                         data.elmRoot.className    = folder.getState() === Const.FILE.STATE.LOADING ? 'finder-body loading' : 'finder-body';
5618                         // data.elmRoot.style.height = ( data.h - data.headH ) + 'px';
5619                         
5620                         while( j < iconList.length ) iconList.pop().destroy();
5621                         data.elmScroll.style.height = ( l * ICON_HEIGHT ) + 'px';
5622                 },
5623                 onScroll : function(){
5624                         var _w       = this.nodeRoot.width();
5625                         
5626                         var data     = this,
5627                                 iconList = data.iconList,
5628                                 folder   = this.folder,
5629                                 i        = 0,
5630                                 j        = 0,
5631                                 l        = folder.getChildFileLength(),
5632                                 scrollY  = -this.nodeRoot.scrollY(),
5633                                 rootH    = scrollY + this.nodeRoot.height(),
5634                                 startIndex = 0 < iconList.length ? iconList[ 0 ]._index : 0,
5635                                 icon;
5636                         
5637                         // console.log( ' > ' + scrollY + ' , ' + rootH )
5638                         for( ; i < l; ++i ){
5639                                 if( ( i + 1 ) * ICON_HEIGHT < scrollY || rootH < i * ICON_HEIGHT ){
5640                                         if( iconList.length <= j ) continue;
5641                                         icon = iconList[ j ];
5642                                         if( icon._index !== i ) continue;
5643                                         icon.destroy();
5644                                         iconList.splice( j, 1 );
5645                                         continue;
5646                                 };
5647                                 if( iconList.length <= j || iconList[ j ]._index !== i ){
5648                                         if( i < startIndex ){
5649                                                 iconList.splice( j, 0, FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) );                    
5650                                         } else
5651                                         if( startIndex + iconList.length <= i ){
5652                                                 iconList.push( FinderIconClass.get( this, folder.getChildFileAt( i ), _w, i, data.style ) );                    
5653                                         };                                      
5654                                 };
5655                                 ++j;
5656                         };
5657                         
5658                         //while( j < iconList.length ) iconList.pop().destroy();
5659                 },
5660                 resize : function( w ){
5661                         var list = this.iconList,
5662                                 i    = list.length;
5663                         for( ; i; ) list[ --i ].resize( w );
5664                 },
5665                 destroy : function(){
5666                         var icon;
5667                         while( icon = this.iconList.shift() ) icon.destroy();
5668                         
5669                         this.elm.parentNode.removeChild( this.elm );
5670                 }
5671         };
5672         
5673         var ApplicationButton = function(){};
5674         ApplicationButton.prototype = {
5675                 elm     : null,
5676                 button  : null,
5677                 app     : null,
5678                 file    : null,
5679                 fileUID : -1,
5680                 init    : function( ui, elmParent, app, file ){
5681                         if( this.elm === null ){
5682                                 this.elm = document.createElement( 'div' );
5683                         };
5684                         elmParent.appendChild( this.elm );
5685                         this.elm.className = 'button';
5686                         this.elm.innerHTML = app.getDisplayName();
5687                         
5688                         var that = this;
5689                         this.button = ui.createButton( this.elm, function(){
5690                                 that.onClick();
5691                                 // that = null;
5692                         } );
5693                         
5694                         this.app     = app;
5695                         this.file    = file;
5696                         this.fileUID = file.getUID();
5697                 },
5698                 onClick : function(){
5699                         this.app.boot( this.file );
5700                         return false;
5701                 },
5702                 destroy : function(){
5703                         var elm = this.elm;
5704                         elm.parentNode.removeChild( elm );
5705                         
5706                         this.button.destroy();
5707                         //this.kill()
5708                         //this.elm = elm;
5709                 }
5710         };
5711         
5712         var DetailPageClass = function(){};
5713         DetailPageClass.prototype = Util.extend( new PageClass(), {
5714                 appButtons : null,
5715                 init : function( finderData ){
5716                         this.finderData = finderData;
5717                         this.apiuser    = finderData.apiuser;
5718                         this.nodeRoot   = finderData.nodeRoot;
5719                         this.elmRoot    = finderData.elmRoot;
5720                         this.elmScroll  = finderData.elmScroll;
5721                         
5722                         if( this.elm === null ){
5723                                 this.elm = Util.pullHtmlAsTemplete( [
5724                                         '<div class="finder-detail">',
5725                                                 '<div class="file-icon"><div></div></div>',
5726                                                 '<div class="finder-detail-filename break-word">file name</div>',
5727                                                 '<div class="finder-detail-summary break-word">file descriptiion</div>',
5728                                                 '<div>View this file</div>',
5729                                                 '<div class="viewer-apps"></div>',                                              
5730                                                 '<div>Edit this file</div>',
5731                                                 '<div class="editor-apps"></div>',
5732                                         '</div>'
5733                                 ].join( '' ) );
5734                         };
5735                         this.elm.style.display = 'none';
5736                         this.elmScroll.appendChild( this.elm );
5737                         this.node = this.nodeRoot.createNode( this.elm, true, false );
5738                         
5739                         this.ui = this.apiuser.createUIGroup( this.node );
5740                         this.appButtons = [];
5741                 },
5742                 draw : function( file ){
5743                         var elm        = this.elm,
5744                                 thumb      = file.getThumbnail(),
5745                                 elmThumb   = Util.getElementsByClassName( elm, 'file-icon' )[ 0 ].firstChild,
5746                                 elmName    = Util.getElementsByClassName( elm, 'finder-detail-filename' )[ 0 ],
5747                                 elmDesc    = Util.getElementsByClassName( elm, 'finder-detail-summary' )[ 0 ],
5748                                 tmpButtons = Util.copyArray( this.appButtons ),
5749                                 apps, app, elmContainer;
5750                         if( thumb.image ){
5751                                 elmThumb.className = 'has-thumbnail';
5752                                 elmThumb.style.backgroundImage = [ 'url(', thumb.image, ')' ].join( '' );
5753                         } else {
5754                                 elmThumb.className = thumb.className;
5755                                 elmThumb.style.backgroundImage = '';
5756                         };
5757                         
5758                         elmName.firstChild.data = file.getName();
5759                         elmDesc.firstChild.data = file.getSummary();
5760                         this.node.width( this.nodeRoot.width() );
5761                         this.node.height( this.nodeRoot.height() );
5762                         
5763                         this.appButtons.length = 0;
5764                         
5765                         apps         = file.viewerApplicationList();
5766                         elmContainer = Util.getElementsByClassName( elm, 'viewer-apps' )[ 0 ];
5767                         for( i = 0; i < apps.length; ++i ){
5768                                 button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton();
5769                                 button.init( this.ui, elmContainer, apps[ i ], file );
5770                                 this.appButtons.push( button );
5771                         };
5772                         apps         = file.editorApplicationList();
5773                         elmContainer = Util.getElementsByClassName( elm, 'editor-apps' )[ 0 ];
5774                         for( i = 0; i < apps.length; ++i ){
5775                                 button = 0 < tmpButtons.length ? tmpButtons.shift() : new ApplicationButton();
5776                                 button.init( this.ui, elmContainer, apps[ i ], file );
5777                                 this.appButtons.push( button );
5778                         };
5779                         
5780                         while( button = tmpButtons.shift() ) button.destroy();
5781                         
5782                         this.resize();
5783                 },
5784                 pan : function(){
5785                         var page = this,
5786                                 x    = page.currentX = easeOutQuad( page.panTime, page.startX, page.offsetX, page.panTotalTime );
5787                         // page.elm.style.left = x + 'px';
5788                         this.node.x( x );
5789                         if( page.panTotalTime < ++page.panTime ){
5790                                 delete page.panTime;
5791                                 delete page.startX;
5792                                 delete page.offsetX;                                    
5793                                 delete page.panTotalTime;
5794                                 delete page.sliding;
5795                                 if( this.isPanOut === true ) this.elm.style.display = 'none';
5796                         };
5797                 },
5798                 onScroll : function(){
5799                         
5800                 },
5801                 resize : function(){
5802                         this.elmScroll.style.height = this.nodeRoot.height() + 'px';
5803                 },
5804                 destroy : function(){
5805                         var button;
5806                         while( button = this.appButtons.shift() ) button.destroy();
5807                         this.ui.destroy();
5808                         this.node.remove();
5809                 }
5810         });
5811         
5812 /**
5813  * FinderPrivateData
5814  */
5815         var FinderPrivateData = Class.create(
5816                 Class.PRIVATE_DATA, {
5817                 finder       : null,
5818                 apiuser      : null,
5819                 elmRoot      : null,
5820                 nodeRoot     : null,
5821                 elmScroll    : null,
5822                 elmPath      : null,
5823                 nodePath     : null,
5824                 tree         : null,
5825                 onSelect     : null,
5826                 viewerOption : null,
5827                 editorOption : null,
5828                 pathList     : null,
5829                 headH        : 0,
5830                 iconW        : 0,
5831                 iconH        : 0,
5832                 style        : 0,
5833                 pageIcons1   : null,
5834                 pageIcons2   : null,
5835                 panInPage    : null,
5836                 panOutPage   : null,
5837                 pageDetail   : null,
5838                 currentFile  : null,
5839                 Constructor : function( finder, apiuser, elm, tree, onSelect, viewerOption, editorOption ){
5840                         this.finder       = finder;
5841                         this.apiuser      = apiuser;
5842                         if( PointingDeviceEventTree.isNodeInstance( elm ) === true ){
5843                                 this.nodeRoot = elm;
5844                                 this.elmRoot  = PointingDeviceEventTree._getNodePrivateData( elm ).elm;
5845                         } else {
5846                                 // App が eventTree を持っている?
5847                                 // App が eventTree を持っていない
5848                                 this.elmRoot  = elm;
5849                         };
5850                         this.nodeRoot.addEventListener( 'click', this.onIconClick, this );
5851                         this.nodeRoot.addEventListener( 'scroll', this.onScroll, this );
5852                         
5853                         this.elmScroll    = document.createElement( 'div' );
5854                         this.elmRoot.appendChild( this.elmScroll );
5855                         this.elmScroll.className     = 'finder-elm-scroll';
5856                         this.elmScroll.style.cssText = 'width:100%;overflow:hidden;';
5857                         
5858                         this.tree         = tree;
5859                         this.onSelect     = onSelect;
5860                         this.viewerOption = viewerOption;
5861                         this.editorOption = editorOption;
5862                         
5863                         var size          = Util.getElementSize( ELM_ORIGIN_FINDER_ICON );
5864                         this.iconW        = size.width;
5865                         this.iconH        = size.height;
5866                         
5867                         tree.addTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw, this );
5868                         Util.addClass( this.elmRoot, 'finder-body' );
5869                         
5870                         if( this.panInPage === null ){
5871                                 this.pageIcons1 = new PageClass();
5872                                 this.pageIcons2 = new PageClass();
5873                                 this.pageDetail = new DetailPageClass();
5874                         };
5875                         this.pageIcons1.init( this.nodeRoot, this.elmRoot, this.elmScroll );
5876                         this.pageIcons2.init( this.nodeRoot, this.elmRoot, this.elmScroll );
5877                         this.pageDetail.init( this );
5878                 },
5879                 onIconClick : function( e ){
5880                         if( this.panInPage === this.pageDetail ) return;
5881                         
5882                         var target = e.target,
5883                                 list   = this.panInPage.iconList,
5884                                 i, icon,
5885                                 file;
5886                         if( target === this.nodeRoot ) return;
5887                         for( i = list.length; i; ){
5888                                 icon = list[ --i ];
5889                                 if( icon.node === target ){
5890                                         i = icon._index;
5891                                         file = this.currentFile.getChildFileAt( i );
5892                                         if( target.width() - 30 < e.layerX ){
5893                                                 this.tree.down( i );
5894                                                 this.draw( this.w, this.h, 1, true );
5895                                         } else
5896                                         if( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER ){
5897                                                 this.tree.down( i );
5898                                                 this.draw( this.w, this.h, 1 );
5899                                         } else
5900                                         if( Type.isFunction( this.onSelect ) === true ){ /* && this.onSelect( file ) === true */
5901                                                 this.onSelect( file );
5902                                         } else {
5903                                                 this.tree.down( i );
5904                                                 this.draw( this.w, this.h, 1 );
5905                                         };
5906                                         file.destroy();
5907                                         break;
5908                                 };
5909                         };
5910                 },
5911                 onScroll : function( e ){
5912                         this.panInPage.onScroll( e );
5913                 },
5914                 onPathClick : function( e ){
5915                         var target = e.target,
5916                                 i      = target.nodeIndex();
5917                         if( target === this.nodePath || this.nodePath.numNode() - 1 === i ) return;
5918                         this.tree.up( i );
5919                         this.draw( this.w, this.h, -1 );
5920                 },
5921                 draw : function( w, h, way, showDetail ){
5922                         var data = this, page;
5923                         data.w = w = Type.isFinite( w ) === true ? w : data.w;
5924                         data.h = h = Type.isFinite( h ) === true ? h : data.h;
5925                         
5926                         var file     = this.currentFile = this.tree.getCurrentFile(),
5927                                 isFolder = showDetail !== true && ( file.getChildFileLength() !== -1 || file.getType() === Const.FILE.TYPE.FOLDER );
5928                         
5929                         data.elmPath && data.drawPath( w );
5930                         page = this.panInPage;
5931                         if( Type.isNumber( way ) === true ){
5932                                 if( page.sliding === false ){
5933                                         if( isFolder === true ){
5934                                                 this.panInPage = page === this.pageIcons1 ? this.pageIcons2 : ( page === this.pageIcons2 ? this.pageIcons1 : this.panOutPage );
5935                                         } else {
5936                                                 this.panInPage = this.pageDetail;
5937                                         };
5938                                         this.panOutPage = page;
5939                                 };
5940                                 this.panInPage.panInReady( way );
5941                                 //this.panInPage.elm.className = 'panIN';
5942                                 this.panOutPage.panOutReady( way );
5943                                 //this.panOutPage.elm.className = 'panOut';
5944                                 this.nodeRoot.disabled( true );
5945                                 SystemTimer.add( this.apiuser, this.tick, 16, false, this );
5946                         } else {
5947                                 if( isFolder === true ){
5948                                         this.panInPage = page === null ? this.pageIcons1 : page;
5949                                 } else {
5950                                         this.panInPage = this.pageDetail;
5951                                 };
5952                         };
5953                         this.panInPage.draw( file );
5954                         
5955                         data.nodeRoot.invalidateScrollbar();
5956                 },
5957                 tick : function(){
5958                         if( this.panInPage.sliding === false && this.panOutPage.sliding === false ){
5959                                 SystemTimer.remove( this.apiuser, this.tick );
5960                                 this.nodeRoot.disabled( false );
5961                                 this.nodeRoot.invalidateScrollbar();
5962                                 return;
5963                         };
5964                         this.panInPage.sliding === true && this.panInPage.pan();
5965                         this.panOutPage.sliding  === true && this.panOutPage.pan();
5966                 },
5967                 drawPath : function( w ){
5968                         if( !this.elmPath.parentNode ) return;
5969                         w = this.nodePath.width();
5970                         var data      = this,
5971                                 tree      = data.tree,
5972                                 pathList  = data.pathList,
5973                                 i         = 0,
5974                                 l         = tree.hierarchy() + 1,
5975                                 m         = pathList.length,
5976                                 wList     = [],
5977                                 totalW    = 0,
5978                                 minW      = FinderPrivateData.MIN_PATH_WIDTH,
5979                                 file, path, pathW, offset, remove, pathX = 0, fit = false;
5980                         
5981                         for( ; i < l; ++i ){
5982                                 file = i !== l - 1 ? tree.getParentFileAt( i ) : this.currentFile;
5983                                 if( i < m ){
5984                                         pathList[ i ].init( this, file, i );
5985                                 } else {
5986                                         pathList.push( PathClass.get( this, file, i ) );
5987                                 };
5988                         };
5989                         while( l < pathList.length ) pathList.pop().destroy();
5990                         
5991                         for( i = l; i; ){
5992                                 pathW = pathList[ --i ].textWidth();
5993                                 wList.push( pathW );
5994                                 totalW += pathW;
5995                         };
5996                         
5997                         //if( minW * ( l + 1 ) * 1.2 < w ){
5998                                 console.log( totalW + ' , ' + w )
5999                                 while( true ){
6000                                         if( fit === true ) break;
6001                                         for( i = 0; i < l; ++i ){
6002                                                 offset = totalW - w;
6003                                                 if( offset <= 0 ){
6004                                                         fit = true;
6005                                                         break;
6006                                                 };
6007                                                 remove = l - i;
6008                                                 remove = offset < remove ? offset : remove;
6009                                                 pathW  = wList[ i ];
6010                                                 if( pathW - remove < minW ){
6011                                                         totalW -= ( pathW - minW );
6012                                                         wList[ i ] = minW;
6013                                                 } else {
6014                                                         wList[ i ] = pathW - remove;
6015                                                         totalW -= remove;
6016                                                 };
6017                                         };
6018                                 };
6019                                 for( i = 0; i < l; ++i ){
6020                                         path  = pathList[ i ];
6021                                         pathW = wList[ i ];
6022                                         path.update( pathX, pathW );
6023                                         pathX += pathW;
6024                                 };                      
6025                         //} else {
6026                                 
6027                         //};
6028                 },
6029                 createPath : function( node ){
6030                         if( this.elmPath ) return;
6031                         
6032                         if( PointingDeviceEventTree.isNodeInstance( node ) === true ){
6033                                 this.nodePath = node;
6034                                 this.elmPath  = PointingDeviceEventTree._getNodePrivateData( node ).elm;
6035                                 
6036                                 node.addEventListener( 'click', this.onPathClick, this );
6037                                 Util.addClass( this.elmPath, 'finder-path' );
6038                                 // this.elmPath  = document.createElement( 'div' );
6039                                 // this.elmPath.className = ;
6040                                 this.pathList = [];
6041                                 // this.headH    = 0;
6042                                 AsyncCall.add( this.apiuser, this.draw, null, this );
6043                         };
6044                 },
6045                 onKill : function(){
6046                         this.tree.removeTreeEventListener( Const.TREE.EVENT.UPDATE, this.draw );
6047
6048                         if( this.pathList ){
6049                                 while( this.pathList.length > 0 ) this.pathList.shift().destroy();
6050                         };
6051                         
6052                         this.pageIcons1.destroy();
6053                         this.pageIcons2.destroy();
6054                         this.pageDetail.destroy();
6055                         this.nodeRoot.remove();
6056                         
6057                         FINDER_LIST.splice( Util.getIndex( FINDER_LIST, this.finder ), 1 );
6058                         var data = ApplicationPrivateData.get( this.apiuser ),
6059                                 list = data.finderList,
6060                                 i    = Util.getIndex( list, this.finder );
6061                         i !== -1 && list.splice( i, 1 );
6062                 }
6063         });
6064         FinderPrivateData.MIN_PATH_WIDTH = 25;
6065
6066 /**
6067  * FinderClass
6068  */
6069         var Finder = Class.create(
6070                 FinderPrivateData, {
6071                 Constructor : function( application, elmRoot, tree, onSelect, viewerOption, editorOption ){
6072                         Finder.newPrivateData( this, this, application, elmRoot, tree, onSelect, viewerOption, editorOption );
6073                 },
6074                 MIN_WIDTH  : 200,
6075                 MIN_HEIGHT : 200,
6076                 resize : function( w, h ){
6077                         var data = Finder.getPrivateData( this );
6078                         data.panInPage && data.panInPage.resize( w );
6079                 },
6080                 createPath : function( node ){
6081                         return Finder.getPrivateData( this ).createPath( node );
6082                 },
6083                 destroy : function(){
6084                         this.kill();
6085                 }
6086         });
6087
6088         return {
6089                 init: function(){
6090                         
6091                 },
6092                 create: function( application, elmTarget, tree, onSelect, viewerOption, editorOption ){
6093                         //if( Application.isApplicationInstance( _application ) === false ) return;
6094                         
6095                         var finder = new Finder( application, elmTarget, tree, onSelect, viewerOption, editorOption );
6096                         FINDER_LIST.push( finder );
6097                         return finder;
6098                 },
6099                 registerFinderHead: function(){
6100                         
6101                 },
6102                 registerFinderPane: function( _finderPane ){
6103                         
6104                 },
6105                 isFinderInstance: function( _finder ){
6106                         return _finder instanceof Finder;
6107                 },
6108                 isFinderPaneInstance: function(){
6109                         
6110                 },
6111                 isFinderHeadInstance: function(){
6112                 }
6113         };
6114 })();
6115
6116
6117 /*
6118  * -- len, %
6119  * marginBottom, marginLeft, marginRight, marginTop, margin
6120  * padding, paddingBottom, paddingLeft, paddingRight, paddingTop
6121  * fontSize, textIndent
6122  * height, width
6123  * bottom, left, right, top                     (len, %)
6124  *
6125  * -- len
6126  * borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderWidth,
6127  * letterSpacing
6128  *
6129  * -- color
6130  * backgroundColor
6131  * borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor
6132  * color
6133  *
6134  * -- special
6135  * clip                 rect(0px, 40px, 40px, 0px);
6136  * backgroundPosition   (len, %)
6137  * opacity
6138  * lineHeight           (len, %, num)
6139  * zIndex                       ( order )
6140  */
6141
6142 var DHTML = ( function(){
6143         
6144         var TICKET_ARRAY = [],
6145                 fpms         = 50,
6146                 round        = Math.round,
6147                 cround       = function( v ){ return round( v * 100 ) / 100 };
6148         
6149         function startAnimation( _elm, _cssObject, _onComplete, _onEnterFrame, _numFrames ){
6150                 var _ticket, i = TICKET_ARRAY.length;
6151                 for( ; i; ){
6152                         _ticket = TICKET_ARRAY[ --i ];
6153                         if( _ticket.elm === _elm ){
6154                                 return;
6155                         };
6156                 };
6157                 
6158                 var _currentValues     = [],
6159                         _offsetValues      = [],
6160                         _endValues         = [],
6161                         _targetProperties  = [],
6162                         _units             = [];
6163                 var target, current,
6164                         inlineStyle    = CSS.getInlineStyle( _elm ),
6165                         currentStyle   = CSS.getWrappedStyle( _elm ),
6166                         targetStyle    = CSS.getWrappedStyle( _elm, _cssObject );
6167                         targetStyle.pxPerEm = currentStyle.get( 'fontSize' )._toPx();
6168                 for( var p in _cssObject ){
6169                         p       = Util.camelize( p );
6170                         target  = targetStyle.get( p );
6171                         current = currentStyle.get( p );
6172
6173                         if( target.isValid() === false || current.isValid() === false || current.equal( target ) !== false ){
6174                                 target.clear();
6175                                 current.clear();
6176                                 continue;
6177                         };
6178                         
6179                         current.convert( target );
6180                         // alert( current.getValue() + ' , ' + target.getValue() )
6181                         _currentValues.push( current.getValue() );
6182                         _offsetValues.push( current.getOffset( target ) );
6183                         _endValues.push( target.getValue() );
6184                         _targetProperties.push( p );
6185                         _units.push( target.getUnit() );
6186
6187                         // IE has trouble with opacity if it does not have layout
6188                         // Force it by setting the zoom level                   
6189                         if( p === 'opacity' && SPECIAL.hasLayout ){
6190                                 if( SPECIAL.hasLayout( _elm ) === false ) inlineStyle.zoom = 1;
6191                                 inlineStyle.filter = current.getValueText();
6192                         } else {
6193                                 inlineStyle[ p ]   = current.getValueText();
6194                         };
6195                         
6196                         target.clear();
6197                         current.clear();
6198                 };
6199                 
6200                 var i, cssTexts = [];
6201                 for( i = 0; i < _numFrames; ++i ){
6202                         if( i < _numFrames - 1 ){
6203                                 tickValue( _currentValues, _offsetValues, _numFrames );
6204                                 cssTexts.push( createCssText( _currentValues, _targetProperties, targetStyle, inlineStyle ) );
6205                         } else {
6206                                 cssTexts.push( createCssText( _endValues, _targetProperties, targetStyle, inlineStyle ) );
6207                         };
6208                 };
6209                 
6210                 TICKET_ARRAY.push( new AnimationTaskClass(
6211                         _elm, cssTexts,
6212                         Type.isFunction( _onComplete ) === true   ? _onComplete   : null,
6213                         Type.isFunction( _onEnterFrame ) === true ? _onEnterFrame : null,
6214                         _numFrames
6215                 ) );
6216                 
6217                 currentStyle.clear();
6218                 targetStyle.clear();            
6219                 SystemTimer.add( SUPER_USER_KEY, onEnterFrame, 1000 / fpms );
6220         };
6221         
6222         function tickValue( current, offset, numFrames ){
6223                 if( Type.isArray( current ) === true ){
6224                         var ret, i = current.length;
6225                         for( ; i; ){
6226                                 --i;
6227                                 ret = tickValue( current[ i ], offset[ i ], numFrames );
6228                                 if( Type.isNumber( ret ) === true ) current[ i ] = ret;
6229                         };
6230                 } else {
6231                         return current + offset / numFrames;
6232                 };
6233         };
6234         function createCssText( update, props, style, inline ){
6235                 var prop;
6236                 for( var i = props.length; i; ){
6237                         prop = style.get( props[ --i ] );
6238                         prop.setValue( update[ i ] );
6239                         inline[ Util.uncamelize( prop.name ) ] = prop.getValueText();
6240                         //if( prop.name === 'backgroundColor' ) alert( prop.getValueText() + '|' + update[ i ].join( ',') )
6241                         prop.clear();
6242                 };
6243                 return CSS.toCssText( inline );
6244         };
6245         
6246         function onEnterFrame(){
6247                 var _ticket, l,
6248                         i = 0;
6249                 while( i < TICKET_ARRAY.length ){
6250                         _ticket = TICKET_ARRAY[ i ];
6251                         l       = _ticket.cssTexts.length;
6252                         _ticket.elm.style.cssText = _ticket.cssTexts.shift();
6253                         if( l === 1 ){
6254                                 _ticket.onComplete && _ticket.onComplete();
6255                                 delete _ticket.elm;
6256                                 delete _ticket.cssTexts;
6257                                 delete _ticket.onComplete;
6258                                 delete _ticket.onEnterFrame;
6259                                 delete _ticket.numFrame;
6260                                 TICKET_ARRAY.splice( i, 1 );
6261                         } else {
6262                                 _ticket.onEnterFrame && _ticket.onEnterFrame( l / _ticket.numFrame );
6263                                 ++i;
6264                         };
6265                 };
6266                 if( TICKET_ARRAY.length === 0 ){
6267                         SystemTimer.remove( SUPER_USER_KEY, onEnterFrame );
6268                 };
6269         };
6270         
6271         var AnimationTaskClass = function( elm, cssTexts, onEnterFrame, onComplete, numFrame ){
6272                 this.elm          = elm;
6273                 this.cssTexts     = cssTexts;
6274                 this.onEnterFrame = onEnterFrame;
6275                 this.onComplete   = onComplete;
6276                 this.numFrame     = numFrame;
6277         };
6278         
6279         var VisualEffectClass = function( elm ){
6280                 this.elm = elm;
6281         };
6282         VisualEffectClass.prototype = {
6283                 anime : function( _cssObject, _onComplete, _onEnterFrame, _time ){
6284                         var _numFrames = Math.floor( _time / fpms );
6285                         startAnimation( this.elm, _cssObject, _onComplete, _onEnterFrame, _numFrames );
6286                 },
6287                 fadeIn : function(){
6288                         
6289                 },
6290                 fadeOut : function(){
6291                         
6292                 },
6293                 update : function( x, y, w, h ){
6294                         var _cssText = this.elm.style.cssText;
6295                 }
6296         };
6297         
6298         return {
6299                 create: function( application, _elm ){
6300                         return new VisualEffectClass( _elm );
6301                 },
6302                 isInstanceOfVisualEffect: function( _instance){
6303                         return _instance instanceof VisualEffectClass;
6304                 }
6305         }
6306 })();
6307
6308
6309 /* --------------------------------------------
6310  * 
6311  */
6312
6313         Application.onCurrentApplicationChange( SUPER_USER_KEY );
6314         
6315         SERVICE_LIST.push( MouseEvent );
6316         
6317         new EventTicketClass( window, 'unload', function(){
6318                 var _service;
6319                 while( SERVICE_LIST.length > 0 ){
6320                         _service = SERVICE_LIST.shift();
6321                         Type.isFunction( _service.onSystemShutdown ) === true && _service.onSystemShutdown();
6322                 }
6323         });
6324         // beforeunload
6325
6326
6327 /* ---------------------------------------------
6328  * broadcast to global
6329  */
6330         window.gOS = {};
6331         
6332         gOS.registerApplication = Application.register;
6333         gOS.registerDriver      = File.registerDriver;
6334         
6335 var BoxModel
6336
6337 var DOM = ( function( window, document ){
6338         var DIV_LIST  = [],
6339                 SPAN_LIST = [],
6340                 TEXT_LIST = [];
6341         
6342         var elmTextSize;
6343         
6344         function correctNodes( node ){
6345                 var child;
6346                 if( node && node.parentNode ){
6347                         while( node.lastChild ) correctNodes( node.lastChild );
6348                         node.parentNode.removeChild( node );
6349                         if( node.nodeType === 1 ){
6350                                 switch( node.tagName ){
6351                                         case 'DIV':
6352                                                 DIV_LIST.push( node );
6353                                                 break;
6354                                         case 'SPAN':
6355                                                 SPAN_LIST.push( node );
6356                                                 break;
6357                                         
6358                                 };
6359                                 node.removeAttribute( 'className' );
6360                                 node.removeAttribute( 'style' );
6361                                 node.removeAttribute( 'id' );
6362                         } else
6363                         if( node.nodeType === 3 ){
6364                                 node.data = '';
6365                                 TEXT_LIST.push( node );
6366                         };
6367                 };
6368         };
6369         
6370         return {
6371                 createDiv : function(){
6372                         return 0 < DIV_LIST.length ? DIV_LIST.shift() : document.createElement( 'div' );
6373                 },
6374                 createSpan : function(){
6375                         
6376                 },
6377                 createText : function(){
6378                         
6379                 },
6380                 getTextSize : function( elm, content ){
6381                         var span = DOM.createSpan(),
6382                                 text = DOM.createText(),
6383                                 w, h;
6384                         elm.appendChild( span );
6385                         span.style.cssText = 'visibility:hidden;position:absolute;';
6386                         span.appendChild( text );
6387                         text.data = content;
6388                         w = span.offsetWidth;
6389                         h = span.offsetHeight;
6390                         DOM.correctNodes( span );
6391                         return [ w, h ];
6392                 },
6393                 correctNodes : function( node ){
6394                         var child;
6395                         if( node && node.parentNode ){
6396                                 while( node.lastChild ) DOM.correctNodes( node.lastChild );
6397                                 node.parentNode.removeChild( node );
6398                                 if( node.nodeType === 1 ){
6399                                         switch( node.tagName ){
6400                                                 case 'DIV':
6401                                                         DIV_LIST.push( node );
6402                                                         break;
6403                                                 case 'SPAN':
6404                                                         SPAN_LIST.push( node );
6405                                                         break;
6406                                                 
6407                                         };
6408                                         node.removeAttribute( 'className' );
6409                                         node.removeAttribute( 'style' );
6410                                         node.removeAttribute( 'id' );
6411                                 } else
6412                                 if( node.nodeType === 3 ){
6413                                         node.data = '';
6414                                         TEXT_LIST.push( node );
6415                                 };
6416                         };
6417                 }
6418         }
6419 })( window, document );
6420
6421 var XBrowserStyle = ( function(){
6422         var     EMPTY          = '',
6423                 CORON          = ':',
6424                 SEMICORON      = ';',
6425                 SPACE          = ' ',
6426                 UNITS          = 'px,cm,mm,in,pt,pc,em,%'.split( ',' ),
6427                 CLIP_SEPARATOR = UA.isIE === true && UA.ieVersion < 8 ? ' ' : ',';
6428
6429         var SPECIAL = ( function(){
6430                 var special = {};
6431                 if( UA.isIE === true && UA.ieVersion < 9 ){
6432                         if( UA.ACTIVEX === true ){
6433                                 // special.opacity    = 'ActiveXOpacity';
6434                                 special.setFilters = function( style ){
6435                                         var filters = ( style.filter || '' ).split( ') ' ),
6436                                                 data    = {},
6437                                                 i       = filters.length,
6438                                                 filter, names, props, prop, j, l, key, v;
6439                                         for( ; i; ){
6440                                                 filter   = filters[ --i ].split( ' ' ).join( '' ).split( '(' );
6441                                                 if( filter.length !== 2 ) continue;
6442                                                 names    = filter[ 0 ].split( '.' ); // progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=120,strength=9)
6443                                                 props    = filter[ 1 ].split( ',' ); // 
6444                                                 filter   = {};
6445                                                 for( j = 0, l = props.length; j < l; ++j ){
6446                                                         prop = props[ j ].split( '=' );
6447                                                         key  = prop[ 0 ].toLowerCase();
6448                                                         v    = prop[ 1 ];
6449                                                         filter[ key ] = v; //v.charAt( 0 ) === '#' ? v : parseInt( v );
6450                                                 };
6451                                                 data[ names[ names.length - 1 ] ] = filter;
6452                                         };
6453                                         
6454                                         style.filter  = data;
6455                                         style.opacity = data.alpha && data.alpha.opacity ? data.alpha.opacity / 100 : 1;
6456                                 };
6457                                 special.hasLayout = function( elm ){
6458                                         return elm.currentStyle.hasLayout;
6459                                 };
6460                         } else {
6461                                 special.opacity = null;
6462                         };
6463                 } else {
6464                         var style = document.documentElement.style;
6465                         special.opacity = style.opacity           !== undefined ? 'opacity' : 
6466                                                         style.MozOpacity          !== undefined ? 'MozOpacity' :
6467                                                         style.KhtmlOpacity        !== undefined ? 'KhtmlOpacity' :
6468                                                         style[ '-khtml-opacity' ] !== undefined ? 'KhtmlOpacity' : null;
6469
6470                         // if( style.backgroundPositionX === undefined ){
6471                                 special.setBackgroundPositionXY = function( style ){
6472                                         var bgp = ( style.backgroundPosition || '' ).split( ' ' );
6473                                         style.backgroundPositionX = bgp[ 0 ] || 0;
6474                                         style.backgroundPositionY = bgp[ 1 ] || 0;
6475                                 };
6476                         // };
6477                         if( style.clipTop === undefined && style[ 'clip-top' ] === undefined ){
6478                                 special.setClipTopRightBottomLeft = function( style ){
6479                                         var clip = style.clip;
6480                                         if( !cliop || clip.indexOf( 'rect(' ) === -1 ){
6481                                                 style.clipTop    = 0;
6482                                                 style.clipRight  = 0;
6483                                                 style.clipBottom = 0;
6484                                                 style.clipLeft   = 0;
6485                                                 return;
6486                                         };
6487                                         clip = clip.split( '(' )[ 1 ].split( ')' )[ 0 ].split( clip.indexOf( ',' ) !== -1 ? ',' : ' ' );
6488                                         ret.clipTop    = clip[ 0 ];
6489                                         ret.clipRight  = clip[ 1 ];
6490                                         ret.clipBottom = clip[ 2 ];
6491                                         ret.clipLeft   = clip[ 3 ];
6492                                 };
6493                         };
6494                 };
6495                 return special;
6496         })();
6497         
6498         function cssToObject( css ){
6499                 var ret      = {}, i, nv, n, v,
6500                         parse    = Util.parse,
6501                         isNumber = Type.isNumber,
6502                         camelize = Util.camelize;
6503                 if( Type.isString( css ) === true ){
6504                         css = css.split( SEMICORON );
6505                         for( i = css.length; i; ){
6506                                 nv = css[ --i ].split( CORON ); // filter の場合, progid: がくる
6507                                 n  = nv.shift();
6508                                 if( isNumber( parse( n ) ) === true ) continue;
6509                                 v  = nv.join( EMPTY );
6510                                 while( v.charAt( 0 ) === ' ' ) v = v.substr( 1 );
6511                                 ret[ camelize( n ) ] = parse( v );
6512                         };
6513                 } else {
6514                         for( n in css ){
6515                                 if( Type.isNumber( parse( n ) ) === false ) ret[ n ] = parse( css[ n ] );
6516                         };
6517                 };
6518
6519                 if( SPECIAL.setFilters ){
6520                         SPECIAL.setFilters( ret );
6521                 } else {
6522                         ret.opacity = SPECIAL.opacity !== null ? ret[ SPECIAL.opacity ] : 1;
6523                 };
6524                 
6525                 SPECIAL.setBackgroundPositionXY && SPECIAL.setBackgroundPositionXY( ret );
6526                 SPECIAL.setClipTopRightBottomLeft && SPECIAL.setClipTopRightBottomLeft( ret );
6527                 
6528                 return ret;
6529         };
6530
6531         var COLOR = ( function(){
6532                 var ret = {}, v, name,
6533                         list = [
6534                                 '0', 'BLACK',
6535                                 'FF0000', 'RED',
6536                                 '00FF00', 'LIME',
6537                                 '0000FF', 'BLUE',
6538                                 'FFFF00', 'YELLOW',
6539                                 '00FFFF', 'AQUA',
6540                                 '00FFFF', 'CYAN',
6541                                 'FF00FF', 'MAGENTA',
6542                                 'FF00FF', 'FUCHSIA',
6543                                 'FFFFFF', 'WHITE',
6544                                 '008000', 'GREEN',
6545                                 '800080', 'PURPLE',
6546                                 '800000', 'MAROON',
6547                                 '000080', 'NAVY',
6548                                 '808000', 'OLIVE',
6549                                 '008080', 'TEAL',
6550                                 '808080', 'GRAY',
6551                                 'C0C0C0', 'SILVER',
6552                                 '696969', 'DIMGRAY',
6553                                 '708090', 'SLATEGRAY',
6554                                 'A9A9A9', 'DARKGRAY',
6555                                 'DCDCDC', 'GAINSBORO',
6556                                 '191970', 'MIDNIGHTBLUE',
6557                                 '6A5ACD', 'SLATEBLUE',
6558                                 '0000CD', 'MEDIUMBLUE',
6559                                 '4169E1', 'ROYALBLUE',
6560                                 '1E90FF', 'DODGERBLUE',
6561                                 '87CEEB', 'SKYBLUE',
6562                                 '4682B4', 'STEELBLUE',
6563                                 'ADD8E6', 'LIGHTBLUE',
6564                                 'AFEEEE', 'PALETURQUOISE',
6565                                 '40E0D0', 'TURQUOISE',
6566                                 'E0FFFF', 'LIGHTCYAN',
6567                                 '7FFFD4', 'AQUAMARINE',
6568                                 '006400', 'DARKGREEN',
6569                                 '2E8B57', 'SEAGREEN',
6570                                 '90EE90', 'LIGHTGREEN',
6571                                 '7FFF00', 'CHARTREUSE',
6572                                 'ADFF2F', 'GREENYELLOW',
6573                                 '32CD32', 'LIMEGREEN',
6574                                 '9ACD32', 'YELLOWGREEN',
6575                                 '6B8E23', 'OLIVEDRAB',
6576                                 'BCB76B', 'DARKKHAKI',
6577                                 'EEE8AA', 'PALEGOLDENROD',
6578                                 'FFFFE0', 'LIGHTYELLOW',
6579                                 'FFD700', 'GOLD',
6580                                 'DAA520', 'GOLDENROD',
6581                                 'B8860B', 'DARKGOLDENROD',
6582                                 'BC8F8F', 'ROSYBROWN',
6583                                 'CD5C5C', 'INDIANRED',
6584                                 '8B4513', 'SADDLEBROWN',
6585                                 'A0522D', 'SIENNA',
6586                                 'CD853F', 'PERU',
6587                                 'DEB887', 'BURLYWOOD',
6588                                 'F5F5DC', 'BEIGE',
6589                                 'F5DEB3', 'WHEAT',
6590                                 'F4A460', 'SANDYBROWN',
6591                                 'D2B48C', 'TAN',
6592                                 'D2691E', 'CHOCOLATE',
6593                                 'B22222', 'FIREBRICK',
6594                                 'A52A2A', 'BROWN',
6595                                 'FA8072', 'SALMON',
6596                                 'FFA500', 'ORANGE',
6597                                 'FF7F50', 'CORAL',
6598                                 'FF6347', 'TOMATO',
6599                                 'FF69B4', 'HOTPINK',
6600                                 'FFC0CB', 'PINK',
6601                                 'FF1493', 'DEEPPINK',
6602                                 'DB7093', 'PALEVIOLETRED',
6603                                 'EE82EE', 'VIOLET',
6604                                 'DDA0DD', 'PLUM',
6605                                 'DA70D6', 'ORCHILD',
6606                                 '9400D3', 'DARKVIOLET',
6607                                 '8A2BE2', 'BLUEVIOLET',
6608                                 '9370DB', 'MEDIUMPURPLE',
6609                                 'D8BFD8', 'THISTLE',
6610                                 'E6E6FA', 'LAVENDER',
6611                                 'FFE4E1', 'MISTYROSE',
6612                                 'FFFFF0', 'IVORY',
6613                                 'FFFACD', 'LEMONCHIFFON'
6614                         ];
6615                 for( i = list.length; i; ){
6616                         v    = list[ --i ];
6617                         name = list[ --i ];
6618                         ret[ name ] = parseInt( v, 16 );
6619                 };
6620                 return ret;
6621         })();
6622         
6623         var PARAMS = ( function(){
6624                 var ret = {};
6625                 register( ret.percent = {},
6626                         'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent'
6627                 );
6628                 register( ret.offset = {},
6629                         'height,width,bottom,left,right,top'
6630                 );              
6631                 register( ret.size = {},
6632                         'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing'
6633                 );
6634                 register( ret.color = {},
6635                         'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color'
6636                 );
6637                 register( ret.region = {},
6638                         'margin,padding,borderWidth,borderColor'
6639                 );              
6640                 register( ret.special = {},
6641                         'clip,backgroundPosition,opacity,lineHeight,zIndex'
6642                 );
6643                 register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' );
6644                 
6645                 register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' );
6646                 register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' );
6647                 register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' );
6648                 register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' );
6649                 
6650                 function register( obj, params ){
6651                         params = params.split( ',' );
6652                         for( var i=params.length; i; ) obj[ params[ --i ] ] = true;
6653                 };
6654                 return ret;
6655         })();
6656         
6657         /*
6658          * 
6659          */
6660         var Property = Class.create(
6661                 'Property',
6662                 Class.POOL_OBJECT,
6663                 {
6664                         Constructor : function( name, value, unit, pxPerEm ){
6665                                 this.name    = name;
6666                                 this.value   = value;
6667                                 this.unit    = unit;
6668                                 this.pxPerEm = pxPerEm; // XXpx = 1em;
6669                         },
6670                         name    : '',
6671                         value   : 0,
6672                         pxPerEm : 12, // 1em === ??px
6673                         unit    : '',
6674                         equal : function( prop ){
6675                                 if( this.unit === prop.unit ){
6676                                         return this.value === prop.value;
6677                                 };
6678                                 return Math.abs( this.toPx() - prop.toPx() ) < 1;
6679                         },
6680                         convert: function( prop ){
6681                                 var u = prop.unit, v;
6682                                 if( this.unit === u ) return;
6683                                 this.value = v = this.toPx();
6684                                 this.unit  = u;
6685                                 if( u !== px ){
6686                                         this.value = u === 'em' ? v / this.pxPerEm : Util.pxTo( v, u );
6687                                 };
6688                         },
6689                         setValue: function( v ){
6690                                 this.value = v;
6691                         },
6692                         getValue: function(){
6693                                 return this.value;
6694                         },
6695                         getOffset: function( prop ){
6696                                 return prop.value - this.value;
6697                         },
6698                         getUnit: function(){
6699                                 return this.unit;
6700                         },
6701                         getValueText: function(){
6702                                 return this.value === 0 ? '0' : this.value + this.unit;
6703                         },
6704                         toPx: function(){
6705                                 var v = this.value, u = this.unit;
6706                                 if( u === px )   return v;
6707                                 if( u === 'em' ) return v * this.pxPerEm;
6708                                 if( u === '' && this.name === 'lineHeight' ) return v * this.pxPerEm;
6709                                 return Util.toPx( v, u );
6710                         },
6711                         isValid: function( t ){
6712                                 t = t || this;
6713                                 var n = t.name,
6714                                         v = t.value,
6715                                         u = t.unit,
6716                                         z = u !== '' ? true : v === 0;
6717                                 if( PARAMS.percent[ n ] === true ) return z;
6718                                 if( PARAMS.offset[ n ] === true  ) return z;
6719                                 if( PARAMS.size[ n ] === true  )   return z && u !== '%';
6720                                 if( PARAMS.special[ n ] === true  ){
6721                                         if( n === 'lineHeight' ) return true;
6722                                         if( n === 'opacity' )    return 0 <= v && v <= 1 && u === '';
6723                                         if( n === 'zIndex'  )    return u === '';
6724                                 };
6725                                 return false;
6726                         }
6727                 }
6728         );
6729         
6730         /**
6731          * backgroundPosition, clip
6732          */
6733         var PropertyGroup = Class.create(
6734                 'PropertyGroup',
6735                 Class.POOL_OBJECT,
6736                 {
6737                         Constructor : function( name ){
6738                                 this.name  = name;
6739                                 this.props = [];
6740                                 for( var i = 1, l = arguments.length; i<l; ++i ){
6741                                         this.props.push( arguments[ i ] );
6742                                 };
6743                         },
6744                         name  : '',
6745                         equal : function( prop ){
6746                                 var ps = this.props, i = ps.length;
6747                                 for( ; i; ){
6748                                         --i;
6749                                         if( ps[ i ].equal( prop[ i ] ) === false ) return false;
6750                                 };
6751                                 return true;
6752                         },
6753                         convert : function( prop ){
6754                                 var ps = this.props, i = ps.length;
6755                                 for( ; i; ){
6756                                         --i;
6757                                         ps[ i ].convert( prop[ i ] );
6758                                 };
6759                         },
6760                         setValue : function( ary ){
6761                                 var ps = this.props, i = 0, l = ps.length;
6762                                 for( ; i<l; ++i ){
6763                                         ps[ i ].setValue( ary[ i ] );
6764                                 };
6765                         },
6766                         getValue : function(){
6767                                 var ret = [], ps = this.props, i = 0, l = ps.length;
6768                                 for( ; i<l; ++i ){
6769                                         ret.push( ps[ i ].getValue() );
6770                                 };
6771                                 return ret;
6772                         },
6773                         getOffset : function( prop ){
6774                                 var ret = [],
6775                                         ps  = this.props,
6776                                         _ps = prop.props,
6777                                         i   = 0,
6778                                         l = ps.length;
6779                                 for( ; i<l; ++i ){
6780                                         ret.push( ps[ i ].getOffset( _ps[ i ] ) );
6781                                 };
6782                                 return ret;
6783                         },
6784                         getUnit : function(){
6785                                 var ret = [], ps = this.props, i = 0, l = ps.length;
6786                                 for( ; i<l; ++i ){
6787                                         ret.push( ps[ i ].getUnit() );
6788                                 };
6789                                 return ret;
6790                         },
6791                         getValueText : function(){
6792                                 var ret = [], ps = this.props, i = 0, l = ps.length;
6793                                 for( ; i<l; ++i ){
6794                                         ret.push( ps[ i ].getValueText() );
6795                                 };                      
6796                                 if( this.name === 'clip' ){
6797                                         return 'rect(' + ret.join( CLIP_SEPARATOR ) + ')';
6798                                 };
6799                                 return ret.join( ' ' );
6800                         },
6801                         onKill : function(){
6802                                 var ps = this.props, i = ps.length;
6803                                 for( ; i; ){
6804                                         ps[ --i ].kill();
6805                                 };
6806                         },
6807                         isValid : function( t ){
6808                                 t = t || this;
6809                                 var ps = t.props, i = ps.length;
6810                                 for( ; i; ){
6811                                         if( ps[ --i ].isValid() === false ) return false;
6812                                 };
6813                                 return true;
6814                         }
6815                 }
6816         );
6817         
6818         /**
6819          * margin, padding, borderWidth, borderColor
6820          */
6821         var FrexibleProperty = PropertyGroup.inherits(
6822                 'FrexibleProperty',
6823                 Class.POOL_OBJECT, {
6824                         Constructor : function( name ){
6825                                 this.name  = name;
6826                                 this.props = [];
6827                                 for( var i = 1, l = arguments.length; i<l; ++i ){
6828                                         this.props.push( arguments[ i ] );
6829                                 };
6830                                 // top, bottom, left, right, topbottom, leftright, all                          
6831                         }
6832                 }
6833         );
6834
6835         var ColorProperty = Class.create(
6836                 'ColorProperty',
6837                 Class.POOL_OBJECT, {
6838                         Constructor : function( name, r, g, b, pct ){
6839                                 this.name = name;
6840                                 this.r    = r;
6841                                 this.g    = g;
6842                                 this.b    = b;
6843                                 this.pct  = pct;
6844                         },
6845                         name  : '',
6846                         equal : function( prop ){
6847                                 if( this.pct === prop.pct ){
6848                                         return this.r === prop.r && this.g === prop.g && this.b === prop.b;
6849                                 };
6850                                 var rgb  = this._toPct(),
6851                                         _rgb = prop._toPct(),
6852                                         i    = rgb.length;
6853                                 for( ; i; ){
6854                                         --i;
6855                                         if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false;
6856                                 };
6857                                 return true;
6858                         },
6859                         convert : function( prop ){
6860                                 var u = prop.pct, x;
6861                                 if( this.pct === u ) return;
6862                                 x = u === true ? 100 / 255 : 2.55;
6863                                 this.r  *= x;
6864                                 this.g  *= x;
6865                                 this.b  *= x;
6866                                 this.pct = u;
6867                         },
6868                         setValue : function( rgb ){
6869                                 this.r = rgb[ 0 ];
6870                                 this.g = rgb[ 1 ];
6871                                 this.b = rgb[ 2 ];
6872                         },
6873                         getValue : function(){
6874                                 return [ this.r, this.g, this.b ];
6875                         },
6876                         getOffset : function( prop ){
6877                                 return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ];
6878                         },
6879                         getUnit : function(){
6880                                 return this.pct === true ? '%' : '';
6881                         },
6882                         getValueText : function(){
6883                                 if( this.pct === true ){
6884                                         return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' );
6885                                 };
6886                                 var round = Math.round;
6887                                 //return [ 'rgb(', round( this.r ), ',', round( this.g ), ',', round( this.b ), ')' ].join( '' );
6888                                 
6889                                 var rgb   = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 );
6890                                 return '#' + rgb.substr( rgb.length - 6 );
6891                         },
6892                         _toPct : function(){
6893                                 if( this.pct === true ) return [ this.r, this.g, this.b ];
6894                                 return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ];
6895                         },
6896                         isValid : function( t ){
6897                                 var isFinite = window.isFinite;
6898                                 if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false;
6899                                 if( 0 > this.r || 0 > this.g || 0 > this.b ) return false;
6900                                 if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100;
6901                                 return this.r <= 255 && this.g <= 255 && this.b <= 255;
6902                         }
6903                 }
6904         );
6905         
6906         var isString       = Type.isString,
6907                 isNumber       = Type.isNumber;
6908         var REG_UINIT      = /.*\d(\w{1,2})?/,
6909                 $1             = '$1',
6910                 px             = 'px',
6911                 REG_XXXXXX     = /^#[\da-fA-F]{6}?/,
6912                 REG_XXX        = /^#[\da-fA-F]{3}?/;
6913         
6914         var WrappedStyle = Class.create(
6915                 'WrappedStyle',
6916                 Class.POOL_OBJECT,
6917                 {
6918                         Constructor : function( style ){
6919                                 this.style   = style;
6920                                 var fontsize = this.get( 'fontSize' );
6921                                 this.pxPerEm = fontsize.toPx();
6922                                 fonstsize.kill();
6923                         },
6924                         get: function( p ){
6925                                 if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){
6926                                         if( p === 'clip' )        return this.getClip();
6927                                         if( p === 'margin' )      return this.getMarginPaddingBorder( p, '' );
6928                                         if( p === 'padding' )     return this.getMarginPaddingBorder( p, '' );
6929                                         if( p === 'borderWidth' ) return this.getMarginPaddingBorder( 'border', 'Width' );
6930                                         if( p === 'borderColor' ) return this.getBorderColor( 'borderColor' );
6931                                         if( p === 'backgroundPosition' ) return this.getBackgroundPosition( p );
6932                                         // opacity, zindex, lineHeight
6933                                         return new Property( p, this.getValue( x ), this.getUnit( x ), this.pxPerEm );
6934                                 };
6935                                 var x = this.style[ p ], e, v, u;
6936                                 if( PARAMS.offset[ p ] === true ){
6937                                         return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm );
6938                                         /*
6939                                         e = this.elm;
6940                                         if( p === 'width'  ) v = e.offsetWidth;
6941                                         if( p === 'height' ) v = e.offsetHeight;
6942                                         if( p === 'top'    ) v = e.offsetTop;
6943                                         if( p === 'bottom' ) v = e.offsetBottom;
6944                                         if( p === 'left'   ) v = e.offsetLeft;
6945                                         if( p === 'right'  ) v = e.offsetRight;
6946                                         u = this.getUnit( x, p );
6947                                         // alert( p + this.pxTo( v, u ) + u )
6948                                         return new Property( p, this.pxTo( v, u ), u, this.pxPerEm ); */
6949                                 };
6950                                 if( p === 'fontSize' ){ // xx-small 等
6951                                         v = Util.absoluteFontSizeToPx( x );
6952                                         if( v !== 0 ){
6953                                                 return new Property( p, v, px, this.pxPerEm );
6954                                         };
6955                                 };                      
6956                                 if( PARAMS.percent[ p ] === true ){
6957                                         // alert( p + ' , ' + x + ' , ' + this.getUnit( x, p ) )
6958                                         return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm );
6959                                 };
6960                                 if( PARAMS.size[ p ] === true ){
6961                                         return new Property( p, this.getValue( x ), this.getUnit( x, p ), this.pxPerEm );
6962                                 };
6963                                 if( PARAMS.color[ p ] === true ){
6964                                         return this.getColor( x, p );
6965                                 };
6966                         },
6967                         pxTo: function( px, unit ){
6968                                 if( unit === 'em' ) return px / this.pxPerEm;
6969                                 return Util.pxTo( px, unit );
6970                         },
6971                         getValue: function( x ){
6972                                 return isString( x ) === true ? parseInt( x ) :
6973                                        isNumber( x ) === true ? x : 0;
6974                         },
6975                         getUnit: function( x, p ){
6976                                 var u;
6977                                 if( isString( x ) === true ){
6978                                         u = x.replace( REG_UINIT, $1 );
6979                                         if( p === 'lineHeight' ) return u;
6980                                         if( PARAMS.unit[ u ] !== true ) return px;
6981                                         return u;
6982                                 };
6983                                 return px;
6984                         },
6985                         getColor: function( x, p ){
6986                                 var rgb = COLOR[ x.toUpperCase() ],
6987                                         pct = false,
6988                                         r   = 0,
6989                                         g   = 0,
6990                                         b   = 0;
6991                                 if( isNumber( rgb ) === true ){
6992                                         r = ( rgb & 0xff0000 ) >> 16;
6993                                         g = ( rgb & 0xff00 ) >> 8;
6994                                         b = ( rgb & 0xff );
6995                                 } else
6996                                 if( x.match( REG_XXXXXX ) ){
6997                                         r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 );
6998                                         g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 );
6999                                         b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 );
7000                                         //alert( x + ' g: ' + g )
7001                                 } else                  
7002                                 if( x.match( REG_XXX ) ){
7003                                         r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
7004                                         g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );
7005                                         b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );
7006                                 } else
7007                                 if( x.indexOf( 'rgb(' ) === 0 ){
7008                                         rgb = x.substr( 4 ).split( ',' );
7009                                         r = parseFloat( rgb[ 0 ] );
7010                                         g = parseFloat( rgb[ 1 ] );
7011                                         b = parseFloat( rgb[ 2 ] );
7012                                         if( x.indexOf( '%' ) !== -1 ) pct = true;
7013                                 } else {
7014                                         r = 255;
7015                                         g = 255;
7016                                         b = 255;
7017                                 };
7018                                 return new ColorProperty( p, r, g, b, pct );
7019                         },
7020                         getClip: function( name ){
7021                                 // rect(...)    クリップします。<top>, <bottom> は上端からの、 <right>, <left> は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。
7022                                 // position:absolute または position:fixed を適用した要素に対してのみ有効です。
7023                                 var top    = this.get( name + 'Top' ),
7024                                         right  = this.get( name + 'Right' ),
7025                                         bottom = this.get( name + 'Bottom' ),
7026                                         left   = this.get( name + 'Left' ),
7027                                         ret    = new PropertyGroup( name, top, right, bottom, left );
7028                                 if( ret.isValid() === true ) return ret;
7029                                 ret.kill();
7030                                 all    = this.style[ name ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( CLIP_SEPARATOR );
7031                                 return new PropertyGroup( name,
7032                                         new Property( name + 'Top',    all[ 0 ], px, this.pxPerEm ),
7033                                         new Property( name + 'Right',  all[ 1 ], px, this.pxPerEm ),
7034                                         new Property( name + 'Bottom', all[ 2 ], px, this.pxPerEm ),
7035                                         new Property( name + 'Left',   all[ 3 ], px, this.pxPerEm )
7036                                 );
7037                         },
7038                         getBackgroundPosition: function( name ){
7039                                 var x   = this.get( name + 'X' ),
7040                                         y   = this.get( name + 'Y' ),
7041                                         ret = new PropertyGroup( name, x, y ),
7042                                         xy;
7043                                 if( ret.isValid() === true ) return ret;
7044                                 ret.kill();
7045                                 xy  = this.style[ name ].split( ' ' );
7046                                 return new PropertyGroup( name,
7047                                         new Property( name + 'X', this.getValue( xy[ 0 ] ), this.getUnit( xy[ 0 ] ), this.pxPerEm ),
7048                                         new Property( name + 'Y', this.getValue( xy[ 1 ] ), this.getUnit( xy[ 1 ] ), this.pxPerEm )
7049                                 );
7050                         },
7051                         getMarginPaddingBorder: function( name, width ){
7052                                 var props  = [ name + 'Top'    + width,
7053                                                    name + 'Right'  + width,
7054                                                    name + 'Bottom' + width,
7055                                                    name + 'Left'   + width ],
7056                                         top    = this.get( props[ 0 ] ),
7057                                         right  = this.get( props[ 1 ] ),
7058                                         bottom = this.get( props[ 2 ] ),
7059                                         left   = this.get( props[ 3 ] ),
7060                                         ret    = new FrexibleProperty( name, top, right, bottom, left ),
7061                                         klass, pxPerEm, getValue, getUnit,
7062                                         all, _0, _1, _2, _3, v, u;
7063                                 if( ret.isValid() === true ) return ret;
7064                                 ret.kill();
7065                                 klass    = Property;
7066                                 pxPerEm  = this.pxPerEm;
7067                                 getValue = this.getValue;
7068                                 getUnit  = this.getUnit;
7069                                 all = this.style[ name + width ].split( ' ' );
7070                                 _0 = all[ 0 ];
7071                                 _1 = all[ 1 ];
7072                                 _2 = all[ 2 ];
7073                                 _3 = all[ 3 ];
7074                                 v  = getValue( _0 );
7075                                 u  = getUnit( _0 );
7076                                 switch( all.length ){
7077                                         case 1 :
7078                                                 top    = new klass( props[ 0 ], v, u, pxPerEm );
7079                                                 right  = new klass( props[ 1 ], v, u, pxPerEm );
7080                                                 bottom = new klass( props[ 2 ], v, u, pxPerEm );
7081                                                 left   = new klass( props[ 3 ], v, u, pxPerEm );
7082                                                 break;
7083                                         case 2 :
7084                                                 top    = new klass( props[ 0 ], v, u, pxPerEm );
7085                                                 bottom = new klass( props[ 2 ], v, u, pxPerEm );
7086                                                 v  = getValue( _1 );
7087                                                 u  = getUnit( _1 );
7088                                                 right  = new klass( props[ 1 ], v, u, pxPerEm );
7089                                                 left   = new klass( props[ 3 ], v, u, pxPerEm );
7090                                                 break;
7091                                         case 3 :
7092                                                 top    = new klass( props[ 0 ], v, u, pxPerEm );
7093                                                 v  = getValue( _1 );
7094                                                 u  = getUnit( _1 );
7095                                                 right  = new klass( props[ 1 ], v, u, pxPerEm );
7096                                                 left   = new klass( props[ 3 ], v, u, pxPerEm );
7097                                                 bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm );
7098                                                 break;
7099                                         case 4 :
7100                                                 top    = new klass( props[ 0 ], v, u, pxPerEm );
7101                                                 right  = new klass( props[ 1 ], getValue( _1 ), getUnit( _1 ), pxPerEm );
7102                                                 bottom = new klass( props[ 2 ], getValue( _2 ), getUnit( _2 ), pxPerEm );
7103                                                 left   = new klass( props[ 3 ], getValue( _3 ), getUnit( _3 ), pxPerEm );
7104                                                 break;
7105                                 };
7106                                 return new FrexibleProperty( name, top, right, bottom, left );
7107                         },
7108                         getBorderColor: function( name ){
7109                                 var props    = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ),
7110                                         top      = this.get( props[ 0 ] ),
7111                                         right    = this.get( props[ 1 ] ),
7112                                         bottom   = this.get( props[ 2 ] ),
7113                                         left     = this.get( props[ 3 ] ),
7114                                         ret      = new FrexibleProperty( name, top, right, bottom, left ),
7115                                         all, _0, _1, getColor;
7116                                 if( ret.isValid() === true ) return ret;
7117                                 ret.kill();
7118                                 getColor = this.getColor;
7119                                 all = this.style[ name ].split( ' ' );
7120                                 _0  = all[ 0 ];
7121                                 _1  = all[ 1 ];
7122                                 switch( all.length ){
7123                                         case 1 :
7124                                                 top    = getColor( _0, props[ 0 ] );
7125                                                 right  = getColor( _0, props[ 1 ] );
7126                                                 bottom = getColor( _0, props[ 2 ] );
7127                                                 left   = getColor( _0, props[ 3 ] );
7128                                                 break;
7129                                         case 2 :
7130                                                 top    = getColor( _0, props[ 0 ] );
7131                                                 right  = getColor( _1, props[ 1 ] );
7132                                                 bottom = getColor( _0, props[ 2 ] );
7133                                                 left   = getColor( _1, props[ 3 ] );
7134                                                 break;
7135                                         case 3 :
7136                                                 top    = getColor( _0,       props[ 0 ] );
7137                                                 right  = getColor( _1,       props[ 1 ] );
7138                                                 bottom = getColor( all[ 2 ], props[ 2 ] );
7139                                                 left   = getColor( _1,       props[ 3 ] );
7140                                                 break;
7141                                         case 4 :
7142                                                 top    = getColor( _0,       props[ 0 ] );
7143                                                 right  = getColor( _1,       props[ 1 ] );
7144                                                 bottom = getColor( all[ 2 ], props[ 2 ] );
7145                                                 left   = getColor( all[ 3 ], props[ 3 ] );
7146                                                 break;
7147                                 };
7148                                 return new FrexibleProperty( name, top, right, bottom, left );
7149                         }
7150                 }
7151         );
7152         function camelizeHash( obj ){
7153                 var p, _p, came = Util.camelize;
7154                 for( p in obj ){
7155                         _p = came( p );
7156                         if( _p === p ) continue;
7157                         obj[ _p ] = obj[ _p ] || obj[ p ];
7158                         delete obj[ p ];
7159                 };
7160         };      
7161         return {
7162                 create: function( css ){
7163                         return new WrappedStyle( camelizeHash( p ) );
7164                 }
7165         };
7166 })();
7167
7168 var XDocument = ( function( window, document ){
7169         
7170         var getIndex = Util.getIndex;
7171         
7172         var DEF_ATTRS = [];
7173         
7174         var AbstractLayoutManager = Class.create(
7175                 'AbstractLayoutManager',
7176                 Class.ABSTRACT, {
7177                         reflow : function(){}
7178                 }
7179         );
7180         
7181         var BasicLayoutManager = AbstractLayoutManager.inherits(
7182                 'BasicLayoutManager',
7183                 {
7184                         Constructor : function(){
7185                                 
7186                         }
7187                 }
7188         );
7189         
7190         var AbstractStylePrivate = Class.create(
7191                 Class.ABSTRACT | Class.PRIVATE_DATA,
7192                 {
7193                         register : function( node ){
7194                                 var list = this.nodeList;
7195                                 if( !list ){
7196                                         this.nodeList = [ node ];
7197                                         return;
7198                                 };
7199                                 if( getIndex( list, node ) === -1 ) list[ list.length ] = node;
7200                         },
7201                         unRegister : function( node ){
7202                                 var list = this.nodeList,
7203                                         i    = getIndex( list, node );
7204                                 if( i !== -1 && list.splice( i, 1 ) && list.length === 0 ) delete this.nodeList;
7205                         },
7206                         clone : function(){
7207                                 var styleClass = Class.getClass( this.User ),
7208                                         dataClass  = Class.getClass( this );
7209                         },
7210                         attr : function( prop, v ){
7211                                 var update    = prop[ 0 ],
7212                                         propID    = prop[ 1 ],
7213                                         type      = prop[ 2 ],
7214                                         list      = prop[ 3 ],
7215                                         length    = !!( type & DEF_ATTRS.LENGTH    ),
7216                                         percent   = !!( type & DEF_ATTRS.PERCENT   ),
7217                                         color     = !!( type & DEF_ATTRS.COLOR     ),
7218                                         uDecimal  = !!( type & DEF_ATTRS.U_DECIMAL ),
7219                                         numerical = !!( type & DEF_ATTRS.NUMERICAL ),
7220                                         flag      = !!( type & DEF_ATTRS.BOOLEAN   ),
7221                                         quartet   = !!( type & DEF_ATTRS.QUARTET   ),
7222                                         url       = !!( type & DEF_ATTRS.URL       ),
7223                                         fontName  = !!( type & DEF_ATTRS.FONT_NAME ),
7224                                         list      = !!( type & DEF_ATTRS.LIST      ),
7225                                         combi     = !!( type & DEF_ATTRS.COMBI     ),
7226                                         data      = this.data,
7227                                         _v        = -1,
7228                                         _type, i, l, nodes;
7229                                         
7230                                 if( v !== undefined ){
7231                                         if( Type.isNumber( v ) === true ){
7232                                                 if( numerical === false ){
7233                                                         if( uDecimal === false || v < 0 || 1 < v ) throw new Error( '' );
7234                                                 };
7235                                         } else
7236                                         if( Type.isBoolean( v ) === true ){
7237                                                 if( flag === false ) throw new Error( '' );
7238                                         } else
7239                                         if( Type.isString( v ) === true ){
7240                                                 if( url === false && fontName === false ){
7241                                                         if( v.indexOf( ' ' ) !== -1 ){
7242                                                                 v = v.split( ' ' );
7243                                                         } else {
7244                                                                 if( length === false && percent === false && color === false ) throw new Error( '' );
7245                                                         };
7246                                                 };
7247                                         };                                      
7248                                         if( Type.isArray( v ) === true ){
7249                                                 if( v.length <= 4 && quartet === true ){
7250                                                         _type = type ^ DEF_ATTRS.QUARTET;
7251                                                 } else
7252                                                 if( v.length === 2 && combi === true ){
7253                                                         _type = type ^ DEF_ATTRS.COMBI;
7254                                                 } else {
7255                                                         throw new Error( '' );
7256                                                 };
7257                                                 switch( v.length ){
7258                                                         case 1 :
7259                                                                 this.attr( [ propID  , _type, list ], v[ 0 ] );
7260                                                                 this.attr( [ ++propID, _type, list ], v[ 0 ] );
7261                                                                 this.attr( [ ++propID, _type, list ], v[ 0 ] );
7262                                                                 this.attr( [ ++propID, _type, list ], v[ 0 ] );
7263                                                                 break;
7264                                                         case 2 :
7265                                                                 this.attr( [ propID  , _type, list ], v[ 0 ] );
7266                                                                 this.attr( [ ++propID, _type, list ], v[ 1 ] );
7267                                                                 this.attr( [ ++propID, _type, list ], v[ 0 ] );
7268                                                                 this.attr( [ ++propID, _type, list ], v[ 1 ] );
7269                                                                 break;
7270                                                         case 3 :
7271                                                                 this.attr( [ propID  , _type, list ], v[ 0 ] );
7272                                                                 this.attr( [ ++propID, _type, list ], v[ 1 ] );
7273                                                                 this.attr( [ ++propID, _type, list ], v[ 2 ] );
7274                                                                 this.attr( [ ++propID, _type, list ], v[ 1 ] );
7275                                                                 break;
7276                                                         case 4 :
7277                                                                 this.attr( [ propID  , _type, list ], v[ 0 ] );
7278                                                                 this.attr( [ ++propID, _type, list ], v[ 1 ] );
7279                                                                 this.attr( [ ++propID, _type, list ], v[ 2 ] );
7280                                                                 this.attr( [ ++propID, _type, list ], v[ 3 ] );
7281                                                                 break;
7282                                                         default :
7283                                                 };
7284                                                 return this.User;
7285                                         };
7286                                         if( this.invalidateLayout < update ) this.invalidate = update;
7287                                         
7288                                         if( list ) _v = Util.getIndex( list, v );
7289                                         data[ propID ] = _v !== -1 ? _v : v;
7290                                         return this.User;
7291                                 };
7292                                 if( this.invalidate === DEF_ATTRS.REFLOW ){
7293                                         nodes = this.nodeList;
7294                                         if( nodes ){
7295                                                 for( i = 0, l = nodes.length; i < l; ++i ){
7296                                                         nodes[ i ].reflow();
7297                                                 };
7298                                         };
7299                                 };
7300                                 v = data[ propID ];
7301                                 if( quartet === true ) return [ v, data[ ++propID ], data[ ++propID ], data[ ++propID ] ];
7302                                 if( combi === true ) return [ v, data[ ++propID ] ];
7303                                 if( list && Type.isNumber( v ) === true ) return list[ v ];
7304                                 return v;
7305                         }
7306                 }
7307         );
7308         
7309         var PaintPrivate = AbstractStylePrivate.inherits(
7310                 'PaintPrivate',
7311                 Class.PRIVATE_DATA | Class.POOL_OBJECT,
7312                 {
7313                         Constructor : function(){
7314                                 this.data = [];
7315                                 this.invalidate = 0;
7316                         },
7317                         cssText : function(){
7318                                 
7319                         },
7320                         cssObject : function(){
7321                                 
7322                         },
7323                         paint : function( node ){
7324                                 
7325                         }
7326                 }
7327         );
7328         
7329         var PaintStyle = Class.create(
7330                 'PaintStyle',
7331                 Class.POOL_OBJECT,
7332                 PaintPrivate,
7333                 {
7334                         Constructor : function(){
7335                                 PaintStyle.newPrivateData( this );
7336                         },
7337                         borderWidth : function( v ){
7338                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderWidth, v );
7339                         },
7340                         borderColor : function(){
7341                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderColor, v );
7342                         },
7343                         borderStyle : function(){
7344                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.borderStyle, v );
7345                         },
7346                         cornerRadius : function(){
7347                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.cornerRadius, v );
7348                         },
7349                         bgColor : function(){
7350                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgColor, v );
7351                         },
7352                         bgAlpha : function(){
7353                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgAlpha, v );
7354                         },
7355                         bgImgUrl : function(){
7356                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgUrl, v );
7357                         },
7358                         bgImgRepeatX : function(){
7359                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatX, v );
7360                         },
7361                         bgImgRepeatY : function(){
7362                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgRepeatY, v );
7363                         },
7364                         bgImgPositionX : function(){
7365                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionX, v );
7366                         },
7367                         bgImgPositionY : function(){
7368                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.bgImgPositionY, v );
7369                         },
7370                         shadowColor : function(){
7371                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowColor, v );
7372                         },
7373                         shadowAlpha : function(){
7374                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowAlpha, v );
7375                         },
7376                         shadowOffsetX : function(){
7377                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetX, v );
7378                         },
7379                         shadowOffsetY : function(){
7380                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowOffsetY, v );
7381                         },
7382                         shadowBlur : function(){
7383                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowBlur, v );
7384                         },
7385                         shadowSpread : function(){
7386                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowSpread, v );
7387                         },
7388                         shadowInset : function(){
7389                                 return PaintStyle.getPrivateData( this ).attr( PaintPrivate.shadowInset, v );
7390                         }
7391                 }
7392         );
7393         
7394         var TypoPrivate = AbstractStylePrivate.inherits(
7395                 'TypoPrivate',
7396                 Class.PRIVATE_DATA | Class.POOL_OBJECT,
7397                 {
7398                         Constructor : function(){
7399                                 this.data = [];
7400                                 this.invalidate = 0;
7401                         },
7402                         cssText : function(){
7403                                 
7404                         },
7405                         cssObject : function(){
7406                                 
7407                         }
7408                 }
7409         );
7410         
7411         var TypoStyle = Class.create(
7412                 'TypoStyle',
7413                 Class.POOL_OBJECT,
7414                 TypoPrivate,
7415                 {
7416                         Constructor : function( v ){
7417                                 TypoStyle.newPrivateData( this );
7418                         },
7419                         color : function( v ){
7420                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.color, v );
7421                         },
7422                         fontFamily : function( v ){
7423                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontFamily, v );
7424                         },
7425                         fontSize : function( v ){
7426                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.fontSize, v );
7427                         },
7428                         bold : function( v ){
7429                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.bold, v );
7430                         },
7431                         italic : function( v ){
7432                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.italic, v );
7433                         },
7434                         lineHeight : function( v ){
7435                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.lineHeight, v );
7436                         },
7437                         letterSpacing : function( v ){
7438                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.letterSpacing, v );
7439                         },
7440                         wordSpacing : function( v ){
7441                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.wordSpacing, v );
7442                         },
7443                         align : function( v ){
7444                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.align, v );
7445                         },
7446                         decoration : function( v ){
7447                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.decoration, v );
7448                         },
7449                         transform : function( v ){
7450                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.transform, v );
7451                         },
7452                         shadowColor : function( v ){
7453                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowColor, v );
7454                         },
7455                         shadowOffsetX : function( v ){
7456                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetX, v );
7457                         },
7458                         shadowOffsetY : function( v ){
7459                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowOffsetY, v );
7460                         },
7461                         shadowBlur : function( v ){
7462                                 return TypoStyle.getPrivateData( this ).attr( TypoPrivate.shadowBlur, v );
7463                         }
7464                 }
7465         );
7466         
7467         var LayoutPrivate = AbstractStylePrivate.inherits(
7468                 'LayoutPrivate',
7469                 Class.PRIVATE_DATA | Class.POOL_OBJECT,
7470                 {
7471                         Constructor : function(){
7472                                 this.data = [];
7473                                 this.invalidate = 0;
7474                         },
7475                         cssText : function(){
7476                                 
7477                         },
7478                         cssObject : function(){
7479                                 
7480                         }
7481                 }
7482         );
7483         
7484         DEF_ATTRS.LENGTH            =  1;
7485         DEF_ATTRS.PERCENT           =  2;
7486         DEF_ATTRS.COLOR             =  4;
7487         DEF_ATTRS.U_DECIMAL         =  8;
7488         DEF_ATTRS.NUMERICAL         = 16;
7489         DEF_ATTRS.BOOLEAN           = 32;
7490         DEF_ATTRS.QUARTET           = 64;
7491         DEF_ATTRS.URL               = 128;
7492         DEF_ATTRS.FONT_NAME         = 256;
7493         DEF_ATTRS.LIST              = 512;
7494         DEF_ATTRS.AUTO              = 1024;
7495         DEF_ATTRS.COMBI             = 2048;
7496         DEF_ATTRS.BORDER_STYLE      = 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(',');
7497         DEF_ATTRS.POSITION_X        = 'left,center,right'.split(',');
7498         DEF_ATTRS.POSITION_Y        = 'top,center,bottom'.split(',');
7499         DEF_ATTRS.ALIGN             = 'left,center,right,justify'.split(',');
7500         DEF_ATTRS.TEXT_DECORATION   = 'none,underline,overline,line-through,blink'.split(',');
7501         DEF_ATTRS.TEXT_TRANSFORM    = 'none,capitalize,lowercase,uppercase'.split(',');
7502         DEF_ATTRS.WIDTH_HEIGHT      = 'auto'.split(',');
7503         DEF_ATTRS.PAINT             = 1; // 再描画のみ必要
7504         DEF_ATTRS.REFLOW            = 2; // レイアウトの再計算が必要
7505         
7506         PaintPrivate.borderWidth    = [ DEF_ATTRS.REFLOW,  0, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH      ]; // em [ top, right, bottom, left ]
7507         PaintPrivate.borderColor    = [ DEF_ATTRS.PAINT,   4, DEF_ATTRS.QUARTET | DEF_ATTRS.DEF_COLOR   ]; // color [ top, right, bottom, left ]
7508         PaintPrivate.borderStyle    = [ DEF_ATTRS.REFLOW,  8, DEF_ATTRS.QUARTET | DEF_ATTRS.LIST, DEF_ATTRS.BORDER_STYLE ]; // string [ top, right, bottom, left ]
7509         PaintPrivate.cornerRadius   = [ DEF_ATTRS.PAINT,  12, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, px [ top, right, bottom, left ]
7510         PaintPrivate.bgColor        = [ DEF_ATTRS.PAINT,  16, DEF_ATTRS.COLOR     ]; // color
7511         PaintPrivate.bgAlpha        = [ DEF_ATTRS.PAINT,  17, DEF_ATTRS.U_DECIMAL ]; // 0 - 1
7512         PaintPrivate.bgImgUrl       = [ DEF_ATTRS.PAINT,  18, DEF_ATTRS.URL       ]; // url
7513         PaintPrivate.bgImgRepeatX   = [ DEF_ATTRS.PAINT,  19, DEF_ATTRS.BOOLEAN   ]; // true / false
7514         PaintPrivate.bgImgRepeatY   = [ DEF_ATTRS.PAINT,  20, DEF_ATTRS.BOOLEAN   ]; // true / false
7515         PaintPrivate.bgImgPositionX = [ DEF_ATTRS.PAINT,  21, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_X ]; // em %, px, string
7516         PaintPrivate.bgImgPositionY = [ DEF_ATTRS.PAINT,  22, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.LIST, DEF_ATTRS.POSITION_Y ]; // em %, px, string
7517         PaintPrivate.shadowColor    = [ DEF_ATTRS.PAINT,  23, DEF_ATTRS.COLOR     ]; // color
7518         PaintPrivate.shadowAlpha    = [ DEF_ATTRS.PAINT,  24, DEF_ATTRS.U_DECIMAL ]; // 0 - 1
7519         PaintPrivate.shadowOffsetX  = [ DEF_ATTRS.PAINT,  25, DEF_ATTRS.LENGTH    ]; // em
7520         PaintPrivate.shadowOffsetY  = [ DEF_ATTRS.PAINT,  26, DEF_ATTRS.LENGTH    ]; // em
7521         PaintPrivate.shadowBlur     = [ DEF_ATTRS.PAINT,  27, DEF_ATTRS.LENGTH    ]; // em
7522         PaintPrivate.shadowSpread   = [ DEF_ATTRS.PAINT,  28, DEF_ATTRS.LENGTH    ]; // em
7523         PaintPrivate.shadowInset    = [ DEF_ATTRS.PAINT,  29, DEF_ATTRS.BOOLEAN   ]; // true / false
7524         
7525         TypoPrivate.color           = [ DEF_ATTRS.PAINT,   0, DEF_ATTRS.COLOR     ]; // color
7526         TypoPrivate.fontFamily      = [ DEF_ATTRS.REFLOW,  1, DEF_ATTRS.FONT_NAME ]; // string
7527         TypoPrivate.fontSize        = [ DEF_ATTRS.REFLOW,  2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ]; // em, %
7528         TypoPrivate.bold            = [ DEF_ATTRS.REFLOW,  3, DEF_ATTRS.BOOLEAN   ]; // true / false
7529         TypoPrivate.italic          = [ DEF_ATTRS.REFLOW,  4, DEF_ATTRS.BOOLEAN   ]; // true / false
7530         TypoPrivate.lineHeight      = [ DEF_ATTRS.REFLOW,  5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT | DEF_ATTRS.NUMERICAL ]; // em, %, 
7531         TypoPrivate.letterSpacing   = [ DEF_ATTRS.REFLOW,  6, DEF_ATTRS.LENGTH    ]; // em
7532         TypoPrivate.wordSpacing     = [ DEF_ATTRS.REFLOW,  7, DEF_ATTRS.LENGTH    ];
7533         TypoPrivate.align           = [ DEF_ATTRS.REFLOW,  8, DEF_ATTRS.LIST, DEF_ATTRS.ALIGN           ];
7534         TypoPrivate.decoration      = [ DEF_ATTRS.PAINT,   9, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_DECORATION ];
7535         TypoPrivate.transform       = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.LIST, DEF_ATTRS.TEXT_TRANSFORM  ];
7536         TypoPrivate.shadowColor     = [ DEF_ATTRS.PAINT,  11, DEF_ATTRS.COLOR     ];
7537         TypoPrivate.shadowOffsetX   = [ DEF_ATTRS.PAINT,  12, DEF_ATTRS.LENGTH    ];
7538         TypoPrivate.shadowOffsetY   = [ DEF_ATTRS.PAINT,  13, DEF_ATTRS.LENGTH    ];
7539         TypoPrivate.shadowBlur      = [ DEF_ATTRS.PAINT,  14, DEF_ATTRS.LENGTH    ];
7540         
7541         LayoutPrivate.width         = [ DEF_ATTRS.REFLOW,  0, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ];
7542         LayoutPrivate.minWidth      = [ DEF_ATTRS.REFLOW,  1, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7543         LayoutPrivate.maxWidth      = [ DEF_ATTRS.REFLOW,  2, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7544         LayoutPrivate.height        = [ DEF_ATTRS.REFLOW,  3, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT, DEF_ATTRS.WIDTH_HEIGHT ];
7545         LayoutPrivate.minHeight     = [ DEF_ATTRS.REFLOW,  4, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7546         LayoutPrivate.maxHeight     = [ DEF_ATTRS.REFLOW,  5, DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7547         LayoutPrivate.padding       = [ DEF_ATTRS.REFLOW,  6, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7548         LayoutPrivate.margin        = [ DEF_ATTRS.REFLOW, 10, DEF_ATTRS.QUARTET | DEF_ATTRS.LENGTH | DEF_ATTRS.PERCENT ];
7549
7550
7551         var NodePrivate = Class.create(
7552                 'NodePrivate',
7553                 Class.PRIVATE_DATA | Class.POOL_OBJECT,
7554                 {
7555                         elmWrap       : null,
7556                         textNode      : null,
7557                         contentWidth  : 0,
7558                         contentHeight : 0,
7559                         Constructor   : function( __root, __parent ){
7560                                 this.__root   = __root;
7561                                 if( __parent ) this.__parent = __parent;
7562                         },
7563                         paint : function( v ){
7564                                 if( v instanceof PaintStyle ){
7565                                         this.__paint && this.__paint.unRegister( this );
7566                                         this._paint = v;
7567                                         this.__paint = PaintStyle.getPrivateData( v );                                  
7568                                         this.__paint.register( this );
7569                                         return this.User;
7570                                 } else
7571                                 if( v === null ){
7572                                         this.__paint && this.__paint.unRegister( this );
7573                                         delete this._paint;
7574                                         delete this.__paint;
7575                                         return this.User;
7576                                 };
7577                                 return this._paint;
7578                         },
7579                         typo : function( v ){
7580                                 if( v instanceof TypoStyle ){
7581                                         this.__typo && this.__typo.unRegister( this );
7582                                         this._typo = v;
7583                                         this.__typo = TypoStyle.getPrivateData( v );                                    
7584                                         this.__typo.register( this );
7585                                         return this.User;
7586                                 } else
7587                                 if( v === null ){
7588                                         this.__typo && this.__typo.unRegister( this );
7589                                         delete this._typo;
7590                                         delete this.__typo;
7591                                         return this.User;
7592                                 };
7593                                 return this._typo;
7594                         },
7595                         /**
7596                          * 1. 要素の追加・削除
7597                          * 2. auto 指定時は要素の高さ取得.
7598                          * 3. 親の許す子の最大サイズと自信のスタイル指定から、自身の位置とサイズを計算
7599                          * 4. 描画更新リストに追加
7600                          */
7601                         reflow : function(){
7602                                 var content = this._textContent,
7603                                         layout  = this.__layout,
7604                                         targetW = this.__parent.childWidth,
7605                                         targetH = this.__parent.childHeight,
7606                                         size, data, w, h;
7607                                 
7608                                 if( content || ( this.__paint && this.__paint.hasStyle === true ) || ( this.__typo && this.__typo.hasStyle === true ) ){
7609                                         if( !this.elmWrap ) this.elmWrap = DOM.createDiv();
7610                                         this.__parent.addDiv( this );
7611                                         if( conetnt ){
7612                                                 if( !this.textNode ){
7613                                                         this.textNode = DOM.cerateText();
7614                                                         this.elmWrap.appendChild( this.textNode );
7615                                                 };
7616                                                 if( layout && ( layout.autoWidth === true || layout.autoHeight === true ) ){
7617                                                         size = DOM.getTextSize( this.elmWrap, content );
7618                                                         this.contentWidth  = size[ 0 ];
7619                                                         this.conetntHeight = size[ 1 ];
7620                                                 };
7621                                                 this.textNode.data = content;
7622                                         } else
7623                                         if( this.textNode ){
7624                                                 DOM.correct( this.textNode );
7625                                                 delete this.textNode;
7626                                                 delete this.contentWidth;
7627                                                 delete this.conetntHeight;
7628                                         };
7629                                         this.currentWidth  = this.elmWrap.offsetWidth;
7630                                         this.currentHeight = this.elmWrap.offsetHeight;                                 
7631                                 } else
7632                                 if( this.elmWrap ){
7633                                         DOM.correct( this.elmWrap );
7634                                         delete this.elmWrap;
7635                                         delete this.textNode;
7636                                         delete this.contentWidth;
7637                                         delete this.conetntHeight;
7638                                         delete this.currentWidth;
7639                                         delete this.currentHeight
7640                                 };
7641                                 
7642                                 // this.__parent.layoutManager.reflow();
7643                         },
7644                         addDiv : function( nodeData ){
7645                                 
7646                         }       
7647                 }
7648         );
7649         var Node = Class.create(
7650                 'Node',
7651                 Class.POOL_OBJECT,
7652                 NodePrivate,
7653                 {
7654                         Constructor : function( root, parent ){
7655                                 Node.newPrivateData( this,  LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined, this );
7656                         },
7657                         paint : function( v ){
7658                                 return Node.getPrivateData( this ).paint( v );
7659                         },
7660                         typo : function( v ){
7661                                 return Node.getPrivateData( this ).typo( v );
7662                         },
7663                         remove : function(){
7664                                 Node.getPrivateData( this ).remove();
7665                         },
7666                         nodeIndex : function( v ){
7667                                 return Node.getPrivateData( this ).nodeIndex( v );
7668                         },
7669                         displayIndex : function(){
7670                                 
7671                         },
7672                         disabled : function( v ){
7673                                 return Node.getPrivateData( this ).disabled( v );
7674                         },
7675                         cursor : function( v ){
7676                                 return Node.getPrivateData( this ).cursor( v );
7677                         },
7678                         getAbsolutePositionX : function(){
7679                                 return Node.getPrivateData( this ).getAbsolutePositionX();
7680                         },
7681                         getAbsolutePositionY : function(){
7682                                 return Node.getPrivateData( this ).getAbsolutePositionY();
7683                         },
7684                         addEventListener : function( type, handler, opt_thisObject ){
7685                                 Node.getPrivateData( this ).addEventListener( type, handler, opt_thisObject );
7686                         },
7687                         removeEventListener : function( type, handler ){
7688                                 Node.getPrivateData( this ).removeEventListener( type, handler );
7689                         },
7690                         scrollTo : function( x, y ){
7691                                 Node.getPrivateData( this ).scrollTo( x, y );
7692                         },
7693                         scrollX : function( v ){
7694                                 return Node.getPrivateData( this ).scrollX( v );
7695                         },
7696                         scrollY : function( v ){
7697                                 return Node.getPrivateData( this ).scrollY( v );
7698                         }
7699                 }
7700         );
7701         
7702         var LayoutBoxPrivate = NodePrivate.inherits(
7703                 'LayoutBoxPrivate',
7704                 Class.POOL_OBJECT,
7705                 {
7706                         Constructor : function( layoutManager, root, parent ){
7707                                 this.layoutManager = layoutManager;
7708                                 this._root         = _root;
7709                                 if( _parent ) this._parent = _parent;
7710                         },
7711                         reflow : function(){
7712                                 this.manager.reflow( this );
7713                         },
7714                         repaint : function(){
7715                                 this.manager.repaint( this );
7716                         }
7717                 }
7718         );
7719         
7720         var LayoutBox = Node.inherits(
7721                 'LayoutBox',
7722                 Class.POOL_OBJECT,
7723                 LayoutBoxPrivate,
7724                 {
7725                         Constructor : function( layoutManager, root, parent ){
7726                                 LayoutBox.newPrivateData( this, layoutManager, LayoutBox.getPrivateData( root ), parent ? LayoutBox.getPrivateData( parent ) : undefined );
7727                         },
7728                         layoutManager : function( v ){
7729                                 
7730                         },
7731                         createLayoutBox : function(){
7732                                 
7733                         },
7734                         createContentBox : function(){
7735                                 
7736                         }
7737                 }
7738         );
7739         
7740 })( window, document );
7741         
7742 })( window, document );