<commit_before>FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// Inspector Module

Firebug.Inspector =
{
    create: function()
    {
        offlineFragment = Firebug.browser.document.createDocumentFragment();

        createBoxModelInspector();
        createOutlineInspector();
    },

    destroy: function()
    {
        destroyBoxModelInspector();
        destroyOutlineInspector();

        offlineFragment = null;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Inspect functions

    startInspecting: function()
    {
        Firebug.chrome.selectPanel("HTML");

        createInspectorFrame();

        var size = Firebug.browser.getWindowScrollSize();

        fbInspectFrame.style.width = size.width + "px";
        fbInspectFrame.style.height = size.height + "px";
        /**/

        //addEvent(Firebug.browser.document.documentElement, "mousemove", Firebug.Inspector.onInspectingBody);

        addEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting)
        addEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick)
    },

    stopInspecting: function()
    {
        destroyInspectorFrame();

        Firebug.chrome.inspectButton.restore();

        if (outlineVisible) this.hideOutline();
        removeEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting)
        removeEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick)
    },

    onInspectingClick: function(e)
    {
        fbInspectFrame.style.display = "none";
        var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
        fbInspectFrame.style.display = "block";

        // Avoid inspecting the outline, and the FirebugChrome
        var id = targ.id;
        if (id && /^fbOutline\w$/.test(id)) return;
        if (id == "FirebugChrome") return;

        // Avoid looking at text nodes in Opera
        while (targ.nodeType != 1) targ = targ.parentNode;

        //Firebug.Console.log(targ);
        Firebug.Inspector.stopInspecting();
    },

    onInspecting: function(e)
    {
        if (new Date().getTime() - lastInspecting > 30)
        {
            fbInspectFrame.style.display = "none";
            var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
            fbInspectFrame.style.display = "block";

            // Avoid inspecting the outline, and the FirebugChrome
            var id = targ.id;
            if (id && /^fbOutline\w$/.test(id)) return;
            if (id == "FirebugChrome") return;

            // Avoid looking at text nodes in Opera
            while (targ.nodeType != 1) targ = targ.parentNode;

            if (targ.nodeName.toLowerCase() == "body") return;

            //Firebug.Console.log(e.clientX, e.clientY, targ);
            Firebug.Inspector.drawOutline(targ);

            if (targ[cacheID])
                FBL.Firebug.HTML.selectTreeNode(""+targ[cacheID])

            lastInspecting = new Date().getTime();
        }
    },

    onInspectingBody: function(e)
    {
        if (new Date().getTime() - lastInspecting > 30)
        {
            var targ = e.target;

            // Avoid inspecting the outline, and the FirebugChrome
            var id = targ.id;
            if (id && /^fbOutline\w$/.test(id)) return;
            if (id == "FirebugChrome") return;

            // Avoid looking at text nodes in Opera
            while (targ.nodeType != 1) targ = targ.parentNode;

            if (targ.nodeName.toLowerCase() == "body") return;

            //Firebug.Console.log(e.clientX, e.clientY, targ);
            Firebug.Inspector.drawOutline(targ);

            if (targ[cacheID])
                FBL.Firebug.HTML.selectTreeNode(""+targ[cacheID])

            lastInspecting = new Date().getTime();
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Inspector Outline

    drawOutline: function(el)
    {
        var box = Firebug.browser.getElementBox(el);

        var top = box.top;
        var left = box.left;
        var height = box.height;
        var width = box.width;

        var border = 2;
        var o = outlineElements;

        o.fbOutlineT.style.top = top-border + "px";
        o.fbOutlineT.style.left = left + "px";
        o.fbOutlineT.style.width = width + "px";

        o.fbOutlineB.style.top = top+height + "px";
        o.fbOutlineB.style.left = left + "px";
        o.fbOutlineB.style.width = width + "px";

        o.fbOutlineL.style.top = top-border + "px";
        o.fbOutlineL.style.left = left-border + "px";
        o.fbOutlineL.style.height = height+2*border + "px";

        o.fbOutlineR.style.top = top-border + "px";
        o.fbOutlineR.style.left = left+width + "px";
        o.fbOutlineR.style.height = height+2*border + "px";

        if (!outlineVisible) this.showOutline();
    },

    hideOutline: function()
    {
        if (!outlineVisible) return;

        for (var name in outline)
            offlineFragment.appendChild(outlineElements[name]);

        outlineVisible = false;
    },

    showOutline: function()
    {
        if (outlineVisible) return;

        for (var name in outline)
            Firebug.browser.document.getElementsByTagName("body")[0].appendChild(outlineElements[name]);

        outlineVisible = true;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Box Model

    drawBoxModel: function(el)
    {
        var box = Firebug.browser.getElementBox(el);

        var windowSize = Firebug.browser.getWindowSize();
        var scrollPosition = Firebug.browser.getWindowScrollPosition();

        // element may be occluded by the chrome, when in frame mode
        var offsetHeight = Firebug.chrome.type == "frame" ? FirebugChrome.height : 0;

        // if element box is not inside the viewport, don't draw the box model
        if (box.top > scrollPosition.top + windowSize.height - offsetHeight ||
            box.left > scrollPosition.left + windowSize.width ||
            scrollPosition.top > box.top + box.height ||
            scrollPosition.left > box.left + box.width )
            return;

        var top = box.top;
        var left = box.left;
        var height = box.height;
        var width = box.width;

        var margin = Firebug.browser.getMeasurementBox(el, "margin");
        var padding = Firebug.browser.getMeasurementBox(el, "padding");

        boxModelStyle.top = top - margin.top + "px";
        boxModelStyle.left = left - margin.left + "px";
        boxModelStyle.height = height + margin.top + margin.bottom + "px";
        boxModelStyle.width = width + margin.left + margin.right + "px";

        boxPaddingStyle.top = margin.top + "px";
        boxPaddingStyle.left = margin.left + "px";
        boxPaddingStyle.height = height + "px";
        boxPaddingStyle.width = width + "px";

        boxContentStyle.top = margin.top + padding.top + "px";
        boxContentStyle.left = margin.left + padding.left + "px";
        boxContentStyle.height = height - padding.top - padding.bottom + "px";
        boxContentStyle.width = width - padding.left - padding.right + "px";

        if (!boxModelVisible) this.showBoxModel();
    },

    hideBoxModel: function()
    {
        if (boxModelVisible)
        {
            offlineFragment.appendChild(boxModel);
            boxModelVisible = false;
        }
    },

    showBoxModel: function()
    {
        if (!boxModelVisible)
        {
            Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel);
            boxModelVisible = true;
        }
    }

};

// ************************************************************************************************
// Inspector Internals

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Shared variables

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Internal variables

var offlineFragment = null;

var boxModelVisible = false;

var boxModel, boxModelStyle, boxMargin, boxMarginStyle,
boxPadding, boxPaddingStyle, boxContent, boxContentStyle;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";

var inspectStyle = resetStyle + "z-index: 2147483500;";
var inspectFrameStyle = resetStyle + "z-index: 2147483550; top:0; left:0; background:url(" +
                        Application.location.skinDir + "pixel_transparent.gif);";

//if (Application.isTraceMode) inspectFrameStyle = resetStyle + "z-index: 2147483550; top: 0; left: 0; background: #ff0; opacity: 0.05; _filter: alpha(opacity=5);";

var inspectModelStyle = inspectStyle + "opacity:0.8; _filter:alpha(opacity=80);";
var inspectMarginStyle = inspectStyle + "background: #EDFF64; height:100%; width:100%;";
var inspectPaddingStyle = inspectStyle + "background: SlateBlue;";
var inspectContentStyle = inspectStyle + "background: SkyBlue;";

var outlineStyle = {
    fbHorizontalLine: "background: #3875D7; height: 2px;",
    fbVerticalLine: "background: #3875D7; width: 2px;"
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var lastInspecting = 0;
var fbInspectFrame = null;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var outlineVisible = false;
var outlineElements = {};
var outline = {
  "fbOutlineT": "fbHorizontalLine",
  "fbOutlineL": "fbVerticalLine",
  "fbOutlineB": "fbHorizontalLine",
  "fbOutlineR": "fbVerticalLine"
};

var getInspectingTarget = function()
{

};

// ************************************************************************************************
// Section

var createInspectorFrame = function createInspectorFrame()
{
    fbInspectFrame = createGlobalElement("div");
    fbInspectFrame.id = "fbInspectFrame";
    fbInspectFrame.style.cssText = inspectFrameStyle;
    Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame);
};

var destroyInspectorFrame = function createInspectorFrame()
{
    Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame);
};

var createOutlineInspector = function createOutlineInspector()
{
    for (var name in outline)
    {
        var el = outlineElements[name] = createGlobalElement("div");
        el.id = name;
        el.style.cssText = inspectStyle + outlineStyle[outline[name]];
        offlineFragment.appendChild(el);
    }
};

var destroyOutlineInspector = function destroyOutlineInspector()
{
    for (var name in outline)
    {
        var el = outlineElements[name];
        el.parentNode.removeChild(el);
    }
};

var createBoxModelInspector = function createBoxModelInspector()
{
    boxModel = createGlobalElement("div");
    boxModel.id = "fbBoxModel";
    boxModelStyle = boxModel.style;
    boxModelStyle.cssText = inspectModelStyle;

    boxMargin = createGlobalElement("div");
    boxMargin.id = "fbBoxMargin";
    boxMarginStyle = boxMargin.style;
    boxMarginStyle.cssText = inspectMarginStyle;
    boxModel.appendChild(boxMargin);

    boxPadding = createGlobalElement("div");
    boxPadding.id = "fbBoxPadding";
    boxPaddingStyle = boxPadding.style;
    boxPaddingStyle.cssText = inspectPaddingStyle;
    boxModel.appendChild(boxPadding);

    boxContent = createGlobalElement("div");
    boxContent.id = "fbBoxContent";
    boxContentStyle = boxContent.style;
    boxContentStyle.cssText = inspectContentStyle;
    boxModel.appendChild(boxContent);

    offlineFragment.appendChild(boxModel);
};

var destroyBoxModelInspector = function destroyBoxModelInspector()
{
    boxModel.parentNode.removeChild(boxModel);
};

// ************************************************************************************************
// Section

// ************************************************************************************************
}});<commit_msg>Implemented a "crop" method in drawOutline() to avoid triggering the scrollbar when drawing the outline outside the viewport.<commit_after>FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// Inspector Module

Firebug.Inspector =
{
    create: function()
    {
        offlineFragment = Firebug.browser.document.createDocumentFragment();

        createBoxModelInspector();
        createOutlineInspector();
    },

    destroy: function()
    {
        destroyBoxModelInspector();
        destroyOutlineInspector();

        offlineFragment = null;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Inspect functions

    startInspecting: function()
    {
        Firebug.chrome.selectPanel("HTML");

        createInspectorFrame();

        var size = Firebug.browser.getWindowScrollSize();

        fbInspectFrame.style.width = size.width + "px";
        fbInspectFrame.style.height = size.height + "px";
        /**/

        //addEvent(Firebug.browser.document.documentElement, "mousemove", Firebug.Inspector.onInspectingBody);

        addEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting)
        addEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick)
    },

    stopInspecting: function()
    {
        destroyInspectorFrame();

        Firebug.chrome.inspectButton.restore();

        if (outlineVisible) this.hideOutline();
        removeEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting)
        removeEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick)
    },

    onInspectingClick: function(e)
    {
        fbInspectFrame.style.display = "none";
        var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
        fbInspectFrame.style.display = "block";

        // Avoid inspecting the outline, and the FirebugChrome
        var id = targ.id;
        if (id && /^fbOutline\w$/.test(id)) return;
        if (id == "FirebugChrome") return;

        // Avoid looking at text nodes in Opera
        while (targ.nodeType != 1) targ = targ.parentNode;

        //Firebug.Console.log(targ);
        Firebug.Inspector.stopInspecting();
    },

    onInspecting: function(e)
    {
        if (new Date().getTime() - lastInspecting > 30)
        {
            fbInspectFrame.style.display = "none";
            var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
            fbInspectFrame.style.display = "block";

            // Avoid inspecting the outline, and the FirebugChrome
            var id = targ.id;
            if (id && /^fbOutline\w$/.test(id)) return;
            if (id == "FirebugChrome") return;

            // Avoid looking at text nodes in Opera
            while (targ.nodeType != 1) targ = targ.parentNode;

            if (targ.nodeName.toLowerCase() == "body") return;

            //Firebug.Console.log(e.clientX, e.clientY, targ);
            Firebug.Inspector.drawOutline(targ);

            if (targ[cacheID])
                FBL.Firebug.HTML.selectTreeNode(""+targ[cacheID])

            lastInspecting = new Date().getTime();
        }
    },

    onInspectingBody: function(e)
    {
        if (new Date().getTime() - lastInspecting > 30)
        {
            var targ = e.target;

            // Avoid inspecting the outline, and the FirebugChrome
            var id = targ.id;
            if (id && /^fbOutline\w$/.test(id)) return;
            if (id == "FirebugChrome") return;

            // Avoid looking at text nodes in Opera
            while (targ.nodeType != 1) targ = targ.parentNode;

            if (targ.nodeName.toLowerCase() == "body") return;

            //Firebug.Console.log(e.clientX, e.clientY, targ);
            Firebug.Inspector.drawOutline(targ);

            if (targ[cacheID])
                FBL.Firebug.HTML.selectTreeNode(""+targ[cacheID])

            lastInspecting = new Date().getTime();
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Inspector Outline

    drawOutline: function(el)
    {
        var box = Firebug.browser.getElementBox(el);

        var top = box.top;
        var left = box.left;
        var height = box.height;
        var width = box.width;

        var border = 2;
        var o = outlineElements;

        o.fbOutlineT.style.top = top-border + "px";
        o.fbOutlineT.style.left = left + "px";
        o.fbOutlineT.style.width = width + "px";

        o.fbOutlineB.style.top = top+height + "px";
        o.fbOutlineB.style.left = left + "px";
        o.fbOutlineB.style.width = width + "px";

        o.fbOutlineL.style.top = top-border + "px";
        o.fbOutlineL.style.left = left-border + "px";
        o.fbOutlineL.style.height = height+2*border + "px";

        o.fbOutlineR.style.top = top-border + "px";
        o.fbOutlineR.style.left = left+width + "px";
        o.fbOutlineR.style.height = height+2*border + "px";

        if (!outlineVisible) this.showOutline();
    },

    /**
     *
     *   llttttttrr
     *   llttttttrr
     *   ll      rr
     *   ll      rr
     *   llbbbbbbrr
     *   llbbbbbbrr
     */
    drawOutline: function(el)
    {
        var border = 2;
        var scrollbarSize = 17;

        var windowSize = Firebug.browser.getWindowSize();
        var scrollSize = Firebug.browser.getWindowScrollSize();
        var scrollPosition = Firebug.browser.getWindowScrollPosition();

        var offsetX = scrollSize.height > windowSize.height ? // is *vertical* scrollbar visible
                      scrollbarSize :
                      0;

        var offsetY = scrollSize.width > windowSize.width ? // is *horizontal* scrollbar visible
                      scrollbarSize :
                      0;

        var box = Firebug.browser.getElementBox(el);

        var top = box.top;
        var left = box.left;
        var height = box.height;
        var width = box.width;

        var freeHorizontalSpace = scrollPosition.left + windowSize.width - left - width - offsetX;
        var freeVerticalSpace = scrollPosition.top + windowSize.height - top - height - offsetY;
        var numVerticalBorders = freeVerticalSpace > 0 ? 2 : 1;

        var o = outlineElements;
        var style;

        style = o.fbOutlineT.style;
        style.top = top-border + "px";
        style.left = left + "px";
        style.height = border + "px";  // TODO: on initialize()
        style.width = width + "px";

        style = o.fbOutlineL.style;
        style.top = top-border + "px";
        style.left = left-border + "px";
        style.height = height+ numVerticalBorders*border + "px";
        style.width = border + "px";  // TODO: on initialize()

        style = o.fbOutlineB.style;
        if (freeVerticalSpace > 0)
        {
            style.top = top+height + "px";
            style.left = left + "px";
            style.width = width + "px";
            //style.height = border + "px"; // TODO: on initialize() or worst case?
        }
        else
        {
            style.top = -2*border + "px";
            style.left = -2*border + "px";
            style.width = border + "px";
            //style.height = border + "px";
        }

        style = o.fbOutlineR.style;
        if (freeHorizontalSpace > 0)
        {
            style.top = top-border + "px";
            style.left = left+width + "px";
            style.height = height + numVerticalBorders*border + "px";
            style.width = (freeHorizontalSpace < border ? freeHorizontalSpace : border) + "px";
        }
        else
        {
            style.top = -2*border + "px";
            style.left = -2*border + "px";
            style.height = border + "px";
            style.width = border + "px";
        }

        if (!outlineVisible) this.showOutline();
    },

    hideOutline: function()
    {
        if (!outlineVisible) return;

        for (var name in outline)
            offlineFragment.appendChild(outlineElements[name]);

        outlineVisible = false;
    },

    showOutline: function()
    {
        if (outlineVisible) return;

        for (var name in outline)
            Firebug.browser.document.getElementsByTagName("body")[0].appendChild(outlineElements[name]);

        outlineVisible = true;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Box Model

    drawBoxModel: function(el)
    {
        var box = Firebug.browser.getElementBox(el);

        var windowSize = Firebug.browser.getWindowSize();
        var scrollPosition = Firebug.browser.getWindowScrollPosition();

        // element may be occluded by the chrome, when in frame mode
        var offsetHeight = Firebug.chrome.type == "frame" ? FirebugChrome.height : 0;

        // if element box is not inside the viewport, don't draw the box model
        if (box.top > scrollPosition.top + windowSize.height - offsetHeight ||
            box.left > scrollPosition.left + windowSize.width ||
            scrollPosition.top > box.top + box.height ||
            scrollPosition.left > box.left + box.width )
            return;

        var top = box.top;
        var left = box.left;
        var height = box.height;
        var width = box.width;

        var margin = Firebug.browser.getMeasurementBox(el, "margin");
        var padding = Firebug.browser.getMeasurementBox(el, "padding");

        boxModelStyle.top = top - margin.top + "px";
        boxModelStyle.left = left - margin.left + "px";
        boxModelStyle.height = height + margin.top + margin.bottom + "px";
        boxModelStyle.width = width + margin.left + margin.right + "px";

        boxPaddingStyle.top = margin.top + "px";
        boxPaddingStyle.left = margin.left + "px";
        boxPaddingStyle.height = height + "px";
        boxPaddingStyle.width = width + "px";

        boxContentStyle.top = margin.top + padding.top + "px";
        boxContentStyle.left = margin.left + padding.left + "px";
        boxContentStyle.height = height - padding.top - padding.bottom + "px";
        boxContentStyle.width = width - padding.left - padding.right + "px";

        if (!boxModelVisible) this.showBoxModel();
    },

    hideBoxModel: function()
    {
        if (boxModelVisible)
        {
            offlineFragment.appendChild(boxModel);
            boxModelVisible = false;
        }
    },

    showBoxModel: function()
    {
        if (!boxModelVisible)
        {
            Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel);
            boxModelVisible = true;
        }
    }

};

// ************************************************************************************************
// Inspector Internals

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Shared variables

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Internal variables

var offlineFragment = null;

var boxModelVisible = false;

var boxModel, boxModelStyle, boxMargin, boxMarginStyle,
boxPadding, boxPaddingStyle, boxContent, boxContentStyle;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";

var inspectStyle = resetStyle + "z-index: 2147483500;";
var inspectFrameStyle = resetStyle + "z-index: 2147483550; top:0; left:0; background:url(" +
                        Application.location.skinDir + "pixel_transparent.gif);";

//if (Application.isTraceMode) inspectFrameStyle = resetStyle + "z-index: 2147483550; top: 0; left: 0; background: #ff0; opacity: 0.05; _filter: alpha(opacity=5);";

var inspectModelStyle = inspectStyle + "opacity:0.8; _filter:alpha(opacity=80);";
var inspectMarginStyle = inspectStyle + "background: #EDFF64; height:100%; width:100%;";
var inspectPaddingStyle = inspectStyle + "background: SlateBlue;";
var inspectContentStyle = inspectStyle + "background: SkyBlue;";

var outlineStyle = {
    fbHorizontalLine: "background: #3875D7;height: 2px;",
    fbVerticalLine: "background: #3875D7;width: 2px;"
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var lastInspecting = 0;
var fbInspectFrame = null;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var outlineVisible = false;
var outlineElements = {};
var outline = {
  "fbOutlineT": "fbHorizontalLine",
  "fbOutlineL": "fbVerticalLine",
  "fbOutlineB": "fbHorizontalLine",
  "fbOutlineR": "fbVerticalLine"
};

var getInspectingTarget = function()
{

};

// ************************************************************************************************
// Section

var createInspectorFrame = function createInspectorFrame()
{
    fbInspectFrame = createGlobalElement("div");
    fbInspectFrame.id = "fbInspectFrame";
    fbInspectFrame.style.cssText = inspectFrameStyle;
    Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame);
};

var destroyInspectorFrame = function createInspectorFrame()
{
    Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame);
};

var createOutlineInspector = function createOutlineInspector()
{
    for (var name in outline)
    {
        var el = outlineElements[name] = createGlobalElement("div");
        el.id = name;
        el.style.cssText = inspectStyle + outlineStyle[outline[name]];
        offlineFragment.appendChild(el);
    }
};

var destroyOutlineInspector = function destroyOutlineInspector()
{
    for (var name in outline)
    {
        var el = outlineElements[name];
        el.parentNode.removeChild(el);
    }
};

var createBoxModelInspector = function createBoxModelInspector()
{
    boxModel = createGlobalElement("div");
    boxModel.id = "fbBoxModel";
    boxModelStyle = boxModel.style;
    boxModelStyle.cssText = inspectModelStyle;

    boxMargin = createGlobalElement("div");
    boxMargin.id = "fbBoxMargin";
    boxMarginStyle = boxMargin.style;
    boxMarginStyle.cssText = inspectMarginStyle;
    boxModel.appendChild(boxMargin);

    boxPadding = createGlobalElement("div");
    boxPadding.id = "fbBoxPadding";
    boxPaddingStyle = boxPadding.style;
    boxPaddingStyle.cssText = inspectPaddingStyle;
    boxModel.appendChild(boxPadding);

    boxContent = createGlobalElement("div");
    boxContent.id = "fbBoxContent";
    boxContentStyle = boxContent.style;
    boxContentStyle.cssText = inspectContentStyle;
    boxModel.appendChild(boxContent);

    offlineFragment.appendChild(boxModel);
};

var destroyBoxModelInspector = function destroyBoxModelInspector()
{
    boxModel.parentNode.removeChild(boxModel);
};

// ************************************************************************************************
// Section

// ************************************************************************************************
}});<|endoftext|>


<commit_before>var Square = require('./square');
var Rook = require('./pieces/rook');
var Bishop = require('./pieces/bishop');
var Queen = require('./pieces/queen');
var Knight = require('./pieces/knight');
var King = require('./pieces/king');
var BlackPawn = require('./pieces/black-pawn');
var WhitePawn = require('./pieces/white-pawn');

function Board (context, canvas) {
  this.gameOver = false;
  this.nextTurn = true;
  this.context = context;
  this.canvas = canvas;
  this.squares = [];
};

Board.prototype.drawBoard = function () {
  for (var i = 0; i < 4; i++) {
    for (var j = 0; j < 4; j++) {
      var x = j * 200;
      var y = i * 200;
      this.context.fillStyle = "grey";
      this.context.fillRect(x + 100, y, 100, 100);
      this.context.fillRect(x, y + 100, 100, 100);
    };
  };

  for (var i = 0; i < this.squares.length; i++) {
  var context = this.context;
    var square = this.squares[i]
    if (square.piece) {
      addIcon (square, this.context)
    }
  }
};

function addIcon (square, context) {
  var icon = new Image(80, 80);
  icon.src = square.piece.src;

  icon.onload = function () {
    var x = (square.xCoordinate * 100 + 20)
    var y = (square.yCoordinate * 100 + 10)
    context.drawImage(icon, x, y);
  };
}

Board.prototype.addSquaresToBoard = function () {
  for (var i = 0; i <= 7; i++) {
    for (var j = 0; j <= 7; j++) {
      this.squares.push(new Square(this, j, i));
    };
  };
};

Board.prototype.makeBoardClickable = function () {
  var board = this;
  this.canvas.addEventListener("mousedown", selectSquare);
  var targetSquare;

  function selectSquare (event) {
    var canvas_x = event.pageX;
    var canvas_y = event.pageY;

    var indexOfSquare = (Math.floor(canvas_y / 100) * 8) + Math.floor(canvas_x / 100)
    targetSquare = board.squares[indexOfSquare]

    var startX = targetSquare.xCoordinate * 100;
    var startY = targetSquare.yCoordinate * 100;
    board.context.fillStyle = "yellow";
    board.context.fillRect(startX, startY, 100, 100);
    if (targetSquare.isOccupied()) {
      addIcon(targetSquare, board.context);
    }

    board.canvas.removeEventListener("mousedown", selectSquare, false);
    board.canvas.addEventListener("mousedown", selectPiece);
  }

  function selectPiece (event) {
    board.canvas.removeEventListener("mousedown", selectPiece, false);
    board.canvas.addEventListener("mousedown", selectSquare, false);

    var canvas_x = event.pageX;
    var canvas_y = event.pageY;

    var indexOfSquare = (Math.floor(canvas_y / 100) * 8) + Math.floor(canvas_x / 100);
    var pieceSquare = board.squares[indexOfSquare];

    pieceSquare.piece.move(targetSquare);
  }
};

Board.prototype.addPiecesToBoard = function () {
  loadBlack(this);
  loadWhite(this);
}

function loadBlack (board) {
  board.squares[0].piece = new Rook (board.squares[0], "black");
  board.squares[1].piece = new Knight (board.squares[1], "black");
  board.squares[2].piece = new Bishop (board.squares[2], "black");
  board.squares[3].piece = new Queen (board.squares[3], "black");
  board.squares[4].piece = new King (board.squares[4], "black");
  board.squares[5].piece = new Bishop (board.squares[5], "black");
  board.squares[6].piece = new Knight (board.squares[6], "black");
  board.squares[7].piece = new Rook (board.squares[7], "black");
  for (var i = 8; i < 16; i++) {
    board.squares[i].piece = new BlackPawn (board.squares[i], "black");
  }
};

function loadWhite (board) {
  for (var i = 48; i < 56; i++) {
    board.squares[i].piece = new WhitePawn (board.squares[i], "white");
  }
  board.squares[56].piece = new Rook (board.squares[56], "white");
  board.squares[57].piece = new Knight (board.squares[57], "white");
  board.squares[58].piece = new Bishop (board.squares[58], "white");
  board.squares[59].piece = new Queen (board.squares[59], "white");
  board.squares[60].piece = new King (board.squares[60], "white");
  board.squares[61].piece = new Bishop (board.squares[61], "white");
  board.squares[62].piece = new Knight (board.squares[62], "white");
  board.squares[63].piece = new Rook (board.squares[63], "white");
};

Board.prototype.canMoveHere = function (square) {
  var pieces = [];
  for (var i = 0; i < this.squares.length; i++) {
    //filter by player turn/color eventually
    if (this.squares[i].piece) {
      pieces.push(this.squares[i].piece);
    }
  }
  return pieces;
};

Board.prototype.pieceCount = function () {
  return this.squares.reduce(function (count, square) {
    if (square.piece) {
      count++;
    }
    return count;
  }, 0);
};

Board.prototype.findSquare = function (x, y) {
    return this.squares[(y * 8) + x];
};

module.exports = Board;
<commit_msg>refactored square highlighing into highlightSelectedSquare funtion.<commit_after>var Square = require('./square');
var Rook = require('./pieces/rook');
var Bishop = require('./pieces/bishop');
var Queen = require('./pieces/queen');
var Knight = require('./pieces/knight');
var King = require('./pieces/king');
var BlackPawn = require('./pieces/black-pawn');
var WhitePawn = require('./pieces/white-pawn');

function Board (context, canvas) {
  this.gameOver = false;
  this.nextTurn = true;
  this.context = context;
  this.canvas = canvas;
  this.squares = [];
};

Board.prototype.drawBoard = function () {
  for (var i = 0; i < 4; i++) {
    for (var j = 0; j < 4; j++) {
      var x = j * 200;
      var y = i * 200;
      this.context.fillStyle = "grey";
      this.context.fillRect(x + 100, y, 100, 100);
      this.context.fillRect(x, y + 100, 100, 100);
    };
  };

  for (var i = 0; i < this.squares.length; i++) {
  var context = this.context;
    var square = this.squares[i]
    if (square.piece) {
      addIcon (square, this.context)
    }
  }
};

function addIcon (square, context) {
  var icon = new Image(80, 80);
  icon.src = square.piece.src;

  icon.onload = function () {
    var x = (square.xCoordinate * 100 + 20)
    var y = (square.yCoordinate * 100 + 10)
    context.drawImage(icon, x, y);
  };
}

Board.prototype.addSquaresToBoard = function () {
  for (var i = 0; i <= 7; i++) {
    for (var j = 0; j <= 7; j++) {
      this.squares.push(new Square(this, j, i));
    };
  };
};

Board.prototype.makeBoardClickable = function () {
  var board = this;
  this.canvas.addEventListener("mousedown", selectSquare);
  var targetSquare;

  function selectSquare (event) {
    var canvas_x = event.pageX;
    var canvas_y = event.pageY;

    var indexOfSquare = (Math.floor(canvas_y / 100) * 8) + Math.floor(canvas_x / 100)
    targetSquare = board.squares[indexOfSquare]

    highlightSelectedSquare(board, targetSquare);

    board.canvas.removeEventListener("mousedown", selectSquare, false);
    board.canvas.addEventListener("mousedown", selectPiece);
  }

  function selectPiece (event) {
    board.canvas.removeEventListener("mousedown", selectPiece, false);
    board.canvas.addEventListener("mousedown", selectSquare, false);

    var canvas_x = event.pageX;
    var canvas_y = event.pageY;

    var indexOfSquare = (Math.floor(canvas_y / 100) * 8) + Math.floor(canvas_x / 100);
    var pieceSquare = board.squares[indexOfSquare];

    pieceSquare.piece.move(targetSquare);
  }
};

function highlightSelectedSquare (board, targetSquare) {
  var startX = targetSquare.xCoordinate * 100;
  var startY = targetSquare.yCoordinate * 100;
  board.context.fillStyle = "yellow";
  board.context.fillRect(startX, startY, 100, 100);
  if (targetSquare.isOccupied()) {
    addIcon(targetSquare, board.context);
  }
};

Board.prototype.addPiecesToBoard = function () {
  loadBlack(this);
  loadWhite(this);
}

function loadBlack (board) {
  board.squares[0].piece = new Rook (board.squares[0], "black");
  board.squares[1].piece = new Knight (board.squares[1], "black");
  board.squares[2].piece = new Bishop (board.squares[2], "black");
  board.squares[3].piece = new Queen (board.squares[3], "black");
  board.squares[4].piece = new King (board.squares[4], "black");
  board.squares[5].piece = new Bishop (board.squares[5], "black");
  board.squares[6].piece = new Knight (board.squares[6], "black");
  board.squares[7].piece = new Rook (board.squares[7], "black");
  for (var i = 8; i < 16; i++) {
    board.squares[i].piece = new BlackPawn (board.squares[i], "black");
  }
};

function loadWhite (board) {
  for (var i = 48; i < 56; i++) {
    board.squares[i].piece = new WhitePawn (board.squares[i], "white");
  }
  board.squares[56].piece = new Rook (board.squares[56], "white");
  board.squares[57].piece = new Knight (board.squares[57], "white");
  board.squares[58].piece = new Bishop (board.squares[58], "white");
  board.squares[59].piece = new Queen (board.squares[59], "white");
  board.squares[60].piece = new King (board.squares[60], "white");
  board.squares[61].piece = new Bishop (board.squares[61], "white");
  board.squares[62].piece = new Knight (board.squares[62], "white");
  board.squares[63].piece = new Rook (board.squares[63], "white");
};

Board.prototype.canMoveHere = function (square) {
  var pieces = [];
  for (var i = 0; i < this.squares.length; i++) {
    //filter by player turn/color eventually
    if (this.squares[i].piece) {
      pieces.push(this.squares[i].piece);
    }
  }
  return pieces;
};

Board.prototype.pieceCount = function () {
  return this.squares.reduce(function (count, square) {
    if (square.piece) {
      count++;
    }
    return count;
  }, 0);
};

Board.prototype.findSquare = function (x, y) {
    return this.squares[(y * 8) + x];
};

module.exports = Board;
<|endoftext|>


<commit_before>angular.module('app.main', [])

.controller('mainCtrl', function($scope, $state, $ionicHistory, Facebook, store, $rootScope, $http, Game) {

  $scope.isDisabled = false;
  $scope.invitations = [];

  $scope.newGame = function () {
    $scope.isDisabled = true;
    $state.go('newGame');
    $scope.isDisabled = false;
  };

  $scope.account = function () {
    $ionicHistory.goBack();
  };

  $scope.getInvitations = function () {
    $http({
      url: Config.api + '/invitations',
      method: 'get'
    })
    .then(function (response) {
      if (response.data.invitations) {
        $scope.invitations = [];
        response.data.invitations.forEach(function(invitation) {
          if (invitation.creator.id !== store.get('remote_id')) {
            $scope.invitations.push(invitation);
          }
        });
      }
    })
    .catch(function (error) {
      console.dir(error);
    });
  };

  $scope.accept = function (invitation) {
    $http({
      url: Config.api + '/invitations',
      method: 'post',
      data: {
        invitation: invitation,
        accept: true
      }
    })
    .then(function (response) {
      // socket.emit(acceptInvite, {
      //   invitation: invitation,
      //   name: store.get('profile').name
      // });
      console.log(response);
    })
    .catch(function (error) {
      console.error(error);
    });
  };

  $scope.decline = function (invitation) {
    $http({
      url: Config.api + '/invitations',
      method: 'post',
      data: {
        invitation: invitation,
        accept: false
      }
    })
    .then(function (response) {
      // socket.emit(declineInvite, {
      //   invitation: invitation,
      //   name: store.get('profile').name
      // });
      console.log(response);
    })
    .catch(function (error) {
      console.error(error);
    });
  };

  $scope.getFriends = function () {
    Facebook.api('/me/friends?access_token=' + store.get('fb_access_token'), function (response) {
      //TODO: FB authentication expired, handle this error
      if (response.error) {

      } else {
        $rootScope.friends = response.data;
      }
    });
  };

  $scope.getFriends();
  $scope.getInvitations();
  Game.checkGame()
  .then(function (newGame) {
    if (newGame) {
      Game.getGame()
      .then(function () {
        console.log(Game.game);
      });
    }
  })
  .catch(function (error) {
    console.log(error);
  });

  //Would be better along is authenticated redirect around/from login
  // socket.emit('onlineCheck', {
  //   user_fb: store.get('profile').user_id.split('|')[1],
  //   name: store.get('profile').name
  // });
});
<commit_msg>(chore) remove logging statement<commit_after>angular.module('app.main', [])

.controller('mainCtrl', function($scope, $state, $ionicHistory, Facebook, store, $rootScope, $http, Game) {

  $scope.isDisabled = false;
  $scope.invitations = [];

  $scope.newGame = function () {
    $scope.isDisabled = true;
    $state.go('newGame');
    $scope.isDisabled = false;
  };

  $scope.account = function () {
    $ionicHistory.goBack();
  };

  $scope.getInvitations = function () {
    $http({
      url: Config.api + '/invitations',
      method: 'get'
    })
    .then(function (response) {
      if (response.data.invitations) {
        $scope.invitations = [];
        response.data.invitations.forEach(function(invitation) {
          if (invitation.creator.id !== store.get('remote_id')) {
            $scope.invitations.push(invitation);
          }
        });
      }
    })
    .catch(function (error) {
      console.dir(error);
    });
  };

  $scope.accept = function (invitation) {
    $http({
      url: Config.api + '/invitations',
      method: 'post',
      data: {
        invitation: invitation,
        accept: true
      }
    })
    .then(function (response) {
      // socket.emit(acceptInvite, {
      //   invitation: invitation,
      //   name: store.get('profile').name
      // });
      console.log(response);
    })
    .catch(function (error) {
      console.error(error);
    });
  };

  $scope.decline = function (invitation) {
    $http({
      url: Config.api + '/invitations',
      method: 'post',
      data: {
        invitation: invitation,
        accept: false
      }
    })
    .then(function (response) {
      // socket.emit(declineInvite, {
      //   invitation: invitation,
      //   name: store.get('profile').name
      // });
      console.log(response);
    })
    .catch(function (error) {
      console.error(error);
    });
  };

  $scope.getFriends = function () {
    Facebook.api('/me/friends?access_token=' + store.get('fb_access_token'), function (response) {
      //TODO: FB authentication expired, handle this error
      if (response.error) {

      } else {
        $rootScope.friends = response.data;
      }
    });
  };

  $scope.getFriends();
  $scope.getInvitations();
  Game.checkGame()
  .then(function (newGame) {
    if (newGame) {
      Game.getGame()
      .then(function () {
      });
    }
  })
  .catch(function (error) {
    console.log(error);
  });

  //Would be better along is authenticated redirect around/from login
  // socket.emit('onlineCheck', {
  //   user_fb: store.get('profile').user_id.split('|')[1],
  //   name: store.get('profile').name
  // });
});
<|endoftext|>


<commit_before>import React from 'react';
import NotificationList from './NotificationList';
import NotificationDetails from './NotificationDetails';
import NotificationHeading from './NotificationHeading';
import NotificationApi from './NotificationApi';

export default class NotificationContainer extends React.Component {

	constructor(props) {
		super(props);

		this.state = {
			isArchive: false,
			displayDetails: false,
			notificationDetails: {
				message: {}
			}
		};
		this.showDetails = this.showDetails.bind(this);
		this.showList = this.showList.bind(this);
		this.appendArchiveList = this.appendArchiveList.bind(this);
		this.goToArchiveList = this.goToArchiveList.bind(this);
		this.showNonArchivedList = this.showNonArchivedList.bind(this);
		this.resetListOnCloseDrawer = this.resetListOnCloseDrawer.bind(this);
	}

	showDetails(notification) {
		const state = {
			displayDetails: true,
			notificationDetails: notification
		};
		if(!this.state.isArchive && !notification.isRead) {
			this.props.notificationRead(notification);
		}
		this.refs.heading && this.refs.heading.focus();
		this.setState(state);
	}

	showList() {
		this.setState({
			displayDetails: false
		});
	}

	appendArchiveList(archivedNotification) {
		this.props.archiveNotification(archivedNotification);
		this.setState({
			displayDetails: false
		});
	}

	goToArchiveList() {
		this.refs.closeButton && this.refs.closeButton.focus();
		this.setState({
			isArchive: true
		});
	}

	showNonArchivedList() {
		this.setState({
			isArchive: false
		});
	}

	resetListOnCloseDrawer() {
		this.setState({
			displayDetails: false,
			isArchive: false,
			list: this.state.notificationList
		});
		this.props.closeDrawer();
	}

	hyphenateWords(sentence) {
		const maxLength = 12;
		if (typeof sentence !== 'string') {
			return sentence;
		}
		return sentence.split(' ').map((word) => {
			if (word.length <= maxLength) {
				return word;
			}
			const chunkCount = Math.floor(word.length / maxLength) + 1;
			const chunkSize = Math.round(word.length / chunkCount);

			let result = '';
			for (let spacer = '', i = 0; i < chunkCount; i++) {
				const chunkStart = i * chunkSize;
				const chunkEnd = (i + 1) * chunkSize;
				result += spacer + word.substring(chunkStart, chunkEnd);
				spacer = '\u00AD';
			}
			return result;
		}).join(' ');
	}

	render() {

		// Move the X button up 3px
		const paddingTop = (parseInt(this.props.config.appHeaderClientHeight) - 3) + 'px';
		const closIconPadding = {
			'paddingTop': paddingTop
		}
		return (

						<button aria-label="Close Notification" onClick={this.resetListOnCloseDrawer}>

						</button>

						<NotificationHeading back={this.showList} isList={!this.state.isArchive && !this.state.displayDetails}
						isDetails={this.state.displayDetails} isArchive={this.state.isArchive} archiveBack={this.showNonArchivedList} />

								<NotificationList list={this.props.list} config={this.props.config} showDetails={this.showDetails} isError={this.props.apiError}
								 appendArchiveList={this.appendArchiveList} isArchiveTray={false} goToArchiveList={this.goToArchiveList} hyphenateWords={this.hyphenateWords}/>

									 Notification Archive

						<NotificationList list={this.props.archivedList} config={this.props.config} showDetails={this.showDetails} isError={this.props.apiError}
						 appendArchiveList={this.appendArchiveList} isArchiveTray={true} goToArchiveList={this.goToArchiveList} hyphenateWords={this.hyphenateWords}/>

						<NotificationDetails notification={this.state.notificationDetails} closeDrawer={this.props.closeDrawer} apiConfig={this.props.config} appendArchiveList={this.appendArchiveList}
							coachmarkListener={this.props.coachmarkListener} hyphenateWords={this.hyphenateWords}/>

		);
	}
}
<commit_msg>removed extra space?<commit_after>import React from 'react';
import NotificationList from './NotificationList';
import NotificationDetails from './NotificationDetails';
import NotificationHeading from './NotificationHeading';
import NotificationApi from './NotificationApi';

export default class NotificationContainer extends React.Component {

	constructor(props) {
		super(props);

		this.state = {
			isArchive: false,
			displayDetails: false,
			notificationDetails: {
				message: {}
			}
		};
		this.showDetails = this.showDetails.bind(this);
		this.showList = this.showList.bind(this);
		this.appendArchiveList = this.appendArchiveList.bind(this);
		this.goToArchiveList = this.goToArchiveList.bind(this);
		this.showNonArchivedList = this.showNonArchivedList.bind(this);
		this.resetListOnCloseDrawer = this.resetListOnCloseDrawer.bind(this);
	}

	showDetails(notification) {
		const state = {
			displayDetails: true,
			notificationDetails: notification
		};
		if(!this.state.isArchive && !notification.isRead) {
			this.props.notificationRead(notification);
		}
		this.refs.heading && this.refs.heading.focus();
		this.setState(state);
	}

	showList() {
		this.setState({
			displayDetails: false
		});
	}

	appendArchiveList(archivedNotification) {
		this.props.archiveNotification(archivedNotification);
		this.setState({
			displayDetails: false
		});
	}

	goToArchiveList() {
		this.refs.closeButton && this.refs.closeButton.focus();
		this.setState({
			isArchive: true
		});
	}

	showNonArchivedList() {
		this.setState({
			isArchive: false
		});
	}

	resetListOnCloseDrawer() {
		this.setState({
			displayDetails: false,
			isArchive: false,
			list: this.state.notificationList
		});
		this.props.closeDrawer();
	}

	hyphenateWords(sentence) {
		const maxLength = 12;
		if (typeof sentence !== 'string') {
			return sentence;
		}
		return sentence.split(' ').map((word) => {
			if (word.length <= maxLength) {
				return word;
			}
			const chunkCount = Math.floor(word.length / maxLength) + 1;
			const chunkSize = Math.round(word.length / chunkCount);

			let result = '';
			for (let spacer = '', i = 0; i < chunkCount; i++) {
				const chunkStart = i * chunkSize;
				const chunkEnd = (i + 1) * chunkSize;
				result += spacer + word.substring(chunkStart, chunkEnd);
				spacer = '\u00AD';
			}
			return result;
		}).join(' ');
	}

	render() {

		// Move the X button up 3px
		const paddingTop = (parseInt(this.props.config.appHeaderClientHeight) - 3) + 'px';
		const closIconPadding = {
			'paddingTop': paddingTop
		}
		return (

						<button aria-label="Close Notification" onClick={this.resetListOnCloseDrawer}>

						</button>

						<NotificationHeading back={this.showList} isList={!this.state.isArchive && !this.state.displayDetails}
						isDetails={this.state.displayDetails} isArchive={this.state.isArchive} archiveBack={this.showNonArchivedList} />

								<NotificationList list={this.props.list} config={this.props.config} showDetails={this.showDetails} isError={this.props.apiError}
								 appendArchiveList={this.appendArchiveList} isArchiveTray={false} goToArchiveList={this.goToArchiveList} hyphenateWords={this.hyphenateWords}/>

									 Notification Archive

						<NotificationList list={this.props.archivedList} config={this.props.config} showDetails={this.showDetails} isError={this.props.apiError}
						 appendArchiveList={this.appendArchiveList} isArchiveTray={true} goToArchiveList={this.goToArchiveList} hyphenateWords={this.hyphenateWords}/>

						<NotificationDetails notification={this.state.notificationDetails} closeDrawer={this.props.closeDrawer} apiConfig={this.props.config} appendArchiveList={this.appendArchiveList}
							coachmarkListener={this.props.coachmarkListener} hyphenateWords={this.hyphenateWords}/>

		);
	}
}
<|endoftext|>


<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Created by Gavin Chan at 2017/4/5 14:06.
 */

"use strict";

const restify = require('restify');
const assert = require('assert-plus');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const async = require('async');

const moray = require('./moray');
const storage = require('./storage');

const files = module.exports = {};

files.upload = (req, res, next) => {
  const params = req.body;
  assert.arrayOfObject(params, "params");
  req.log.info(params);
  let data = [];

  async.mapSeries(params, (param, callback) => {
    const cache = param.path;
    const data_area = req.config.data_area;
    const file_type = param.type || "";
    const uploaded_by = param.uploaded_by;
    const crypto_method = param.crypto || "rc4";
    const visibility = param.visibility || "public";
    const key = param.key || req.config.password || "default password.";
    const hash = crypto.createHash('sha1');
    hash.update(key);
    const hash_key = hash.digest('base64');

    if (!cache || !uploaded_by) {
      const err = {
        message: "path和uploaded_by一定要有！",
        context: param
      };
      req.log.error(err, err.message);

      return callback(null, err);
    }

    const file_size = fs.statSync(cache).size;
    storage.save(
      {
        data_area: data_area,
        cache: cache,
        key: hash_key,
        crypto_method: crypto_method
      },
      /**
       * @param err
       * @param common
       * @param saves
       */
      (err, common, saves) => {
        if (err) {
          req.log.error(err, err.message);

          return callback(null, err);
        }

        common.filename = param.originalname;
        common.uploaded_by = uploaded_by;
        common.crypto_method = crypto_method;
        common.visibility = visibility;
        common.size = file_size;
        common.type = file_type;
        const ret = JSON.stringify(common);
        common.key = hash_key;
        for (let k in saves) {
          common[k] = saves[k];
        }

        data.push(common);
        callback(null, JSON.parse(ret));
      }
    );
  },(err, results) => {

    if (err) {
      req.log.error(err);
      next(err);
    }
    req.log.info(data, "数据库存储");

    moray.save({log: req.log, data: data}, err => {
      if (err) {
        req.log.error(err, "数据库存储时：");

        //删除已存储文件
        data.forEach(function (item) {
          fs.unlink(item.save_path, (e) => {
            if (e) {
              req.log.error(e, "删除" + item.filename + "时：");
            }
          })
        });

        return next(err);
      }

      res.send(results);
    });

  });

};

files.download = (req, res, next) => {
  req.log.debug(req.params, "下载参数");
  moray.query({
      ret:["*"],
      cond:{
        uuid: req.params.uuid
      }
    },
    (error, results) => {
      req.log.info(results.rows, "查询结果：");
      if (error) {
        req.log.error(error, "查询时：");
        return next(error);
      }

      if (results.rows.length === 0) {
        return next(new restify.InvalidArgumentError("文件不存在！"));
      }

      const result = results.rows[0];

      req.log.info({
        save_path: result.save_path,
        crypto_method: result.crypto_method,
        key: result.key,
        filename: result.filename,
        cache_area: req.params.cache_area
      }, "obtain");

      storage.obtain({
        save_path: result.save_path,
        crypto_method: result.crypto_method,
        key: result.key,
        cache_area: req.params.cache_area
      }, (err, path) => {
        res.send({uuid: req.params.uuid, path: path, filename: result.filename});
        return next();
      });
    }
  );
};

files.getList = (req, res, next) => {
  moray.query({
    ret:["uuid", "filename", "type", "size", "visibility", "uploaded_by", "last_modify"],
    cond:req.params},
    (error, results) => {
      req.log.info(results.rows, "查询结果：");
      if (error) {
        req.log.error(error, "查询时：");
        return next(error);
      }
      res.send(results.rows);
      return next();
    }
  );
};<commit_msg>返回文件类型<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Created by Gavin Chan at 2017/4/5 14:06.
 */

"use strict";

const restify = require('restify');
const assert = require('assert-plus');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const async = require('async');

const moray = require('./moray');
const storage = require('./storage');

const files = module.exports = {};

files.upload = (req, res, next) => {
  const params = req.body;
  assert.arrayOfObject(params, "params");
  req.log.info(params);
  let data = [];

  async.mapSeries(params, (param, callback) => {
    const cache = param.path;
    const data_area = req.config.data_area;
    const file_type = param.type || "";
    const uploaded_by = param.uploaded_by;
    const crypto_method = param.crypto || "rc4";
    const visibility = param.visibility || "public";
    const key = param.key || req.config.password || "default password.";
    const hash = crypto.createHash('sha1');
    hash.update(key);
    const hash_key = hash.digest('base64');

    if (!cache || !uploaded_by) {
      const err = {
        message: "path和uploaded_by一定要有！",
        context: param
      };
      req.log.error(err, err.message);

      return callback(null, err);
    }

    const file_size = fs.statSync(cache).size;
    storage.save(
      {
        data_area: data_area,
        cache: cache,
        key: hash_key,
        crypto_method: crypto_method
      },
      /**
       * @param err
       * @param common
       * @param saves
       */
      (err, common, saves) => {
        if (err) {
          req.log.error(err, err.message);

          return callback(null, err);
        }

        common.filename = param.originalname;
        common.uploaded_by = uploaded_by;
        common.crypto_method = crypto_method;
        common.visibility = visibility;
        common.size = file_size;
        common.type = file_type;
        const ret = JSON.stringify(common);
        common.key = hash_key;
        for (let k in saves) {
          common[k] = saves[k];
        }

        data.push(common);
        callback(null, JSON.parse(ret));
      }
    );
  },(err, results) => {

    if (err) {
      req.log.error(err);
      next(err);
    }
    req.log.info(data, "数据库存储");

    moray.save({log: req.log, data: data}, err => {
      if (err) {
        req.log.error(err, "数据库存储时：");

        //删除已存储文件
        data.forEach(function (item) {
          fs.unlink(item.save_path, (e) => {
            if (e) {
              req.log.error(e, "删除" + item.filename + "时：");
            }
          })
        });

        return next(err);
      }

      res.send(results);
    });

  });

};

files.download = (req, res, next) => {
  req.log.debug(req.params, "下载参数");
  moray.query({
      ret:["*"],
      cond:{
        uuid: req.params.uuid
      }
    },
    (error, results) => {
      req.log.info(results.rows, "查询结果：");
      if (error) {
        req.log.error(error, "查询时：");
        return next(error);
      }

      if (results.rows.length === 0) {
        return next(new restify.InvalidArgumentError("文件不存在！"));
      }

      const result = results.rows[0];

      req.log.info({
        save_path: result.save_path,
        crypto_method: result.crypto_method,
        key: result.key,
        filename: result.filename,
        cache_area: req.params.cache_area
      }, "obtain");

      storage.obtain({
        save_path: result.save_path,
        crypto_method: result.crypto_method,
        key: result.key,
        cache_area: req.params.cache_area
      }, (err, path) => {
        res.send({uuid: req.params.uuid, path: path, type: result.type, filename: result.filename});
        return next();
      });
    }
  );
};

files.getList = (req, res, next) => {
  moray.query({
    ret:["uuid", "filename", "type", "size", "visibility", "uploaded_by", "last_modify"],
    cond:req.params},
    (error, results) => {
      req.log.info(results.rows, "查询结果：");
      if (error) {
        req.log.error(error, "查询时：");
        return next(error);
      }
      res.send(results.rows);
      return next();
    }
  );
};<|endoftext|>


<commit_before>'use strict';

describeComponent('lib/flight-orientation', function () {

  // Initialize the component and attach it to the DOM
  beforeEach(function () {
    setupComponent();
  });

  it('should be defined', function () {
    expect(this.component).toBeDefined();
  });

  it('should do something', function () {
    expect(true).toBe(false);
  });

});
<commit_msg>Removing failing scaffold test<commit_after>'use strict';

describeComponent('lib/flight-orientation', function () {

  // Initialize the component and attach it to the DOM
  beforeEach(function () {
    setupComponent();
  });

  it('should be defined', function () {
    expect(this.component).toBeDefined();
  });

});
<|endoftext|>


<commit_before>devise.define(['jquery'], function($) {

    var nodeHeight = 82;

    /**
     * We need to set the nodeHeight to calculate
     * offsets.
     */
    function setNodeHeight(nodesView)
    {
        nodeHeight = nodesView.children().first().children('.dvs-node-inner-wrapper').height();
    }

    /**
     * This calculates the node positions for all
     * the nodes inside of the nodesData
     */
    function calculateNodePositions(nodesView, nodesData)
    {
        nodesView.children().each(function(index, child)
        {
            var cid = $(child).data('node-cid');
            var node = nodesData[cid];
            var body = nodesView.closest('body');

            // groups have nested nodes inside of them
            if (node.binding === 'group')
            {
                for (var i = 0; i < node.data.length; i++)
                {
                    var current = node.data[i];
                    current.position = getCoordinatesForNode(current.key, current.cid, body);
                }
            }

            node.position = (node.binding === 'group')
                ? getCoordinatesForGroupNode(node, body)
                : getCoordinatesForNode(node.key, node.cid, body);

            node.position.side = getSideForNode(node.position);
        });
    }

    /**
     * This adjusts the nodes in the DOM
     * to their new positions
     */
    function adjustNodeDOMPositions(nodesView, nodesData)
    {
        nodesView.children().each(function(index, child)
        {
            var el = $(child);
            var cid = el.data('node-cid');
            var node = nodesData[cid];

            el.css('top', node.position.top);
            el.removeClass('left right');
            el.addClass(node.position.side);
        });
    }

    /**
     * Get the coordinates for a cid or key inside this view
     */
    function getCoordinatesForNode(key, cid, view)
    {
        var hidden, coordinates;
        var placeholder = view.find('[data-dvs-placeholder="' + key + '"]').last();
        var element = view.find('[data-devise-' + cid + ']').first();

        if (element.length)
        {
            hidden = !element.is(':visible');

            if (hidden) element.show();
            coordinates = element.offset();
            if (hidden) element.hide();

            if (typeof coordinates === 'object' && coordinates.top) return coordinates;
            return getCoordinatesFromParent(element);
        }

        placeholder.show();
        coordinates = placeholder.offset();
        placeholder.hide();

        // if (typeof coordinates === 'object' && coordinates.top) return coordinates;

        return getCoordinatesFromParent(placeholder);
    }

    /**
     * finds the first node in the group with a position
     */
    function getCoordinatesForGroupNode(groupNode, view)
    {
        var position = false;

        $.each(groupNode.data.categories, function(index, category)
        {
            for (var i = 0; i < category.nodes.length; i++)
            {
                var node = category.nodes[i];
                var nodePosition = getCoordinatesForNode(node.key, node.cid, view);
                if (!position) position = nodePosition;
            }
        });

        return position;
    }

    /**
     * Pick left or right side for this node
     */
    function getSideForNode(coordinates)
    {
        var half = $(window).width() / 2;

        if (typeof coordinates == 'undefined') return 'float';

        if (coordinates.left > half) return 'right';

        return 'left';
    }

    /**
     * This makes sure that no two nodes touch each other
     */
    function solveNodeCollisions(nodesView, nodesData)
    {
        var nodes = nodesData;

        var view = nodesView.closest('body');

        for (var i = 0; i < nodes.length; i++)
        {
            for (var j = 0; j < nodes.length; j++)
            {
                if (i != j && hasNodeCollision(nodes[i], nodes[j]))
                {
                    nodes[j].position.top += nodeHeight;
                }
            }
        }
    }

    /**
     * Figures out if we have a node collision
     */
    function hasNodeCollision(node1, node2)
    {
        if (node1.position.side != node2.position.side) return false;

        return Math.abs(node1.position.top - node2.position.top) < nodeHeight;
    }

    /**
     * Get the coordinates from the parent of this view,
     * sometimes stuff is nested in some deep DOM tree
     * and that stuff is hidden... so hidden elements we
     * cannot get coordinates for because it is hidden.
     * we could try unhiding it but that would give us
     * some flashy stuff on the page...
     */
    function getCoordinatesFromParent(placeholder)
    {
        var sanity = 50;
        var child = placeholder;
        var parent = placeholder.parent();
        var coordinates;

        while (child !== parent && sanity--)
        {
            coordinates = parent.offset();
            if (typeof coordinates === 'object' && coordinates.top) return coordinates;
            child = parent;
            parent = child.parent();
        }

        return { top: 0, left: 0 };
    }

    /**
     * recalculates node positions
     */
    return {
    	recalculateNodePositions: function(nodesView, nodesData)
    	{
            setNodeHeight(nodesView);
            calculateNodePositions(nodesView, nodesData);
            solveNodeCollisions(nodesView, nodesData);
            adjustNodeDOMPositions(nodesView, nodesData);

    	}
	};

});<commit_msg>Arrow positions tweaked<commit_after>devise.define(['jquery'], function($) {

    var nodeHeight = 40;

    /**
     * We need to set the nodeHeight to calculate
     * offsets.
     */
    function setNodeHeight(nodesView)
    {
        nodeHeight = nodesView.children().first().children('.dvs-node-inner-wrapper').height();
    }

    /**
     * This calculates the node positions for all
     * the nodes inside of the nodesData
     */
    function calculateNodePositions(nodesView, nodesData)
    {
        nodesView.children().each(function(index, child)
        {
            var cid = $(child).data('node-cid');
            var node = nodesData[cid];
            var body = nodesView.closest('body');

            // groups have nested nodes inside of them
            if (node.binding === 'group')
            {
                for (var i = 0; i < node.data.length; i++)
                {
                    var current = node.data[i];
                    current.position = getCoordinatesForNode(current.key, current.cid, body);
                }
            }

            node.position = (node.binding === 'group')
                ? getCoordinatesForGroupNode(node, body)
                : getCoordinatesForNode(node.key, node.cid, body);

            node.position.side = getSideForNode(node.position);
        });
    }

    /**
     * This adjusts the nodes in the DOM
     * to their new positions
     */
    function adjustNodeDOMPositions(nodesView, nodesData)
    {
        nodesView.children().each(function(index, child)
        {
            var el = $(child);
            var cid = el.data('node-cid');
            var node = nodesData[cid];

            el.css('top', node.position.top);
            el.removeClass('left right');
            el.addClass(node.position.side);
        });
    }

    /**
     * Get the coordinates for a cid or key inside this view
     */
    function getCoordinatesForNode(key, cid, view)
    {
        var hidden, coordinates;
        var placeholder = view.find('[data-dvs-placeholder="' + key + '"]').last();
        var element = view.find('[data-devise-' + cid + ']').first();

        if (element.length)
        {
            hidden = !element.is(':visible');

            if (hidden) element.show();
            coordinates = element.offset();
            if (hidden) element.hide();

            if (typeof coordinates === 'object' && coordinates.top) return coordinates;
            return getCoordinatesFromParent(element);
        }

        placeholder.show();
        coordinates = placeholder.offset();
        placeholder.hide();

        // if (typeof coordinates === 'object' && coordinates.top) return coordinates;

        return getCoordinatesFromParent(placeholder);
    }

    /**
     * finds the first node in the group with a position
     */
    function getCoordinatesForGroupNode(groupNode, view)
    {
        var position = false;

        $.each(groupNode.data.categories, function(index, category)
        {
            for (var i = 0; i < category.nodes.length; i++)
            {
                var node = category.nodes[i];
                var nodePosition = getCoordinatesForNode(node.key, node.cid, view);
                if (!position) position = nodePosition;
            }
        });

        return position;
    }

    /**
     * Pick left or right side for this node
     */
    function getSideForNode(coordinates)
    {
        var half = $(window).width() / 2;

        if (typeof coordinates == 'undefined') return 'float';

        if (coordinates.left > half) return 'right';

        return 'left';
    }

    /**
     * This makes sure that no two nodes touch each other
     */
    function solveNodeCollisions(nodesView, nodesData)
    {
        var nodes = nodesData;

        var view = nodesView.closest('body');

        for (var i = 0; i < nodes.length; i++)
        {
            for (var j = 0; j < nodes.length; j++)
            {
                if (i != j && hasNodeCollision(nodes[i], nodes[j]))
                {
                    nodes[i].position.top += nodeHeight;
                }
            }
        }
    }

    /**
     * Figures out if we have a node collision
     */
    function hasNodeCollision(node1, node2)
    {
        if (node1.position.side != node2.position.side) return false;

        return Math.abs(node1.position.top - node2.position.top) < (nodeHeight);
    }

    /**
     * Get the coordinates from the parent of this view,
     * sometimes stuff is nested in some deep DOM tree
     * and that stuff is hidden... so hidden elements we
     * cannot get coordinates for because it is hidden.
     * we could try unhiding it but that would give us
     * some flashy stuff on the page...
     */
    function getCoordinatesFromParent(placeholder)
    {
        var sanity = 50;
        var child = placeholder;
        var parent = placeholder.parent();
        var coordinates;

        while (child !== parent && sanity--)
        {
            coordinates = parent.offset();
            if (typeof coordinates === 'object' && coordinates.top) return coordinates;
            child = parent;
            parent = child.parent();
        }

        return { top: 0, left: 0 };
    }

    /**
     * recalculates node positions
     */
    return {
    	recalculateNodePositions: function(nodesView, nodesData)
    	{
            setNodeHeight(nodesView);
            calculateNodePositions(nodesView, nodesData);
            solveNodeCollisions(nodesView, nodesData);
            adjustNodeDOMPositions(nodesView, nodesData);

    	}
	};

});<|endoftext|>


<commit_before>(function($) {
    var debug = 1;

	// Convienence function that won't hang IE.
	function log() {
	    if (window.console && debug) {
	       if (arguments.length == 1) console.log (arguments[0]);
	       else console.log(arguments);
	    }
	};
	// class: $.jqplot.LogAxisRenderer
	// A plugin for a jqPlot to render a logarithmic axis.
    $.jqplot.LogAxisRenderer = function() {
        // prop: seriesDefaults
        // Default properties which will be applied directly to the series.
        // Properties
        /// base - the logarithmic base, commonly 2, 10 or Math.E
        // tickDistribution - 'even' or 'power'.  'even' gives equal pixel
        // spacing of the ticks on the plot.  'power' gives ticks in powers
        // of 10.
        this.seriesDefaults = {
            base : 10,
            tickDistribution :'even'
        };
    };

    $.jqplot.LogAxisRenderer.prototype.init = function(options) {
        $.extend(true, this.renderer, options);
        for (var d in this.renderer.seriesDefaults) {
            if (this[d] == null) this[d] = this.renderer.seriesDefaults[d];
        }
    };

    $.jqplot.LogAxisRenderer.prototype.draw = function() {
        if (this.show) {
            // populate the axis label and value properties.
            this.renderer.createTicks.call(this);
            // fill a div with axes labels in the right direction.
            // Need to pregenerate each axis to get it's bounds and
            // position it and the labels correctly on the plot.
            var dim=0;
            var temp;

            this._elem = $('

');
            //for (var s in axis.style) $(axis._elem).css(s, axis.style[s]);

            if (this.showTicks) {
                var t = this._ticks;
                for (var i=0; i<t.length; i++) {
                    var tick = t[i];
                    if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                        var elem = tick.draw();
                        //var elem = $(frag).appendTo(axis._elem).get(0);
                        elem.appendTo(this._elem);
                    }
                }
            }
        }
        return this._elem;
    };

    $.jqplot.LogAxisRenderer.prototype.set = function() {
        var dim = 0;
        var temp;
        if (this.show && this.showTicks) {
            var t = this._ticks;
            for (var i=0; i<t.length; i++) {
                var tick = t[i];
                if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                    if (this.name == 'xaxis' || this.name == 'x2axis') {
                        temp = tick._elem.outerHeight(true);
                    }
                    else {
                        temp = tick._elem.outerWidth(true);
                    }
                    if (temp > dim) dim = temp;
                }
            }
            if (this.name == 'xaxis') this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
            else if (this.name == 'x2axis') this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
            else if (this.name == 'yaxis') this._elem.css({'width':dim+'px', left:'0px', top:'0px'});
            else if (this.name == 'y2axis') this._elem.css({'width':dim+'px', right:'0px', top:'0px'});
        }
    };

    $.jqplot.LogAxisRenderer.prototype.createTicks = function() {
        // we're are operating on an axis here
        var ticks = this._ticks;
        var name = this.name;
        var db = this._dataBounds;
        var dim, interval;
        var min, max;
        var pos1, pos2;
        var tt, i;

        //////////////////
        // fix me
        /////////////////
        // if we already have ticks, use them.
        // ticks must be in order of increasing value.
        if (ticks.length) {
            // for (i=0; i<ticks.length; i++){
            //     var t = ticks[i];
            //     if (!t.label) t.label = t.value.toString();
            //     // set iitial css positioning styles for the ticks.
            //     var pox = i*15+'px';
            //     switch (name) {
            //         case 'xaxis':
            //             t._styles = {position:'absolute', top:'0px', left:pox, paddingTop:'10px'};
            //             break;
            //         case 'x2axis':
            //             t._styles = {position:'absolute', bottom:'0px', left:pox, paddingBottom:'10px'};
            //             break;
            //         case 'yaxis':
            //             t._styles = {position:'absolute', right:'0px', top:pox, paddingRight:'10px'};
            //             break;
            //         case 'y2axis':
            //             t._styles = {position:'absolute', left:'0px', top:pox, paddingLeft:'10px'};
            //             break;
            //     }
            // }
            // this.numberTicks = ticks.length;
            // this.min = ticks[0].value;
            // this.max = ticks[this.numberTicks-1].value;
            // this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
        }

        // we don't have any ticks yet, let's make some!
        else {
            if (name == 'xaxis' || name == 'x2axis') {
                dim = this._plotDimensions.width;
            }
            else {
                dim = this._plotDimensions.height;
            }

            min = ((this.min != null) ? this.min : db.min);
            max = ((this.max != null) ? this.max : db.max);
            // perform some checks
            if (this.min != null && this.min <= 0) throw('log axis minimum must be greater than 0');
            if (this.max != null && this.max <= 0) throw('log axis maximum must be greater than 0');
            // if (this.pad >1.99) this.pad = 1.99;
            var range = max - min;
            var rmin, rmax;

            if (this.tickDistribution == 'even') {
                // for log axes, open up range to get a nice power of axis.renderer.base.
                rmin = min - min*((this.pad-1)/2);
                rmax = max + max*((this.pad-1)/2);
                this.min = rmin;
                this.max = rmax;
                range = this.max - this.min;

                if (this.numberTicks == null){
                    if (dim > 100) {
                        this.numberTicks = parseInt(3+(dim-100)/75);
                    }
                    else {
                        this.numberTicks = 2;
                    }
                }

                var u = Math.pow(this.base, (1/(this.numberTicks-1)*Math.log(this.max/this.min)/Math.log(this.base)));
                for (var i=0; i<this.numberTicks; i++){
                    tt = this.min * Math.pow(u, i);
                    var t = new this.tickRenderer(this.tickOptions);
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) t.showMark = false;
                    t.setTick(tt, this.name);
                    this._ticks.push(t);
                }

            }

            else if (this.tickDistribution == 'power'){

                // for log axes, open up range to get a nice power of axis.renderer.base.
                rmin = Math.pow(this.base, Math.ceil(Math.log(min*(2-this.pad))/Math.log(this.base))-1);
                rmax = Math.pow(this.base, Math.floor(Math.log(max*this.pad)/Math.log(this.base))+1);
                this.min = rmin;
                this.max = rmax;
                range = this.max - this.min;

                var fittedTicks = 0;
                var minorTicks = 0;
                if (this.numberTicks == null){
                    if (dim > 100) {
                        this.numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
                        if (this.numberTicks < 2) this.numberTicks = 2;
                        fittedTicks = parseInt(3+(dim-100)/75);
                    }
                    else {
                        this.numberTicks = 2;
                        fittedTicks = 2;
                    }
                    // if we don't have enough ticks, add some intermediate ticks
                    // how many to have between major ticks.
                    if (this.numberTicks < fittedTicks-1) {
                        minorTicks = Math.floor(fittedTicks/this.numberTicks);
                    }
                }

                for (var i=0; i<this.numberTicks; i++){
                    tt = Math.pow(this.base, i - this.numberTicks + 1) * this.max;
                    var t = new this.tickRenderer(this.tickOptions);
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) t.showMark = false;
                    t.setTick(tt, this.name);
                    this._ticks.push(t);

                    if (minorTicks && i<this.numberTicks-1) {
                        var tt1 = Math.pow(this.base, i - this.numberTicks + 2) * this.max;
                        var spread = tt1 - tt;
                        var interval = tt1 / (minorTicks+1);
                        for (var j=minorTicks-1; j>=0; j--) {
                            var val = tt1-interval*(j+1);
                            var t = new this.tickRenderer(this.tickOptions);
                            if (!this.showTicks) {
                                t.showLabel = false;
                                t.showMark = false;
                            }
                            else if (!this.showTickMarks) t.showMark = false;
                            t.setTick(val, this.name);
                            this._ticks.push(t);
                        }
                    }
                }
            }
        }
    };

    $.jqplot.LogAxisRenderer.prototype.pack = function(pos, offsets) {
        var lb = parseInt(this.base);
        var ticks = this._ticks;
        var trans = function (v) { return Math.log(v)/Math.log(lb); };
        max = trans(this.max);
        min = trans(this.min);
        var offmax = offsets.max;
        var offmin = offsets.min;

        for (var p in pos) {
            this._elem.css(p, pos[p]);
        }

        this._offsets = offsets;
        // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
        var pixellength = offmax - offmin;
        var unitlength = max - min;

        // point to unit and unit to point conversions references to Plot DOM element top left corner.
        this.p2u = function(p){
            return (p - offmin) * unitlength / pixellength + min;
        };

        this.u2p = function(u){
            return (trans(u) - min) * pixellength / unitlength + offmin;
        };

        // point to unit and unit to point conversions references to Grid DOM element top left corner.
        this.series_p2u = function(p){
            return p * unitlength / pixellength + min;
        };

        if (this.name == 'xaxis' || this.name == 'x2axis'){
            this.series_u2p = function(u){
                return (trans(u) - min) * pixellength / unitlength;
            };
        }
        // yaxis is max at top of canvas.
        else {
            this.series_u2p = function(u){
                return (trans(u) - max) * pixellength / unitlength;
            };
        }

        if (this.show) {
            if (this.name == 'xaxis' || this.name == 'x2axis') {
                for (i=0; i<ticks.length; i++) {
                    var t = ticks[i];
                    var shim = t.getWidth()/2;
                    var val = this.u2p(t.value) - shim + 'px';
                    t._elem.css('left', val);
                }
            }
            else {
                for (i=0; i<ticks.length; i++) {
                    var t = ticks[i];
                    var shim = t.getHeight()/2;
                    var val = this.u2p(t.value) - shim + 'px';
                    t._elem.css('top', val);
                }
            }
        }
    };
})(jQuery);<commit_msg>minor documentation mod.<commit_after>(function($) {
    var debug = 1;

	// Convienence function that won't hang IE.
	function log() {
	    if (window.console && debug) {
	       if (arguments.length == 1) console.log (arguments[0]);
	       else console.log(arguments);
	    }
	};
	// class: $.jqplot.LogAxisRenderer
	// A plugin for a jqPlot to render a logarithmic axis.
    $.jqplot.LogAxisRenderer = function() {
        // prop: seriesDefaults
        // Default properties which will be applied directly to the series.
        //
        // Group: Properties
        //
        // Properties
        /// base - the logarithmic base, commonly 2, 10 or Math.E
        // tickDistribution - 'even' or 'power'.  'even' gives equal pixel
        // spacing of the ticks on the plot.  'power' gives ticks in powers
        // of 10.
        this.seriesDefaults = {
            base : 10,
            tickDistribution :'even'
        };
    };

    $.jqplot.LogAxisRenderer.prototype.init = function(options) {
        $.extend(true, this.renderer, options);
        for (var d in this.renderer.seriesDefaults) {
            if (this[d] == null) this[d] = this.renderer.seriesDefaults[d];
        }
    };

    $.jqplot.LogAxisRenderer.prototype.draw = function() {
        if (this.show) {
            // populate the axis label and value properties.
            this.renderer.createTicks.call(this);
            // fill a div with axes labels in the right direction.
            // Need to pregenerate each axis to get it's bounds and
            // position it and the labels correctly on the plot.
            var dim=0;
            var temp;

            this._elem = $('

');
            //for (var s in axis.style) $(axis._elem).css(s, axis.style[s]);

            if (this.showTicks) {
                var t = this._ticks;
                for (var i=0; i<t.length; i++) {
                    var tick = t[i];
                    if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                        var elem = tick.draw();
                        //var elem = $(frag).appendTo(axis._elem).get(0);
                        elem.appendTo(this._elem);
                    }
                }
            }
        }
        return this._elem;
    };

    $.jqplot.LogAxisRenderer.prototype.set = function() {
        var dim = 0;
        var temp;
        if (this.show && this.showTicks) {
            var t = this._ticks;
            for (var i=0; i<t.length; i++) {
                var tick = t[i];
                if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                    if (this.name == 'xaxis' || this.name == 'x2axis') {
                        temp = tick._elem.outerHeight(true);
                    }
                    else {
                        temp = tick._elem.outerWidth(true);
                    }
                    if (temp > dim) dim = temp;
                }
            }
            if (this.name == 'xaxis') this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
            else if (this.name == 'x2axis') this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
            else if (this.name == 'yaxis') this._elem.css({'width':dim+'px', left:'0px', top:'0px'});
            else if (this.name == 'y2axis') this._elem.css({'width':dim+'px', right:'0px', top:'0px'});
        }
    };

    $.jqplot.LogAxisRenderer.prototype.createTicks = function() {
        // we're are operating on an axis here
        var ticks = this._ticks;
        var name = this.name;
        var db = this._dataBounds;
        var dim, interval;
        var min, max;
        var pos1, pos2;
        var tt, i;

        //////////////////
        // fix me
        /////////////////
        // if we already have ticks, use them.
        // ticks must be in order of increasing value.
        if (ticks.length) {
            // for (i=0; i<ticks.length; i++){
            //     var t = ticks[i];
            //     if (!t.label) t.label = t.value.toString();
            //     // set iitial css positioning styles for the ticks.
            //     var pox = i*15+'px';
            //     switch (name) {
            //         case 'xaxis':
            //             t._styles = {position:'absolute', top:'0px', left:pox, paddingTop:'10px'};
            //             break;
            //         case 'x2axis':
            //             t._styles = {position:'absolute', bottom:'0px', left:pox, paddingBottom:'10px'};
            //             break;
            //         case 'yaxis':
            //             t._styles = {position:'absolute', right:'0px', top:pox, paddingRight:'10px'};
            //             break;
            //         case 'y2axis':
            //             t._styles = {position:'absolute', left:'0px', top:pox, paddingLeft:'10px'};
            //             break;
            //     }
            // }
            // this.numberTicks = ticks.length;
            // this.min = ticks[0].value;
            // this.max = ticks[this.numberTicks-1].value;
            // this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
        }

        // we don't have any ticks yet, let's make some!
        else {
            if (name == 'xaxis' || name == 'x2axis') {
                dim = this._plotDimensions.width;
            }
            else {
                dim = this._plotDimensions.height;
            }

            min = ((this.min != null) ? this.min : db.min);
            max = ((this.max != null) ? this.max : db.max);
            // perform some checks
            if (this.min != null && this.min <= 0) throw('log axis minimum must be greater than 0');
            if (this.max != null && this.max <= 0) throw('log axis maximum must be greater than 0');
            // if (this.pad >1.99) this.pad = 1.99;
            var range = max - min;
            var rmin, rmax;

            if (this.tickDistribution == 'even') {
                // for log axes, open up range to get a nice power of axis.renderer.base.
                rmin = min - min*((this.pad-1)/2);
                rmax = max + max*((this.pad-1)/2);
                this.min = rmin;
                this.max = rmax;
                range = this.max - this.min;

                if (this.numberTicks == null){
                    if (dim > 100) {
                        this.numberTicks = parseInt(3+(dim-100)/75);
                    }
                    else {
                        this.numberTicks = 2;
                    }
                }

                var u = Math.pow(this.base, (1/(this.numberTicks-1)*Math.log(this.max/this.min)/Math.log(this.base)));
                for (var i=0; i<this.numberTicks; i++){
                    tt = this.min * Math.pow(u, i);
                    var t = new this.tickRenderer(this.tickOptions);
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) t.showMark = false;
                    t.setTick(tt, this.name);
                    this._ticks.push(t);
                }

            }

            else if (this.tickDistribution == 'power'){

                // for log axes, open up range to get a nice power of axis.renderer.base.
                rmin = Math.pow(this.base, Math.ceil(Math.log(min*(2-this.pad))/Math.log(this.base))-1);
                rmax = Math.pow(this.base, Math.floor(Math.log(max*this.pad)/Math.log(this.base))+1);
                this.min = rmin;
                this.max = rmax;
                range = this.max - this.min;

                var fittedTicks = 0;
                var minorTicks = 0;
                if (this.numberTicks == null){
                    if (dim > 100) {
                        this.numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
                        if (this.numberTicks < 2) this.numberTicks = 2;
                        fittedTicks = parseInt(3+(dim-100)/75);
                    }
                    else {
                        this.numberTicks = 2;
                        fittedTicks = 2;
                    }
                    // if we don't have enough ticks, add some intermediate ticks
                    // how many to have between major ticks.
                    if (this.numberTicks < fittedTicks-1) {
                        minorTicks = Math.floor(fittedTicks/this.numberTicks);
                    }
                }

                for (var i=0; i<this.numberTicks; i++){
                    tt = Math.pow(this.base, i - this.numberTicks + 1) * this.max;
                    var t = new this.tickRenderer(this.tickOptions);
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) t.showMark = false;
                    t.setTick(tt, this.name);
                    this._ticks.push(t);

                    if (minorTicks && i<this.numberTicks-1) {
                        var tt1 = Math.pow(this.base, i - this.numberTicks + 2) * this.max;
                        var spread = tt1 - tt;
                        var interval = tt1 / (minorTicks+1);
                        for (var j=minorTicks-1; j>=0; j--) {
                            var val = tt1-interval*(j+1);
                            var t = new this.tickRenderer(this.tickOptions);
                            if (!this.showTicks) {
                                t.showLabel = false;
                                t.showMark = false;
                            }
                            else if (!this.showTickMarks) t.showMark = false;
                            t.setTick(val, this.name);
                            this._ticks.push(t);
                        }
                    }
                }
            }
        }
    };

    $.jqplot.LogAxisRenderer.prototype.pack = function(pos, offsets) {
        var lb = parseInt(this.base);
        var ticks = this._ticks;
        var trans = function (v) { return Math.log(v)/Math.log(lb); };
        max = trans(this.max);
        min = trans(this.min);
        var offmax = offsets.max;
        var offmin = offsets.min;

        for (var p in pos) {
            this._elem.css(p, pos[p]);
        }

        this._offsets = offsets;
        // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
        var pixellength = offmax - offmin;
        var unitlength = max - min;

        // point to unit and unit to point conversions references to Plot DOM element top left corner.
        this.p2u = function(p){
            return (p - offmin) * unitlength / pixellength + min;
        };

        this.u2p = function(u){
            return (trans(u) - min) * pixellength / unitlength + offmin;
        };

        // point to unit and unit to point conversions references to Grid DOM element top left corner.
        this.series_p2u = function(p){
            return p * unitlength / pixellength + min;
        };

        if (this.name == 'xaxis' || this.name == 'x2axis'){
            this.series_u2p = function(u){
                return (trans(u) - min) * pixellength / unitlength;
            };
        }
        // yaxis is max at top of canvas.
        else {
            this.series_u2p = function(u){
                return (trans(u) - max) * pixellength / unitlength;
            };
        }

        if (this.show) {
            if (this.name == 'xaxis' || this.name == 'x2axis') {
                for (i=0; i<ticks.length; i++) {
                    var t = ticks[i];
                    var shim = t.getWidth()/2;
                    var val = this.u2p(t.value) - shim + 'px';
                    t._elem.css('left', val);
                }
            }
            else {
                for (i=0; i<ticks.length; i++) {
                    var t = ticks[i];
                    var shim = t.getHeight()/2;
                    var val = this.u2p(t.value) - shim + 'px';
                    t._elem.css('top', val);
                }
            }
        }
    };
})(jQuery);<|endoftext|>


<commit_before>StandaloneDashboard (function (db) {
	var chart = new ChartComponent ();
	chart.setCaption ("Country wide sales");
	chart.setLabels (["Country A", "Country B", "Country C"]);
	chart.addSeries ("sales", "Sales", [10, 7, 11])
	db.addComponent(chart);

	chart.addDrillStep (function (done, params) {
	    alert ("Filtering states for country: " + params.label);
	    chart.setLabels (["State A", "State B"])
	    chart.addSeries ("sales", "Sales", [4, 3])

	    done (); // This is required
	});

	chart.addDrillStep (function (done, params) {
	    alert ("Filtering states for state: " + params.label);
	    chart.setLabels ([ "City A", "City B", "City C", "City D"])
	    chart.addSeries ("sales", "Sales", [3, 1, 4, 2])

	    done (); // This is required
	});
});<commit_msg>don't alert<commit_after>StandaloneDashboard (function (db) {
	var chart = new ChartComponent ();
	chart.setCaption ("Country wide sales");
	chart.setLabels (["Country A", "Country B", "Country C"]);
	chart.addSeries ("sales", "Sales", [10, 7, 11])
	db.addComponent(chart);

	chart.addDrillStep (function (done, params) {
	    chart.setLabels (["State A", "State B"])
	    chart.addSeries ("sales", "Sales", [4, 3])

	    done (); // This is required
	});

	chart.addDrillStep (function (done, params) {
	    chart.setLabels ([ "City A", "City B", "City C", "City D"])
	    chart.addSeries ("sales", "Sales", [3, 1, 4, 2])

	    done (); // This is required
	});
});<|endoftext|>