OSDN Git Service

client is version0.4.33, fixed balloon 0deg position, boot editor with panel data.
[pettanr/pettanr.git] / public / assets / common.js
index 540227f..3a2e2ff 100644 (file)
@@ -1,16 +1,16 @@
 /*\r
  * pettanR common.js\r
- *   version 0.4.17\r
+ *   version 0.4.33\r
  * \r
  * author: itozyun\r
  */\r
 \r
 /*\r
- * http://pettanr.sourceforge.jp/test/type.html
+ * http://pettanr.sourceforge.jp/test/type.html\r
  */\r
        var Type = {\r
                isObject : function(v) {\r
-                       return v !== null && Type.isArray(v) === false && typeof v === 'object';\r
+                       return v !== null && typeof v === 'object';\r
                },\r
                isFunction : function(v) {\r
                        return typeof v === 'function';\r
@@ -75,7 +75,7 @@
 \r
 var pettanr = ( function(){\r
        var     FUNCTION_ARRAY = [],\r
-               URL = document.location.href.split( '#')[ 0],\r
+               URL = document.location.href.split( '#')[ 0 ],\r
                IS_LOCAL = URL.indexOf( 'file:') === 0,\r
                URL_PARAMS = ( function(){\r
                        var search = document.location.search,\r
@@ -105,20 +105,20 @@ var pettanr = ( function(){
                    }\r
                    return {};\r
                })(),\r
-               IS_DEBUG = typeof URL_PARAMS.debug === 'boolean' ? URL_PARAMS.debug : IS_LOCAL === true,\r
+               IS_DEBUG = Type.isBoolean( URL_PARAMS.debug ) ? URL_PARAMS.debug : IS_LOCAL === true,\r
                jqWindow , jqDocument , jqBody;\r
        return {\r
-               version: '0.4.17',\r
+               version: '0.4.33',\r
                init: function(){\r
-                       jqWindow = $( window);\r
-                       jqDocument = $( document);\r
-                       jqBody = $( document.body);\r
+                       jqWindow   = $( window );\r
+                       jqDocument = $( document );\r
+                       jqBody     = $( document.body );\r
                        \r
                        var l = FUNCTION_ARRAY.length,\r
                                _fn;\r
                        for( var i=0; i<l; i++){\r
                                _fn = FUNCTION_ARRAY[ i];\r
-                               _fn.init && _fn.init( _fn === pettanr.view ? FUNCTION_ARRAY : undefined);\r
+                               _fn.init && _fn.init( _fn === pettanr.view ? FUNCTION_ARRAY : undefined );\r
                        }\r
                        \r
                        delete pettanr.init;\r
@@ -161,8 +161,7 @@ var pettanr = ( function(){
                        var pre = document.createElement('pre');\r
                        pre.appendChild( document.createTextNode('\n'));\r
                        return pre.firstChild.data;\r
-               })(),\r
-               IS_IFRAME: !!window.parent\r
+               })()\r
        }\r
 })();\r
 \r
@@ -221,7 +220,7 @@ pettanr.util = ( function(){
                        }\r
                        var i, l, _children = _elm.childNodes, _array = [];\r
                        if( _children && typeof _children.length === 'number'){\r
-                               // liveNode > array\r
+                               // liveNode > array\r
                                for( i=0, l=_children.length; i<l; ++i){\r
                                        _array.push( _children[ i ] );\r
                                }\r
@@ -316,7 +315,6 @@ pettanr.util = ( function(){
                        } else {\r
                                parentElm && parentElm.appendChild( img);\r
                        }\r
-                       return size;\r
                        \r
                /* LICENSE: MIT\r
                 * AUTHOR: uupaa.js@gmail.com\r
@@ -359,114 +357,8 @@ pettanr.util = ( function(){
                                // HTMLCanvasElement\r
                                return { width: image.width, height: image.height };\r
                        }\r
-               },\r
-               loadImage: function( URLorELM, onLoad, onError, delay, timeout){\r
-                       delay = delay || 250;\r
-                       timeout = timeout || 5000;\r
-                       var type = typeof URLorELM,\r
-                               img, images, src, abstractPath;\r
-                       if( type === 'string'){\r
-                               src = URLorELM;\r
-                               // images = [];\r
-                       } else\r
-                       // http://d.hatena.ne.jp/hottolinkblog/20090228/1235823487\r
-                       if( type === 'object' && typeof URLorELM.hspace !== 'undefined' && typeof URLorELM.vspace !== 'undefined'){\r
-                               img = URLorELM;\r
-                               images = [ img];\r
-                               src = img.src;\r
-                       } else {\r
-                               return;\r
-                       }\r
-                       abstractPath = this.getAbsolutePath( src);\r
                        \r
-                       loadImage( images, abstractPath, onLoadAsync, onErrorAsync, delay, timeout);\r
-                       \r
-                       function onLoadAsync( abspath, actualW, actualH){\r
-                               if( abstractPath !== abspath) return;\r
-                               var _g_onUpdateFunction = pettanr.util.createGlobalFunction( onLoad);\r
-                                       _onTimeout = pettanr.util.createGlobalFunc( [\r
-                                               'function(){',\r
-                                                       'window["', _g_onUpdateFunction, '"]( "', abspath, '", ', actualW, ',  ', actualH, ');',\r
-                                                       'window["', _g_onUpdateFunction, '"] = null;',\r
-                                               '}'\r
-                                       ].join( ''));\r
-                               onLoad && setTimeout( window[ _onTimeout], 0);\r
-                               window[ _onTimeout] = null;\r
-                       }\r
-                       function onErrorAsync( abspath){\r
-                               if( abstractPath !== abspath) return;\r
-                               var _g_onUpdateFunction = pettanr.util.createGlobalFunction( onError);\r
-                                       _onTimeout = pettanr.util.createGlobalFunc( [\r
-                                               'function(){',\r
-                                                       'window["', _g_onUpdateFunction, '"]( "', abspath, '");',\r
-                                                       'window["', _g_onUpdateFunction, '"] = null;',\r
-                                               '}'\r
-                                       ].join( ''));\r
-                               onError && setTimeout( window[ _onTimeout], 0);\r
-                               window[ _onTimeout] = null;\r
-                       }\r
-                       \r
-               /*  LICENSE: MIT?\r
-                *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
-                *  AUTHOR: uupaa.js@gmail.com\r
-                * \r
-                *  fixed for ie6-8 by pettanr\r
-                *   new Image -> document.createElement( 'img')\r
-                */\r
-                       function loadImage( images, abspath, onLoad, onError, delay, timeout) {\r
-                               images = images || document.images;\r
-                               var img,\r
-                                       i = 0, l = images.length,\r
-                                       tick = 0;\r
-                               for(; i < l; ++i) {\r
-                                       img = images[i];\r
-                                       if ( img.src === abspath && img.complete) {\r
-                                               var size = pettanr.util.getImageSize( img);\r
-                                               onLoad( abspath, size.width, size.height);\r
-                                               return;\r
-                                       }\r
-                               }\r
-                               img = document.createElement( 'img'); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る\r
-                               img.finish = false;\r
-                               img.onabort = img.onerror = function() {\r
-                                       if (img.finish) { return; }\r
-                                       img.finish = true;\r
-                                       onError(abspath);\r
-                                       img.onload = img.onabort = img.onerror = "";\r
-                               };\r
-                               img.onload  = function() {\r
-                                       img.finish = true;\r
-                                       if (window.opera && !img.complete) {\r
-                                               onError(abspath);\r
-                                               img.onload = img.onabort = img.onerror = "";\r
-                                               return;\r
-                                       }\r
-                                       var size = pettanr.util.getImageSize( img);\r
-                                       onLoad( abspath, size.width, size.height);\r
-                                       img.onload = img.onabort = img.onerror = "";\r
-                                       //img = void 0;\r
-                               };\r
-                               img.src = abspath;\r
-                               if (!img.finish && timeout) {\r
-                                       setTimeout(function() {\r
-                                               if (img.finish) { return; }\r
-                                               if (img.complete) {\r
-                                                       img.finish = true;\r
-                                                       if (img.width) { return; }\r
-                                                       onError(abspath);\r
-                                                       img.onload = img.onabort = img.onerror = "";\r
-                                                       return;\r
-                                               }\r
-                                               if ((tick += delay) > timeout) {\r
-                                                       img.finish = true;\r
-                                                       onError(abspath);\r
-                                                       img.onload = img.onabort = img.onerror = "";\r
-                                                       return;\r
-                                               }\r
-                                               setTimeout(arguments.callee, delay);\r
-                                       }, 0);\r
-                               }\r
-                       }\r
+                       return size;\r
                },\r
                getAbsolutePath: function( path) {\r
                        var e = document.createElement("div");\r
@@ -511,7 +403,7 @@ pettanr.util = ( function(){
                        return ret;\r
                },\r
                getChildIndex: function( _parent, _child){\r
-                       var _children = _parent.getElementsByTagName( _child.tagName),\r
+                       var _children = _parent.getElementsByTagName( _child.tagName ),\r
                                l = _children.length;\r
                        for(var i=0; i<l; ++i){\r
                                if( _children[ i] === _child) return i;\r
@@ -537,7 +429,7 @@ pettanr.util = ( function(){
                        }\r
                },\r
                getIndex: function( _array, _element){\r
-                       if( Array.prototype.indexof){\r
+                       if( Array.prototype.indexof ){\r
                                pettanr.util.getIndex = function( _array, _element){\r
                                        return _array.indexof( _element);\r
                                }\r
@@ -551,6 +443,13 @@ pettanr.util = ( function(){
                        }\r
                        return pettanr.util.getIndex( _array, _element);\r
                },\r
+               copyArray: function( _array ){\r
+                       var ret = new Array( l );\r
+                       for(var i=0, l = _array.length; i<l; ++i){\r
+                               ret[ i ] = _array[ i ];\r
+                       }\r
+                       return ret;\r
+               },\r
                /*\r
                 * \r
                 */\r
@@ -763,62 +662,58 @@ pettanr.ua = ( function(){
 \r
 \r
 pettanr.CONST = ( function(){\r
-       var isLocal = pettanr.LOCAL === true || pettanr.URL_PARAMS.exjson === false,\r
-               isLocalhost = document.location.href.indexOf( 'http:\/\/localhost:3000\/' ) === 0,\r
-               PETTANR_ROOT_PATH = isLocalhost === true ? 'http:\/\/localhost:3000\/' : 'http:\/\/pettanr.heroku.com\/';\r
+       var SERVER_SUPPORT    = !( 'has_server_support' in window && has_server_support === false ),\r
+               PETTANR_ROOT_PATH = ( function(){\r
+                       if( SERVER_SUPPORT === false ){\r
+                               var h1 = document.getElementsByTagName( 'h1' )[ 0 ];\r
+                               if( h1 ){\r
+                                       var a = h1.getElementsByTagName( 'a' )[ 0 ];\r
+                                       return a ? a.href : '';\r
+                               }\r
+                               return '';\r
+                       }\r
+                       var loc = document.location;\r
+                       return [ loc.protocol, '\/\/', loc.host, '\/' ].join( '' );\r
+               })(),\r
+               RELATIVE = ( function(){\r
+                       var ret  = '',\r
+                               loc  = document.location,\r
+                               path = [ loc.protocol, '\/', loc.host, '\/', loc.pathname.split( '\\' ).join( '\/' ) ].join( '' ),\r
+                               l    = path.split( '\/' ).length - PETTANR_ROOT_PATH.split( '\/' ).length;\r
+                       for( var i=0; i<l; ++i ){\r
+                               ret += '..\/';\r
+                       }\r
+                       return ret;\r
+               })();\r
                \r
        return {\r
                PETTANR_ROOT_PATH:                      PETTANR_ROOT_PATH,\r
-               URL_ORIGINAL_PICTURES_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'original_pictures.json',\r
-               URL_RESOURCE_PICTURES_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'resource_pictures.json',\r
-               URL_COMICS_JSON:                        ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'comics.json',\r
-               URL_PANELS_JSON:                        ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'panels.json',\r
+               URL_ORIGINAL_PICTURES_JSON: ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'original_pictures.json',\r
+               URL_RESOURCE_PICTURES_JSON: ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'resource_pictures.json',\r
+               URL_COMICS_JSON:                        ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'comics.json',\r
+               URL_PANELS_JSON:                        ( SERVER_SUPPORT === false ? 'json\/' : PETTANR_ROOT_PATH ) + 'panels.json',\r
                NS_PETTANR_COMIC:                       'pettanr-comic',\r
-               RESOURCE_PICTURE_PATH:          ( isLocal === true ? pettanr.ROOT_PATH : PETTANR_ROOT_PATH) + 'resource_pictures\/',\r
-               CREATE_COMIC_JS:                        isLocal === true ? 'js\/create_new_comic.js' : PETTANR_ROOT_PATH + 'comics\/new.js',\r
-               CREATE_PANEL_JS:                        isLocal === true ? 'js\/create_new_panel.js' : PETTANR_ROOT_PATH + 'panels\/new.js',\r
-               UPLOAD_PICTURE_JS:                      isLocal === true ? 'js\/upload_picture.js' : PETTANR_ROOT_PATH + 'original_pictures\/new.js',\r
-               REGISTER_ARTIST_JS:                     isLocal === true ? 'js\/register_artist.js' : PETTANR_ROOT_PATH + 'artists\/new.js',\r
-               JQUERY_URL:                                     isLocal === true ? 'javascripts\/jquery-1.6.2.min.js' : PETTANR_ROOT_PATH + 'assets\/jquery-162_min.js'\r
+               RESOURCE_PICTURE_PATH:          ( SERVER_SUPPORT === false ? RELATIVE : PETTANR_ROOT_PATH ) + 'resource_pictures\/',\r
+               SYSTEM_PICTURE_PATH:            ( SERVER_SUPPORT === false ? RELATIVE : PETTANR_ROOT_PATH ) + 'system_pictures\/',\r
+               CREATE_COMIC_JS:                        SERVER_SUPPORT === false ? 'js\/create_new_comic.js' : PETTANR_ROOT_PATH + 'comics\/new.js',\r
+               CREATE_PANEL_JS:                        SERVER_SUPPORT === false ? 'js\/create_new_panel.js' : PETTANR_ROOT_PATH + 'panels\/new.js',\r
+               UPLOAD_PICTURE_JS:                      SERVER_SUPPORT === false ? 'js\/upload_picture.js' : PETTANR_ROOT_PATH + 'original_pictures\/new.js',\r
+               REGISTER_ARTIST_JS:                     SERVER_SUPPORT === false ? 'js\/register_artist.js' : PETTANR_ROOT_PATH + 'artists\/new.js',\r
+               JQUERY_URL:                                     SERVER_SUPPORT === false ? 'javascripts\/jquery-1.6.2.min.js' : PETTANR_ROOT_PATH + 'assets\/jquery-162_min.js',\r
+               SERVER_SUPPORT:                         SERVER_SUPPORT\r
        }\r
 })();\r
 \r
 pettanr.view = ( function(){\r
        /* create iframe overlay for user console */\r
-       var location = document.location.pathname,\r
-               isWorkPage =    document.location.href.indexOf( 'http:\/\/localhost:3000\/' ) === 0 ||\r
-                                               location.indexOf( pettanr.CONST.PETTANR_ROOT_PATH ) === 0 ||\r
-                                               location.indexOf( '\/work.html') !== -1,\r
-               deep =  location.indexOf( '\/diary\/') !== -1 ||\r
-                               location.indexOf( '\/test\/') !== -1 ||\r
-                               location.indexOf( '\/help\/') !== -1 ||\r
-                               location.indexOf( '\/sitemap\/') !== -1 ||\r
-                               location.indexOf( '\/wiki\/') !== -1,\r
-               LoginUserNavi;\r
-       \r
-       if( isWorkPage === false){\r
-               LoginUserNavi = {\r
-                       show: function(){\r
-                               var i = pettanr.util.getChildIndex( this.parentNode, this );\r
-                               document.location.href = [\r
-                                               deep === true ? '../' : '',\r
-                                               'work.html',\r
-                                               typeof i === 'number' ? '?view=' + i : ''\r
-                                       ].join( '');\r
-                               return false;\r
-                       },\r
-                       hide: function(){}\r
-               }\r
-       } else {\r
-               LoginUserNavi = {\r
+       var LoginUserNavi = {\r
                        show: function(){\r
                                var i = pettanr.util.getChildIndex( this.parentNode, this );\r
-                               i !== -1 && pettanr.view.show( i );\r
+                               i !== -1 && bootApplication( i );\r
                                return false;\r
                        },\r
                        hide: function(){}\r
                }\r
-       }\r
 \r
        /* debug info */\r
        // ua version, lang, os, plugin ( vml, svg), standerdmode, balloon, rimg\r
@@ -833,40 +728,10 @@ pettanr.view = ( function(){
        var jqWindow,\r
                APPLICATION_LIST = [],\r
                LUNCHER_APPLICATION_LIST = [],\r
-               navi = document.getElementById('global-navi'),\r
-               currentApplication;\r
-       \r
-       function onWindowResize(){\r
-               var w = jqWindow.width(),\r
-                       h = jqWindow.height();\r
-               currentApplication && currentApplication.resize && currentApplication.resize( w, h);\r
-               pettanr.overlay.currentID !== null && pettanr.overlay.onWindowResize( w, h);\r
-       }\r
+               currentApplication = null;\r
        \r
        var AbstractBasicPane = function(){\r
-               this.rootElement = null;\r
-               this.onOpen = function( _w, _h, _option ){\r
-                       // overrride\r
-               };\r
-               this.onClose = function(){\r
-                       // overrride\r
-                       return true;\r
-               } // false の場合、close の拒否 \r
                this.onPaneResize = function( _w, _h ){}\r
-               this.open = function( _w, _h, _option ){\r
-                       if( this.MIN_WIDTH > _w || this.MIN_HEIGHT > _h ){\r
-                               if( Type.isHTMLElement( this.rootElement ) === true ){\r
-                                       // 小さすぎる!、と表示\r
-                               }\r
-                               return;\r
-                       }\r
-                       this.onOpen( _w, _h, _option );\r
-               }\r
-               this.close = function(){\r
-                       if( this.onClose() === false ){\r
-                               \r
-                       }\r
-               }\r
                this.resize = function( _w, _h ){\r
                        if( this.MIN_WIDTH > _w || this.MIN_HEIGHT > _h ){\r
                                if( Type.isHTMLElement( this.rootElement ) === true ){\r
@@ -879,125 +744,219 @@ pettanr.view = ( function(){
                this.MIN_WIDTH = 240;\r
                this.MIN_HEIGHT = 240;\r
        }\r
+       \r
        var AbstractApplication = function(){\r
+               var instance;\r
                this.displayName = 'app name';\r
                this.ID = 'app id';\r
+               this.rootElement = null;\r
+               this.parentElement = null;\r
+               this.nextSibling = null;\r
+               this.open = function( _w, _h /*, _option */ ){\r
+                       instance = this;\r
+                       if( this.MIN_WIDTH > _w || this.MIN_HEIGHT > _h ){\r
+                               if( Type.isHTMLElement( this.rootElement ) === true ){\r
+                                       // 小さすぎる!、と表示\r
+                               }\r
+                       }\r
+                       if( arguments.length > 2){\r
+                               // argumentsRellay( this.onOpen, arguments );\r
+                               this.onOpen.apply( this, arguments );\r
+                       } else {\r
+                               this.onOpen( _w, _h );\r
+                       }\r
+               }\r
+               this.close = function(){\r
+                       if( this.onClose() === false ){\r
+                               return false;\r
+                       }\r
+               }\r
+               this.onOpen = function( _w, _h /*, _option */ ){\r
+                       // overrride\r
+               };\r
+               this.onClose = function(){\r
+                       // overrride\r
+                       return true;\r
+               } // false の場合、close の拒否 \r
+               this.addEventListener = function(){\r
+                       \r
+               }\r
        }\r
        AbstractApplication.prototype = new AbstractBasicPane();\r
        \r
-       return {\r
-               init: function( _funcArray ){\r
-                       jqWindow = pettanr.jqWindow();\r
-                       jqWindow.resize( onWindowResize);\r
-                       \r
-                       var _option = {}; // urlパラメータ\r
-                       \r
-                       pettanr.view.show( pettanr.URL_PARAMS.view || 0, _option );\r
-                       \r
-                       delete pettanr.view.init;\r
-               },\r
-               show: function( APPLICATIONorINDEX, _option ){\r
-                       if( isWorkPage === false ) return;\r
-                       \r
-                       var _applicetion,\r
-                               _elm, i, l,\r
-                               nodesA = navi.getElementsByTagName( 'a') || [],\r
-                               _index = -1;\r
-                       if( typeof APPLICATIONorINDEX === 'number' && APPLICATIONorINDEX < LUNCHER_APPLICATION_LIST.length){\r
-                               _applicetion = LUNCHER_APPLICATION_LIST[ APPLICATIONorINDEX ];\r
-                       } else\r
-                       if( typeof APPLICATIONorINDEX === 'string' ){\r
-                               for( i=0, l=LUNCHER_APPLICATION_LIST.length; i<l; ++i ){\r
-                                       if( APPLICATIONorINDEX === APPLICATION_LIST[ i ].ID ){\r
-                                               _applicetion = APPLICATION_LIST[ i ];\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       } else\r
-                       if( pettanr.view.isApplicationInstance( APPLICATIONorINDEX ) === true ){\r
-                               _applicetion = APPLICATIONorINDEX;\r
-                       } else\r
-                       if( !currentApplication ){\r
-                               _applicetion = LUNCHER_APPLICATION_LIST[ 0 ];\r
+       var ApplicationReference = function( application ){\r
+               this.inOverlay = false;\r
+               this.getUID = function(){\r
+                       return pettanr.util.getIndex( APPLICATION_LIST, application );\r
+               }\r
+               this.boot = function( /* _option */ ){\r
+                       if( arguments.length > 0 ){\r
+                               bootApplication( application, pettanr.util.copyArray( arguments ) );\r
                        } else {\r
-                               return;\r
+                               bootApplication( application );\r
                        }\r
-                       \r
-                       if( !_applicetion ) return;\r
+               }\r
+               this.bootInOverlay = function( /* _option */ ){\r
+                       this.inOverlay = true;\r
+                       pettanr.overlay.show( application, pettanr.util.copyArray( arguments ) );\r
+               }\r
+               this.shutdown = function(){\r
+                       if( this.inOverlay === true ){\r
+                               pettanr.overlay.hide();\r
+                               this.inOverlay = false;\r
+                       } else {\r
+                               bootApplication( 0 );\r
+                       }\r
+               }\r
+               this.addToLancher = function(){\r
+                       if( pettanr.util.getIndex( LUNCHER_APPLICATION_LIST, application ) !== -1 ) return;\r
+                       LUNCHER_APPLICATION_LIST.push( application );\r
+       \r
+                       var navi = document.getElementById('global-navi'),\r
+                               item = document.createElement('a');\r
+                       navi.appendChild( item );\r
+                       navi.style.width = ( ( item.offsetWidth || 80 ) * LUNCHER_APPLICATION_LIST.length ) + 'px';\r
+                       item.href = '#';\r
+                       item.appendChild( document.createTextNode( application.displayName ));\r
+                       item.onclick = LoginUserNavi.show;\r
+               }\r
+       }\r
+\r
+       function bootApplication( APPLICATIONorINDEX, _arguments ){\r
+               var _application,\r
+                       i, j, l, \r
+                       nodesA = document.getElementById('global-navi').getElementsByTagName( 'a') || [],\r
+                       _index = -1;\r
+               if( typeof APPLICATIONorINDEX === 'number' && APPLICATIONorINDEX < LUNCHER_APPLICATION_LIST.length){\r
+                       _application = LUNCHER_APPLICATION_LIST[ APPLICATIONorINDEX ];\r
+               } else\r
+               if( typeof APPLICATIONorINDEX === 'string' ){\r
                        for( i=0, l=LUNCHER_APPLICATION_LIST.length; i<l; ++i ){\r
-                               if( _applicetion === LUNCHER_APPLICATION_LIST[ i ] ){\r
-                                       _index = i;\r
+                               if( APPLICATIONorINDEX === APPLICATION_LIST[ i ].ID ){\r
+                                       _application = APPLICATION_LIST[ i ];\r
                                        break;\r
                                }\r
                        }\r
-                       if( _index !== -1 ){\r
-                               for( i=0, l=nodesA.length; i<l; ++i ){\r
-                                       nodesA[ i ].className = _index === i ? 'current' : '';\r
-                               }\r
+               } else\r
+               if( pettanr.view.isApplicationInstance( APPLICATIONorINDEX ) === true ){\r
+                       _application = APPLICATIONorINDEX;\r
+               } else\r
+               if( !currentApplication ){\r
+                       _application = LUNCHER_APPLICATION_LIST[ 0 ];\r
+               } else {\r
+                       return;\r
+               }\r
+               \r
+               if( !_application ) return;\r
+               \r
+               for( i=0, l=LUNCHER_APPLICATION_LIST.length; i<l; ++i ){\r
+                       if( _application === LUNCHER_APPLICATION_LIST[ i ] ){\r
+                               for( j=0, l=nodesA.length; j<l; ++j ){\r
+                                       nodesA[ j ].className = i === j ? 'current' : '';\r
+                               }                                       \r
+                               break;\r
                        }\r
+               }\r
+               \r
+               if( currentApplication === _application ) return;\r
+               if( currentApplication ){\r
+                       currentApplication.close();\r
+                       currentApplication.rootElement && currentApplication.rootElement.parentNode &&\r
+                               currentApplication.rootElement.parentNode.removeChild( currentApplication.rootElement );\r
+               }\r
                        \r
-                       if( currentApplication === _applicetion ) return;\r
+               currentApplication = _application;\r
+               \r
+               if( _application.nextSibling && _application.nextSibling.parentNode === _application.parentElement ){\r
+                       _application.parentElement.insertBefore( _application.rootElement, _application.nextSibling );\r
+               } else\r
+               if( _application.parentElement ){\r
+                       _application.parentElement.appendChild( _application.rootElement );\r
+               } else {\r
+                       _application.rootElement && document.body.appendChild( _application.rootElement );\r
+               }\r
                        \r
-                       if( currentApplication ){\r
-                               _elm = currentApplication.rootElement;\r
-                               if( _elm ){\r
-                                       _elm.style.display = 'none';\r
-                               }\r
-                               typeof currentApplication.onClose === 'function' && currentApplication.onClose();\r
-                       }\r
-                       currentApplication = _applicetion;\r
+               if( _arguments ){\r
+                       _arguments.unshift( jqWindow.width(), jqWindow.height() );\r
+                       _application.open.apply( _application, _arguments );\r
+                       // argumentsRellay( _application.open, _arguments );\r
+               } else {\r
+                       _application.open( jqWindow.width(), jqWindow.height() );\r
+               }\r
+               pettanr.view.currentID = _application.ID;\r
+       }\r
+       \r
+       function argumentsRellay( _method, _arguments ){\r
+               alert( typeof _method )\r
+               l = _arguments.length;\r
+               if( l > 0 ){\r
+                       var _arg = [];\r
+                       for( i=0; i<l; ++i ){\r
+                               _arg.push( 'a[' + i + ']' );\r
+                       }\r
+                       window['_method'] = _method;\r
+                       //eval( '_method(' + _arg.join(',') + ')' );\r
+                       var f = new Function( 'a', '_method(' + _arg.join(',') + ')' );\r
+                       f( _arguments );\r
+                       window['_method'] = undefined;\r
+               } else {\r
+                       _method();\r
+               }               \r
+       }\r
+       \r
+       function onWindowResize(){\r
+               var w = jqWindow.width(),\r
+                       h = jqWindow.height();\r
+               currentApplication && currentApplication.resize( w, h );\r
+               pettanr.overlay.onWindowResize( w, h );\r
+               pettanr.form.onWindowResize( w, h );\r
+       }\r
+\r
+       return {\r
+               init: function( _funcArray ){\r
+                       jqWindow = pettanr.jqWindow();\r
+                       jqWindow.resize( onWindowResize );\r
                        \r
-                       _elm = _applicetion.rootElement;\r
-                       if( _elm ){\r
-                               _elm.style.display = 'block';\r
-                       }\r
-                       typeof _applicetion.open === 'function' && _applicetion.open( jqWindow.width(), jqWindow.height(), _option );\r
+                       var _option = {}; // urlパラメータ\r
+                       \r
+                       onWindowResize();\r
                        \r
-                       this.currentID = _applicetion.ID;\r
+                       bootApplication( pettanr.URL_PARAMS.view || 0 );\r
+                       \r
+                       delete pettanr.view.init;\r
                },\r
                createBasicPane: function( _class, _options ){\r
                        _class.prototype = new AbstractBasicPane();\r
                        return new _class( _options );\r
                },\r
-               registerAsBasicPane: function( _class ){\r
-                       _class.prototype = new AbstractBasicPane();\r
+               _getAbstractApplication: function(){\r
+                       return new AbstractApplication();\r
                },\r
-               createApplication: function( _class, _options ){\r
+               registerApplication: function( _class, _options ){\r
                        _class.prototype = new AbstractApplication();\r
-                       return new _class( _options );\r
-               },\r
-               registerApplication: function( _application, _addToLancher ){\r
-                       if( pettanr.view._isApplicationInstance( _application ) === true ){\r
-                               \r
+                       _application = new _class( _options );\r
+                       \r
+                       var elm = _application.rootElement;\r
+                       if( Type.isHTMLElement( elm ) === false ) return null;\r
+                        \r
+                       _application.parentElement = elm.parentNode;\r
+                       _application.nextSibling = elm.nextSibling;\r
+                       \r
+                       if( elm.parentNode ){\r
+                               elm.parentNode.removeChild( elm );\r
                        }\r
                        APPLICATION_LIST.push( _application );\r
-                       if( _addToLancher === true ){\r
-                               pettanr.view.addApplicationToLancher( _application );\r
-                       }\r
-               },\r
-               addApplicationToLancher: function( _application ){\r
-                       // if( pettanr.view.isApplicationInstance( _application ) === false ) return;\r
-                       \r
-                       if( pettanr.util.getIndex( LUNCHER_APPLICATION_LIST, _application ) !== -1 ) return;\r
-                       LUNCHER_APPLICATION_LIST.push( _application );\r
-\r
-                       var item = document.createElement('a');\r
-                       navi.appendChild( item );\r
-                       navi.style.width = ( ( item.offsetWidth || 80 ) * LUNCHER_APPLICATION_LIST.length ) + 'px';\r
-                       item.href = '#';\r
-                       item.appendChild( document.createTextNode( _application.displayName ));\r
-                       item.onclick = LoginUserNavi.show;\r
+                       return new ApplicationReference( _application );\r
                },\r
                isBasicPaneInstance: function( _basicPane ){\r
                        return  _basicPane instanceof AbstractBasicPane;\r
                },\r
                isApplicationInstance: function( _application ){\r
-                       return pettanr.util.getIndex( APPLICATION_LIST, _application ) !== -1;\r
-                       // return _application instanceof AbstractApplication;\r
-               },\r
-               _isApplicationInstance: function( _application ){\r
                        return _application instanceof AbstractApplication;\r
                },\r
+               isApplicationReference: function( _reference ){\r
+                       return _reference instanceof ApplicationReference;\r
+               },\r
                currentID:      null,\r
                EDITOR:         'editor',\r
                OVERLAY:        'overlay'\r
@@ -1006,88 +965,96 @@ pettanr.view = ( function(){
 \r
 pettanr.overlay = ( function(){\r
        var SHADOW_OPACITY = 0.5,\r
+               ELM_CONTAINER = document.getElementById( 'overlay-container' ),\r
                jqConteiner, jqShadow, jqCloseButton,// jqBody, \r
                currentOverlay = null,\r
+               bootParams = null,\r
                visible = false,\r
                windowW, windowH;\r
 \r
-       function close(){\r
-               currentOverlay && currentOverlay.onClose && currentOverlay.onClose();\r
-               pettanr.overlay.hide();         \r
-       }\r
        function asyncResize(){\r
-               currentOverlay.onWindowResize( windowW, windowH);\r
+               currentOverlay.resize( windowW, windowH );\r
        }\r
        function onCloseClick( e){\r
-               close();\r
+               pettanr.overlay.hide();\r
                e.preventDefault();\r
                return false;           \r
        }\r
+       function onFadeInComplete(){\r
+\r
+       }\r
+       function onFadeOutComplete(){\r
+               currentOverlay.close();\r
+               currentOverlay.rootElement.style.display = 'none';\r
+               currentOverlay.rootElement.style.visibility = 'hidden';\r
+               currentOverlay = null;  \r
+       }\r
        return {\r
                init: function(){\r
                        //jqBody = pettanr.jqBody();\r
                        jqConteiner = $( '#overlay-container');\r
                        jqShadow = $( '#overlay-shadow');\r
-                       jqCloseButton = $( '#overlay-close-button').click( onCloseClick);\r
+                       jqCloseButton = $( '#overlay-close-button').click( onCloseClick );\r
                        \r
-                       pettanr.key.addKeyDownEvent( pettanr.view.OVERLAY, 27, false, false, close); // 27.esc\r
+                       pettanr.key.addKeyDownEvent( pettanr.view.OVERLAY, 27, false, false, pettanr.overlay.hide ); // 27.esc\r
                        \r
                        delete pettanr.overlay.init;\r
                },\r
-               show: function( _currentOverlay){\r
-                       if( visible === true && currentOverlay === _currentOverlay) return;\r
+               show: function( _overlay, _bootParams ){\r
+                       if( visible === true && currentOverlay === _overlay ) return;\r
+                       if( pettanr.view.isApplicationInstance( _overlay ) === false ) return;\r
+                       \r
                        document.body.style.overflow = 'hidden';\r
+                       \r
+                       this.visible = visible = true;\r
+                       this.currentID = _overlay.ID;\r
+                       currentOverlay = _overlay;\r
+                       bootParams = _bootParams;\r
+\r
                        jqConteiner.stop().css( {\r
                                filter:         '',\r
                                opacity:        '',\r
                                top:            document.documentElement.scrollTop || document.body.scrollTop\r
-                       }).fadeIn();\r
-                       this.visible = visible = true;\r
-                       currentOverlay = _currentOverlay;\r
-                       this.currentID = _currentOverlay.ID;\r
-                       jqCloseButton.toggle( !!_currentOverlay.onClose);\r
+                       }).fadeIn( onFadeInComplete );\r
+                       \r
+                       currentOverlay.rootElement.style.display = '';\r
+                       currentOverlay.rootElement.style.visibility = 'visible';\r
+                       \r
+                       ELM_CONTAINER.insertBefore( currentOverlay.rootElement, document.getElementById( 'overlay-close-button' ));\r
+       \r
+                       if( Type.isArray( bootParams ) === true ){\r
+                               bootParams.unshift( windowW, windowH )\r
+                               currentOverlay.open.apply( currentOverlay, bootParams );\r
+                       } else {\r
+                               currentOverlay.open( windowW, windowH, bootParams );\r
+                       }\r
                },\r
                hide: function(){\r
-                       currentOverlay = null;\r
                        if( visible === false) return;\r
                        document.body.style.overflow = '';\r
+                       \r
                        jqConteiner.stop().css( {\r
                                filter:         '',\r
                                opacity:        ''\r
-                       }).fadeOut();\r
+                       }).fadeOut( onFadeOutComplete );\r
                        this.visible = visible = false;\r
                        this.currentID = null;\r
                },\r
                visible: visible,\r
                currentID: null,\r
-               onWindowResize: function( _windowW, _windowH){\r
+               onWindowResize: function( _windowW, _windowH ){\r
+                       windowW = _windowW;\r
+                       windowH = _windowH;                     \r
+                       \r
+                       if( currentOverlay === null ) return;\r
+                       \r
                        jqConteiner.css({\r
                                height:         _windowH,\r
                                top:            document.documentElement.scrollTop || document.body.scrollTop\r
                        });\r
-                       jqShadow.css( { height: _windowH});\r
-                       windowW = _windowW;\r
-                       windowH = _windowH;\r
+                       jqShadow.css( { height: _windowH });\r
                        // 先にeditorのcanvasを確定する。\r
-                       currentOverlay && currentOverlay.onWindowResize && setTimeout( asyncResize, 0);\r
-               },\r
-               registerOverlay: function( _basicPane){\r
-                       var _api = pettanr.view.createBasicPane( _basicPane );\r
-                       // OverlayAPI\r
-                       return {\r
-                               show: function( _basicPane ){\r
-                                       \r
-                               },\r
-                               hide: function( _basciPane ){\r
-                                       \r
-                               },\r
-                               isCurrent: function( _basicPane ){\r
-                                       \r
-                               }\r
-                       }\r
-               },\r
-               isOverlay: function( _basicPane ){\r
-                       \r
+                       setTimeout( asyncResize, 0);\r
                }\r
        }\r
 })();\r
@@ -1123,21 +1090,21 @@ pettanr.key = ( function(){
                log.html( [ e.keyCode, e.shiftKey, e.ctrlKey, e.altKey, e.type].join( ','));\r
                //keyOperationChatcher.val( '');\r
                var cancel = false,\r
-                       callback = e.type,\r
+                       type = e.type,\r
                        key = e.keyCode,\r
                        overlayEnabled = pettanr.overlay.visible === true,\r
                        currentViewID = overlayEnabled === true ? pettanr.overlay.currentID : pettanr.view.currentID;\r
-               if( callback === 'keypress') callback = 'keydown';\r
-               if( pettanr.form.keyEventRellay( e) === false){\r
+               if( type === 'keypress') type = 'keydown';\r
+               if( pettanr.form.keyEventRellay( e ) === false ){\r
                        var shift = e.shiftKey,\r
                                ctrl = e.ctrlKey,\r
                                l = KEYEVENT_ARRAY.length,\r
                                d;\r
                        if( key === 16 || e.shiftKey === true){\r
-                               shiftEnabled = callback !== 'keyup';\r
+                               shiftEnabled = type !== 'keyup';\r
                        }\r
                        if( key === 17 || e.ctrlKey === true){\r
-                               ctrlEnabled = callback !== 'keyup';\r
+                               ctrlEnabled = type !== 'keyup';\r
                        }\r
 \r
                        for( var i=0; i<l; i++){\r
@@ -1150,24 +1117,26 @@ pettanr.key = ( function(){
                                        ( d.shift === undefined || d.shift === shift) &&\r
                                        ( d.ctrl === undefined || d.ctrl === ctrl)\r
                                ){\r
-                                       ( function( func, e){\r
-                                               func && setTimeout( function(){\r
-                                                       func( e);\r
-                                                       func = e = null;\r
-                                               }, 0);\r
-                                       })( d[callback], e);\r
+                                       Type.isFunction( d[ type ]) === true && new asyncCallback( d[ type ], e );\r
                                        cancel = true;\r
                                }\r
                        }\r
                }\r
                if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true){ // 13.enter 18.esc 9.tab 27.esc   || ( key === 13 && overlayEnabled === false)\r
                        e.preventDefault();\r
-               e.keyCode = 0;\r
+               e.keyCode      = 0;\r
                e.cancelBubble = true;\r
-               e.returnValue = false;\r
+               e.returnValue  = false;\r
                        return false;\r
                }\r
        }\r
+       function asyncCallback( func, e ){\r
+               window.setTimeout( _callback, 0 );\r
+               function _callback(){\r
+                       func( e );\r
+                       func = e = null;\r
+               }\r
+       }       \r
        \r
        var keyPress = pettanr.ua.isIE === true && pettanr.ua.ieRenderingVersion < 8 ? ( function( e){\r
                        var key = e.keyCode;\r
@@ -1183,12 +1152,12 @@ pettanr.key = ( function(){
 \r
                        jqWindow = pettanr.jqWindow().focus();\r
                        keyOperationChatcher = pettanr.jqDocument()\r
-                               .keydown( keyHit)\r
-                               .keyup( keyHit)\r
+                               .keydown( keyHit )\r
+                               .keyup( keyHit )\r
                                .mouseenter( function(){\r
                                        jqWindow.focus();\r
                                });\r
-                       keyPress && keyOperationChatcher.keypress( keyPress);\r
+                       keyPress !== null && keyOperationChatcher.keypress( keyPress );\r
 \r
                        delete pettanr.key.init;\r
                },\r
@@ -1237,6 +1206,8 @@ pettanr.form = ( function(){
        var     FORM_GROUP_TABLE = {},\r
                currentID = null,\r
                currentItem = null,\r
+               CLASSNAME_COMBOBOX_OPTION = 'combobox-option',\r
+               windowW, windowH,\r
                ELM_A_ORIGIN = ( function(){\r
                        var ret = document.createElement( 'a');\r
                        ret.href = '#';\r
@@ -1246,99 +1217,152 @@ pettanr.form = ( function(){
                        var ret = document.createElement( 'input');\r
                        ret.type = 'text';\r
                        return ret;\r
+               })(),\r
+               ELM_COMBOBOX = ( function(){\r
+                       var ret = document.createElement( 'a'),\r
+                               elmToggle = document.createElement( 'span' ),\r
+                               elmValue = document.createElement( 'span' );\r
+                       ret.href = '#';\r
+                       ret.appendChild( elmToggle );\r
+                       ret.appendChild( elmValue );\r
+                       elmToggle.className = 'combobox-toggle';\r
+                       elmValue.className = 'combobox-value';\r
+                       \r
+                       elmToggle.appendChild( document.createTextNode( '▼' ));\r
+                       elmValue.appendChild( document.createTextNode( 'null' ));\r
+                       return ret;\r
                })();\r
                \r
-       var InputTextClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater){\r
-               validater = typeof validater === 'function' ? validater : null;\r
+       var InputTextClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater ){\r
+               validater = Type.isFunction( validater ) === true ? validater : null;\r
                \r
-               var elmValue = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'editable-value')[ 0],\r
+               var elmValue = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'editable-value' )[ 0],\r
                        value,\r
-                       index = GROUP_ID ? FORM_GROUP_TABLE[ GROUP_ID].length : -1,\r
-                       instance,\r
+                       instance = this,\r
                        focus = false,\r
                        visible = true,\r
                        enabled = true,\r
-                       elmA = ELM_A_ORIGIN.cloneNode( true);\r
+                       elmA = ELM_A_ORIGIN.cloneNode( true );\r
                \r
-               if( elmValue === undefined){\r
+               if( elmValue === undefined ){\r
                        alert( 'error!');\r
                }\r
                value = elmValue.innerHTML;\r
                elmValue.innerHTML = '';\r
                elmValue.className += ' editable-text';\r
+               try {\r
+                       elmA.innerHTML = value;\r
+               } catch(e){\r
+                       alert( value )\r
+               }\r
                \r
-               elmA.innerHTML = value;\r
-               elmValue.appendChild( elmA);\r
+               elmValue.appendChild( elmA );\r
                WRAPPER_ELM.onclick = onClick;\r
                \r
-               function onClick( e){\r
+               function onClick(){\r
                        focus = true;\r
-                       start( instance);\r
+                       start( instance );\r
                        elmA.style.display = 'none';\r
-                       elmValue.appendChild( ELM_INPUT_TEXT);\r
+                       elmValue.appendChild( ELM_INPUT_TEXT );\r
                        ELM_INPUT_TEXT.value = value;\r
                        ELM_INPUT_TEXT.focus();\r
                        ELM_INPUT_TEXT.select();\r
-                       e && e.preventDefault();\r
                        return false;\r
                }\r
                \r
-               return {\r
-                       init: function(){\r
-                               instance = this;\r
-                               delete this.init;\r
-                       },\r
-                       value: function( _value){\r
-                               if( _value !== undefined){\r
-                                       elmA.innerHTML = _value;\r
-                                       value = _value;\r
-                                       \r
-                                       if( focus === true){\r
-                                               ELM_INPUT_TEXT.value = value;\r
-                                       }\r
-                               }\r
-                               currentItem === instance && this.finish();\r
-                               return value;\r
-                       },\r
-                       start: function(){\r
-                               onClick();\r
-                       },\r
-                       finish: function( keep){\r
-                               var _newValue = ELM_INPUT_TEXT.value,\r
-                                       _validated = validater !== null ? '' + validater( _newValue) : _newValue;\r
-                               _newValue = keep !== true ? _validated : value;\r
-\r
-                               elmValue.removeChild( ELM_INPUT_TEXT);\r
-                               \r
-                               elmA.innerHTML = _newValue;\r
-                               elmA.style.display = 'block';\r
+               this.value = function( _value ){\r
+                       if( _value !== undefined){\r
+                               elmA.innerHTML = _value;\r
+                               value = _value;\r
                                \r
-                               ON_UPDATE_FUNCTION && _newValue !== value && ON_UPDATE_FUNCTION( _newValue, value);\r
-                               finish( instance);\r
-                               value = _newValue;\r
-                               focus = false;\r
-                       },\r
-                       enabled: function(){\r
-                               return enabled;\r
-                       },\r
-                       visible: function( _visible){\r
-                               if( _visible === true){\r
-                                       WRAPPER_ELM.style.display = '';\r
-                                       visible = true;\r
-                               } else\r
-                               if( _visible === false){\r
-                                       WRAPPER_ELM.style.display = 'none';\r
-                                       visible = false;\r
+                               if( focus === true){\r
+                                       ELM_INPUT_TEXT.value = value;\r
                                }\r
-                               return visible;\r
-                       },\r
-                       index : index,\r
-                       groupID: GROUP_ID\r
+                       }\r
+                       currentItem === instance && instance.blur();\r
+                       return value;\r
+               }\r
+               this.focus = function(){\r
+                       onClick();\r
+               }\r
+               this.blur = function( keep ){\r
+                       var _newValue = ELM_INPUT_TEXT.value,\r
+                               _validated = validater !== null ? '' + validater( _newValue ) : _newValue;\r
+                       _newValue = keep !== 27 ? _validated : value; // 27:ESC\r
+\r
+                       elmValue.removeChild( ELM_INPUT_TEXT );\r
+                       \r
+                       elmA.innerHTML = _newValue;\r
+                       elmA.style.display = 'block';\r
+                       \r
+                       ON_UPDATE_FUNCTION && _newValue !== value && ON_UPDATE_FUNCTION( _newValue, value );\r
+                       \r
+                       value = _newValue;\r
+                       focus = false;\r
+                       \r
+                       currentItem = null;\r
+               }\r
+               this.enabled = function(){\r
+                       return enabled;\r
+               }\r
+               this.visible = function( _visible ){\r
+                       if( _visible === true){\r
+                               WRAPPER_ELM.style.display = '';\r
+                               visible = true;\r
+                       } else\r
+                       if( _visible === false){\r
+                               WRAPPER_ELM.style.display = 'none';\r
+                               visible = false;\r
+                       }\r
+                       return visible;\r
                }\r
+               this.groupID = GROUP_ID;\r
+       }\r
+       \r
+       var ButtonClass = function( WRAPPER_ELM, ON_CLICK_FUNCTION, GROUP_ID ){\r
+               var className = WRAPPER_ELM.className || '',\r
+                       instance = this,\r
+                       focus = false,\r
+                       visible = true,\r
+                       enabled = true;\r
+                       \r
+               WRAPPER_ELM.onclick = onClick;\r
+               \r
+               function onClick(){\r
+                       focus = true;\r
+                       ON_CLICK_FUNCTION();\r
+                       return false;\r
+               }\r
+               this.focus = function(){\r
+                       focus = true;\r
+                       WRAPPER_ELM.className = className + ' button-has-focus';\r
+                       start( instance );\r
+               }\r
+               this.blur = function( keyCode ){\r
+                       keyCode === 13 && ON_CLICK_FUNCTION();\r
+                       WRAPPER_ELM.className = className;\r
+                       focus = false;\r
+                       finish( instance );\r
+               }\r
+               this.enabled = function(){\r
+                       return enabled;\r
+               }\r
+               this.visible = function( _visible ){\r
+                       if( _visible === true){\r
+                               WRAPPER_ELM.style.display = '';\r
+                               visible = true;\r
+                       } else\r
+                       if( _visible === false){\r
+                               WRAPPER_ELM.style.display = 'none';\r
+                               visible = false;\r
+                       }\r
+                       return visible;\r
+               }\r
+               this.groupID = GROUP_ID;\r
        }\r
 \r
-       var FileInputClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater, elmFileInput){\r
-               validater = typeof validater === 'function' ? validater : null;\r
+       var FileInputClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater, elmFileInput ){\r
+               validater = Type.isFunction( validater ) === true ? validater : null;\r
                \r
                var elmFilePath = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'file-path')[ 0],\r
                        value,\r
@@ -1346,8 +1370,8 @@ pettanr.form = ( function(){
                        instance,\r
                        focus = false,\r
                        visible = true,\r
-                       enabled = true,\r
-                       elmFileInput = WRAPPER_ELM.getElementsByTagName('input')[0] || elmFileInput || document.createElement( 'input');\r
+                       enabled = true;\r
+               elmFileInput = WRAPPER_ELM.getElementsByTagName('input')[0] || elmFileInput || document.createElement( 'input');\r
                elmFileInput.type = 'file';\r
                elmFileInput.style.visivility = 'hidden';\r
 \r
@@ -1356,7 +1380,7 @@ pettanr.form = ( function(){
                \r
                function onClick( e){\r
                        focus = true;\r
-                       start( instance);\r
+                       start( instance );\r
                        elmFileInput.click();\r
                        return false;\r
                }\r
@@ -1369,10 +1393,10 @@ pettanr.form = ( function(){
                                instance = this;\r
                                delete this.init;\r
                        },\r
-                       start: function(){\r
+                       focus: function(){\r
                                onClick();\r
                        },\r
-                       finish: function( keep){\r
+                       blur: function( keep ){\r
                                focus = false;\r
                        },\r
                        enabled: function(){\r
@@ -1394,30 +1418,266 @@ pettanr.form = ( function(){
                }\r
        }\r
 \r
+       var ComboBoxClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID ){\r
+               var elmBox = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'combobox' )[ 0 ],\r
+                       elmA = ELM_COMBOBOX.cloneNode( true ),\r
+                       elmToggle = pettanr.util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],\r
+                       elmValue = pettanr.util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,\r
+                       value, index = 0,\r
+                       optionList = [],\r
+                       instance = this,\r
+                       oldBodyMouseupHandler,\r
+                       focus = false,\r
+                       visible = true,\r
+                       enabled = true;\r
+                       \r
+               elmBox.appendChild( elmA );\r
+               WRAPPER_ELM.onclick = onClick;\r
+               \r
+               function onClick(){\r
+                       WRAPPER_ELM.onclick = null;\r
+                       focus = true;\r
+                       elmA.className = 'combobox-has-focus';\r
+                       start( instance );\r
+                       OptionControl.show( instance, optionList );\r
+                       return false;\r
+               }\r
+               this.elm = elmBox;\r
+               this.focus = function(){\r
+                       onClick();\r
+               }\r
+               this.blur = function( keyCode ){\r
+                       OptionControl.hide( instance );\r
+                       focus = false;\r
+                       elmA.className = '';\r
+                       finish( instance );\r
+                       WRAPPER_ELM.onclick = onClick;\r
+               }\r
+               this.enabled = function(){\r
+                       return enabled;\r
+               }\r
+               this.visible = function( _visible ){\r
+                       if( _visible === true){\r
+                               WRAPPER_ELM.style.display = '';\r
+                               visible = true;\r
+                       } else\r
+                       if( _visible === false){\r
+                               WRAPPER_ELM.style.display = 'none';\r
+                               visible = false;\r
+                       }\r
+                       return visible;\r
+               }\r
+               this.value = function( _value ){\r
+                       var i, j,\r
+                               l=optionList.length,\r
+                               _option;\r
+                       if( Type.isString( _value ) === true && value !== _value ){\r
+                               for( i=0; i<l; ++i ){\r
+                                       _option = optionList[ i ];\r
+                                       if( _value === _option.value ){\r
+                                               value = _value;\r
+                                               index = i;\r
+                                               elmValue.data = _option.displayValue;\r
+                                               if( focus === true ){\r
+                                                       OptionControl.update( instance, _value );\r
+                                               }\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       return value;\r
+               }\r
+               this.selectIndex = function(){\r
+                       return index;\r
+               }\r
+               this.createOption = function( displayValue, _value, isSelected ){\r
+                       var exist = false,\r
+                               option = null, _option,\r
+                               _index;\r
+                       _value = _value || displayValue;\r
+                       for( var i = 0, l = optionList.length; i < l; ++i ){\r
+                               if( _value === optionList[ i ].value ){\r
+                                       option = optionList[ i ];\r
+                                       _index = i;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if( option === null ){\r
+                               option = new OptionClass( instance, displayValue, _value );\r
+                               _index = optionList.length;\r
+                               optionList.push( option );\r
+                       }\r
+                       if( isSelected === true ){\r
+                               elmValue.data = option.displayValue;\r
+                               value = _value;\r
+                               index = _index;\r
+                               for( i = 0, l = optionList.length; i < l; ++i ){\r
+                                       _option = optionList[ i ];\r
+                                       _option.current( _option.value === _value );\r
+                               }\r
+                       }\r
+                       return option;\r
+               }\r
+               this.groupID = GROUP_ID;\r
+       }\r
+       \r
+       var OptionControl = ( function(){\r
+               var ELM_OPTION_WRAPPER = ( function(){\r
+                               var ret = document.createElement( 'ul' );\r
+                               ret.className = 'option-container';\r
+                               return ret;\r
+                       })();\r
+               var currentCombobox = null,\r
+                       optionList,\r
+                       elm,\r
+                       value,\r
+                       currentOption,\r
+                       currentIndex;\r
+               \r
+               function updateCurrrentOption( _value, _updateCombobox ){\r
+                       var _option;\r
+                       for( var i=0, l=optionList.length; i<l; ++i ){\r
+                               _option = optionList[ i ]\r
+                               if( _value === _option.value ){\r
+                                       currentOption && currentOption.current( false );\r
+                                       _option.current( true );\r
+                                       currentOption = _option;\r
+                                       currentIndex = i;\r
+                                       _updateCombobox === true && currentCombobox.value( _value );\r
+                               }\r
+                       }\r
+               }\r
+               function bodyMouseupHandler(){\r
+                       currentCombobox.blur();\r
+                       OptionControl.hide( currentCombobox );\r
+               }\r
+               function updateWrapperPosition(){\r
+                       var position = pettanr.util.getAbsolutePosition( elm );\r
+                       \r
+                       ELM_OPTION_WRAPPER.style.cssText = [\r
+                                       'width:', elm.offsetWidth - 2, 'px;',\r
+                                       'left:', position.x, 'px;',\r
+                                       'top:', position.y + elm.offsetHeight, 'px;'\r
+                               ].join('');                     \r
+               }\r
+               return {\r
+                       show: function( _combobox, _optionList ){\r
+                               if( currentItem !== _combobox || currentCombobox === _combobox ) return;\r
+                               currentCombobox && currentCombobox.blur();\r
+                               \r
+                               currentCombobox = _combobox;\r
+                               optionList = _optionList;\r
+                               elm = _combobox.elm;\r
+                               \r
+                               updateCurrrentOption( _combobox.value(), false );\r
+                               \r
+                               for( var i=0, l=optionList.length; i<l; ++i ){\r
+                                       ELM_OPTION_WRAPPER.appendChild( optionList[ i ].elm );\r
+                               }\r
+                               \r
+                               document.body.appendChild( ELM_OPTION_WRAPPER );\r
+                               oldBodyMouseupHandler = document.body.onmouseup;\r
+                               document.body.onmouseup = bodyMouseupHandler;\r
+                               \r
+                               updateWrapperPosition();\r
+                       },\r
+                       hide: function( _combobox ){\r
+                               if( currentCombobox !== _combobox ) return;\r
 \r
-       function start( _currentItem){\r
-               currentItem !== _currentItem && currentItem && currentItem.finish();\r
+                               ELM_OPTION_WRAPPER.parentNode && ELM_OPTION_WRAPPER.parentNode.removeChild( ELM_OPTION_WRAPPER );\r
+                               while( ELM_OPTION_WRAPPER.firstChild ){\r
+                                       ELM_OPTION_WRAPPER.removeChild( ELM_OPTION_WRAPPER.firstChild );\r
+                               }\r
+                               currentCombobox = null;\r
+                               currentOption = null;\r
+                               currentIndex = 0;\r
+                               \r
+                               document.body.onmouseup = oldBodyMouseupHandler;\r
+                       },\r
+                       change: function( down ){\r
+                               var l = optionList.length,\r
+                                       way = down === true ? 1 : -1;\r
+                                       i = currentIndex + way\r
+                               if( currentCombobox === false || l < 2 ) return;\r
+                               i = i < 0 ?\r
+                                               l - 1 :\r
+                                               i < l ? i : 0;\r
+                               updateCurrrentOption( optionList[ i ].value, false );\r
+                       },\r
+                       update: function( _combobox, _value ){\r
+                               if( currentCombobox !== _combobox || currentItem !== _combobox ) return;\r
+                               if( currentOption.value === _value ) return;\r
+                               updateCurrrentOption( _value, true );\r
+                       },\r
+                       decide: function(){\r
+                               currentCombobox.value( currentOption.value );\r
+                               currentCombobox.blur();\r
+                               OptionControl.hide( currentCombobox );\r
+                       },\r
+                       onWindowResize: function( _w, _h ){\r
+                               setTimeout( updateWrapperPosition, 0 );\r
+                       }\r
+               }\r
+       })();\r
+       \r
+               var OptionClass = function( combobox, displayValue, value ){\r
+                       var elm = document.createElement( 'li' ),\r
+                               a = document.createElement( 'a' ),\r
+                               isCurrent = undefined;\r
+                       elm.appendChild( a );\r
+                       a.appendChild( document.createTextNode( displayValue ));\r
+                       elm.className = CLASSNAME_COMBOBOX_OPTION;\r
+                       a.href = '#';\r
+                       \r
+                       a.onmousedown = onClick; // onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!\r
+                       function onClick(){\r
+                               OptionControl.update( combobox, value );\r
+                               OptionControl.hide( combobox );\r
+                               combobox.blur();\r
+                               return false;\r
+                       }\r
+                       this.elm = elm;\r
+                       this.displayValue = displayValue;\r
+                       this.value = value = value || displayValue;\r
+                       this.current = function( _isCurrent ){\r
+                               if( Type.isBoolean( _isCurrent ) === true && isCurrent !== _isCurrent ){\r
+                                       elm.className = CLASSNAME_COMBOBOX_OPTION + ( _isCurrent === true ? ' current-option' : '' );\r
+                                       isCurrent = _isCurrent;\r
+                               }\r
+                               return !!isCurrent;\r
+                       }\r
+               }\r
+       \r
+\r
+       function start( _currentItem ){\r
+               currentItem !== _currentItem && currentItem && currentItem.blur();\r
                currentItem = _currentItem;\r
        }\r
-       function finish( _currentItem){\r
-               if( currentItem !== _currentItem) return;\r
-               currentItem = null;\r
+       function finish( _currentItem ){\r
+               currentItem = currentItem === _currentItem ? null : currentItem;\r
        }\r
 \r
-       function tabShift( _groupID, _index, _way){\r
-               var GROUP_ARRAY = FORM_GROUP_TABLE[ _groupID] || [],\r
+       function tabShift( _groupID, _index, _way ){\r
+               // currentApplication の確認\r
+               //if( _applicationID === ( pettanr.overlay.visible === true ? pettanr.overlay.currentID : pettanr.view.currentID )){\r
+               //      return;\r
+               //};\r
+               var GROUP_ARRAY = FORM_GROUP_TABLE[ _groupID ] || [],\r
                        l = GROUP_ARRAY.length,\r
-                       i = _index +_way;\r
-               if( l < 2) return;\r
-               while( i !== _index){\r
+                       i = _index + _way,\r
+                       _item;\r
+               if( l < 2 ) return;\r
+               while( i !== _index ){\r
                        i = i < 0 ?\r
-                               l -1 :\r
-                               i === l ? 0 : i; // 0 < i < l\r
-                       if( GROUP_ARRAY[ i].enabled() === true && GROUP_ARRAY[ i].visible() === true) break;\r
+                               l - 1 :\r
+                               i < l ? i : 0; // 0 < i < l\r
+                       _item = GROUP_ARRAY[ i ];\r
+                       if( _item.enabled() === true && _item.visible() === true ){\r
+                               setTimeout( _item.focus, 0 );\r
+                               return;\r
+                       }\r
                        i += _way;\r
                }\r
-               if( i === _index) return;\r
-               setTimeout( GROUP_ARRAY[ i].start, 0);\r
        }\r
 \r
        return {\r
@@ -1425,49 +1685,75 @@ pettanr.form = ( function(){
                focus: function(){\r
                        return currentItem !== null; \r
                },\r
-               keyEventRellay: function( e){\r
-                       if( e.type === 'keyup') return false;\r
-                       if( currentItem === null) return false;\r
+               keyEventRellay: function( e ){\r
+                       if( e.type === 'keyup' ) return false;\r
+                       if( currentItem === null ) return false;\r
                        \r
                        var keyCode = e.keyCode;\r
-                       if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt\r
-                               var _groupID = currentItem.groupID,\r
-                                       _index = currentItem.index;\r
-                               currentItem.finish( keyCode === 27);\r
-                               keyCode === 9 && _groupID && tabShift( _groupID, _index, e.shiftKey === true ? -1 : 1);\r
-                               keyCode === 13 && _groupID && tabShift( _groupID, _index, 1);\r
+                       var _groupID = currentItem.groupID,\r
+                               _index = pettanr.util.getIndex( FORM_GROUP_TABLE[ _groupID ], currentItem );\r
+                       if( currentItem instanceof ComboBoxClass ) {\r
+                               if( 37 <= keyCode && keyCode <= 40 ){ // ↑38 ←37 →39 ↓40\r
+                                       OptionControl.change( keyCode === 40 );\r
+                                       return true;\r
+                               } else\r
+                               keyCode === 13 && OptionControl.decide();\r
+                       }\r
+                       if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true ){ // 13.return 27.esc 9.tab 18.alt\r
+                               currentItem && currentItem.blur( keyCode );\r
+                               keyCode === 9 && _groupID && tabShift( _groupID, _index, e.shiftKey === true ? -1 : 1 );\r
+                               keyCode === 13 && _groupID && tabShift( _groupID, _index, 1 );\r
                        }\r
                        return true;\r
                },\r
-               createInputText: function( _elm, _onUpdate, _groupID, _validater){\r
+               createUIGroup: function( _applicationReferance ){\r
+                       \r
+               },\r
+               createInputText: function( _elm, _onUpdate, _groupID, _validater ){\r
                        if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){\r
                                FORM_GROUP_TABLE[ _groupID] = [];\r
                        }\r
-                       var ret = new InputTextClass( _elm, _onUpdate, _groupID, _validater);\r
-                       ret.init();\r
-                       _groupID && FORM_GROUP_TABLE[ _groupID].push( ret);\r
+                       var ret = new InputTextClass( _elm, _onUpdate, _groupID, _validater );\r
+                       _groupID && FORM_GROUP_TABLE[ _groupID ].push( ret );\r
                        return ret;\r
                },\r
-               createFileInput: function( _elm, _onUpdate, _groupID, _validater, _elmFileInput){\r
+               createButton: function( _elm, _onClick, _groupID ){\r
+                       if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){\r
+                               FORM_GROUP_TABLE[ _groupID ] = [];\r
+                       }\r
+                       var ret = new ButtonClass( _elm, _onClick, _groupID );\r
+                       _groupID && FORM_GROUP_TABLE[ _groupID ].push( ret );\r
+                       return ret;\r
+               },\r
+               createFileInput: function( _elm, _onUpdate, _groupID, _validater, _elmFileInput ){\r
                        if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){\r
                                FORM_GROUP_TABLE[ _groupID] = [];\r
                        }\r
-                       var ret = FileInputClass( _elm, _onUpdate, _groupID, _validater, _elmFileInput);\r
-                       ret.init();\r
+                       var ret = FileInputClass( _elm, _onUpdate, _groupID, _validater, _elmFileInput );\r
                        _groupID && FORM_GROUP_TABLE[ _groupID].push( ret);\r
                        return ret;\r
                },\r
+               createCombobox: function( _elm, _onUpdate, _groupID, _optionList ){\r
+                       if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){\r
+                               FORM_GROUP_TABLE[ _groupID ] = [];\r
+                       }\r
+                       var ret = new ComboBoxClass( _elm, _onUpdate, _groupID );\r
+                       _groupID && FORM_GROUP_TABLE[ _groupID ].push( ret );\r
+                       return ret;\r
+               },\r
                createCheckBox: function(){\r
                        \r
                },\r
                createRadio: function(){\r
                        \r
                },\r
-               createButton: function(){\r
+               createSlider: function(){\r
                        \r
                },\r
-               createListBox: function(){\r
-                       \r
+               onWindowResize: function( w, h ){\r
+                       windowW = w;\r
+                       windowH = h;\r
+                       currentItem instanceof ComboBoxClass && OptionControl.onWindowResize( w, h );\r
                }\r
        }\r
 })();\r
@@ -1500,15 +1786,15 @@ pettanr.form = ( function(){
  * \r
  */\r
 pettanr.balloon = ( function() {\r
-       var MIN_BALLOON_WIDTH = 30,\r
+       var MIN_BALLOON_WIDTH  = 30,\r
                MIN_BALLOON_HEIGHT = 30,\r
-               TAIL_WIDTH = 6,\r
-               TAIL_HEIGHT = 10,\r
-               STROKE_WIDTH = 1.2,\r
-               PADDING_TOP = TAIL_HEIGHT,\r
-               PADDING_LEFT = TAIL_HEIGHT,\r
-               ACCURACY = 1, // 有効少数桁        \r
-               IS_VML = pettanr.ua.isIE === true && pettanr.ua.ieVersion < 9,\r
+               NUM_BALLOON_IMAGE  = 24,\r
+               TAIL_WIDTH         = 6,\r
+               TAIL_HEIGHT        = 10,\r
+               STROKE_WIDTH       = 1.2,\r
+               PADDING_TOP        = TAIL_HEIGHT,\r
+               PADDING_LEFT       = TAIL_HEIGHT,\r
+               IS_VML             = pettanr.ua.isIE === true && pettanr.ua.ieVersion < 9,\r
                ELM_BALLOON_ORIGIN = ( function(){\r
                        var ret;\r
                        try {\r
@@ -1534,39 +1820,47 @@ pettanr.balloon = ( function() {
                                return null;\r
                        }\r
                })(),\r
-               NUM_BALLOON_IMAGE = 24,\r
-               vectorEnabled = ELM_BALLOON_ORIGIN !== null && pettanr.URL_PARAMS.vector !== false;\r
-       if( IS_VML === true && pettanr.ua.VML === false) vectorEnabled = false;\r
+               vectorEnabled = ELM_BALLOON_ORIGIN !== null &&\r
+                                               pettanr.URL_PARAMS.vector !== false &&\r
+                                               !( IS_VML === true && pettanr.ua.VML === false )\r
 \r
-       var XBROWSER_BALLOON_CLASS = function( w, h, a){\r
-               var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true) : document.createElement( 'img'), // pettanr.imageに変更\r
-                       path = balloonElm.getElementsByTagName( 'path')[ 0],\r
-                       shape = balloonElm.getElementsByTagName( 'shape')[ 0],\r
-                       cos = Math.cos, sin = Math.sin,\r
-                       abs = Math.abs, pow = Math.pow,\r
-                       round = Math.round,\r
-                       floor = Math.floor,\r
-                       TARGET = TAIL_WIDTH * TAIL_WIDTH,\r
-                       DEG_TO_RAD = Math.PI / 180,\r
+       var cos        = Math.cos,\r
+               sin        = Math.sin,\r
+               abs        = function(v){ return v >= 0 ? v : -1; },\r
+               pow        = Math.pow,\r
+               round      = Math.round,\r
+               floor      = Math.floor,\r
+               TARGET     = TAIL_WIDTH * TAIL_WIDTH,\r
+               isFinit    = Type.isFinite,\r
+               ACCURACY   = 1, // 有効少数桁      \r
+               cround     = function ( v, r ){\r
+                                               r = r || ACCURACY;\r
+                                               return round( v * pow( 10.0, r )) / pow( 10.0, r );\r
+                                       },\r
+               DEG_TO_RAD = Math.PI / 180;\r
+\r
+       var XBROWSER_BALLOON_CLASS = function( w, h, a ){\r
+               var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true ) : document.createElement( 'img' ), // pettanr.imageに変更\r
+                       path = balloonElm.getElementsByTagName( 'path' )[ 0 ],\r
+                       shape = balloonElm.getElementsByTagName( 'shape' )[ 0 ],\r
+                       instance = this,\r
                        l = ',';\r
                \r
-               draw( a, w, h);\r
-               \r
-               function draw( _a, _w, _h){\r
-                       a = _a !== undefined ? _a : a;\r
-                       w = _w !== undefined ? _w -PADDING_TOP *2 : w;\r
-                       h = _h !== undefined ? _h -PADDING_LEFT *2 : h;\r
+               function draw( _a, _w, _h ){\r
+                       a  = isFinit( _a ) === true ? _a : a;\r
+                       w  = isFinit( _w ) === true ? _w - PADDING_TOP * 2 : w;\r
+                       h  = isFinit( _h ) === true ? _h - PADDING_LEFT * 2 : h;\r
 \r
                        if( vectorEnabled === false){\r
-                               balloonElm.setAttribute( 'src', balloonUrlBuilder( a));\r
+                               balloonElm.setAttribute( 'src', pettanr.balloon.getBalloonUrl( w, h, _a ));\r
                                return;\r
                        }\r
                        \r
-                       var rx = w /2,\r
-                               ry = h /2,\r
-                               tailRad = a * DEG_TO_RAD,\r
-                               tailX = rx +( rx +TAIL_HEIGHT) * cos( tailRad),\r
-                               tailY = ry +( ry +TAIL_HEIGHT) * sin( tailRad),\r
+                       var rx      = w / 2,\r
+                               ry      = h / 2,\r
+                               tailRad = _a * DEG_TO_RAD,\r
+                               tailX   = rx + ( rx + TAIL_HEIGHT ) * sin( tailRad ),\r
+                               tailY   = ry - ( ry + TAIL_HEIGHT ) * cos( tailRad ),\r
                                startX, startY, endX, endY;\r
                /*\r
                 * tailの太さをTAIL_WIDTHに一致させるため、角度を絞りつつ計算\r
@@ -1576,28 +1870,28 @@ pettanr.balloon = ( function() {
                                tailDeg = 0, d;\r
                        \r
                        for( var i = 45; i > 0.01; i /= 2){\r
-                               d = ( tailDeg +i) /2;\r
-                               startRad = ( a +d) * DEG_TO_RAD;\r
-                               endRad = ( a -d) * DEG_TO_RAD;\r
+                               d = ( tailDeg + i ) /2;\r
+                               startRad = ( _a + d ) * DEG_TO_RAD;\r
+                               endRad   = ( _a - d ) * DEG_TO_RAD;\r
                                \r
-                               _startX = rx +cos( startRad) *rx;\r
-                               _startY = ry +sin( startRad) *ry;\r
-                               _endX = rx +cos( endRad) *rx;\r
-                               _endY = ry +sin( endRad) *ry;   //円弧上のY位置=円中心Y+sin(角度×PI÷180)×円半径\r
+                               _startX  = rx + sin( startRad ) * rx;\r
+                               _startY  = ry - cos( startRad ) * ry;\r
+                               _endX    = rx + sin( endRad ) * rx;\r
+                               _endY    = ry - cos( endRad ) * ry;     //円弧上のY位置=円中心Y+sin(角度×PI÷180)×円半径\r
                                        \r
-                               if( pow( ( _startX -_endX), 2) + pow( ( _startY -_endY), 2) < TARGET){\r
+                               if( pow( ( _startX - _endX ), 2 ) + pow( ( _startY - _endY ), 2 ) < TARGET ){\r
                                        tailDeg += i;\r
-                                       startX = _startX;\r
-                                       startY = _startY;\r
-                                       endX = _endX;\r
-                                       endY = _endY;                                           \r
+                                       startX  = _startX;\r
+                                       startY  = _startY;\r
+                                       endX    = _endX;\r
+                                       endY    = _endY;\r
                                }\r
                        }\r
 \r
                /*\r
                 * \r
                 */                     \r
-                       if( IS_VML === true){\r
+                       if( IS_VML === true ){\r
                                var _tailX = tailX *10,\r
                                        _tailY = tailY *10,\r
                                        __startX = startX *10,\r
@@ -1607,75 +1901,74 @@ pettanr.balloon = ( function() {
                                        __w = w *10,\r
                                        __h = h *10;\r
                                \r
-                               shape.style.width = w +'px';\r
-                               shape.style.height = h +'px';\r
-                               shape.coordsize = [ __w, __h].join( l);\r
+                               shape.style.width = w + 'px';\r
+                               shape.style.height = h + 'px';\r
+                               shape.coordsize = [ __w, __h ].join( l );\r
                                shape.path = [\r
                                        ' ar ', 0, l, 0, l, __w, l, __h, l,\r
-                                       round( __endX), l, round( __endY), l,\r
-                                       round( __startX), l, round( __startY),\r
-                                       ' l ', round( _tailX), l, round( _tailY),\r
+                                       round( __endX ), l, round( __endY ), l,\r
+                                       round( __startX ), l, round( __startY ),\r
+                                       ' l ', round( _tailX ), l, round( _tailY ),\r
                                        ' x e'\r
                                ].join( '');\r
 \r
-                               balloonElm.style.marginTop =  _tailY < 0 ? floor( ( 60 +_tailY) /10) : 10;\r
-                               balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 +_tailX) /10) : 10;\r
+                               balloonElm.style.marginTop =  _tailY < 0 ? floor( ( 60 + _tailY) / 10 ) : 10;\r
+                               balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 + _tailX) / 10 ) : 10;\r
                        } else {\r
-                               balloonElm.setAttribute( 'width', w +PADDING_LEFT *2);\r
-                               balloonElm.setAttribute( 'height', h +PADDING_TOP *2);\r
+                               balloonElm.setAttribute( 'width', w + PADDING_LEFT *2 );\r
+                               balloonElm.setAttribute( 'height', h + PADDING_TOP *2 );\r
                                path.setAttribute( 'd', [\r
-                                       'M', cround( tailX + PADDING_LEFT), l, cround( tailY +PADDING_TOP),\r
-                                       'L', cround( startX +PADDING_LEFT), l, cround( startY +PADDING_TOP),\r
+                                       'M', cround( tailX + PADDING_LEFT ), l, cround( tailY + PADDING_TOP ),\r
+                                       'L', cround( startX + PADDING_LEFT ), l, cround( startY + PADDING_TOP ),\r
                                        'A', rx, l, ry,\r
                                        '0 1 1',                        // flag\r
-                                       cround( endX +PADDING_LEFT), l, cround( endY +PADDING_TOP),\r
+                                       cround( endX + PADDING_LEFT ), l, cround( endY + PADDING_TOP ),\r
                                        'z'\r
                                ].join( ' '));\r
                        }\r
-                       function cround( v, r){\r
-                               r = r || ACCURACY;\r
-                               return round( v *pow( 10.0, r)) /pow( 10.0, r);\r
-                       }\r
                }\r
+\r
+               draw( a, w, h );\r
                \r
-               function balloonUrlBuilder( _a){\r
-                       var d = 360 /NUM_BALLOON_IMAGE;\r
-                       _a += 90 +d /2;\r
-                       return [ 'system_pictures\/_w', _a < 360 -d /2 ? floor( _a /d) : 0, '.gif'].join( '');\r
+               this.elm = balloonElm;\r
+               this.resize = draw;\r
+               this.angle = function( _a ){\r
+                       _a !== undefined && _a !== a &&\r
+                               vectorEnabled === false ? pettanr.balloon.getBalloonUrl( w, h, _a ) : draw( _a );\r
+                       return a;\r
                }\r
-               return {\r
-                       elm: balloonElm,\r
-                       resize: draw,\r
-                       angle: function( _a){\r
-                               _a !== undefined && _a !== a &&\r
-                                       vectorEnabled === false ? balloonUrlBuilder( _a) : draw( _a);\r
-                               return a;\r
-                       },\r
-                       type: function( _type){\r
-                               //draw( _a);\r
-                       },\r
-                       getURL: function(){\r
-                               return balloonUrlBuilder( a);\r
-                       },\r
-                       destroy: function(){\r
-                               balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm);\r
-                               balloonElm = null;\r
-                               delete this.destroy;\r
-                       }\r
+               this.type = function( _type ){\r
+                       //draw( _a);\r
+               }\r
+               this.destroy = function(){\r
+                       delete instance.destroy;\r
+                       balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm );\r
+                       balloonElm = path = shape = instance = null;\r
                }\r
        };\r
        \r
        IS_VML === false && vectorEnabled === true && ( function(){\r
-               var detect = XBROWSER_BALLOON_CLASS.apply( {}, [ 100, 100, 0]),\r
-                       size = pettanr.util.getElementSize( detect.elm);\r
+               var detect = new XBROWSER_BALLOON_CLASS( 100, 100, 0 ),\r
+                       size = pettanr.util.getElementSize( detect.elm );\r
                vectorEnabled = size.width !== 0 && size.height !== 0;\r
                detect.destroy();\r
                detect = size = null;\r
        })();\r
 \r
        return {\r
-           createBalloon: function( _w, _h, _a){\r
-               return XBROWSER_BALLOON_CLASS.apply( {}, [ _w, _h, _a]);\r
+           createBalloon: function( _w, _h, _a ){\r
+               return new XBROWSER_BALLOON_CLASS( _w, _h, _a );\r
+           },\r
+           isBalloonInstance: function( _ballon ){\r
+               \r
+           },\r
+           getBalloonUrl: function( _w, _h, _a ){\r
+                       var d = 360 / NUM_BALLOON_IMAGE;\r
+                       _a = _a + d / 2;\r
+                       return [\r
+                               pettanr.CONST.SYSTEM_PICTURE_PATH, '_w',\r
+                               _a < 360 - d / 2 ? floor( _a / d ) : 0,\r
+                               '.gif' ].join( '' );\r
            },\r
                TYPE_NONE:                              0,\r
                TYPE_SPEACH_BALLOON:    1,\r
@@ -1709,185 +2002,280 @@ pettanr.balloon = ( function() {
  *     -moz-transform:scale( -1, -1);\r
  */\r
 pettanr.image = ( function(){\r
-       var REG_PNG = /\.png?/i,\r
-               IS_CSS3 = 0,\r
-               IS_VML = 1,\r
-               IS_ACTIVEX = 2,\r
-               IS_CANVAS = 3,\r
-               IS_FLASH = 4,\r
-               IS_SILVERLIGHT = 5,\r
-               IS_SERVER = 6,\r
+       \r
+       var FetchImageControl = ( function(){\r
+               var TASK_LIST = [];\r
+\r
+               /* \r
+                * FetchClass original is\r
+                * \r
+                * LICENSE: MIT?\r
+                *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
+                *  AUTHOR: uupaa.js@gmail.com\r
+                * \r
+                */\r
+\r
+               var FetchClass = function( abspath, onLoadCallback, onErrorCallback, delay, timeout ){\r
+                       var img,\r
+                               size,\r
+                               tick = 0,\r
+                               timer = null,\r
+                               finish = false;\r
+                               /*\r
+                       if( pettanr.ua.isIE === false && pettanr.ua.ieVersion < 8 ){\r
+                               var images = document.images,\r
+                                       i=0, l= images.length;\r
+                               for( i=0; i<l; ++i ){\r
+                                       img = images[ i ];\r
+                                       if( img.src === abspath && img.complete ){\r
+                                               finish = true;\r
+                                               size = pettanr.util.getImageSize( img );\r
+                                               timer = window.setTimeout( asyncCallback, 0 );\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               images = null;\r
+                       }*/\r
+                       //if( finish === false ){\r
+                               img = document.createElement( 'img' ); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る\r
+                               img.onabort = img.onerror = onError;\r
+                               img.onload = onLoad;\r
+                               img.src = abspath;\r
+                               finish === false && timeout && detect();\r
+                       //}\r
+                       \r
+                       function onError(){\r
+                               if( finish === true ) return;\r
+                               finish = true;\r
+                               timer = window.setTimeout( asyncCallback, 10 );\r
+                       }                       \r
+                       function onLoad(){\r
+                               // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
+                               // if( timer ) return; // これがあると safari3.2 で駄目、、、\r
+                               finish = true;\r
+                               timer !== null && window.clearTimeout( timer );\r
+                               if( window.opera && !img.complete ){\r
+                                       timer = window.setTimeout( asyncCallback, 10 );\r
+                                       return;\r
+                               }\r
+                               size = pettanr.util.getImageSize( img );\r
+                               timer = window.setTimeout( asyncCallback, 10 );\r
+                       }\r
+                       function detect(){\r
+                               if( finish === true ) return;\r
+                               if( img.complete ){\r
+                                       finish = true;\r
+                                       if( img.width ) return;\r
+                                       timer = window.setTimeout( asyncCallback, 10 );\r
+                                       return;\r
+                               }\r
+                               if( ( tick += delay ) > timeout ){\r
+                                       finish = true;\r
+                                       timer = window.setTimeout( asyncCallback, 10 );\r
+                                       return;\r
+                               }\r
+                               timer = window.setTimeout( detect, delay );\r
+                       }\r
+                       \r
+                       function asyncCallback(){\r
+                               size ? onLoadCallback( abspath, size.width, size.height ) : onErrorCallback( abspath );\r
+                               destroy();\r
+                       }\r
+                       function destroy(){\r
+                               finish = true;\r
+                               img.src = img.onload = img.onabort = img.onerror = '';\r
+                               img = void 0\r
+                               size = onLoadCallback = onErrorCallback = timer = null;\r
+                       }\r
+                       this.stop = function(){\r
+                               timer !== null && window.clearTimeout( timer );\r
+                               destroy();                      \r
+                       }\r
+               }\r
+               \r
+               return {\r
+                       load: function( URLorELM, onLoad, onError, delay, opt_timeout ){\r
+                               var src, fetch;\r
+                               if( Type.isString( URLorELM ) === true ){\r
+                                       src = URLorELM;\r
+                               } else\r
+                               if( Type.isHTMLElement( URLorELM ) === true && URLorELM.tagName.toLowerCase() === 'img' ){\r
+                                       src = URLorELM.src;\r
+                               } else {\r
+                                       return;\r
+                               }\r
+                               \r
+                               fetch = new FetchClass(\r
+                                       pettanr.util.getAbsolutePath( src ),\r
+                                       onLoad, onError,\r
+                                       Type.isFinite( delay ) === true ? delay : 250,\r
+                                       Type.isFinite( opt_timeout ) === true ? opt_timeout : undefined\r
+                               );\r
+                               // TASK_LIST.push( fetch );\r
+                               \r
+                               return fetch;\r
+                       }\r
+               }\r
+       })();\r
+       \r
+       var REG_PNG           = /\.png?/i,\r
+               IS_CSS3           = 0,\r
+               IS_VML            = 1,\r
+               IS_ACTIVEX        = 2,\r
+               IS_CANVAS         = 3,\r
+               IS_FLASH          = 4,\r
+               IS_SILVERLIGHT    = 5,\r
+               IS_SERVER         = 6,\r
                IS_ACTIVEX_SERVER = 7,\r
                BACKEND = ( function(){\r
-                       if( pettanr.DEBUG === true && pettanr.URL_PARAMS.rimg){\r
+                       if( pettanr.DEBUG === true && pettanr.URL_PARAMS.rimg ){\r
                                var rimg = pettanr.URL_PARAMS.rimg.toLowerCase();\r
-                               if( rimg === 'css3') return IS_CSS3;\r
-                               if( rimg === 'activex') return IS_ACTIVEX;\r
-                               if( rimg === 'vml') return IS_VML;\r
-                       }\r
-                       if( pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 9) return IS_CSS3; // 不十分!\r
-                       if( pettanr.ua.VML === true) return IS_VML;\r
-                       if( pettanr.ua.ACTIVEX === true) return IS_ACTIVEX;\r
-                       if( pettanr.FLASH === true) return IS_FLASH;\r
-                       if( pettanr.SILVERLIGHT === true) return IS_SILVERLIGHT;\r
+                               if( rimg === 'css3' ) return IS_CSS3;\r
+                               if( rimg === 'activex' ) return IS_ACTIVEX;\r
+                               if( rimg === 'vml' ) return IS_VML;\r
+                       }\r
+                       if( pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 9 ) return IS_CSS3; // 不十分!\r
+                       if( pettanr.ua.VML === true ) return IS_VML;\r
+                       if( pettanr.ua.ACTIVEX === true ) return IS_ACTIVEX;\r
+                       if( pettanr.FLASH === true ) return IS_FLASH;\r
+                       if( pettanr.SILVERLIGHT === true ) return IS_SILVERLIGHT;\r
                        return IS_SERVER;\r
                })(),\r
                BACKEND_WHEN_PNG = ( function(){\r
-                       if( pettanr.ua.isIE === false || pettanr.ua.ieVersion > 6) return BACKEND;\r
-                       if( pettanr.ua.VML === true) return IS_VML;\r
-                       if( pettanr.FLASH === true) return IS_FLASH;\r
-                       if( pettanr.SILVERLIGHT === true) return IS_SILVERLIGHT;\r
-                       if( pettanr.ua.ACTIVEX === true) return IS_ACTIVEX_SERVER;\r
+                       if( pettanr.ua.isIE === false || pettanr.ua.ieVersion > 6 ) return BACKEND;\r
+                       if( pettanr.ua.VML === true ) return IS_VML;\r
+                       if( pettanr.FLASH === true ) return IS_FLASH;\r
+                       if( pettanr.SILVERLIGHT === true ) return IS_SILVERLIGHT;\r
+                       if( pettanr.ua.ACTIVEX === true ) return IS_ACTIVEX_SERVER;\r
                        return IS_SERVER;\r
                })(),\r
+               CLASS_NAME         = 'reversible-image-container',\r
+               CLASS_NAME_LOADING = CLASS_NAME + ' loading',\r
+               CLASS_NAME_ERROR   = CLASS_NAME +' error',\r
+               RETRY_DELAY        = 5000,\r
+               NUM_RETRY          = 3,\r
                ReversibleImageClass,\r
                ReversibleImageClassWithPingfix;\r
        \r
-       var XBackendReversibleImageClass = ( function(){\r
-               var CLASS_NAME = 'reversible-image-container',\r
-                       CLASS_NAME_LOADING = CLASS_NAME + ' loading',\r
-                       CLASS_NAME_ERROR = CLASS_NAME +' error',\r
-                       RETRY_DELAY = 5000;\r
-                       NUM_RETRY = 3;\r
-               \r
-               var css3Image = function( url, w, h, onLoadCallback){\r
-                       var elmWrap = document.createElement( 'div'),\r
-                               elmImg,\r
-                               loaded = false,\r
-                               retryTimer = null;\r
-                       elmWrap.className = CLASS_NAME_LOADING;\r
-                       pettanr.util.loadImage( url, onLoad, onError, 100, 10000);\r
-                       function onLoad( _url, _actualW, _actualH){\r
-                               if( elmWrap === null) return;\r
-                               elmImg = new Image;\r
-                               /*\r
-                                * createElement 直後に append しないと、ie(ActiveX)で img が正しく表示されない.\r
-                                */\r
-                               elmWrap.appendChild( elmImg);\r
-                               elmImg.setAttribute( 'src', url);\r
-                               elmWrap.className = CLASS_NAME;\r
-                               onLoadCallback && onLoadCallback( _url, _actualW, _actualH);\r
-                               onLoadCallback = null;\r
-                               loaded = true;\r
-                               resize( w, h);\r
-                       }\r
-                       function onError( _url){\r
-                               if( elmWrap === null) return;\r
-                               elmWrap.className = CLASS_NAME_ERROR;\r
-                               retryTimer = setTimeout( function(){\r
-                                       elmWrap.className = CLASS_NAME_LOADING;\r
-                                       pettanr.util.loadImage( url, onLoad, onError, 100, 10000);\r
-                               }, RETRY_DELAY);\r
-                       }\r
-                       function resize( _w, _h){\r
-                               w = _w !== undefined ? _w : w;\r
-                               h = _h !== undefined ? _h : h;\r
-                               if( loaded === false) return;\r
-                               elmImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : '';\r
-                       }\r
-                       return {\r
-                               elm : elmWrap,\r
-                               resize: resize,\r
-                               destroy: function(){\r
-                                       loaded === true && elmWrap.removeChild( elmImg);\r
-                                       retryTimer !== null && clearTimeout( retryTimer);\r
-                                       elmWrap = vmlImg = onLoadCallback = retryTimer = null;\r
-                                       elmWrap = elmImg = onLoadCallback = null;\r
-                                       delete this.destroy;\r
-                               }\r
-                       }\r
+       var css3Image = function( url, w, h, onLoadCallback ){\r
+               var elmWrap    = document.createElement( 'div' ),\r
+                       elmImg     = null,\r
+                       retryTimer = null,\r
+                       fetch      = FetchImageControl.load( url, onLoad, onError, 100, 10000 ),\r
+                       instance   = this;\r
+               elmWrap.className = CLASS_NAME_LOADING;\r
+\r
+               function onLoad( _url, _actualW, _actualH ){\r
+                       if( elmWrap === null ) return;\r
+                       elmImg = new Image; // new Image でないと ie6,7 でクラッシュするかも、、、?\r
+                       /*\r
+                        * createElement 直後に append しないと、ie(ActiveX)で img が正しく表示されない.\r
+                        */\r
+                       elmWrap.appendChild( elmImg );\r
+                       elmImg.setAttribute( 'src', url );\r
+                       elmWrap.className = CLASS_NAME;\r
+                       onLoadCallback && onLoadCallback( _url, _actualW, _actualH );\r
+                       onLoadCallback = fetch = null;\r
+                       instance.resize( w, h );\r
+               }\r
+               function onError( _url ){\r
+                       if( elmWrap === null ) return;\r
+                       elmWrap.className = CLASS_NAME_ERROR;\r
+                       retryTimer = window.setTimeout( retry, RETRY_DELAY );\r
+                       fetch = null;\r
                }\r
-               var activexImage = css3Image;\r
-               var vmlImage = function( url, w, h, onLoadCallback){\r
-                       var elmWrap = document.createElement( 'div'),\r
-                               vmlImg,\r
-                               loaded = false,\r
-                               retryTimer = null;\r
+               function retry(){\r
                        elmWrap.className = CLASS_NAME_LOADING;\r
-                       pettanr.util.loadImage( url, onLoad, onError, 100, 10000);\r
-                       function onLoad( _url, _actualW, _actualH){\r
-                               if( elmWrap === null) return;\r
-                               elmWrap.className = CLASS_NAME;\r
-                               vmlImg = document.createElement( 'v:image');\r
-                               vmlImg.src = url;\r
-                               loaded = true;\r
-                               resize( w, h);\r
-                               onLoadCallback && onLoadCallback( _url, _actualW, _actualH);\r
-                               onLoadCallback = null;\r
-                       }\r
-                       function onError( _url){\r
-                               if( elmWrap === null) return;\r
-                               elmWrap.className = CLASS_NAME_ERROR;\r
-                               retryTimer = setTimeout( function(){\r
-                                       elmWrap.className = CLASS_NAME_LOADING;\r
-                                       pettanr.util.loadImage( url, onLoad, onError, 100, 10000);\r
-                               }, RETRY_DELAY);\r
-                       }\r
-                       function resize( _w, _h){\r
-                               w = _w !== undefined ? _w : w;\r
-                               h = _h !== undefined ? _h : h;\r
-                               if( loaded !== true) return;\r
-                               vmlImg.style.width = w < 0 ? -w : w +'px';\r
-                               vmlImg.style.height = h < 0 ? -h : h +'px';\r
-                               //if( flipH !== _flipH || flipV !== _flipV){\r
-                                       vmlImg.parentNode === elmWrap && elmWrap.removeChild( vmlImg);\r
-                               //}\r
-                                       vmlImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : '';\r
-                                       elmWrap.appendChild( vmlImg);\r
-                       }\r
-                       return {\r
-                               elm : elmWrap,\r
-                               resize: resize,\r
-                               destroy: function(){\r
-                                       loaded === true && elmWrap.removeChild( vmlImg);\r
-                                       retryTimer !== null && clearTimeout( retryTimer);\r
-                                       elmWrap = vmlImg = onLoadCallback = retryTimer = null;\r
-                                       delete this.destroy;\r
-                               }\r
-                       }\r
+                       fetch = FetchImageControl.load( url, onLoad, onError, 100, 10000 );\r
+               }\r
+\r
+               this.elm = elmWrap;\r
+               this.resize = function( _w, _h ){\r
+                       w = _w !== undefined ? _w : w;\r
+                       h = _h !== undefined ? _h : h;\r
+                       if( elmImg === null ) return;\r
+                       elmImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : '';\r
                }\r
-               var serverImage = function( url, w, h, onLoadCallback){\r
+               this.destroy = function(){\r
+                       delete instance.destroy;\r
                        \r
+                       elmImg !== null && elmWrap.removeChild( elmImg );\r
+                       retryTimer !== null && window.clearTimeout( retryTimer );\r
+                       fetch !== null && fetch.stop();\r
+                       elmWrap = elmImg = onLoadCallback = retryTimer = fetch = instance = null;\r
                }\r
+       }\r
                \r
-               return function( url, w, h, onLoadCallback){\r
-                               var flipH = w < 0,\r
-                                       flipV = h < 0,\r
-                                       onLoadCallbackAsync = onLoadCallback,// ? function(){ setTimeout( onLoadCallback, 0);} : undefined,// 一度読み込んだ画像は即座にonLoadになるため遅延\r
-                                       xBackendImage = ( function( urlIsXDomain){\r
-                                               if( BACKEND === IS_CSS3) return css3Image.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
-                                               if( BACKEND === IS_VML) return vmlImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
-                                               if( BACKEND === IS_ACTIVEX) return activexImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
-                                               return serverImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
-                                       })();\r
-                               return {\r
-                                       elm: xBackendImage.elm,\r
-                                       w: function( _w){\r
-                                               _w !== undefined && xBackendImage.resize( _w, h);\r
-                                               return w;\r
-                                       },\r
-                                       h: function( _h){\r
-                                               _h !== undefined && xBackendImage.resize( w, _h);\r
-                                               return h;\r
-                                       },\r
-                                       resize: xBackendImage.resize,\r
-                                       destroy: function(){\r
-                                               xBackendImage.destroy && xBackendImage.destroy();\r
-                                               xBackendImage = onLoadCallback = onLoadCallbackAsync = null;\r
-                                               delete this.destroy;\r
-                                       }\r
-                               }\r
-                       }\r
-       })();\r
+       var activexImage = css3Image;\r
+       \r
+       var vmlImage = function( url, w, h, onLoadCallback ){\r
+               var elmWrap = document.createElement( 'div' ),\r
+                       vmlImg = null,\r
+                       retryTimer = null,\r
+                       fetch = FetchImageControl.load( url, onLoad, onError, 100, 10000 ),\r
+                       instance = this;\r
+               elmWrap.className = CLASS_NAME_LOADING;\r
+               function onLoad( _url, _actualW, _actualH ){\r
+                       if( elmWrap === null ) return;\r
+                       elmWrap.className = CLASS_NAME;\r
+                       vmlImg = document.createElement( 'v:image' );\r
+                       vmlImg.src = url;\r
+                       onLoadCallback && onLoadCallback( _url, _actualW, _actualH );\r
+                       onLoadCallback = fetch = null;\r
+                       instance.resize( w, h );\r
+               }\r
+               function onError( _url ){\r
+                       if( elmWrap === null ) return;\r
+                       elmWrap.className = CLASS_NAME_ERROR;\r
+                       retryTimer = window.setTimeout( retry, RETRY_DELAY );\r
+                       fetch = null;\r
+               }\r
+               function retry(){\r
+                       elmWrap.className = CLASS_NAME_LOADING;\r
+                       fetch = FetchImageControl.load( url, onLoad, onError, 100, 10000 );\r
+               }\r
+               \r
+               this.elm = elmWrap;\r
+               this.resize = function( _w, _h ){\r
+                       w = _w !== undefined ? _w : w;\r
+                       h = _h !== undefined ? _h : h;\r
+                       if( vmlImg === null ) return;\r
+                       vmlImg.style.width  = ( w < 0 ? -w : w ) + 'px';\r
+                       vmlImg.style.height = ( h < 0 ? -h : h ) + 'px';\r
+                       //if( flipH !== _flipH || flipV !== _flipV){\r
+                               vmlImg.parentNode === elmWrap && elmWrap.removeChild( vmlImg );\r
+                       //}\r
+                               vmlImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : '';\r
+                               elmWrap.appendChild( vmlImg );\r
+               }\r
+               this.destroy = function(){\r
+                       instance.destroy;\r
+                       \r
+                       vmlImg !== null && elmWrap.removeChild( vmlImg );\r
+                       retryTimer !== null && window.clearTimeout( retryTimer );\r
+                       fetch !== null && fetch.stop();\r
+                       elmWrap = vmlImg = onLoadCallback = retryTimer = fetch = instance = null;\r
+               }\r
+       }\r
+       \r
+       var serverImage = css3Image; // function( url, w, h, onLoadCallback ){}\r
+       \r
+       if( BACKEND === IS_CSS3 )    ReversibleImageClass = css3Image;\r
+       if( BACKEND === IS_VML )     ReversibleImageClass = vmlImage;\r
+       if( BACKEND === IS_ACTIVEX ) ReversibleImageClass = activexImage;\r
+       if( BACKEND === IS_SERVER )  ReversibleImageClass = activexImage;\r
+       \r
+       css3Image = vmlImage = activexImage = activexImage = null;\r
+       \r
        return {\r
                createReversibleImage: function( url, w, h, onLoadCallback){\r
-                       return XBackendReversibleImageClass.apply( {}, [ url, w, h, onLoadCallback]);\r
+                       return new ReversibleImageClass( url, w, h, onLoadCallback );\r
                }\r
        }\r
 })();\r
 \r
 /*\r
- * bind : 製本
+ * bind : 製本\r
  */\r
 pettanr.bind = ( function(){\r
        var BIND_WORKER_ARRAY = [],\r
@@ -1976,10 +2364,10 @@ pettanr.bind = ( function(){
                        \r
                        for( var i=0, l=_comicElements.length; i<l; ++i){\r
                                _comicElement = _comicElements[ i];\r
-                               if( _comicElement.resource_picture){\r
-                                       _rPic = _comicElement.resource_picture || {};\r
+                               _rPic = _comicElement.resource_picture;\r
+                               if( _rPic ){\r
                                        _rImg = pettanr.image.createReversibleImage(\r
-                                                       [ RESOURCE_PICTURE_PATH, _rPic.id, '.', _rPic.ext].join( ''),\r
+                                                       [ RESOURCE_PICTURE_PATH, _rPic.id, '.', _rPic.ext ].join( ''),\r
                                                        _comicElement.width, _comicElement.height\r
                                                );\r
                                        _elmImgWrap = document.createElement( 'div');\r
@@ -1987,15 +2375,15 @@ pettanr.bind = ( function(){
                                        _elmImgWrap.appendChild( _rImg.elm);\r
                                        _elmImgWrap.className = NAMESPACE_CLASSNAME + 'image';\r
                                        _elmImgWrap.style.cssText = [\r
-                                               'width:', Math.abs( _comicElement.width), 'px;',\r
-                                               'height:', Math.abs( _comicElement.height), 'px;',\r
-                                               'left:', _comicElement.x, 'px;',\r
-                                               'top:', _comicElement.y, 'px;',\r
-                                               'z-index:', _comicElement.z, ';'\r
+                                               'width:',  Math.abs( _comicElement.width ), 'px;',\r
+                                               'height:', Math.abs( _comicElement.height ), 'px;',\r
+                                               'left:',   _comicElement.x, 'px;',\r
+                                               'top:',    _comicElement.y, 'px;',\r
+                                               'z-index:',_comicElement.z, ';'\r
                                        ].join( '');\r
                                } else {\r
-                                       _elmBalloonWrap = document.createElement( 'div');\r
-                                       _elmPanel.appendChild( _elmBalloonWrap);\r
+                                       _elmBalloonWrap = document.createElement( 'div' );\r
+                                       _elmPanel.appendChild( _elmBalloonWrap );\r
                                        _elmBalloonWrap.className = NAMESPACE_CLASSNAME + 'balloon';\r
                                        _elmBalloonWrap.style.cssText = [\r
                                                'width:', _comicElement.width, 'px;',\r
@@ -2005,7 +2393,7 @@ pettanr.bind = ( function(){
                                                'z-index:', _comicElement.z, ';'\r
                                        ].join( '');\r
 \r
-                                       _balloon = pettanr.balloon.createBalloon( _comicElement.width, _comicElement.height, _comicElement.tail);\r
+                                       _balloon = pettanr.balloon.createBalloon( _comicElement.width, _comicElement.height, _comicElement.tail );\r
                                        _elmBalloonWrap.appendChild( _balloon.elm);\r
                                        \r
                                        _elmText = ELM_TEXT_ORIGN.cloneNode( true);\r
@@ -2115,7 +2503,7 @@ var VisualEffect = ( function(){
                 * coputedStyle と一致も削除\r
                 * updateTraget ととして記録\r
                 * 初期値を cssObject としてセット\r
-                * cssTest にセット zoom もセット 
+                * cssTest にセット zoom もセット\r
                 */\r
                \r
                //\r
@@ -2127,7 +2515,7 @@ var VisualEffect = ( function(){
 \r
                        // IE has trouble with opacity if it does not have layout\r
                        // Force it by setting the zoom level\r
-                       style.zoom = 1;
+                       style.zoom = 1;\r
                 */\r
                \r
                var _currentParameters = [],\r
@@ -2177,7 +2565,7 @@ var VisualEffect = ( function(){
                                        _target = _css.substr( 0, _separate +1);\r
                                        _value = _css.substr( _separate +1);\r
                                        /*\r
-                                        * ie filter
+                                        * ie filter\r
                                         */\r
                                        if( _target === FILTER){\r
                                                for( j=0; j<_numAttributes; ++j){\r
@@ -2190,7 +2578,7 @@ var VisualEffect = ( function(){
                                                        }\r
                                                }\r
                                        /*\r
-                                        * other
+                                        * other\r
                                         */\r
                                        } else {\r
                                                _number = '' + parseFloat( _value);\r
@@ -2209,7 +2597,7 @@ var VisualEffect = ( function(){
                        return; \r
                }\r
                /*\r
-                * 一度に update する Attributes が少ない場合、cssText は使用しない.
+                * 一度に update する Attributes が少ない場合、cssText は使用しない.\r
                 */\r
        }\r
        \r
@@ -2218,16 +2606,16 @@ var VisualEffect = ( function(){
                return {\r
                        elm:    ELM,\r
                        onEnterFrame: function(){\r
-                               var _updateCss = {};\r
+                               var _updateCss = {}, i;\r
                                if( numFrames === 1){\r
-                                       for( var i=0; i<l; ++i){\r
+                                       for( i=0; i<l; ++i){\r
                                                _updateCss[ targetAttributes[ i]] = endParameters[ i];\r
                                                ++i;\r
                                        }\r
                                        updateCss( ELM, currentParameters, targetAttributes, l);\r
                                        onComplete !== null && onComplete();\r
                                } else {\r
-                                       for( var i=0; i<l; ++i){\r
+                                       for( i=0; i<l; ++i){\r
                                                _updateCss[ targetAttributes[ i]] = currentParameters[ i] = Math.floor( currentParameters[ i] + offsetParameters[ i]);\r
                                                ++i;\r
                                        }\r