<commit_before>/** Used as default pool (equal temperament 12 semi-tones). */
var ET12POOL = ["Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G"];

/**
* Represents a musical note.
*
* @constructor
* @param name   The name of the note.
* @param freq   Frequency of the note (optional).
* @param octave Index/octave of the note (optional).
* @param name2  Secondary name of the note (optional).
* @returns A Note object.
*/
function Note(name, freq, octave, name2){
    this.name   = name;
    this.octave = octave || 0;
    this.freq   = freq   || 0;
    this.name2  = name2  || "";

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Sets name. */
    this.setName = function(newName){
        this.name = newName;
    };

    /** Sets octave. */
    this.setOctave = function(newOctave){
        this.octave = newOctave;
    };

    /** Sets freq. */
    this.setFreq = function(newFreq){
        this.freq = newFreq;
    };

    /** Sets the secondary name (name2). */
    this.setName2 = function(newName2){
        this.name2 = newName2;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    /** Returns the primitive value of the object, used by the + operator. */
    this.valueOf = function(){
        return this.freq;
    };

    /** Returns name. */
    this.getName = function(){
        return this.name;
    };

    /** Returns octave. */
    this.getOctave = function(){
        return this.octave;
    };

    /** Returns freq. */
    this.getFreq = function(){
        return this.freq;
    };

    /** Returns secondary name (name2). */
    this.getName2 = function(){
        return this.name2;
    };

    /** Returns the object state as a string. */
    this.toString = function(){
        return "name=" + this.name + " name2=" + this.name2 + " freq=" + this.freq + " octave=" + this.octave;
    };
}

/**
* Represents a group of notes. Parent constructor for Chord and Scale.
* @constructor
* @param notes An array of Note objects.
* @param name  Name for the NoteCollection (optional).
* @param name2 Secondary name for the NoteCollection (optional).
*/
function NoteCollection(notes, name, name2){
    if (!(notes instanceof Array)) throw new Error("notes must be an array of Note");
    this.notes  = notes;           // array of notes
    this.notes2 = notes.slice(0);  // original notes (clone)
    this.name   = name  || "";
    this.name2  = name2 || "";
    this.size   = notes.length;

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Change the notes. */ // !!! Should this implement variable arguments?
    this.setNotes = function(notes){
        if (!(notes instanceof Array)) throw new Error("notes must be an array of Note");
        this.notes = notes;
        this.size  = this.notes.length;
    };

    /** Adds one note. */
    this.addNote = function(note){
        if (!(note instanceof Note)) throw new Error("note must be a Note object");
        this.notes.push(note);
        this.size++;
    };

    /** Changes the name of the NoteCollection object. */
    this.setName = function(newName){
        this.name = newName;
    };

    /** Changes the secondary name of the NoteCollection object. */
    this.setName2 = function(newName){
        this.name2 = newName;
    };

    /** Resets notes to its original state (notes2). */
    this.reset = function(){
        this.notes = this.notes2.slice(0);
        this.size  = this.notes.length;
    };

    /** Sends the first note to the last index. */  // !!! Can this be more efficient?
    this.rotate = function(){
        this.notes.push(this.notes.shift());
    };

    /** Sends the last note to the first index. */  // !!! Can this be more efficient?
    this.rotateBack = function(){
        this.notes.unshift(this.notes.pop());
    };

    /** Reverses the order of the notes. */
    this.reverse = function(){
        this.notes.reverse();
    };

    /** Removes the note at given index. */
    this.removeNoteAt = function(index){
        if (index < 0) throw new Error("index must be > 0");
        this.notes.splice(index, 1);
        this.size--;
    };

    /** Removes all the notes with given name. */
    this.removeNotesWithName = function(name){
        this.notes = this.notes.filter(
            function(element){
                return element.name !== name;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes with given secondary name (name2). */
    this.removeNotesWithName2 = function(name){
        this.notes = this.notes.filter(
            function(element){
                return element.name2 !== name;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes with given frequency. */
    this.removeNotesWithFreq = function(freq){
        this.notes = this.notes.filter(
            function(element){
                return element.freq !== freq;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes within a frequency range, inclusive. */
    this.removeNotesWithFreqRange = function(fromFreq, toFreq){
        this.notes = this.notes.filter(
            function(element){
                return element.freq < fromFreq || element.freq > toFreq;
            });
        this.size = this.notes.length;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    /** Returns the object state as a string */
    this.toString = function(){
        var returnString = "name=" + this.name + "\nname2=" + this.name2 + "\nsize=" + this.size;
        returnString += "\nnotes=\n";
        for (var i in this.notes){
            returnString += "<";
            returnString += this.notes[i].toString();
            returnString += ">";
        }
        returnString += "\nnotes2=\n";
        for (var j in this.notes2){
            returnString += "<";
            returnString += this.notes2[j].toString();
            returnString += ">";
        }
        return returnString;
    };

    /** Retunrs the size of the string NoteCollection. */
    this.getSize = function(){
        return this.size;
    };

    /** Returns the notes. */
    this.getNotes = function(){
        return this.notes;
    };

    /** Returns the original notes. */
    this.getOriginalNotes = function(){
        return this.notes2;
    };

    /** Returns name. */
    this.getName = function(){
        return this.name;
    };

    /** Returns secondary name (name2) */
    this.getName2 = function(){
        return this.name2;
    };

    /** Returns the name of the notes as a string. */
    this.getNotesAsString = function(){
        var returnString = "";
        for (var i in this.notes)
            returnString += this.notes[i].name + " ";
        return returnString;
    };

    /** Returns the name of the original notes as a string. */
    this.getOriginalNotesAsString = function(){
        var returnString = "";
        for (var i in this.notes2)
            returnString += this.notes2[i].name + " ";
        return returnString;
    };

    /** Returns the frequencies of the notes as a string. */
    this.getFreqsAsString = function(){
        var returnString = "";
        for (var i in this.notes)
            returnString += this.notes[i].freq + " ";
        return returnString;
    };

    /** Builds an array of the indexes the notes have in a pool. */
    this.toIndexes = function(pool){
        var thePool = pool || ET12POOL;
        var returnArray = [];
        for (var i in this.notes)
            returnArray.push(thePool.indexOf(this.notes[i].name));
        return returnArray;
    };

    /** Builds a formula based on the indexes the notes have in a pool. */ // !!! this can be more efficient
    this.toFormula = function(pool){
        var thePool       = pool || ET12POOL;
        var indexArray    = this.toIndexes();
        var returnArray   = [];
        var formulaLength = indexArray.length;
        var poolLength    = thePool.length;
        for (var i = 0; i < formulaLength; i++){
            var sum = indexArray[i] - indexArray[(i + 1) % formulaLength];
            if (sum > 0) sum -= poolLength;
            returnArray.push(Math.abs(sum));
        }
        return returnArray;
    };

}

/**
* Represents a group of notes as a Chord.
* Inherits fron NoteCollection.
* @constructor
* @param notes An array of Note objects.
* @param name  Name for the NoteCollection (optional).
* @param name2 Secondary name for the NoteCollection (optional).
*/
function Chord(notes, name, name2){
    NoteCollection.apply(this, arguments);  // inherits from NoteCollection

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Sets notes to nth inversion. Sets to previous inversions if n is negative. */ // !!! can this be done more efficiently?
    this.invert = function(n){
        if (typeof(n) !== "number") throw new Error("n must be of type number");
        if (n > 0)
            for (var i = 0; i < n; i++)
                this.notes.push(this.notes.shift());
        if (n < 0)
            for (var j = 0; j > n; j--)
                this.notes.unshift(this.notes.pop());
    };

    /**
    * Sets notes to nth inversion, using the original notes (notes2) as reference.
    * Sets to previous inversions if n is negative.
    */
    this.invertOriginal = function(n){
        if (typeof(n) !== "number") throw new Error("n must be of type number");
        this.reset();
        this.invert(n);
    };
}

/**
* Group of Note objects with melodic dynamics (like a succession of notes).
*
* @constructor
*/
function Scale(notes, name, name2){
    NoteCollection.apply(this, arguments);  // inherits from NoteCollection
}

/**
* Represents a group of chords
* @constructor
*/
function ChordCollection(chords, name, name2){
    if (!(chords instanceof Array)) throw new Error("chords must be an array of Chord");
    this.name   = name  || "";
    this.name2  = name2 || "";
    this.chords = chords;
    this.size   = chords.length;

    // ==============================================
    //                   Mutators
    // ==============================================

    this.setChords = function(newChords){
        if (!(chords instanceof Array)) throw new Error("chords must be an array of Chord");
        this.chords = newChords;
        this.size   = chords.length;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    this.getChords = function(){
        return this.chords;
    };

    this.getChordsNames = function(){
        var returnString = "";
        for (var i in this.chords)
            returnString += this.chords[i].name + " ";
        return returnString;
    };

    this.getChordsNotesAsString = function(){
        var returnString = "";
        for (var i in this.chords)
            returnString += "< " + this.chords[i].getNotesAsString() + "> ";
        return returnString;
    };

    this.toString = function(){
        var returnString = "name=" + this.name + "\nname2=" + this.name2 + "\nsize=" + this.size;
        returnString += "\n\nchords= ";
        for (var i in this.chords){
            returnString += "\n<<<\n";
            returnString += this.chords[i].toString();
            returnString += "\n>>>";
        }
        return returnString;
    };
}

/**
* Represents a group of chords.
* @constructor
*/
function Harmony(chords, name, name2){
    ChordCollection.apply(this, arguments);
}

// node exports
exports.Note            = Note;
exports.NoteCollection  = NoteCollection;
exports.Chord           = Chord;
exports.Scale           = Scale;
exports.ChordCollection = ChordCollection;
exports.Harmony         = Harmony;
<commit_msg>Chord now inherits NoteCollection.prototype<commit_after>/** Used as default pool (equal temperament 12 semi-tones). */
var ET12POOL = ["Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G"];

/**
* Represents a musical note.
*
* @constructor
* @param name   The name of the note.
* @param freq   Frequency of the note (optional).
* @param octave Index/octave of the note (optional).
* @param name2  Secondary name of the note (optional).
* @returns A Note object.
*/
function Note(name, freq, octave, name2){
    this.name   = name   || "";
    this.octave = octave || 0;
    this.freq   = freq   || 0;
    this.name2  = name2  || "";

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Sets name. */
    this.setName = function(newName){
        this.name = newName;
    };

    /** Sets octave. */
    this.setOctave = function(newOctave){
        this.octave = newOctave;
    };

    /** Sets freq. */
    this.setFreq = function(newFreq){
        this.freq = newFreq;
    };

    /** Sets the secondary name (name2). */
    this.setName2 = function(newName2){
        this.name2 = newName2;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    /** Returns the primitive value of the object, used by the + operator. */
    this.valueOf = function(){
        return this.freq;
    };

    /** Returns name. */
    this.getName = function(){
        return this.name;
    };

    /** Returns octave. */
    this.getOctave = function(){
        return this.octave;
    };

    /** Returns freq. */
    this.getFreq = function(){
        return this.freq;
    };

    /** Returns secondary name (name2). */
    this.getName2 = function(){
        return this.name2;
    };

    /** Returns the object state as a string. */
    this.toString = function(){
        return "name=" + this.name + " name2=" + this.name2 + " freq=" + this.freq + " octave=" + this.octave;
    };
}

/**
* Represents a group of notes. Parent constructor for Chord and Scale.
* @constructor
* @param notes An array of Note objects.
* @param name  Name for the NoteCollection (optional).
* @param name2 Secondary name for the NoteCollection (optional).
*/
function NoteCollection(notes, name, name2){
    // if (!(notes instanceof Array)) throw new Error("notes must be an array of Note");
    this.notes  = notes;                           // array of notes
    this.notes2 = notes ? notes.slice(0) : notes;  // original notes (clone)
    this.name   = name  || "";
    this.name2  = name2 || "";
    this.size   = notes ? notes.length : 0;

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Change the notes. */ // !!! Should this implement variable arguments?
    this.setNotes = function(notes){
        if (!(notes instanceof Array)) throw new Error("notes must be an array of Note");
        this.notes = notes;
        this.size  = this.notes.length;
    };

    /** Adds one note. */
    this.addNote = function(note){
        if (!(note instanceof Note)) throw new Error("note must be a Note object");
        this.notes.push(note);
        this.size++;
    };

    /** Changes the name of the NoteCollection object. */
    this.setName = function(newName){
        this.name = newName;
    };

    /** Changes the secondary name of the NoteCollection object. */
    this.setName2 = function(newName){
        this.name2 = newName;
    };

    /** Resets notes to its original state (notes2). */
    this.reset = function(){
        this.notes = this.notes2.slice(0);
        this.size  = this.notes.length;
    };

    /** Sends the first note to the last index. */  // !!! Can this be more efficient?
    this.rotate = function(){
        this.notes.push(this.notes.shift());
    };

    /** Sends the last note to the first index. */  // !!! Can this be more efficient?
    this.rotateBack = function(){
        this.notes.unshift(this.notes.pop());
    };

    /** Reverses the order of the notes. */
    this.reverse = function(){
        this.notes.reverse();
    };

    /** Removes the note at given index. */
    this.removeNoteAt = function(index){
        if (index < 0) throw new Error("index must be > 0");
        this.notes.splice(index, 1);
        this.size--;
    };

    /** Removes all the notes with given name. */
    this.removeNotesWithName = function(name){
        this.notes = this.notes.filter(
            function(element){
                return element.name !== name;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes with given secondary name (name2). */
    this.removeNotesWithName2 = function(name){
        this.notes = this.notes.filter(
            function(element){
                return element.name2 !== name;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes with given frequency. */
    this.removeNotesWithFreq = function(freq){
        this.notes = this.notes.filter(
            function(element){
                return element.freq !== freq;
            });
        this.size = this.notes.length;
    };

    /** Removes all the notes within a frequency range, inclusive. */
    this.removeNotesWithFreqRange = function(fromFreq, toFreq){
        this.notes = this.notes.filter(
            function(element){
                return element.freq < fromFreq || element.freq > toFreq;
            });
        this.size = this.notes.length;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    /** Returns the object state as a string */
    this.toString = function(){
        var returnString = "name=" + this.name + "\nname2=" + this.name2 + "\nsize=" + this.size;
        returnString += "\nnotes=\n";
        for (var i in this.notes){
            returnString += "<";
            returnString += this.notes[i].toString();
            returnString += ">";
        }
        returnString += "\nnotes2=\n";
        for (var j in this.notes2){
            returnString += "<";
            returnString += this.notes2[j].toString();
            returnString += ">";
        }
        return returnString;
    };

    /** Retunrs the size of the string NoteCollection. */
    this.getSize = function(){
        return this.size;
    };

    /** Returns the notes. */
    this.getNotes = function(){
        return this.notes;
    };

    /** Returns the original notes. */
    this.getOriginalNotes = function(){
        return this.notes2;
    };

    /** Returns name. */
    this.getName = function(){
        return this.name;
    };

    /** Returns secondary name (name2) */
    this.getName2 = function(){
        return this.name2;
    };

    /** Returns the name of the notes as a string. */
    this.getNotesAsString = function(){
        var returnString = "";
        for (var i in this.notes)
            returnString += this.notes[i].name + " ";
        return returnString;
    };

    /** Returns the name of the original notes as a string. */
    this.getOriginalNotesAsString = function(){
        var returnString = "";
        for (var i in this.notes2)
            returnString += this.notes2[i].name + " ";
        return returnString;
    };

    /** Returns the frequencies of the notes as a string. */
    this.getFreqsAsString = function(){
        var returnString = "";
        for (var i in this.notes)
            returnString += this.notes[i].freq + " ";
        return returnString;
    };

    /** Builds an array of the indexes the notes have in a pool. */
    this.toIndexes = function(pool){
        var thePool = pool || ET12POOL;
        var returnArray = [];
        for (var i in this.notes)
            returnArray.push(thePool.indexOf(this.notes[i].name));
        return returnArray;
    };

    /** Builds a formula based on the indexes the notes have in a pool. */ // !!! this can be more efficient
    this.toFormula = function(pool){
        var thePool       = pool || ET12POOL;
        var indexArray    = this.toIndexes();
        var returnArray   = [];
        var formulaLength = indexArray.length;
        var poolLength    = thePool.length;
        for (var i = 0; i < formulaLength; i++){
            var sum = indexArray[i] - indexArray[(i + 1) % formulaLength];
            if (sum > 0) sum -= poolLength;
            returnArray.push(Math.abs(sum));
        }
        return returnArray;
    };

}

/**
* Represents a group of notes as a Chord.
* Inherits fron NoteCollection.
* @constructor
* @param notes An array of Note objects.
* @param name  Name for the NoteCollection (optional).
* @param name2 Secondary name for the NoteCollection (optional).
*/
function Chord(notes, name, name2){
    NoteCollection.apply(this, arguments);  // inherits from NoteCollection

    // ==============================================
    //                   Mutators
    // ==============================================

    /** Sets notes to nth inversion. Sets to previous inversions if n is negative. */ // !!! can this be done more efficiently?
    this.invert = function(n){
        if (typeof(n) !== "number") throw new Error("n must be of type number");
        if (n > 0)
            for (var i = 0; i < n; i++)
                this.notes.push(this.notes.shift());
        if (n < 0)
            for (var j = 0; j > n; j--)
                this.notes.unshift(this.notes.pop());
    };

    /**
    * Sets notes to nth inversion, using the original notes (notes2) as reference.
    * Sets to previous inversions if n is negative.
    */
    this.invertOriginal = function(n){
        if (typeof(n) !== "number") throw new Error("n must be of type number");
        this.reset();
        this.invert(n);
    };
}
Chord.prototype = new NoteCollection();
Chord.prototype.constructor = Chord;

/**
* Group of Note objects with melodic dynamics (like a succession of notes).
*
* @constructor
*/
function Scale(notes, name, name2){
    NoteCollection.apply(this, arguments);  // inherits from NoteCollection
}

/**
* Represents a group of chords
* @constructor
*/
function ChordCollection(chords, name, name2){
    if (!(chords instanceof Array)) throw new Error("chords must be an array of Chord");
    this.name   = name  || "";
    this.name2  = name2 || "";
    this.chords = chords;
    this.size   = chords.length;

    // ==============================================
    //                   Mutators
    // ==============================================

    this.setChords = function(newChords){
        if (!(chords instanceof Array)) throw new Error("chords must be an array of Chord");
        this.chords = newChords;
        this.size   = chords.length;
    };

    // ==============================================
    //                  Accessors
    // ==============================================

    this.getChords = function(){
        return this.chords;
    };

    this.getChordsNames = function(){
        var returnString = "";
        for (var i in this.chords)
            returnString += this.chords[i].name + " ";
        return returnString;
    };

    this.getChordsNotesAsString = function(){
        var returnString = "";
        for (var i in this.chords)
            returnString += "< " + this.chords[i].getNotesAsString() + "> ";
        return returnString;
    };

    this.toString = function(){
        var returnString = "name=" + this.name + "\nname2=" + this.name2 + "\nsize=" + this.size;
        returnString += "\n\nchords= ";
        for (var i in this.chords){
            returnString += "\n<<<\n";
            returnString += this.chords[i].toString();
            returnString += "\n>>>";
        }
        return returnString;
    };
}

/**
* Represents a group of chords.
* @constructor
*/
function Harmony(chords, name, name2){
    ChordCollection.apply(this, arguments);
}

// node exports
exports.Note            = Note;
exports.NoteCollection  = NoteCollection;
exports.Chord           = Chord;
exports.Scale           = Scale;
exports.ChordCollection = ChordCollection;
exports.Harmony         = Harmony;
<|endoftext|>


<commit_before>var conf = {
  name: "pollseed",
  age: 34,
  job: "programmer",
  birth: "tokyo",
  mariage: true
};

var User = function(conf) {
  if (conf) {
    this.name = conf.name;
    this.age = conf.age;
    this.job = conf.job;
    this.birth = conf.birth;
    this.mariage = conf.mariage;
  }
}.
  method('getName', function() {
    return this.name;
  }).
  method('getAge', function() {
    return this.age;
  }).
  method('getJob', function() {
    return this.job;
  }).
  method('getBirth', function() {
    return this.birth;
  }).
  method('getMariage', function() {
    return this.mariage;
  }).
  method('setName', function(name) {
    this.name = name;
    return this;
  }).
  method('setAge', function(age) {
    this.age = age;
    return this;
  }).
  method('setJob', function(job) {
    this.job = job;
    return this;
  }).
  method('setMariage', function(mariage) {
    this.mariage;
    return this;
  });

<commit_msg>Update userInfo.js<commit_after>var conf = {
  name: "pollseed",
  age: 34,
  job: "programmer",
  birth: "tokyo",
  mariage: true
};

var User = function(conf) {
  if (conf) {
    this.name = conf.name;
    this.age = conf.age;
    this.job = conf.job;
    this.birth = conf.birth;
    this.mariage = conf.mariage;
  }
}.
  method('getName', function() {
    return this.name;
  }).
  method('getAge', function() {
    return this.age;
  }).
  method('getJob', function() {
    return this.job;
  }).
  method('getBirth', function() {
    return this.birth;
  }).
  method('getMariage', function() {
    return this.mariage;
  }).
  method('setName', function(name) {
    this.name = name;
    return this;
  }).
  method('setAge', function(age) {
    this.age = age;
    return this;
  }).
  method('setJob', function(job) {
    this.job = job;
    return this;
  }).
  method('setBirth', function(birth) {
    this.birth = birth;
    return this;
  })
  method('setMariage', function(mariage) {
    this.mariage;
    return this;
  });

var u = new User();
u.setName('pollseed').setAge(36).setJob('Programmer').setMariage(true).setBirth('tokyo').getName();
<|endoftext|>


<commit_before>'use strict';

var SyntaxReferenceError = require('./error').SyntaxReferenceError;
var MatchError = require('./error').MatchError;
var names = require('../utils/names');
var generic = require('./generic');
var parse = require('./grammar/parse');
var generate = require('./grammar/generate');
var walk = require('./grammar/walk');
var buildMatchTree = require('./match-tree').buildMatchTree;
var matchAsTree = require('./match').matchAsTree;
var trace = require('./trace');
var search = require('./search');
var getStructureFromConfig = require('./structure').getStructureFromConfig;
var cssWideKeywords = buildMatchTree(parse('inherit | initial | unset'));
var cssWideKeywordsWithExpression = buildMatchTree(parse('inherit | initial | unset | <expression>'));

function dumpMapSyntax(map, syntaxAsAst) {
    var result = {};

    for (var name in map) {
        if (map[name].syntax) {
            result[name] = syntaxAsAst ? map[name].syntax : generate(map[name].syntax);
        }
    }

    return result;
}

function valueHasVar(value) {
    var hasVar = false;

    this.syntax.walk(value, function(node) {
        if (node.type === 'Function' && node.name.toLowerCase() === 'var') {
            hasVar = true;
        }
    });

    return hasVar;
}

function buildMatchResult(match, error, interations) {
    return {
        matched: match,
        interations: interations,
        error: error,
        getTrace: trace.getTrace,
        isType: trace.isType,
        isProperty: trace.isProperty,
        isKeyword: trace.isKeyword
    };
}

function matchSyntax(lexer, syntax, node, useCommon) {
    var result;

    if (!node) {
        return buildMatchResult(null, new Error('Node is undefined'));
    }

    if (valueHasVar.call(lexer, node)) {
        return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
    }

    if (useCommon) {
        result = matchAsTree(node, lexer.valueCommonSyntax, lexer);
    }

    if (!useCommon || !result.match) {
        result = matchAsTree(node, syntax.match, lexer);
        if (!result.match) {
            return buildMatchResult(null, new MatchError('Mismatch', lexer, syntax.syntax, node, result.tokens, result.error), result.interations);
        }
    }

    return buildMatchResult(result, null, result.interations);
}

var Lexer = function(config, syntax, structure) {
    this.valueCommonSyntax = cssWideKeywords;
    this.syntax = syntax;
    this.generic = false;
    this.properties = {};
    this.types = {};
    this.structure = structure || getStructureFromConfig(config);

    if (config) {
        if (config.generic) {
            this.generic = true;
            for (var name in generic) {
                this.addType_(name, generic[name]);
            }
        }

        if (config.types) {
            for (var name in config.types) {
                this.addType_(name, config.types[name]);
            }
        }

        if (config.properties) {
            for (var name in config.properties) {
                this.addProperty_(name, config.properties[name]);
            }
        }
    }
};

Lexer.prototype = {
    structure: {},
    checkStructure: function(ast) {
        function collectWarning(node, message) {
            warns.push({
                node: node,
                message: message
            });
        }

        var structure = this.structure;
        var warns = [];

        this.syntax.walk(ast, function(node) {
            if (structure.hasOwnProperty(node.type)) {
                structure[node.type].check(node, collectWarning);
            } else {
                collectWarning(node, 'Unknown node type `' + node.type + '`');
            }
        });

        return warns.length ? warns : false;
    },

    createDescriptor: function(syntax, type, name) {
        var descriptor = {
            type: type,
            name: name,
            syntax: null,
            match: null
        };

        if (typeof syntax === 'function') {
            descriptor.match = {
                type: 'Generic',
                fn: syntax
            };
        } else {
            if (typeof syntax === 'string') {
                // lazy parsing on first access
                Object.defineProperty(descriptor, 'syntax', {
                    get: function() {
                        Object.defineProperty(descriptor, 'syntax', {
                            value: parse(syntax)
                        });

                        return descriptor.syntax;
                    }
                });
            } else {
                descriptor.syntax = syntax;
            }

            Object.defineProperty(descriptor, 'match', {
                get: function() {
                    Object.defineProperty(descriptor, 'match', {
                        value: buildMatchTree(descriptor.syntax)
                    });

                    return descriptor.match;
                }
            });
        }

        return descriptor;
    },
    addProperty_: function(name, syntax) {
        this.properties[name] = this.createDescriptor(syntax, 'Property', name);
    },
    addType_: function(name, syntax) {
        this.types[name] = this.createDescriptor(syntax, 'Type', name);

        if (syntax === generic.expression) {
            this.valueCommonSyntax = cssWideKeywordsWithExpression;
        }
    },

    matchDeclaration: function(node) {
        if (node.type !== 'Declaration') {
            return buildMatchResult(null, new Error('Not a Declaration node'));
        }

        return this.matchProperty(node.property, node.value);
    },
    matchProperty: function(propertyName, value) {
        var property = names.property(propertyName);

        // don't match syntax for a custom property
        if (property.custom) {
            return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
        }

        var propertySyntax = property.vendor
            ? this.getProperty(property.name) || this.getProperty(property.basename)
            : this.getProperty(property.name);

        if (!propertySyntax) {
            return buildMatchResult(null, new SyntaxReferenceError('Unknown property', propertyName));
        }

        return matchSyntax(this, propertySyntax, value, true);
    },
    matchType: function(typeName, value) {
        var typeSyntax = this.getType(typeName);

        if (!typeSyntax) {
            return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));
        }

        return matchSyntax(this, typeSyntax, value, false);
    },
    match: function(syntax, value) {
        if (!syntax || !syntax.type) {
            return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
        }

        if (!syntax.match) {
            syntax = this.createDescriptor(syntax);
        }

        return matchSyntax(this, syntax, value, false);
    },

    findValueFragments: function(propertyName, value, type, name) {
        return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
    },
    findDeclarationValueFragments: function(declaration, type, name) {
        return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
    },
    findAllFragments: function(ast, type, name) {
        var result = [];

        this.syntax.walk(ast, {
            visit: 'Declaration',
            enter: function(declaration) {
                result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
            }.bind(this)
        });

        return result;
    },

    getProperty: function(name) {
        return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
    },
    getType: function(name) {
        return this.types.hasOwnProperty(name) ? this.types[name] : null;
    },

    validate: function() {
        function validate(syntax, name, broken, descriptor) {
            if (broken.hasOwnProperty(name)) {
                return broken[name];
            }

            broken[name] = false;
            if (descriptor.syntax !== null) {
                walk(descriptor.syntax, function(node) {
                    if (node.type !== 'Type' && node.type !== 'Property') {
                        return;
                    }

                    var map = node.type === 'Type' ? syntax.types : syntax.properties;
                    var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;

                    if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
                        broken[name] = true;
                    }
                }, this);
            }
        }

        var brokenTypes = {};
        var brokenProperties = {};

        for (var key in this.types) {
            validate(this, key, brokenTypes, this.types[key]);
        }

        for (var key in this.properties) {
            validate(this, key, brokenProperties, this.properties[key]);
        }

        brokenTypes = Object.keys(brokenTypes).filter(function(name) {
            return brokenTypes[name];
        });
        brokenProperties = Object.keys(brokenProperties).filter(function(name) {
            return brokenProperties[name];
        });

        if (brokenTypes.length || brokenProperties.length) {
            return {
                types: brokenTypes,
                properties: brokenProperties
            };
        }

        return null;
    },
    dump: function(syntaxAsAst) {
        return {
            generic: this.generic,
            types: dumpMapSyntax(this.types, syntaxAsAst),
            properties: dumpMapSyntax(this.properties, syntaxAsAst)
        };
    },
    toString: function() {
        return JSON.stringify(this.dump());
    }
};

module.exports = Lexer;
<commit_msg>fix lexer's match result<commit_after>'use strict';

var SyntaxReferenceError = require('./error').SyntaxReferenceError;
var MatchError = require('./error').MatchError;
var names = require('../utils/names');
var generic = require('./generic');
var parse = require('./grammar/parse');
var generate = require('./grammar/generate');
var walk = require('./grammar/walk');
var buildMatchTree = require('./match-tree').buildMatchTree;
var matchAsTree = require('./match').matchAsTree;
var trace = require('./trace');
var search = require('./search');
var getStructureFromConfig = require('./structure').getStructureFromConfig;
var cssWideKeywords = buildMatchTree(parse('inherit | initial | unset'));
var cssWideKeywordsWithExpression = buildMatchTree(parse('inherit | initial | unset | <expression>'));

function dumpMapSyntax(map, syntaxAsAst) {
    var result = {};

    for (var name in map) {
        if (map[name].syntax) {
            result[name] = syntaxAsAst ? map[name].syntax : generate(map[name].syntax);
        }
    }

    return result;
}

function valueHasVar(value) {
    var hasVar = false;

    this.syntax.walk(value, function(node) {
        if (node.type === 'Function' && node.name.toLowerCase() === 'var') {
            hasVar = true;
        }
    });

    return hasVar;
}

function buildMatchResult(match, error, interations) {
    return {
        matched: match,
        interations: interations,
        error: error,
        getTrace: trace.getTrace,
        isType: trace.isType,
        isProperty: trace.isProperty,
        isKeyword: trace.isKeyword
    };
}

function matchSyntax(lexer, syntax, node, useCommon) {
    var result;

    if (!node) {
        return buildMatchResult(null, new Error('Node is undefined'));
    }

    if (valueHasVar.call(lexer, node)) {
        return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
    }

    if (useCommon) {
        result = matchAsTree(node, lexer.valueCommonSyntax, lexer);
    }

    if (!useCommon || !result.match) {
        result = matchAsTree(node, syntax.match, lexer);
        if (!result.match) {
            return buildMatchResult(null, new MatchError('Mismatch', lexer, syntax.syntax, node, result.tokens, result.error), result.interations);
        }
    }

    return buildMatchResult(result.match, null, result.interations);
}

var Lexer = function(config, syntax, structure) {
    this.valueCommonSyntax = cssWideKeywords;
    this.syntax = syntax;
    this.generic = false;
    this.properties = {};
    this.types = {};
    this.structure = structure || getStructureFromConfig(config);

    if (config) {
        if (config.generic) {
            this.generic = true;
            for (var name in generic) {
                this.addType_(name, generic[name]);
            }
        }

        if (config.types) {
            for (var name in config.types) {
                this.addType_(name, config.types[name]);
            }
        }

        if (config.properties) {
            for (var name in config.properties) {
                this.addProperty_(name, config.properties[name]);
            }
        }
    }
};

Lexer.prototype = {
    structure: {},
    checkStructure: function(ast) {
        function collectWarning(node, message) {
            warns.push({
                node: node,
                message: message
            });
        }

        var structure = this.structure;
        var warns = [];

        this.syntax.walk(ast, function(node) {
            if (structure.hasOwnProperty(node.type)) {
                structure[node.type].check(node, collectWarning);
            } else {
                collectWarning(node, 'Unknown node type `' + node.type + '`');
            }
        });

        return warns.length ? warns : false;
    },

    createDescriptor: function(syntax, type, name) {
        var descriptor = {
            type: type,
            name: name,
            syntax: null,
            match: null
        };

        if (typeof syntax === 'function') {
            descriptor.match = {
                type: 'Generic',
                fn: syntax
            };
        } else {
            if (typeof syntax === 'string') {
                // lazy parsing on first access
                Object.defineProperty(descriptor, 'syntax', {
                    get: function() {
                        Object.defineProperty(descriptor, 'syntax', {
                            value: parse(syntax)
                        });

                        return descriptor.syntax;
                    }
                });
            } else {
                descriptor.syntax = syntax;
            }

            Object.defineProperty(descriptor, 'match', {
                get: function() {
                    Object.defineProperty(descriptor, 'match', {
                        value: buildMatchTree(descriptor.syntax)
                    });

                    return descriptor.match;
                }
            });
        }

        return descriptor;
    },
    addProperty_: function(name, syntax) {
        this.properties[name] = this.createDescriptor(syntax, 'Property', name);
    },
    addType_: function(name, syntax) {
        this.types[name] = this.createDescriptor(syntax, 'Type', name);

        if (syntax === generic.expression) {
            this.valueCommonSyntax = cssWideKeywordsWithExpression;
        }
    },

    matchDeclaration: function(node) {
        if (node.type !== 'Declaration') {
            return buildMatchResult(null, new Error('Not a Declaration node'));
        }

        return this.matchProperty(node.property, node.value);
    },
    matchProperty: function(propertyName, value) {
        var property = names.property(propertyName);

        // don't match syntax for a custom property
        if (property.custom) {
            return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
        }

        var propertySyntax = property.vendor
            ? this.getProperty(property.name) || this.getProperty(property.basename)
            : this.getProperty(property.name);

        if (!propertySyntax) {
            return buildMatchResult(null, new SyntaxReferenceError('Unknown property', propertyName));
        }

        return matchSyntax(this, propertySyntax, value, true);
    },
    matchType: function(typeName, value) {
        var typeSyntax = this.getType(typeName);

        if (!typeSyntax) {
            return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));
        }

        return matchSyntax(this, typeSyntax, value, false);
    },
    match: function(syntax, value) {
        if (!syntax || !syntax.type) {
            return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
        }

        if (!syntax.match) {
            syntax = this.createDescriptor(syntax);
        }

        return matchSyntax(this, syntax, value, false);
    },

    findValueFragments: function(propertyName, value, type, name) {
        return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
    },
    findDeclarationValueFragments: function(declaration, type, name) {
        return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
    },
    findAllFragments: function(ast, type, name) {
        var result = [];

        this.syntax.walk(ast, {
            visit: 'Declaration',
            enter: function(declaration) {
                result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
            }.bind(this)
        });

        return result;
    },

    getProperty: function(name) {
        return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
    },
    getType: function(name) {
        return this.types.hasOwnProperty(name) ? this.types[name] : null;
    },

    validate: function() {
        function validate(syntax, name, broken, descriptor) {
            if (broken.hasOwnProperty(name)) {
                return broken[name];
            }

            broken[name] = false;
            if (descriptor.syntax !== null) {
                walk(descriptor.syntax, function(node) {
                    if (node.type !== 'Type' && node.type !== 'Property') {
                        return;
                    }

                    var map = node.type === 'Type' ? syntax.types : syntax.properties;
                    var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;

                    if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
                        broken[name] = true;
                    }
                }, this);
            }
        }

        var brokenTypes = {};
        var brokenProperties = {};

        for (var key in this.types) {
            validate(this, key, brokenTypes, this.types[key]);
        }

        for (var key in this.properties) {
            validate(this, key, brokenProperties, this.properties[key]);
        }

        brokenTypes = Object.keys(brokenTypes).filter(function(name) {
            return brokenTypes[name];
        });
        brokenProperties = Object.keys(brokenProperties).filter(function(name) {
            return brokenProperties[name];
        });

        if (brokenTypes.length || brokenProperties.length) {
            return {
                types: brokenTypes,
                properties: brokenProperties
            };
        }

        return null;
    },
    dump: function(syntaxAsAst) {
        return {
            generic: this.generic,
            types: dumpMapSyntax(this.types, syntaxAsAst),
            properties: dumpMapSyntax(this.properties, syntaxAsAst)
        };
    },
    toString: function() {
        return JSON.stringify(this.dump());
    }
};

module.exports = Lexer;
<|endoftext|>


<commit_before>var Vector2 = function(x, y) { // basic position class, holds x and y coordinates and utility functions
    this.x = x;
    this.y = y;

    this.add = function(other) {
        return new Vector2(this.x + other.x, this.y + other.y);
    };

    this.distance = function(pos) {
        var dx = pos.x - this.x;
        var dy = pos.y - this.y;

        return Math.abs(Math.sqrt((dx * dx) + (dy * dy)));
    };

    this.manhattan = function(pos) {
        return(Math.abs(this.x - pos.x) + Math.abs(this.y - pos.y));
    };

    this.clone = function() {
        return(new Vector2(this.x, this.y));
    };

    this.toString = function() {
        return("(" + this.x + ", " + this.y + ")");
    };
};

/*
* LightSource constructor
*
* Changed and used code from:
* http://heyjavascript.com/shadowcasting-field-of-view-on-canvas-with-javascript/
*
* @class Roguelike.LightSource
* @classdesc The object that is responsible for generating rooms and corridors
*
* @param {Roguelike.Game} game - Reference to the current game object
* @param {object} options - The object that holds all options for this lightsource
*/
Roguelike.LightSource = function(game, options){

    /*
    * @property {Roguelike.Game} game - Reference to the current game object
    */
    this.game = game;

    /*
    * @property {object} gradient -
    */
    this.gradient = options.gradient;

    /*
    * @property {object} mapSize - object that holds the size of the current map
    */
    this.mapSize = {x: game.map.tilesX, y: game.map.tilesY};

    /*
    * @property {object} doesTileBlock -
    */
    this.doesTileBlock = options.getLightLevel;

    /*
    * @property {object} doesTileBlock -
    */
    this.tiles = [];

    /*
    * @property {object} doesTileBlock -
    */
    this.position = new Vector2(-1, -1);

    /*
    * @property {object} doesTileBlock -
    */
    this.radius = options.radius;

    /*
    * @property {object} doesTileBlock -
    */
    this.oldRadius = options.radius;

    /*
    * @property {array} mult - Multipliers for transforming coordinates into other octants
    */
    this.mult = [
        [1,  0,  0, -1, -1,  0,  0,  1],
        [0,  1, -1,  0,  0, -1,  1,  0],
        [0,  1,  1,  0,  0, -1, -1,  0],
        [1,  0,  0,  1, -1,  0,  0, -1]
    ];

};

Roguelike.LightSource.prototype = {

    /*
    * Calculates an octant. Called by the this.calculate when calculating lighting
    * @protected
    *
    * @param {Roguelike.Map} map - The map for which we have to generate rooms
    */
    calculateOctant: function(cx, cy, row, start, end, radius, xx, xy, yx, yy, id) {
        this.tiles.push({
            x: cx,
            y: cy,
            lightLevel: 0
        });

        var new_start = 0;

        if(start < end) return;

        var radius_squared = radius * radius;

        for(var i = row; i<radius+1; i++) {
            var dx = -i-1;
            var dy = -i;

            var blocked = false;

            while(dx <= 0) {

                dx += 1;

                var X = cx + dx * xx + dy * xy;
                var Y = cy + dx * yx + dy * yy;

                if(X < this.mapSize.x && X >= 0 && Y < this.mapSize.y && Y >=0) {

                    var l_slope = (dx-0.5)/(dy+0.5);
                    var r_slope = (dx+0.5)/(dy-0.5);

                    if(start < r_slope) {
                        continue;
                    } else if( end > l_slope) {
                        break;
                    } else {
                        if(dx*dx + dy*dy < radius_squared) {
                            var pos1 = new Vector2(X, Y);
                            var pos2 = this.position;
                            var d = (pos1.x - pos2.x) * (pos1.x - pos2.x) + (pos1.y - pos2.y) * (pos1.y - pos2.y);

                            this.tiles.push({
                                x: X,
                                y: Y,
                                lightLevel: (this.gradient === false) ? 1 : (1 - (d / (this.radius * this.radius)))
                            });
                        }

                        if(blocked) {
                            if(this.doesTileBlock(X, Y)) {
                                new_start = r_slope;
                                continue;
                            } else {
                                blocked = false;
                                start = new_start;
                            }
                        } else {
                            if(this.doesTileBlock(X, Y) && i < radius) {
                                blocked = true;
                                this.calculateOctant(cx, cy, i+1, start, l_slope, this.radius, xx, xy, yx, yy, id+1);

                                new_start = r_slope;
                            }
                        }
                    }
                }
            }

            if(blocked) break;
        }
    },

    // sets flag lit to false on all tiles within radius of position specified
    clear: function () {
        var i = this.tiles.length;
        while(i--) {
            this.tiles[i].lightLevel = 0;
        }

        var o = this.tiles;
        this.tiles = [];
        return o;
    },

    // sets flag lit to true on all tiles within radius of position specified
    calculate: function () {
        for(var i = 0; i<8; i++) {
            this.calculateOctant(this.position.x, this.position.y, 1, 1.0, 0.0, this.radius,
                this.mult[0][i], this.mult[1][i], this.mult[2][i], this.mult[3][i], 0);
        }

        this.tiles.push({
            x: this.position.x,
            y: this.position.y,
            lightLevel: 1
        })

        return this.tiles;
    },

    // update the position of the light source
    update: function(x, y) {
        this.position = new Vector2(x, y);
        return this.clear().concat(this.calculate());
    }

};<commit_msg>LightSource object now has a function to check a tile.<commit_after>var Vector2 = function(x, y) { // basic position class, holds x and y coordinates and utility functions
    this.x = x;
    this.y = y;

    this.add = function(other) {
        return new Vector2(this.x + other.x, this.y + other.y);
    };

    this.distance = function(pos) {
        var dx = pos.x - this.x;
        var dy = pos.y - this.y;

        return Math.abs(Math.sqrt((dx * dx) + (dy * dy)));
    };

    this.manhattan = function(pos) {
        return(Math.abs(this.x - pos.x) + Math.abs(this.y - pos.y));
    };

    this.clone = function() {
        return(new Vector2(this.x, this.y));
    };

    this.toString = function() {
        return("(" + this.x + ", " + this.y + ")");
    };
};

/*
* LightSource constructor
*
* Changed and used code from:
* http://heyjavascript.com/shadowcasting-field-of-view-on-canvas-with-javascript/
*
* @class Roguelike.LightSource
* @classdesc The object that is responsible for generating rooms and corridors
*
* @param {Roguelike.Game} game - Reference to the current game object
* @param {object} options - The object that holds all options for this lightsource
*/
Roguelike.LightSource = function(game, options){

    /*
    * @property {Roguelike.Game} game - Reference to the current game object
    */
    this.game = game;

    /*
    * @property {object} gradient -
    */
    this.gradient = options.gradient;

    /*
    * @property {object} mapSize - object that holds the size of the current map
    */
    this.mapSize = {x: game.map.tilesX, y: game.map.tilesY};

    /*
    * @property {object} doesTileBlock -
    */
    this.tiles = [];

    /*
    * @property {object} doesTileBlock -
    */
    this.position = new Vector2(-1, -1);

    /*
    * @property {object} doesTileBlock -
    */
    this.radius = options.radius;

    /*
    * @property {object} doesTileBlock -
    */
    this.oldRadius = options.radius;

    /*
    * @property {array} mult - Multipliers for transforming coordinates into other octants
    */
    this.mult = [
        [1,  0,  0, -1, -1,  0,  0,  1],
        [0,  1, -1,  0,  0, -1,  1,  0],
        [0,  1,  1,  0,  0, -1, -1,  0],
        [1,  0,  0,  1, -1,  0,  0, -1]
    ];

};

Roguelike.LightSource.prototype = {

    doesTileBlock: function(x, y){
        return this.game.map.tiles[y][x].blockLight;
    },

    /*
    * Calculates an octant. Called by the this.calculate when calculating lighting
    * @protected
    */
    calculateOctant: function(cx, cy, row, start, end, radius, xx, xy, yx, yy, id) {
        this.tiles.push({
            x: cx,
            y: cy,
            lightLevel: 0
        });

        var new_start = 0;

        if(start < end) return;

        var radius_squared = radius * radius;

        for(var i = row; i<radius+1; i++) {
            var dx = -i-1;
            var dy = -i;

            var blocked = false;

            while(dx <= 0) {

                dx += 1;

                var X = cx + dx * xx + dy * xy;
                var Y = cy + dx * yx + dy * yy;

                if(X < this.mapSize.x && X >= 0 && Y < this.mapSize.y && Y >=0) {

                    var l_slope = (dx-0.5)/(dy+0.5);
                    var r_slope = (dx+0.5)/(dy-0.5);

                    if(start < r_slope) {
                        continue;
                    } else if( end > l_slope) {
                        break;
                    } else {
                        if(dx*dx + dy*dy < radius_squared) {
                            var pos1 = new Vector2(X, Y);
                            var pos2 = this.position;
                            var d = (pos1.x - pos2.x) * (pos1.x - pos2.x) + (pos1.y - pos2.y) * (pos1.y - pos2.y);

                            this.tiles.push({
                                x: X,
                                y: Y,
                                lightLevel: (this.gradient === false) ? 1 : (1 - (d / (this.radius * this.radius)))
                            });
                        }

                        if(blocked) {
                            if(this.doesTileBlock(X, Y)) {
                                new_start = r_slope;
                                continue;
                            } else {
                                blocked = false;
                                start = new_start;
                            }
                        } else {
                            if(this.doesTileBlock(X, Y) && i < radius) {
                                blocked = true;
                                this.calculateOctant(cx, cy, i+1, start, l_slope, this.radius, xx, xy, yx, yy, id+1);

                                new_start = r_slope;
                            }
                        }
                    }
                }
            }

            if(blocked) break;
        }
    },

    // sets flag lit to false on all tiles within radius of position specified
    clear: function () {
        var i = this.tiles.length;
        while(i--) {
            this.tiles[i].lightLevel = 0;
        }

        var o = this.tiles;
        this.tiles = [];
        return o;
    },

    // sets flag lit to true on all tiles within radius of position specified
    calculate: function () {
        for(var i = 0; i<8; i++) {
            this.calculateOctant(this.position.x, this.position.y, 1, 1.0, 0.0, this.radius,
                this.mult[0][i], this.mult[1][i], this.mult[2][i], this.mult[3][i], 0);
        }

        this.tiles.push({
            x: this.position.x,
            y: this.position.y,
            lightLevel: 1
        })

        return this.tiles;
    },

    // update the position of the light source
    update: function(x, y) {
        this.position = new Vector2(x, y);
        return this.clear().concat(this.calculate());
    }

};<|endoftext|>


<commit_before>// Load in dependencies
var computedStyle = require('computed-style');

// Free-flow of ideas
// Create same of node - styles could change, but this is for `normal` case
// Trim down node content - styles could change
// User-agent sniffing - Last resort
// Can we sniff on padding etc?
// Is there a constant for all browsers? Tried 19px. Disproven (IE10, Chrome).
// Is padding fucking with us? Nope (in Chrome).
// Try out 100% line-height. Acts as expected (for Chrome).
// Create a dummy node with font-size:normal!important,height:auto!important (double check if needed)
//    then, calculate font-size to height ratio

// TODO: For testing against need of CSS overrides, need to clean out ratio every time since it will be pre-cached otherwise.
// TODO: Also test that ratio is used

// Create our lineHeight calculator
function lineHeight(node) {
  // Grab the line-height via style
  var lineHeightStr = computedStyle(node, 'line-height'),
      lnHeight = Math.round(parseFloat(lineHeightStr, 10));

  // If the line-height is "normal", calculate by font-size
  if (lineHeightStr === 'normal') {
    // If we don't yet have our ratio, calculate it
    var _ratio = lineHeight._ratio;
    if (_ratio === undefined) {
      // Create a temporary node
      var _node = document.createElement('div');
      _node.innerHTML = ' ';

      // Append it to the body
      var body = document.body;
      body.appendChild(_node);

      // TODO: Determine if we need CSS overrides since the styling has to be "normal" to even enter this case
      // Calculate the font-size and height
      var _fontSizeStr = computedStyle(_node, 'font-size'),
          _fontSize = parseFloat(fontSizeStr, 10),
          _height = _node.offsetHeight;

      // Save our ratio
      _ratio = _height / _fontSize;
      lineHeight._ratio = _ratio;

      // Remove our child from the DOM
      body.removeChild(_node);
    }

    // Calculate the height with our ratio
    var fontSizeStr = computedStyle(node, 'font-size'),
        fontSize = parseFloat(fontSizeStr, 10);
    lnHeight = Math.round(fontSize * _ratio);
  }

  // Return the calculated height
  return lnHeight;
}

// Export lineHeight
module.exports = lineHeight;<commit_msg>Corrected improper variable usage<commit_after>// Load in dependencies
var computedStyle = require('computed-style');

// Free-flow of ideas
// Create same of node - styles could change, but this is for `normal` case
// Trim down node content - styles could change
// User-agent sniffing - Last resort
// Can we sniff on padding etc?
// Is there a constant for all browsers? Tried 19px. Disproven (IE10, Chrome).
// Is padding fucking with us? Nope (in Chrome).
// Try out 100% line-height. Acts as expected (for Chrome).
// Create a dummy node with font-size:normal!important,height:auto!important (double check if needed)
//    then, calculate font-size to height ratio

// TODO: For testing against need of CSS overrides, need to clean out ratio every time since it will be pre-cached otherwise.
// TODO: Also test that ratio is used

// Create our lineHeight calculator
function lineHeight(node) {
  // Grab the line-height via style
  var lineHeightStr = computedStyle(node, 'line-height'),
      lnHeight = Math.round(parseFloat(lineHeightStr, 10));

  console.log('x', lnHeight);

  // If the line-height is "normal", calculate by font-size
  if (lineHeightStr === 'normal') {
    // If we don't yet have our ratio, calculate it
    var _ratio = lineHeight._ratio;
    if (_ratio === undefined) {
      // Create a temporary node
      var _node = document.createElement('div');
      _node.innerHTML = ' ';

      // Append it to the body
      var body = document.body;
      body.appendChild(_node);

      // TODO: Determine if we need CSS overrides since the styling has to be "normal" to even enter this case
      // Calculate the font-size and height
      var _fontSizeStr = computedStyle(_node, 'font-size'),
          _fontSize = parseFloat(_fontSizeStr, 10),
          _height = _node.offsetHeight;

      console.log('zzz', _fontSizeStr, _fontSize);

      // Save our ratio
      _ratio = _height / _fontSize;
      lineHeight._ratio = _ratio;

      // Remove our child from the DOM
      body.removeChild(_node);
    }

    // Calculate the height with our ratio
    var fontSizeStr = computedStyle(node, 'font-size'),
        fontSize = parseFloat(fontSizeStr, 10);
    lnHeight = Math.round(fontSize * _ratio);
  }

  // Return the calculated height
  return lnHeight;
}

// Export lineHeight
module.exports = lineHeight;<|endoftext|>


<commit_before>(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['./../../eventhandler/dist/eventhandler.min.js'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory(require('eventhandler'));
    } else {
        // Browser globals (root is window)
        root.FSM = factory(root.EventHandler);
    }
}(this, function(EventHandler) {
    'use strict'

    /**
     * @constructor
     * @param {object} [owner]
     */
    function FSM(owner) {
        EventHandler.call(this, owner || this);

        this._states = {};
        this._currentState;
        this._prevState;
    }

    FSM.prototype = Object.create(EventHandler.prototype);
    FSM.constructor = FSM;

    /**
     * Initializes the states collection with more states.
     * Every state already has a 'Default' event
     * @param {object} [states] - {
     *                              StateOne: {
     *                                          'EventOne' : 'StateTwo'
     *                                        },
     *                              StateTwo: {
     *                                          'EventTwo' : 'StateOne'
     *                                        }
     *                          }
     * @param {string} [initialState]
     */
    FSM.prototype.addStates = function(states, initialState) {
        if (typeof states === 'object')
            for (var state in states) {
                this._states[state] = states[state];
            }

        if (initialState !== undefined)
            this.setCurrentState(initialState);
    };

    /**
     * Looks up the event passed in from the state's event map and return the new state if the event exists.
     * @param  {string} event
     */
    FSM.prototype.handleStateEvent = function(event) {
        if (this._currentState !== undefined) {
            var eventMap = this._states[this._currentState];
            var nextState = eventMap[event];

            if (nextState !== undefined) {
                this.setCurrentState(nextState);
                this.triggerChangeEvents(event);
            }
        }
    };

    /**
     * Emits all change events.
     * @param  {string} event
     */
    FSM.prototype.triggerChangeEvents = function(event) {
        var currState = this._currentState;
        var prevState = this._prevState;

        var data = {
            event: event,
            from: prevState,
            to: currState
        };

        this.emit('changeState:from.' + prevState, data);
        this.emit('changeState:to.' + currState, data);
        this.emit('changeState:from.' + prevState + '>to.' + currState, data);
        this.emit('changeState', data);
    };

    /**
     * Updates the current state to the state that's passed in. Emits all change events.
     * @param  {string} state
     */
    FSM.prototype.changeState = function(state) {
        this.setCurrentState(state);
        this.triggerChangeEvents();
    };

    /**
     * Modifier.
     * Fires event(s) with data pertaining to the state.
     * Sets the current state to the state passed in without triggering events if it's the initial state.
     * @param {string} state
     */
    FSM.prototype.setCurrentState = function(state) {
        if (this._currentState !== undefined)
            this._prevState = this._currentState.toString();
        this._currentState = state;
    };

    /**
     * Accessor.
     */
    FSM.prototype.getCurrentState = function() {
        return this._currentState;
    };

    /**
     * Accessor.
     */
    FSM.prototype.getPreviousState = function() {
        return this._prevState;
    };

    /**
     * Adds a listener to be triggered when the state changes.
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeState = function(callback) {
        this.on('changeState', callback);
    };

    /**
     * Adds a listener to be triggered when the state changes from a specific state.
     * @param  {string} from
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateFrom = function(from, callback) {
        this.on('changeState:from.' + from, callback);
    };

    /**
     * Adds a listener to be triggered when the state changes
     * @param  {string} to
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateTo = function(to, callback) {
        this.on('changeState:to.' + to, callback);
    };

    /**
     * Adds a listener to be triggered when the state changes
     * @param  {string|null} from
     * @param  {string|null} to
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateFromTo = function(from, to, callback) {
        var fromToStr = (from === null) ? '' : 'from.' + from;
        if ((from !== null) && (to !== null))
            fromToStr += '>';
        fromToStr += (to === null) ? '' : 'to.' + to;

        this.on('changeState:' + fromToStr, callback);
    };

    return FSM;
}));
<commit_msg>Breaking:Changed global variable name to FiniteStateMachine.<commit_after>(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['./../../eventhandler/dist/eventhandler.min.js'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory(require('eventhandler'));
    } else {
        // Browser globals (root is window)
        root.FiniteStateMachine = factory(root.EventHandler);
    }
}(this, function(EventHandler) {
    'use strict'

    /**
     * @constructor
     * @param {object} [owner]
     */
    function FSM(owner) {
        EventHandler.call(this, owner || this);

        this._states = {};
        this._currentState;
        this._prevState;
    }

    FSM.prototype = Object.create(EventHandler.prototype);
    FSM.constructor = FSM;

    /**
     * Initializes the states collection with more states.
     * Every state already has a 'Default' event
     * @param {object} [states] - {
     *                              StateOne: {
     *                                          'EventOne' : 'StateTwo'
     *                                        },
     *                              StateTwo: {
     *                                          'EventTwo' : 'StateOne'
     *                                        }
     *                          }
     * @param {string} [initialState]
     */
    FSM.prototype.addStates = function(states, initialState) {
        if (typeof states === 'object')
            for (var state in states) {
                this._states[state] = states[state];
            }

        if (initialState !== undefined)
            this.setCurrentState(initialState);
    };

    /**
     * Looks up the event passed in from the state's event map and return the new state if the event exists.
     * @param  {string} event
     */
    FSM.prototype.handleStateEvent = function(event) {
        if (this._currentState !== undefined) {
            var eventMap = this._states[this._currentState];
            var nextState = eventMap[event];

            if (nextState !== undefined) {
                this.setCurrentState(nextState);
                this.triggerChangeEvents(event);
            }
        }
    };

    /**
     * Emits all change events.
     * @param  {string} event
     */
    FSM.prototype.triggerChangeEvents = function(event) {
        var currState = this._currentState;
        var prevState = this._prevState;

        var data = {
            event: event,
            from: prevState,
            to: currState
        };

        this.emit('changeState:from.' + prevState, data);
        this.emit('changeState:to.' + currState, data);
        this.emit('changeState:from.' + prevState + '>to.' + currState, data);
        this.emit('changeState', data);
    };

    /**
     * Updates the current state to the state that's passed in. Emits all change events.
     * @param  {string} state
     */
    FSM.prototype.changeState = function(state) {
        this.setCurrentState(state);
        this.triggerChangeEvents();
    };

    /**
     * Modifier.
     * Fires event(s) with data pertaining to the state.
     * Sets the current state to the state passed in without triggering events if it's the initial state.
     * @param {string} state
     */
    FSM.prototype.setCurrentState = function(state) {
        if (this._currentState !== undefined)
            this._prevState = this._currentState.toString();
        this._currentState = state;
    };

    /**
     * Accessor.
     */
    FSM.prototype.getCurrentState = function() {
        return this._currentState;
    };

    /**
     * Accessor.
     */
    FSM.prototype.getPreviousState = function() {
        return this._prevState;
    };

    /**
     * Adds a listener to be triggered when the state changes.
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeState = function(callback) {
        this.on('changeState', callback);
    };

    /**
     * Adds a listener to be triggered when the state changes from a specific state.
     * @param  {string} from
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateFrom = function(from, callback) {
        this.on('changeState:from.' + from, callback);
    };

    /**
     * Adds a listener to be triggered when the state changes
     * @param  {string} to
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateTo = function(to, callback) {
        this.on('changeState:to.' + to, callback);
    };

    /**
     * Adds a listener to be triggered when the state changes
     * @param  {string|null} from
     * @param  {string|null} to
     * @param  {function} callback - Is passed an optional paramater for event data.
     */
    FSM.prototype.onChangeStateFromTo = function(from, to, callback) {
        var fromToStr = (from === null) ? '' : 'from.' + from;
        if ((from !== null) && (to !== null))
            fromToStr += '>';
        fromToStr += (to === null) ? '' : 'to.' + to;

        this.on('changeState:' + fromToStr, callback);
    };

    return FSM;
}));
<|endoftext|>


<commit_before>var Writable = require('stream').Writable,
    util = require('util'),
    memory = [];

function MemoryStream(options) {
  Writable.call(this, options);
}

util.inherits(MemoryStream, Writable);

MemoryStream.prototype._write = function _write(chunk, encoding, callback) {
  try {
    memory.push(JSON.parse(chunk));
    callback();
  } catch (e) {
    callback(e)
  }
};

module.exports = function (options) { return new MemoryStream(options); };
module.exports.MemoryStream = MemoryStream;
module.exports.memory = memory;
<commit_msg>Data stored in a property of the instance instead of a shared variable.<commit_after>var Writable = require('stream').Writable,
    util = require('util');

function MemoryStream(options) {
  Writable.call(this, options);
  this.memory = [];
}

util.inherits(MemoryStream, Writable);

MemoryStream.prototype._write = function _write(chunk, encoding, callback) {
  try {
    this.memory.push(JSON.parse(chunk));
    callback();
  } catch (e) {
    callback(e);
  }
};

module.exports = function (options) { return new MemoryStream(options); };
module.exports.MemoryStream = MemoryStream;
<|endoftext|>


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

foam.locale = foam.locale || 'en';

foam.CLASS({
  package: 'foam.i18n',
  name: 'MessageAxiom',

  properties: [
    {
      name: 'name',
      class: 'String'
    },
    {
      name: 'description',
      class: 'String'
    },
    {
      name: 'messageMap',
      help: 'Map of language codes to the message in that language.',
      class: 'Object',
    },
    {
      name: 'message',
      class: 'String',
      getter: function() {
        return this.message_ || this.messageMap[foam.locale];
      },
      setter: function(m) { this.message_ = m; },
    },
    {
      name: 'message_',
      class: 'Simple',
    },
  ],
  methods: [
    function installInClass(cls) {
      Object.defineProperty(
        cls,
        this.name,
        {
          value: this.message,
          configurable: false
        });
    },
    function installInProto(proto) {
      this.installInClass(proto);
    },
  ],
});

foam.CLASS({
  package: 'foam.i18n',
  name: 'MessagesExtension',
  refines: 'foam.core.Model',

  properties: [
    {
      name: 'messages',
      class: 'AxiomArray',
      of: 'foam.i18n.MessageAxiom'
    }
  ]
});

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

foam.locale = foam.locale || 'en';

foam.CLASS({
  package: 'foam.i18n',
  name: 'MessageAxiom',

  properties: [
    {
      name: 'name',
      class: 'String'
    },
    {
      name: 'description',
      class: 'String'
    },
    {
      name: 'messageMap',
      help: 'Map of language codes to the message in that language.',
      class: 'Object'
    },
    {
      name: 'message',
      class: 'String',
      getter: function() {
        return this.message_ || this.messageMap[foam.locale];
      },
      setter: function(m) { this.message_ = m; },
    },
    {
      name: 'message_',
      class: 'Simple',
    },
  ],
  methods: [
    function installInClass(cls) {
      Object.defineProperty(
        cls,
        this.name,
        {
          value: this.message,
          configurable: false
        });
    },
    function installInProto(proto) {
      this.installInClass(proto);
    },
  ],
});

foam.CLASS({
  package: 'foam.i18n',
  name: 'MessagesExtension',
  refines: 'foam.core.Model',

  properties: [
    {
      name: 'messages',
      class: 'AxiomArray',
      of: 'foam.i18n.MessageAxiom'
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DIG',
  extends: 'foam.nanos.http.DefaultHttpParameters',

  documentation: 'Data Integration Gateway - Perform DAO operations against a web service',

  requires: [
    'foam.net.web.HTTPRequest'
  ],

  implements: [
    'foam.mlang.Expressions',
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  tableColumns: [
    'id',
    'daoKey.name',
    'cmd',
    'format'
  ],

  searchColumns: [],

  constants: [
    {
      name: 'MAX_URL_SIZE',
      value: 2000,
      type: 'Integer'
    }
  ],

  imports: [
    'AuthenticatedNSpecDAO'
  ],

  sections: [
    {
      name: 'details'
    },
    {
      name: 'supportDetails'
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      name: 'id',
      label: 'Request Name',
      section: 'details'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      section: 'supportDetails'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdByAgent',
      section: 'supportDetails'
    },
    {
      class: 'DateTime',
      name: 'created',
      documentation: 'The date and time of when the User was created in the system.',
      createVisibility: 'HIDDEN',
      updateVisibility: 'RO',
      section: 'supportDetails',
      includeInDigest: true
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      documentation: 'The date and time the User was last modified.',
      createVisibility: 'HIDDEN',
      updateVisibility: 'RO',
      section: 'supportDetails',
      storageOptional: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      section: 'supportDetails',
      readPermissionRequired: true,
      writePermissionRequired: true,
      storageOptional: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.boot.NSpec',
      label: 'Data Access Object (DAO)',
      name: 'daoKey',
      documentation: `The DAO in the DIG request.`,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'DAO',
              dao: X.AuthenticatedNSpecDAO
                .where(E.AND(
                  E.EQ(foam.nanos.boot.NSpec.SERVE, true),
                  E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO')
                ))
                .orderBy(foam.nanos.boot.NSpec.ID)
            }
          ]
        };
      },
      value: 'userDAO',
      section: 'details'
    },
    {
      name: 'cmd',
      label: 'API Command',
      section: 'details'
    },
    {
      name: 'format',
      label: 'Data Format',
      section: 'details',
      visibility: function(cmd) {
        return ( cmd == 'SELECT' || cmd == 'PUT' ) ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'String',
      name: 'key',
      label: 'Object ID',
      section: 'details',
      visibility: function(cmd) {
        return ( cmd == 'SELECT' || cmd == 'REMOVE' ) ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
  },
  {
      class: 'String',
      name: 'q',
      label: 'Select Query',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'Long',
      name: 'limit',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      },
      value: 1000,
      max: 1000,
      min: 0
    },
    {
      class: 'Long',
      name: 'skip',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      },
      min: 0
    },
    {
      name: 'data',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'PUT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'URL',
      name: 'postURL',
      hidden: true
    },
    {
      name: 'snippet',
      label: 'Snippet',
      documentation: 'show a specific type of request would look like in a given language.',
      section: 'details',
      view: { class: 'foam.nanos.dig.DigSnippetView' },
      expression: function(key, data, daoKey, cmd, format, q, limit, skip) {
        var query = false;
        var url = "/service/dig";

        if ( daoKey ) {
          url += "?";
          query = true;
          url += "dao=" + daoKey;
        }
        if ( cmd ) {
          url += query ? "&" : "?";
          query = true;
          url += "cmd=" + cmd.name.toLowerCase();
        }
        if ( format ) {
          url += query ? "&" : "?";
          query = true;
          url += "format=" + format.name.toLowerCase();
        }
        if ( key ) {
          url += query ? "&" : "?";
          query = true;
          url += "id=" + key;
        }
        if ( q ) {
          url += query ? "&" : "?";
          query = true;
          url += "q=" + encodeURIComponent(q);
        }
        if ( limit > 0 && limit != Number.MAX_SAFE_INTEGER && limit != 1000 ) {
          url += query ? "&" : "?";
          query = true;
          url += "limit=" + limit;
        }
        if ( skip > 0 && skip != Number.MAX_SAFE_INTEGER ) {
          url += query ? "&" : "?";
          query = true;
          url += "skip=" + skip;
        }
        this.postURL = url;

        if ( data ) {
          if ( data.length + url.length < this.MAX_URL_SIZE ) {
            url += query ? "&" : "?";
            query = true;
            url += "data=" + encodeURIComponent(data);
          }
        }

        return url;
      }
    },
    {
      class: 'String',
      name: 'result',
      value: 'No Request Sent Yet.',
      view: { class: 'foam.nanos.dig.ResultView' },
      section: 'details',
      visibility: 'RO'
    },
    {
      class: 'String',
      name: 'Description',
      section: 'details',
      view: { class: 'foam.u2.tag.TextArea', rows: 4, cols: 144 }
    }
  ],

  actions: [
    {
      name: 'postButton',
      label: 'Send Request',
      code: async function() {
        var req = this.HTTPRequest.create({
          url: window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + this.postURL + "&sessionId=" + localStorage.defaultSession,
          method: 'POST',
          payload: this.data,
        }).send();

        var resp = await req.then(async function(resp) {
          var temp = await resp.payload.then(function(result) {
            return result;
          });
          return temp;
        }, async function(error) {
          var temp = await error.payload.then(function(result) {
            return result;
          });
          return temp;
        });
        this.result = resp;
      }
    }
  ]
});
<commit_msg>Updated description field to not be upper case<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DIG',
  extends: 'foam.nanos.http.DefaultHttpParameters',

  documentation: 'Data Integration Gateway - Perform DAO operations against a web service',

  requires: [
    'foam.net.web.HTTPRequest'
  ],

  implements: [
    'foam.mlang.Expressions',
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  tableColumns: [
    'id',
    'daoKey.name',
    'cmd',
    'format'
  ],

  searchColumns: [],

  constants: [
    {
      name: 'MAX_URL_SIZE',
      value: 2000,
      type: 'Integer'
    }
  ],

  imports: [
    'AuthenticatedNSpecDAO'
  ],

  sections: [
    {
      name: 'details'
    },
    {
      name: 'supportDetails'
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      name: 'id',
      label: 'Request Name',
      section: 'details'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      section: 'supportDetails'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdByAgent',
      section: 'supportDetails'
    },
    {
      class: 'DateTime',
      name: 'created',
      documentation: 'The date and time of when the User was created in the system.',
      createVisibility: 'HIDDEN',
      updateVisibility: 'RO',
      section: 'supportDetails',
      includeInDigest: true
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      documentation: 'The date and time the User was last modified.',
      createVisibility: 'HIDDEN',
      updateVisibility: 'RO',
      section: 'supportDetails',
      storageOptional: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      section: 'supportDetails',
      readPermissionRequired: true,
      writePermissionRequired: true,
      storageOptional: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.boot.NSpec',
      label: 'Data Access Object (DAO)',
      name: 'daoKey',
      documentation: `The DAO in the DIG request.`,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'DAO',
              dao: X.AuthenticatedNSpecDAO
                .where(E.AND(
                  E.EQ(foam.nanos.boot.NSpec.SERVE, true),
                  E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO')
                ))
                .orderBy(foam.nanos.boot.NSpec.ID)
            }
          ]
        };
      },
      value: 'userDAO',
      section: 'details'
    },
    {
      name: 'cmd',
      label: 'API Command',
      section: 'details'
    },
    {
      name: 'format',
      label: 'Data Format',
      section: 'details',
      visibility: function(cmd) {
        return ( cmd == 'SELECT' || cmd == 'PUT' ) ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'String',
      name: 'key',
      label: 'Object ID',
      section: 'details',
      visibility: function(cmd) {
        return ( cmd == 'SELECT' || cmd == 'REMOVE' ) ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
  },
  {
      class: 'String',
      name: 'q',
      label: 'Select Query',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'Long',
      name: 'limit',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      },
      value: 1000,
      max: 1000,
      min: 0
    },
    {
      class: 'Long',
      name: 'skip',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'SELECT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      },
      min: 0
    },
    {
      name: 'data',
      section: 'details',
      visibility: function(cmd) {
        return (cmd == 'PUT') ? foam.u2.DisplayMode.RW : foam.u2.DisplayMode.HIDDEN;
      }
    },
    {
      class: 'URL',
      name: 'postURL',
      hidden: true
    },
    {
      name: 'snippet',
      label: 'Snippet',
      documentation: 'show a specific type of request would look like in a given language.',
      section: 'details',
      view: { class: 'foam.nanos.dig.DigSnippetView' },
      expression: function(key, data, daoKey, cmd, format, q, limit, skip) {
        var query = false;
        var url = "/service/dig";

        if ( daoKey ) {
          url += "?";
          query = true;
          url += "dao=" + daoKey;
        }
        if ( cmd ) {
          url += query ? "&" : "?";
          query = true;
          url += "cmd=" + cmd.name.toLowerCase();
        }
        if ( format ) {
          url += query ? "&" : "?";
          query = true;
          url += "format=" + format.name.toLowerCase();
        }
        if ( key ) {
          url += query ? "&" : "?";
          query = true;
          url += "id=" + key;
        }
        if ( q ) {
          url += query ? "&" : "?";
          query = true;
          url += "q=" + encodeURIComponent(q);
        }
        if ( limit > 0 && limit != Number.MAX_SAFE_INTEGER && limit != 1000 ) {
          url += query ? "&" : "?";
          query = true;
          url += "limit=" + limit;
        }
        if ( skip > 0 && skip != Number.MAX_SAFE_INTEGER ) {
          url += query ? "&" : "?";
          query = true;
          url += "skip=" + skip;
        }
        this.postURL = url;

        if ( data ) {
          if ( data.length + url.length < this.MAX_URL_SIZE ) {
            url += query ? "&" : "?";
            query = true;
            url += "data=" + encodeURIComponent(data);
          }
        }

        return url;
      }
    },
    {
      class: 'String',
      name: 'result',
      value: 'No Request Sent Yet.',
      view: { class: 'foam.nanos.dig.ResultView' },
      section: 'details',
      visibility: 'RO'
    },
    {
      class: 'String',
      name: 'description',
      section: 'details',
      view: { class: 'foam.u2.tag.TextArea', rows: 4, cols: 144 }
    }
  ],

  actions: [
    {
      name: 'postButton',
      label: 'Send Request',
      code: async function() {
        var req = this.HTTPRequest.create({
          url: window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + this.postURL + "&sessionId=" + localStorage.defaultSession,
          method: 'POST',
          payload: this.data,
        }).send();

        var resp = await req.then(async function(resp) {
          var temp = await resp.payload.then(function(result) {
            return result;
          });
          return temp;
        }, async function(error) {
          var temp = await error.payload.then(function(result) {
            return result;
          });
          return temp;
        });
        this.result = resp;
      }
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DIG',
  extends: 'foam.nanos.http.DefaultHttpParameters',

  documentation: 'Data Integration Gateway - Perform DAO operations against a web service',

  tableColumns: [
    'id',
    'daoKey',
    'cmd',
    'format',
    'owner'
  ],

  searchColumns: [],

  properties: [
    'id',
    {
      class: 'String',
      name: 'daoKey',
      label: 'DAO',
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return foam.u2.view.ChoiceView.create({
          dao: X.nSpecDAO
            .where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            .orderBy(foam.nanos.boot.NSpec.ID),
          objToChoice: function(nspec) {
            return [nspec.id, nspec.id];
          }
        });
      }
    },
    'cmd',
    'format',
    {
      class: 'String',
      name: 'dao',
      hidden: true,
      transient: true,
      postSet: function(old, nu) {
        this.daoKey = nu;
      }
    },
    'q',
    {
        class: 'String',
        name: 'key'
    },
    {
      class: 'EMail',
      displayWidth: 100,
      name: 'email'
    },
    {
      class: 'EMail',
      displayWidth: 100,
      name: 'subject'
    },
    'data',
    {
      class: 'URL',
      // TODO: appears not to work if named 'url', find out why.
      name: 'digURL',
      label: 'URL',
      displayWidth: 120,
      view: 'foam.nanos.dig.LinkView',
      setter: function() {}, // Prevent from ever getting set
      expression: function(key, data, email, subject, daoKey, cmd, format, q) {
        var query = false;
        var url = "/service/dig";

        if ( daoKey ) {
          url += query ? "&" : "?";
          query = true;
          url += "dao=" + daoKey;
        }
        if ( cmd ) {
          url += query ? "&" : "?";
          query = true;
          url += "cmd=" + cmd.name.toLowerCase();
        }
        if ( format ) {
          url += query ? "&" : "?";
          query = true;
          url += "cmd=" + format.name.toLowerCase();
        }
        if ( key ) {
          url += query ? "&" : "?";
          query = true;
          url += "id=" + key;
        }
        if ( data ) {
          url += query ? "&" : "?";
          query = true;
          url += "data=" + data;
        }
        if ( email ) {
          url += query ? "&" : "?";
          query = true;
          url += "email=" + email;
        }
        if ( subject ) {
          url += query ? "&" : "?";
          query = true;
          url += "subject=" + subject;
        }
        if ( q ) {
          url += query ? "&" : "?";
          query = true;
          url += "&q=" + q;
        }

        return url;
      }
    }
  ],

  methods: [
  ]
});
<commit_msg>Fix bug in DIG format URL creation.<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DIG',
  extends: 'foam.nanos.http.DefaultHttpParameters',

  documentation: 'Data Integration Gateway - Perform DAO operations against a web service',

  tableColumns: [
    'id',
    'daoKey',
    'cmd',
    'format',
    'owner'
  ],

  searchColumns: [],

  properties: [
    'id',
    {
      class: 'String',
      name: 'daoKey',
      label: 'DAO',
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return foam.u2.view.ChoiceView.create({
          dao: X.nSpecDAO
            .where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            .orderBy(foam.nanos.boot.NSpec.ID),
          objToChoice: function(nspec) {
            return [nspec.id, nspec.id];
          }
        });
      }
    },
    'cmd',
    'format',
    {
      class: 'String',
      name: 'dao',
      hidden: true,
      transient: true,
      postSet: function(old, nu) {
        this.daoKey = nu;
      }
    },
    'q',
    {
        class: 'String',
        name: 'key'
    },
    {
      class: 'EMail',
      displayWidth: 100,
      name: 'email'
    },
    {
      class: 'EMail',
      displayWidth: 100,
      name: 'subject'
    },
    'data',
    {
      class: 'URL',
      // TODO: appears not to work if named 'url', find out why.
      name: 'digURL',
      label: 'URL',
      displayWidth: 120,
      view: 'foam.nanos.dig.LinkView',
      setter: function() {}, // Prevent from ever getting set
      expression: function(key, data, email, subject, daoKey, cmd, format, q) {
        var query = false;
        var url = "/service/dig";

        if ( daoKey ) {
          url += query ? "&" : "?";
          query = true;
          url += "dao=" + daoKey;
        }
        if ( cmd ) {
          url += query ? "&" : "?";
          query = true;
          url += "cmd=" + cmd.name.toLowerCase();
        }
        if ( format ) {
          url += query ? "&" : "?";
          query = true;
          url += "format=" + format.name.toLowerCase();
        }
        if ( key ) {
          url += query ? "&" : "?";
          query = true;
          url += "id=" + key;
        }
        if ( data ) {
          url += query ? "&" : "?";
          query = true;
          url += "data=" + data;
        }
        if ( email ) {
          url += query ? "&" : "?";
          query = true;
          url += "email=" + email;
        }
        if ( subject ) {
          url += query ? "&" : "?";
          query = true;
          url += "subject=" + subject;
        }
        if ( q ) {
          url += query ? "&" : "?";
          query = true;
          url += "&q=" + q;
        }

        return url;
      }
    }
  ],

  methods: [
  ]
});
<|endoftext|>