<commit_before>/* Copyright (c) 2012-2015 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */
/* global define, requirejs, _  */

var isFirefox = document.URL.indexOf( 'resource://' ) === 0;
var isFirefoxOS = document.URL.indexOf( 'app://' ) === 0;
var isChrome = document.URL.indexOf( 'chrome-extension://' ) === 0;
var isNode = false;
var isCordovaAndroid = document.URL.indexOf( 'file:///android_asset' ) === 0;
var isCordovaiOS = navigator.isCordovaApp == true;
var isCordova = isCordovaAndroid  == true || isCordovaiOS == true;
var isWeb = document.URL.indexOf( 'http' ) === 0;
var isOSX = navigator.appVersion.indexOf("Mac")!==-1;
var isWin = navigator.appVersion.indexOf("Win")!==-1;

/**
 * The main loader module for the application
 * @name TSLoader
 */
(function () {
  // the value of this var is replaced to "true" by the build script
  var PRODUCTION = "@@PRODUCTION";
  var PRO = "@@PROVERSION";

  // Disabling all output to console in production mode
  if (PRODUCTION == "true") {
    console = console || {};
    console.log = function(){};
    console.warn = function(){};
    console.time = function(){};
    console.timeEnd = function(){};
    //console.error = function(){};
  }

  // Check for running in node-webkit
  try {
    require('nw.gui');
    isNode = true;
  } catch(e) {
    console.log("node-webkit not found!");
  }

  var PRO_JS = "pro/js/pro.api";
  if(PRO.indexOf("@@PROVERS") == 0 || PRO == "false") { PRO_JS = 'js/pro'; }

  // Setting up the IO functionality according to the platform
  var IO_JS = "web/web.api";
  if( isFirefox ) {
    IO_JS = "mozilla/mozilla.api";
    PRO_JS = 'js/pro';
  } else if ( isChrome ) {
    IO_JS = "chromium/chrome.api";
    PRO_JS = 'js/pro';
  } else if (isNode){
    IO_JS = "node-webkit/node-webkit.api";
  } else if (isCordova){
    IO_JS = "cordova/cordova.api";
  } else if (isWeb){
    IO_JS = "web/web.api";
  }

  console.log("Loading Loader - Firefox: "+isFirefox+" | ChromeExt: "+isChrome+" | Node: "+isNode+" | Cordova: "+isCordova+" | Web: "+isWeb+" | isWin: "+isWin);

  requirejs.config({
    map: {
      '*': {
        'css':   'libs/require-css/css.min',
        'text':  'libs/requiretext/index'
      }
    },
    paths: {
      jquery:                 'libs/jquery/dist/jquery.min',
      jqueryui:               'libs/jqueryui/jquery-ui.min',
//      jqueryuidraggable:      'libs/jqueryui/ui/draggable',
//      jqueryuidroppable:      'libs/jqueryui/ui/droppable',
//      jqueryuimouse:          'libs/jqueryui/ui/mouse',
//      jqueryuiposition:       'libs/jqueryui/ui/position',
//      jqueryuiselectable:     'libs/jqueryui/ui/selectable',
//      jqueryuisortable:       'libs/jqueryui/ui/sortable',
//      jqueryuiwidget:         'libs/jqueryui/ui/widget',

      bootstrap:              'libs/bootstrap/dist/js/bootstrap.min',
      bootstrap3xeditable:    'libs/x-editable/dist/bootstrap3-editable/js/bootstrap-editable.min',
      bootstrapvalidator:     'libs/bootstrap-validator/dist/validator.min',
      jquerysimplecolorpicker:'libs/jquery-simplecolorpicker/jquery.simplecolorpicker',
      underscore:             'libs/underscore/index',
      d3:                     'libs/d3/d3.min',
      i18next:                'libs/i18next/i18next.amd.withJQuery.min',
      mousetrap:              'libs/mousetrap/mousetrap.min',
      mousetrapgb:            'libs/mousetrap/plugins/global-bind/mousetrap-global-bind.min',
      select2:                'libs/select2/select2.min',
      hammerjs:               'libs/hammerjs/hammer.min',
      jqueryhammerjs:         'libs/jquery.hammer.js/jquery.hammer',
      handlebarsjs:           'libs/handlebars/handlebars.min',
      pdfjs:                  'libs/pdfjs/build/pdf',
      webdavlib:              'web/webdavlib',
      jszip:                  'libs/jszip/dist/jszip.min',
      hopscotch:              'libs/hopscotch/dist/js/hopscotch.min',
      noty:                   'libs/noty/js/noty/packaged/jquery.noty.packaged.min',

      tscore:                 'js/core.api',
      tssetting:              'js/settings.api',
      tssettingsdefault:      'js/settings.default',
      tsoptions:              'js/options.ui',
      tspersmanager:          'js/perspective.manager',
      tstagutils:             'js/tagutils',
      tssearch:               'js/search',
      tsfileopener:           'js/fileopener',
      tstagsui:               'js/tags.ui',
      tsdirectoriesui:        'js/directories.ui',
      tscoreui:               'js/core.ui',
      tspostioapi:            'js/postioapi',
      tsdirectorybrowser:     'js/directorybrowser',
      tsutils:                'js/utils',
      tsioutils:              'js/ioutils',
      tsmeta:                 'js/meta',
      tsgettingstarted:       'js/gettingstarted',
      tsextapi:               'js/ext.api',
      tsextmanager:           'js/extension.manager',
      tsioapi:                 IO_JS,
      tspro:                   PRO_JS
    },
    shim: {
      'underscore':               { exports: '_' },
      'bootstrap':                { deps: ['jquery'] },
      'jqueryui':                 { deps: ['jquery'] },
//      'jqueryuiwidget':           { deps: ['jqueryui'] },
//      'jqueryuiposition':         { deps: ['jqueryui'] },
//      'jqueryuimouse':            { deps: ['jqueryui','jqueryuiwidget'] },
//      'jqueryuiselectable':       { deps: ['jqueryui','jqueryuiwidget','jqueryuimouse'] },
//      'jqueryuisortable':         { deps: ['jqueryui','jqueryuiwidget','jqueryuimouse'] },
//      'jqueryuidroppable':        { deps: ['jqueryui','jqueryuimouse','jqueryuidraggable'] },
//      'jqueryuidraggable':        { deps: ['jqueryui','jqueryuimouse'] },
      'jquerysimplecolorpicker':  { deps: ['jquery','bootstrap'] },
      'bootstrap3xeditable':      { deps: ['jquery','jqueryui','bootstrap'] },
      'bootstrapvalidator':       { deps: ['jquery','bootstrap'] },
      'i18next':                  { deps: ['jquery'] },
      'select2':                  { deps: ['jquery'] },
      'hammerjs':                 { deps: ['jquery'] },
      'jqueryhammerjs':           { deps: ['hammerjs'] },
      'mousetrapgb':              { deps: ['mousetrap'] },
      'tscore':                   { deps: [
        'jquery',
        'jqueryui',
//        'jqueryuimouse',
//        'jqueryuidraggable',
//        'jqueryuidroppable',
//        'jqueryuiposition',
//        'jqueryuiselectable',
//        'jqueryuisortable',
        'hammerjs',
        'jqueryhammerjs',
        'bootstrap',
        'bootstrap3xeditable',
        'bootstrapvalidator',
        'jquerysimplecolorpicker',
        'i18next',
        'mousetrap',
        'mousetrapgb',
        'select2',
        'handlebarsjs',
        'tssettingsdefault',
        'noty',
    ] }
    }
  });

  define(function (require) {
    requirejs(['tscore','underscore'], function (core) {
      if(isCordova) {
        require(["cordova.js"]);
      } else {
        core.initApp();
      }
    });
  });

})();
<commit_msg>preparing migration to nw.js 0.13<commit_after>/* Copyright (c) 2012-2015 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */
/* global define, requirejs, _  */

var isFirefox = document.URL.indexOf( 'resource://' ) === 0;
var isFirefoxOS = document.URL.indexOf( 'app://' ) === 0;
var isChrome = document.URL.indexOf( 'chrome-extension://' ) === 0;
var isNode = false;
var isCordovaAndroid = document.URL.indexOf( 'file:///android_asset' ) === 0;
var isCordovaiOS = navigator.isCordovaApp == true;
var isCordova = isCordovaAndroid  == true || isCordovaiOS == true;
var isWeb = document.URL.indexOf( 'http' ) === 0;
var isOSX = navigator.appVersion.indexOf("Mac")!==-1;
var isWin = navigator.appVersion.indexOf("Win")!==-1;

/**
 * The main loader module for the application
 * @name TSLoader
 */
(function () {
  // the value of this var is replaced to "true" by the build script
  var PRODUCTION = "@@PRODUCTION";
  var PRO = "@@PROVERSION";

  // Disabling all output to console in production mode
  if (PRODUCTION == "true") {
    console = console || {};
    console.log = function(){};
    console.warn = function(){};
    console.time = function(){};
    console.timeEnd = function(){};
    //console.error = function(){};
  }

  // Check for running in node-webkit
  try {
    require('nw.gui');
    isNode = true;
  } catch(e) {
    console.log("node-webkit not found!");
  }

  var PRO_JS = "pro/js/pro.api";
  if(PRO.indexOf("@@PROVERS") == 0 || PRO == "false") { PRO_JS = 'js/pro'; }

  // Setting up the IO functionality according to the platform
  var IO_JS = "web/web.api";
  if( isFirefox ) {
    IO_JS = "mozilla/mozilla.api";
    PRO_JS = 'js/pro';
  } else if ( isChrome && !isNode ) {
    isNode = false;
    IO_JS = "chromium/chrome.api";
    PRO_JS = 'js/pro';
  } else if (isNode){
    isChrome = false;
    IO_JS = "node-webkit/node-webkit.api";
  } else if (isCordova){
    IO_JS = "cordova/cordova.api";
  } else if (isWeb){
    IO_JS = "web/web.api";
  }

  console.log("Loading Loader - Firefox: "+isFirefox+" | ChromeExt: "+isChrome+" | Node: "+isNode+" | Cordova: "+isCordova+" | Web: "+isWeb+" | isWin: "+isWin);

  requirejs.config({
    map: {
      '*': {
        'css':   'libs/require-css/css.min',
        'text':  'libs/requiretext/index'
      }
    },
    paths: {
      jquery:                 'libs/jquery/dist/jquery.min',
      jqueryui:               'libs/jqueryui/jquery-ui.min',
//      jqueryuidraggable:      'libs/jqueryui/ui/draggable',
//      jqueryuidroppable:      'libs/jqueryui/ui/droppable',
//      jqueryuimouse:          'libs/jqueryui/ui/mouse',
//      jqueryuiposition:       'libs/jqueryui/ui/position',
//      jqueryuiselectable:     'libs/jqueryui/ui/selectable',
//      jqueryuisortable:       'libs/jqueryui/ui/sortable',
//      jqueryuiwidget:         'libs/jqueryui/ui/widget',

      bootstrap:              'libs/bootstrap/dist/js/bootstrap.min',
      bootstrap3xeditable:    'libs/x-editable/dist/bootstrap3-editable/js/bootstrap-editable.min',
      bootstrapvalidator:     'libs/bootstrap-validator/dist/validator.min',
      jquerysimplecolorpicker:'libs/jquery-simplecolorpicker/jquery.simplecolorpicker',
      underscore:             'libs/underscore/index',
      d3:                     'libs/d3/d3.min',
      i18next:                'libs/i18next/i18next.amd.withJQuery.min',
      mousetrap:              'libs/mousetrap/mousetrap.min',
      mousetrapgb:            'libs/mousetrap/plugins/global-bind/mousetrap-global-bind.min',
      select2:                'libs/select2/select2.min',
      hammerjs:               'libs/hammerjs/hammer.min',
      jqueryhammerjs:         'libs/jquery.hammer.js/jquery.hammer',
      handlebarsjs:           'libs/handlebars/handlebars.min',
      pdfjs:                  'libs/pdfjs/build/pdf',
      webdavlib:              'web/webdavlib',
      jszip:                  'libs/jszip/dist/jszip.min',
      hopscotch:              'libs/hopscotch/dist/js/hopscotch.min',
      noty:                   'libs/noty/js/noty/packaged/jquery.noty.packaged.min',

      tscore:                 'js/core.api',
      tssetting:              'js/settings.api',
      tssettingsdefault:      'js/settings.default',
      tsoptions:              'js/options.ui',
      tspersmanager:          'js/perspective.manager',
      tstagutils:             'js/tagutils',
      tssearch:               'js/search',
      tsfileopener:           'js/fileopener',
      tstagsui:               'js/tags.ui',
      tsdirectoriesui:        'js/directories.ui',
      tscoreui:               'js/core.ui',
      tspostioapi:            'js/postioapi',
      tsdirectorybrowser:     'js/directorybrowser',
      tsutils:                'js/utils',
      tsioutils:              'js/ioutils',
      tsmeta:                 'js/meta',
      tsgettingstarted:       'js/gettingstarted',
      tsextapi:               'js/ext.api',
      tsextmanager:           'js/extension.manager',
      tsioapi:                 IO_JS,
      tspro:                   PRO_JS
    },
    shim: {
      'underscore':               { exports: '_' },
      'bootstrap':                { deps: ['jquery'] },
      'jqueryui':                 { deps: ['jquery'] },
//      'jqueryuiwidget':           { deps: ['jqueryui'] },
//      'jqueryuiposition':         { deps: ['jqueryui'] },
//      'jqueryuimouse':            { deps: ['jqueryui','jqueryuiwidget'] },
//      'jqueryuiselectable':       { deps: ['jqueryui','jqueryuiwidget','jqueryuimouse'] },
//      'jqueryuisortable':         { deps: ['jqueryui','jqueryuiwidget','jqueryuimouse'] },
//      'jqueryuidroppable':        { deps: ['jqueryui','jqueryuimouse','jqueryuidraggable'] },
//      'jqueryuidraggable':        { deps: ['jqueryui','jqueryuimouse'] },
      'jquerysimplecolorpicker':  { deps: ['jquery','bootstrap'] },
      'bootstrap3xeditable':      { deps: ['jquery','jqueryui','bootstrap'] },
      'bootstrapvalidator':       { deps: ['jquery','bootstrap'] },
      'i18next':                  { deps: ['jquery'] },
      'select2':                  { deps: ['jquery'] },
      'hammerjs':                 { deps: ['jquery'] },
      'jqueryhammerjs':           { deps: ['hammerjs'] },
      'mousetrapgb':              { deps: ['mousetrap'] },
      'tscore':                   { deps: [
        'jquery',
        'jqueryui',
//        'jqueryuimouse',
//        'jqueryuidraggable',
//        'jqueryuidroppable',
//        'jqueryuiposition',
//        'jqueryuiselectable',
//        'jqueryuisortable',
        'hammerjs',
        'jqueryhammerjs',
        'bootstrap',
        'bootstrap3xeditable',
        'bootstrapvalidator',
        'jquerysimplecolorpicker',
        'i18next',
        'mousetrap',
        'mousetrapgb',
        'select2',
        'handlebarsjs',
        'tssettingsdefault',
        'noty',
    ] }
    }
  });

  define(function (require) {
    requirejs(['tscore','underscore'], function (core) {
      if(isCordova) {
        require(["cordova.js"]);
      } else {
        core.initApp();
      }
    });
  });

})();
<|endoftext|>


<commit_before>// core frameworks
var io = require('socket.io')(server);
var _ = require('underscore');
var repo = require('./repository');

function getAllUsers(roomkey){
  // console.log("printing people in da room")
  // console.log(io.sockets.adapter.rooms[roomkey])
  // var clients = io.clients(roomkey);
  // return clients;
  // THIS WILL BE CALLED FROM THE METHODS FROM REDIS
}

// sockets!
io.on('connection', function(socket){
  socket.on("joinRoom", function(data){
    socket.join(data.roomkey, function(error){
      repo.createUser(data.username, data.roomkey);
      io.to(data.roomkey).emit("message", {username: data.username, roomkey: data.roomkey});
      var payload = repo.getUsers(data.roomkey);
      console.log(payload);
      if(error){console.log("error:" + error);}
    });
  });

  socket.on("dealCards", function(data){
    // stubbed to only work on one person
    socket.emit("updateHand", randomHand(5));
  });

});

// function randomHand(quantity){
//   var newHand = []
//   for(var i=0; i < quantity; i++ ){
//     newHand.push(randomCard())
//   }
//   return newHand;
// }

// function randomCard(){
//   var suits = ["hearts", "clubs", "spades", "diamonds"];
//   var values = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"];
//   return {suit:_.sample(suits), value: _.sample(values)};
// }<commit_msg>working on sending list of users<commit_after>// core frameworks
var io = require('socket.io')(server);
var _ = require('underscore');
var repo = require('./repository');

function getAllUsers(roomkey){
  // console.log("printing people in da room")
  // console.log(io.sockets.adapter.rooms[roomkey])
  // var clients = io.clients(roomkey);
  // return clients;
  // THIS WILL BE CALLED FROM THE METHODS FROM REDIS
}

// sockets!
io.on('connection', function(socket){
  socket.on("joinRoom", function(data){
    socket.join(data.roomkey, function(error){
      repo.createUser(data.username, data.roomkey);
      io.to(data.roomkey).emit("message", {username: data.username, roomkey: data.roomkey});
      if(error){console.log("error:" + error);}
    });
  });

  socket.on("dealCards", function(data){
    // stubbed to only work on one person
    socket.emit("updateHand", randomHand(5));
  });

});

// function randomHand(quantity){
//   var newHand = []
//   for(var i=0; i < quantity; i++ ){
//     newHand.push(randomCard())
//   }
//   return newHand;
// }

// function randomCard(){
//   var suits = ["hearts", "clubs", "spades", "diamonds"];
//   var values = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"];
//   return {suit:_.sample(suits), value: _.sample(values)};
// }<|endoftext|>


<commit_before>
/**
 * on (EventHandler)
 * @param  {Any} ...args
 * @return {Function}
 */
export default function on(...args) {

	if(!args.length){
		throw new Error('Please pass an event type e.g "click"');
	}

	return (target, method, descriptor) => {

		// register events
		on.helper.registerEvent(target, ...args, method, descriptor.value);

	}
}

/*****************************************
 * ########## Decorator Helper ###########
 *****************************************/

// define namespace
on.helper = {};

/**
 * Helper for registering events
 * @param  {String} event
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerEvent = (target, eventDomain, method, callback = function(){}) => {

	// define namespaces
	on.helper.registerNamespaces(target);

	if(target.$appDecorators.on.events[method]) {
		throw new Error(`The method: "${method}" already exists!`);
	}

	// prepare event domain
	let [ event, delegateSelector ] = on.helper.prepareEventDomain(eventDomain);

	// define events
	target.$appDecorators.on.events[eventDomain] = callback;

	return target;

};

/**
 * Prepare eventDomain
 * @param  {String} eventDomain
 * @return {Array}
 */
on.helper.prepareEventDomain = (eventDomain) => {

	let splitedEventDomain = eventDomain.split(' ');
	let event = splitedEventDomain[0];
	let delegateSelector = undefined;
	if(splitedEventDomain[1]){
		delegateSelector = splitedEventDomain.splice(1).join(' ');
	}

	return [ event, delegateSelector ];

}

/**
 * Register on created callback
 * @param  {Object} target
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerOnCreatedCallback = (target, callback) => {

	// define $onCreated callbacks
	if(!target.$onCreated) {
		target.$onCreated = [];
	}

	// init render engine
	target.$onCreated.push(callback);

	return target;

};

/**
 * Register on Detached callback
 * @param  {Object} target
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerOnDeatchedCallback = (target, callback) => {

	// define $onCreated callbacks
	if(!target.$onDetached) {
		target.$Detached = [];
	}

	// init render engine
	target.$onDetached.push(callback);

	return target;

};

/**
 * Register namespace of on decorator
 * @param  {Function|Objet} target
 * @return {Function} target
 */
on.helper.registerNamespaces = (target) => {

	// if namespace already exists do nothing
	if(target.$appDecorators && target.$appDecorators.on){
		return target;
	}

	// define namespace
	target.$appDecorators = {
		on: {
			events: {},
		},
	};

	return target;
};
<commit_msg>src/decorators/on.js: changed object structure of target.$appDecorators.on<commit_after>
/**
 * on (EventHandler)
 * @param  {Any} ...args
 * @return {Function}
 */
export default function on(...args) {

	if(!args.length){
		throw new Error('Please pass an event type e.g "click"');
	}

	return (target, method, descriptor) => {

		// register events
		on.helper.registerEvent(target, ...args, method, descriptor.value);

	}
}

/*****************************************
 * ########## Decorator Helper ###########
 *****************************************/

// define namespace
on.helper = {};

/**
 * Helper for registering events
 * @param  {String} event
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerEvent = (target, eventDomain, method, callback = function(){}) => {

	// define namespaces
	on.helper.registerNamespaces(target);

	if(target.$appDecorators.on.events[eventDomain]) {
		throw new Error(`The method: "${method}" already exists!`);
	}

	// define events
	target.$appDecorators.on.events[eventDomain] = callback;

	return target;

};

/**
 * Prepare eventDomain
 * @param  {String} eventDomain
 * @return {Array}
 */
on.helper.prepareEventDomain = (eventDomain) => {

	let splitedEventDomain = eventDomain.split(' ');
	let event = splitedEventDomain[0];
	let delegateSelector = undefined;
	if(splitedEventDomain[1]){
		delegateSelector = splitedEventDomain.splice(1).join(' ');
	}

	return [ event, delegateSelector ];

}

/**
 * Register on created callback
 * @param  {Object} target
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerOnCreatedCallback = (target, callback) => {

	// define $onCreated callbacks
	if(!target.$onCreated) {
		target.$onCreated = [];
	}

	// init render engine
	target.$onCreated.push(callback);

	return target;

};

/**
 * Register on Detached callback
 * @param  {Object} target
 * @param  {Function} callback
 * @return {Function} target
 */
on.helper.registerOnDeatchedCallback = (target, callback) => {

	// define $onCreated callbacks
	if(!target.$onDetached) {
		target.$Detached = [];
	}

	// init render engine
	target.$onDetached.push(callback);

	return target;

};

/**
 * Register namespace of on decorator
 * @param  {Function|Objet} target
 * @return {Function} target
 */
on.helper.registerNamespaces = (target) => {

	// if namespace already exists do nothing
	if(target.$appDecorators && target.$appDecorators.on){
		return target;
	}

	// define namespace
	target.$appDecorators = {
		on: {
			events: {},
		},
	};

	return target;
};
<|endoftext|>


<commit_before>export default {
  supportedLocales: [
    'en-US',
    'en-GB',
    'en-CA',
    'fr-FR',
    'fr-CA',
    'de-DE',
    'it-IT',
    'es-ES',
    'es-419',
    'ja-JP',
    'pt-BR',
  ],
  sourceLocale: 'en-US',
  sourceFolder: './src',
  localizationFolder: './localization',
};
<commit_msg>add en-AU to default supported locale (#22)<commit_after>export default {
  supportedLocales: [
    'en-US',
    'en-GB',
    'en-CA',
    'en-AU',
    'fr-FR',
    'fr-CA',
    'de-DE',
    'it-IT',
    'es-ES',
    'es-419',
    'ja-JP',
    'pt-BR',
  ],
  sourceLocale: 'en-US',
  sourceFolder: './src',
  localizationFolder: './localization',
};
<|endoftext|>


<commit_before>import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { filters2cql } from '@folio/stripes-components/lib/FilterGroups';
import SearchAndSort from '@folio/stripes-smart-components/lib/SearchAndSort';

import uuid from 'uuid';
import ViewUser from './ViewUser';
import UserForm from './UserForm';
import { toUserAddresses } from './converters/address';
import { getFullName } from './util';
import packageInfo from './package';

const INITIAL_RESULT_COUNT = 30;
const RESULT_COUNT_INCREMENT = 30;

const filterConfig = [
  {
    label: 'Status',
    name: 'active',
    cql: 'active',
    values: [
      { name: 'Active', cql: 'true' },
      { name: 'Inactive', cql: 'false' },
    ],
  },
  {
    label: 'Patron group',
    name: 'pg',
    cql: 'patronGroup',
    values: [], // will be filled in by componentWillUpdate
  },
];

class Users extends React.Component {
  static propTypes = {
    resources: PropTypes.shape({
      patronGroups: PropTypes.shape({
        records: PropTypes.arrayOf(PropTypes.object),
      }),
      addressTypes: PropTypes.shape({
        records: PropTypes.arrayOf(PropTypes.object),
      }),
    }).isRequired,
    mutator: PropTypes.shape({
      creds: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
      perms: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
      records: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
    }).isRequired,
    onSelectRow: PropTypes.func,
    onComponentWillUnmount: PropTypes.func,
    visibleColumns: PropTypes.arrayOf(PropTypes.string),
    disableRecordCreation: PropTypes.bool,
    showSingleResult: PropTypes.bool,
  };

  static defaultProps = {
    showSingleResult: true,
  }

  static manifest = Object.freeze({
    query: {
      initialValue: {
        query: '',
        filters: 'active.Active',
        sort: 'Name',
      },
    },
    resultCount: { initialValue: INITIAL_RESULT_COUNT },
    records: {
      type: 'okapi',
      records: 'users',
      recordsRequired: '%{resultCount}',
      perRequest: 30,
      path: 'users',
      GET: {
        params: {
          query: (...args) => {
            /*
              This code is not DRY as it is copied from makeQueryFunction in stripes-components.
              This is necessary, as makeQueryFunction only referneces query paramaters as a data source.
              STRIPES-480 is intended to correct this and allow this query function to be replace with a call
              to makeQueryFunction.
              https://issues.folio.org/browse/STRIPES-480
            */
            const resourceData = args[2];
            const sortMap = {
              Active: 'active',
              Name: 'personal.lastName personal.firstName',
              'Patron Group': 'patronGroup.group',
              Username: 'username',
              Barcode: 'barcode',
              Email: 'personal.email',
            };

            let cql = `(username="${resourceData.query.query}*" or personal.firstName="${resourceData.query.query}*" or personal.lastName="${resourceData.query.query}*" or personal.email="${resourceData.query.query}*" or barcode="${resourceData.query.query}*" or id="${resourceData.query.query}*" or externalSystemId="${resourceData.query.query}*")`;

            const filterCql = filters2cql(filterConfig, resourceData.query.filters);
            if (filterCql) {
              if (cql) {
                cql = `(${cql}) and ${filterCql}`;
              } else {
                cql = filterCql;
              }
            }

            const { sort } = resourceData.query;
            if (sort) {
              const sortIndexes = sort.split(',').map((sort1) => {
                let reverse = false;
                if (sort1.startsWith('-')) {
                  // eslint-disable-next-line no-param-reassign
                  sort1 = sort1.substr(1);
                  reverse = true;
                }
                let sortIndex = sortMap[sort1] || sort1;
                if (reverse) {
                  sortIndex = `${sortIndex.replace(' ', '/sort.descending ')}/sort.descending`;
                }
                return sortIndex;
              });

              cql += ` sortby ${sortIndexes.join(' ')}`;
            }

            return cql;
          },
        },
        staticFallback: { params: {} },
      },
    },
    creds: {
      type: 'okapi',
      path: 'authn/credentials',
      fetch: false,
    },
    perms: {
      type: 'okapi',
      path: 'perms/users',
      fetch: false,
    },
    patronGroups: {
      type: 'okapi',
      path: 'groups?query=cql.allRecords=1 sortby group',
      records: 'usergroups',
    },
    addressTypes: {
      type: 'okapi',
      path: 'addresstypes?query=cql.allRecords=1 sortby desc',
      records: 'addressTypes',
    },
    uniquenessValidator: {
      type: 'okapi',
      records: 'users',
      accumulate: 'true',
      path: 'users',
      fetch: false,
    },
  });

  componentWillUpdate() {
    const pg = (this.props.resources.patronGroups || {}).records || [];
    if (pg && pg.length) {
      const pgFilterConfig = filterConfig.find(group => group.name === 'pg');
      pgFilterConfig.values = pg.map(rec => ({ name: rec.group, cql: rec.id }));
    }
  }

  massageNewRecord = (userdata) => {
    if (userdata.personal.addresses) {
      const addressTypes = (this.props.resources.addressTypes || {}).records || [];
      // eslint-disable-next-line no-param-reassign
      userdata.personal.addresses = toUserAddresses(userdata.personal.addresses, addressTypes);
    }
  }

  // XXX something prevents exceptions in this function from being received: see STRIPES-483
  create = (userdata) => {
    const { mutator } = this.props;
    const creds = Object.assign({}, userdata.creds, { username: userdata.username }, userdata.creds.password ? {} : { password: '' });
    const user = Object.assign({}, userdata, { id: uuid() });
    if (user.creds) delete user.creds;

    mutator.records.POST(user)
      .then(newUser => mutator.creds.POST(Object.assign(creds, { userId: newUser.id })))
      .then(newCreds => mutator.perms.POST({ userId: newCreds.userId, permissions: [] }))
      .then((perms) => {
        mutator.query.update({ _path: `/users/view/${perms.userId}`, layer: null });
      });
  }

  render() {
    const props = this.props;
    const { onSelectRow, disableRecordCreation, onComponentWillUnmount } = this.props;
    const patronGroups = (props.resources.patronGroups || {}).records || [];
    const initialPath = (_.get(packageInfo, ['stripes', 'home']) ||
                         _.get(packageInfo, ['stripes', 'route']));

    const resultsFormatter = {
      Status: user => (user.active ? 'Active' : 'Inactive'),
      Name: user => getFullName(user),
      Barcode: user => user.barcode,
      'Patron Group': (user) => {
        const pg = patronGroups.filter(g => g.id === user.patronGroup)[0];
        return pg ? pg.group : '?';
      },
      Username: user => user.username,
      Email: user => _.get(user, ['personal', 'email']),
    };

    return (<SearchAndSort
      moduleName={packageInfo.name.replace(/.*\//, '')}
      moduleTitle={packageInfo.stripes.displayName}
      objectName="user"
      baseRoute={packageInfo.stripes.route}
      initialPath={initialPath}
      filterConfig={filterConfig}
      initialFilters={this.constructor.manifest.query.initialValue.filters}
      initialResultCount={INITIAL_RESULT_COUNT}
      resultCountIncrement={RESULT_COUNT_INCREMENT}
      viewRecordComponent={ViewUser}
      editRecordComponent={UserForm}
      newRecordInitialValues={{ active: true, personal: { preferredContactTypeId: '002' } }}
      visibleColumns={this.props.visibleColumns ? this.props.visibleColumns : ['Status', 'Name', 'Barcode', 'Patron Group', 'Username', 'Email']}
      resultsFormatter={resultsFormatter}
      onSelectRow={onSelectRow}
      onCreate={this.create}
      onComponentWillUnmount={onComponentWillUnmount}
      massageNewRecord={this.massageNewRecord}
      finishedResourceName="perms"
      viewRecordPerms="users.item.get"
      newRecordPerms="users.item.post,login.item.post,perms.users.item.post"
      disableRecordCreation={disableRecordCreation}
      parentResources={props.resources}
      parentMutator={props.mutator}
      showSingleResult={props.showSingleResult}
    />);
  }
}

export default Users;
<commit_msg>placate eslint, hopefully<commit_after>import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { filters2cql } from '@folio/stripes-components/lib/FilterGroups';
import SearchAndSort from '@folio/stripes-smart-components/lib/SearchAndSort';

import uuid from 'uuid';
import ViewUser from './ViewUser';
import UserForm from './UserForm';
import { toUserAddresses } from './converters/address';
import { getFullName } from './util';
import packageInfo from './package';

const INITIAL_RESULT_COUNT = 30;
const RESULT_COUNT_INCREMENT = 30;

const filterConfig = [
  {
    label: 'Status',
    name: 'active',
    cql: 'active',
    values: [
      { name: 'Active', cql: 'true' },
      { name: 'Inactive', cql: 'false' },
    ],
  },
  {
    label: 'Patron group',
    name: 'pg',
    cql: 'patronGroup',
    values: [], // will be filled in by componentWillUpdate
  },
];

class Users extends React.Component {
  static propTypes = {
    resources: PropTypes.shape({
      patronGroups: PropTypes.shape({
        records: PropTypes.arrayOf(PropTypes.object),
      }),
      addressTypes: PropTypes.shape({
        records: PropTypes.arrayOf(PropTypes.object),
      }),
    }).isRequired,
    mutator: PropTypes.shape({
      creds: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
      perms: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
      records: PropTypes.shape({
        POST: PropTypes.func.isRequired,
      }),
    }).isRequired,
    onSelectRow: PropTypes.func,
    onComponentWillUnmount: PropTypes.func,
    visibleColumns: PropTypes.arrayOf(PropTypes.string),
    disableRecordCreation: PropTypes.bool,
    showSingleResult: PropTypes.bool,
  };

  static defaultProps = {
    showSingleResult: true,
  }

  static manifest = Object.freeze({
    query: {
      initialValue: {
        query: '',
        filters: 'active.Active',
        sort: 'Name',
      },
    },
    resultCount: { initialValue: INITIAL_RESULT_COUNT },
    records: {
      type: 'okapi',
      records: 'users',
      recordsRequired: '%{resultCount}',
      perRequest: 30,
      path: 'users',
      GET: {
        params: {
          query: (...args) => {
            /*
              This code is not DRY as it is copied from makeQueryFunction in stripes-components.
              This is necessary, as makeQueryFunction only referneces query paramaters as a data source.
              STRIPES-480 is intended to correct this and allow this query function to be replace with a call
              to makeQueryFunction.
              https://issues.folio.org/browse/STRIPES-480
            */
            const resourceData = args[2];
            const sortMap = {
              Active: 'active',
              Name: 'personal.lastName personal.firstName',
              'Patron Group': 'patronGroup.group',
              Username: 'username',
              Barcode: 'barcode',
              Email: 'personal.email',
            };

            let cql = `(username="${resourceData.query.query}*" or personal.firstName="${resourceData.query.query}*" or personal.lastName="${resourceData.query.query}*" or personal.email="${resourceData.query.query}*" or barcode="${resourceData.query.query}*" or id="${resourceData.query.query}*" or externalSystemId="${resourceData.query.query}*")`;

            const filterCql = filters2cql(filterConfig, resourceData.query.filters);
            if (filterCql) {
              if (cql) {
                cql = `(${cql}) and ${filterCql}`;
              } else {
                cql = filterCql;
              }
            }

            const { sort } = resourceData.query;
            if (sort) {
              const sortIndexes = sort.split(',').map((sort1) => {
                let reverse = false;
                if (sort1.startsWith('-')) {
                  // eslint-disable-next-line no-param-reassign
                  sort1 = sort1.substr(1);
                  reverse = true;
                }
                let sortIndex = sortMap[sort1] || sort1;
                if (reverse) {
                  sortIndex = `${sortIndex.replace(' ', '/sort.descending ')}/sort.descending`;
                }
                return sortIndex;
              });

              cql += ` sortby ${sortIndexes.join(' ')}`;
            }

            return cql;
          },
        },
        staticFallback: { params: {} },
      },
    },
    creds: {
      type: 'okapi',
      path: 'authn/credentials',
      fetch: false,
    },
    perms: {
      type: 'okapi',
      path: 'perms/users',
      fetch: false,
    },
    patronGroups: {
      type: 'okapi',
      path: 'groups?query=cql.allRecords=1 sortby group',
      records: 'usergroups',
    },
    addressTypes: {
      type: 'okapi',
      path: 'addresstypes?query=cql.allRecords=1 sortby desc',
      records: 'addressTypes',
    },
    uniquenessValidator: {
      type: 'okapi',
      records: 'users',
      accumulate: 'true',
      path: 'users',
      fetch: false,
    },
  });

  componentWillUpdate() {
    const pg = (this.props.resources.patronGroups || {}).records || [];
    if (pg && pg.length) {
      const pgFilterConfig = filterConfig.find(group => group.name === 'pg');
      pgFilterConfig.values = pg.map(rec => ({ name: rec.group, cql: rec.id }));
    }
  }

  massageNewRecord = (userdata) => {
    if (userdata.personal.addresses) {
      const addressTypes = (this.props.resources.addressTypes || {}).records || [];
      // eslint-disable-next-line no-param-reassign
      userdata.personal.addresses = toUserAddresses(userdata.personal.addresses, addressTypes);
    }
  }

  // XXX something prevents exceptions in this function from being received: see STRIPES-483
  create = (userdata) => {
    const { mutator } = this.props;
    const creds = Object.assign({}, userdata.creds, { username: userdata.username }, userdata.creds.password ? {} : { password: '' });
    const user = Object.assign({}, userdata, { id: uuid() });
    if (user.creds) delete user.creds;

    mutator.records.POST(user)
      .then(newUser => mutator.creds.POST(Object.assign(creds, { userId: newUser.id })))
      .then(newCreds => mutator.perms.POST({ userId: newCreds.userId, permissions: [] }))
      .then((perms) => {
        mutator.query.update({ _path: `/users/view/${perms.userId}`, layer: null });
      });
  }

  render() {
    const props = this.props;
    const { onSelectRow, disableRecordCreation, onComponentWillUnmount, showSingleResult } = this.props;
    const patronGroups = (props.resources.patronGroups || {}).records || [];
    const initialPath = (_.get(packageInfo, ['stripes', 'home']) ||
                         _.get(packageInfo, ['stripes', 'route']));

    const resultsFormatter = {
      Status: user => (user.active ? 'Active' : 'Inactive'),
      Name: user => getFullName(user),
      Barcode: user => user.barcode,
      'Patron Group': (user) => {
        const pg = patronGroups.filter(g => g.id === user.patronGroup)[0];
        return pg ? pg.group : '?';
      },
      Username: user => user.username,
      Email: user => _.get(user, ['personal', 'email']),
    };

    return (<SearchAndSort
      moduleName={packageInfo.name.replace(/.*\//, '')}
      moduleTitle={packageInfo.stripes.displayName}
      objectName="user"
      baseRoute={packageInfo.stripes.route}
      initialPath={initialPath}
      filterConfig={filterConfig}
      initialFilters={this.constructor.manifest.query.initialValue.filters}
      initialResultCount={INITIAL_RESULT_COUNT}
      resultCountIncrement={RESULT_COUNT_INCREMENT}
      viewRecordComponent={ViewUser}
      editRecordComponent={UserForm}
      newRecordInitialValues={{ active: true, personal: { preferredContactTypeId: '002' } }}
      visibleColumns={this.props.visibleColumns ? this.props.visibleColumns : ['Status', 'Name', 'Barcode', 'Patron Group', 'Username', 'Email']}
      resultsFormatter={resultsFormatter}
      onSelectRow={onSelectRow}
      onCreate={this.create}
      onComponentWillUnmount={onComponentWillUnmount}
      massageNewRecord={this.massageNewRecord}
      finishedResourceName="perms"
      viewRecordPerms="users.item.get"
      newRecordPerms="users.item.post,login.item.post,perms.users.item.post"
      disableRecordCreation={disableRecordCreation}
      parentResources={props.resources}
      parentMutator={props.mutator}
      showSingleResult={showSingleResult}
    />);
  }
}

export default Users;
<|endoftext|>


<commit_before>import React from 'react'

export default function Duration ({ className, seconds }) {
  return (
    <time dateTime={`P${Math.round(seconds)}S`} className={className}>
      {format(seconds)}
    </time>
  )
}

function format (seconds) {
  const date = new Date(seconds * 1000)
  const hh = date.getHours()
  const mm = date.getMinutes()
  const ss = pad(date.getSeconds())
  if (hh) {
    return `${hh}:${pad(mm)}:${ss}`
  }
  return `${mm}:${ss}`
}

function pad (string) {
  return ('0' + string).slice(-2)
}
<commit_msg>Fix incorrect duration calculation in demo app.<commit_after>import React from 'react'

export default function Duration ({ className, seconds }) {
  return (
    <time dateTime={`P${Math.round(seconds)}S`} className={className}>
      {format(seconds)}
    </time>
  )
}

function format (seconds) {
  const date = new Date(seconds * 1000)
  const hh = date.getUTCHours()
  const mm = date.getUTCMinutes()
  const ss = pad(date.getUTCSeconds())
  if (hh) {
    return `${hh}:${pad(mm)}:${ss}`
  }
  return `${mm}:${ss}`
}

function pad (string) {
  return ('0' + string).slice(-2)
}
<|endoftext|>


<commit_before>//Grab the inline template
var template = document.getElementById('template').innerHTML;

//Compile the template
var compiled_template = Handlebars.compile(template);

//Create helper for dealing with JSON
Handlebars.registerHelper('toJSON', function(obj) {
    return JSON.stringify(obj, null, 3);
});

//Render the data into the template
var rendered = compiled_template({name: "Luke", power: "force"});

//Overwrite the contents of #target with the renderer HTML
document.getElementById('target').innerHTML = rendered;

/* W3Data ver 1.31 by W3Schools.com */
var w3DataObject = {};
function w3DisplayData(id, data) {
    var htmlObj, htmlTemplate, html, arr = [], a, l, rowClone, x, j, i, ii, cc, repeat, repeatObj, repeatX = "";
    htmlObj = document.getElementById(id);
    htmlTemplate = w3InitTemplate(id, htmlObj);
    html = htmlTemplate.cloneNode(true);
    arr = w3GetElementsByAttribute(html, "w3-repeat");
    l = arr.length;
    for (j = (l - 1); j >= 0; j -= 1) {
        cc = arr[j].getAttribute("w3-repeat").split(" ");
        if (cc.length == 1) {
            repeat = cc[0];
        } else {
            repeatX = cc[0];
            repeat = cc[2];
        }
        arr[j].removeAttribute("w3-repeat");
        repeatObj = data[repeat];
        if (repeatObj && typeof repeatObj == "object" && repeatObj.length != "undefined") {
            i = 0;
            for (x in repeatObj) {
                i += 1;
                rowClone = arr[j];
                rowClone = w3NeedleInHaystack(rowClone, "element", repeatX, repeatObj[x]);
                a = rowClone.attributes;
                for (ii = 0; ii < a.length; ii += 1) {
                    a[ii].value = w3NeedleInHaystack(a[ii], "attribute", repeatX, repeatObj[x]).value;
                }
                (i === repeatObj.length) ? arr[j].parentNode.replaceChild(rowClone, arr[j]) : arr[j].parentNode.insertBefore(rowClone, arr[j]);
            }
        } else {
            console.log("w3-repeat must be an array. " + repeat + " is not an array.");
            continue;
        }
    }
    html = w3NeedleInHaystack(html, "element");
    htmlObj.parentNode.replaceChild(html, htmlObj);
    function w3InitTemplate(id, obj) {
        var template;
        template = obj.cloneNode(true);
        if (w3DataObject.hasOwnProperty(id)) {return w3DataObject[id];}
        w3DataObject[id] = template;
        return template;
    }
    function w3GetElementsByAttribute(x, att) {
        var arr = [], arrCount = -1, i, l, y = x.getElementsByTagName("*"), z = att.toUpperCase();
        l = y.length;
        for (i = -1; i < l; i += 1) {
            if (i == -1) {y[i] = x;}
            if (y[i].getAttribute(z) !== null) {arrCount += 1; arr[arrCount] = y[i];}
        }
        return arr;
    }
    function w3NeedleInHaystack(elmnt, typ, repeatX, x) {
        var value, rowClone, pos1, haystack, pos2, needle = [], needleToReplace, i, cc, r;
        rowClone = elmnt.cloneNode(true);
        pos1 = 0;
        while (pos1 > -1) {
            haystack = (typ == "attribute") ? rowClone.value : rowClone.innerHTML;
            pos1 = haystack.indexOf("{{", pos1);
            if (pos1 === -1) {break;}
            pos2 = haystack.indexOf("}}", pos1 + 1);
            needleToReplace = haystack.substring(pos1 + 2, pos2);
            needle = needleToReplace.split("||");
            value = undefined;
            for (i = 0; i < needle.length; i += 1) {
                needle[i] = needle[i].replace(/^\s+|\s+$/gm, ''); //trim
                //value = ((x && x[needle[i]]) || (data && data[needle[i]]));
                if (x) {value = x[needle[i]];}
                if (value === undefined && data) {value = data[needle[i]];}
                if (value === undefined) {
                    cc = needle[i].split(".");
                    if (cc[0] == repeatX) {value = x[cc[1]]; }
                }
                if (value === undefined) {
                    if (needle[i] == repeatX) {value = x;}
                }
                if (value === undefined) {
                    if (needle[i].substr(0, 1) == '"') {
                        value = needle[i].replace(/"/g, "");
                    } else if (needle[i].substr(0,1) == "'") {
                        value = needle[i].replace(/'/g, "");
                    }
                }
                if (value !== undefined) {break;}
            }
            if (value !== undefined) {
                r = "{{" + needleToReplace + "}}";
                if (typ == "attribute") {
                    rowClone.value = rowClone.value.replace(r, value);
                } else {
                    w3ReplaceHTML(rowClone, r, value);
                }
            }
            pos1 = pos1 + 1;
        }
        return rowClone;
    }
    function w3ReplaceHTML(a, r, result) {
        var b, l, i, a, x, j;
        if (a.hasAttributes()) {
            b = a.attributes;
            l = b.length;
            for (i = 0; i < l; i += 1) {
                if (b[i].value.indexOf(r) > -1) {b[i].value = b[i].value.replace(r, result);}
            }
        }
        x = a.getElementsByTagName("*");
        l = x.length;
        a.innerHTML = a.innerHTML.replace(r, result);
    }
}
function w3IncludeHTML() {
  var z, i, elmnt, file, xhttp;
  z = document.getElementsByTagName("*");
  for (i = 0; i < z.length; i++) {
    elmnt = z[i];
    if (file) {
      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          elmnt.innerHTML = this.responseText;
          elmnt.removeAttribute("w3-include-html");
          w3IncludeHTML();
        }
      }
      xhttp.open("GET", file, true);
      xhttp.send();
      return;
    }
  }
}
function w3Http(target, readyfunc, xml, method) {
    var httpObj;
    if (!method) {method = "GET"; }
    if (window.XMLHttpRequest) {
        httpObj = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        httpObj = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (httpObj) {
        if (readyfunc) {httpObj.onreadystatechange = readyfunc;}
        httpObj.open(method, target, true);
        httpObj.send(xml);
    }
}
<commit_msg>Added additional line for w3data plugin<commit_after>//Grab the inline template
var template = document.getElementById('template').innerHTML;

//Compile the template
var compiled_template = Handlebars.compile(template);

//Create helper for dealing with JSON
Handlebars.registerHelper('toJSON', function(obj) {
    return JSON.stringify(obj, null, 3);
});

//Render the data into the template
var rendered = compiled_template({name: "Luke", power: "force"});

//Overwrite the contents of #target with the renderer HTML
document.getElementById('target').innerHTML = rendered;

/* W3Data ver 1.31 by W3Schools.com */
var w3DataObject = {};
function w3DisplayData(id, data) {
    var htmlObj, htmlTemplate, html, arr = [], a, l, rowClone, x, j, i, ii, cc, repeat, repeatObj, repeatX = "";
    htmlObj = document.getElementById(id);
    htmlTemplate = w3InitTemplate(id, htmlObj);
    html = htmlTemplate.cloneNode(true);
    arr = w3GetElementsByAttribute(html, "w3-repeat");
    l = arr.length;
    for (j = (l - 1); j >= 0; j -= 1) {
        cc = arr[j].getAttribute("w3-repeat").split(" ");
        if (cc.length == 1) {
            repeat = cc[0];
        } else {
            repeatX = cc[0];
            repeat = cc[2];
        }
        arr[j].removeAttribute("w3-repeat");
        repeatObj = data[repeat];
        if (repeatObj && typeof repeatObj == "object" && repeatObj.length != "undefined") {
            i = 0;
            for (x in repeatObj) {
                i += 1;
                rowClone = arr[j];
                rowClone = w3NeedleInHaystack(rowClone, "element", repeatX, repeatObj[x]);
                a = rowClone.attributes;
                for (ii = 0; ii < a.length; ii += 1) {
                    a[ii].value = w3NeedleInHaystack(a[ii], "attribute", repeatX, repeatObj[x]).value;
                }
                (i === repeatObj.length) ? arr[j].parentNode.replaceChild(rowClone, arr[j]) : arr[j].parentNode.insertBefore(rowClone, arr[j]);
            }
        } else {
            console.log("w3-repeat must be an array. " + repeat + " is not an array.");
            continue;
        }
    }
    html = w3NeedleInHaystack(html, "element");
    htmlObj.parentNode.replaceChild(html, htmlObj);
    function w3InitTemplate(id, obj) {
        var template;
        template = obj.cloneNode(true);
        if (w3DataObject.hasOwnProperty(id)) {return w3DataObject[id];}
        w3DataObject[id] = template;
        return template;
    }
    function w3GetElementsByAttribute(x, att) {
        var arr = [], arrCount = -1, i, l, y = x.getElementsByTagName("*"), z = att.toUpperCase();
        l = y.length;
        for (i = -1; i < l; i += 1) {
            if (i == -1) {y[i] = x;}
            if (y[i].getAttribute(z) !== null) {arrCount += 1; arr[arrCount] = y[i];}
        }
        return arr;
    }
    function w3NeedleInHaystack(elmnt, typ, repeatX, x) {
        var value, rowClone, pos1, haystack, pos2, needle = [], needleToReplace, i, cc, r;
        rowClone = elmnt.cloneNode(true);
        pos1 = 0;
        while (pos1 > -1) {
            haystack = (typ == "attribute") ? rowClone.value : rowClone.innerHTML;
            pos1 = haystack.indexOf("{{", pos1);
            if (pos1 === -1) {break;}
            pos2 = haystack.indexOf("}}", pos1 + 1);
            needleToReplace = haystack.substring(pos1 + 2, pos2);
            needle = needleToReplace.split("||");
            value = undefined;
            for (i = 0; i < needle.length; i += 1) {
                needle[i] = needle[i].replace(/^\s+|\s+$/gm, ''); //trim
                //value = ((x && x[needle[i]]) || (data && data[needle[i]]));
                if (x) {value = x[needle[i]];}
                if (value === undefined && data) {value = data[needle[i]];}
                if (value === undefined) {
                    cc = needle[i].split(".");
                    if (cc[0] == repeatX) {value = x[cc[1]]; }
                }
                if (value === undefined) {
                    if (needle[i] == repeatX) {value = x;}
                }
                if (value === undefined) {
                    if (needle[i].substr(0, 1) == '"') {
                        value = needle[i].replace(/"/g, "");
                    } else if (needle[i].substr(0,1) == "'") {
                        value = needle[i].replace(/'/g, "");
                    }
                }
                if (value !== undefined) {break;}
            }
            if (value !== undefined) {
                r = "{{" + needleToReplace + "}}";
                if (typ == "attribute") {
                    rowClone.value = rowClone.value.replace(r, value);
                } else {
                    w3ReplaceHTML(rowClone, r, value);
                }
            }
            pos1 = pos1 + 1;
        }
        return rowClone;
    }
    function w3ReplaceHTML(a, r, result) {
        var b, l, i, a, x, j;
        if (a.hasAttributes()) {
            b = a.attributes;
            l = b.length;
            for (i = 0; i < l; i += 1) {
                if (b[i].value.indexOf(r) > -1) {b[i].value = b[i].value.replace(r, result);}
            }
        }
        x = a.getElementsByTagName("*");
        l = x.length;
        a.innerHTML = a.innerHTML.replace(r, result);
    }
}
function w3IncludeHTML() {
  var z, i, elmnt, file, xhttp;
  z = document.getElementsByTagName("*");
  for (i = 0; i < z.length; i++) {
    elmnt = z[i];
    file = elmnt.getAttribute("w3-include-html");
    if (file) {
      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          elmnt.innerHTML = this.responseText;
          elmnt.removeAttribute("w3-include-html");
          w3IncludeHTML();
        }
      }
      xhttp.open("GET", file, true);
      xhttp.send();
      return;
    }
  }
}
function w3Http(target, readyfunc, xml, method) {
    var httpObj;
    if (!method) {method = "GET"; }
    if (window.XMLHttpRequest) {
        httpObj = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        httpObj = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (httpObj) {
        if (readyfunc) {httpObj.onreadystatechange = readyfunc;}
        httpObj.open(method, target, true);
        httpObj.send(xml);
    }
}
<|endoftext|>


<commit_before>/*
 * angular-elastic v2.1.0
 * (c) 2013 Monospaced http://monospaced.com
 * License: MIT
 */

angular.module('monospaced.elastic', [])

  .constant('msdElasticConfig', {
    append: ''
  })

  .directive('msdElastic', ['$timeout', '$window', 'msdElasticConfig', function($timeout, $window, config) {
    'use strict';

    return {
      require: 'ngModel',
      restrict: 'A, C',
      link: function(scope, element, attrs, ngModel){

        // cache a reference to the DOM element
        var ta = element[0],
            $ta = element;

        // ensure the element is a textarea, and browser is capable
        if (ta.nodeName !== 'TEXTAREA' || !$window.getComputedStyle) {
          return;
        }

        // set these properties before measuring dimensions
        $ta.css({
          'overflow': 'hidden',
          'overflow-y': 'hidden',
          'word-wrap': 'break-word'
        });

        // force text reflow
        var text = ta.value;
        ta.value = '';
        ta.value = text;

        var appendText = attrs.msdElastic || config.append,
            append = appendText === '\\n' ? '\n' : appendText,
            $win = angular.element($window),
            mirrorStyle = 'position: absolute; top: -999px; right: auto; bottom: auto; left: 0 ;' +
                          'overflow: hidden; -webkit-box-sizing: content-box;' +
                          '-moz-box-sizing: content-box; box-sizing: content-box;' +
                          'min-height: 0 !important; height: 0 !important; padding: 0;' +
                          'word-wrap: break-word; border: 0;',
            $mirror = angular.element('<textarea tabindex="-1" ' +
                                      'style="' + mirrorStyle + '"/>').data('elastic', true),
            mirror = $mirror[0],
            taStyle = getComputedStyle(ta),
            resize = taStyle.getPropertyValue('resize'),
            borderBox = taStyle.getPropertyValue('box-sizing') === 'border-box' ||
                        taStyle.getPropertyValue('-moz-box-sizing') === 'border-box' ||
                        taStyle.getPropertyValue('-webkit-box-sizing') === 'border-box',
            boxOuter = !borderBox ? {width: 0, height: 0} : {
                          width:  parseInt(taStyle.getPropertyValue('border-right-width'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-right'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-left'), 10) +
                                  parseInt(taStyle.getPropertyValue('border-left-width'), 10),
                          height: parseInt(taStyle.getPropertyValue('border-top-width'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-top'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-bottom'), 10) +
                                  parseInt(taStyle.getPropertyValue('border-bottom-width'), 10)
                        },
            minHeightValue = parseInt(taStyle.getPropertyValue('min-height'), 10),
            heightValue = parseInt(taStyle.getPropertyValue('height'), 10),
            minHeight = Math.max(minHeightValue, heightValue) - boxOuter.height,
            maxHeight = parseInt(taStyle.getPropertyValue('max-height'), 10),
            mirrored,
            active,
            copyStyle = ['font-family',
                         'font-size',
                         'font-weight',
                         'font-style',
                         'letter-spacing',
                         'line-height',
                         'text-transform',
                         'word-spacing',
                         'text-indent'];

        // exit if elastic already applied (or is the mirror element)
        if ($ta.data('elastic')) {
          return;
        }

        // Opera returns max-height of -1 if not set
        maxHeight = maxHeight && maxHeight > 0 ? maxHeight : 9e4;

        // append mirror to the DOM
        if (mirror.parentNode !== document.body) {
          angular.element(document.body).append(mirror);
        }

        // set resize and apply elastic
        $ta.css({
          'resize': (resize === 'none' || resize === 'vertical') ? 'none' : 'horizontal'
        }).data('elastic', true);

        /*
         * methods
         */

        function initMirror(){
          mirrored = ta;
          // copy the essential styles from the textarea to the mirror
          taStyle = getComputedStyle(ta);
          angular.forEach(copyStyle, function(val){
            mirrorStyle += val + ':' + taStyle.getPropertyValue(val) + ';';
          });
          mirror.setAttribute('style', mirrorStyle);
        }

        function adjust() {
          var taHeight,
              mirrorHeight,
              width,
              overflow;

          if (mirrored !== ta) {
            initMirror();
          }

          // active flag prevents actions in function from calling adjust again
          if (!active) {
            active = true;

            mirror.value = ta.value + append; // optional whitespace to improve animation
            mirror.style.overflowY = ta.style.overflowY;

            taHeight = ta.style.height === '' ? 'auto' : parseInt(ta.style.height, 10);

            // update mirror width in case the textarea width has changed
            width = parseInt(getComputedStyle(ta).getPropertyValue('width'), 10) - boxOuter.width;
            mirror.style.width = width + 'px';

            mirror.overflow = 'scroll';
            mirrorHeight = mirror.scrollHeight;
            mirror.overflow = 'hidden';

            if (mirrorHeight > maxHeight) {
              mirrorHeight = maxHeight;
              overflow = 'scroll';
            } else if (mirrorHeight < minHeight) {
              mirrorHeight = minHeight;
            }
            mirrorHeight += boxOuter.height;

            ta.style.overflowY = overflow || 'hidden';

            if (taHeight !== mirrorHeight) {
              ta.style.height = mirrorHeight + 'px';
            }

            // small delay to prevent an infinite loop
            $timeout(function(){
              active = false;
            }, 1);

          }
        }

        function forceAdjust(){
          active = false;
          adjust();
        }

        /*
         * initialise
         */

        // listen
        if ('onpropertychange' in ta && 'oninput' in ta) {
          // IE9
          ta['oninput'] = ta.onkeyup = adjust;
        } else {
          ta['oninput'] = adjust;
        }

        $win.bind('resize', forceAdjust);

        scope.$watch(function(){
          return ngModel.$modelValue;
        }, function(newValue){
          forceAdjust();
        });

        /*
         * destroy
         */

        scope.$on('$destroy', function(){
          $mirror.remove();
          $win.unbind('resize', forceAdjust);
        });
      }
    };

  }]);
<commit_msg>remove force reflow<commit_after>/*
 * angular-elastic v2.1.0
 * (c) 2013 Monospaced http://monospaced.com
 * License: MIT
 */

angular.module('monospaced.elastic', [])

  .constant('msdElasticConfig', {
    append: ''
  })

  .directive('msdElastic', ['$timeout', '$window', 'msdElasticConfig', function($timeout, $window, config) {
    'use strict';

    return {
      require: 'ngModel',
      restrict: 'A, C',
      link: function(scope, element, attrs, ngModel){

        // cache a reference to the DOM element
        var ta = element[0],
            $ta = element;

        // ensure the element is a textarea, and browser is capable
        if (ta.nodeName !== 'TEXTAREA' || !$window.getComputedStyle) {
          return;
        }

        // set these properties before measuring dimensions
        $ta.css({
          'overflow': 'hidden',
          'overflow-y': 'hidden',
          'word-wrap': 'break-word'
        });

        // force text reflow
        var text = ta.value;
        ta.value = '';
        ta.value = text;

        var appendText = attrs.msdElastic || config.append,
            append = appendText === '\\n' ? '\n' : appendText,
            $win = angular.element($window),
            mirrorStyle = 'position: absolute; top: -999px; right: auto; bottom: auto; left: 0 ;' +
                          'overflow: hidden; -webkit-box-sizing: content-box;' +
                          '-moz-box-sizing: content-box; box-sizing: content-box;' +
                          'min-height: 0 !important; height: 0 !important; padding: 0;' +
                          'word-wrap: break-word; border: 0;',
            $mirror = angular.element('<textarea tabindex="-1" ' +
                                      'style="' + mirrorStyle + '"/>').data('elastic', true),
            mirror = $mirror[0],
            taStyle = getComputedStyle(ta),
            resize = taStyle.getPropertyValue('resize'),
            borderBox = taStyle.getPropertyValue('box-sizing') === 'border-box' ||
                        taStyle.getPropertyValue('-moz-box-sizing') === 'border-box' ||
                        taStyle.getPropertyValue('-webkit-box-sizing') === 'border-box',
            boxOuter = !borderBox ? {width: 0, height: 0} : {
                          width:  parseInt(taStyle.getPropertyValue('border-right-width'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-right'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-left'), 10) +
                                  parseInt(taStyle.getPropertyValue('border-left-width'), 10),
                          height: parseInt(taStyle.getPropertyValue('border-top-width'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-top'), 10) +
                                  parseInt(taStyle.getPropertyValue('padding-bottom'), 10) +
                                  parseInt(taStyle.getPropertyValue('border-bottom-width'), 10)
                        },
            minHeightValue = parseInt(taStyle.getPropertyValue('min-height'), 10),
            heightValue = parseInt(taStyle.getPropertyValue('height'), 10),
            minHeight = Math.max(minHeightValue, heightValue) - boxOuter.height,
            maxHeight = parseInt(taStyle.getPropertyValue('max-height'), 10),
            mirrored,
            active,
            copyStyle = ['font-family',
                         'font-size',
                         'font-weight',
                         'font-style',
                         'letter-spacing',
                         'line-height',
                         'text-transform',
                         'word-spacing',
                         'text-indent'];

        // exit if elastic already applied (or is the mirror element)
        if ($ta.data('elastic')) {
          return;
        }

        // Opera returns max-height of -1 if not set
        maxHeight = maxHeight && maxHeight > 0 ? maxHeight : 9e4;

        // append mirror to the DOM
        if (mirror.parentNode !== document.body) {
          angular.element(document.body).append(mirror);
        }

        // set resize and apply elastic
        $ta.css({
          'resize': (resize === 'none' || resize === 'vertical') ? 'none' : 'horizontal'
        }).data('elastic', true);

        /*
         * methods
         */

        function initMirror(){
          mirrored = ta;
          // copy the essential styles from the textarea to the mirror
          taStyle = getComputedStyle(ta);
          angular.forEach(copyStyle, function(val){
            mirrorStyle += val + ':' + taStyle.getPropertyValue(val) + ';';
          });
          mirror.setAttribute('style', mirrorStyle);
        }

        function adjust() {
          var taHeight,
              mirrorHeight,
              width,
              overflow;

          if (mirrored !== ta) {
            initMirror();
          }

          // active flag prevents actions in function from calling adjust again
          if (!active) {
            active = true;

            mirror.value = ta.value + append; // optional whitespace to improve animation
            mirror.style.overflowY = ta.style.overflowY;

            taHeight = ta.style.height === '' ? 'auto' : parseInt(ta.style.height, 10);

            // update mirror width in case the textarea width has changed
            width = parseInt(getComputedStyle(ta).getPropertyValue('width'), 10) - boxOuter.width;
            mirror.style.width = width + 'px';

            mirrorHeight = mirror.scrollHeight;

            if (mirrorHeight > maxHeight) {
              mirrorHeight = maxHeight;
              overflow = 'scroll';
            } else if (mirrorHeight < minHeight) {
              mirrorHeight = minHeight;
            }
            mirrorHeight += boxOuter.height;

            ta.style.overflowY = overflow || 'hidden';

            if (taHeight !== mirrorHeight) {
              ta.style.height = mirrorHeight + 'px';
            }

            // small delay to prevent an infinite loop
            $timeout(function(){
              active = false;
            }, 1);

          }
        }

        function forceAdjust(){
          active = false;
          adjust();
        }

        /*
         * initialise
         */

        // listen
        if ('onpropertychange' in ta && 'oninput' in ta) {
          // IE9
          ta['oninput'] = ta.onkeyup = adjust;
        } else {
          ta['oninput'] = adjust;
        }

        $win.bind('resize', forceAdjust);

        scope.$watch(function(){
          return ngModel.$modelValue;
        }, function(newValue){
          forceAdjust();
        });

        /*
         * destroy
         */

        scope.$on('$destroy', function(){
          $mirror.remove();
          $win.unbind('resize', forceAdjust);
        });
      }
    };

  }]);
<|endoftext|>


<commit_before>var _tics = (function () {
	'use strict';

	var provider = null;
	var helper = null;

	var trackPage = function () {
		provider.trackPage();
	};

	var trackEvent = function (e) {
		provider.track(helper.evTarget(e), helper.ev(e));
	};

	var trackEvents = function () {
		var fields = helper.get('input, select, textarea');
		var links = helper.get('a');
		var buttons = helper.get('button');

		helper.addListeners(fields, 'change', function (e) {
			trackEvent(e);
		});

		helper.addListeners(links, 'click', function (e) {
			trackEvent(e);
		});

		helper.addListeners(buttons, 'click', function (e) {
			trackEvent(e);
		});
	};

	var initialize = function (analyticsProvider) {
		provider = analyticsProvider;
		helper = _tics.helper;
	};

	return {
		init: initialize,
		page: trackPage,
		events: trackEvents,
	};
}());<commit_msg>new feature: add custom event<commit_after>var _tics = (function () {
	'use strict';

	var provider = null;
	var helper = null;

	var trackPage = function () {
		provider.trackPage();
	};

	var trackEvent = function (e) {
		provider.track(helper.evTarget(e), helper.ev(e));
	};

	var trackEvents = function () {
		var fields = helper.get('input, select, textarea');
		var links = helper.get('a');
		var buttons = helper.get('button');

		helper.addListeners(fields, 'change', function (e) {
			trackEvent(e);
		});

		helper.addListeners(links, 'click', function (e) {
			trackEvent(e);
		});

		helper.addListeners(buttons, 'click', function (e) {
			trackEvent(e);
		});
	};

	var addCustomEvent = function (selector, action) {
		var elements = helper.get(selector);

		if (!elements || elements.length === 0) {
			return;
		}

		helper.addListeners(elements, action, function (e) {
			trackEvent(e);
		});
	};

	var initialize = function (analyticsProvider) {
		provider = analyticsProvider;
		helper = _tics.helper;
	};

	return {
		init: initialize,
		page: trackPage,
		events: trackEvents,
		customEvent: addCustomEvent
	};
}());<|endoftext|>