<commit_before>$_('gEngine').main(function(){

    var request= $('connections').functions.request;
    var ui = null;

    var loadImages= function(list){
        return new Promise(function(setFinish){
            var count= list.length;
            var done= 0;

            var check= function(){
                if(done == count)
                    setFinish();
            };

            list.forEach(function(item){
                if(!gamedata.images[item]){
                    var img= new $$.Image();
                    img.onload= function(){
                        gamedata.images[item]= img;
                        done++;
                        check();
                    };
                    img.onerror= function(){
                        $$.console.log('image loading failed!');
                    };
                    img.src= item;
                }else{
                    done++;
                    check();
                }
            });
        });
    };

    var getDateOutfit= function(){
        return gamedata.date.outfits[gamedata.date.activeOutfit];
    };

    var textLabel= function(text, zLevel){
        var TextBox= $('canvas').TextBox;
        var item= new TextBox(text, 0, 0, zLevel);
        item.font= '15px/20px sans-serif';
        item.color= '#fff';
        return item;
    };

    var buildActionList= function(actions, sceneName){
        var Layer= $('canvas').Layer;
        var HitArea= $('canvas').HitArea;

        ui.actionList.hidden= true;
        ui.actionList.clear();
        actions.forEach(function(item, index){
            var label= new Layer(10, index * 20);
            label.addElement(new textLabel(item.caption, 0));
            label.elements(0).color= '#dedede';
            label.addElement(new HitArea(0, 0, 200, 20, 1));

            if(gamedata.actions[sceneName] && gamedata.actions[sceneName][item.action])
                label.elements(1).onclick= function(){ gamedata.actions[sceneName][item.action].apply(gamedata, [item]); };
            else
                $$.console.warn('action "'+item.action+'" for scene "'+sceneName+'" does not exist!');

            label.elements(1).onmouseover= function(){
                label.elements(0).color= '#fff';
                gamedata.playerSays(selectText(item.text));
            };
            label.elements(1).onmouseout= function(){
                label.elements(0).color= '#dedede';
                gamedata.playerSays('');
            };

            label.elements(1).cursor= 'pointer';
            ui.actionList.addElement(label);
        });
        ui.actionList.hidden= false;
    };

    var selectText= function(options){
        var index= Math.round(Math.random() * (options.length-1));
        return options[index];
    };

//  create a new Game
    this.newGame= function(options){
        return new Promise(function(setFinish){
            var Canvas= $('canvas').Canvas;
            var Image= $('canvas').Image;
            var FilledRect= $('canvas').FilledRect;
            var Layer= $('canvas').Layer;

//          set up the UI
            ui= {
                canvas : new Canvas(options.canvas),
                bg : new FilledRect(0, 0, options.canvas.width, options.canvas.height, '#000', 0),
                loadingLabel : textLabel('loading Data...', 2),
                scene : new Image(null, 200, 0, 1),
                actionList : new Layer(1200, 50),
                chatBox : {
                    player : textLabel(''),
                    date : textLabel(''),
                    last : textLabel('')
                }
            };
            gamedata.ui= ui;

            ui.canvas.maxFps= 30;
            ui.canvas.fpsOverlay= true;
//          background
            ui.canvas.addElement(ui.bg);
//          loading label
            ui.canvas.addElement(ui.loadingLabel);
            ui.loadingLabel.x= ui.canvas.width / 2 - ui.canvas.measureText(ui.loadingLabel).width / 2;
            ui.loadingLabel.y= ui.canvas.height / 2 - 10;
//          scene image
            ui.canvas.addElement(ui.scene);
            ui.scene.hidden= true;
//          actions list
            ui.canvas.addElement(ui.actionList);
//          chatbox
            var chatLayer= new Layer(0, 615, 1);
            var chatFont= '17px/20px sans-serif';
            var aling= 'center';
            ui.chatBox.player.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.player);
            ui.chatBox.date.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.date);
            ui.chatBox.last.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.last);
            ui.chatBox.player.aling= aling;
            ui.canvas.addElement(chatLayer);

//          start rendering
            ui.canvas.start();

//          load resources
            var done= 0;
            var count= 0;
            var ready= false;

            var check= function(){
                if(ready && count == done){
                    ui.loadingLabel.hidden= true;
                    setFinish();
                }
            };

            count++;
            request(options.playerFile).then(function(data){
                gamedata.player= JSON.parse(data);
                done++;
                check();
            });

            count++;
            request(options.dateFile).then(function(data){
                gamedata.date= JSON.parse(data);
                done++;
                check();
            });

            if(options.descriptionsFile){
                count++;
                request(options.descriptionsFile).then(function(data){
                    gamedata.descriptions= JSON.parse(data);
                    done++;
                    check();
                });
            }
            ready= true;
            check();
        });
    };

    this.createLocation= function(name, sceneFiles){
        gamedata.locations[name]= sceneFiles;
    };

    this.loadLocation= function(name){
        ui.loadingLabel.content= 'loading Loaction...';
        ui.loadingLabel.hidden= false;
        return new Promise(function(setFinish){
            var location= gamedata.locations[name];
            var images= [];
            var cout= location.length;
            var done= 0;

            var check= function(){
                done++;
                if(done == cout){
                    loadImages(images).then(function(){
                        ui.loadingLabel.hidden= true;
                        setFinish();
                    });
                }
            };

            if(gamedata.scenes.length > 0)
                gamedata.scenes= [];
            location.forEach(function(item){
                request(item).then(function(data){
                    if(item.indexOf('.json') > -1){
                        data= JSON.parse(data);
                        for(var i in data.scenes){
//                          prepare scene
                            let scene= data.scenes[i];

                            if(scene.images){
                                for(var j= 0; j<scene.images.length; j++){
                                    scene.images[j]= data.images[scene.images[j]];
                                }
                            }

                            if(scene.outfits){
                                for(var j in scene.outfits){
                                    scene.outfits[j]= data.images[scene.outfits[j]];
                                }
                            }
//                          add scene
                            if(!gamedata.scenes[i])
                                gamedata.scenes[i]= scene;
                            else
                                $$.console.error('scene "'+i+'" does already exist!');
                        }
//                      add images
                        data.images.forEach(function(item){
                            if(images.indexOf(item) < 0)
                                images.push(item);
                        });
                    }else if(item.indexOf('.js') > -1){
                        data= new Function(data)();
                        for(var i in data){
                            gamedata.actions[i]= data[i];
                        }
                    }
                        check();
                });
            });
        });
    };

    this.goToScene= function(name){

//      select scene
        if(!gamedata.scenes[name]){
            $$.console.error('scene "'+name+'" does not exist!');
            return false;
        }

        gamedata.activeScene= gamedata.scenes[name];
        gamedata.sceneName= name;
        var scene= gamedata.activeScene;

//      init scene
        if(gamedata.actions[name] && gamedata.actions[name].__init__)
            gamedata.actions[name].__init__.apply(gamedata, [scene.actions]);

//      select scene image
        if(scene.imageSelection){
            let type= scene.imageSelection;
            if(type == 'outfit')
                ui.scene.source= gamedata.images[scene.outfits[getDateOutfit()]];

        }else if(scene.images.length < 2)
            ui.scene.source= gamedata.images[scene.images[0]];

        buildActionList(scene.actions, name);

        if(ui.scene.hidden)
            ui.scene.hidden= false;
    };

    this.playerSays= function(text){
        if(!this.playerTextLocked){
            if(text !== ''){
                var dateTextHeight= ui.canvas.measureTextHeight(ui.chatBox.date.content, 20);
                var lastTextHeight= ui.canvas.measureTextHeight(ui.chatBox.last.content, 20);
                var textHeight= ui.canvas.measureTextHeight(text, 20);
                var margin= 5;
                var space= 115;

                if(lastTextHeight + margin + dateTextHeight + margin + textHeight > space){
                    ui.chatBox.last.hidden= true;
                    ui.chatBox.date.y= 0;
                    ui.chatBox.player.y= dateTextHeight + margin;
                }
                if(dateTextHeight + margin + textHeight > space){
                    ui.chatBox.date.hidden= true;
                    ui.player.y= 0;
                }

                ui.chatBox.player.content= gamedata.player.name + ': ' + text;
                ui.chatBox.player.x= (ui.canvas.width / 2) - (ui.canvas.measureText(ui.chatBox.player).width / 2);
                ui.chatBox.player.hidden= false;
            }else{
                ui.chatBox.player.hidden= true;
            }
        }
    };

    this.dateSays= function(text){
        gamedata.chatLog.push({ person : 'player', text : ui.chatBox.player.content });
        gamedata.chatLog.push({ person : 'date', text : text });

        var playerTextHeight= ui.canvas.measureTextHeight(ui.chatBox.player.content, 20);
        var textHeight= ui.canvas.measureTextHeight(text, 20);
        var margin= 5;
        var space= 115;

        if(ui.chatBox.player.content !== '' && (playerTextHeight + margin + textHeight) < space){
            ui.chatBox.last.content= ui.chatBox.player.content;
            ui.chatBox.last.x= ui.chatBox.player.x;
            ui.chatBox.last.y= 0;
            ui.chatBox.last.hidden= false;
            ui.chatBox.date.y= playerTextHeight + margin;
            ui.chatBox.player.y= playerTextHeight + margin + textHeight + margin;
        }else{
            ui.chatBox.last.hidden= true;
            ui.chatBox.date.y= 0;
            ui.chatBox.player.y= textHeight + 10;
        }
        ui.chatBox.date.content= gamedata.date.name + ': ' + text;
        ui.chatBox.date.x= (ui.canvas.width / 2) - (ui.canvas.measureText(ui.chatBox.date).width / 2);
        ui.chatBox.date.hidden= false;
        ui.chatBox.player.hidden= true;
    };

    this.addActions= function(){

    };

    var gamedata= {
        player : null,
        date : null,
        descriptions : null,
        friend : null,
        activeScene : null,
        sceneName : '',
        scenes : {},
        actions : {},
        locations : {},
        images : {},
        ui : null,
        chatLog: [],
        playerTextLocked : false,
        playerSays : this.playerSays,
        dateSays : this.dateSays,
        selectText : selectText,
        goToScene : this.goToScene
    };

    this.gamedata= gamedata;
});<commit_msg>move the playerChatTextLock into the engine<commit_after>$_('gEngine').main(function(){

    var request= $('connections').functions.request;
    var ui = null;

    var loadImages= function(list){
        return new Promise(function(setFinish){
            var count= list.length;
            var done= 0;

            var check= function(){
                if(done == count)
                    setFinish();
            };

            list.forEach(function(item){
                if(!gamedata.images[item]){
                    var img= new $$.Image();
                    img.onload= function(){
                        gamedata.images[item]= img;
                        done++;
                        check();
                    };
                    img.onerror= function(){
                        $$.console.log('image loading failed!');
                    };
                    img.src= item;
                }else{
                    done++;
                    check();
                }
            });
        });
    };

    var getDateOutfit= function(){
        return gamedata.date.outfits[gamedata.date.activeOutfit];
    };

    var textLabel= function(text, zLevel){
        var TextBox= $('canvas').TextBox;
        var item= new TextBox(text, 0, 0, zLevel);
        item.font= '15px/20px sans-serif';
        item.color= '#fff';
        return item;
    };

    var buildActionList= function(actions, sceneName){
        var Layer= $('canvas').Layer;
        var HitArea= $('canvas').HitArea;

        ui.actionList.hidden= true;
        ui.actionList.clear();
        actions.forEach(function(item, index){
            var label= new Layer(10, index * 20);
            label.addElement(new textLabel(item.caption, 0));
            label.elements(0).color= '#dedede';
            label.addElement(new HitArea(0, 0, 200, 20, 1));

            if(gamedata.actions[sceneName] && gamedata.actions[sceneName][item.action])
                label.elements(1).onclick= function(){
                    gamedata.playerTextLocked= true;
                    gamedata.actions[sceneName][item.action].apply(gamedata, [item]);
                    gamedata.playerTextLocked= false;
                };
            else
                $$.console.warn('action "'+item.action+'" for scene "'+sceneName+'" does not exist!');

            label.elements(1).onmouseover= function(){
                label.elements(0).color= '#fff';
                gamedata.playerSays(selectText(item.text));
            };
            label.elements(1).onmouseout= function(){
                label.elements(0).color= '#dedede';
                gamedata.playerSays('');
            };

            label.elements(1).cursor= 'pointer';
            ui.actionList.addElement(label);
        });
        ui.actionList.hidden= false;
    };

    var selectText= function(options){
        var index= Math.round(Math.random() * (options.length-1));
        return options[index];
    };

//  create a new Game
    this.newGame= function(options){
        return new Promise(function(setFinish){
            var Canvas= $('canvas').Canvas;
            var Image= $('canvas').Image;
            var FilledRect= $('canvas').FilledRect;
            var Layer= $('canvas').Layer;

//          set up the UI
            ui= {
                canvas : new Canvas(options.canvas),
                bg : new FilledRect(0, 0, options.canvas.width, options.canvas.height, '#000', 0),
                loadingLabel : textLabel('loading Data...', 2),
                scene : new Image(null, 200, 0, 1),
                actionList : new Layer(1200, 50),
                chatBox : {
                    player : textLabel(''),
                    date : textLabel(''),
                    last : textLabel('')
                }
            };
            gamedata.ui= ui;

            ui.canvas.maxFps= 30;
            ui.canvas.fpsOverlay= true;
//          background
            ui.canvas.addElement(ui.bg);
//          loading label
            ui.canvas.addElement(ui.loadingLabel);
            ui.loadingLabel.x= ui.canvas.width / 2 - ui.canvas.measureText(ui.loadingLabel).width / 2;
            ui.loadingLabel.y= ui.canvas.height / 2 - 10;
//          scene image
            ui.canvas.addElement(ui.scene);
            ui.scene.hidden= true;
//          actions list
            ui.canvas.addElement(ui.actionList);
//          chatbox
            var chatLayer= new Layer(0, 615, 1);
            var chatFont= '17px/20px sans-serif';
            var aling= 'center';
            ui.chatBox.player.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.player);
            ui.chatBox.date.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.date);
            ui.chatBox.last.font= chatFont;
            ui.chatBox.player.aling= aling;
            chatLayer.addElement(ui.chatBox.last);
            ui.chatBox.player.aling= aling;
            ui.canvas.addElement(chatLayer);

//          start rendering
            ui.canvas.start();

//          load resources
            var done= 0;
            var count= 0;
            var ready= false;

            var check= function(){
                if(ready && count == done){
                    ui.loadingLabel.hidden= true;
                    setFinish();
                }
            };

            count++;
            request(options.playerFile).then(function(data){
                gamedata.player= JSON.parse(data);
                done++;
                check();
            });

            count++;
            request(options.dateFile).then(function(data){
                gamedata.date= JSON.parse(data);
                done++;
                check();
            });

            if(options.descriptionsFile){
                count++;
                request(options.descriptionsFile).then(function(data){
                    gamedata.descriptions= JSON.parse(data);
                    done++;
                    check();
                });
            }
            ready= true;
            check();
        });
    };

    this.createLocation= function(name, sceneFiles){
        gamedata.locations[name]= sceneFiles;
    };

    this.loadLocation= function(name){
        ui.loadingLabel.content= 'loading Loaction...';
        ui.loadingLabel.hidden= false;
        return new Promise(function(setFinish){
            var location= gamedata.locations[name];
            var images= [];
            var cout= location.length;
            var done= 0;

            var check= function(){
                done++;
                if(done == cout){
                    loadImages(images).then(function(){
                        ui.loadingLabel.hidden= true;
                        setFinish();
                    });
                }
            };

            if(gamedata.scenes.length > 0)
                gamedata.scenes= [];
            location.forEach(function(item){
                request(item).then(function(data){
                    if(item.indexOf('.json') > -1){
                        data= JSON.parse(data);
                        for(var i in data.scenes){
//                          prepare scene
                            let scene= data.scenes[i];

                            if(scene.images){
                                for(var j= 0; j<scene.images.length; j++){
                                    scene.images[j]= data.images[scene.images[j]];
                                }
                            }

                            if(scene.outfits){
                                for(var j in scene.outfits){
                                    scene.outfits[j]= data.images[scene.outfits[j]];
                                }
                            }
//                          add scene
                            if(!gamedata.scenes[i])
                                gamedata.scenes[i]= scene;
                            else
                                $$.console.error('scene "'+i+'" does already exist!');
                        }
//                      add images
                        data.images.forEach(function(item){
                            if(images.indexOf(item) < 0)
                                images.push(item);
                        });
                    }else if(item.indexOf('.js') > -1){
                        data= new Function(data)();
                        for(var i in data){
                            gamedata.actions[i]= data[i];
                        }
                    }
                        check();
                });
            });
        });
    };

    this.goToScene= function(name){

//      select scene
        if(!gamedata.scenes[name]){
            $$.console.error('scene "'+name+'" does not exist!');
            return false;
        }

        gamedata.activeScene= gamedata.scenes[name];
        gamedata.sceneName= name;
        var scene= gamedata.activeScene;

//      init scene
        if(gamedata.actions[name] && gamedata.actions[name].__init__)
            gamedata.actions[name].__init__.apply(gamedata, [scene.actions]);

//      select scene image
        if(scene.imageSelection){
            let type= scene.imageSelection;
            if(type == 'outfit')
                ui.scene.source= gamedata.images[scene.outfits[getDateOutfit()]];

        }else if(scene.images.length < 2)
            ui.scene.source= gamedata.images[scene.images[0]];

        buildActionList(scene.actions, name);

        if(ui.scene.hidden)
            ui.scene.hidden= false;
    };

    this.playerSays= function(text){
        if(!this.playerTextLocked){
            if(text !== ''){
                var dateTextHeight= ui.canvas.measureTextHeight(ui.chatBox.date.content, 20);
                var lastTextHeight= ui.canvas.measureTextHeight(ui.chatBox.last.content, 20);
                var textHeight= ui.canvas.measureTextHeight(text, 20);
                var margin= 5;
                var space= 115;

                if(lastTextHeight + margin + dateTextHeight + margin + textHeight > space){
                    ui.chatBox.last.hidden= true;
                    ui.chatBox.date.y= 0;
                    ui.chatBox.player.y= dateTextHeight + margin;
                }
                if(dateTextHeight + margin + textHeight > space){
                    ui.chatBox.date.hidden= true;
                    ui.player.y= 0;
                }

                ui.chatBox.player.content= gamedata.player.name + ': ' + text;
                ui.chatBox.player.x= (ui.canvas.width / 2) - (ui.canvas.measureText(ui.chatBox.player).width / 2);
                ui.chatBox.player.hidden= false;
            }else{
                ui.chatBox.player.hidden= true;
            }
        }
    };

    this.dateSays= function(text){
        gamedata.chatLog.push({ person : 'player', text : ui.chatBox.player.content });
        gamedata.chatLog.push({ person : 'date', text : text });

        var playerTextHeight= ui.canvas.measureTextHeight(ui.chatBox.player.content, 20);
        var textHeight= ui.canvas.measureTextHeight(text, 20);
        var margin= 5;
        var space= 115;

        if(ui.chatBox.player.content !== '' && (playerTextHeight + margin + textHeight) < space){
            ui.chatBox.last.content= ui.chatBox.player.content;
            ui.chatBox.last.x= ui.chatBox.player.x;
            ui.chatBox.last.y= 0;
            ui.chatBox.last.hidden= false;
            ui.chatBox.date.y= playerTextHeight + margin;
            ui.chatBox.player.y= playerTextHeight + margin + textHeight + margin;
        }else{
            ui.chatBox.last.hidden= true;
            ui.chatBox.date.y= 0;
            ui.chatBox.player.y= textHeight + 10;
        }
        ui.chatBox.date.content= gamedata.date.name + ': ' + text;
        ui.chatBox.date.x= (ui.canvas.width / 2) - (ui.canvas.measureText(ui.chatBox.date).width / 2);
        ui.chatBox.date.hidden= false;
        ui.chatBox.player.hidden= true;
    };

    this.addActions= function(){

    };

    var gamedata= {
        player : null,
        date : null,
        descriptions : null,
        friend : null,
        activeScene : null,
        sceneName : '',
        scenes : {},
        actions : {},
        locations : {},
        images : {},
        ui : null,
        chatLog: [],
        playerTextLocked : false,
        playerSays : this.playerSays,
        dateSays : this.dateSays,
        selectText : selectText,
        goToScene : this.goToScene
    };

    this.gamedata= gamedata;
});<|endoftext|>


<commit_before>// Load in dependencies
var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');

// Define our bookmark parser
function BookmarkCollection(bookmarks, options) {
  // Inherit from EventEmitter
  EventEmitter.call(this);

  // Fallback options
  options = options || {};

  // Parse now
  var bookmarksArr = BookmarkCollection.parse(bookmarks, options);
  this.bookmarksArr = bookmarksArr;

  // Save options for later
  this.options = options;
}

// Extend from EventEmitter
BookmarkCollection.parse = function (bookmarks, options) {
  // Denote the root of the bookmarks
  var bookmarksRoot = bookmarks;

  // Find the first child which contains all our bookmarks
  var whitelistedFolders = options.folders;
  var rootChildren = bookmarksRoot.children;
  var bookmarkMenu = rootChildren.filter(function (container) {
    // TODO: Consider container.root === 'bookmarksMenuFolder'
    return container.title === 'Bookmarks Menu';
  })[0];
  var bookmarkFolders = bookmarkMenu.children;
  var approvedFolders = bookmarkFolders;
  if (whitelistedFolders) {
    // TODO: It is possible for there to be bookmarks in the menu itself...
    approvedFolders = bookmarkFolders.filter(function (folder) {
      return whitelistedFolders.indexOf(folder.title) !== -1;
    });
  }

  // Format content
  function parseFolder(folder) {
    var children = folder.children || [];
    return {
      type: 'folder',
      title: folder.title,
      children: children.map(parseBookmark)
    };
  }
  function parseBookmark(bookmark) {
    // Find the proper description
    var annos = bookmark.annos || [];
    var descriptionNode = annos.filter(function (anno) {
      return anno.name === 'bookmarkProperties/description';
    })[0] || {};
    var description = descriptionNode.value || bookmark.title;

    // Grab the title and bookmark
    var title = bookmark.title;
    var uri = bookmark.uri;

    // If the uri is not defined, add the bookmark as a folder
    if (uri === undefined) {
      return parseFolder(bookmark);
    }

    // Create and return the object
    return {
      type: 'bookmark',
      title: title,
      dateAdded: bookmark.dateAdded,
      lastModified: bookmark.lastModified,
      description: description,
      uri: uri
    };
  }

  // Map and return the approved folders
  var retArr = approvedFolders.map(parseFolder);
  return retArr;
};

BookmarkCollection.prototype = _.extend({
  toArray: function () {
    return this.bookmarksArr;
  }
}, EventEmitter.prototype);

// Create sugar fn for parsing bookmarks
function parseBookmarks(bookmarks, options) {
  // Generate a new collection
  var collection = new BookmarkCollection(bookmarks, options);

  // Return the bookmarks as an array
  return collection.toArray();
}

// Expose the BookmarkCollection via parseBookmarks
parseBookmarks.BookmarkCollection = BookmarkCollection;

// Expose parseBookmarks
module.exports = parseBookmarks;<commit_msg>Adding TODO for self<commit_after>// Load in dependencies
var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');

// Define our bookmark parser
function BookmarkCollection(bookmarks, options) {
  // Inherit from EventEmitter
  EventEmitter.call(this);

  // Fallback options
  options = options || {};

  // Parse now
  var bookmarksArr = BookmarkCollection.parse(bookmarks, options);
  this.bookmarksArr = bookmarksArr;

  // Save options for later
  this.options = options;
}

// Extend from EventEmitter
BookmarkCollection.parse = function (bookmarks, options) {
  // Denote the root of the bookmarks
  var bookmarksRoot = bookmarks;

  // Find the first child which contains all our bookmarks
  var whitelistedFolders = options.folders;
  var rootChildren = bookmarksRoot.children;
  var bookmarkMenu = rootChildren.filter(function (container) {
    // TODO: Consider container.root === 'bookmarksMenuFolder'
    return container.title === 'Bookmarks Menu';
  })[0];
  var bookmarkFolders = bookmarkMenu.children;
  var approvedFolders = bookmarkFolders;
  if (whitelistedFolders) {
    // TODO: It is possible for there to be bookmarks in the menu itself...
    approvedFolders = bookmarkFolders.filter(function (folder) {
      return whitelistedFolders.indexOf(folder.title) !== -1;
    });
  }

  // Format content
  function parseFolder(folder) {
    var children = folder.children || [];
    return {
      type: 'folder',
      title: folder.title,
      children: children.map(parseBookmark)
    };
  }
  function parseBookmark(bookmark) {
    // Find the proper description
    var annos = bookmark.annos || [];
    var descriptionNode = annos.filter(function (anno) {
      return anno.name === 'bookmarkProperties/description';
    })[0] || {};
    var description = descriptionNode.value || bookmark.title;

    // Grab the title and bookmark
    var title = bookmark.title;
    var uri = bookmark.uri;

    // If the uri is not defined, add the bookmark as a folder
    if (uri === undefined) {
      return parseFolder(bookmark);
    }

    // Create and return the object
    return {
      type: 'bookmark',
      title: title,
      dateAdded: bookmark.dateAdded,
      lastModified: bookmark.lastModified,
      description: description,
      uri: uri
    };
  }

  // Map and return the approved folders
  var retArr = approvedFolders.map(parseFolder);
  return retArr;
};

BookmarkCollection.prototype = _.extend({
  toArray: function () {
    return this.bookmarksArr;
  }
}, EventEmitter.prototype);

// TODO: Delete me into cli folder
// Create sugar fn for parsing bookmarks
function parseBookmarks(bookmarks, options) {
  // Generate a new collection
  var collection = new BookmarkCollection(bookmarks, options);

  // Return the bookmarks as an array
  return collection.toArray();
}

// Expose the BookmarkCollection via parseBookmarks
parseBookmarks.BookmarkCollection = BookmarkCollection;

// Expose parseBookmarks
module.exports = parseBookmarks;<|endoftext|>


<commit_before>const fetch = require('isomorphic-fetch')
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json()

module.exports = (app) => {
  app.get('/api/v1/profile/info', (request, response) => {
    fetch(`http://koha:8081/api/v1/patrons/${request.session.borrowerNumber}`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        response.status(res.status).send(res.statusText)
        throw Error()
      }
    }).then(json => response.status(200).send(parsePatron(json)))
      .catch(error => {
        console.log(error)
        response.sendStatus(500)
      })
  })

  app.post('/api/v1/profile/info', jsonParser, (request, response) => {
    const patron = {
      address: request.body.address,
      zipcode: request.body.zipcode,
      city: request.body.city,
      country: request.body.country,
      smsalertnumber: request.body.mobile,
      phone: request.body.telephone,
      email: request.body.email
    }

    fetch(`http://koha:8081/api/v1/patrons/${request.session.borrowerNumber}`, {
      method: 'PUT',
      headers: {
        'Cookie': request.session.kohaSession
      },
      body: JSON.stringify(patron)
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        response.status(res.status).send(res.body)
      }
    }).then(json => response.status(200).send(parsePatron(json)))
      .catch(error => {
        console.log(error)
        response.sendStatus(500)
      })
  })

  app.get('/api/v1/profile/loans', (request, response) => {
    response.send({
      name: 'Ola finn Oddvar Nordmann',
      pickup: [
        {
          recordId: 'xx',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Haruki Murakami',
          publicationYear: '1987',
          expiry: '2016-09-21',
          pickupNumber: '40/20220'
        },
        {
          recordId: 'yy',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Haruki Murakami',
          publicationYear: '1987',
          expiry: '2016-09-21',
          pickupNumber: '40/20220'
        }
      ],
      reservations: [
        {
          recordId: 'xx',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Lars- Saabye Christensen',
          orderedDate: '2016-12-03',
          waitingPeriod: 'xxx',
          branchCode: 'dfb'
        },
        {
          recordId: 'yy',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Lars- Saabye Christensen',
          orderedDate: '2016-12-03',
          waitingPeriod: 'xxx',
          branchCode: 'dfb'
        }
      ],
      loans: [
        {
          recordId: 'xx',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Lars- Saabye Christensen',
          publicationYear: '1987',
          dueDate: '2016-12-05'
        },
        {
          recordId: 'yy',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Lars- Saabye Christensen',
          publicationYear: '1987',
          dueDate: '2016-12-05'
        }
      ]
    })
  })

  app.post('/api/v1/profile/settings', jsonParser, (request, response) => {
    request.session.profileSettings = request.body
    response.sendStatus(200)
  })

  app.get('/api/v1/profile/settings', (request, response) => {
    if (request.session.profileSettings) {
      response.send(request.session.profileSettings)
    } else {
      response.send({
        alerts: {
          reminderOfDueDate: {
            sms: true,
            email: false
          },
          reminderOfPickup: {
            sms: false,
            email: true
          }
        },
        reciepts: {
          loans: {
            email: true
          },
          returns: {
            email: true
          }
        }
      })
    }
  })

  function parsePatron (patron) {
    return {
      borrowerNumber: patron.borrowernumber || '',
      name: `${patron.firstname} ${patron.surname}`,
      address: patron.address || '',
      zipcode: patron.zipcode || '',
      city: patron.city || '',
      country: patron.country || '',
      mobile: patron.smsalertnumber || '', // is this the only sms number?
      telephone: patron.phone || '',
      email: patron.email || '',
      birthdate: patron.dateofbirth || '',
      loanerCardIssued: patron.dateenrolled || '',
      loanerCategory: patron.categorycode || '',
      lastUpdated: '2016-02-01'
    }
  }
}
<commit_msg>Patron-client: add routes and methods to fetch loans and holds in backend<commit_after>const fetch = require('isomorphic-fetch')
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json()

module.exports = (app) => {
  app.get('/api/v1/profile/info', (request, response) => {
    fetch(`http://koha:8081/api/v1/patrons/${request.session.borrowerNumber}`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        response.status(res.status).send(res.statusText)
        throw Error()
      }
    }).then(json => response.status(200).send(parsePatron(json)))
      .catch(error => {
        console.log(error)
        response.sendStatus(500)
      })
  })

  app.post('/api/v1/profile/info', jsonParser, (request, response) => {
    const patron = {
      address: request.body.address,
      zipcode: request.body.zipcode,
      city: request.body.city,
      country: request.body.country,
      smsalertnumber: request.body.mobile,
      phone: request.body.telephone,
      email: request.body.email
    }

    fetch(`http://koha:8081/api/v1/patrons/${request.session.borrowerNumber}`, {
      method: 'PUT',
      headers: {
        'Cookie': request.session.kohaSession
      },
      body: JSON.stringify(patron)
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        response.status(res.status).send(res.body)
      }
    }).then(json => response.status(200).send(parsePatron(json)))
      .catch(error => {
        console.log(error)
        response.sendStatus(500)
      })
  })

  app.get('/api/v1/profile/loans', (request, response) => {
    Promise.all([fetchAllCheckouts(request), fetchAllHolds(request), fetchAllPickups(request)])
    .then(data => {
      const [checkouts, holds, pickups] = data
      response.send({
        name: 'Ola finn Oddvar Nordmann',
        loans: checkouts,
        reservations: holds,
        pickup: pickups
      })
    })
  })

  app.get('/api/v1/profile/checkouts', (request, response) => {
    fetchAllCheckouts(request)
    .then(res => {
      console.log(res)
      response.status(200).send(res)
    }).catch(error => {
      console.log(error)
      response.sendStatus(500)
    })
  })

  app.get('/api/v1/profile/holds', (request, response) => {
    fetchAllHolds(request)
    .then(res => {
      console.log(res)
      response.status(200).send(res)
    }).catch(error => {
      console.log(error)
      response.sendStatus(500)
    })
  })

  app.get('/api/v1/profile/pickups', (request, response) => {
    fetchAllPickups(request)
    .then(res => {
      console.log(res)
      response.status(200).send(res)
    }).catch(error => {
      console.log(error)
      response.sendStatus(500)
    })
  })

  function fetchAllPickups (request) {
    return new Promise((resolve) => {
      resolve([
        {
          recordId: 'xx',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Haruki Murakami',
          publicationYear: '1987',
          expiry: '2016-09-21',
          pickupNumber: '40/20220'
        },
        {
          recordId: 'yy',
          title: 'Hard-Boiled Wonderland and the End of the World',
          author: 'Haruki Murakami',
          publicationYear: '1987',
          expiry: '2016-09-21',
          pickupNumber: '40/20220'
        }
      ])
    })
  }

  function fetchAllHolds (request) {
    return fetch(`http://koha:8081/api/v1/holds?borrowernumber=${request.session.borrowerNumber}`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        throw Error(res.statusText)
      }
    }).then(json => {
      const promises = json.map(hold => fetchHoldFromBiblioNumber(hold, request))
      return Promise.all(promises)
    }).then(holds => {
      return holds
    })
  }

  function fetchHoldFromBiblioNumber (hold, request) {
    return fetch(`http://koha:8081/api/v1/biblios/${hold.biblionumber}`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        throw Error(res.statusText)
      }
    }).then(json => {
      return {
        recordId: hold.biblionumber,
        title: json.title,
        author: json.author,
        orderedDate: hold.reservedate,
        waitingPeriod: 'cirka 2-4 uker',
        branchCode: hold.branchcode
      }
    })
  }

  function fetchAllCheckouts (request) {
    return fetch(`http://koha:8081/api/v1/checkouts?borrowernumber=${request.session.borrowerNumber}`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        throw Error(res.statusText)
      }
    }).then(json => {
      const promises = json.map(loan => fetchLoanFromItemNumber(loan, request))
      return Promise.all(promises)
    }).then(loans => {
      return loans
    })
  }

  function fetchLoanFromItemNumber (loan, request) {
    return fetch(`http://koha:8081/api/v1/items/${loan.itemnumber}/biblio`, {
      method: 'GET',
      headers: {
        'Cookie': request.session.kohaSession
      }
    }).then(res => {
      if (res.status === 200) {
        return res.json()
      } else {
        throw Error(res.statusText)
      }
    }).then(json => {
      return {
        itemNumber: loan.itemnumber,
        recordId: json.biblionumber,
        dueDate: loan.date_due,
        title: json.title,
        author: json.author,
        publicationYear: json.publicationyear
      }
    })
  }

  app.post('/api/v1/profile/settings', jsonParser, (request, response) => {
    request.session.profileSettings = request.body
    response.sendStatus(200)
  })

  app.get('/api/v1/profile/settings', (request, response) => {
    if (request.session.profileSettings) {
      response.send(request.session.profileSettings)
    } else {
      response.send({
        alerts: {
          reminderOfDueDate: {
            sms: true,
            email: false
          },
          reminderOfPickup: {
            sms: false,
            email: true
          }
        },
        reciepts: {
          loans: {
            email: true
          },
          returns: {
            email: true
          }
        }
      })
    }
  })

  function parsePatron (patron) {
    return {
      borrowerNumber: patron.borrowernumber || '',
      name: `${patron.firstname} ${patron.surname}`,
      address: patron.address || '',
      zipcode: patron.zipcode || '',
      city: patron.city || '',
      country: patron.country || '',
      mobile: patron.smsalertnumber || '', // is this the only sms number?
      telephone: patron.phone || '',
      email: patron.email || '',
      birthdate: patron.dateofbirth || '',
      loanerCardIssued: patron.dateenrolled || '',
      loanerCategory: patron.categorycode || '',
      lastUpdated: '2016-02-01'
    }
  }
}
<|endoftext|>


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

/**
 * @fileoverview Methods for creating parts of SVG path strings.  See
 * developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

/**
 * @name Blockly.utils.Paths
 * @namespace
 */
goog.provide('Blockly.utils.Paths');

/**
 * Create a string representing the given x, y pair.  It does not matter whether
 * the coordinate is relative or absolute.  The result has leading
 * and trailing spaces, and separates the x and y coordinates with a comma but
 * no space.
 * @param {number} x The x coordinate.
 * @param {number} y The y coordinate.
 * @return {string} A string of the format ' x,y '
 * @public
 */
Blockly.utils.Paths.point = function(x, y) {
  return ' ' + x + ',' + y + ' ';
};
/**
 * Draw a curbic or quadratic curve.  See
 * developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve
 * These coordinates are unitless and hence in the user coordinate system.
 * @param {string} command The command to use.
 *     Should be one of: c, C, s, S, q, Q.
 * @param {string} points  An array containing all of the points to pass to the
 *     curve command, in order.  The points are represented as strings of the
 *     format ' x, y '.
 * @return {string} A string defining one or more Bezier curves.  See the MDN
 *     documentation for exact format.
 * @public
 */
Blockly.utils.Paths.curve = function(command, points) {
  return command + points.join('');
};
/**
 * Move the cursor to the given position without drawing a line.
 * The coordinates are absolute.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} x The absolute x coordinate.
 * @param {number} y The absolute y coordinate.
 * @return {string} A string of the format ' M x,y '
 * @public
 */
Blockly.utils.Paths.moveTo = function(x, y) {
  return ' M ' + x + ',' + y + ' ';
};
/**
 * Move the cursor to the given position without drawing a line.
 * Coordinates are relative.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} dx The relative x coordinate.
 * @param {number} dy The relative y coordinate.
 * @return {string} A string of the format ' m dx,dy '
 * @public
 */
Blockly.utils.Paths.moveBy = function(dx, dy) {
  return ' m ' + dx + ',' + dy + ' ';
};

/**
 * Draw a line from the current point to the end point, which is the current
 * point shifted by dx along the x-axis and dy along the y-axis.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} dx The relative x coordinate.
 * @param {number} dy The relative y coordinate.
 * @return {string} A string of the format ' L dx,dy '
 * @public
 */
Blockly.utils.Paths.lineTo = function(dx, dy) {
  return ' l ' + dx + ',' + dy + ' ';
};

/**
 * Draw multiple lines connecting all of the given points in order.  This is
 * equivalent to a series of 'l' commands.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {!Array.<string>} points An array containing all of the points to
 *     draw lines to, in order.  The points are represented as strings of the
 *     format ' dx, dy '.
 * @return {string} A string of the format ' l (dx,dy)+ '
 * @public
 */
Blockly.utils.Paths.line = function(points) {
  return 'l' + points.join('');
};

/**
 * Draw a horizontal or vertical line.
 * The first argument specifies the direction and whether the given position is
 * relative or absolute.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#LineTo_path_commands
 * @param {string} command The command to prepend to the coordinate.  This
 *     should be one of: V, v, H, h.  See
 * @param {number} val The coordinate to pass to the command.  It may be
 *     absolute or relative.
 * @return {string} A string of the format ' command val '
 * @public
 */
Blockly.utils.Paths.lineOnAxis = function(command, val) {
  return command + ' ' + val;
};

/**
 * Draw an elliptical arc curve.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Elliptical_Arc_Curve
 * @param {string} command The command string.  Either 'a' or 'A'.
 * @param {string} flags The flag string.  See the MDN documentation for a
 *     description and examples.
 * @param {number} radius The radius of the arc to draw.
 * @param {string} point The point to move the cursor to after drawing the arc,
 *     specified either in absolute or relative coordinates depending on the
 *     command.
 * @return {string} A string of the format 'command radius radius flags point'
 * @public
 */
Blockly.utils.Paths.arc = function(command, flags, radius, point) {
  return command + ' ' + radius + ' ' + radius + ' ' + flags + point;
};
<commit_msg>Lowercase l in comments<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2019 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Methods for creating parts of SVG path strings.  See
 * developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

/**
 * @name Blockly.utils.Paths
 * @namespace
 */
goog.provide('Blockly.utils.Paths');

/**
 * Create a string representing the given x, y pair.  It does not matter whether
 * the coordinate is relative or absolute.  The result has leading
 * and trailing spaces, and separates the x and y coordinates with a comma but
 * no space.
 * @param {number} x The x coordinate.
 * @param {number} y The y coordinate.
 * @return {string} A string of the format ' x,y '
 * @public
 */
Blockly.utils.Paths.point = function(x, y) {
  return ' ' + x + ',' + y + ' ';
};
/**
 * Draw a curbic or quadratic curve.  See
 * developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve
 * These coordinates are unitless and hence in the user coordinate system.
 * @param {string} command The command to use.
 *     Should be one of: c, C, s, S, q, Q.
 * @param {string} points  An array containing all of the points to pass to the
 *     curve command, in order.  The points are represented as strings of the
 *     format ' x, y '.
 * @return {string} A string defining one or more Bezier curves.  See the MDN
 *     documentation for exact format.
 * @public
 */
Blockly.utils.Paths.curve = function(command, points) {
  return command + points.join('');
};
/**
 * Move the cursor to the given position without drawing a line.
 * The coordinates are absolute.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} x The absolute x coordinate.
 * @param {number} y The absolute y coordinate.
 * @return {string} A string of the format ' M x,y '
 * @public
 */
Blockly.utils.Paths.moveTo = function(x, y) {
  return ' M ' + x + ',' + y + ' ';
};
/**
 * Move the cursor to the given position without drawing a line.
 * Coordinates are relative.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} dx The relative x coordinate.
 * @param {number} dy The relative y coordinate.
 * @return {string} A string of the format ' m dx,dy '
 * @public
 */
Blockly.utils.Paths.moveBy = function(dx, dy) {
  return ' m ' + dx + ',' + dy + ' ';
};

/**
 * Draw a line from the current point to the end point, which is the current
 * point shifted by dx along the x-axis and dy along the y-axis.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {number} dx The relative x coordinate.
 * @param {number} dy The relative y coordinate.
 * @return {string} A string of the format ' l dx,dy '
 * @public
 */
Blockly.utils.Paths.lineTo = function(dx, dy) {
  return ' l ' + dx + ',' + dy + ' ';
};

/**
 * Draw multiple lines connecting all of the given points in order.  This is
 * equivalent to a series of 'l' commands.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands
 * @param {!Array.<string>} points An array containing all of the points to
 *     draw lines to, in order.  The points are represented as strings of the
 *     format ' dx, dy '.
 * @return {string} A string of the format ' l (dx,dy)+ '
 * @public
 */
Blockly.utils.Paths.line = function(points) {
  return 'l' + points.join('');
};

/**
 * Draw a horizontal or vertical line.
 * The first argument specifies the direction and whether the given position is
 * relative or absolute.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#LineTo_path_commands
 * @param {string} command The command to prepend to the coordinate.  This
 *     should be one of: V, v, H, h.  See
 * @param {number} val The coordinate to pass to the command.  It may be
 *     absolute or relative.
 * @return {string} A string of the format ' command val '
 * @public
 */
Blockly.utils.Paths.lineOnAxis = function(command, val) {
  return command + ' ' + val;
};

/**
 * Draw an elliptical arc curve.
 * These coordinates are unitless and hence in the user coordinate system.
 * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Elliptical_Arc_Curve
 * @param {string} command The command string.  Either 'a' or 'A'.
 * @param {string} flags The flag string.  See the MDN documentation for a
 *     description and examples.
 * @param {number} radius The radius of the arc to draw.
 * @param {string} point The point to move the cursor to after drawing the arc,
 *     specified either in absolute or relative coordinates depending on the
 *     command.
 * @return {string} A string of the format 'command radius radius flags point'
 * @public
 */
Blockly.utils.Paths.arc = function(command, flags, radius, point) {
  return command + ' ' + radius + ' ' + radius + ' ' + flags + point;
};
<|endoftext|>


<commit_before>Polymer({
  is: 'pie-chart',
  properties: {
    title: '',
    inputs: {
      notify: true,
      type: Array,
      value: [{
        input: 'slice',
        txt: 'Pick a dimension',
        selectedValue: 0,
        selectedName: 'label',
        uitype: 'single-value'
      }, {
        input: 'sliceSize',
        txt: 'Pick a messure',
        selectedValue: 1,
        selectedName: 'count',
        uitype: 'single-value'
      }]
    },
    settings: {
      notify: true,
      type: Array,
      value: [{
        input: 'displayTxt',
        txt: 'Placement of lables',
        uitype: 'dropDown',
        selectedValue: Array,
        selectedName: Array,
        options: [{
            key: 'None',
            value: 0
        }, {
            key: 'inside',
            value: 1
        }, {
            key: 'outside',
            value: 2
        }]
      }, {
        input: 'innerRadius',
        txt: 'Inner radius',
        uitype: 'Number',
        selectedValue: 0
      }]
    },
    hideSettings: true,
    source: {
      type: Array,
      value: []
    },
    external: Array,
    svg: Object
  },

  behaviors: [
    PolymerD3.chartBehavior,
    PolymerD3.colorPickerBehavior
  ],

  _toggleView: function() {
    this.hideSettings = !this.hideSettings;
  },

  _parseData(){
    var me = this;
    me.newData =[];
    me.source.forEach(function(d) {
      d[me.getInputsProperty('sliceSize')] = +d[me.getInputsProperty('sliceSize')];
      me.newData.push(d);
    });
  },

  draw: function() {
    var me = this;
    me.makeChartWrap();
    var sliceHeader = this.inputs[0].selectedName;
    var sliceSizeHeader = this.inputs[1].selectedName;
    var donutWidth = 75;
    var legendRectSize = 18;
    var legendSpacing = 4;
    var width = this.getWidth(),
      height = this.getHeight(),
      radius = Math.min(width, height) / 2;

    var color = d3.scale.ordinal()//this  needs to change, its hardcoded
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

    var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

    var labelArc = d3.svg.arc()
      .outerRadius(radius - 40)
      .innerRadius(radius - 40);

    me._parseData();

    var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d[me.getInputsProperty('sliceSize')];
        // return d[sliceSizeHeader];
      });

    this.svg
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    me.gWrap = me.svg.select("g");

    var g = me.gWrap.selectAll(".arc")
      .data(pie(me.newData))
      .enter().append("g")
      .attr("class", "arc");

    g.append("path")
      .attr("d", arc)
      .style("fill", function(d) {
        return color(d.data[me.getInputsProperty('slice')]);
        // return color(d.data[sliceHeader]);
      });

    g.append("text")
      .attr("transform", function(d) {
        return "translate(" + labelArc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .text(function(d) {
        return d.data[me.getInputsProperty('slice')];
        // return d.data[sliceHeader]+":" + d.data[sliceSizeHeader];
      });
  }
});<commit_msg>Modified pie chart inner radius<commit_after>Polymer({
  is: 'pie-chart',
  properties: {
    title: '',
    inputs: {
      notify: true,
      type: Array,
      value: [{
        input: 'slice',
        txt: 'Pick a dimension',
        selectedValue: 0,
        selectedName: 'label',
        uitype: 'single-value'
      }, {
        input: 'sliceSize',
        txt: 'Pick a messure',
        selectedValue: 1,
        selectedName: 'count',
        uitype: 'single-value'
      }]
    },
    settings: {
      notify: true,
      type: Array,
      value: [{
        input: 'displayTxt',
        txt: 'Placement of lables',
        uitype: 'dropDown',
        selectedValue: Array,
        selectedName: Array,
        options: [{
            key: 'None',
            value: 0
        }, {
            key: 'inside',
            value: 1
        }, {
            key: 'outside',
            value: 2
        }]
      }, {
        input: 'innerRadius',
        txt: 'Inner radius',
        uitype: 'Number',
        selectedValue: 0
      }]
    },
    hideSettings: true,
    source: {
      type: Array,
      value: []
    },
    external: Array,
    svg: Object
  },

  behaviors: [
    PolymerD3.chartBehavior,
    PolymerD3.colorPickerBehavior
  ],

  _toggleView: function() {
    this.hideSettings = !this.hideSettings;
  },

  _parseData(){
    var me = this;
    me.newData =[];
    me.source.forEach(function(d) {
      d[me.getInputsProperty('sliceSize')] = +d[me.getInputsProperty('sliceSize')];
      me.newData.push(d);
    });
  },

  draw: function() {
    var me = this;
    me.makeChartWrap();
    var sliceHeader = this.inputs[0].selectedName;
    var sliceSizeHeader = this.inputs[1].selectedName;
    var donutWidth = 75;
    var legendRectSize = 18;
    var legendSpacing = 4;
    var width = this.getWidth(),
      height = this.getHeight(),
      radius = Math.min(width, height) / 2;

    var color = d3.scale.ordinal()//this  needs to change, its hardcoded
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

    var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(me.getSettingsProperty("innerRadius"));

    var labelArc = d3.svg.arc()
      .outerRadius(radius - 40)
      .innerRadius(radius - 40);

    me._parseData();

    var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d[me.getInputsProperty('sliceSize')];
      });

    this.svg
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    me.gWrap = me.svg.select("g");

    var g = me.gWrap.selectAll(".arc")
      .data(pie(me.newData))
      .enter().append("g")
      .attr("class", "arc");

    g.append("path")
      .attr("d", arc)
      .style("fill", function(d) {
        return color(d.data[me.getInputsProperty('slice')]);
      });

    g.append("text")
      .attr("transform", function(d) {
        return "translate(" + labelArc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .text(function(d) {
        return d.data[me.getInputsProperty('slice')];
      });
  }
});<|endoftext|>


<commit_before>document.getElementById("navMenu").innerHTML =
'
'+
    '
'+
        '
'+
            'Home'+
        '
'+
    '
About Us'+
    '
' +
    '
Mission
'+
          '
E-Board
'+
          '
AIMS Lab
'+
        '
'+
      '
'   +
    '
Members'+
    '

Prospective Members Application
'+
          '
E-Board Application
' +
    + '
'+
      '
' +
            '
'+
            ' Events'+
            ''+
            '
'+
              '
Upcoming Events
'+
              '
Past Events
'
              + '
'+
          '
'+
            '
'+
            'Contact'+
            ''+
            '
'+
              '
Professors
'+
              '
Resources
'+
              '
' +
        '
'+

'
';

// ''+
//   '<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">'+
//     ''+
//   '</button>'+
//   'Navbar'+
//   '
'+
//     '
'+
//       '
'+
//         'Home (current)'+
//       '
'+
//       '
'+
//         'Features'+
//       '
'+
//       '
'+
//         'Pricing'+
//       '
'+
//       '
'+
//         ''+
//           Dropdown link
//         ''+
//         '
'+
//           'Action'+
//           'Another action'+
//           'Something else here'+
//         '
'+
//       '
'+
//     '
'+
//   '
'+
// '';

// ''+
//   '
'+
//     '
'+
//       'WebSiteName'+
//     '
'+
//     '
'+
//       '
Home
'+
//       '
'+
//         'Page 1'+
//         ''+
//         '
'+
//           '
Page 1-1
'+
//           '
Page 1-2
'+
//           '
Page 1-3
'+
//         '
'+
//       '
'+
//       '
Page 2
'+
//       '
Page 3
'+
//     '
'+
//   '
'+
// '';
<commit_msg>Update nav.js<commit_after>document.getElementById("navMenu").innerHTML =
'
'+
    '
'+
        '
'+
            'Home'+
        '
'+
    '
About Us'+
    '
' +
    '
Mission
'+
          '
E-Board
'+
          '
AIMS Lab
'+
        '
'+
      '
'   +
    '
Members'+
    '

Prospective Members Application
'+
          '
E-Board Application
'
    + '
'+
      '
' +
            '
'+
            ' Events'+
            ''+
            '
'+
              '
Upcoming Events
'+
              '
Past Events
'
              + '
'+
          '
'+
            '
'+
            'Contact'+
            ''+
            '
'+
              '
Professors
'+
              '
Resources
'+
              '
' +
        '
'+

'
';

// ''+
//   '<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">'+
//     ''+
//   '</button>'+
//   'Navbar'+
//   '
'+
//     '
'+
//       '
'+
//         'Home (current)'+
//       '
'+
//       '
'+
//         'Features'+
//       '
'+
//       '
'+
//         'Pricing'+
//       '
'+
//       '
'+
//         ''+
//           Dropdown link
//         ''+
//         '
'+
//           'Action'+
//           'Another action'+
//           'Something else here'+
//         '
'+
//       '
'+
//     '
'+
//   '
'+
// '';

// ''+
//   '
'+
//     '
'+
//       'WebSiteName'+
//     '
'+
//     '
'+
//       '
Home
'+
//       '
'+
//         'Page 1'+
//         ''+
//         '
'+
//           '
Page 1-1
'+
//           '
Page 1-2
'+
//           '
Page 1-3
'+
//         '
'+
//       '
'+
//       '
Page 2
'+
//       '
Page 3
'+
//     '
'+
//   '
'+
// '';
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// XHRSpy

var XHRSpy = function()
{
    this.requestHeaders = [];
    this.responseHeaders = [];
};

XHRSpy.prototype =
{
    method: null,
    url: null,
    async: null,

    xhrRequest: null,

    href: null,

    loaded: false,

    logRow: null,

    responseText: null,

    requestHeaders: null,
    responseHeaders: null,

    sourceLink: null, // {href:"file.html", line: 22}

    getURL: function()
    {
        return this.href;
    }
};

// ************************************************************************************************
// XMLHttpRequestWrapper

var XMLHttpRequestWrapper = function(activeXObject)
{
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper internal variables

    var xhrRequest = typeof activeXObject != "undefined" ?
                activeXObject :
                new _XMLHttpRequest(),

        spy = new XHRSpy(),

        self = this,

        reqType,
        reqUrl,
        reqStartTS;

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper internal methods

    var updateSelfProperties = function()
    {
        var self = self;

        for (var propName in xhrRequest)
        {
            try
            {
                var propValue = xhrRequest[propName];

                if (!isFunction(propValue))
                    self[propName] = propValue;
            }
            catch(E)
            {
                //console.log(propName, E.message);
            }
        }
    };

    var updateXHRProperties = function()
    {
        var self = self;

        for (var propName in self)
        {
            try
            {
                var propValue = self[propName];

                if (!xhrRequest[propName])
                {
                    xhrRequest[propName] = propValue;
                }
            }
            catch(E)
            {
                //console.log(propName, E.message);
            }
        }
    };

    var logXHR = function()
    {
        var row = Firebug.Console.log(spy, null, "spy", Firebug.Spy.XHR);

        if (row)
        {
            setClass(row, "loading");
            spy.logRow = row;
        }
    };

    var finishXHR = function()
    {
        var duration = new Date().getTime() - reqStartTS;
        var success = xhrRequest.status == 200;

        var responseHeadersText = xhrRequest.getAllResponseHeaders();
        var responses = responseHeadersText ? responseHeadersText.split(/[\n\r]/) : [];
        var reHeader = /^(\S+):\s*(.*)/;

        for (var i=0, l=responses.length; i<l; i++)
        {
            var text = responses[i];
            var match = text.match(reHeader);

            if (match)
            {
                var name = match[1];
                var value = match[2];

                // update the spy mimeType property so we can detect when to show
                // custom response viewers (such as HTML, XML or JSON viewer)
                if (name == "Content-Type")
                    spy.mimeType = value;

                /*
                if (name == "Last Modified")
                {
                    if (!spy.cacheEntry)
                        spy.cacheEntry = [];

                    spy.cacheEntry.push({
                       name: [name],
                       value: [value]
                    });
                }
                /**/

                spy.responseHeaders.push({
                   name: [name],
                   value: [value]
                });
            }
        }

        with({
            row: spy.logRow,
            status: xhrRequest.status + " " + xhrRequest.statusText,
            time: duration,
            success: success
        })
        {
            setTimeout(function(){

                spy.responseText = xhrRequest.responseText;

                // update row information to avoid "ethernal spinning gif" bug in IE
                row = row || spy.logRow;

                // if chrome document is not loaded, there will be no row yet, so just ignore
                if (!row) return;

                FBL.removeClass(row, "loading");

                if (!success)
                    FBL.setClass(row, "error");

                var item = FBL.$$(".spyStatus", row)[0];
                item.innerHTML = status;

                var item = FBL.$$(".spyTime", row)[0];
                item.innerHTML = time + "ms";

            },200);
        }

        spy.loaded = true;

        self.status = xhrRequest.status;
        self.statusText = xhrRequest.statusText;
        self.responseText = xhrRequest.responseText;
        self.responseXML = xhrRequest.responseXML;

        updateSelfProperties();
    };

    var handleStateChange = function()
    {
        //Firebug.Console.log("onreadystatechange");

        self.readyState = xhrRequest.readyState;

        if (xhrRequest.readyState == 4)
        {
            finishXHR();

            xhrRequest.onreadystatechange = function(){};
        }

        //Firebug.Console.log(spy.url + ": " + xhrRequest.readyState);

        self.onreadystatechange();
    };

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper public properties and handlers

    this.readyState = 0;

    this.onreadystatechange = function(){};

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper public methods

    this.open = function(method, url, async, user, password)
    {
        //Firebug.Console.log("xhrRequest open");

        updateSelfProperties();

        if (spy.loaded)
            spy = new XHRSpy();

        spy.method = method;
        spy.url = url;
        spy.async = async;
        spy.href = url;
        spy.xhrRequest = xhrRequest;
        spy.urlParams = parseURLParamsArray(url);

        if (!FBL.isIE && async)
            xhrRequest.onreadystatechange = handleStateChange;

        // xhr.open.apply not available in IE
        if (typeof xhrRequest.open.apply != "undefined")
            xhrRequest.open.apply(xhrRequest, arguments)
        else
            xhrRequest.open(method, url, async, user, password);

        if (FBL.isIE && async)
            xhrRequest.onreadystatechange = handleStateChange;

    };

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

    this.send = function(data)
    {
        //Firebug.Console.log("xhrRequest send");

        spy.data = data;

        reqStartTS = new Date().getTime();

        updateXHRProperties();

        try
        {
            xhrRequest.send(data);
        }
        catch(e)
        {
            throw e;
        }
        finally
        {
            logXHR();

            if (!spy.async)
            {
                self.readyState = xhrRequest.readyState;

                finishXHR();
            }
        }
    };

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

    this.setRequestHeader = function(header, value)
    {
        spy.requestHeaders.push({name: [header], value: [value]});
        return xhrRequest.setRequestHeader(header, value);
    };

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

    this.getResponseHeader = function(header)
    {
        return xhrRequest.getResponseHeader(header);
    };

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

    this.getAllResponseHeaders = function()
    {
        return xhrRequest.getAllResponseHeaders();
    };

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

    this.abort = function()
    {
        return xhrRequest.abort();
    };

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Clone XHR object

    var supportsApply = xhrRequest &&
            xhrRequest.open &&
            typeof xhrRequest.open.apply != "undefined";

    for (var propName in xhrRequest)
    {
        if (propName == "onreadystatechange")
            continue;

        try
        {
            var propValue = xhrRequest[propName];

            if (isFunction(propValue))
            {
                if (typeof self[propName] == "undefined")
                {
                    this[propName] = supportsApply ?
                        // if the browser supports apply
                        function()
                        {
                            return xhrRequest[propName].apply(xhrRequest, arguments)
                        }
                        :
                        function(a,b,c,d,e)
                        {
                            return xhrRequest[propName](a,b,c,d,e)
                        };
                }
            }
            else
                this[propName] = propValue;
        }
        catch(E)
        {
            //console.log(propName, E.message);
        }
    }
    /**/

    return this;
};

// ************************************************************************************************
// ActiveXObject Wrapper (IE6 only)

var _ActiveXObject;
var isIE6 =  /msie 6/i.test(navigator.appVersion);

if (isIE6)
{
    window._ActiveXObject = window.ActiveXObject;

    var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP ";

    window.ActiveXObject = function(name)
    {
        var error = null;

        try
        {
            var activeXObject = new window._ActiveXObject(name);
        }
        catch(e)
        {
            error = e;
        }
        finally
        {
            if (!error)
            {
                if (xhrObjects.indexOf(" " + name + " ") != -1)
                    return new XMLHttpRequestWrapper(activeXObject);
                else
                    return activeXObject;
            }
            else
                throw error.message;
        }
    };
}

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

// Register the XMLHttpRequestWrapper for non-IE6 browsers
if (!isIE6)
{
    var _XMLHttpRequest = XMLHttpRequest;
    window.XMLHttpRequest = function()
    {
        return new XMLHttpRequestWrapper();
    }
}

// ************************************************************************************************
}})();
<commit_msg>Merging r7408 - Issue 3181: Missing XHR methods/properties - XHR representation is properly updated when the request is aborted<commit_after>/* See license.txt for terms of usage */

(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// XHRSpy

var XHRSpy = function()
{
    this.requestHeaders = [];
    this.responseHeaders = [];
};

XHRSpy.prototype =
{
    method: null,
    url: null,
    async: null,

    xhrRequest: null,

    href: null,

    loaded: false,

    logRow: null,

    responseText: null,

    requestHeaders: null,
    responseHeaders: null,

    sourceLink: null, // {href:"file.html", line: 22}

    getURL: function()
    {
        return this.href;
    }
};

// ************************************************************************************************
// XMLHttpRequestWrapper

var XMLHttpRequestWrapper = function(activeXObject)
{
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper internal variables

    var xhrRequest = typeof activeXObject != "undefined" ?
                activeXObject :
                new _XMLHttpRequest(),

        spy = new XHRSpy(),

        self = this,

        reqType,
        reqUrl,
        reqStartTS;

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper internal methods

    var updateSelfPropertiesIgnore = {
        abort: 1,
        channel: 1,
        getInterface: 1,
        mozBackgroundRequest: 1,
        multipart: 1,
        onreadystatechange: 1,
        open: 1,
        send: 1,
        setRequestHeader: 1
    };

    var updateSelfProperties = function()
    {
        for (var propName in xhrRequest)
        {
            if (propName in updateSelfPropertiesIgnore)
                continue;

            try
            {
                var propValue = xhrRequest[propName];

                if (propValue && !isFunction(propValue))
                    self[propName] = propValue;
            }
            catch(E)
            {
                //console.log(propName, E.message);
            }
        }
    };

    var updateXHRPropertiesIgnore = {
        channel: 1,
        onreadystatechange: 1,
        readyState: 1,
        responseBody: 1,
        responseText: 1,
        responseXML: 1,
        status: 1,
        statusText: 1,
        upload: 1
    };

    var updateXHRProperties = function()
    {
        for (var propName in self)
        {
            try
            {
                if (propName in updateXHRPropertiesIgnore)
                    continue;

                var propValue = self[propName];

                if (propValue && !xhrRequest[propName])
                {
                    xhrRequest[propName] = propValue;
                }
            }
            catch(E)
            {
                //console.log(propName, E.message);
            }
        }
    };

    var logXHR = function()
    {
        var row = Firebug.Console.log(spy, null, "spy", Firebug.Spy.XHR);

        if (row)
        {
            setClass(row, "loading");
            spy.logRow = row;
        }
    };

    var finishXHR = function()
    {
        var duration = new Date().getTime() - reqStartTS;
        var success = xhrRequest.status == 200;

        var responseHeadersText = xhrRequest.getAllResponseHeaders();
        var responses = responseHeadersText ? responseHeadersText.split(/[\n\r]/) : [];
        var reHeader = /^(\S+):\s*(.*)/;

        for (var i=0, l=responses.length; i<l; i++)
        {
            var text = responses[i];
            var match = text.match(reHeader);

            if (match)
            {
                var name = match[1];
                var value = match[2];

                // update the spy mimeType property so we can detect when to show
                // custom response viewers (such as HTML, XML or JSON viewer)
                if (name == "Content-Type")
                    spy.mimeType = value;

                /*
                if (name == "Last Modified")
                {
                    if (!spy.cacheEntry)
                        spy.cacheEntry = [];

                    spy.cacheEntry.push({
                       name: [name],
                       value: [value]
                    });
                }
                /**/

                spy.responseHeaders.push({
                   name: [name],
                   value: [value]
                });
            }
        }

        with({
            row: spy.logRow,
            status: xhrRequest.status + " " + xhrRequest.statusText,
            time: duration,
            success: success
        })
        {
            setTimeout(function(){

                spy.responseText = xhrRequest.responseText;

                // update row information to avoid "ethernal spinning gif" bug in IE
                row = row || spy.logRow;

                // if chrome document is not loaded, there will be no row yet, so just ignore
                if (!row) return;

                // update the XHR representation data
                handleRequestStatus(success, status, time);

            },200);
        }

        spy.loaded = true;
        /*
        // commented because they are being updated by the updateSelfProperties() function
        self.status = xhrRequest.status;
        self.statusText = xhrRequest.statusText;
        self.responseText = xhrRequest.responseText;
        self.responseXML = xhrRequest.responseXML;
        /**/
        updateSelfProperties();
    };

    var handleStateChange = function()
    {
        //Firebug.Console.log("onreadystatechange");

        self.readyState = xhrRequest.readyState;

        if (xhrRequest.readyState == 4)
        {
            finishXHR();

            xhrRequest.onreadystatechange = function(){};
        }

        //Firebug.Console.log(spy.url + ": " + xhrRequest.readyState);

        self.onreadystatechange();
    };

    // update the XHR representation data
    var handleRequestStatus = function(success, status, time)
    {
        var row = spy.logRow;
        FBL.removeClass(row, "loading");

        if (!success)
            FBL.setClass(row, "error");

        var item = FBL.$$(".spyStatus", row)[0];
        item.innerHTML = status;

        if (time)
        {
            var item = FBL.$$(".spyTime", row)[0];
            item.innerHTML = time + "ms";
        }
    };

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper public properties and handlers

    this.readyState = 0;

    this.onreadystatechange = function(){};

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // XMLHttpRequestWrapper public methods

    this.open = function(method, url, async, user, password)
    {
        //Firebug.Console.log("xhrRequest open");

        updateSelfProperties();

        if (spy.loaded)
            spy = new XHRSpy();

        spy.method = method;
        spy.url = url;
        spy.async = async;
        spy.href = url;
        spy.xhrRequest = xhrRequest;
        spy.urlParams = parseURLParamsArray(url);

        if (!FBL.isIE && async)
            xhrRequest.onreadystatechange = handleStateChange;

        // xhr.open.apply not available in IE
        if (typeof xhrRequest.open.apply != "undefined")
            xhrRequest.open.apply(xhrRequest, arguments)
        else
            xhrRequest.open(method, url, async, user, password);

        if (FBL.isIE && async)
            xhrRequest.onreadystatechange = handleStateChange;

    };

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

    this.send = function(data)
    {
        //Firebug.Console.log("xhrRequest send");

        spy.data = data;

        reqStartTS = new Date().getTime();

        updateXHRProperties();

        try
        {
            xhrRequest.send(data);
        }
        catch(e)
        {
            throw e;
        }
        finally
        {
            logXHR();

            if (!spy.async)
            {
                self.readyState = xhrRequest.readyState;

                finishXHR();
            }
        }
    };

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

    this.setRequestHeader = function(header, value)
    {
        spy.requestHeaders.push({name: [header], value: [value]});
        return xhrRequest.setRequestHeader(header, value);
    };

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

    this.abort = function()
    {
        xhrRequest.abort();
        updateSelfProperties();
        handleRequestStatus(false, "Aborted");
    };

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    /*
    this.getResponseHeader = function(header)
    {
        return xhrRequest.getResponseHeader(header);
    };

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

    this.getAllResponseHeaders = function()
    {
        return xhrRequest.getAllResponseHeaders();
    };

    /**/
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Clone XHR object

    var supportsApply = xhrRequest &&
            xhrRequest.open &&
            typeof xhrRequest.open.apply != "undefined";

    for (var propName in xhrRequest)
    {
        if (propName in updateSelfPropertiesIgnore)
            continue;

        try
        {
            var propValue = xhrRequest[propName];

            if (isFunction(propValue))
            {
                if (typeof self[propName] == "undefined")
                {
                    this[propName] = (function(name, xhr){

                        return supportsApply ?
                            // if the browser supports apply
                            function()
                            {
                                return xhr[name].apply(xhr, arguments)
                            }
                            :
                            function(a,b,c,d,e)
                            {
                                return xhr[name](a,b,c,d,e)
                            };

                    })(propName, xhrRequest);
                }
            }
            else
                this[propName] = propValue;
        }
        catch(E)
        {
            //console.log(propName, E.message);
        }
    }
    /**/

    return this;
};

// ************************************************************************************************
// ActiveXObject Wrapper (IE6 only)

var _ActiveXObject;
var isIE6 =  /msie 6/i.test(navigator.appVersion);

if (isIE6)
{
    window._ActiveXObject = window.ActiveXObject;

    var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP ";

    window.ActiveXObject = function(name)
    {
        var error = null;

        try
        {
            var activeXObject = new window._ActiveXObject(name);
        }
        catch(e)
        {
            error = e;
        }
        finally
        {
            if (!error)
            {
                if (xhrObjects.indexOf(" " + name + " ") != -1)
                    return new XMLHttpRequestWrapper(activeXObject);
                else
                    return activeXObject;
            }
            else
                throw error.message;
        }
    };
}

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

// Register the XMLHttpRequestWrapper for non-IE6 browsers
if (!isIE6)
{
    var _XMLHttpRequest = XMLHttpRequest;
    window.XMLHttpRequest = function()
    {
        return new XMLHttpRequestWrapper();
    }
}

// ************************************************************************************************
}})();
<|endoftext|>


<commit_before>// @flow

import React from 'react'
import {ScrollView, View, Text, StyleSheet} from 'react-native'
import {openUrl} from '@frogpond/open-url'
import {callPhone} from '../../components/call-phone'
import {sendEmail} from '../../components/send-email'
import * as c from '@frogpond/colors'
import type {DirectoryItem} from './types'
import {
	Avatar,
	Title,
	Subheading,
	Chip,
	FAB,
	List,
	Portal,
} from 'react-native-paper'
import type {TopLevelViewPropsTypeWithParams} from '../types'

type Props = TopLevelViewPropsTypeWithParams<{contact: DirectoryItem}>

export function DirectoryDetailView(props: Props) {
	const {
		displayName,
		campusLocations,
		displayTitle,
		photo,
		officeHours,
		profileUrl,
		email,
		departments,
		username,
	} = props.navigation.state.params.contact

	let [fabOpen, setFabOpen] = React.useState(false)

	let fabActions = [
		...campusLocations.map(loc => ({
			icon: 'phone',
			label:
				campusLocations.length === 1
					? 'Call'
					: `Call ${loc.buildingabbr} ${loc.room}`,
			onPress: () => callPhone(loc.phone),
		})),
		...(email
			? [
					{
						icon: 'email',
						label: 'Email',
						onPress: () => sendEmail({to: [email], subject: '', body: ''}),
					},
			  ]
			: []),
	]

	let showFab = fabActions.length >= 1

	return (
		<>
			{showFab ? (
				<Portal>
					<FAB.Group
						actions={fabActions}
						icon={fabOpen ? 'close' : 'more-vert'}
						onStateChange={({open}) => setFabOpen(open)}
						open={fabOpen}
					/>
				</Portal>
			) : null}

			<ScrollView contentContainerStyle={showFab ? styles.fabbedContainer : {}}>
				<Avatar.Image size={96} source={{uri: photo}} style={styles.image} />

				<Title style={[styles.header, styles.headerName]}>{displayName}</Title>

				<Subheading style={[styles.header, styles.headerTitle]}>
					{displayTitle}
				</Subheading>

				<View style={styles.departments}>
					{departments.map((dept, key) => (
						<Chip
							key={key}
							accessibilityLabel={`Department: ${dept.name}`}
							icon="group"
							onPress={() => openUrl(dept.href)}
							style={styles.departmentChip}
						>
							{dept.name}
						</Chip>
					))}
				</View>

				{officeHours ? (
					<List.Item
						description={officeHours}
						left={props => <List.Icon {...props} icon="sentiment-satisfied" />}
						title="Office Hours"
					/>
				) : null}

				{email ? (
					<List.Item
						description={email}
						left={props => <List.Icon {...props} icon="email" />}
						onPress={() => sendEmail({to: [email], subject: '', body: ''})}
						title="Email"
					/>
				) : null}

				{campusLocations.map((loc, i) => {
					let shortRoom = `${loc.buildingabbr} ${loc.room}`.trim()
					return (
						<List.Item
							key={i}
							description={`${shortRoom ? `${shortRoom} • ` : ''}${loc.phone}`}
							left={props => <List.Icon {...props} icon="room" />}
							onPress={() => callPhone(loc.phone)}
							right={props => <List.Icon {...props} icon="phone" />}
							title={loc.display}
						/>
					)
				})}

				{profileUrl ? (
					<List.Item
						description={profileUrl}
						left={props => <List.Icon {...props} icon="link" />}
						onPress={() => openUrl(profileUrl)}
						title="Professional Profile"
					/>
				) : null}

				{username ? (
					<List.Item
						left={props => <List.Icon {...props} icon="open-in-new" />}
						onPress={() =>
							openUrl(
								`https://www.stolaf.edu/directory/search?lookup=${username}`,
							)
						}
						title="View on the St. Olaf Directory"
					/>
				) : null}

				<Text selectable={true} style={[styles.footer, styles.poweredBy]}>
					Powered by the St. Olaf Directory
				</Text>
			</ScrollView>
		</>
	)
}
DirectoryDetailView.navigationOptions = {
	title: 'Contact',
}

const styles = StyleSheet.create({
	image: {
		alignSelf: 'center',
		marginTop: 10,
	},
	departments: {
		flexDirection: 'row',
		justifyContent: 'center',
	},
	departmentChip: {
		margin: 2,
	},
	fabbedContainer: {
		paddingBottom: 50,
	},
	header: {
		justifyContent: 'center',
		textAlign: 'center',
		marginHorizontal: 30,
	},
	headerName: {
		marginTop: 10,
		fontSize: 22,
		fontWeight: 'bold',
	},
	headerTitle: {
		marginBottom: 10,
		fontSize: 14,
	},
	footer: {
		fontSize: 10,
		color: c.iosDisabledText,
		textAlign: 'center',
	},
	poweredBy: {
		paddingBottom: 20,
	},
})
<commit_msg>fix wrapping departments on android<commit_after>// @flow

import React from 'react'
import {ScrollView, View, Text, StyleSheet} from 'react-native'
import {openUrl} from '@frogpond/open-url'
import {callPhone} from '../../components/call-phone'
import {sendEmail} from '../../components/send-email'
import * as c from '@frogpond/colors'
import type {DirectoryItem} from './types'
import {
	Avatar,
	Title,
	Subheading,
	Chip,
	FAB,
	List,
	Portal,
} from 'react-native-paper'
import type {TopLevelViewPropsTypeWithParams} from '../types'

type Props = TopLevelViewPropsTypeWithParams<{contact: DirectoryItem}>

export function DirectoryDetailView(props: Props) {
	const {
		displayName,
		campusLocations,
		displayTitle,
		photo,
		officeHours,
		profileUrl,
		email,
		departments,
		username,
	} = props.navigation.state.params.contact

	let [fabOpen, setFabOpen] = React.useState(false)

	let fabActions = [
		...campusLocations.map(loc => ({
			icon: 'phone',
			label:
				campusLocations.length === 1
					? 'Call'
					: `Call ${loc.buildingabbr} ${loc.room}`,
			onPress: () => callPhone(loc.phone),
		})),
		...(email
			? [
					{
						icon: 'email',
						label: 'Email',
						onPress: () => sendEmail({to: [email], subject: '', body: ''}),
					},
			  ]
			: []),
	]

	let showFab = fabActions.length >= 1

	return (
		<>
			{showFab ? (
				<Portal>
					<FAB.Group
						actions={fabActions}
						icon={fabOpen ? 'close' : 'more-vert'}
						onStateChange={({open}) => setFabOpen(open)}
						open={fabOpen}
					/>
				</Portal>
			) : null}

			<ScrollView contentContainerStyle={showFab ? styles.fabbedContainer : {}}>
				<Avatar.Image size={96} source={{uri: photo}} style={styles.image} />

				<Title style={[styles.header, styles.headerName]}>{displayName}</Title>

				<Subheading style={[styles.header, styles.headerTitle]}>
					{displayTitle}
				</Subheading>

				<View style={styles.departments}>
					{departments.map((dept, key) => (
						<Chip
							key={key}
							accessibilityLabel={`Department: ${dept.name}`}
							icon="group"
							onPress={() => openUrl(dept.href)}
							style={styles.departmentChip}
						>
							{dept.name}
						</Chip>
					))}
				</View>

				{officeHours ? (
					<List.Item
						description={officeHours}
						left={props => <List.Icon {...props} icon="sentiment-satisfied" />}
						title="Office Hours"
					/>
				) : null}

				{email ? (
					<List.Item
						description={email}
						left={props => <List.Icon {...props} icon="email" />}
						onPress={() => sendEmail({to: [email], subject: '', body: ''})}
						title="Email"
					/>
				) : null}

				{campusLocations.map((loc, i) => {
					let shortRoom = `${loc.buildingabbr} ${loc.room}`.trim()
					return (
						<List.Item
							key={i}
							description={`${shortRoom ? `${shortRoom} • ` : ''}${loc.phone}`}
							left={props => <List.Icon {...props} icon="room" />}
							onPress={() => callPhone(loc.phone)}
							right={props => <List.Icon {...props} icon="phone" />}
							title={loc.display}
						/>
					)
				})}

				{profileUrl ? (
					<List.Item
						description={profileUrl}
						left={props => <List.Icon {...props} icon="link" />}
						onPress={() => openUrl(profileUrl)}
						title="Professional Profile"
					/>
				) : null}

				{username ? (
					<List.Item
						left={props => <List.Icon {...props} icon="open-in-new" />}
						onPress={() =>
							openUrl(
								`https://www.stolaf.edu/directory/search?lookup=${username}`,
							)
						}
						title="View on the St. Olaf Directory"
					/>
				) : null}

				<Text selectable={true} style={[styles.footer, styles.poweredBy]}>
					Powered by the St. Olaf Directory
				</Text>
			</ScrollView>
		</>
	)
}
DirectoryDetailView.navigationOptions = {
	title: 'Contact',
}

const styles = StyleSheet.create({
	image: {
		alignSelf: 'center',
		marginTop: 10,
	},
	departments: {
		flexDirection: 'row',
		justifyContent: 'center',
		flexWrap: 'wrap',
	},
	departmentChip: {
		margin: 2,
	},
	fabbedContainer: {
		paddingBottom: 50,
	},
	header: {
		justifyContent: 'center',
		textAlign: 'center',
		marginHorizontal: 30,
	},
	headerName: {
		marginTop: 10,
		fontSize: 22,
		fontWeight: 'bold',
	},
	headerTitle: {
		marginBottom: 10,
		fontSize: 14,
	},
	footer: {
		fontSize: 10,
		color: c.iosDisabledText,
		textAlign: 'center',
	},
	poweredBy: {
		paddingBottom: 20,
	},
})
<|endoftext|>


<commit_before>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2013 Sebastian Werner
==================================================================================================
*/

core.Class("core.mvc.presenter.Abstract",
{
  include: [core.property.MGeneric, core.event.MEventTarget, core.util.MLogging],

  /**
   * @parent {core.mvc.presenter.Abstract} Parent presenter to attach to this presenter
   */
  construct : function(parent)
  {

    // Keep reference to parent presenter
    this.__parent = parent;
  },

  members :
  {
    /**
     * {core.mvc.presenter.Abstract} Returns the parent presenter.
     */
    getParent : function() {
      return this.__parent;
    }

  }
});
<commit_msg>Added event parent support for presenter<commit_after>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2013 Sebastian Werner
==================================================================================================
*/

core.Class("core.mvc.presenter.Abstract",
{
  include: [core.property.MGeneric, core.event.MEventTarget, core.util.MLogging],

  /**
   * @parent {core.mvc.presenter.Abstract} Parent presenter to attach to this presenter
   */
  construct : function(parent)
  {

    // Keep reference to parent presenter
    this.__parent = parent;
  },

  members :
  {
    /**
     * {core.mvc.presenter.Abstract} Returns the parent presenter.
     */
    getParent : function() {
      return this.__parent;
    },

    /**
     * {core.mvc.presenter.Abstract} Returns the event parent - which is our parent presenter.
     */
    getEventParent : function() {
      return this.__parent;
    }
  }
});
<|endoftext|>