<commit_before>/*!
 * This file is part of {@link https://github.com/MovLib MovLib}.
 *
 * Copyright © 2013-present {@link https://movlib.org/ MovLib}.
 *
 * MovLib 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.
 *
 * MovLib 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 MovLib.
 * If not, see {@link http://www.gnu.org/licenses/ gnu.org/licenses}.
 */

/* jshint browser:true */

/**
 * @module MovLib
 * @namespace modules
 * @submodule InputHTML
 * @author Richard Fussenegger <richard@fussenegger.info>
 * @author Markus Deutschl <mdeutschl.mmt-m2012@fh-salzburg.ac.at>
 * @copyright © 2013 MovLib
 * @license http://www.gnu.org/licenses/agpl.html AGPL-3.0
 * @link https://movlib.org/
 * @since 0.0.1-dev
 * @param {window} window
 * @param {document} document
 * @param {MovLib} MovLib
 * @return {undefined}
 */
(function (window, document, MovLib) {
  "use strict";

  /**
   * WYSIWYG editor for the InputHTML form elemement partial plus other handy features.
   *
   * @class InputHTML
   * @constructor
   * @param {HTMLElement} element
   *   The .inputhtml element to work with.
   */
  function InputHTML(element) {

    /**
     * The form's textarea, contains the HTML source.
     *
     * @property textarea
     * @type HTMLElement
     */
    this.textarea = element.children[1].children[1];

    /**
     * The
 wrapping the WYSIWYG buttons.
     *
     * @property editor
     * @type HTMLElement
     */
    this.editor = element.children[2];

    /**
     * The content editable
.
     *
     * @property content
     * @type HTMLElement
     */
    this.content = this.editor.children[0].children[0];

    // Enhance the current element.
    this.init(element);
  }

  InputHTML.prototype = {

    /**
     * Copy the content of the content editable element back into the textarea.
     *
     * @method copyToTextarea
     * @chainable
     * @return {InputHTML}
     */
    copyToTextarea: function () {
      this.textarea.value = this.content.innerHTML;
      return this;
    },

    /**
     * React on focus changes.
     *
     * @method focus
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    focus: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Focus event is now totally disabled for this HTMLElement! (Doesn't account for mouse clicks ;)
      return this;
    },

    /**
     * Initialize .inputhtml element.
     *
     * @method init
     * @chainable
     * @param {HTMLElement} element
     *   The element to initialize.
     * @return {InputHTML}
     */
    init: function (element) {
      // Copy textarea's content into our content area.
      // @todo Does this really trigger a single reflow?
      this.content.innerHTML = this.textarea.value;

      // We have to copy the divs content back into the textarea directly before the form is submitted to ensure that
      // the content is automatically passed to our webserver via the browser. We only do this once instead of updating
      // the textarea on every key event.
      element.form.addEventListener("submit", this.copyToTextarea.bind(this), false);

      // React on various content events.
      this.content.addEventListener("focus", this.focus.bind(this), false);
      this.content.addEventListener("keydown", this.focus.bind(this), false);
      this.content.addEventListener("keyup", this.focus.bind(this), false);

      // Use this to print an HTMLElement to the console!
      //console.dir(element);
      //
      // How to document: http://yui.github.io/yuidoc/syntax/index.html
      //
      // Helpful code: https://github.com/jakiestfu/Medium.js/blob/master/medium.js
      //
      // Remember IE9+ support!
      // Remember if something results in more than a single reflow hide and show element.

      return this;
    },

    /**
     * React on keydown changes.
     *
     * @method keydown
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    keydown: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Keydown event is now totally disabled for this HTMLElement!
      return this;
    },

    /**
     * React on keyup changes.
     *
     * @method keyup
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    keyup: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Keyup event is now totally disabled for this HTMLElement!
      return this;
    }

  };

  /**
   * Attach InputHTML to the MovLib modules namespace.
   *
   * @method
   * @chainable
   * @param {HTMLCollection} context
   *   The context we are currently working with.
   * @return {MovLib}
   */
  MovLib.modules.InputHTML = function (context) {
    var elements = context.getElementsByClassName("inputhtml");

    // Go through all matching HTMLElements and enhance them if they aren't already enhanced.
    for (var i = 0; i < elements.length; ++i) {
      if (!elements[i].inputhtml) {
        elements[i].inputhtml = new InputHTML(elements[i]);
      }
    }

    return MovLib;
  };

})(window, window.document, window.MovLib);
<commit_msg>Fixed selection of the editor div.<commit_after>/*!
 * This file is part of {@link https://github.com/MovLib MovLib}.
 *
 * Copyright © 2013-present {@link https://movlib.org/ MovLib}.
 *
 * MovLib 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.
 *
 * MovLib 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 MovLib.
 * If not, see {@link http://www.gnu.org/licenses/ gnu.org/licenses}.
 */

/* jshint browser:true */

/**
 * @module MovLib
 * @namespace modules
 * @submodule InputHTML
 * @author Richard Fussenegger <richard@fussenegger.info>
 * @author Markus Deutschl <mdeutschl.mmt-m2012@fh-salzburg.ac.at>
 * @copyright © 2013 MovLib
 * @license http://www.gnu.org/licenses/agpl.html AGPL-3.0
 * @link https://movlib.org/
 * @since 0.0.1-dev
 * @param {window} window
 * @param {document} document
 * @param {MovLib} MovLib
 * @return {undefined}
 */
(function (window, document, MovLib) {
  "use strict";

  /**
   * WYSIWYG editor for the InputHTML form elemement partial plus other handy features.
   *
   * @class InputHTML
   * @constructor
   * @param {HTMLElement} element
   *   The .inputhtml element to work with.
   */
  function InputHTML(element) {

    /**
     * The form's textarea, contains the HTML source.
     *
     * @property textarea
     * @type HTMLElement
     */
    this.textarea = element.children[1].children[1];

    /**
     * The
 wrapping the WYSIWYG buttons.
     *
     * @property editor
     * @type HTMLElement
     */
    this.editor = element.children[2];

    /**
     * The content editable
.
     *
     * @property content
     * @type HTMLElement
     */
    this.content = this.editor.children[this.editor.children.length - 1].children[0];

    // Enhance the current element.
    this.init(element);
  }

  InputHTML.prototype = {

    /**
     * Copy the content of the content editable element back into the textarea.
     *
     * @method copyToTextarea
     * @chainable
     * @return {InputHTML}
     */
    copyToTextarea: function () {
      this.textarea.value = this.content.innerHTML;
      return this;
    },

    /**
     * React on focus changes.
     *
     * @method focus
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    focus: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Focus event is now totally disabled for this HTMLElement! (Doesn't account for mouse clicks ;)
      return this;
    },

    /**
     * Initialize .inputhtml element.
     *
     * @method init
     * @chainable
     * @param {HTMLElement} element
     *   The element to initialize.
     * @return {InputHTML}
     */
    init: function (element) {
      // Copy textarea's content into our content area.
      // @todo Does this really trigger a single reflow?
      this.content.innerHTML = this.textarea.value;

      // We have to copy the divs content back into the textarea directly before the form is submitted to ensure that
      // the content is automatically passed to our webserver via the browser. We only do this once instead of updating
      // the textarea on every key event.
      element.form.addEventListener("submit", this.copyToTextarea.bind(this), false);

      // React on various content events.
      this.content.addEventListener("focus", this.focus.bind(this), false);
      this.content.addEventListener("keydown", this.focus.bind(this), false);
      this.content.addEventListener("keyup", this.focus.bind(this), false);

      // Use this to print an HTMLElement to the console!
      //console.dir(element);
      //
      // How to document: http://yui.github.io/yuidoc/syntax/index.html
      //
      // Helpful code: https://github.com/jakiestfu/Medium.js/blob/master/medium.js
      //
      // Remember IE9+ support!
      // Remember if something results in more than a single reflow hide and show element.

      return this;
    },

    /**
     * React on keydown changes.
     *
     * @method keydown
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    keydown: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Keydown event is now totally disabled for this HTMLElement!
      return this;
    },

    /**
     * React on keyup changes.
     *
     * @method keyup
     * @chainable
     * @param {Event} event
     *   The focus event.
     * @return {InputHTML}
     */
    keyup: function (event) {
      event.preventDefault();
      event.returnValue = false;
      // Keyup event is now totally disabled for this HTMLElement!
      return this;
    }

  };

  /**
   * Attach InputHTML to the MovLib modules namespace.
   *
   * @method
   * @chainable
   * @param {HTMLCollection} context
   *   The context we are currently working with.
   * @return {MovLib}
   */
  MovLib.modules.InputHTML = function (context) {
    var elements = context.getElementsByClassName("inputhtml");

    // Go through all matching HTMLElements and enhance them if they aren't already enhanced.
    for (var i = 0; i < elements.length; ++i) {
      if (!elements[i].inputhtml) {
        elements[i].inputhtml = new InputHTML(elements[i]);
      }
    }

    return MovLib;
  };

})(window, window.document, window.MovLib);
<|endoftext|>


<commit_before>// Set up the DataTable in table.blade.php
var DataTableHandle = function () {
    var options = null;
    var ajaxParams = null;
    var the = null;
    return {
        init: function (tmpOptions) {
            if (!$().dataTable) {
                return;
            }
            // default settings
            options = $.extend(true, {
                src: null, // table selector
                filterApplyAction: null,
                filterCancelAction: null,
                editURL: null,
                deleteURL: null,
                column_model: null,
                primary_key: null,
                defaultParams: {},
                dataTable: {
                    ajax: { // define ajax settings
                        "type": "POST", // request type
                        "data": function (data) { // add request parameters before submit
                            $.each(ajaxParams, function (key, value) {
                                data[key] = value;
                            });
                        }
                    },
                    columns: {},
                    aaSorting: [],
                    aoColumnDefs: [
                        {
                            targets: -1,
                            render: function (data, type, col) {
                                var primaryCol = the.getPrimaryKeyCol();
                                if (primaryCol != null) {
                                    var tmpEditURL = options.editURL + '/' + col[primaryCol];
                                    var _tmpButtons = " Edit ";
                                    _tmpButtons += "<button style='margin: 0px' class='btn btn-xs btn-danger btn-remove' data-id='" + col[primaryCol] + "'> Delete</button>";
                                    return _tmpButtons;
                                }
                                else {
                                    return null;
                                }
                            }
                        }
                    ],
                    drawCallback: function() { // Do not display tfoot if datatable is empty
                        if(this.api().rows().count() === 0) {
                            this.find('tfoot').hide();
                        } else {
                            this.find('tfoot').show();
                        }
                    },
                    buttons: []
                }
            }, tmpOptions);

            the = this;
            the.initAjaxParams();

            options.dataTable.columns.push({
                name: 'tmpActions',
                orderable: false
            });

            var $table = $(options.src);
            var dataTable = $table.DataTable(options.dataTable);

            $table.on('click', 'button.btn-remove', function () {
                if (!window.confirm('Are you sure you want to delete this item? This cannot be reversed.')) {
                    return;
                }
                $.ajax({
                    url: options.deleteURL + '/' + $(this).data('id') + '/delete',
                    method: 'POST'
                }).done(function (data) {
                    if (data.success) {
                        dataTable.ajax.reload();
                    }
                    else {
                        alert(data.error);
                    }
                });
            });

            // Select all button clicked
            $table.on('click', '#selectAll', function () {
                $table.find('tbody input[type="checkbox"]').prop('checked', this.checked);
            });

            // Batch delete items
            $table.on('click', '#batchDelete', function () {
                var ids = [];
                $table.find('tbody input[type="checkbox"]').each(function(){
                    if($(this).is(':checked')) {
                        ids.push($(this).val());
                    }
                });

                if (ids.length > 0) {
                    if (!window.confirm('Are you sure you want to delete selected item(s)? This cannot be reversed.')) {
                        return;
                    }
                    $.ajax({
                        url: options.deleteURL + '/destroy',
                        method: 'POST',
                        data: {ids:ids},
                    }).done(function (data) {
                        if (data.success) {
                            dataTable.ajax.reload();
                            $table.find('#selectAll').prop('checked', false);
                        }
                        else {
                            alert(data.error);
                        }
                    });
                }
            });

            // Batch activate / deactivate items
            $table.on('click', '#batchActivate', function () {
                toogleActivate('active');
            });

            $table.on('click', '#batchDeactivate', function () {
                toogleActivate('inactive');
            });

            function toogleActivate(status) {
                var ids = [];
                $table.find('tbody input[type="checkbox"]').each(function(){
                    if($(this).is(':checked')) {
                        ids.push($(this).val());
                    }
                });

                if (ids.length > 0) {
                    if (!window.confirm('Are you sure?')) {
                        return;
                    }
                    $.ajax({
                        url: options.deleteURL + '/toggle_activate',
                        method: 'POST',
                        data: {status: status, ids:ids},
                    }).done(function (data) {
                        if (data.success) {
                            dataTable.ajax.reload();
                            $table.find('#selectAll').prop('checked', false);
                        }
                        else {
                            alert(data.error);
                        }
                    });
                }
            }

            $(options.filterApplyAction).click(function () {
                the.initAjaxParams();
                dataTable.ajax.reload();
            });
            $(options.filterCancelAction).click(function () {
                $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])')
                    .not(':button, :submit, :reset, :hidden')
                    .val('')
                    .removeAttr('checked')
                    .removeAttr('selected');
                $('.select2-hidden-accessible').val('').trigger('change');

                the.initAjaxParams();
                dataTable.ajax.reload();
            });
        },
        getPrimaryKeyCol: function () {
            var ColNum = null;
            $.each(options.column_model, function (key, obj) {
                if (obj.column_name == options.primary_key) {
                    ColNum = key;
                }
            });
            return ColNum;
        },
        setAjaxParam: function (name, value) {
            ajaxParams[name] = value;
        },
        addAjaxParam: function (name, value) {
            if (!ajaxParams[name]) {
                ajaxParams[name] = [];
            }
            skip = false;
            for (var i = 0; i < (ajaxParams[name]).length; i++) { // check for duplicates
                if (ajaxParams[name][i] === value) {
                    skip = true;
                }
            }
            if (skip === false) {
                ajaxParams[name].push(value);
            }
        },
        initAjaxParams: function () {
            ajaxParams = options.defaultParams;
            // get all typeable inputs
            $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])').each(function () {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });
            // get all checkboxes
            $('input.form-filter[type="checkbox"]:checked').each(function () {
                the.addAjaxParam($(this).attr("name"), $(this).val());
            });
            // get all radio buttons
            $('input.form-filter[type="radio"]:checked').each(function () {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });
        }
    }
}()
<commit_msg>Fixes #717 Update javascript<commit_after>// Set up the DataTable in table.blade.php
var DataTableHandle = function () {
    var options = null;
    var ajaxParams = null;
    var the = null;
    return {
        init: function (tmpOptions) {
            if (!$().dataTable) {
                return;
            }
            // default settings
            options = $.extend(true, {
                src: null, // table selector
                filterApplyAction: null,
                filterCancelAction: null,
                editURL: null,
                deleteURL: null,
                column_model: null,
                primary_key: null,
                defaultParams: {},
                dataTable: {
                    ajax: { // define ajax settings
                        "type": "POST", // request type
                        "data": function (data) { // add request parameters before submit
                            $.each(ajaxParams, function (key, value) {
                                data[key] = value;
                            });
                        }
                    },
                    columns: {},
                    aaSorting: [],
                    aoColumnDefs: [
                        {
                            targets: -1,
                            render: function (data, type, col) {
                                var primaryCol = the.getPrimaryKeyCol();
                                if (primaryCol != null) {
                                    var tmpEditURL = options.editURL + '/' + col[primaryCol];
                                    var _tmpButtons = " Edit ";
                                    _tmpButtons += "<button style='margin: 0px' class='btn btn-xs btn-danger btn-remove' data-id='" + col[primaryCol] + "'> Delete</button>";
                                    return _tmpButtons;
                                }
                                else {
                                    return null;
                                }
                            }
                        }
                    ],
                    createdRow: function( row, data, dataIndex ) {
                        primaryCol = the.getPrimaryKeyCol();
                        if (primaryCol != null) {
                            $(row).attr('data-id', data[primaryCol]);
                        }
                    },
                    drawCallback: function() { // Do not display tfoot if datatable is empty
                        if(this.api().rows().count() === 0) {
                            this.find('tfoot').hide();
                        } else {
                            this.find('tfoot').show();
                        }
                    },
                    buttons: []
                }
            }, tmpOptions);

            the = this;
            the.initAjaxParams();

            options.dataTable.columns.push({
                name: 'tmpActions',
                orderable: false
            });

            var $table = $(options.src);
            var dataTable = $table.DataTable(options.dataTable);

            if (dataTable.column('lft:name').length > 0) {
                dataTable.order( [ dataTable.column('lft:name').index(), 'desc' ] );
                dataTable.draw();
            }

            $table.on('click', 'button.btn-remove', function () {
                if (!window.confirm('Are you sure you want to delete this item? This cannot be reversed.')) {
                    return;
                }
                $.ajax({
                    url: options.deleteURL + '/' + $(this).data('id') + '/delete',
                    method: 'POST'
                }).done(function (data) {
                    if (data.success) {
                        dataTable.ajax.reload();
                    }
                    else {
                        alert(data.error);
                    }
                });
            });

            // Select all button clicked
            $table.on('click', '#selectAll', function () {
                $table.find('tbody input[type="checkbox"]').prop('checked', this.checked);
            });

            // Batch delete items
            $table.on('click', '#batchDelete', function () {
                var ids = [];
                $table.find('tbody input[type="checkbox"]').each(function(){
                    if($(this).is(':checked')) {
                        ids.push($(this).val());
                    }
                });

                if (ids.length > 0) {
                    if (!window.confirm('Are you sure you want to delete selected item(s)? This cannot be reversed.')) {
                        return;
                    }
                    $.ajax({
                        url: options.deleteURL + '/destroy',
                        method: 'POST',
                        data: {ids:ids},
                    }).done(function (data) {
                        if (data.success) {
                            dataTable.ajax.reload();
                            $table.find('#selectAll').prop('checked', false);
                        }
                        else {
                            alert(data.error);
                        }
                    });
                }
            });

            // Batch activate / deactivate items
            $table.on('click', '#batchActivate', function () {
                toogleActivate('active');
            });

            $table.on('click', '#batchDeactivate', function () {
                toogleActivate('inactive');
            });

            function toogleActivate(status) {
                var ids = [];
                $table.find('tbody input[type="checkbox"]').each(function(){
                    if($(this).is(':checked')) {
                        ids.push($(this).val());
                    }
                });

                if (ids.length > 0) {
                    if (!window.confirm('Are you sure?')) {
                        return;
                    }
                    $.ajax({
                        url: options.deleteURL + '/toggle_activate',
                        method: 'POST',
                        data: {status: status, ids:ids},
                    }).done(function (data) {
                        if (data.success) {
                            dataTable.ajax.reload();
                            $table.find('#selectAll').prop('checked', false);
                        }
                        else {
                            alert(data.error);
                        }
                    });
                }
            }

            $(options.filterApplyAction).click(function () {
                the.initAjaxParams();
                dataTable.ajax.reload();
            });
            $(options.filterCancelAction).click(function () {
                $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])')
                    .not(':button, :submit, :reset, :hidden')
                    .val('')
                    .removeAttr('checked')
                    .removeAttr('selected');
                $('.select2-hidden-accessible').val('').trigger('change');

                the.initAjaxParams();
                dataTable.ajax.reload();
            });
        },
        getPrimaryKeyCol: function () {
            var ColNum = null;
            $.each(options.column_model, function (key, obj) {
                if (obj.column_name == options.primary_key) {
                    ColNum = key;
                }
            });
            return ColNum;
        },
        setAjaxParam: function (name, value) {
            ajaxParams[name] = value;
        },
        addAjaxParam: function (name, value) {
            if (!ajaxParams[name]) {
                ajaxParams[name] = [];
            }
            skip = false;
            for (var i = 0; i < (ajaxParams[name]).length; i++) { // check for duplicates
                if (ajaxParams[name][i] === value) {
                    skip = true;
                }
            }
            if (skip === false) {
                ajaxParams[name].push(value);
            }
        },
        initAjaxParams: function () {
            ajaxParams = options.defaultParams;
            // get all typeable inputs
            $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])').each(function () {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });
            // get all checkboxes
            $('input.form-filter[type="checkbox"]:checked').each(function () {
                the.addAjaxParam($(this).attr("name"), $(this).val());
            });
            // get all radio buttons
            $('input.form-filter[type="radio"]:checked').each(function () {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });
        }
    }
}()
<|endoftext|>


<commit_before>	$('.navbar-header .nav a h4').html('Users');
	// 09/14/2021 START
	// 09/14/2021, AKT - Updated User.js file formatting
	user_form_attributes = [
		{name:'id', label:'Graphene ID', edit:false},
		{name:'unique_id',label:'Unique ID', edit:[{type:'matches',name:'modify_unique_id',value:true}]},
		{name:'first_name',label:'First Name'},
		{name:'last_name',label:'Last Name'},
		{name:'email',label:'Email'},
        {type:"switch",label: "Modify Unique ID",name: "modify_unique_id",value: false,options: [{value: false},{value: true}], parse:false},
	];

	$('#table').html(`

User Information

Site Permissions

Group Memberships

Group Admins

Developer Apps

Developer Workflows

			`);
	user_groups_memberships_template= `

			{{#group_members}}
				{{#group}}

						{{group.name}}

				{{/group}}
			{{/group_members}}

		{{^group_members}}

No Group Memberships

		{{/group_members}}
	`;

	user_app_developers_template = `

		{{#app_developers}}
			{{#app}}

					{{app.name}}

			{{/app}}
		{{/app_developers}}

	{{^app_developers}}

Not a Developer of any Apps

	{{/app_developers}}
`;

    user_workflow_developers_template = `

        {{#workflow_developers}}
            {{#workflow}}

                    {{workflow.name}}

            {{/workflow}}
        {{/workflow_developers}}

    {{^workflow_developers}}

Not a Developer of any Workflows

    {{/workflow_developers}}
    `;

	user_group_admins_template = `

			{{#group_admins}}
				{{#group}}

						{{group.name}}
						{{#apps_admin}}{{/apps_admin}}
						{{#content_admin}}{{/content_admin}}

				{{/group}}
			{{/group_admins}}

		{{^group_admins}}

No Group Admin Privileges

		{{/group_admins}}`;

	new gform({
		name:'user_search',
		el:'#user-search',
		actions:[],
		label:false,
		fields:[
			{name:'query',label:false,placeholder:'Search', pre:'',help:"Start typing a name to search i.e. john
"},
			{type:'output',name:'results',label:false}
		]
		})
		.on('change:query',function(){
			if(typeof gform.instances.user !== 'undefined'){
				gform.instances.user.destroy();
			}
            $('.user-view').hide();
		})
		.on('change:query',_.debounce(function(e){
			$.ajax({
				url: '/api/users/search/'+this.toJSON().query,
				success: function(data) {
					e.form.find('results').update({value:templates['user_list'].render({users:data})})
				}.bind(e)
			})
		},500))

	$('body').on('click','.list-group-item.user', function(e){
		if(typeof gform.instances.user !== 'undefined'){
			gform.instances.user.destroy();
		}
		if(typeof gform.instances.site_permissions !=='undefined'){
			gform.instances.site_permissions.destroy();
		}
		$.ajax({
			// url: '/api/users/search/'+this.toJSON().query,
			url: '/api/users/'+e.currentTarget.dataset.id+'/info',
			success: function(data) {
				$('.user-view').show();
				//Show User Group Memberships
				$('.user-group-memberships').html(gform.m(user_groups_memberships_template,data));
				// Show the apps where the users is the lead developer
				$('.user-app-developers').html(gform.m(user_app_developers_template,data));
				// Show the workflows where the users is the lead developer
				$('.user-workflow-developers').html(gform.m(user_workflow_developers_template,data));
				// Show the groups where the user is the admin
				$('.user-group-admins').html(gform.m(user_group_admins_template,data));

				// Edit User
				new gform({
					actions:[
                        {"type":"button","label":"Save","action":"save","modifiers":"btn btn-primary"},
						{"type":"button","label":" Impersonate User","action":"impersonate","modifiers":"btn btn-danger"}
					],
					el: "#user-info",
					name: 'user',
					data:data,
					strict:false,
					fields:user_form_attributes
				})
				.on('save',function(e){
					$.ajax({
						url: '/api/users/'+e.form.get().id,
						type: 'PUT',
						dataType : 'json',
						contentType: 'application/json',
						data: JSON.stringify(e.form.get()),
						success: function(data) {
							e.form.set(data);
							toastr.success("Updated Site Permissions Successfully");
						},error: function(data){
							toastr.error(data);
                        }
					})
				})
				.on('impersonate',function(form_data){
					$.ajax({
						url: '/api/users/'+form_data.form.get().id+'/impersonate',
						type: 'GET',
						success: function(data) {
							window.location = '/';
					}
					});
				});

				new gform({
					actions:[{type:'save'}],
					el: ".user-site-permissions",
					name: 'site_permissions',
					data:data,
					strict:false,
					"fields":[
						{type:'hidden', name:'user_id'},
						{
							"type": "checkbox",
							"label": "Site Admin",
							"name": "site_admin",
							"multiple": true,
							"options": [
								{
									"label": "Yes",
									"value": false
								},
								{
									"label": "Yes",
									"value": true
								}
							]
						},{
							"type": "checkbox",
							"label": "Site Developer",
							"name": "site_developer",
							"multiple": true,
							"options": [
								{
									"label": "Yes",
									"value": false
								},
								{
									"label": "Yes",
									"value": true
								}
							]
						}
					],
					"el":".user-site-permissions",
					"data":{
						user_id:data.id,
						site_developer:data.site_members[0].site_developer,
						site_admin:data.site_members[0].site_admin
					},
					"actions":[
						{"type":"save","label":"Update Permissions","modifiers":"btn btn-primary"}
					]
				}).on('save',function(e){
					$.ajax({
						url: '/api/users/'+e.form.get().user_id+'/info',
						type: 'PUT',
						dataType : 'json',
						contentType: 'application/json',
						data: JSON.stringify(e.form.get()),
						success: function(data) {
							e.form.set(data);
							toastr.success("Updated Site Permissions Successfully");
						},error: function(data){
							toastr.error(data);
						}
					})
				})
			}.bind(e)

		});
	});<commit_msg>Fix URL Search Link for Group Admins<commit_after>	$('.navbar-header .nav a h4').html('Users');
	// 09/14/2021 START
	// 09/14/2021, AKT - Updated User.js file formatting
	user_form_attributes = [
		{name:'id', label:'Graphene ID', edit:false},
		{name:'unique_id',label:'Unique ID', edit:[{type:'matches',name:'modify_unique_id',value:true}]},
		{name:'first_name',label:'First Name'},
		{name:'last_name',label:'Last Name'},
		{name:'email',label:'Email'},
        {type:"switch",label: "Modify Unique ID",name: "modify_unique_id",value: false,options: [{value: false},{value: true}], parse:false},
	];

	$('#table').html(`

User Information

Site Permissions

Group Memberships

Group Admins

Developer Apps

Developer Workflows

			`);
	user_groups_memberships_template= `

			{{#group_members}}
				{{#group}}

						{{group.name}}

				{{/group}}
			{{/group_members}}

		{{^group_members}}

No Group Memberships

		{{/group_members}}
	`;

	user_app_developers_template = `

		{{#app_developers}}
			{{#app}}

					{{app.name}}

			{{/app}}
		{{/app_developers}}

	{{^app_developers}}

Not a Developer of any Apps

	{{/app_developers}}
`;

    user_workflow_developers_template = `

        {{#workflow_developers}}
            {{#workflow}}

                    {{workflow.name}}

            {{/workflow}}
        {{/workflow_developers}}

    {{^workflow_developers}}

Not a Developer of any Workflows

    {{/workflow_developers}}
    `;

	user_group_admins_template = `

			{{#group_admins}}
				{{#group}}

						{{group.name}}
						{{#apps_admin}}{{/apps_admin}}
						{{#content_admin}}{{/content_admin}}

				{{/group}}
			{{/group_admins}}

		{{^group_admins}}

No Group Admin Privileges

		{{/group_admins}}`;

	new gform({
		name:'user_search',
		el:'#user-search',
		actions:[],
		label:false,
		fields:[
			{name:'query',label:false,placeholder:'Search', pre:'',help:"Start typing a name to search i.e. john
"},
			{type:'output',name:'results',label:false}
		]
		})
		.on('change:query',function(){
			if(typeof gform.instances.user !== 'undefined'){
				gform.instances.user.destroy();
			}
            $('.user-view').hide();
		})
		.on('change:query',_.debounce(function(e){
			$.ajax({
				url: '/api/users/search/'+this.toJSON().query,
				success: function(data) {
					e.form.find('results').update({value:templates['user_list'].render({users:data})})
				}.bind(e)
			})
		},500))

	$('body').on('click','.list-group-item.user', function(e){
		if(typeof gform.instances.user !== 'undefined'){
			gform.instances.user.destroy();
		}
		if(typeof gform.instances.site_permissions !=='undefined'){
			gform.instances.site_permissions.destroy();
		}
		$.ajax({
			// url: '/api/users/search/'+this.toJSON().query,
			url: '/api/users/'+e.currentTarget.dataset.id+'/info',
			success: function(data) {
				$('.user-view').show();
				//Show User Group Memberships
				$('.user-group-memberships').html(gform.m(user_groups_memberships_template,data));
				// Show the apps where the users is the lead developer
				$('.user-app-developers').html(gform.m(user_app_developers_template,data));
				// Show the workflows where the users is the lead developer
				$('.user-workflow-developers').html(gform.m(user_workflow_developers_template,data));
				// Show the groups where the user is the admin
				$('.user-group-admins').html(gform.m(user_group_admins_template,data));

				// Edit User
				new gform({
					actions:[
                        {"type":"button","label":"Save","action":"save","modifiers":"btn btn-primary"},
						{"type":"button","label":" Impersonate User","action":"impersonate","modifiers":"btn btn-danger"}
					],
					el: "#user-info",
					name: 'user',
					data:data,
					strict:false,
					fields:user_form_attributes
				})
				.on('save',function(e){
					$.ajax({
						url: '/api/users/'+e.form.get().id,
						type: 'PUT',
						dataType : 'json',
						contentType: 'application/json',
						data: JSON.stringify(e.form.get()),
						success: function(data) {
							e.form.set(data);
							toastr.success("Updated Site Permissions Successfully");
						},error: function(data){
							toastr.error(data);
                        }
					})
				})
				.on('impersonate',function(form_data){
					$.ajax({
						url: '/api/users/'+form_data.form.get().id+'/impersonate',
						type: 'GET',
						success: function(data) {
							window.location = '/';
					}
					});
				});

				new gform({
					actions:[{type:'save'}],
					el: ".user-site-permissions",
					name: 'site_permissions',
					data:data,
					strict:false,
					"fields":[
						{type:'hidden', name:'user_id'},
						{
							"type": "checkbox",
							"label": "Site Admin",
							"name": "site_admin",
							"multiple": true,
							"options": [
								{
									"label": "Yes",
									"value": false
								},
								{
									"label": "Yes",
									"value": true
								}
							]
						},{
							"type": "checkbox",
							"label": "Site Developer",
							"name": "site_developer",
							"multiple": true,
							"options": [
								{
									"label": "Yes",
									"value": false
								},
								{
									"label": "Yes",
									"value": true
								}
							]
						}
					],
					"el":".user-site-permissions",
					"data":{
						user_id:data.id,
						site_developer:data.site_members[0].site_developer,
						site_admin:data.site_members[0].site_admin
					},
					"actions":[
						{"type":"save","label":"Update Permissions","modifiers":"btn btn-primary"}
					]
				}).on('save',function(e){
					$.ajax({
						url: '/api/users/'+e.form.get().user_id+'/info',
						type: 'PUT',
						dataType : 'json',
						contentType: 'application/json',
						data: JSON.stringify(e.form.get()),
						success: function(data) {
							e.form.set(data);
							toastr.success("Updated Site Permissions Successfully");
						},error: function(data){
							toastr.error(data);
						}
					})
				})
			}.bind(e)

		});
	});<|endoftext|>


<commit_before>var debug = require('debug')('www:error');

exports.get = function(req, done, fail, res){
    var err = this.error;
    switch(err.status){
        case 301:
        case 303:
            return res.redirect(err.status, err.message);
        case 401:
            return res.redirect(303, '/login?next=' + req.originalUrl);
        case 500:
            debug(err);
            break;
        default:
            break;
    }
    done({
        message: err.message || err,
        stack: err.stack
    });
};
<commit_msg>update debug entry for error/server.js<commit_after>var debug = require('debug')('ics:error');

exports.get = function(req, done, fail, res){
    var err = this.error;

    switch(err.status){
        case 301:
        case 303:
            return res.redirect(err.status, err.message);
        case 401:
            return res.redirect(303, '/login?next=' + req.originalUrl);
        case 500:
            debug(err);
            break;
        default:
            break;
    }

    done({
        message: err.message || err,
        stack: err.stack
    });
};
<|endoftext|>


<commit_before>(function (angular) {
'use strict';

	angular.module('ngCaptureWeb', ['ngProgress'])
		// TWEETER SERVICE AUTH AND QUERY
		.service('captureweb', ['$http', function (http) {
			return {
				asyncCaptureWeb: function(data) {
					var queryUrl = '/capturewebquery';
					var promise = http.post(queryUrl, data).then(function (response) {
						return response;
					});
					return promise;
				},

				asyncCaptureWebPdf: function(data) {
					var queryUrl = '/capturewebquerypdf';
					var promise = http.post(queryUrl, data).then(function (response) {
						return response;
					});
					return promise;
				},

				asyncGetUserAgents: function() {
					var queryUrl = '/useragents';
					var promise = http.get(queryUrl).then(function (response) {
						return response;
					});
					return promise;
				}

			};
        }])
		// DIRECTIVE
		.directive('captureweb', ['captureweb', 'ngProgress', '$timeout', '$location', '$anchorScroll',function(captureweb, ngProgress, timeout, location, anchorScroll) {
			return {
				restrict : 'AE',
				scope: { url:'=' },
				template:
					'
' +
                        '

Url	<input type="text" name="input" ng-model="url">
' +
                        '
	{{u.name}}
' +
                        '
Resolution	<select ng-model="resolution" ng-options="r.id for r in resolutions"></select>
' +
                        '
Clip (top,left,width,height)	<input ng-model="rect" type="text" placeholder="10,100,200,300"/>
' +
                        '
	{{c.id}}
' +
                        '
User-Agent	choose
'+
                        	'
{{family.$.description}}
' +
                        		'
{{family2.$.description}}' +
                        			'
' +
		                        		'
{{family3.$.useragent}}' +
		                        		'

' +
	                        		'
' +
		                        		'
{{family3.$.description}}' +
		                        			'
' +
				                        		'
{{family4.$.useragent}}' +
				                        		'

' +
		                        		'

' +
                        		'

' +
                        	'
' +
                        	'
<input ng-model="useragent" type="text" size="83" placeholder="Agent string" />
' +
                        '

' +
					'

' +
                        // '

' +
                        '<button name="capture" ng-click="captureweb()">Capture as IMAGE</button>' +
                        // '

' +
                        '<button name="capture" ng-click="capturewebpdf()">Capture as PDF</button>
' +
                        '
' +
	                        '
' +
	                        // 'Download me' +
	                        '

' +
	                    '
' +
                        // '<button name="helper" ng-click="showDrawHelper()">Position helper</button>' +
                        // '<object id="pdfDoc" data="data:application/pdf;base64,{{jsonpdf.json}}" type="application/pdf" width="100%" height="600px"></object>' +
					'
',
				link : function(scope, element, attrs) {
                    scope.jsonImage = {json: {'info': 'below will your image displayed => click Capture as IMAGE button first'}};
                    scope.jsonPdf = {json: {'info': 'below will your pdf displayed => click Capture as PDF button first'}};
                    scope.resolutions = [
						{id: 'iPhone 3GS (420x480)', name:'420x480'},
						{id: 'Nokia N900 (800x480)', name:'800x480'},
						{id: 'iPhone 4s (960x640)', name:'960x640'},
						{id: 'Galaxy Notes (1280x800)', name:'1280x800'},
						{id: 'iPad 2 (1024x768)', name:'1024x768'},
						{id: 'Galaxy Tab 10,1 (1280x800)', name:'1280x800'},
						{id: 'Playbook (1024x600)', name:'1024x600'},
						{id: 'Galaxy Tab 8,9 (1280x800)', name:'1280x800'},
						{id: 'iPad 3 (2048x1536)', name:'2048x1536'},
						{id: 'Macbook Air (1440x900)', name:'1440x900'},
						{id: 'iMac (2560x1440)', name:'2560x1440'},
						{id: 'Macbook pro Retina (2880x1800)', name:'2880x1800'}
					  ];

					scope.clips = [
						{id: '100,200,200,300', name:'100,200,200,300'},
						{id: '100,200,300,400', name:'100,200,300,400'},
						{id: '100,200,400,500', name:'100,200,400,500'}
					];

					scope.urls = [
						{url: 'http://www.vice.com/', name: 'www.vice.com'},
						{url: 'http://www.nationalgeographic.fr/', name: 'www.nationalgeographic.fr'},
						{url: 'https://maps.google.com/maps/ms?f=q&hl=fr&geocode=&ie=UTF8&msa=0&msid=101908501337757093341.000443bee508411eb6e9a&ll=48.874383,2.372553&spn=0.008581,0.020084&iwloc=00044e3190ebe22c0b86c&source=embed', name: 'gmap example'},
						{url: 'http://rue89.nouvelobs.com/', name: 'rue89.nouvelobs.com'}
					];

					scope.resolution = scope.resolutions[11];

                    var img = document.images[0];
					img.onclick = function() {
					    var url = img.src.replace(/^data:image\/png/, 'data:application/octet-stream');
					    window.location.href = url;
					};

					scope.setAgent = function(agent) { scope.useragent = agent; }
					scope.setClip = function(clip) { scope.rect = clip; }
					scope.setUrl = function(url) { scope.url = url; }

					scope.captureweb = function() {
						var param = {
							url: scope.url,
                     		mime: 'image/png',
                     		viewportSize: { w: scope.resolution.name.split('x')[0], h: scope.resolution.name.split('x')[1] }
                     	};

                     	if (scope.rect)
                     		param.viewportRect = {
                     			top: scope.rect.split(',')[0],
                     			left: scope.rect.split(',')[1],
                     			w: scope.rect.split(',')[2],
                     			h: scope.rect.split(',')[3]
                     		};

                     	if (scope.useragent) param.userAgent = scope.useragent;

                     	ngProgress.start();

						captureweb.asyncCaptureWeb( param ).then(function(d) {
							ngProgress.stop();
							ngProgress.complete();
							scope.jsonpdf = undefined;
							scope.json = {json: 'data:image/png;base64,'+d.data};
							scope.jsonImage = {json: {'info': 'here we are !!!! click on it to download it'}};
							scope.gotoResult();
						});
					};

					scope.capturewebpdf = function() {
						var param = {
							url: scope.url,
                     		mime: 'application/pdf',
                     		viewportSize: { w: scope.resolution.name.split('x')[0], h: scope.resolution.name.split('x')[1] }
                     	};

                     	if (scope.rect)
                     		param.viewportRect = {
                     			top: scope.rect.split(',')[0],
                     			left: scope.rect.split(',')[1],
                     			w: scope.rect.split(',')[2],
                     			h: scope.rect.split(',')[3]
                     		};

                     	if (scope.useragent) param.userAgent = scope.useragent;

                     	ngProgress.start();

						captureweb.asyncCaptureWebPdf( param ).then(function(d) {
							ngProgress.stop();
							ngProgress.complete();
							scope.json = undefined;
							scope.jsonpdf = {json: d.data};
							$('#pdfDoc').html('<object id="pdfDoc" data="data:application/pdf;base64,'+scope.jsonpdf.json+'" type="application/pdf" width="100%" height="600px"></object>');
							scope.jsonImage = {json: {'info': 'here we are !!!! you can save it '}};
							scope.gotoResult();
						});
					};

					scope.fetchUserAgents = function() {
						captureweb.asyncGetUserAgents( ).then(function(d) {
							if (d && d.data && d.data.useragentswitcher)
							scope.useragents = d.data.useragentswitcher.folder;
							scope.useragents = scope.useragents.slice(0, 5);
							// clean
							scope.useragents[2].folder = scope.useragents[3].folder.slice(1,2);
							scope.useragents[3].folder = scope.useragents[3].folder.slice(1,2);
							scope.useragents[4].folder = scope.useragents[4].folder.slice(0,3);
						});
					};

					scope.fetchUserAgents();

					scope.showDrawHelper = function() {
						showCanvas();
					};

					scope.generateIds = function(id) {
						var re = new RegExp('[ ()]', 'g');
						return id.replace(re, '_');
					};

					scope.toggleAgents = function(id) { $('#'+id).toggle(); };
					scope.toggleAgentPanel = function(id) { $('#agentPanel').toggle();};

					scope.gotoResult = function (){
					    // set the location.hash to the id of
					    // the element you wish to scroll to.
					    location.hash('result');

					    // call $anchorScroll()
					    anchorScroll();
					 };

				}
			};
		}]);
})(angular);<commit_msg>timeout for scroll<commit_after>(function (angular) {
'use strict';

	angular.module('ngCaptureWeb', ['ngProgress'])
		// TWEETER SERVICE AUTH AND QUERY
		.service('captureweb', ['$http', function (http) {
			return {
				asyncCaptureWeb: function(data) {
					var queryUrl = '/capturewebquery';
					var promise = http.post(queryUrl, data).then(function (response) {
						return response;
					});
					return promise;
				},

				asyncCaptureWebPdf: function(data) {
					var queryUrl = '/capturewebquerypdf';
					var promise = http.post(queryUrl, data).then(function (response) {
						return response;
					});
					return promise;
				},

				asyncGetUserAgents: function() {
					var queryUrl = '/useragents';
					var promise = http.get(queryUrl).then(function (response) {
						return response;
					});
					return promise;
				}

			};
        }])
		// DIRECTIVE
		.directive('captureweb', ['captureweb', 'ngProgress', '$timeout', '$location', '$anchorScroll',function(captureweb, ngProgress, timeout, location, anchorScroll) {
			return {
				restrict : 'AE',
				scope: { url:'=' },
				template:
					'
' +
                        '

Url	<input type="text" name="input" ng-model="url">
' +
                        '
	{{u.name}}
' +
                        '
Resolution	<select ng-model="resolution" ng-options="r.id for r in resolutions"></select>
' +
                        '
Clip (top,left,width,height)	<input ng-model="rect" type="text" placeholder="10,100,200,300"/>
' +
                        '
	{{c.id}}
' +
                        '
User-Agent	choose
'+
                        	'
{{family.$.description}}
' +
                        		'
{{family2.$.description}}' +
                        			'
' +
		                        		'
{{family3.$.useragent}}' +
		                        		'

' +
	                        		'
' +
		                        		'
{{family3.$.description}}' +
		                        			'
' +
				                        		'
{{family4.$.useragent}}' +
				                        		'

' +
		                        		'

' +
                        		'

' +
                        	'
' +
                        	'
<input ng-model="useragent" type="text" size="83" placeholder="Agent string" />
' +
                        '

' +
					'

' +
                        // '

' +
                        '<button name="capture" ng-click="captureweb()">Capture as IMAGE</button>' +
                        // '

' +
                        '<button name="capture" ng-click="capturewebpdf()">Capture as PDF</button>
' +
                        '
' +
	                        '
' +
	                        // 'Download me' +
	                        '

' +
	                    '
' +
                        // '<button name="helper" ng-click="showDrawHelper()">Position helper</button>' +
                        // '<object id="pdfDoc" data="data:application/pdf;base64,{{jsonpdf.json}}" type="application/pdf" width="100%" height="600px"></object>' +
					'
',
				link : function(scope, element, attrs) {
                    scope.jsonImage = {json: {'info': 'below will your image displayed => click Capture as IMAGE button first'}};
                    scope.jsonPdf = {json: {'info': 'below will your pdf displayed => click Capture as PDF button first'}};
                    scope.resolutions = [
						{id: 'iPhone 3GS (420x480)', name:'420x480'},
						{id: 'Nokia N900 (800x480)', name:'800x480'},
						{id: 'iPhone 4s (960x640)', name:'960x640'},
						{id: 'Galaxy Notes (1280x800)', name:'1280x800'},
						{id: 'iPad 2 (1024x768)', name:'1024x768'},
						{id: 'Galaxy Tab 10,1 (1280x800)', name:'1280x800'},
						{id: 'Playbook (1024x600)', name:'1024x600'},
						{id: 'Galaxy Tab 8,9 (1280x800)', name:'1280x800'},
						{id: 'iPad 3 (2048x1536)', name:'2048x1536'},
						{id: 'Macbook Air (1440x900)', name:'1440x900'},
						{id: 'iMac (2560x1440)', name:'2560x1440'},
						{id: 'Macbook pro Retina (2880x1800)', name:'2880x1800'}
					  ];

					scope.clips = [
						{id: '100,200,200,300', name:'100,200,200,300'},
						{id: '100,200,300,400', name:'100,200,300,400'},
						{id: '100,200,400,500', name:'100,200,400,500'}
					];

					scope.urls = [
						{url: 'http://www.vice.com/', name: 'www.vice.com'},
						{url: 'http://www.nationalgeographic.fr/', name: 'www.nationalgeographic.fr'},
						{url: 'https://maps.google.com/maps/ms?f=q&hl=fr&geocode=&ie=UTF8&msa=0&msid=101908501337757093341.000443bee508411eb6e9a&ll=48.874383,2.372553&spn=0.008581,0.020084&iwloc=00044e3190ebe22c0b86c&source=embed', name: 'gmap example'},
						{url: 'http://rue89.nouvelobs.com/', name: 'rue89.nouvelobs.com'}
					];

					scope.resolution = scope.resolutions[11];

                    var img = document.images[0];
					img.onclick = function() {
					    var url = img.src.replace(/^data:image\/png/, 'data:application/octet-stream');
					    window.location.href = url;
					};

					scope.setAgent = function(agent) { scope.useragent = agent; }
					scope.setClip = function(clip) { scope.rect = clip; }
					scope.setUrl = function(url) { scope.url = url; }

					scope.captureweb = function() {
						var param = {
							url: scope.url,
                     		mime: 'image/png',
                     		viewportSize: { w: scope.resolution.name.split('x')[0], h: scope.resolution.name.split('x')[1] }
                     	};

                     	if (scope.rect)
                     		param.viewportRect = {
                     			top: scope.rect.split(',')[0],
                     			left: scope.rect.split(',')[1],
                     			w: scope.rect.split(',')[2],
                     			h: scope.rect.split(',')[3]
                     		};

                     	if (scope.useragent) param.userAgent = scope.useragent;

                     	ngProgress.start();

						captureweb.asyncCaptureWeb( param ).then(function(d) {
							ngProgress.stop();
							ngProgress.complete();
							scope.jsonpdf = undefined;
							scope.json = {json: 'data:image/png;base64,'+d.data};
							scope.jsonImage = {json: {'info': 'here we are !!!! click on it to download it'}};
							timeout(scope.gotoResult, 1000);
						});
					};

					scope.capturewebpdf = function() {
						var param = {
							url: scope.url,
                     		mime: 'application/pdf',
                     		viewportSize: { w: scope.resolution.name.split('x')[0], h: scope.resolution.name.split('x')[1] }
                     	};

                     	if (scope.rect)
                     		param.viewportRect = {
                     			top: scope.rect.split(',')[0],
                     			left: scope.rect.split(',')[1],
                     			w: scope.rect.split(',')[2],
                     			h: scope.rect.split(',')[3]
                     		};

                     	if (scope.useragent) param.userAgent = scope.useragent;

                     	ngProgress.start();

						captureweb.asyncCaptureWebPdf( param ).then(function(d) {
							ngProgress.stop();
							ngProgress.complete();
							scope.json = undefined;
							scope.jsonpdf = {json: d.data};
							$('#pdfDoc').html('<object id="pdfDoc" data="data:application/pdf;base64,'+scope.jsonpdf.json+'" type="application/pdf" width="100%" height="600px"></object>');
							scope.jsonImage = {json: {'info': 'here we are !!!! you can save it '}};
							timeout(scope.gotoResult, 1000);
						});
					};

					scope.fetchUserAgents = function() {
						captureweb.asyncGetUserAgents( ).then(function(d) {
							if (d && d.data && d.data.useragentswitcher)
							scope.useragents = d.data.useragentswitcher.folder;
							scope.useragents = scope.useragents.slice(0, 5);
							// clean
							scope.useragents[2].folder = scope.useragents[3].folder.slice(1,2);
							scope.useragents[3].folder = scope.useragents[3].folder.slice(1,2);
							scope.useragents[4].folder = scope.useragents[4].folder.slice(0,3);
						});
					};

					scope.fetchUserAgents();

					scope.showDrawHelper = function() {
						showCanvas();
					};

					scope.generateIds = function(id) {
						var re = new RegExp('[ ()]', 'g');
						return id.replace(re, '_');
					};

					scope.toggleAgents = function(id) { $('#'+id).toggle(); };
					scope.toggleAgentPanel = function(id) { $('#agentPanel').toggle();};

					scope.gotoResult = function (){
					    // set the location.hash to the id of
					    // the element you wish to scroll to.
					    location.hash('result');

					    // call $anchorScroll()
					    anchorScroll();
					 };

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


<commit_before>/*
 * jQuery UI Nested Sortable
 * v 2.0 / 29 oct 2012
 * http://mjsarfatti.com/sandbox/nestedSortable
 *
 * Depends on:
 *	 jquery.ui.sortable.js 1.10+
 *
 * Copyright (c) 2010-2013 Manuele J Sarfatti
 * Licensed under the MIT License
 * http://www.opensource.org/licenses/mit-license.php
 */
(function( factory ) {
	"use strict";

	var define = window.define;

	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([
			"jquery",
			"jquery-ui/sortable"
		], factory );
	} else {

		// Browser globals
		factory( window.jQuery );
	}
}(function($) {
	"use strict";

	function isOverAxis( x, reference, size ) {
		return ( x > reference ) && ( x < ( reference + size ) );
	}

	$.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {

		options: {
			disableParentChange: false,
			doNotClear: false,
			expandOnHover: 700,
			isAllowed: function() { return true; },
			isTree: false,
			listType: "ol",
			maxLevels: 0,
			protectRoot: false,
			rootID: null,
			rtl: false,
			startCollapsed: false,
			tabSize: 20,

			branchClass: "mjs-nestedSortable-branch",
			collapsedClass: "mjs-nestedSortable-collapsed",
			disableNestingClass: "mjs-nestedSortable-no-nesting",
			errorClass: "mjs-nestedSortable-error",
			expandedClass: "mjs-nestedSortable-expanded",
			hoveringClass: "mjs-nestedSortable-hovering",
			leafClass: "mjs-nestedSortable-leaf",
			disabledClass: "mjs-nestedSortable-disabled"
		},

		_create: function() {
			var self = this,
				err;

			this.element.data("ui-sortable", this.element.data("mjs-nestedSortable"));

			// mjs - prevent browser from freezing if the HTML is not correct
			if (!this.element.is(this.options.listType)) {
				err = "nestedSortable: " +
					"Please check that the listType option is set to your actual list type";

				throw new Error(err);
			}

			// if we have a tree with expanding/collapsing functionality,
			// force 'intersect' tolerance method
			if (this.options.isTree && this.options.expandOnHover) {
				this.options.tolerance = "intersect";
			}

			$.ui.sortable.prototype._create.apply(this, arguments);

			// prepare the tree by applying the right classes
			// (the CSS is responsible for actual hide/show functionality)
			if (this.options.isTree) {
				$(this.items).each(function() {
					var $li = this.item,
						hasCollapsedClass = $li.hasClass(self.options.collapsedClass),
						hasExpandedClass = $li.hasClass(self.options.expandedClass);

					if ($li.children(self.options.listType).length) {
						$li.addClass(self.options.branchClass);
						// expand/collapse class only if they have children

						if ( !hasCollapsedClass && !hasExpandedClass ) {
							if (self.options.startCollapsed) {
								$li.addClass(self.options.collapsedClass);
							} else {
								$li.addClass(self.options.expandedClass);
							}
						}
					} else {
						$li.addClass(self.options.leafClass);
					}
				});
			}
		},

		_destroy: function() {
			this.element
				.removeData("mjs-nestedSortable")
				.removeData("ui-sortable");
			return $.ui.sortable.prototype._destroy.apply(this, arguments);
		},

		_mouseDrag: function(event) {
			var i,
				item,
				itemElement,
				intersection,
				self = this,
				o = this.options,
				scrolled = false,
				$document = $(document),
				previousTopOffset,
				parentItem,
				level,
				childLevels,
				itemAfter,
				itemBefore,
				newList,
				method,
				a,
				previousItem,
				nextItem,
				helperIsNotSibling;

			//Compute the helpers position
			this.position = this._generatePosition(event);
			this.positionAbs = this._convertPositionTo("absolute");

			if (!this.lastPositionAbs) {
				this.lastPositionAbs = this.positionAbs;
			}

			//Do scrolling
			if (this.options.scroll) {
				if (this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {

					if (
						(
							this.overflowOffset.top +
							this.scrollParent[0].offsetHeight
						) -
						event.pageY <
						o.scrollSensitivity
					) {
						scrolled = this.scrollParent.scrollTop() + o.scrollSpeed;
						this.scrollParent.scrollTop(scrolled);
					} else if (
						event.pageY -
						this.overflowOffset.top <
						o.scrollSensitivity
					) {
						scrolled = this.scrollParent.scrollTop() - o.scrollSpeed;
						this.scrollParent.scrollTop(scrolled);
					}

					if (
						(
							this.overflowOffset.left +
							this.scrollParent[0].offsetWidth
						) -
						event.pageX <
						o.scrollSensitivity
					) {
						scrolled = this.scrollParent.scrollLeft() + o.scrollSpeed;
						this.scrollParent.scrollLeft(scrolled);
					} else if (
						event.pageX -
						this.overflowOffset.left <
						o.scrollSensitivity
					) {
						scrolled = this.scrollParent.scrollLeft() - o.scrollSpeed;
						this.scrollParent.scrollLeft(scrolled);
					}

				} else {

					if (
						event.pageY -
						$document.scrollTop() <
						o.scrollSensitivity
					) {
						scrolled = $document.scrollTop() - o.scrollSpeed;
						$document.scrollTop(scrolled);
					} else if (
						$(window).height() -
						(
							event.pageY -
							$document.scrollTop()
						) <
						o.scrollSensitivity
					) {
						scrolled = $document.scrollTop() + o.scrollSpeed;
						$document.scrollTop(scrolled);
					}

					if (
						event.pageX -
						$document.scrollLeft() <
						o.scrollSensitivity
					) {
						scrolled = $document.scrollLeft() - o.scrollSpeed;
						$document.scrollLeft(scrolled);
					} else if (
						$(window).width() -
						(
							event.pageX -
							$document.scrollLeft()
						) <
						o.scrollSensitivity
					) {
						scrolled = $document.scrollLeft() + o.scrollSpeed;
						$document.scrollLeft(scrolled);
					}

				}

				if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
					$.ui.ddmanager.prepareOffsets(this, event);
				}
			}

			//Regenerate the absolute position used for position checks
			this.positionAbs = this._convertPositionTo("absolute");

			// mjs - find the top offset before rearrangement,
			previousTopOffset = this.placeholder.offset().top;

			//Set the helper position
			if (!this.options.axis || this.options.axis !== "y") {
				this.helper[0].style.left = this.position.left + "px";
			}
			if (!this.options.axis || this.options.axis !== "x") {
				this.helper[0].style.top = this.position.top + "px";
			}

			// mjs - check and reset hovering state at each cycle
			this.hovering = this.hovering ? this.hovering : null;
			this.mouseentered = this.mouseentered ? this.mouseentered : false;

			// mjs - let's start caching some variables
			(function() {
				var _parentItem = this.placeholder.parent().parent();
				if (_parentItem && _parentItem.closest(".ui-sortable").length) {
					parentItem = _parentItem;
				}
			}.call(this));

			level = this._getLevel(this.placeholder);
			childLevels = this._getChildLevels(this.helper);
			newList = document.createElement(o.listType);

			//Rearrange
			for (i = this.items.length - 1; i >= 0; i--) {

				//Cache variables and intersection, continue if no intersection
				item = this.items[i];
				itemElement = item.item[0];
				intersection = this._intersectsWithPointer(item);
				if (!intersection) {
					continue;
				}

				// Only put the placeholder inside the current Container, skip all
				// items form other containers. This works because when moving
				// an item from one container to another the
				// currentContainer is switched before the placeholder is moved.
				//
				// Without this moving items in "sub-sortables" can cause the placeholder to jitter
				// beetween the outer and inner container.
				if (item.instance !== this.currentContainer) {
					continue;
				}

				// No action if intersected item is disabled
				// and the element above or below in the direction we're going is also disabled
				if (itemElement.className.indexOf(o.disabledClass) !== -1) {
					// Note: intersection hardcoded direction values from
					// jquery.ui.sortable.js:_intersectsWithPointer
					if (intersection === 2) {
						// Going down
						itemAfter = this.items[i + 1];
						if (itemAfter && itemAfter.item.hasClass(o.disabledClass)) {
							continue;
						}

					} else if (intersection === 1) {
						// Going up
						itemBefore = this.items[i - 1];
						if (itemBefore && itemBefore.item.hasClass(o.disabledClass)) {
							continue;
						}
					}
				}

				method = intersection === 1 ? "next" : "prev";

				// cannot intersect with itself
				// no useless actions that have been done before
				// no action if the item moved is the parent of the item checked
				if (itemElement !== this.currentItem[0] &&
					this.placeholder[method]()[0] !== itemElement &&
					!$.contains(this.placeholder[0], itemElement) &&
					(
						this.options.type === "semi-dynamic" ?
							!$.contains(this.element[0], itemElement) :
							true
					)
				) {

					// mjs - we are intersecting an element:
					// trigger the mouseenter event and store this state
					if (!this.mouseentered) {
						$(itemElement).mouseenter();
						this.mouseentered = true;
					}

					// mjs - if the element has children and they are hidden,
					// show them after a delay (CSS responsible)
					if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) {
						if (!this.hovering) {
							$(itemElement).addClass(o.hoveringClass);
							this.hovering = window.setTimeout(function() {
								$(itemElement)
									.removeClass(o.collapsedClass)
									.addClass(o.expandedClass);

								self.refreshPositions();
								self._trigger("expand", event, self._uiHash());
							}, o.expandOnHover);
						}
					}

					this.direction = intersection === 1 ? "down" : "up";

					// mjs - rearrange the elements and reset timeouts and hovering state
					if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
						$(itemElement).mouseleave();
						this.mouseentered = false;
						$(itemElement).removeClass(o.hoveringClass);
						if (this.hovering) {
							window.clearTimeout(this.hovering);
						}
						this.hovering = null;

						// mjs - do not switch container if
						// it's a root item and 'protectRoot' is true
						// or if it's not a root item but we are trying to make it root
						if (o.protectRoot &&
							!(
								this.currentItem[0].parentNode === this.element[0] &&
								// it's a root item
								itemElement.parentNode !== this.element[0]
								// it's intersecting a non-root item
							)
						) {
							if (this.currentItem[0].parentNode !== this.element[0] &&
								itemElement.parentNode === this.element[0]
							) {

								if ( !$(itemElement).children(o.listType).length) {
									itemElement.appendChild(newList);
									if (o.isTree) {
										$(itemElement)
											.removeClass(o.leafClass)
											.addClass(o.branchClass + " " + o.expandedClass);
									}
								}

								if (this.direction === "down") {
									$(itemElement).prev().children(o.listType);
								} else {
									$(itemElement).children(o.listType);
								}

								if (a[0] !== undefined) {
									this._rearrange(event, null, a);
								}

							} else {
								this._rearrange(event, item);
							}
						} else if (!o.protectRoot) {
							this._rearrange(event, item);
						}
					} else {
						break;
					}

					// Clear emtpy ul's/ol's
					this._clearEmpty(itemElement);

					this._trigger("change", event, this._uiHash());
					break;
				}
			}

			// mjs - to find the previous sibling in the list,
			// keep backtracking until we hit a valid list item.
			(function() {
				var _previousItem = this.placeholder.prev();
				if (_previousItem.length) {
					previousItem = _previousItem;
				} else {
					previousItem = null;
				}
			}.call(this));

			if (previousItem != null) {
				while (
					previousItem[0].nodeName.toLowerCase() !== "li" ||
					previousItem[0].className.indexOf(o.disabledClass) !== -1 ||
					previousItem[0] === this.currentItem[0] ||
					previousItem[0] === this.helper[0]
				) {
					if (previousItem[0].previousSibling) {
						previousItem = $(previousItem[0].previousSibling);
					} else {
						previousItem = null;
						break;
					}
				}
			}

			// mjs - to find the next sibling in the list,
			// keep stepping forward until we hit a valid list item.
			(function() {
				var _nextItem = this.placeholder.next();
				if (_nextItem.length) {
					nextItem = _nextItem;
				} else {
					nextItem = null;
				}
			}.call(this));

			if (nextItem != null) {
				while (
					nextItem[0].nodeName.toLowerCase() !== "li" ||
					nextItem[0].className.indexOf(o.disabledClass) !== -1 ||
					nextItem[0] === this.currentItem[0] ||
					nextItem[0] === this.helper[0]
				) {
					if (nextItem[0].nextSibling) {
						nextItem = $(nextItem[0].nextSibling);
					} else {
						nextItem = null;
						break;
					}
				}
			}

			this.beyondMaxLevels = 0;

			// mjs - if the item is moved to the left, send it one level up
			// but only if it's at the bottom of the list
			if (parentItem != null &&
				nextItem == null &&
				o.protectRoot && parentItem[0].parentNode !== this.element[0] &&
				(
					o.rtl &&
					(
						this.positionAbs.left +
						this.helper.outerWidth() > parentItem.offset().left +
						parentItem.outerWidth()
					) ||
					!o.rtl && (this.positionAbs.left < parentItem.offset().left)
				)
			) {

				parentItem.after(this.placeholder[0]);
				helperIsNotSibling = !parentItem
											.children(o.listItem)
											.children("li:visible:not(.ui-sortable-helper")
											.length;
				if (o.isTree && helperIsNotSibling) {
					parentItem
						.removeClass(this.options.branchClass + " " + this.options.expandedClass)
						.addClass(this.options.leafClass);
				}

				this._clearEmpty(parentItem[0]);
				this._trigger("change", event, this._uiHash());
				// mjs - if the item is below a sibling and is moved to the right,
				// make it a child of that sibling
			} else if (previousItem != null &&
				!previousItem.hasClass(o.disableNestingClass) &&
				(
					previousItem.children(o.listType).length &&
					previousItem.children(o.listType).is(":visible") ||
					!previousItem.children(o.listType).length
				) &&
				!(o.protectRoot && this.currentItem[0].parentNode === this.element[0]) &&
				(
					o.rtl &&
					(
						this.positionAbs.left +
						this.helper.outerWidth() <
						previousItem.offset().left +
						previousItem.outerWidth() -
						o.tabSize
					) ||
					!o.rtl &&
					(this.positionAbs.left > previousItem.offset().left + o.tabSize)
				)
			) {

				this._isAllowed(previousItem, level, level + childLevels + 1);

				if (!previousItem.children(o.listType).length) {
					previousItem[0].appendChild(newList);
					if (o.isTree) {
						previousItem
							.removeClass(o.leafClass)
							.addClass(o.branchClass + " " + o.expandedClass);
					}
				}

				// mjs - if this item is being moved from the top, add it to the top of the list.
				if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
					previousItem.children(o.listType).prepend(this.placeholder);
				} else {
					// mjs - otherwise, add it to the bottom of the list.
					previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
				}

				this._trigger("change", event, this._uiHash());
			} else {
				this._isAllowed(parentItem, level, level + childLevels);
			}

			//Post events to containers
			this._contactContainers(event);

			//Interconnect with droppables
			if ($.ui.ddmanager) {
				$.ui.ddmanager.drag(this, event);
			}

			//Call callbacks
			this._trigger("sort", event, this._uiHash());

			this.lastPositionAbs = this.positionAbs;
			return false;

		},

		_mouseStop: function(event) {
			// mjs - if the item is in a position not allowed, send it back
			if (this.beyondMaxLevels) {

				this.placeholder.removeClass(this.options.errorClass);

				if (this.domPosition.prev) {
					$(this.domPosition.prev).after(this.placeholder);
				} else {
					$(this.domPosition.parent).prepend(this.placeholder);
				}

				this._trigger("revert", event, this._uiHash());

			}

			// mjs - clear the hovering timeout, just to be sure
			$("." + this.options.hoveringClass)
				.mouseleave()
				.removeClass(this.options.hoveringClass);

			this.mouseentered = false;
			if (this.hovering) {
				window.clearTimeout(this.hovering);
			}
			this.hovering = null;

			this._relocate_event = event;
			this._pid_current = $(this.domPosition.parent).parent().attr("id");
			this._sort_current = this.domPosition.prev ? $(this.domPosition.prev).next().index() : 0;
			$.ui.sortable.prototype._mouseStop.apply(this, arguments); //asybnchronous execution, @see _clear for the relocate event.
		},

		// mjs - this function is slightly modified
		// to make it easier to hover over a collapsed element and have it expand
		_intersectsWithSides: function(item) {

			var half = this.options.isTree ? .8 : .5,
				isOverBottomHalf = isOverAxis(
					this.positionAbs.top + this.offset.click.top,
					item.top + (item.height * half),
					item.height
				),
				isOverTopHalf = isOverAxis(
					this.positionAbs.top + this.offset.click.top,
					item.top - (item.height * half),
					item.height
				),
				isOverRightHalf = isOverAxis(
					this.positionAbs.left + this.offset.click.left,
					item.left + (item.width / 2),
					item.width
				),
				verticalDirection = this._getDragVerticalDirection(),
				horizontalDirection = this._getDragHorizontalDirection();

			if (this.floating && horizontalDirection) {
				return (
					(horizontalDirection === "right" && isOverRightHalf) ||
					(horizontalDirection === "left" && !isOverRightHalf)
				);
			} else {
				return verticalDirection && (
					(verticalDirection === "down" && isOverBottomHalf) ||
					(verticalDirection === "up" && isOverTopHalf)
				);
			}

		},

		_contactContainers: function() {

			if (this.options.protectRoot && this.currentItem[0].parentNode === this.element[0] ) {
				return;
			}

			$.ui.sortable.prototype._contactContainers.apply(this, arguments);

		},

		_clear: function() {
			var i,
				item;

			$.ui.sortable.prototype._clear.apply(this, arguments);

			//relocate event
			if (!(this._pid_current === this._uiHash().item.parent().parent().attr("id") &&
				this._sort_current === this._uiHash().item.index())) {
				this._trigger("relocate", this._relocate_event, this._uiHash());
			}

			// mjs - clean last empty ul/ol
			for (i = this.items.length - 1; i >= 0; i--) {
				item = this.items[i].item[0];
				this._clearEmpty(item);
			}

		},

		serialize: function(options) {

			var o = $.extend({}, this.options, options),
				items = this._getItemsAsjQuery(o && o.connected),
				str = [];

			$(items).each(function() {
				var res = ($(o.item || this).attr(o.attribute || "id") || "")
						.match(o.expression || (/(.+)[-=_](.+)/)),
					pid = ($(o.item || this).parent(o.listType)
						.parent(o.items)
						.attr(o.attribute || "id") || "")
						.match(o.expression || (/(.+)[-=_](.+)/));

				if (res) {
					str.push(
						(
							(o.key || res[1]) +
							"[" +
							(o.key && o.expression ? res[1] : res[2]) + "]"
						) +
						"=" +
						(pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
				}
			});

			if (!str.length && o.key) {
				str.push(o.key + "=");
			}

			return str.join("&");

		},

		toHierarchy: function(options) {

			var o = $.extend({}, this.options, options),
				ret = [];

			$(this.element).children(o.items).each(function() {
				var level = _recursiveItems(this);
				ret.push(level);
			});

			return ret;

			function _recursiveItems(item) {
				var id = ($(item).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[-=_](.+)/)),
					currentItem;
				if (id) {
					currentItem = {
						"id": id[2]
					};

					if ($(item).children(o.listType).children(o.items).length > 0) {
						currentItem.children = [];
						$(item).children(o.listType).children(o.items).each(function() {
							var level = _recursiveItems(this);
							currentItem.children.push(level);
						});
					}
					return currentItem;
				}
			}
		},

		toArray: function(options) {

			var o = $.extend({}, this.options, options),
				sDepth = o.startDepthCount || 0,
				ret = [],
				left = 1;

			if (!o.excludeRoot) {
				ret.push({
					"item_id": o.rootID,
					"parent_id": null,
					"depth": sDepth,
					"left": left,
					"right": ($(o.items, this.element).length + 1) * 2
				});
				left++;
			}

			$(this.element).children(o.items).each(function() {
				left = _recursiveArray(this, sDepth + 1, left);
			});

			ret = ret.sort(function(a, b) { return (a.left - b.left); });

			return ret;

			function _recursiveArray(item, depth, _left) {

				var right = _left + 1,
					id,
					pid,
					parentItem;

				if ($(item).children(o.listType).children(o.items).length > 0) {
					depth++;
					$(item).children(o.listType).children(o.items).each(function() {
						right = _recursiveArray($(this), depth, right);
					});
					depth--;
				}

				id = ($(item).attr(o.attribute || "id")).match(o.expression || (/(.+)[-=_](.+)/));

				if (depth === sDepth + 1) {
					pid = o.rootID;
				} else {
					parentItem = ($(item).parent(o.listType)
											.parent(o.items)
											.attr(o.attribute || "id"))
											.match(o.expression || (/(.+)[-=_](.+)/));
					pid = parentItem[2];
				}

				if (id) {
						ret.push({
							"item_id": id[2],
							"parent_id": pid,
							"depth": depth,
							"left": _left,
							"right": right
						});
				}

				_left = right + 1;
				return _left;
			}

		},

		_clearEmpty: function(item) {
			var o = this.options,
				emptyList = $(item).children(o.listType);

			if (emptyList.length && !emptyList.children().length && !o.doNotClear) {
				if (o.isTree) {
					$(item)
						.removeClass(o.branchClass + " " + o.expandedClass)
						.addClass(o.leafClass);
				}

				emptyList.remove();
			} else if (
				o.isTree &&
				emptyList.length &&
				emptyList.children().length &&
				emptyList.is(":visible")
			) {
				$(item)
					.removeClass(o.leafClass)
					.addClass(o.branchClass + " " + o.expandedClass);
			} else if (
				o.isTree &&
				emptyList.length &&
				emptyList.children().length &&
				!emptyList.is(":visible")
			) {
				$(item)
					.removeClass(o.leafClass)
					.addClass(o.branchClass + " " + o.collapsedClass);
			}

		},

		_getLevel: function(item) {

			var level = 1,
				list;

			if (this.options.listType) {
				list = item.closest(this.options.listType);
				while (list && list.length > 0 && !list.is(".ui-sortable")) {
					level++;
					list = list.parent().closest(this.options.listType);
				}
			}

			return level;
		},

		_getChildLevels: function(parent, depth) {
			var self = this,
				o = this.options,
				result = 0;
			depth = depth || 0;

			$(parent).children(o.listType).children(o.items).each(function(index, child) {
				result = Math.max(self._getChildLevels(child, depth + 1), result);
			});

			return depth ? result + 1 : result;
		},

		_isAllowed: function(parentItem, level, levels) {
			var o = this.options,
				// this takes into account the maxLevels set to the recipient list
				maxLevels = this
					.placeholder
					.closest(".ui-sortable")
					.nestedSortable("option", "maxLevels"),

				// Check if the parent has changed to prevent it, when o.disableParentChange is true
				oldParent = this.currentItem.parent().parent(),
				disabledByParentchange = o.disableParentChange && (
					//From somewhere to somewhere else, except the root
					parentItem !== null && !oldParent.is(parentItem) ||
					parentItem === null && oldParent.is("li")	//From somewhere to the root
				);
			// mjs - is the root protected?
			// mjs - are we nesting too deep?
			if (
				disabledByParentchange ||
				!o.isAllowed(this.placeholder, parentItem, this.currentItem)
			) {
				this.placeholder.addClass(o.errorClass);
				if (maxLevels < levels && maxLevels !== 0) {
					this.beyondMaxLevels = levels - maxLevels;
				} else {
					this.beyondMaxLevels = 1;
				}
			} else {
				if (maxLevels < levels && maxLevels !== 0) {
					this.placeholder.addClass(o.errorClass);
					this.beyondMaxLevels = levels - maxLevels;
				} else {
					this.placeholder.removeClass(o.errorClass);
					this.beyondMaxLevels = 0;
				}
			}
		}

	}));

	$.mjs.nestedSortable.prototype.options = $.extend(
		{},
		$.ui.sortable.prototype.options,
		$.mjs.nestedSortable.prototype.options
	);
}));
<commit_msg>Removed unused JS file<commit_after><|endoftext|>


<commit_before>define([
    "dojo/_base/declare","dijit/layout/BorderContainer","dojo/on",
    "dojo/dom-class","dijit/layout/ContentPane","dojo/dom-construct",
    "../PageGrid","../formatter","../../WorkspaceManager","dojo/_base/lang",
    "dojo/dom-attr"
], function(
    declare, BorderContainer, on,
    domClass,ContentPane,domConstruct,
    Grid,formatter,WorkspaceManager,lang,
    domAttr
){
    return declare([BorderContainer], {
        "baseClass": "Model",
        "disabled":false,
        "query": null,
        data: null,
        containerType: "model",
        _setDataAttr: function(data){
            this.data = data;
            console.log("Model Data: ", data);
            this.refresh();
        },
        getModelPath: function(){
            return this.data.path + this.data.name;
        },
        refresh: function(){
            var self = this;

            if (!this._started) { return; }
            if (this.data) {
                var output=['

'];
                output.push("Metabolic Model - " + this.data.name + '
');
                /*
                output.push('
'+
                                '
View in:
 '+
                                ''+
                            '
')
                */

                output.push('

');
                if (this.data.autoMeta){
                    Object.keys(this.data.autoMeta).forEach(function(key){
                        output.push("
" + key + "	" + this.data.autoMeta[key] + "
");
                    },this);
                }
                output.push("

");

                // get download links for related downloads
                var downloads = [];
                var path = this.data.path+'.'+this.data.name;
                WorkspaceManager.getFolderContents(path, true)
                    .then(function(objs) {
                        var paths = [];
                        for (var i=0; i<objs.length; i++) {
                            var obj = objs[i];
                            if (obj.type === 'folder') continue;

                            downloads.push({
                                            path: obj.path,
                                            name: obj.name,
                                            size: formatter.humanFileSize(obj.size, 1)
                                          })
                            paths.push(obj.path);
                        }

                        // fetch downloads urls, return objs containing them
                        return WorkspaceManager.getDownloadUrls(paths)
                                        .then(function(urls) {
                                            for (var i=0; i<downloads.length; i++)
                                                downloads[i].url = urls[i];
                                            return downloads;
                                        })
                    }).then(function(dls) {
                        console.log(self.viewer)
                        output.push('
Downloads
')
                        var table = ['

File	Size
']
                        for (var i in dls) {
                            var dl = dls[i];
                            table.push('
'+
                                            ' '+dl.name+'	'+
                                            ''+dl.size+'	'+
                                       '
');
                        }
                        table.push('
');

                        output = output.concat(table);
                        self.viewer.set("content", output.join(""));
                    })
            }
        },
        startup: function(){
            console.log("Model Viewer Startup()");
            if (this._started) {return;}
            this.inherited(arguments);
            this.viewer = new ContentPane({content: "Loading Metabolic Model...", region: "center"});
            this.addChild(this.viewer);
            this.refresh();

            /*
            this.on("i:click", function(evt){
                var rel = domAttr.get(evt.target,'rel');
                if (rel) {
                    WorkspaceManager.downloadFile(rel);
                }else{
                    console.warn("link not found: ", rel);
                }
            });
            */
        }
    });
});
<commit_msg>remove logging<commit_after>define([
    "dojo/_base/declare","dijit/layout/BorderContainer","dojo/on",
    "dojo/dom-class","dijit/layout/ContentPane","dojo/dom-construct",
    "../PageGrid","../formatter","../../WorkspaceManager","dojo/_base/lang",
    "dojo/dom-attr"
], function(
    declare, BorderContainer, on,
    domClass,ContentPane,domConstruct,
    Grid,formatter,WorkspaceManager,lang,
    domAttr
){
    return declare([BorderContainer], {
        "baseClass": "Model",
        "disabled":false,
        "query": null,
        data: null,
        containerType: "model",
        _setDataAttr: function(data){
            this.data = data;
            console.log("Model Data: ", data);
            this.refresh();
        },
        getModelPath: function(){
            return this.data.path + this.data.name;
        },
        refresh: function(){
            var self = this;

            if (!this._started) { return; }
            if (this.data) {
                var output=['

'];
                output.push("Metabolic Model - " + this.data.name + '
');
                /*
                output.push('
'+
                                '
View in:
 '+
                                ''+
                            '
')
                */

                output.push('

');
                if (this.data.autoMeta){
                    Object.keys(this.data.autoMeta).forEach(function(key){
                        output.push("
" + key + "	" + this.data.autoMeta[key] + "
");
                    },this);
                }
                output.push("

");

                // get download links for related downloads
                var downloads = [];
                var path = this.data.path+'.'+this.data.name;
                WorkspaceManager.getFolderContents(path, true)
                    .then(function(objs) {
                        var paths = [];
                        for (var i=0; i<objs.length; i++) {
                            var obj = objs[i];
                            if (obj.type === 'folder') continue;

                            downloads.push({
                                            path: obj.path,
                                            name: obj.name,
                                            size: formatter.humanFileSize(obj.size, 1)
                                          })
                            paths.push(obj.path);
                        }

                        // fetch downloads urls, return objs containing them
                        return WorkspaceManager.getDownloadUrls(paths)
                                        .then(function(urls) {
                                            for (var i=0; i<downloads.length; i++)
                                                downloads[i].url = urls[i];
                                            return downloads;
                                        })
                    }).then(function(dls) {
                        // add download table
                        output.push('
Downloads
')
                        var table = ['

File	Size
']
                        for (var i in dls) {
                            var dl = dls[i];
                            table.push('
'+
                                            ' '+dl.name+'	'+
                                            ''+dl.size+'	'+
                                       '
');
                        }
                        table.push('
');

                        output = output.concat(table);
                        self.viewer.set("content", output.join(""));
                    })
            }
        },
        startup: function(){
            console.log("Model Viewer Startup()");
            if (this._started) {return;}
            this.inherited(arguments);
            this.viewer = new ContentPane({content: "Loading Metabolic Model...", region: "center"});
            this.addChild(this.viewer);
            this.refresh();

            /*
            this.on("i:click", function(evt){
                var rel = domAttr.get(evt.target,'rel');
                if (rel) {
                    WorkspaceManager.downloadFile(rel);
                }else{
                    console.warn("link not found: ", rel);
                }
            });
            */
        }
    });
});
<|endoftext|>


<commit_before>
/*
 * old library of stuff that needs to be ported to jQuery style JS
 */

var helpwin = null;
var helploc = null;
function deleteRec(url) {
	if (confirm("Are you sure you want to delete this record?")) {
		document.location = url;
	}
}

function deleteRec2(msg,url) {
	if (confirm(msg))
		document.location = url;
}

function help(loc) {
	if (helpwin && !helpwin.closed) {
			helpwin.close();
			helpwin = '';
      helploc = loc;
			setTimeout("openhelp()",500)
	} else {
  	helploc = loc;
		openhelp();
  }
}

function openhelp() {
helpwin=window.open(helploc,"help",'screenX=100,screenY=100,width=350,height=350,scrollbars=yes');
  if (window.focus) {helpwin.focus()}
}
function print_self(){
  window.focus();
  if (typeof(window.print) != "undefined"){
    window.print();
  } else {
    show_print_alert();
  }
}

function show_print_alert() {
   alert("Please use your browser's print button");
}

function MM_openBrWindow(theURL,winName,features) { //v2.0
  window.open(theURL,winName,features);
}

var pic = null;
var t_url;
var t_w;
var t_h;
//window.onunload =  closePic;

function viewImage(url,w,h) {
   openpic(url,w,h);
}

function openpic(url,w,h) {
    if (w == null || w == 0) {
		w = 120;
    }
    if (h == null || h == 0){
	h = 120;
    }

    if (pic){
	pic.close();
	pic = null;
	t_url = url;
	t_w = w;
	t_h = h;
	setTimeout("openit()",500);
	} else {
	do_openpic(url,w,h);
	}
}

function openit() {
	do_openpic(t_url,t_w,t_h);
	t_url = null;
	t_w = null;
	t_h = null;
}

function do_openpic(url,w,h) {
    w +=30;
    h +=30;
    //var features = "scrollbars=auto,toolbar=yes,location=yes,menubar=yes,screenx=150,screeny=150";
    var	features = "dependent=yes,width=" + w + ",height=" + h + ",noresize,scrollbars=auto,toolbar=no,location=no,menubar=no,screenx=150,screeny=150";
//    alert(features);
    pic = window.open(url,"picwin",features);
    //    setTimeout("createContent()",100);

}
function createContent(){
    if (!pic.document){
	setTimeout("createContent()",100);
    } else {
	var url ="aaa";
	var w=100;
	var h=200;
	pic.document.write('');
	pic.document.write('');
	if (window.focus){pic.focus();}
    }
}

<commit_msg>remove old JS file<commit_after><|endoftext|>