<commit_before>FileActions={
	actions:{},
	defaults:{},
	icons:{},
	currentFile:null,
	register:function(mime,name,icon,action){
		if(!FileActions.actions[mime]){
			FileActions.actions[mime]={};
		}
		FileActions.actions[mime][name]=action;
		FileActions.icons[name]=icon;
	},
	setDefault:function(mime,name){
		FileActions.defaults[mime]=name;
	},
	get:function(mime,type){
		var actions={};
		if(FileActions.actions.all){
			actions=$.extend( actions, FileActions.actions.all )
		}
		if(mime){
			if(FileActions.actions[mime]){
				actions=$.extend( actions, FileActions.actions[mime] )
			}
			var mimePart=mime.substr(0,mime.indexOf('/'));
			if(FileActions.actions[mimePart]){
				actions=$.extend( actions, FileActions.actions[mimePart] )
			}
		}
		if(type){//type is 'dir' or 'file'
			if(FileActions.actions[type]){
				actions=$.extend( actions, FileActions.actions[type] )
			}
		}
		return actions;
	},
	getDefault:function(mime,type){
		if(mime){
			var mimePart=mime.substr(0,mime.indexOf('/'));
		}
		var name=false;
		if(mime && FileActions.defaults[mime]){
			name=FileActions.defaults[mime];
		}else if(mime && FileActions.defaults[mimePart]){
			name=FileActions.defaults[mimePart];
		}else if(type && FileActions.defaults[type]){
			name=FileActions.defaults[type];
		}else{
			name=FileActions.defaults.all;
		}
		var actions=this.get(mime,type);
		return actions[name];
	},
	display:function(parent, filename, type){
		FileActions.currentFile=parent;
		$('#fileList span.fileactions, #fileList td.date a.action').remove();
		var actions=FileActions.get(FileActions.getCurrentMimeType(),FileActions.getCurrentType());
		var file=FileActions.getCurrentFile();
		if($('tr').filterAttr('data-file',file).data('renaming')){
			return;
		}
		parent.children('a.name').append('');
		var defaultAction=FileActions.getDefault(FileActions.getCurrentMimeType(),FileActions.getCurrentType());
		for(name in actions){
			// no rename and share action for the 'Shared' dir
			if((name=='Rename' || name =='Share') && type=='dir' && filename=='Shared') { continue; }
			if((name=='Download' || actions[name]!=defaultAction) && name!='Delete'){
				var img=FileActions.icons[name];
				if(img.call){
					img=img(file);
				}
				var html='';
				if(img) { html+=' '; }
				html += name+'';
				var element=$(html);
				element.data('action',name);
				element.click(function(event){
					event.stopPropagation();
					event.preventDefault();
					var action=actions[$(this).data('action')];
					var currentFile=FileActions.getCurrentFile();
					FileActions.hide();
					action(currentFile);
				});
				element.hide();
				parent.find('a.name>span.fileactions').append(element);
			}
		}
		if(actions['Delete'] && (type!='dir' || filename != 'Shared')){ // no delete action for the 'Shared' dir
			var img=FileActions.icons['Delete'];
			if(img.call){
				img=img(file);
			}
			var html='';
			var element=$(html);
			if(img){
				element.append($(''));
			}
			element.data('action','Delete');
			element.click(function(event){
				event.stopPropagation();
				event.preventDefault();
				var action=actions[$(this).data('action')];
				var currentFile=FileActions.getCurrentFile();
				FileActions.hide();
				action(currentFile);
			});
			element.hide();
			parent.parent().children().last().append(element);
		}
		$('#fileList .action').css('-o-transition-property','none');//temporarly disable
		$('#fileList .action').fadeIn(200,function(){
			$('#fileList .action').css('-o-transition-property','opacity');
		});
		return false;
	},
	hide:function(){
		$('#fileList span.fileactions, #fileList td.date a.action').fadeOut(200,function(){
			$(this).remove();
		});
	},
	getCurrentFile:function(){
		return FileActions.currentFile.parent().attr('data-file');
	},
	getCurrentMimeType:function(){
		return FileActions.currentFile.parent().attr('data-mime');
	},
	getCurrentType:function(){
		return FileActions.currentFile.parent().attr('data-type');
	}
}

$(document).ready(function(){
	if($('#allowZipDownload').val() == 1){
		var downloadScope = 'all';
	} else {
		var downloadScope = 'file';
	}
	FileActions.register(downloadScope,'Download',function(){return OC.imagePath('core','actions/download')},function(filename){
		window.location=OC.filePath('files', 'ajax', 'download.php') + '?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val());
	});
});

FileActions.register('all','Delete',function(){return OC.imagePath('core','actions/delete')},function(filename){
	if(Files.cancelUpload(filename)) {
		if(filename.substr){
			filename=[filename];
		}
		$.each(filename,function(index,file){
			var filename = $('tr').filterAttr('data-file',file);
			filename.hide();
			filename.find('input[type="checkbox"]').removeAttr('checked');
			filename.removeClass('selected');
		});
		procesSelection();
	}else{
		FileList.do_delete(filename);
	}
});

FileActions.register('all','Rename',function(){return OC.imagePath('core','actions/rename')},function(filename){
	FileList.rename(filename);
});

FileActions.register('dir','Open','',function(filename){
	window.location=OC.linkTo('files', 'index.php') + '&dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});

FileActions.setDefault('dir','Open');
<commit_msg>committed patch (bug #967) to add missing translations for file actions<commit_after>FileActions={
	actions:{},
	defaults:{},
	icons:{},
	currentFile:null,
	register:function(mime,name,icon,action){
		if(!FileActions.actions[mime]){
			FileActions.actions[mime]={};
		}
		FileActions.actions[mime][name]=action;
		FileActions.icons[name]=icon;
	},
	setDefault:function(mime,name){
		FileActions.defaults[mime]=name;
	},
	get:function(mime,type){
		var actions={};
		if(FileActions.actions.all){
			actions=$.extend( actions, FileActions.actions.all )
		}
		if(mime){
			if(FileActions.actions[mime]){
				actions=$.extend( actions, FileActions.actions[mime] )
			}
			var mimePart=mime.substr(0,mime.indexOf('/'));
			if(FileActions.actions[mimePart]){
				actions=$.extend( actions, FileActions.actions[mimePart] )
			}
		}
		if(type){//type is 'dir' or 'file'
			if(FileActions.actions[type]){
				actions=$.extend( actions, FileActions.actions[type] )
			}
		}
		return actions;
	},
	getDefault:function(mime,type){
		if(mime){
			var mimePart=mime.substr(0,mime.indexOf('/'));
		}
		var name=false;
		if(mime && FileActions.defaults[mime]){
			name=FileActions.defaults[mime];
		}else if(mime && FileActions.defaults[mimePart]){
			name=FileActions.defaults[mimePart];
		}else if(type && FileActions.defaults[type]){
			name=FileActions.defaults[type];
		}else{
			name=FileActions.defaults.all;
		}
		var actions=this.get(mime,type);
		return actions[name];
	},
	display:function(parent, filename, type){
		FileActions.currentFile=parent;
		$('#fileList span.fileactions, #fileList td.date a.action').remove();
		var actions=FileActions.get(FileActions.getCurrentMimeType(),FileActions.getCurrentType());
		var file=FileActions.getCurrentFile();
		if($('tr').filterAttr('data-file',file).data('renaming')){
			return;
		}
		parent.children('a.name').append('');
		var defaultAction=FileActions.getDefault(FileActions.getCurrentMimeType(),FileActions.getCurrentType());
		for(name in actions){
			// no rename and share action for the 'Shared' dir
			if((name=='Rename' || name =='Share') && type=='dir' && filename=='Shared') { continue; }
			if((name=='Download' || actions[name]!=defaultAction) && name!='Delete'){
				var img=FileActions.icons[name];
				if(img.call){
					img=img(file);
				}
				var html='';
				if(img) { html+=' '; }
				html += t('files', name) +'';
				var element=$(html);
				element.data('action',name);
				element.click(function(event){
					event.stopPropagation();
					event.preventDefault();
					var action=actions[$(this).data('action')];
					var currentFile=FileActions.getCurrentFile();
					FileActions.hide();
					action(currentFile);
				});
				element.hide();
				parent.find('a.name>span.fileactions').append(element);
			}
		}
		if(actions['Delete'] && (type!='dir' || filename != 'Shared')){ // no delete action for the 'Shared' dir
			var img=FileActions.icons['Delete'];
			if(img.call){
				img=img(file);
			}
			var html='';
			var element=$(html);
			if(img){
				element.append($(''));
			}
			element.data('action','Delete');
			element.click(function(event){
				event.stopPropagation();
				event.preventDefault();
				var action=actions[$(this).data('action')];
				var currentFile=FileActions.getCurrentFile();
				FileActions.hide();
				action(currentFile);
			});
			element.hide();
			parent.parent().children().last().append(element);
		}
		$('#fileList .action').css('-o-transition-property','none');//temporarly disable
		$('#fileList .action').fadeIn(200,function(){
			$('#fileList .action').css('-o-transition-property','opacity');
		});
		return false;
	},
	hide:function(){
		$('#fileList span.fileactions, #fileList td.date a.action').fadeOut(200,function(){
			$(this).remove();
		});
	},
	getCurrentFile:function(){
		return FileActions.currentFile.parent().attr('data-file');
	},
	getCurrentMimeType:function(){
		return FileActions.currentFile.parent().attr('data-mime');
	},
	getCurrentType:function(){
		return FileActions.currentFile.parent().attr('data-type');
	}
}

$(document).ready(function(){
	if($('#allowZipDownload').val() == 1){
		var downloadScope = 'all';
	} else {
		var downloadScope = 'file';
	}
	FileActions.register(downloadScope,'Download',function(){return OC.imagePath('core','actions/download')},function(filename){
		window.location=OC.filePath('files', 'ajax', 'download.php') + '?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val());
	});
});

FileActions.register('all','Delete',function(){return OC.imagePath('core','actions/delete')},function(filename){
	if(Files.cancelUpload(filename)) {
		if(filename.substr){
			filename=[filename];
		}
		$.each(filename,function(index,file){
			var filename = $('tr').filterAttr('data-file',file);
			filename.hide();
			filename.find('input[type="checkbox"]').removeAttr('checked');
			filename.removeClass('selected');
		});
		procesSelection();
	}else{
		FileList.do_delete(filename);
	}
});

FileActions.register('all','Rename',function(){return OC.imagePath('core','actions/rename')},function(filename){
	FileList.rename(filename);
});

FileActions.register('dir','Open','',function(filename){
	window.location=OC.linkTo('files', 'index.php') + '&dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});

FileActions.setDefault('dir','Open');
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   MySystem.NodeView
// Copyright: @2011 Concord Consortium
// ==========================================================================
/*globals MySystem RaphaelViews */

sc_require('views/editable_label');
sc_require('views/terminal');
sc_require('views/remove_button');
sc_require('mixins/arrow_drawing');

/** @class

  Display class for displaying a Link. Expects its 'content' property to be a MySystem.Link record.

  @extends SC.View
*/
MySystem.LinkView = RaphaelViews.RaphaelView.extend(SC.ContentDisplay,
/** @scope MySystem.LinkView.prototype */ {

  displayProperties: 'content.endNode.x content.endNode.y content.startNode.x content.startNode.y lineColor borderColor borderOpacity lineWidth borderWidth'.w(),

  childViews: 'removeButtonView'.w(),

  // PROPERTIES
  lineColorBinding: '*content.color',
  borderColor: '#ADD8E6',

  borderOpacity: function () {
    return this.get('isSelected') ? 1.0 : 0;
  }.property('isSelected'),

  lineWidth: 6,
  borderWidth: 3,

  isHovered: NO,
  showRemoveButtonForHover: NO,
  unhoverInterval: 500,
  _unhoverTimer: null,

  isHoveredDidChange: function () {
    if (this._unhoverTimer) this._unhoverTimer.invalidate();

    if (this.get('isHovered')) {
      this.set('showRemoveButtonForHover', YES);
    }
    else {
      this._unhoverTimer = SC.Timer.schedule({
        target: this,
        action: 'unhoverTimeout',
        interval: this.get('unhoverInterval')
      });
    }
  }.observes('isHovered'),

  unhoverTimeout: function () {
    this.set('showRemoveButtonForHover', NO);
  },

  diagramControllerBinding: 'MySystem.nodesController',
  onlySelectedDiagramObjectBinding: '*diagramController.onlySelectedObject',

  isOnlySelectedDiagramObject: function () {
    return this.get('onlySelectedDiagramObject') === this.get('content');
  }.property('onlySelectedDiagramObject', 'content'),

  isRemoveButtonOccluded: NO,

  isRemoveButtonVisible: function () {
    return (this.get('showRemoveButtonForHover') || this.get('isOnlySelectedDiagramObject')) && !this.get('isRemoveButtonOccluded');
  }.property('showRemoveButtonForHover', 'isOnlySelectedDiagramObject', 'isRemoveButtonOccluded'),

  removeButtonX: 0,
  removeButtonY: 0,

  removeButtonView: MySystem.RemoveButtonView.design({
    isVisibleBinding: '.parentView.isRemoveButtonVisible',
    normalCircleStrokeBinding: '.parentView.lineColor',
    normalXStrokeBinding: '.parentView.lineColor',
    cxBinding: '.parentView.removeButtonX',
    cyBinding: '.parentView.removeButtonY'
  }),

  // RENDER METHODS
  renderCallback: function (raphaelCanvas, lineAttrs, headAttrs, borderAttrs, borderAttrs2) {
    var tail    = raphaelCanvas.path().attr(lineAttrs),
        head    = raphaelCanvas.path().attr(headAttrs),
        border  = raphaelCanvas.path().attr(borderAttrs),
        border2 = raphaelCanvas.path().attr(borderAttrs2),
        label   = raphaelCanvas.text().attr(this._getLabelAttrs(tail)),
        labelBg = raphaelCanvas.rect().attr(this._getLabelBackgroundAttrs(raphaelCanvas, label)),

        ret     = raphaelCanvas.set().push(
          border,
          border2,
          tail,
          head,
          labelBg,
          label.toFront()
        );

    this._setRemoveButtonLocation(ret);
    return ret;
  },

  render: function (context, firstTime) {
    var content   = this.get('content'),
        startNode = content.get('startNode'),
        endNode   = content.get('endNode'),
        startX    = 0,
        startY    = 0,
        endX      = 0,
        endY      = 0;

        if (!!startNode) {
          startX = startNode.get('x');
          startY = startNode.get('y');
        }

        if (!!endNode) {
          endX = endNode.get('x');
          endY = endNode.get('y');
        }

        var startingAtTop = (content.get('startTerminal') === 'a'),
            endingAtTop   = (content.get('endTerminal') === 'a');

        if (startingAtTop) {
          startX = startX + 50;
          startY = startY;
        } else {
          startX = startX + 50;
          startY = startY + 110;
        }
        if (endingAtTop) {
          endX = endX + 50;
          endY = endY;
        } else {
          endX = endX + 50;
          endY = endY + 110;
        }

        var pathStr   = MySystem.ArrowDrawing.arrowPath(startX,startY,endX,endY,startingAtTop,endingAtTop);
        var lineColor = this.get('lineColor') || "#000099";

        var borderAttrs = {
          'path':           pathStr.tail + pathStr.head,
          'stroke':         this.get('borderColor'),
          'opacity':        this.get('borderOpacity'),
          'stroke-width':   this.get('lineWidth') + 2 + 2 * this.get('borderWidth'),  // the border "around" the line is really a fat line behind it
          'stroke-linecap': 'round'
        },

        borderAttrs2 = {    // a white line of separation between the arrow and the border
          'path':           pathStr.tail + pathStr.head,
          'stroke':         '#FFFFFF',
          'opacity':        this.get('borderOpacity'),
          'stroke-width':   this.get('lineWidth') + 3,
          'stroke-linecap': 'round'
        },

        lineAttrs = {
          'path':           pathStr.tail,
          'stroke':         lineColor,
          'stroke-width':   this.get('lineWidth'),
          'stroke-linecap': 'round'
        },

        headAttrs = {
          'path':           pathStr.head,
          'stroke':         lineColor,
          'fill':           lineColor,
          'stroke-width':   this.get('lineWidth'),
          'stroke-linecap': 'round'
        },

        raphaelObject,
        border,
        border2,
        head,
        line,
        labelBg,
        label;

    if (firstTime) {
      context.callback(this, this.renderCallback, lineAttrs, headAttrs, borderAttrs, borderAttrs2);
      this.renderChildViews(context, firstTime);
    }
    else {
      raphaelObject = this.get('raphaelObject');
      border        = raphaelObject.items[0];
      border2       = raphaelObject.items[1];
      line          = raphaelObject.items[2];
      head          = raphaelObject.items[3];
      labelBg       = raphaelObject.items[4];
      label         = raphaelObject.items[5];

      border.attr(borderAttrs);
      border2.attr(borderAttrs2);
      line.attr(lineAttrs);
      head.attr(headAttrs);
      label.attr(this._getLabelAttrs(line));
      labelBg.attr(this._getLabelBackgroundAttrs(this, label));

      labelBg.toFront();
      label.toFront();

      this._setRemoveButtonLocation(raphaelObject);
    }
  },

  _getLabelAttrs: function(path) {
    if (path.getTotalLength() < 1) return {};

    var center = path.getPointAtLength(path.getTotalLength() * (2/3));
    var text = this.get('content').get('text');

    return {
      'x':              center.x,
      'y':              center.y,
      'fill':           'black',
      'text':           !!text ? text : ""
    };
  },

  _getLabelBackgroundAttrs: function(canvas, label) {
    var bb = label.getBBox();
    if (bb.height === 0){
      return {};
    }
    var hpad = 10;
    var vpad = 6;
    return {
      'x':              bb.x - hpad/2,
      'y':              bb.y - vpad/2,
      'width':          bb.width + hpad,
      'height':         bb.height + vpad + 1, // offset just a little more on the bottom so the text looks visually centered
      'r':              5,
      'fill':           'white',
      'stroke':         '#444444',
      'stroke-width':   1,
      'stroke-opacity': 0.5
    };
  },

  _setRemoveButtonLocation: function (raphaelObject) {
    var line = raphaelObject.items[2],
        distanceAlongLine   = 35,
        distanceAlongNormal = 18,
        len, p1, p2, scale, dx, dy, x, y, occluded;

    if (line.attr('path').length < 1) return;     // this can happen after our content is destroyed

    len = line.getTotalLength();
    p2  = line.getPointAtLength(len);

    if (len > 50) {
      p1 = line.getPointAtLength(len - distanceAlongLine);

      dx = p2.x - p1.x;
      dy = p2.y - p1.y;
      scale = distanceAlongNormal / distanceAlongLine * (dx > 0 ? 1 : -1);

      x = p1.x + scale * dy;
      y = p1.y - scale * dx;
      occluded = NO;
    }
    else {
      x = 0;
      y = 0;
      occluded = YES;
    }

    this.set('removeButtonX', x);
    this.set('removeButtonY', y);
    this.set('isRemoveButtonOccluded', occluded);
  },

  mouseEntered: function () {
    this.set('isHovered', YES);
    return YES;
  },

  mouseExited: function () {
    this.set('isHovered', NO);
    return YES;
  },

  removeButtonClicked: function () {
    MySystem.statechart.sendAction('deleteDiagramObject', this, this.get('content'));
  }

});

<commit_msg>Make border around selected links slightly fatter<commit_after>// ==========================================================================
// Project:   MySystem.NodeView
// Copyright: @2011 Concord Consortium
// ==========================================================================
/*globals MySystem RaphaelViews */

sc_require('views/editable_label');
sc_require('views/terminal');
sc_require('views/remove_button');
sc_require('mixins/arrow_drawing');

/** @class

  Display class for displaying a Link. Expects its 'content' property to be a MySystem.Link record.

  @extends SC.View
*/
MySystem.LinkView = RaphaelViews.RaphaelView.extend(SC.ContentDisplay,
/** @scope MySystem.LinkView.prototype */ {

  displayProperties: 'content.endNode.x content.endNode.y content.startNode.x content.startNode.y lineColor borderColor borderOpacity lineWidth borderWidth'.w(),

  childViews: 'removeButtonView'.w(),

  // PROPERTIES
  lineColorBinding: '*content.color',
  borderColor: '#ADD8E6',

  borderOpacity: function () {
    return this.get('isSelected') ? 1.0 : 0;
  }.property('isSelected'),

  lineWidth: 6,
  borderWidth: 4,

  isHovered: NO,
  showRemoveButtonForHover: NO,
  unhoverInterval: 500,
  _unhoverTimer: null,

  isHoveredDidChange: function () {
    if (this._unhoverTimer) this._unhoverTimer.invalidate();

    if (this.get('isHovered')) {
      this.set('showRemoveButtonForHover', YES);
    }
    else {
      this._unhoverTimer = SC.Timer.schedule({
        target: this,
        action: 'unhoverTimeout',
        interval: this.get('unhoverInterval')
      });
    }
  }.observes('isHovered'),

  unhoverTimeout: function () {
    this.set('showRemoveButtonForHover', NO);
  },

  diagramControllerBinding: 'MySystem.nodesController',
  onlySelectedDiagramObjectBinding: '*diagramController.onlySelectedObject',

  isOnlySelectedDiagramObject: function () {
    return this.get('onlySelectedDiagramObject') === this.get('content');
  }.property('onlySelectedDiagramObject', 'content'),

  isRemoveButtonOccluded: NO,

  isRemoveButtonVisible: function () {
    return (this.get('showRemoveButtonForHover') || this.get('isOnlySelectedDiagramObject')) && !this.get('isRemoveButtonOccluded');
  }.property('showRemoveButtonForHover', 'isOnlySelectedDiagramObject', 'isRemoveButtonOccluded'),

  removeButtonX: 0,
  removeButtonY: 0,

  removeButtonView: MySystem.RemoveButtonView.design({
    isVisibleBinding: '.parentView.isRemoveButtonVisible',
    normalCircleStrokeBinding: '.parentView.lineColor',
    normalXStrokeBinding: '.parentView.lineColor',
    cxBinding: '.parentView.removeButtonX',
    cyBinding: '.parentView.removeButtonY'
  }),

  // RENDER METHODS
  renderCallback: function (raphaelCanvas, lineAttrs, headAttrs, borderAttrs, borderAttrs2) {
    var tail    = raphaelCanvas.path().attr(lineAttrs),
        head    = raphaelCanvas.path().attr(headAttrs),
        border  = raphaelCanvas.path().attr(borderAttrs),
        border2 = raphaelCanvas.path().attr(borderAttrs2),
        label   = raphaelCanvas.text().attr(this._getLabelAttrs(tail)),
        labelBg = raphaelCanvas.rect().attr(this._getLabelBackgroundAttrs(raphaelCanvas, label)),

        ret     = raphaelCanvas.set().push(
          border,
          border2,
          tail,
          head,
          labelBg,
          label.toFront()
        );

    this._setRemoveButtonLocation(ret);
    return ret;
  },

  render: function (context, firstTime) {
    var content   = this.get('content'),
        startNode = content.get('startNode'),
        endNode   = content.get('endNode'),
        startX    = 0,
        startY    = 0,
        endX      = 0,
        endY      = 0;

        if (!!startNode) {
          startX = startNode.get('x');
          startY = startNode.get('y');
        }

        if (!!endNode) {
          endX = endNode.get('x');
          endY = endNode.get('y');
        }

        var startingAtTop = (content.get('startTerminal') === 'a'),
            endingAtTop   = (content.get('endTerminal') === 'a');

        if (startingAtTop) {
          startX = startX + 50;
          startY = startY;
        } else {
          startX = startX + 50;
          startY = startY + 110;
        }
        if (endingAtTop) {
          endX = endX + 50;
          endY = endY;
        } else {
          endX = endX + 50;
          endY = endY + 110;
        }

        var pathStr   = MySystem.ArrowDrawing.arrowPath(startX,startY,endX,endY,startingAtTop,endingAtTop);
        var lineColor = this.get('lineColor') || "#000099";

        var borderAttrs = {
          'path':           pathStr.tail + pathStr.head,
          'stroke':         this.get('borderColor'),
          'opacity':        this.get('borderOpacity'),
          'stroke-width':   this.get('lineWidth') + 2 + 2 * this.get('borderWidth'),  // the border "around" the line is really a fat line behind it
          'stroke-linecap': 'round'
        },

        borderAttrs2 = {    // a white line of separation between the arrow and the border
          'path':           pathStr.tail + pathStr.head,
          'stroke':         '#FFFFFF',
          'opacity':        this.get('borderOpacity'),
          'stroke-width':   this.get('lineWidth') + 3,
          'stroke-linecap': 'round'
        },

        lineAttrs = {
          'path':           pathStr.tail,
          'stroke':         lineColor,
          'stroke-width':   this.get('lineWidth'),
          'stroke-linecap': 'round'
        },

        headAttrs = {
          'path':           pathStr.head,
          'stroke':         lineColor,
          'fill':           lineColor,
          'stroke-width':   this.get('lineWidth'),
          'stroke-linecap': 'round'
        },

        raphaelObject,
        border,
        border2,
        head,
        line,
        labelBg,
        label;

    if (firstTime) {
      context.callback(this, this.renderCallback, lineAttrs, headAttrs, borderAttrs, borderAttrs2);
      this.renderChildViews(context, firstTime);
    }
    else {
      raphaelObject = this.get('raphaelObject');
      border        = raphaelObject.items[0];
      border2       = raphaelObject.items[1];
      line          = raphaelObject.items[2];
      head          = raphaelObject.items[3];
      labelBg       = raphaelObject.items[4];
      label         = raphaelObject.items[5];

      border.attr(borderAttrs);
      border2.attr(borderAttrs2);
      line.attr(lineAttrs);
      head.attr(headAttrs);
      label.attr(this._getLabelAttrs(line));
      labelBg.attr(this._getLabelBackgroundAttrs(this, label));

      labelBg.toFront();
      label.toFront();

      this._setRemoveButtonLocation(raphaelObject);
    }
  },

  _getLabelAttrs: function(path) {
    if (path.getTotalLength() < 1) return {};

    var center = path.getPointAtLength(path.getTotalLength() * (2/3));
    var text = this.get('content').get('text');

    return {
      'x':              center.x,
      'y':              center.y,
      'fill':           'black',
      'text':           !!text ? text : ""
    };
  },

  _getLabelBackgroundAttrs: function(canvas, label) {
    var bb = label.getBBox();
    if (bb.height === 0){
      return {};
    }
    var hpad = 10;
    var vpad = 6;
    return {
      'x':              bb.x - hpad/2,
      'y':              bb.y - vpad/2,
      'width':          bb.width + hpad,
      'height':         bb.height + vpad + 1, // offset just a little more on the bottom so the text looks visually centered
      'r':              5,
      'fill':           'white',
      'stroke':         '#444444',
      'stroke-width':   1,
      'stroke-opacity': 0.5
    };
  },

  _setRemoveButtonLocation: function (raphaelObject) {
    var line = raphaelObject.items[2],
        distanceAlongLine   = 35,
        distanceAlongNormal = 18,
        len, p1, p2, scale, dx, dy, x, y, occluded;

    if (line.attr('path').length < 1) return;     // this can happen after our content is destroyed

    len = line.getTotalLength();
    p2  = line.getPointAtLength(len);

    if (len > 50) {
      p1 = line.getPointAtLength(len - distanceAlongLine);

      dx = p2.x - p1.x;
      dy = p2.y - p1.y;
      scale = distanceAlongNormal / distanceAlongLine * (dx > 0 ? 1 : -1);

      x = p1.x + scale * dy;
      y = p1.y - scale * dx;
      occluded = NO;
    }
    else {
      x = 0;
      y = 0;
      occluded = YES;
    }

    this.set('removeButtonX', x);
    this.set('removeButtonY', y);
    this.set('isRemoveButtonOccluded', occluded);
  },

  mouseEntered: function () {
    this.set('isHovered', YES);
    return YES;
  },

  mouseExited: function () {
    this.set('isHovered', NO);
    return YES;
  },

  removeButtonClicked: function () {
    MySystem.statechart.sendAction('deleteDiagramObject', this, this.get('content'));
  }

});

<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var errors = require("../errno.json");
var sendError = require('../utils').sendError;
var tokenlib = require('../tokenlib');

module.exports = function(conf, logError, storage) {
  /**
   * Middleware that validates the given token is valid (should be included into
   * the "token" parameter.
   **/
  function validateToken(req, res, next) {
    req.token = req.param('token');
    storage.getCallUrlData(req.token, function(err, urlData) {
      if (res.serverError(err)) return;
      if (urlData === null) {
        sendError(res, 404, errors.INVALID_TOKEN, "Token not found.");
        return;
      }
      req.callUrlData = urlData;
      next();
    });
  }

  /**
   * Middleware that requires the given parameters to be set.
   **/
  function requireParams() {
    var params = Array.prototype.slice.call(arguments);
    return function(req, res, next) {
      var missingParams;

      if (!req.accepts("json")) {
        sendError(res, 406, errors.BADJSON,
                  "Request body should be defined as application/json");
        return;
      }

      missingParams = params.filter(function(param) {
        return req.body[param] === undefined;
      });

      if (missingParams.length > 0) {
        sendError(res, 400, errors.MISSING_PARAMETERS,
                  "Missing: " + missingParams.join(", "));
        return;
      }
      next();
    };
  }

  /**
   * Middleware that ensures a valid simple push url is present in the request.
   **/
  function validateSimplePushURL(req, res, next) {
      if (!req.accepts("json")) {
        sendError(res, 406, errors.BADJSON,
                  "Request body should be defined as application/json");
        return;
      }

    req.simplePushURLs = req.body.simplePushURLs || {};

    var simplePushURL = req.body.simplePushURL ||
      req.query.simplePushURL ||
      req.body.simple_push_url;  // Bug 1032966 - Handle old simple_push_url format

    if (simplePushURL !== undefined) {
      req.simplePushURLs.calls = simplePushURL;
    }

    if (Object.keys(req.simplePushURLs).length !== 0) {

      for (var topic in req.simplePushURLs) {
        if (req.simplePushURLs[topic].indexOf('http') !== 0) {
          sendError(res, 400, errors.INVALID_PARAMETERS,
                    "simplePushURLs." + topic + " should be a valid url");
          return;
        }
      }
      next();
    } else {
      sendError(res, 400, errors.MISSING_PARAMETERS,
                "Missing: simplePushURLs.calls, simplePushURLs.rooms");
      return;
    }
  }

  /**
   * Middleware that ensures a valid callType is present in the request.
   **/
  function validateCallType(req, res, next) {
    requireParams("callType")(req, res, function() {
      if (req.body.callType !== "audio" &&
          req.body.callType !== "audio-video") {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "callType should be 'audio' or 'audio-video'");
        return;
      }
      next();
    });
  }

  /**
   * Validates the call url params are valid.
   *
   * In case they aren't, error out with an HTTP 400.
   * If they are valid, store them in the urlData parameter of the request.
   **/
  function validateCallUrlParams(req, res, next) {
    var expiresIn = conf.get('callUrls').timeout,
        maxTimeout = conf.get('callUrls').maxTimeout;

    if (req.body.hasOwnProperty('expiresIn')) {
      expiresIn = parseInt(req.body.expiresIn, 10);

      if (isNaN(expiresIn)) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be a valid number");
        return;
      } else if (expiresIn > maxTimeout) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be less than " + maxTimeout);
        return;
      }
    }
    if (req.token === undefined) {
      req.token = tokenlib.generateToken(conf.get('callUrls').tokenSize);
    }

    req.urlData = {
      userMac: req.user,
      callerId: req.body.callerId,
      timestamp: parseInt(Date.now() / 1000, 10),
      issuer: req.body.issuer || ''
    };

    if (expiresIn !== undefined) {
      req.urlData.expires = req.urlData.timestamp +
                            expiresIn * tokenlib.ONE_HOUR;
    }
    next();
  }

  /**
   * Validate the room url parameters passed in the body.
   **/
  function validateRoomUrlParams(req, res, next) {
    var roomsConf = conf.get('rooms');

    var expiresIn = roomsConf.defaultTTL,
        maxTTL = roomsConf.maxTTL,
        serverMaxSize = roomsConf.maxSize,
        maxSize;

    if (req.body.hasOwnProperty('roomName')) {
      if (req.body.roomName.length > roomsConf.maxRoomNameSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "roomName should be shorter than " +
                  roomsConf.maxRoomNameSize + " characters");
        return;
      }
    }

    if (req.body.hasOwnProperty('roomOwner')) {
      if (req.body.roomOwner.length > roomsConf.maxRoomOwnerSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "roomOwner should be shorter than " +
                  roomsConf.maxRoomOwnerSize + " characters");
        return;
      }
    }

    if (req.body.hasOwnProperty('expiresIn')) {
      expiresIn = parseInt(req.body.expiresIn, 10);

      if (isNaN(expiresIn)) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be a valid number");
        return;
      } else if (expiresIn > maxTTL) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn cannot be greater than " + maxTTL);
        return;
      }
    }

    if(req.body.hasOwnProperty('maxSize')) {
      maxSize = parseInt(req.body.maxSize, 10);

      if (maxSize > serverMaxSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "maxSize cannot be greater than " + serverMaxSize);
        return;
      }
    }

    req.roomRequestData = {
      roomName: req.body.roomName,
      expiresIn: expiresIn,
      roomOwner: req.body.roomOwner,
      maxSize: maxSize
    };

    next();
  }

  /**
   * Middleware that validates the given token (should be included into
   * the "token" parameter).
   **/
  function validateRoomToken(req, res, next) {
    req.token = req.param('token');
    storage.getRoomData(req.token, function(err, roomData) {
      if (res.serverError(err)) return;
      if (roomData === null) {
        sendError(res, 404, errors.INVALID_TOKEN, "Token not found.");
        return;
      }
      req.roomStorageData = roomData;
      next();
    });
  }

  function isRoomOwner(req, res, next) {
    if (req.user === req.roomStorageData.roomOwnerHmac) {
      next();
      return;
    }
    sendError(
      res, 403, errors.UNDEFINED,
      "Authenticated user is not the owner of this room."
    );
  }

  /**
   * Checks that the current user is either a room participant or a room
   * owner.
   **/
  function isRoomParticipant(req, res, next) {
    if (req.token === undefined) {
      throw new Error("req.token should be defined to use isRoomParticipant");
    }
    if (req.roomStorageData === undefined) {
      throw new Error("req.roomStorageData should be defined to use " +
                      "isRoomParticipant");
    }

    storage.getRoomParticipants(req.token, function(err, participants) {
      if (res.serverError(err)) return;

      var isParticipant = participants.some(function(p) {
        return p.hawkIdHmac === req.hawkIdHmac;
      });

      var isOwner = (req.user === req.roomStorageData.roomOwnerHmac);

      if (!isParticipant && !isOwner) {
        sendError(
          res, 403, errors.UNDEFINED,
          "Authenticated user is neither a participant of the room" +
          " nor the room owner."
        );
        return;
      }

      req.roomStorageData.participants = participants.map(function(participant) {
        delete participant.hawkIdHmac;
        return participant;
      });
      next();
    });
  }

  return {
    validateToken: validateToken,
    requireParams: requireParams,
    validateSimplePushURL: validateSimplePushURL,
    validateCallType: validateCallType,
    validateCallUrlParams: validateCallUrlParams,
    validateRoomUrlParams: validateRoomUrlParams,
    validateRoomToken: validateRoomToken,
    isRoomOwner: isRoomOwner,
    isRoomParticipant: isRoomParticipant
  };
}
<commit_msg>Update validators documentation<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var errors = require("../errno.json");
var sendError = require('../utils').sendError;
var tokenlib = require('../tokenlib');

module.exports = function(conf, logError, storage) {
  /**
   * Middleware that validates the given token is valid (should be included into
   * the "token" parameter.
   **/
  function validateToken(req, res, next) {
    req.token = req.param('token');
    storage.getCallUrlData(req.token, function(err, urlData) {
      if (res.serverError(err)) return;
      if (urlData === null) {
        sendError(res, 404, errors.INVALID_TOKEN, "Token not found.");
        return;
      }
      req.callUrlData = urlData;
      next();
    });
  }

  /**
   * Middleware that requires the given parameters to be set.
   **/
  function requireParams() {
    var params = Array.prototype.slice.call(arguments);
    return function(req, res, next) {
      var missingParams;

      if (!req.accepts("json")) {
        sendError(res, 406, errors.BADJSON,
                  "Request body should be defined as application/json");
        return;
      }

      missingParams = params.filter(function(param) {
        return req.body[param] === undefined;
      });

      if (missingParams.length > 0) {
        sendError(res, 400, errors.MISSING_PARAMETERS,
                  "Missing: " + missingParams.join(", "));
        return;
      }
      next();
    };
  }

  /**
   * Middleware that ensures a valid simple push url is present in the request.
   **/
  function validateSimplePushURL(req, res, next) {
      if (!req.accepts("json")) {
        sendError(res, 406, errors.BADJSON,
                  "Request body should be defined as application/json");
        return;
      }

    req.simplePushURLs = req.body.simplePushURLs || {};

    var simplePushURL = req.body.simplePushURL ||
      req.query.simplePushURL ||
      req.body.simple_push_url;  // Bug 1032966 - Handle old simple_push_url format

    if (simplePushURL !== undefined) {
      req.simplePushURLs.calls = simplePushURL;
    }

    if (Object.keys(req.simplePushURLs).length !== 0) {

      for (var topic in req.simplePushURLs) {
        if (req.simplePushURLs[topic].indexOf('http') !== 0) {
          sendError(res, 400, errors.INVALID_PARAMETERS,
                    "simplePushURLs." + topic + " should be a valid url");
          return;
        }
      }
      next();
    } else {
      sendError(res, 400, errors.MISSING_PARAMETERS,
                "Missing: simplePushURLs.calls, simplePushURLs.rooms");
      return;
    }
  }

  /**
   * Middleware that ensures a valid callType is present in the request.
   **/
  function validateCallType(req, res, next) {
    requireParams("callType")(req, res, function() {
      if (req.body.callType !== "audio" &&
          req.body.callType !== "audio-video") {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "callType should be 'audio' or 'audio-video'");
        return;
      }
      next();
    });
  }

  /**
   * Validates the call url params are valid.
   *
   * In case they aren't, error out with an HTTP 400.
   * If they are valid, store them in the urlData parameter of the request.
   **/
  function validateCallUrlParams(req, res, next) {
    var expiresIn = conf.get('callUrls').timeout,
        maxTimeout = conf.get('callUrls').maxTimeout;

    if (req.body.hasOwnProperty('expiresIn')) {
      expiresIn = parseInt(req.body.expiresIn, 10);

      if (isNaN(expiresIn)) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be a valid number");
        return;
      } else if (expiresIn > maxTimeout) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be less than " + maxTimeout);
        return;
      }
    }
    if (req.token === undefined) {
      req.token = tokenlib.generateToken(conf.get('callUrls').tokenSize);
    }

    req.urlData = {
      userMac: req.user,
      callerId: req.body.callerId,
      timestamp: parseInt(Date.now() / 1000, 10),
      issuer: req.body.issuer || ''
    };

    if (expiresIn !== undefined) {
      req.urlData.expires = req.urlData.timestamp +
                            expiresIn * tokenlib.ONE_HOUR;
    }
    next();
  }

  /**
   * Validate the room url parameters passed in the body.
   **/
  function validateRoomUrlParams(req, res, next) {
    var roomsConf = conf.get('rooms');

    var expiresIn = roomsConf.defaultTTL,
        maxTTL = roomsConf.maxTTL,
        serverMaxSize = roomsConf.maxSize,
        maxSize;

    if (req.body.hasOwnProperty('roomName')) {
      if (req.body.roomName.length > roomsConf.maxRoomNameSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "roomName should be shorter than " +
                  roomsConf.maxRoomNameSize + " characters");
        return;
      }
    }

    if (req.body.hasOwnProperty('roomOwner')) {
      if (req.body.roomOwner.length > roomsConf.maxRoomOwnerSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "roomOwner should be shorter than " +
                  roomsConf.maxRoomOwnerSize + " characters");
        return;
      }
    }

    if (req.body.hasOwnProperty('expiresIn')) {
      expiresIn = parseInt(req.body.expiresIn, 10);

      if (isNaN(expiresIn)) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn should be a valid number");
        return;
      } else if (expiresIn > maxTTL) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "expiresIn cannot be greater than " + maxTTL);
        return;
      }
    }

    if(req.body.hasOwnProperty('maxSize')) {
      maxSize = parseInt(req.body.maxSize, 10);

      if (maxSize > serverMaxSize) {
        sendError(res, 400, errors.INVALID_PARAMETERS,
                  "maxSize cannot be greater than " + serverMaxSize);
        return;
      }
    }

    req.roomRequestData = {
      roomName: req.body.roomName,
      expiresIn: expiresIn,
      roomOwner: req.body.roomOwner,
      maxSize: maxSize
    };

    next();
  }

  /**
   * Validates the given token exists and is valid.
   *
   * Once this is done, populates the:
   * - req.roomStorageData and
   * - req.token parameters with the appropriate values.
   **/
  function validateRoomToken(req, res, next) {
    req.token = req.param('token');
    storage.getRoomData(req.token, function(err, roomData) {
      if (res.serverError(err)) return;
      if (roomData === null) {
        sendError(res, 404, errors.INVALID_TOKEN, "Token not found.");
        return;
      }
      req.roomStorageData = roomData;
      next();
    });
  }

  /**
   * Checks the current connected hawk session is one of the room owner's one.
   **/
  function isRoomOwner(req, res, next) {
    if (req.user === req.roomStorageData.roomOwnerHmac) {
      next();
      return;
    }
    sendError(
      res, 403, errors.UNDEFINED,
      "Authenticated user is not the owner of this room."
    );
  }

  /**
   * Checks that the current user is either a room participant or a room
   * owner.
   **/
  function isRoomParticipant(req, res, next) {
    if (req.token === undefined) {
      throw new Error("req.token should be defined to use isRoomParticipant");
    }
    if (req.roomStorageData === undefined) {
      throw new Error("req.roomStorageData should be defined to use " +
                      "isRoomParticipant");
    }

    storage.getRoomParticipants(req.token, function(err, participants) {
      if (res.serverError(err)) return;

      var isParticipant = participants.some(function(p) {
        return p.hawkIdHmac === req.hawkIdHmac;
      });

      var isOwner = (req.user === req.roomStorageData.roomOwnerHmac);

      if (!isParticipant && !isOwner) {
        sendError(
          res, 403, errors.UNDEFINED,
          "Authenticated user is neither a participant of the room" +
          " nor the room owner."
        );
        return;
      }

      req.roomStorageData.participants = participants.map(function(participant) {
        delete participant.hawkIdHmac;
        return participant;
      });
      next();
    });
  }

  return {
    validateToken: validateToken,
    requireParams: requireParams,
    validateSimplePushURL: validateSimplePushURL,
    validateCallType: validateCallType,
    validateCallUrlParams: validateCallUrlParams,
    validateRoomUrlParams: validateRoomUrlParams,
    validateRoomToken: validateRoomToken,
    isRoomOwner: isRoomOwner,
    isRoomParticipant: isRoomParticipant
  };
};
<|endoftext|>


<commit_before>(function(){
	var templates_ = {},
		helper_ = {
			get: function(id){
				return templates_[id]
			},
			resolve: function(node, id){
				var nodes = templates_[id];
				if (nodes != null)
					return nodes;

				var selector = ':template[id='+this.attr.id+']',
					parent = node.parent,
					tmpl = null
					;
				while (parent != null) {
					tmpl = jmask(parent.nodes)
						.filter(selector)
						.get(0);

					if (tmpl != null)
						return tmpl.nodes;

					parent = parent.parent;
				}
				log_warn('Template was not found', id);
				return null;
			},
			register: function(id, nodes){
				if (id == null) {
					log_warn('`:template` must be define via id attr.');
					return;
				}
				templates_[id] = nodes;
			}
		};

	Mask.templates = helper_;
	Mask.registerHandler(':template', {
		render: function() {
			helper_.register(this.attr.id, this.nodes);
		}
	});

	Mask.registerHandler(':import', {
		renderStart: function() {
			var id = this.attr.id;
			if (id == null) {
				log_error('`:import` shoud reference the template via id attr')
				return;
			}
			this.nodes = helper_.resolve(id);
		}
	});
}());<commit_msg>fix Template importer. Correct context<commit_after>(function(){
	var templates_ = {},
		helper_ = {
			get: function(id){
				return templates_[id]
			},
			resolve: function(node, id){
				var nodes = templates_[id];
				if (nodes != null)
					return nodes;

				var selector = ':template[id=' + id +']',
					parent = node.parent,
					tmpl = null
					;
				while (parent != null) {
					tmpl = jmask(parent.nodes)
						.filter(selector)
						.get(0);

					if (tmpl != null)
						return tmpl.nodes;

					parent = parent.parent;
				}
				log_warn('Template was not found', id);
				return null;
			},
			register: function(id, nodes){
				if (id == null) {
					log_warn('`:template` must be define via id attr.');
					return;
				}
				templates_[id] = nodes;
			}
		};

	Mask.templates = helper_;
	Mask.registerHandler(':template', {
		render: function() {
			helper_.register(this.attr.id, this.nodes);
		}
	});

	Mask.registerHandler(':import', {
		renderStart: function() {
			var id = this.attr.id;
			if (id == null) {
				log_error('`:import` shoud reference the template via id attr')
				return;
			}
			this.nodes = helper_.resolve(this, id);
		}
	});
}());<|endoftext|>


<commit_before>/* eslint-disable max-len */

export const JSON_BACKUP_VERSION = '0.0.1';
export const REDUX_PREFIX = 'SPECTRUM';
export const LEDGER_ETH_KD_PATH = "44'/60'/0'/";
/* eslint-disable */
export const ERC20_ABI = [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}];
/* eslint-enable */
export const SUI_COLORS = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue', 'violet', 'purple', 'pink', 'brown', 'grey', 'black'];
export const IPFS_GATEWAY = 'https://ipfs.infura.io/ipfs/';
export const IPFS_API_CONFIG = { host: 'ipfs.infura.io', port: '5001', protocol: 'https' };
// SEED DATA
export const DEFAULT_SESSION_ID = 'main';

export const DEFAULT_NETWORKS = [
  {
    name: 'Ethereum',
    symbol: 'ETH',
    description: 'Official Ethereum Mainnet',
    provider: 'https://mainnet.infura.io',
    id: 'eth-mainnet',
    color: 'violet',
    chainId: 1,
    enabled: true,
    default: true,
    explorerAddressPrefix: 'https://etherscan.io/address/',
    explorerBlockPrefix: 'https://etherscan.io/block/',
    explorerTransactionPrefix: 'https://etherscan.io/tx/',
  },
  {
    name: 'Kovan',
    symbol: 'KETH',
    description: 'Kovan PoA Testnet',
    provider: 'https://kovan.infura.io/',
    // provider: 'http://localhost:8545',
    id: 'eth-kovan',
    color: 'pink',
    enabled: true,
    default: true,
    chainId: 42,
    explorerAddressPrefix: 'https://kovan.etherscan.io/address/',
    explorerBlockPrefix: 'https://kovan.etherscan.io/block/',
    explorerTransactionPrefix: 'https://kovan.etherscan.io/tx/',
  },
  {
    name: 'Ethereum Classic',
    symbol: 'ETC',
    description: 'Old Unforked Chain',
    provider: 'https://digixparity04.digix.io',
    id: 'etc',
    chainId: 61,
    color: 'green',
    enabled: true,
    default: true,
    explorerAddressPrefix: 'https://gastracker.io/addr/',
    explorerBlockPrefix: 'https://gastracker.io/block/',
    explorerTransactionPrefix: 'https://gastracker.io/tx/',
  },
  {
    name: 'TestRPC',
    symbol: 'ETH-testrpc',
    description: 'Virtual Test Chain',
    provider: 'http://localhost:6545',
    id: 'eth-testrpc',
    color: 'blue',
    chainId: 1,
    enabled: false,
    default: false,
  },
  //   name: 'Ropsten Testnet',
  //   symbol: 'ETH-ropsten',
  //   description: 'Etheruem Public Testnet',
  //   provider: 'https://ropsten.infura.io',
  //   id: 'eth-ropsten',
  //   color: 'teal',
  //   chainId: 3,
  //   enabled: false,
  //   default: false,
  //   explorerAddressPrefix: 'https://testnet.etherscan.io/address/',
  //   explorerBlockPrefix: 'https://testnet.etherscan.io/block/',
  //   explorerTransactionPrefix: 'https://testnet.etherscan.io/tx/',
  // },
];

export const DEFAULT_KEYSTORE_TYPES = [
  {
    id: 'v3',
    name: 'Single Account',
    subtitle: 'v3 Encrypted Keystore',
    description: 'The standard "default" wallet used by Geth, Parity, and many other services',
    color: 'green',
    icon: 'key',
  },
  {
    id: 'ledger',
    name: 'Ledger Wallet',
    subtitle: 'Nano S (or blue) Hardware Wallet',
    description: 'Ethereum hardware wallet, based on robust safety features for storing cryptographic assets and securing digital payments. It connects to any computer via USB.',
    color: 'black',
    icon: 'usb',
  },
  {
    id: 'cold',
    name: 'Cold Accounts',
    subtitle: 'for Offline Signing / Read Only',
    description: 'Reference to an Ethereum address that allows for generating offline signing data, or simply checking account balances',
    color: 'blue',
    icon: 'hide',
  },
  {
    id: 'multisig',
    name: 'MultiSig Wallet',
    subtitle: 'Multi-party sigining for increased security',
    description: 'Assigns multiple other keystores to administer a contract that can execute transactions with a miniumum threashold of approvals',
    color: 'orange',
    icon: 'users',
  },
];

export const DEFAULT_TOKENS = [
  {
    address: '0x7a1767df4bad56ba284ac2a07b55d0825abab91c',
    symbol: 'DGX-test',
    decimals: 9,
    // type: 'default',
    network: 'eth-kovan',
    name: 'DGX Kovan',
    color: 'orange',
  }, {
    address: '0x1312f9ec97a2377c8e2ba6f088afdfedfe59398c',
    symbol: 'DGDR',
    decimals: 9,
    default: true,
    // type: 'default',
    network: 'etc',
    name: 'DGD ETC Redemption',
    color: 'olive',
  // }, {
  //   address: '0xAc709FcB44a43c35F0DA4e3163b117A17F3770f5',
  //   symbol: 'ARC',
  //   decimals: 18,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Arcade City Tokens',
  //   color: 'violet',
  // }, {
  //   address: '0x74c1e4b8cae59269ec1d85d3d4f324396048f4ac',
  //   symbol: '🍺  ',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'BeerCoin',
  //   color: 'orange',
  // }, {
  //   address: '0x1e797Ce986C3CFF4472F7D38d5C4aba55DfEFE40',
  //   symbol: 'BCDN',
  //   decimals: 15,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'BlockCDN',
  //   color: 'teal',
  // }, {
  //   address: '0xbb9bc244d798123fde783fcc1c72d3bb8c189413',
  //   symbol: 'DAO',
  //   decimals: 16,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'The DAO Tokens',
  //   color: 'red',
  // }, {
  //   address: '0x5c40eF6f527f4FbA68368774E6130cE6515123f2',
  //   symbol: 'DAO-extra',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'The DAO extraBalance Tokens',
  //   color: 'grey',
  }, {
    address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
    symbol: 'DGD',
    decimals: 9,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'DigixDAO Tokens',
    color: 'blue',
  // }, {
  //   address: '0x54bda709fed875224eae569bb6817d96ef7ed9ad',
  //   symbol: 'DGD-badge',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'DigixDAO Proposer Badges',
  //   color: 'black',
  }, {
    address: '0xa74476443119A942dE498590Fe1f2454d7D4aC0d',
    symbol: 'GNT',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'Golem Network Tokens',
    color: 'brown',
  // }, {
  //   address: '0xb582baaf5e749d6aa98a22355a9d08b4c4d013c8',
  //   symbol: 'HKG',
  //   decimals: 3,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Hacker Gold',
  //   color: 'orange',
  }, {
    address: '0x888666CA69E0f178DED6D75b5726Cee99A87D698',
    symbol: 'ICN',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'ICONOMI Tokens',
    color: 'black',
  }, {
    address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
    symbol: 'MKR',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'MakerDAO Tokens',
    color: 'teal',
  // }, {
  //   address: '0xD8912C10681D8B21Fd3742244f44658dBA12264E',
  //   symbol: 'PLU',
  //   decimals: 18,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Plutons',
  //   color: 'brown',
  }, {
    address: '0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5',
    symbol: 'REP',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'Augur Rep',
    color: 'purple',
  }, {
    address: '0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009',
    symbol: 'SNGLS',
    decimals: 0,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'SingularDTV Signals',
    color: 'red',
  // }, {
  //   address: '0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7',
  //   symbol: '🦄  ',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Unicorn',
  //   color: 'black',
  },
];
<commit_msg>disable testrpc & classic<commit_after>/* eslint-disable max-len */

export const JSON_BACKUP_VERSION = '0.0.1';
export const REDUX_PREFIX = 'SPECTRUM';
export const LEDGER_ETH_KD_PATH = "44'/60'/0'/";
/* eslint-disable */
export const ERC20_ABI = [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}];
/* eslint-enable */
export const SUI_COLORS = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue', 'violet', 'purple', 'pink', 'brown', 'grey', 'black'];
export const IPFS_GATEWAY = 'https://ipfs.infura.io/ipfs/';
export const IPFS_API_CONFIG = { host: 'ipfs.infura.io', port: '5001', protocol: 'https' };
// SEED DATA
export const DEFAULT_SESSION_ID = 'main';

export const DEFAULT_NETWORKS = [
  {
    name: 'Ethereum',
    symbol: 'ETH',
    description: 'Official Ethereum Mainnet',
    provider: 'https://mainnet.infura.io',
    id: 'eth-mainnet',
    color: 'violet',
    chainId: 1,
    enabled: true,
    default: true,
    explorerAddressPrefix: 'https://etherscan.io/address/',
    explorerBlockPrefix: 'https://etherscan.io/block/',
    explorerTransactionPrefix: 'https://etherscan.io/tx/',
  },
  {
    name: 'Kovan',
    symbol: 'KETH',
    description: 'Kovan PoA Testnet',
    provider: 'https://kovan.infura.io/',
    // provider: 'http://localhost:8545',
    id: 'eth-kovan',
    color: 'pink',
    enabled: true,
    default: true,
    chainId: 42,
    explorerAddressPrefix: 'https://kovan.etherscan.io/address/',
    explorerBlockPrefix: 'https://kovan.etherscan.io/block/',
    explorerTransactionPrefix: 'https://kovan.etherscan.io/tx/',
  },
  {
    name: 'Ethereum Classic',
    symbol: 'ETC',
    description: 'Old Unforked Chain',
    provider: 'https://digixparity04.digix.io',
    id: 'etc',
    chainId: 61,
    color: 'green',
    enabled: false,
    default: false,
    explorerAddressPrefix: 'https://gastracker.io/addr/',
    explorerBlockPrefix: 'https://gastracker.io/block/',
    explorerTransactionPrefix: 'https://gastracker.io/tx/',
  },
  // {
  //   name: 'TestRPC',
  //   symbol: 'ETH-testrpc',
  //   description: 'Virtual Test Chain',
  //   provider: 'http://localhost:6545',
  //   id: 'eth-testrpc',
  //   color: 'blue',
  //   chainId: 1,
  //   enabled: false,
  //   default: false,
  // },
  //   name: 'Ropsten Testnet',
  //   symbol: 'ETH-ropsten',
  //   description: 'Etheruem Public Testnet',
  //   provider: 'https://ropsten.infura.io',
  //   id: 'eth-ropsten',
  //   color: 'teal',
  //   chainId: 3,
  //   enabled: false,
  //   default: false,
  //   explorerAddressPrefix: 'https://testnet.etherscan.io/address/',
  //   explorerBlockPrefix: 'https://testnet.etherscan.io/block/',
  //   explorerTransactionPrefix: 'https://testnet.etherscan.io/tx/',
  // },
];

export const DEFAULT_KEYSTORE_TYPES = [
  {
    id: 'v3',
    name: 'Single Account',
    subtitle: 'v3 Encrypted Keystore',
    description: 'The standard "default" wallet used by Geth, Parity, and many other services',
    color: 'green',
    icon: 'key',
  },
  {
    id: 'ledger',
    name: 'Ledger Wallet',
    subtitle: 'Nano S (or blue) Hardware Wallet',
    description: 'Ethereum hardware wallet, based on robust safety features for storing cryptographic assets and securing digital payments. It connects to any computer via USB.',
    color: 'black',
    icon: 'usb',
  },
  {
    id: 'cold',
    name: 'Cold Accounts',
    subtitle: 'for Offline Signing / Read Only',
    description: 'Reference to an Ethereum address that allows for generating offline signing data, or simply checking account balances',
    color: 'blue',
    icon: 'hide',
  },
  {
    id: 'multisig',
    name: 'MultiSig Wallet',
    subtitle: 'Multi-party sigining for increased security',
    description: 'Assigns multiple other keystores to administer a contract that can execute transactions with a miniumum threashold of approvals',
    color: 'orange',
    icon: 'users',
  },
];

export const DEFAULT_TOKENS = [
  {
    address: '0x7a1767df4bad56ba284ac2a07b55d0825abab91c',
    symbol: 'DGX-test',
    decimals: 9,
    // type: 'default',
    network: 'eth-kovan',
    name: 'DGX Kovan',
    color: 'orange',
  }, {
    address: '0x1312f9ec97a2377c8e2ba6f088afdfedfe59398c',
    symbol: 'DGDR',
    decimals: 9,
    default: true,
    // type: 'default',
    network: 'etc',
    name: 'DGD ETC Redemption',
    color: 'olive',
  // }, {
  //   address: '0xAc709FcB44a43c35F0DA4e3163b117A17F3770f5',
  //   symbol: 'ARC',
  //   decimals: 18,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Arcade City Tokens',
  //   color: 'violet',
  // }, {
  //   address: '0x74c1e4b8cae59269ec1d85d3d4f324396048f4ac',
  //   symbol: '🍺  ',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'BeerCoin',
  //   color: 'orange',
  // }, {
  //   address: '0x1e797Ce986C3CFF4472F7D38d5C4aba55DfEFE40',
  //   symbol: 'BCDN',
  //   decimals: 15,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'BlockCDN',
  //   color: 'teal',
  // }, {
  //   address: '0xbb9bc244d798123fde783fcc1c72d3bb8c189413',
  //   symbol: 'DAO',
  //   decimals: 16,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'The DAO Tokens',
  //   color: 'red',
  // }, {
  //   address: '0x5c40eF6f527f4FbA68368774E6130cE6515123f2',
  //   symbol: 'DAO-extra',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'The DAO extraBalance Tokens',
  //   color: 'grey',
  }, {
    address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
    symbol: 'DGD',
    decimals: 9,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'DigixDAO Tokens',
    color: 'blue',
  // }, {
  //   address: '0x54bda709fed875224eae569bb6817d96ef7ed9ad',
  //   symbol: 'DGD-badge',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'DigixDAO Proposer Badges',
  //   color: 'black',
  }, {
    address: '0xa74476443119A942dE498590Fe1f2454d7D4aC0d',
    symbol: 'GNT',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'Golem Network Tokens',
    color: 'brown',
  // }, {
  //   address: '0xb582baaf5e749d6aa98a22355a9d08b4c4d013c8',
  //   symbol: 'HKG',
  //   decimals: 3,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Hacker Gold',
  //   color: 'orange',
  }, {
    address: '0x888666CA69E0f178DED6D75b5726Cee99A87D698',
    symbol: 'ICN',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'ICONOMI Tokens',
    color: 'black',
  }, {
    address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
    symbol: 'MKR',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'MakerDAO Tokens',
    color: 'teal',
  // }, {
  //   address: '0xD8912C10681D8B21Fd3742244f44658dBA12264E',
  //   symbol: 'PLU',
  //   decimals: 18,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Plutons',
  //   color: 'brown',
  }, {
    address: '0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5',
    symbol: 'REP',
    decimals: 18,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'Augur Rep',
    color: 'purple',
  }, {
    address: '0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009',
    symbol: 'SNGLS',
    decimals: 0,
    // type: 'default',
    network: 'eth-mainnet',
    name: 'SingularDTV Signals',
    color: 'red',
  // }, {
  //   address: '0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7',
  //   symbol: '🦄  ',
  //   decimals: 0,
  //   // type: 'default',
  //   network: 'eth-mainnet',
  //   name: 'Unicorn',
  //   color: 'black',
  },
];
<|endoftext|>


<commit_before>/* Is this needed? */
angular.module("loadmaster",[])
  .config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

/* User controller with angularjs */
function userCtrl($scope) {

	$scope.IS_MOBILE=true
	window.myscope = $scope;
	window.db = $scope.isDatabaseEmpty;

	$scope.numberOfRows;

	$scope.shortName = 'WebSqlDB';
	$scope.version = '1.0';
	$scope.displayName = 'WebSqlDB';
	$scope.maxSize = 65535;
	$scope.host = 'http://195.231.85.191:5000';

	$scope.init = function(){
/* 		debugging function */

/* 		$scope.dropTables(); */

/* 		End of debugging functions */
		$scope.initializeDB()
		$scope.isAccessTokenInDatabase()
		$scope.checkLastTripFinished()
		$scope.checkLengthOfDatabase()

	    $.mobile.buttonMarkup.hoverDelay = 0;
		$.mobile.defaultPageTransition   = 'none';
	    $.mobile.defaultDialogTransition = 'none';

		if($scope.access_token != ""){
			$scope.checkInterval();
		}
	}

	$scope.checkInterval = function(){
		$scope.intervalID = setInterval(function(){
				$scope.$apply(function(scope){
					document.addEventListener("deviceready", function(){
					}, false);
				scope.checkConnection();
			  	})
			}, 5000);
	}

	$scope.isAccessTokenInDatabase = function(){
			// initial variables
		if(!$scope.db){
			$scope.createNewDB()
		}

		$scope.db.transaction(function (tx){
			tx.executeSql('SELECT * FROM Auth', [], function (tx, result){  // Fetch records from SQLite
				var dataset = result.rows;
				if (dataset.length == 0 ){
					$.mobile.changePage("#tokencontainer");
				}
				else if(!!dataset.length){
					$scope.access_token = dataset.item(0).access_token;
					$scope.imei = dataset.item(0).imei;
					$.mobile.changePage("#home");
				}
			});
		});
	}

	/* check Connection */
	$scope.checkConnection = function(){
		console.log("Checking connection");
		if(navigator.connection.type == Connection.UNKNOWN || navigator.connection.type == Connection.NONE || navigator.connection.type == Connection.CELL || navigator.connection.type == Connection.CELL_2G){
			console.log('Unknown connection');
		} else if(navigator.connection.type == Connection.CELL_3G || navigator.connection.type == Connection.CELL_4G || navigator.connection.type == Connection.WIFI ||navigator.connection.type == Connection.ETHERNET){
			console.log("Found connection. Checking if database is empty ")
			$scope.isDatabaseEmpty();
		}
	}

	/* Is database empty */
	$scope.isDatabaseEmpty = function() {
		if(!$scope.db){
			$scope.createNewDB()
		}

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
	         transaction.executeSql(query, [], function(tx, results){
		         var dataset = results.rows;
		         if (dataset.length == 0){
			        $scope.numberOfRows = results.rows.length;
	        		console.log($scope.numberOfRows)

		         }else if (dataset.length > 0){
			        var item = dataset.item(0)
					if (item['_is_finished'] == undefined) {
			        } else if(item['_is_finished'] == 1) {
				        $scope.syncToDatabase();
			        }
		         }
	         },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
		console.log($scope.numberOfRows)
		$scope.$emit('rows', $scope.numberOfRows);
	}

	$scope.createNewDB = function(){
		if (!window.openDatabase) {
			alert('Databases are not supported in this browser.');
			return;
		}
		$scope.db = openDatabase($scope.shortName, $scope.version, $scope.displayName, $scope.maxSize);
	}

	$scope.checkLastTripFinished = function(){
		if(!$scope.db){	$scope.createNewDB() }

		var numberOfRows;

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
      transaction.executeSql(query, [], function(tx, results){
       	var dataset = results.rows;
				if (dataset.length > 0){
	       	var item = dataset.item(dataset.length-1)
					if (item['_is_finished'] == undefined) {
						$scope.promptUnfinishedTrip()
					}
	      }
      },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
		return numberOfRows;
	}

	$scope.promptUnfinishedTrip = function(){
		var confirm=window.confirm('Du har en uafsluttet tur. Vil du fortsætte din tur?? Hvis du trykker cancel, vil din uafsluttede tur blive slettet.')
		if(confirm){
			$.mobile.changePage('#two')
		}else{
			/* 	Deletes synced rows from trips table */
			var confirm=window.confirm('Er du sikker? Din uafsluttede tur vil blive slettet hvis du trykker ok. Tryk cancel for at fortsætte turen')
			if(confirm){
				$scope.db.transaction(function(transaction) {
					transaction.executeSql('DELETE FROM Trip WHERE id = (SELECT MAX(Id) from Trip)');
					},function error(err){alert('error deleting from database ' + err)}, function success(){}
				);
			}else{
				$.mobile.changePage('#two')
			}
		}
	}

	/* Sync to server */
	$scope.syncToDatabase = function () {

		if(!$scope.db){
			$scope.createNewDB()
		}

			$scope.db.transaction(function (tx)
				{
					tx.executeSql('SELECT * FROM Trip', [], function (tx, result)  // Fetch records from SQLite
					{
						var dataset = result.rows;
						var trips = new Array();
						for (var i = 0, item = null; i < dataset.length; i++) {
							item = dataset.item(i);
							var trip = {
								trip_id			: item['Id'],
								cargo			: item['_cargo'],
								license_plate 	: item['_license_plate'],
								start_location 	: item['_start_location'],
								start_address 	: item['_start_address'],
								end_location 	: item['_end_location'],
								end_address	 	: item['_end_address'],
								start_timestamp : item['_start_timestamp'],
								end_timestamp 	: item['_end_timestamp'],
								start_comments 	: item['_start_comments'],
								end_comments 	: item['_end_comments']
							};

							if(!!item['_is_finished']){
								console.log(trip)
								trips.push(trip);
							}
						}
						$scope.InsertRecordOnServerFunction(trips);      // Call Function for insert Record into SQl Server
					});
				});
			}

	/* Syncs with server */
	$scope.InsertRecordOnServerFunction = function(trips){  // Function for insert Record into SQl Server
		$.ajax({
			type: "POST",
			url: $scope.host + "/api/v1/trips",
			data :  {
			     access_token	: $scope.access_token, // Skal kun sættes en gang ind i databasen
			     trips			: trips,
			     device_id		: $scope.imei
			 },

			processdata: true,
			success: function (msg)
			{
				console.log('succes!!!!')
				console.log()
				//On Successfull service call
				$scope.dropAllRows(); //Uncomment this when success message is received. Make this function receive synced rows from server
			},
			error: function (msg) {
				window.msg = msg;
				console.log(msg);
				console.log(msg.status);
				if(!!msg.responseText && !!msg.responseText.err_ids){
					if(JSON.parse(msg.responseText).err_ids != 0){
						$scope.dropRowsSynced(JSON.parse(msg.responseText).err_ids)
					}
				}

				else if(msg.status == 401){
					$scope.resetAccessToken()
				}

				else if(msg.status == 404){
					console.log("404 error ")
					}
			}
		});
	};

/* 	Reset access token if incorrect */
	$scope.resetAccessToken = function(){
	 	if(!$scope.db){
			$scope.createNewDB()
		}

		console.log("Deleting access token and device id from table")

		/* 	Deletes synced rows from trips table */
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('DELETE FROM Auth', [/* Insert array of IDs of synced rows. See below */]);
			},function error(err){alert('error resetting accesstoken ' + err)}, function success(){}
		);
		console.log("access token er " + $scope.access_token)
		alert("Access token er forkert")
		clearInterval($scope.intervalID);
		$.mobile.changePage("#tokencontainer");
	}

	/* Drops synced rows */
	$scope.dropAllRows = function(){

		 if(!$scope.db){
			$scope.createNewDB()
		}

		/* 	Deletes synced rows from trips table */
			$scope.db.transaction(function(transaction) {
				transaction.executeSql('DELETE FROM Trip WHERE _is_finished = 1', [/* Insert array of IDs of synced rows. See below */]);
				},function error(err){alert('error deleting from database ' + err)}, function success(){}
			);
			return false;

		}

		/* Drops synced rows */
	$scope.dropRowsSynced = function(err_ids){

		if(!$scope.db){
			$scope.createNewDB()
		}

		/* 	Deletes synced rows from trips table */
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('DELETE FROM Trip WHERE id <> *', [err_ids]);
			},function error(err){alert('error deleting from database ' + err)}, function success(){}
		);
		return false;
	}

		/* 	Starting new trip*/
	$scope.submitStartNewTrip = function($event){

		$event.preventDefault();
		$.mobile.changePage("#home");
	}

	$scope.submitToken = function($event){

		console.log($scope.access_token)

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('INSERT INTO AUTH (access_token, imei) VALUES ("'+$scope.access_token+'", "'+$scope.imei+'")',[]);
			},function error(err){alert('error on save to local db ' + err)}, function success(){}
		);

		$scope.checkInterval()
		$event.preventDefault();
		$.mobile.changePage("#home");

		return false;
	}

	/* --------------  Database ---------------- */
	// called when the application loads
	$scope.initializeDB = function(){

			// initial variables

		// This alert is used to make sure the application is loaded correctly
		// you can comment this out once you have the application working
		console.log("DEBUGGING: we are in the InitializeDB function");

		// this line tries to open the database base locally on the device
		// if it does not exist, it will create it and return a database object stored in variable db
		if(!$scope.db){
			$scope.createNewDB()
		}
		// this line will try to create the table User in the database justcreated/openned
		$scope.db.transaction(function(tx){

			tx.executeSql( 'CREATE TABLE IF NOT EXISTS Auth(access_token varchar, imei varchar)', []);

			// this line actually creates the table User if it does not exist and sets up the three columns and their types
			// note the UserId column is an auto incrementing column which is useful if you want to pull back distinct rows
			// easily from the table.
			tx.executeSql( 'CREATE TABLE IF NOT EXISTS Trip(Id INTEGER PRIMARY KEY AUTOINCREMENT, _license_plate varchar, _cargo varchar, _start_timestamp int, _start_location int, _start_address varchar,  _start_comments varchar, _end_timestamp int, _end_location int, _end_address varchar, _end_comments varchar, _is_finished int)', [])},
			function error(err){alert('error on init local db ' + err)}, function success(){console.log("database created")}
		)
	}

	// this is the function that puts values into the database from page #home
	$scope.AddStartValuesToDB = function(trip) {
		$scope.startlocation=trip.start_location
		console.log("cargo er " + trip.cargo);

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			console.log("Cargo er i submit og vi kører nu addstartvalues to db" + $scope.cargo);
			transaction.executeSql('INSERT INTO Trip(_license_plate, _cargo, _start_timestamp, _start_location, _start_address, _start_comments) VALUES ("'+trip.license_plate+'", "'+trip.cargo+'", "'+trip.start_timestamp+'", "'+trip.start_location+'", "'+trip.start_address+'", "'+trip.start_comments+'")');
		},function error(err){alert('error on save to local db ' + err)}, function success(){});
		return false;
	}

	// this is the function that puts values into the database from page #home
	$scope.AddEndValuesToDB = function(trip) {
	 	$scope.endlocation=trip.end_location

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('UPDATE Trip SET _end_timestamp ="'+trip.end_timestamp+'", _end_location ="'+trip.end_location+'", _end_address ="'+trip.end_address+'", _end_comments ="'+trip.end_comments+'", _is_finished = 1 WHERE Id = (SELECT MAX(Id) from Trip)',[]);
			},function error(err){console.log('error on save to local db '); console.log(err)}, function success(){}
		);
		return false;
	}

	$scope.checkLengthOfDatabase = function() {
		if(!$scope.db){
			$scope.createNewDB()
		}

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
	         transaction.executeSql(query, [], function(tx, results){
		        $scope.numberOfRows = results.rows.length;
        		console.log($scope.numberOfRows)
	         },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
	}

	$scope.$watch("numberOfRows", function () {
		console.log($scope.numberOfRows)
		if($scope.numberOfRows == undefined)
		{
			return false
		}
		else if($scope.numberOfRows > 0){
			$("div.database").html( "<span>Antal ture i databasen : </spam>" + $scope.numberOfRows );
		}
	})

/* DEBUGGING functions */

$scope.dropTables = function(){

	shortName = 'WebSqlDB';
	version = '1.0';
	displayName = 'WebSqlDB';
	maxSize = 65535;

	db = openDatabase(shortName, version, displayName, maxSize);

	db.transaction(function(tx){

		// IMPORTANT FOR DEBUGGING!!!!
		// you can uncomment these next twp lines if you want the table Trip and the table Auth to be empty each time the application runs
		tx.executeSql( 'DROP TABLE Trip');
		tx.executeSql( 'DROP TABLE Auth');

	})
}

}

<commit_msg>no changes<commit_after>/* Is this needed? */
angular.module("loadmaster",[])
  .config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

/* User controller with angularjs */
function userCtrl($scope) {

	$scope.IS_MOBILE=true
	window.myscope = $scope;
	window.db = $scope.isDatabaseEmpty;

	$scope.numberOfRows;

	$scope.shortName = 'WebSqlDB';
	$scope.version = '1.0';
	$scope.displayName = 'WebSqlDB';
	$scope.maxSize = 65535;
	$scope.host = 'http://195.231.85.191:5000';

	$scope.init = function(){
/* 		debugging function */

/* 		$scope.dropTables(); */

/* 		End of debugging functions */
		$scope.initializeDB()
		$scope.isAccessTokenInDatabase()
		$scope.checkLastTripFinished()
		$scope.checkLengthOfDatabase()

	    $.mobile.buttonMarkup.hoverDelay = 0;
		$.mobile.defaultPageTransition   = 'none';
	    $.mobile.defaultDialogTransition = 'none';

		if($scope.access_token != ""){
			$scope.checkInterval();
		}
	}

	$scope.checkInterval = function(){
		$scope.intervalID = setInterval(function(){
				$scope.$apply(function(scope){
					document.addEventListener("deviceready", function(){
					}, false);
				scope.checkConnection();
			  	})
			}, 5000);
	}

	$scope.isAccessTokenInDatabase = function(){
			// initial variables
		if(!$scope.db){
			$scope.createNewDB()
		}

		$scope.db.transaction(function (tx){
			tx.executeSql('SELECT * FROM Auth', [], function (tx, result){  // Fetch records from SQLite
				var dataset = result.rows;
				if (dataset.length == 0 ){
					$.mobile.changePage("#tokencontainer");
				}
				else if(!!dataset.length){
					$scope.access_token = dataset.item(0).access_token;
					$scope.imei = dataset.item(0).imei;
					$.mobile.changePage("#home");
				}
			});
		});
	}

	/* check Connection */
	$scope.checkConnection = function(){
		console.log("Checking connection");
		if(navigator.connection.type == Connection.UNKNOWN || navigator.connection.type == Connection.NONE || navigator.connection.type == Connection.CELL || navigator.connection.type == Connection.CELL_2G){
			console.log('Unknown connection');
		} else if(navigator.connection.type == Connection.CELL_3G || navigator.connection.type == Connection.CELL_4G || navigator.connection.type == Connection.WIFI ||navigator.connection.type == Connection.ETHERNET){
			console.log("Found connection. Checking if database is empty ")
			$scope.isDatabaseEmpty();
		}
	}

	/* Is database empty */
	$scope.isDatabaseEmpty = function() {
		if(!$scope.db){
			$scope.createNewDB()
		}

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
	         transaction.executeSql(query, [], function(tx, results){
		         var dataset = results.rows;
		         if (dataset.length == 0){
			        $scope.numberOfRows = results.rows.length;
	        		console.log($scope.numberOfRows)

		         }else if (dataset.length > 0){
			        var item = dataset.item(0)
					if (item['_is_finished'] == undefined) {
			        } else if(item['_is_finished'] == 1) {
				        $scope.syncToDatabase();
			        }
		         }
	         },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
		console.log($scope.numberOfRows)
		$scope.$emit('rows', $scope.numberOfRows);
	}

	$scope.createNewDB = function(){
		if (!window.openDatabase) {
			alert('Databases are not supported in this browser.');
			return;
		}
		$scope.db = openDatabase($scope.shortName, $scope.version, $scope.displayName, $scope.maxSize);
	}

	$scope.checkLastTripFinished = function(){
		if(!$scope.db){	$scope.createNewDB() }

		var numberOfRows;

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
      transaction.executeSql(query, [], function(tx, results){
       	var dataset = results.rows;
				if (dataset.length > 0){
	       	var item = dataset.item(dataset.length-1)
					if (item['_is_finished'] == undefined) {
						$scope.promptUnfinishedTrip()
					}
	      }
      },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
		return numberOfRows;
	}

	$scope.promptUnfinishedTrip = function(){
		var confirm=window.confirm('Du har en uafsluttet tur. Vil du fortsætte din tur?? Hvis du trykker cancel, vil din uafsluttede tur blive slettet.')
		if(confirm){
			$.mobile.changePage('#two')
		}else{
			/* 	Deletes synced rows from trips table */
			var confirm=window.confirm('Er du sikker? Din uafsluttede tur vil blive slettet hvis du trykker ok. Tryk cancel for at fortsætte turen')
			if(confirm){
				$scope.db.transaction(function(transaction) {
					transaction.executeSql('DELETE FROM Trip WHERE id = (SELECT MAX(Id) from Trip)');
					},function error(err){alert('error deleting from database ' + err)}, function success(){}
				);
			}else{
				$.mobile.changePage('#two')
			}
		}
	}

	/* Sync to server */
	$scope.syncToDatabase = function () {

		if(!$scope.db){
			$scope.createNewDB()
		}

			$scope.db.transaction(function (tx)
				{
					tx.executeSql('SELECT * FROM Trip', [], function (tx, result)  // Fetch records from SQLite
					{
						var dataset = result.rows;
						var trips = new Array();
						for (var i = 0, item = null; i < dataset.length; i++) {
							item = dataset.item(i);
							var trip = {
								trip_id			: item['Id'],
								cargo			: item['_cargo'],
								license_plate 	: item['_license_plate'],
								start_location 	: item['_start_location'],
								start_address 	: item['_start_address'],
								end_location 	: item['_end_location'],
								end_address	 	: item['_end_address'],
								start_timestamp : item['_start_timestamp'],
								end_timestamp 	: item['_end_timestamp'],
								start_comments 	: item['_start_comments'],
								end_comments 	: item['_end_comments']
							};

							if(!!item['_is_finished']){
								console.log(trip)
								trips.push(trip);
							}
						}
						$scope.InsertRecordOnServerFunction(trips);      // Call Function for insert Record into SQl Server
					});
				});
			}

	/* Syncs with server */
	$scope.InsertRecordOnServerFunction = function(trips){  // Function for insert Record into SQl Server
		$.ajax({
			type: "POST",
			url: $scope.host + "/api/v1/trips",
			data :  {
			     access_token	: $scope.access_token, // Skal kun sættes en gang ind i databasen
			     trips			: trips,
			     device_id		: $scope.imei
			 },

			processdata: true,
			success: function (msg)
			{
				console.log('succes!!!!')
				console.log()
				//On Successfull service call
				$scope.dropAllRows(); //Uncomment this when success message is received. Make this function receive synced rows from server
			},
			error: function (msg) {
				window.msg = msg;
				console.log(msg);
				console.log(msg.status);
				if(!!msg.responseText && !!msg.responseText.err_ids){
					if(JSON.parse(msg.responseText).err_ids != 0){
						$scope.dropRowsSynced(JSON.parse(msg.responseText).err_ids)
					}
				}

				else if(msg.status == 401){
					$scope.resetAccessToken()
				}

				else if(msg.status == 404){
					console.log("404 error ")
					}
			}
		});
	};

/* 	Reset access token if incorrect */
	$scope.resetAccessToken = function(){
	 	if(!$scope.db){
			$scope.createNewDB()
		}

		console.log("Deleting access token and device id from table")

		/* 	Deletes synced rows from trips table */
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('DELETE FROM Auth', [/* Insert array of IDs of synced rows. See below */]);
			},function error(err){alert('error resetting accesstoken ' + err)}, function success(){}
		);
		console.log("access token er " + $scope.access_token)
		alert("Access token er forkert")
		clearInterval($scope.intervalID);
		$.mobile.changePage("#tokencontainer");
	}

	/* Drops synced rows */
	$scope.dropAllRows = function(){

		 if(!$scope.db){
			$scope.createNewDB()
		}

		/* 	Deletes synced rows from trips table */
			$scope.db.transaction(function(transaction) {
				transaction.executeSql('DELETE FROM Trip WHERE _is_finished = 1', [/* Insert array of IDs of synced rows. See below */]);
				},function error(err){alert('error deleting from database ' + err)}, function success(){}
			);
			return false;

		}

		/* Drops synced rows */
	$scope.dropRowsSynced = function(err_ids){

		if(!$scope.db){
			$scope.createNewDB()
		}

		/* 	Deletes synced rows from trips table */
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('DELETE FROM Trip WHERE id <> *', [err_ids]);
			},function error(err){alert('error deleting from database ' + err)}, function success(){}
		);
		return false;
	}

		/* 	Starting new trip*/
	$scope.submitStartNewTrip = function($event){

		$event.preventDefault();
		$.mobile.changePage("#home");
	}

	$scope.submitToken = function($event){

		console.log($scope.access_token)

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('INSERT INTO AUTH (access_token, imei) VALUES ("'+$scope.access_token+'", "'+$scope.imei+'")',[]);
			},function error(err){alert('error on save to local db ' + err)}, function success(){}
		);

		$scope.checkInterval()
		$event.preventDefault();
		$.mobile.changePage("#home");

		return false;
	}

	/* --------------  Database ---------------- */
	// called when the application loads
	$scope.initializeDB = function(){

			// initial variables

		// This alert is used to make sure the application is loaded correctly
		// you can comment this out once you have the application working
		console.log("DEBUGGING: we are in the InitializeDB function");

		// this line tries to open the database base locally on the device
		// if it does not exist, it will create it and return a database object stored in variable db
		if(!$scope.db){
			$scope.createNewDB()
		}
		// this line will try to create the table User in the database justcreated/openned
		$scope.db.transaction(function(tx){

			tx.executeSql( 'CREATE TABLE IF NOT EXISTS Auth(access_token varchar, imei varchar)', []);

			// this line actually creates the table User if it does not exist and sets up the three columns and their types
			// note the UserId column is an auto incrementing column which is useful if you want to pull back distinct rows
			// easily from the table.
			tx.executeSql( 'CREATE TABLE IF NOT EXISTS Trip(Id INTEGER PRIMARY KEY AUTOINCREMENT, _license_plate varchar, _cargo varchar, _start_timestamp int, _start_location int, _start_address varchar,  _start_comments varchar, _end_timestamp int, _end_location int, _end_address varchar, _end_comments varchar, _is_finished int)', [])},
			function error(err){alert('error on init local db ' + err)}, function success(){console.log("database created")}
		)
	}

	// this is the function that puts values into the database from page #home
	$scope.AddStartValuesToDB = function(trip) {
		$scope.startlocation=trip.start_location
		console.log("cargo er " + trip.cargo);

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			console.log("Cargo er i submit og vi kører nu addstartvalues to db" + $scope.cargo);
			transaction.executeSql('INSERT INTO Trip(_license_plate, _cargo, _start_timestamp, _start_location, _start_address, _start_comments) VALUES ("'+trip.license_plate+'", "'+trip.cargo+'", "'+trip.start_timestamp+'", "'+trip.start_location+'", "'+trip.start_address+'", "'+trip.start_comments+'")');
		},function error(err){alert('error on save to local db ' + err)}, function success(){});
		return false;
	}

	// this is the function that puts values into the database from page #home
	$scope.AddEndValuesToDB = function(trip) {
	 	$scope.endlocation=trip.end_location

		// this is the section that actually inserts the values into the User table
		$scope.db.transaction(function(transaction) {
			transaction.executeSql('UPDATE Trip SET _end_timestamp ="'+trip.end_timestamp+'", _end_location ="'+trip.end_location+'", _end_address ="'+trip.end_address+'", _end_comments ="'+trip.end_comments+'", _is_finished = 1 WHERE Id = (SELECT MAX(Id) from Trip)',[]);
			},function error(err){console.log('error on save to local db '); console.log(err)}, function success(){}
		);
		return false;
	}

	$scope.checkLengthOfDatabase = function() {
		if(!$scope.db){
			$scope.createNewDB()
		}

		query = "SELECT * FROM Trip;";
		$scope.db.transaction(function(transaction){
	         transaction.executeSql(query, [], function(tx, results){
		        $scope.numberOfRows = results.rows.length;
        		console.log($scope.numberOfRows)
	         },function error(err){alert('error selecting from database ' + err)}, function success(){});
		});
	}

	$scope.$watch("numberOfRows", function () {
		console.log($scope.numberOfRows)
		if($scope.numberOfRows == undefined)
		{
			return false
		}
		else if($scope.numberOfRows > 0){
			$("div.database").html( "<span>Antal ture i databasen : </spam>" + $scope.numberOfRows );
		}
	})

/* DEBUGGING functions */

$scope.dropTables = function(){

	shortName = 'WebSqlDB';
	version = '1.0';
	displayName = 'WebSqlDB';
	maxSize = 65535;

	db = openDatabase(shortName, version, displayName, maxSize);

	db.transaction(function(tx){

		// IMPORTANT FOR DEBUGGING!!!!
		// you can uncomment these next twp lines if you want the table Trip and the table Auth to be empty each time the application runs
		tx.executeSql( 'DROP TABLE Trip');
		tx.executeSql( 'DROP TABLE Auth');

	})
}

}

<|endoftext|>


<commit_before>// use of ajax vs getJSON for headers use to get markdown (body vs body_htmml)
// todo: pages, configure issue url, open in new window?

var CurrentPage = 0;

function parse_link_header(link)
{
    var entries;
    if (link)
    {
        entries = link.split(",");
    }

    var links = { };
    for (var i in entries)
    {
        var entry = entries[i];
        var link = { };
        link.name = entry.match(/rel=\"([^\"]*)/)[1];
        link.url = entry.match(/<([^>]*)/)[1];
        link.page = entry.match(/page=(\d+).*$/)[1];
        links[link.name] = link;
    }
    return links;
}

function load_github_comments(repo_name, comment_id, page_id)
{
    //var repo_name = "dwilliamson/donw.io";

    if (page_id === undefined)
        page_id = 1;

    var api_url = "https://api.github.com/repos/" + repo_name;
    var api_issue_url = api_url + "/issues/" + comment_id;
    var api_comments_url = api_url + "/issues/" + comment_id + "/comments" + "?page=" + page_id;

    //var url = "https://github.com/dwilliamson/donw.io/issues/" + comment_id;
    var url = "https://github.com/" + repo_name + "/issues/" + comment_id;

    $(document).ready(function ()
    {
        $.getJSON(api_issue_url, function(data) {
            NbComments = data.comments;
        });

        $.ajax(api_comments_url, {
            headers: {Accept: "application/vnd.github.v3.html+json"},
            dataType: "json",
            success: function(comments, textStatus, jqXHR) {

                // Add post button to first page
                if (page_id == 1)
                    $("#gh-comments-list").append(" Post a comment on Github");

                // Individual comments
                $.each(comments, function(i, comment) {

                    var date = new Date(comment.created_at);

                    var t = "
";
                    t += "";
                    t += "" + comment.user.login + "";
                    //t += " posted at ";
                    t += " posted at ";
                    t += "" + date.toUTCString() + "";
                    t += "

";
                    t += comment.body_html;
                    t += "
";
                    $("#gh-comments-list").append(t);
                });

                // Setup comments button if there are more pages to display
                var links = parse_link_header(jqXHR.getResponseHeader("Link"));
                if ("next" in links)
                {
                    $("#gh-load-comments").attr("onclick", "load_github_comments('" + repo_name + "'," + comment_id + "," + (page_id + 1) + ");");
                    $("#gh-load-comments").show();
                }
                else
                {
                    $("#gh-load-comments").hide();
                }
            },
            error: function() {
                $("#gh-comments-list").append("Comments are not open for this post yet.");
            }
        });
    });
}<commit_msg>modify<commit_after>// use of ajax vs getJSON for headers use to get markdown (body vs body_htmml)
// todo: pages, configure issue url, open in new window?

var CurrentPage = 0;

function parse_link_header(link)
{
    var entries;
    if (link)
    {
        entries = link.split(",");
    }

    var links = { };
    for (var i in entries)
    {
        var entry = entries[i];
        var link = { };
        link.name = entry.match(/rel=\"([^\"]*)/)[1];
        link.url = entry.match(/<([^>]*)/)[1];
        link.page = entry.match(/page=(\d+).*$/)[1];
        links[link.name] = link;
    }
    return links;
}

function load_github_comments(repo_name, comment_id, page_id)
{
    //var repo_name = "dwilliamson/donw.io";

    if (page_id === undefined)
        page_id = 1;

    var api_url = "https://api.github.com/repos/" + repo_name;
    var api_issue_url = api_url + "/issues/" + comment_id;
    var api_comments_url = api_url + "/issues/" + comment_id + "/comments" + "?page=" + page_id;

    //var url = "https://github.com/dwilliamson/donw.io/issues/" + comment_id;
    var url = "https://github.com/" + repo_name + "/issues/" + comment_id;

    $(document).ready(function ()
    {
        $.getJSON(api_issue_url, function(data) {
            NbComments = data.comments;
        });

        $.ajax(api_comments_url, {
            headers: {Accept: "application/vnd.github.v3.html+json"},
            dataType: "json",
            success: function(comments, textStatus, jqXHR) {

                // Add post button to first page
                if (page_id == 1)
                    $("#gh-comments-list").append(" Post a comment on Github");

                // Individual comments
                $.each(comments, function(i, comment) {

                    var date = new Date(comment.created_at);

                    var t = "
";
                    t += "";
                    t += "" + comment.user.login + "";
                    //t += " posted at ";
                    t += "  ";
                    t += "" + date.toUTCString() + "";
                    t += "

";
                    t += comment.body_html;
                    t += "
";
                    $("#gh-comments-list").append(t);
                });

                // Setup comments button if there are more pages to display
                var links = parse_link_header(jqXHR.getResponseHeader("Link"));
                if ("next" in links)
                {
                    $("#gh-load-comments").attr("onclick", "load_github_comments('" + repo_name + "'," + comment_id + "," + (page_id + 1) + ");");
                    $("#gh-load-comments").show();
                }
                else
                {
                    $("#gh-load-comments").hide();
                }
            },
            error: function() {
                $("#gh-comments-list").append("Comments are not open for this post yet.");
            }
        });
    });
}<|endoftext|>