<commit_before>angular.module('opal.controllers').controller(
    'EditItemCtrl', function($scope, $cookieStore, $timeout,
                             $modalInstance, $modal, $q,
                             ngProgressLite,
                             profile, item, options, episode) {

        $scope.profile = profile;
        $scope.the_episode = episode;
        $scope.episode = episode.makeCopy();
        // Some fields should only be shown for certain categories.
        // Make that category available to the template.
        $scope.episode_category = episode.category;
        $scope.editing = {};
        $scope.editing[item.columnName] = item.makeCopy();

        $scope.editingMode = function(){
            return !_.isUndefined($scope.editing[item.columnName].id);
        };

        // This is the patientname displayed in the modal header
  	    $scope.editingName = item.episode.demographics[0].first_name + ' ' + episode.demographics[0].surname;

        $scope.columnName = item.columnName;

  	    for (var name in options) {
  		    if (name.indexOf('micro_test') != 0) {
  			    $scope[name + '_list'] = _.uniq(options[name]);
  		    };
  	    };

        $scope.macros = options.macros;
        $scope.select_macro = function(item){
            return item.expanded;
        };

        // TODO - don't hardcode this
	    if (item.columnName == 'microbiology_test' || item.columnName == 'lab_test' || item.columnName == 'investigation') {
		    $scope.microbiology_test_list = [];
		    $scope.microbiology_test_lookup = {};
		    $scope.micro_test_defaults =  options.micro_test_defaults;

		    for (var name in options) {
			    if (name.indexOf('micro_test') == 0) {
				    for (var ix = 0; ix < options[name].length; ix++) {
					    $scope.microbiology_test_list.push(options[name][ix]);
					    $scope.microbiology_test_lookup[options[name][ix]] = name;
				    };
			    };
		    };

		    $scope.$watch('editing.test', function(testName) {
			    $scope.testType = $scope.microbiology_test_lookup[testName];
                if( _.isUndefined(testName) || _.isUndefined($scope.testType) ){
                    return;
                }
                if($scope.testType in $scope.micro_test_defaults){
                    _.each(
                        _.pairs($scope.micro_test_defaults[$scope.testType]),
                        function(values){
                            var field =  values[0];
                            var _default =  values[1];
                            var val = _default
                            if($scope.editing[item.columnName][field]){
                              val = $scope.editing[item.columnName][field]
                            }
                            $scope.editing[field] =  val;
                        });
                }
		    });
	    };

	    $scope.episode_category_list = ['Inpatient', 'Outpatient', 'Review'];

        $scope.delete = function(result){
            $modalInstance.close(result);
            var modal = $modal.open({
                templateUrl: '/templates/modals/delete_item_confirmation.html/',
                controller: 'DeleteItemConfirmationCtrl',
                resolve: {
                    item: function() {
                        return item;
                    }
                }
            });
        };

        //
        // Save the item that we're editing.
        //

      $scope.saving = false;

	    $scope.save = function(result) {
            $scope.saving = true;
            ngProgressLite.set(0);
            ngProgressLite.start();
            to_save = [item.save($scope.editing[item.columnName])];
            if(!angular.equals($scope.the_episode.makeCopy(), $scope.episode)){
                to_save.push($scope.the_episode.save($scope.episode));
            }
            $q.all(to_save).then(function() {
                $scope.saving = false;
                ngProgressLite.done();
      			    $modalInstance.close(result);
		    });

	    };

        // Let's have a nice way to kill the modal.
	    $scope.cancel = function() {
		    $modalInstance.close('cancel');
	    };

        $scope.undischarge = function() {
            undischargeMoadal = $modal.open({
                templateUrl: '/templates/modals/undischarge.html/',
                controller: 'UndischargeCtrl',
                resolve: {episode: function(){ return episode } }
            }
            ).result.then(function(result){
                $modalInstance.close(episode.location[0])
            });
        };

        $scope.prepopulate = function($event) {
            $event.preventDefault();
            var data = $($event.target).data()
            _.each(_.keys(data), function(key){
                if(data[key] == 'true'){
                    data[key] = true;
                    return
                }
                if(data[key] == 'false'){
                    data[key] = false;
                    return
                }
            });
            angular.extend($scope.editing[item.columnName], data);
        };
    });
<commit_msg>edit item for microbiology test not using the new editting format<commit_after>angular.module('opal.controllers').controller(
    'EditItemCtrl', function($scope, $cookieStore, $timeout,
                             $modalInstance, $modal, $q,
                             ngProgressLite,
                             profile, item, options, episode) {

        $scope.profile = profile;
        $scope.the_episode = episode;
        $scope.episode = episode.makeCopy();
        // Some fields should only be shown for certain categories.
        // Make that category available to the template.
        $scope.episode_category = episode.category;
        $scope.editing = {};
        $scope.editing[item.columnName] = item.makeCopy();

        $scope.editingMode = function(){
            return !_.isUndefined($scope.editing[item.columnName].id);
        };

        // This is the patientname displayed in the modal header
  	    $scope.editingName = item.episode.demographics[0].first_name + ' ' + episode.demographics[0].surname;

        $scope.columnName = item.columnName;

  	    for (var name in options) {
  		    if (name.indexOf('micro_test') != 0) {
  			    $scope[name + '_list'] = _.uniq(options[name]);
  		    };
  	    };

        $scope.macros = options.macros;
        $scope.select_macro = function(item){
            return item.expanded;
        };

        // TODO - don't hardcode this
	    if (item.columnName == 'microbiology_test' || item.columnName == 'lab_test' || item.columnName == 'investigation') {
		    $scope.microbiology_test_list = [];
		    $scope.microbiology_test_lookup = {};
		    $scope.micro_test_defaults =  options.micro_test_defaults;

		    for (var name in options) {
			    if (name.indexOf('micro_test') == 0) {
				    for (var ix = 0; ix < options[name].length; ix++) {
					    $scope.microbiology_test_list.push(options[name][ix]);
					    $scope.microbiology_test_lookup[options[name][ix]] = name;
				    };
			    };
		    };

		    $scope.$watch('editing.microbiology_test.test', function(testName) {
			    $scope.testType = $scope.microbiology_test_lookup[testName];
                if( _.isUndefined(testName) || _.isUndefined($scope.testType) ){
                    return;
                }
                if($scope.testType in $scope.micro_test_defaults){
                    _.each(
                        _.pairs($scope.micro_test_defaults[$scope.testType]),
                        function(values){
                            var field =  values[0];
                            var _default =  values[1];
                            var val = _default
                            if($scope.editing[item.columnName][field]){
                              val = $scope.editing[item.columnName][field]
                            }
                            $scope.editing[field] =  val;
                        });
                }
		    });
	    };

	    $scope.episode_category_list = ['Inpatient', 'Outpatient', 'Review'];

        $scope.delete = function(result){
            $modalInstance.close(result);
            var modal = $modal.open({
                templateUrl: '/templates/modals/delete_item_confirmation.html/',
                controller: 'DeleteItemConfirmationCtrl',
                resolve: {
                    item: function() {
                        return item;
                    }
                }
            });
        };

        //
        // Save the item that we're editing.
        //

      $scope.saving = false;

	    $scope.save = function(result) {
            $scope.saving = true;
            ngProgressLite.set(0);
            ngProgressLite.start();
            to_save = [item.save($scope.editing[item.columnName])];
            if(!angular.equals($scope.the_episode.makeCopy(), $scope.episode)){
                to_save.push($scope.the_episode.save($scope.episode));
            }
            $q.all(to_save).then(function() {
                $scope.saving = false;
                ngProgressLite.done();
      			    $modalInstance.close(result);
		    });

	    };

        // Let's have a nice way to kill the modal.
	    $scope.cancel = function() {
		    $modalInstance.close('cancel');
	    };

        $scope.undischarge = function() {
            undischargeMoadal = $modal.open({
                templateUrl: '/templates/modals/undischarge.html/',
                controller: 'UndischargeCtrl',
                resolve: {episode: function(){ return episode } }
            }
            ).result.then(function(result){
                $modalInstance.close(episode.location[0])
            });
        };

        $scope.prepopulate = function($event) {
            $event.preventDefault();
            var data = $($event.target).data()
            _.each(_.keys(data), function(key){
                if(data[key] == 'true'){
                    data[key] = true;
                    return
                }
                if(data[key] == 'false'){
                    data[key] = false;
                    return
                }
            });
            angular.extend($scope.editing[item.columnName], data);
        };
    });
<|endoftext|>


<commit_before>/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Main = imports.ui.main;
const DBus = imports.dbus;
const Lang = imports.lang;
const St = imports.gi.St;
const Pango = imports.gi.Pango;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell');

const _ = Gettext.gettext;

const BUS_NAME = 'org.gnome.GPaste';
const OBJECT_PATH = '/org/gnome/GPaste';

const GPasteInterface = {
    name: BUS_NAME,
    methods: [
        { name: 'GetHistory', inSignature: '', outSignature: 'as' },
        { name: 'Select', inSignature: 'u', outSignature: '' },
        { name: 'Delete', inSignature: 'u', outSignature: '' },
        { name: 'Empty', inSignature: '', outSignature: '' },
        //{ name: 'Start', inSignature: '', outSignature: '' },
        //{ name: 'Quit', inSignature: '', outSignature: '' },
        ],
    signals: [
        { name: 'Changed', inSignature: '', outSignature: '' },
        ],
    properties: [
        ]
};
let GPasteProxy = DBus.makeProxyClass(GPasteInterface);

function Indicator() {
    this._init.apply(this, arguments);
}

Indicator.prototype = {
    __proto__: PanelMenu.SystemStatusButton.prototype,

    _init: function() {
        PanelMenu.SystemStatusButton.prototype._init.call(this, 'edit-paste-symbolic');
        this._proxy = new GPasteProxy(DBus.session, BUS_NAME, OBJECT_PATH);
        this._fillMenu();
        this._proxy.connect('Changed', Lang.bind(this, this._fillMenu));
    },

    _select: function(index) {
        this._proxy.SelectRemote(index);
    },

    _delete: function(index) {
        this._proxy.DeleteRemote(index);
    },

    _empty: function() {
        this._proxy.EmptyRemote();
    },
/*
    _toggleDaemon: function() {
        print("Toggled " + this._killSwitch.state);
        if (this._killSwitch.state)
            this._proxy.StartRemote();
        else
            this._proxy.QuitRemote();
    },
*/
    _fillMenu: function() {
        this.menu.removeAll();
        //this._killSwitch = new PopupMenu.PopupSwitchMenuItem(_("GPaste daemon"), true);
        //this._killSwitch.connect('toggled', Lang.bind(this, this._toggleDaemon));
        //this.menu.addMenuItem(this._killSwitch);
        //this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
        this._proxy.GetHistoryRemote(Lang.bind(this, function(history) {
            if (history.length == 0) {
                let emptyItem = new PopupMenu.PopupMenuItem('(Empty)', {reactive: false});
                this.menu.addMenuItem(emptyItem);
            } else {
                let index;
                let limit = 20;
                if (history.length < 20) limit = history.length;
                for (index = 0; index < limit; ++index) {
                    let selection = new PopupMenu.PopupMenuItem(history[index].replace('\n', ' '));
                    let label = selection.label;
                    let inner_index = index;
                    label.clutter_text.max_length = 60;
                    label.clutter_text.ellipsize = Pango.EllipsizeMode.END;
                    //selection.actor.button_mask = St.ButtonMask.ONE | St.ButtonMask.THREE;
                    selection.connect('activate', Lang.bind(this, function(actor, event) {
                        this._select(inner_index);
                    }));
                    let deletor = new St.Button({label: 'x'});
                    deletor.connect('clicked', Lang.bind(this, function(actor, event) {
                        this._delete(inner_index);
                    }));
                    selection.indicator = deletor;
                    selection.addActor(deletor);
                    this.menu.addMenuItem(selection);
                }
                this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
                let emptyItem = new PopupMenu.PopupMenuItem('Empty history');
                emptyItem.connect('activate', Lang.bind(this, this._empty));
                this.menu.addMenuItem(emptyItem)
            }
        }));
    }
};

function main() {
    let indicator = new Indicator();
    Main.panel._statusBox.add(indicator.actor);
    Main.panel._menus.addMenu(indicator.menu);
}
<commit_msg>try to fix gnome-shell extension<commit_after>/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Main = imports.ui.main;
const DBus = imports.dbus;
const Lang = imports.lang;
const St = imports.gi.St;
const Pango = imports.gi.Pango;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell');

const _ = Gettext.gettext;

const BUS_NAME = 'org.gnome.GPaste';
const OBJECT_PATH = '/org/gnome/GPaste';

const GPasteInterface = {
    name: BUS_NAME,
    methods: [
        { name: 'GetHistory', inSignature: '', outSignature: 'as' },
        { name: 'Select', inSignature: 'u', outSignature: '' },
        { name: 'Delete', inSignature: 'u', outSignature: '' },
        { name: 'Empty', inSignature: '', outSignature: '' },
        //{ name: 'Start', inSignature: '', outSignature: '' },
        //{ name: 'Quit', inSignature: '', outSignature: '' },
        ],
    signals: [
        { name: 'Changed', inSignature: '', outSignature: '' },
        ],
    properties: [
        ]
};
let GPasteProxy = DBus.makeProxyClass(GPasteInterface);

function Indicator() {
    this._init.apply(this, arguments);
}

Indicator.prototype = {
    __proto__: PanelMenu.SystemStatusButton.prototype,

    _init: function() {
        PanelMenu.SystemStatusButton.prototype._init.call(this, 'edit-paste-symbolic');
        this._proxy = new GPasteProxy(DBus.session, BUS_NAME, OBJECT_PATH);
        this._fillMenu();
        this._proxy.connect('Changed', Lang.bind(this, this._fillMenu));
    },

    _select: function(index) {
        this._proxy.SelectRemote(index);
    },

    _delete: function(index) {
        this._proxy.DeleteRemote(index);
    },

    _empty: function() {
        this._proxy.EmptyRemote();
    },
/*
    _toggleDaemon: function() {
        print("Toggled " + this._killSwitch.state);
        if (this._killSwitch.state)
            this._proxy.StartRemote();
        else
            this._proxy.QuitRemote();
    },
*/
    _fillMenu: function() {
        this.menu.removeAll();
        //this._killSwitch = new PopupMenu.PopupSwitchMenuItem(_("GPaste daemon"), true);
        //this._killSwitch.connect('toggled', Lang.bind(this, this._toggleDaemon));
        //this.menu.addMenuItem(this._killSwitch);
        //this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
        this._proxy.GetHistoryRemote(Lang.bind(this, function(history) {
            if (history.length == 0) {
                let emptyItem = new PopupMenu.PopupMenuItem('(Empty)', {reactive: false});
                this.menu.addMenuItem(emptyItem);
            } else {
                let index;
                let limit = 20;
                if (history.length < 20) limit = history.length;
                for (index = 0; index < limit; ++index) {
                    let selection = new PopupMenu.PopupMenuItem(history[index].replace('\n', ' '));
                    let label = selection.label;
                    let inner_index = index;
                    label.clutter_text.max_length = 60;
                    label.clutter_text.ellipsize = Pango.EllipsizeMode.END;
                    //selection.actor.button_mask = St.ButtonMask.ONE | St.ButtonMask.THREE;
                    selection.connect('activate', Lang.bind(this, function(actor, event) {
                        this._select(inner_index);
                    }));
                    let deletor = new St.Button({label: 'x'});
                    deletor.connect('clicked', Lang.bind(this, function(actor, event) {
                        this._delete(inner_index);
                    }));
                    selection.indicator = deletor;
                    selection.addActor(deletor);
                    this.menu.addMenuItem(selection);
                }
                this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
                let emptyItem = new PopupMenu.PopupMenuItem('Empty history');
                emptyItem.connect('activate', Lang.bind(this, this._empty));
                this.menu.addMenuItem(emptyItem)
            }
        }));
    }
};

function main() {
    let indicator = new Indicator();
    STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['gpaste'] = Indicator();
    Main.panel._statusBox.add(indicator.actor);
    Main.panel._menus.addMenu(indicator.menu);
}
<|endoftext|>


<commit_before>var number = require('./number'),
    string = require('./string'),
    bool = require('./boolean');

/**
 * Clone an object
 *
 *     clone(x)
 *
 * @param {*} x
 * @return {*} clone
 */
exports.clone = function clone(x) {
  if (x == null) {
    // null or undefined
    return x;
  }

  if (typeof(x.clone) === 'function') {
    return x.clone();
  }

  if (number.isNumber(x) || string.isString(x) || bool.isBoolean(x)) {
    return x;
  }

  if (Array.isArray(x)) {
    return x.map(function (value) {
      return clone(value);
    });
  }

  if (x instanceof Object) {
    if (x instanceof Number) {
      return new Number(x);
    }
    if (x instanceof String) {
      return new String(x);
    }
    if (x instanceof Boolean) {
      return new Boolean(x);
    }

    var m = {};
    for (var key in x) {
      if (x.hasOwnProperty(key)) {
        m[key] = clone(x[key]);
      }
    }
    return x;
  }

  throw new TypeError('Cannot clone ' + x);
};

/**
 * Extend object a with the properties of object b
 * @param {Object} a
 * @param {Object} b
 * @return {Object} a
 */
exports.extend = function extend (a, b) {
  for (var prop in b) {
    if (b.hasOwnProperty(prop)) {
      a[prop] = b[prop];
    }
  }
  return a;
};

/**
 * Deep extend an object a with the properties of object b
 * @param {Object} a
 * @param {Object} b
 * @returns {Object}
 */
exports.deepExtend = function deepExtend (a, b) {
  for (var prop in b) {
    if (b.hasOwnProperty(prop)) {
      if (b[prop] && b[prop].constructor === Object) {
        if (a[prop] === undefined) {
          a[prop] = {};
        }
        if (a[prop].constructor === Object) {
          deepExtend(a[prop], b[prop]);
        }
        else {
          a[prop] = b[prop];
        }
      } else {
        a[prop] = b[prop];
      }
    }
  }
  return a;
};

/**
 * Deep test equality of all fields in two pairs of arrays or objects.
 * @param {Array | Object} a
 * @param {Array | Object} b
 * @returns {boolean}
 */
exports.deepEqual = function deepEqual (a, b) {
  var prop, i, len;
  if (Array.isArray(a)) {
    if (!Array.isArray(b)) {
      return false;
    }

    if (a.length != b.length) {
      return false;
    }

    for (i = 0, len = a.length; i < len; i++) {
      if (!exports.deepEqual(a[i], b[i])) {
        return false;
      }
    }
    return true;
  }
  else if (a instanceof Object) {
    if (Array.isArray(b) || !(b instanceof Object)) {
      return false;
    }

    for (prop in a) {
      if (a.hasOwnProperty(prop)) {
        if (!exports.deepEqual(a[prop], b[prop])) {
          return false;
        }
      }
    }
    for (prop in b) {
      if (b.hasOwnProperty(prop)) {
        if (!exports.deepEqual(a[prop], b[prop])) {
          return false;
        }
      }
    }
    return true;
  }
  else {
    return (a == b);
  }
};
<commit_msg>Minor improvement in object.clone<commit_after>/**
 * Clone an object
 *
 *     clone(x)
 *
 * Can clone any primitive type, array, and object.
 * If x has a function clone, this function will be invoked to clone the object.
 *
 * @param {*} x
 * @return {*} clone
 */
exports.clone = function clone(x) {
  var type = typeof x;

  if (type === 'number' || type === 'string' || type === 'boolean' ||
      x === null || x === undefined) {
    // immutable primitive types
    return x;
  }

  // use clone function of the object when available
  if (typeof x.clone === 'function') {
    return x.clone();
  }

  // array
  if (Array.isArray(x)) {
    return x.map(function (value) {
      return clone(value);
    });
  }

  // object
  if (x instanceof Object) {
    var m = {};
    for (var key in x) {
      if (x.hasOwnProperty(key)) {
        m[key] = clone(x[key]);
      }
    }
    return x;
  }

  // this should never happen
  throw new TypeError('Cannot clone ' + x);
};

/**
 * Extend object a with the properties of object b
 * @param {Object} a
 * @param {Object} b
 * @return {Object} a
 */
exports.extend = function extend (a, b) {
  for (var prop in b) {
    if (b.hasOwnProperty(prop)) {
      a[prop] = b[prop];
    }
  }
  return a;
};

/**
 * Deep extend an object a with the properties of object b
 * @param {Object} a
 * @param {Object} b
 * @returns {Object}
 */
exports.deepExtend = function deepExtend (a, b) {
  for (var prop in b) {
    if (b.hasOwnProperty(prop)) {
      if (b[prop] && b[prop].constructor === Object) {
        if (a[prop] === undefined) {
          a[prop] = {};
        }
        if (a[prop].constructor === Object) {
          deepExtend(a[prop], b[prop]);
        }
        else {
          a[prop] = b[prop];
        }
      } else {
        a[prop] = b[prop];
      }
    }
  }
  return a;
};

/**
 * Deep test equality of all fields in two pairs of arrays or objects.
 * @param {Array | Object} a
 * @param {Array | Object} b
 * @returns {boolean}
 */
exports.deepEqual = function deepEqual (a, b) {
  var prop, i, len;
  if (Array.isArray(a)) {
    if (!Array.isArray(b)) {
      return false;
    }

    if (a.length != b.length) {
      return false;
    }

    for (i = 0, len = a.length; i < len; i++) {
      if (!exports.deepEqual(a[i], b[i])) {
        return false;
      }
    }
    return true;
  }
  else if (a instanceof Object) {
    if (Array.isArray(b) || !(b instanceof Object)) {
      return false;
    }

    for (prop in a) {
      if (a.hasOwnProperty(prop)) {
        if (!exports.deepEqual(a[prop], b[prop])) {
          return false;
        }
      }
    }
    for (prop in b) {
      if (b.hasOwnProperty(prop)) {
        if (!exports.deepEqual(a[prop], b[prop])) {
          return false;
        }
      }
    }
    return true;
  }
  else {
    return (a == b);
  }
};
<|endoftext|>


<commit_before>$('
').attr('id', 'panelbox').prependTo(document.body);
/* $('
').attr('id','panel').appendTo('#engine');
$('
').attr('id','code').appendTo('#engine');*/
/* looper number */
var panelid = 0;
/* create div tag panelbox and assign it with unique id */
$('
').attr('id', 'node' + panelid).appendTo('#panelbox');
/* creates form for buttons to create elements */
$('<form>').attr('id', 'node' + panelid).appendTo('#panelbox' + panelid)
panelid++;
$('
').appendTo('#panelbox');
//$('
').attr('id','precodediv').appendTo('#engine');
$('<button>').attr('id', 'input').text('Input').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'textarea').text('Textarea').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'radioggrp').text('Radio Group').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'radio').text('Radio').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'checkbox').text('Checkbox').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'password').text('Password').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'hidden').text('Hidden').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'dropmenu').text('Dropmenu').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'option').text('Option').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'break').text('Break').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'button').text('Submit').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'clear').text('Clear').attr('class', 'panelengine').appendTo(
  '#panel');
/* $('.panelengine').each(function() {
	$(this).after( $(document.createElement('br')) );
}); */
$('
').appendTo('#panel');

function grouprad() {
  radgrp++;
  return false;
}

function makeoption() {
  selectnum++;
  $('<option>').attr('value', 'option' + selectnum).text('option' + selectnum).appendTo(
    '#select' + dropnum);
  return false;
}
$('#input').click(function () {
  inputnum++;
  $('<input type="text">').attr('id', 'input' + inputnum).attr('placeholder',
    'input' + inputnum).appendTo('#form' + formnum);
  return false;
});
$('#textarea').click(function () {
  txnum++;
  $('<textarea>').attr('id', 'textarea' + txnum).attr('placeholder', 'text' +
    txnum + ' to be entered').appendTo('#form' + formnum);
  return false;
});
$('#radio').click(function () {
  radnum++;
  $('').text('radio' + radnum).append($('<input type="radio">').attr(
    'id', 'grp' + radgrp).attr('value', 'radio' + radnum)).appendTo('#form' +
    formnum);
  return false;
});
$('#checkbox').click(function () {
  ckboxnum++;
  $('').text(' ck' + ckboxnum + ' ').append($(
    '<input type="checkbox">').attr('id', 'ck' + ckboxnum)).appendTo('#form' +
    formnum);
  return false;
});
$('#password').click(function () {
  passnum++;
  $('<input type="password">').attr('id', 'password' + passnum).attr('value',
    'password' + passnum).attr('placeholder', 'password' + passnum).appendTo(
    '#form' + formnum);
  return false;
});
$('#hidden').click(function () {
  hidnum++;
  $('<input type="hidden">').attr('id', 'hidden' + hidnum).attr('value',
    'value' + hidnum).appendTo('#form' + formnum);
  return false;
});
$('#dropmenu').click(function () {
  dropnum++;
  $('<select>').attr('id', 'select' + dropnum).appendTo('#form' + formnum);
  makeoption();
  makeoption();
  return false;
});
$('#break').click(function () {
  $('
').appendTo('#form' + formnum);
  return false;
});
$('#button').click(function () {
  $('#msgbox').html(
    '

Now you can click on submit button on the form to see what is being sent to server in URL code.

Click on the code below will enable you to see the full HTML codes of this form.

Hint: Fill out the form as if it was for the real and then resubmit - you will see the URL codes with all inputs.

'
  );
  $('#getcode').show();
  buttnum++;
  $('<button>').attr('id', 'submit' + buttnum).text('submit').attr('value',
    'req' + buttnum).appendTo('#form' + formnum);
  return false;
});
$('#option').click(function () {
  makeoption();
});
$('#radioggrp').click(function () {
  grouprad();
});
$('#clear').click(function () {
  inputnum = 0;
  radnum = 0;
  radgrp = 0;
  ckboxnum = 0;
  selectnum = 0;
  txnum = 0, hidnum = 0, dropnum = 0, formnum = 0;
  buttnum = 0;
  passnum = 0;
  $('#precode').empty();
  $('#seralize').empty();
  $('#sql0').empty();
});
$("
").attr("id", "msgbox").html(
  '
Begin by formulaing your form to your own liking - be sure to add "submit button" from above when you are done.
'
).css("font-size", "14px").css("text-weight", "bold").css("color", "gray").css(
  "font-family", "arial").appendTo("#code");
$("<button>").attr("id", "getcode").text("Code").hide().appendTo("#code");
//$('<button>').attr('id','getserialize').text('seralize').appendTo('#code');
$('
').attr('id', 'precode').appendTo('#sql0');
$('').attr('id', 'realcodes').css('whiteSpace', 'pre-wrap').appendTo(
  '#precode');
$('
').attr('id', 'seralize').appendTo('#sql0');
$('
').attr('id', 'showurl').appendTo('#seralize');
$('
').attr('id', 'showcodejson').appendTo('#seralize');
$('#getcode').click(function () {
  String.prototype.escapeHTML = function () {
    return (this.replace(/>/g, '>').replace(/</g, '<').replace(/"/g,
      '"'));
  };
  var codeEl = $('#form0').html();
  $('#realcodes').text(codeEl);
}); //end of click event for 'get code'
$('#form' + formnum).submit(function (e) {
  e.preventDefault(e);
  var data = {};
  //Gathering the Data
  $.each(this.elements, function (i, v) {
    var input = $(v);
    if (input.is(':checkbox')) {
      if (input.is(':checked')) {
        data[input.attr("id")] = input.val();
      }
    } else {
      data[input.attr("id")] = input.val();
    }
  }); // end of $.each
  var output = JSON.stringify(data);
  $('#showurl').text(output);
}); //end of click event for 'showurl'
<commit_msg>auto-committing via script<commit_after>$('
').attr('id', 'panelbox').prependTo(document.body);
/* $('
').attr('id','panel').appendTo('#engine');
$('
').attr('id','code').appendTo('#engine');*/
/* looper number */
var panelid = 0;
/* create div tag panelbox and assign it with unique id */
$('
').attr('id', 'node' + panelid).appendTo('#panelbox');
/* creates form for buttons to create elements */
$('<form>').attr('id', 'node' + panelid).appendTo('#panelbox' + panelid)
panelid++;
$('
').appendTo('#panelbox');
//$('
').attr('id','precodediv').appendTo('#engine');
$('<button>').attr('id', 'input').text('Input').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'textarea').text('Textarea').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'radioggrp').text('Radio Group').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'radio').text('Radio').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'checkbox').text('Checkbox').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'password').text('Password').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'hidden').text('Hidden').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'dropmenu').text('Dropmenu').attr('class',
  'panelengine').appendTo('#panel');
$('<button>').attr('id', 'option').text('Option').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'break').text('Break').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'button').text('Submit').attr('class', 'panelengine').appendTo(
  '#panel');
$('<button>').attr('id', 'clear').text('Clear').attr('class', 'panelengine').appendTo(
  '#panel');
/* $('.panelengine').each(function() {
  $(this).after( $(document.createElement('br')) );
}); */
$('
').appendTo('#panel');

function grouprad() {
  radgrp++;
  return false;
}

function makeoption() {
  selectnum++;
  $('<option>').attr('value', 'option' + selectnum).text('option' + selectnum).appendTo(
    '#select' + dropnum);
  return false;
}
$('#input').click(function () {
  inputnum++;
  $('<input type="text">').attr('id', 'input' + inputnum).attr('placeholder',
    'input' + inputnum).appendTo('#form' + formnum);
  return false;
});
$('#textarea').click(function () {
  txnum++;
  $('<textarea>').attr('id', 'textarea' + txnum).attr('placeholder', 'text' +
    txnum + ' to be entered').appendTo('#form' + formnum);
  return false;
});
$('#radio').click(function () {
  radnum++;
  $('').text('radio' + radnum).append($('<input type="radio">').attr(
    'id', 'grp' + radgrp).attr('value', 'radio' + radnum)).appendTo('#form' +
    formnum);
  return false;
});
$('#checkbox').click(function () {
  ckboxnum++;
  $('').text(' ck' + ckboxnum + ' ').append($('<input type="checkbox">')
    .attr('id', 'ck' + ckboxnum)).appendTo('#form' + formnum);
  return false;
});
$('#password').click(function () {
  passnum++;
  $('<input type="password">').attr('id', 'password' + passnum).attr('value',
    'password' + passnum).attr('placeholder', 'password' + passnum).appendTo(
    '#form' + formnum);
  return false;
});
$('#hidden').click(function () {
  hidnum++;
  $('<input type="hidden">').attr('id', 'hidden' + hidnum).attr('value',
    'value' + hidnum).appendTo('#form' + formnum);
  return false;
});
$('#dropmenu').click(function () {
  dropnum++;
  $('<select>').attr('id', 'select' + dropnum).appendTo('#form' + formnum);
  makeoption();
  makeoption();
  return false;
});
$('#break').click(function () {
  $('
').appendTo('#form' + formnum);
  return false;
});
$('#button').click(function () {
  $('#msgbox').html(
    '

Now you can click on submit button on the form to see what is being sent to server in URL code.

Click on the code below will enable you to see the full HTML codes of this form.

Hint: Fill out the form as if it was for the real and then resubmit - you will see the URL codes with all inputs.

'
  );
  $('#getcode').show();
  buttnum++;
  $('<button>').attr('id', 'submit' + buttnum).text('submit').attr('value',
    'req' + buttnum).appendTo('#form' + formnum);
  return false;
});
$('#option').click(function () {
  makeoption();
});
$('#radioggrp').click(function () {
  grouprad();
});
$('#clear').click(function () {
  inputnum = 0;
  radnum = 0;
  radgrp = 0;
  ckboxnum = 0;
  selectnum = 0;
  txnum = 0, hidnum = 0, dropnum = 0, formnum = 0;
  buttnum = 0;
  passnum = 0;
  $('#precode').empty();
  $('#seralize').empty();
  $('#sql0').empty();
});
$("
").attr("id", "msgbox").html(
  '
Begin by formulaing your form to your own liking - be sure to add "submit button" from above when you are done.
'
).css("font-size", "14px").css("text-weight", "bold").css("color", "gray").css(
  "font-family", "arial").appendTo("#code");
$("<button>").attr("id", "getcode").text("Code").hide().appendTo("#code");
//$('<button>').attr('id','getserialize').text('seralize').appendTo('#code');
$('
').attr('id', 'precode').appendTo('#sql0');
$('').attr('id', 'realcodes').css('whiteSpace', 'pre-wrap').appendTo(
  '#precode');
$('
').attr('id', 'seralize').appendTo('#sql0');
$('
').attr('id', 'showurl').appendTo('#seralize');
$('
').attr('id', 'showcodejson').appendTo('#seralize');
$('#getcode').click(function () {
  String.prototype.escapeHTML = function () {
    return (this.replace(/>/g, '>').replace(/</g, '<').replace(/"/g,
      '"'));
  };
  var codeEl = $('#form0').html();
  $('#realcodes').text(codeEl);
}); //end of click event for 'get code'
$('#form' + formnum).submit(function (e) {
  e.preventDefault(e);
  var data = {};
  //Gathering the Data
  $.each(this.elements, function (i, v) {
    var input = $(v);
    if (input.is(':checkbox')) {
      if (input.is(':checked')) {
        data[input.attr("id")] = input.val();
      }
    } else {
      data[input.attr("id")] = input.val();
    }
  }); // end of $.each
  var output = JSON.stringify(data);
  $('#showurl').text(output);
}); //end of click event for 'showurl'<|endoftext|>


<commit_before>var FileInput = React.createClass({
	propTypes: {
		onChange: React.PropTypes.func.isRequired
	},
	render: function(){
		return <input type='file' id='file' onChange={this.props.onChange} />;
	}
})

var CharacterProfile = React.createClass({
	render: function(){
		return (

HP: {this.props.hp} / {this.props.maxHp}

Mana: {this.props.mp} / {this.props.maxMp}

Armor Class: {this.props.armorClass}

Experience: {this.props.exp}

Strength: {this.props.str}

Intelligence: {this.props.int}

Constitution: {this.props.con}

Dextery: {this.props.dex}

		);
	}
});

var MainEditor = React.createClass({
	getInitialState: function(){
		return {};
	},
	savefileSelected: function(e) {
		var reader = new FileReader();
		var self = this;
		reader.onload = (function(theFile) {
			console.log(reader.result.byteLength + ' bytes');
			console.log(self);
			var dataView = new DataView(reader.result);
			// source: https://www.gamefaqs.com/pc/574556-castle-of-the-winds-1-a-question-of-vengeance/faqs/2405
			self.setState({
				str: dataView.getInt8(0x80),
				int: dataView.getInt8(0x81),
				con: dataView.getInt8(0x82),
				dex: dataView.getInt8(0x83),
				strBase: dataView.getInt8(0x84),
				intBase: dataView.getInt8(0x85),
				conBase: dataView.getInt8(0x86),
				dexBase: dataView.getInt8(0x87),

				hp: dataView.getInt16(0x94, true),
				maxHp: dataView.getInt16(0x96, true),
				mp: dataView.getInt16(0x98, true),
				maxMp: dataView.getInt16(0x9A, true),
				armorClass: dataView.getInt16(0xA6, true),

				exp: dataView.getInt32(0x9E, true),
				expAlt: dataView.getInt32(0xA2, true)
			});
		});
		reader.readAsArrayBuffer(e.target.files[0]);
	},
	render: function(){
		return (

				<FileInput onChange={this.savefileSelected} />
				<CharacterProfile
					str={this.state.str} int={this.state.int} con={this.state.con} dex={this.state.dex}
					hp={this.state.hp} maxHp={this.state.maxHp}
					mp={this.state.mp} maxMp={this.state.maxMp}
					exp={this.state.exp} armorClass={this.state.armorClass} />

		);
	}
});

ReactDOM.render(<MainEditor />, document.getElementById('react-app'));<commit_msg>Define savegame fields in a explicit way<commit_after>// source: https://www.gamefaqs.com/pc/574556-castle-of-the-winds-1-a-question-of-vengeance/faqs/2405
// fieldName: [offset, numberOfBytes (littleEndian)]
var FIELDS = {
	str: [0x80, 1],
	int: [0x81, 1],
	con: [0x82, 1],
	dex: [0x83, 1],
	strBase: [0x84, 1],
	intBase: [0x85, 1],
	conBase: [0x86, 1],
	dexBase: [0x87, 1],

	hp: [0x94, 2],
	maxHp: [0x96, 2],
	mp: [0x98, 2],
	maxMp: [0x9A, 2],
	level: [0x9C, 2],
	armorClass: [0xA6, 2],

	exp: [0x9E, 4],
	expAlt: [0xA2, 4],

	// spells: {
	// 	heaMinorWounds: [0x1B2, 1],
	// 	fireBall: [0x31A, 1]
	// },

	// spellsSlots:
	// 	[
	// 		[0x38E, 2], [0x390, 2], [0x392, 2], [0x394, 2], [0x396, 2], [0x398, 2], [0x39A, 2], [0x39C, 2], [0x39E, 2], [0x3A0, 2]
	// 	]
}

var FileInput = React.createClass({
	propTypes: {
		onChange: React.PropTypes.func.isRequired
	},
	render: function(){
		return <input type='file' id='file' onChange={this.props.onChange} />;
	}
})

var CharacterProfile = React.createClass({
	render: function(){
		return (

HP: {this.props.hp} / {this.props.maxHp}

Mana: {this.props.mp} / {this.props.maxMp}

Armor Class: {this.props.armorClass}

Experience: {this.props.exp}

Strength: {this.props.str}

Intelligence: {this.props.int}

Constitution: {this.props.con}

Dextery: {this.props.dex}

		);
	}
});

var MainEditor = React.createClass({
	getInitialState: function(){
		return {};
	},
	savefileSelected: function(e) {
		var reader = new FileReader();
		var self = this;
		reader.onload = (function(theFile) {
			console.log(reader.result.byteLength + ' bytes');
			var dataView = new DataView(reader.result);
			var state = {};
			for(var property in FIELDS){
				if(FIELDS.hasOwnProperty(property)){
					var [offset, numBytes] = FIELDS[property];
					if (numBytes === 1){
						state[property] = dataView.getInt8(offset);
					} else if (numBytes === 2){
						state[property] = dataView.getInt16(offset, true);
					} else if (numBytes === 4){
						state[property] = dataView.getInt32(offset, true);
					}
				}
			}
			self.setState(state);
			console.log(self.state);
		});
		reader.readAsArrayBuffer(e.target.files[0]);
	},
	render: function(){
		return (

				<FileInput onChange={this.savefileSelected} />
				<CharacterProfile
					str={this.state.str} int={this.state.int} con={this.state.con} dex={this.state.dex}
					hp={this.state.hp} maxHp={this.state.maxHp}
					mp={this.state.mp} maxMp={this.state.maxMp}
					exp={this.state.exp} armorClass={this.state.armorClass} />

		);
	}
});

ReactDOM.render(<MainEditor />, document.getElementById('react-app'));<|endoftext|>


<commit_before>/** Angular App Code */
(function() {
	var app = angular.module('brynn', [ ]);

	app.controller('EnchantController', ['$scope', function($scope) {
		var scope = $scope;
		this.magic = 0;
		this.successStart = 25;
		this.successEnd = 40;
		this.success = this.successStart;
		this.selectedElixir = null;
		scope.brEmpty = 100;
		scope.brFull = 0;
		var fill = $("#fill");
		var brEmptyText = $("#brEmpty");
		var brFullText = $("#brFull");
		var brValues = {empty:100, full:0};

		this.calcSuccess = function() {
			if (this.magic <= 100)
				this.success = Math.floor(this.successStart + (this.successEnd - this.successStart) * (this.magic / 100.0));
			else
				this.success = this.successStart;
		}

		this.updateBrText = function() {
			if (brValues.empty < 41)
				brEmptyText.css("display", "none");
			if (brValues.full >= 41)
				brFullText.css("display", "initial");
			scope.$apply(function() {
				scope.brEmpty = Math.floor(brValues.empty);
				scope.brFull = Math.floor(brValues.full);
			});
		}

		this.addMagic = function(br) {
			this.magic = this.magic + br;
			this.calcSuccess();
			TweenMax.to(fill, 0.5, {
				top:Math.max(143 - 143 * (this.magic / 100), 0),
				ease:Power4.easeOut
			});
			TweenMax.to(brEmptyText, 0.5, {
				top:Math.max(217 - 74 * (this.magic / 100), 0),
				ease:Power4.easeOut
			});
			TweenMax.to(brFullText, 0.5, {
				top:Math.max(291 - 74 * Math.min(this.magic / 100, 1), 0),
				ease:Power4.easeOut
			});
			var emptyTarget = 100 - this.magic;
			var fullTarget = this.magic;
			TweenMax.to(brValues, 0.5, {
				empty:emptyTarget,
				full:fullTarget,
				ease:Power4.easeOut,
				onUpdate:this.updateBrText
			});
		}

		this.addElixir = function(elixir) {
			var brMin;
			var brMax;
			switch (elixir)
			{
				case 1:
					brMin = 1;
					brMax = 10;
					break;
				case 2:
					brMin = 10;
					brMax = 50;
					break;
				case 3:
					brMin = 3;
					brMax = 5;
					break;
				default:
					brMin = 0;
					brMax = 0;
					break;
			}
			this.addMagic(randomInt(brMin, brMax));
		};

		this.cancel = function() {
			TweenMax.killTweensOf(fill);
			TweenMax.killTweensOf(brEmptyText);
			TweenMax.killTweensOf(brFullText);
			TweenMax.killTweensOf(brValues);
			this.magic = 0;
			this.calcSuccess();
			fill.css("top", 143);
			brEmptyText.css("top", 217);
			brFullText.css("top", 291);
			brEmptyText.css("display", "initial");
			brFullText.css("display", "none");
			scope.brEmpty = 100;
			scope.brFull = 0;
			brValues.empty = 100;
			brValues.full = 0;
			this.selectedElixir = null;
		}

		this.begin = function() {

		}
	}]);
})();
<commit_msg>Small adjustment to brFull<commit_after>/** Angular App Code */
(function() {
	var app = angular.module('brynn', [ ]);

	app.controller('EnchantController', ['$scope', function($scope) {
		var scope = $scope;
		this.magic = 0;
		this.successStart = 25;
		this.successEnd = 40;
		this.success = this.successStart;
		this.selectedElixir = null;
		scope.brEmpty = 100;
		scope.brFull = 0;
		var fill = $("#fill");
		var brEmptyText = $("#brEmpty");
		var brFullText = $("#brFull");
		var brValues = {empty:100, full:0};

		this.calcSuccess = function() {
			if (this.magic <= 100)
				this.success = Math.floor(this.successStart + (this.successEnd - this.successStart) * (this.magic / 100.0));
			else
				this.success = this.successStart;
		}

		this.updateBrText = function() {
			if (brValues.empty < 41)
				brEmptyText.css("display", "none");
			if (brValues.full >= 41)
				brFullText.css("display", "initial");
			scope.$apply(function() {
				scope.brEmpty = Math.floor(brValues.empty);
				scope.brFull = Math.ceil(brValues.full);
			});
		}

		this.addMagic = function(br) {
			this.magic = this.magic + br;
			this.calcSuccess();
			TweenMax.to(fill, 0.5, {
				top:Math.max(143 - 143 * (this.magic / 100), 0),
				ease:Power4.easeOut
			});
			TweenMax.to(brEmptyText, 0.5, {
				top:Math.max(217 - 74 * (this.magic / 100), 0),
				ease:Power4.easeOut
			});
			TweenMax.to(brFullText, 0.5, {
				top:Math.max(291 - 74 * Math.min(this.magic / 100, 1), 0),
				ease:Power4.easeOut
			});
			var emptyTarget = 100 - this.magic;
			var fullTarget = this.magic;
			TweenMax.to(brValues, 0.5, {
				empty:emptyTarget,
				full:fullTarget,
				ease:Power4.easeOut,
				onUpdate:this.updateBrText
			});
		}

		this.addElixir = function(elixir) {
			var brMin;
			var brMax;
			switch (elixir)
			{
				case 1:
					brMin = 1;
					brMax = 10;
					break;
				case 2:
					brMin = 10;
					brMax = 50;
					break;
				case 3:
					brMin = 3;
					brMax = 5;
					break;
				default:
					brMin = 0;
					brMax = 0;
					break;
			}
			this.addMagic(randomInt(brMin, brMax));
		};

		this.cancel = function() {
			TweenMax.killTweensOf(fill);
			TweenMax.killTweensOf(brEmptyText);
			TweenMax.killTweensOf(brFullText);
			TweenMax.killTweensOf(brValues);
			this.magic = 0;
			this.calcSuccess();
			fill.css("top", 143);
			brEmptyText.css("top", 217);
			brFullText.css("top", 291);
			brEmptyText.css("display", "initial");
			brFullText.css("display", "none");
			scope.brEmpty = 100;
			scope.brFull = 0;
			brValues.empty = 100;
			brValues.full = 0;
			this.selectedElixir = null;
		}

		this.begin = function() {

		}
	}]);
})();
<|endoftext|>


<commit_before>//
// Preset manager class.  Holds a reference to the current
// preset and manages saving, updating, or clearing it.
//

var OCRJS = OCRJS || {};

OCRJS.PresetManager = OCRJS.OcrBase.extend({
    constructor: function(parent, state) {
        this.base(parent);
        this.parent = parent;

        this.state = state;

        this._dialog = $("#dialog", this.parent);
        this._opentmpl = $.template($("#openDialog"));
        this._opentmplitem = $.template($("#openDialogItem"));
        this._updatetmpl = $.template($("#updateDialog"));
        this._createtmpl = $.template($("#createDialog"));

        this._listeners = {
            saveDialogOpen: [],
            saveDialogClose: [],
            openDialogOpen: [],
            openDialogClose: [],
            openPreset: [],
            newPreset: [],
        };

        // flag telling us we should continue to
        // offer the open dialog after the current
        // save dialog
        this._continueaction = null;

        this.setupEvents();
    },

    setupEvents: function() {
        var self = this;

        $("#new_script, #new_script_button").click(function(event) {
            self.newPreset();
        });

        $("#save_script, #save_script_button").click(function(event) {
            if (self.state.getOpen()) {
                self.saveExistingPreset(self.state.getOpen(),
                    self.state.getTreeScript(), function(data) {
                        self.setCurrentOpenPreset(self.state.getOpen(), self.state.getName(), data, false);
                    });
            } else {
                self.showCreatePresetDialog();
            }
        });

        $("#save_script_as").click(function(event) {
            self.showCreatePresetDialog();
        });

        $("#open_script").click(function(event) {
            self.showOpenPresetDialog();
        });

        $("#download_script").click(function(event) {
            $("#fetch_script_slug").val(self.state.getCurrentSlug());
            $("#fetch_script_data").val(self.state.getTreeJSON());
            $("#fetch_script").submit();
        });

        $("#cancel_dialog").live("click", function(event) {
            self._dialog.dialog("close");
            event.stopPropagation();
            event.preventDefault();
        });
    },

    newPreset: function() {
        console.log("New preset...");
        if (this.state.isDirty()) {
            this._continueaction = this.newPreset;
            this.showUnsavedPresetDialog(!this._opened);
            return;
        }
        this.callListeners("newPreset");
        this.state.clear();
        this._continueaction = null;
    },

    setCurrentOpenPreset: function(slug, name, data, reload) {
        this.state.setOpen(slug, name);
        if (reload) {
            this.state.setScript(data);
        }
    },

    showOpenPresetDialog: function() {
        var self = this;
        console.log("Showing open preset dialog...");

        if (this.state.isDirty()) {
            this._continueaction = this.showOpenPresetDialog;
            this.showUnsavedPresetDialog();
            return;
        }

        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._opentmpl, {}));

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            position: pos,
            width: tb.width(),
            modal: true,
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("openDialogClose");
            },
        });
        $.getJSON("/presets/list/", {
                format: "json",
                paginate_by: -1,
            }, function(data) {
            console.log("Preset data", data);
            $.each(data, function(i, preset) {
                $("#open_preset_list", self._dialog).append(
                    $.tmpl(self._opentmplitem, preset)
                );
            });
            $("li", "#open_preset_list").textOverflow("...", true);
            $("#open_preset_list").selectable({
                selected: function(event, ui) {
                    self.validateOpenSelection();
                },
            });
        });
        this._dialog.find("input[type='submit']").click(function(event) {
            var item =  self._dialog.find(".preset_item.ui-selected").first();
            var slug = item.data("slug");
            self.openPreset(slug, function(data) {
                self.callListeners("openPreset");
                self.setCurrentOpenPreset(slug, $.trim(item.text()), data, true);
                self._dialog.dialog("close");
                self._continueaction = null;
            }, OCRJS.ajaxErrorHandler);
            event.preventDefault();
            event.stopPropagation();
        });
    },

    showUnsavedPresetDialog: function(saveas) {
        console.log("Showing unsaved preset dialog...");
        var self = this;
        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._updatetmpl, {}));
        this._dialog.find("#submit_save_script").attr("disabled", saveas);
        this._dialog.find("#submit_save_script").click(function(event) {
            var data = self.state.getTreeScript();
            self.saveExistingPreset(self._opened, data, function(data) {
                self.setCurrentOpenPreset(self._opened, name, data, false);
                self._dialog.dialog("close");
                if (self._continueaction)
                    self._continueaction()
            }, OCRJS.ajaxErrorHandler);
        });
        this._dialog.find("#submit_save_script_as").click(function(event) {
            self.showCreatePresetDialog();
        });
        this._dialog.find("#submit_close_without_saving").click(function(event) {
            console.log("Abandoned changes!");
            self.state.clear();
            self._dialog.dialog("close");
            if (self._continueaction)
                self._continueaction();
        });

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            modal: true,
            position: pos,
            width: tb.width(),
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("saveDialogClose");
            },
        });
    },

    showCreatePresetDialog: function() {
        console.log("Showing create preset dialog...");
        var self = this;
        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._createtmpl, {}));
        this._dialog.find("input[type='text']").keyup(function(event) {
            self.validateNewForm();
        });
        this._dialog.find("#submit_create_new").click(function(event) {
            event.preventDefault();
            event.stopPropagation();
            var currdata = self.state.getTreeScript();
            self.saveCreatedPreset(
                self._dialog.find("#id_name").val(),
                self._dialog.find("#id_tags").val(),
                self._dialog.find("#id_description").val(),
                self._dialog.find("#id_public").prop("checked"),
                currdata,
                function(data) {
                    self.setCurrentOpenPreset(data,
                            self._dialog.find("#id_name").val(), currdata, false)
                    self._dialog.dialog("close");
                    if (self._continueaction)
                        self._continueaction();
                },
                OCRJS.ajaxErrorHandler
            );
        });

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            modal: true,
            position: pos,
            width: tb.width(),
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("saveDialogClose");
            },
        });
        this.callListeners("saveDialogOpen");
    },

    validateOpenSelection: function() {
        var selection = this._dialog.find(".preset_item.ui-selected");
        var submit = this._dialog.find("#submit_open_preset");
        submit.attr("disabled", selection.length != 1);
    },

    validateNewForm: function() {
        var namefield = this._dialog.find("#id_name");
        var submit = this._dialog.find("#submit_create_new");
        submit.attr("disabled", $.trim(namefield.val()) == "");
    },

    saveExistingPreset: function(slug, script, successfunc, errorfunc) {
        if (!script || $.map(script, function(k,v){ return k;}).length == 0)
            throw "Attempt to save existing preset with no data! " + slug;
        $.ajax({
            url: "/presets/update_data/" + slug,
            data: {data: JSON.stringify(script, null, 2)},
            type: "POST",
            error: errorfunc,
            success: successfunc,
        });
    },

    saveCreatedPreset: function(name, tags, description, private, script, successfunc, errorfunc) {
        if (!script || $.map(script, function(k,v){ return k;}).length == 0)
            throw "Attempt to save new preset with no data! " + name;
        $.ajax({
            url: "/presets/createjson/",
            type: "POST",
            data: {
                name: name,
                tags: tags,
                description: description,
                private: private,
                data: JSON.stringify(script, null, 2),
            },
            error: errorfunc,
            statusCode: {
                200: function(data) {
                    console.error("200", data);
                },
                201: successfunc,
            },
        });
    },

    openPreset: function(slug, successfunc, errorfunc) {
        $.ajax({
            url: "/presets/data/" + slug,
            data: {format: "json"},
            success: successfunc,
            error: errorfunc,
        });
    },
});
<commit_msg>Allow opening presets with a double click<commit_after>//
// Preset manager class.  Holds a reference to the current
// preset and manages saving, updating, or clearing it.
//

var OCRJS = OCRJS || {};

OCRJS.PresetManager = OCRJS.OcrBase.extend({
    constructor: function(parent, state) {
        this.base(parent);
        this.parent = parent;

        this.state = state;

        this._dialog = $("#dialog", this.parent);
        this._opentmpl = $.template($("#openDialog"));
        this._opentmplitem = $.template($("#openDialogItem"));
        this._updatetmpl = $.template($("#updateDialog"));
        this._createtmpl = $.template($("#createDialog"));

        this._listeners = {
            saveDialogOpen: [],
            saveDialogClose: [],
            openDialogOpen: [],
            openDialogClose: [],
            openPreset: [],
            newPreset: [],
        };

        // flag telling us we should continue to
        // offer the open dialog after the current
        // save dialog
        this._continueaction = null;

        this.setupEvents();
    },

    setupEvents: function() {
        var self = this;

        $("#new_script, #new_script_button").click(function(event) {
            self.newPreset();
        });

        $("#save_script, #save_script_button").click(function(event) {
            if (self.state.getOpen()) {
                self.saveExistingPreset(self.state.getOpen(),
                    self.state.getTreeScript(), function(data) {
                        self.setCurrentOpenPreset(self.state.getOpen(), self.state.getName(), data, false);
                    });
            } else {
                self.showCreatePresetDialog();
            }
        });

        $("#save_script_as").click(function(event) {
            self.showCreatePresetDialog();
        });

        $("#open_script").click(function(event) {
            self.showOpenPresetDialog();
        });

        $("#download_script").click(function(event) {
            $("#fetch_script_slug").val(self.state.getCurrentSlug());
            $("#fetch_script_data").val(self.state.getTreeJSON());
            $("#fetch_script").submit();
        });

        $("#cancel_dialog").live("click", function(event) {
            self._dialog.dialog("close");
            event.stopPropagation();
            event.preventDefault();
        });
    },

    newPreset: function() {
        console.log("New preset...");
        if (this.state.isDirty()) {
            this._continueaction = this.newPreset;
            this.showUnsavedPresetDialog(!this._opened);
            return;
        }
        this.callListeners("newPreset");
        this.state.clear();
        this._continueaction = null;
    },

    setCurrentOpenPreset: function(slug, name, data, reload) {
        this.state.setOpen(slug, name);
        if (reload) {
            this.state.setScript(data);
        }
    },

    showOpenPresetDialog: function() {
        var self = this;
        console.log("Showing open preset dialog...");

        if (this.state.isDirty()) {
            this._continueaction = this.showOpenPresetDialog;
            this.showUnsavedPresetDialog();
            return;
        }

        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._opentmpl, {}));

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            position: pos,
            width: tb.width(),
            modal: true,
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("openDialogClose");
            },
        });

        $.getJSON("/presets/list/", {
                format: "json",
                paginate_by: -1,
            }, function(data) {
            console.log("Preset data", data);
            $.each(data, function(i, preset) {
                $("#open_preset_list", self._dialog).append(
                    $.tmpl(self._opentmplitem, preset)
                );
            });
            $("li", "#open_preset_list").textOverflow("...", true);
            $("#open_preset_list").selectable({
                selected: function(event, ui) {
                    self.validateOpenSelection();
                },
            }).find("li").dblclick(function(event) {
                self._openPresetFromList($(this));
            });
        });
        this._dialog.find("input[type='submit']").click(function(event) {
            var item =  self._dialog.find(".preset_item.ui-selected").first();
            self._openPresetFromList(item);
        });
    },

    _openPresetFromList: function(item) {
        var self = this;
        var slug = item.data("slug");
        console.log("Opening preset", item);
        this.openPreset(slug, function(data) {
            self.callListeners("openPreset");
            self.setCurrentOpenPreset(slug, $.trim(item.text()), data, true);
            self._dialog.dialog("close");
            self._continueaction = null;
        }, OCRJS.ajaxErrorHandler);
        event.preventDefault();
        event.stopPropagation();
    },

    showUnsavedPresetDialog: function(saveas) {
        console.log("Showing unsaved preset dialog...");
        var self = this;
        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._updatetmpl, {}));
        this._dialog.find("#submit_save_script").attr("disabled", saveas);
        this._dialog.find("#submit_save_script").click(function(event) {
            var data = self.state.getTreeScript();
            self.saveExistingPreset(self._opened, data, function(data) {
                self.setCurrentOpenPreset(self._opened, name, data, false);
                self._dialog.dialog("close");
                if (self._continueaction)
                    self._continueaction()
            }, OCRJS.ajaxErrorHandler);
        });
        this._dialog.find("#submit_save_script_as").click(function(event) {
            self.showCreatePresetDialog();
        });
        this._dialog.find("#submit_close_without_saving").click(function(event) {
            console.log("Abandoned changes!");
            self.state.clear();
            self._dialog.dialog("close");
            if (self._continueaction)
                self._continueaction();
        });

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            modal: true,
            position: pos,
            width: tb.width(),
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("saveDialogClose");
            },
        });
    },

    showCreatePresetDialog: function() {
        console.log("Showing create preset dialog...");
        var self = this;
        var tb = $(this.parent);
        var pos = [tb.offset().left, tb.offset().top + tb.height()];
        this._dialog.html($.tmpl(this._createtmpl, {}));
        this._dialog.find("input[type='text']").keyup(function(event) {
            self.validateNewForm();
        });
        this._dialog.find("#submit_create_new").click(function(event) {
            event.preventDefault();
            event.stopPropagation();
            var currdata = self.state.getTreeScript();
            self.saveCreatedPreset(
                self._dialog.find("#id_name").val(),
                self._dialog.find("#id_tags").val(),
                self._dialog.find("#id_description").val(),
                self._dialog.find("#id_public").prop("checked"),
                currdata,
                function(data) {
                    self.setCurrentOpenPreset(data,
                            self._dialog.find("#id_name").val(), currdata, false)
                    self._dialog.dialog("close");
                    if (self._continueaction)
                        self._continueaction();
                },
                OCRJS.ajaxErrorHandler
            );
        });

        this._dialog.dialog({
            dialogClass: "preset_manager_dialog",
            modal: true,
            position: pos,
            width: tb.width(),
            close: function(e, ui) {
                self._dialog.children().remove();
                self.callListeners("saveDialogClose");
            },
        });
        this.callListeners("saveDialogOpen");
    },

    validateOpenSelection: function() {
        var selection = this._dialog.find(".preset_item.ui-selected");
        var submit = this._dialog.find("#submit_open_preset");
        submit.attr("disabled", selection.length != 1);
    },

    validateNewForm: function() {
        var namefield = this._dialog.find("#id_name");
        var submit = this._dialog.find("#submit_create_new");
        submit.attr("disabled", $.trim(namefield.val()) == "");
    },

    saveExistingPreset: function(slug, script, successfunc, errorfunc) {
        if (!script || $.map(script, function(k,v){ return k;}).length == 0)
            throw "Attempt to save existing preset with no data! " + slug;
        $.ajax({
            url: "/presets/update_data/" + slug,
            data: {data: JSON.stringify(script, null, 2)},
            type: "POST",
            error: errorfunc,
            success: successfunc,
        });
    },

    saveCreatedPreset: function(name, tags, description, private, script, successfunc, errorfunc) {
        if (!script || $.map(script, function(k,v){ return k;}).length == 0)
            throw "Attempt to save new preset with no data! " + name;
        $.ajax({
            url: "/presets/createjson/",
            type: "POST",
            data: {
                name: name,
                tags: tags,
                description: description,
                private: private,
                data: JSON.stringify(script, null, 2),
            },
            error: errorfunc,
            statusCode: {
                200: function(data) {
                    console.error("200", data);
                },
                201: successfunc,
            },
        });
    },

    openPreset: function(slug, successfunc, errorfunc) {
        $.ajax({
            url: "/presets/data/" + slug,
            data: {format: "json"},
            success: successfunc,
            error: errorfunc,
        });
    },
});
<|endoftext|>


<commit_before>//parse Empty Node as self closing node
var he = require("he");

var defaultOptions = {
    attributeNamePrefix : "@_",
    attrNodeName: false,
    textNodeName : "#text",
    ignoreAttributes : true,
    encodeHTMLchar: false,
    cdataTagName: false,
    cdataPositionChar: "\\c",
    format: false
};

function Parser(options){
    this.options = Object.assign({},defaultOptions,options);
    if(this.options.ignoreAttributes) {
        this.isAttribute = a => false;
    }else{
        this.attrPrefixLen = this.options.attributeNamePrefix.length;
        this.isAttribute = isAttribute;
    }
    if(this.options.cdataTagName){
        this.isCDATA = isCDATA;
    }else{
        this.isCDATA = a => false;
    }
    this.replaceCDATAstr = replaceCDATAstr;
    this.replaceCDATAarr = replaceCDATAarr;
    if(this.options.encodeHTMLchar){
        this.encodeHTMLchar = encodeHTMLchar;
    }else{
        this.encodeHTMLchar = a => a;
    }

    if(this.options.format){
        this.indentate = indentate;
        this.tagEndChar = ">\n";
        this.newLine = "\n";
    }else{
        this.indentate = () => "";
        this.tagEndChar = ">";
        this.newLine = "";
    }

}

Parser.prototype.parse = function(jObj){
    return this.j2x(jObj,0).val;
}

Parser.prototype.j2x = function(jObj,level){
    var xmlStr = "", attrStr = "" , val = "";
    var keys = Object.keys(jObj);
    var len = keys.length;
    for(var i=0;i<len;i++){
        var key = keys[i];
        if(typeof jObj[key] !== "object"){//premitive type
            var attr = this.isAttribute(key);
            if(attr){
                attrStr += " " +attr+"=\""+ this.encodeHTMLchar(jObj[key], true) +"\"";
            }else if(this.isCDATA(key)){
                if(jObj[this.options.textNodeName]){
                    val += this.replaceCDATAstr(jObj[this.options.textNodeName], jObj[key]);
                }else{
                    val += this.replaceCDATAstr("", jObj[key]);
                }
            }else{//tag value
                if(key === this.options.textNodeName){
                    if(jObj[this.options.cdataTagName]){
                        //value will added while processing cdata
                    }else{
                        val += this.encodeHTMLchar(jObj[key]);
                    }
                }else{
                    val += this.indentate(level) + "<" + key + ">" +this.encodeHTMLchar(jObj[key])+"</"+key+ this.tagEndChar;
                }
            }
        }else if(Array.isArray(jObj[key])){//repeated nodes
            if(this.isCDATA(key)){
                //check if textnode is present -> replace the value
                //else just add the value

                if(jObj[this.options.textNodeName]){
                    val += this.replaceCDATAarr(jObj[this.options.textNodeName], jObj[key]);
                }else{
                    val += this.replaceCDATAarr("", jObj[key]);
                }
            }else{//nested nodes
                var arrLen = jObj[key].length;
                for(var j=0;j<arrLen;j++){
                    var item = jObj[key][j];
                    if(typeof item === "object"){
                        var result = this.j2x(item,level+1);
                        val += this.indentate(level)
                                    + "<"+key + result.attrStr
                                    + this.tagEndChar
                                    + result.val
                                    + this.newLine
                                    + this.indentate(level)
                                    + "</"+key+this.tagEndChar;
                    }else{
                        val += this.indentate(level) + "<"+key+">"+  this.encodeHTMLchar(item) + "</"+key+this.tagEndChar;
                    }
                }
            }
        }else{

            if(this.options.attrNodeName && key === this.options.attrNodeName){
                var Ks = Object.keys(jObj[key]);
                var L = Ks.length;
                for(var j=0;j<L;j++){
                    attrStr += " "+Ks[j]+"=\"" + this.encodeHTMLchar(jObj[key][Ks[j]]) + "\"";
                }
            }else{
                var result = this.j2x(jObj[key],level+1);
                val  += this.indentate(level)
                            + "<" + key + result.attrStr
                            + this.tagEndChar
                            + result.val
                            + this.newLine
                            + this.indentate(level)
                            + "</"+key+this.tagEndChar;
            }
        }
    }
    return {attrStr : attrStr , val : val};
}

function replaceCDATAstr(str,cdata){
    str = this.encodeHTMLchar(str);
    if(this.options.cdataPositionChar === "" || str === ""){
        return str + "<![CDATA[" +cdata+"]]>";
    }else{
        return str.replace(this.options.cdataPositionChar,"<![CDATA[" +cdata+"]]>")
    }
}

function replaceCDATAarr(str,cdata){
    str = this.encodeHTMLchar(str);
    if(this.options.cdataPositionChar === "" || str === ""){
        return str + "<![CDATA[" + cdata.join("]]><![CDATA[")+"]]>";
    }else{
        for(var v in cdata){
            str = str.replace(this.options.cdataPositionChar, "<![CDATA[" +cdata[v]+"]]>");
        }
        return str;
    }
}

function indentate(level){
    return "\t".repeat(level);
}
function encodeHTMLchar(val, isAttribute){
    return he.encode("" + val, {isAttributeValue : isAttribute, useNamedReferences: true});
}

function isAttribute(name,options){
    if(name.startsWith(this.options.attributeNamePrefix)){
        return name.substr(this.attrPrefixLen);
    }else{
        return false;
    }
}

function isCDATA(name){
    if(name === this.options.cdataTagName){
        return true;
    }else{
        return false;
    }
}
//formatting
//indentation
//\n after each closing or self closing tag

module.exports = Parser;<commit_msg>j2x: provide option to give indentation depth<commit_after>//parse Empty Node as self closing node
var he = require("he");

var defaultOptions = {
    attributeNamePrefix : "@_",
    attrNodeName: false,
    textNodeName : "#text",
    ignoreAttributes : true,
    encodeHTMLchar: false,
    cdataTagName: false,
    cdataPositionChar: "\\c",
    format: false,
    indentBy: "  "
};

function Parser(options){
    this.options = Object.assign({},defaultOptions,options);
    if(this.options.ignoreAttributes) {
        this.isAttribute = a => false;
    }else{
        this.attrPrefixLen = this.options.attributeNamePrefix.length;
        this.isAttribute = isAttribute;
    }
    if(this.options.cdataTagName){
        this.isCDATA = isCDATA;
    }else{
        this.isCDATA = a => false;
    }
    this.replaceCDATAstr = replaceCDATAstr;
    this.replaceCDATAarr = replaceCDATAarr;
    if(this.options.encodeHTMLchar){
        this.encodeHTMLchar = encodeHTMLchar;
    }else{
        this.encodeHTMLchar = a => a;
    }

    if(this.options.format){
        this.indentate = indentate;
        this.tagEndChar = ">\n";
        this.newLine = "\n";
    }else{
        this.indentate = () => "";
        this.tagEndChar = ">";
        this.newLine = "";
    }

}

Parser.prototype.parse = function(jObj){
    return this.j2x(jObj,0).val;
}

Parser.prototype.j2x = function(jObj,level){
    var xmlStr = "", attrStr = "" , val = "";
    var keys = Object.keys(jObj);
    var len = keys.length;
    for(var i=0;i<len;i++){
        var key = keys[i];
        if(typeof jObj[key] !== "object"){//premitive type
            var attr = this.isAttribute(key);
            if(attr){
                attrStr += " " +attr+"=\""+ this.encodeHTMLchar(jObj[key], true) +"\"";
            }else if(this.isCDATA(key)){
                if(jObj[this.options.textNodeName]){
                    val += this.replaceCDATAstr(jObj[this.options.textNodeName], jObj[key]);
                }else{
                    val += this.replaceCDATAstr("", jObj[key]);
                }
            }else{//tag value
                if(key === this.options.textNodeName){
                    if(jObj[this.options.cdataTagName]){
                        //value will added while processing cdata
                    }else{
                        val += this.encodeHTMLchar(jObj[key]);
                    }
                }else{
                    val += this.indentate(level) + "<" + key + ">" +this.encodeHTMLchar(jObj[key])+"</"+key+ this.tagEndChar;
                }
            }
        }else if(Array.isArray(jObj[key])){//repeated nodes
            if(this.isCDATA(key)){
                //check if textnode is present -> replace the value
                //else just add the value

                if(jObj[this.options.textNodeName]){
                    val += this.replaceCDATAarr(jObj[this.options.textNodeName], jObj[key]);
                }else{
                    val += this.replaceCDATAarr("", jObj[key]);
                }
            }else{//nested nodes
                var arrLen = jObj[key].length;
                for(var j=0;j<arrLen;j++){
                    var item = jObj[key][j];
                    if(typeof item === "object"){
                        var result = this.j2x(item,level+1);
                        val += this.indentate(level)
                                    + "<"+key + result.attrStr
                                    + this.tagEndChar
                                    + result.val
                                    + this.newLine
                                    + this.indentate(level)
                                    + "</"+key+this.tagEndChar;
                    }else{
                        val += this.indentate(level) + "<"+key+">"+  this.encodeHTMLchar(item) + "</"+key+this.tagEndChar;
                    }
                }
            }
        }else{

            if(this.options.attrNodeName && key === this.options.attrNodeName){
                var Ks = Object.keys(jObj[key]);
                var L = Ks.length;
                for(var j=0;j<L;j++){
                    attrStr += " "+Ks[j]+"=\"" + this.encodeHTMLchar(jObj[key][Ks[j]]) + "\"";
                }
            }else{
                var result = this.j2x(jObj[key],level+1);
                val  += this.indentate(level)
                            + "<" + key + result.attrStr
                            + this.tagEndChar
                            + result.val
                            + this.newLine
                            + this.indentate(level)
                            + "</"+key+this.tagEndChar;
            }
        }
    }
    return {attrStr : attrStr , val : val};
}

function replaceCDATAstr(str,cdata){
    str = this.encodeHTMLchar(str);
    if(this.options.cdataPositionChar === "" || str === ""){
        return str + "<![CDATA[" +cdata+"]]>";
    }else{
        return str.replace(this.options.cdataPositionChar,"<![CDATA[" +cdata+"]]>")
    }
}

function replaceCDATAarr(str,cdata){
    str = this.encodeHTMLchar(str);
    if(this.options.cdataPositionChar === "" || str === ""){
        return str + "<![CDATA[" + cdata.join("]]><![CDATA[")+"]]>";
    }else{
        for(var v in cdata){
            str = str.replace(this.options.cdataPositionChar, "<![CDATA[" +cdata[v]+"]]>");
        }
        return str;
    }
}

function indentate(level){
    return this.options.indentBy.repeat(level);
}
function encodeHTMLchar(val, isAttribute){
    return he.encode("" + val, {isAttributeValue : isAttribute, useNamedReferences: true});
}

function isAttribute(name,options){
    if(name.startsWith(this.options.attributeNamePrefix)){
        return name.substr(this.attrPrefixLen);
    }else{
        return false;
    }
}

function isCDATA(name){
    if(name === this.options.cdataTagName){
        return true;
    }else{
        return false;
    }
}
//formatting
//indentation
//\n after each closing or self closing tag

module.exports = Parser;<|endoftext|>


<commit_before>'use strict';

var ngFileToJson = angular.module('ngFileToJson',[]);

ngFileToJson.directive('ngFileToJson', function(){
    var module,
        splitColumns,
        createObject,
        cleanUpString,
        parseString,
        validTypes = ['string', 'number', 'object', 'boolean', 'array'];

    // module to be returned
    module = {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
            result: '=',
            headerField: '@headerField',
            typeField: '@typeField',
            delimiter: '@delimiter',
            rowDelimiter: '@rowDelimiter'
        },
        template: '
<input ng-model="uploadFile" type="file">
',
        link: function(scope, element){
            // when the element changes (eg. file selected) the HTML5 FileReader will load the file
            element.on('change', function(event){
                var uploadedFile = new FileReader();

                uploadedFile.readAsBinaryString(event.target.files[0]);

                uploadedFile.onload = function(e){
                    scope.$apply(function(){
                        scope.result = createObject(e.target.result, scope);
                    });
                };
            });
        }
    };

    // The function that actually converts the string into an object
    createObject = function(str, overrides) {
        var options = {
            headerField: 'true',
            typeField: 'false',
            delimiter: ',',
            rowDelimiter: '\n'
        };

        // override the defaults if set in the attributes
        options.headerField = overrides.headerField || options.headerField;
        options.typeField = overrides.typeField || options.typeField;
        options.delimiter = overrides.delimiter || options.delimiter;
        options.rowDelimiter = overrides.rowDelimiter || options.rowDelimiter;

        var obj = [],
            rows,
            row,
            columns,
            header,
            types = [],
            items,
            i,
            value;

        options.headerField = options.headerField && !(options.headerField === 'false') ? true : false;
        options.typeField = options.typeField && !(options.typeField === 'false') ? true : false;

        rows = cleanUpString(str).split(options.rowDelimiter);

        if(options.headerField){
            // set keys
            row = rows.shift();
            header = row.split(options.delimiter);
        }

        if(options.typeField){
            // set type
            row = rows.shift();
            types = row.split(options.delimiter);

            // check for valid types
            for(i = 0; i < types.length; i++){
                if(!(validTypes.indexOf(types[i].toLowerCase()) > -1)){
                    types[i] = 'string';
                } else {
                    types[i] = types[i].toLowerCase();
                }
            }
        }

        while(rows.length > 0){
            // set values
            row = rows.shift();
            columns = splitColumns(row, options.delimiter);

            // if header row exists use this for the keys
            if(header){
                items = {};
                for(i = 0; i < columns.length; i++){
                    if(types.length && types[i]){
                        // if the types array is set
                        value = parseString(types[i], columns[i]);
                        items[header[i] || ''] = value;
                    } else {
                        // set the key/value
                        items[header[i] || ''] = columns[i];
                    }
                }
                obj.push(items);

            // otherwise will be an array
            } else {
                items = [];
                for(i = 0; i < columns.length; i++){
                    value = parseString(types[i], columns[i]);
                    items.push(value);
                }
                obj.push(items);
            }
        }

        // return compiled JSON object
        return obj;
    };

    // special function to split row into columns using a delimiter since RegEx does not have a good way to do this
    splitColumns = function(row, delimiter){
        var characters = row.split(''),
            inQuotes = false,
            indexes = [],
            i,
            lastIndex = 0,
            columns = [];

        // if a delimiter is between two double quotes, then it is part of the string and not counted
        for(i = 0; i < characters.length; i++){
            if(characters[i] === '"'){
                inQuotes = !inQuotes;
            }

            if(!inQuotes && characters[i] === delimiter){
                indexes.push(i);
            }
        }

        // all indexes are now used to split the columns
        if(indexes.length) {
            for(i = 0; i < indexes.length; i++){
                columns.push(row.slice(lastIndex, indexes[i]));
                lastIndex = indexes[i] + 1;
            }
            // last column
            columns.push(row.slice(lastIndex, characters.length));
        }

        return columns;
    };

    // helper function to clean up line breaks
    // this breaks down the string into characters, removes the carriage return, and builds the string again
    // it also replaces invalid characters inserted by spreadsheets and other text editors
    cleanUpString = function(str){
        var arr = str.split(''),
            i;

        // start from the last item since items will be removed which will mess up the loop
        for(i = arr.length - 1; i >=0; i--){
            if(arr[i] === '\r'){
                arr.splice(i, 1);
            }
        }

        str = arr.join('');

        // smart single quotes and apostrophe
        str = str.replace(/[\u2018\u2019\u201Aâ]/g, "\'");
        // smart double quotes
        str = str.replace(/[\u201C\u201D\u201E]/g, "\"");
        // ellipsis
        str = str.replace(/\u2026/g, "...");
        // dashes
        str = str.replace(/[\u2013\u2014]/g, "-");
        // circumflex
        str = str.replace(/\u02C6/g, "^");
        // open angle bracket
        str = str.replace(/\u2039/g, "<");
        // close angle bracket
        str = str.replace(/\u203A/g, ">");
        // spaces
        str = str.replace(/[\u02DC\u00A0]/g, " ");

        return str;
    };

    parseString = function(type, value){
        var obj,
            arr;

        switch(type) {
            case 'string':
                return (new String(value)).valueOf();
            case 'number':
                return parseInt(value);
            case 'object':
                if(value) {
                    value = value.replace(/^"|"$/g, '');
                    try {
                        obj = JSON.parse(JSON.stringify(eval("(" + value + ")")));
                    } catch(e){
                        return {};
                    }
                    return obj;
                } else {
                    return {};
                }
            case 'array':
                if(value) {
                    try {
                        obj = [];
                        value = value.replace(/^"?\[|\]"?$/g, '');
                        arr = value.split(',');
                        angular.forEach(arr, function(item) {
                            if((item.toLowerCase().indexOf('true') > -1) || (item.toLowerCase().indexOf('false') > -1)){
                                obj.push(parseString('boolean', item));
                            } else if(item.indexOf('{') > -1){
                                obj.push(parseString('object', item));
                            } else if(item.indexOf('[') > -1){
                                obj.push(parseString('array', item));
                            } else if(item.indexOf("'") > -1){
                                item = item.replace(/["']/g, '');
                                obj.push(parseString('string', item));
                            } else if(item.match(/\d/)){
                                obj.push(parseString('number', item));
                            }
                        });
                    } catch(e){
                        return [];
                    }
                    return obj;
                } else {
                    return [];
                }
            case 'boolean':
                return (new Boolean(value.toLowerCase())).valueOf();
            default:
                return (new String(value)).valueOf();
        }
    };

    // Expose directive
    return module;
});
<commit_msg>adjusting code for jshint warnings<commit_after>var ngFileToJson = angular.module('ngFileToJson',[]);

ngFileToJson.directive('ngFileToJson', function(){
    'use strict';

    var module,
        splitColumns,
        createObject,
        cleanUpString,
        parseString,
        validTypes = ['string', 'number', 'object', 'boolean', 'array'];

    // module to be returned
    module = {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
            result: '=',
            headerField: '@headerField',
            typeField: '@typeField',
            delimiter: '@delimiter',
            rowDelimiter: '@rowDelimiter'
        },
        template: '
<input ng-model="uploadFile" type="file">
',
        link: function(scope, element){
            // when the element changes (eg. file selected) the HTML5 FileReader will load the file
            element.on('change', function(event){
                var uploadedFile = new FileReader();

                uploadedFile.readAsBinaryString(event.target.files[0]);

                uploadedFile.onload = function(e){
                    scope.$apply(function(){
                        scope.result = createObject(e.target.result, scope);
                    });
                };
            });
        }
    };

    // The function that actually converts the string into an object
    createObject = function(str, overrides) {
        var options = {
            headerField: 'true',
            typeField: 'false',
            delimiter: ',',
            rowDelimiter: '\n'
        };

        // override the defaults if set in the attributes
        options.headerField = overrides.headerField || options.headerField;
        options.typeField = overrides.typeField || options.typeField;
        options.delimiter = overrides.delimiter || options.delimiter;
        options.rowDelimiter = overrides.rowDelimiter || options.rowDelimiter;

        var obj = [],
            rows,
            row,
            columns,
            header,
            types = [],
            items,
            i,
            value;

        options.headerField = options.headerField && options.headerField === 'true' ? true : false;
        options.typeField = options.typeField && options.typeField === 'true' ? true : false;

        rows = cleanUpString(str).split(options.rowDelimiter);

        if(options.headerField){
            // set keys
            row = rows.shift();
            header = row.split(options.delimiter);
        }

        if(options.typeField){
            // set type
            row = rows.shift();
            types = row.split(options.delimiter);

            // check for valid types
            for(i = 0; i < types.length; i++){
                if(validTypes.indexOf(types[i].toLowerCase()) === -1){
                    types[i] = 'string';
                } else {
                    types[i] = types[i].toLowerCase();
                }
            }
        }

        while(rows.length > 0){
            // set values
            row = rows.shift();
            columns = splitColumns(row, options.delimiter);

            // if header row exists use this for the keys
            if(header){
                items = {};
                for(i = 0; i < columns.length; i++){
                    if(types.length && types[i]){
                        // if the types array is set
                        value = parseString(types[i], columns[i]);
                        items[header[i] || ''] = value;
                    } else {
                        // set the key/value
                        items[header[i] || ''] = columns[i];
                    }
                }
                obj.push(items);

            // otherwise will be an array
            } else {
                items = [];
                for(i = 0; i < columns.length; i++){
                    value = parseString(types[i], columns[i]);
                    items.push(value);
                }
                obj.push(items);
            }
        }

        // return compiled JSON object
        return obj;
    };

    // special function to split row into columns using a delimiter since RegEx does not have a good way to do this
    splitColumns = function(row, delimiter){
        var characters = row.split(''),
            inQuotes = false,
            indexes = [],
            i,
            lastIndex = 0,
            columns = [];

        // if a delimiter is between two double quotes, then it is part of the string and not counted
        for(i = 0; i < characters.length; i++){
            if(characters[i] === '"'){
                inQuotes = !inQuotes;
            }

            if(!inQuotes && characters[i] === delimiter){
                indexes.push(i);
            }
        }

        // all indexes are now used to split the columns
        if(indexes.length) {
            for(i = 0; i < indexes.length; i++){
                columns.push(row.slice(lastIndex, indexes[i]));
                lastIndex = indexes[i] + 1;
            }
            // last column
            columns.push(row.slice(lastIndex, characters.length));
        }

        return columns;
    };

    // helper function to clean up line breaks
    // this breaks down the string into characters, removes the carriage return, and builds the string again
    // it also replaces invalid characters inserted by spreadsheets and other text editors
    cleanUpString = function(str){
        var arr = str.split(''),
            i;

        // start from the last item since items will be removed which will mess up the loop
        for(i = arr.length - 1; i >=0; i--){
            if(arr[i] === '\r'){
                arr.splice(i, 1);
            }
        }

        str = arr.join('');

        // smart single quotes and apostrophe
        str = str.replace(/[\u2018\u2019\u201Aâ]/g, "\'");
        // smart double quotes
        str = str.replace(/[\u201C\u201D\u201E]/g, "\"");
        // ellipsis
        str = str.replace(/\u2026/g, "...");
        // dashes
        str = str.replace(/[\u2013\u2014]/g, "-");
        // circumflex
        str = str.replace(/\u02C6/g, "^");
        // open angle bracket
        str = str.replace(/\u2039/g, "<");
        // close angle bracket
        str = str.replace(/\u203A/g, ">");
        // spaces
        str = str.replace(/[\u02DC\u00A0]/g, " ");

        return str;
    };

    parseString = function(type, value){
        var obj,
            arr;

        switch(type) {
            case 'string':
                return String(value);
            case 'number':
                return parseInt(value);
            case 'object':
                if(value) {
                    value = value.replace(/^"|"$/g, '');
                    try {
                        obj = JSON.parse(JSON.stringify(eval("(" + value + ")")));
                    } catch(e){
                        return {};
                    }
                    return obj;
                } else {
                    return {};
                }
                break;
            case 'array':
                if(value) {
                    try {
                        obj = [];
                        value = value.replace(/^"?\[|\]"?$/g, '');
                        arr = value.split(',');
                        angular.forEach(arr, function(item) {
                            if((item.toLowerCase().indexOf('true') > -1) || (item.toLowerCase().indexOf('false') > -1)){
                                obj.push(parseString('boolean', item));
                            } else if(item.indexOf('{') > -1){
                                obj.push(parseString('object', item));
                            } else if(item.indexOf('[') > -1){
                                obj.push(parseString('array', item));
                            } else if(item.indexOf("'") > -1){
                                item = item.replace(/["']/g, '');
                                obj.push(parseString('string', item));
                            } else if(item.match(/\d/)){
                                obj.push(parseString('number', item));
                            }
                        });
                    } catch(e){
                        return [];
                    }
                    return obj;
                } else {
                    return [];
                }
                break;
            case 'boolean':
                return Boolean(value.toLowerCase());
            default:
                return String(value);
        }
    };

    // Expose directive
    return module;
});
<|endoftext|>