<commit_before>var lineFunc = d3.svg.line()
    .x(function(d) {
      return map.latLngToLayerPoint(d.latLng).x;
    })
    .y(function(d) {
      return map.latLngToLayerPoint(d.latLng).y;
    })
    .interpolate('linear');

function project(point) {
    var latlng = new L.LatLng(point[1], point[0]);
    var layerPoint = map.latLngToLayerPoint(latlng);
    return [layerPoint.x, layerPoint.y];
}
var linepath = d3.geo.path().projection(project);

function pathCollection(){
    return pyLeaflet.pyLeaflet_path().x(function(d) {
      pt = map.latLngToLayerPoint([ this.pathcoords.x(d[0]),this.pathcoords.y(d[1]) ]);
      return pt.x;
    }.bind(this)).y(function(d) {
      pt = map.latLngToLayerPoint([ this.pathcoords.x(d[0]),this.pathcoords.y(d[1]) ]);
      return pt.y;
    }.bind(this)).apply(this, pyLeaflet.getMod(this.props.paths, i));
}

function mypath(vertices, pathcodes) {
    var n_vertices = {
      M: 1,
      m: 1,
      L: 1,
      l: 1,
      Q: 2,
      q: 2,
      T: 1,
      t: 1,
      S: 2,
      s: 2,
      C: 3,
      c: 3,
      Z: 0,
      z: 0
    };
    var defined = function(d, i) {
      return true;
    };
    var points = [], segments = [], i_v = 0, i_c = -1, halt = 0, nullpath = false;
    if (!pathcodes) {
        pathcodes = [ "M" ];
        for (var i = 1; i < vertices.length; i++) pathcodes.push("L");
    }
    while (++i_c < pathcodes.length) {
        halt = i_v + n_vertices[pathcodes[i_c]];
        points = [];
        while (i_v < halt) {
          if (defined.call(this, vertices[i_v], i_v)) {
            points.push(vertices[i_v].x,vertices[i_v].y);
            i_v++;
          } else {
            points = null;
            i_v = halt;
          }
        }
        if (!points) {
          nullpath = true;
        } else if (nullpath && points.length > 0) {
          segments.push("M", points[0], points[1]);
          nullpath = false;
        } else {
          segments.push(pathcodes[i_c]);
          segments = segments.concat(points);
        }
    }
    if (i_v != vertices.length) console.warn("Warning: not all vertices used in Path");
    return segments.join(" ");
}

function pathpath(p){
    vertices = [];
    p.geometry.coordinates.forEach(function(d){
        l=map.latLngToLayerPoint(d);
        vertices.push(l)
    })
    return mypath(vertices, p.geometry.pathcodes)
}

function displaypath(p){
    vertices = [];
    p.geometry.coordinates.forEach(function(d){
        vertices.push({x:d[0],y:d[1]})
    })
    return mypath(vertices, p.geometry.pathcodes)
}

function displaypath_translate(d){
    l=map.latLngToLayerPoint(d.properties.translate);
    return "translate("+l.x+","+l.y+")"
}

var lines           = {type:'FeatureCollection',features:[]};
var markers         = {type:'FeatureCollection',features:[]};
var paths           = {type:'FeatureCollection',features:[]};
var displaypaths    = {type:'FeatureCollection',features:[]};
mdata.axes.slice(0,1).forEach(function(a){
    a.collections.forEach(function(c){
        c.paths.forEach(function(p,i){
            mpath = {
                id: c.id+'path'+i,
                type:'Feature',
                geometry:{
                    type:'LineString',
                    coordinates:[],
                    pathcodes:p[1]
                },
                properties:{
                    edgewidth: (c.edgewidths.length>=i)?c.edgewidths[i]:c.edgewidths[0],
                    edgecolor: (c.edgecolors.length>=i)?c.edgecolors[i]:c.edgecolors[0],
                    facecolor: (c.facecolors.length>=i)?c.facecolors[i]:c.facecolors[0],
                    alpha: (c.alphas.length>=i)?c.alphas[i]:c.alphas[0],
                }
            }
            if (c.pathcoordinates=='data'){
                p[0].forEach(function(d){
                    mpath.geometry.coordinates.push([d[1],d[0]])
                })
                paths.features.push(mpath)
            } else if (c.pathcoordinates=='display'){
                mpath.properties.translate = [mdata.data[c.offsets][i][1],mdata.data[c.offsets][i][0]];
                p[0].forEach(function(d){
                    mpath.geometry.coordinates.push([d[0],d[1]])
                })
                displaypaths.features.push(mpath)
            }
        })
    })

    a.lines.forEach(function(l){
        line = {
            id: l.id,
            type:'Feature',
            geometry:{
                type:'LineString',
                coordinates:[]
            },
            properties:{
                width:l.linewidth,
                color:l.color,
                alpha:l.alpha,
                dasharray:l.dasharray,
            }
        }
        mdata.data[l.data].forEach(function(d){
            line.geometry.coordinates.push([d[l.yindex], d[l.xindex]])
        })
        lines.features.push(line)
    })
    a.markers.forEach(function(m){
        mdata.data[m.data].forEach(function(d){
            marker = {
                id: m.id,
                type:'Feature',
                latLng: L.latLng(d[m.yindex], d[m.xindex]),
                properties:{
                    edgewidth:m.edgewidth,
                    edgecolor:m.edgecolor,
                    facecolor:m.facecolor,
                    alpha:m.alpha,
                    markertype:'circle',
                    radius:m.markerpath[0][0][1]
                }
            }
            markers.features.push(marker)
        })
    })
    a.paths.forEach(function(p){
        mpath = {
            id: p.id,
            type:'Feature',
            geometry:{
                type:'LineString',
                coordinates:[],
                pathcodes:p.pathcodes
            },
            properties:{
                edgewidth:p.edgewidth,
                edgecolor:p.edgecolor,
                facecolor:p.facecolor,
                alpha:p.alpha,
                dasharray:p.dasharray,
            }
        }
        mdata.data[p.data].forEach(function(d){
            mpath.geometry.coordinates.push([d[p.yindex], d[p.xindex]])
        })
        paths.features.push(mpath)
    })
})

d3lines = g2.selectAll('.line')
    .data(lines.features)
    .enter()
    .append("path");
d3lines
    .attr("d", linepath)
    .attr('class','line')
    .attr('stroke', function(d){return d.properties.color})
    .attr('stroke-width', function(d){return d.properties.width})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("stroke-dasharray", function(d){return d.properties.dasharray})
    .style('fill', 'none')
    .attr('id', function(d){return d.id});

d3markers = g2.selectAll(".marker")
    .data(markers.features).enter()
    .append('circle');
d3markers
    .attr('class', function(d){return 'marker marker-'+d.id})
    .attr("cx", function (d) { return map.latLngToLayerPoint(d.latLng).x;})
    .attr("cy", function (d) { return map.latLngToLayerPoint(d.latLng).y;})
    .attr("r", function (d) { return d.properties.radius+"px";})
    .attr("fill-opacity", function(d){return d.properties.alpha})
    .attr("fill", function(d){return d.properties.facecolor});

d3paths = g2.selectAll('.path')
    .data(paths.features)
    .enter()
    .append("path");
d3paths
    .attr("d", pathpath )
    .attr('class','path')
    .attr('stroke', function(d){return d.properties.edgecolor})
    .attr('stroke-width', function(d){return d.properties.edgewidth})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("stroke-dasharray", function(d){return d.properties.dasharray})
    .style('fill', function(d){return d.properties.facecolor})
    .style('fill-opacity', function(d){return d.properties.alpha})
    .attr('id', function(d){return d.id});

d3displaypaths = g2.selectAll('.displaypath')
    .data(displaypaths.features)
    .enter()
    .append("path");
d3displaypaths
    .attr("d", displaypath)
    .attr('class','displaypath')
    .attr('stroke', function(d){return d.properties.edgecolor})
    .attr('stroke-width', function(d){return d.properties.edgewidth})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("transform", displaypath_translate)
    .style('fill', function(d){return d.properties.facecolor})
    .style('fill-opacity', function(d){return d.properties.alpha})
    .attr('id', function(d){return d.id});

g2.selectAll('.line')
    .attr("d", ppath);

<commit_msg>working on collections, super messy<commit_after>var lineFunc = d3.svg.line()
    .x(function(d) {
      return map.latLngToLayerPoint(d.latLng).x;
    })
    .y(function(d) {
      return map.latLngToLayerPoint(d.latLng).y;
    })
    .interpolate('linear');

function project(point) {
    var latlng = new L.LatLng(point[1], point[0]);
    var layerPoint = map.latLngToLayerPoint(latlng);
    return [layerPoint.x, layerPoint.y];
}
var linepath = d3.geo.path().projection(project);

function pathCollection(){
    return pyLeaflet.pyLeaflet_path().x(function(d) {
      pt = map.latLngToLayerPoint([ this.pathcoords.x(d[0]),this.pathcoords.y(d[1]) ]);
      return pt.x;
    }.bind(this)).y(function(d) {
      pt = map.latLngToLayerPoint([ this.pathcoords.x(d[0]),this.pathcoords.y(d[1]) ]);
      return pt.y;
    }.bind(this)).apply(this, pyLeaflet.getMod(this.props.paths, i));
}

function mypath(vertices, pathcodes) {
    var n_vertices = {
      M: 1,
      m: 1,
      L: 1,
      l: 1,
      Q: 2,
      q: 2,
      T: 1,
      t: 1,
      S: 2,
      s: 2,
      C: 3,
      c: 3,
      Z: 0,
      z: 0
    };
    var defined = function(d, i) {
      return true;
    };
    var points = [], segments = [], i_v = 0, i_c = -1, halt = 0, nullpath = false;
    if (!pathcodes) {
        pathcodes = [ "M" ];
        for (var i = 1; i < vertices.length; i++) pathcodes.push("L");
    }
    while (++i_c < pathcodes.length) {
        halt = i_v + n_vertices[pathcodes[i_c]];
        points = [];
        while (i_v < halt) {
          if (defined.call(this, vertices[i_v], i_v)) {
            points.push(vertices[i_v].x,vertices[i_v].y);
            i_v++;
          } else {
            points = null;
            i_v = halt;
          }
        }
        if (!points) {
          nullpath = true;
        } else if (nullpath && points.length > 0) {
          segments.push("M", points[0], points[1]);
          nullpath = false;
        } else {
          segments.push(pathcodes[i_c]);
          segments = segments.concat(points);
        }
    }
    if (i_v != vertices.length) console.warn("Warning: not all vertices used in Path");
    return segments.join(" ");
}

function pathpath(p){
    vertices = [];
    p.geometry.coordinates.forEach(function(d){
        l=map.latLngToLayerPoint(d);
        vertices.push(l)
    })
    return mypath(vertices, p.geometry.pathcodes)
}

function displaypath(p){
    vertices = [];
    p.geometry.coordinates.forEach(function(d){
        vertices.push({x:d[0],y:d[1]})
    })
    return mypath(vertices, p.geometry.pathcodes)
}

function displaypath_translate(d){
    l=map.latLngToLayerPoint(d.properties.translate);
    return "translate("+l.x+","+l.y+")"
}

var lines           = {type:'FeatureCollection',features:[]};
var markers         = {type:'FeatureCollection',features:[]};
var paths           = {type:'FeatureCollection',features:[]};
var displaypaths    = {type:'FeatureCollection',features:[]};
mdata.axes.slice(0,1).forEach(function(a){
    a.collections.forEach(function(c){
        c.paths.forEach(function(p,i){
            mpath = {
                id: c.id+'path'+i,
                type:'Feature',
                geometry:{
                    type:'LineString',
                    coordinates:[],
                    pathcodes:p[1]
                },
                properties:{
                    edgewidth: (c.edgewidths.length>=i)?c.edgewidths[i]:c.edgewidths[0],
                    edgecolor: (c.edgecolors.length>=i)?c.edgecolors[i]:c.edgecolors[0],
                    facecolor: (c.facecolors.length>=i)?c.facecolors[i]:c.facecolors[0],
                    alpha: (c.alphas.length>=i)?c.alphas[i]:c.alphas[0],
                }
            }
            // means the path is actual signal
            if (c.coordinates == 'data' || c.pathcoordinates == 'data'){
                p[0].forEach(function(d){
                    mpath.geometry.coordinates.push([d[1],d[0]])
                })
                paths.features.push(mpath)
            // means the path is a symbol
            } else if (c.pathcoordinates == "display"){
                if (c.offsetcoordinates == "display"){
                    mpath.properties.translate = [mdata.data[c.offsets][i][1],mdata.data[c.offsets][i][0]];
                    p[0].forEach(function(d){
                        mpath.geometry.coordinates.push([d[0],d[1]])
                    })
                    displaypaths.features.push(mpath)
                } else if (c.offsetcoordinates == "data"){
                    mpath.properties.translate = [0,0]
                    mdata.data[c.offsets].forEach(function(o,j){
                        mpath = {
                            id: c.id+'path'+j,
                            type:'Feature',
                            geometry:{
                                type:'LineString',
                                coordinates:[],
                                pathcodes:p[1]
                            },
                            properties:{
                                edgewidth: (c.edgewidths.length>=j)?c.edgewidths[j]:c.edgewidths[0],
                                edgecolor: (c.edgecolors.length>=j)?c.edgecolors[j]:c.edgecolors[0],
                                facecolor: (c.facecolors.length>=j)?c.facecolors[j]:c.facecolors[0],
                                alpha: (c.alphas.length>=j)?c.alphas[j]:c.alphas[0],
                                translate : [0,0]
                            }
                        }
                        p[0].forEach(function(d){
                            mpath.geometry.coordinates.push([o[0]+d[0],o[1]+d[1]])
                        })
                        paths.features.push(mpath)
                    })
                }
            }
        })
    })

    a.lines.forEach(function(l){
        line = {
            id: l.id,
            type:'Feature',
            geometry:{
                type:'LineString',
                coordinates:[]
            },
            properties:{
                width:l.linewidth,
                color:l.color,
                alpha:l.alpha,
                dasharray:l.dasharray,
            }
        }
        mdata.data[l.data].forEach(function(d){
            line.geometry.coordinates.push([d[l.yindex], d[l.xindex]])
        })
        lines.features.push(line)
    })
    a.markers.forEach(function(m){
        mdata.data[m.data].forEach(function(d){
            marker = {
                id: m.id,
                type:'Feature',
                latLng: L.latLng(d[m.yindex], d[m.xindex]),
                properties:{
                    edgewidth:m.edgewidth,
                    edgecolor:m.edgecolor,
                    facecolor:m.facecolor,
                    alpha:m.alpha,
                    markertype:'circle',
                    radius:m.markerpath[0][0][1]
                }
            }
            markers.features.push(marker)
        })
    })
    a.paths.forEach(function(p){
        mpath = {
            id: p.id,
            type:'Feature',
            geometry:{
                type:'LineString',
                coordinates:[],
                pathcodes:p.pathcodes
            },
            properties:{
                edgewidth:p.edgewidth,
                edgecolor:p.edgecolor,
                facecolor:p.facecolor,
                alpha:p.alpha,
                dasharray:p.dasharray,
            }
        }
        mdata.data[p.data].forEach(function(d){
            mpath.geometry.coordinates.push([d[p.yindex], d[p.xindex]])
        })
        paths.features.push(mpath)
    })
})

d3lines = g2.selectAll('.line')
    .data(lines.features)
    .enter()
    .append("path");
d3lines
    .attr("d", linepath)
    .attr('class','line')
    .attr('stroke', function(d){return d.properties.color})
    .attr('stroke-width', function(d){return d.properties.width})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("stroke-dasharray", function(d){return d.properties.dasharray})
    .style('fill', 'none')
    .attr('id', function(d){return d.id});

d3markers = g2.selectAll(".marker")
    .data(markers.features).enter()
    .append('circle');
d3markers
    .attr('class', function(d){return 'marker marker-'+d.id})
    .attr("cx", function (d) { return map.latLngToLayerPoint(d.latLng).x;})
    .attr("cy", function (d) { return map.latLngToLayerPoint(d.latLng).y;})
    .attr("r", function (d) { return d.properties.radius+"px";})
    .attr("fill-opacity", function(d){return d.properties.alpha})
    .attr("fill", function(d){return d.properties.facecolor});

d3paths = g2.selectAll('.path')
    .data(paths.features)
    .enter()
    .append("path");
d3paths
    .attr("d", pathpath )
    .attr('class','path')
    .attr('stroke', function(d){return d.properties.edgecolor})
    .attr('stroke-width', function(d){return d.properties.edgewidth})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("stroke-dasharray", function(d){return d.properties.dasharray})
    .style('fill', function(d){return d.properties.facecolor})
    .style('fill-opacity', function(d){return d.properties.alpha})
    .attr('id', function(d){return d.id});

d3displaypaths = g2.selectAll('.displaypath')
    .data(displaypaths.features)
    .enter()
    .append("path");
d3displaypaths
    .attr("d", displaypath)
    .attr('class','displaypath')
    .attr('stroke', function(d){return d.properties.edgecolor})
    .attr('stroke-width', function(d){return d.properties.edgewidth})
    .attr("stroke-opacity", function(d){return d.properties.alpha})
    .attr("transform", displaypath_translate)
    .style('fill', function(d){return d.properties.facecolor})
    .style('fill-opacity', function(d){return d.properties.alpha})
    .attr('id', function(d){return d.id});

g2.selectAll('.line')
    .attr("d", ppath);

<|endoftext|>


<commit_before>// A map to keep track of the audio
const audioCache = new Map();

// Create a new audio context.
const ctx = new AudioContext();
ctx.listener.setPosition(0, 0, 0);
// Create a AudioGainNode to control the main volume.
const mainVolume = ctx.createGain();
// Connect the main volume node to the context destination.
mainVolume.connect(ctx.destination);
var fortissimo = ['ff','mf', 'pp'];
export function play(pitch, xPercentage, yPercentage ) {
  // Create an object with a sound source and a volume control.
  const sound = {
    source: ctx.createBufferSource(),
    volume: ctx.createGain(),
    panner: ctx.createPanner()
  };
  // Connect the sound source to the volume control.
  sound.source.connect(sound.volume);
  // Instead of hooking up the volume to the main volume, hook it up to the panner.
  sound.volume.connect(sound.panner);
  // And hook up the panner to the main volume.
  sound.panner.connect(mainVolume);
  // Setup the audio position of the sound
  //set z index to zero for 2d sound
  sound.panner.setPosition(xPercentage / 100, yPercentage / 100, 0);
  console.log("x percentage: ", xPercentage / 100);
  console.log("y percentage: ", yPercentage / 100);
  console.log("pitch number: ", pitch);
  let fortissimoNo = Math.round((Math.random()*2));
  // Make the sound source loop.
  sound.source.loop = false;
  // Check if the cache has the current pitch in memory already
  if (audioCache.has(pitch + fortissimoNo)) {
    let buffer = audioCache.get(pitch + fortissimoNo);
    sound.buffer = buffer;
    // Make the sound source use the buffer and start playing it
    sound.source.buffer = buffer;
    sound.source.start(ctx.currentTime);
  } else {
    console.log('/samples/mp3piano/Piano.' + fortissimo[fortissimoNo] + '.' + pitch + '.mp3');

    let request = new XMLHttpRequest();
    request.open('GET', chrome.extension.getURL('/samples/mp3piano/Piano.' + fortissimo[fortissimoNo] + '.' + pitch + '.mp3'), true);

    request.responseType = 'arraybuffer';
    request.onload = function(e) {
      // Create a buffer from the response ArrayBuffer.
      ctx.decodeAudioData(this.response, function onSuccess(buffer) {
        // Store the sound in the audioCache
        audioCache.set(pitch + fortissimoNo, buffer);
        sound.buffer = buffer;
        // Make the sound source use the buffer and start playing it
        sound.source.buffer = buffer;
        sound.source.start(ctx.currentTime);
      }, function onFailure() {
        console.error('Failed to load audio', arguments);
      });
    };
    request.send();
  }
};
<commit_msg>fixing z dimension for playback<commit_after>// A map to keep track of the audio
const audioCache = new Map();

// Create a new audio context.
const ctx = new AudioContext();
ctx.listener.setPosition(0, 0, 0);
// Create a AudioGainNode to control the main volume.
const mainVolume = ctx.createGain();
// Connect the main volume node to the context destination.
mainVolume.connect(ctx.destination);
var fortissimo = ['ff','mf', 'pp'];
export function play(pitch, xPercentage, yPercentage ) {
  // Create an object with a sound source and a volume control.
  const sound = {
    source: ctx.createBufferSource(),
    volume: ctx.createGain(),
    panner: ctx.createPanner()
  };
  // Connect the sound source to the volume control.
  sound.source.connect(sound.volume);
  // Instead of hooking up the volume to the main volume, hook it up to the panner.
  sound.volume.connect(sound.panner);
  // And hook up the panner to the main volume.
  sound.panner.connect(mainVolume);
  // Setup the audio position of the sound
  //set z index to zero for 2d sound
  sound.panner.setPosition(xPercentage / 100, yPercentage / 100, 0.5);
  console.log("x percentage: ", xPercentage / 100);
  console.log("y percentage: ", yPercentage / 100);
  console.log("pitch number: ", pitch);
  let fortissimoNo = Math.round((Math.random()*2));
  // Make the sound source loop.
  sound.source.loop = false;
  // Check if the cache has the current pitch in memory already
  if (audioCache.has(pitch + fortissimoNo)) {
    let buffer = audioCache.get(pitch + fortissimoNo);
    sound.buffer = buffer;
    // Make the sound source use the buffer and start playing it
    sound.source.buffer = buffer;
    sound.source.start(ctx.currentTime);
  } else {
    console.log('/samples/mp3piano/Piano.' + fortissimo[fortissimoNo] + '.' + pitch + '.mp3');

    let request = new XMLHttpRequest();
    request.open('GET', chrome.extension.getURL('/samples/mp3piano/Piano.' + fortissimo[fortissimoNo] + '.' + pitch + '.mp3'), true);

    request.responseType = 'arraybuffer';
    request.onload = function(e) {
      // Create a buffer from the response ArrayBuffer.
      ctx.decodeAudioData(this.response, function onSuccess(buffer) {
        // Store the sound in the audioCache
        audioCache.set(pitch + fortissimoNo, buffer);
        sound.buffer = buffer;
        // Make the sound source use the buffer and start playing it
        sound.source.buffer = buffer;
        sound.source.start(ctx.currentTime);
      }, function onFailure() {
        console.error('Failed to load audio', arguments);
      });
    };
    request.send();
  }
};
<|endoftext|>


<commit_before>import { csv, json } from 'd3';
import uuid from 'uuid';

/**
 * _transformToHierarchy - Transforms a flat array of parent-child links
 * into a hierarchy.
 *
 * @param {array<object>} links           Set of parent-child link objects
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {array<object>} Single-element array containing the root node object.
 */
function _transformToHierarchy(links, attributeFields) {
  const nodesByName = {};

  const assignNode = (name) => {
    if (!nodesByName[name]) {
      nodesByName[name] = { name };
    }
    return nodesByName[name];
  };

  const assignNodeWithAttributes = (name, attributes) => {
    if (!nodesByName[name]) {
      nodesByName[name] = {
        name,
        attributes,
      };
    }
    return nodesByName[name];
  };

  // Create nodes for each unique source and target.
  links.forEach((link) => {
    // if `attributeFields` is defined, create/overwrite current `link.attributes`
    if (attributeFields) {
      const customAttributes = {};
      attributeFields.forEach((field) => {
        customAttributes[field] = link[field];
      });
      link.attributes = customAttributes;
    }

    link.source = assignNode(link.parent);
    link.target = assignNodeWithAttributes(link.child, link.attributes);
    const parent = link.source;
    const child = link.target;

    parent.id = uuid.v4();
    child.id = uuid.v4();
    child.parent = parent.name || null;

    parent._collapsed = child._collapsed = false; // eslint-disable-line
    // NOTE We assign to a custom `_children` field instead of D3's reserved
    // `children` to avoid update anomalies when collapsing/re-expanding nodes.
    parent._children ? parent._children.push(child) : parent._children = [child];
  });

  // Extract & return the root node
  const rootLinks = links.filter((link) => !link.source.parent);
  return [rootLinks[0].source];
}

/**
 * parseCSV - Parses a CSV file into a hierarchy structure.
 *
 * @param {string} csvFilePath     Path to CSV file to be parsed.
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseCSV(csvFilePath, attributeFields) {
  return new Promise((resolve, reject) => {
    try {
      csv(csvFilePath, (data) => resolve(_transformToHierarchy(data, attributeFields))); // lol hello Lisp
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * parseJSON - Parses a hierarchical JSON file that requires no further transformation.
 *
 * @param {string} jsonFilePath Path to JSON file to be parsed.
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseJSON(jsonFilePath) {
  return new Promise((resolve, reject) => {
    try {
      json(jsonFilePath, (data) => resolve([data]));
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * parseFlatJSON - Parses a flat JSON file into a hierarchy structure.
 *
 * @param {string} jsonFilePath Path to flat JSON file to be parsed.
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseFlatJSON(jsonFilePath, attributeFields) {
  return new Promise((resolve, reject) => {
    try {
      json(jsonFilePath, (data) => resolve(_transformToHierarchy(data, attributeFields)));
    } catch (err) {
      reject(err);
    }
  });
}

export default {
  parseCSV,
  parseJSON,
  parseFlatJSON,
};
<commit_msg>Adds `generateHierarchy` util method<commit_after>import { csv, json } from 'd3';
import uuid from 'uuid';

/**
 * _transformToHierarchy - Transforms a flat array of parent-child links
 * into a hierarchy.
 *
 * @param {array<object>} links           Set of parent-child link objects
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {array<object>} Single-element array containing the root node object.
 */
function _transformToHierarchy(links, attributeFields) {
  const nodesByName = {};

  const assignNode = (name) => {
    if (!nodesByName[name]) {
      nodesByName[name] = { name };
    }
    return nodesByName[name];
  };

  const assignNodeWithAttributes = (name, attributes) => {
    if (!nodesByName[name]) {
      nodesByName[name] = {
        name,
        attributes,
      };
    }
    return nodesByName[name];
  };

  // Create nodes for each unique source and target.
  links.forEach((link) => {
    // if `attributeFields` is defined, create/overwrite current `link.attributes`
    if (attributeFields) {
      const customAttributes = {};
      attributeFields.forEach((field) => {
        customAttributes[field] = link[field];
      });
      link.attributes = customAttributes;
    }

    link.source = assignNode(link.parent);
    link.target = assignNodeWithAttributes(link.child, link.attributes);
    const parent = link.source;
    const child = link.target;

    parent.id = uuid.v4();
    child.id = uuid.v4();
    child.parent = parent.name || null;

    parent._collapsed = child._collapsed = false; // eslint-disable-line
    // NOTE We assign to a custom `_children` field instead of D3's reserved
    // `children` to avoid update anomalies when collapsing/re-expanding nodes.
    parent._children ? parent._children.push(child) : parent._children = [child];
  });

  // Extract & return the root node
  const rootLinks = links.filter((link) => !link.source.parent);
  return [rootLinks[0].source];
}

/**
 * parseCSV - Parses a CSV file into a hierarchy structure.
 *
 * @param {string} csvFilePath     Path to CSV file to be parsed.
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseCSV(csvFilePath, attributeFields) {
  return new Promise((resolve, reject) => {
    try {
      csv(csvFilePath, (data) => resolve(_transformToHierarchy(data, attributeFields))); // lol hello Lisp
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * parseJSON - Parses a hierarchical JSON file that requires no further transformation.
 *
 * @param {string} jsonFilePath Path to JSON file to be parsed.
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseJSON(jsonFilePath) {
  return new Promise((resolve, reject) => {
    try {
      json(jsonFilePath, (data) => resolve([data]));
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * parseFlatJSON - Parses a flat JSON file into a hierarchy structure.
 *
 * @param {string} jsonFilePath Path to flat JSON file to be parsed.
 * @param {array<string>|undefined} attributeFields Set of `link` fields to be used as attributes
 *
 * @return {Promise} Returns hierarchy array if resolved, error object if rejected.
 */
function parseFlatJSON(jsonFilePath, attributeFields) {
  return new Promise((resolve, reject) => {
    try {
      json(jsonFilePath, (data) => resolve(_transformToHierarchy(data, attributeFields)));
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * generateHierarchy - Generates a hierarchical array from
 * a flat array of links.
 *
 * @param {array<object>} flatArray Flat array of `link` objects
 *
 * @return {array<object>} Hierarchical single-element array.
 */
function generateHierarchy(flatArray) {
  return _transformToHierarchy(flatArray);
}

export default {
  parseCSV,
  parseJSON,
  parseFlatJSON,
  generateHierarchy,
};
<|endoftext|>


<commit_before>var poolFactory = function( constr, init, onAcquired, onReleased, reset, capacity ) {

		if( !reset ) reset = idFunc;
		if( !capacity ) capacity = 20;

		var stack = [],
			count = 0,
			created= 0,
			dropped= 0,
			pool = {
				get count() { return count; },
				get capacity() {
					return capacity;
				},
				set capacity( val ) {
					if( val < stack.length ) {
						stack.length = val;
					}
					capacity = val;
				},
				drop: function( nb ) {
					if( nb === undefined || nb > count ) nb = count;
					while( nb-- > 0 ) {
						stack[ --count ] = null;
					}
				},
				get created() { return created; },
				set created( val ) { created = val; },
				get dropped() { return dropped; },
				set dropped( val ) { dropped = val; }
			};
		return {
			acquirer: function() {
				var obj;
				if( count > 0 ) {
					obj = stack[ --count ];
					stack[ count ] = null;
				}
				else {
					obj = constr();
					created++;
				}
				init.apply( obj, arguments );
				onAcquired( obj );
				return obj;
			},
			releaser: function( obj ) {
				onReleased( obj );
				if( count < capacity ) {
					reset( obj );
					stack[ count++ ] = obj;
				}
				else dropped++;
			},
			disposer: function() {
				onReleased( this );
				if( count < capacity ) {
					reset( this );
					stack[ count++ ] = this;
				}
				else dropped++;
			},
			pool: pool
		};
	},
	attachPool = function(klass, options) {
		if(klass._pool) throw "This is already a pool: " + klass;
		var def = poolFactory(options.constr, options.init, options.reset, options.capacity),
			acquireName = options.acquireName || "acquire",
			releaseName = options.releaseName || "release",
			disposeName = options.disposeName || "dispose",
			proto = options.proto;
		klass[ acquireName ] = def.acquirer;
		klass[ releaseName ] = def.releaser;
		if( proto ) proto[ disposeName ] = def.disposer;
		klass._pool = def.pool;
		return klass;
	},
	// The class for the pools:
	Pool = {},
	pool = function( options ) {
		return attachPool( Object_create( Pool ), options );
	};
<commit_msg>Fix arguments parsing in attachPool()<commit_after>var poolFactory = function( constr, init, onAcquired, onReleased, reset, capacity ) {

		if( !reset ) reset = idFunc;
		if( !capacity ) capacity = 20;

		var stack = [],
			count = 0,
			created= 0,
			dropped= 0,
			pool = {
				get count() { return count; },
				get capacity() {
					return capacity;
				},
				set capacity( val ) {
					if( val < stack.length ) {
						stack.length = val;
					}
					capacity = val;
				},
				drop: function( nb ) {
					if( nb === undefined || nb > count ) nb = count;
					while( nb-- > 0 ) {
						stack[ --count ] = null;
					}
				},
				get created() { return created; },
				set created( val ) { created = val; },
				get dropped() { return dropped; },
				set dropped( val ) { dropped = val; }
			};
		return {
			acquirer: function() {
				var obj;
				if( count > 0 ) {
					obj = stack[ --count ];
					stack[ count ] = null;
				}
				else {
					obj = constr();
					created++;
				}
				init.apply( obj, arguments );
				onAcquired( obj );
				return obj;
			},
			releaser: function( obj ) {
				onReleased( obj );
				if( count < capacity ) {
					reset( obj );
					stack[ count++ ] = obj;
				}
				else dropped++;
			},
			disposer: function() {
				onReleased( this );
				if( count < capacity ) {
					reset( this );
					stack[ count++ ] = this;
				}
				else dropped++;
			},
			pool: pool
		};
	},
	attachPool = function( klass, options ) {
		if( klass._pool ) throw "This is already a pool: " + klass;
		var constr = options.constr,
			init = options.init || noopFunc,
			onAcquired = options.onAcquired || noopFunc,
			onReleased = options.onReleased || noopFunc,
			reset = options.reset || noopFunc,
			capacity = options.capacity || 32,
			def = poolFactory( constr, init, onAcquired,  onReleased, reset, capacity ),
			acquireName = options.acquireName || "acquire",
			releaseName = options.releaseName || "release",
			disposeName = options.disposeName || "dispose",
			proto = options.proto;
		klass[ acquireName ] = def.acquirer;
		klass[ releaseName ] = def.releaser;
		if( proto ) proto[ disposeName ] = def.disposer;
		klass._pool = def.pool;
		return klass;
	},
	// The class for the pools:
	Pool = {},
	pool = function( options ) {
		return attachPool( Object_create( Pool ), options );
	};
<|endoftext|>


<commit_before>import passport from 'passport';
import passportLocal from 'passport-local';
import { OAuth2Strategy } from 'passport-google-oauth';
import { User } from '../data/models';
import config from '../config';
import {
  ACTIVE,
  PENDING,
} from '../constants/userStatus';

/* eslint-disable */
const LocalStrategy = passportLocal.Strategy;
passport.use(
  'google',
  new OAuth2Strategy(
    {
      clientID: config.google.clientID,
      clientSecret: config.google.clientSecret,
      callbackURL: config.google.callbackURL,
      passReqToCallback: true,
    },
    (req, accessToken, refreshToken, profile, done) => {
      const { displayName, id, emails } = profile;
      const email = (emails[0].value || '').toLowerCase();
      const google = {
        id: profile.id,
        token: accessToken,
        refreshToken,
      }
      const userObj = {
        google,
        name: displayName,
        email: email,
        status: ACTIVE,
      }
      const message = 'Successfully Logged In';
      process.nextTick(async () => {
        try {
          if (!req.user) {
            const userWithEmail = await User.findOne({ email });
            if (userWithEmail && userWithEmail.status === PENDING) {
              const u = Object.assign({}, userObj, userWithEmail);
              await u.save();
              return done(null, {
                success: true,
                message,
                user: u,
              });
            }
            let user = await User.findOne({ 'google.id': profile.id });
            if (user) {
              user.google = google;
              await user.save();
            }
            user = Object.assign({}, userObj, new User());
            await user.save();
            return done(null, {
              success: true,
              message,
              user,
            });

          }
          const user = req.user;
          await user.save();
          return done(null, {
            success: true,
            message,
            user,
          });
        } catch (error) {
           return done(null, false, {
            success: false,
            message: error,
          });
        }
      });
    },
  ),
);

passport.serializeUser((req, done) => {
  done(null, req.user._id);
});

passport.deserializeUser((id, done) => {
  User.findById(id, (err, req) => {
    done(err, req);
  });
});
<commit_msg>moja attempt #5<commit_after>import passport from 'passport';
import passportLocal from 'passport-local';
import { OAuth2Strategy } from 'passport-google-oauth';
import { User } from '../data/models';
import config from '../config';
import {
  ACTIVE,
  PENDING,
} from '../constants/userStatus';

/* eslint-disable */
const LocalStrategy = passportLocal.Strategy;
passport.use(
  'google',
  new OAuth2Strategy(
    {
      clientID: config.google.clientID,
      clientSecret: config.google.clientSecret,
      callbackURL: config.google.callbackURL,
      passReqToCallback: true,
    },
    (req, accessToken, refreshToken, profile, done) => {
      const { displayName, id, emails } = profile;
      const email = (emails[0].value || '').toLowerCase();
      const google = {
        id: profile.id,
        token: accessToken,
        refreshToken,
      }
      const userObj = {
        google,
        name: displayName,
        email: email,
        status: ACTIVE,
      }
      const message = 'Successfully Logged In';
      process.nextTick(async () => {
        try {
          if (!req.user) {
            const userWithEmail = await User.findOne({ email });
            if (userWithEmail && userWithEmail.status === PENDING) {
              const u = Object.assign({}, userObj, userWithEmail);
              await u.save();
              return done(null, {
                success: true,
                message,
                user: u,
              });
            }
            let user = await User.findOne({ 'google.id': profile.id });
            if (user) {
              user.google = google;
            } else {
              user = Object.assign({}, userObj, new User());
            }
            await user.save();
            return done(null, {
              success: true,
              message,
              user,
            });

          }
          const user = req.user;
          await user.save();
          return done(null, {
            success: true,
            message,
            user,
          });
        } catch (error) {
           return done(null, false, {
            success: false,
            message: error,
          });
        }
      });
    },
  ),
);

passport.serializeUser((req, done) => {
  done(null, req.user._id);
});

passport.deserializeUser((id, done) => {
  User.findById(id, (err, req) => {
    done(err, req);
  });
});
<|endoftext|>


<commit_before>import StaticClass from './StaticClass';

/**
 * UUID util class
 * @static
 * @private
 */
export default class Uuid extends StaticClass {
  /**
   * Generate a UUID4 string
   * @returns {string} - Uuid
   */
  static uuid4() {
    // Use the secure method if possible
    return typeof crypto !== 'undefined' ? Uuid._uuid4Safe() : Uuid._uuid4Unsafe();
  }

  /**
   * Unsafe UUID4 generation using Math.random
   * @returns {string} - Uuid
   *
   * @see http://stackoverflow.com/a/8809472
   * @license MIT|Public Domain
   * @private
   */
  static _uuid4Unsafe() {
    let d = new Date().getTime();

    if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
      d += performance.now(); // use high-precision timer if available
    }

    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
      const r = (d + Math.random() * 16) % 16 | 0;

      d = Math.floor(d / 16);
      return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
    });
  }

  /**
   * Safe UUID4 generation using the crypto api
   * @returns {String} - Uuid
   * @private
   */
  static _uuid4Safe() {
    let data = new Uint8Array(16);

    crypto.getRandomValues(data);

    // cast to array so we can use pop()
    data = [].slice.call(data);

    // Replace 'xx' with a two width base 16 number
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/xx/g, () => {
      // Prepend 00 for padding and grab the last two characters
      return ('00' + data.pop().toString(16)).slice(-2);
    });
  }

  /**
   * Empty uuid as per spec
   * @returns {string} - Uuid
   */
  static nil() {
    return '0000000-0000-0000-0000-000000000000';
  }
}
<commit_msg>Update Uuid crypto detection<commit_after>import StaticClass from './StaticClass';

/**
 * UUID util class
 * @static
 * @private
 */
export default class Uuid extends StaticClass {
  /**
   * Generate a UUID4 string
   * @returns {string} - Uuid
   */
  static uuid4() {
    // Use the secure method if possible
    return typeof crypto !== 'undefined' && crypto.getRandomValues ? Uuid._uuid4Safe() : Uuid._uuid4Unsafe();
  }

  /**
   * Unsafe UUID4 generation using Math.random
   * @returns {string} - Uuid
   *
   * @see http://stackoverflow.com/a/8809472
   * @license MIT|Public Domain
   * @private
   */
  static _uuid4Unsafe() {
    let d = new Date().getTime();

    if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
      d += performance.now(); // use high-precision timer if available
    }

    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
      const r = (d + Math.random() * 16) % 16 | 0;

      d = Math.floor(d / 16);
      return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
    });
  }

  /**
   * Safe UUID4 generation using the crypto api
   * @returns {String} - Uuid
   * @private
   */
  static _uuid4Safe() {
    let data = new Uint8Array(16);

    crypto.getRandomValues(data);

    // cast to array so we can use pop()
    data = [].slice.call(data);

    // Replace 'xx' with a two width base 16 number
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/xx/g, () => {
      // Prepend 00 for padding and grab the last two characters
      return ('00' + data.pop().toString(16)).slice(-2);
    });
  }

  /**
   * Empty uuid as per spec
   * @returns {string} - Uuid
   */
  static nil() {
    return '0000000-0000-0000-0000-000000000000';
  }
}
<|endoftext|>


<commit_before>/*
 * 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.
 */

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

    This file contains methods that ensure that the blocks in the Blockly workspace are attached to each other in a valid sequence.
 */

function validateBlocklyGraph(){
    var blocks = Blockly.getMainWorkspace().getTopBlocks();

	document.getElementById("XMLOutput").value = "";
    if(blocks.length == 0){
        document.getElementById('validation-error-p').innerHTML = "Workspace is empty";
        return false;
    } else if(blocks.length > 1){
        document.getElementById('validation-error-p').innerHTML = "Only the start block is allowed to be placed directly in the workspace";
        return false;
	} else if(blocks[0].type != "block_0"){
        document.getElementById('validation-error-p').innerHTML = "It is compulsory to use the start block (block_0:start)";
        return false;
    } else {
        var blocklyValidationResult = validateBlock(blocks[0]);

        if(blocklyValidationResult) {
            generateXML();
            document.getElementById('validation-error-p').innerHTML = "";
        } else {
            document.getElementById('validation-error-p').innerHTML = "not valid";
        }
        return blocklyValidationResult;
    }
}

//get all blocks. Send each block's slots for validation. Send each child block of each slot for validation
function validateBlock(block){
	var blockValidationResult   = true;
    var availableNotchNumbers   = block.getStatementInputNames();

    for(var i=0; i<availableNotchNumbers.length; i++) {
        var notchNumber         = availableNotchNumbers[i];
        var slotContents        = block.getSlotContentsList(notchNumber);
        var errorContext        = block.type+", slot #"+(i+1);  // not a unique context, but will do for now; the slot# makes sense as a local base-1 number

        var actualChildren = getBlockTypesOfSlotContents(slotContents);
        var thisNotchIsValid = validatorDict[block.type][notchNumber].validate(actualChildren)
        console.log("notch", block.type, notchNumber, actualChildren, validatorDict[block.type][notchNumber], thisNotchIsValid );

        blockValidationResult = thisNotchIsValid && blockValidationResult;
        for(var j=0;j<slotContents.length;j++){
            blockValidationResult = validateBlock(slotContents[j]) && blockValidationResult; // check each of the child blocks in turn
        }
    }
	return blockValidationResult;
}

function getBlockTypesOfSlotContents(blockArray){
	var ans = [];
	for(var i=0; i<blockArray.length; i++){
		ans.push( blockArray[i].type );
	}
	return ans;
}
<commit_msg>Use the setWarningText API to show the validation errors where they happen<commit_after>/*
 * 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.
 */

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

    This file contains methods that ensure that the blocks in the Blockly workspace are attached to each other in a valid sequence.
 */

function validateBlocklyGraph(){
    var blocks = Blockly.getMainWorkspace().getTopBlocks();

	document.getElementById("XMLOutput").value = "";
    if(blocks.length == 0){
        document.getElementById('validation-error-p').innerHTML = "Workspace is empty";
        return false;
    } else if(blocks.length > 1){
        document.getElementById('validation-error-p').innerHTML = "Only the start block is allowed to be placed directly in the workspace";
        return false;
	} else if(blocks[0].type != "block_0"){
        document.getElementById('validation-error-p').innerHTML = "It is compulsory to use the start block (block_0:start)";
        return false;
    } else {
        var blocklyValidationResult = validateBlock(blocks[0]);

        if(blocklyValidationResult) {
            generateXML();
            document.getElementById('validation-error-p').innerHTML = "";
        } else {
            document.getElementById('validation-error-p').innerHTML = "not valid";
        }
        return blocklyValidationResult;
    }
}

//get all blocks. Send each block's slots for validation. Send each child block of each slot for validation
function validateBlock(block){
	var blockValidationResult   = true;
    var availableNotchNumbers   = block.getStatementInputNames();
    var thisBlockErrors         = [];

    for(var i=0; i<availableNotchNumbers.length; i++) {
        var notchNumber         = availableNotchNumbers[i];
        var slotContents        = block.getSlotContentsList(notchNumber);
        var errorContext        = block.type+", slot #"+(i+1);  // not a unique context, but will do for now; the slot# makes sense as a local base-1 number

        var actualChildren = getBlockTypesOfSlotContents(slotContents);
        var thisNotchIsValid = validatorDict[block.type][notchNumber].validate(actualChildren)
        console.log("notch", block.type, notchNumber, actualChildren, validatorDict[block.type][notchNumber], thisNotchIsValid );

        if (!thisNotchIsValid) {
            thisBlockErrors.push(block.getInput(notchNumber).fieldRow[1].getText());
        }
        blockValidationResult = thisNotchIsValid && blockValidationResult;
        for(var j=0;j<slotContents.length;j++){
            blockValidationResult = validateBlock(slotContents[j]) && blockValidationResult; // check each of the child blocks in turn
        }
    }
    if (thisBlockErrors.length > 0) {
        block.setWarningText("These connections are not valid: '" + thisBlockErrors.join("'\n'") + "'" );
    } else {
        block.setWarningText(null);
    }
	return blockValidationResult;
}

function getBlockTypesOfSlotContents(blockArray){
	var ans = [];
	for(var i=0; i<blockArray.length; i++){
		ans.push( blockArray[i].type );
	}
	return ans;
}
<|endoftext|>


<commit_before>function getAnimationDuration(element, prop = 'Animation') {
    let computed = window.getComputedStyle(element);
    if (computed) {
        let duration = computed[`${prop.toLowerCase()}Duration`] ||
            computed[`webkit${prop}Duration`] ||
            computed[`moz${prop}Duration`] ||
            computed[`ms${prop}Duration`] ||
            computed[`o${prop}Duration`];
        if (duration) {
            return parseFloat(duration);
        }
    }
    return 0;
}

function getTransitionDuration(element) {
    return getAnimationDuration(element, 'Transition');
}

export class PageView {
    constructor(view) {
        let element = document.createElement('section');
        element.className = 'page-view';
        Object.defineProperty(element, 'destroy', {
            value: () =>
                view.destroy().then(() => {
                    if (element && element.parentNode) {
                        element.parentNode.removeChild(element);
                    }
                    return Promise.resolve();
                })
            ,
        });
        Object.defineProperty(element, 'hide', {
            value: (immediate) =>
                new Promise((resolve) => {
                    element.setAttribute('hidden', '');
                    if (!immediate) {
                        element.setAttribute('data-hidden-animation', '');
                        let duration = getAnimationDuration(element) ||
                            getTransitionDuration(element) || 0;
                        setTimeout(() => {
                            element.removeAttribute('data-hidden-animation');
                            resolve();
                        }, duration * 1000);
                    } else {
                        resolve();
                    }
                }),
        });
        Object.defineProperty(element, 'show', {
            value: (immediate) =>
                new Promise((resolve) => {
                    element.removeAttribute('hidden');
                    if (!immediate) {
                        element.setAttribute('data-hidden-animation', '');
                        let duration = getAnimationDuration(element) ||
                            getTransitionDuration(element) || 0;
                        setTimeout(() => {
                            element.removeAttribute('data-hidden-animation');
                            resolve();
                        }, duration * 1000);
                    } else {
                        resolve();
                    }
                }),
        });
        return element;
    }
}
<commit_msg>refactor: improve page dispatcher<commit_after>function getAnimationDuration(element, prop = 'Animation') {
    let computed = window.getComputedStyle(element);
    if (computed) {
        let duration = computed[`${prop.toLowerCase()}Duration`] ||
            computed[`webkit${prop}Duration`] ||
            computed[`moz${prop}Duration`] ||
            computed[`ms${prop}Duration`] ||
            computed[`o${prop}Duration`];
        if (duration) {
            return parseFloat(duration);
        }
    }
    return 0;
}

function getTransitionDuration(element) {
    return getAnimationDuration(element, 'Transition');
}

export class PageView {
    constructor(view) {
        let element = document.createElement('section');
        element.className = 'page-view';
        Object.defineProperty(element, 'destroy', {
            value: (immediate) =>
                view.destroy().then(() => {
                    element.hide(immediate).then(() => {
                        if (element && element.parentNode) {
                            element.parentNode.removeChild(element);
                        }
                    });
                    return Promise.resolve();
                })
            ,
        });
        Object.defineProperty(element, 'hide', {
            value: (immediate) =>
                new Promise((resolve) => {
                    element.setAttribute('hidden', '');
                    if (!immediate) {
                        element.setAttribute('data-hidden-animation', '');
                        let duration = getAnimationDuration(element) ||
                            getTransitionDuration(element) || 0;
                        setTimeout(() => {
                            element.removeAttribute('data-hidden-animation');
                            resolve();
                        }, duration * 1000);
                    } else {
                        resolve();
                    }
                }),
        });
        Object.defineProperty(element, 'show', {
            value: (immediate) =>
                new Promise((resolve) => {
                    element.removeAttribute('hidden');
                    if (!immediate) {
                        element.setAttribute('data-hidden-animation', '');
                        let duration = getAnimationDuration(element) ||
                            getTransitionDuration(element) || 0;
                        setTimeout(() => {
                            element.removeAttribute('data-hidden-animation');
                            resolve();
                        }, duration * 1000);
                    } else {
                        resolve();
                    }
                }),
        });
        return element;
    }
}
<|endoftext|>


<commit_before>import template from './vue-toastr.html'
import toast from './toast/toast.js'
export default {
    template: template,
    name: 'vueToastr',
    data() {
        var positions = ['toast-top-right', 'toast-bottom-right', 'toast-bottom-left', 'toast-top-left', 'toast-top-full-width', 'toast-bottom-full-width', 'toast-top-center', 'toast-bottom-center']
        var list = {}
        for (var i = 0; i <= positions.length - 1; i++) {
            list[positions[i]] = new Object();
        }
        return {
            positions,
            defaultPosition: 'toast-top-right',
            defaultType: 'success',
            defaultCloseOnHover: true,
            defaultTimeout: 5000,
            defaultProgressBar: true,
            defaultProgressBarValue: null,
            defaultPreventDuplicates: false,
            list,
            index: 0,
        }
    },
    created() {
        // console.log("Created");
    },
    mounted() {
        // console.log("ready", this.list);
    },
    components: {
        toast
    },
    methods: {
        addToast(data) {
            this.index++;
            data['index'] = this.index;
            this.$set(this.list[data.position], this.index, data);
            //if have onCreated
            if (typeof data.onCreated !== 'undefined') {
                // wait doom update after call cb
                this.$nextTick(() => {
                    data.onCreated()
                })
            }
        },
        removeToast(data) {
            var item = this.list[data.position][data.index];
            // console.log("remove toast", data, item);
            if (typeof item != "undefined") {
                this.$delete(this.list[data.position], data.index);
                // if have onClosed
                if (typeof data.onClosed !== 'undefined') {
                    // wait doom update after call cb
                    this.$nextTick(() => {
                        data.onClosed()
                    })
                }
            }
        },
        setProgress(data, newValue) {
            var item = this.list[data.position][data.index];
            if (typeof item != "undefined") {
                this.$set(item, 'progressBarValue', newValue);
            }
        },
        Add(d) {
            return this.AddData(this.processObjectData(d))
        },
        AddData(data) {
            if (typeof data !== 'object') {
                console.log('AddData accept only Object', data)
                return false
            }
            if (data.preventDuplicates) {
                var listKeys = Object.keys(this.list[data.position]);
                for (var i = 0; i < listKeys.length; i++) {
                    if (this.list[data.position].title === data.title && this.list[data.position].msg === data.msg) {
                        console.log('Prevent Dublicates', data)
                        return false
                    }
                }
            }
            this.addToast(data)
            return data
        },
        processObjectData(data) {
            // if Object
            if (typeof data === 'object' && typeof data.msg !== 'undefined') {
                if (typeof data.position === 'undefined') {
                    data.position = this.defaultPosition
                }
                if (typeof data.type === 'undefined') {
                    data.type = this.defaultType
                }
                if (typeof data.timeout === 'undefined') {
                    data.timeout = this.defaultTimeout
                }
                // have progressBar ?
                if (typeof data.progressbar === 'undefined') {
                    data.progressbar = this.defaultProgressBar
                }
                // should progressBar be bound to timer or is set manually ?
                if (typeof data.progressBarValue === 'undefined') {
                    data.progressBarValue = this.defaultProgressBarValue
                }

                if (typeof data.closeOnHover === 'undefined') {
                    data.closeOnHover = this.defaultCloseOnHover
                }

                if (typeof data.preventDuplicates === 'undefined') {
                    data.preventDuplicates = this.defaultPreventDuplicates;
                }
                return data
            }
            // if String
            return {
                msg: data.toString(),
                position: this.defaultPosition,
                type: this.defaultType,
                timeout: this.defaultTimeout,
                closeOnHover: this.defaultCloseOnHover,
                progressbar: this.defaultProgressBar,
                progressBarValue: this.defaultProgressBarValue
            }
        },
        e(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'error'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        s(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'success'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        w(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'warning'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        i(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'info'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        Close(data) {
            // console.log(data)
            this.removeToast(data)
        },
        removeByType(toastType) {
            for (var i = 0; i < this.positions.length; i++) {
                var listKeys = Object.keys(this.list[this.positions[i]]);
                for (var j = 0; j < listKeys.length; j++) {
                    if (this.list[this.positions[i]][listKeys[j]]['type'] === toastType) {
                        this.Close(this.list[this.positions[i]][listKeys[j]]);
                    }
                }
            }
        },
        clearAll() {
            for (var i = 0; i < this.positions.length; i++) {
                var listKeys = Object.keys(this.list[this.positions[i]]);
                for (var j = 0; j < listKeys.length; j++) {
                    this.Close(this.list[this.positions[i]][listKeys[j]]);
                }
            }
        },
    }
}<commit_msg>Fixed a couple of problems in preventDuplicates<commit_after>import template from './vue-toastr.html'
import toast from './toast/toast.js'
export default {
    template: template,
    name: 'vueToastr',
    data() {
        var positions = ['toast-top-right', 'toast-bottom-right', 'toast-bottom-left', 'toast-top-left', 'toast-top-full-width', 'toast-bottom-full-width', 'toast-top-center', 'toast-bottom-center']
        var list = {}
        for (var i = 0; i <= positions.length - 1; i++) {
            list[positions[i]] = new Object();
        }
        return {
            positions,
            defaultPosition: 'toast-top-right',
            defaultType: 'success',
            defaultCloseOnHover: true,
            defaultTimeout: 5000,
            defaultProgressBar: true,
            defaultProgressBarValue: null,
            defaultPreventDuplicates: false,
            list,
            index: 0,
        }
    },
    created() {
        // console.log("Created");
    },
    mounted() {
        // console.log("ready", this.list);
    },
    components: {
        toast
    },
    methods: {
        addToast(data) {
            this.index++;
            data['index'] = this.index;
            this.$set(this.list[data.position], this.index, data);
            //if have onCreated
            if (typeof data.onCreated !== 'undefined') {
                // wait doom update after call cb
                this.$nextTick(() => {
                    data.onCreated()
                })
            }
        },
        removeToast(data) {
            var item = this.list[data.position][data.index];
            // console.log("remove toast", data, item);
            if (typeof item != "undefined") {
                this.$delete(this.list[data.position], data.index);
                // if have onClosed
                if (typeof data.onClosed !== 'undefined') {
                    // wait doom update after call cb
                    this.$nextTick(() => {
                        data.onClosed()
                    })
                }
            }
        },
        setProgress(data, newValue) {
            var item = this.list[data.position][data.index];
            if (typeof item != "undefined") {
                this.$set(item, 'progressBarValue', newValue);
            }
        },
        Add(d) {
            return this.AddData(this.processObjectData(d))
        },
        AddData(data) {
            if (typeof data !== 'object') {
                console.log('AddData accept only Object', data)
                return false
            }
            if (data.preventDuplicates) {
                var listKeys = Object.keys(this.list[data.position]);
                for (var i = 0; i < listKeys.length; i++) {
                    if (this.list[data.position][listKeys[i]].title === data.title && this.list[data.position][listKeys[i]].msg === data.msg) {
                        console.log('Prevent Duplicates', data)
                        return false
                    }
                }
            }
            this.addToast(data)
            return data
        },
        processObjectData(data) {
            // if Object
            if (typeof data === 'object' && typeof data.msg !== 'undefined') {
                if (typeof data.position === 'undefined') {
                    data.position = this.defaultPosition
                }
                if (typeof data.type === 'undefined') {
                    data.type = this.defaultType
                }
                if (typeof data.timeout === 'undefined') {
                    data.timeout = this.defaultTimeout
                }
                // have progressBar ?
                if (typeof data.progressbar === 'undefined') {
                    data.progressbar = this.defaultProgressBar
                }
                // should progressBar be bound to timer or is set manually ?
                if (typeof data.progressBarValue === 'undefined') {
                    data.progressBarValue = this.defaultProgressBarValue
                }

                if (typeof data.closeOnHover === 'undefined') {
                    data.closeOnHover = this.defaultCloseOnHover
                }

                if (typeof data.preventDuplicates === 'undefined') {
                    data.preventDuplicates = this.defaultPreventDuplicates;
                }
                return data
            }
            // if String
            return {
                msg: data.toString(),
                position: this.defaultPosition,
                type: this.defaultType,
                timeout: this.defaultTimeout,
                closeOnHover: this.defaultCloseOnHover,
                progressbar: this.defaultProgressBar,
                progressBarValue: this.defaultProgressBarValue,
                preventDuplicates: this.defaultPreventDuplicates
            }
        },
        e(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'error'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        s(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'success'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        w(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'warning'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        i(msg, title) {
            var data = this.processObjectData(msg)
            data['type'] = 'info'
            if (typeof title !== 'undefined') {
                data['title'] = title
            }
            return this.AddData(data)
        },
        Close(data) {
            // console.log(data)
            this.removeToast(data)
        },
        removeByType(toastType) {
            for (var i = 0; i < this.positions.length; i++) {
                var listKeys = Object.keys(this.list[this.positions[i]]);
                for (var j = 0; j < listKeys.length; j++) {
                    if (this.list[this.positions[i]][listKeys[j]]['type'] === toastType) {
                        this.Close(this.list[this.positions[i]][listKeys[j]]);
                    }
                }
            }
        },
        clearAll() {
            for (var i = 0; i < this.positions.length; i++) {
                var listKeys = Object.keys(this.list[this.positions[i]]);
                for (var j = 0; j < listKeys.length; j++) {
                    this.Close(this.list[this.positions[i]][listKeys[j]]);
                }
            }
        },
    }
}<|endoftext|>


<commit_before>/* Exports an object that defines
 *  all of the configuration needed by the projects'
 *  depended-on grunt tasks.
 *
 * You can find the parent object in: node_modules/lineman/config/application.coffee
 */

module.exports = require(process.env['LINEMAN_MAIN']).config.extend('application', {

  // html5push state simulation
  server: {
    pushState: true
  },

  // configure lineman to load additional angular related npm tasks
  loadNpmTasks: [
    "grunt-angular-templates",
    "grunt-concat-sourcemap",
    "grunt-ngmin"
  ],

  // we don't have handlebars templates or coffeescript by default
  removeTasks: {
    common: ["concat", "handlebars", "coffee", "jst"]
  },

  // task override configuration
  prependTasks: {
    dist: ["ngmin"],         // ngmin should run in dist only
    common: ["ngtemplates"] // ngtemplates runs in dist and dev
  },

  // swaps concat_sourcemap in place of vanilla concat
  appendTasks: {
    common: ["concat_sourcemap"]
  },

  // configuration for grunt-angular-templates
  ngtemplates: {
    app: { // "app" matches the name of the angular module defined in app.js
      options: {
        base: "app/templates"
      },
      src: "app/templates/**/*.html",
      // puts angular templates in a different spot than lineman looks for other templates in order not to conflict with the watch process
      dest: "generated/angular/template-cache.js"
    }
  },

  // configuration for grunt-ngmin, this happens _after_ concat once, which is the ngmin ideal :)
  ngmin: {
    js: {
      src: "<%= files.js.concatenated %>",
      dest: "<%= files.js.concatenated %>"
    }
  },

  // generates a sourcemap for js, specs, and css with inlined sources
  // grunt-angular-templates expects that a module already be defined to inject into
  // this configuration orders the template inclusion _after_ the app level module
  concat_sourcemap: {
    options: {
      sourcesContent: true
    },
    js: {
      src: ["<banner:meta.banner>", "<%= files.js.vendor %>", "<%= files.coffee.generated %>", "<%= files.js.app %>", "<%= files.ngtemplates.dest %>"],
      dest: "<%= files.js.concatenated %>"
    },
    spec: {
      src: ["<%= files.js.specHelpers %>", "<%= files.coffee.generatedSpecHelpers %>", "<%= files.js.spec %>", "<%= files.coffee.generatedSpec %>"],
      dest: "<%= files.js.concatenatedSpec %>"
    },
    css: {
      src: ["<%= files.less.generatedVendor %>", "<%= files.sass.generatedVendor %>", "<%= files.css.vendor %>", "<%= files.less.generatedApp %>", "<%= files.sass.generatedApp %>", "<%= files.css.app %>"],
      dest: "<%= files.css.concatenated %>"
    }
  },

  // configures grunt-watch-nospawn to listen for changes to
  // and recompile angular templates, also swaps lineman default
  // watch target concat with concat_sourcemap
  watch: {
    ngtemplates: {
      files: "app/templates/**/*.html",
      tasks: ["ngtemplates", "concat_sourcemap:js"]
    },
    js: {
      files: ["<%= files.js.vendor %>", "<%= files.js.app %>"],
      tasks: ["concat_sourcemap:js"]
    },
    coffee: {
      files: "<%= files.coffee.app %>",
      tasks: ["coffee", "concat_sourcemap:js"]
    },
    jsSpecs: {
      files: ["<%= files.js.specHelpers %>", "<%= files.js.spec %>"],
      tasks: ["concat_sourcemap:spec"]
    },
    coffeeSpecs: {
      files: ["<%= files.coffee.specHelpers %>", "<%= files.coffee.spec %>"],
      tasks: ["coffee", "concat_sourcemap:spec"]
    },
    css: {
      files: ["<%= files.css.vendor %>", "<%= files.css.app %>"],
      tasks: ["concat_sourcemap:css"]
    },
    less: {
      files: ["<%= files.less.vendor %>", "<%= files.less.app %>"],
      tasks: ["less", "concat_sourcemap:css"]
    },
    sass: {
      files: ["<%= files.sass.vendor %>", "<%= files.sass.app %>"],
      tasks: ["sass", "concat_sourcemap:css"]
    }
  }

});
<commit_msg>[balrog-ui] We need coffeescript again!<commit_after>/* Exports an object that defines
 *  all of the configuration needed by the projects'
 *  depended-on grunt tasks.
 *
 * You can find the parent object in: node_modules/lineman/config/application.coffee
 */

module.exports = require(process.env['LINEMAN_MAIN']).config.extend('application', {

  // html5push state simulation
  server: {
    pushState: true
  },

  // configure lineman to load additional angular related npm tasks
  loadNpmTasks: [
    "grunt-angular-templates",
    "grunt-concat-sourcemap",
    "grunt-ngmin"
  ],

  // we don't have handlebars templates or coffeescript by default
  removeTasks: {
    common: ["concat", "handlebars", "jst"]
  },

  // task override configuration
  prependTasks: {
    dist: ["ngmin"],         // ngmin should run in dist only
    common: ["ngtemplates"] // ngtemplates runs in dist and dev
  },

  // swaps concat_sourcemap in place of vanilla concat
  appendTasks: {
    common: ["concat_sourcemap"]
  },

  // configuration for grunt-angular-templates
  ngtemplates: {
    app: { // "app" matches the name of the angular module defined in app.js
      options: {
        base: "app/templates"
      },
      src: "app/templates/**/*.html",
      // puts angular templates in a different spot than lineman looks for other templates in order not to conflict with the watch process
      dest: "generated/angular/template-cache.js"
    }
  },

  // configuration for grunt-ngmin, this happens _after_ concat once, which is the ngmin ideal :)
  ngmin: {
    js: {
      src: "<%= files.js.concatenated %>",
      dest: "<%= files.js.concatenated %>"
    }
  },

  // generates a sourcemap for js, specs, and css with inlined sources
  // grunt-angular-templates expects that a module already be defined to inject into
  // this configuration orders the template inclusion _after_ the app level module
  concat_sourcemap: {
    options: {
      sourcesContent: true
    },
    js: {
      src: ["<banner:meta.banner>", "<%= files.js.vendor %>", "<%= files.coffee.generated %>", "<%= files.js.app %>", "<%= files.ngtemplates.dest %>"],
      dest: "<%= files.js.concatenated %>"
    },
    spec: {
      src: ["<%= files.js.specHelpers %>", "<%= files.coffee.generatedSpecHelpers %>", "<%= files.js.spec %>", "<%= files.coffee.generatedSpec %>"],
      dest: "<%= files.js.concatenatedSpec %>"
    },
    css: {
      src: ["<%= files.less.generatedVendor %>", "<%= files.sass.generatedVendor %>", "<%= files.css.vendor %>", "<%= files.less.generatedApp %>", "<%= files.sass.generatedApp %>", "<%= files.css.app %>"],
      dest: "<%= files.css.concatenated %>"
    }
  },

  // configures grunt-watch-nospawn to listen for changes to
  // and recompile angular templates, also swaps lineman default
  // watch target concat with concat_sourcemap
  watch: {
    ngtemplates: {
      files: "app/templates/**/*.html",
      tasks: ["ngtemplates", "concat_sourcemap:js"]
    },
    js: {
      files: ["<%= files.js.vendor %>", "<%= files.js.app %>"],
      tasks: ["concat_sourcemap:js"]
    },
    coffee: {
      files: "<%= files.coffee.app %>",
      tasks: ["coffee", "concat_sourcemap:js"]
    },
    jsSpecs: {
      files: ["<%= files.js.specHelpers %>", "<%= files.js.spec %>"],
      tasks: ["concat_sourcemap:spec"]
    },
    coffeeSpecs: {
      files: ["<%= files.coffee.specHelpers %>", "<%= files.coffee.spec %>"],
      tasks: ["coffee", "concat_sourcemap:spec"]
    },
    css: {
      files: ["<%= files.css.vendor %>", "<%= files.css.app %>"],
      tasks: ["concat_sourcemap:css"]
    },
    less: {
      files: ["<%= files.less.vendor %>", "<%= files.less.app %>"],
      tasks: ["less", "concat_sourcemap:css"]
    },
    sass: {
      files: ["<%= files.sass.vendor %>", "<%= files.sass.app %>"],
      tasks: ["sass", "concat_sourcemap:css"]
    }
  }

});
<|endoftext|>


<commit_before>/**
 * @file XML Writer
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global  _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfObjectForEach*/
/*global _gpfArrayForEachFalsy*/
/*global _gpfIgnore*/
/*global _GpfStreamBufferedRead*/ // gpf.stream.BufferedRead
/*exported _GpfXmlWriter*/ // gpf.xml.Writer
/*#endif*/

_gpfErrorDeclare("xml/writer", {

    /**
     * ### Summary
     *
     * Invalid XML Writer state
     *
     * ### Description
     *
     * This error is used when a method can not be called due to the current XML writer state
     */
    invalidXmlWriterState: "Invalid XML Writer state",

    /**
     * ### Summary
     *
     * Invalid XML name
     *
     * ### Description
     *
     * Invalid XML Element and attribute name
     */
    invalidXmlName: "Invalid XML name",

    /**
     * ### Summary
     *
     * Invalid XML namespace prefix
     *
     * ### Description
     *
     * Invalid XML namespace prefix
     */
    invalidXmlNamespacePrefix: "Invalid XML namespace prefix",

    /**
     * ### Summary
     *
     * Unknown XML namespace prefix
     *
     * ### Description
     *
     * This error is triggered when an element or an attribute is prefixed with an unknown namespace prefix
     */
    unknownXmlNamespacePrefix: "Unknown XML namespace prefix"

});

var
    _gpfXmlWriterNameValidation = new RegExp("^[a-z_][a-zA-Z0-9_\\-]*$"),
    _gpfXmlWriterNamespacePrefixValidation = new RegExp("^(|[a-z_][a-zA-Z0-9_]*)$"),
    _gpfXmlWriterPredefinedNamespacePrefixes = ["xml", "xmlns"],

    _GpfXmlWriter = _gpfDefine({
        $class: "gpf.xml.Writer",
        $extend: _GpfStreamBufferedRead,

        /**
         * XML writer
         *
         * @constructor gpf.xml.Writer
         * @implements {gpf.interfaces.IReadableStream}
         * @implements {gpf.interfaces.IXmlContentHandler}
         * @extends gpf.stream.BufferedRead
         */
        constructor: function () {
            this._elements = [];
            this._nextNamespaces = {};
        },

        _elements: [],
        _nextNamespaces: {},
        _started: false,

        _checkIfStarted: function (started) {
            if (this._started !== started) {
                gpf.Error.invalidXmlWriterState();
            }
        },

        _checkIfElementsExist: function (hasElements) {
            if (hasElements !== (this._elements.length !== 0)) {
                gpf.Error.invalidXmlWriterState();
            }
        },

        _checkState: function (started, hasElements) {
            this._checkIfStarted(started);
            if (undefined !== hasElements) {
                this._checkIfElementsExist(hasElements);
            }
        },

        _addContentToElement: function (element) {
            if (!element.content) {
                this._appendToReadBuffer(">");
                element.content = true;
            }
        },

        _addContentToLastElement: function () {
            var element = this._elements[0];
            if (element) {
                return this._addContentToElement(element);
            }
        },

        _checkValidName: function (name) {
            if (!name.match(_gpfXmlWriterNameValidation)) {
                gpf.Error.invalidXmlName();
            }
        },

        _getNamespacePrefixURI: function (prefix) {
            return _gpfArrayForEachFalsy(this._elements, function (element) {
                return element.namespaces[prefix];
            });
        },

        _checkNamespacePrefixWasDefined: function (prefix) {
            if (!this._getNamespacePrefixURI(prefix)) {
                gpf.Error.unknownXmlNamespacePrefix();
            }
        },

        _checkNamespacePrefix: function (prefix) {
            if (prefix !== "xml") {
                this._checkNamespacePrefixWasDefined(prefix);
            }
        },

        _checkQualifiedName: function (qName) {
            var columnPos = qName.indexOf(":");
            if (-1 === columnPos) {
                this._checkValidName(qName);
            } else {
                this._checkNamespacePrefix(qName.substr(0, columnPos));
                this._checkValidName(qName.substr(columnPos + 1));
            }
        },

        _writeAttribute: function (qName, value) {
            this._appendToReadBuffer(" " + qName + "=\"");
            this._appendToReadBuffer(_gpfStringEscapeFor(value.toString(), "xml"));
            this._appendToReadBuffer("\"");
        },

        _validateAndwriteAttribute: function (value, qName) {
            this._checkQualifiedName(qName);
            this._writeAttribute(qName, value);
        },

        _processAttributes: function (attributes) {
            _gpfObjectForEach(attributes, this._validateAndwriteAttribute, this);
        },

        _processNamespaces: function (namespaces) {
            _gpfObjectForEach(namespaces, function (value, name) {
                /*jshint validthis:true*/
                var me = this; //eslint-disable-line no-invalid-this
                if (name) {
                    me._writeAttribute("xmlns:" + name, value);
                } else {
                    me._writeAttribute("xmlns", value);
                }
            }, this);
        },

        _checkNotAPredefinedNamespacePrefix: function (prefix) {
            if (_gpfXmlWriterPredefinedNamespacePrefixes.indexOf(prefix) !== -1) {
                gpf.Error.invalidXmlNamespacePrefix();
            }
        },

        _checkValidNamespacePrefix: function (prefix) {
            if (!prefix.match(_gpfXmlWriterNamespacePrefixValidation)) {
                gpf.Error.invalidXmlNamespacePrefix();
            }
            this._checkNotAPredefinedNamespacePrefix(prefix);
        },

        // region gpf.interfaces.IXmlContentHandler

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#characters */
        characters: function (buffer) {
            this._checkState(true, true);
            this._addContentToLastElement();
            this._appendToReadBuffer(_gpfStringEscapeFor(buffer.toString(), "xml"));
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#endDocument */
        endDocument: function () {
            this._checkState(true, false);
            this._completeReadBuffer();
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#endElement */
        endElement: function () {
            this._checkState(true, true);
            var element = this._elements.shift();
            if (element.content) {
                this._appendToReadBuffer("</" + element.qName + ">");
            } else {
                this._appendToReadBuffer("/>");
            }
            return Promise.resolve();
        },

        /**
         * @gpf:sameas gpf.interfaces.IXmlContentHandler#endPrefixMapping
         * Actually this call is ignored since closing the element owning the namespaces will do the same.
         */
        endPrefixMapping: function (prefix) {
            this._checkState(true);
            _gpfIgnore(prefix);
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#processingInstruction */
        processingInstruction: function (target, data) {
            this._checkState(true, false);
            this._appendToReadBuffer("<?" + target + " " + data + "?>\n");
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startDocument */
        startDocument: function () {
            this._checkState(false, false);
            this._started = true;
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startElement */
        startElement: function (qName, attributes) {
            var namespaces = this._nextNamespaces;
            this._checkState(true);
            this._addContentToLastElement();
            this._elements.unshift({
                qName: qName,
                namespaces: namespaces
            });
            this._nextNamespaces = {};
            this._checkQualifiedName(qName);
            this._appendToReadBuffer("<" + qName);
            if (attributes) {
                this._processAttributes(attributes);
            }
            this._processNamespaces(namespaces);
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startPrefixMapping */
        startPrefixMapping: function (prefix, uri) {
            this._checkState(true);
            this._checkValidNamespacePrefix(prefix);
            if (this._nextNamespaces[prefix]) {
                gpf.Error.invalidXmlWriterState();
            }
            this._nextNamespaces[prefix] = uri;
        }

        //endregion

    });
<commit_msg>WIP (#266)<commit_after>/**
 * @file XML Writer
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfEmptyFunc*/
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global  _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfObjectForEach*/
/*global _gpfArrayForEachFalsy*/
/*global _gpfIgnore*/
/*global _GpfStreamBufferedRead*/ // gpf.stream.BufferedRead
/*exported _GpfXmlWriter*/ // gpf.xml.Writer
/*#endif*/

_gpfErrorDeclare("xml/writer", {

    /**
     * ### Summary
     *
     * Invalid XML Writer state
     *
     * ### Description
     *
     * This error is used when a method can not be called due to the current XML writer state
     */
    invalidXmlWriterState: "Invalid XML Writer state"

});

var
    _GpfXmlWriter = _gpfDefine({
        $class: "gpf.xml.Writer",
        $extend: _GpfStreamBufferedRead,

        /**
         * XML writer
         *
         * @constructor gpf.xml.Writer
         * @implements {gpf.interfaces.IReadableStream}
         * @implements {gpf.interfaces.IXmlContentHandler}
         * @extends gpf.stream.BufferedRead
         */
        constructor: function () {
            this._elements = [];
            this._nextNamespaces = {};
            this._checkIfStarted = gpf.Error.invalidXmlWriterState;
        },

        _elements: [],
        _nextNamespaces: {},

        _checkIfElementsExist: function (hasElements) {
            if (hasElements !== (this._elements.length !== 0)) {
                gpf.Error.invalidXmlWriterState();
            }
        },

        _checkState: function (hasElements) {
            this._checkIfStarted();
            if (undefined !== hasElements) {
                this._checkIfElementsExist(hasElements);
            }
        },

        _addContentToElement: function (element) {
            if (!element.content) {
                this._appendToReadBuffer(">");
                element.content = true;
            }
        },

        _addContentToLastElement: function () {
            var element = this._elements[0];
            if (element) {
                return this._addContentToElement(element);
            }
        },

        _writeAttribute: function (qName, value) {
            this._appendToReadBuffer(" " + qName + "=\"");
            this._appendToReadBuffer(_gpfStringEscapeFor(value.toString(), "xml"));
            this._appendToReadBuffer("\"");
        },

        _getNamespacePrefixes: function () {

            return _gpfArrayForEachFalsy(this._elements, function (element) {
                return element.namespaces[prefix];
            });
        },

        _processAttributes: function (attributes) {
            _gpfObjectForEach(attributes,function (value, qName){
                /*jshint validthis:true*/
                var me = this; //eslint-disable-line no-invalid-this
                _gpfXmlCheckQualifiedAttributeName(qName, me._getNamespacePrefixes());
                me._writeAttribute(qName, value);
            }, this);
        },

        _processNamespaces: function (namespaces) {
            _gpfObjectForEach(namespaces, function (value, name) {
                /*jshint validthis:true*/
                var me = this; //eslint-disable-line no-invalid-this
                if (name) {
                    me._writeAttribute("xmlns:" + name, value);
                } else {
                    me._writeAttribute("xmlns", value);
                }
            }, this);
        },

        // region gpf.interfaces.IXmlContentHandler

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#characters */
        characters: function (buffer) {
            this._checkState(true);
            this._addContentToLastElement();
            this._appendToReadBuffer(_gpfStringEscapeFor(buffer.toString(), "xml"));
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#endDocument */
        endDocument: function () {
            this._checkState(false);
            this._checkIfStarted = gpf.Error.invalidXmlWriterState;
            this._completeReadBuffer();
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#endElement */
        endElement: function () {
            this._checkState(true);
            var element = this._elements.shift();
            if (element.content) {
                this._appendToReadBuffer("</" + element.qName + ">");
            } else {
                this._appendToReadBuffer("/>");
            }
            return Promise.resolve();
        },

        /**
         * @gpf:sameas gpf.interfaces.IXmlContentHandler#endPrefixMapping
         * Actually this call is ignored since closing the element owning the namespaces will do the same.
         */
        endPrefixMapping: function (prefix) {
            this._checkState(true);
            _gpfIgnore(prefix);
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#processingInstruction */
        processingInstruction: function (target, data) {
            this._checkState(false);
            this._appendToReadBuffer("<?" + target + " " + data + "?>\n");
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startDocument */
        startDocument: function () {
            this._checkIfStarted = _gpfEmptyFunc;
            this.startDocument = gpf.Error.invalidXmlWriterState;
            this._checkState(false);
            this._started = true;
            return Promise.resolve();
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startElement */
        startElement: function (qName, attributes) {
            var namespaces = this._nextNamespaces;
            this._checkState(true);
            this._addContentToLastElement();
            this._elements.unshift({
                qName: qName,
                namespaces: namespaces
            });
            this._nextNamespaces = {};
            this._checkQualifiedName(qName);
            this._appendToReadBuffer("<" + qName);
            if (attributes) {
                this._processAttributes(attributes);
            }
            this._processNamespaces(namespaces);
        },

        /** @gpf:sameas gpf.interfaces.IXmlContentHandler#startPrefixMapping */
        startPrefixMapping: function (prefix, uri) {
            this._checkState(true);
            this._checkValidNamespacePrefix(prefix);
            if (this._nextNamespaces[prefix]) {
                gpf.Error.invalidXmlWriterState();
            }
            this._nextNamespaces[prefix] = uri;
        }

        //endregion

    });
<|endoftext|>


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

    angular.module('angular-reverse-url', ['ngRoute'])
        .filter('reverseUrl', ['$route', function ($route) {
            var regexp = /:([A-Za-z0-9]*)\\*?\\??/g;

            return _.memoize(function (controller, params) {
                var targetRoute;
                angular.forEach($route.routes, function (route) {
                    if (route.controller === controller) {

                        // we need to check we are passing the parameters in
                        var success = true;
                        var matches = regexp.exec(route.originalPath);

                        // we can't allow empty params if this route is expecting params
                        if ((matches !== null) && (matches.length > 0) && (angular.isDefined(params) === false)) {
                            success = false;
                        }

                        // TODO: check params exist for each match

                        if (success === true) {
                            targetRoute = route.originalPath;
                            return false;
                        }
                    }
                });
                targetRoute = targetRoute.replace(regexp, function (match, pattern) {
                    return params[pattern];
                });
                return '#' + targetRoute;
            }, function (controller, params) {
                return controller + JSON.stringify(params);
            });
        }]);
}());
<commit_msg>tidying it up briefly<commit_after>(function () {
    'use strict';

    angular.module('angular-reverse-url', ['ngRoute'])
        .filter('reverseUrl', ['$route', function ($route) {
            var regexp = /:([A-Za-z0-9]*)\\*?\\??/g;

            return _.memoize(function (controller, params) {
                var targetRoute;
                angular.forEach($route.routes, function (route) {
                    if (route.controller === controller) {

                        // we need to check we are passing the parameters in
                        var success = true;
                        var matches = regexp.exec(route.originalPath);

                        // we can't allow empty params if this route is expecting params
                        if ((matches !== null) && (matches.length > 0) && (angular.isUndefined(params) === true)) {
                            success = false;
                        }

                        // TODO: check params exist for each match

                        if (success === true) {
                            targetRoute = route.originalPath;
                            return;
                        }
                    }
                });
                targetRoute = targetRoute.replace(regexp, function (match, pattern) {
                    return params[pattern];
                });
                return '#' + targetRoute;
            }, function (controller, params) {
                return controller + JSON.stringify(params);
            });
        }]);
}());
<|endoftext|>