<commit_before>YUI.add('pnm-place', function (Y) {

var FLICKR_API_KEY = YUI.namespace('Env.Flickr').API_KEY || '',

    Lang = Y.Lang,
    Place;

Place = Y.Base.create('place', Y.Model, [Y.ModelSync.YQL], {

    idAttribute: 'woeid',
    cache      : new Y.CacheOffline(),

    queries: {
        placeFromId    : 'SELECT * FROM geo.places WHERE woeid={id}',
        placeFromLatLon: 'SELECT * FROM geo.places WHERE woeid ' +
                            'IN (SELECT place.woeid FROM flickr.places ' +
                            'WHERE api_key={api_key} ' +
                            'AND lat={latitude} ' +
                            'AND lon={longitude})'
    },

    buildQuery: function () {
        if (this.isNew()) {
            // assumes we at least have a lat/lon
            return Lang.sub(this.queries.placeFromLatLon, {
                api_key  : FLICKR_API_KEY,
                latitude : this.get('latitude'),
                longitude: this.get('longitude')
            });
        }

        return Lang.sub(this.queries.placeFromId, {id: this.get('id')});
    },

    parse: function (results) {
        if ( ! results) { return; }

        var data     = results.place,
            centroid = data.centroid,
            country  = data.country,
            region   = data.admin1,
            locality = data.locality1;

        return {
            woeid    : data.woeid,
            latitude : centroid.latitude,
            longitude: centroid.longitude,
            country  : country && country.content,
            region   : region && region.content,
            locality : locality && locality.content
        };
    },

    toString: function () {
        var country  = this.get('country'),
            region   = this.get('region'),
            locality = this.get('locality');

        if (locality) {
            return (locality + ', ' + region);
        }

        if (region) {
            return (region + ', ' + country);
        }

        return country || '';
    }

}, {

    ATTRS: {
        woeid    : {},
        latitude : {},
        longitude: {},
        country  : {},
        region   : {},
        locality : {}
    }

});

Y.namespace('PNM').Place = Place;

}, '0.5.0', {
    requires: [
        'cache-offline',
        'gallery-model-sync-yql',
        'model',
        'yql'
    ]
});
<commit_msg>Update Place model to only request specific fields from YQL.<commit_after>YUI.add('pnm-place', function (Y) {

var FLICKR_API_KEY = YUI.namespace('Env.Flickr').API_KEY || '',

    Lang = Y.Lang,
    Place;

Place = Y.Base.create('place', Y.Model, [Y.ModelSync.YQL], {

    idAttribute: 'woeid',
    cache      : new Y.CacheOffline(),

    queries: {
        placeFromId    : 'SELECT {attrs} FROM geo.places WHERE woeid={id}',
        placeFromLatLon: 'SELECT {attrs} FROM geo.places WHERE woeid ' +
                            'IN (SELECT place.woeid FROM flickr.places ' +
                            'WHERE api_key={api_key} ' +
                            'AND lat={latitude} ' +
                            'AND lon={longitude})'
    },

    buildQuery: function () {
        if (this.isNew()) {
            // assumes we at least have a lat/lon
            return Lang.sub(this.queries.placeFromLatLon, {
                api_key  : FLICKR_API_KEY,
                latitude : this.get('latitude'),
                longitude: this.get('longitude'),
                attrs    : Place.YQL_ATTRS
            });
        }

        return Lang.sub(this.queries.placeFromId, {
            id   : this.get('id'),
            attrs: Place.YQL_ATTRS
        });
    },

    parse: function (results) {
        if ( ! results) { return; }

        var data     = results.place,
            centroid = data.centroid,
            country  = data.country,
            region   = data.admin1,
            locality = data.locality1;

        return {
            woeid    : data.woeid,
            latitude : centroid.latitude,
            longitude: centroid.longitude,
            country  : country && country.content,
            region   : region && region.content,
            locality : locality && locality.content
        };
    },

    toString: function () {
        var country  = this.get('country'),
            region   = this.get('region'),
            locality = this.get('locality');

        if (locality) {
            return (locality + ', ' + region);
        }

        if (region) {
            return (region + ', ' + country);
        }

        return country || '';
    }

}, {

    ATTRS: {
        woeid    : {},
        latitude : {},
        longitude: {},
        country  : {},
        region   : {},
        locality : {}
    },

    YQL_ATTRS: ['woeid', 'centroid', 'country', 'admin1', 'locality1']

});

Y.namespace('PNM').Place = Place;

}, '0.5.0', {
    requires: [
        'cache-offline',
        'gallery-model-sync-yql',
        'model',
        'yql'
    ]
});
<|endoftext|>


<commit_before>//This code is heavily based on code from
//http://mbostock.github.io/d3/talk/20111018/tree.html

d3.selection.prototype.moveToFront = function() {
  return this.each(function(){
    this.parentNode.appendChild(this);
  });
};

var scaleSize = d3.scale.linear()
    .domain([1,100])
    .range([80,4000]);

var markers = [
   { id: 0, name: 'circle', path: 'M 0, 0  m -5, 0  a 5,5 0 1,0 10,0  a 5,5 0 1,0 -10,0', viewbox: '-6 -6 12 12' },
   { id: 1, name: 'square', path: 'M 0,0 m -5,-5 L 5,-5 L 5,5 L -5,5 Z', viewbox: '-5 -5 10 10' },
   { id: 2, name: 'arrow', path: 'M 0,0 m -5,-5 L 5,0 L -5,5 Z', viewbox: '-5 -5 10 10' },
   { id: 2, name: 'stub', path: 'M 0,0 m -1,-5 L 1,-5 L 1,5 L -1,5 Z', viewbox: '-1 -5 2 10' }
];

d3.bst = function (d3, canvasID, w, h) {

//    d3.select("#reset").on("click", reset);

    //defaults
    var bst = {},
        mw = 0, mh = 0,
        w = w || 1280,
        h = h || 800,
        i = 0,
        tree,
        depthStep = 75,
        canvasID = canvasID, //canvasID must have hash like "#vis" or "#canvas"
        root;
    var svgGroup, defs;

    var drag = d3.behavior.drag()
        //.origin(function(d) {  });
        .on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended);

    // error when zooming directly after pan on OSX
    // https://github.com/mbostock/d3/issues/2205
    var zoom = d3.behavior.zoom()
        .scaleExtent([0.1,5])
        //.on("dblclick.zoom",null)
        .on("zoom", zoomHandler);
        //.on("mousedown.zoom",null);
        zoom.scale(1);
    zoom.translate([(w/2), 0]);
    allZoom.push(zoom);

    bst.init = function (_w, _h, _mw, _mh, ds) {
        mw = _mw;
        mh = _mh;
        w = _w;
        h = _h;
        depthStep = ds;
        return bst;
    };

    //boilerplate stuff
    bst.make = function (data) {
        tree = d3.layout.tree()
            .nodeSize([50, 50]);
        diagonal = d3.svg.diagonal();
            //.projection(function(d, i) { if(i >= 0) return [d.x + 50, d.y]; else return [d.x, d.y] });

        vis = d3.select(canvasID).append("svg:svg")
            .attr("width", w )
            .attr("height", h )
            .attr("id", "svg" + canvasID.substr(4))
            .classed("svg", true)
            //.attr("height", h * 2)
            .call(zoom)
            .call(drag);

        svgGroup = vis.append("svg:g")
            .attr("transform", "translate(" + (mh + (w/2)) + "," + mw + ")");
        allSVG.push(svgGroup);

        defs = vis.append('svg:defs');

       var marker = defs.selectAll('marker')
         .data(markers)
         .enter()
         .append('svg:marker')
           .attr('id', function(d){ return 'marker_' + d.name; })
           .attr("markerUnits", "userSpaceOnUse")
           .attr('markerHeight', 5)
           .attr('markerWidth', 5)
           //.attr('markerUnits', 'strokeWidth')
           .attr('orient', 'auto')
           .attr('refX', 0)
           .attr('refY', 0)
           .attr('viewBox', function(d){ return d.viewbox; })
           .append('svg:path')
             .attr('d', function(d){ return d.path; })
             .attr('fill', function(d,i) { return "#ccc"; });

        root = data;
        root.x0 = 0;
        root.y0 = (w) / 2;

        update(root);
    };

    return bst;

    function toggle (d) {

        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
    }

    function update(source) {
        var duration = 600;

        // Compute the new tree layout.
        var nodes = tree.nodes(root).reverse();

        // Normalize for fixed-depth.
        nodes.forEach(function(d) { d.y = 50 + d.depth * depthStep; });
        // nodes.forEach(function(d) { d.x = -1 * d.x; }); // -1 here flips. Fixed for new representation

        // Update the nodes…
        var node = svgGroup.selectAll("g.node")
            .data(nodes, function(d) { return d.id || (d.id = ++i); })
            .on("mouseover", mouseover)
            .on("mouseout", mouseout);

        // Enter any new nodes at the parent's previous position.
        var nodeEnter = node.enter().append("svg:g")
            .attr("class", "node")
            // .attr("d", d3.svg.symbol()
            //     .type(function(d) { return d.shape || "rect"; })
            //     .size( 1 )
            // )
            .attr("transform", function(d) {
                return "translate(" + source.x0 + "," + source.y0 + ")";
            })
            .on("click", function(d) { toggle(d); update(d); })
            .on("mouseover", mouseover)
            .on("mouseout", mouseout);

        nodeEnter.append('path')
            .attr("d", d3.svg.symbol()
                .type(function(d) { return d.shape || "rect"; })
                .size(function(d) { return scaleSize(d.size) || 1; })
            )
            .style("fill", function(d) {
                return BridgesVisualizer.getColor(d.color) || "#fff";
            })
            .style("opacity", function(d) {
                return d.role ? 0 : ( d.opacity || 1 );
            });

        nodeEnter.append("svg:text")
            .classed("nodeLabel", true)
            .attr("dy", ".35em")
            .attr("x", "20px")
            .attr("y",  "-7px")
            .attr("text-anchor", "start")
            .style("opacity", 0.0)
            .text( function( d ) { return d.name; } );

       if(nodes[0].key !== null) {
           nodeEnter.append("svg:text")
            .attr("dy", ".35em")
            .attr("x", "-8px")
            .attr("y",  "-15px")
            .attr("text-anchor", "start")
            // .style("display", "none")
            .text(function(d) { return d.key || ""; } );
       }

        // Transition nodes to their new position.
        var nodeUpdate = node.transition()
            .duration(duration)
            .attr("transform", function(d) {
                // var dx = d.x-15;
                var dx = d.x;
                return "translate(" + dx + "," + d.y + ")";
            });

        // Transition exiting nodes to the parent's new position.
        var nodeExit = node.exit().transition()
            .duration(duration)
            .attr("transform", function(d) {
                return "translate(" + (source.x) + "," + source.y + ")";
            })
            .remove();

        // Update the links…
        var link = svgGroup.selectAll("path.link")
            .data(tree.links(nodes), function(d) {
                return d.target.id;
            });

        // Enter any new links at the parent's previous position.
        link.enter().insert("svg:path", "g")
            .attr("class", "link")
            .style("stroke", function(d,i) {
                if(d.target.linkProperties) return BridgesVisualizer.getColor(d.target.linkProperties.color);
                return "#ccc";
            })
            .style("stroke-width", function(d,i) {
                if(d.target.linkProperties) return BridgesVisualizer.strokeWidthRange(d.target.linkProperties.thickness);
                return BridgesVisualizer.strokeWidthRange(1);
            })
            .style("opacity", function(d,i) {
                if(d.target.name == "NULL") return 0;
                return d.opacity || 1;
            })
            .attr("d", function(d) {
              var o = {x: source.x0, y: source.y0};
              return diagonal({source: o, target: o});
            })
            .attr('marker-start', function(d,i){ return 'url(#marker_circle)'; })
            .attr('marker-end', function(d,i){ return 'url(#marker_arrow)'; })
            .transition()
            .duration(duration)
            .attr("d", diagonal);

        // Transition links to their new position.
        link.transition()
            .duration(duration)
            .attr("d", diagonal);
        // Transition exiting nodes to the parent's new position.
        link.exit().transition()
            .duration(duration)
            .attr("d", function(d) {
              var o = {x: source.x, y: source.y};
              return diagonal({source: o, target: o});
            })
            .remove();
        // Stash the old positions for transition.
        nodes.forEach(function(d) {
            d.x0 = d.x;
            d.y0 = d.y;
        });

        // Add line breaks to node labels
        svgGroup.selectAll('text.nodeLabel').each(insertLineBreaks);
    }

// Function to add line breaks to node labels/names
function insertLineBreaks (d){
	var el = d3.select(this);
    var words = d3.select(this).text().split('\n');

    // if(words.length > 1) {
        el.text('');

        for (var i = 0; i < words.length; i++) {
            var tspan = el.append('tspan').text(words[i]);
            if (i > 0)
            tspan.attr('x',"20").attr('dy','15');
            //tspan.attr('x',"0").attr('dy','15');
        }
    // }
}

//    // zoom function
function zoomHandler() {
    //console.log("zoom");
    svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

function dragstarted() {
    //console.log("dragstart");
    //d3.event.sourceEvent.stopPropagation();
    d3.select(this).classed("dragging", true);
}

function dragged() {
     //console.log("dragging");
    //svgGroup.attr("transform", "translate(" + d3.event.translate + ")");
}
function dragended() {
//    console.log("dragend");
    d3.select(this).classed("dragging", false);
}

function mouseover() {
    // d3.select(this).select("text").transition()
    //     .duration(750)
    //     .style("display","block");
    BridgesVisualizer.textMouseover(this, "tree");
    // var el = d3.select(this);
    // el.moveToFront();
}

function mouseout() {
    // d3.select(this).select("text").transition()
    //     .duration(750)
    //     .style("display","none");
    BridgesVisualizer.textMouseout(this);
}

};
<commit_msg>Bringing tree vis up to date<commit_after>//This code is heavily based on code from
//http://mbostock.github.io/d3/talk/20111018/tree.html

d3.selection.prototype.moveToFront = function() {
  return this.each(function(){
    this.parentNode.appendChild(this);
  });
};

var scaleSize = d3.scale.linear()
    .domain([1,100])
    .range([80,4000]);

var markers = [
   { id: 0, name: 'circle', path: 'M 0, 0  m -5, 0  a 5,5 0 1,0 10,0  a 5,5 0 1,0 -10,0', viewbox: '-6 -6 12 12' },
   { id: 1, name: 'square', path: 'M 0,0 m -5,-5 L 5,-5 L 5,5 L -5,5 Z', viewbox: '-5 -5 10 10' },
   { id: 2, name: 'arrow', path: 'M 0,0 m -5,-5 L 5,0 L -5,5 Z', viewbox: '-5 -5 10 10' },
   { id: 2, name: 'stub', path: 'M 0,0 m -1,-5 L 1,-5 L 1,5 L -1,5 Z', viewbox: '-1 -5 2 10' }
];

d3.bst = function (d3, canvasID, w, h) {

    //defaults
    var bst = {},
        mw = 0, mh = 0,
        w = w || 1280,
        h = h || 800,
        i = 0,
        tree,
        depthStep = 75,
        canvasID = canvasID, //canvasID must have hash like "#vis" or "#canvas"
        root;
    var visID = canvasID.substr(4);
    var svgGroup, defs;
    var finalTranslate = BridgesVisualizer.defaultTransforms.list.translate;
    var finalScale =  BridgesVisualizer.defaultTransforms.list.scale;

    var transformObject = BridgesVisualizer.getTransformObjectFromCookie(visID);
    if(transformObject){
        finalTranslate = transformObject.translate;
        finalScale = transformObject.scale;
    }

    var drag = d3.behavior.drag()
        .on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended);

    var zoom = d3.behavior.zoom()
        .translate(finalTranslate)
        .scale(finalScale)
        .scaleExtent([0.1,5])
        .on("zoom", zoomHandler);
    allZoom.push(zoom);

    bst.init = function (_w, _h, _mw, _mh, ds) {
        mw = _mw;
        mh = _mh;
        w = _w;
        h = _h;
        depthStep = ds;
        return bst;
    };

    //boilerplate stuff
    bst.make = function (data) {
        tree = d3.layout.tree()
            .nodeSize([50, 50]);
        diagonal = d3.svg.diagonal();
            //.projection(function(d, i) { if(i >= 0) return [d.x + 50, d.y]; else return [d.x, d.y] });

        vis = d3.select(canvasID).append("svg:svg")
            .attr("width", w )
            .attr("height", h )
            .attr("id", "svg" + canvasID.substr(4))
            .classed("svg", true)
            //.attr("height", h * 2)
            .call(zoom)
            .call(drag);

        svgGroup = vis.append("svg:g")
                      .attr('transform', 'translate(' + zoom.translate() + ') scale(' + zoom.scale() + ')');
        allSVG.push(svgGroup);

        defs = vis.append('svg:defs');

       var marker = defs.selectAll('marker')
         .data(markers)
         .enter()
         .append('svg:marker')
           .attr('id', function(d){ return 'marker_' + d.name; })
           .attr("markerUnits", "userSpaceOnUse")
           .attr('markerHeight', 5)
           .attr('markerWidth', 5)
           //.attr('markerUnits', 'strokeWidth')
           .attr('orient', 'auto')
           .attr('refX', 0)
           .attr('refY', 0)
           .attr('viewBox', function(d){ return d.viewbox; })
           .append('svg:path')
             .attr('d', function(d){ return d.path; })
             .attr('fill', function(d,i) { return "#ccc"; });

        root = data;
        root.x0 = 0;
        root.y0 = (w) / 2;

        update(root);
    };

    return bst;

    function toggle (d) {

        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
    }

    function update(source) {
        var duration = 600;

        // Compute the new tree layout.
        var nodes = tree.nodes(root).reverse();

        // Normalize for fixed-depth.
        nodes.forEach(function(d) { d.y = 50 + d.depth * depthStep; });
        // nodes.forEach(function(d) { d.x = -1 * d.x; }); // -1 here flips. Fixed for new representation

        // Update the nodes…
        var node = svgGroup.selectAll("g.node")
            .data(nodes, function(d) { return d.id || (d.id = ++i); });
            // .on("mouseover", mouseover)
            // .on("mouseout", mouseout);

        // Enter any new nodes at the parent's previous position.
        var nodeEnter = node.enter().append("svg:g")
            .attr("class", "node")
            .classed("clickthrough", function(d) {
                if(d.name == "NULL") return true;
            })
            .attr("transform", function(d) {
                return "translate(" + source.x0 + "," + source.y0 + ")";
            })
            .on("click", function(d) { toggle(d); update(d); })
            .on("mouseover", BridgesVisualizer.textMouseover)
            .on("mouseout", BridgesVisualizer.textMouseout);

        nodeEnter.append('path')
            .attr("d", d3.svg.symbol()
                .type(function(d) { return d.shape || "rect"; })
                .size(function(d) { return scaleSize(d.size) || 1; })
            )
            .style("fill", function(d) {
                return BridgesVisualizer.getColor(d.color) || "#fff";
            })
            .style("opacity", function(d) {
                return d.role ? 0 : ( d.opacity || 1 );
            });

       if(nodes[0].key !== null) {
           nodeEnter.append("svg:text")
            .attr("dy", ".35em")
            .attr("x", "-8px")
            .attr("y",  "-15px")
            .attr("text-anchor", "start")
            .text(function(d) { return d.key || ""; } );
       }

        // Transition nodes to their new position.
        var nodeUpdate = node.transition()
            .duration(duration)
            .attr("transform", function(d) {
                var dx = d.x;
                return "translate(" + dx + "," + d.y + ")";
            });

        // Transition exiting nodes to the parent's new position.
        var nodeExit = node.exit().transition()
            .duration(duration)
            .attr("transform", function(d) {
                return "translate(" + (source.x) + "," + source.y + ")";
            })
            .remove();

        // Update the links…
        var link = svgGroup.selectAll("path.link")
            .data(tree.links(nodes), function(d) {
                return d.target.id;
            });

        // Enter any new links at the parent's previous position.
        link.enter().insert("svg:path", "g")
            .attr("class", "link")
            .style("stroke", function(d,i) {
                if(d.target.linkProperties) return BridgesVisualizer.getColor(d.target.linkProperties.color);
                return "#ccc";
            })
            .style("stroke-width", function(d,i) {
                if(d.target.linkProperties) return BridgesVisualizer.strokeWidthRange(d.target.linkProperties.thickness);
                return BridgesVisualizer.strokeWidthRange(1);
            })
            .style("opacity", function(d,i) {
                if(d.target.name == "NULL") return 0;
                return d.opacity || 1;
            })
            .attr("d", function(d) {
              var o = {x: source.x0, y: source.y0};
              return diagonal({source: o, target: o});
            })
            .attr('marker-start', function(d,i){ return 'url(#marker_circle)'; })
            .attr('marker-end', function(d,i){ return 'url(#marker_arrow)'; })
            .transition()
            .duration(duration)
            .attr("d", diagonal);

        // Transition links to their new position.
        link.transition()
            .duration(duration)
            .attr("d", diagonal);
        // Transition exiting nodes to the parent's new position.
        link.exit().transition()
            .duration(duration)
            .attr("d", function(d) {
              var o = {x: source.x, y: source.y};
              return diagonal({source: o, target: o});
            })
            .remove();
        // Stash the old positions for transition.
        nodes.forEach(function(d) {
            d.x0 = d.x;
            d.y0 = d.y;
        });

        // Add line breaks to node labels
        svgGroup.selectAll('text.nodeLabel').each(insertLineBreaks);
    }

// Function to add line breaks to node labels/names
function insertLineBreaks (d){
	var el = d3.select(this);
    var words = d3.select(this).text().split('\n');

    // if(words.length > 1) {
        el.text('');

        for (var i = 0; i < words.length; i++) {
            var tspan = el.append('tspan').text(words[i]);
            if (i > 0)
            tspan.attr('x',"20").attr('dy','15');
            //tspan.attr('x',"0").attr('dy','15');
        }
    // }
}

//    // zoom function
function zoomHandler() {
    //console.log("zoom");
    svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

function dragstarted() {
    //console.log("dragstart");
    //d3.event.sourceEvent.stopPropagation();
    d3.select(this).classed("dragging", true);
}

function dragged() {
     //console.log("dragging");
    //svgGroup.attr("transform", "translate(" + d3.event.translate + ")");
}
function dragended() {
//    console.log("dragend");
    d3.select(this).classed("dragging", false);
}

function mouseover() {
    // d3.select(this).select("text").transition()
    //     .duration(750)
    //     .style("display","block");
    BridgesVisualizer.textMouseover(d3.select(this), "tree");
    // var el = d3.select(this);
    // el.moveToFront();
}

function mouseout() {
    // d3.select(this).select("text").transition()
    //     .duration(750)
    //     .style("display","none");
    BridgesVisualizer.textMouseout(this);
}

};
<|endoftext|>


<commit_before>function dungeonGen(){
    fillMap();
    window.rooms = [];
    //room(leftX, topY, rightX, botY)
    var room1 = new room(115,130,130,115);
    var room2 = new room(115,175,130,145);
    var room3 = new room(145,130,160,115);
    var room4 = new room(70,90,90,70);
    window.rooms.push(room1);
    window.rooms.push(room2);
    window.rooms.push(room3);
    window.rooms.push(room4);
    room1.connectTo(room2);
    room1.connectTo(room3);
    room1.connectTo(room4);
    /*connectRooms(room1, room2);
    connectRooms(room1, room3);
    connectRooms(room1, room3);
    connectRooms(room1,room4);*/
}

function roomGen(numRooms)
{
    var i;
    var nextRoom, randRoom;
    var leftX, rightX, botY, topY;
    for(i=0; i < numRooms; i++)
    {
        console.log("starting attempt at creating room");
        leftX = randomBetween(10,200);
        rightX = randomBetween(leftX, leftX+20);
        botY = randomBetween(10,200);
        topY = randomBetween(botY, botY+20);

        nextRoom = new room(leftX,topY,rightX,botY);
        while (nextRoom != false)
        {
            console.log("attempting again");
            leftX = randomBetween(10,200);
            rightX = randomBetween(leftX, leftX+20);
            botY = randomBetween(10,200);
            topY = randomBetween(botY, botY+20);
            nextRoom = new room(leftX,topY,rightX,botY);
        }
        window.rooms.push(nextRoom);
        randRoom = rooms[ randomBetween(0,window.rooms.length - 1) ];
        while(randRoom != nextRoom)
        {
            randRoom = rooms[ randomBetween(0,window.rooms.length - 1) ];
        }
        nextRoom.connectTo(randRoom);
        window.rooms.push(nextRoom);
    }

}

function fillMap()
{
    var i,j;
    var wall = getObjectById(window.structureObjects, "wall");
    for(i=1; i<248; i++)
    {
        for(j=1; j<248; j++)
        {
            window.map[i][j].push(wall);
        }
    }
}

function room(leftX, topY, rightX, botY){
    this.leftX = leftX;
    this.topY = topY;
    this.rightX = rightX;
    this.botY = botY;
    this.centerX = Math.floor((this.leftX + this.rightX)/2);
    this.centerY = Math.floor((this.topY + this.botY)/2);
    var i,j;
    for(i=0; i<window.rooms.length; i++)
    {
        if(window.rooms[i].intersecting(this))
            return false;
    }

    for(i = leftX; i<= rightX; i++){
        for(j = botY; j<= topY; j++)
        {
            window.map[i][j].pop();
        }
    }

    this.intersecting = function(room2)
    {
        return(this.leftX <= room2.rightX &&this.rightX >= room2.leftX && //need to confirm that this works.
        this.botY <= room2.topY && this.topY >= room2.botY)
    };

    this.connectTo = function(connectingRoom)
    {
        //If the center of this room is between the left and right bounds of the connecting room
        //AND the center of the connecting room is within the left and right bounds of this room
        if(this.centerX >= connectingRoom.leftX && this.centerX <= connectingRoom.rightX
            && connectingRoom.centerX >= this.leftX && connectingRoom.centerX <= this.rightX)
        {
            //If the center of this y is higher than the center of connecting rooms y
            if(this.centerY > connectingRoom.centerY)
            {
                makeVertHallway(this.centerX, connectingRoom.topY, this.botY);
            }
            else
            {
                makeVertHallway(this.centerX, this.topY, connectingRoom.botY);
            }
        }
        //If this and connecting room line up vertically...
        else if(this.centerY >= connectingRoom.botY && this.centerY <= connectingRoom.topY
                && connectingRoom.centerY >= this.botY && connectingRoom.centerY <= this.topY)
        {
            //If this is more right that connecting room
            if(this.centerX > connectingRoom.centerX)
            {
                makeHorizHallway(this.centerY, connectingRoom.rightX, this.leftX);
            }
            else
            {
                makeHorizHallway(this.centerY, this.rightX, connectingRoom.leftX);
            }
        }
        //The rooms do not line up vertically
        else
        {
            //If this center is left of the connecting room center
            if(this.centerX < connectingRoom.centerX)
            {
                makeHorizHallway(this.centerY, this.rightX, connectingRoom.centerX);
            }
            else
            {
                makeHorizHallway(this.centerY, connectingRoom.centerX, this.rightX);
            }
            //If this is lower than connecting room center
            if(this.centerY < connectingRoom.centerY)
            {
                makeVertHallway(connectingRoom.centerX, this.topY, connectingRoom.centerY);
            }
            else
            {
                makeVertHallway(connectingRoom.centerX, connectingRoom.topY, this.centerY);
            }
        }

    };

    return this;
}

function makeHorizHallway(y, x1, x2)
{
    var i;
    for(i=x1; i<=x2; i++){
        while(window.map[i][y].peek().type == "structure")
            window.map[i][y].pop();
    }
}

function makeVertHallway(x, y1, y2){
    var i;
    for(i=y1; i<= y2; i++)
    {
        while(window.map[x][i].peek().type == "structure")
        {
            window.map[x][i].pop();
        }
    }
}<commit_msg>more random dungeon generation, now stable creation but not 100% connection rate between rooms<commit_after>function dungeonGen(){
    fillMap();
    window.rooms = [];
    //room(leftX, topY, rightX, botY)
    var room1 = new room(115,130,130,115);
    window.rooms.push(room1);
    //var room2 = new room(115,175,130,145);
    //var room3 = new room(145,130,160,115);
    //var room4 = new room(70,90,90,70);
    //window.rooms.push(room1);
    //window.rooms.push(room2);
    //window.rooms.push(room3);
    //window.rooms.push(room4);
    //room1.connectTo(room2);
    //room1.connectTo(room3);
    //room1.connectTo(room4);
    roomGen(10);
    /*connectRooms(room1, room2);
    connectRooms(room1, room3);
    connectRooms(room1, room3);
    connectRooms(room1,room4);*/
}

function roomGen(numRooms)
{
    var i;
    var nextRoom, randRoom;
    var leftX, rightX, botY, topY;
    for(i=0; i < numRooms; i++)
    {
        console.log("starting attempt at creating room");
        leftX = randomBetween(10,200);
        rightX = randomBetween(leftX, leftX+20);
        botY = randomBetween(10,200);
        topY = randomBetween(botY, botY+20);

        nextRoom = new room(leftX,topY,rightX,botY);
        while (nextRoom == false)
        {
            console.log("attempting again");
            leftX = randomBetween(10,200);
            rightX = randomBetween(leftX, leftX+10);
            botY = randomBetween(10,200);
            topY = randomBetween(botY, botY+10);
            nextRoom = new room(leftX,topY,rightX,botY);
        }
        randRoom = rooms[ randomBetween(0,window.rooms.length - 1) ];

        randRoom.connectTo(nextRoom);
        //window.rooms.push(nextRoom);
    }

}

function fillMap()
{
    var i,j;
    var wall = getObjectById(window.structureObjects, "wall");
    for(i=1; i<248; i++)
    {
        for(j=1; j<248; j++)
        {
            window.map[i][j].push(wall);
        }
    }
}

function room(leftX, topY, rightX, botY){
    this.leftX = leftX;
    this.topY = topY;
    this.rightX = rightX;
    this.botY = botY;
    this.centerX = Math.floor((this.leftX + this.rightX)/2);
    this.centerY = Math.floor((this.topY + this.botY)/2);
    var i,j;
    for(i=0; i<window.rooms.length; i++)
    {
        if(window.rooms[i].intersecting(this))
            return false;
    }

    for(i = leftX; i<= rightX; i++){
        for(j = botY; j<= topY; j++)
        {
            while(window.map[i][j].peek().type == "structure")
                window.map[i][j].pop();
        }
    }

    this.intersecting = function(room2)
    {
        return(this.leftX <= room2.rightX &&this.rightX >= room2.leftX && //need to confirm that this works.
        this.botY <= room2.topY && this.topY >= room2.botY)
    };

    this.connectTo = function(connectingRoom)
    {
        console.log("connecting");
        //If the center of this room is between the left and right bounds of the connecting room
        //AND the center of the connecting room is within the left and right bounds of this room
        if(this.centerX >= connectingRoom.leftX && this.centerX <= connectingRoom.rightX
            && connectingRoom.centerX >= this.leftX && connectingRoom.centerX <= this.rightX)
        {
            //If the center of this y is higher than the center of connecting rooms y
            if(this.centerY > connectingRoom.centerY)
            {
                makeVertHallway(this.centerX, connectingRoom.topY, this.botY);
            }
            else
            {
                makeVertHallway(this.centerX, this.topY, connectingRoom.botY);
            }
        }
        //If this and connecting room line up vertically...
        else if(this.centerY >= connectingRoom.botY && this.centerY <= connectingRoom.topY
                && connectingRoom.centerY >= this.botY && connectingRoom.centerY <= this.topY)
        {
            //If this is more right that connecting room
            if(this.centerX > connectingRoom.centerX)
            {
                makeHorizHallway(this.centerY, connectingRoom.rightX, this.leftX);
            }
            else
            {
                makeHorizHallway(this.centerY, this.rightX, connectingRoom.leftX);
            }
        }
        //The rooms do not line up vertically
        else
        {
            //If this center is left of the connecting room center
            console.log("diagonal");
            if(this.centerX < connectingRoom.centerX)
            {
                makeHorizHallway(this.centerY, this.rightX, connectingRoom.centerX);
            }
            else
            {
                makeHorizHallway(this.centerY, connectingRoom.centerX, this.rightX);
            }
            //If this is lower than connecting room center
            if(this.centerY < connectingRoom.centerY)
            {
                makeVertHallway(connectingRoom.centerX, this.topY, connectingRoom.centerY);
            }
            else
            {
                makeVertHallway(connectingRoom.centerX, connectingRoom.topY, this.centerY);
            }
        }

    };
    window.rooms.push(this);
    return this;
}

function makeHorizHallway(y, x1, x2)
{
    var i;
    for(i=x1; i<=x2; i++){
        while(window.map[i][y].peek().type == "structure")
            window.map[i][y].pop();
    }
}

function makeVertHallway(x, y1, y2){
    var i;
    for(i=y1; i<= y2; i++)
    {
        while(window.map[x][i].peek().type == "structure")
        {
            window.map[x][i].pop();
        }
    }
}<|endoftext|>


<commit_before>define(['jquery', 'inheritance', 'throbber', 'bind', 'domReady!'], function($, inheritance, throbber) {

    var Throb = Class.extend({
        init: function (throbber, brand) {
            var that = this;

            this.throbber = $(throbber);
            this.brand = $(brand);

            this.throb = new Throbber({
                color: '#B16848',
                size: 28,
                fade: 1500,
                rotationspeed: 10,
                lines: 10,
                strokewidth: 2.4,
            }).appendTo(this.throbber.get(0));

            this.active = 0;

            $('body').ajaxSend(function () {
                if (that.active == 0) {
                    that.start();
                }

                that.active++;
            });

            $('body').ajaxComplete(function () {
                that.active--;

                setTimeout(function () {
                    if (that.active == 0) {
                        that.stop();
                    }
                }, 500);
            });
        },
        stop: function () {
            this.throbber.hide();
            this.brand.show();

            this.throb.start();
        },
        start: function () {
            this.throbber.show();
            this.brand.hide();

            this.throb.start();
        }
    });

    var instance = null;

    /**
     * This one listens to click events and loads the href in the content div
     * instead of reloading the full page.
     */
    var Ajaxify = Class.extend({
        init: function () {
            if (instance !== null) {
                throw Error('Only one instance of Ajaxify allowed!');
            }

            var that = this;

            this.throb = new Throb('.throbber', '.brand');

            this.contents = ['#content', '#right'];
            this.selector = '#top, #right, #content, #footer';

            this.internalInit();

            $(window).bind('hashchange', function (event) {
                var href = document.location.hash.substring(1);
                if (typeof href != 'undefined' && href != '') {
                    that.loadPage(href);
                }
            });

            $(window).trigger('hashchange');
        },
        internalInit: function () {
            var that = this;

            $(this.selector).find('a')
                .unbind('click.ajaxify')
                .bind('click.ajaxify', function (event) {
                var href = $(this).attr('href');

                if (that.isRelative(href)) {
                    that.setPage(href);
                } else {
                    // open external links in new window/tab
                    window.open(href, "_blank");
                }
                return false;

            });

            $('body').trigger('ajaxifyInit');
        },
        loadPage: function (href) {
            var that = this;
            $(that.contents.join(',')).find('> *').remove();
            $.ajax(href, {
                success: function (data, textStatus, xhr) {
                    var html = $(data);
                    for (var index in that.contents) {
                        var content = that.contents[index];
                        $(content).html(html.find(content + ' > *'));
                    }
                    that.internalInit();
                },
                error: function (xhr) {
                    $(that.contents[0]).html(xhr.responseText);
                }
            });
        },
        setPage: function (href) {
            document.location.hash = href;
        },
        isRelative: function (href) {
            return !/^http(s)?:\/\//.test(href);
        },
    });

    return (function() {
        if (instance === null) {
            instance = new Ajaxify();
        }

        return instance;
    })();
});

<commit_msg>adding #queue to ajaxify because it's not in #right anymore<commit_after>define(['jquery', 'inheritance', 'throbber', 'bind', 'domReady!'], function($, inheritance, throbber) {

    var Throb = Class.extend({
        init: function (throbber, brand) {
            var that = this;

            this.throbber = $(throbber);
            this.brand = $(brand);

            this.throb = new Throbber({
                color: '#B16848',
                size: 28,
                fade: 1500,
                rotationspeed: 10,
                lines: 10,
                strokewidth: 2.4,
            }).appendTo(this.throbber.get(0));

            this.active = 0;

            $('body').ajaxSend(function () {
                if (that.active == 0) {
                    that.start();
                }

                that.active++;
            });

            $('body').ajaxComplete(function () {
                that.active--;

                setTimeout(function () {
                    if (that.active == 0) {
                        that.stop();
                    }
                }, 500);
            });
        },
        stop: function () {
            this.throbber.hide();
            this.brand.show();

            this.throb.start();
        },
        start: function () {
            this.throbber.show();
            this.brand.hide();

            this.throb.start();
        }
    });

    var instance = null;

    /**
     * This one listens to click events and loads the href in the content div
     * instead of reloading the full page.
     */
    var Ajaxify = Class.extend({
        init: function () {
            if (instance !== null) {
                throw Error('Only one instance of Ajaxify allowed!');
            }

            var that = this;

            this.throb = new Throb('.throbber', '.brand');

            this.contents = ['#content', '#right'];
            this.selector = '#top, #queue, #right, #content, #footer';

            this.internalInit();

            $(window).bind('hashchange', function (event) {
                var href = document.location.hash.substring(1);
                if (typeof href != 'undefined' && href != '') {
                    that.loadPage(href);
                }
            });

            $(window).trigger('hashchange');
        },
        internalInit: function () {
            var that = this;

            $(this.selector).find('a')
                .unbind('click.ajaxify')
                .bind('click.ajaxify', function (event) {
                var href = $(this).attr('href');

                if (that.isRelative(href)) {
                    that.setPage(href);
                } else {
                    // open external links in new window/tab
                    window.open(href, "_blank");
                }
                return false;

            });

            $('body').trigger('ajaxifyInit');
        },
        loadPage: function (href) {
            var that = this;
            $(that.contents.join(',')).find('> *').remove();
            $.ajax(href, {
                success: function (data, textStatus, xhr) {
                    var html = $(data);
                    for (var index in that.contents) {
                        var content = that.contents[index];
                        $(content).html(html.find(content + ' > *'));
                    }
                    that.internalInit();
                },
                error: function (xhr) {
                    $(that.contents[0]).html(xhr.responseText);
                }
            });
        },
        setPage: function (href) {
            document.location.hash = href;
        },
        isRelative: function (href) {
            return !/^http(s)?:\/\//.test(href);
        },
    });

    return (function() {
        if (instance === null) {
            instance = new Ajaxify();
        }

        return instance;
    })();
});

<|endoftext|>


<commit_before>/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * 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
 * FACEBOOK 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.
 */

var Comment = React.createClass({
  render: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return (

          {this.props.author}

    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (

Comments

        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />

    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment, index) {
      return (
        // `key` is a React-specific concept and is not mandatory for the
        // purpose of this tutorial. if you're curious, see more here:
        // http://facebook.github.io/react/docs/multiple-components.html#dynamic-children
        <Comment author={comment.author} key={index}>
          {comment.text}
        </Comment>
      );
    });
    return (

        {commentNodes}

    );
  }
});

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

React.render(
  <CommentBox url="comments.json" pollInterval={2000} />,
  document.getElementById('content')
);
<commit_msg>Update to match changes on website<commit_after>/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * 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
 * FACEBOOK 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.
 */

var Comment = React.createClass({
  rawMarkup: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return { __html: rawMarkup };
  },

  render: function() {
    return (

          {this.props.author}

    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (

Comments

        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />

    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment, index) {
      return (
        // `key` is a React-specific concept and is not mandatory for the
        // purpose of this tutorial. if you're curious, see more here:
        // http://facebook.github.io/react/docs/multiple-components.html#dynamic-children
        <Comment author={comment.author} key={index}>
          {comment.text}
        </Comment>
      );
    });
    return (

        {commentNodes}

    );
  }
});

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

React.render(
  <CommentBox url="comments.json" pollInterval={2000} />,
  document.getElementById('content')
);
<|endoftext|>


<commit_before>/** @license
 * Copyright 2020 Google Inc. All Rights Reserved.
 *
 * 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.
 */

/**
 * @fileoverview This file contains helper definitions that can be used for
 * loading and interacting with an Emscripten/WebAssembly module.
 */

goog.provide('GoogleSmartCard.EmscriptenModule');

goog.require('GoogleSmartCard.ExecutableModule');
goog.require('GoogleSmartCard.Logging');
goog.require('GoogleSmartCard.PromiseHelpers');
goog.require('GoogleSmartCard.TypedMessage');
goog.require('goog.Promise');
goog.require('goog.html.TrustedResourceUrl');
goog.require('goog.log.Logger');
goog.require('goog.messaging.AbstractChannel');
goog.require('goog.net.jsloader');
goog.require('goog.string.Const');

goog.scope(function() {

const GSC = GoogleSmartCard;

const LOGGER_SCOPE = 'EmscriptenModule';
const WRAPPER_SUBLOGGER_SCOPE = 'Wrapper';

/**
 * Class that allows to load and run the Emscripten module with the given name
 * and exchange messages with it.
 * @constructor
 * @extends GSC.ExecutableModule
 */
GSC.EmscriptenModule = function(moduleName) {
  EmscriptenModule.base(this, 'constructor');

  /** @type {string} @const @private */
  this.moduleName_ = moduleName;
  /** @type {!goog.log.Logger} @const @private */
  this.fromModuleMessagesLogger_ = GSC.Logging.getScopedLogger(LOGGER_SCOPE);
  /** @type {!goog.log.Logger} @const @private */
  this.logger_ = GSC.Logging.getChildLogger(
      this.fromModuleMessagesLogger_, WRAPPER_SUBLOGGER_SCOPE);
  /** @type {!goog.promise.Resolver<void>} @const @private */
  this.loadPromiseResolver_ = goog.Promise.withResolver();
  GSC.PromiseHelpers.suppressUnhandledRejectionError(
      this.loadPromiseResolver_.promise);
  /** @type {!EmscriptenModuleMessageChannel} @const @private */
  this.messageChannel_ = new EmscriptenModuleMessageChannel;
  // Object that is an entry point on the C++ side and is used for exchanging
  // messages with it. Untyped, since the class "GoogleSmartCardModule" is
  // defined within the Emscripten module (using Embind) and therefore isn't
  // known to Closure Compiler.
  /** @private */
  this.googleSmartCardModule_ = null;
};

const EmscriptenModule = GSC.EmscriptenModule;
goog.inherits(EmscriptenModule, GSC.ExecutableModule);

/** @override */
EmscriptenModule.prototype.getLogger = function() {
  return this.logger_;
};

/** @override */
EmscriptenModule.prototype.startLoading = function() {
  this.load_().then(() => {
    this.loadPromiseResolver_.resolve();
  }, (e) => {
    this.logger_.warning('Failed to load the Emscripten module: ' + e);
    this.dispose();
    this.loadPromiseResolver_.reject(e);
  });
};

/** @override */
EmscriptenModule.prototype.getLoadPromise = function() {
  return this.loadPromiseResolver_.promise;
};

/** @override */
EmscriptenModule.prototype.getMessageChannel = function() {
  return this.messageChannel_;
};

/** @override */
EmscriptenModule.prototype.disposeInternal = function() {
  this.logger_.fine('Disposed');
  delete this.googleSmartCardModule_;
  this.messageChannel_.dispose();
  EmscriptenModule.base(this, 'disposeInternal');
};

/**
 * Asynchronously loads and executes the Emscripten module.
 * @return {!Promise<void>}
 * @private
 */
EmscriptenModule.prototype.load_ = async function() {
  // First step: Asynchronously load the JS file containing the runtime support
  // code autogenerated by Emscripten. By convention (see build rules in
  // //common/make/internal/executable_building_emscripten.mk), the file's base
  // name is the module name.
  const jsUrl = goog.html.TrustedResourceUrl.format(goog.string.Const.from(
      '/%{moduleName}.js'), {'moduleName': this.moduleName_});
  await goog.net.jsloader.safeLoad(jsUrl);

  // Second step: Run the factory function that asynchronously loads the
  // Emscripten module and creates the Emscripten API's Module object. By
  // convention (see the EXPORT_NAME parameter in
  // //common/make/internal/executable_building_emscripten.mk), the function has
  // a specific name based on the module name.
  const factoryFunction = goog.global[
      `loadEmscriptenModule_${this.moduleName_}`];
  GSC.Logging.checkWithLogger(this.logger_, factoryFunction,
                              'Emscripten factory function not defined');
  const emscriptenApiModule = await factoryFunction(
      this.getEmscriptenApiModuleSettings_());

  // Third step: Create the object that serves as an entry point on the C++
  // side and is used for exchanging messages with it. By convention (see the
  // entry_point_emscripten.cc files), the class is named GoogleSmartCardModule.
  const GoogleSmartCardModule = emscriptenApiModule['GoogleSmartCardModule'];
  GSC.Logging.checkWithLogger(this.logger_, GoogleSmartCardModule,
                              'GoogleSmartCardModule class not defined');
  this.googleSmartCardModule_ = new GoogleSmartCardModule((message) => {
    this.messageChannel_.onMessageFromModule(message);
  });

  // Wire up outgoing messages with the module.
  this.messageChannel_.onModuleCreated(this.googleSmartCardModule_);
};

/**
 * Constructs the settings object for the Emscripten module instance.
 * @return {!Object}
 * @private
 */
EmscriptenModule.prototype.getEmscriptenApiModuleSettings_ = function() {
  return {
    'onAbort': () => {
      this.onModuleCrashed_();
    },
    'print': (message) => {
      this.onModuleStdoutReceived_(message);
    },
    'printErr': (message) => {
      this.onModuleStderrReceived_(message);
    },
  };
};

/**
 * Handles the Emscripten module's crash.
 * @private
 */
EmscriptenModule.prototype.onModuleCrashed_ = function() {
  this.logger_.severe('The Emscripten module crashed');
  this.dispose();
};

/**
 * Handles an stdout message received from the Emscripten module.
 * @param {string} message
 * @private
 */
EmscriptenModule.prototype.onModuleStdoutReceived_ = function(message) {
  // TODO(#185): Consider downgrading to the "fine" level once structured log
  // messages are received from the module.
  this.fromModuleMessagesLogger_.info(message);
};

/**
 * Handles an stderr message received from the Emscripten module.
 * @param {string} message
 * @private
 */
EmscriptenModule.prototype.onModuleStderrReceived_ = function(message) {
  // TODO(#185): Consider downgrading to the "fine" level once structured log
  // messages are received from the module.
  this.fromModuleMessagesLogger_.info(message);
};

/**
 * @constructor
 * @extends goog.messaging.AbstractChannel
 * @package
 */
function EmscriptenModuleMessageChannel() {
  goog.messaging.AbstractChannel.call(this);
  /** @type {!Array<!Object>} @private */
  this.pendingOutgoingMessages_ = [];
  // Instance of the "GoogleSmartCardModule" class that is defined via Embind.
  /** @private */
  this.googleSmartCardModule_ = null;
}

goog.inherits(EmscriptenModuleMessageChannel, goog.messaging.AbstractChannel);

/** @override */
EmscriptenModuleMessageChannel.prototype.send = function(serviceName, payload) {
  GSC.Logging.check(goog.isObject(payload));
  goog.asserts.assertObject(payload);
  const typedMessage = new GSC.TypedMessage(serviceName, payload);
  const message = typedMessage.makeMessage();
  if (this.isDisposed())
    return;
  if (!this.googleSmartCardModule_ || this.pendingOutgoingMessages_.length) {
    // Enqueue the message: either the module isn't fully loaded yet or we're
    // still sending the previously enqueued messages to it.
    this.pendingOutgoingMessages_.push(message);
    return;
  }
  this.sendNow_(message);
};

/** @override */
EmscriptenModuleMessageChannel.prototype.disposeInternal = function() {
  delete this.googleSmartCardModule_;
  EmscriptenModuleMessageChannel.base(this, 'disposeInternal');
};

/**
 * @param {?} googleSmartCardModule
 * @package
 */
EmscriptenModuleMessageChannel.prototype.onModuleCreated =
    function(googleSmartCardModule) {
  this.googleSmartCardModule_ = googleSmartCardModule;
  // Send all previously enqueued messages. Note that, in theory, new items
  // might be added to the array while we're iterating over it, which should be
  // fine as the for-of loop will visit all of them.
  for (const message of this.pendingOutgoingMessages_)
    this.sendNow_(message);
  this.pendingOutgoingMessages_ = [];
};

/**
 * @param {?} message
 * @package
 */
EmscriptenModuleMessageChannel.prototype.onMessageFromModule =
    function(message) {
  const typedMessage = GSC.TypedMessage.parseTypedMessage(message);
  if (!typedMessage) {
    GSC.Logging.fail(
        'Failed to parse message received from Emscripten module: ' +
        GSC.DebugDump.debugDump(message));
  }
  this.deliver(typedMessage.type, typedMessage.data);
};

/**
 * @param {!Object} message
 * @private
 */
EmscriptenModuleMessageChannel.prototype.sendNow_ = function(message) {
  // Note: The method name must match the string in the GoogleSmartCardModule
  // Embind class definition in the entry_point_emscripten.cc files.
  this.googleSmartCardModule_['postMessage'](message);
};

});  // goog.scope
<commit_msg>Free C++ object on Emscripten module disposal (#270)<commit_after>/** @license
 * Copyright 2020 Google Inc. All Rights Reserved.
 *
 * 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.
 */

/**
 * @fileoverview This file contains helper definitions that can be used for
 * loading and interacting with an Emscripten/WebAssembly module.
 */

goog.provide('GoogleSmartCard.EmscriptenModule');

goog.require('GoogleSmartCard.ExecutableModule');
goog.require('GoogleSmartCard.Logging');
goog.require('GoogleSmartCard.PromiseHelpers');
goog.require('GoogleSmartCard.TypedMessage');
goog.require('goog.Promise');
goog.require('goog.html.TrustedResourceUrl');
goog.require('goog.log.Logger');
goog.require('goog.messaging.AbstractChannel');
goog.require('goog.net.jsloader');
goog.require('goog.string.Const');

goog.scope(function() {

const GSC = GoogleSmartCard;

const LOGGER_SCOPE = 'EmscriptenModule';
const WRAPPER_SUBLOGGER_SCOPE = 'Wrapper';

/**
 * Class that allows to load and run the Emscripten module with the given name
 * and exchange messages with it.
 * @constructor
 * @extends GSC.ExecutableModule
 */
GSC.EmscriptenModule = function(moduleName) {
  EmscriptenModule.base(this, 'constructor');

  /** @type {string} @const @private */
  this.moduleName_ = moduleName;
  /** @type {!goog.log.Logger} @const @private */
  this.fromModuleMessagesLogger_ = GSC.Logging.getScopedLogger(LOGGER_SCOPE);
  /** @type {!goog.log.Logger} @const @private */
  this.logger_ = GSC.Logging.getChildLogger(
      this.fromModuleMessagesLogger_, WRAPPER_SUBLOGGER_SCOPE);
  /** @type {!goog.promise.Resolver<void>} @const @private */
  this.loadPromiseResolver_ = goog.Promise.withResolver();
  GSC.PromiseHelpers.suppressUnhandledRejectionError(
      this.loadPromiseResolver_.promise);
  /** @type {!EmscriptenModuleMessageChannel} @const @private */
  this.messageChannel_ = new EmscriptenModuleMessageChannel;
  // Object that is an entry point on the C++ side and is used for exchanging
  // messages with it. Untyped, since the class "GoogleSmartCardModule" is
  // defined within the Emscripten module (using Embind) and therefore isn't
  // known to Closure Compiler.
  /** @private */
  this.googleSmartCardModule_ = null;
};

const EmscriptenModule = GSC.EmscriptenModule;
goog.inherits(EmscriptenModule, GSC.ExecutableModule);

/** @override */
EmscriptenModule.prototype.getLogger = function() {
  return this.logger_;
};

/** @override */
EmscriptenModule.prototype.startLoading = function() {
  this.load_().then(() => {
    this.loadPromiseResolver_.resolve();
  }, (e) => {
    this.logger_.warning('Failed to load the Emscripten module: ' + e);
    this.dispose();
    this.loadPromiseResolver_.reject(e);
  });
};

/** @override */
EmscriptenModule.prototype.getLoadPromise = function() {
  return this.loadPromiseResolver_.promise;
};

/** @override */
EmscriptenModule.prototype.getMessageChannel = function() {
  return this.messageChannel_;
};

/** @override */
EmscriptenModule.prototype.disposeInternal = function() {
  this.logger_.fine('Disposed');
  // Call `delete()` on the C++ object before dropping the reference on it, in
  // order to make the C++ destructor called.
  // Note: The method is accessed using the square bracket notation, to make
  // sure that Closure Compiler doesn't rename this method call.
  this.googleSmartCardModule_['delete']();
  delete this.googleSmartCardModule_;
  this.messageChannel_.dispose();
  EmscriptenModule.base(this, 'disposeInternal');
};

/**
 * Asynchronously loads and executes the Emscripten module.
 * @return {!Promise<void>}
 * @private
 */
EmscriptenModule.prototype.load_ = async function() {
  // First step: Asynchronously load the JS file containing the runtime support
  // code autogenerated by Emscripten. By convention (see build rules in
  // //common/make/internal/executable_building_emscripten.mk), the file's base
  // name is the module name.
  const jsUrl = goog.html.TrustedResourceUrl.format(goog.string.Const.from(
      '/%{moduleName}.js'), {'moduleName': this.moduleName_});
  await goog.net.jsloader.safeLoad(jsUrl);

  // Second step: Run the factory function that asynchronously loads the
  // Emscripten module and creates the Emscripten API's Module object. By
  // convention (see the EXPORT_NAME parameter in
  // //common/make/internal/executable_building_emscripten.mk), the function has
  // a specific name based on the module name.
  const factoryFunction = goog.global[
      `loadEmscriptenModule_${this.moduleName_}`];
  GSC.Logging.checkWithLogger(this.logger_, factoryFunction,
                              'Emscripten factory function not defined');
  const emscriptenApiModule = await factoryFunction(
      this.getEmscriptenApiModuleSettings_());

  // Third step: Create the object that serves as an entry point on the C++
  // side and is used for exchanging messages with it. By convention (see the
  // entry_point_emscripten.cc files), the class is named GoogleSmartCardModule.
  const GoogleSmartCardModule = emscriptenApiModule['GoogleSmartCardModule'];
  GSC.Logging.checkWithLogger(this.logger_, GoogleSmartCardModule,
                              'GoogleSmartCardModule class not defined');
  this.googleSmartCardModule_ = new GoogleSmartCardModule((message) => {
    this.messageChannel_.onMessageFromModule(message);
  });

  // Wire up outgoing messages with the module.
  this.messageChannel_.onModuleCreated(this.googleSmartCardModule_);
};

/**
 * Constructs the settings object for the Emscripten module instance.
 * @return {!Object}
 * @private
 */
EmscriptenModule.prototype.getEmscriptenApiModuleSettings_ = function() {
  return {
    'onAbort': () => {
      this.onModuleCrashed_();
    },
    'print': (message) => {
      this.onModuleStdoutReceived_(message);
    },
    'printErr': (message) => {
      this.onModuleStderrReceived_(message);
    },
  };
};

/**
 * Handles the Emscripten module's crash.
 * @private
 */
EmscriptenModule.prototype.onModuleCrashed_ = function() {
  this.logger_.severe('The Emscripten module crashed');
  this.dispose();
};

/**
 * Handles an stdout message received from the Emscripten module.
 * @param {string} message
 * @private
 */
EmscriptenModule.prototype.onModuleStdoutReceived_ = function(message) {
  // TODO(#185): Consider downgrading to the "fine" level once structured log
  // messages are received from the module.
  this.fromModuleMessagesLogger_.info(message);
};

/**
 * Handles an stderr message received from the Emscripten module.
 * @param {string} message
 * @private
 */
EmscriptenModule.prototype.onModuleStderrReceived_ = function(message) {
  // TODO(#185): Consider downgrading to the "fine" level once structured log
  // messages are received from the module.
  this.fromModuleMessagesLogger_.info(message);
};

/**
 * @constructor
 * @extends goog.messaging.AbstractChannel
 * @package
 */
function EmscriptenModuleMessageChannel() {
  goog.messaging.AbstractChannel.call(this);
  /** @type {!Array<!Object>} @private */
  this.pendingOutgoingMessages_ = [];
  // Instance of the "GoogleSmartCardModule" class that is defined via Embind.
  /** @private */
  this.googleSmartCardModule_ = null;
}

goog.inherits(EmscriptenModuleMessageChannel, goog.messaging.AbstractChannel);

/** @override */
EmscriptenModuleMessageChannel.prototype.send = function(serviceName, payload) {
  GSC.Logging.check(goog.isObject(payload));
  goog.asserts.assertObject(payload);
  const typedMessage = new GSC.TypedMessage(serviceName, payload);
  const message = typedMessage.makeMessage();
  if (this.isDisposed())
    return;
  if (!this.googleSmartCardModule_ || this.pendingOutgoingMessages_.length) {
    // Enqueue the message: either the module isn't fully loaded yet or we're
    // still sending the previously enqueued messages to it.
    this.pendingOutgoingMessages_.push(message);
    return;
  }
  this.sendNow_(message);
};

/** @override */
EmscriptenModuleMessageChannel.prototype.disposeInternal = function() {
  delete this.googleSmartCardModule_;
  EmscriptenModuleMessageChannel.base(this, 'disposeInternal');
};

/**
 * @param {?} googleSmartCardModule
 * @package
 */
EmscriptenModuleMessageChannel.prototype.onModuleCreated =
    function(googleSmartCardModule) {
  this.googleSmartCardModule_ = googleSmartCardModule;
  // Send all previously enqueued messages. Note that, in theory, new items
  // might be added to the array while we're iterating over it, which should be
  // fine as the for-of loop will visit all of them.
  for (const message of this.pendingOutgoingMessages_)
    this.sendNow_(message);
  this.pendingOutgoingMessages_ = [];
};

/**
 * @param {?} message
 * @package
 */
EmscriptenModuleMessageChannel.prototype.onMessageFromModule =
    function(message) {
  const typedMessage = GSC.TypedMessage.parseTypedMessage(message);
  if (!typedMessage) {
    GSC.Logging.fail(
        'Failed to parse message received from Emscripten module: ' +
        GSC.DebugDump.debugDump(message));
  }
  this.deliver(typedMessage.type, typedMessage.data);
};

/**
 * @param {!Object} message
 * @private
 */
EmscriptenModuleMessageChannel.prototype.sendNow_ = function(message) {
  // Note: The method name must match the string in the GoogleSmartCardModule
  // Embind class definition in the entry_point_emscripten.cc files.
  // The method is accessed using the square bracket notation, to make sure that
  // Closure Compiler doesn't rename this method call.
  this.googleSmartCardModule_['postMessage'](message);
};

});  // goog.scope
<|endoftext|>


<commit_before>if (FML.isModLoaded("Mekanism")) {
    NEI.override("Mekanism:MachineBlock2", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    NEI.override("Mekanism:GasTank", [100]);
    NEI.override("Mekanism:*PlasticBlock", [0]);
    NEI.override("Mekanism:Balloon", [0]);
    NEI.override("Mekanism:GlowPanel", [0]);
    NEI.override("Mekanism:PlasticFence", [0]);
}<commit_msg>Remove hiding gas tanks as it hides the new tiered versions.<commit_after>if (FML.isModLoaded("Mekanism")) {
    NEI.override("Mekanism:MachineBlock2", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    NEI.override("Mekanism:*PlasticBlock", [0]);
    NEI.override("Mekanism:Balloon", [0]);
    NEI.override("Mekanism:GlowPanel", [0]);
    NEI.override("Mekanism:PlasticFence", [0]);
}<|endoftext|>