<commit_before>/*jshint jquery: true, browser: true*/
/*global angular, d3*/

angular.module("insight", [])
    .config(["$interpolateProvider", function ($interpolateProvider) {
        "use strict";

        $interpolateProvider.startSymbol("[[");
        $interpolateProvider.endSymbol("]]");
    }]);

var INSIGHT = {
    height: 548,
    width: 900,
    smallPadding: 40,
    largePadding: 70,
    fontHeight: 14,
    fontWidth: 10,
    palette: [
        "#f89406",
        "#51A351",
        "#7D1935",
        "#4A96AD",
        "#DE1B1B",
        "#E9E581",
        "#A2AB58",
        "#FFE658",
        "#118C4E",
        "#193D4F"
    ]
};

function Insights($scope, $http) {
    "use strict";

    $scope.getOptions = function() {
        $scope.inputs = [];
        $scope.abscissa = null;
        $scope.vary_by = null;
        $scope.customInputs = {};
        $scope.currentOptions = {};

        var params = {"insight": $scope.selectedInsight.id};
        $http({method: "GET", url: "/cbmonitor/get_insight_options/", params: params})
        .success(function(data) {
            $scope.inputs = data;
            resetCharts();
        });
    };

    $scope.getData = function() {
        var params = {
            "insight": $scope.selectedInsight.id,
            "abscissa": $scope.abscissa,
            "inputs": JSON.stringify($scope.currentOptions)
        };
        if ($scope.vary_by !== null ) {
            params.vary_by = $scope.vary_by;
        }
        $http({method: "GET", url: "/cbmonitor/get_insight_data/", params: params})
        .success(function(data) {
            resetCharts();
            if ($.isEmptyObject(data)) {
                drawWarning();
            } else {
                drawScatterPlot(data, $scope.vary_by);
            }
        });
    };

    $scope.updateData = function(title, value, option) {
        if (value === "As X-axis") {
            if ($scope.abscissa !== null && $scope.abscissa !== title) {
                $scope.currentOptions[$scope.abscissa] = $scope.resetAbscissaTo;
            }
            $scope.abscissa = title;
            $scope.resetAbscissaTo = $scope.inputs[option.$index].options[0];
        } else if ($scope.abscissa === title) {
            $scope.abscissa = null;
        }

        if (value === "Vary by") {
            if ($scope.vary_by !== null && $scope.vary_by !== title) {
                $scope.currentOptions[$scope.vary_by] = $scope.resetVaryByTo;
            }
            $scope.vary_by = title;
            $scope.resetVaryByTo = $scope.inputs[option.$index].options[0];
        } else if ($scope.vary_by === title) {
            $scope.vary_by = null;
        }

        if ($scope.abscissa !== null) {
            $scope.getData();
        } else {
            resetCharts();
        }
    };

    $http.get("/cbmonitor/get_insight_defaults/").success(function(insights) {
        $scope.insights = insights;
        $scope.selectedInsight = insights[0];
        var query = window.location.search.split("=");
        for (var i=0, l=insights.length; i < l; i++) {
            if (insights[i].id === query[query.length - 1]) {
                $scope.selectedInsight = insights[i];
                break;
            }
        }
        $scope.getOptions();
    });
}

function drawBase() {
    "use strict";

    d3.select("#chart").append("svg").attr({
        height: INSIGHT.height, width: INSIGHT.width
    });

    d3.select("svg").append("rect").attr({
        height: INSIGHT.height, width: INSIGHT.width,
        rx: 5, ry: 5,
        fill: "white",
        stroke: "#cccccc"
    });
}

function addFocus(seqid) {
    "use strict";

    var focus = d3.select("svg").append("g")
                                .attr("class", "focus")
                                .style("display", "none");
    focus.append("text").attr({
        dx: "15px", dy: "25px",
        fill: INSIGHT.palette[seqid]
    });
    return focus;
}

function showFocus(focus, obj, yScale) {
    "use strict";

    var x = d3.mouse(obj)[0],
        y = d3.mouse(obj)[1],
        formatValue = d3.format(".1f"),
        value = formatValue(yScale.invert(y));
    focus
        .style("display", null)
        .attr("transform", "translate(" + x + "," + y + ")")
        .select("text").text(value);
}

function drawDataPoints(circles, xScale, yScale, seqid) {
    "use strict";

    var focus = addFocus(seqid);

    circles
        .append("circle")
        .on("mouseover", function() {
            showFocus(focus, this, yScale);
            d3.select(this).transition().duration(200)
                .attr({ r: 7 });
        })
        .on("mouseout", function() {
            focus.style("display", "none");
            d3.select(this).transition().duration(200)
                .attr({ r: 5 });
        })
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white", stroke: "white" });
        })
        .attr({
            cx: function(d) { return xScale(d[0]); },
            cy: function(d) { return yScale(d[1]); },
            r: 5,
            stroke: INSIGHT.palette[seqid], "stroke-width": 3
        });
}

function drawSplines(data, xScale, yScale, seqid) {
    "use strict";

    var line = d3.svg.line()
        .x(function(d) { return xScale(d[0]); })
        .y(function(d) { return yScale(d[1]); })
        .interpolate("cardinal");

    var focus = addFocus(seqid);

    d3.select("svg")
        .append("path")
        .on("mouseover", function() { showFocus(focus, this, yScale); })
        .on("mouseout", function() { focus.style("display", "none"); })
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ stroke: "white" });
        })
        .attr({
            "d": line(data),
            stroke: INSIGHT.palette[seqid], "stroke-width": 2,
            "fill-opacity": 0.0,
            "pointer-events": "stroke"
        });
}

function drawLines(lines, xScale, yScale) {
    "use strict";

    lines.append("line")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ stroke: "white" });
        })
        .attr({
            x1: function(d) { return xScale(d[0]); },
            y1: function(d) { return yScale(d[1]); },
            x2: function(d) { return xScale(d[2]); },
            y2: function(d) { return yScale(d[3]); },
            stroke: "#cccccc", "shape-rendering": "crispEdges"
        });
}

function drawAxes(xScale, yScale, xTickValues) {
    "use strict";

    var areaPadding = 10;

    var xAxis = d3.svg.axis()
                      .scale(xScale)
                      .orient("bottom")
                      .tickValues(xTickValues);

    d3.select("svg").append("g")
        .attr("class", "axis")
        .attr("transform", "translate(0, " + (INSIGHT.height - INSIGHT.smallPadding + areaPadding) + ")")
        .call(xAxis);

    var yAxis = d3.svg.axis()
                      .scale(yScale)
                      .orient("left")
                      .ticks(5);
    d3.select("svg").append("g")
        .attr("class", "axis")
        .attr("transform", "translate(" + (INSIGHT.largePadding - areaPadding) + ", 0)")
        .call(yAxis);
}

function drawLegendTitle(title) {
    "use strict";

    d3.select("svg").append("g").append("text")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white" });
        })
        .text(title + ":")
        .attr({
            x: INSIGHT.largePadding + 5,
            y: (INSIGHT.smallPadding + INSIGHT.fontHeight) / 2,
            "font-size": INSIGHT.fontHeight,
            fill: "black"
        });

}

function drawLegend(legend, legendPadding, legendInterval) {
    "use strict";

    legend.append("text")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white" });
        })
        .text(function(d) { return d; })
        .attr({
            x: function(d, i) { return INSIGHT.largePadding + legendPadding + i * legendInterval; },
            y: (INSIGHT.smallPadding + INSIGHT.fontHeight) / 2,
            "font-size": INSIGHT.fontHeight,
            "font-weight": "bold",
            fill: function(d, i) { return INSIGHT.palette[i]; }
        });
}

function drawWarning() {
    "use strict";

    d3.select("svg").append("text")
        .text("No data")
        .attr({
            x: INSIGHT.width / 2 - 50, y: INSIGHT.height / 2,
            class: "warning"
        });
}

function resetCharts() {
    "use strict";

    d3.selectAll("circle").remove();
    d3.selectAll("line").remove();
    d3.selectAll("g").remove();
    d3.selectAll("path").remove();
    d3.selectAll("text").remove();
}

function drawScatterPlot(data, vary_by) {
    "use strict";

    /******************************** MIN MAX *********************************/
    var xMin = Number.MAX_VALUE,
        xMax = Number.MIN_VALUE,
        yMax = Number.MIN_VALUE;

    Object.keys(data).forEach(function(key) {
        xMin = Math.min(xMin, d3.min(data[key], function(d) { return d[0]; }));
        xMax = Math.max(xMax, d3.max(data[key], function(d) { return d[0]; }));
        yMax = Math.max(yMax, d3.max(data[key], function(d) { return d[1]; }));

    });

    /********************************* SCALES *********************************/
    var yScale = d3.scale.linear()
                         .domain([0, yMax])
                         .range([INSIGHT.height - INSIGHT.smallPadding, INSIGHT.smallPadding]);
    var xScale;
    if (isNaN(xMin) || isNaN(xMax)) {
        xScale = d3.scale.ordinal()
                         .range([INSIGHT.largePadding, INSIGHT.width - INSIGHT.smallPadding]);
    } else {
        xScale = d3.scale.linear()
                         .domain([xMin, xMax])
                         .range([INSIGHT.largePadding, INSIGHT.width - INSIGHT.smallPadding]);
    }
    /********************************** TICKS *********************************/
    var yTickValues = yScale.ticks(5);
    var xTickValues = [];
    Object.keys(data).forEach(function(key) {
        for (var i=0, l=data[key].length; i < l; i++) {
            if (xTickValues.indexOf(data[key][i][0] === -1)) {
                xTickValues.push(data[key][i][0]);
            }
        }
    });
    /********************************** GRID **********************************/
    var linesXY = [[xMax, yMax, xMin, yMax]];
    for (var i=0, l=xTickValues.length; i<l; i++) {
        linesXY.push([xTickValues[i], 0, xTickValues[i], yMax]);
    }
    for (i=0, l=yTickValues.length; i<l; i++) {
        linesXY.push([xMin, yTickValues[i], xMax, yTickValues[i]]);
    }
    var lines = d3.select("svg").selectAll("line")
                                .data(linesXY)
                                .enter();
    drawLines(lines, xScale, yScale);
    /****************************** DATA POINTS *******************************/
    var circles = d3.select("svg").selectAll("circle"),
        seqid = 0,
        legendInterval = 0;
    Object.keys(data).forEach(function(key) {
        drawSplines(data[key], xScale, yScale, seqid);
        drawDataPoints(circles.data(data[key]).enter(), xScale, yScale, seqid);

        legendInterval = Math.max((key.length + 1) * INSIGHT.fontWidth, legendInterval);
        seqid++;
    });
    if (vary_by !== null) {
        var legend = d3.select("svg").append("g").selectAll("text"),
            legendPadding = (vary_by.length + 1) * INSIGHT.fontWidth;
        drawLegendTitle(vary_by);
        drawLegend(legend.data(Object.keys(data)).enter(), legendPadding, legendInterval);
    }

    /********************************** AXES **********************************/
    drawAxes(xScale, yScale, xTickValues);
    /**************************************************************************/
}

$(document).ready(function(){
    "use strict";

    drawBase();
});
<commit_msg>pass actual value of data point<commit_after>/*jshint jquery: true, browser: true*/
/*global angular, d3*/

angular.module("insight", [])
    .config(["$interpolateProvider", function ($interpolateProvider) {
        "use strict";

        $interpolateProvider.startSymbol("[[");
        $interpolateProvider.endSymbol("]]");
    }]);

var INSIGHT = {
    height: 548,
    width: 900,
    smallPadding: 40,
    largePadding: 70,
    fontHeight: 14,
    fontWidth: 10,
    palette: [
        "#f89406",
        "#51A351",
        "#7D1935",
        "#4A96AD",
        "#DE1B1B",
        "#E9E581",
        "#A2AB58",
        "#FFE658",
        "#118C4E",
        "#193D4F"
    ]
};

function Insights($scope, $http) {
    "use strict";

    $scope.getOptions = function() {
        $scope.inputs = [];
        $scope.abscissa = null;
        $scope.vary_by = null;
        $scope.customInputs = {};
        $scope.currentOptions = {};

        var params = {"insight": $scope.selectedInsight.id};
        $http({method: "GET", url: "/cbmonitor/get_insight_options/", params: params})
        .success(function(data) {
            $scope.inputs = data;
            resetCharts();
        });
    };

    $scope.getData = function() {
        var params = {
            "insight": $scope.selectedInsight.id,
            "abscissa": $scope.abscissa,
            "inputs": JSON.stringify($scope.currentOptions)
        };
        if ($scope.vary_by !== null ) {
            params.vary_by = $scope.vary_by;
        }
        $http({method: "GET", url: "/cbmonitor/get_insight_data/", params: params})
        .success(function(data) {
            resetCharts();
            if ($.isEmptyObject(data)) {
                drawWarning();
            } else {
                drawScatterPlot(data, $scope.vary_by);
            }
        });
    };

    $scope.updateData = function(title, value, option) {
        if (value === "As X-axis") {
            if ($scope.abscissa !== null && $scope.abscissa !== title) {
                $scope.currentOptions[$scope.abscissa] = $scope.resetAbscissaTo;
            }
            $scope.abscissa = title;
            $scope.resetAbscissaTo = $scope.inputs[option.$index].options[0];
        } else if ($scope.abscissa === title) {
            $scope.abscissa = null;
        }

        if (value === "Vary by") {
            if ($scope.vary_by !== null && $scope.vary_by !== title) {
                $scope.currentOptions[$scope.vary_by] = $scope.resetVaryByTo;
            }
            $scope.vary_by = title;
            $scope.resetVaryByTo = $scope.inputs[option.$index].options[0];
        } else if ($scope.vary_by === title) {
            $scope.vary_by = null;
        }

        if ($scope.abscissa !== null) {
            $scope.getData();
        } else {
            resetCharts();
        }
    };

    $http.get("/cbmonitor/get_insight_defaults/").success(function(insights) {
        $scope.insights = insights;
        $scope.selectedInsight = insights[0];
        var query = window.location.search.split("=");
        for (var i=0, l=insights.length; i < l; i++) {
            if (insights[i].id === query[query.length - 1]) {
                $scope.selectedInsight = insights[i];
                break;
            }
        }
        $scope.getOptions();
    });
}

function drawBase() {
    "use strict";

    d3.select("#chart").append("svg").attr({
        height: INSIGHT.height, width: INSIGHT.width
    });

    d3.select("svg").append("rect").attr({
        height: INSIGHT.height, width: INSIGHT.width,
        rx: 5, ry: 5,
        fill: "white",
        stroke: "#cccccc"
    });
}

function addFocus(seqid) {
    "use strict";

    var focus = d3.select("svg").append("g")
                                .attr("class", "focus")
                                .style("display", "none");
    focus.append("text").attr({
        dx: "15px", dy: "25px",
        fill: INSIGHT.palette[seqid]
    });
    return focus;
}

function showFocus(focus, obj, yScale, value) {
    "use strict";

    var x = d3.mouse(obj)[0],
        y = d3.mouse(obj)[1],
        formatValue = d3.format(".1f");
    if (value === undefined) {
        value = formatValue(yScale.invert(y));
    }
    focus
        .style("display", null)
        .attr("transform", "translate(" + x + "," + y + ")")
        .select("text").text(value);
}

function drawDataPoints(circles, xScale, yScale, seqid) {
    "use strict";

    var focus = addFocus(seqid);

    circles
        .append("circle")
        .on("mouseover", function(d) {
            showFocus(focus, this, yScale, d[1]);
            d3.select(this).transition().duration(200)
                .attr({ r: 7 });
        })
        .on("mouseout", function() {
            focus.style("display", "none");
            d3.select(this).transition().duration(200)
                .attr({ r: 5 });
        })
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white", stroke: "white" });
        })
        .attr({
            cx: function(d) { return xScale(d[0]); },
            cy: function(d) { return yScale(d[1]); },
            r: 5,
            stroke: INSIGHT.palette[seqid], "stroke-width": 3
        });
}

function drawSplines(data, xScale, yScale, seqid) {
    "use strict";

    var line = d3.svg.line()
        .x(function(d) { return xScale(d[0]); })
        .y(function(d) { return yScale(d[1]); })
        .interpolate("cardinal");

    var focus = addFocus(seqid);

    d3.select("svg")
        .append("path")
        .on("mouseover", function() { showFocus(focus, this, yScale); })
        .on("mouseout", function() { focus.style("display", "none"); })
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ stroke: "white" });
        })
        .attr({
            "d": line(data),
            stroke: INSIGHT.palette[seqid], "stroke-width": 2,
            "fill-opacity": 0.0,
            "pointer-events": "stroke"
        });
}

function drawLines(lines, xScale, yScale) {
    "use strict";

    lines.append("line")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ stroke: "white" });
        })
        .attr({
            x1: function(d) { return xScale(d[0]); },
            y1: function(d) { return yScale(d[1]); },
            x2: function(d) { return xScale(d[2]); },
            y2: function(d) { return yScale(d[3]); },
            stroke: "#cccccc", "shape-rendering": "crispEdges"
        });
}

function drawAxes(xScale, yScale, xTickValues) {
    "use strict";

    var areaPadding = 10;

    var xAxis = d3.svg.axis()
                      .scale(xScale)
                      .orient("bottom")
                      .tickValues(xTickValues);

    d3.select("svg").append("g")
        .attr("class", "axis")
        .attr("transform", "translate(0, " + (INSIGHT.height - INSIGHT.smallPadding + areaPadding) + ")")
        .call(xAxis);

    var yAxis = d3.svg.axis()
                      .scale(yScale)
                      .orient("left")
                      .ticks(5);
    d3.select("svg").append("g")
        .attr("class", "axis")
        .attr("transform", "translate(" + (INSIGHT.largePadding - areaPadding) + ", 0)")
        .call(yAxis);
}

function drawLegendTitle(title) {
    "use strict";

    d3.select("svg").append("g").append("text")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white" });
        })
        .text(title + ":")
        .attr({
            x: INSIGHT.largePadding + 5,
            y: (INSIGHT.smallPadding + INSIGHT.fontHeight) / 2,
            "font-size": INSIGHT.fontHeight,
            fill: "black"
        });

}

function drawLegend(legend, legendPadding, legendInterval) {
    "use strict";

    legend.append("text")
        .transition().duration(500).ease("linear").each("start", function() {
            d3.select(this).attr({ fill: "white" });
        })
        .text(function(d) { return d; })
        .attr({
            x: function(d, i) { return INSIGHT.largePadding + legendPadding + i * legendInterval; },
            y: (INSIGHT.smallPadding + INSIGHT.fontHeight) / 2,
            "font-size": INSIGHT.fontHeight,
            "font-weight": "bold",
            fill: function(d, i) { return INSIGHT.palette[i]; }
        });
}

function drawWarning() {
    "use strict";

    d3.select("svg").append("text")
        .text("No data")
        .attr({
            x: INSIGHT.width / 2 - 50, y: INSIGHT.height / 2,
            class: "warning"
        });
}

function resetCharts() {
    "use strict";

    d3.selectAll("circle").remove();
    d3.selectAll("line").remove();
    d3.selectAll("g").remove();
    d3.selectAll("path").remove();
    d3.selectAll("text").remove();
}

function drawScatterPlot(data, vary_by) {
    "use strict";

    /******************************** MIN MAX *********************************/
    var xMin = Number.MAX_VALUE,
        xMax = Number.MIN_VALUE,
        yMax = Number.MIN_VALUE;

    Object.keys(data).forEach(function(key) {
        xMin = Math.min(xMin, d3.min(data[key], function(d) { return d[0]; }));
        xMax = Math.max(xMax, d3.max(data[key], function(d) { return d[0]; }));
        yMax = Math.max(yMax, d3.max(data[key], function(d) { return d[1]; }));

    });

    /********************************* SCALES *********************************/
    var yScale = d3.scale.linear()
                         .domain([0, yMax])
                         .range([INSIGHT.height - INSIGHT.smallPadding, INSIGHT.smallPadding]);
    var xScale;
    if (isNaN(xMin) || isNaN(xMax)) {
        xScale = d3.scale.ordinal()
                         .range([INSIGHT.largePadding, INSIGHT.width - INSIGHT.smallPadding]);
    } else {
        xScale = d3.scale.linear()
                         .domain([xMin, xMax])
                         .range([INSIGHT.largePadding, INSIGHT.width - INSIGHT.smallPadding]);
    }
    /********************************** TICKS *********************************/
    var yTickValues = yScale.ticks(5);
    var xTickValues = [];
    Object.keys(data).forEach(function(key) {
        for (var i=0, l=data[key].length; i < l; i++) {
            if (xTickValues.indexOf(data[key][i][0] === -1)) {
                xTickValues.push(data[key][i][0]);
            }
        }
    });
    /********************************** GRID **********************************/
    var linesXY = [[xMax, yMax, xMin, yMax]];
    for (var i=0, l=xTickValues.length; i<l; i++) {
        linesXY.push([xTickValues[i], 0, xTickValues[i], yMax]);
    }
    for (i=0, l=yTickValues.length; i<l; i++) {
        linesXY.push([xMin, yTickValues[i], xMax, yTickValues[i]]);
    }
    var lines = d3.select("svg").selectAll("line")
                                .data(linesXY)
                                .enter();
    drawLines(lines, xScale, yScale);
    /****************************** DATA POINTS *******************************/
    var circles = d3.select("svg").selectAll("circle"),
        seqid = 0,
        legendInterval = 0;
    Object.keys(data).forEach(function(key) {
        drawSplines(data[key], xScale, yScale, seqid);
        drawDataPoints(circles.data(data[key]).enter(), xScale, yScale, seqid);

        legendInterval = Math.max((key.length + 1) * INSIGHT.fontWidth, legendInterval);
        seqid++;
    });
    if (vary_by !== null) {
        var legend = d3.select("svg").append("g").selectAll("text"),
            legendPadding = (vary_by.length + 1) * INSIGHT.fontWidth;
        drawLegendTitle(vary_by);
        drawLegend(legend.data(Object.keys(data)).enter(), legendPadding, legendInterval);
    }

    /********************************** AXES **********************************/
    drawAxes(xScale, yScale, xTickValues);
    /**************************************************************************/
}

$(document).ready(function(){
    "use strict";

    drawBase();
});
<|endoftext|>


<commit_before>export default function(circles) {
  return encloseBasis(findBasis(circles, circles.length, []));
}

function findBasis(L, n, B) {
  var circle = encloseBasis(B);

  for (var i = 0; i < n; ++i) {
    var p = L[i];
    if (!circle || !encloses(circle, p)) {
      B = findBasis(L, i + 1, extendBasis(B, p));
      circle = encloseBasis(B);
    }
  }

  return B;
}

function extendBasis(B, p) {
  var i, j;
  if (enclosesAll(p, B)) return [p];

  // If we get here then B must have at least one element.
  for (i = 0; i < B.length; ++i) if (enclosesAll(encloseBasis2(B[i], p), B)) return [B[i], p];

  // If we get here then B must have at least two elements.
  for (i = 0; i < B.length - 1; ++i) {
    for (j = i + 1; j < B.length; ++j) {
      if (isBasis3(B[i], B[j], p) && enclosesAll(encloseBasis3(B[i], B[j], p), B)) {
        return [B[i], B[j], p];
      }
    }
  }

  // If we get here then something is very wrong.
  throw new Error;
}

function encloses(a, b) {
  var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
  return dr > -1e-9 && dr * dr * (1 + 1e-9) + 1e-9 > dx * dx + dy * dy;
}

function enclosesAll(a, B) {
  for (var i = 0; i < B.length; ++i) if (!encloses(a, B[i])) return false;
  return true;
}

function encloseBasis(B) {
  switch (B.length) {
    case 1: return encloseBasis1(B[0]);
    case 2: return encloseBasis2(B[0], B[1]);
    case 3: return encloseBasis3(B[0], B[1], B[2]);
  }
}

function encloseBasis1(a) {
  return {
    x: a.x,
    y: a.y,
    r: a.r
  };
}

function encloseBasis2(a, b) {
  var x1 = a.x, y1 = a.y, r1 = a.r,
      x2 = b.x, y2 = b.y, r2 = b.r,
      x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
      l = Math.sqrt(x21 * x21 + y21 * y21);
  return {
    x: (x1 + x2 + x21 / l * r21) / 2,
    y: (y1 + y2 + y21 / l * r21) / 2,
    r: (l + r1 + r2) / 2
  };
}

function encloseBasis3(a, b, c) {
  var x1 = a.x, y1 = a.y, r1 = a.r,
      x2 = b.x, y2 = b.y, r2 = b.r,
      x3 = c.x, y3 = c.y, r3 = c.r,
      a2 = x1 - x2,
      a3 = x1 - x3,
      b2 = y1 - y2,
      b3 = y1 - y3,
      c2 = r2 - r1,
      c3 = r3 - r1,
      d1 = x1 * x1 + y1 * y1 - r1 * r1,
      d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
      d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
      ab = a3 * b2 - a2 * b3,
      xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
      xb = (b3 * c2 - b2 * c3) / ab,
      ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
      yb = (a2 * c3 - a3 * c2) / ab,
      A = xb * xb + yb * yb - 1,
      B = 2 * (r1 + xa * xb + ya * yb),
      C = xa * xa + ya * ya - r1 * r1,
      r = A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B,
      x = x1 + xa - xb * r,
      y = y1 + ya - yb * r;
  return {
    x: x,
    y: y,
    r: Math.max(
      Math.sqrt((x1 -= x) * x1 + (y1 -= y) * y1) + r1,
      Math.sqrt((x2 -= x) * x2 + (y2 -= y) * y2) + r2,
      Math.sqrt((x3 -= x) * x3 + (y3 -= y) * y3) + r3
    )
  };
}

function isBasis3(a, b, c) {
  return !encloses(encloseBasis2(a, b), c)
      && !encloses(encloseBasis2(a, c), b)
      && !encloses(encloseBasis2(b, c), a);
}
<commit_msg>Air it out.<commit_after>export default function(circles) {
  return encloseBasis(findBasis(circles, circles.length, []));
}

function findBasis(L, n, B) {
  var circle = encloseBasis(B);

  for (var i = 0; i < n; ++i) {
    var p = L[i];
    if (!circle || !encloses(circle, p)) {
      B = findBasis(L, i + 1, extendBasis(B, p));
      circle = encloseBasis(B);
    }
  }

  return B;
}

function extendBasis(B, p) {
  var i, j;

  if (enclosesAll(p, B)) return [p];

  // If we get here then B must have at least one element.
  for (i = 0; i < B.length; ++i) if (enclosesAll(encloseBasis2(B[i], p), B)) return [B[i], p];

  // If we get here then B must have at least two elements.
  for (i = 0; i < B.length - 1; ++i) {
    for (j = i + 1; j < B.length; ++j) {
      if (isBasis3(B[i], B[j], p) && enclosesAll(encloseBasis3(B[i], B[j], p), B)) {
        return [B[i], B[j], p];
      }
    }
  }

  // If we get here then something is very wrong.
  throw new Error;
}

function encloses(a, b) {
  var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
  return dr > -1e-9 && dr * dr * (1 + 1e-9) + 1e-9 > dx * dx + dy * dy;
}

function enclosesAll(a, B) {
  for (var i = 0; i < B.length; ++i) if (!encloses(a, B[i])) return false;
  return true;
}

function encloseBasis(B) {
  switch (B.length) {
    case 1: return encloseBasis1(B[0]);
    case 2: return encloseBasis2(B[0], B[1]);
    case 3: return encloseBasis3(B[0], B[1], B[2]);
  }
}

function encloseBasis1(a) {
  return {
    x: a.x,
    y: a.y,
    r: a.r
  };
}

function encloseBasis2(a, b) {
  var x1 = a.x, y1 = a.y, r1 = a.r,
      x2 = b.x, y2 = b.y, r2 = b.r,
      x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
      l = Math.sqrt(x21 * x21 + y21 * y21);
  return {
    x: (x1 + x2 + x21 / l * r21) / 2,
    y: (y1 + y2 + y21 / l * r21) / 2,
    r: (l + r1 + r2) / 2
  };
}

function encloseBasis3(a, b, c) {
  var x1 = a.x, y1 = a.y, r1 = a.r,
      x2 = b.x, y2 = b.y, r2 = b.r,
      x3 = c.x, y3 = c.y, r3 = c.r,
      a2 = x1 - x2,
      a3 = x1 - x3,
      b2 = y1 - y2,
      b3 = y1 - y3,
      c2 = r2 - r1,
      c3 = r3 - r1,
      d1 = x1 * x1 + y1 * y1 - r1 * r1,
      d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
      d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
      ab = a3 * b2 - a2 * b3,
      xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
      xb = (b3 * c2 - b2 * c3) / ab,
      ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
      yb = (a2 * c3 - a3 * c2) / ab,
      A = xb * xb + yb * yb - 1,
      B = 2 * (r1 + xa * xb + ya * yb),
      C = xa * xa + ya * ya - r1 * r1,
      r = A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B,
      x = x1 + xa - xb * r,
      y = y1 + ya - yb * r;
  return {
    x: x,
    y: y,
    r: Math.max(
      Math.sqrt((x1 -= x) * x1 + (y1 -= y) * y1) + r1,
      Math.sqrt((x2 -= x) * x2 + (y2 -= y) * y2) + r2,
      Math.sqrt((x3 -= x) * x3 + (y3 -= y) * y3) + r3
    )
  };
}

function isBasis3(a, b, c) {
  return !encloses(encloseBasis2(a, b), c)
      && !encloses(encloseBasis2(a, c), b)
      && !encloses(encloseBasis2(b, c), a);
}
<|endoftext|>


<commit_before><commit_msg>Adding a new demo file<commit_after><|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2018 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

function assertDimensionsMatch(toCheck, left, top, width, height) {
  assertEquals('Top did not match.', top, toCheck.top);
  assertEquals('Left did not match.', left, toCheck.left);
  assertEquals('Width did not match.', width, toCheck.width);
  assertEquals('Height did not match.', height, toCheck.height);
}

/**
 * Make a mock workspace object with two properties: getBlocksBoundingBox and
 * scale.
 */
function makeMockWs(scale, x, y, width, height) {
  return {
    getBlocksBoundingBox: function() {
      return {
        width: width,
        height: height,
        x: x,
        y: y
      }
    },
    scale: 1
  };
}

// Empty workspace.
var test_GetContentDimensionsExact_empty = function() {
  var ws = makeMockWs(1, 0, 0, 0, 0)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(defaultZoom, 0, 0, 0, 0);

  // zoom in.
  ws.scale = 2;
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(zoomIn, 0, 0, 0, 0);

  // zoom out.
  ws.scale = .5;
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(zoomOut, 0, 0, 0, 0);
};

// Non-empty workspace, with top-left corner at ws origin.
var test_GetContentDimensionsExact_nonEmptyAtOrigin = function() {
  var ws = makeMockWs(1, 0, 0, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, 0, 0, 100, 100);

  // zoom in.
  ws.scale = 2;
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, 0, 0, 200, 200);

  // zoom out.
  ws.scale = .5;
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, 0, 0, 50, 50);
};

// Non-empty workspace, with top-left corner in positive ws coordinates.
var test_GetContentDimensionsExact_nonEmptyPositiveOrigin = function() {
  var ws = makeMockWs(1, 10, 10, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, 10, 10, 100, 100);

  // Changing zoom will change both width/height and origin location in pixels.

  // zoom in.
  ws.scale = 2;
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, 20, 20, 200, 200);

  // zoom out.
  ws.scale = .5;
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, 5, 5, 50, 50);
};

// Non-empty workspace, with top-left corner in negative ws coordinates.
var test_GetContentDimensionsExact_nonEmptyNegativeOrigin = function() {
  var ws = makeMockWs(1, -10, -10, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, -10, -10, 100, 100);

  // Changing zoom will change both width/height and origin location in pixels.

  // zoom in.
  ws.scale = 2;
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, -20, -20, 200, 200);

  // zoom out.
  ws.scale = .5;
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, -5, -5, 50, 50);
};

<commit_msg>Break tests out into individual cases<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2018 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

function assertDimensionsMatch(toCheck, left, top, width, height) {
  assertEquals('Top did not match.', top, toCheck.top);
  assertEquals('Left did not match.', left, toCheck.left);
  assertEquals('Width did not match.', width, toCheck.width);
  assertEquals('Height did not match.', height, toCheck.height);
}

/**
 * Make a mock workspace object with two properties: getBlocksBoundingBox and
 * scale.
 */
function makeMockWs(scale, x, y, width, height) {
  return {
    getBlocksBoundingBox: function() {
      return {
        width: width,
        height: height,
        x: x,
        y: y
      }
    },
    scale: scale
  };
}

// Empty workspace.
var test_GetContentDimensionsExact_empty = function() {
  var ws = makeMockWs(1, 0, 0, 0, 0)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(defaultZoom, 0, 0, 0, 0);
}

var test_GetContentDimensionsExact_emptyZoomIn = function() {
  var ws = makeMockWs(2, 0, 0, 0, 0)
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(zoomIn, 0, 0, 0, 0);
}

var test_GetContentDimensionsExact_emptyZoomOut = function() {
  var ws = makeMockWs(.5, 0, 0, 0, 0)
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  assertDimensionsMatch(zoomOut, 0, 0, 0, 0);
}

// Non-empty workspace, with top-left corner at ws origin.
var test_GetContentDimensionsExact_nonEmptyAtOrigin = function() {
  var ws = makeMockWs(1, 0, 0, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, 0, 0, 100, 100);
}

var test_GetContentDimensionsExact_nonEmptyAtOriginZoomIn = function() {
  var ws = makeMockWs(2, 0, 0, 100, 100)
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, 0, 0, 200, 200);
}

var test_GetContentDimensionsExact_nonEmptyAtOriginZoomOut = function() {
  var ws = makeMockWs(.5, 0, 0, 100, 100)
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, 0, 0, 50, 50);
}

// Non-empty workspace, with top-left corner in positive ws coordinates.
var test_GetContentDimensionsExact_nonEmptyPositiveOrigin = function() {
  var ws = makeMockWs(1, 10, 10, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, 10, 10, 100, 100);
}

// Changing zoom will change both width/height and origin location in pixels.
var test_GetContentDimensionsExact_nonEmptyPositiveOriginZoomIn = function() {
  var ws = makeMockWs(2, 10, 10, 100, 100)
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, 20, 20, 200, 200);
}

var test_GetContentDimensionsExact_nonEmptyPositiveOriginZoomOut = function() {
  var ws = makeMockWs(.5, 10, 10, 100, 100)
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, 5, 5, 50, 50);
}

// Non-empty workspace, with top-left corner in negative ws coordinates.
var test_GetContentDimensionsExact_nonEmptyNegativeOrigin = function() {
  var ws = makeMockWs(1, -10, -10, 100, 100)
  var defaultZoom = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // Pixel and ws units are the same at default zoom.
  assertDimensionsMatch(defaultZoom, -10, -10, 100, 100);
}

// Changing zoom will change both width/height and origin location in pixels.
var test_GetContentDimensionsExact_nonEmptyNegativeOriginZoomIn = function() {
  var ws = makeMockWs(2, -10, -10, 100, 100)
  var zoomIn = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 2 pixels at this zoom level.
  assertDimensionsMatch(zoomIn, -20, -20, 200, 200);
}

var test_GetContentDimensionsExact_nonEmptyNegativeOriginZoomOut = function() {
  var ws = makeMockWs(.5, -10, -10, 100, 100)
  var zoomOut = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
  // 1 ws unit = 0.5 pixels at this zoom level.
  assertDimensionsMatch(zoomOut, -5, -5, 50, 50);
}
<|endoftext|>


<commit_before>var express = require('express');

var app = express();
app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(app.router);
    app.set('view engine', 'jade');
    app.set('views', __dirname + '/public');
    app.set('view options', { layout: false });
    app.set('basepath', __dirname + '/public');
});

app.configure('development', function () {
    app.use(express.static(__dirname + '/dist'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {
    var oneYear = 31557600000;
    app.use(express.static(__dirname + '/dist', { maxAge: oneYear }));
    app.use(express.errorHandler());
});

console.log("Web server has started.\n");
app.listen(30002, '0.0.0.0');
<commit_msg>updated,<commit_after>var express = require('express');

var app = express();
app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(app.router);
    app.set('view engine', 'jade');
    app.set('views', __dirname + '/public');
    app.set('view options', { layout: false });
    app.set('basepath', __dirname + '/public');
});

app.configure('development', function () {
    app.use(express.static(__dirname + '/dist'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {
    var oneYear = 31557600000;
    app.use(express.static(__dirname + '/dist', { maxAge: oneYear }));
    app.use(express.errorHandler());
});

console.log("Web server has started.\n");
app.listen(30001, '0.0.0.0');
<|endoftext|>


<commit_before>// Déclaration du module 'users'
angular.module('pzWebApp.users', [
    'ngRoute',
    'pzWebApp.shared'
]);

// Configuration du module 'users'
angular.module('pzWebApp.users').config(function ($routeProvider) {

    // TODO Définir les routes spécifiques au module 'users' ici
    $routeProvider
        .when("/inscription", {
            templateUrl: "users/template/inscription.tpl.html",
            controller: "inscriptionCtrl",
            controllerAs: "ctrl"
        })
        .when("/edition", {
            templateUrl: "users/template/edition.tpl.html",
            controller: "editionCtrl",
            controllerAs: "ctrl"
        })
        .when("/connexion", {
            templateUrl: "users/template/connexion.tpl.html",
            controller: "connexionCtrl",
            controllerAs: "ctrl"
        }).when("/validation", {
            templateUrl: "users/template/validation.tpl.html",
            controller: "validationCtrl",
            controllerAs: "ctrl"
        });
});

// Contrôleur principal du module 'users'
// Usage de la syntaxe 'controller as', pas besoin du '$scope'
angular.module('pzWebApp.users').controller('inscriptionCtrl', function (userService, inscriptionService, $location) {
    function handleResponse(response) {
        return response.data
    }

    var self = this;

    self.title = "Page d'inscription";
    self.response = null;

    this.saveForm = function () {
        if (this.inscriptionForm.$invalid) {
            alert('Un champs est vide ou invalide !')
            return
        }
        self.client = this.client;
        inscriptionService.promessePost(this.client)
            .then(function (reponse) {
                userService.login(reponse.data);
                //$location.path('/')
            }, function (reason) {
                if (reason.status == 400)
                    alert(reason.data);
                else
                    alert('Une erreur est intervenue')
            }
                );
    }

});

angular.module('pzWebApp.users').controller('editionCtrl', function (userService, editionService, $location, $localStorage) {

    var self = this;

    self.title = "Page d'edition";
    self.client = {};
    angular.copy($localStorage.client, self.client);
    self.change = false;
    self.login = self.client.login;
    self.mdp = self.client.mdp;

    function putClient(client) {
        editionService.promessePut(client)
            .then(function () {
                $localStorage.client = self.client
                alert("Vos informations personnelles ont bien été mises à jour.")
                $location.path('/')
            });
    }

    this.saveForm = function () {
        if (this.editionForm.$dirty) {

            if (this.editionForm.$invalid) {
                alert('Un champs est vide ou invalide !')
                return
            }
            var confirmMessage = undefined
            if (this.client.login != self.login) {
                confirmMessage = "Voulez-vous vraiment modifier votre login ?"
            }

            if (this.client.mdp != self.mdp) {
                if (confirmMessage) {
                    confirmMessage = confirmMessage.replace("?", "et votre mdp ?")
                } else {
                    confirmMessage = "Voulez-vous vraiment modifier votre mdp ?"
                }
            }

            if (confirmMessage) {
                if (confirm(confirmMessage)) {
                    putClient(this.client)
                } else {
                    self.client.login = self.login;
                    self.client.mdp = self.mdp;
                }
            } else {
                putClient(this.client)
            }
        }
    }
});

angular.module('pzWebApp.users').controller('connexionCtrl', function (userService, connexionService, $location, $localStorage) {

    var self = this;

    self.title = "Page de connexion";
    self.client = ""
    this.saveForm = function () {
        if (this.connexionForm.$invalid) {
            alert('Un champs est vide ou invalide !')
            return
        }
        //Redirection vers le home
        connexionService.promessePut(this.login, this.mdp)
            .then(function (response) {

                userService.login(response.data);

                if(!$localStorage.panierFinal){
                    $location.path('/');

                }
                else{
                    $location.path('/commande');
                }

            } , function (reason) {

                 if (reason.status == 400)
                    alert(reason.data);
                else
                    alert('Une erreur est intervenue')
            });
    }

});

angular.module('pzWebApp.users').controller('validationCtrl', function (userService, validationService, $location, $routeParams) {

    var self = this;
    self.id = $routeParams.id
    self.hash = $routeParams.hash
    self.information =""
    self.title = "Page de validation";

    validationService.promessePut(self.id, self.hash)
        .then(function (response) {
            self.information = "Votre compte a bien été validé."
            userService.login(response.data);
        }, function (reason) {
            if (reason.status == 400) {
                self.information=reason.data
            }
            else {
                alert('Une erreur est intervenue')
            }
        });

});<commit_msg>#10<commit_after>// Déclaration du module 'users'
angular.module('pzWebApp.users', [
    'ngRoute',
    'pzWebApp.shared'
]);

// Configuration du module 'users'
angular.module('pzWebApp.users').config(function ($routeProvider) {

    // TODO Définir les routes spécifiques au module 'users' ici
    $routeProvider
        .when("/inscription", {
            templateUrl: "users/template/inscription.tpl.html",
            controller: "inscriptionCtrl",
            controllerAs: "ctrl"
        })
        .when("/edition", {
            templateUrl: "users/template/edition.tpl.html",
            controller: "editionCtrl",
            controllerAs: "ctrl"
        })
        .when("/connexion", {
            templateUrl: "users/template/connexion.tpl.html",
            controller: "connexionCtrl",
            controllerAs: "ctrl"
        }).when("/validation", {
            templateUrl: "users/template/validation.tpl.html",
            controller: "validationCtrl",
            controllerAs: "ctrl"
        });
});

// Contrôleur principal du module 'users'
// Usage de la syntaxe 'controller as', pas besoin du '$scope'
angular.module('pzWebApp.users').controller('inscriptionCtrl', function (userService, inscriptionService, $location) {
    function handleResponse(response) {
        return response.data
    }

    var self = this;

    self.title = "Page d'inscription";
    self.response = null;

    this.saveForm = function () {
        if (this.inscriptionForm.$invalid) {
            alert('Un champs est vide ou invalide !')
            return
        }
        self.client = this.client;
        inscriptionService.promessePost(this.client)
            .then(function (reponse) {
                $location.path('/')
                alert("Pour valider votre inscription, vous devez valider l'adresse mail.")
            }, function (reason) {
                if (reason.status == 400)
                    alert(reason.data);
                else
                    alert('Une erreur est intervenue')
            }
                );
    }

});

angular.module('pzWebApp.users').controller('editionCtrl', function (userService, editionService, $location, $localStorage) {

    var self = this;

    self.title = "Page d'edition";
    self.client = {};
    angular.copy($localStorage.client, self.client);
    self.change = false;
    self.login = self.client.login;
    self.mdp = self.client.mdp;

    function putClient(client) {
        editionService.promessePut(client)
            .then(function () {
                $localStorage.client = self.client
                alert("Vos informations personnelles ont bien été mises à jour.")
                $location.path('/')
            });
    }

    this.saveForm = function () {
        if (this.editionForm.$dirty) {

            if (this.editionForm.$invalid) {
                alert('Un champs est vide ou invalide !')
                return
            }
            var confirmMessage = undefined
            if (this.client.login != self.login) {
                confirmMessage = "Voulez-vous vraiment modifier votre login ?"
            }

            if (this.client.mdp != self.mdp) {
                if (confirmMessage) {
                    confirmMessage = confirmMessage.replace("?", "et votre mdp ?")
                } else {
                    confirmMessage = "Voulez-vous vraiment modifier votre mdp ?"
                }
            }

            if (confirmMessage) {
                if (confirm(confirmMessage)) {
                    putClient(this.client)
                } else {
                    self.client.login = self.login;
                    self.client.mdp = self.mdp;
                }
            } else {
                putClient(this.client)
            }
        }
    }
});

angular.module('pzWebApp.users').controller('connexionCtrl', function (userService, connexionService, $location, $localStorage) {

    var self = this;

    self.title = "Page de connexion";
    self.client = ""
    this.saveForm = function () {
        if (this.connexionForm.$invalid) {
            alert('Un champs est vide ou invalide !')
            return
        }
        connexionService.promessePut(this.login, this.mdp)
            .then(function (response) {

                userService.login(response.data);

                if (!$localStorage.panierFinal) {
                    $location.path('/');
                }
                else {
                    $location.path('/commande');
                }
            }, function (reason) {

                if (reason.status == 400)
                    alert(reason.data);
                else
                    alert('Une erreur est intervenue')
            });
    }

});

angular.module('pzWebApp.users').controller('validationCtrl', function (userService, validationService, $location, $routeParams, $localStorage) {

    var self = this;
    self.id = $routeParams.id
    self.hash = $routeParams.hash
    self.information = ""
    self.title = "Page de validation";

    validationService.promessePut(self.id, self.hash)
        .then(function (response) {
            self.information = "Votre compte a bien été validé."
            userService.login(response.data);
            if (!$localStorage.panierFinal) {
                $location.path('/');
            }
            else {
                $location.path('/commande');
            }
        }, function (reason) {
            if (reason.status == 400) {
                self.information = reason.data
            }
            else {
                alert('Une erreur est intervenue')
            }
        });

});<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Glenn Ruehle
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
 * Modified for AsciiDoc
 * Copyright (c) 2014 Thomas Kern
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true,  regexp: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window, Worker */

define(function (require, exports, module) {
    "use strict";

    // Brackets modules
    var AppInit = brackets.getModule("utils/AppInit"),
        NativeApp = brackets.getModule("utils/NativeApp"),
        DocumentManager = brackets.getModule("document/DocumentManager"),
        EditorManager = brackets.getModule("editor/EditorManager"),
        ExtensionUtils = brackets.getModule("utils/ExtensionUtils"),
        FileSystem      = brackets.getModule("filesystem/FileSystem"),
        FileUtils = brackets.getModule("file/FileUtils"),
        LanguageManager = brackets.getModule("language/LanguageManager"),
        WorkspaceManager = brackets.getModule("view/WorkspaceManager"),
        MainViewManager = brackets.getModule("view/MainViewManager"),
        PreferencesManager = brackets.getModule("preferences/PreferencesManager");

    // Templates
    var panelHTML = require("text!templates/panel.html");

    // jQuery objects
    var $icon,
        $iframe,
        $panel;

    // Other vars
    var currentDoc,
        panel,
        fileExtensions = ["ad", "adoc", "asciidoc", "asc"],
        visible = false,
        usesStem = false,
        realVisibility = false;

    // Define AsciiDoc mode
    require("mode/asciidoc");
    LanguageManager.defineLanguage("asciidoc", {
        name: "AsciiDoc",
        mode: "asciidoc",
        fileExtensions: fileExtensions,
        blockComment: ["////", "////"],
        lineComment: ["//"]
    });

    // Prefs
    var prefs = PreferencesManager.getExtensionPrefs("asciidoc-preview");
    prefs.definePreference("showtitle", "boolean", true);
    prefs.definePreference("numbered", "boolean", false);
    prefs.definePreference("mjax", "boolean", false);
    prefs.definePreference("autosync", "boolean", false);
    prefs.definePreference("updatesave", "boolean", false);
    prefs.definePreference("theme", "string", "asciidoctor");
    prefs.definePreference("safemode", "string", "safe");
    prefs.definePreference("basedir", "string", "");
    prefs.definePreference("imagesdir", "string", "");
    prefs.definePreference("defaultdir", "string", "");
    prefs.definePreference("doctype", "string", "article");

    // Webworker for AscciDoc into HTML conversion
    var converterWorker = new Worker(ExtensionUtils.getModulePath(module, "lib/converter-worker.js"));
    // assembly of final HTML page
    var output = require("lib/output"),
        // utils for handling syncing between editor an preview panes
        syncEdit = require("lib/sync"),
        // common utils
        utils = require("lib/utils"),
        htmlExporter = require("lib/exporter"),
        settingsPanel = require("lib/settings");

    // time needed for the latest conversion in ms
    var lastDuration = 500;
    // timestamp when conversion started
    var conversionStart = 0;
    // current editing location info in generated HTML
    var previewLocationInfo = null,
        outline = null,
        docDirChanged = false,
        updateOnSave = prefs.get("updatesave"),
        autosync = prefs.get("autosync");

    // (based on code in brackets.js)
    function handleLinkClick(e) {
        // Check parents too, in case link has inline formatting tags
        var node = e.target,
            url;
        while (node) {
            if (node.tagName === "A") {
                url = node.getAttribute("href");
                if (url) {
                    if (!url.match(/^#/)) {
                        NativeApp.openURLInDefaultBrowser(url);
                    } else if (url.match(/^#goto_/)) {
                        // if URL contains special #goto_ fragment identifier,
                        // use line number to jump to this line in document editor.
                        jumpToLine(parseInt(url.substr(6), 10) - 1);
                    }
                }
                e.preventDefault();
                break;
            }
            node = node.parentElement;
        }
        // Close settings dropdown, if open
        settingsPanel.hide();
    }

    function isDocDirChanged() {
        return docDirChanged;
    }

    /**
     * Jump to specified line in source editor. Centers
     * line in view.
     */
    function jumpToLine(line) {
        var editor = EditorManager.getCurrentFullEditor();
        editor.setCursorPos(line, 0, true);
        editor.focus();

        var codeMirror = editor._codeMirror;
        codeMirror.addLineClass(line, "wrap", "flash");
        window.setTimeout(function () {
            codeMirror.removeLineClass(line, "wrap", "flash");
        }, 1000);
    }

    function loadDoc(doc, preserveScrollPos) {
        if (doc && visible && $iframe) {
            var docText = utils.stripYamlFrontmatter(doc.getText()),
                scrollPos = 0;

            if (preserveScrollPos) {
                scrollPos = $iframe.contents()[0].body.scrollTop;
            } else {
                scrollPos = 0;
                previewLocationInfo = null;
            }

            var defaultAttributes = 'icons=font@ ' +
                                    'platform=opal platform-opal ' +
                                    'env=browser env-browser ' +
                                    'sectids ' +  // force generation of section ids
                                    'source-highlighter=highlight.js@ ';
            var numbered = prefs.get("numbered") ? 'numbered' : 'numbered!';
            var showtitle = prefs.get("showtitle") ? 'showtitle' : 'showtitle!';
            var safemode = prefs.get("safemode") || "safe";
            var doctype = prefs.get("doctype") || "article";

            // baseDir will be used as the base URL to retrieve include files via Ajax requests
            var baseDir = prefs.get("basedir") || utils.getDefaultBaseDir(doc);

            var attributes = defaultAttributes.concat(' ')
                .concat(numbered).concat(' ')
                .concat(showtitle);

            // imagesDir will be used as the base URL to retrieve images
            var imagesDir =  prefs.get("imagesdir");
            if (imagesDir) {
                attributes += ' imagesDir=' + utils.toUrl(imagesDir);
            }

            // Check if directories were overridden in settings panel
            // and post a warning dialog if the current document directory changed.

            var defBaseDir = utils.normalizePath(utils.getDefaultBaseDir(doc));
            docDirChanged = !utils.pathEqual(prefs.get("defaultdir"), defBaseDir);
            if (docDirChanged) {
                prefs.set("defaultdir", defBaseDir);
                prefs.save();
            }

            // structure to pass docText, options, and attributes.
            var data = {
                docText: docText,
                // current working directory
                cwd: FileUtils.getDirectoryPath(window.location.href),
                // Asciidoctor options
                basedir: FileUtils.stripTrailingSlash(baseDir),
                safemode: safemode,
                doctype: doctype,
                header_footer: false,
                // Asciidoctor attributes
                attributes: attributes
            };

            if (lastDuration >= 500 || !preserveScrollPos) {
               displaySpinner(true);
            }

            // perform conversion in worker thread
            conversionStart = new Date().getTime();
            converterWorker.postMessage(data);

            converterWorker.onmessage = function (e) {
                lastDuration = e.data.duration;
                outline = e.data.outline;
                usesStem = e.data.stem;

                var theme = prefs.get("theme");
                if (theme === "default") { // recover from deprecated setting
                    theme = "asciidoctor";
                }

                var $locButton = $("#asciidoc-sync-location-button");
                if (outline) {
                    $locButton.show();
                    updatePreviewLocation();
                } else {
                    $locButton.hide();
                }

                if (autosync) {
                    var pos = syncEdit.getTopPos($iframe[0], previewLocationInfo);
                    if (pos) {
                        scrollPos = pos;
                    }
                }

                var html = output.createPage(e.data, utils.toUrl(baseDir) + '/', scrollPos, prefs);
                $iframe.attr("srcdoc", html);
                conversionStart = 0;
                displaySpinner(false);
            };

            $iframe.load(function () {

                var dirsDefined = prefs.get("imagesdir") !== '' || prefs.get("basedir") !== '';
                if (isDocDirChanged() && dirsDefined) {
                    settingsPanel.showWarning($panel, prefs);
                } else {
                    settingsPanel.hideWarning();
                }

                // Open external browser when links are clicked
                // (similar to what brackets.js does - but attached to the iframe's document)
                $iframe[0].contentDocument.body.addEventListener("click", handleLinkClick, true);

                if (usesStem && prefs.get("mjax") && !this.contentWindow.MathJax) {
                    prefs.set("mjax", false);
                    alert("'MathJax' could not be accessed online and is also not available from cache. " +
                          "You are either working offline or access to the internet failed. " +
                          "Rendering of mathematical expressions has been switched off.");
                }
            });
        }
    }

    var timer;

    function documentChange(e) {
        if (updateOnSave) {
            return;
        }

        // throttle updates
        if (timer) {
            window.clearTimeout(timer);
        }

        // Estimate timeout based on time needed for
        // actual document conversion. Never longer than
        // 5000 ms.
        var timeout = 150;
        var currentTime = new Date().getTime();

        if (conversionStart > 0) {
            timeout = Math.min(lastDuration - currentTime + conversionStart, 5000);
            if (timeout < 150) {
                timeout = 150;
            }
        }

        timer = window.setTimeout(function () {
            timer = null;
            loadDoc(e.target, true);
        }, timeout);
    }

    function resizeIframe() {
        if (visible && $iframe) {
            var iframeWidth = panel.$panel.innerWidth();
            $iframe.attr("width", iframeWidth + "px");
        }
    }

    function updateSettings() {
        // Save preferences
        prefs.save();
        updateOnSave = prefs.get("updatesave");
        autosync = prefs.get("autosync");
        // Re-render
        loadDoc(currentDoc, true);
    }

    function setPanelVisibility(isVisible) {
        if (isVisible === realVisibility) {
            return;
        }

        realVisibility = isVisible;
        if (isVisible) {
            if (!panel) {
                $panel = $(panelHTML);
                $iframe = $panel.find("#panel-asciidoc-preview-frame");

                panel = WorkspaceManager.createBottomPanel("asciidoc-preview-panel", $panel);
                $panel.on("panelResizeUpdate", function (e, newSize) {
                    $iframe.attr("height", newSize);
                });
                $iframe.attr("height", $panel.height());

                window.setTimeout(resizeIframe);

                // create settings panel
                settingsPanel.create($panel, prefs, updateSettings);

                // attach handler to sync-location-button
                $("#asciidoc-sync-location-button")
                    .click(function () {
                         updatePreviewLocation(true);
                    });

                // attach handler to export-file-button
                $("#asciidoc-export-file-button")
                    .click(function () {
                         htmlExporter.execute(currentDoc, prefs, displaySpinner);
                    });
            }
            loadDoc(DocumentManager.getCurrentDocument());
            $icon.toggleClass("active");
            panel.show();
        } else {
            $icon.toggleClass("active");
            panel.hide();
        }
    }

    function updateOnSaveHandler(event, entry) {
        if (realVisibility && updateOnSave && entry && currentDoc && entry.fullPath === currentDoc.file.fullPath) {
            loadDoc(currentDoc, true);
        }
    }

    // React to user manually changing the language of the file
    // to AsciiDoc from the status bar
    function languageChanged(e, oldLanguage, newLanguage) {
        if (newLanguage.getMode() === "asciidoc" || oldLanguage.getMode() === "asciidoc") {
            currentDocChangedHandler();
        }
    }

    function currentDocChangedHandler() {
        var doc = DocumentManager.getCurrentDocument();

        // listen to language changes initiated by the user
        $(doc).on("languageChanged", languageChanged);

        if (currentDoc) {
            $(currentDoc).off("change", documentChange);
            FileSystem.off("change", updateOnSaveHandler);
            currentDoc = null;
        }

        if (doc && doc.getLanguage().getMode() === "asciidoc") {
            currentDoc = doc;
            $(currentDoc).on("change", documentChange);
            // Detect if file changed on disk
            FileSystem.on("change", updateOnSaveHandler);
            $icon.css({
                display: "block"
            });
            settingsPanel.setDocDir(utils.getDefaultBaseDir(currentDoc));
            setPanelVisibility(visible);
            loadDoc(doc);
        } else {
            $icon.css({
                display: "none"
            });
            setPanelVisibility(false);
        }
    }

    function toggleVisibility() {
        visible = !visible;
        setPanelVisibility(visible);
    }

    /**
     * Updates global variable previewLocationInfo with information
     * corresponding to the current position of the text cursor.
     *
     * @param {Boolean} sync if true, scrolls corresponding positions
     *                       of preview pane and text cursor position into view.
     */
    function updatePreviewLocation(sync) {
        var editor = EditorManager.getCurrentFullEditor();
        var cursor = editor.getCursorPos();
        if (outline && cursor) {
            // store current editing location info with respect to HTML
            previewLocationInfo = syncEdit.findLocationInfo(outline, cursor.line + 1);
            if (previewLocationInfo) {
                previewLocationInfo.lineno = cursor.line + 1;
            }
            if (sync) {
                var topPos = syncEdit.getTopPos($iframe[0], previewLocationInfo);
                $iframe[0].contentWindow.scrollTo(0, topPos);
                editor.setCursorPos(cursor, true);
                editor.focus();
            }
        }
    }

    /**
     * Shows or hides a busy indicator
     * @param {Boolean} show display indicator on true, hide on false
     */
    function displaySpinner(show) {
        var $spinner = $("#asciidoc-busy-spinner");

        if (show) {
            $spinner.show();
        } else {
            $spinner.hide();
        }
    }

    // Insert CSS for this extension
    ExtensionUtils.loadStyleSheet(module, "styles/AsciidocPreview.css");

    // Add toolbar icon
    $icon = $("<a>")
        .attr({
            id: "asciidoc-preview-icon",
            href: "#"
        })
        .css({
            display: "none"
        })
        .click(toggleVisibility)
        .appendTo($("#main-toolbar .buttons"));

    // Add a document change handler
    MainViewManager.on("currentFileChange", currentDocChangedHandler);

    // currentDocumentChange is *not* called for the initial document. Use
    // appReady() to set initial state.
    AppInit.appReady(function () {
        currentDocChangedHandler();
    });

    // Listen for resize events
    WorkspaceManager.on("workspaceUpdateLayout", resizeIframe);
    $("#sidebar").on("panelCollapsed panelExpanded panelResizeUpdate", resizeIframe);
});
<commit_msg>fix attachment of event handlers<commit_after>/*
 * Copyright (c) 2012 Glenn Ruehle
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
 * Modified for AsciiDoc
 * Copyright (c) 2014 Thomas Kern
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true,  regexp: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window, Worker */

define(function (require, exports, module) {
    "use strict";

    // Brackets modules
    var AppInit = brackets.getModule("utils/AppInit"),
        NativeApp = brackets.getModule("utils/NativeApp"),
        DocumentManager = brackets.getModule("document/DocumentManager"),
        EditorManager = brackets.getModule("editor/EditorManager"),
        ExtensionUtils = brackets.getModule("utils/ExtensionUtils"),
        FileSystem      = brackets.getModule("filesystem/FileSystem"),
        FileUtils = brackets.getModule("file/FileUtils"),
        LanguageManager = brackets.getModule("language/LanguageManager"),
        WorkspaceManager = brackets.getModule("view/WorkspaceManager"),
        MainViewManager = brackets.getModule("view/MainViewManager"),
        PreferencesManager = brackets.getModule("preferences/PreferencesManager");

    // Templates
    var panelHTML = require("text!templates/panel.html");

    // jQuery objects
    var $icon,
        $iframe,
        $panel;

    // Other vars
    var currentDoc,
        panel,
        fileExtensions = ["ad", "adoc", "asciidoc", "asc"],
        visible = false,
        usesStem = false,
        realVisibility = false;

    // Define AsciiDoc mode
    require("mode/asciidoc");
    LanguageManager.defineLanguage("asciidoc", {
        name: "AsciiDoc",
        mode: "asciidoc",
        fileExtensions: fileExtensions,
        blockComment: ["////", "////"],
        lineComment: ["//"]
    });

    // Prefs
    var prefs = PreferencesManager.getExtensionPrefs("asciidoc-preview");
    prefs.definePreference("showtitle", "boolean", true);
    prefs.definePreference("numbered", "boolean", false);
    prefs.definePreference("mjax", "boolean", false);
    prefs.definePreference("autosync", "boolean", false);
    prefs.definePreference("updatesave", "boolean", false);
    prefs.definePreference("theme", "string", "asciidoctor");
    prefs.definePreference("safemode", "string", "safe");
    prefs.definePreference("basedir", "string", "");
    prefs.definePreference("imagesdir", "string", "");
    prefs.definePreference("defaultdir", "string", "");
    prefs.definePreference("doctype", "string", "article");

    // Webworker for AscciDoc into HTML conversion
    var converterWorker = new Worker(ExtensionUtils.getModulePath(module, "lib/converter-worker.js"));
    // assembly of final HTML page
    var output = require("lib/output"),
        // utils for handling syncing between editor an preview panes
        syncEdit = require("lib/sync"),
        // common utils
        utils = require("lib/utils"),
        htmlExporter = require("lib/exporter"),
        settingsPanel = require("lib/settings");

    // time needed for the latest conversion in ms
    var lastDuration = 500;
    // timestamp when conversion started
    var conversionStart = 0;
    // current editing location info in generated HTML
    var previewLocationInfo = null,
        outline = null,
        docDirChanged = false,
        updateOnSave = prefs.get("updatesave"),
        autosync = prefs.get("autosync");

    // (based on code in brackets.js)
    function handleLinkClick(e) {
        // Check parents too, in case link has inline formatting tags
        var node = e.target,
            url;
        while (node) {
            if (node.tagName === "A") {
                url = node.getAttribute("href");
                if (url) {
                    if (!url.match(/^#/)) {
                        NativeApp.openURLInDefaultBrowser(url);
                    } else if (url.match(/^#goto_/)) {
                        // if URL contains special #goto_ fragment identifier,
                        // use line number to jump to this line in document editor.
                        jumpToLine(parseInt(url.substr(6), 10) - 1);
                    }
                }
                e.preventDefault();
                break;
            }
            node = node.parentElement;
        }
        // Close settings dropdown, if open
        settingsPanel.hide();
    }

    function isDocDirChanged() {
        return docDirChanged;
    }

    /**
     * Jump to specified line in source editor. Centers
     * line in view.
     */
    function jumpToLine(line) {
        var editor = EditorManager.getCurrentFullEditor();
        editor.setCursorPos(line, 0, true);
        editor.focus();

        var codeMirror = editor._codeMirror;
        codeMirror.addLineClass(line, "wrap", "flash");
        window.setTimeout(function () {
            codeMirror.removeLineClass(line, "wrap", "flash");
        }, 1000);
    }

    function loadDoc(doc, preserveScrollPos) {
        if (doc && visible && $iframe) {
            var docText = utils.stripYamlFrontmatter(doc.getText()),
                scrollPos = 0;

            if (preserveScrollPos) {
                var body = $iframe.contents()[0].body;
                if (body !== null) {
                    scrollPos = body.scrollTop;
                }
            } else {
                scrollPos = 0;
                previewLocationInfo = null;
            }

            var defaultAttributes = 'icons=font@ ' +
                                    'platform=opal platform-opal ' +
                                    'env=browser env-browser ' +
                                    'sectids ' + // force generation of section ids
                                    'source-highlighter=highlight.js@ ';
            var numbered = prefs.get("numbered") ? 'numbered' : 'numbered!';
            var showtitle = prefs.get("showtitle") ? 'showtitle' : 'showtitle!';
            var safemode = prefs.get("safemode") || "safe";
            var doctype = prefs.get("doctype") || "article";

            // baseDir will be used as the base URL to retrieve include files via Ajax requests
            var baseDir = prefs.get("basedir") || utils.getDefaultBaseDir(doc);

            var attributes = defaultAttributes.concat(' ')
                .concat(numbered).concat(' ')
                .concat(showtitle);

            // imagesDir will be used as the base URL to retrieve images
            var imagesDir =  prefs.get("imagesdir");
            if (imagesDir) {
                attributes += ' imagesDir=' + utils.toUrl(imagesDir);
            }

            // Check if directories were overridden in settings panel
            // and post a warning dialog if the current document directory changed.

            var defBaseDir = utils.normalizePath(utils.getDefaultBaseDir(doc));
            docDirChanged = !utils.pathEqual(prefs.get("defaultdir"), defBaseDir);
            if (docDirChanged) {
                prefs.set("defaultdir", defBaseDir);
                prefs.save();
            }

            // structure to pass docText, options, and attributes.
            var data = {
                docText: docText,
                // current working directory
                cwd: FileUtils.getDirectoryPath(window.location.href),
                // Asciidoctor options
                basedir: FileUtils.stripTrailingSlash(baseDir),
                safemode: safemode,
                doctype: doctype,
                header_footer: false,
                // Asciidoctor attributes
                attributes: attributes
            };

            if (lastDuration >= 500 || !preserveScrollPos) {
               displaySpinner(true);
            }

            // perform conversion in worker thread
            conversionStart = new Date().getTime();
            converterWorker.postMessage(data);

            converterWorker.onmessage = function (e) {
                lastDuration = e.data.duration;
                outline = e.data.outline;
                usesStem = e.data.stem;

                var theme = prefs.get("theme");
                if (theme === "default") { // recover from deprecated setting
                    theme = "asciidoctor";
                }

                var $locButton = $("#asciidoc-sync-location-button");
                if (outline) {
                    $locButton.show();
                    updatePreviewLocation();
                } else {
                    $locButton.hide();
                }

                if (autosync) {
                    var pos = syncEdit.getTopPos($iframe[0], previewLocationInfo);
                    if (pos) {
                        scrollPos = pos;
                    }
                }

                var html = output.createPage(e.data, utils.toUrl(baseDir) + '/', scrollPos, prefs);
                $iframe.attr("srcdoc", html);
                conversionStart = 0;
                displaySpinner(false);
            };

            $iframe.load(function () {

                var dirsDefined = prefs.get("imagesdir") !== '' || prefs.get("basedir") !== '';
                if (isDocDirChanged() && dirsDefined) {
                    settingsPanel.showWarning($panel, prefs);
                } else {
                    settingsPanel.hideWarning();
                }

                // Open external browser when links are clicked
                // (similar to what brackets.js does - but attached to the iframe's document)
                $iframe[0].contentDocument.body.addEventListener("click", handleLinkClick, true);

                if (usesStem && prefs.get("mjax") && !this.contentWindow.MathJax) {
                    prefs.set("mjax", false);
                    alert("'MathJax' could not be accessed online and is also not available from cache. " +
                          "You are either working offline or access to the internet failed. " +
                          "Rendering of mathematical expressions has been switched off.");
                }
            });
        }
    }

    var timer;

    function documentChange(e) {
        if (updateOnSave) {
            return;
        }

        // throttle updates
        if (timer) {
            window.clearTimeout(timer);
        }

        // Estimate timeout based on time needed for
        // actual document conversion. Never longer than
        // 5000 ms.
        var timeout = 150;
        var currentTime = new Date().getTime();

        if (conversionStart > 0) {
            timeout = Math.min(lastDuration - currentTime + conversionStart, 5000);
            if (timeout < 150) {
                timeout = 150;
            }
        }

        timer = window.setTimeout(function () {
            timer = null;
            loadDoc(e.target, true);
        }, timeout);
    }

    function resizeIframe() {
        if (visible && $iframe) {
            var iframeWidth = panel.$panel.innerWidth();
            $iframe.attr("width", iframeWidth + "px");
        }
    }

    function updateSettings() {
        // Save preferences
        prefs.save();
        updateOnSave = prefs.get("updatesave");
        autosync = prefs.get("autosync");
        // Re-render
        loadDoc(currentDoc, true);
    }

    function setPanelVisibility(isVisible) {
        if (isVisible === realVisibility) {
            return;
        }

        realVisibility = isVisible;
        if (isVisible) {
            if (!panel) {
                $panel = $(panelHTML);
                $iframe = $panel.find("#panel-asciidoc-preview-frame");

                panel = WorkspaceManager.createBottomPanel("asciidoc-preview-panel", $panel);
                $panel.on("panelResizeUpdate", function (e, newSize) {
                    $iframe.attr("height", newSize);
                });
                $iframe.attr("height", $panel.height());

                window.setTimeout(resizeIframe);
                // create settings panel
                settingsPanel.create($panel, prefs, updateSettings);

                // attach handler to sync-location-button
                $("#asciidoc-sync-location-button")
                    .click(function () {
                         updatePreviewLocation(true);
                    });

                // attach handler to export-file-button
                $("#asciidoc-export-file-button")
                    .click(function () {
                         htmlExporter.execute(currentDoc, prefs, displaySpinner);
                    });
            }
            loadDoc(DocumentManager.getCurrentDocument());
            $icon.toggleClass("active");
            panel.show();
        } else {
            $icon.toggleClass("active");
            panel.hide();
        }
    }

    function updateOnSaveHandler(event, entry) {
        if (realVisibility && updateOnSave && entry && currentDoc && entry.fullPath === currentDoc.file.fullPath) {
            loadDoc(currentDoc, true);
        }
    }

    // React to user manually changing the language of the file
    // to AsciiDoc from the status bar
    function languageChanged(e, oldLanguage, newLanguage) {
        if (newLanguage.getMode() === "asciidoc" || oldLanguage.getMode() === "asciidoc") {
            currentDocChangedHandler();
        }
    }

    function currentDocChangedHandler() {
        var doc = DocumentManager.getCurrentDocument();

        // listen to language changes initiated by the user
        $(doc).off("languageChanged", languageChanged);
        $(doc).on("languageChanged", languageChanged);

        if (currentDoc) {
            $(currentDoc).off("change", documentChange);
            currentDoc = null;
        }

        if (doc && doc.getLanguage().getMode() === "asciidoc") {
            currentDoc = doc;
            $(currentDoc).on("change", documentChange);
            $icon.css({
                display: "block"
            });
            settingsPanel.setDocDir(utils.getDefaultBaseDir(currentDoc));
            setPanelVisibility(visible);
            loadDoc(doc);
        } else {
            $icon.css({
                display: "none"
            });
            setPanelVisibility(false);
        }
    }

    function toggleVisibility() {
        visible = !visible;
        setPanelVisibility(visible);
    }

    /**
     * Updates global variable previewLocationInfo with information
     * corresponding to the current position of the text cursor.
     *
     * @param {Boolean} sync if true, scrolls corresponding positions
     *                       of preview pane and text cursor position into view.
     */
    function updatePreviewLocation(sync) {
        var editor = EditorManager.getCurrentFullEditor();
        var cursor = editor.getCursorPos();
        if (outline && cursor) {
            // store current editing location info with respect to HTML
            previewLocationInfo = syncEdit.findLocationInfo(outline, cursor.line + 1);
            if (previewLocationInfo) {
                previewLocationInfo.lineno = cursor.line + 1;
            }
            if (sync) {
                var topPos = syncEdit.getTopPos($iframe[0], previewLocationInfo);
                $iframe[0].contentWindow.scrollTo(0, topPos);
                editor.setCursorPos(cursor, true);
                editor.focus();
            }
        }
    }

    /**
     * Shows or hides a busy indicator
     * @param {Boolean} show display indicator on true, hide on false
     */
    function displaySpinner(show) {
        var $spinner = $("#asciidoc-busy-spinner");

        if (show) {
            $spinner.show();
        } else {
            $spinner.hide();
        }
    }

    // Insert CSS for this extension
    ExtensionUtils.loadStyleSheet(module, "styles/AsciidocPreview.css");

    // Add toolbar icon
    $icon = $("<a>")
        .attr({
            id: "asciidoc-preview-icon",
            href: "#"
        })
        .css({
            display: "none"
        })
        .click(toggleVisibility)
        .appendTo($("#main-toolbar .buttons"));

    // Add a document change handler
    MainViewManager.on("currentFileChange", currentDocChangedHandler);
    // Detect if file changed on disk
    FileSystem.on("change", updateOnSaveHandler);

    // Listen for resize events
    WorkspaceManager.on("workspaceUpdateLayout", resizeIframe);
    $("#sidebar").on("panelCollapsed panelExpanded panelResizeUpdate", resizeIframe);
    // currentDocumentChange is *not* called for the initial document. Use
    // appReady() to set initial state.
    AppInit.appReady(function () {
        currentDocChangedHandler();
    });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs'),
    isutf8 = require('isutf8'),
    program = require('commander'),
    typograf = new (require('../dist/typograf'))(),
    modes = ['digit', 'name', 'default'],
    langs = ['en', 'ru'];

program
    .version(require('../package.json').version)
    .usage('[options] <file>')
    .option('-d, --disable <rules>', 'disable rules (separated by commas)')
    .option('-e, --enable <rules>', 'enable rules (separated by commas)')
    .option('-l, --lang <lang>', 'set language rules: ' + '"' + langs.join('", "') + '"')
    .option('--mode <mode>', 'HTML entities as: "digit" -  , "name" - &nbsp, "default" - UTF-8 symbols')
    .parse(process.argv);

function getRules(str) {
    return (str || '').split(/,|;/);
}

function printText(text) {
    process.stdout.write(typograf
        .disable(getRules(program.disable))
        .enable(getRules(program.enable))
        .execute(text, {lang: program.lang, mode: program.mode}));
}

if(process.stdin.isTTY && !program.args.length) {
    program.help();
}

if(!program.lang) {
    console.error('Error: required parameter lang.');
    process.exit(1);
}

if(langs.indexOf(program.lang) === -1) {
    console.error('Error: language "' + program.lang + '" is not supported.');
    process.exit(1);
}

if(modes.indexOf(program.mode || 'default') === -1) {
    console.error('Error: mode "' + program.mode + '" is not supported.');
    process.exit(1);
}

var file = program.args[0],
    buf = '';

if(process.stdin.isTTY) {
    if(fs.existsSync(file) && fs.statSync(file).isFile()) {
        buf = fs.readFileSync(file);
        if(isutf8(buf)) {
            printText(buf);
        } else {
            console.error(file + ': is not utf-8');
            process.exit(1);
        }
    } else {
        console.error(file + ': no such file');
        process.exit(1);
    }

    process.exit(0);
} else {
    process.stdin.setEncoding('utf8');

    process.stdin.on('readable', function() {
        var chunk = process.stdin.read();
        if(chunk !== null) {
            buf += chunk;
        }
    });

    process.stdin.on('end', function() {
        printText(buf);
        process.exit(0);
    });
}
<commit_msg>Рефакторинг<commit_after>#!/usr/bin/env node

var fs = require('fs'),
    isutf8 = require('isutf8'),
    program = require('commander'),
    Typograf = require('../dist/typograf'),
    typograf = new Typograf(),
    langs = Typograf._langs,
    modes = ['digit', 'name', 'default'];

program
    .version(require('../package.json').version)
    .usage('[options] <file>')
    .option('-d, --disable <rules>', 'disable rules (separated by commas)')
    .option('-e, --enable <rules>', 'enable rules (separated by commas)')
    .option('-l, --lang <lang>', 'set language rules: ' + '"' + langs.join('", "') + '"')
    .option('--mode <mode>', 'HTML entities as: "digit" -  , "name" - &nbsp, "default" - UTF-8 symbols')
    .parse(process.argv);

function getRules(str) {
    return (str || '').split(/,|;/);
}

function printText(text) {
    process.stdout.write(typograf
        .disable(getRules(program.disable))
        .enable(getRules(program.enable))
        .execute(text, {lang: program.lang, mode: program.mode}));
}

if(process.stdin.isTTY && !program.args.length) {
    program.help();
}

if(!program.lang) {
    console.error('Error: required parameter lang.');
    process.exit(1);
}

if(langs.indexOf(program.lang) === -1) {
    console.error('Error: language "' + program.lang + '" is not supported.');
    process.exit(1);
}

if(modes.indexOf(program.mode || 'default') === -1) {
    console.error('Error: mode "' + program.mode + '" is not supported.');
    process.exit(1);
}

var file = program.args[0],
    buf = '';

if(process.stdin.isTTY) {
    if(fs.existsSync(file) && fs.statSync(file).isFile()) {
        buf = fs.readFileSync(file);
        if(isutf8(buf)) {
            printText(buf);
        } else {
            console.error(file + ': is not utf-8');
            process.exit(1);
        }
    } else {
        console.error(file + ': no such file');
        process.exit(1);
    }

    process.exit(0);
} else {
    process.stdin.setEncoding('utf8');

    process.stdin.on('readable', function() {
        var chunk = process.stdin.read();
        if(chunk !== null) {
            buf += chunk;
        }
    });

    process.stdin.on('end', function() {
        printText(buf);
        process.exit(0);
    });
}
<|endoftext|>