<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc directive
     * @restrict A
     * @name requisition-product-grid.productGridCell
     *
     * @description
     * Responsible for rendering the product grid cell based on the column source and requisitions type.
     * It also keeps track of the validation as well as changes made to the related cells.
     *
     * @example
     * Here we extend our product grid cell with the directive.
     * ```
     * <td ng-repeat="column in visibleColumns | orderBy : 'displayOrder'" product-grid-cell></td>
     * ```
     */
    angular
        .module('requisition-product-grid')
        .directive('productGridCell', productGridCell);

    productGridCell.$inject = [
        '$q', '$templateRequest', '$compile', 'requisitionValidator', 'TEMPLATE_COLUMNS',
        'COLUMN_SOURCES', 'COLUMN_TYPES'
    ];

    function productGridCell($q, $templateRequest, $compile, requisitionValidator, TEMPLATE_COLUMNS,
                             COLUMN_SOURCES, COLUMN_TYPES) {

        return {
            restrict: 'A',
            link: link,
            scope: {
                requisition: '=',
                column: '=',
                lineItem: '='
            }
        };

        function link(scope, element) {
            var requisition = scope.requisition,
                column = scope.column,
                lineItem = scope.lineItem;

            scope.lineItem = lineItem;
            scope.column = column;
            scope.validate = validate;
            scope.canNotSkip = canNotSkip;

            angular.forEach(column.$dependencies, function (depencency) {
                watchDependency(depencency, column);
            });

            scope.$watch(function(){
                if(lineItem.skipped){
                    return false;
                }
                return lineItem.$errors[column.name];
            }, function(error){
                if (error) {
                    scope.invalidMessage = error;
                }
            });

            updateCellContents();

            function updateCellContents(){
                var templateUrl = '';
                if(column.name === TEMPLATE_COLUMNS.SKIPPED) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-skip.html';
                } else if(column.name === TEMPLATE_COLUMNS.TOTAL_LOSSES_AND_ADJUSTMENTS) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-total-losses-and-adjustments.html';
                } else if(column.$type === COLUMN_TYPES.NUMERIC && !isReadOnly()){
                    templateUrl = 'requisition-product-grid/product-grid-cell-input-numeric.html';
                } else if(!isReadOnly()) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-input-text.html';
                } else if(column.$type === COLUMN_TYPES.CURRENCY) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-currency.html';
                } else {
                    templateUrl = 'requisition-product-grid/product-grid-cell-text.html'
                }
                $templateRequest(templateUrl).then(replaceCell);
            }

            function replaceCell(newTemplate) {
                var cellWrapperPath = 'requisition-product-grid/product-grid-cell.html';
                $templateRequest(cellWrapperPath).then(function(template){
                    template = angular.element(template);
                    template.html(newTemplate);

                    var cell = $compile(template)(scope);
                    element.replaceWith(cell);

                    element = cell;
                });
            }

            function validate() {
                requisitionValidator.validateLineItemField(
                    scope.lineItem,
                    column,
                    requisition.template.columnsMap,
                    requisition
                );
            }

            function isReadOnly() {
                if (requisition.$isApproved() || requisition.$isReleased()) return true;
                if (requisition.$isAuthorized() || requisition.$isInApproval()) {
                    return [
                        TEMPLATE_COLUMNS.APPROVED_QUANTITY, TEMPLATE_COLUMNS.REMARKS
                    ].indexOf(column.name) === -1;
                }
                return column.source !== COLUMN_SOURCES.USER_INPUT;
            }

            function canNotSkip() {
                return !lineItem.canBeSkipped(scope.requisition);
            }

            function watchDependency(name, column) {
                var dependent = requisition.template.getColumn(name);
                if (dependent.$display) {
                    scope.$watch('lineItem.' + name, function(newValue, oldValue) {
                        if (newValue !== oldValue) {
                            if (column.source === COLUMN_SOURCES.CALCULATED) {
                                scope.lineItem.updateFieldValue(column, requisition);
                            }
                            validate();
                        }
                    });
                } else {
                    angular.forEach(dependent.$dependencies, function (dependency) {
                        watchDependency(dependency, dependent);
                    });
                }
            }
        }
    }

})();
<commit_msg>Fixed error display on the product grid<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc directive
     * @restrict A
     * @name requisition-product-grid.productGridCell
     *
     * @description
     * Responsible for rendering the product grid cell based on the column source and requisitions type.
     * It also keeps track of the validation as well as changes made to the related cells.
     *
     * @example
     * Here we extend our product grid cell with the directive.
     * ```
     * <td ng-repeat="column in visibleColumns | orderBy : 'displayOrder'" product-grid-cell></td>
     * ```
     */
    angular
        .module('requisition-product-grid')
        .directive('productGridCell', productGridCell);

    productGridCell.$inject = [
        '$q', '$templateRequest', '$compile', 'requisitionValidator', 'TEMPLATE_COLUMNS',
        'COLUMN_SOURCES', 'COLUMN_TYPES'
    ];

    function productGridCell($q, $templateRequest, $compile, requisitionValidator, TEMPLATE_COLUMNS,
                             COLUMN_SOURCES, COLUMN_TYPES) {

        return {
            restrict: 'A',
            link: link,
            scope: {
                requisition: '=',
                column: '=',
                lineItem: '='
            }
        };

        function link(scope, element) {
            var requisition = scope.requisition,
                column = scope.column,
                lineItem = scope.lineItem;

            scope.lineItem = lineItem;
            scope.column = column;
            scope.validate = validate;
            scope.canNotSkip = canNotSkip;

            angular.forEach(column.$dependencies, function (depencency) {
                watchDependency(depencency, column);
            });

            scope.$watch(function(){
                if(lineItem.skipped){
                    return false;
                }
                return lineItem.$errors[column.name];
            }, function(error){
                scope.invalidMessage = error ? error : undefined;
            });

            updateCellContents();

            function updateCellContents(){
                var templateUrl = '';
                if(column.name === TEMPLATE_COLUMNS.SKIPPED) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-skip.html';
                } else if(column.name === TEMPLATE_COLUMNS.TOTAL_LOSSES_AND_ADJUSTMENTS) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-total-losses-and-adjustments.html';
                } else if(column.$type === COLUMN_TYPES.NUMERIC && !isReadOnly()){
                    templateUrl = 'requisition-product-grid/product-grid-cell-input-numeric.html';
                } else if(!isReadOnly()) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-input-text.html';
                } else if(column.$type === COLUMN_TYPES.CURRENCY) {
                    templateUrl = 'requisition-product-grid/product-grid-cell-currency.html';
                } else {
                    templateUrl = 'requisition-product-grid/product-grid-cell-text.html'
                }
                $templateRequest(templateUrl).then(replaceCell);
            }

            function replaceCell(newTemplate) {
                var cellWrapperPath = 'requisition-product-grid/product-grid-cell.html';
                $templateRequest(cellWrapperPath).then(function(template){
                    template = angular.element(template);
                    template.html(newTemplate);

                    var cell = $compile(template)(scope);
                    element.replaceWith(cell);

                    element = cell;
                });
            }

            function validate() {
                requisitionValidator.validateLineItemField(
                    scope.lineItem,
                    column,
                    requisition.template.columnsMap,
                    requisition
                );
            }

            function isReadOnly() {
                if (requisition.$isApproved() || requisition.$isReleased()) return true;
                if (requisition.$isAuthorized() || requisition.$isInApproval()) {
                    return [
                        TEMPLATE_COLUMNS.APPROVED_QUANTITY, TEMPLATE_COLUMNS.REMARKS
                    ].indexOf(column.name) === -1;
                }
                return column.source !== COLUMN_SOURCES.USER_INPUT;
            }

            function canNotSkip() {
                return !lineItem.canBeSkipped(scope.requisition);
            }

            function watchDependency(name, column) {
                var dependent = requisition.template.getColumn(name);
                if (dependent.$display) {
                    scope.$watch('lineItem.' + name, function(newValue, oldValue) {
                        if (newValue !== oldValue) {
                            if (column.source === COLUMN_SOURCES.CALCULATED) {
                                scope.lineItem.updateFieldValue(column, requisition);
                            }
                            validate();
                        }
                    });
                } else {
                    angular.forEach(dependent.$dependencies, function (dependency) {
                        watchDependency(dependency, dependent);
                    });
                }
            }
        }
    }

})();
<|endoftext|>


<commit_before>var target = document.getElementById('now-playing-metadata');
var options = { attributes: true, childList: true, characterData: true };

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (addon_exists){
      self.postMessage(mutation.target.textContent);
    }
  });
});

var addon_exists = true;

observer.observe(target, options); // set up

self.port.on("detach", function() { // to disable posting messages after add-on removal
  addon_exists = false;
});
<commit_msg>Adds notification when restarting song on Grooveshark<commit_after>var target_metadata = document.getElementById('now-playing-metadata'),
    target_play_pause = document.getElementById('play-pause'),
    options = { attributes: true, childList: true, characterData: true };

var observer_metadata = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (addon_exists){
      self.postMessage(mutation.target_metadata.textContent);
    }
  });
});

var observer_play_pause = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (addon_exists){
      var started_playing = document.getElementById('play-pause').outerHTML;
      if (/class="\S* \S* playing/.test(started_playing)){
        self.postMessage(target_metadata.textContent);
      }
    }
  });
});

var addon_exists = true;

observer_metadata.observe(target_metadata, options); // set up
observer_play_pause.observe(target_play_pause, options);

self.port.on("detach", function() { // to disable posting messages after add-on removal
  addon_exists = false;
});
<|endoftext|>


<commit_before>// mapping for standard US keyboards. Replace the $.keymap.normal, $.keymap.shift, $.keymap.ctrl and $.keymap.alt arrays as needed
// Version: 2.1
// Copyright (c) 2013 Daniel Wachsstock
// MIT license:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

// requires Array.prototype.forEach, so lets me nice to IE8
if ( !Array.prototype.forEach ) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope, this[i], i, this);
    }
  }
}

// depends on jQuery to normalize the keydown event
(function($){
	// returns the sendkeys http://bililite.com/blog/2011/01/23/improved-sendkeys/ equivalent of the character, with addtions from the
	// Microsoft version (http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx)
	// and their indicators of control keys (+^%)
	$.keymap = function (evt){
		var c = evt.which, shift = evt.shiftKey, ctrl = evt.ctrlKey, alt = evt.altKey;
		var ret;
		if (shift && $.keymap.shift[c]){
			ret = $.keymap.shift[c];
			shift = false;
		}else if (ctrl && $.keymap.ctrl[c]){
			ret = $.keymap.ctrl[c];
			ctrl = false;
		}else if (alt && $.keymap.alt[c]){
			ret = $.keymap.alt[c];
			alt = false;
		}else{
			ret = $.keymap.normal[c];
		}
		if (!ret) return false;
		if (alt) ret = '%' + ret;
		ret = ret.replace('%^', '^%'); // normalize control-alt letters
		if (ctrl) ret = '^' + ret;
		if (shift) ret = '+' + ret;
		// make sure control characters are uppercase
		return $.keymap.normalize(ret);
	}

	var aliasgenerator = {
		// VIM notation (and jquery.hotkeys numeric keypad notation)
		'^<(.*)>$': '$1', // strip the brackets
		'(?:k|num_)(\\d)': 'num$1', // numeric keypad indicator; change to num1 now; we will change it to {1} etc. later
		'\\b(?:k|num_)([a-z]+)': '$1', // replace kHome with Home etc.; we can't distinguish keypad direction keys
		// the sendkeys aliases
		bksp: 'backspace',
		bs: 'backspace',
		del: 'delete',
		down: 'downarrow',
		left: 'leftarrow',
		right: 'rightarrow',
		up: 'uparrow',
		// hotkeys plugin (https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js), and modifiers from VIM
		's(hift)?[+-]': '+',
		'c(trl)?[+-]': '^',
		'm(eta)?[+-]': '%', // needs to be before a(lt)- so the met[a-] doesn't match!
		'a(lt)?[+-]': '%',
		pageup: 'pgup',
		pguparrow: 'pgup', // in case we overcorrected above
		pagedown: 'pgdn',
		decimal: '.',
		// VIM notation (http://polarhome.com/vim/manual/v71/intro.html#key-notation)
		minus: 'subtract',
		point: '.',
		lt: '<',
		'#(\\d+)': 'f$1', // this is documented for ex (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html#tag_20_40_13_24) but no reason not to include it
		// Jonathan Tang's keycode.js (https://github.com/nostrademons/keycode.js)
		'page_up': 'pgup',
		'page_down': 'pgdn',
		'escape': 'esc',
		'num\\+': 'add',
		'num-': 'subtract',
		'num\\*': 'multiply',
		'num/': 'divide',

		'^\\+(\\w)$': function (match, p1) {return p1.toUpperCase()}, // uppercase shifted letters
		'[+^%]\\w$': function(match) {return match.toUpperCase()}, // control-letters are uppercase
		'[+^%]+': function (match) { // normalize the order of shift-ctrl-alt
			return (/\+/.test(match) ? '+' : '') +
				(/\^/.test(match) ? '^' : '') +
				(/%/.test(match) ? '%' : '')
		}
	};
	var aliases =[];
	for (alias in aliasgenerator){
		// mark whole words
		var name = aliasgenerator[alias];
		if (/^\w$/.test(alias)) alias = '\\b'+alias
		if (/\w$/.test(alias)) alias += '\\b'
		aliases.push({alias: new RegExp(alias), name: name});
	}

	$.keymap.normalize = function(c){
		// mark uppercase letters
		c = c.replace(/\b[A-Z]\b/, '+$&');
		// simple things to keep notation consistent
		c = c.replace(/\s/g,'').replace(/\w/g, function (match) {return match.toLowerCase()});
		aliases.forEach(function(alias) { c=c.replace(alias.alias, alias.name) });
		// anything with a word in it must mean a special key; make sure it's bracketed, and remove the numeric keypad indicator (we indicate it by leaving it in {})
		if (!/{/.test(c)) c = c.replace(/[\w.]{2,}/, '{$&');
		if (!/}/.test(c)) c = c.replace(/[\w.]{2,}/, '$&}');
		c = c.replace (/num([\d.])/i, '$1');
		return c;
	}

	$.keymap.normalizeList = function(str){
		// normalize a list of space-delimited characters.
		return $.trim($.map(str.split(/\s+/), $.keymap.normalize).join(' '));
	}

	$.keymap.normal = {
		 8	: '{backspace}',
		46	: '{delete}',
		13	: '{enter}',
		27	: '{esc}',
		45	: '{insert}',
		 9	: '{tab}'
	};
	'space pgup pgdn end home leftarrow uparrow rightarrow downarrow'.
		split(' ').forEach(function(c,i) {$.keymap.normal[i+32] = '{'+c+'}'});
	"0123456789"
		.split('').forEach(function(c,i) {$.keymap.normal[i+48] = c});
	$.keymap.normal[59] = ';'; // Firefox only!
	"abcdefghijklmnopqrstuvwxyz"
		.split('').forEach(function(c,i) {$.keymap.normal[i+65] = c});
	"0 1 2 3 4 5 6 7 8 9 multiply add unused subtract . divide". // numeric keypad keys
		split(' ').forEach(function(c,i) {$.keymap.normal[i+96] = '{'+c+'}'});
	for(i=1;i<=12;++i)
		$.keymap.normal[i+111] = '{f'+i+'}'; // function keys
	';=,-./`'
		.split('').forEach(function(c,i) {$.keymap.normal[i+186] = c});
	"[\\]'"
		.split('').forEach(function(c,i) {$.keymap.normal[i+219] = c});

	$.keymap.shift = {
		192: '~',
		 49: '!',
		 50: '@',
		 51: '#',
		 52: '$',
		 53: '{%}',
		 54: '{^}',
		 55: '&',
		 56: '*',
		 57: '(',
		 59: ':', // Firefox only!
		 48: ')',
		189: '_',
		187: '{+}',
		219: '{{}',
		220: '|',
		221: '}',
		186: ':',
		222: '"',
		188: '<',
		190: '>',
		191: '?'
	};

	$.keymap.ctrl = {};

	$.keymap.alt = {};

	// based on John Resig's hotkeys (https://github.com/jeresig/jquery.hotkeys)
	// $.event.special documentation at http://learn.jquery.com/events/event-extensions/
	// Initialize with $.keymap.hotkeys('keydown');
	// use with $(element).on('keydown, {keys: '%1', allowDefault: true}, function(){});

	// first, create an index of namespaces to identify each keystroke list
	var nss = {};
	var nsIndex = 0;
	function hotkeysnamespace(keys){
		return nss[keys] || (nss[keys] = 'hotkeys'+ (++nsIndex));
	}

	["keydown","keyup"].forEach(function(type){
		$.event.special[type] = $.event.special[type] || {};
		$.event.special[type].add = function(handleObj){
			if (!handleObj.data || typeof handleObj.data.keys != 'string') return;
			var keys = ' '+$.keymap.normalizeList(handleObj.data.keys); // the space makes the comparison easier later
			// Use the keys as a sort of namespace for the event. This is a hack for removing the handler later.
			handleObj.namespace = handleObj.namespace.split('.').
				concat(hotkeysnamespace(keys)).sort().join('.'); // add the new namespace in alphabetical order
			var origHandler = handleObj.handler;
			var currSequence = '';
			handleObj.handler = function (event){
				var self = $(this);
				var key = ' '+$.keymap(event);
				if (!key) return; // avoid problems with control keys
				currSequence += key;
				if (currSequence == keys) {
					self.trigger('keymapcomplete', [currSequence]);
					currSequence = ''; // restart
					return origHandler.apply(this, arguments);
				}
				// find the portion of the current sequence that could be a prefix of the sought keys
				while (currSequence){
					if (keys.indexOf(currSequence) == 0){
						self.trigger('keymapprefix', [currSequence]);
						return !!handleObj.data.allowDefault;
					}
					currSequence = currSequence.replace(/ \S+/, ''); // strip the first key
				}
			};
		};
	});

	function addnamespace (types, keys){
		var ns = '.'+hotkeysnamespace(' '+$.keymap.normalizeList(keys)); // note that we added a space in add, above
		return types.replace (/(\S)(\s)|$/g, '$1'+ns+'$2');;
	}
	// monkey patch remove so we can do $(elem).off('keydown', {keys: '^A'}) (basically fake the off('keydown', handler) syntax into accepting an object instead
	var oldRemove = $.event.remove;
	$.event.remove = function (elem, types, handler, selector){
		// remove just looks for the guid to match., so we can fake it out.
		// off(types, object) becomes remove (elem, types, undefined, object)
		// off(types, selector, object) becomes  remove (elem, types, object, selector)
		if (handler === undefined && $.isPlainObject(selector) && selector.keys){
			var args = [elem, addnamespace (types, selector.keys)];
		}else if ($.isPlainObject(handler) && handler.keys){
			args = [elem, addnamespace (types, handler.keys), undefined, selector];
		}else{
			args = arguments;
		}
		return oldRemove.apply(this,args);
	}

})(jQuery);<commit_msg>correct normalization of special keys<commit_after>// mapping for standard US keyboards. Replace the $.keymap.normal, $.keymap.shift, $.keymap.ctrl and $.keymap.alt arrays as needed
// Version: 2.1
// Copyright (c) 2013 Daniel Wachsstock
// MIT license:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

// requires Array.prototype.forEach, so lets me nice to IE8
if ( !Array.prototype.forEach ) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope, this[i], i, this);
    }
  }
}

// depends on jQuery to normalize the keydown event
(function($){
	// returns the sendkeys http://bililite.com/blog/2011/01/23/improved-sendkeys/ equivalent of the character, with addtions from the
	// Microsoft version (http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx)
	// and their indicators of control keys (+^%)
	$.keymap = function (evt){
		var c = evt.which, shift = evt.shiftKey, ctrl = evt.ctrlKey, alt = evt.altKey;
		var ret;
		if (shift && $.keymap.shift[c]){
			ret = $.keymap.shift[c];
			shift = false;
		}else if (ctrl && $.keymap.ctrl[c]){
			ret = $.keymap.ctrl[c];
			ctrl = false;
		}else if (alt && $.keymap.alt[c]){
			ret = $.keymap.alt[c];
			alt = false;
		}else{
			ret = $.keymap.normal[c];
		}
		if (!ret) return false;
		if (alt) ret = '%' + ret;
		if (ctrl) ret = '^' + ret;
		if (shift) ret = '+' + ret;
		// make sure control characters are uppercase
		return $.keymap.normalize(ret);
	}

	var aliasgenerator = {
		// VIM notation (and jquery.hotkeys numeric keypad notation)
		'^<(.*)>$': '$1', // strip the brackets
		'(?:k|num_)(\\d)': 'num$1', // numeric keypad indicator; change to num1 now; we will change it to {1} etc. later
		'\\b(?:k|num_)([a-z]+)': '$1', // replace kHome with Home etc.; we can't distinguish keypad direction keys
		// the sendkeys aliases
		bksp: 'backspace',
		bs: 'backspace',
		del: 'delete',
		down: 'downarrow',
		left: 'leftarrow',
		right: 'rightarrow',
		up: 'uparrow',
		// hotkeys plugin (https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js), and modifiers from VIM
		's(hift)?[+-]': '+',
		'c(trl)?[+-]': '^',
		'm(eta)?[+-]': '%', // needs to be before a(lt)- so the met[a-] doesn't match!
		'a(lt)?[+-]': '%',
		pageup: 'pgup',
		pguparrow: 'pgup', // in case we overcorrected above
		pagedown: 'pgdn',
		decimal: '.',
		// VIM notation (http://polarhome.com/vim/manual/v71/intro.html#key-notation)
		minus: 'subtract',
		point: '.',
		lt: '<',
		'#(\\d+)': 'f$1', // this is documented for ex (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html#tag_20_40_13_24) but no reason not to include it
		// Jonathan Tang's keycode.js (https://github.com/nostrademons/keycode.js)
		'page_up': 'pgup',
		'page_down': 'pgdn',
		'escape': 'esc',
		'num\\+': 'add',
		'num-': 'subtract',
		'num\\*': 'multiply',
		'num/': 'divide',

		// make sure the special keys by themselves are marked
		'^[+%^]$': '{$&}',

		'^\\+(\\w)$': function (match, p1) {return p1.toUpperCase()}, // uppercase shifted letters
		'[+^%]\\w$': function(match) {return match.toUpperCase()}, // control-letters are uppercase
		'[+^%]+': function (match) { // normalize the order of shift-ctrl-alt
			return (/\+/.test(match) ? '+' : '') +
				(/\^/.test(match) ? '^' : '') +
				(/%/.test(match) ? '%' : '')
		}
	};
	var aliases =[];
	for (alias in aliasgenerator){
		// mark whole words
		var name = aliasgenerator[alias];
		if (/^\w$/.test(alias)) alias = '\\b'+alias
		if (/\w$/.test(alias)) alias += '\\b'
		aliases.push({alias: new RegExp(alias), name: name});
	}

	$.keymap.normalize = function(c){
		// mark uppercase letters
		c = c.replace(/\b[A-Z]\b/, '+$&');
		// simple things to keep notation consistent
		c = c.replace(/\s/g,'').replace(/\w/g, function (match) {return match.toLowerCase()});
		aliases.forEach(function(alias) { c=c.replace(alias.alias, alias.name) });
		// anything with a word in it must mean a special key; make sure it's bracketed, and remove the numeric keypad indicator (we indicate it by leaving it in {})
		if (!/{/.test(c)) c = c.replace(/[\w.]{2,}/, '{$&');
		if (!/}/.test(c)) c = c.replace(/[\w.]{2,}/, '$&}');
		c = c.replace (/num([\d.])/i, '$1');
		return c;
	}

	$.keymap.normalizeList = function(str){
		// normalize a list of space-delimited characters.
		return $.trim($.map(str.split(/\s+/), $.keymap.normalize).join(' '));
	}

	$.keymap.normal = {
		 8	: '{backspace}',
		46	: '{delete}',
		13	: '{enter}',
		27	: '{esc}',
		45	: '{insert}',
		 9	: '{tab}'
	};
	'space pgup pgdn end home leftarrow uparrow rightarrow downarrow'.
		split(' ').forEach(function(c,i) {$.keymap.normal[i+32] = '{'+c+'}'});
	"0123456789"
		.split('').forEach(function(c,i) {$.keymap.normal[i+48] = c});
	$.keymap.normal[59] = ';'; // Firefox only!
	"abcdefghijklmnopqrstuvwxyz"
		.split('').forEach(function(c,i) {$.keymap.normal[i+65] = c});
	"0 1 2 3 4 5 6 7 8 9 multiply add unused subtract . divide". // numeric keypad keys
		split(' ').forEach(function(c,i) {$.keymap.normal[i+96] = '{'+c+'}'});
	for(i=1;i<=12;++i)
		$.keymap.normal[i+111] = '{f'+i+'}'; // function keys
	';=,-./`'
		.split('').forEach(function(c,i) {$.keymap.normal[i+186] = c});
	"[\\]'"
		.split('').forEach(function(c,i) {$.keymap.normal[i+219] = c});

	$.keymap.shift = {
		192: '~',
		 49: '!',
		 50: '@',
		 51: '#',
		 52: '$',
		 53: '{%}',
		 54: '{^}',
		 55: '&',
		 56: '*',
		 57: '(',
		 59: ':', // Firefox only!
		 48: ')',
		189: '_',
		187: '{+}',
		219: '{{}',
		220: '|',
		221: '}',
		186: ':',
		222: '"',
		188: '<',
		190: '>',
		191: '?'
	};

	$.keymap.ctrl = {};

	$.keymap.alt = {};

	// based on John Resig's hotkeys (https://github.com/jeresig/jquery.hotkeys)
	// $.event.special documentation at http://learn.jquery.com/events/event-extensions/
	// Initialize with $.keymap.hotkeys('keydown');
	// use with $(element).on('keydown, {keys: '%1', allowDefault: true}, function(){});

	// first, create an index of namespaces to identify each keystroke list
	var nss = {};
	var nsIndex = 0;
	function hotkeysnamespace(keys){
		return nss[keys] || (nss[keys] = 'hotkeys'+ (++nsIndex));
	}

	["keydown","keyup"].forEach(function(type){
		$.event.special[type] = $.event.special[type] || {};
		$.event.special[type].add = function(handleObj){
			if (!handleObj.data || typeof handleObj.data.keys != 'string') return;
			var keys = ' '+$.keymap.normalizeList(handleObj.data.keys); // the space makes the comparison easier later
			// Use the keys as a sort of namespace for the event. This is a hack for removing the handler later.
			handleObj.namespace = handleObj.namespace.split('.').
				concat(hotkeysnamespace(keys)).sort().join('.'); // add the new namespace in alphabetical order
			var origHandler = handleObj.handler;
			var currSequence = '';
			handleObj.handler = function (event){
				var self = $(this);
				var key = ' '+$.keymap(event);
				if (!key) return; // avoid problems with control keys
				currSequence += key;
				if (currSequence == keys) {
					self.trigger('keymapcomplete', [currSequence]);
					currSequence = ''; // restart
					return origHandler.apply(this, arguments);
				}
				// find the portion of the current sequence that could be a prefix of the sought keys
				while (currSequence){
					if (keys.indexOf(currSequence) == 0){
						self.trigger('keymapprefix', [currSequence]);
						return !!handleObj.data.allowDefault;
					}
					currSequence = currSequence.replace(/ \S+/, ''); // strip the first key
				}
			};
		};
	});

	function addnamespace (types, keys){
		var ns = '.'+hotkeysnamespace(' '+$.keymap.normalizeList(keys)); // note that we added a space in add, above
		return types.replace (/(\S)(\s)|$/g, '$1'+ns+'$2');;
	}
	// monkey patch remove so we can do $(elem).off('keydown', {keys: '^A'}) (basically fake the off('keydown', handler) syntax into accepting an object instead
	var oldRemove = $.event.remove;
	$.event.remove = function (elem, types, handler, selector){
		// remove just looks for the guid to match., so we can fake it out.
		// off(types, object) becomes remove (elem, types, undefined, object)
		// off(types, selector, object) becomes  remove (elem, types, object, selector)
		if (handler === undefined && $.isPlainObject(selector) && selector.keys){
			var args = [elem, addnamespace (types, selector.keys)];
		}else if ($.isPlainObject(handler) && handler.keys){
			args = [elem, addnamespace (types, handler.keys), undefined, selector];
		}else{
			args = arguments;
		}
		return oldRemove.apply(this,args);
	}

})(jQuery);<|endoftext|>


<commit_before>/* jshint node:true */

function NTLM_No_Proxy() {}

NTLM_No_Proxy.prototype.close = function() {

};

NTLM_No_Proxy.prototype.negotiate = function(ntlm_negotiate, negotiate_callback) {
    var challenge = new Buffer(40),
        offset = 0;

    var header = 'NTLMSSP\0';
    for (var i = 0; i < header.length; i++) {
        challenge.writeUInt8(header.charCodeAt(i), offset++);
    }

    challenge.writeUInt8(0x02, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x28, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x01, offset++);
    challenge.writeUInt8(0x82, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x01, offset++);
    challenge.writeUInt8(0x23, offset++);
    challenge.writeUInt8(0x45, offset++);
    challenge.writeUInt8(0x67, offset++);
    challenge.writeUInt8(0x89, offset++);
    challenge.writeUInt8(0xab, offset++);
    challenge.writeUInt8(0xcd, offset++);
    challenge.writeUInt8(0xef, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);
    challenge.writeUInt8(0x00, offset++);

    negotiate_callback(null, challenge);
};

NTLM_No_Proxy.prototype.authenticate = function(ntlm_authenticate, authenticate_callback) {
    authenticate_callback(null, true);
};

module.exports = NTLM_No_Proxy;
<commit_msg>Updated generated challenge to NTLMv2<commit_after>/* jshint node:true */

function NTLM_No_Proxy() {}

NTLM_No_Proxy.prototype.close = function() {

};

const NEGOTIATE_OEM         = 1 << 1;
const REQUEST_TARGET        = 1 << 2;
const TARGET_TYPE_DOMAIN    = 1 << 16;
const NEGOTIATE_NTLM2_KEY   = 1 << 19;
const NEGOTIATE_TARGET_INFO = 1 << 23;

NTLM_No_Proxy.prototype.negotiate = function(ntlm_negotiate, negotiate_callback) {
    const targetName = 'ALPHA';
    const flags = NEGOTIATE_OEM || REQUEST_TARGET || TARGET_TYPE_DOMAIN || NEGOTIATE_NTLM2_KEY || NEGOTIATE_TARGET_INFO;
    var challenge = new Buffer(40 + targetName.length),
        offset = 0;

    const header = 'NTLMSSP\0';
    offset += challenge.write(header, 0, 'ascii');

    // Type 2 message
    offset = challenge.writeUInt32LE(0x00000002, offset);

    // Target name security buffer
    offset = challenge.writeUInt16LE(targetName.length, offset);
    offset = challenge.writeUInt16LE(targetName.length, offset);
    offset = challenge.writeUInt32LE(40, offset);

    // Flags
    offset = challenge.writeUInt32LE(flags, offset);

    // Server challenge
    offset = challenge.writeUInt32LE(0x89abcdef, offset);
    offset = challenge.writeUInt32LE(0x01234567, offset);

    // Context
    offset = challenge.writeUInt32LE(0, offset);
    offset = challenge.writeUInt32LE(0, offset);

    // Target name data
    offset += challenge.write(targetName, offset, 'ascii');
    console.log(challenge.toString('base64'));

    negotiate_callback(null, challenge);
};

NTLM_No_Proxy.prototype.authenticate = function(ntlm_authenticate, authenticate_callback) {
    authenticate_callback(null, true);
};

module.exports = NTLM_No_Proxy;
<|endoftext|>


<commit_before>/* global _ */
'use strict';

angular.module('metadatamanagementApp').factory('StudySearchService',
  function(ElasticSearchClient, $q, LanguageService, CleanJSObjectService,
    SearchFilterHelperService) {
    var createQueryObject = function() {
      return {
        index: 'studies',
        type: 'studies'
      };
    };

    var createTermFilters = function(filter, dataAcquisitionProjectId) {
      var termFilter;
      if (!CleanJSObjectService.isNullOrEmpty(filter) ||
        !CleanJSObjectService.isNullOrEmpty(dataAcquisitionProjectId)) {
        termFilter = [];
      }
      if (!CleanJSObjectService.isNullOrEmpty(dataAcquisitionProjectId)) {
        var projectFilter = {
          term: {
            dataAcquisitionProjectId: dataAcquisitionProjectId
          }
        };
        termFilter.push(projectFilter);
      }
      if (!CleanJSObjectService.isNullOrEmpty(filter)) {
        termFilter = _.concat(termFilter,
          SearchFilterHelperService.createTermFilters('studies', filter));
      }
      return termFilter;
    };

    var findOneById = function(id) {
      var deferred = $q.defer();
      var query = createQueryObject();
      query.id = id;
      ElasticSearchClient.getSource(query, function(error, response) {
          if (error) {
            deferred.reject(error);
          } else {
            deferred.resolve(response);
          }
        });
      return deferred;
    };
    var findStudies = function(studyIds, selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body.query = {};
      query.body._source = selectedAttributes;
      query.body.query.docs = {
        'ids': studyIds
      };
      return ElasticSearchClient.mget(query);
    };
    var findStudy = function(studyId, selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body._source = selectedAttributes;
      query.body.query = {
        'bool': {
          'must': [{
            'match_all': {}
          }],
          'filter': [{
            'term': {
              '_id': studyId
            }
          }]
        }
      };
      return ElasticSearchClient.search(query);
    };

    var findOneByProjectId = function(dataAcquisitionProjectId,
      selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body.size = 1;
      query.body._source = selectedAttributes;
      query.body.query = {
        'bool': {
          'must': [{
            'match_all': {}
          }],
          'filter': [{
            'term': {
              'dataAcquisitionProjectId': dataAcquisitionProjectId
            }
          }]
        }
      };
      return ElasticSearchClient.search(query);
    };

    var findSurveySeries = function(term, filter,
      dataAcquisitionProjectId) {
      var query = createQueryObject();
      var termFilters = createTermFilters(filter, dataAcquisitionProjectId);

      query.body = {
        'size': 0,
        'aggs': {
            'surveySeries': {
                'terms': {
                  'field': 'surveySeries.' +
                    LanguageService.getCurrentInstantly(),
                  'include': '.*' + term + '.*'
                }
              }
          }
      };

      if (termFilters) {
        query.body.query = {
          bool: {
          }
        };
        query.body.query.bool.filter = termFilters;
      }

      return ElasticSearchClient.search(query).then(function(result) {
        return _.map(result.aggregations.surveySeries.buckets, 'key');
      });
    };

    return {
      findOneById: findOneById,
      findStudies: findStudies,
      findStudy: findStudy,
      findOneByProjectId: findOneByProjectId,
      findSurveySeries: findSurveySeries
    };
  });
<commit_msg>#1256 added i18nstring handling for survey series filter<commit_after>/* global _ */
'use strict';

angular.module('metadatamanagementApp').factory('StudySearchService',
  function(ElasticSearchClient, $q, CleanJSObjectService,
    SearchFilterHelperService) {
    var createQueryObject = function() {
      return {
        index: 'studies',
        type: 'studies'
      };
    };

    var createTermFilters = function(filter, dataAcquisitionProjectId) {
      var termFilter;
      if (!CleanJSObjectService.isNullOrEmpty(filter) ||
        !CleanJSObjectService.isNullOrEmpty(dataAcquisitionProjectId)) {
        termFilter = [];
      }
      if (!CleanJSObjectService.isNullOrEmpty(dataAcquisitionProjectId)) {
        var projectFilter = {
          term: {
            dataAcquisitionProjectId: dataAcquisitionProjectId
          }
        };
        termFilter.push(projectFilter);
      }
      if (!CleanJSObjectService.isNullOrEmpty(filter)) {
        termFilter = _.concat(termFilter,
          SearchFilterHelperService.createTermFilters('studies', filter));
      }
      return termFilter;
    };

    var findOneById = function(id) {
      var deferred = $q.defer();
      var query = createQueryObject();
      query.id = id;
      ElasticSearchClient.getSource(query, function(error, response) {
          if (error) {
            deferred.reject(error);
          } else {
            deferred.resolve(response);
          }
        });
      return deferred;
    };
    var findStudies = function(studyIds, selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body.query = {};
      query.body._source = selectedAttributes;
      query.body.query.docs = {
        'ids': studyIds
      };
      return ElasticSearchClient.mget(query);
    };
    var findStudy = function(studyId, selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body._source = selectedAttributes;
      query.body.query = {
        'bool': {
          'must': [{
            'match_all': {}
          }],
          'filter': [{
            'term': {
              '_id': studyId
            }
          }]
        }
      };
      return ElasticSearchClient.search(query);
    };

    var findOneByProjectId = function(dataAcquisitionProjectId,
      selectedAttributes) {
      var query = createQueryObject();
      query.body = {};
      query.body.size = 1;
      query.body._source = selectedAttributes;
      query.body.query = {
        'bool': {
          'must': [{
            'match_all': {}
          }],
          'filter': [{
            'term': {
              'dataAcquisitionProjectId': dataAcquisitionProjectId
            }
          }]
        }
      };
      return ElasticSearchClient.search(query);
    };

    var findSurveySeries = function(filter,
      dataAcquisitionProjectId) {
      var query = createQueryObject();
      var termFilters = createTermFilters(filter, dataAcquisitionProjectId);

      query.body = {
        'size': 0,
        'aggs': {
            'surveySeriesDe': {
                'terms': {
                  'field': 'surveySeries.de',
                  'include': '.*.*'
                },
                'aggs': {
                  'surveySeriesEn': {
                    'terms': {
                      'field': 'surveySeries.en',
                      'include': '.*.*'
                    }
                  }
                }
              }
          }
      };

      if (termFilters) {
        query.body.query = {
          bool: {
          }
        };
        query.body.query.bool.filter = termFilters;
      }

      return ElasticSearchClient.search(query).then(function(result) {
        var surveySeries = _.map([result.aggregations.surveySeriesDe.buckets],
          function(buckets) {
            var bucket;
            var surveySeriesArray = [];
            for (bucket of buckets) {
              var surveySeriesElement = {
                'de': bucket.key,
                'en': bucket.surveySeriesEn.buckets[0].key
              };
              surveySeriesArray.push(surveySeriesElement);
            }
            return surveySeriesArray;
          });
        return surveySeries;
      });
    };

    return {
      findOneById: findOneById,
      findStudies: findStudies,
      findStudy: findStudy,
      findOneByProjectId: findOneByProjectId,
      findSurveySeries: findSurveySeries
    };
  });
<|endoftext|>


<commit_before>/**
 * Add and delete 'rows' to any container element.
 *
 * @author		Stephen Lewis (http://github.com/experience/)
 * @copyright   Experience Internet
 * @version     1.1.1
 */

(function($) {

    $.fn.roland = function(options) {
        var opts = $.extend({}, $.fn.roland.defaults, options);

        return this.each(function() {
            var $container = $(this);
            updateIndexes($container, opts);
            updateNav($container, opts);

            // Adds a row.
            $container.find('.' + opts.addRowClass).bind('click', function(e) {
                e.preventDefault();

                var $link       = $(this);
                var $parentRow  = $link.closest('.' + opts.rowClass);
                var $lastRow    = $container.find('.' + opts.rowClass + ':last');
                var $cloneRow   = $lastRow.clone(true);
                var eventData   = {};

                // Reset the field values.
                $cloneRow.find('input').each(function() {
                    var type = $(this).attr('type');

                    switch (type.toLowerCase()) {
                        case 'checkbox':
                        case 'radio':
                            $(this).attr('checked', false);
                            break;

                        case 'email':
                        case 'password':
                        case 'search':
                        case 'text':
                            $(this).val('');
                            break;
                    }
                });

                // Pre-add event. Only checks return value from last listener.
                if ($link.data('events').preAddRow !== undefined) {
                    eventData = {container : $container, options : opts, newRow : $cloneRow};
                    $cloneRow = $link.triggerHandler('preAddRow', [eventData]);

                    // Returning FALSE prevents the row being added.
                    if ($cloneRow === false) {
                        return;
                    }
                }

                // If the 'add row' link lives inside a row, insert the new row after it.
                // Otherwise, just tag it on the end.
                typeof $parentRow === 'object' ? $parentRow.after($cloneRow) : $lastRow.append($cloneRow);

                // Post-add event.
                if ($link.data('events').postAddRow !== undefined) {
                    eventData = {container : $container, options : opts};
                    $link.triggerHandler('postAddRow', [eventData]);
                }

                // Update everything.
                updateIndexes($container, opts);
                updateNav($container, opts);
            });

            // Removes a row.
            $container.find('.' + opts.removeRowClass).bind('click', function(e) {
                e.preventDefault();

                var $row = $(this).closest('.' + opts.rowClass);

                // Can't remove the last row.
                if ($row.siblings().length == 0) {
                    return false;
                }

                $row.remove();

                // Update everything.
                updateIndexes($container, opts);
                updateNav($container, opts);
            });
        });
    };

    // Defaults.
    $.fn.roland.defaults = {
        rowClass        : 'row',
        addRowClass     : 'add_row',
        removeRowClass  : 'remove_row'
    };

    /* ------------------------------------------
     * PRIVATE METHODS
     * -----------------------------------------*/

    // Updates the indexes of any form elements.
	function updateIndexes($container, opts) {
		$container.find('.' + opts.rowClass).each(function(rowCount) {
			regex = /^([a-z_]+)\[(?:[0-9]+)\]\[([a-z_]+)\]$/;

			$(this).find('input, select, textarea').each(function(fieldCount) {
				var fieldName	= $(this).attr('name');
				fieldName	= fieldName.replace(regex, '$1[' + rowCount + '][$2]');
				$(this).attr('name', fieldName);
			});

		});
	};

    // Updates the navigation buttons.
	function updateNav($container, opts) {
		var $remove = $container.find('.' + opts.removeRowClass);
		var $rows	= $container.find('.' + opts.rowClass);
        $rows.size() == 1 ? $remove.hide() : $remove.show();
	};

})(jQuery);

/* End of file      : jquery.roland.js */
<commit_msg>Update 'id' indexes when adding or deleting rows.<commit_after>/**
 * Add and delete 'rows' to any container element.
 *
 * @author      Stephen Lewis (http://github.com/experience/)
 * @copyright   Experience Internet
 * @version     1.1.1
 */

(function($) {

  $.fn.roland = function(options) {
    var opts = $.extend({}, $.fn.roland.defaults, options);

    return this.each(function() {
      var $container = $(this);
      updateIndexes($container, opts);
      updateNav($container, opts);

      // Adds a row.
      $container.find('.' + opts.addRowClass).bind('click', function(e) {
        e.preventDefault();

        var $link       = $(this);
        var $parentRow  = $link.closest('.' + opts.rowClass);
        var $lastRow    = $container.find('.' + opts.rowClass + ':last');
        var $cloneRow   = $lastRow.clone(true);
        var eventData   = {};

        // Reset the field values.
        $cloneRow.find('input').each(function() {
          var type = $(this).attr('type');

          switch (type.toLowerCase()) {
            case 'checkbox':
            case 'radio':
              $(this).attr('checked', false);
              break;

            case 'email':
            case 'password':
            case 'search':
            case 'text':
              $(this).val('');
              break;
          }
        });

        // Pre-add event. Only checks return value from last listener.
        if ($link.data('events').preAddRow !== undefined) {
          eventData = {container : $container, options : opts, newRow : $cloneRow};
          $cloneRow = $link.triggerHandler('preAddRow', [eventData]);

          // Returning FALSE prevents the row being added.
          if ($cloneRow === false) {
            return;
          }
        }

        // If the 'add row' link lives inside a row, insert the new row after it.
        // Otherwise, just tag it on the end.
        typeof $parentRow === 'object'
          ? $parentRow.after($cloneRow) : $lastRow.append($cloneRow);

        // Post-add event.
        if ($link.data('events').postAddRow !== undefined) {
          eventData = {container : $container, options : opts};
          $link.triggerHandler('postAddRow', [eventData]);
        }

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);
      });

      // Removes a row.
      $container.find('.' + opts.removeRowClass).bind('click', function(e) {
        e.preventDefault();

        var $row = $(this).closest('.' + opts.rowClass);

        // Can't remove the last row.
        if ($row.siblings().length == 0) {
          return false;
        }

        $row.remove();

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);
      });
    });
  };

  // Defaults.
  $.fn.roland.defaults = {
    rowClass        : 'row',
    addRowClass     : 'add_row',
    removeRowClass  : 'remove_row'
  };

  /* ------------------------------------------
   * PRIVATE METHODS
   * -----------------------------------------*/

  // Updates the indexes of any form elements.
  function updateIndexes($container, opts) {
    $container.find('.' + opts.rowClass).each(function(rowCount) {
      regex = /^([a-z_]+)\[(?:[0-9]+)\]\[([a-z_]+)\]$/;

      $(this).find('input, select, textarea').each(function(fieldCount) {
        $field = $(this);

        if ($field.attr('id')) {
          $field.attr('id',
            $field.attr('id').replace(regex, '$1[' + rowCount + '][$2]'));
        }

        var fieldName = $(this).attr('name');

        if (fieldName) {
          fieldName = fieldName.replace(regex, '$1[' + rowCount + '][$2]');
          $(this).attr('name', fieldName);
        }
      });
    });
  };

  // Updates the navigation buttons.
  function updateNav($container, opts) {
    var $remove = $container.find('.' + opts.removeRowClass);
    var $rows = $container.find('.' + opts.rowClass);
    $rows.size() == 1 ? $remove.hide() : $remove.show();
  };

})(jQuery);

/* End of file      : jquery.roland.js */
<|endoftext|>


<commit_before>var assert = require("assert"),
    path = require("path"),
    entities = require('../');

describe("Encode->decode test", function(){
	var testcases = [
		{
			input: "asdf & ÿ ü '",
			xml: "asdf & ÿ ü '",
			html: "asdf & ÿ ü '"
		}, {
			input: "&",
			xml: "&#38;",
			html: "&#38;"
		},
	];
	testcases.forEach(function(tc) {
		var encodedXML = entities.encodeXML(tc.input);
		it("should XML encode " + tc.input, function(){
			assert.equal(encodedXML, tc.xml);
		});
		it("should default to XML encode " + tc.input, function(){
			assert.equal(entities.encode(tc.input), tc.xml);
		});
		it("should XML decode " + encodedXML, function(){
			assert.equal(entities.decodeXML(encodedXML), tc.input);
		});
		it("should default to XML encode " + encodedXML, function(){
			assert.equal(entities.decode(encodedXML), tc.input);
		});
		it("should default strict to XML encode " + encodedXML, function(){
			assert.equal(entities.decodeStrict(encodedXML), tc.input);
		});

		var encodedHTML5 = entities.encodeHTML5(tc.input);
		it("should HTML5 encode " + tc.input, function(){
			assert.equal(encodedHTML5, tc.html);
		});
		it("should HTML5 decode " + encodedHTML5, function(){
			assert.equal(entities.decodeHTML(encodedHTML5), tc.input);
		});
	});
});

describe("Decode test", function(){
	var testcases = [
		{ input: "&amp;",  output: "&" },
		{ input: "&#38;",  output: "&" },
		{ input: "&#x26;", output: "&" },
		{ input: "&#X26;", output: "&" },
		{ input: "&#38;",  output: "&" },
		{ input: "&#38;", output: "&" },
		{ input: "&#38;", output: "&" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" }
	];
	testcases.forEach(function(tc) {
		it("should XML decode " + tc.input, function(){
			assert.equal(entities.decodeXML(tc.input), tc.output);
		});
		it("should HTML4 decode " + tc.input, function(){
			assert.equal(entities.decodeHTML(tc.input), tc.output);
		});
		it("should HTML5 decode " + tc.input, function(){
			assert.equal(entities.decodeHTML(tc.input), tc.output);
		});
	});
});

var levels = ["xml", "entities"];

describe("Documents", function(){
	levels
	.map(function(n){ return path.join("..", "maps", n); })
	.map(require)
	.forEach(function(doc, i){
		describe("Decode", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decode("&" + e + ";", l), doc[e]);
					}
				});
			});
		});

		describe("Decode strict", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decodeStrict("&" + e + ";", l), doc[e]);
					}
				});
			});
		});

		describe("Encode", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decode(entities.encode(doc[e], l), l), doc[e]);
					}
				});
			});
		});
	});

	var legacy = require("../maps/legacy.json");

	describe("Legacy", function(){
		it("should decode", runLegacy);
	});

	function runLegacy(){
		Object.keys(legacy).forEach(function(e){
			assert.equal(entities.decodeHTML("&" + e), legacy[e]);
		});
	}
});

var astral = {
	"1D306": "\uD834\uDF06",
	"1D11E": "\uD834\uDD1E"
};

var astralSpecial = {
	"80":    "\u20AC",
	"110000": "\uFFFD"
};

describe("Astral entities", function(){
	Object.keys(astral).forEach(function(c){
		it("should decode " + astral[c], function(){
			assert.equal(entities.decode("&#x" + c + ";"), astral[c]);
		});

		it("should encode " + astral[c], function(){
			assert.equal(entities.encode(astral[c]), "&#x" + c + ";");
		});
	});

	Object.keys(astralSpecial).forEach(function(c){
		it("special should decode \\u" + c, function(){
			assert.equal(entities.decode("&#x" + c + ";"), astralSpecial[c]);
		});
	});
});
<commit_msg>use double-quotes<commit_after>var assert = require("assert"),
    path = require("path"),
    entities = require("../");

describe("Encode->decode test", function(){
	var testcases = [
		{
			input: "asdf & ÿ ü '",
			xml: "asdf & ÿ ü '",
			html: "asdf & ÿ ü '"
		}, {
			input: "&",
			xml: "&#38;",
			html: "&#38;"
		},
	];
	testcases.forEach(function(tc) {
		var encodedXML = entities.encodeXML(tc.input);
		it("should XML encode " + tc.input, function(){
			assert.equal(encodedXML, tc.xml);
		});
		it("should default to XML encode " + tc.input, function(){
			assert.equal(entities.encode(tc.input), tc.xml);
		});
		it("should XML decode " + encodedXML, function(){
			assert.equal(entities.decodeXML(encodedXML), tc.input);
		});
		it("should default to XML encode " + encodedXML, function(){
			assert.equal(entities.decode(encodedXML), tc.input);
		});
		it("should default strict to XML encode " + encodedXML, function(){
			assert.equal(entities.decodeStrict(encodedXML), tc.input);
		});

		var encodedHTML5 = entities.encodeHTML5(tc.input);
		it("should HTML5 encode " + tc.input, function(){
			assert.equal(encodedHTML5, tc.html);
		});
		it("should HTML5 decode " + encodedHTML5, function(){
			assert.equal(entities.decodeHTML(encodedHTML5), tc.input);
		});
	});
});

describe("Decode test", function(){
	var testcases = [
		{ input: "&amp;",  output: "&" },
		{ input: "&#38;",  output: "&" },
		{ input: "&#x26;", output: "&" },
		{ input: "&#X26;", output: "&" },
		{ input: "&#38;",  output: "&" },
		{ input: "&#38;", output: "&" },
		{ input: "&#38;", output: "&" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" },
		{ input: ":",     output: ":" }
	];
	testcases.forEach(function(tc) {
		it("should XML decode " + tc.input, function(){
			assert.equal(entities.decodeXML(tc.input), tc.output);
		});
		it("should HTML4 decode " + tc.input, function(){
			assert.equal(entities.decodeHTML(tc.input), tc.output);
		});
		it("should HTML5 decode " + tc.input, function(){
			assert.equal(entities.decodeHTML(tc.input), tc.output);
		});
	});
});

var levels = ["xml", "entities"];

describe("Documents", function(){
	levels
	.map(function(n){ return path.join("..", "maps", n); })
	.map(require)
	.forEach(function(doc, i){
		describe("Decode", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decode("&" + e + ";", l), doc[e]);
					}
				});
			});
		});

		describe("Decode strict", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decodeStrict("&" + e + ";", l), doc[e]);
					}
				});
			});
		});

		describe("Encode", function(){
			it(levels[i], function(){
				Object.keys(doc).forEach(function(e){
					for(var l = i; l < levels.length; l++){
						assert.equal(entities.decode(entities.encode(doc[e], l), l), doc[e]);
					}
				});
			});
		});
	});

	var legacy = require("../maps/legacy.json");

	describe("Legacy", function(){
		it("should decode", runLegacy);
	});

	function runLegacy(){
		Object.keys(legacy).forEach(function(e){
			assert.equal(entities.decodeHTML("&" + e), legacy[e]);
		});
	}
});

var astral = {
	"1D306": "\uD834\uDF06",
	"1D11E": "\uD834\uDD1E"
};

var astralSpecial = {
	"80":    "\u20AC",
	"110000": "\uFFFD"
};

describe("Astral entities", function(){
	Object.keys(astral).forEach(function(c){
		it("should decode " + astral[c], function(){
			assert.equal(entities.decode("&#x" + c + ";"), astral[c]);
		});

		it("should encode " + astral[c], function(){
			assert.equal(entities.encode(astral[c]), "&#x" + c + ";");
		});
	});

	Object.keys(astralSpecial).forEach(function(c){
		it("special should decode \\u" + c, function(){
			assert.equal(entities.decode("&#x" + c + ";"), astralSpecial[c]);
		});
	});
});
<|endoftext|>


<commit_before>"use strict";

var ObjectId = require("mongodb").ObjectId;
require("mongodb-toolkit");
var generateCode = require("../../../utils/code-generator");

var PackingManager = require('../../production/finishing-printing/packing-manager');
var ProductManager = require('../../master/product-manager');
var StorageManager = require('../../master/storage-manager');
var InventoryDocumentManager = require('../inventory-document-manager');

var Models = require("dl-models");
var Map = Models.map;
var PackingReceiptModel = Models.inventory.finishingPrinting.FPPackingReceipt;

var BaseManager = require("module-toolkit").BaseManager;
var i18n = require("dl-i18n");
var moment = require("moment");

module.exports = class FPPackingReceiptManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(Map.inventory.finishingPrinting.collection.FPPackingReceipt);

        this.packingManager = new PackingManager(db, user);
        this.productManager = new ProductManager(db, user);
        this.storageManager = new StorageManager(db, user);
        this.inventoryDocumentManager = new InventoryDocumentManager(db, user);
    }

    _getQuery(paging) {
        var _default = {
            _deleted: false
        },
            pagingFilter = paging.filter || {},
            keywordFilter = {},
            query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var packingCodeFilter = {
                "packingCode": {
                    "$regex": regex
                }
            };
            var dateFilter = {
                "date": {
                    "$regex": regex
                }
            };
            var buyerFilter = {
                "buyer": {
                    "$regex": regex
                }
            };
            var productionOrderNoFilter = {
                "productionOrderNo": {
                    "$regex": regex
                }
            };
            var colorNameFilter = {
                "colorName": {
                    "$regex": regex
                }
            };
            var constructionFilter = {
                "construction": {
                    "$regex": regex
                }
            };
            var createdByFilter = {
                "_createdBy": {
                    "$regex": regex
                }
            };
            keywordFilter["$or"] = [packingCodeFilter, dateFilter, buyerFilter, productionOrderNoFilter, colorNameFilter, constructionFilter, createdByFilter];
        }
        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _beforeInsert(data) {
        data.code = generateCode();
        return Promise.resolve(data);
    }

    _validate(packingReceipt) {
        var errors = {};
        var valid = packingReceipt;

        var getDbPackingReceipt = this.collection.singleOrDefault({
            _id: new ObjectId(valid._id)
        });
        var getDuplicatePackingReceipt = this.collection.singleOrDefault({
            _id: {
                '$ne': new ObjectId(valid._id)
            },
            code: valid.code
        });
        var getPacking = valid.packingId && ObjectId.isValid(valid.packingId) ? this.packingManager.getSingleByIdOrDefault(valid.packingId) : Promise.resolve(null);

        var getStorage = valid.items ? this.storageManager.collection.find({ name: "Gudang Jadi Finishing Printing" }).toArray() : Promise.resolve([]);

        valid.items = valid.items instanceof Array ? valid.items : [];
        var products = valid.items.map((item) => item.product ? item.product : null);
        var getProducts = products.length > 0 ? this.productManager.collection.find({ name: { "$in": products } }).toArray() : Promise.resolve([]);

        return Promise.all([getDbPackingReceipt, getDuplicatePackingReceipt, getPacking, getStorage, getProducts])
            .then((results) => {
                var _dbPackingReceipt = results[0];
                var _duplicatePackingReceipt = results[1];
                var _packing = results[2];
                var _storages = results[3];
                var _products = results[4];

                if (_dbPackingReceipt)
                    valid.code = _dbPackingReceipt.code; // prevent code changes.

                if (_duplicatePackingReceipt)
                    errors["code"] = i18n.__("PackingReceipt.code.isExist: %s is exist", i18n.__("PackingReceipt.code._:Code"));

                if (!valid.packingId || valid.packingId === '')
                    errors["packingId"] = i18n.__("PackingReceipt.packingId.isRequired:%s is required", i18n.__("PackingReceipt.packingId._:Packing")); //"Grade harus diisi";
                else if (!_packing)
                    errors["packingId"] = i18n.__("PackingReceipt.packingId: %s not found", i18n.__("PackingReceipt.KanbanId._:Packing"));

                if (!valid.date)
                    errors["date"] = i18n.__("PackingReceipt.date.isRequired:%s is required", i18n.__("PackingReceipt.date._:Date")); //"Grade harus diisi";

                if (!valid.accepted && !valid.declined) {
                    errors["accepted"] = i18n.__("PackingReceipt.accepted.isRequired:%s is required", i18n.__("PackingReceipt.accepted._:Accepted")); //"Grade harus diisi";
                    errors["declined"] = i18n.__("PackingReceipt.declined.isRequired:%s is required", i18n.__("PackingReceipt.declined._:Declined")); //"Grade harus diisi";
                }

                if (valid.items.length > 0) {
                    var itemErrors = [];
                    for (var i = 0; i < _packing.items.length; i++) {
                        var itemError = {};
                        if (valid.items[i].quantity !== _packing.items[i].quantity && (!valid.items[i].notes || valid.items[i].notes === "")) {
                            itemError["notes"] = i18n.__("PackingReceipt.items.notes.isRequired:%s is required", i18n.__("PackingReceipt.items.notes._:Notes")); //"Note harus diisi";
                        }
                        itemErrors.push(itemError);
                    }

                    for (var itemError of itemErrors) {
                        if (Object.getOwnPropertyNames(itemError).length > 0) {
                            errors.items = itemErrors;
                            break;
                        }
                    }
                }

                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require('module-toolkit').ValidationError;
                    return Promise.reject(new ValidationError('data does not pass validation', errors));
                }

                valid.packingId = _packing._id;
                valid.packingCode = _packing.code;

                //Inventory Document Validation
                valid.storageId = _storages.length > 0 ? new ObjectId(_storages[0]._id) : null;
                valid.referenceType = "Penerimaan Packing Gudang Jadi";
                valid.type = "IN";

                for (var i = 0; i < valid.items.length; i++) {
                    valid.items[i].uomId = _products[i].uomId;
                    valid.items[i].productId = _products[i]._id;
                }

                valid.buyer = _packing.buyer;
                valid.productionOrderNo = _packing.productionOrderNo;
                valid.colorName = _packing.colorName;
                valid.construction = _packing.construction;
                valid.packingUom = _packing.packingUom;

                if (!valid.stamp) {
                    valid = new PackingReceiptModel(valid);
                }

                valid.stamp(this.user.username, "manager");
                return Promise.resolve(valid);

            })
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${Map.inventory.finishingPrinting.collection.PackingReceipt}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        }
        var codeIndex = {
            name: `ix_${Map.inventory.finishingPrinting.collection.PackingReceipt}_code`,
            key: {
                code: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, codeIndex]);
    }

    _afterInsert(id) {
        return this.getSingleById(id)
            .then((packingReceipt) => {
                var packingReceiptId = id;
                var packingReceipt = packingReceipt;
                return this.packingManager.getSingleById(packingReceipt.packingId)
                    .then((packing) => {
                        packing.accepted = true;
                        return this.packingManager.update(packing)
                            .then((id) => {
                                packingReceipt.referenceNo = `RFNO-${packingReceipt.code}`;
                                return this.inventoryDocumentManager.create(packingReceipt)
                                    .then((inventoryDocument) => Promise.resolve(packingReceiptId))
                            })
                    })
            })
    }
};
<commit_msg>add packing receipt report<commit_after>"use strict";

var ObjectId = require("mongodb").ObjectId;
require("mongodb-toolkit");
var generateCode = require("../../../utils/code-generator");

var PackingManager = require('../../production/finishing-printing/packing-manager');
var ProductManager = require('../../master/product-manager');
var StorageManager = require('../../master/storage-manager');
var InventoryDocumentManager = require('../inventory-document-manager');

var Models = require("dl-models");
var Map = Models.map;
var PackingReceiptModel = Models.inventory.finishingPrinting.FPPackingReceipt;

var BaseManager = require("module-toolkit").BaseManager;
var i18n = require("dl-i18n");
var moment = require("moment");

module.exports = class FPPackingReceiptManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(Map.inventory.finishingPrinting.collection.FPPackingReceipt);

        this.packingManager = new PackingManager(db, user);
        this.productManager = new ProductManager(db, user);
        this.storageManager = new StorageManager(db, user);
        this.inventoryDocumentManager = new InventoryDocumentManager(db, user);
    }

    _getQuery(paging) {
        var _default = {
            _deleted: false
        },
            pagingFilter = paging.filter || {},
            keywordFilter = {},
            query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var packingCodeFilter = {
                "packingCode": {
                    "$regex": regex
                }
            };
            var dateFilter = {
                "date": {
                    "$regex": regex
                }
            };
            var buyerFilter = {
                "buyer": {
                    "$regex": regex
                }
            };
            var productionOrderNoFilter = {
                "productionOrderNo": {
                    "$regex": regex
                }
            };
            var colorNameFilter = {
                "colorName": {
                    "$regex": regex
                }
            };
            var constructionFilter = {
                "construction": {
                    "$regex": regex
                }
            };
            var createdByFilter = {
                "_createdBy": {
                    "$regex": regex
                }
            };
            keywordFilter["$or"] = [packingCodeFilter, dateFilter, buyerFilter, productionOrderNoFilter, colorNameFilter, constructionFilter, createdByFilter];
        }
        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _beforeInsert(data) {
        data.code = generateCode();
        return Promise.resolve(data);
    }

    _validate(packingReceipt) {
        var errors = {};
        var valid = packingReceipt;

        var getDbPackingReceipt = this.collection.singleOrDefault({
            _id: new ObjectId(valid._id)
        });
        var getDuplicatePackingReceipt = this.collection.singleOrDefault({
            _id: {
                '$ne': new ObjectId(valid._id)
            },
            code: valid.code
        });
        var getPacking = valid.packingId && ObjectId.isValid(valid.packingId) ? this.packingManager.getSingleByIdOrDefault(valid.packingId) : Promise.resolve(null);

        var getStorage = valid.items ? this.storageManager.collection.find({ name: "Gudang Jadi Finishing Printing" }).toArray() : Promise.resolve([]);

        valid.items = valid.items instanceof Array ? valid.items : [];
        var products = valid.items.map((item) => item.product ? item.product : null);
        var getProducts = products.length > 0 ? this.productManager.collection.find({ name: { "$in": products } }).toArray() : Promise.resolve([]);

        return Promise.all([getDbPackingReceipt, getDuplicatePackingReceipt, getPacking, getStorage, getProducts])
            .then((results) => {
                var _dbPackingReceipt = results[0];
                var _duplicatePackingReceipt = results[1];
                var _packing = results[2];
                var _storages = results[3];
                var _products = results[4];

                if (_dbPackingReceipt)
                    valid.code = _dbPackingReceipt.code; // prevent code changes.

                if (_duplicatePackingReceipt)
                    errors["code"] = i18n.__("PackingReceipt.code.isExist: %s is exist", i18n.__("PackingReceipt.code._:Code"));

                if (!valid.packingId || valid.packingId === '')
                    errors["packingId"] = i18n.__("PackingReceipt.packingId.isRequired:%s is required", i18n.__("PackingReceipt.packingId._:Packing")); //"Grade harus diisi";
                else if (!_packing)
                    errors["packingId"] = i18n.__("PackingReceipt.packingId: %s not found", i18n.__("PackingReceipt.KanbanId._:Packing"));

                if (!valid.date)
                    errors["date"] = i18n.__("PackingReceipt.date.isRequired:%s is required", i18n.__("PackingReceipt.date._:Date")); //"Grade harus diisi";

                if (!valid.accepted && !valid.declined) {
                    errors["accepted"] = i18n.__("PackingReceipt.accepted.isRequired:%s is required", i18n.__("PackingReceipt.accepted._:Accepted")); //"Grade harus diisi";
                    errors["declined"] = i18n.__("PackingReceipt.declined.isRequired:%s is required", i18n.__("PackingReceipt.declined._:Declined")); //"Grade harus diisi";
                }

                if (valid.items.length > 0) {
                    var itemErrors = [];
                    for (var i = 0; i < _packing.items.length; i++) {
                        var itemError = {};
                        if (valid.items[i].quantity !== _packing.items[i].quantity && (!valid.items[i].notes || valid.items[i].notes === "")) {
                            itemError["notes"] = i18n.__("PackingReceipt.items.notes.isRequired:%s is required", i18n.__("PackingReceipt.items.notes._:Notes")); //"Note harus diisi";
                        }
                        itemErrors.push(itemError);
                    }

                    for (var itemError of itemErrors) {
                        if (Object.getOwnPropertyNames(itemError).length > 0) {
                            errors.items = itemErrors;
                            break;
                        }
                    }
                }

                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require('module-toolkit').ValidationError;
                    return Promise.reject(new ValidationError('data does not pass validation', errors));
                }

                valid.packingId = _packing._id;
                valid.packingCode = _packing.code;

                //Inventory Document Validation
                valid.storageId = _storages.length > 0 ? new ObjectId(_storages[0]._id) : null;
                valid.referenceType = "Penerimaan Packing Gudang Jadi";
                valid.type = "IN";

                for (var i = 0; i < valid.items.length; i++) {
                    valid.items[i].uomId = _products[i].uomId;
                    valid.items[i].productId = _products[i]._id;
                }

                valid.buyer = _packing.buyer;
                valid.date = new Date(valid.date);
                valid.productionOrderNo = _packing.productionOrderNo;
                valid.colorName = _packing.colorName;
                valid.construction = _packing.construction;
                valid.packingUom = _packing.packingUom;

                if (!valid.stamp) {
                    valid = new PackingReceiptModel(valid);
                }

                valid.stamp(this.user.username, "manager");
                return Promise.resolve(valid);

            })
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${Map.inventory.finishingPrinting.collection.PackingReceipt}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        }
        var codeIndex = {
            name: `ix_${Map.inventory.finishingPrinting.collection.PackingReceipt}_code`,
            key: {
                code: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, codeIndex]);
    }

    _afterInsert(id) {
        return this.getSingleById(id)
            .then((packingReceipt) => {
                var packingReceiptId = id;
                var packingReceipt = packingReceipt;
                return this.packingManager.getSingleById(packingReceipt.packingId)
                    .then((packing) => {
                        packing.accepted = true;
                        return this.packingManager.update(packing)
                            .then((id) => {
                                packingReceipt.referenceNo = `RFNO-${packingReceipt.code}`;
                                return this.inventoryDocumentManager.create(packingReceipt)
                                    .then((inventoryDocument) => Promise.resolve(packingReceiptId))
                            })
                    })
            })
    }

    getReport(info) {
        var _defaultFilter = {
            _deleted: false
        };
        var query = {};

        var packingCodeFilter = {};
        var buyerFilter = {};
        var productionOrderNoFilter = {};
        var _createdByFilter = {};

        var dateFrom = info.dateFrom ? (new Date(info.dateFrom)) : (new Date(1900, 1, 1));
        var dateTo = info.dateTo ? (new Date(info.dateTo + "T23:59")) : (new Date());

        if (info.packingCode && info.packingCode !== "") {
            packingCodeFilter = { "packingCode": info.packingCode };
        }

        if (info.buyer && info.buyer !== "") {
            buyerFilter = { "buyer": info.buyer };
        }

        if (info.productionOrderNo && info.productionOrderNo !== "") {
            productionOrderNoFilter = { "productionOrderNo": info.productionOrderNo };
        }

        if (info._createdBy && info._createdBy !== "") {
            _createdByFilter = { "_createdBy": info._createdBy };
        }

        var dateFilter = {
            "date": {
                $gte: new Date(dateFrom),
                $lte: new Date(dateTo)
            }
        };

        query = { "$and": [_defaultFilter, packingCodeFilter, buyerFilter, productionOrderNoFilter, _createdByFilter, dateFilter] }

        return this._createIndexes()
            .then((createdIndexResults) => {
                return this.collection
                    .where(query)
                    .execute();
            })
    }

    getXls(results, query) {
        var xls = [];
        xls.data = [];
        xls.options = [];
        xls.name = "";

        var index = 1;
        var dateFormat = "DD/MM/YYYY";

        for (var result of results.data) {
            if (result.items) {
                for (var item of result.items) {
                    var detail = {};
                    detail["No"] = index;
                    detail["Kode Paking"] = result.packingCode ? result.packingCode : "";
                    detail["Tanggal"] = result.date ? moment(result.date).format(dateFormat) : "";
                    detail["Buyer"] = result.buyer ? result.buyer : "";
                    detail["Nomor Order"] = result.productionOrderNo ? result.productionOrderNo : "";
                    detail["Warna"] = result.colorName ? result.colorName : "";
                    detail["Konstruksi"] = result.construction ? result.construction : "";
                    detail["Diterima Oleh"] = result._createdBy ? result._createdBy : "";
                    detail["UOM"] = result.packingUom ? result.packingUom : "";
                    detail["Nama Barang"] = item.product ? item.product : "";
                    detail["Kuantiti Diterima"] = item.quantity ? item.quantity : 0;
                    detail["Remark"] = item.remark ? item.remark : "";
                    detail["Catatan"] = item.notes ? item.notes : "";

                    xls.options["No"] = "number";
                    xls.options["Kode Paking"] = "string";
                    xls.options["Tanggal"] = "string";
                    xls.options["Buyer"] = "string";
                    xls.options["Nomor Order"] = "string";
                    xls.options["Warna"] = "string";
                    xls.options["Konstruksi"] = "string";
                    xls.options["Diterima Oleh"] = "string";
                    xls.options["UOM"] = "string";
                    xls.options["Nama Barang"] = "string";
                    xls.options["Kuantiti Diterima"] = "number";
                    xls.options["Remark"] = "string";
                    xls.options["Catatan"] = "string";

                    index++;
                    xls.data.push(detail);
                }
            }
        }

        if (query.dateFrom && query.dateTo) {
            xls.name = `Laporan Penerimaan Packing ${moment(new Date(query.dateFrom)).format(dateFormat)} - ${moment(new Date(query.dateTo)).format(dateFormat)}.xlsx`
        } else if (!query.dateFrom && query.dateTo) {
            xls.name = `Laporan Penerimaan Packing ${moment(new Date(query.dateTo)).format(dateFormat)}.xlsx`
        } else if (query.dateFrom && !query.dateTo) {
            xls.name = `Laporan Penerimaan Packing ${moment(new Date(query.dateFrom)).format(dateFormat)}.xlsx`
        } else {
            xls.name = `Laporan Penerimaan Packing.xlsx`;
        }

        return Promise.resolve(xls);
    }
};
<|endoftext|>


<commit_before>import angular from 'angular';
import _ from 'underscore';

angular.module('dimApp')
  .directive('dimTalentGrid', TalentGrid)
  .filter('talentGridNodes', function() {
    return function(nodes, hiddenColumns) {
      return _.filter(nodes || [], function(node) {
        return !node.hidden && node.column >= hiddenColumns;
      });
    };
  });

function TalentGrid() {
  return {
    bindToController: true,
    controller: TalentGridCtrl,
    controllerAs: 'vm',
    scope: {
      talentGrid: '=',
      perksOnly: '=',
      infuse: '&dimInfuse'
    },
    restrict: 'E',
    replace: true,
    template: [
      '<svg preserveAspectRatio="xMaxYMin meet" svg-bind-viewbox="0 0 {{(vm.numColumns * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}} {{(vm.numRows * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor + 1}}" class="talent-grid" ng-attr-height="{{(vm.numRows * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}}" ng-attr-width="{{(vm.numColumns * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}}">',
      ' <g ng-attr-transform="scale({{vm.scaleFactor}})">',
      '  <g class="talent-node" ng-attr-transform="translate({{(node.column - vm.hiddenColumns) * (vm.totalNodeSize)}},{{node.row * (vm.totalNodeSize)}})" ng-repeat="node in vm.talentGrid.nodes | talentGridNodes:vm.hiddenColumns track by $index" ng-class="{ \'talent-node-activated\': node.activated, \'talent-node-showxp\': (!node.activated && node.xpRequired), \'talent-node-default\': (node.activated && !node.xpRequired && !node.exclusiveInColumn) }" ng-click="node.hash == 1270552711 ? vm.infuse({\'$event\': $event}) : true">',
      '    <circle r="16" cx="-17" cy="17" transform="rotate(-90)" class="talent-node-xp" ng-attr-stroke-width="{{node.xp ? 2 : 0}}" ng-attr-stroke-dasharray="{{100.0 * node.xp / node.xpRequired}} 100" />',
      '    <image class="talent-node-img" xlink:href="" ng-attr-xlink:href="{{ node.icon | bungieIcon }}" x="20" y="20" height="96" width="96" transform="scale(0.25)"/>',
      '    <title>{{node.name}}\n{{node.description}}</title>',
      '  </g>',
      '</g>',
      '</svg>'
    ].join('')
  };
}

function TalentGridCtrl(dimInfoService, $translate) {
  const infuseHash = 1270552711;
  var vm = this;
  vm.nodeSize = 34;
  vm.nodePadding = 4;
  vm.scaleFactor = 1.1;
  vm.totalNodeSize = vm.nodeSize + vm.nodePadding;

  vm.nodeClick = function(node, $event) {
    if (node.hash === infuseHash) {
      vm.infuse({ $event });
    } else if (node.exclusiveInColumn) {
      // popup warning
      dimInfoService.show('lostitems', {
        type: 'warning',
        title: $translate.instant('Help.ChangingPerks'),
        body: $translate.instant('Help.ChangingPerksInfo'),
        hide: $translate.instant('Help.NeverShow')
      });
    }
  };

  vm.hiddenColumns = 0;
  if (vm.perksOnly) {
    if (_.find(vm.talentGrid.nodes, { hash: infuseHash })) {
      vm.hiddenColumns += 1;
    }
    if (_.find(vm.talentGrid.nodes, { hash: 2133116599 })) {
      vm.hiddenColumns += 1;
    }
  }

  if (vm.talentGrid) {
    const visibleNodes = _.reject(vm.talentGrid.nodes, 'hidden');
    vm.numColumns = _.max(visibleNodes, 'column').column + 1 - vm.hiddenColumns;
    vm.numRows = vm.perksOnly ? 2 : (_.max(visibleNodes, 'row').row + 1);
  }
}

<commit_msg>Wrong id for change-perks info popup<commit_after>import angular from 'angular';
import _ from 'underscore';

angular.module('dimApp')
  .directive('dimTalentGrid', TalentGrid)
  .filter('talentGridNodes', function() {
    return function(nodes, hiddenColumns) {
      return _.filter(nodes || [], function(node) {
        return !node.hidden && node.column >= hiddenColumns;
      });
    };
  });

function TalentGrid() {
  return {
    bindToController: true,
    controller: TalentGridCtrl,
    controllerAs: 'vm',
    scope: {
      talentGrid: '=',
      perksOnly: '=',
      infuse: '&dimInfuse'
    },
    restrict: 'E',
    replace: true,
    template: [
      '<svg preserveAspectRatio="xMaxYMin meet" svg-bind-viewbox="0 0 {{(vm.numColumns * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}} {{(vm.numRows * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor + 1}}" class="talent-grid" ng-attr-height="{{(vm.numRows * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}}" ng-attr-width="{{(vm.numColumns * vm.totalNodeSize - vm.nodePadding) * vm.scaleFactor}}">',
      ' <g ng-attr-transform="scale({{vm.scaleFactor}})">',
      '  <g class="talent-node" ng-attr-transform="translate({{(node.column - vm.hiddenColumns) * (vm.totalNodeSize)}},{{node.row * (vm.totalNodeSize)}})" ng-repeat="node in vm.talentGrid.nodes | talentGridNodes:vm.hiddenColumns track by $index" ng-class="{ \'talent-node-activated\': node.activated, \'talent-node-showxp\': (!node.activated && node.xpRequired), \'talent-node-default\': (node.activated && !node.xpRequired && !node.exclusiveInColumn) }" ng-click="node.hash == 1270552711 ? vm.infuse({\'$event\': $event}) : true">',
      '    <circle r="16" cx="-17" cy="17" transform="rotate(-90)" class="talent-node-xp" ng-attr-stroke-width="{{node.xp ? 2 : 0}}" ng-attr-stroke-dasharray="{{100.0 * node.xp / node.xpRequired}} 100" />',
      '    <image class="talent-node-img" xlink:href="" ng-attr-xlink:href="{{ node.icon | bungieIcon }}" x="20" y="20" height="96" width="96" transform="scale(0.25)"/>',
      '    <title>{{node.name}}\n{{node.description}}</title>',
      '  </g>',
      '</g>',
      '</svg>'
    ].join('')
  };
}

function TalentGridCtrl(dimInfoService, $translate) {
  const infuseHash = 1270552711;
  var vm = this;
  vm.nodeSize = 34;
  vm.nodePadding = 4;
  vm.scaleFactor = 1.1;
  vm.totalNodeSize = vm.nodeSize + vm.nodePadding;

  vm.nodeClick = function(node, $event) {
    if (node.hash === infuseHash) {
      vm.infuse({ $event });
    } else if (node.exclusiveInColumn) {
      // popup warning
      dimInfoService.show('changeperks', {
        type: 'warning',
        title: $translate.instant('Help.ChangingPerks'),
        body: $translate.instant('Help.ChangingPerksInfo'),
        hide: $translate.instant('Help.NeverShow')
      });
    }
  };

  vm.hiddenColumns = 0;
  if (vm.perksOnly) {
    if (_.find(vm.talentGrid.nodes, { hash: infuseHash })) {
      vm.hiddenColumns += 1;
    }
    if (_.find(vm.talentGrid.nodes, { hash: 2133116599 })) {
      vm.hiddenColumns += 1;
    }
  }

  if (vm.talentGrid) {
    const visibleNodes = _.reject(vm.talentGrid.nodes, 'hidden');
    vm.numColumns = _.max(visibleNodes, 'column').column + 1 - vm.hiddenColumns;
    vm.numRows = vm.perksOnly ? 2 : (_.max(visibleNodes, 'row').row + 1);
  }
}

<|endoftext|>