<!--
 Copyright (C) 2012 Google Inc. All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1.  Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
 2.  Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     its contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE html>
<html>
<head>
<style>
body {
    margin: 0;
    padding: 0;
}

body.platform-mac {
    font-size: 11px;
    font-family: Menlo, Monaco;
}

body.platform-windows {
    font-size: 12px;
    font-family: Consolas, Lucida Console;
}

body.platform-linux {
    font-size: 11px;
    font-family: dejavu sans mono;
}

.fill {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

.dimmed {
    background-color: rgba(0, 0, 0, 0.31);
}

#canvas {
    pointer-events: none;
}

.controls-line {
    display: flex;
    justify-content: center;
    margin: 10px 0;
}

.message-box {
    padding: 2px 4px;
    display: flex;
    align-items: center;
    cursor: default;
    overflow: hidden;
}

#paused-in-debugger {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

#reloading-blanket {
    background-color: rgb(255, 255, 255);
}

.controls-line > * {
    background-color: rgb(255, 255, 194);
    border: 1px solid rgb(202, 202, 202);
    height: 22px;
    box-sizing: border-box;
}

.controls-line .button {
    width: 26px;
    margin-left: -1px;
    margin-right: 0;
    padding: 0;
    flex-shrink: 0;
    flex-grow: 0;
}

.controls-line .button:hover {
    cursor: pointer;
}

.controls-line .button .glyph {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.75);
    opacity: 0.8;
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    position: relative;
}

.controls-line .button:active .glyph {
    top: 1px;
    left: 1px;
}

#resume-button .glyph {
    -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAKCAYAAABv7tTEAAAAAXNSR0IArs4c6QAAAFJJREFUKM+10bEJgGAMBeEPbR3BLRzEVdzEVRzELRzBVohVwEJ+iODBlQfhBeJhsmHU4C0KnFjQV6J0x1SNAhdWDJUoPTB3PvLLeaUhypM3n3sD/qc7lDrdpIEAAAAASUVORK5CYII=);
    -webkit-mask-size: 13px 10px;
    background-color: rgb(66, 129, 235);
}

#step-over-button .glyph {
    -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAYAAAC5Sw6hAAAAAXNSR0IArs4c6QAAAOFJREFUKM+N0j8rhXEUB/DPcxW35CqhvIBrtqibkklhV8qkTHe4ZbdblcXgPVhuMdqUTUl5A2KRRCF5LGc4PT1P7qnfcr5/zu/8KdTHLFaxjHnc4RZXKI0QYxjgLQTVd42l/0wmg5iFX3iq5H6w22RS4DyRH7CB8cAXcBTGJT6xUmd0mEwuMdFQcA3fwXvGTAan8BrgPabTL9fRRyfx91PRMwyjGwcJ2EyCfsrfpPw2Pipz24NT/MZciiQYVshzOKnZ5Hturxt3k2MnCpS4SPkeHpPR8Sh3tYgttBoW9II2/AHiaEqvD2Fc0wAAAABJRU5ErkJggg==);
    -webkit-mask-size: 18px 10px;
}

.px {
    color: rgb(128, 128, 128);
}

#element-title {
    position: absolute;
    z-index: 10;
}

#tag-name {
    /* Keep this in sync with view-source.css (.html-tag) */
    color: rgb(136, 18, 128);
}

#node-id {
    /* Keep this in sync with view-source.css (.html-attribute-value) */
    color: rgb(26, 26, 166);
}

#class-name {
    /* Keep this in sync with view-source.css (.html-attribute-name) */
    color: rgb(153, 69, 0);
}

/* Material */
.hidden {
    display: none !important;
}

.tooltip-content,
.material-tooltip-arrow {
    position: absolute;
    z-index: 10;
    -webkit-user-select: none;
}

.tooltip-content {
    background-color: #333740;
    font-size: 11px;
    line-height: 14px;
    padding: 5px 8px;
    border-radius: 3px;
    color: white;
    box-sizing: border-box;
    max-width: calc(100% - 4px);
    border: 1px solid hsla(0, 0%, 100%, 0.3);
    z-index: 1;
    background-clip: padding-box;
    will-change: transform;
    text-rendering: optimizeLegibility;
    pointer-events: none;
}

.element-info {
    display: flex;
    align-content: stretch;
}

.material-tooltip-arrow {
    border: solid;
    border-color: #333740 transparent;
    border-width: 0 8px 8px 8px;
    z-index: 2;
    margin-top: 1px;
}

.material-tooltip-arrow.tooltip-arrow-top {
    border-width: 8px 8px 0 8px;
    margin-top: -1px;
}

.element-description {
    flex: 1 1;
    word-wrap: break-word;
    word-break: break-all;
}

.dimensions {
    border-left: 1px solid hsl(0, 0%, 50%);
    padding-left: 7px;
    margin-left: 7px;
    float: right;
    flex: 0 0 auto;
    white-space: nowrap;
    display: flex;
    align-items: center;
    color: hsl(0, 0%, 85%);
}

.material-node-width {
    margin-right: 2px;
}

.material-node-height {
    margin-left: 2px;
}

.material-tag-name {
    color: hsl(304, 77%, 70%);
}

.material-node-id {
    color: hsl(27, 100%, 70%);
}

.material-class-name {
    color: hsl(202,92%,77%);
}

</style>
<script>
const lightGridColor = "rgba(0,0,0,0.2)";
const darkGridColor = "rgba(0,0,0,0.7)";
const transparentColor = "rgba(0, 0, 0, 0)";
const gridBackgroundColor = "rgba(255, 255, 255, 0.8)";

function drawPausedInDebuggerMessage(message)
{
    window._controlsVisible = true;
    document.querySelector(".controls-line").style.visibility = "visible";
    document.getElementById("paused-in-debugger").textContent = message;
    document.body.classList.add("dimmed");
}

function showReloadingBlanket()
{
    var element = document.getElementById("reloading-blanket");
    element.style.display = "block";
}

function _drawGrid(context, rulerAtRight, rulerAtBottom)
{
    if (window._gridPainted)
        return;
    window._gridPainted = true;

    context.save();

    var pageFactor = pageZoomFactor * pageScaleFactor;
    var scrollX = window.scrollX * pageScaleFactor;
    var scrollY = window.scrollY * pageScaleFactor;
    function zoom(x)
    {
        return Math.round(x * pageFactor);
    }
    function unzoom(x)
    {
        return Math.round(x / pageFactor);
    }

    var width = canvasWidth / pageFactor;
    var height = canvasHeight / pageFactor;

    const gridSubStep = 5;
    const gridStep = 50;

    {
        // Draw X grid background
        context.save();
        context.fillStyle = gridBackgroundColor;
        if (rulerAtBottom)
            context.fillRect(0, zoom(height) - 15, zoom(width), zoom(height));
        else
            context.fillRect(0, 0, zoom(width), 15);

        // Clip out backgrounds intersection
        context.globalCompositeOperation = "destination-out";
        context.fillStyle = "red";
        if (rulerAtRight)
            context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
        else
            context.fillRect(0, 0, 15, zoom(height));
        context.restore();

        // Draw Y grid background
        context.fillStyle = gridBackgroundColor;
        if (rulerAtRight)
            context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
        else
            context.fillRect(0, 0, 15, zoom(height));
    }

    context.lineWidth = 1;
    context.strokeStyle = darkGridColor;
    context.fillStyle = darkGridColor;
    {
        // Draw labels.
        context.save();
        context.translate(-scrollX, 0.5 - scrollY);
        var maxY = height + unzoom(scrollY);
        for (var y = 2 * gridStep; y < maxY; y += 2 * gridStep) {
            context.save();
            context.translate(scrollX, zoom(y));
            context.rotate(-Math.PI / 2);
            context.fillText(y, 2, rulerAtRight ? zoom(width) - 7 : 13);
            context.restore();
        }
        context.translate(0.5, -0.5);
        var maxX = width + unzoom(scrollX);
        for (var x = 2 * gridStep; x < maxX; x += 2 * gridStep) {
            context.save();
            context.fillText(x, zoom(x) + 2, rulerAtBottom ? scrollY + zoom(height) - 7 : scrollY + 13);
            context.restore();
        }
        context.restore();
    }

    {
        // Draw vertical grid
        context.save();
        if (rulerAtRight) {
            context.translate(zoom(width), 0);
            context.scale(-1, 1);
        }
        context.translate(-scrollX, 0.5 - scrollY);
        var maxY = height + unzoom(scrollY);
        for (var y = gridStep; y < maxY; y += gridStep) {
            context.beginPath();
            context.moveTo(scrollX, zoom(y));
            var markLength = (y % (gridStep * 2)) ? 5 : 8;
            context.lineTo(scrollX + markLength, zoom(y));
            context.stroke();
        }
        context.strokeStyle = lightGridColor;
        for (var y = gridSubStep; y < maxY; y += gridSubStep) {
            if (!(y % gridStep))
                continue;
            context.beginPath();
            context.moveTo(scrollX, zoom(y));
            context.lineTo(scrollX + gridSubStep, zoom(y));
            context.stroke();
        }
        context.restore();
    }

    {
        // Draw horizontal grid
        context.save();
        if (rulerAtBottom) {
            context.translate(0, zoom(height));
            context.scale(1, -1);
        }
        context.translate(0.5 - scrollX, -scrollY);
        var maxX = width + unzoom(scrollX);
        for (var x = gridStep; x < maxX; x += gridStep) {
            context.beginPath();
            context.moveTo(zoom(x), scrollY);
            var markLength = (x % (gridStep * 2)) ? 5 : 8;
            context.lineTo(zoom(x), scrollY + markLength);
            context.stroke();
        }
        context.strokeStyle = lightGridColor;
        for (var x = gridSubStep; x < maxX; x += gridSubStep) {
            if (!(x % gridStep))
                continue;
            context.beginPath();
            context.moveTo(zoom(x), scrollY);
            context.lineTo(zoom(x), scrollY + gridSubStep);
            context.stroke();
        }
        context.restore();
    }

    context.restore();
}

function drawViewSize()
{
    var text = viewportSize.width + "px \u00D7 " + viewportSize.height + "px";
    context.save();
    context.font = "20px ";
    switch (platform) {
    case "windows": context.font = "14px Consolas, Lucida Console"; break;
    case "mac": context.font = "14px Menlo, Monaco"; break;
    case "linux": context.font = "14px dejavu sans mono"; break;
    }

    var frameWidth = canvasWidth;
    var textWidth = context.measureText(text).width;
    context.fillStyle = gridBackgroundColor;
    context.fillRect(frameWidth - textWidth - 12, 0, frameWidth, 25);
    context.fillStyle = darkGridColor;
    context.fillText(text, frameWidth - textWidth - 6, 18);
    context.restore();
}

function resetCanvas(canvasElement)
{
    canvasElement.width = deviceScaleFactor * viewportSize.width;
    canvasElement.height = deviceScaleFactor * viewportSize.height;
    canvasElement.style.width = viewportSize.width + "px";
    canvasElement.style.height = viewportSize.height + "px";
    var context = canvasElement.getContext("2d");
    context.scale(deviceScaleFactor, deviceScaleFactor);
}

function reset(resetData)
{
    window.viewportSize = resetData.viewportSize;
    window.deviceScaleFactor = resetData.deviceScaleFactor;
    window.pageScaleFactor = resetData.pageScaleFactor;
    window.pageZoomFactor = resetData.pageZoomFactor;
    window.scrollX = Math.round(resetData.scrollX);
    window.scrollY = Math.round(resetData.scrollY);

    window.canvas = document.getElementById("canvas");
    window.context = canvas.getContext("2d");
    resetCanvas(canvas);

    window.canvasWidth = viewportSize.width;
    window.canvasHeight = viewportSize.height;

    window._controlsVisible = false;
    document.querySelector(".controls-line").style.visibility = "hidden";
    document.getElementById("element-title").style.visibility = "hidden";
    document.getElementById("reloading-blanket").style.display = "none";
    document.getElementById("tooltip-container").removeChildren();

    document.body.classList.remove("dimmed");

    window._gridPainted = false;
}

function _drawElementTitle(context, elementInfo, bounds)
{
    document.getElementById("tag-name").textContent = elementInfo.tagName;
    document.getElementById("node-id").textContent = elementInfo.idValue ? "#" + elementInfo.idValue : "";
    document.getElementById("class-name").textContent = (elementInfo.className || "").trimEnd(50);
    document.getElementById("node-width").textContent = elementInfo.nodeWidth;
    document.getElementById("node-height").textContent = elementInfo.nodeHeight;
    var elementTitle = document.getElementById("element-title");

    var titleWidth = elementTitle.offsetWidth + 6;
    var titleHeight = elementTitle.offsetHeight + 4;

    var anchorTop = bounds.minY;
    var anchorBottom = bounds.maxY;
    var anchorLeft = bounds.minX;

    const arrowHeight = 7;
    var renderArrowUp = false;
    var renderArrowDown = false;

    var boxX = Math.max(2, anchorLeft);
    if (boxX + titleWidth > canvasWidth)
        boxX = canvasWidth - titleWidth - 2;

    var boxY;
    if (anchorTop > canvasHeight) {
        boxY = canvasHeight - titleHeight - arrowHeight;
        renderArrowDown = true;
    } else if (anchorBottom < 0) {
        boxY = arrowHeight;
        renderArrowUp = true;
    } else if (anchorBottom + titleHeight + arrowHeight < canvasHeight) {
        boxY = anchorBottom + arrowHeight - 4;
        renderArrowUp = true;
    } else if (anchorTop - titleHeight - arrowHeight > 0) {
        boxY = anchorTop - titleHeight - arrowHeight + 3;
        renderArrowDown = true;
    } else
        boxY = arrowHeight;

    context.save();
    context.translate(0.5, 0.5);
    context.beginPath();
    context.moveTo(boxX, boxY);
    if (renderArrowUp) {
        context.lineTo(boxX + 2 * arrowHeight, boxY);
        context.lineTo(boxX + 3 * arrowHeight, boxY - arrowHeight);
        context.lineTo(boxX + 4 * arrowHeight, boxY);
    }
    context.lineTo(boxX + titleWidth, boxY);
    context.lineTo(boxX + titleWidth, boxY + titleHeight);
    if (renderArrowDown) {
        context.lineTo(boxX + 4 * arrowHeight, boxY + titleHeight);
        context.lineTo(boxX + 3 * arrowHeight, boxY + titleHeight + arrowHeight);
        context.lineTo(boxX + 2 * arrowHeight, boxY + titleHeight);
    }
    context.lineTo(boxX, boxY + titleHeight);
    context.closePath();
    context.fillStyle = "rgb(255, 255, 194)";
    context.fill();
    context.strokeStyle = "rgb(128, 128, 128)";
    context.stroke();

    context.restore();

    elementTitle.style.visibility = "visible";
    elementTitle.style.top = (boxY + 3) + "px";
    elementTitle.style.left = (boxX + 3) + "px";
}

function _createElementDescription(elementInfo)
{
    var elementInfoElement = createElement("div", "element-info");
    var descriptionElement = elementInfoElement.createChild("div", "element-description monospace");
    var tagNameElement = descriptionElement.createChild("b").createChild("span", "material-tag-name");
    tagNameElement.textContent = elementInfo.tagName;
    var nodeIdElement = descriptionElement.createChild("span", "material-node-id");
    nodeIdElement.textContent = elementInfo.idValue ? "#" + elementInfo.idValue : "";
    nodeIdElement.classList.toggle("hidden", !elementInfo.idValue);

    var classNameElement = descriptionElement.createChild("span", "material-class-name");
    classNameElement.textContent = (elementInfo.className || "").trim(50);
    classNameElement.classList.toggle("hidden", !elementInfo.className);
    var dimensionsElement = elementInfoElement.createChild("div", "dimensions");
    dimensionsElement.createChild("span", "material-node-width").textContent = Math.round(elementInfo.nodeWidth * 100) / 100;
    dimensionsElement.createTextChild("\u00d7");
    dimensionsElement.createChild("span", "material-node-height").textContent = Math.round(elementInfo.nodeHeight * 100) / 100;
    return elementInfoElement;
}

function _drawMaterialElementTitle(elementInfo, bounds)
{
    var tooltipContainer = document.getElementById("tooltip-container");
    tooltipContainer.removeChildren();
    _createMaterialTooltip(tooltipContainer, bounds, _createElementDescription(elementInfo), true);
}

function _createMaterialTooltip(parentElement, bounds, contentElement, withArrow)
{
    var tooltipContainer = parentElement.createChild("div");
    var tooltipContent = tooltipContainer.createChild("div", "tooltip-content");
    tooltipContent.appendChild(contentElement);

    var titleWidth = tooltipContent.offsetWidth;
    var titleHeight = tooltipContent.offsetHeight;
    var arrowRadius = 8;
    var pageMargin = 2;

    var boxX = Math.min(bounds.minX, canvasWidth - titleWidth - pageMargin);

    var boxY = bounds.minY - arrowRadius - titleHeight;
    var onTop = true;
    if (boxY < 0) {
        boxY = Math.min(canvasHeight - titleHeight, bounds.maxY + arrowRadius);
        onTop = false;
    } else if (bounds.minY > canvasHeight) {
        boxY = canvasHeight - arrowRadius - titleHeight;
    }

    tooltipContent.style.top = boxY + "px";
    tooltipContent.style.left = boxX + "px";
    if (!withArrow)
        return;

    var tooltipArrow = tooltipContainer.createChild("div", "material-tooltip-arrow");
    // Left align arrow to the tooltip but ensure it is pointing to the element.
    var tooltipBorderRadius = 2;
    var arrowX = boxX + arrowRadius + tooltipBorderRadius;
    if (arrowX < bounds.minX)
        arrowX = bounds.minX + arrowRadius;
    // Hide arrow if element is completely off the sides of the page.
    var arrowHidden = arrowX < pageMargin + tooltipBorderRadius || arrowX + arrowRadius * 2 > canvasWidth - pageMargin - tooltipBorderRadius;
    tooltipArrow.classList.toggle("hidden", arrowHidden);
    if (!arrowHidden) {
        tooltipArrow.classList.toggle("tooltip-arrow-top", onTop);
        tooltipArrow.style.top = (onTop ? boxY + titleHeight : boxY - arrowRadius) + "px";
        tooltipArrow.style.left = arrowX + "px";
    }
}

function _drawRulers(context, bounds, rulerAtRight, rulerAtBottom)
{
    context.save();
    var width = canvasWidth;
    var height = canvasHeight;
    context.strokeStyle = "rgba(128, 128, 128, 0.3)";
    context.lineWidth = 1;
    context.translate(0.5, 0.5);

    if (rulerAtRight) {
        for (var y in bounds.rightmostXForY) {
            context.beginPath();
            context.moveTo(width, y);
            context.lineTo(bounds.rightmostXForY[y], y);
            context.stroke();
        }
    } else {
        for (var y in bounds.leftmostXForY) {
            context.beginPath();
            context.moveTo(0, y);
            context.lineTo(bounds.leftmostXForY[y], y);
            context.stroke();
        }
    }

    if (rulerAtBottom) {
        for (var x in bounds.bottommostYForX) {
            context.beginPath();
            context.moveTo(x, height);
            context.lineTo(x, bounds.topmostYForX[x]);
            context.stroke();
        }
    } else {
        for (var x in bounds.topmostYForX) {
            context.beginPath();
            context.moveTo(x, 0);
            context.lineTo(x, bounds.topmostYForX[x]);
            context.stroke();
        }
    }

    context.restore();
}

function drawPath(context, commands, fillColor, outlineColor, bounds)
{
    var commandsIndex = 0;

    function extractPoints(count)
    {
        var points = [];

        for (var i = 0; i < count; ++i) {
            var x = Math.round(commands[commandsIndex++]);
            bounds.maxX = Math.max(bounds.maxX, x);
            bounds.minX = Math.min(bounds.minX, x);

            var y = Math.round(commands[commandsIndex++]);
            bounds.maxY = Math.max(bounds.maxY, y);
            bounds.minY = Math.min(bounds.minY, y);

            bounds.leftmostXForY[y] = Math.min(bounds.leftmostXForY[y] || Number.MAX_VALUE, x);
            bounds.rightmostXForY[y] = Math.max(bounds.rightmostXForY[y] || Number.MIN_VALUE, x);
            bounds.topmostYForX[x] = Math.min(bounds.topmostYForX[x] || Number.MAX_VALUE, y);
            bounds.bottommostYForX[x] = Math.max(bounds.bottommostYForX[x] || Number.MIN_VALUE, y);
            points.push(x, y);
        }
        return points;
    }

    context.save();
    var commandsLength = commands.length;
    var path = new Path2D();
    while (commandsIndex < commandsLength) {
        switch (commands[commandsIndex++]) {
        case "M":
            path.moveTo.apply(path, extractPoints(1));
            break;
        case "L":
            path.lineTo.apply(path, extractPoints(1));
            break;
        case "C":
            path.bezierCurveTo.apply(path, extractPoints(3));
            break;
        case "Q":
            path.quadraticCurveTo.apply(path, extractPoints(2));
            break;
        case "Z":
            path.closePath();
            break;
        }
    }
    path.closePath();
    context.lineWidth = 0;
    context.fillStyle = fillColor;
    context.fill(path);

    if (outlineColor) {
        context.lineWidth = 2;
        context.strokeStyle = outlineColor;
        context.stroke(path);
    }

    context.restore();
    return path;
}

function emptyBounds()
{
    var bounds = {
        minX: Number.MAX_VALUE,
        minY: Number.MAX_VALUE,
        maxX: Number.MIN_VALUE,
        maxY: Number.MIN_VALUE,
        leftmostXForY: {},
        rightmostXForY: {},
        topmostYForX: {},
        bottommostYForX: {}
    };
    return bounds;
}

function _drawLayoutGridHighlight(highlight, context)
{
    var originX = highlight.columns.origin;
    var originY = highlight.rows.origin;

    var columnGap = highlight.columns.gap;
    var rowGap = highlight.rows.gap;

    var rows = highlight.rows.positions;
    var columns = highlight.columns.positions;

    if (!rows.length || !columns.length)
        return;

    context.save();
    context.translate(originX + 0.5, originY + 0.5);
    context.scale(pageScaleFactor, pageScaleFactor)

    if (columnGap > 1 && highlight.isPrimaryGrid) {
        var top = rows[0];
        var height = rows[rows.length - 1] - rows[0];
        for (var i = 1; i < columns.length - 1; i++)
            context.clearRect(columns[i] - columnGap, top, columnGap, height);
    }

    if (rowGap > 1 && highlight.isPrimaryGrid) {
        var left = columns[0];
        var width = columns[columns.length - 1] - columns[0];
        for (var i = 1; i < rows.length - 1; i++)
            context.clearRect(left, rows[i] - rowGap, width, rowGap);
    }

    context.setLineDash([3, 3]);
    context.strokeStyle = highlight.color;

    for (var column = 1; column < columns.length; column++) {
        var x = columns[column - 1];
        var width = columns[column] - columns[column - 1];
        if (column !== columns.length - 1)
            width -= columnGap;
        for (var row = 1; row < rows.length; row++) {
            var y = rows[row - 1];
            var height = rows[row] - rows[row - 1];
            if (row !== rows.length - 1)
                height -= rowGap;
            context.strokeRect(x, y, width, height);
        }
    }
    context.restore();
}

function drawHighlight(highlight, context)
{
    context = context || window.context;
    context.save();

    var bounds = emptyBounds();

    for (var paths = highlight.paths.slice(); paths.length;) {
        var path = paths.pop();
        drawPath(context, path.path, path.fillColor, path.outlineColor, bounds);
        if (paths.length) {
            context.save();
            context.globalCompositeOperation = "destination-out";
            drawPath(context, paths[paths.length - 1].path, "red", null, bounds);
            context.restore();
        }
    }

    var rulerAtRight = highlight.paths.length && highlight.showRulers && bounds.minX < 20 && bounds.maxX + 20 < canvasWidth;
    var rulerAtBottom = highlight.paths.length && highlight.showRulers && bounds.minY < 20 && bounds.maxY + 20 < canvasHeight;

    if (highlight.showRulers)
        _drawGrid(context, rulerAtRight, rulerAtBottom);

    if (highlight.paths.length) {
        if (highlight.showExtensionLines)
            _drawRulers(context, bounds, rulerAtRight, rulerAtBottom);

        if (highlight.elementInfo && highlight.displayAsMaterial)
           _drawMaterialElementTitle(highlight.elementInfo, bounds);
        else if (highlight.elementInfo)
           _drawElementTitle(context, highlight.elementInfo, bounds);
    }
    if (highlight.gridInfo) {
        for (var grid of highlight.gridInfo)
            _drawLayoutGridHighlight(grid, context);
    }
    context.restore();

    return { bounds: bounds };
}

function drawScreenshotBorder(rect)
{
    var context = window.context;
    context.save();
    context.fillStyle = "rgba(0, 0, 0, 0.2)";
    context.beginPath();
    context.moveTo(rect.x1 - 0.5, rect.y1 - 0.5);
    context.lineTo(rect.x1 - 0.5, rect.y2 + 0.5);
    context.lineTo(rect.x2 + 0.5, rect.y2 + 0.5);
    context.lineTo(rect.x2 + 0.5, rect.y1 - 0.5);
    context.lineTo(rect.x1 - 0.5, rect.y1 - 0.5);
    context.fill();
    context.strokeStyle = "rgba(255, 255, 255, 0.9)";
    context.lineWidth = 1;
    context.beginPath();
    context.moveTo(rect.x1 - 0.5, rect.y1 - 0.5);
    context.lineTo(rect.x1 - 0.5, rect.y2 + 0.5);
    context.lineTo(rect.x2 + 0.5, rect.y2 + 0.5);
    context.lineTo(rect.x2 + 0.5, rect.y1 - 0.5);
    context.lineTo(rect.x1 - 0.5, rect.y1 - 0.5);
    context.stroke();
    context.restore();
}

function setPlatform(platform)
{
    window.platform = platform;
    document.body.classList.add("platform-" + platform);
}

function dispatch(message)
{
    var functionName = message.shift();
    window[functionName].apply(null, message);
}

function log(text)
{
    document.getElementById("log").createChild("div").textContent = text;
}

function onResumeClick()
{
    InspectorOverlayHost.resume();
}

function onStepOverClick()
{
    InspectorOverlayHost.stepOver();
}

function onLoaded()
{
    document.getElementById("resume-button").addEventListener("click", onResumeClick);
    document.getElementById("step-over-button").addEventListener("click", onStepOverClick);
}

function eventHasCtrlOrMeta(event)
{
    return window.platform == "mac" ? (event.metaKey && !event.ctrlKey) : (event.ctrlKey && !event.metaKey);
}

function onDocumentKeyDown(event)
{
    if (!window._controlsVisible)
        return;
    if (event.key == "F8" || eventHasCtrlOrMeta(event) && event.keyCode == 220 /* backslash */)
        InspectorOverlayHost.resume();
    else if (event.key == "F10" || eventHasCtrlOrMeta(event) && event.keyCode == 222 /* single quote */)
        InspectorOverlayHost.stepOver();
}

Element.prototype.createChild = function(tagName, className)
{
    var element = createElement(tagName, className);
    element.addEventListener("click", function(e) { e.stopPropagation(); }, false);
    this.appendChild(element);
    return element;
}

Element.prototype.createTextChild = function(text)
{
    var element = document.createTextNode(text);
    this.appendChild(element);
    return element;
}

Element.prototype.removeChildren = function()
{
    if (this.firstChild)
        this.textContent = "";
}

function createElement(tagName, className)
{
    var element = document.createElement(tagName);
    if (className)
        element.className = className;
    return element;
}

String.prototype.trimEnd = function(maxLength)
{
    if (this.length <= maxLength)
        return String(this);
    return this.substr(0, maxLength - 1) + "\u2026";
}

window.addEventListener("DOMContentLoaded", onLoaded);
document.addEventListener("keydown", onDocumentKeyDown);
</script>
</head>
<body class="fill">
</body>
<canvas id="canvas" class="fill"></canvas>
<div id="element-title">
  <span id="tag-name"></span><span id="node-id"></span><span id="class-name"></span>
  <span id="node-width"></span><span class="px">px</span><span class="px"> &#xD7; </span><span id="node-height"></span><span class="px">px</span>
</div>
<div id="tooltip-container"></div>
<div id="reloading-blanket" class="fill" style="display: none"></div>
<div class="controls-line">
    <div class="message-box"><div id="paused-in-debugger"></div></div>
    <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div>
    <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div>
</div>
<div id="log"></div>
</html>
