
/***** easyXDM.debug.js *****/
/**
 * easyXDM
 * http://easyxdm.net/
 * Copyright(c) 2009-2011, ÃÜyvind Sean Kinsey, oyvind@kinsey.no.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
(function(J,c,l,G,g,D){var b=this;var j=Math.floor(Math.random()*100)*100;var m=Function.prototype;var M=/^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/;var N=/[\-\w]+\/\.\.\//;var B=/([^:])\/\//g;var E="";var k={};var I=J.easyXDM;var Q="easyXDM_";var A;var u=false;function y(T,V){var U=typeof T[V];return U=="function"||(!!(U=="object"&&T[V]))||U=="unknown"}function q(T,U){return !!(typeof(T[U])=="object"&&T[U])}function n(T){return Object.prototype.toString.call(T)==="[object Array]"}var r,t;if(y(J,"addEventListener")){r=function(V,T,U){V.addEventListener(T,U,false)};t=function(V,T,U){V.removeEventListener(T,U,false)}}else{if(y(J,"attachEvent")){r=function(T,V,U){T.attachEvent("on"+V,U)};t=function(T,V,U){T.detachEvent("on"+V,U)}}else{throw new Error("Browser not supported")}}var S=false,F=[],H;if("readyState" in c){H=c.readyState;S=H=="complete"||(~navigator.userAgent.indexOf("AppleWebKit/")&&(H=="loaded"||H=="interactive"))}else{S=!!c.body}function o(){o=m;S=true;for(var T=0;T<F.length;T++){F[T]()}F.length=0}if(!S){if(y(J,"addEventListener")){r(c,"DOMContentLoaded",o)}else{r(c,"readystatechange",function(){if(c.readyState=="complete"){o()}});if(c.documentElement.doScroll&&J===top){(function e(){if(S){return}try{c.documentElement.doScroll("left")}catch(T){G(e,1);return}o()}())}}r(J,"load",o)}function C(U,T){if(S){U.call(T);return}F.push(function(){U.call(T)})}function i(){var V=parent;if(E!==""){for(var T=0,U=E.split(".");T<U.length;T++){V=V[U[T]]}}return V.easyXDM}function d(T){J.easyXDM=I;E=T;if(E){Q="easyXDM_"+E.replace(".","_")+"_"}return k}function v(T){return T.match(M)[3]}function f(V){var T=V.match(M);var W=T[2],X=T[3],U=T[4]||"";if((W=="http:"&&U==":80")||(W=="https:"&&U==":443")){U=""}return W+"//"+X+U}function x(T){T=T.replace(B,"$1/");if(!T.match(/^(http||https):\/\//)){var U=(T.substring(0,1)==="/")?"":l.pathname;if(U.substring(U.length-1)!=="/"){U=U.substring(0,U.lastIndexOf("/")+1)}T=l.protocol+"//"+l.host+U+T}while(N.test(T)){T=T.replace(N,"")}return T}function L(T,W){var Y="",V=T.indexOf("#");if(V!==-1){Y=T.substring(V);T=T.substring(0,V)}var X=[];for(var U in W){if(W.hasOwnProperty(U)){X.push(U+"="+D(W[U]))}}return T+(u?"#":(T.indexOf("?")==-1?"?":"&"))+X.join("&")+Y}var O=(function(T){T=T.substring(1).split("&");var V={},W,U=T.length;while(U--){W=T[U].split("=");V[W[0]]=g(W[1])}return V}(/xdm_e=/.test(l.search)?l.search:l.hash));function p(T){return typeof T==="undefined"}function K(){var U={};var V={a:[1,2,3]},T='{"a":[1,2,3]}';if(JSON&&typeof JSON.stringify==="function"&&JSON.stringify(V).replace((/\s/g),"")===T){return JSON}if(Object.toJSON){if(Object.toJSON(V).replace((/\s/g),"")===T){U.stringify=Object.toJSON}}if(typeof String.prototype.evalJSON==="function"){V=T.evalJSON();if(V.a&&V.a.length===3&&V.a[2]===3){U.parse=function(W){return W.evalJSON()}}}if(U.stringify&&U.parse){K=function(){return U};return U}return null}function P(T,U,V){var X;for(var W in U){if(U.hasOwnProperty(W)){if(W in T){X=U[W];if(typeof X==="object"){P(T[W],X,V)}else{if(!V){T[W]=U[W]}}}else{T[W]=U[W]}}}return T}function a(){var T=c.createElement("iframe");T.name=Q+"TEST";P(T.style,{position:"absolute",left:"-2000px",top:"0px"});c.body.appendChild(T);A=!(T.contentWindow===J.frames[T.name]);c.body.removeChild(T)}function w(T){if(p(A)){a()}var V;if(A){V=c.createElement('<iframe name="'+T.props.name+'"/>')}else{V=c.createElement("IFRAME");V.name=T.props.name}V.id=V.name=T.props.name;delete T.props.name;if(T.onLoad){r(V,"load",T.onLoad)}if(typeof T.container=="string"){T.container=c.getElementById(T.container)}if(!T.container){V.style.position="absolute";V.style.top="-2000px";T.container=c.body}var U=T.props.src;delete T.props.src;P(V,T.props);V.border=V.frameBorder=0;T.container.appendChild(V);V.src=U;T.props.src=U;return V}function R(W,V){if(typeof W=="string"){W=[W]}var U,T=W.length;while(T--){U=W[T];U=new RegExp(U.substr(0,1)=="^"?U:("^"+U.replace(/(\*)/g,".$1").replace(/\?/g,".")+"$"));if(U.test(V)){return true}}return false}function h(V){var aa=V.protocol,U;V.isHost=V.isHost||p(O.xdm_p);u=V.hash||false;if(!V.props){V.props={}}if(!V.isHost){V.channel=O.xdm_c;V.secret=O.xdm_s;V.remote=O.xdm_e;aa=O.xdm_p;if(V.acl&&!R(V.acl,V.remote)){throw new Error("Access denied for "+V.remote)}}else{V.remote=x(V.remote);V.channel=V.channel||"default"+j++;V.secret=Math.random().toString(16).substring(2);if(p(aa)){if(f(l.href)==f(V.remote)){aa="4"}else{if(y(J,"postMessage")||y(c,"postMessage")){aa="1"}else{if(y(J,"ActiveXObject")&&y(J,"execScript")){aa="3"}else{if(navigator.product==="Gecko"&&"frameElement" in J&&navigator.userAgent.indexOf("WebKit")==-1){aa="5"}else{if(V.remoteHelper){V.remoteHelper=x(V.remoteHelper);aa="2"}else{aa="0"}}}}}}}switch(aa){case"0":P(V,{interval:100,delay:2000,useResize:true,useParent:false,usePolling:false},true);if(V.isHost){if(!V.local){var Y=l.protocol+"//"+l.host,T=c.body.getElementsByTagName("img"),Z;var W=T.length;while(W--){Z=T[W];if(Z.src.substring(0,Y.length)===Y){V.local=Z.src;break}}if(!V.local){V.local=J}}var X={xdm_c:V.channel,xdm_p:0};if(V.local===J){V.usePolling=true;V.useParent=true;V.local=l.protocol+"//"+l.host+l.pathname+l.search;X.xdm_e=V.local;X.xdm_pa=1}else{X.xdm_e=x(V.local)}if(V.container){V.useResize=false;X.xdm_po=1}V.remote=L(V.remote,X)}else{P(V,{channel:O.xdm_c,remote:O.xdm_e,useParent:!p(O.xdm_pa),usePolling:!p(O.xdm_po),useResize:V.useParent?false:V.useResize})}U=[new k.stack.HashTransport(V),new k.stack.ReliableBehavior({}),new k.stack.QueueBehavior({encode:true,maxLength:4000-V.remote.length}),new k.stack.VerifyBehavior({initiate:V.isHost})];break;case"1":U=[new k.stack.PostMessageTransport(V)];break;case"2":U=[new k.stack.NameTransport(V),new k.stack.QueueBehavior(),new k.stack.VerifyBehavior({initiate:V.isHost})];break;case"3":U=[new k.stack.NixTransport(V)];break;case"4":U=[new k.stack.SameOriginTransport(V)];break;case"5":U=[new k.stack.FrameElementTransport(V)];break}U.push(new k.stack.QueueBehavior({lazy:V.lazy,remove:true}));return U}function z(W){var X,V={incoming:function(Z,Y){this.up.incoming(Z,Y)},outgoing:function(Y,Z){this.down.outgoing(Y,Z)},callback:function(Y){this.up.callback(Y)},init:function(){this.down.init()},destroy:function(){this.down.destroy()}};for(var U=0,T=W.length;U<T;U++){X=W[U];P(X,V,true);if(U!==0){X.down=W[U-1]}if(U!==T-1){X.up=W[U+1]}}return X}function s(T){T.up.down=T.down;T.down.up=T.up;T.up=T.down=null}P(k,{version:"2.4.11.104",query:O,stack:{},apply:P,getJSONObject:K,whenReady:C,noConflict:d});k.DomHelper={on:r,un:t,requiresJSON:function(T){if(!q(J,"JSON")){c.write('<script type="text/javascript" src="'+T+'"><\/script>')}}};(function(){var T={};k.Fn={set:function(U,V){T[U]=V},get:function(V,U){var W=T[V];if(U){delete T[V]}return W}}}());k.Socket=function(U){var T=z(h(U).concat([{incoming:function(X,W){U.onMessage(X,W)},callback:function(W){if(U.onReady){U.onReady(W)}}}])),V=f(U.remote);this.origin=f(U.remote);this.destroy=function(){T.destroy()};this.postMessage=function(W){T.outgoing(W,V)};T.init()};k.Rpc=function(V,U){if(U.local){for(var X in U.local){if(U.local.hasOwnProperty(X)){var W=U.local[X];if(typeof W==="function"){U.local[X]={method:W}}}}}var T=z(h(V).concat([new k.stack.RpcBehavior(this,U),{callback:function(Y){if(V.onReady){V.onReady(Y)}}}]));this.origin=f(V.remote);this.destroy=function(){T.destroy()};T.init()};k.stack.SameOriginTransport=function(U){var V,X,W,T;return(V={outgoing:function(Z,aa,Y){W(Z);if(Y){Y()}},destroy:function(){if(X){X.parentNode.removeChild(X);X=null}},onDOMReady:function(){T=f(U.remote);if(U.isHost){P(U.props,{src:L(U.remote,{xdm_e:l.protocol+"//"+l.host+l.pathname,xdm_c:U.channel,xdm_p:4}),name:Q+U.channel+"_provider"});X=w(U);k.Fn.set(U.channel,function(Y){W=Y;G(function(){V.up.callback(true)},0);return function(Z){V.up.incoming(Z,T)}})}else{W=i().Fn.get(U.channel,true)(function(Y){V.up.incoming(Y,T)});G(function(){V.up.callback(true)},0)}},init:function(){C(V.onDOMReady,V)}})};k.stack.PostMessageTransport=function(W){var Y,Z,U,V;function T(aa){if(aa.origin){return f(aa.origin)}if(aa.uri){return f(aa.uri)}if(aa.domain){return l.protocol+"//"+aa.domain}throw"Unable to retrieve the origin of the event"}function X(ab){var aa=T(ab);if(aa==V&&ab.data.substring(0,W.channel.length+1)==W.channel+" "){Y.up.incoming(ab.data.substring(W.channel.length+1),aa)}}return(Y={outgoing:function(ab,ac,aa){U.postMessage(W.channel+" "+ab,ac||V);if(aa){aa()}},destroy:function(){t(J,"message",X);if(Z){U=null;Z.parentNode.removeChild(Z);Z=null}},onDOMReady:function(){V=f(W.remote);if(W.isHost){r(J,"message",function aa(ab){if(ab.data==W.channel+"-ready"){U=("postMessage" in Z.contentWindow)?Z.contentWindow:Z.contentWindow.document;t(J,"message",aa);r(J,"message",X);G(function(){Y.up.callback(true)},0)}});P(W.props,{src:L(W.remote,{xdm_e:f(l.href),xdm_c:W.channel,xdm_p:1}),name:Q+W.channel+"_provider"});Z=w(W)}else{r(J,"message",X);U=("postMessage" in J.parent)?J.parent:J.parent.document;U.postMessage(W.channel+"-ready",V);G(function(){Y.up.callback(true)},0)}},init:function(){C(Y.onDOMReady,Y)}})};k.stack.FrameElementTransport=function(U){var V,X,W,T;return(V={outgoing:function(Z,aa,Y){W.call(this,Z);if(Y){Y()}},destroy:function(){if(X){X.parentNode.removeChild(X);X=null}},onDOMReady:function(){T=f(U.remote);if(U.isHost){P(U.props,{src:L(U.remote,{xdm_e:f(l.href),xdm_c:U.channel,xdm_p:5}),name:Q+U.channel+"_provider"});X=w(U);X.fn=function(Y){delete X.fn;W=Y;G(function(){V.up.callback(true)},0);return function(Z){V.up.incoming(Z,T)}}}else{if(c.referrer&&f(c.referrer)!=O.xdm_e){J.parent.location=O.xdm_e}W=J.frameElement.fn(function(Y){V.up.incoming(Y,T)});V.up.callback(true)}},init:function(){C(V.onDOMReady,V)}})};k.stack.NixTransport=function(U){var W,Y,X,T,V;return(W={outgoing:function(aa,ab,Z){X(aa);if(Z){Z()}},destroy:function(){V=null;if(Y){Y.parentNode.removeChild(Y);Y=null}},onDOMReady:function(){T=f(U.remote);if(U.isHost){try{if(!y(J,"getNixProxy")){J.execScript("Class NixProxy\n    Private m_parent, m_child, m_Auth\n\n    Public Sub SetParent(obj, auth)\n        If isEmpty(m_Auth) Then m_Auth = auth\n        SET m_parent = obj\n    End Sub\n    Public Sub SetChild(obj)\n        SET m_child = obj\n        m_parent.ready()\n    End Sub\n\n    Public Sub SendToParent(data, auth)\n        If m_Auth = auth Then m_parent.send(CStr(data))\n    End Sub\n    Public Sub SendToChild(data, auth)\n        If m_Auth = auth Then m_child.send(CStr(data))\n    End Sub\nEnd Class\nFunction getNixProxy()\n    Set GetNixProxy = New NixProxy\nEnd Function\n","vbscript")}V=getNixProxy();V.SetParent({send:function(ab){W.up.incoming(ab,T)},ready:function(){G(function(){W.up.callback(true)},0)}},U.secret);X=function(ab){V.SendToChild(ab,U.secret)}}catch(aa){throw new Error("Could not set up VBScript NixProxy:"+aa.message)}P(U.props,{src:L(U.remote,{xdm_e:f(l.href),xdm_c:U.channel,xdm_s:U.secret,xdm_p:3}),name:Q+U.channel+"_provider"});Y=w(U);Y.contentWindow.opener=V}else{if(c.referrer&&f(c.referrer)!=O.xdm_e){J.parent.location=O.xdm_e}try{V=J.opener}catch(Z){throw new Error("Cannot access window.opener")}V.SetChild({send:function(ab){b.setTimeout(function(){W.up.incoming(ab,T)},0)}});X=function(ab){V.SendToParent(ab,U.secret)};G(function(){W.up.callback(true)},0)}},init:function(){C(W.onDOMReady,W)}})};k.stack.NameTransport=function(X){var Y;var aa,ae,W,ac,ad,U,T;function ab(ah){var ag=X.remoteHelper+(aa?"#_3":"#_2")+X.channel;ae.contentWindow.sendMessage(ah,ag)}function Z(){if(aa){if(++ac===2||!aa){Y.up.callback(true)}}else{ab("ready");Y.up.callback(true)}}function af(ag){Y.up.incoming(ag,U)}function V(){if(ad){G(function(){ad(true)},0)}}return(Y={outgoing:function(ah,ai,ag){ad=ag;ab(ah)},destroy:function(){ae.parentNode.removeChild(ae);ae=null;if(aa){W.parentNode.removeChild(W);W=null}},onDOMReady:function(){aa=X.isHost;ac=0;U=f(X.remote);X.local=x(X.local);if(aa){k.Fn.set(X.channel,function(ah){if(aa&&ah==="ready"){k.Fn.set(X.channel,af);Z()}});T=L(X.remote,{xdm_e:X.local,xdm_c:X.channel,xdm_p:2});P(X.props,{src:T+"#"+X.channel,name:Q+X.channel+"_provider"});W=w(X)}else{X.remoteHelper=X.remote;k.Fn.set(X.channel,af)}ae=w({props:{src:X.local+"#_4"+X.channel},onLoad:function ag(){var ah=ae||this;t(ah,"load",ag);k.Fn.set(X.channel+"_load",V);(function ai(){if(typeof ah.contentWindow.sendMessage=="function"){Z()}else{G(ai,50)}}())}})},init:function(){C(Y.onDOMReady,Y)}})};k.stack.HashTransport=function(V){var Y;var ad=this,ab,W,T,Z,ai,X,ah;var ac,U;function ag(ak){if(!ah){return}var aj=V.remote+"#"+(ai++)+"_"+ak;((ab||!ac)?ah.contentWindow:ah).location=aj}function aa(aj){Z=aj;Y.up.incoming(Z.substring(Z.indexOf("_")+1),U)}function af(){if(!X){return}var aj=X.location.href,al="",ak=aj.indexOf("#");if(ak!=-1){al=aj.substring(ak)}if(al&&al!=Z){aa(al)}}function ae(){W=setInterval(af,T)}return(Y={outgoing:function(aj,ak){ag(aj)},destroy:function(){J.clearInterval(W);if(ab||!ac){ah.parentNode.removeChild(ah)}ah=null},onDOMReady:function(){ab=V.isHost;T=V.interval;Z="#"+V.channel;ai=0;ac=V.useParent;U=f(V.remote);if(ab){V.props={src:V.remote,name:Q+V.channel+"_provider"};if(ac){V.onLoad=function(){X=J;ae();Y.up.callback(true)}}else{var al=0,aj=V.delay/50;(function ak(){if(++al>aj){throw new Error("Unable to reference listenerwindow")}try{X=ah.contentWindow.frames[Q+V.channel+"_consumer"]}catch(am){}if(X){ae();Y.up.callback(true)}else{G(ak,50)}}())}ah=w(V)}else{X=J;ae();if(ac){ah=parent;Y.up.callback(true)}else{P(V,{props:{src:V.remote+"#"+V.channel+new Date(),name:Q+V.channel+"_consumer"},onLoad:function(){Y.up.callback(true)}});ah=w(V)}}},init:function(){C(Y.onDOMReady,Y)}})};k.stack.ReliableBehavior=function(U){var W,Y;var X=0,T=0,V="";return(W={incoming:function(ab,Z){var aa=ab.indexOf("_"),ac=ab.substring(0,aa).split(",");ab=ab.substring(aa+1);if(ac[0]==X){V="";if(Y){Y(true)}}if(ab.length>0){W.down.outgoing(ac[1]+","+X+"_"+V,Z);if(T!=ac[1]){T=ac[1];W.up.incoming(ab,Z)}}},outgoing:function(ab,Z,aa){V=ab;Y=aa;W.down.outgoing(T+","+(++X)+"_"+ab,Z)}})};k.stack.QueueBehavior=function(V){var Y,Z=[],ac=true,W="",ab,T=0,U=false,X=false;function aa(){if(V.remove&&Z.length===0){s(Y);return}if(ac||Z.length===0||ab){return}ac=true;var ad=Z.shift();Y.down.outgoing(ad.data,ad.origin,function(ae){ac=false;if(ad.callback){G(function(){ad.callback(ae)},0)}aa()})}return(Y={init:function(){if(p(V)){V={}}if(V.maxLength){T=V.maxLength;X=true}if(V.lazy){U=true}else{Y.down.init()}},callback:function(ae){ac=false;var ad=Y.up;aa();ad.callback(ae)},incoming:function(ag,ae){if(X){var af=ag.indexOf("_"),ad=parseInt(ag.substring(0,af),10);W+=ag.substring(af+1);if(ad===0){if(V.encode){W=g(W)}Y.up.incoming(W,ae);W=""}}else{Y.up.incoming(ag,ae)}},outgoing:function(ah,ae,ag){if(V.encode){ah=D(ah)}var ad=[],af;if(X){while(ah.length!==0){af=ah.substring(0,T);ah=ah.substring(af.length);ad.push(af)}while((af=ad.shift())){Z.push({data:ad.length+"_"+af,origin:ae,callback:ad.length===0?ag:null})}}else{Z.push({data:ah,origin:ae,callback:ag})}if(U){Y.down.init()}else{aa()}},destroy:function(){ab=true;Y.down.destroy()}})};k.stack.VerifyBehavior=function(X){var Y,W,U,V=false;function T(){W=Math.random().toString(16).substring(2);Y.down.outgoing(W)}return(Y={incoming:function(ab,Z){var aa=ab.indexOf("_");if(aa===-1){if(ab===W){Y.up.callback(true)}else{if(!U){U=ab;if(!X.initiate){T()}Y.down.outgoing(ab)}}}else{if(ab.substring(0,aa)===U){Y.up.incoming(ab.substring(aa+1),Z)}}},outgoing:function(ab,Z,aa){Y.down.outgoing(W+"_"+ab,Z,aa)},callback:function(Z){if(X.initiate){T()}}})};k.stack.RpcBehavior=function(Z,U){var W,ab=U.serializer||K();var aa=0,Y={};function T(ac){ac.jsonrpc="2.0";W.down.outgoing(ab.stringify(ac))}function X(ac,ae){var ad=Array.prototype.slice;return function(){var af=arguments.length,ah,ag={method:ae};if(af>0&&typeof arguments[af-1]==="function"){if(af>1&&typeof arguments[af-2]==="function"){ah={success:arguments[af-2],error:arguments[af-1]};ag.params=ad.call(arguments,0,af-2)}else{ah={success:arguments[af-1]};ag.params=ad.call(arguments,0,af-1)}Y[""+(++aa)]=ah;ag.id=aa}else{ag.params=ad.call(arguments,0)}if(ac.namedParams&&ag.params.length===1){ag.params=ag.params[0]}T(ag)}}function V(aj,ai,ae,ah){if(!ae){if(ai){T({id:ai,error:{code:-32601,message:"Procedure not found."}})}return}var ag,ad;if(ai){ag=function(ak){ag=m;T({id:ai,result:ak})};ad=function(ak,al){ad=m;var am={id:ai,error:{code:-32099,message:ak}};if(al){am.error.data=al}T(am)}}else{ag=ad=m}if(!n(ah)){ah=[ah]}try{var ac=ae.method.apply(ae.scope,ah.concat([ag,ad]));if(!p(ac)){ag(ac)}}catch(af){ad(af.message)}}return(W={incoming:function(ad,ac){var ae=ab.parse(ad);if(ae.method){if(U.handle){U.handle(ae,T)}else{V(ae.method,ae.id,U.local[ae.method],ae.params)}}else{var af=Y[ae.id];if(ae.error){if(af.error){af.error(ae.error)}}else{if(af.success){af.success(ae.result)}}delete Y[ae.id]}},init:function(){if(U.remote){for(var ac in U.remote){if(U.remote.hasOwnProperty(ac)){Z[ac]=X(U.remote[ac],ac)}}}W.down.init()},destroy:function(){for(var ac in U.remote){if(U.remote.hasOwnProperty(ac)&&Z.hasOwnProperty(ac)){delete Z[ac]}}W.down.destroy()}})};b.easyXDM=k})(window,document,location,window.setTimeout,decodeURIComponent,encodeURIComponent); webtool_path = "http://www.shopmorganhill.com/webtools";

/***** json2.js *****/
var JSON;
if (!JSON) {
    JSON = {};
}

(function () {
    "use strict";

    function f(n) {
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                this.getUTCFullYear()     + '-' +
                f(this.getUTCMonth() + 1) + '-' +
                f(this.getUTCDate())      + 'T' +
                f(this.getUTCHours())     + ':' +
                f(this.getUTCMinutes())   + ':' +
                f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON      =
            Number.prototype.toJSON  =
            Boolean.prototype.toJSON = function (key) {
                return this.valueOf();
            };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

        escapable.lastIndex = 0;
        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            return typeof c === 'string' ? c :
                '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"' : '"' + string + '"';
    }


    function str(key, holder) {


        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

            return String(value);

        case 'object':

            if (!value) {
                return 'null';
            }

            gap += indent;
            partial = [];

            if (Object.prototype.toString.apply(value) === '[object Array]') {


                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

                v = partial.length === 0 ? '[]' : gap ?
                    '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
                    '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    if (typeof rep[i] === 'string') {
                        k = rep[i];
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

                for (k in value) {
                    if (Object.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

            v = partial.length === 0 ? '{}' : gap ?
                '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
                '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {
			var i;
            gap = '';
            indent = '';

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

            } else if (typeof space === 'string') {
                indent = space;
            }

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                    typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

            return str('', {'': value});
        };
    }

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

            var j;

            function walk(holder, key) {

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }

            text = String(text);
            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }
			
            if (/^[\],:{}\s]*$/
                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

                j = eval('(' + text + ')');

                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }

            throw new SyntaxError('JSON.parse');
        };
    }
}());


/***** tools.js *****/
SC = new ShopCity();

if (window.addEventListener)
{
	window.addEventListener('load', sc_main, false);
}
else if (window.attachEvent)
{
	window.attachEvent('onload', sc_main);
}

function sc_main()
{
	if(SC.Widgets.length == 0)
	{
		SC.Code.parse();
	}
}



function ShopCity()
{
	this.Widgets = new Array(); // List of widgets
}

ShopCity.prototype.Code = function()
{
}

ShopCity.prototype.Code.parse = function()
{
	var tags = window.document.getElementsByTagName("a");
	
	for(var i = 0; i < tags.length; i++)
	{
		var elem = tags[i];
		
		var type = this.getWidgetType(elem);
		
		if(type != "")
		{
			var widget = {
				"element": elem,
				"type": type,
				"business": this.getWidgetBusiness(elem),
				"theme": this.getWidgetTheme(elem),
				"page": this.getWidgetPage(elem),
				"category": this.getWidgetCategory(elem),
				"flags": {"auto": null, "categories": null}
			}
			
			this.getWidgetFlags(widget.flags, elem)
			
			SC.Widgets.push(widget);
		}
		
	}
	
	this.createWidgets();
}

ShopCity.prototype.Code.getWidgetType = function(elem)
{
	return this.getClassSuffix("sc-widget-", elem);
}

ShopCity.prototype.Code.getWidgetBusiness = function(elem)
{
	return this.getClassSuffix("sc-business-", elem);
}

ShopCity.prototype.Code.getWidgetTheme = function(elem)
{
	var res = this.getClassSuffix("sc-theme-", elem);
	return (res != "default") ? (res) : ("");
}

ShopCity.prototype.Code.getWidgetPage = function(elem)
{
	var res = this.getClassSuffix("sc-page-", elem);
	return (res != "default") ? (res) : ("");
}

ShopCity.prototype.Code.getWidgetCategory = function(elem)
{
	var res = this.getClassSuffix("sc-category-", elem);
	return (res != "default") ? (res) : ("");
}

ShopCity.prototype.Code.getWidgetFlags = function(flags, elem)
{
	this.getWidgetFlagsOfType(flags, "sc-enable-", 1, elem)
	this.getWidgetFlagsOfType(flags, "sc-disable-", 0, elem);
}

ShopCity.prototype.Code.getWidgetFlagsOfType = function(flags, class_prefix, bit, elem)
{
	var suffixes = this.getClassSuffixes(class_prefix, elem);
	
	for(var i = 0; i < suffixes.length; i++)
	{
		if(suffixes[i] != "")
		{
			flags[suffixes[i]] = bit;
		}
	}
	
	return flags;
}


ShopCity.prototype.Code.getClassSuffix = function(class_prefix, elem)
{
	var classes = elem.className.split(" ");
	for(var i = 0; i < classes.length; i++)
	{
		var class_name = classes[i];
		if(class_name.search(class_prefix) == 0)
		{
			return class_name.substr(class_prefix.length);
		}
	}
	return "";
}

ShopCity.prototype.Code.getClassSuffixes = function(class_prefix, elem)
{
	var classes = elem.className.split(" ");
	var suffixes = new Array();
	for(var i = 0; i < classes.length; i++)
	{
		var class_name = classes[i];
		if(class_name.search(class_prefix) == 0)
		{
			suffixes.push(class_name.substr(class_prefix.length));
		}
	}
	return suffixes;
}

/**
 * Converts located tags into widgets
 */
ShopCity.prototype.Code.createWidgets = function()
{
	for(var i = 0; i < SC.Widgets.length; i++)
	{
		var widget = SC.Widgets[i];
		
		var div_tag = document.createElement("div");
		
		div_tag.className = "sc-widget " + widget.element.className;
		widget.element.parentNode.replaceChild(div_tag, widget.element);
		widget.element = div_tag;
		
		SC.Code.generateTheme(widget);
		
		page_params = "";
		
		if(widget.page != "")
		{
			page_params += "&page=" + widget.page;
		}
		
		if(widget.category != "")
		{
			page_params += "&catid=" + widget.category;
		}
		
		if(widget.flags.categories != null)
		{
			page_params += "&show_categories=1";
		}
		
		widget.socket = new easyXDM.Socket({
			remote: webtool_path + "/resize_intermediate.html?url=" + escape(widget.type + "/?listingid=" + widget.business + page_params),
			container: widget.element,
			onMessage: function(message, origin){
				var frame = this.container.getElementsByTagName("iframe")[0];
				frame.allowTransparency  = "true";
				frame.style.height = (parseInt(message, 10) + 10) + "px";
			},
			onReady : function()
			{
				var frame = this.container.getElementsByTagName("iframe")[0];
				frame.style.width = "100%";
			}
		});
		
		widget.socket.postMessage(escape(window.JSON.stringify([widget.theme, widget.flags])));
	}
}

/**
 * Figures out the color theme based on the document
 */
ShopCity.prototype.Code.generateTheme = function(widget)
{
	this.insertProbes(widget);
	widget.theme = {
		text: this.readProbe(widget.probes.text),
		link: this.readProbe(widget.probes.link),
		title: this.readProbe(widget.probes.title)
	};
	this.extractProbes(widget);
}

ShopCity.prototype.Code.insertProbes = function(widget)
{
	// TODO: allow for custom probe attibutes for example using an a with class or id,
	//       or a different tag for title.
	if(!widget.probes)
	{
		widget.probes = {
			text: document.createElement("p"),
			link: document.createElement("a"), // used to test link style
			title: document.createElement("h1") // used to test title style
		}
		
		widget.probes.link.href = "#";
		
		widget.element.appendChild(widget.probes.title);
		widget.element.appendChild(widget.probes.text);
		widget.probes.text.appendChild(widget.probes.link);
	}
}

ShopCity.prototype.Code.readProbe = function(probe)
{
	return {
		box:
		{
			margin: {
				width: this.getBoxStyle(probe, "margin", "")
			},
			border: {
				color: this.getBoxStyle(probe, "border", "Color", this.normalizeColor),
				width: this.getBoxStyle(probe, "border", "Width", null),
				style: this.getBoxStyle(probe, "border", "Style", null)
			},
			padding: {
				width: this.getBoxStyle(probe, "padding", "")
			}
		},
		background:
		{
			color: this.normalizeColor(this.getStyle(probe, "backgroundColor"))
		},
		font: {
			color: this.normalizeColor(this.getStyle(probe, "color")),
			family: this.getStyle(probe, "fontFamily"),
			size: this.getStyle(probe, "fontSize"),
			line_height: this.getStyle(probe, "lineHeight"),
			weight: this.getStyle(probe, "fontWeight"),
			style: this.getStyle(probe, "fontStyle"),
			decoration: this.getStyle(probe, "textDecoration")
		},
		alignment: {
			horizontal: this.getStyle(probe, "textAlign"),
			vertical: this.getStyle(probe, "verticalAlign")
		}
	};	
}

ShopCity.prototype.Code.extractProbes = function(widget)
{
	if(widget.probes)
	{
		widget.element.removeChild(widget.probes.title);
		widget.probes.text.removeChild(widget.probes.link);
		widget.element.removeChild(widget.probes.text);
		
		widget.probes = null;
	}
}

ShopCity.prototype.Code.getStyle = function(el, prop)
{
	if(el != null)
	{
		// Note: check getComputedStyle first it is the standard and works
		// better in Opera (which supporst both)
		if (window.getComputedStyle)
		{
			return window.getComputedStyle(el, null)[prop];
		}
		else if(el.currentStyle)
		{
			return el.currentStyle[prop];
		}
		else
		{
			return el.style[prop];
		}
	}
	
	return null;
}

ShopCity.prototype.Code.getBoxStyle = function(el, prop, suffix, filter)
{
	if(!filter)
	{
		filter = function(x){return x};
	}
	return {
		right: filter(this.getStyle(el, prop + "Right" + suffix)),
		top: filter(this.getStyle(el, prop + "Top" + suffix)),
		left: filter(this.getStyle(el, prop + "Left" + suffix)),
		bottom: filter(this.getStyle(el, prop + "Bottom" + suffix))
	}
}

/*
 * Normalize the color to rbga to save storage space
 * TODO: implement this method.
 */
ShopCity.prototype.Code.normalizeColor = function(color)
{
	return color;
}



