<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const ICON_SORT = '';

const USER_TEMPLATE = '
 {{ COL_FIELD }}
';

const CLUSTER_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='icon-cluster'></i>${ICON_SORT}</div>`;
const MODEL_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-object-group'></i>${ICON_SORT}</div>`;
const CACHE_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-database'></i>${ICON_SORT}</div>`;
const IGFS_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-folder-o'></i>${ICON_SORT}</div>`;

const ACTIONS_TEMPLATE = `

            Become this user

            Revoke admin
            Grant admin

            Remove user

            Activity detail

`;

const EMAIL_TEMPLATE = '
{{ COL_FIELD }}
';

export default [
    {name: 'actions', enableHiding: false, displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'actions', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false, visible: false},
    {name: 'user', enableHiding: false, displayName: 'User', categoryDisplayName: 'User', field: 'userName', cellTemplate: USER_TEMPLATE, minWidth: 160, enableFiltering: true, pinnedLeft: true, filter: { placeholder: 'Filter by name...' }},
    {name: 'email', displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
    {name: 'company', displayName: 'Company', categoryDisplayName: 'Company', field: 'company', minWidth: 180, enableFiltering: true, filter: { placeholder: 'Filter by company...' }},
    {name: 'country', displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by country...' }},
    {name: 'lastlogin', displayName: 'Last login', categoryDisplayName: 'Last login', field: 'lastLogin', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 135, width: 135, enableFiltering: false, visible: false},
    {name: 'lastactivity', displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 135, width: 135, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
    // Configurations
    {name: 'cfg_clusters', displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Clusters count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_models', displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Models count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_caches', displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Caches count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_igfs', displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'IGFS count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    // Activities Total
    {name: 'cfg', displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of configuration usages', minWidth: 70, width: 70, enableFiltering: false},
    {name: 'qry', displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of queries usages', minWidth: 70, width: 70, enableFiltering: false},
    {name: 'demo', displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of demo startup', minWidth: 85, width: 85, enableFiltering: false},
    {name: 'dnld', displayName: 'Dnld', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent downloads', minWidth: 80, width: 80, enableFiltering: false},
    {name: 'starts', displayName: 'Starts', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent startup', minWidth: 87, width: 87, enableFiltering: false},
    // Activities Configuration
    {name: 'clusters', displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration clusters', minWidth: 100, width: 100, enableFiltering: false, visible: false},
    {name: 'model', displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration model', minWidth: 87, width: 87, enableFiltering: false, visible: false},
    {name: 'caches', displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration caches', minWidth: 96, width: 96, enableFiltering: false, visible: false},
    {name: 'igfs', displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration IGFS', minWidth: 85, width: 85, enableFiltering: false, visible: false},
    {name: 'summary', displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration summary', minWidth: 111, width: 111, enableFiltering: false, visible: false},
    // Activities Queries
    {name: 'execute', displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query executions', minWidth: 98, width: 98, enableFiltering: false, visible: false},
    {name: 'explain', displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query explain executions', minWidth: 95, width: 95, enableFiltering: false, visible: false},
    {name: 'scan', displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Scan query executions', minWidth: 80, width: 80, enableFiltering: false, visible: false}
];
<commit_msg>IGNITE-4943 Web Console: Improved tooltips on "Admin panel" screen.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const ICON_SORT = '';

const USER_TEMPLATE = '
' +
    ' {{ COL_FIELD }}
';

const CLUSTER_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='icon-cluster'></i>${ICON_SORT}</div>`;
const MODEL_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-object-group'></i>${ICON_SORT}</div>`;
const CACHE_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-database'></i>${ICON_SORT}</div>`;
const IGFS_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-folder-o'></i>${ICON_SORT}</div>`;

const ACTIONS_TEMPLATE = `

            Become this user

            Revoke admin
            Grant admin

            Remove user

            Activity detail

`;

const EMAIL_TEMPLATE = '
{{ COL_FIELD }}
';
const DATE_WITH_TITLE = '
{{ COL_FIELD | date:"M/d/yy HH:mm" }}
';
const VALUE_WITH_TITLE = '
{{ COL_FIELD }}
';

export default [
    {name: 'actions', enableHiding: false, displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'actions', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false, visible: false},
    {name: 'user', enableHiding: false, displayName: 'User', categoryDisplayName: 'User', field: 'userName', cellTemplate: USER_TEMPLATE, minWidth: 160, enableFiltering: true, pinnedLeft: true, filter: { placeholder: 'Filter by name...' }},
    {name: 'email', displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
    {name: 'company', displayName: 'Company', categoryDisplayName: 'Company', field: 'company', cellTemplate: VALUE_WITH_TITLE, minWidth: 180, enableFiltering: true, filter: { placeholder: 'Filter by company...' }},
    {name: 'country', displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', cellTemplate: VALUE_WITH_TITLE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by country...' }},
    {name: 'lastlogin', displayName: 'Last login', categoryDisplayName: 'Last login', field: 'lastLogin', cellTemplate: DATE_WITH_TITLE, minWidth: 135, width: 135, enableFiltering: false, visible: false},
    {name: 'lastactivity', displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellTemplate: DATE_WITH_TITLE, minWidth: 135, width: 135, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
    // Configurations
    {name: 'cfg_clusters', displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Clusters count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_models', displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Models count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_caches', displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Caches count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    {name: 'cfg_igfs', displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'IGFS count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
    // Activities Total
    {name: 'cfg', displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of configuration usages', minWidth: 70, width: 70, enableFiltering: false},
    {name: 'qry', displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of queries usages', minWidth: 70, width: 70, enableFiltering: false},
    {name: 'demo', displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of demo startup', minWidth: 85, width: 85, enableFiltering: false},
    {name: 'dnld', displayName: 'Dnld', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent downloads', minWidth: 80, width: 80, enableFiltering: false},
    {name: 'starts', displayName: 'Starts', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent startup', minWidth: 87, width: 87, enableFiltering: false},
    // Activities Configuration
    {name: 'clusters', displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration clusters', minWidth: 100, width: 100, enableFiltering: false, visible: false},
    {name: 'model', displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration model', minWidth: 87, width: 87, enableFiltering: false, visible: false},
    {name: 'caches', displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration caches', minWidth: 96, width: 96, enableFiltering: false, visible: false},
    {name: 'igfs', displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration IGFS', minWidth: 85, width: 85, enableFiltering: false, visible: false},
    {name: 'summary', displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration summary', minWidth: 111, width: 111, enableFiltering: false, visible: false},
    // Activities Queries
    {name: 'execute', displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query executions', minWidth: 98, width: 98, enableFiltering: false, visible: false},
    {name: 'explain', displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query explain executions', minWidth: 95, width: 95, enableFiltering: false, visible: false},
    {name: 'scan', displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', cellTemplate: VALUE_WITH_TITLE, type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Scan query executions', minWidth: 80, width: 80, enableFiltering: false, visible: false}
];
<|endoftext|>


<commit_before>/*!
Deck JS - deck.help-area
Copyright (c) 2018-2018 Rémi Emonet
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/

/*
This module create a "help popup" which other extensions can contribute to.
This popup can contain help about default keybindings (going further in a
clean manner would most likely need to refactor key handling), information
coming from the presentation itself (author, abstact, etc.), access to rare
tools that have no key binding and edition of rare configuration variables.
*/
(function($, undefined) {
  var $document = $(document);
  var rootCounter;

  var maybeAddSnippet = function() {
    var options = $.deck('getOptions');
    if (options.snippets.helparea) {
      $('.helparea-div.auto-inserted').remove();
      if ($(options.selectors.helpareaDiv).size() > 0 && options.alert.helparea) {
        alert("'options.snippets.helparea' is true but a "+options.selectors.helpareaDiv+" has been found."
              +"\nThis might cause interaction glitches."
              +"\n"
              +"\nSuggestion: remove your html snippet or pass the {snippets: {helparea: false}} option."
             );
      }
      $('<div/>').addClass('helparea-div').addClass('auto-inserted')
        .append($('<div/>').addClass('helparea').attr('data-progress', 'max-height: 0.9*screen.height')
          .append($('<h3/>').text('Help, Tools and Configuration'))
          .append($('<h4/>').text('Keys'))
          .append($('<div/>').addClass('helpkeys'))
        )
      .appendTo($.deck('getContainer'));
    }
  };

  var bindKeyEvents = function() {
    $document.unbind('keydown.deckhelparea');
    $document.bind('keydown.deckhelparea', function(event) {
      var key = $.deck('getOptions').keys.helparea;
      if (event.which === key || $.inArray(event.which, key) > -1) {
        event.preventDefault();
        $.deck('toggleHelpArea');
      }
    });
  };

    /*
  var populateDatalist = function() {
    var options = $.deck('getOptions');
    var $datalist = $(options.selectors.gotoDatalist);

    $.each($.deck('getSlides'), function(i, $slide) {
      var id = $slide.attr('id');
      if (id) {
        $datalist.append('<option value="' + id + '">');
      }
    });
  };
*/

  /*
  Extends defaults/options.

  options.keys.helparea
    The numeric keycode used to show the Help Area.

  */
  $.extend(true, $.deck.defaults, {
    classes: {
      helparea: 'deck-helparea'
    },

    selectors: {
      helpareaDiv: '.helparea-div'
    },

    snippets: {
      helparea: true
    },

    alert: {
      helparea: true
    },

    keys: {
      helparea: 72 // h
    },
  });

  /*
  jQuery.deck('helpAdvertiseKey')

  Add a key binding in the help area, from its keyPath.
  The keypath is what to put after options.keys, to get the key code.
  */
  $.deck('extend', 'helpAdvertiseKey', function(keyPath, docStringOrElement) {
    var options = $.deck('getOptions');
      $('<div/>').text(String.fromCharCode(options.keys[keyPath])).attr('title', keyPath) // TODO parse foo.bar.foo and handle list with modifiers
      .appendTo($('.helparea-div .helpkeys'))
      $('<div/>').text(docStringOrElement)
      .appendTo($('.helparea-div .helpkeys'))
  });

  /*
  jQuery.deck('showHelpArea')

  Shows the Help Area by adding the class specified by the helparea class
  option to the deck container.
  */
  $.deck('extend', 'showHelpArea', function() {
    var options = $.deck('getOptions');
    $.deck('getContainer').addClass(options.classes.helparea);
  });

  /*
  jQuery.deck('hideHelpArea')

  Hides the Help Area by removing the class specified by the helparea class
  option from the deck container.
  */
  $.deck('extend', 'hideHelpArea', function() {
    var options = $.deck('getOptions');
    $.deck('getContainer').removeClass(options.classes.helparea);
  });

  /*
  jQuery.deck('toggleHelpArea')

  Toggles between showing and hiding the Help Area.
  */
  $.deck('extend', 'toggleHelpArea', function() {
    var options = $.deck('getOptions');
    var hasClass = $.deck('getContainer').hasClass(options.classes.helparea);
    $.deck(hasClass ? 'hideHelpArea' : 'showHelpArea');
  });

  $document.bind('deck.init', function() {
    maybeAddSnippet();
    bindKeyEvents();
    $.deck('helpAdvertiseKey', 'helparea', 'Toggle this help area');
  });
})(jQuery);

<commit_msg>[help-area] document helpAdvertiseKey<commit_after>/*!
Deck JS - deck.help-area
Copyright (c) 2018-2018 Rémi Emonet
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/

/*
This module create a "help popup" which other extensions can contribute to.
This popup can contain help about default keybindings (going further in a
clean manner would most likely need to refactor key handling), information
coming from the presentation itself (author, abstact, etc.), access to rare
tools that have no key binding and edition of rare configuration variables.
*/
(function($, undefined) {
  var $document = $(document);
  var rootCounter;

  var maybeAddSnippet = function() {
    var options = $.deck('getOptions');
    if (options.snippets.helparea) {
      $('.helparea-div.auto-inserted').remove();
      if ($(options.selectors.helpareaDiv).size() > 0 && options.alert.helparea) {
        alert("'options.snippets.helparea' is true but a "+options.selectors.helpareaDiv+" has been found."
              +"\nThis might cause interaction glitches."
              +"\n"
              +"\nSuggestion: remove your html snippet or pass the {snippets: {helparea: false}} option."
             );
      }
      $('<div/>').addClass('helparea-div').addClass('auto-inserted')
        .append($('<div/>').addClass('helparea').attr('data-progress', 'max-height: 0.9*screen.height')
          .append($('<h3/>').text('Help, Tools and Configuration'))
          .append($('<h4/>').text('Keys'))
          .append($('<div/>').addClass('helpkeys'))
        )
      .appendTo($.deck('getContainer'));
    }
  };

  var bindKeyEvents = function() {
    $document.unbind('keydown.deckhelparea');
    $document.bind('keydown.deckhelparea', function(event) {
      var key = $.deck('getOptions').keys.helparea;
      if (event.which === key || $.inArray(event.which, key) > -1) {
        event.preventDefault();
        $.deck('toggleHelpArea');
      }
    });
  };

    /*
  var populateDatalist = function() {
    var options = $.deck('getOptions');
    var $datalist = $(options.selectors.gotoDatalist);

    $.each($.deck('getSlides'), function(i, $slide) {
      var id = $slide.attr('id');
      if (id) {
        $datalist.append('<option value="' + id + '">');
      }
    });
  };
*/

  /*
  Extends defaults/options.

  options.keys.helparea
    The numeric keycode used to show the Help Area.

  */
  $.extend(true, $.deck.defaults, {
    classes: {
      helparea: 'deck-helparea'
    },

    selectors: {
      helpareaDiv: '.helparea-div'
    },

    snippets: {
      helparea: true
    },

    alert: {
      helparea: true
    },

    keys: {
      helparea: 72 // h
    },
  });

  /*
  jQuery.deck('helpAdvertiseKey', keyPath, docStringOrElement)

  Add a key binding in the help area, from its keyPath.
  The keypath is what to put after options.keys, to get the key code.
  */
  $.deck('extend', 'helpAdvertiseKey', function(keyPath, docStringOrElement) {
    var options = $.deck('getOptions');
      $('<div/>').text(String.fromCharCode(options.keys[keyPath])).attr('title', keyPath) // TODO parse foo.bar.foo and handle list with modifiers
      .appendTo($('.helparea-div .helpkeys'))
      $('<div/>').text(docStringOrElement)
      .appendTo($('.helparea-div .helpkeys'))
  });

  /*
  jQuery.deck('showHelpArea')

  Shows the Help Area by adding the class specified by the helparea class
  option to the deck container.
  */
  $.deck('extend', 'showHelpArea', function() {
    var options = $.deck('getOptions');
    $.deck('getContainer').addClass(options.classes.helparea);
  });

  /*
  jQuery.deck('hideHelpArea')

  Hides the Help Area by removing the class specified by the helparea class
  option from the deck container.
  */
  $.deck('extend', 'hideHelpArea', function() {
    var options = $.deck('getOptions');
    $.deck('getContainer').removeClass(options.classes.helparea);
  });

  /*
  jQuery.deck('toggleHelpArea')

  Toggles between showing and hiding the Help Area.
  */
  $.deck('extend', 'toggleHelpArea', function() {
    var options = $.deck('getOptions');
    var hasClass = $.deck('getContainer').hasClass(options.classes.helparea);
    $.deck(hasClass ? 'hideHelpArea' : 'showHelpArea');
  });

  $document.bind('deck.init', function() {
    maybeAddSnippet();
    bindKeyEvents();
    $.deck('helpAdvertiseKey', 'helparea', 'Toggle this help area');
  });
})(jQuery);

<|endoftext|>


<commit_before>
var Compiler = require('../../compiler')
var expect = require('chai').expect
var Promise = require('bluebird')

var PENDING = {}

module.exports = function() {

  var Given = sugar(this, this.Given)
  var When  = sugar(this, this.When)
  var Then  = sugar(this, this.Then)

  Given(/^a BMS file as follows$/, function (string) {
    this._text = string
    this._compileResult = Compiler.compile(this._text)
  })

  Then(/^there should be (\d+) header sentences$/, function (arg1) {
    return PENDING
  })

  Then(/^there should be (\d+) channel sentence$/, function (arg1) {
    return PENDING
  })

  Then(/^the header "([^"]*)" should have value "([^"]*)"$/, function (arg1, arg2) {
    return PENDING
  })

  Then(/^there should be (\d+) objects$/, function (arg1) {
    return PENDING
  })

  Then(/^there should be (\d+) object at beat (\d+)$/, function (arg1, arg2) {
    return PENDING
  })

}

function sugar(world, defineFunction) {
  return function(pattern, f) {
    defineFunction.call(world, pattern, function() {
      var callback = arguments[arguments.length - 1]
      Promise.try(f, [].slice.call(arguments), world).then(
        function(result) {
          if (result == PENDING) {
            callback.pending()
          } else {
            callback()
          }
        },
        function(err) {
          callback(err)
        }
      )
    })
  }
}

<commit_msg>test(compiler): add step definition for asserting sentence counts<commit_after>
var Compiler = require('../../compiler')
var expect = require('chai').expect
var Promise = require('bluebird')

var PENDING = {}

module.exports = function() {

  var Given = sugar(this, this.Given)
  var When  = sugar(this, this.When)
  var Then  = sugar(this, this.Then)

  Given(/^a BMS file as follows$/, function (string) {
    this._text = string
    this._compileResult = Compiler.compile(this._text)
  })

  Then(/^there should be (\d+) header sentences$/, function (n) {
    expect(this._compileResult.headerSentences).to.equal(+n)
  })

  Then(/^there should be (\d+) channel sentence$/, function (n) {
    expect(this._compileResult.channelSentences).to.equal(+n)
  })

  Then(/^the header "([^"]*)" should have value "([^"]*)"$/, function (arg1, arg2) {
    return PENDING
  })

  Then(/^there should be (\d+) objects$/, function (arg1) {
    return PENDING
  })

  Then(/^there should be (\d+) object at beat (\d+)$/, function (arg1, arg2) {
    return PENDING
  })

}

function sugar(world, defineFunction) {
  return function(pattern, f) {
    defineFunction.call(world, pattern, function() {
      var callback = arguments[arguments.length - 1]
      Promise.try(f, [].slice.call(arguments), world).then(
        function(result) {
          if (result == PENDING) {
            callback.pending()
          } else {
            callback()
          }
        },
        function(err) {
          callback(err)
        }
      )
    })
  }
}

<|endoftext|>


<commit_before>var AdminFilters = function(element, filtersElement, filterGroups) {
    var $root = $(element);
    var $container = $('.filters', $root);
    var lastCount = 0;

    function getCount(name) {
        var idx = name.indexOf('_');

        if (idx === -1) {
            return 0;
        }

        return parseInt(name.substr(3, idx - 3), 10);
    }

    function makeName(name) {
        var result = 'flt' + lastCount + '_' + name;
        lastCount += 1;
        return result;
    }

    function changeOperation() {
        var $row = $(this).closest('tr');
        var $el = $('.filter-val:input', $row);
        var count = getCount($el.attr('name'));
        $el.attr('name', 'flt' + count + '_' + $(this).val());
        $('button', $root).show();
    }

    function removeFilter() {
        $(this).closest('tr').remove();
        if($('.filters tr').length == 0) {
            $('button', $root).hide();
            $('a[class=btn]', $root).hide();
            $('.filters tbody').remove();
        } else {
            $('button', $root).show();
        }

        return false;
    }

    function addFilter(name, subfilters) {
        var $el = $('
').appendTo($container);

        // Filter list
        $el.append(
            $('').append(
                $('')
                    .append($('×'))
                    .append(' ')
                    .append(name)
                    .click(removeFilter)
                )
        );

        // Filter type
        var $select = $('<select class="filter-op" />')
                      .change(changeOperation);

        $(subfilters).each(function() {
            $select.append($('<option/>').attr('value', this.arg).text(this.operation));
        });

        $el.append(
            $('').append($select)
        );

        $select.select2({width: 'resolve'});

        // Input
        var filter = subfilters[0];

        var $field;

        if (filter.options) {
            $field = $('<select class="filter-val" />')
                        .attr('name', makeName(filter.arg));

            $(filter.options).each(function() {
                $field.append($('<option/>')
                    .val(this[0]).text(this[1]));
            });

            $el.append($('').append($field));
            $field.select2({width: 'resolve'});
        } else
        {
            $field = $('<input type="text" class="filter-val form-control" />')
                        .attr('name', makeName(filter.arg));
            $el.append($('').append($field));
        }

        if (filter.type) {
            $field.attr('data-role', filter.type);
            faForm.applyStyle($field, filter.type);
        }
    }

    $('a.filter', filtersElement).click(function() {
        var name = $(this).text().trim();

        addFilter(name, filterGroups[name]);

        $('button', $root).show();

        //return false;
    });

    $('.filter-op', $root).change(changeOperation);
    $('.filter-val', $root).change(function() {
        $('button', $root).show();
    });
    $('.remove-filter', $root).click(removeFilter);

    $('.filter-val', $root).each(function() {
        var count = getCount($(this).attr('name'));
        if (count > lastCount)
            lastCount = count;
    });

    lastCount += 1;
};
<commit_msg>Fix parsing by using correct format for filter<commit_after>var AdminFilters = function(element, filtersElement, filterGroups) {
    var $root = $(element);
    var $container = $('.filters', $root);
    var lastCount = 0;

    function getCount(name) {
        var idx = name.indexOf('_');

        if (idx === -1) {
            return 0;
        }

        return parseInt(name.substr(3, idx - 3), 10);
    }

    function makeName(name) {
        var result = 'flt' + lastCount + '_' + name;
        lastCount += 1;
        return result;
    }

    function changeOperation() {
        var $row = $(this).closest('tr');
        var $el = $('.filter-val:input', $row);
        var count = getCount($el.attr('name'));
        $el.attr('name', 'flt' + count + '_' + $(this).val());
        $('button', $root).show();
    }

    function removeFilter() {
        $(this).closest('tr').remove();
        if($('.filters tr').length == 0) {
            $('button', $root).hide();
            $('a[class=btn]', $root).hide();
            $('.filters tbody').remove();
        } else {
            $('button', $root).show();
        }

        return false;
    }

    function addFilter(name, subfilters) {
        var $el = $('
').appendTo($container);

        // Filter list
        $el.append(
            $('').append(
                $('')
                    .append($('×'))
                    .append(' ')
                    .append(name)
                    .click(removeFilter)
                )
        );

        // Filter type
        var $select = $('<select class="filter-op" />')
                      .change(changeOperation);

        $(subfilters).each(function() {
            $select.append($('<option/>').attr('value', this.arg).text(this.operation));
        });

        $el.append(
            $('').append($select)
        );

        $select.select2({width: 'resolve'});

        // Input
        var filter = subfilters[0];

        var $field;

        if (filter.options) {
            $field = $('<select class="filter-val" />')
                        .attr('name', makeName(filter.arg));

            $(filter.options).each(function() {
                $field.append($('<option/>')
                    .val(this[0]).text(this[1]));
            });

            $el.append($('').append($field));
            $field.select2({width: 'resolve'});
        } else
        {
            $field = $('<input type="text" class="filter-val form-control" />')
                        .attr('name', makeName(filter.arg));
            $el.append($('').append($field));
        }

        if (filter.type) {
            $field.attr('data-role', filter.type);
            if (filter.type == "datepicker") {
                $field.attr('data-date-format', "YYYY-MM-DD");
            }
            faForm.applyStyle($field, filter.type);
        }
    }

    $('a.filter', filtersElement).click(function() {
        var name = $(this).text().trim();

        addFilter(name, filterGroups[name]);

        $('button', $root).show();

        //return false;
    });

    $('.filter-op', $root).change(changeOperation);
    $('.filter-val', $root).change(function() {
        $('button', $root).show();
    });
    $('.remove-filter', $root).click(removeFilter);

    $('.filter-val', $root).each(function() {
        var count = getCount($(this).attr('name'));
        if (count > lastCount)
            lastCount = count;
    });

    lastCount += 1;
};
<|endoftext|>


<commit_before>var uuid = require('node-uuid');
var id = uuid.v4()

var jsonDataPort = []
var host = window.location.hostname
var frames = 0

var dataManipulationFunction = (arg) => {}
var defineCommandToServer = () => {}

var wsPort = new WebSocket('ws://' + host + ':6000')
wsPort.onmessage = function (event) {
    jsonDataPort = JSON.parse(event.data)
}

var ws = new WebSocket('ws://' + host + jsonDataPort.port +"/?id="+id )
ws.onmessage = function (event) {
    frames++
    dataManipulationFunction(event.data)
}

var countFpsFunction = () =>
    {
      setTimeout(countFPS,1000)
      console.log("fps : " +frames)
      frames = 0
      console.log(JSON.stringify(jsonData,1))
    }
    setTimeout(countFPS,1000)

var sendCommand = () =>
{
    setTimeout(sendCommand,16.667)
    ws.send( defineCommandToServer() )
}
setTimeout(sendCommand,1000)

module.exports.dataManipulation = (f) => { dataManipulationFunction = f }
module.exports.commandToServer = (f) => { commandToServerFunction = f }
module.exports.countFps = () => { countFpsFunction() }<commit_msg>corrected some mistakes<commit_after>var uuid = require('node-uuid');
var id = uuid.v4()

var jsonDataPort = []
var host = window.location.hostname
var frames = 0
var fps = 0

var dataManipulationFunction = (arg) => {}
var defineCommandToServer = () => {}

var wsPort = new WebSocket('ws://' + host + ':6000')
wsPort.onmessage = function (event) {
    jsonDataPort = JSON.parse(event.data)

    var ws = new WebSocket('ws://' + host + jsonDataPort.port +"/?id="+id )
    ws.onmessage = function (event) {
        frames++
        dataManipulationFunction(event.data)
    }
}

var countFpsFunction = () =>
{
    setTimeout(countFpsFunction,1000)
    fps = frames
    frames = 0
}
setTimeout(countFpsFunction,1000)

var sendCommand = () =>
{
    setTimeout(sendCommand,16.667)
    ws.send( defineCommandToServer() )
}
setTimeout(sendCommand,1000)

module.exports.dataManipulation = (f) => { dataManipulationFunction = f }
module.exports.commandToServer = (f) => { commandToServerFunction = f }
module.exports.countFps = () => { return fps }<|endoftext|>


<commit_before>const React = require('react');
const {
    List, ListItem, ListItemContent,
    Grid, Cell,
    Button, Icon,
    Switch,
} = require('react-mdl');
const { Link } = require('react-router');

export const AppsLinkList = ({ apps }) => (
    <List style={{ textAlign: 'left' }}>
    {apps.length > 0 && apps.map(({ appName, description = '-', icon = 'apps' }) => (
        <ListItem twoLine key={appName}>
            <ListItemContent avatar={icon} subtitle={description}>
                <Link key={appName} to={`/applications/${appName}`}>
                    {appName}
                </Link>
            </ListItemContent>
        </ListItem>
    ))}
    </List>
);

export const HeaderTitle = ({ title, actions, subtitle }) => (

{title}

                {subtitle && {subtitle}}

                {actions}

);

export const FormButtons = ({ submitText = 'Create', onCancel }) => (

        <Button type="submit" ripple raised primary icon="add">
            <Icon name="add" />
            { submitText }
        </Button>

        <Button type="cancel" ripple raised onClick={onCancel} style={{ float: 'right' }}>
            <Icon name="cancel" />
            Cancel
        </Button>

);

export const SwitchWithLabel = ({ onChange, children, checked }) => (

            <Switch onChange={onChange} checked={checked} />

        {children}

);

export const TogglesLinkList = ({ toggles }) => (
    <List style={{ textAlign: 'left' }}>
    {toggles.length > 0 && toggles.map(({ name, description = '-', icon = 'toggle' }) => (
        <ListItem twoLine key={name}>
            <ListItemContent avatar={icon} subtitle={description}>
                <Link key={name} to={`/features/edit//${name}`}>
                    {name}
                </Link>
            </ListItemContent>
        </ListItem>
    ))}
    </List>
);
<commit_msg>Fixed typo in toggle link<commit_after>const React = require('react');
const {
    List, ListItem, ListItemContent,
    Grid, Cell,
    Button, Icon,
    Switch,
} = require('react-mdl');
const { Link } = require('react-router');

export const AppsLinkList = ({ apps }) => (
    <List style={{ textAlign: 'left' }}>
    {apps.length > 0 && apps.map(({ appName, description = '-', icon = 'apps' }) => (
        <ListItem twoLine key={appName}>
            <ListItemContent avatar={icon} subtitle={description}>
                <Link key={appName} to={`/applications/${appName}`}>
                    {appName}
                </Link>
            </ListItemContent>
        </ListItem>
    ))}
    </List>
);

export const HeaderTitle = ({ title, actions, subtitle }) => (

{title}

                {subtitle && {subtitle}}

                {actions}

);

export const FormButtons = ({ submitText = 'Create', onCancel }) => (

        <Button type="submit" ripple raised primary icon="add">
            <Icon name="add" />
            { submitText }
        </Button>

        <Button type="cancel" ripple raised onClick={onCancel} style={{ float: 'right' }}>
            <Icon name="cancel" />
            Cancel
        </Button>

);

export const SwitchWithLabel = ({ onChange, children, checked }) => (

            <Switch onChange={onChange} checked={checked} />

        {children}

);

export const TogglesLinkList = ({ toggles }) => (
    <List style={{ textAlign: 'left' }}>
    {toggles.length > 0 && toggles.map(({ name, description = '-', icon = 'toggle' }) => (
        <ListItem twoLine key={name}>
            <ListItemContent avatar={icon} subtitle={description}>
                <Link key={name} to={`/features/edit/${name}`}>
                    {name}
                </Link>
            </ListItemContent>
        </ListItem>
    ))}
    </List>
);
<|endoftext|>


<commit_before>export { Base, Params };

/**
 * A base class for extracting and keeping weights. It composes of a Float32Array and a shape. It can
 * be used as CNN (depthwise, pointwise and bias) filter weights.
 *
 * @member {Float32Array} defaultInput
 *   The default input Float32Array. Its byteOffset will be checked against defaultByteOffsetBegin.
 * Its content will be interpret as weights if privilegeInput is null. Otherwise, its content
 * will be ignored if privilegeInput is not null.
 *
 * @member {number} defaultByteOffsetBegin
 *   The weights[] begins at defaultInput's defaultByteOffsetBegin (relative to defaultInput.buffer,
 * not to defaultInput.byteOffset). If this value less than defaultInput.byteOffset, the
 * initialization will fail (i.e. ( isValid() == false ) ).
 *
 * @member {number} defaultByteOffsetEnd
 *   The weights[] ends at defaultInput's defaultByteOffsetEnd (relative to defaultInput.buffer,
 * not to defaultInput.byteOffset) exclusively.
 *
 * @member {Float32Array} privilegeInput
 *   The privilege input Float32Array. If not null, its content will be interpret as weights and
 * the content of defaultInput will be ignored.
 *
 * @member {number} privilegeByteOffsetBegin
 *   The weights[] begins at privilegeInput's privilegeByteOffsetBegin (relative to privilegeInput.buffer,
 * not to privilegeInput.byteOffset). If this value less than privilegeInput.byteOffset, the
 * initialization will fail (i.e. ( isValid() == false ) ).
 *
 * @member {number} privilegeByteOffsetEnd
 *   The weights[] ends at privilegeInput's privilegeByteOffsetEnd (relative to privilegeInput.buffer,
 * not to privilegeInput.byteOffset) exclusively.
 *
 * @member {number[]} shape
 *   The weights shape (element count for every dimension). The shape.length is dimension. If ( shape.length == 0 ),
 * it is 0-dimension (i.e. scalar). Theinitialization will fail (i.e. ( isValid() == false ) ) if shape is too large
 * (or NaN) (exceeds the defaultInput (or, privilegeInput if not null) bounding).
 *
 * @member {Float32Array} weights
 *  The values. It is a reference (sub-range) to the underlying defaultInput (or privilegeInput).
 */
class Base {

  /**
   * Create Float32Array weights[] over the defaultInput (or privilegeInput) according to the specific
   * byteOffsetBegin, shape, and weightConverter.
   *
   * The defaultInput and privilegeInput can not both be null. If one of them is null, the non-null is used.
   * If both are non-null, the privilegeInput will be used.
   *
   * @return {boolean} Return false, if initialization failed.
   */
  init( defaultInput, defaultByteOffsetBegin, privilegeInput, privilegeByteOffsetBegin, shape ) {

    this.defaultInput =   defaultInput;
    this.privilegeInput = privilegeInput;
    this.shape =          shape;
    this.weights =        null;   // So that ( isValid() == false ) if re-initialization failed.

    //let weightCount =     ( shape ) ? shape.reduce( ( accumulator, currentValue ) => accumulator * currentValue ) : 0;
    let weightCount =     ( shape ) ? tf.sizeFromShape( shape ) : 0; // tf.sizeFromShape() can handle zero length (i.e. scalar).
    let weightByteCount = weightCount * Float32Array.BYTES_PER_ELEMENT;

    let input, byteOffsetBegin;
    let byteOffsetEnd; // Exclusive. As the next filter's begin.

    if ( privilegeInput ) {       // privilegeInput first.

      if ( privilegeByteOffsetBegin < privilegeInput.byteOffset )
        return false;  // Failed, the privilege beginning position is illegal (less than bounding).

      input = privilegeInput;
      byteOffsetBegin = this.privilegeByteOffsetBegin = privilegeByteOffsetBegin;
      byteOffsetEnd =   this.privilegeByteOffsetEnd =   privilegeByteOffsetBegin + weightByteCount;
      this.defaultByteOffsetBegin = this.defaultByteOffsetEnd = defaultByteOffsetBegin; // Stay at beginning for not used.

    } else if ( defaultInput ) {  // defaultInput second.

      if ( defaultByteOffsetBegin < defaultInput.byteOffset )
        return false;  // Failed, the default beginning position is illegal (less than bounding).

      input = defaultInput;
      byteOffsetBegin = this.defaultByteOffsetBegin = defaultByteOffsetBegin;
      byteOffsetEnd =   this.defaultByteOffsetEnd =   defaultByteOffsetBegin + weightByteCount;
      this.privilegeByteOffsetBegin = this.privilegeByteOffsetEnd = privilegeByteOffsetBegin; // Stay at beginning for not used.

    } else {
      return false;  // Failed, both privilege and default input are null.
    }

    // Bounded by the input.byteLength.
    let legalByteOffsetEnd = input.byteOffset + input.byteLength;
    if ( byteOffsetEnd > legalByteOffsetEnd )
      return false;  // Failed, if shape is too large (or NaN).

    this.weights = new Float32Array( input.buffer, byteOffsetBegin, weightCount );  // Share the underlying array buffer.
    return true;     // Success.
  }

  /** @return {number} Return the absolute value of the trucated value. */
  static toPositiveInteger( v ) {
    return Math.abs( Math.trunc( v ) );
  }

  /** @return Return true, if initialization is success (i.e. ( this.weights != null )). */
  isValid()                      { return ( this.weights ) ? true : false; }

  get weightByteCount()          { return this.weights.byteLength; }
  get weightCount()              { return this.weights.length; }
}

/**
 * The parameters for the weights of a neural network layer.
 *
 * @member {Map} parameterMap
 *   All parameters provided by this object. Its keys are the same as init()'s parameterMap. Its values are
 * combined from init()'s parameterMap and inputFloat32Array (or fixedWeights).
 *
 * @member {number} parameterCountExtracted
 *   How many parameters are extracted from inputFloat32Array or fixedWeights in fact. Only existed if init()
 * successfully. The same as this.weightCount (i.e. length of this.weights[] and this.weightsModified[]).
 *
 * @member {number} parameterCount
 *   Always ( parameterMap.size ). This is the total parameter count provided by this object
 * if init() successfully.
 *
//!!! ...unfinished...
 * @member {number} inChannels
 *   The input channel count of this neural network layer.
 *
 * @member {number} channelMultiplier
 *   Every input channel will be expanded into how many channels.
 *
 * @member {number} outChannels
 *   The output channel count of this neural network layer.
 *
 * @member {Float32Array} weightsModified
 *  The copied extracted values. They are copied from inputFloat32Array or fixedWeights, and then converted
 * to positive integer. Its length will be the same as parameterCountExtracted.
 */
class Params extends Base {

  /**
   *
   * The parameterMap should have at least:
   *
   * - Params.Keys.inChannels
   *   {number} There will be how many input channels. (Input channel count)
   *
   *
   * The parameterMap could also have (and any other custom key-value pairs):
   *
   * - Params.Keys.channelMultiplier
   *   {number} Every input channel will be expanded into how many channels.
   *     - If not null, it will be used instead of extracting from inputFloat32Array or fixedWeights. (By specifying)
   *     - If null, extracted from inputFloat32Array or fixedWeights. (By evolution)
   *
   * - Params.Keys.outChannels
   *   {number} There will be how many output channels. (Output channel count)
   *     - If Number.isFinite(), it will be used instead of extracting from inputFloat32Array or fixedWeights. (By specifying)
   *     - If Infinity (Number.POSITIVE_INFINITY), it will be ( inChannels * channelMultiplier ). (By channelMultiplier)
   *     - If null, extracted from inputFloat32Array or fixedWeights. (By evolution)
   *
   *
   * @param {Float32Array} inputFloat32Array
   *   A Float32Array whose values will be interpret as weights. It should have ( parameterCountExtractedAtLeast ) or
   * ( parameterCountExtractedAtLeast + 1 ) or ( parameterCountExtractedAtLeast + 2 ) elements according to the
   * value of channelMultiplier and outChannels.
   *
   * @param {number} byteOffsetBegin
   *   The position to start to decode from the inputFloat32Array. This is relative to the inputFloat32Array.buffer
   * (not to the inputFloat32Array.byteOffset).
   *
   * @param {Map} parameterMap
   *   Describe what parameters to be used or extracted. The keys of parameterMap will be viewed as parameter names.
   * The values of parameterMap will be viewed as parameter values. If the value of a [ key, value ] entry is null,
   * the parameter's value will be extracted from inputFloat32Array or fixedWeights (i.e. by evolution). Otherwise,
   * the parameter's value will be the value of the [ key, value ] entry (i.e. by specifying).
   *
   * @param {Float32Array|Array} fixedWeights
   *   If null, extract parameters from inputFloat32Array. If not null, extract parameters from it instead of
   * inputFloat32Array. When not null, it should have parameterCountExtracted elements (i.e. the count of null values
   * of parameterMap).
   *
   * @return {boolean} Return false, if initialization failed.
   *
   * @override
   */
  init( inputFloat32Array, byteOffsetBegin, parameterMap, fixedWeights = null ) {

    this.weightsModified = this.parameterMap = null; // So that distinguishable if re-initialization failed.

    if ( !parameterMap )
      return false;  // Don not know what parameters to be used or extracted.

    let inChannels = parameterMap.get( Params.Keys.inChannels );
    if ( !inChannels )
      return false;  // At least, there should be a (required) parameter (i.e. input channel count).

    this.parameterMap = new Map( parameterMap );  // Copy so that the original map will not be modified.

    // Collect what parameters should be extracted from input array (rather than use values in the parameterMap).
    // At the same time, its array index will also be recorded for extracting its value from array.
    let arrayIndexMap = new Map();
    {
      let i = 0;
      for ( let [ key, value ] of parameterMap ) {
        // A null value means it should be extracted from inputFloat32Array or fixedWeights (i.e. by evolution).
        if ( !value ) {
          arrayIndexMap.set( key, i ); // Record the index to this.weightsModified[].
          ++i;
        }
      }
    }

    let parameterCountExtracted = arrayIndexMap.size; // Determine how many parameters should be extracted from array.

    // If has fixedWeights, use it as priviledge input.
    let privilegeInput;
    if ( fixedWeights ) {
      if ( fixedWeights instanceof Float32Array )
        privilegeInput = fixedWeights;
      else
        privilegeInput = new Float32Array( fixedWeights );  // Convert to Float32Array.
    }

    // Extract a block of input array.
    let bInitOk = super.init( inputFloat32Array, byteOffsetBegin, privilegeInput, 0, [ parameterCountExtracted ] );

    if ( !bInitOk )
      return false;

    // Copy and convert to integer.
    //
    // Do not modify the original array data. When backtracking (to try another neural network layer
    // configuration), the original data is necessary.
    this.weightsModified = new Float32Array( this.weights );
    this.weightsModified.forEach( ( element, i, array ) => array[ i ] = Base.toPositiveInteger( element ) );

    // Extract (by evolution) values from array into map.
    for ( let [ key, arrayIndex ] of arrayIndexMap ) {
      this.parameterMap.set( key, this.weightsModified[ arrayIndex ] );
    }

    // If original parameterMap has output channel count and its value is infinity, its value should be depend
    // on channelMultiplier (i.e. by channelMultiplier).
    //
    // Usually, the embedding layer uses this behavior.
    let outChannelsOriginal = parameterMap.get( Params.Keys.outChannels );
    if ( outChannelsOriginal ) {
      if ( !Number.isFinite( outChannelsOriginal ) ) {
        let channelMultiplier = this.channelMultiplier;   // May be specified or extracted.
        let outChannels = inChannels * channelMultiplier;
        this.parameterMap.set( Params.Keys.outChannels, outChannels );
      } else {
        // Use the original value in parameterMap as output channel count (i.e. by specifying).
      }
    } else {
      // Either use the extracted value as output channel count (i.e. by evolution),
      // or there is no output channel count in fact.
    }

    return bInitOk;
  }

  get parameterCountExtracted() { return this.weightCount; }
  get parameterCount()          { return this.parameterMap.size; }

  get inChannels()        { return this.parameterMap.get( Params.Keys.inChannels ); }
  get channelMultiplier() { return this.parameterMap.get( Params.Keys.channelMultiplier ); }
  get outChannels()       { return this.parameterMap.get( Params.Keys.outChannels ); }
}

/**
 * Define parameter keys.
 *
 * They are (static) symbol objects used as keys of Params.init()'s parameterMap. They can be seen inside Map when
 * debugging, and are faster than string (or String object) when Map's key comparing.
 */
Params.Keys = class {
//   // Although they are functions, they should not be called. They are (static function) objects used as keys of
//   // Params.init()'s parameterMap. Using function object (rather than general object) so that the (function) name
//   // can be seen inside Map when debugging. Using function object (rather than string or String object) so that
//   // Map's key comparing is faster.
//   static inChannels()        {}
//   static channelMultiplier() {}
//   static outChannels()       {}
}

Params.Keys.inChannels =        Symbol("inChannels");
Params.Keys.channelMultiplier = Symbol("channelMultiplier");
Params.Keys.outChannels =       Symbol("outChannels");

Params.Keys.dilationHeight =    Symbol("dilationHeight");
Params.Keys.dilationWidth =     Symbol("dilationWidth");
Params.Keys.filterHeight =      Symbol("filterHeight");
Params.Keys.filterWidth =       Symbol("filterWidth");
<commit_msg>Update Weights.js<commit_after>export { Base, Params };

/**
 * A base class for extracting and keeping weights. It composes of a Float32Array and a shape. It can
 * be used as CNN (depthwise, pointwise and bias) filter weights.
 *
 * @member {Float32Array} defaultInput
 *   The default input Float32Array. Its byteOffset will be checked against defaultByteOffsetBegin.
 * Its content will be interpret as weights if privilegeInput is null. Otherwise, its content
 * will be ignored if privilegeInput is not null.
 *
 * @member {number} defaultByteOffsetBegin
 *   The weights[] begins at defaultInput's defaultByteOffsetBegin (relative to defaultInput.buffer,
 * not to defaultInput.byteOffset). If this value less than defaultInput.byteOffset, the
 * initialization will fail (i.e. ( isValid() == false ) ).
 *
 * @member {number} defaultByteOffsetEnd
 *   The weights[] ends at defaultInput's defaultByteOffsetEnd (relative to defaultInput.buffer,
 * not to defaultInput.byteOffset) exclusively.
 *
 * @member {Float32Array} privilegeInput
 *   The privilege input Float32Array. If not null, its content will be interpret as weights and
 * the content of defaultInput will be ignored.
 *
 * @member {number} privilegeByteOffsetBegin
 *   The weights[] begins at privilegeInput's privilegeByteOffsetBegin (relative to privilegeInput.buffer,
 * not to privilegeInput.byteOffset). If this value less than privilegeInput.byteOffset, the
 * initialization will fail (i.e. ( isValid() == false ) ).
 *
 * @member {number} privilegeByteOffsetEnd
 *   The weights[] ends at privilegeInput's privilegeByteOffsetEnd (relative to privilegeInput.buffer,
 * not to privilegeInput.byteOffset) exclusively.
 *
 * @member {number[]} shape
 *   The weights shape (element count for every dimension). The shape.length is dimension. If ( shape.length == 0 ),
 * it is 0-dimension (i.e. scalar). Theinitialization will fail (i.e. ( isValid() == false ) ) if shape is too large
 * (or NaN) (exceeds the defaultInput (or, privilegeInput if not null) bounding).
 *
 * @member {Float32Array} weights
 *  The values. It is a reference (sub-range) to the underlying defaultInput (or privilegeInput).
 */
class Base {

  /**
   * Create Float32Array weights[] over the defaultInput (or privilegeInput) according to the specific
   * byteOffsetBegin, shape, and weightConverter.
   *
   * The defaultInput and privilegeInput can not both be null. If one of them is null, the non-null is used.
   * If both are non-null, the privilegeInput will be used.
   *
   * @return {boolean} Return false, if initialization failed.
   */
  init( defaultInput, defaultByteOffsetBegin, privilegeInput, privilegeByteOffsetBegin, shape ) {

    this.defaultInput =   defaultInput;
    this.privilegeInput = privilegeInput;
    this.shape =          shape;
    this.weights =        null;   // So that ( isValid() == false ) if re-initialization failed.

    //let weightCount =     ( shape ) ? shape.reduce( ( accumulator, currentValue ) => accumulator * currentValue ) : 0;
    let weightCount =     ( shape ) ? tf.sizeFromShape( shape ) : 0; // tf.sizeFromShape() can handle zero length (i.e. scalar).
    let weightByteCount = weightCount * Float32Array.BYTES_PER_ELEMENT;

    let input, byteOffsetBegin;
    let byteOffsetEnd; // Exclusive. As the next filter's begin.

    if ( privilegeInput ) {       // privilegeInput first.

      if ( privilegeByteOffsetBegin < privilegeInput.byteOffset )
        return false;  // Failed, the privilege beginning position is illegal (less than bounding).

      input = privilegeInput;
      byteOffsetBegin = this.privilegeByteOffsetBegin = privilegeByteOffsetBegin;
      byteOffsetEnd =   this.privilegeByteOffsetEnd =   privilegeByteOffsetBegin + weightByteCount;
      this.defaultByteOffsetBegin = this.defaultByteOffsetEnd = defaultByteOffsetBegin; // Stay at beginning for not used.

    } else if ( defaultInput ) {  // defaultInput second.

      if ( defaultByteOffsetBegin < defaultInput.byteOffset )
        return false;  // Failed, the default beginning position is illegal (less than bounding).

      input = defaultInput;
      byteOffsetBegin = this.defaultByteOffsetBegin = defaultByteOffsetBegin;
      byteOffsetEnd =   this.defaultByteOffsetEnd =   defaultByteOffsetBegin + weightByteCount;
      this.privilegeByteOffsetBegin = this.privilegeByteOffsetEnd = privilegeByteOffsetBegin; // Stay at beginning for not used.

    } else {
      return false;  // Failed, both privilege and default input are null.
    }

    // Bounded by the input.byteLength.
    let legalByteOffsetEnd = input.byteOffset + input.byteLength;
    if ( byteOffsetEnd > legalByteOffsetEnd )
      return false;  // Failed, if shape is too large (or NaN).

    this.weights = new Float32Array( input.buffer, byteOffsetBegin, weightCount );  // Share the underlying array buffer.
    return true;     // Success.
  }

  /** @return {number} Return the absolute value of the trucated value. */
  static toPositiveInteger( v ) {
    return Math.abs( Math.trunc( v ) );
  }

  /** @return Return true, if initialization is success (i.e. ( this.weights != null )). */
  isValid()                      { return ( this.weights ) ? true : false; }

  get weightByteCount()          { return this.weights.byteLength; }
  get weightCount()              { return this.weights.length; }
}

/**
 * The parameters for the weights of a neural network layer.
 *
 * @member {Map} parameterMap
 *   All parameters provided by this object. Its keys are the same as init()'s parameterMap. Its values are
 * combined from init()'s parameterMap and inputFloat32Array (or fixedWeights).
 *
 * @member {number} parameterCountExtracted
 *   How many parameters are extracted from inputFloat32Array or fixedWeights in fact. Only existed if init()
 * successfully. The same as this.weightCount (i.e. length of this.weights[] and this.weightsModified[]).
 *
 * @member {number} parameterCount
 *   Always ( parameterMap.size ). This is the total parameter count provided by this object
 * if init() successfully.
 *
 * @member {number} inChannels
 *   The input channel count of this neural network layer.
 *
 * @member {number} channelMultiplier
 *   Every input channel will be expanded into how many channels.
 *
 * @member {number} outChannels
 *   The output channel count of this neural network layer.
 *
 * @member {Float32Array} weightsModified
 *  The copied extracted values. They are copied from inputFloat32Array or fixedWeights, and then converted
 * to positive integer. Its length will be the same as parameterCountExtracted.
 */
class Params extends Base {

  /**
   *
   * The parameterMap should have at least:
   *
   * - Params.Keys.inChannels
   *   {number} There will be how many input channels. (Input channel count)
   *
   *
   * The parameterMap could also have (and any other custom key-value pairs):
   *
   * - Params.Keys.channelMultiplier
   *   {number} Every input channel will be expanded into how many channels.
   *     - If not null, it will be used instead of extracting from inputFloat32Array or fixedWeights. (By specifying)
   *     - If null, extracted from inputFloat32Array or fixedWeights. (By evolution)
   *
   * - Params.Keys.outChannels
   *   {number} There will be how many output channels. (Output channel count)
   *     - If Number.isFinite(), it will be used instead of extracting from inputFloat32Array or fixedWeights. (By specifying)
   *     - If Infinity (Number.POSITIVE_INFINITY), it will be ( inChannels * channelMultiplier ). (By channelMultiplier)
   *     - If null, extracted from inputFloat32Array or fixedWeights. (By evolution)
   *
   *
   * @param {Float32Array} inputFloat32Array
   *   A Float32Array whose values will be interpret as weights. It should have ( parameterCountExtractedAtLeast ) or
   * ( parameterCountExtractedAtLeast + 1 ) or ( parameterCountExtractedAtLeast + 2 ) elements according to the
   * value of channelMultiplier and outChannels.
   *
   * @param {number} byteOffsetBegin
   *   The position to start to decode from the inputFloat32Array. This is relative to the inputFloat32Array.buffer
   * (not to the inputFloat32Array.byteOffset).
   *
   * @param {Map} parameterMap
   *   Describe what parameters to be used or extracted. The keys of parameterMap will be viewed as parameter names.
   * The values of parameterMap will be viewed as parameter values. If the value of a [ key, value ] entry is null,
   * the parameter's value will be extracted from inputFloat32Array or fixedWeights (i.e. by evolution). Otherwise,
   * the parameter's value will be the value of the [ key, value ] entry (i.e. by specifying).
   *
   * @param {Float32Array|Array} fixedWeights
   *   If null, extract parameters from inputFloat32Array. If not null, extract parameters from it instead of
   * inputFloat32Array. When not null, it should have parameterCountExtracted elements (i.e. the count of null values
   * of parameterMap).
   *
   * @return {boolean} Return false, if initialization failed.
   *
   * @override
   */
  init( inputFloat32Array, byteOffsetBegin, parameterMap, fixedWeights = null ) {

    this.weightsModified = this.parameterMap = null; // So that distinguishable if re-initialization failed.

    if ( !parameterMap )
      return false;  // Don not know what parameters to be used or extracted.

    let inChannels = parameterMap.get( Params.Keys.inChannels );
    if ( !inChannels )
      return false;  // At least, there should be a (required) parameter (i.e. input channel count).

    this.parameterMap = new Map( parameterMap );  // Copy so that the original map will not be modified.

    // Collect what parameters should be extracted from input array (rather than use values in the parameterMap).
    // At the same time, its array index will also be recorded for extracting its value from array.
    let arrayIndexMap = new Map();
    {
      let i = 0;
      for ( let [ key, value ] of parameterMap ) {
        // A null value means it should be extracted from inputFloat32Array or fixedWeights (i.e. by evolution).
        if ( !value ) {
          arrayIndexMap.set( key, i ); // Record the index to this.weightsModified[].
          ++i;
        }
      }
    }

    let parameterCountExtracted = arrayIndexMap.size; // Determine how many parameters should be extracted from array.

    // If has fixedWeights, use it as priviledge input.
    let privilegeInput;
    if ( fixedWeights ) {
      if ( fixedWeights instanceof Float32Array )
        privilegeInput = fixedWeights;
      else
        privilegeInput = new Float32Array( fixedWeights );  // Convert to Float32Array.
    }

    // Extract a block of input array.
    let bInitOk = super.init( inputFloat32Array, byteOffsetBegin, privilegeInput, 0, [ parameterCountExtracted ] );

    if ( !bInitOk )
      return false;

    // Copy and convert to integer.
    //
    // Do not modify the original array data. When backtracking (to try another neural network layer
    // configuration), the original data is necessary.
    this.weightsModified = new Float32Array( this.weights );
    this.weightsModified.forEach( ( element, i, array ) => array[ i ] = Base.toPositiveInteger( element ) );

    // Extract (by evolution) values from array into map.
    for ( let [ key, arrayIndex ] of arrayIndexMap ) {
      this.parameterMap.set( key, this.weightsModified[ arrayIndex ] );
    }

    // If original parameterMap has output channel count and its value is infinity, its value should be depend
    // on channelMultiplier (i.e. by channelMultiplier).
    //
    // Usually, the embedding layer uses this behavior.
    let outChannelsOriginal = parameterMap.get( Params.Keys.outChannels );
    if ( outChannelsOriginal ) {
      if ( !Number.isFinite( outChannelsOriginal ) ) {
        let channelMultiplier = this.channelMultiplier;   // May be specified or extracted.
        let outChannels = inChannels * channelMultiplier;
        this.parameterMap.set( Params.Keys.outChannels, outChannels );
      } else {
        // Use the original value in parameterMap as output channel count (i.e. by specifying).
      }
    } else {
      // Either use the extracted value as output channel count (i.e. by evolution),
      // or there is no output channel count in fact.
    }

    return bInitOk;
  }

  get parameterCountExtracted() { return this.weightCount; }
  get parameterCount()          { return this.parameterMap.size; }

  // Most kinds of layers have these parameters.

  get inChannels()        { return this.parameterMap.get( Params.Keys.inChannels ); }
  get channelMultiplier() { return this.parameterMap.get( Params.Keys.channelMultiplier ); }
  get outChannels()       { return this.parameterMap.get( Params.Keys.outChannels ); }

  // Convolution layer have these parameters.

  get dilationHeight()    { return this.parameterMap.get( Params.Keys.dilationHeight ); }
  get dilationWidth()     { return this.parameterMap.get( Params.Keys.dilationWidth ); }
  get filterHeight()      { return this.parameterMap.get( Params.Keys.filterHeight ); }
  get filterWidth()       { return this.parameterMap.get( Params.Keys.filterWidth ); }
}

/**
 * Define parameter keys.
 *
 * They are (static) symbol objects used as keys of Params.init()'s parameterMap. They can be seen inside Map when
 * debugging, and are faster than string (or String object) when Map's key comparing.
 */
Params.Keys = class {
//   // Although they are functions, they should not be called. They are (static function) objects used as keys of
//   // Params.init()'s parameterMap. Using function object (rather than general object) so that the (function) name
//   // can be seen inside Map when debugging. Using function object (rather than string or String object) so that
//   // Map's key comparing is faster.
//   static inChannels()        {}
//   static channelMultiplier() {}
//   static outChannels()       {}
}

Params.Keys.inChannels =        Symbol("inChannels");
Params.Keys.channelMultiplier = Symbol("channelMultiplier");
Params.Keys.outChannels =       Symbol("outChannels");

Params.Keys.dilationHeight =    Symbol("dilationHeight");
Params.Keys.dilationWidth =     Symbol("dilationWidth");
Params.Keys.filterHeight =      Symbol("filterHeight");
Params.Keys.filterWidth =       Symbol("filterWidth");
<|endoftext|>


<commit_before>/*
 * DonkeySlider - a jQuery/Hammer based donkey slider
 * Author: Samuel Delesque <hello@samueldelesque.me>
 *
 *
 * Dependencies:
 *
 * jQuery - http://jquery.com/
 * jQuery.Hammer - http://hammerjs.github.io/
 * (jQuery.transform - http://louisremi.github.io/jquery.transform.js/  for old browser support)
 *
 *
 *  example usage:

	//HTML

Dummy text

Dummy text

Dummy text

	//JS
	$(document).ready(function() {
		window.myDonkey = new DonkeySlider(".slider-container");
	});

	//CSS (for the handles, optional)
	.handles{
		margin-top:10px;
		text-align: center;
	.handles b{
		display: inline-block;
		margin: 6px;
		width: 10px;
		height: 10px;
		background: #eee;
		position: relative;
		border-radius:10px;
	}
	.handles b.active:before{
		content: "";
		position: absolute;
		top: 2px;
		left: 2px;
		width: 6px;
		height: 6px;
		background: #000;
		border-radius:6px;
	}

 *
 */

(function(window,$,hammer) {
	if(!$)console.error("jQuery is required for Donkey.");
	if(!hammer)console.error("jQuery.hammer is required for Donkey.");
	$.fn.hammer = hammer;
	window.DonkeySlider = function(container,slider,slides,handles){
		var _ = {
			$el:null,
			w:{},
			activeSlide:null,
			slideWidth:240,
			slideMargin:20,
			offset:0,
			movement:0,
			direction:null,

			//slides fill 90% of window width
			showPercent:0.9,

			//if the slider has margins
			sliderMargin:20,

			init: function(container,slider,slides,handles){
				//construct the jQuery elements for later use
				_.$w = $(window);

				if(!container){console.error("Please pass a valid jQuery selector to DonkeySlider()");return;}
				_.$container = $(container);

				if(!slider){slider = ".slider"}
				_.$slider = $(slider,_.$container);

				if(!slides){slides = ".slide"}
				_.$slides = $(slides,_.$slider);

				if(!handles){handles = ".handles"}
				_.$handles = $(handles,_.$container);

				_.count = _.$slides.length;

				_.listen();
				_.setStyles();
				return _;
			},

			setStyles: function(){
				_.$container.css({
					overflow:"hidden",
					width:"100%",
					paddingRight:_.slideMargin,
					boxSizing:"border-box",
				});
				_.$slides.css({
					position:"relative",
					marginLeft:_.slideMargin,
					boxSizing:"border-box",
					float:"left",
				});
			},

			swiping: function(e){
				switch(e.type){
					case "dragleft":
					case "dragright":
						_.offset = Math.round(e.gesture.deltaX+_.movement);
						_.direction = e.type;
						_.$slider.css({
							transform:"translateX("+_.offset+"px)"
						});
					break;

					case "release":
						var pos = _.offset;
						if(_.direction == "dragleft"){pos-=100;}
						else{pos+=100;}
						var index = -1 * Math.round(pos/_.width()),
							min = -((_.count-1) * _.width()),
							max = 0;

						if(pos < min)index = _.count-1;
						if(pos > max)index = 0;
						_.showSlide(index);
					break;
				}
			},

			next: function(){
				var next = _.activeSlide + 1;
				if(next >= _.count)next=0;
				_.showSlide(next);
			},

			prev: function(){
				var prev = _.activeSlide - 1;
				if(prev <= 0)prev=_.count-1;
				_.showSlide(prev);
			},

			width: function(){
				return _.slideWidth + _.slideMargin;
			},

			showSlide: function(index){
				var offset = -index*_.width();
				if(index == _.count-1)offset += (1-_.showPercent) * _.slideWidth;
				_.$slider.animate({
					transform:"translateX("+Math.round(offset)+"px)"
				});
				_.movement = offset;
				_.activeSlide = index;

				_.$handles.find("b").removeClass("active").eq(index).addClass("active");
			},

			listen: function(){
				_.$w.resize(function(){
					_.slideWidth = Math.round((_.$w.width()-(_.sliderMargin * 2)) * _.showPercent);
					_.$slides.css("width",_.slideWidth);
					_.$slider.css({
						width: (_.slideWidth+_.slideMargin) * _.count
					});
				});
				_.$w.trigger("resize");

				_.$slider.hammer({drag_lock_to_axis: true}).on("release dragleft dragright swipeleft swiperight", _.swiping);
				_.$slider.trigger("release");

				for(i=0;i<_.count;i++){_.$handles.append("")}
				_.$handles.find("b").on("click",function(e){_.showSlide($(this).index())}).eq(0).addClass("active");
			}
		}
		return _.init(container,slider,slides,handles);
	}
})(window,jQuery,jQuery.fn.hammer);
<commit_msg>Fixed some margin issue when showPercent == 100<commit_after>/*
 * DonkeySlider - a jQuery/Hammer based donkey slider
 * Author: Samuel Delesque <hello@samueldelesque.me>
 *
 *
 * Dependencies:
 *
 * jQuery - http://jquery.com/
 * jQuery.Hammer - http://hammerjs.github.io/
 * (jQuery.transform - http://louisremi.github.io/jquery.transform.js/  for old browser support)
 *
 *
 *  example usage:

	//HTML

Dummy text

Dummy text

Dummy text

	//JS
	$(document).ready(function() {
		window.myDonkey = new DonkeySlider(".slider-container");
	});

	//CSS (for the handles, optional)
	.handles{
		margin-top:10px;
		text-align: center;
	.handles b{
		display: inline-block;
		margin: 6px;
		width: 10px;
		height: 10px;
		background: #eee;
		position: relative;
		border-radius:10px;
	}
	.handles b.active:before{
		content: "";
		position: absolute;
		top: 2px;
		left: 2px;
		width: 6px;
		height: 6px;
		background: #000;
		border-radius:6px;
	}

 *
 */

(function(window,$,hammer) {
	if(!$)console.error("jQuery is required for Donkey.");
	if(!hammer)console.error("jQuery.hammer is required for Donkey.");
	$.fn.hammer = hammer;
	window.DonkeySlider = function(container,slider,slides,handles){
		var _ = {
			$el:null,
			w:{},
			activeSlide:null,
			slideWidth:240,
			offset:0,
			movement:0,
			direction:null,

			//% of window width
			showPercent:100,

			//if the slider has margins
			sliderMargin:30,

			//if the slides have margins
			slidesMargin:10,

			init: function(container,slider,slides,handles){
				//construct the jQuery elements for later use
				_.$w = $(window);

				if(!container){console.error("Please pass a valid jQuery selector to DonkeySlider()");return;}
				_.$container = $(container);

				if(!slider){slider = ".slider"}
				_.$slider = $(slider,_.$container);

				if(!slides){slides = ".slide"}
				_.$slides = $(slides,_.$slider);

				if(!handles){handles = ".handles"}
				_.$handles = $(handles,_.$container);

				_.count = _.$slides.length;

				_.listen();
				_.setStyles();
				return _;
			},

			setStyles: function(){
				_.$container.css({
					overflow:"hidden",
					width:"100%",
					padding:"0 "+_.sliderMargin+"px",
					boxSizing:"border-box",
				});
				_.$slides.css({
					position:"relative",
					marginLeft:_.slidesMargin,
					boxSizing:"border-box",
					float:"left",
				}).eq(0).css("margin-left",0);
			},

			swiping: function(e){
				switch(e.type){
					case "dragleft":
					case "dragright":
						_.offset = Math.round(e.gesture.deltaX+_.movement);
						_.direction = e.type;
						_.$slider.css({
							transform:"translateX("+_.offset+"px)"
						});
					break;

					case "release":
						var pos = _.offset;
						if(_.direction == "dragleft"){pos-=100;}
						else{pos+=100;}
						var index = -1 * Math.round(pos/_.width()),
							min = -((_.count-1) * _.width()),
							max = 0;

						if(pos < min)index = _.count-1;
						if(pos > max)index = 0;
						_.showSlide(index);
					break;
				}
			},

			next: function(){
				var next = _.activeSlide + 1;
				if(next >= _.count)next=0;
				_.showSlide(next);
			},

			prev: function(){
				var prev = _.activeSlide - 1;
				if(prev <= 0)prev=_.count-1;
				_.showSlide(prev);
			},

			width: function(){
				return _.slideWidth + _.slidesMargin;
			},

			showSlide: function(index){
				var offset = -index*_.width();
				if(_.showPercent!==100){
					var correct = (1-_.showPercent/100) * _.slideWidth + (2 * _.sliderMargin) - _.slidesMargin;
					if(index == _.count-1)offset += correct;
				}
				_.$slider.animate({
					transform:"translateX("+Math.round(offset)+"px)"
				});
				_.movement = offset;
				_.activeSlide = index;

				_.$handles.find("b").removeClass("active").eq(index).addClass("active");
			},

			listen: function(){
				_.$w.resize(function(){
					_.slideWidth = Math.round((_.$w.width()-(_.sliderMargin * 2)) * _.showPercent/100);
					_.$slides.css("width",_.slideWidth);
					_.$slider.css({
						width: (_.slideWidth+_.slidesMargin) * _.count + _.sliderMargin * 2
					});
				});
				_.$w.trigger("resize");

				_.$slider.hammer({drag_lock_to_axis: true}).on("release dragleft dragright swipeleft swiperight", _.swiping);
				_.$slider.trigger("release");

				for(i=0;i<_.count;i++){_.$handles.append("")}
				_.$handles.find("b").on("click",function(e){_.showSlide($(this).index())}).eq(0).addClass("active");
			}
		}
		return _.init(container,slider,slides,handles);
	}
})(window,jQuery,jQuery.fn.hammer);
<|endoftext|>


<commit_before><commit_msg>Okay, added draglistener.js, really, this time.<commit_after>
// author: Cesar A. Longoria II
// copyright (under MIT?): 2014-2015

/**
	key: stores these in a table, so a key makes later removal convenient.

	mousedown: event on mouse down.

	drag: function(e,dragData)
		- e: mousemove event
		- dragData
				. [key1,key2,...]: arrays of all offsets between element and document.
				. timing: array of times mousemove was called, in epoch millis.
				. length: function returning current length of offset data arrays.
				. diff: function(a,b,index) returning subtraction of offset array data
				    at index between nodes stored under dragData as keys a and b.
				. first: function(a,b) performing diff with index = 0.
				. last: function(a,b) performing diff with index = dragData.length-1.

	mouseup: event on mouse up.

	relatedNodes: nodes whichs' offsets from document to track and store under
	  their given key names in the dragData object passed to the drag function.

	params: eh... extraneous options and parameters...
		- selection: setting params.selection to true will allow the default
		    mousedown behavior.  Otherwise, the actual mousedown listener will
		    always end with { e.preventDefault(); return true; }.
*/

Element.prototype.addDragListener =
	function(key,mousedown,drag,mouseup,relatedNodes,params)
{
	if (!this._dragEvents)
		this._dragEvents = {};

	var startFunc;
	var dragFunc;
	var endFunc;

	var offsetArrays = {};
	var timingArray = [];

	for (var i in relatedNodes)
		offsetArrays[i] = [];

	var dragging = false;

	var self = this;

	var trueOffset = function(node)
	{
		var n = node;
		var off = {x:0,y:0};
		while (n.offsetParent)
		{
			off.x += parseFloat(n.offsetLeft);
			off.y += parseFloat(n.offsetTop);
			n = n.offsetParent;
		}
		return off;
	};

	this.dragging = function(){return dragging};

	this.addEventListener('mousedown',startFunc=function(e)
	{
		dragging = true;

		offsetArrays = {mouse:[]};
		timingArray = [];

		// NOTE: Can't seem to decide which key variable name to use...
		for (var k in relatedNodes)
			offsetArrays[k] = [];

		var pushCurrent = function(e)
		{
			for (var p in relatedNodes)
				offsetArrays[p].push(trueOffset(relatedNodes[p]));

			offsetArrays.mouse.push({
				x:parseFloat(e.pageX) + parseFloat(document.body.scrollLeft),
				y:parseFloat(e.pageY) + parseFloat(document.body.scrollTop)
			});

			timingArray.push(new Date().getTime());
		};

		document.addEventListener('mousemove',dragFunc=function(e)
		{
			pushCurrent(e);

			var dragData = {
				length:function(){return offsetArrays.mouse.length},
				diff:function(a,b,index)
				{
					return {
						x:this[a][index].x-this[b][index].x,
						y:this[a][index].y-this[b][index].y
					};
				},
				first:function(a,b){return this.diff(a,b,0)},
				last:function(a,b){return this.diff(a,b,this.length()-1)}
			};

			// NOTE: Oh boy.  Full copy of all arrays *every mousemove*.  This needs
			//   to be made into a read-only Array accessor of sorts.  I'll leave it
			//   at this, for now, though.
			for (var p in offsetArrays)
				dragData[p] = offsetArrays[p].slice(0);
			dragData.timing = timingArray.slice(0);

			drag(e,dragData);
		});

		document.addEventListener('mouseup',endFunc=function endFunc(e)
		{
			mouseup(e);

			dragging = false;
			document.removeEventListener('mousemove',dragFunc);
			document.removeEventListener('mouseup',endFunc);
		});

		self._dragEvents[key].dragFunc = dragFunc;
		self._dragEvents[key].endFunc = endFunc;

		// Run the mousedown function.
		pushCurrent(e);
		mousedown(e);

		// Prevent highlight selection, by default.
		if (!params || !params.selection)
		{
			e.preventDefault();
			return false;
		}
	});

	this._dragEvents[key] = {startFunc:startFunc};
};

Element.prototype.removeDragListener = function(key)
{
	var a = this._dragEvents[key];
	this.removeEventListener('mousedown',a.startFunc);
	document.removeEventListener('mousemove',a.dragFunc);
	document.removeEventListener('mouseup',a.endFunc);
}

<|endoftext|>


<commit_before>/* global document */
(function() {
    'use strict';

    function Controller(
      $timeout,
      $scope,
      LanguageService
    ) {
      var $ctrl = this;
      var formElements = ['INPUT', 'SELECT', 'TEXTAREA', 'MD-SELECT'];
      $ctrl.currentLanguage = LanguageService.getCurrentInstantly();
      $ctrl.currentPackageIndex = null;
      $ctrl.currentFocusElement = null;
      $ctrl.focus = false;
      $ctrl.packageElement = document.getElementById('packages');
      $ctrl.dataPackageList = {
        dataPackage: {
          type: 'dataPackage',
          en: 'FDZ-DZHW Datapackage',
          de: 'FDZ-DZHW Datenpaket'
        },
        externalDataPackage: {
          type: 'externalDataPackage',
          en: 'External Data Package',
          de: 'Externes Datenpaket'
        },
        customDataPackage: {
          type: 'customDataPackage',
          en: 'Custom Data Package',
          de: 'Benutzerdefiniertes Datenpaket'
        }
      };

      $ctrl.$onInit = function() {
        $ctrl.packages = $ctrl.packages || [];
      };

      $ctrl.addPackage = function() {
        $ctrl.packages.push({
          type: ''
        });
      };

      $ctrl.deletePackage = function(index) {
        $ctrl.packages.splice(index, 1);
        $ctrl.currentForm.$setDirty();
      };

      $ctrl.move = function(dir) {
        var move = {
          up: -1,
          down: +1
        };
        $ctrl.packages
          .splice($ctrl.currentPackageIndex + parseInt(move[dir]), 0,
            $ctrl.packages.splice($ctrl.currentPackageIndex, 1)[0]);
        $ctrl.currentPackageIndex = $ctrl.currentPackageIndex + parseInt(
          move[dir]
        );
        $timeout(function() {
          document.getElementsByName(
            angular.element($ctrl.currentFocusElement)
              .attr('name').split('_')[0] + '_' + $ctrl.currentPackageIndex)[0]
            .focus();
        }, 1000);

        $ctrl.currentForm.$setDirty();
      };

      $scope.$watch(function() {
        return document.activeElement;
      }, function(value) {
        if ($ctrl.packageElement.contains(value) && formElements
          .indexOf(value.tagName) > -1) {
          var dataSources = document.getElementById('dataSources');
          if (!dataSources.contains(value)) {
            $ctrl.focus = true;
            $ctrl.currentFocusElement = value;
            $ctrl.currentPackageIndex = parseInt(
              angular.element(value).attr('name').slice(-1)
            );
          }
        } else {
          $ctrl.focus = false;
        }
      });
    }

    angular
      .module('metadatamanagementApp')
      .controller('listDataPackageController', Controller);
  }

)
();
<commit_msg>#2978 Fix: after restoring a version with no analysisDataPackage I cannot add one<commit_after>/* global document */
(function() {
    'use strict';

    function Controller(
      $timeout,
      $scope,
      LanguageService
    ) {
      var $ctrl = this;
      var formElements = ['INPUT', 'SELECT', 'TEXTAREA'];
      $ctrl.currentLanguage = LanguageService.getCurrentInstantly();
      $ctrl.currentPackageIndex = null;
      $ctrl.currentFocusElement = null;
      $ctrl.focus = false;
      $ctrl.packageElement = document.getElementById('packages');
      $ctrl.dataPackageList = {
        dataPackage: {
          type: 'dataPackage',
          en: 'FDZ-DZHW Datapackage',
          de: 'FDZ-DZHW Datenpaket'
        },
        externalDataPackage: {
          type: 'externalDataPackage',
          en: 'External Data Package',
          de: 'Externes Datenpaket'
        },
        customDataPackage: {
          type: 'customDataPackage',
          en: 'Custom Data Package',
          de: 'Benutzerdefiniertes Datenpaket'
        }
      };

      $ctrl.$onInit = function() {
        $ctrl.packages = $ctrl.packages || [];
      };

      $ctrl.addPackage = function() {
        $ctrl.packages = $ctrl.packages || [];
        $ctrl.packages.push({
          type: ''
        });
      };

      $ctrl.deletePackage = function(index) {
        $ctrl.packages.splice(index, 1);
        $ctrl.currentForm.$setDirty();
      };

      $ctrl.move = function(dir) {
        var move = {
          up: -1,
          down: +1
        };
        $ctrl.packages
          .splice($ctrl.currentPackageIndex + parseInt(move[dir]), 0,
            $ctrl.packages.splice($ctrl.currentPackageIndex, 1)[0]);
        $ctrl.currentPackageIndex = $ctrl.currentPackageIndex + parseInt(
          move[dir]
        );
        $timeout(function() {
          document.getElementsByName(
            angular.element($ctrl.currentFocusElement)
              .attr('name').split('_')[0] + '_' + $ctrl.currentPackageIndex)[0]
            .focus();
        }, 1000);

        $ctrl.currentForm.$setDirty();
      };

      $scope.$watch(function() {
        return document.activeElement;
      }, function(value) {
        if ($ctrl.packageElement.contains(value) && formElements
          .indexOf(value.tagName) > -1) {
          console.log('package: ' + value.tagName);
          var dataSources = document.getElementById('dataSources');
          if (!dataSources.contains(value)) {
            $ctrl.focus = true;
            $ctrl.currentFocusElement = value;
            $ctrl.currentPackageIndex = parseInt(
              angular.element(value).attr('name').slice(-1)
            );
          }
        } else {
          $ctrl.focus = false;
        }
      });
    }

    angular
      .module('metadatamanagementApp')
      .controller('listDataPackageController', Controller);
  }

)
();
<|endoftext|>