<commit_before>var defaultAppearance = {};
defaultAppearance.clip = "none";
defaultAppearance.pointColor = [1, 0, 0];
defaultAppearance.lineColor = [0, 0, 1];
defaultAppearance.pointSize = 5;
defaultAppearance.lineSize = 1;
defaultAppearance.alpha = 1;
defaultAppearance.overhangLine = 1.1;
defaultAppearance.overhangSeg = 1;
defaultAppearance.dimDependent = 1;
defaultAppearance.fontFamily = "sans-serif";

function setDefaultAppearance(obj) {
    var key;
    for (key in obj)
        if (obj[key] !== null)
            defaultAppearance[key] = obj[key];
}
if (instanceInvocationArguments.defaultAppearance)
    setDefaultAppearance(instanceInvocationArguments.defaultAppearance);

function csinit(gslp) {

    // establish defaults for geoOps
    Object.keys(geoOps).forEach(function(opName) {
        var op = geoOps[opName];
        if (op.updatePosition !== undefined && op.stateSize === undefined)
            op.stateSize = 0;
    });

    //Main Data:
    //args          The arguments of the operator
    //type          The operator
    //kind          L,P,C, wird automatisch zugeordnet

    //Relevant fields for appearance:
    //color
    //size
    //alpha
    //overhang
    //clip
    //visible       zum ein und ausblenden
    //isshowing     das wird durch den Konstruktionsbaum vererbt
    //movable

    csgeo.gslp = gslp;

    csgeo.csnames = {}; //Lookup für elemente mit über Namen

    var k, l, f, el, op;
    var totalStateSize = 0;

    csgeo.points = [];
    csgeo.lines = [];
    csgeo.conics = [];
    csgeo.free = [];
    var ctp = 0;
    var ctf = 0;
    var ctl = 0;
    var ctc = 0;
    var dropped = {};

    // Das ist für alle gleich
    for (k = 0; k < gslp.length; k++) {
        el = gslp[k];
        var macro = geoMacros[el.type];
        if (macro) {
            var expansion = macro(el).slice();
            // Replace single element gslp[k] with all the elements
            // from expansion, using gslp.splice(k, 1, expansion[0], ...)
            expansion.splice(0, 0, k, 1);
            gslp.splice.apply(gslp, expansion);
            --k; // process the first expanded element
            continue;
        }
        csgeo.csnames[el.name] = el;
        op = geoOps[el.type];
        if (!op) {
            console.error(el);
            console.error("Operation " + el.type + " not implemented yet");
            dropped[el.name] = true;
            gslp.splice(k, 1);
            k--;
            continue;
        }
        if (el.args) {
            for (l = 0; l < el.args.length; ++l) {
                if (dropped.hasOwnProperty(el.args[l]))
                    break;
            }
            if (l < el.args.length) { // we did break
                console.log("Dropping " + el.name +
                    " due to dropped argument " + el.args[l]);
                dropped[el.name] = true;
                gslp.splice(k, 1);
                k--;
                continue;
            }
        }
        el.kind = op.kind;
        el.stateIdx = totalStateSize;
        totalStateSize += op.stateSize;
        el.incidences = [];
        el.isshowing = true;
        el.movable = false;
        if (op.isMovable) {
            el.movable = true;
            csgeo.free[ctf++] = el;
        }

        if (el.kind === "P") {
            csgeo.points[ctp] = el;
            pointDefault(el);
            ctp += 1;
        }
        if (el.kind === "L") {
            csgeo.lines[ctl] = el;
            lineDefault(el);
            ctl += 1;
        }
        if (el.kind === "C") {
            csgeo.conics[ctc] = el;
            lineDefault(el);
            ctc += 1;
        }
        if (el.kind === "S") {
            csgeo.lines[ctl] = el;
            segmentDefault(el);
            ctl += 1;
        }
    }
    stateLastGood = stateIn = stateOut = new Float64Array(totalStateSize);
    // initially, stateIn and stateOut are the same, so that initialize can
    // write some state and updatePosition can immediately use it
    for (k = 0; k < gslp.length; k++) {
        el = gslp[k];
        op = geoOps[el.type];
        tracingInitial = true; // might get reset by initialize
        if (op.initialize) {
            stateInIdx = stateOutIdx = el.stateIdx;
            el.param = op.initialize(el);
            assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully initialized");
        }
        stateInIdx = stateOutIdx = el.stateIdx;
        op.updatePosition(el, false);
        assert(stateInIdx === el.stateIdx + op.stateSize, "State fully consumed");
        assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully updated");
        isShowing(el, op);
    }
    stateLastGood = new Float64Array(totalStateSize);
    stateOut = new Float64Array(totalStateSize);
    stateContinueFromHere();
    tracingInitial = false;
    guessIncidences();
}

// Setzen der Default appearance

function pointDefault(el) {

    if (el.size === undefined) el.size = defaultAppearance.pointSize;
    el.size = CSNumber.real(el.size);
    if (el.type !== "Free") {
        el.color = List.realVector(el.color || defaultAppearance.pointColor);
        el.color = List.scalmult(CSNumber.real(defaultAppearance.dimDependent), el.color);
    } else {
        el.color = List.realVector(el.color || defaultAppearance.pointColor);
    }
    if (el.alpha === undefined) el.alpha = defaultAppearance.alpha;
    el.alpha = CSNumber.real(el.alpha);

    if (el.drawtrace) {
        if (typeof el.tracedim === "undefined") el.tracedim = 1;
        if (typeof el.tracelength === "undefined") el.tracelength = 100;
        if (typeof el.traceskip === "undefined") el.traceskip = 1;
        el._traces = new Array(el.tracelength);
        el._traces_index = 0;
        el._traces_tick = 0;
    }
}

function lineDefault(el) {
    if (el.size === undefined) el.size = defaultAppearance.lineSize;
    el.size = CSNumber.real(el.size);
    el.color = List.realVector(el.color || defaultAppearance.lineColor);
    if (el.alpha === undefined) el.alpha = defaultAppearance.alpha;
    el.alpha = CSNumber.real(el.alpha);
    el.clip = General.string(el.clip || defaultAppearance.clip);
    if (el.overhang === undefined)
        el.overhang = defaultAppearance.overhangLine;
    el.overhang = CSNumber.real(el.overhang);
    if (el.dashtype)
        el.dashtype = General.wrap(el.dashtype);
}

function segmentDefault(el) {
    if (el.overhang === undefined)
        el.overhang = defaultAppearance.overhangSeg;
    lineDefault(el);
    el.clip = General.string("end");
}

// TODO: Use this in csinit to avoid code duplication
function addElement(el) {
    console.log(el.name);

    if (csgeo.csnames[el.name] !== undefined) {
        console.log("Element name '" + el.name + "' already exists");

        // TODO Update position of existing element does not work :-(
        var existingEl = csgeo.csnames[el.name];
        existingEl.pos = el.pos;

        stateContinueFromHere();
        updateCindy();

        return {
            'ctype': 'geo',
            'value': existingEl
        };
    }

    csgeo.gslp.push(el);
    csgeo.csnames[el.name] = el;
    var totalStateSize = stateLastGood.length;
    var op = geoOps[el.type];
    el.kind = op.kind;
    el.stateIdx = totalStateSize;
    totalStateSize += op.stateSize;
    el.incidences = [];
    el.isshowing = true;
    el.movable = false;

    if (op.isMovable) {
        el.movable = true;
        csgeo.free.push(el);
    }

    if (el.kind === "P") {
        csgeo.points.push(el);
        pointDefault(el);
    }
    if (el.kind === "L") {
        csgeo.lines.push(el);
        lineDefault(el);
    }
    if (el.kind === "C") {
        csgeo.conics.push(el);
        lineDefault(el);
    }
    if (el.kind === "S") {
        csgeo.lines.push(el);
        segmentDefault(el);
    }

    if (true || op.stateSize !== 0) {
        var prevState = stateLastGood;
        stateLastGood = stateIn = stateOut = new Float64Array(totalStateSize);
        stateLastGood.set(prevState); // make new state a copy of old state
        // initially, stateIn and stateOut are the same, so that initialize can
        // write some state and updatePosition can immediately use it
        if (op.initialize) {
            tracingInitial = true;
            stateInIdx = stateOutIdx = el.stateIdx;
            el.param = op.initialize(el);
            assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully initialized");
            tracingInitial = false;
        }
        stateInIdx = stateOutIdx = el.stateIdx;
        op.updatePosition(el, false);
        assert(stateInIdx === el.stateIdx + op.stateSize, "State fully consumed");
        assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully updated");
        stateLastGood = new Float64Array(totalStateSize);
        stateOut = new Float64Array(totalStateSize);
    } else {
        // Do the updatePosition call with correct state handling around it.
    }
    stateContinueFromHere();
    isShowing(el, op);

    geoDependantsCache = {};
    //guessIncidences();
}

function onSegment(p, s) { //TODO was ist mit Fernpunkten
    // TODO das ist eine sehr teure implementiereung
    // Geht das einfacher?
    var el1 = csgeo.csnames[s.args[0]].homog;
    var el2 = csgeo.csnames[s.args[1]].homog;
    var elm = p.homog;

    var x1 = CSNumber.div(el1.value[0], el1.value[2]);
    var y1 = CSNumber.div(el1.value[1], el1.value[2]);
    var x2 = CSNumber.div(el2.value[0], el2.value[2]);
    var y2 = CSNumber.div(el2.value[1], el2.value[2]);
    var xm = CSNumber.div(elm.value[0], elm.value[2]);
    var ym = CSNumber.div(elm.value[1], elm.value[2]);

    if (CSNumber._helper.isAlmostReal(x1) &&
        CSNumber._helper.isAlmostReal(y1) &&
        CSNumber._helper.isAlmostReal(x2) &&
        CSNumber._helper.isAlmostReal(y2) &&
        CSNumber._helper.isAlmostReal(xm) &&
        CSNumber._helper.isAlmostReal(ym)) {
        x1 = x1.value.real;
        y1 = y1.value.real;
        x2 = x2.value.real;
        y2 = y2.value.real;
        xm = xm.value.real;
        ym = ym.value.real;
        var d12 = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        var d1m = Math.sqrt((x1 - xm) * (x1 - xm) + (y1 - ym) * (y1 - ym));
        var d2m = Math.sqrt((x2 - xm) * (x2 - xm) + (y2 - ym) * (y2 - ym));
        var dd = d12 - d1m - d2m;
        return dd * dd < 0.000000000000001;

    }
    return false;

}

function isShowing(el, op) {
    el.isshowing = true;
    if (el.args) {
        for (var i = 0; i < el.args.length; i++) {
            if (!csgeo.csnames[el.args[i]].isshowing) {
                el.isshowing = false;
                return;
            }
        }
    }
    /*    if (el.kind==="P" ||el.kind==="L"){

            if(!List.helper.isAlmostReal(el.homog)){
                el.isshowing=false;
                return;
            }
        }*/

    if (op.visiblecheck) {
        op.visiblecheck(el);
    }

}

var geoDependantsCache = {};

function getGeoDependants(mover) {
    var deps = geoDependantsCache[mover.name];
    if (deps) return deps;
    var depSet = {};
    var k = 0;
    deps = [];
    depSet[mover.name] = mover;
    var gslp = csgeo.gslp;
    for (var i = 0; i < gslp.length; ++i) {
        var el = gslp[i];
        var args = el.args;
        if (!args) continue;
        for (var j = 0; j < args.length; ++j) {
            var arg = args[j];
            if (depSet.hasOwnProperty(arg)) {
                depSet[el.name] = el;
                deps[k++] = el;
            }
        }
    }
    geoDependantsCache[mover.name] = deps;
    /*
    console.log("getGeoDependants(" + mover.name + ") := [" +
                deps.map(function(el) { return el.name; }).join(",") + "]");
    */
    return deps;
}

function guessIncidences() {

    var gslp = csgeo.gslp;
    for (var i = 0; i < csgeo.lines.length; i++) {
        var l = csgeo.lines[i];
        for (var j = 0; j < csgeo.points.length; j++) {
            var p = csgeo.points[j];
            var pn = List.scaldiv(List.abs(p.homog), p.homog);
            var ln = List.scaldiv(List.abs(l.homog), l.homog);
            var prod = CSNumber.abs(List.scalproduct(pn, ln));
            if (prod.value.real < 0.0000000000001) {
                p.incidences.push(l.name);
                l.incidences.push(p.name);

            }

        }
    }

}
<commit_msg>Move existing point to given location when creating points<commit_after>var defaultAppearance = {};
defaultAppearance.clip = "none";
defaultAppearance.pointColor = [1, 0, 0];
defaultAppearance.lineColor = [0, 0, 1];
defaultAppearance.pointSize = 5;
defaultAppearance.lineSize = 1;
defaultAppearance.alpha = 1;
defaultAppearance.overhangLine = 1.1;
defaultAppearance.overhangSeg = 1;
defaultAppearance.dimDependent = 1;
defaultAppearance.fontFamily = "sans-serif";

function setDefaultAppearance(obj) {
    var key;
    for (key in obj)
        if (obj[key] !== null)
            defaultAppearance[key] = obj[key];
}
if (instanceInvocationArguments.defaultAppearance)
    setDefaultAppearance(instanceInvocationArguments.defaultAppearance);

function csinit(gslp) {

    // establish defaults for geoOps
    Object.keys(geoOps).forEach(function(opName) {
        var op = geoOps[opName];
        if (op.updatePosition !== undefined && op.stateSize === undefined)
            op.stateSize = 0;
    });

    //Main Data:
    //args          The arguments of the operator
    //type          The operator
    //kind          L,P,C, wird automatisch zugeordnet

    //Relevant fields for appearance:
    //color
    //size
    //alpha
    //overhang
    //clip
    //visible       zum ein und ausblenden
    //isshowing     das wird durch den Konstruktionsbaum vererbt
    //movable

    csgeo.gslp = gslp;

    csgeo.csnames = {}; //Lookup für elemente mit über Namen

    var k, l, f, el, op;
    var totalStateSize = 0;

    csgeo.points = [];
    csgeo.lines = [];
    csgeo.conics = [];
    csgeo.free = [];
    var ctp = 0;
    var ctf = 0;
    var ctl = 0;
    var ctc = 0;
    var dropped = {};

    // Das ist für alle gleich
    for (k = 0; k < gslp.length; k++) {
        el = gslp[k];
        var macro = geoMacros[el.type];
        if (macro) {
            var expansion = macro(el).slice();
            // Replace single element gslp[k] with all the elements
            // from expansion, using gslp.splice(k, 1, expansion[0], ...)
            expansion.splice(0, 0, k, 1);
            gslp.splice.apply(gslp, expansion);
            --k; // process the first expanded element
            continue;
        }
        csgeo.csnames[el.name] = el;
        op = geoOps[el.type];
        if (!op) {
            console.error(el);
            console.error("Operation " + el.type + " not implemented yet");
            dropped[el.name] = true;
            gslp.splice(k, 1);
            k--;
            continue;
        }
        if (el.args) {
            for (l = 0; l < el.args.length; ++l) {
                if (dropped.hasOwnProperty(el.args[l]))
                    break;
            }
            if (l < el.args.length) { // we did break
                console.log("Dropping " + el.name +
                    " due to dropped argument " + el.args[l]);
                dropped[el.name] = true;
                gslp.splice(k, 1);
                k--;
                continue;
            }
        }
        el.kind = op.kind;
        el.stateIdx = totalStateSize;
        totalStateSize += op.stateSize;
        el.incidences = [];
        el.isshowing = true;
        el.movable = false;
        if (op.isMovable) {
            el.movable = true;
            csgeo.free[ctf++] = el;
        }

        if (el.kind === "P") {
            csgeo.points[ctp] = el;
            pointDefault(el);
            ctp += 1;
        }
        if (el.kind === "L") {
            csgeo.lines[ctl] = el;
            lineDefault(el);
            ctl += 1;
        }
        if (el.kind === "C") {
            csgeo.conics[ctc] = el;
            lineDefault(el);
            ctc += 1;
        }
        if (el.kind === "S") {
            csgeo.lines[ctl] = el;
            segmentDefault(el);
            ctl += 1;
        }
    }
    stateLastGood = stateIn = stateOut = new Float64Array(totalStateSize);
    // initially, stateIn and stateOut are the same, so that initialize can
    // write some state and updatePosition can immediately use it
    for (k = 0; k < gslp.length; k++) {
        el = gslp[k];
        op = geoOps[el.type];
        tracingInitial = true; // might get reset by initialize
        if (op.initialize) {
            stateInIdx = stateOutIdx = el.stateIdx;
            el.param = op.initialize(el);
            assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully initialized");
        }
        stateInIdx = stateOutIdx = el.stateIdx;
        op.updatePosition(el, false);
        assert(stateInIdx === el.stateIdx + op.stateSize, "State fully consumed");
        assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully updated");
        isShowing(el, op);
    }
    stateLastGood = new Float64Array(totalStateSize);
    stateOut = new Float64Array(totalStateSize);
    stateContinueFromHere();
    tracingInitial = false;
    guessIncidences();
}

// Setzen der Default appearance

function pointDefault(el) {

    if (el.size === undefined) el.size = defaultAppearance.pointSize;
    el.size = CSNumber.real(el.size);
    if (el.type !== "Free") {
        el.color = List.realVector(el.color || defaultAppearance.pointColor);
        el.color = List.scalmult(CSNumber.real(defaultAppearance.dimDependent), el.color);
    } else {
        el.color = List.realVector(el.color || defaultAppearance.pointColor);
    }
    if (el.alpha === undefined) el.alpha = defaultAppearance.alpha;
    el.alpha = CSNumber.real(el.alpha);

    if (el.drawtrace) {
        if (typeof el.tracedim === "undefined") el.tracedim = 1;
        if (typeof el.tracelength === "undefined") el.tracelength = 100;
        if (typeof el.traceskip === "undefined") el.traceskip = 1;
        el._traces = new Array(el.tracelength);
        el._traces_index = 0;
        el._traces_tick = 0;
    }
}

function lineDefault(el) {
    if (el.size === undefined) el.size = defaultAppearance.lineSize;
    el.size = CSNumber.real(el.size);
    el.color = List.realVector(el.color || defaultAppearance.lineColor);
    if (el.alpha === undefined) el.alpha = defaultAppearance.alpha;
    el.alpha = CSNumber.real(el.alpha);
    el.clip = General.string(el.clip || defaultAppearance.clip);
    if (el.overhang === undefined)
        el.overhang = defaultAppearance.overhangLine;
    el.overhang = CSNumber.real(el.overhang);
    if (el.dashtype)
        el.dashtype = General.wrap(el.dashtype);
}

function segmentDefault(el) {
    if (el.overhang === undefined)
        el.overhang = defaultAppearance.overhangSeg;
    lineDefault(el);
    el.clip = General.string("end");
}

// TODO: Use this in csinit to avoid code duplication
function addElement(el) {
    console.log(el.name);

    if (csgeo.csnames[el.name] !== undefined) {
        console.log("Element name '" + el.name + "' already exists");

        var existingEl = csgeo.csnames[el.name];
        movepointscr(existingEl, el.pos, "homog");

        return {
            'ctype': 'geo',
            'value': existingEl
        };
    }

    csgeo.gslp.push(el);
    csgeo.csnames[el.name] = el;
    var totalStateSize = stateLastGood.length;
    var op = geoOps[el.type];
    el.kind = op.kind;
    el.stateIdx = totalStateSize;
    totalStateSize += op.stateSize;
    el.incidences = [];
    el.isshowing = true;
    el.movable = false;

    if (op.isMovable) {
        el.movable = true;
        csgeo.free.push(el);
    }

    if (el.kind === "P") {
        csgeo.points.push(el);
        pointDefault(el);
    }
    if (el.kind === "L") {
        csgeo.lines.push(el);
        lineDefault(el);
    }
    if (el.kind === "C") {
        csgeo.conics.push(el);
        lineDefault(el);
    }
    if (el.kind === "S") {
        csgeo.lines.push(el);
        segmentDefault(el);
    }

    if (true || op.stateSize !== 0) {
        var prevState = stateLastGood;
        stateLastGood = stateIn = stateOut = new Float64Array(totalStateSize);
        stateLastGood.set(prevState); // make new state a copy of old state
        // initially, stateIn and stateOut are the same, so that initialize can
        // write some state and updatePosition can immediately use it
        if (op.initialize) {
            tracingInitial = true;
            stateInIdx = stateOutIdx = el.stateIdx;
            el.param = op.initialize(el);
            assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully initialized");
            tracingInitial = false;
        }
        stateInIdx = stateOutIdx = el.stateIdx;
        op.updatePosition(el, false);
        assert(stateInIdx === el.stateIdx + op.stateSize, "State fully consumed");
        assert(stateOutIdx === el.stateIdx + op.stateSize, "State fully updated");
        stateLastGood = new Float64Array(totalStateSize);
        stateOut = new Float64Array(totalStateSize);
    } else {
        // Do the updatePosition call with correct state handling around it.
    }
    stateContinueFromHere();
    isShowing(el, op);

    geoDependantsCache = {};
    //guessIncidences();
}

function onSegment(p, s) { //TODO was ist mit Fernpunkten
    // TODO das ist eine sehr teure implementiereung
    // Geht das einfacher?
    var el1 = csgeo.csnames[s.args[0]].homog;
    var el2 = csgeo.csnames[s.args[1]].homog;
    var elm = p.homog;

    var x1 = CSNumber.div(el1.value[0], el1.value[2]);
    var y1 = CSNumber.div(el1.value[1], el1.value[2]);
    var x2 = CSNumber.div(el2.value[0], el2.value[2]);
    var y2 = CSNumber.div(el2.value[1], el2.value[2]);
    var xm = CSNumber.div(elm.value[0], elm.value[2]);
    var ym = CSNumber.div(elm.value[1], elm.value[2]);

    if (CSNumber._helper.isAlmostReal(x1) &&
        CSNumber._helper.isAlmostReal(y1) &&
        CSNumber._helper.isAlmostReal(x2) &&
        CSNumber._helper.isAlmostReal(y2) &&
        CSNumber._helper.isAlmostReal(xm) &&
        CSNumber._helper.isAlmostReal(ym)) {
        x1 = x1.value.real;
        y1 = y1.value.real;
        x2 = x2.value.real;
        y2 = y2.value.real;
        xm = xm.value.real;
        ym = ym.value.real;
        var d12 = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        var d1m = Math.sqrt((x1 - xm) * (x1 - xm) + (y1 - ym) * (y1 - ym));
        var d2m = Math.sqrt((x2 - xm) * (x2 - xm) + (y2 - ym) * (y2 - ym));
        var dd = d12 - d1m - d2m;
        return dd * dd < 0.000000000000001;

    }
    return false;

}

function isShowing(el, op) {
    el.isshowing = true;
    if (el.args) {
        for (var i = 0; i < el.args.length; i++) {
            if (!csgeo.csnames[el.args[i]].isshowing) {
                el.isshowing = false;
                return;
            }
        }
    }
    /*    if (el.kind==="P" ||el.kind==="L"){

            if(!List.helper.isAlmostReal(el.homog)){
                el.isshowing=false;
                return;
            }
        }*/

    if (op.visiblecheck) {
        op.visiblecheck(el);
    }

}

var geoDependantsCache = {};

function getGeoDependants(mover) {
    var deps = geoDependantsCache[mover.name];
    if (deps) return deps;
    var depSet = {};
    var k = 0;
    deps = [];
    depSet[mover.name] = mover;
    var gslp = csgeo.gslp;
    for (var i = 0; i < gslp.length; ++i) {
        var el = gslp[i];
        var args = el.args;
        if (!args) continue;
        for (var j = 0; j < args.length; ++j) {
            var arg = args[j];
            if (depSet.hasOwnProperty(arg)) {
                depSet[el.name] = el;
                deps[k++] = el;
            }
        }
    }
    geoDependantsCache[mover.name] = deps;
    /*
    console.log("getGeoDependants(" + mover.name + ") := [" +
                deps.map(function(el) { return el.name; }).join(",") + "]");
    */
    return deps;
}

function guessIncidences() {

    var gslp = csgeo.gslp;
    for (var i = 0; i < csgeo.lines.length; i++) {
        var l = csgeo.lines[i];
        for (var j = 0; j < csgeo.points.length; j++) {
            var p = csgeo.points[j];
            var pn = List.scaldiv(List.abs(p.homog), p.homog);
            var ln = List.scaldiv(List.abs(l.homog), l.homog);
            var prod = CSNumber.abs(List.scalproduct(pn, ln));
            if (prod.value.real < 0.0000000000001) {
                p.incidences.push(l.name);
                l.incidences.push(p.name);

            }

        }
    }

}
<|endoftext|>


<commit_before>/*
 * CS3283/4 dataModifier.js
 * This acts as a facade class for modifying and update data for storage facade
 *
 */

import dataAdd from './dataAdd';
import dataDelete from './dataDelete';
import dataUpdate from './dataUpdate';
import exceptions from '../exceptions';

export default class dataModifier {
  static constructor() {}

  static deleteAllEntities() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteAllEntities(0)
        .then(data => resolve(data))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static createNewFile(organizationId, filePath, folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataAdd.createNewFile(organizationId, filePath, folderId)
        .then(fileId => resolve(fileId))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static createNewFolder(organizationId, folderPath, folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataAdd.createNewFolder(organizationId, folderPath, folderId)
        .then(data => resolve(true))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static saveFile(fileId, file) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataUpdate.saveFile(fileId, file)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static deleteFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteFile(fileId)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static deleteFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteFolder(folderId)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }
}
<commit_msg>Remove paramenter in dataDelete.deleteAllEntities in dataModifier.js<commit_after>/*
 * CS3283/4 dataModifier.js
 * This acts as a facade class for modifying and update data for storage facade
 *
 */

import dataAdd from './dataAdd';
import dataDelete from './dataDelete';
import dataUpdate from './dataUpdate';
import exceptions from '../exceptions';

export default class dataModifier {
  static constructor() {}

  static deleteAllEntities() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteAllEntities()
        .then(data => resolve(data))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static createNewFile(organizationId, filePath, folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataAdd.createNewFile(organizationId, filePath, folderId)
        .then(fileId => resolve(fileId))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static createNewFolder(organizationId, folderPath, folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataAdd.createNewFolder(organizationId, folderPath, folderId)
        .then(data => resolve(true))
        .catch(sqlErr => reject(sqlErr))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static saveFile(fileId, file) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataUpdate.saveFile(fileId, file)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static deleteFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteFile(fileId)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }

  static deleteFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        dataDelete.deleteFolder(folderId)
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  }
}
<|endoftext|>


<commit_before>(function (angular) {
    'use strict';

    //// JavaScript Code ////
    function nodeFilter() {

        var showByName = function(query,node_name) {
            if (!query) {
                return true;
            }
            return node_name.toLowerCase().indexOf(query.toLowerCase()) !== -1;
        };

        var showByMonitor = function(selectedMonitor,monitors) {
            if (selectedMonitor === 'All Nodes') {
                return true;
            }

            if (selectedMonitor === 'Any Alert') {
                return monitors.length > 0;
            }

            return monitors.indexOf(selectedMonitor) !== -1;
        };

        var showByTags = function(tags,nodeTags) {
            for (var i=0; i < tags.length ; i++) {
                if (!tags[i].state) {
                    continue;
                }
                if (tags[i].state === 1) {
                    if (nodeTags.indexOf(tags[i].name) === -1) {
                        return false;
                    }
                } else {
                    if (nodeTags.indexOf(tags[i].name) !== -1) {
                        return false;
                    }
                }
            }
            return true;
        };

        return function(node, query, monitor, tags) {
            return (showByName(query, node.alias) && showByMonitor(monitor, node.failed_monitors) && showByTags(tags,node.tags));
        };
    }

    //// Angular Code ////
    angular.module('codeine').filter('nodeFilter', nodeFilter);

})(angular);

<commit_msg>issue #27 - fix filtered nodes by colletor<commit_after>(function (angular) {
    'use strict';

    //// JavaScript Code ////
    function nodeFilter() {

        var showByName = function(query,node_name) {
            if (!query) {
                return true;
            }
            return node_name.toLowerCase().indexOf(query.toLowerCase()) !== -1;
        };

        var showByMonitor = function(selectedMonitor,monitors) {
            if (selectedMonitor === 'All Nodes') {
                return true;
            }

            if (selectedMonitor === 'Any Alert') {
                return monitors.length > 0;
            }

            return monitors.indexOf(selectedMonitor) !== -1;
        };
        var showByCollectors = function(selectedMonitor,collectors) {
            if (selectedMonitor === 'All Nodes') {
                return true;
            }

            if (selectedMonitor === 'Any Alert') {
                return collectors.length > 0;
            }

            return collectors.indexOf(selectedMonitor) !== -1;
        };

        var showByTags = function(tags,nodeTags) {
            for (var i=0; i < tags.length ; i++) {
                if (!tags[i].state) {
                    continue;
                }
                if (tags[i].state === 1) {
                    if (nodeTags.indexOf(tags[i].name) === -1) {
                        return false;
                    }
                } else {
                    if (nodeTags.indexOf(tags[i].name) !== -1) {
                        return false;
                    }
                }
            }
            return true;
        };

        return function(node, query, monitor, tags) {
            return (showByName(query, node.alias) &&
            (showByMonitor(monitor, node.failed_monitors) || showByCollectors(monitor, node.failed_collectors)) &&
            showByTags(tags,node.tags));
        };
    }

    //// Angular Code ////
    angular.module('codeine').filter('nodeFilter', nodeFilter);

})(angular);

<|endoftext|>


<commit_before>/* jslint node: true */
'use strict';

const stringFormat      = require('./string_format.js');
const { Errors }        = require('./enig_error.js');

//  deps
const pty               = require('node-pty');
const decode            = require('iconv-lite').decode;
const createServer      = require('net').createServer;
const paths             = require('path');
const sanatizeFilename  = require('sanitize-filename');

module.exports = class Door {
    constructor(client) {
        this.client     = client;
        this.restored   = false;
    }

    prepare(ioType, cb) {
        this.io = ioType;

        //  we currently only have to do any real setup for 'socket'
        if('socket' !== ioType) {
            return cb(null);
        }

        this.sockServer = createServer(conn => {
            this.sockServer.getConnections( (err, count) => {

                //  We expect only one connection from our DOOR/emulator/etc.
                if(!err && count <= 1) {
                    this.client.term.output.pipe(conn);

                    conn.on('data', this.doorDataHandler.bind(this));

                    conn.once('end', () => {
                        return this.restoreIo(conn);
                    });

                    conn.once('error', err => {
                        this.client.log.info( { error : err.message }, 'Door socket server connection');
                        return this.restoreIo(conn);
                    });
                }
            });
        });

        this.sockServer.listen(0, () => {
            return cb(null);
        });
    }

    run(exeInfo, cb) {
        this.encoding = (exeInfo.encoding || 'cp437').toLowerCase();

        if('socket' === this.io && !this.sockServer) {
            return cb(Errors.UnexpectedState('Socket server is not running'));
        }

        const cwd = exeInfo.cwd || paths.dirname(exeInfo.cmd);

        const formatObj = {
            dropFile        : exeInfo.dropFile,
            dropFilePath    : exeInfo.dropFilePath,
            node            : exeInfo.node.toString(),
            srvPort         : this.sockServer ? this.sockServer.address().port.toString() : '-1',
            userId          : this.client.user.userId.toString(),
            userName        : sanatizeFilename(this.client.user.username),
            userNameRaw     : this.client.user.username,
            cwd             : cwd,
        };

        const args = exeInfo.args.map( arg => stringFormat(arg, formatObj) );

        const door = pty.spawn(exeInfo.cmd, args, {
            cols        : this.client.term.termWidth,
            rows        : this.client.term.termHeight,
            cwd         : cwd,
            env         : exeInfo.env,
            encoding    : null, //  we want to handle all encoding ourself
        });

        if('stdio' === this.io) {
            this.client.log.debug('Using stdio for door I/O');

            this.client.term.output.pipe(door);

            door.on('data', this.doorDataHandler.bind(this));

            door.once('close', () => {
                return this.restoreIo(door);
            });
        } else if('socket' === this.io) {
            this.client.log.debug(
                { srvPort : this.sockServer.address().port, srvSocket : this.sockServerSocket },
                'Using temporary socket server for door I/O'
            );
        }

        door.once('exit', exitCode => {
            this.client.log.info( { exitCode : exitCode }, 'Door exited');

            if(this.sockServer) {
                this.sockServer.close();
            }

            //  we may not get a close
            if('stdio' === this.io) {
                this.restoreIo(door);
            }

            door.removeAllListeners();

            return cb(null);
        });
    }

    doorDataHandler(data) {
        this.client.term.write(decode(data, this.encoding));
    }

    restoreIo(piped) {
        if(!this.restored && this.client.term.output) {
            this.client.term.output.unpipe(piped);
            this.client.term.output.resume();
            this.restored = true;
        }
    }
};
<commit_msg>Better handling of 'socket' io<commit_after>/* jslint node: true */
'use strict';

const stringFormat      = require('./string_format.js');
const { Errors }        = require('./enig_error.js');

//  deps
const pty               = require('node-pty');
const decode            = require('iconv-lite').decode;
const createServer      = require('net').createServer;
const paths             = require('path');
const sanatizeFilename  = require('sanitize-filename');

module.exports = class Door {
    constructor(client) {
        this.client     = client;
        this.restored   = false;
    }

    prepare(ioType, cb) {
        this.io = ioType;

        //  we currently only have to do any real setup for 'socket'
        if('socket' !== ioType) {
            return cb(null);
        }

        this.sockServer = createServer(conn => {
            conn.once('end', () => {
                return this.restoreIo(conn);
            });

            conn.once('error', err => {
                this.client.log.info( { error : err.message }, 'Door socket server connection');
                return this.restoreIo(conn);
            });

            this.sockServer.getConnections( (err, count) => {
                //  We expect only one connection from our DOOR/emulator/etc.
                if(!err && count <= 1) {
                    this.client.term.output.pipe(conn);
                    conn.on('data', this.doorDataHandler.bind(this));
                }
            });
        });

        this.sockServer.listen(0, () => {
            return cb(null);
        });
    }

    run(exeInfo, cb) {
        this.encoding = (exeInfo.encoding || 'cp437').toLowerCase();

        if('socket' === this.io && !this.sockServer) {
            return cb(Errors.UnexpectedState('Socket server is not running'));
        }

        const cwd = exeInfo.cwd || paths.dirname(exeInfo.cmd);

        const formatObj = {
            dropFile        : exeInfo.dropFile,
            dropFilePath    : exeInfo.dropFilePath,
            node            : exeInfo.node.toString(),
            srvPort         : this.sockServer ? this.sockServer.address().port.toString() : '-1',
            userId          : this.client.user.userId.toString(),
            userName        : sanatizeFilename(this.client.user.username),
            userNameRaw     : this.client.user.username,
            cwd             : cwd,
        };

        const args = exeInfo.args.map( arg => stringFormat(arg, formatObj) );

        const door = pty.spawn(exeInfo.cmd, args, {
            cols        : this.client.term.termWidth,
            rows        : this.client.term.termHeight,
            cwd         : cwd,
            env         : exeInfo.env,
            encoding    : null, //  we want to handle all encoding ourself
        });

        if('stdio' === this.io) {
            this.client.log.debug('Using stdio for door I/O');

            this.client.term.output.pipe(door);

            door.on('data', this.doorDataHandler.bind(this));

            door.once('close', () => {
                return this.restoreIo(door);
            });
        } else if('socket' === this.io) {
            this.client.log.debug(
                { srvPort : this.sockServer.address().port, srvSocket : this.sockServerSocket },
                'Using temporary socket server for door I/O'
            );
        }

        door.once('exit', exitCode => {
            this.client.log.info( { exitCode : exitCode }, 'Door exited');

            if(this.sockServer) {
                this.sockServer.close();
            }

            //  we may not get a close
            if('stdio' === this.io) {
                this.restoreIo(door);
            }

            door.removeAllListeners();

            return cb(null);
        });
    }

    doorDataHandler(data) {
        this.client.term.write(decode(data, this.encoding));
    }

    restoreIo(piped) {
        if(!this.restored && this.client.term.output) {
            this.client.term.output.unpipe(piped);
            this.client.term.output.resume();
            this.restored = true;
        }
    }
};
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var restify = require('restify')
   , mongoose = require('mongoose')
   , clientSessions = require("client-sessions")
   , toobusy = require('toobusy');

module.exports = function (app, config, sessionKey) {

   app.use(restify.acceptParser(app.acceptable));
   app.use(restify.authorizationParser());
   app.use(restify.dateParser());
   app.use(restify.queryParser());
   app.use(restify.jsonp());
   app.use(restify.gzipResponse());
   app.use(restify.bodyParser());

   // send a 503 if the server is too busy
    app.use(function(req, res, next) {
      if (toobusy()) res.send(503, "I'm busy right now, sorry.");
      else next();
    });

   app.use(clientSessions({
     cookieName: 'session',    // defaults to session_state
     secret: sessionKey,
     // true session duration:
     // will expire after duration (ms)
     // from last session.reset() or
     // initial cookie.
     duration: config.session_timeout, // defaults to 20 minutes, in ms
     // refresh every access
     path: '/',
     httpOnly: true, // defaults to true
     secure: false   // defaults to false
   }));

    app.use(restify.throttle({
      burst: 100,
      rate: 50,
      ip: true,
      overrides: {
        '192.168.1.1': {
           rate: 0,        // unlimited
           burst: 0
         }
      }
    }));
   app.use(restify.conditionalRequest());
}
<commit_msg>Having an issue with toobusy module<commit_after>
/**
 * Module dependencies.
 */

var restify = require('restify')
   , mongoose = require('mongoose')
   // , toobusy = require('toobusy')
   , clientSessions = require("client-sessions");

module.exports = function (app, config, sessionKey) {

   app.use(restify.acceptParser(app.acceptable));
   app.use(restify.authorizationParser());
   app.use(restify.dateParser());
   app.use(restify.queryParser());
   app.use(restify.jsonp());
   app.use(restify.gzipResponse());
   app.use(restify.bodyParser());

   // send a 503 if the server is too busy
   /*
    app.use(function(req, res, next) {
      if (toobusy()) res.send(503, "I'm busy right now, sorry.");
      else next();
    });
*/

   app.use(clientSessions({
     cookieName: 'session',    // defaults to session_state
     secret: sessionKey,
     // true session duration:
     // will expire after duration (ms)
     // from last session.reset() or
     // initial cookie.
     duration: config.session_timeout, // defaults to 20 minutes, in ms
     // refresh every access
     path: '/',
     httpOnly: true, // defaults to true
     secure: false   // defaults to false
   }));

    app.use(restify.throttle({
      burst: 100,
      rate: 50,
      ip: true,
      overrides: {
        '192.168.1.1': {
           rate: 0,        // unlimited
           burst: 0
         }
      }
    }));
   app.use(restify.conditionalRequest());
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you 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.
 *
 */
/**
 * The resource namespace contains methods that are used to load the asset extensions by reading the asset.js
 * @namespace
 * @example
 *          var resources=require('resources').resources;
 *          resources.init();
 * @requires event
 * @requires utils
 * @requires store
 */
var resources = {};
(function(core, resources, artifacts) {
    var log = new Log();
    var getRxtExtensionPath = function(type, options) {
        return options.CONFIG_BASE_PATH + options.EXTENSION_PATH + type;
    };
    var getAssetScriptPath = function(type, options) {
        return getRxtExtensionPath(type, options) + options.ASSET_SCRIPT_PATH;
    };
    var getDefaultAssetScriptPath = function(options) {
        return options.DEFAULT_ASSET_SCRIPT;
    };
    var getDefaultAssetTypeScriptPath = function(options, type) {
        return '/extensions/assets/' + type + '/asset.js';
    };
    var getAssetExtensionPath = function(type) {
        return constants.ASSET_EXTENSION_ROOT + '/' + type;
    };
    var addToConfigs = function(tenantId, type, assetResource) {
        var configs = core.configs(tenantId);
        if (!configs.assetResources) {
            configs.assetResources = {};
        }
        configs.assetResources[type] = assetResource;
    };
    var loadAssetScriptContent = function(path) {
        var file = new File(path);
        var content = '';
        if (!file.isExists()) {
            if (log.isDebugEnabled()) {
                log.debug('Unable to locate default asset script at path ' + path);
            }
            return content;
        }
        try {
            file.open('r');
            content = file.readAll();
        } catch (e) {
            log.error('Unable to read the default asset script.A custom asset script will not be loaded from ' + path);
        } finally {
            file.close();
        }
        return content;
    };
    var loadDefaultAssetScript = function(options, type, assetResource) {
        var content = loadAssetScriptContent(getDefaultAssetScriptPath(options));
        if (content) {
            assetResource = evalAssetScript(content, assetResource, 'default', 'default')
        }
        return assetResource;
    };
    var loadAssetScript = function(options, type, assetResource) {
        var path = getDefaultAssetTypeScriptPath(options, type);
        var content = loadAssetScriptContent(path);
        var defConfiguration = assetResource.configure();
        var ref = require('utils').reflection;
        if (content) {
            assetResource = evalAssetScript(content, assetResource, path, type);
            var ptr = assetResource.configure;
            //The configuration object of the default asset.js needs to be combined with
            //what is defined by the user in per type asset script
            assetResource.configure = function() {
                var configs = defConfiguration; //Assume the user has not defined a configuration
                //If the user has defined some configuration logic
                if (ptr) {
                    var customConfig = ptr();
                    //Combine the configuration
                    ref.copyAllPropValues(customConfig, configs);
                }
                return configs;
            };
        }
        return assetResource;
    };
    var evalAssetScript = function(scriptContent, assetResource, path, type) {
        var module = 'function(asset,log){' + scriptContent + '};';
        var modulePtr = null;
        try {
            modulePtr = eval(module);
        } catch (e) {
            log.error('Unable to evaluate asset script content at  path: ' + path + '.Exception: ' + e);
        }
        if (!modulePtr) {
            return modulePtr;
        }
        try {
            var assetLog = new Log('asset-' + type + '-script');
            modulePtr.call(this, assetResource, assetLog);
        } catch (e) {
            log.error('Unable execute asset script content of ' + path + '.Exception: ' + e);
        }
        return assetResource;
    };
    var buildDefaultResources = function(options, type, assetResource) {
        var asset = {};
        asset.manager = null;
        asset.renderer = null;
        asset.server = null;
        asset.configure = null;
        asset = loadDefaultAssetScript(options, type, asset);
        assetResource._default = asset;
        assetResource.configure = asset.configure;
    };
    var buildAssetResources = function(options, type, assetResource) {
        var asset = {};
        asset.manager = null;
        asset.renderer = null;
        asset.server = null;
        asset.configure = assetResource.configure;
        asset = loadAssetScript(options, type, asset);
        assetResource.manager = asset.manager;
        assetResource.renderer = asset.renderer;
        assetResource.server = asset.server;
        assetResource.configure = asset.configure;
    };
    /**
     * Loads the artifacts found within an asset
     * @param  String type     The asset type
     * @param  Number tenantId The tenant ID
     */
    var loadAssetArtifacts = function(type, tenantId) {
        var path = getAssetExtensionPath(type);
        artifacts.loadDirectory(path, tenantId, type);
    };
    /**
     * Loads the artifacts defined for the default asset type
     * @param  {[type]} options  [description]
     * @param  {[type]} type     [description]
     * @param  {[type]} tenantId [description]
     * @return {[type]}          [description]
     */
    var loadDefaultAssetArtifacts = function(tenantId) {
        loadAssetArtifacts('default', tenantId);
    };
    var loadResources = function(options, tenantId, sysRegistry) {
        var manager = core.rxtManager(tenantId);
        var rxts = manager.listRxtTypes();
        var type;
        var map = {};
        for (var index in rxts) {
            type = rxts[index];
            var asset = {};
            asset.manager = null;
            asset.renderer = null;
            asset.server = null;
            asset.configure = null;
            buildDefaultResources(options, type, asset);
            buildAssetResources(options, type, asset);
            //Perform any rxt mutations
            if (asset.configure) {
                manager.applyMutator(type, asset.configure());
            }
            addToConfigs(tenantId, type, asset);
            //Load any artifacts
            loadAssetArtifacts(type, tenantId);
        }
        loadDefaultAssetArtifacts(tenantId);
    };
    var matchFile = function(fileName,dir){
        var files = dir.listFiles();
        var found = false;
        for(var index = 0 ; (index <  files.length ) && (!found); index++){
            if(files[index].getName() === fileName){
                found = true;
            }
        }
        return found;
    };
    var hasAppScript = function(dir){
        return matchFile('app.js',dir);
    };
    var hasAssetScript = function(dir){
        return matchFile('asset.js',dir);
    };
    var readScriptContent = function(file){
        var content = '';
        try{
            file.open('r');
            content = file.readAll();
        } catch(e){
            log.error('Unable to read contents of '+file.getPath()+' '+file.getName(),e);
        } finally{
            file.close();
        }
        return content;
    };
    var appExtensionPath = function(dir){
        return dir.getPath()+'/app.js';
    };
    var assetExtensionPath = function(dir){
        return dir.getPath()+'/asset.js';
    }
    var evalExtensionScript = function(dir){
        var file = new File(appExtensionPath(dir));
        var content = readScriptContent(file);
        var script = 'function(app,log){' + content + '}';
        var module = {};
        var  l = new Log(file.getName());
        var ptr;
        module.dependencies = [];
        ptr = eval(script);
        ptr.call(this,module,l);
        return module;
    };
    function DefaultAppExtensionMediatorImpl(path){
        this.path = path;
        this.assetExtension = {};
        this.init();
    }
    DefaultAppExtensionMediatorImpl.prototype.init = function(){
        var extensionDir = new File(this.path);
        var scriptFile = new File(assetExtensionPath(extensionDir));
        var content = readScriptContent(scriptFile);
        var extension = {};
        var script = 'function(asset,log) { '+content+' \n } ';
        var l = new Log();
        var ptr = eval(script);
        ptr.call(this,extension,l);
        this.assetExtension = extension || {};
        //log.info(this.assetExtension.renderer().pageDecorators);
    };
    DefaultAppExtensionMediatorImpl.prototype.manager = function(){
        return this.assetExtension.manager;
    };
    DefaultAppExtensionMediatorImpl.prototype.renderer = function(){
        return this.assetExtension.renderer;
    };
    DefaultAppExtensionMediatorImpl.prototype.configs = function(){
        return this.assetExtension.configs;
    };
    DefaultAppExtensionMediatorImpl.prototype.resolveCaramelResources = function(resourcePath,theme,caramelThemeResolver) {
        var file;
        var fullPath = this.path + '/' + resourcePath;
        file = new File(fullPath);
        if(file.isExists()){
            return fullPath;
        }
        return caramelThemeResolver(theme, resourcePath);
    };
    function DefaultAppExtensionMediator(impl) {
        this.impl = impl;
    }
    DefaultAppExtensionMediator.prototype.manager = function() {
        if(!this.impl){
            return null;
        }
        return this.impl.manager();
    };
    DefaultAppExtensionMediator.prototype.renderer = function() {
        if(!this.impl){
            return null;
        }
        return this.impl.renderer();
    };
    DefaultAppExtensionMediator.prototype.configs = function() {
        if(!this.impl){
            return null;
        }
        return this.impl.configs();
    };
    DefaultAppExtensionMediator.prototype.resolveCaramelResources = function(resourcePath,theme,caramelThemeResolver) {
        var file;
        var fullPath = this.path + '/' + resourcePath;
        theme = theme || {};
        caramelThemeResolver = caramelThemeResolver || function(theme,path) { return path};
        if(!this.impl){
            return caramelThemeResolver(theme,path);
        }
        return this.impl.resolveCaramelResources(resourcePath,theme,caramelThemeResolver);
    };

    var loadDefaultAppExtensions = function(){
        //Go through each app extension
        var dirPath = '/extensions/app';
        var dir = new File(dirPath);
        var extensionDir;
        var extensionDirs;
        var extension;
        var dependencies;
        var mediator;
        var mediatorImpl;
        var ignore = false;
        var found = false; //Assume that no default extensions will be found
        log.info('loading default asset app extensions');
        if(!dir.isDirectory()){
            log.error('Unable to read the app extension directory');
            return;
        }
        extensionDirs = dir.listFiles() || [];
        extensionDir;
        for(var index = 0; index < extensionDirs.length ; index++){
            extensionDir = extensionDirs [index];
            log.info('checking extension: '+extensionDir.getName());
            //Check if there is an asset script
            if(hasAppScript(extensionDir)){
                //Get the extension details
                extension = evalExtensionScript(extensionDir);
                dependencies = extension.dependencies || [];
                ignore =  extension.ignoreExtension || false;

                if(((dependencies.indexOf(constants.DEFAULT_APP_EXTENSION)>-1) && (!ignore))&&(found)){
                    log.error('An extension which overrides the default asset extension was already loaded, thus app extension: '+extensionDir.getName()
                        +' will be ignored.Please make sure that there is only one app extension which declares a dependency to "default".');
                }

                //Check if "default" is one of the dependencies
                if(((dependencies.indexOf(constants.DEFAULT_APP_EXTENSION)>-1) && (!ignore))&&(!found)){
                    log.info('found an app extension which overrides the default asset extension: '+extensionDir.getName());
                    found = true;
                    //Build a mediator
                    mediatorImpl = new DefaultAppExtensionMediatorImpl(extensionDir.getPath());
                    mediator = new DefaultAppExtensionMediator(mediatorImpl);
                    core.defaultAppExtensionMediator(mediator);
                }

            }
        }
        log.info('finished loading default asset app extensions');
    };
    var init = function(tenantId) {
        var server = require('store').server;
        var options = server.options();
        if (!options.rxt) {
            log.error('Unable to locate rxt configuation block in provided tenant configuration.Check the configuration file that is the registry');
            throw 'Unable to locate rxt configuation block in provided tenant configuration.Check the configuration file that is the registry';
        }
        options = options.rxt;
        var sysRegistry = server.systemRegistry(tenantId);
        loadResources(options, tenantId, sysRegistry);
        loadDefaultAppExtensions(); //TODO:Add support for tenants
    };
    resources.manager = function(tenantId) {
        init(tenantId);
    };
    /**
     * Initializes the resource module and loads up all asset extensions.This method will internally invoke
     * logic that will first read, then evaluate the asset.js files defined in the asset extension directories.If one is not found
     * for a given asset type it will load the default asset.js located in the default asset extension
     */
    resources.init = function() {
        var event = require('event');
        event.on('tenantLoad', function(tenantId) {
            init(tenantId);
        });
    };
}(core, resources, artifacts));<commit_msg>Implemented overriding configuration through a custom app asset extension<commit_after>/*
 *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you 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.
 *
 */
/**
 * The resource namespace contains methods that are used to load the asset extensions by reading the asset.js
 * @namespace
 * @example
 *          var resources=require('resources').resources;
 *          resources.init();
 * @requires event
 * @requires utils
 * @requires store
 */
var resources = {};
(function(core, resources, artifacts) {
    var log = new Log();
    var getRxtExtensionPath = function(type, options) {
        return options.CONFIG_BASE_PATH + options.EXTENSION_PATH + type;
    };
    var getAssetScriptPath = function(type, options) {
        return getRxtExtensionPath(type, options) + options.ASSET_SCRIPT_PATH;
    };
    var getDefaultAssetScriptPath = function(options) {
        return options.DEFAULT_ASSET_SCRIPT;
    };
    var getDefaultAssetTypeScriptPath = function(options, type) {
        return '/extensions/assets/' + type + '/asset.js';
    };
    var getAssetExtensionPath = function(type) {
        return constants.ASSET_EXTENSION_ROOT + '/' + type;
    };
    var addToConfigs = function(tenantId, type, assetResource) {
        var configs = core.configs(tenantId);
        if (!configs.assetResources) {
            configs.assetResources = {};
        }
        configs.assetResources[type] = assetResource;
    };
    var loadAssetScriptContent = function(path) {
        var file = new File(path);
        var content = '';
        if (!file.isExists()) {
            if (log.isDebugEnabled()) {
                log.debug('Unable to locate default asset script at path ' + path);
            }
            return content;
        }
        try {
            file.open('r');
            content = file.readAll();
        } catch (e) {
            log.error('Unable to read the default asset script.A custom asset script will not be loaded from ' + path);
        } finally {
            file.close();
        }
        return content;
    };
    var loadDefaultAssetScript = function(options, type, assetResource) {
        var content = loadAssetScriptContent(getDefaultAssetScriptPath(options));
        if (content) {
            assetResource = evalAssetScript(content, assetResource, 'default', 'default')
        }
        return assetResource;
    };
    var loadAssetScript = function(options, type, assetResource) {
        var path = getDefaultAssetTypeScriptPath(options, type);
        var content = loadAssetScriptContent(path);
        var defConfiguration = assetResource.configure();
        var ref = require('utils').reflection;
        if (content) {
            assetResource = evalAssetScript(content, assetResource, path, type);
            var ptr = assetResource.configure;
            //The configuration object of the default asset.js needs to be combined with
            //what is defined by the user in per type asset script
            assetResource.configure = function() {
                var configs = defConfiguration; //Assume the user has not defined a configuration
                //If the user has defined some configuration logic
                if (ptr) {
                    var customConfig = ptr();
                    //Combine the configuration
                    ref.copyAllPropValues(customConfig, configs);
                }
                return configs;
            };
        }
        return assetResource;
    };
    var evalAssetScript = function(scriptContent, assetResource, path, type) {
        var module = 'function(asset,log){' + scriptContent + '};';
        var modulePtr = null;
        try {
            modulePtr = eval(module);
        } catch (e) {
            log.error('Unable to evaluate asset script content at  path: ' + path + '.Exception: ' + e);
        }
        if (!modulePtr) {
            return modulePtr;
        }
        try {
            var assetLog = new Log('asset-' + type + '-script');
            modulePtr.call(this, assetResource, assetLog);
        } catch (e) {
            log.error('Unable execute asset script content of ' + path + '.Exception: ' + e);
        }
        return assetResource;
    };
    var buildDefaultResources = function(options, type, assetResource) {
        var asset = {};
        var ref = require('utils').reflection;
        asset.manager = null;
        asset.renderer = null;
        asset.server = null;
        asset.configure = null;
        asset = loadDefaultAssetScript(options, type, asset);
        assetResource._default = asset;
        assetResource.configure = asset.configure;
        var ptr = assetResource.configure;
        assetResource.configure = function() {
            var originalConfigs = ptr();
            var defaultAppExtensionMediator = core.defaultAppExtensionMediator();
            var customDefaultConfigs;
            var temp;
            if (defaultAppExtensionMediator) {
                customDefaultConfigs = defaultAppExtensionMediator.configs() ? defaultAppExtensionMediator.configs() : function() {
                    return {}
                };
                temp = customDefaultConfigs();
                ref.copyAllPropValues(temp, originalConfigs);
            }
            return originalConfigs;
        };
    };
    var buildAssetResources = function(options, type, assetResource) {
        var asset = {};
        asset.manager = null;
        asset.renderer = null;
        asset.server = null;
        asset.configure = assetResource.configure;
        asset = loadAssetScript(options, type, asset);
        assetResource.manager = asset.manager;
        assetResource.renderer = asset.renderer;
        assetResource.server = asset.server;
        assetResource.configure = asset.configure;
    };
    /**
     * Loads the artifacts found within an asset
     * @param  String type     The asset type
     * @param  Number tenantId The tenant ID
     */
    var loadAssetArtifacts = function(type, tenantId) {
        var path = getAssetExtensionPath(type);
        artifacts.loadDirectory(path, tenantId, type);
    };
    /**
     * Loads the artifacts defined for the default asset type
     * @param  {[type]} options  [description]
     * @param  {[type]} type     [description]
     * @param  {[type]} tenantId [description]
     * @return {[type]}          [description]
     */
    var loadDefaultAssetArtifacts = function(tenantId) {
        loadAssetArtifacts('default', tenantId);
    };
    var loadResources = function(options, tenantId, sysRegistry) {
        var manager = core.rxtManager(tenantId);
        var rxts = manager.listRxtTypes();
        var type;
        var map = {};
        for (var index in rxts) {
            type = rxts[index];
            var asset = {};
            asset.manager = null;
            asset.renderer = null;
            asset.server = null;
            asset.configure = null;
            buildDefaultResources(options, type, asset);
            buildAssetResources(options, type, asset);
            //Perform any rxt mutations
            if (asset.configure) {
                manager.applyMutator(type, asset.configure());
            }
            addToConfigs(tenantId, type, asset);
            //Load any artifacts
            loadAssetArtifacts(type, tenantId);
        }
        loadDefaultAssetArtifacts(tenantId);
    };
    var matchFile = function(fileName, dir) {
        var files = dir.listFiles();
        var found = false;
        for (var index = 0;
            (index < files.length) && (!found); index++) {
            if (files[index].getName() === fileName) {
                found = true;
            }
        }
        return found;
    };
    var hasAppScript = function(dir) {
        return matchFile('app.js', dir);
    };
    var hasAssetScript = function(dir) {
        return matchFile('asset.js', dir);
    };
    var readScriptContent = function(file) {
        var content = '';
        try {
            file.open('r');
            content = file.readAll();
        } catch (e) {
            log.error('Unable to read contents of ' + file.getPath() + ' ' + file.getName(), e);
        } finally {
            file.close();
        }
        return content;
    };
    var appExtensionPath = function(dir) {
        return dir.getPath() + '/app.js';
    };
    var assetExtensionPath = function(dir) {
        return dir.getPath() + '/asset.js';
    }
    var evalExtensionScript = function(dir) {
        var file = new File(appExtensionPath(dir));
        var content = readScriptContent(file);
        var script = 'function(app,log){' + content + '}';
        var module = {};
        var l = new Log(file.getName());
        var ptr;
        module.dependencies = [];
        ptr = eval(script);
        ptr.call(this, module, l);
        return module;
    };

    function DefaultAppExtensionMediatorImpl(path) {
        this.path = path;
        this.assetExtension = {};
        this.init();
    }
    DefaultAppExtensionMediatorImpl.prototype.init = function() {
        var extensionDir = new File(this.path);
        var scriptFile = new File(assetExtensionPath(extensionDir));
        var content = readScriptContent(scriptFile);
        var extension = {};
        var script = 'function(asset,log) { ' + content + ' \n } ';
        var l = new Log();
        var ptr = eval(script);
        ptr.call(this, extension, l);
        this.assetExtension = extension || {};
        //log.info(this.assetExtension.renderer().pageDecorators);
    };
    DefaultAppExtensionMediatorImpl.prototype.manager = function() {
        return this.assetExtension.manager;
    };
    DefaultAppExtensionMediatorImpl.prototype.renderer = function() {
        return this.assetExtension.renderer;
    };
    DefaultAppExtensionMediatorImpl.prototype.configs = function() {
        return this.assetExtension.configure;
    };
    DefaultAppExtensionMediatorImpl.prototype.resolveCaramelResources = function(resourcePath, theme, caramelThemeResolver) {
        var file;
        var fullPath = this.path + '/' + resourcePath;
        file = new File(fullPath);
        if (file.isExists()) {
            return fullPath;
        }
        return caramelThemeResolver(theme, resourcePath);
    };

    function DefaultAppExtensionMediator(impl) {
        this.impl = impl;
    }
    DefaultAppExtensionMediator.prototype.manager = function() {
        if (!this.impl) {
            return null;
        }
        return this.impl.manager();
    };
    DefaultAppExtensionMediator.prototype.renderer = function() {
        if (!this.impl) {
            return null;
        }
        return this.impl.renderer();
    };
    DefaultAppExtensionMediator.prototype.configs = function() {
        if (!this.impl) {
            return null;
        }
        return this.impl.configs();
    };
    DefaultAppExtensionMediator.prototype.resolveCaramelResources = function(resourcePath, theme, caramelThemeResolver) {
        var file;
        var fullPath = this.path + '/' + resourcePath;
        theme = theme || {};
        caramelThemeResolver = caramelThemeResolver || function(theme, path) {
            return path
        };
        if (!this.impl) {
            return caramelThemeResolver(theme, path);
        }
        return this.impl.resolveCaramelResources(resourcePath, theme, caramelThemeResolver);
    };
    var loadDefaultAppExtensions = function() {
        //Go through each app extension
        var dirPath = '/extensions/app';
        var dir = new File(dirPath);
        var extensionDir;
        var extensionDirs;
        var extension;
        var dependencies;
        var mediator;
        var mediatorImpl;
        var ignore = false;
        var found = false; //Assume that no default extensions will be found
        log.info('loading default asset app extensions');
        if (!dir.isDirectory()) {
            log.error('Unable to read the app extension directory');
            return;
        }
        extensionDirs = dir.listFiles() || [];
        extensionDir;
        for (var index = 0; index < extensionDirs.length; index++) {
            extensionDir = extensionDirs[index];
            log.info('checking extension: ' + extensionDir.getName());
            //Check if there is an asset script
            if (hasAppScript(extensionDir)) {
                //Get the extension details
                extension = evalExtensionScript(extensionDir);
                dependencies = extension.dependencies || [];
                ignore = extension.ignoreExtension || false;
                if (((dependencies.indexOf(constants.DEFAULT_APP_EXTENSION) > -1) && (!ignore)) && (found)) {
                    log.error('An extension which overrides the default asset extension was already loaded, thus app extension: ' + extensionDir.getName() + ' will be ignored.Please make sure that there is only one app extension which declares a dependency to "default".');
                }
                //Check if "default" is one of the dependencies
                if (((dependencies.indexOf(constants.DEFAULT_APP_EXTENSION) > -1) && (!ignore)) && (!found)) {
                    log.info('found an app extension which overrides the default asset extension: ' + extensionDir.getName());
                    found = true;
                    //Build a mediator
                    mediatorImpl = new DefaultAppExtensionMediatorImpl(extensionDir.getPath());
                    mediator = new DefaultAppExtensionMediator(mediatorImpl);
                    core.defaultAppExtensionMediator(mediator);
                }
            }
        }
        log.info('finished loading default asset app extensions');
    };
    var init = function(tenantId) {
        var server = require('store').server;
        var options = server.options();
        if (!options.rxt) {
            log.error('Unable to locate rxt configuation block in provided tenant configuration.Check the configuration file that is the registry');
            throw 'Unable to locate rxt configuation block in provided tenant configuration.Check the configuration file that is the registry';
        }
        options = options.rxt;
        var sysRegistry = server.systemRegistry(tenantId);
        loadDefaultAppExtensions(); //TODO:Add support for tenants
        loadResources(options, tenantId, sysRegistry);
    };
    resources.manager = function(tenantId) {
        init(tenantId);
    };
    /**
     * Initializes the resource module and loads up all asset extensions.This method will internally invoke
     * logic that will first read, then evaluate the asset.js files defined in the asset extension directories.If one is not found
     * for a given asset type it will load the default asset.js located in the default asset extension
     */
    resources.init = function() {
        var event = require('event');
        event.on('tenantLoad', function(tenantId) {
            init(tenantId);
        });
    };
}(core, resources, artifacts));<|endoftext|>


<commit_before>document.getElementById('search_query_query').addEventListener('keydown', function (e) {
    if (e.keyCode === 13) {
        e.preventDefault();
    }
});
var searchParameters = algoliaConfig.tags ? {
    facets: ['tags'],
    facetsRefinements: {
        tags: [algoliaConfig.tags]
    }
} : {};

var search = instantsearch({
    appId: algoliaConfig.app_id,
    apiKey: algoliaConfig.search_key,
    indexName: algoliaConfig.index_name,
    urlSync: {
        trackedParameters: ['query', 'attribute:*', 'page']
    },
    searchFunction: function(helper) {
        var searchResults = $('#search-container');

        if (helper.state.query === ''
            && helper.state.hierarchicalFacetsRefinements.type === undefined
            && helper.state.hierarchicalFacetsRefinements.tags === undefined
            && algoliaConfig.tags.length == 0
        ) {
            searchResults.addClass('hidden');
        } else {
            searchResults.removeClass('hidden');
        }

        helper.search();
    },
    searchParameters: searchParameters
});

search.addWidget(
    instantsearch.widgets.searchBox({
        container: '#search_query_query',
        magnifier: false,
        reset: false,
        wrapInput: false,
        autofocus: true
    })
);

search.addWidget(
    instantsearch.widgets.hits({
        container: '.search-list',
        transformData: function (hit) {
            if (hit.type === 'virtual-package') {
                hit.virtual = true;
            }

            return hit;
        },
        templates: {
            empty: 'No packages found.',
            item: `

{{ language }}

                {{{ _highlightResult.name.value }}}
                {{#virtual}}
                    (Virtual Package)
                {{/virtual}}

{{{ _highlightResult.description.value }}}

            {{#abandoned}}

                 Abandoned!
                {{#replacementPackage}}
                    See {{ replacementPackage }}
                {{/replacementPackage}}

            {{/abandoned}}

            {{#meta}}

                     {{ meta.downloads_formatted }}
                     {{ meta.favers_formatted }}

            {{/meta}}

`
        },
        cssClasses: {
            root: 'packages',
            item: 'row'
        }
    })
);

search.addWidget(
    instantsearch.widgets.pagination({
        container: '.pagination',
        maxPages: 200,
        scrollTo: false,
        showFirstLast: false,
    })
);

search.addWidget(
    instantsearch.widgets.currentRefinedValues({
        container: '.search-facets-active-filters',
        clearAll: 'before',
        clearsQuery: false,
        cssClasses: {
            clearAll: 'pull-right'
        },
        templates: {
            header: 'Active filters',
            item: function (filter) {
                if ('tags' == filter.attributeName) {
                    return 'tag: ' + filter.name
                } else {
                    return filter.attributeName + ': ' + filter.name
                }
            }
        },
        onlyListedAttributes: true,
    })
);

search.addWidget(
    instantsearch.widgets.menu({
        container: '.search-facets-type',
        attributeName: 'type',
        limit: 15,
        showMore: true,
        templates: {
            header: 'Package type'
        }
    })
);

search.addWidget(
    instantsearch.widgets.menu({
        container: '.search-facets-tags',
        attributeName: 'tags',
        limit: 15,
        showMore: true,
        templates: {
            header: 'Tags'
        }
    })
);

search.start();

if(algoliaConfig.tags !== '') {
    search.helper.once('change', function (e) {
        window.history.replaceState(null, 'title', window.location.pathname);
    });
}
<commit_msg>Move to refinementList to have tags combination<commit_after>document.getElementById('search_query_query').addEventListener('keydown', function (e) {
    if (e.keyCode === 13) {
        e.preventDefault();
    }
});
var searchParameters = algoliaConfig.tags ? {
    disjunctiveFacets: ['tags'],
    disjunctiveFacetsRefinements: {
        tags: [algoliaConfig.tags]
    }
} : {};

var search = instantsearch({
    appId: algoliaConfig.app_id,
    apiKey: algoliaConfig.search_key,
    indexName: algoliaConfig.index_name,
    urlSync: {
        trackedParameters: ['query', 'attribute:*', 'page']
    },
    searchFunction: function(helper) {
        var searchResults = $('#search-container');

        if (helper.state.query === ''
            && helper.state.hierarchicalFacetsRefinements.type === undefined
            && helper.state.disjunctiveFacetsRefinements.tags === undefined
            && algoliaConfig.tags.length == 0
        ) {
            searchResults.addClass('hidden');
        } else {
            searchResults.removeClass('hidden');
        }

        helper.search();
    },
    searchParameters: searchParameters
});

search.addWidget(
    instantsearch.widgets.searchBox({
        container: '#search_query_query',
        magnifier: false,
        reset: false,
        wrapInput: false,
        autofocus: true
    })
);

search.addWidget(
    instantsearch.widgets.hits({
        container: '.search-list',
        transformData: function (hit) {
            if (hit.type === 'virtual-package') {
                hit.virtual = true;
            }

            return hit;
        },
        templates: {
            empty: 'No packages found.',
            item: `

{{ language }}

                {{{ _highlightResult.name.value }}}
                {{#virtual}}
                    (Virtual Package)
                {{/virtual}}

{{{ _highlightResult.description.value }}}

            {{#abandoned}}

                 Abandoned!
                {{#replacementPackage}}
                    See {{ replacementPackage }}
                {{/replacementPackage}}

            {{/abandoned}}

            {{#meta}}

                     {{ meta.downloads_formatted }}
                     {{ meta.favers_formatted }}

            {{/meta}}

`
        },
        cssClasses: {
            root: 'packages',
            item: 'row'
        }
    })
);

search.addWidget(
    instantsearch.widgets.pagination({
        container: '.pagination',
        maxPages: 200,
        scrollTo: false,
        showFirstLast: false,
    })
);

search.addWidget(
    instantsearch.widgets.currentRefinedValues({
        container: '.search-facets-active-filters',
        clearAll: 'before',
        clearsQuery: false,
        cssClasses: {
            clearAll: 'pull-right'
        },
        templates: {
            header: 'Active filters',
            item: function (filter) {
                if ('tags' == filter.attributeName) {
                    return 'tag: ' + filter.name
                } else {
                    return filter.attributeName + ': ' + filter.name
                }
            }
        },
        onlyListedAttributes: true,
    })
);

search.addWidget(
    instantsearch.widgets.menu({
        container: '.search-facets-type',
        attributeName: 'type',
        limit: 15,
        showMore: true,
        templates: {
            header: 'Package type'
        }
    })
);

search.addWidget(
    instantsearch.widgets.refinementList({
        container: '.search-facets-tags',
        attributeName: 'tags',
        limit: 15,
        showMore: true,
        templates: {
            header: 'Tags'
        }
    })
);

search.start();

if(algoliaConfig.tags !== '') {
    search.helper.once('change', function (e) {
        window.history.replaceState(null, 'title', window.location.pathname);
    });
}
<|endoftext|>