<?xml version="1.0"?>
<ZopeData>
  <record id="1" aka="AAAAAAAAAAE=">
    <pickle>
      <global name="File" module="OFS.Image"/>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>_Cacheable__manager_id</string> </key>
            <value> <string>http_cache</string> </value>
        </item>
        <item>
            <key> <string>_EtagSupport__etag</string> </key>
            <value> <string>ts26065609.93</string> </value>
        </item>
        <item>
            <key> <string>__name__</string> </key>
            <value> <string>renderjs.js</string> </value>
        </item>
        <item>
            <key> <string>content_type</string> </key>
            <value> <string>application/javascript</string> </value>
        </item>
        <item>
            <key> <string>data</string> </key>
            <value>
              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
            </value>
        </item>
        <item>
            <key> <string>precondition</string> </key>
            <value> <string></string> </value>
        </item>
        <item>
            <key> <string>size</string> </key>
            <value> <int>81123</int> </value>
        </item>
        <item>
            <key> <string>title</string> </key>
            <value> <string></string> </value>
        </item>
      </dictionary>
    </pickle>
  </record>
  <record id="2" aka="AAAAAAAAAAI=">
    <pickle>
      <global name="Pdata" module="OFS.Image"/>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>data</string> </key>
            <value> <string encoding="cdata"><![CDATA[

\n
/*\n
 * from vifib\n
 * js_channel is a very lightweight abstraction on top of\n
 * postMessage which defines message formats and semantics\n
 * to support interactions more rich than just message passing\n
 * js_channel supports:\n
 *  + query/response - traditional rpc\n
 *  + query/update/response - incremental async return of results\n
 *    to a query\n
 *  + notifications - fire and forget\n
 *  + error handling\n
 *\n
 * js_channel is based heavily on json-rpc, but is focused at the\n
 * problem of inter-iframe RPC.\n
 *\n
 * Message types:\n
 *  There are 5 types of messages that can flow over this channel,\n
 *  and you may determine what type of message an object is by\n
 *  examining its parameters:\n
 *  1. Requests\n
 *    + integer id\n
 *    + string method\n
 *    + (optional) any params\n
 *  2. Callback Invocations (or just "Callbacks")\n
 *    + integer id\n
 *    + string callback\n
 *    + (optional) params\n
 *  3. Error Responses (or just "Errors)\n
 *    + integer id\n
 *    + string error\n
 *    + (optional) string message\n
 *  4. Responses\n
 *    + integer id\n
 *    + (optional) any result\n
 *  5. Notifications\n
 *    + string method\n
 *    + (optional) any params\n
 */\n
\n
;var Channel = (function() {\n
    "use strict";\n
\n
    // current transaction id, start out at a random *odd* number between 1 and a million\n
    // There is one current transaction counter id per page, and it\'s shared between\n
    // channel instances.  That means of all messages posted from a single javascript\n
    // evaluation context, we\'ll never have two with the same id.\n
    var s_curTranId = Math.floor(Math.random()*1000001);\n
\n
    // no two bound channels in the same javascript evaluation context may have the same origin, scope, and window.\n
    // futher if two bound channels have the same window and scope, they may not have *overlapping* origins\n
    // (either one or both support \'*\').  This restriction allows a single onMessage handler to efficiently\n
    // route messages based on origin and scope.  The s_boundChans maps origins to scopes, to message\n
    // handlers.  Request and Notification messages are routed using this table.\n
    // Finally, channels are inserted into this table when built, and removed when destroyed.\n
    var s_boundChans = { };\n
\n
    // add a channel to s_boundChans, throwing if a dup exists\n
    function s_addBoundChan(win, origin, scope, handler) {\n
        function hasWin(arr) {\n
            for (var i = 0; i < arr.length; i++) if (arr[i].win === win) return true;\n
            return false;\n
        }\n
\n
        // does she exist?\n
        var exists = false;\n
\n
\n
        if (origin === \'*\') {\n
            // we must check all other origins, sadly.\n
            for (var k in s_boundChans) {\n
                if (!s_boundChans.hasOwnProperty(k)) continue;\n
                if (k === \'*\') continue;\n
                if (typeof s_boundChans[k][scope] === \'object\') {\n
                    exists = hasWin(s_boundChans[k][scope]);\n
                    if (exists) break;\n
                }\n
            }\n
        } else {\n
            // we must check only \'*\'\n
            if ((s_boundChans[\'*\'] && s_boundChans[\'*\'][scope])) {\n
                exists = hasWin(s_boundChans[\'*\'][scope]);\n
            }\n
            if (!exists && s_boundChans[origin] && s_boundChans[origin][scope])\n
            {\n
                exists = hasWin(s_boundChans[origin][scope]);\n
            }\n
        }\n
        if (exists) throw "A channel is already bound to the same window which overlaps with origin \'"+ origin +"\' and has scope \'"+scope+"\'";\n
\n
        if (typeof s_boundChans[origin] != \'object\') s_boundChans[origin] = { };\n
        if (typeof s_boundChans[origin][scope] != \'object\') s_boundChans[origin][scope] = [ ];\n
        s_boundChans[origin][scope].push({win: win, handler: handler});\n
    }\n
\n
    function s_removeBoundChan(win, origin, scope) {\n
        var arr = s_boundChans[origin][scope];\n
        for (var i = 0; i < arr.length; i++) {\n
            if (arr[i].win === win) {\n
                arr.splice(i,1);\n
            }\n
        }\n
        if (s_boundChans[origin][scope].length === 0) {\n
            delete s_boundChans[origin][scope];\n
        }\n
    }\n
\n
    function s_isArray(obj) {\n
        if (Array.isArray) return Array.isArray(obj);\n
        else {\n
            return (obj.constructor.toString().indexOf("Array") != -1);\n
        }\n
    }\n
\n
    // No two outstanding outbound messages may have the same id, period.  Given that, a single table\n
    // mapping "transaction ids" to message handlers, allows efficient routing of Callback, Error, and\n
    // Response messages.  Entries are added to this table when requests are sent, and removed when\n
    // responses are received.\n
    var s_transIds = { };\n
\n
    // class singleton onMessage handler\n
    // this function is registered once and all incoming messages route through here.  This\n
    // arrangement allows certain efficiencies, message data is only parsed once and dispatch\n
    // is more efficient, especially for large numbers of simultaneous channels.\n
    var s_onMessage = function(e) {\n
        try {\n
          var m = JSON.parse(e.data);\n
          if (typeof m !== \'object\' || m === null) throw "malformed";\n
        } catch(e) {\n
          // just ignore any posted messages that do not consist of valid JSON\n
          return;\n
        }\n
\n
        var w = e.source;\n
        var o = e.origin;\n
        var s, i, meth;\n
\n
        if (typeof m.method === \'string\') {\n
            var ar = m.method.split(\'::\');\n
            if (ar.length == 2) {\n
                s = ar[0];\n
                meth = ar[1];\n
            } else {\n
                meth = m.method;\n
            }\n
        }\n
\n
        if (typeof m.id !== \'undefined\') i = m.id;\n
\n
        // w is message source window\n
        // o is message origin\n
        // m is parsed message\n
        // s is message scope\n
        // i is message id (or undefined)\n
        // meth is unscoped method name\n
        // ^^ based on these factors we can route the message\n
\n
        // if it has a method it\'s either a notification or a request,\n
        // route using s_boundChans\n
        if (typeof meth === \'string\') {\n
            var delivered = false;\n
            if (s_boundChans[o] && s_boundChans[o][s]) {\n
                for (var j = 0; j < s_boundChans[o][s].length; j++) {\n
                    if (s_boundChans[o][s][j].win === w) {\n
                        s_boundChans[o][s][j].handler(o, meth, m);\n
                        delivered = true;\n
                        break;\n
                    }\n
                }\n
            }\n
\n
            if (!delivered && s_boundChans[\'*\'] && s_boundChans[\'*\'][s]) {\n
                for (var j = 0; j < s_boundChans[\'*\'][s].length; j++) {\n
                    if (s_boundChans[\'*\'][s][j].win === w) {\n
                        s_boundChans[\'*\'][s][j].handler(o, meth, m);\n
                        break;\n
                    }\n
                }\n
            }\n
        }\n
        // otherwise it must have an id (or be poorly formed\n
        else if (typeof i != \'undefined\') {\n
            if (s_transIds[i]) s_transIds[i](o, meth, m);\n
        }\n
    };\n
\n
    // Setup postMessage event listeners\n
    if (window.addEventListener) window.addEventListener(\'message\', s_onMessage, false);\n
    else if(window.attachEvent) window.attachEvent(\'onmessage\', s_onMessage);\n
\n
    /* a messaging channel is constructed from a window and an origin.\n
     * the channel will assert that all messages received over the\n
     * channel match the origin\n
     *\n
     * Arguments to Channel.build(cfg):\n
     *\n
     *   cfg.window - the remote window with which we\'ll communicate\n
     *   cfg.origin - the expected origin of the remote window, may be \'*\'\n
     *                which matches any origin\n
     *   cfg.scope  - the \'scope\' of messages.  a scope string that is\n
     *                prepended to message names.  local and remote endpoints\n
     *                of a single channel must agree upon scope. Scope may\n
     *                not contain double colons (\'::\').\n
     *   cfg.debugOutput - A boolean value.  If true and window.console.log is\n
     *                a function, then debug strings will be emitted to that\n
     *                function.\n
     *   cfg.debugOutput - A boolean value.  If true and window.console.log is\n
     *                a function, then debug strings will be emitted to that\n
     *                function.\n
     *   cfg.postMessageObserver - A function that will be passed two arguments,\n
     *                an origin and a message.  It will be passed these immediately\n
     *                before messages are posted.\n
     *   cfg.gotMessageObserver - A function that will be passed two arguments,\n
     *                an origin and a message.  It will be passed these arguments\n
     *                immediately after they pass scope and origin checks, but before\n
     *                they are processed.\n
     *   cfg.onReady - A function that will be invoked when a channel becomes "ready",\n
     *                this occurs once both sides of the channel have been\n
     *                instantiated and an application level handshake is exchanged.\n
     *                the onReady function will be passed a single argument which is\n
     *                the channel object that was returned from build().\n
     */\n
    return {\n
        build: function(cfg) {\n
            var debug = function(m) {\n
                if (cfg.debugOutput && window.console && window.console.log) {\n
                    // try to stringify, if it doesn\'t work we\'ll let javascript\'s built in toString do its magic\n
                    try { if (typeof m !== \'string\') m = JSON.stringify(m); } catch(e) { }\n
                    console.log("["+chanId+"] " + m);\n
                }\n
            };\n
\n
            /* browser capabilities check */\n
            if (!window.postMessage) throw("jschannel cannot run this browser, no postMessage");\n
            if (!window.JSON || !window.JSON.stringify || ! window.JSON.parse) {\n
                throw("jschannel cannot run this browser, no JSON parsing/serialization");\n
            }\n
\n
            /* basic argument validation */\n
            if (typeof cfg != \'object\') throw("Channel build invoked without a proper object argument");\n
\n
            if (!cfg.window || !cfg.window.postMessage) throw("Channel.build() called without a valid window argument");\n
\n
            /* we\'d have to do a little more work to be able to run multiple channels that intercommunicate the same\n
             * window...  Not sure if we care to support that */\n
            if (window === cfg.window) throw("target window is same as present window -- not allowed");\n
\n
            // let\'s require that the client specify an origin.  if we just assume \'*\' we\'ll be\n
            // propagating unsafe practices.  that would be lame.\n
            var validOrigin = false;\n
            if (typeof cfg.origin === \'string\') {\n
                var oMatch;\n
                if (cfg.origin === "*") validOrigin = true;\n
                // allow valid domains under http and https.  Also, trim paths off otherwise valid origins.\n
                else if (null !== (oMatch = cfg.origin.match(/^https?:\\/\\/(?:[-a-zA-Z0-9_\\.])+(?::\\d+)?/))) {\n
                    cfg.origin = oMatch[0].toLowerCase();\n
                    validOrigin = true;\n
                }\n
            }\n
\n
            if (!validOrigin) throw ("Channel.build() called with an invalid origin");\n
\n
            if (typeof cfg.scope !== \'undefined\') {\n
                if (typeof cfg.scope !== \'string\') throw \'scope, when specified, must be a string\';\n
                if (cfg.scope.split(\'::\').length > 1) throw "scope may not contain double colons: \'::\'";\n
            }\n
\n
            /* private variables */\n
            // generate a random and psuedo unique id for this channel\n
            var chanId = (function () {\n
                var text = "";\n
                var alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";\n
                for(var i=0; i < 5; i++) text += alpha.charAt(Math.floor(Math.random() * alpha.length));\n
                return text;\n
            })();\n
\n
            // registrations: mapping method names to call objects\n
            var regTbl = { };\n
            // current oustanding sent requests\n
            var outTbl = { };\n
            // current oustanding received requests\n
            var inTbl = { };\n
            // are we ready yet?  when false we will block outbound messages.\n
            var ready = false;\n
            var pendingQueue = [ ];\n
\n
            var createTransaction = function(id,origin,callbacks) {\n
                var shouldDelayReturn = false;\n
                var completed = false;\n
\n
                return {\n
                    origin: origin,\n
                    invoke: function(cbName, v) {\n
                        // verify in table\n
                        if (!inTbl[id]) throw "attempting to invoke a callback of a nonexistent transaction: " + id;\n
                        // verify that the callback name is valid\n
                        var valid = false;\n
                        for (var i = 0; i < callbacks.length; i++) if (cbName === callbacks[i]) { valid = true; break; }\n
                        if (!valid) throw "request supports no such callback \'" + cbName + "\'";\n
\n
                        // send callback invocation\n
                        postMessage({ id: id, callback: cbName, params: v});\n
                    },\n
                    error: function(error, message) {\n
                        completed = true;\n
                        // verify in table\n
                        if (!inTbl[id]) throw "error called for nonexistent message: " + id;\n
\n
                        // remove transaction from table\n
                        delete inTbl[id];\n
\n
                        // send error\n
                        postMessage({ id: id, error: error, message: message });\n
                    },\n
                    complete: function(v) {\n
                        completed = true;\n
                        // verify in table\n
                        if (!inTbl[id]) throw "complete called for nonexistent message: " + id;\n
                        // remove transaction from table\n
                        delete inTbl[id];\n
                        // send complete\n
                        postMessage({ id: id, result: v });\n
                    },\n
                    delayReturn: function(delay) {\n
                        if (typeof delay === \'boolean\') {\n
                            shouldDelayReturn = (delay === true);\n
                        }\n
                        return shouldDelayReturn;\n
                    },\n
                    completed: function() {\n
                        return completed;\n
                    }\n
                };\n
            };\n
\n
            var setTransactionTimeout = function(transId, timeout, method) {\n
              return window.setTimeout(function() {\n
                if (outTbl[transId]) {\n
                  // XXX: what if client code raises an exception here?\n
                  var msg = "timeout (" + timeout + "ms) exceeded on method \'" + method + "\'";\n
                  (1,outTbl[transId].error)("timeout_error", msg);\n
                  delete outTbl[transId];\n
                  delete s_transIds[transId];\n
                }\n
              }, timeout);\n
            };\n
\n
            var onMessage = function(origin, method, m) {\n
                // if an observer was specified at allocation time, invoke it\n
                if (typeof cfg.gotMessageObserver === \'function\') {\n
                    // pass observer a clone of the object so that our\n
                    // manipulations are not visible (i.e. method unscoping).\n
                    // This is not particularly efficient, but then we expect\n
                    // that message observers are primarily for debugging anyway.\n
                    try {\n
                        cfg.gotMessageObserver(origin, m);\n
                    } catch (e) {\n
                        debug("gotMessageObserver() raised an exception: " + e.toString());\n
                    }\n
                }\n
\n
                // now, what type of message is this?\n
                if (m.id && method) {\n
                    // a request!  do we have a registered handler for this request?\n
                    if (regTbl[method]) {\n
                        var trans = createTransaction(m.id, origin, m.callbacks ? m.callbacks : [ ]);\n
                        inTbl[m.id] = { };\n
                        try {\n
                            // callback handling.  we\'ll magically create functions inside the parameter list for each\n
                            // callback\n
                            if (m.callbacks && s_isArray(m.callbacks) && m.callbacks.length > 0) {\n
                                for (var i = 0; i < m.callbacks.length; i++) {\n
                                    var path = m.callbacks[i];\n
                                    var obj = m.params;\n
                                    var pathItems = path.split(\'/\');\n
                                    for (var j = 0; j < pathItems.length - 1; j++) {\n
                                        var cp = pathItems[j];\n
                                        if (typeof obj[cp] !== \'object\') obj[cp] = { };\n
                                        obj = obj[cp];\n
                                    }\n
                                    obj[pathItems[pathItems.length - 1]] = (function() {\n
                                        var cbName = path;\n
                                        return function(params) {\n
                                            return trans.invoke(cbName, params);\n
                                        };\n
                                    })();\n
                                }\n
                            }\n
                            var resp = regTbl[method](trans, m.params);\n
                            if (!trans.delayReturn() && !trans.completed()) trans.complete(resp);\n
                        } catch(e) {\n
                            // automagic handling of exceptions:\n
                            var error = "runtime_error";\n
                            var message = null;\n
                            // * if it\'s a string then it gets an error code of \'runtime_error\' and string is the message\n
                            if (typeof e === \'string\') {\n
                                message = e;\n
                            } else if (typeof e === \'object\') {\n
                                // either an array or an object\n
                                // * if it\'s an array of length two, then  array[0] is the code, array[1] is the error message\n
                                if (e && s_isArray(e) && e.length == 2) {\n
                                    error = e[0];\n
                                    message = e[1];\n
                                }\n
                                // * if it\'s an object then we\'ll look form error and message parameters\n
                                else if (typeof e.error === \'string\') {\n
                                    error = e.error;\n
                                    if (!e.message) message = "";\n
                                    else if (typeof e.message === \'string\') message = e.message;\n
                                    else e = e.message; // let the stringify/toString message give us a reasonable verbose error string\n
                                }\n
                            }\n
\n
                            // message is *still* null, let\'s try harder\n
                            if (message === null) {\n
                                try {\n
                                    message = JSON.stringify(e);\n
                                    /* On MSIE8, this can result in \'out of memory\', which\n
                                     * leaves message undefined. */\n
                                    if (typeof(message) == \'undefined\')\n
                                      message = e.toString();\n
                                } catch (e2) {\n
                                    message = e.toString();\n
                                }\n
                            }\n
\n
                            trans.error(error,message);\n
                        }\n
                    }\n
                } else if (m.id && m.callback) {\n
                    if (!outTbl[m.id] ||!outTbl[m.id].callbacks || !outTbl[m.id].callbacks[m.callback])\n
                    {\n
                        debug("ignoring invalid callback, id:"+m.id+ " (" + m.callback +")");\n
                    } else {\n
                        // XXX: what if client code raises an exception here?\n
                        outTbl[m.id].callbacks[m.callback](m.params);\n
                    }\n
                } else if (m.id) {\n
                    if (!outTbl[m.id]) {\n
                        debug("ignoring invalid response: " + m.id);\n
                    } else {\n
                        // XXX: what if client code raises an exception here?\n
                        if (m.error) {\n
                            (1,outTbl[m.id].error)(m.error, m.message);\n
                        } else {\n
                            if (m.result !== undefined) (1,outTbl[m.id].success)(m.result);\n
                            else (1,outTbl[m.id].success)();\n
                        }\n
                        delete outTbl[m.id];\n
                        delete s_transIds[m.id];\n
                    }\n
                } else if (method) {\n
                    // tis a notification.\n
                    if (regTbl[method]) {\n
                        // yep, there\'s a handler for that.\n
                        // transaction has only origin for notifications.\n
                        regTbl[method]({ origin: origin }, m.params);\n
                        // if the client throws, we\'ll just let it bubble out\n
                        // what can we do?  Also, here we\'ll ignore return values\n
                    }\n
                }\n
            };\n
\n
            // now register our bound channel for msg routing\n
            s_addBoundChan(cfg.window, cfg.origin, ((typeof cfg.scope === \'string\') ? cfg.scope : \'\'), onMessage);\n
\n
            // scope method names based on cfg.scope specified when the Channel was instantiated\n
            var scopeMethod = function(m) {\n
                if (typeof cfg.scope === \'string\' && cfg.scope.length) m = [cfg.scope, m].join("::");\n
                return m;\n
            };\n
\n
            // a small wrapper around postmessage whose primary function is to handle the\n
            // case that clients start sending messages before the other end is "ready"\n
            var postMessage = function(msg, force) {\n
                if (!msg) throw "postMessage called with null message";\n
\n
                // delay posting if we\'re not ready yet.\n
                var verb = (ready ? "post  " : "queue ");\n
                debug(verb + " message: " + JSON.stringify(msg));\n
                if (!force && !ready) {\n
                    pendingQueue.push(msg);\n
                } else {\n
                    if (typeof cfg.postMessageObserver === \'function\') {\n
                        try {\n
                            cfg.postMessageObserver(cfg.origin, msg);\n
                        } catch (e) {\n
                            debug("postMessageObserver() raised an exception: " + e.toString());\n
                        }\n
                    }\n
\n
                    cfg.window.postMessage(JSON.stringify(msg), cfg.origin);\n
                }\n
            };\n
\n
            var onReady = function(trans, type) {\n
                debug(\'ready msg received\');\n
                if (ready) throw "received ready message while in ready state.  help!";\n
\n
                if (type === \'ping\') {\n
                    chanId += \'-R\';\n
                } else {\n
                    chanId += \'-L\';\n
                }\n
\n
                obj.unbind(\'__ready\'); // now this handler isn\'t needed any more.\n
                ready = true;\n
                debug(\'ready msg accepted.\');\n
\n
                if (type === \'ping\') {\n
                    obj.notify({ method: \'__ready\', params: \'pong\' });\n
                }\n
\n
                // flush queue\n
                while (pendingQueue.length) {\n
                    postMessage(pendingQueue.pop());\n
                }\n
\n
                // invoke onReady observer if provided\n
                if (typeof cfg.onReady === \'function\') cfg.onReady(obj);\n
            };\n
\n
            var obj = {\n
                // tries to unbind a bound message handler.  returns false if not possible\n
                unbind: function (method) {\n
                    if (regTbl[method]) {\n
                        if (!(delete regTbl[method])) throw ("can\'t delete method: " + method);\n
                        return true;\n
                    }\n
                    return false;\n
                },\n
                bind: function (method, cb) {\n
                    if (!method || typeof method !== \'string\') throw "\'method\' argument to bind must be string";\n
                    if (!cb || typeof cb !== \'function\') throw "callback missing from bind params";\n
\n
                    if (regTbl[method]) throw "method \'"+method+"\' is already bound!";\n
                    regTbl[method] = cb;\n
                    return this;\n
                },\n
                call: function(m) {\n
                    if (!m) throw \'missing arguments to call function\';\n
                    if (!m.method || typeof m.method !== \'string\') throw "\'method\' argument to call must be string";\n
                    if (!m.success || typeof m.success !== \'function\') throw "\'success\' callback missing from call";\n
\n
                    // now it\'s time to support the \'callback\' feature of jschannel.  We\'ll traverse the argument\n
                    // object and pick out all of the functions that were passed as arguments.\n
                    var callbacks = { };\n
                    var callbackNames = [ ];\n
\n
                    var pruneFunctions = function (path, obj) {\n
                        if (typeof obj === \'object\') {\n
                            for (var k in obj) {\n
                                if (!obj.hasOwnProperty(k)) continue;\n
                                var np = path + (path.length ? \'/\' : \'\') + k;\n
                                if (typeof obj[k] === \'function\') {\n
                                    callbacks[np] = obj[k];\n
                                    callbackNames.push(np);\n
                                    delete obj[k];\n
                                } else if (typeof obj[k] === \'object\') {\n
                                    pruneFunctions(np, obj[k]);\n
                                }\n
                            }\n
                        }\n
                    };\n
                    pruneFunctions("", m.params);\n
\n
                    // build a \'request\' message and send it\n
                    var msg = { id: s_curTranId, method: scopeMethod(m.method), params: m.params };\n
                    if (callbackNames.length) msg.callbacks = callbackNames;\n
\n
                    if (m.timeout)\n
                      // XXX: This function returns a timeout ID, but we don\'t do anything with it.\n
                      // We might want to keep track of it so we can cancel it using clearTimeout()\n
                      // when the transaction completes.\n
                      setTransactionTimeout(s_curTranId, m.timeout, scopeMethod(m.method));\n
\n
                    // insert into the transaction table\n
                    outTbl[s_curTranId] = { callbacks: callbacks, error: m.error, success: m.success };\n
                    s_transIds[s_curTranId] = onMessage;\n
\n
                    // increment current id\n
                    s_curTranId++;\n
\n
                    postMessage(msg);\n
                },\n
                notify: function(m) {\n
                    if (!m) throw \'missing arguments to notify function\';\n
                    if (!m.method || typeof m.method !== \'string\') throw "\'method\' argument to notify must be string";\n
\n
                    // no need to go into any transaction table\n
                    postMessage({ method: scopeMethod(m.method), params: m.params });\n
                },\n
                destroy: function () {\n
                    s_removeBoundChan(cfg.window, cfg.origin, ((typeof cfg.scope === \'string\') ? cfg.scope : \'\'));\n
                    if (window.removeEventListener) window.removeEventListener(\'message\', onMessage, false);\n
                    else if(window.detachEvent) window.detachEvent(\'onmessage\', onMessage);\n
                    ready = false;\n
                    regTbl = { };\n
                    inTbl = { };\n
                    outTbl = { };\n
                    cfg.origin = null;\n
                    pendingQueue = [ ];\n
                    debug("channel destroyed");\n
                    chanId = "";\n
                }\n
            };\n
\n
            obj.bind(\'__ready\', onReady);\n
            setTimeout(function() {\n
                postMessage({ method: scopeMethod(\'__ready\'), params: "ping" }, true);\n
            }, 0);\n
\n
            return obj;\n
        }\n
    };\n
})();\n
;/*\n
 * DOMParser HTML extension\n
 * 2012-09-04\n
 *\n
 * By Eli Grey, http://eligrey.com\n
 * Public domain.\n
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n
 */\n
/*! @source https://gist.github.com/1129031 */\n
(function (DOMParser) {\n
  "use strict";\n
  var DOMParser_proto = DOMParser.prototype,\n
    real_parseFromString = DOMParser_proto.parseFromString;\n
\n
  // Firefox/Opera/IE throw errors on unsupported types\n
  try {\n
    // WebKit returns null on unsupported types\n
    if ((new DOMParser()).parseFromString("", "text/html")) {\n
      // text/html parsing is natively supported\n
      return;\n
    }\n
  } catch (ignore) {}\n
\n
  DOMParser_proto.parseFromString = function (markup, type) {\n
    var result, doc, doc_elt, first_elt;\n
    if (/^\\s*text\\/html\\s*(?:;|$)/i.test(type)) {\n
      doc = document.implementation.createHTMLDocument("");\n
      doc_elt = doc.documentElement;\n
\n
      doc_elt.innerHTML = markup;\n
      first_elt = doc_elt.firstElementChild;\n
\n
      if (doc_elt.childElementCount === 1\n
          && first_elt.localName.toLowerCase() === "html") {\n
        doc.replaceChild(first_elt, doc_elt);\n
      }\n
\n
      result = doc;\n
    } else {\n
      result = real_parseFromString.apply(this, arguments);\n
    }\n
    return result;\n
  };\n
}(DOMParser));\n
\n
;// IE does not support have Document.prototype.contains.\n
if (typeof document.contains !== \'function\') {\n
  Document.prototype.contains = function(node) {\n
    if (node === this || node.parentNode === this)\n
      return true;\n
    return this.documentElement.contains(node);\n
 }\n
}\n
;/*! RenderJs */\n
/*global console*/\n
/*jslint nomen: true*/\n
function loopEventListener(target, type, useCapture, callback) {\n
  "use strict";\n
  //////////////////////////\n
  // Infinite event listener (promise is never resolved)\n
  // eventListener is removed when promise is cancelled/rejected\n
  //////////////////////////\n
  var handle_event_callback,\n
    callback_promise;\n
\n
  function cancelResolver() {\n
    if ((callback_promise !== undefined) &&\n
        (typeof callback_promise.cancel === "function")) {\n
      callback_promise.cancel();\n
    }\n
  }\n
\n
  function canceller() {\n
    if (handle_event_callback !== undefined) {\n
      target.removeEventListener(type, handle_event_callback, useCapture);\n
    }\n
    cancelResolver();\n
  }\n
  function itsANonResolvableTrap(resolve, reject) {\n
\n
    handle_event_callback = function (evt) {\n
      evt.stopPropagation();\n
      evt.preventDefault();\n
      cancelResolver();\n
      callback_promise = new RSVP.Queue()\n
        .push(function () {\n
          return callback(evt);\n
        })\n
        .push(undefined, function (error) {\n
          if (!(error instanceof RSVP.CancellationError)) {\n
            canceller();\n
            reject(error);\n
          }\n
        });\n
    };\n
\n
    target.addEventListener(type, handle_event_callback, useCapture);\n
  }\n
  return new RSVP.Promise(itsANonResolvableTrap, canceller);\n
}\n
\n
/*\n
 * renderJs - Generic Gadget library renderer.\n
 * http://www.renderjs.org/documentation\n
 */\n
(function (document, window, RSVP, DOMParser, Channel, MutationObserver,\n
           Node) {\n
  "use strict";\n
\n
  var gadget_model_dict = {},\n
    javascript_registration_dict = {},\n
    stylesheet_registration_dict = {},\n
    gadget_loading_klass,\n
    loading_klass_promise,\n
    renderJS,\n
    Monitor;\n
\n
  /////////////////////////////////////////////////////////////////\n
  // Helper functions\n
  /////////////////////////////////////////////////////////////////\n
  function listenHashChange(gadget) {\n
\n
    function extractHashAndDispatch(evt) {\n
      var hash = (evt.newURL || window.location.toString()).split(\'#\')[1],\n
        subhashes,\n
        subhash,\n
        keyvalue,\n
        index,\n
        options = {};\n
      if (hash === undefined) {\n
        hash = "";\n
      } else {\n
        hash = hash.split(\'?\')[0];\n
      }\n
\n
      function optionalize(key, value, dict) {\n
        var key_list = key.split("."),\n
          kk,\n
          i;\n
        for (i = 0; i < key_list.length; i += 1) {\n
          kk = key_list[i];\n
          if (i === key_list.length - 1) {\n
            dict[kk] = value;\n
          } else {\n
            if (!dict.hasOwnProperty(kk)) {\n
              dict[kk] = {};\n
            }\n
            dict = dict[kk];\n
          }\n
        }\n
      }\n
\n
      subhashes = hash.split(\'&\');\n
      for (index in subhashes) {\n
        if (subhashes.hasOwnProperty(index)) {\n
          subhash = subhashes[index];\n
          if (subhash !== \'\') {\n
            keyvalue = subhash.split(\'=\');\n
            if (keyvalue.length === 2) {\n
\n
              optionalize(decodeURIComponent(keyvalue[0]),\n
                decodeURIComponent(keyvalue[1]),\n
                options);\n
\n
            }\n
          }\n
        }\n
      }\n
\n
      if (gadget.render !== undefined) {\n
        return gadget.render(options);\n
      }\n
    }\n
\n
    var result = loopEventListener(window, \'hashchange\', false,\n
                                   extractHashAndDispatch),\n
      event = document.createEvent("Event");\n
\n
    event.initEvent(\'hashchange\', true, true);\n
    event.newURL = window.location.toString();\n
    window.dispatchEvent(event);\n
    return result;\n
  }\n
\n
\n
  function removeHash(url) {\n
    var index = url.indexOf(\'#\');\n
    if (index > 0) {\n
      url = url.substring(0, index);\n
    }\n
    return url;\n
  }\n
\n
  function letsCrash(e) {\n
    if (e.constructor === XMLHttpRequest) {\n
      e = {\n
        readyState: e.readyState,\n
        status: e.status,\n
        statusText: e.statusText,\n
        response_headers: e.getAllResponseHeaders()\n
      };\n
    }\n
    if (e.constructor === Array ||\n
        e.constructor === String ||\n
        e.constructor === Object) {\n
      try {\n
        e = JSON.stringify(e);\n
      } catch (ignore) {\n
      }\n
    }\n
    document.getElementsByTagName(\'body\')[0].textContent = e;\n
    // XXX Do not crash the application if it fails\n
    // Where to write the error?\n
    /*global console*/\n
    console.error(e.stack);\n
    console.error(e);\n
  }\n
\n
  /////////////////////////////////////////////////////////////////\n
  // Service Monitor promise\n
  /////////////////////////////////////////////////////////////////\n
  function ResolvedMonitorError(message) {\n
    this.name = "resolved";\n
    if ((message !== undefined) && (typeof message !== "string")) {\n
      throw new TypeError(\'You must pass a string.\');\n
    }\n
    this.message = message || "Default Message";\n
  }\n
  ResolvedMonitorError.prototype = new Error();\n
  ResolvedMonitorError.prototype.constructor = ResolvedMonitorError;\n
\n
  Monitor = function () {\n
    var monitor = this,\n
      promise_list = [],\n
      promise,\n
      reject,\n
      notify,\n
      resolved;\n
\n
    if (!(this instanceof Monitor)) {\n
      return new Monitor();\n
    }\n
\n
    function canceller() {\n
      var len = promise_list.length,\n
        i;\n
      for (i = 0; i < len; i += 1) {\n
        promise_list[i].cancel();\n
      }\n
      // Clean it to speed up other canceller run\n
      promise_list = [];\n
    }\n
\n
    promise = new RSVP.Promise(function (done, fail, progress) {\n
      reject = function (rejectedReason) {\n
        if (resolved) {\n
          return;\n
        }\n
        monitor.isRejected = true;\n
        monitor.rejectedReason = rejectedReason;\n
        resolved = true;\n
        canceller();\n
        return fail(rejectedReason);\n
      };\n
      notify = progress;\n
    }, canceller);\n
\n
    monitor.cancel = function () {\n
      if (resolved) {\n
        return;\n
      }\n
      resolved = true;\n
      promise.cancel();\n
      promise.fail(function (rejectedReason) {\n
        monitor.isRejected = true;\n
        monitor.rejectedReason = rejectedReason;\n
      });\n
    };\n
    monitor.then = function () {\n
      return promise.then.apply(promise, arguments);\n
    };\n
    monitor.fail = function () {\n
      return promise.fail.apply(promise, arguments);\n
    };\n
\n
    monitor.monitor = function (promise_to_monitor) {\n
      if (resolved) {\n
        throw new ResolvedMonitorError();\n
      }\n
      var queue = new RSVP.Queue()\n
        .push(function () {\n
          return promise_to_monitor;\n
        })\n
        .push(function (fulfillmentValue) {\n
          // Promise to monitor is fullfilled, remove it from the list\n
          var len = promise_list.length,\n
            sub_promise_to_monitor,\n
            new_promise_list = [],\n
            i;\n
          for (i = 0; i < len; i += 1) {\n
            sub_promise_to_monitor = promise_list[i];\n
            if (!(sub_promise_to_monitor.isFulfilled ||\n
                sub_promise_to_monitor.isRejected)) {\n
              new_promise_list.push(sub_promise_to_monitor);\n
            }\n
          }\n
          promise_list = new_promise_list;\n
        }, function (rejectedReason) {\n
          if (rejectedReason instanceof RSVP.CancellationError) {\n
            if (!(promise_to_monitor.isFulfilled &&\n
                  promise_to_monitor.isRejected)) {\n
              // The queue could be cancelled before the first push is run\n
              promise_to_monitor.cancel();\n
            }\n
          }\n
          reject(rejectedReason);\n
          throw rejectedReason;\n
        }, function (notificationValue) {\n
          notify(notificationValue);\n
          return notificationValue;\n
        });\n
\n
      promise_list.push(queue);\n
\n
      return this;\n
    };\n
  };\n
\n
  Monitor.prototype = Object.create(RSVP.Promise.prototype);\n
  Monitor.prototype.constructor = Monitor;\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSGadget\n
  /////////////////////////////////////////////////////////////////\n
  function RenderJSGadget() {\n
    if (!(this instanceof RenderJSGadget)) {\n
      return new RenderJSGadget();\n
    }\n
  }\n
  RenderJSGadget.prototype.__title = "";\n
  RenderJSGadget.prototype.__interface_list = [];\n
  RenderJSGadget.prototype.__path = "";\n
  RenderJSGadget.prototype.__html = "";\n
  RenderJSGadget.prototype.__required_css_list = [];\n
  RenderJSGadget.prototype.__required_js_list = [];\n
\n
  function createMonitor(g) {\n
    if (g.__monitor !== undefined) {\n
      g.__monitor.cancel();\n
    }\n
    g.__monitor = new Monitor();\n
    g.__monitor.fail(function (error) {\n
      if (!(error instanceof RSVP.CancellationError)) {\n
        return g.aq_reportServiceError(error);\n
      }\n
    }).fail(function (error) {\n
      // Crash the application if the acquisition generates an error.\n
      return letsCrash(error);\n
    });\n
  }\n
\n
  function clearGadgetInternalParameters(g) {\n
    g.__sub_gadget_dict = {};\n
    createMonitor(g);\n
  }\n
\n
  function loadSubGadgetDOMDeclaration(g) {\n
    var element_list = g.__element.querySelectorAll(\'[data-gadget-scope]\'),\n
      element,\n
      promise_list = [],\n
      scope,\n
      url,\n
      sandbox,\n
      i;\n
\n
    for (i = 0; i < element_list.length; i += 1) {\n
      element = element_list[i];\n
      scope = element.getAttribute("data-gadget-scope");\n
      url = element.getAttribute("data-gadget-url");\n
      sandbox = element.getAttribute("data-gadget-sandbox");\n
      if ((scope !== null) && (url !== null)) {\n
        promise_list.push(g.declareGadget(url, {\n
          element: element,\n
          scope: scope || undefined,\n
          sandbox: sandbox || undefined\n
        }));\n
      }\n
    }\n
\n
    return RSVP.all(promise_list);\n
  }\n
\n
  RenderJSGadget.__ready_list = [clearGadgetInternalParameters,\n
                                 loadSubGadgetDOMDeclaration];\n
  RenderJSGadget.ready = function (callback) {\n
    this.__ready_list.push(callback);\n
    return this;\n
  };\n
\n
  RenderJSGadget.__service_list = [];\n
  RenderJSGadget.declareService = function (callback) {\n
    this.__service_list.push(callback);\n
    return this;\n
  };\n
\n
  function startService(gadget) {\n
    gadget.__monitor.monitor(new RSVP.Queue()\n
      .push(function () {\n
        var i,\n
          service_list = gadget.constructor.__service_list;\n
        for (i = 0; i < service_list.length; i += 1) {\n
          gadget.__monitor.monitor(service_list[i].apply(gadget));\n
        }\n
      })\n
      );\n
  }\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSGadget.declareMethod\n
  /////////////////////////////////////////////////////////////////\n
  RenderJSGadget.declareMethod = function (name, callback) {\n
    this.prototype[name] = function () {\n
      var context = this,\n
        argument_list = arguments;\n
\n
      return new RSVP.Queue()\n
        .push(function () {\n
          return callback.apply(context, argument_list);\n
        });\n
    };\n
    // Allow chain\n
    return this;\n
  };\n
\n
  RenderJSGadget\n
    .declareMethod(\'getInterfaceList\', function () {\n
      // Returns the list of gadget prototype\n
      return this.__interface_list;\n
    })\n
    .declareMethod(\'getRequiredCSSList\', function () {\n
      // Returns a list of CSS required by the gadget\n
      return this.__required_css_list;\n
    })\n
    .declareMethod(\'getRequiredJSList\', function () {\n
      // Returns a list of JS required by the gadget\n
      return this.__required_js_list;\n
    })\n
    .declareMethod(\'getPath\', function () {\n
      // Returns the path of the code of a gadget\n
      return this.__path;\n
    })\n
    .declareMethod(\'getTitle\', function () {\n
      // Returns the title of a gadget\n
      return this.__title;\n
    })\n
    .declareMethod(\'getElement\', function () {\n
      // Returns the DOM Element of a gadget\n
      if (this.__element === undefined) {\n
        throw new Error("No element defined");\n
      }\n
      return this.__element;\n
    });\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSGadget.declareAcquiredMethod\n
  /////////////////////////////////////////////////////////////////\n
  function acquire(child_gadget, method_name, argument_list) {\n
    var gadget = this,\n
      key,\n
      gadget_scope;\n
\n
    for (key in gadget.__sub_gadget_dict) {\n
      if (gadget.__sub_gadget_dict.hasOwnProperty(key)) {\n
        if (gadget.__sub_gadget_dict[key] === child_gadget) {\n
          gadget_scope = key;\n
        }\n
      }\n
    }\n
    return new RSVP.Queue()\n
      .push(function () {\n
        // Do not specify default __acquired_method_dict on prototype\n
        // to prevent modifying this default value (with\n
        // allowPublicAcquiredMethod for example)\n
        var aq_dict = gadget.__acquired_method_dict || {};\n
        if (aq_dict.hasOwnProperty(method_name)) {\n
          return aq_dict[method_name].apply(gadget,\n
                                            [argument_list, gadget_scope]);\n
        }\n
        throw new renderJS.AcquisitionError("aq_dynamic is not defined");\n
      })\n
      .push(undefined, function (error) {\n
        if (error instanceof renderJS.AcquisitionError) {\n
          return gadget.__aq_parent(method_name, argument_list);\n
        }\n
        throw error;\n
      });\n
  }\n
\n
  RenderJSGadget.declareAcquiredMethod =\n
    function (name, method_name_to_acquire) {\n
      this.prototype[name] = function () {\n
        var argument_list = Array.prototype.slice.call(arguments, 0),\n
          gadget = this;\n
        return new RSVP.Queue()\n
          .push(function () {\n
            return gadget.__aq_parent(method_name_to_acquire, argument_list);\n
          });\n
      };\n
\n
      // Allow chain\n
      return this;\n
    };\n
  RenderJSGadget.declareAcquiredMethod("aq_reportServiceError",\n
                                       "reportServiceError");\n
  RenderJSGadget.declareAcquiredMethod("aq_pleasePublishMyState",\n
                                       "pleasePublishMyState");\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSGadget.allowPublicAcquisition\n
  /////////////////////////////////////////////////////////////////\n
  RenderJSGadget.allowPublicAcquisition =\n
    function (method_name, callback) {\n
      this.prototype.__acquired_method_dict[method_name] = callback;\n
\n
      // Allow chain\n
      return this;\n
    };\n
\n
  // Set aq_parent on gadget_instance which call acquire on parent_gadget\n
  function setAqParent(gadget_instance, parent_gadget) {\n
    gadget_instance.__aq_parent = function (method_name, argument_list) {\n
      return acquire.apply(parent_gadget, [gadget_instance, method_name,\n
                                           argument_list]);\n
    };\n
  }\n
\n
  function pleasePublishMyState(param_list, child_gadget_scope) {\n
    var new_param = {},\n
      key;\n
    for (key in this.state_parameter_dict) {\n
      if (this.state_parameter_dict.hasOwnProperty(key)) {\n
        new_param[key] = this.state_parameter_dict[key];\n
      }\n
    }\n
    if (child_gadget_scope === undefined) {\n
      throw new Error("gadget scope is mandatory");\n
    }\n
    new_param[child_gadget_scope] = param_list[0];\n
    param_list = [new_param];\n
    return this.aq_pleasePublishMyState.apply(this, param_list);\n
  }\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSEmbeddedGadget\n
  /////////////////////////////////////////////////////////////////\n
  // Class inheritance\n
  function RenderJSEmbeddedGadget() {\n
    if (!(this instanceof RenderJSEmbeddedGadget)) {\n
      return new RenderJSEmbeddedGadget();\n
    }\n
    RenderJSGadget.call(this);\n
  }\n
  RenderJSEmbeddedGadget.__ready_list = RenderJSGadget.__ready_list.slice();\n
  RenderJSEmbeddedGadget.__service_list =\n
    RenderJSGadget.__service_list.slice();\n
  RenderJSEmbeddedGadget.ready =\n
    RenderJSGadget.ready;\n
  RenderJSEmbeddedGadget.declareService =\n
    RenderJSGadget.declareService;\n
  RenderJSEmbeddedGadget.prototype = new RenderJSGadget();\n
  RenderJSEmbeddedGadget.prototype.constructor = RenderJSEmbeddedGadget;\n
\n
  /////////////////////////////////////////////////////////////////\n
  // privateDeclarePublicGadget\n
  /////////////////////////////////////////////////////////////////\n
  function privateDeclarePublicGadget(url, options, parent_gadget) {\n
    var gadget_instance;\n
    if (options.element === undefined) {\n
      options.element = document.createElement("div");\n
    }\n
\n
    function loadDependency(method, url) {\n
      return function () {\n
        return method(url);\n
      };\n
    }\n
\n
    return new RSVP.Queue()\n
      .push(function () {\n
        return renderJS.declareGadgetKlass(url);\n
      })\n
      // Get the gadget class and instanciate it\n
      .push(function (Klass) {\n
        var i,\n
          template_node_list = Klass.__template_element.body.childNodes;\n
        gadget_loading_klass = Klass;\n
        gadget_instance = new Klass();\n
        gadget_instance.__element = options.element;\n
        for (i = 0; i < template_node_list.length; i += 1) {\n
          gadget_instance.__element.appendChild(\n
            template_node_list[i].cloneNode(true)\n
          );\n
        }\n
        setAqParent(gadget_instance, parent_gadget);\n
        // Load dependencies if needed\n
        return RSVP.all([\n
          gadget_instance.getRequiredJSList(),\n
          gadget_instance.getRequiredCSSList()\n
        ]);\n
      })\n
      // Load all JS/CSS\n
      .push(function (all_list) {\n
        var q = new RSVP.Queue(),\n
          i;\n
        // Load JS\n
        for (i = 0; i < all_list[0].length; i += 1) {\n
          q.push(loadDependency(renderJS.declareJS, all_list[0][i]));\n
        }\n
        // Load CSS\n
        for (i = 0; i < all_list[1].length; i += 1) {\n
          q.push(loadDependency(renderJS.declareCSS, all_list[1][i]));\n
        }\n
        return q;\n
      })\n
      .push(function () {\n
        return gadget_instance;\n
      });\n
  }\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSIframeGadget\n
  /////////////////////////////////////////////////////////////////\n
  function RenderJSIframeGadget() {\n
    if (!(this instanceof RenderJSIframeGadget)) {\n
      return new RenderJSIframeGadget();\n
    }\n
    RenderJSGadget.call(this);\n
  }\n
  RenderJSIframeGadget.__ready_list = RenderJSGadget.__ready_list.slice();\n
  RenderJSIframeGadget.ready =\n
    RenderJSGadget.ready;\n
  RenderJSIframeGadget.__service_list = RenderJSGadget.__service_list.slice();\n
  RenderJSIframeGadget.declareService =\n
    RenderJSGadget.declareService;\n
  RenderJSIframeGadget.prototype = new RenderJSGadget();\n
  RenderJSIframeGadget.prototype.constructor = RenderJSIframeGadget;\n
\n
  /////////////////////////////////////////////////////////////////\n
  // privateDeclareIframeGadget\n
  /////////////////////////////////////////////////////////////////\n
  function privateDeclareIframeGadget(url, options, parent_gadget) {\n
    var gadget_instance,\n
      iframe,\n
      iframe_loading_deferred = RSVP.defer();\n
    if (options.element === undefined) {\n
      throw new Error("DOM element is required to create Iframe Gadget " +\n
                      url);\n
    }\n
\n
    // Check if the element is attached to the DOM\n
    if (!document.contains(options.element)) {\n
      throw new Error("The parent element is not attached to the DOM for " +\n
                      url);\n
    }\n
\n
    gadget_instance = new RenderJSIframeGadget();\n
    setAqParent(gadget_instance, parent_gadget);\n
    iframe = document.createElement("iframe");\n
//    gadget_instance.element.setAttribute("seamless", "seamless");\n
    iframe.setAttribute("src", url);\n
    gadget_instance.__path = url;\n
    gadget_instance.__element = options.element;\n
    // Attach it to the DOM\n
    options.element.appendChild(iframe);\n
\n
    // XXX Manage unbind when deleting the gadget\n
\n
    // Create the communication channel with the iframe\n
    gadget_instance.__chan = Channel.build({\n
      window: iframe.contentWindow,\n
      origin: "*",\n
      scope: "renderJS"\n
    });\n
\n
    // Create new method from the declareMethod call inside the iframe\n
    gadget_instance.__chan.bind("declareMethod",\n
                                function (trans, method_name) {\n
        gadget_instance[method_name] = function () {\n
          var argument_list = arguments,\n
            wait_promise = new RSVP.Promise(function (resolve, reject) {\n
              gadget_instance.__chan.call({\n
                method: "methodCall",\n
                params: [\n
                  method_name,\n
                  Array.prototype.slice.call(argument_list, 0)],\n
                success: function (s) {\n
                  resolve(s);\n
                },\n
                error: function (e) {\n
                  reject(e);\n
                }\n
              });\n
            });\n
          return new RSVP.Queue()\n
            .push(function () {\n
              return wait_promise;\n
            });\n
        };\n
        return "OK";\n
      });\n
\n
    // Wait for the iframe to be loaded before continuing\n
    gadget_instance.__chan.bind("ready", function (trans) {\n
      iframe_loading_deferred.resolve(gadget_instance);\n
      return "OK";\n
    });\n
    gadget_instance.__chan.bind("failed", function (trans, params) {\n
      iframe_loading_deferred.reject(params);\n
      return "OK";\n
    });\n
    gadget_instance.__chan.bind("acquire", function (trans, params) {\n
      gadget_instance.__aq_parent.apply(gadget_instance, params)\n
        .then(function (g) {\n
          trans.complete(g);\n
        }).fail(function (e) {\n
          trans.error(e.toString());\n
        });\n
      trans.delayReturn(true);\n
    });\n
\n
    return RSVP.any([\n
      iframe_loading_deferred.promise,\n
      // Timeout to prevent non renderJS embeddable gadget\n
      // XXX Maybe using iframe.onload/onerror would be safer?\n
      RSVP.timeout(5000)\n
    ]);\n
  }\n
\n
  /////////////////////////////////////////////////////////////////\n
  // RenderJSGadget.declareGadget\n
  /////////////////////////////////////////////////////////////////\n
  RenderJSGadget\n
    .declareMethod(\'declareGadget\', function (url, options) {\n
      var queue,\n
        parent_gadget = this,\n
        local_loading_klass_promise,\n
        previous_loading_klass_promise = loading_klass_promise;\n
\n
      if (options === undefined) {\n
        options = {};\n
      }\n
      if (options.sandbox === undefined) {\n
        options.sandbox = "public";\n
      }\n
\n
      // transform url to absolute url if it is relative\n
      url = renderJS.getAbsoluteURL(url, this.__path);\n
      // Change the global variable to update the loading queue\n
      loading_klass_promise = new RSVP.Queue()\n
        // Wait for previous gadget loading to finish first\n
        .push(function () {\n
          return previous_loading_klass_promise;\n
        })\n
        .push(undefined, function () {\n
          // Forget previous declareGadget error\n
          return;\n
        })\n
        .push(function () {\n
          var method;\n
          if (options.sandbox === "public") {\n
            method = privateDeclarePublicGadget;\n
          } else if (options.sandbox === "iframe") {\n
            method = privateDeclareIframeGadget;\n
          } else {\n
            throw new Error("Unsupported sandbox options \'" +\n
                            options.sandbox + "\'");\n
          }\n
          return method(url, options, parent_gadget);\n
        })\n
        // Set the HTML context\n
        .push(function (gadget_instance) {\n
          // Drop the current loading klass info used by selector\n
          gadget_loading_klass = undefined;\n
          return gadget_instance;\n
        })\n
        .push(undefined, function (e) {\n
          // Drop the current loading klass info used by selector\n
          // even in case of error\n
          gadget_loading_klass = undefined;\n
          throw e;\n
        });\n
      local_loading_klass_promise = loading_klass_promise;\n
\n
      queue = new RSVP.Queue()\n
        .push(function () {\n
          return local_loading_klass_promise;\n
        })\n
        // Set the HTML context\n
        .push(function (gadget_instance) {\n
          var i;\n
          // Trigger calling of all ready callback\n
          function ready_wrapper() {\n
            return gadget_instance;\n
          }\n
          for (i = 0; i < gadget_instance.constructor.__ready_list.length;\n
               i += 1) {\n
            // Put a timeout?\n
            queue.push(gadget_instance.constructor.__ready_list[i]);\n
            // Always return the gadget instance after ready function\n
            queue.push(ready_wrapper);\n
          }\n
\n
          // Store local reference to the gadget instance\n
          if (options.scope !== undefined) {\n
            parent_gadget.__sub_gadget_dict[options.scope] = gadget_instance;\n
            gadget_instance.__element.setAttribute("data-gadget-scope",\n
                                                   options.scope);\n
          }\n
\n
          // Put some attribute to ease page layout comprehension\n
          gadget_instance.__element.setAttribute("data-gadget-url", url);\n
          gadget_instance.__element.setAttribute("data-gadget-sandbox",\n
                                                 options.sandbox);\n
          gadget_instance.__element._gadget = gadget_instance;\n
\n
          if (document.contains(gadget_instance.__element)) {\n
            // Put a timeout\n
            queue.push(startService);\n
          }\n
          // Always return the gadget instance after ready function\n
          queue.push(ready_wrapper);\n
\n
          return gadget_instance;\n
        });\n
      return queue;\n
    })\n
    .declareMethod(\'getDeclaredGadget\', function (gadget_scope) {\n
      if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {\n
        throw new Error("Gadget scope \'" + gadget_scope + "\' is not known.");\n
      }\n
      return this.__sub_gadget_dict[gadget_scope];\n
    })\n
    .declareMethod(\'dropGadget\', function (gadget_scope) {\n
      if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {\n
        throw new Error("Gadget scope \'" + gadget_scope + "\' is not known.");\n
      }\n
      // http://perfectionkills.com/understanding-delete/\n
      delete this.__sub_gadget_dict[gadget_scope];\n
    });\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS selector\n
  /////////////////////////////////////////////////////////////////\n
  renderJS = function (selector) {\n
    var result;\n
    if (selector === window) {\n
      // window is the \'this\' value when loading a javascript file\n
      // In this case, use the current loading gadget constructor\n
      result = gadget_loading_klass;\n
    }\n
    if (result === undefined) {\n
      throw new Error("Unknown selector \'" + selector + "\'");\n
    }\n
    return result;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.AcquisitionError\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.AcquisitionError = function (message) {\n
    this.name = "AcquisitionError";\n
    if ((message !== undefined) && (typeof message !== "string")) {\n
      throw new TypeError(\'You must pass a string.\');\n
    }\n
    this.message = message || "Acquisition failed";\n
  };\n
  renderJS.AcquisitionError.prototype = new Error();\n
  renderJS.AcquisitionError.prototype.constructor =\n
    renderJS.AcquisitionError;\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.getAbsoluteURL\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.getAbsoluteURL = function (url, base_url) {\n
    var doc, base, link,\n
      html = "<!doctype><html><head></head></html>",\n
      isAbsoluteOrDataURL = new RegExp(\'^(?:[a-z]+:)?//|data:\', \'i\');\n
\n
    if (url && base_url && !isAbsoluteOrDataURL.test(url)) {\n
      doc = (new DOMParser()).parseFromString(html, \'text/html\');\n
      base = doc.createElement(\'base\');\n
      link = doc.createElement(\'link\');\n
      doc.head.appendChild(base);\n
      doc.head.appendChild(link);\n
      base.href = base_url;\n
      link.href = url;\n
      return link.href;\n
    }\n
    return url;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.declareJS\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.declareJS = function (url) {\n
    // Prevent infinite recursion if loading render.js\n
    // more than once\n
    var result;\n
    if (javascript_registration_dict.hasOwnProperty(url)) {\n
      result = RSVP.resolve();\n
    } else {\n
      result = new RSVP.Promise(function (resolve, reject) {\n
        var newScript;\n
        newScript = document.createElement(\'script\');\n
        newScript.type = \'text/javascript\';\n
        newScript.src = url;\n
        newScript.onload = function () {\n
          javascript_registration_dict[url] = null;\n
          resolve();\n
        };\n
        newScript.onerror = function (e) {\n
          reject(e);\n
        };\n
        document.head.appendChild(newScript);\n
      });\n
    }\n
    return result;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.declareCSS\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.declareCSS = function (url) {\n
    // https://github.com/furf/jquery-getCSS/blob/master/jquery.getCSS.js\n
    // No way to cleanly check if a css has been loaded\n
    // So, always resolve the promise...\n
    // http://requirejs.org/docs/faq-advanced.html#css\n
    var result;\n
    if (stylesheet_registration_dict.hasOwnProperty(url)) {\n
      result = RSVP.resolve();\n
    } else {\n
      result = new RSVP.Promise(function (resolve, reject) {\n
        var link;\n
        link = document.createElement(\'link\');\n
        link.rel = \'stylesheet\';\n
        link.type = \'text/css\';\n
        link.href = url;\n
        link.onload = function () {\n
          stylesheet_registration_dict[url] = null;\n
          resolve();\n
        };\n
        link.onerror = function (e) {\n
          reject(e);\n
        };\n
        document.head.appendChild(link);\n
      });\n
    }\n
    return result;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.declareGadgetKlass\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.declareGadgetKlass = function (url) {\n
    var result,\n
      xhr;\n
\n
    function parse() {\n
      var tmp_constructor,\n
        key,\n
        parsed_html;\n
      if (!gadget_model_dict.hasOwnProperty(url)) {\n
        // Class inheritance\n
        tmp_constructor = function () {\n
          RenderJSGadget.call(this);\n
        };\n
        tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();\n
        tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();\n
        tmp_constructor.declareMethod =\n
          RenderJSGadget.declareMethod;\n
        tmp_constructor.declareAcquiredMethod =\n
          RenderJSGadget.declareAcquiredMethod;\n
        tmp_constructor.allowPublicAcquisition =\n
          RenderJSGadget.allowPublicAcquisition;\n
        tmp_constructor.ready =\n
          RenderJSGadget.ready;\n
        tmp_constructor.declareService =\n
          RenderJSGadget.declareService;\n
        tmp_constructor.prototype = new RenderJSGadget();\n
        tmp_constructor.prototype.constructor = tmp_constructor;\n
        tmp_constructor.prototype.__path = url;\n
        tmp_constructor.prototype.__acquired_method_dict = {};\n
        tmp_constructor.allowPublicAcquisition("pleasePublishMyState",\n
                                               pleasePublishMyState);\n
        // https://developer.mozilla.org/en-US/docs/HTML_in_XMLHttpRequest\n
        // https://developer.mozilla.org/en-US/docs/Web/API/DOMParser\n
        // https://developer.mozilla.org/en-US/docs/Code_snippets/HTML_to_DOM\n
        tmp_constructor.__template_element =\n
          (new DOMParser()).parseFromString(xhr.responseText, "text/html");\n
        parsed_html = renderJS.parseGadgetHTMLDocument(\n
          tmp_constructor.__template_element,\n
          url\n
        );\n
        for (key in parsed_html) {\n
          if (parsed_html.hasOwnProperty(key)) {\n
            tmp_constructor.prototype[\'__\' + key] = parsed_html[key];\n
          }\n
        }\n
\n
        gadget_model_dict[url] = tmp_constructor;\n
      }\n
\n
      return gadget_model_dict[url];\n
    }\n
\n
    function resolver(resolve, reject) {\n
      function handler() {\n
        var tmp_result;\n
        try {\n
          if (xhr.readyState === 0) {\n
            // UNSENT\n
            reject(xhr);\n
          } else if (xhr.readyState === 4) {\n
            // DONE\n
            if ((xhr.status < 200) || (xhr.status >= 300) ||\n
                (!/^text\\/html[;]?/.test(\n
                  xhr.getResponseHeader("Content-Type") || ""\n
                ))) {\n
              reject(xhr);\n
            } else {\n
              tmp_result = parse();\n
              resolve(tmp_result);\n
            }\n
          }\n
        } catch (e) {\n
          reject(e);\n
        }\n
      }\n
\n
      xhr = new XMLHttpRequest();\n
      xhr.open("GET", url);\n
      xhr.onreadystatechange = handler;\n
      xhr.setRequestHeader(\'Accept\', \'text/html\');\n
      xhr.withCredentials = true;\n
      xhr.send();\n
    }\n
\n
    function canceller() {\n
      if ((xhr !== undefined) && (xhr.readyState !== xhr.DONE)) {\n
        xhr.abort();\n
      }\n
    }\n
\n
    if (gadget_model_dict.hasOwnProperty(url)) {\n
      // Return klass object if it already exists\n
      result = RSVP.resolve(gadget_model_dict[url]);\n
    } else {\n
      // Fetch the HTML page and parse it\n
      result = new RSVP.Promise(resolver, canceller);\n
    }\n
    return result;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.clearGadgetKlassList\n
  /////////////////////////////////////////////////////////////////\n
  // For test purpose only\n
  renderJS.clearGadgetKlassList = function () {\n
    gadget_model_dict = {};\n
    javascript_registration_dict = {};\n
    stylesheet_registration_dict = {};\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // renderJS.parseGadgetHTMLDocument\n
  /////////////////////////////////////////////////////////////////\n
  renderJS.parseGadgetHTMLDocument = function (document_element, url) {\n
    var settings = {\n
        title: "",\n
        interface_list: [],\n
        required_css_list: [],\n
        required_js_list: []\n
      },\n
      i,\n
      element,\n
      isAbsoluteURL = new RegExp(\'^(?:[a-z]+:)?//\', \'i\');\n
\n
    if (!url || !isAbsoluteURL.test(url)) {\n
      throw new Error("The url should be absolute: " + url);\n
    }\n
\n
    if (document_element.nodeType === 9) {\n
      settings.title = document_element.title;\n
\n
      if (document_element.head !== null) {\n
        for (i = 0; i < document_element.head.children.length; i += 1) {\n
          element = document_element.head.children[i];\n
          if (element.href !== null) {\n
            // XXX Manage relative URL during extraction of URLs\n
            // element.href returns absolute URL in firefox but "" in chrome;\n
            if (element.rel === "stylesheet") {\n
              settings.required_css_list.push(\n
                renderJS.getAbsoluteURL(element.getAttribute("href"), url)\n
              );\n
            } else if (element.nodeName === "SCRIPT" &&\n
                       (element.type === "text/javascript" ||\n
                        !element.type)) {\n
              settings.required_js_list.push(\n
                renderJS.getAbsoluteURL(element.getAttribute("src"), url)\n
              );\n
            } else if (element.rel ===\n
                       "http://www.renderjs.org/rel/interface") {\n
              settings.interface_list.push(\n
                renderJS.getAbsoluteURL(element.getAttribute("href"), url)\n
              );\n
            }\n
          }\n
        }\n
      }\n
    } else {\n
      throw new Error("The first parameter should be an HTMLDocument");\n
    }\n
    return settings;\n
  };\n
\n
  /////////////////////////////////////////////////////////////////\n
  // global\n
  /////////////////////////////////////////////////////////////////\n
  window.rJS = window.renderJS = renderJS;\n
  window.__RenderJSGadget = RenderJSGadget;\n
  window.__RenderJSEmbeddedGadget = RenderJSEmbeddedGadget;\n
  window.__RenderJSIframeGadget = RenderJSIframeGadget;\n
\n
  ///////////////////////////////////////////////////\n
  // Bootstrap process. Register the self gadget.\n
  ///////////////////////////////////////////////////\n
\n
  function mergeSubDict(dict) {\n
    var subkey,\n
      subkey2,\n
      subresult2,\n
      value,\n
      result = {};\n
    for (subkey in dict) {\n
      if (dict.hasOwnProperty(subkey)) {\n
        value = dict[subkey];\n
        if (value instanceof Object) {\n
          subresult2 = mergeSubDict(value);\n
          for (subkey2 in subresult2) {\n
            if (subresult2.hasOwnProperty(subkey2)) {\n
              // XXX key should not have an . inside\n
              if (result.hasOwnProperty(subkey + "." + subkey2)) {\n
                throw new Error("Key " + subkey + "." +\n
                                subkey2 + " already present");\n
              }\n
              result[subkey + "." + subkey2] = subresult2[subkey2];\n
            }\n
          }\n
        } else {\n
          if (result.hasOwnProperty(subkey)) {\n
            throw new Error("Key " + subkey + " already present");\n
          }\n
          result[subkey] = value;\n
        }\n
      }\n
    }\n
    return result;\n
\n
  }\n
\n
  function bootstrap() {\n
    var url = removeHash(window.location.href),\n
      tmp_constructor,\n
      root_gadget,\n
      loading_gadget_promise = new RSVP.Queue(),\n
      declare_method_count = 0,\n
      embedded_channel,\n
      notifyReady,\n
      notifyDeclareMethod,\n
      gadget_ready = false,\n
      iframe_top_gadget,\n
      last_acquisition_gadget;\n
\n
    // Create the gadget class for the current url\n
    if (gadget_model_dict.hasOwnProperty(url)) {\n
      throw new Error("bootstrap should not be called twice");\n
    }\n
    loading_klass_promise = new RSVP.Promise(function (resolve, reject) {\n
\n
      last_acquisition_gadget = new RenderJSGadget();\n
      last_acquisition_gadget.__acquired_method_dict = {\n
        getTopURL: function () {\n
          return url;\n
        },\n
        reportServiceError: function (param_list) {\n
          letsCrash(param_list[0]);\n
        },\n
        pleaseRedirectMyHash: function (param_list) {\n
          window.location.replace(param_list[0]);\n
        },\n
        pleasePublishMyState: function (param_list) {\n
          var key,\n
            first = true,\n
            hash = "#";\n
          param_list[0] = mergeSubDict(param_list[0]);\n
          for (key in param_list[0]) {\n
            if (param_list[0].hasOwnProperty(key)) {\n
              if (!first) {\n
                hash += "&";\n
              }\n
              hash += encodeURIComponent(key) + "=" +\n
                encodeURIComponent(param_list[0][key]);\n
              first = false;\n
            }\n
          }\n
          return hash;\n
        }\n
      };\n
      // Stop acquisition on the last acquisition gadget\n
      // Do not put this on the klass, as their could be multiple instances\n
      last_acquisition_gadget.__aq_parent = function (method_name) {\n
        throw new renderJS.AcquisitionError(\n
          "No gadget provides " + method_name\n
        );\n
      };\n
\n
      //we need to determine tmp_constructor\'s value before exit bootstrap\n
      //because of function : renderJS\n
      //but since the channel checking is async,\n
      //we can\'t use code structure like:\n
      // if channel communication is ok\n
      //    tmp_constructor = RenderJSGadget\n
      // else\n
      //    tmp_constructor = RenderJSEmbeddedGadget\n
      if (window.self === window.top) {\n
        // XXX Copy/Paste from declareGadgetKlass\n
        tmp_constructor = function () {\n
          RenderJSGadget.call(this);\n
        };\n
        tmp_constructor.declareMethod = RenderJSGadget.declareMethod;\n
        tmp_constructor.declareAcquiredMethod =\n
          RenderJSGadget.declareAcquiredMethod;\n
        tmp_constructor.allowPublicAcquisition =\n
          RenderJSGadget.allowPublicAcquisition;\n
        tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();\n
        tmp_constructor.ready = RenderJSGadget.ready;\n
        tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();\n
        tmp_constructor.declareService =\n
          RenderJSGadget.declareService;\n
        tmp_constructor.prototype = new RenderJSGadget();\n
        tmp_constructor.prototype.constructor = tmp_constructor;\n
        tmp_constructor.prototype.__path = url;\n
        gadget_model_dict[url] = tmp_constructor;\n
\n
        // Create the root gadget instance and put it in the loading stack\n
        root_gadget = new gadget_model_dict[url]();\n
\n
        tmp_constructor.declareService(function () {\n
          return listenHashChange(this);\n
        });\n
\n
        setAqParent(root_gadget, last_acquisition_gadget);\n
\n
      } else {\n
        // Create the communication channel\n
        embedded_channel = Channel.build({\n
          window: window.parent,\n
          origin: "*",\n
          scope: "renderJS"\n
        });\n
        // Create the root gadget instance and put it in the loading stack\n
        tmp_constructor = RenderJSEmbeddedGadget;\n
        tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();\n
        tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();\n
        tmp_constructor.prototype.__path = url;\n
        root_gadget = new RenderJSEmbeddedGadget();\n
\n
\n
        // Notify parent about gadget instanciation\n
        notifyReady = function () {\n
          if ((declare_method_count === 0) && (gadget_ready === true)) {\n
            embedded_channel.notify({method: "ready"});\n
          }\n
        };\n
\n
        // Inform parent gadget about declareMethod calls here.\n
        notifyDeclareMethod = function (name) {\n
          declare_method_count += 1;\n
          embedded_channel.call({\n
            method: "declareMethod",\n
            params: name,\n
            success: function () {\n
              declare_method_count -= 1;\n
              notifyReady();\n
            },\n
            error: function () {\n
              declare_method_count -= 1;\n
            }\n
          });\n
        };\n
\n
        notifyDeclareMethod("getInterfaceList");\n
        notifyDeclareMethod("getRequiredCSSList");\n
        notifyDeclareMethod("getRequiredJSList");\n
        notifyDeclareMethod("getPath");\n
        notifyDeclareMethod("getTitle");\n
\n
        // Surcharge declareMethod to inform parent window\n
        tmp_constructor.declareMethod = function (name, callback) {\n
          var result = RenderJSGadget.declareMethod.apply(\n
              this,\n
              [name, callback]\n
            );\n
          notifyDeclareMethod(name);\n
          return result;\n
        };\n
\n
        tmp_constructor.declareService =\n
          RenderJSGadget.declareService;\n
        tmp_constructor.declareAcquiredMethod =\n
          RenderJSGadget.declareAcquiredMethod;\n
        tmp_constructor.allowPublicAcquisition =\n
          RenderJSGadget.allowPublicAcquisition;\n
\n
        //Default: Define __aq_parent to inform parent window\n
        tmp_constructor.prototype.__aq_parent = function (method_name,\n
          argument_list, time_out) {\n
          return new RSVP.Promise(function (resolve, reject) {\n
            embedded_channel.call({\n
              method: "acquire",\n
              params: [\n
                method_name,\n
                argument_list\n
              ],\n
              success: function (s) {\n
                resolve(s);\n
              },\n
              error: function (e) {\n
                reject(e);\n
              },\n
              timeout: time_out\n
            });\n
          });\n
        };\n
      }\n
\n
      tmp_constructor.prototype.__acquired_method_dict = {};\n
      tmp_constructor.allowPublicAcquisition("pleasePublishMyState",\n
                                             pleasePublishMyState);\n
      gadget_loading_klass = tmp_constructor;\n
\n
      function init() {\n
        // XXX HTML properties can only be set when the DOM is fully loaded\n
        var settings = renderJS.parseGadgetHTMLDocument(document, url),\n
          j,\n
          key;\n
        for (key in settings) {\n
          if (settings.hasOwnProperty(key)) {\n
            tmp_constructor.prototype[\'__\' + key] = settings[key];\n
          }\n
        }\n
        tmp_constructor.__template_element = document.createElement("div");\n
        root_gadget.__element = document.body;\n
        for (j = 0; j < root_gadget.__element.childNodes.length; j += 1) {\n
          tmp_constructor.__template_element.appendChild(\n
            root_gadget.__element.childNodes[j].cloneNode(true)\n
          );\n
        }\n
        RSVP.all([root_gadget.getRequiredJSList(),\n
                  root_gadget.getRequiredCSSList()])\n
          .then(function (all_list) {\n
            var i,\n
              js_list = all_list[0],\n
              css_list = all_list[1];\n
            for (i = 0; i < js_list.length; i += 1) {\n
              javascript_registration_dict[js_list[i]] = null;\n
            }\n
            for (i = 0; i < css_list.length; i += 1) {\n
              stylesheet_registration_dict[css_list[i]] = null;\n
            }\n
            gadget_loading_klass = undefined;\n
          }).then(function () {\n
\n
            // select the target node\n
            var target = document.querySelector(\'body\'),\n
              // create an observer instance\n
              observer = new MutationObserver(function (mutations) {\n
                var i, k, len, len2, node, added_list;\n
                mutations.forEach(function (mutation) {\n
                  if (mutation.type === \'childList\') {\n
\n
                    len = mutation.removedNodes.length;\n
                    for (i = 0; i < len; i += 1) {\n
                      node = mutation.removedNodes[i];\n
                      if (node.nodeType === Node.ELEMENT_NODE) {\n
                        if (node.hasAttribute("data-gadget-url") &&\n
                            (node._gadget !== undefined)) {\n
                          createMonitor(node._gadget);\n
                        }\n
                        added_list =\n
                          node.querySelectorAll("[data-gadget-url]");\n
                        len2 = added_list.length;\n
                        for (k = 0; k < len2; k += 1) {\n
                          node = added_list[k];\n
                          if (node._gadget !== undefined) {\n
                            createMonitor(node._gadget);\n
                          }\n
                        }\n
                      }\n
                    }\n
\n
                    len = mutation.addedNodes.length;\n
                    for (i = 0; i < len; i += 1) {\n
                      node = mutation.addedNodes[i];\n
                      if (node.nodeType === Node.ELEMENT_NODE) {\n
                        if (node.hasAttribute("data-gadget-url") &&\n
                            (node._gadget !== undefined)) {\n
                          if (document.contains(node)) {\n
                            startService(node._gadget);\n
                          }\n
                        }\n
                        added_list =\n
                          node.querySelectorAll("[data-gadget-url]");\n
                        len2 = added_list.length;\n
                        for (k = 0; k < len2; k += 1) {\n
                          node = added_list[k];\n
                          if (document.contains(node)) {\n
                            if (node._gadget !== undefined) {\n
                              startService(node._gadget);\n
                            }\n
                          }\n
                        }\n
                      }\n
                    }\n
\n
                  }\n
                });\n
              }),\n
              // configuration of the observer:\n
              config = {\n
                childList: true,\n
                subtree: true,\n
                attributes: false,\n
                characterData: false\n
              };\n
\n
            // pass in the target node, as well as the observer options\n
            observer.observe(target, config);\n
\n
            return root_gadget;\n
          }).then(resolve, function (e) {\n
            reject(e);\n
            console.error(e);\n
            throw e;\n
          });\n
      }\n
      document.addEventListener(\'DOMContentLoaded\', init, false);\n
    });\n
\n
    loading_gadget_promise\n
      .push(function () {\n
        return loading_klass_promise;\n
      })\n
      .push(function (root_gadget) {\n
        var i;\n
\n
        function ready_wrapper() {\n
          return root_gadget;\n
        }\n
\n
        if (window.top !== window.self) {\n
          //checking channel should be done before sub gadget\'s declaration\n
          //__ready_list:\n
          //0: clearGadgetInternalParameters\n
          //1: loadSubGadgetDOMDeclaration\n
          //.....\n
          tmp_constructor.__ready_list.splice(1, 0, function () {\n
            return root_gadget.__aq_parent(\'getTopURL\', [], 100)\n
              .then(function (topURL) {\n
                var base = document.createElement(\'base\');\n
                base.href = topURL;\n
                base.target = "_top";\n
                document.head.appendChild(base);\n
                //the channel is ok\n
                //so bind calls to renderJS method on the instance\n
                embedded_channel.bind("methodCall", function (trans, v) {\n
                  root_gadget[v[0]].apply(root_gadget, v[1])\n
                    .then(function (g) {\n
                      trans.complete(g);\n
                    }).fail(function (e) {\n
                      trans.error(e.toString());\n
                    });\n
                  trans.delayReturn(true);\n
                });\n
              })\n
              .fail(function (error) {\n
                if (error === "timeout_error") {\n
                  //the channel fail\n
                  //we consider current gadget is parent gadget\n
                  //redifine last acquisition gadget\n
                  iframe_top_gadget = true;\n
                  tmp_constructor.declareService(function () {\n
                    return listenHashChange(this);\n
                  });\n
                  setAqParent(root_gadget, last_acquisition_gadget);\n
                } else {\n
                  throw error;\n
                }\n
              });\n
          });\n
        }\n
\n
        tmp_constructor.ready(function (g) {\n
          return startService(g);\n
        });\n
\n
        loading_gadget_promise.push(ready_wrapper);\n
        for (i = 0; i < tmp_constructor.__ready_list.length; i += 1) {\n
          // Put a timeout?\n
          loading_gadget_promise\n
            .push(tmp_constructor.__ready_list[i])\n
            // Always return the gadget instance after ready function\n
            .push(ready_wrapper);\n
        }\n
      });\n
    if (window.self === window.top) {\n
      loading_gadget_promise\n
        .fail(function (e) {\n
          letsCrash(e);\n
          throw e;\n
        });\n
    } else {\n
      // Inform parent window that gadget is correctly loaded\n
      loading_gadget_promise\n
        .then(function () {\n
          gadget_ready = true;\n
          notifyReady();\n
        })\n
        .fail(function (e) {\n
          //top gadget in iframe\n
          if (iframe_top_gadget) {\n
            letsCrash(e);\n
          } else {\n
            embedded_channel.notify({method: "failed", params: e.toString()});\n
          }\n
          throw e;\n
        });\n
    }\n
\n
  }\n
  bootstrap();\n
\n
}(document, window, RSVP, DOMParser, Channel, MutationObserver, Node));\n


]]></string> </value>
        </item>
      </dictionary>
    </pickle>
  </record>
</ZopeData>
