<commit_before>$(document).ready(function(){
  $.ajaxSetup({
    async: false
  });
  var backgroundColours = ['green', 'blue', 'purple', 'orange'];
  var moduleId = GetQueryStringParams('moduleId');
  var carousel = $('
');
  var orgUnitId = GetQueryStringParams('ou');

  var moduleAPI = '/d2l/api/le/1.25/' + orgUnitId + '/content/modules/' + moduleId + '/structure/';//ADD SLASH BACK TO END
  var apiRes = makeAPIcall('GET', moduleAPI);
  console.log(apiRes);
  var i = 0;
  apiRes.forEach(function(topic) {
    if (topic.Type === 1) {
      var colour = backgroundColours[i%backgroundColours.length];
      var topicAPI = '/d2l/api/le/1.25/' + orgUnitId + '/content/topics/' + topic.Id;
      var topicAPIRes = makeAPIcall('GET', topicAPI);
      $('
' +
        '
' +
        '
' + topicAPIRes.Title + '
' +
        '
' + topicAPIRes.Description.Text + '
' +
        'Learn More
' +
        '
').appendTo('.carousel-inner');
      $('

').appendTo('.carousel-indicators');
      i++;
    }
  });
  $('.item').first().addClass('active');
  $('.carousel-indicators > li').first().addClass('active');
  $('#carousel-example-generic').carousel();
});

function GetQueryStringParams(sParam) {
  var obj = window;
  var sPageURL = obj.location.search.substring(1);
  console.log(obj.location);
  console.log(sPageURL);
  var sURLVariables = sPageURL.split('&');
  for (var i = 0; i < sURLVariables.length; i++)
  {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam)
    {
      return sParameterName[1];
    }
  }
}

function makeAPIcall(method, api) {
  var res = {};
  function result_success (data) {
    res = data;
  }

  $.ajax(api, {
    method: method,
    xhrFields: {withCredentials: true},
    success: result_success,
    error: result_error
  });
  return res;
}

function result_error(err) {
  console.log(err);
}
<commit_msg>use ajax asyncronously to get rid of deprication warning<commit_after>$(document).ready(function(){
  var backgroundColours = ['green', 'blue', 'purple', 'orange'];
  var moduleId = GetQueryStringParams('moduleId');
  var carousel = $('
');
  var orgUnitId = GetQueryStringParams('ou');

  var i = 0;
  function moduleSuccessCallback (apiRes) {
    apiRes.forEach(function (topic) {
      if (topic.Type === 1) {
        function addTopic(topicAPIRes) {
          var colour = backgroundColours[i % backgroundColours.length];
          $('
' +
            '
' +
            '
' + topicAPIRes.Title + '
' +
            '
' + topicAPIRes.Description.Text + '
' +
            'Learn More
' +
            '
').appendTo('.carousel-inner');
          $('

').appendTo('.carousel-indicators');
          i++;
          $('.item').first().addClass('active');
          $('.carousel-indicators > li').first().addClass('active');
          $('#carousel-example-generic').carousel();
        }
        var topicAPI = '/d2l/api/le/1.25/' + orgUnitId + '/content/topics/' + topic.Id;
        makeAPIcall('GET', topicAPI, addTopic);
      }
    });
  }

  var moduleAPI = '/d2l/api/le/1.25/' + orgUnitId + '/content/modules/' + moduleId + '/structure/';
  makeAPIcall('GET', moduleAPI, moduleSuccessCallback);
});

function GetQueryStringParams(sParam) {
  var obj = window;
  var sPageURL = obj.location.search.substring(1);
  var sURLVariables = sPageURL.split('&');
  for (var i = 0; i < sURLVariables.length; i++)
  {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam)
    {
      return sParameterName[1];
    }
  }
}

function makeAPIcall(method, api, result_success) {
  $.ajax(api, {
    method: method,
    xhrFields: {withCredentials: true},
    success: result_success,
    error: result_error
  });
}

function result_error(err) {
  console.log(err);
}
<|endoftext|>


<commit_before>import path     from 'path'
import gulp     from 'gulp'
import {Server} from 'karma'

import appConfig    from '../../config/appConfig'

const {
    paths
} = appConfig

gulp.task('karma', ['env', 'clean'], done => {
    return new Server({
        configFile: path.join(paths.configs, 'karma.config.js'),
        singleRun: true,
        autoWatch: false
    }, () => {
        done()
    }).start()
})

// gulp.task('karma:watch', done => {
//     return new Server({
//         configFile: path.join(paths.configs, 'karma.config.js'),
//         singleRun: false,
//         autoWatch: true
//     }, () => {
//         done()
//     }).start()
// })
<commit_msg>removed gulp-task karma:watch<commit_after>import path      from 'path'
import gulp      from 'gulp'
import {Server}  from 'karma'

import appConfig from '../../config/appConfig'

const {
    paths
} = appConfig

gulp.task('karma', ['env', 'clean'], done => {
    return new Server({
        configFile: path.join(paths.configs, 'karma.config.js'),
        singleRun: true,
        autoWatch: false
    }, () => {
        done()
    }).start()
})
<|endoftext|>


<commit_before>'use strict';
import gulp         from 'gulp';
import plugins      from 'gulp-load-plugins';
import fs           from 'fs';
import panini       from 'panini';
import yaml         from 'js-yaml';
import async        from 'async';

// Load all Gulp plugins into one variable
const $ = plugins();

const { COMPATIBILITY, PORT, UNCSS_OPTIONS, PATHS } = loadConfig();

function loadConfig() {
  let ymlFile = fs.readFileSync('config.yml', 'utf8');
  return yaml.load(ymlFile);
}

function kitYaml(kits, prefix, datafile, cb) {
  async.eachOf(kits, (kit, name, callback) => {
    var obj = {total: kit.total, blocks: kit.blocks};
    obj.filename = name + '.html'
    obj.datafile = datafile;
    obj.datakey = name;
    obj.blocks = kit.blocks

    var str = "---\n" + yaml.safeDump(obj) + "---\n"
    fs.writeFile(PATHS.build + "/" + prefix + obj.filename, str, callback)
  }, cb)
}

// Resets Panini so that we can assemble using different layouts for the iframes and building block pages
function getNewPanini(options) {
  var p = new panini.Panini(options);
  p.loadBuiltinHelpers();
  p.refresh();
  return p.render()
}

function defaultTemplate(filename, blockname) {

  var text= '
{{> ' + blockname + '}}
'
  var src = require('stream').Readable({ objectMode: true })
  src._read = function () {
    this.push(new $.util.File({
      cwd: "",
      base: "",
      path: filename,
      contents: new Buffer(text)
    }))
    this.push(null)
  }
  return src
}

// Create building block layouts
function buildingBlockFrameLayouts() {
  return gulp.src(['src/building-blocks/*', '!src/building-blocks/*.scss'])
  .pipe($.foreach(function(stream, file) {
    var fileName = file.path.substr(file.path.lastIndexOf("/") + 1);
      var layout = file.path + "/layout.html";
      if (fs.existsSync(layout)) {
        gulp.src(layout)
        .pipe($.rename(function(path) {
          path.basename = fileName;
         }))
        .pipe(gulp.dest(PATHS.build + '/building-block/' + fileName + '/'));
      } else {
        defaultTemplate(fileName + '.html', fileName)
        .pipe(gulp.dest(PATHS.build + '/building-block/' + fileName + '/'));
      }
      return stream;
    }));
}

// Create a building block
function buildingBlockIframe() {
  return gulp.src(PATHS.build + '/building-block/**/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/building-blocks/iframe/',
      partials: 'src/building-blocks/*',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe($.rename(function (path) {
      path.basename += "-iframe";
    }))
    .pipe(gulp.dest(PATHS.dist + "/building-block/"));
  }

// Compiles the building block pages
function buildingBlockPage() {
  return gulp.src(PATHS.build + '/building-block/**/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/building-blocks/page/',
      partials: 'src/partials',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe(gulp.dest(PATHS.dist + "/building-block/"));
}

function kitsStarters(cb) {
  var kits = JSON.parse(fs.readFileSync(PATHS.build + '/data/kits.json', 'utf8'));
  fs.mkdir(PATHS.build + '/kits', () => {kitYaml(kits, 'kits/', 'kits.json', cb)})
}

// Compiles the building block pages
function kitsPages() {
  return gulp.src(PATHS.build + '/kits/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/kits/page/',
      partials: 'src/partials',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe(gulp.dest(PATHS.dist + "/kits/"));
}

gulp.task('kits-pages', gulp.series(kitsStarters, kitsPages));
gulp.task('building-block-pages', gulp.series(buildingBlockFrameLayouts, buildingBlockIframe, buildingBlockPage));
<commit_msg>The same of the commit a5195aa1e01cac783f7c222a31e013a075351be1<commit_after>'use strict';
import gulp         from 'gulp';
import plugins      from 'gulp-load-plugins';
import fs           from 'fs';
import panini       from 'panini';
import yaml         from 'js-yaml';
import async        from 'async';
import path         from 'path';

// Load all Gulp plugins into one variable
const $ = plugins();

const { COMPATIBILITY, PORT, UNCSS_OPTIONS, PATHS } = loadConfig();

function loadConfig() {
  let ymlFile = fs.readFileSync('config.yml', 'utf8');
  return yaml.load(ymlFile);
}

function kitYaml(kits, prefix, datafile, cb) {
  async.eachOf(kits, (kit, name, callback) => {
    var obj = {total: kit.total, blocks: kit.blocks};
    obj.filename = name + '.html'
    obj.datafile = datafile;
    obj.datakey = name;
    obj.blocks = kit.blocks

    var str = "---\n" + yaml.safeDump(obj) + "---\n"
    fs.writeFile(PATHS.build + "/" + prefix + obj.filename, str, callback)
  }, cb)
}

// Resets Panini so that we can assemble using different layouts for the iframes and building block pages
function getNewPanini(options) {
  var p = new panini.Panini(options);
  p.loadBuiltinHelpers();
  p.refresh();
  return p.render()
}

function defaultTemplate(filename, blockname) {

  var text= '
{{> ' + blockname + '}}
'
  var src = require('stream').Readable({ objectMode: true })
  src._read = function () {
    this.push(new $.util.File({
      cwd: "",
      base: "",
      path: filename,
      contents: new Buffer(text)
    }))
    this.push(null)
  }
  return src
}

// Create building block layouts
function buildingBlockFrameLayouts() {
  return gulp.src(['src/building-blocks/*', '!src/building-blocks/*.scss'])
  .pipe($.foreach(function(stream, file) {
    var fileName = file.path.substr(file.path.lastIndexOf(path.sep) + 1);
      var layout = file.path + "/layout.html";
      if (fs.existsSync(layout)) {
        gulp.src(layout)
        .pipe($.rename(function(path) {
          path.basename = fileName;
         }))
        .pipe(gulp.dest(PATHS.build + '/building-block/' + fileName + '/'));
      } else {
        defaultTemplate(fileName + '.html', fileName)
        .pipe(gulp.dest(PATHS.build + '/building-block/' + fileName + '/'));
      }
      return stream;
    }));
}

// Create a building block
function buildingBlockIframe() {
  return gulp.src(PATHS.build + '/building-block/**/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/building-blocks/iframe/',
      partials: 'src/building-blocks/*',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe($.rename(function (path) {
      path.basename += "-iframe";
    }))
    .pipe(gulp.dest(PATHS.dist + "/building-block/"));
  }

// Compiles the building block pages
function buildingBlockPage() {
  return gulp.src(PATHS.build + '/building-block/**/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/building-blocks/page/',
      partials: 'src/partials',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe(gulp.dest(PATHS.dist + "/building-block/"));
}

function kitsStarters(cb) {
  var kits = JSON.parse(fs.readFileSync(PATHS.build + '/data/kits.json', 'utf8'));
  fs.mkdir(PATHS.build + '/kits', () => {kitYaml(kits, 'kits/', 'kits.json', cb)})
}

// Compiles the building block pages
function kitsPages() {
  return gulp.src(PATHS.build + '/kits/*.{html,hbs,handlebars}')
    .pipe(getNewPanini({
      root: PATHS.build,
      layouts: 'src/layouts/kits/page/',
      partials: 'src/partials',
      data: ['src/data/', PATHS.build + '/data'],
      helpers: 'src/panini-helpers/'
    }))
    .pipe(gulp.dest(PATHS.dist + "/kits/"));
}

gulp.task('kits-pages', gulp.series(kitsStarters, kitsPages));
gulp.task('building-block-pages', gulp.series(buildingBlockFrameLayouts, buildingBlockIframe, buildingBlockPage));
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'; // eslint-disable-line
import Match from 'react-router/Match'; // eslint-disable-line
import {Row, Col} from 'react-bootstrap'; // eslint-disable-line

/* shared stripes components */
import Pane from '@folio/stripes-components/lib/Pane'; // eslint-disable-line
import Paneset from '@folio/stripes-components/lib/Paneset'; // eslint-disable-line
import PaneMenu from '@folio/stripes-components/lib/PaneMenu'; // eslint-disable-line
import Button from '@folio/stripes-components/lib/Button'; // eslint-disable-line
import Icon from '@folio/stripes-components/lib/Icon'; // eslint-disable-line
import MultiColumnListUsers from './lib/MultiColumnList'; // eslint-disable-line
import KeyValue from '@folio/stripes-components/lib/KeyValue'; // eslint-disable-line
import TextField from '@folio/stripes-components/lib/TextField'; // eslint-disable-line
import Checkbox from '@folio/stripes-components/lib/Checkbox'; // eslint-disable-line
import FilterPaneSearch from '@folio/stripes-components/lib/FilterPaneSearch'; // eslint-disable-line
import FilterControlGroup from '@folio/stripes-components/lib/FilterControlGroup'; // eslint-disable-line
import Select from '@folio/stripes-components/lib/Select'; // eslint-disable-line
import Layer from '@folio/stripes-components/lib/Layer'; // eslint-disable-line

import UserForm from './UserForm';
import ViewUser from './ViewUser';

class Users extends Component {
  static contextTypes = {
    router: PropTypes.object.isRequired,
  }

  static propTypes = {
    data: PropTypes.object.isRequired,
    pathname: PropTypes.string.isRequired,
    location: PropTypes.object.isRequired,
    mutator: PropTypes.object,
  };

  static manifest = {
    searchResults: [],
    /* detail: {
      fineHistory:[]
    } */
    user: {
      type: 'okapi',
      path: 'users',
      fetch: false,
    },
    users: {
      type: 'okapi',
      records: 'users',
      path: 'users?query=(username="?{query}*" or personal.first_name="?{query}*" or personal.last_name="?{query}*") ?{sort:+sortby} ?{sort:-}',
      staticFallback: { path: 'users' },
    },
  };

  constructor(props) {
    super(props);
    this.state = {
      // Search/Filter state
      activeFilter: true,
      inactiveFilter: false,
      searchTerm: '',
      sortOrder: '',
      addUserMode: false,
    };

    this.onClickAddNewUser = this.onClickAddNewUser.bind(this);
    this.onClickCloseNewUser = this.onClickCloseNewUser.bind(this);
    this.onChangeFilter = this.onChangeFilter.bind(this);
    this.onChangeSearch = this.onChangeSearch.bind(this);
    this.onClearSearch = this.onClearSearch.bind(this);
    this.onSortHandler = this.onSortHandler.bind(this);
    this.onClickItemHandler = this.onClickItemHandler.bind(this);
  }

  componentWillMount() {
    const resultData = [{ Name: 'Pete Sherman', Address: '391 W. Richardson St. Duarte, CA 91010', Fines: '$34.23' }];
    // const fineHistory = [{"Due Date": "11/12/2014", "Amount":"34.23", "Status":"Unpaid"}];
    this.props.mutator.searchResults.replace(resultData);
    // this.props.mutator.detail.replace({fineHistory: fineHistory});
  }

  // search Handlers...
  onChangeFilter(e) {
    const stateObj = {};
    stateObj[e.target.id] = !this.state[e.target.id];
    this.setState(stateObj);
  }

  onChangeSearch(e) {
    const query = e.target.value;
    console.log(`User searched for '${query}' at '${this.props.location.pathname}'`);

    this.setState({ searchTerm: query });
    this.updateSearchSort(query, this.state.sortOrder);
  }

  onClearSearch() {
    console.log('User cleared search');
    this.setState({ searchTerm: '' });
    this.context.router.transitionTo(this.props.location.pathname);
  }

  onSortHandler(heading) {
    const sortMap = {
      Name: 'personal.last_name, personal.first_name',
      Username: 'username',
      Email: 'personal.email',
    };
    const sortOrder = sortMap[heading];
    console.log('User sorted by', sortOrder);
    this.setState({ sortOrder });
    this.updateSearchSort(this.state.searchTerm, sortOrder);
  }

  onClickItemHandler(userId) {
    console.log('User clicked', userId, 'location = ', this.props.location);
    this.context.router.transitionTo(`/users/view/${userId}${this.props.location.search}`);
  }

  // end search Handlers

  // AddUser Handlers
  onClickAddNewUser() {
    console.log('add Clicked');
    this.setState({
      addUserMode: true,
    });
  }

  onClickCloseNewUser() {
    this.setState({
      addUserMode: false,
    });
  }
  // end AddUser Handlers

  updateSearchSort(query, sortOrder) {
    console.log(`updateSearchSort('${query}', '${sortOrder}')`);
    let transitionLoc = this.props.location.pathname;
    // if (sortOrder && !query) query = "cql.allRecords=1";
    if (query) transitionLoc += `?query=${query}`;
    if (sortOrder) {
      transitionLoc += query ? '&' : '?';
      transitionLoc += `sort=${sortOrder}`;
    }
    this.context.router.transitionTo(transitionLoc);
  }

  create(data) {
    this.props.mutator.user.POST(data);
  }

  render() {
    const { data, pathname } = this.props;
    if (!data.users) return <div />;
    const resultMenu = <PaneMenu><button><Icon icon="bookmark" /></button></PaneMenu>;
    const fineHistory = [{ 'Due Date': '11/12/2014', 'Amount': '34.23', 'Status': 'Unpaid' }]; // eslint-disable-line
    const displayUsers = data.users.reduce((results, user) => {
      results.push({
        id: user.id,
        Name: `${user.personal.last_name}, ${user.personal.first_name}`,
        Username: user.username,
        Email: user.personal.email,
      });
      return results;
    }, []);

    /* searchHeader is a 'custom pane header'*/
    const searchHeader = <FilterPaneSearch id="SearchField" onChange={this.onChangeSearch} onClear={this.onClearSearch} value={this.state.searchTerm} />;

    return (
      <Paneset>
        {/* Filter Pane */}
        <Pane defaultWidth="16%" header={searchHeader}>
          <FilterControlGroup label="Filters">
            <Checkbox
              id="activeFilter"
              label="Active"
              checked={this.state.activeFilter}
              onChange={this.onChangeFilter}
              marginBottom0
              hover
              fullWidth
              checkedIcon={<Icon icon="eye" />}
            />
            <Checkbox
              id="inactiveFilter"
              label="Inactive"
              checked={this.state.inactiveFilter}
              onChange={this.onChangeFilter}
              marginBottom0
              hover
              fullWidth
              checkedIcon={<Icon icon="eye" />}
            />
          </FilterControlGroup>
          <FilterControlGroup label="Actions">
            <Button fullWidth onClick={this.onClickAddNewUser}>Add User</Button>
          </FilterControlGroup>
        </Pane>

        {/* Results Pane */}
        <Pane defaultWidth="32%" paneTitle="Results" lastMenu={resultMenu}>
          <MultiColumnListUsers
            contentData={displayUsers}
            onClickItemHandler={this.onClickItemHandler}
            onSortHandler={this.onSortHandler}
          />
        </Pane>

        {/* Details Pane */}
        <Match pattern={`${pathname}/view/:userid`} component={ViewUser} />
        <Layer isOpen={this.state.addUserMode} label="Add New User Dialog">
          <UserForm
            onSubmit={(record) => { this.create(record); }}
            onCancel={this.onClickCloseNewUser}
          />
        </Layer>
      </Paneset>
    );
  }
}

export default Users;
<commit_msg>Now that DMOD-150 is resolved (as invalid), I have reinstated the "null search" for * used as a fallback before a query has been specified. Resolves STRIPES-134.<commit_after>import React, { Component, PropTypes } from 'react'; // eslint-disable-line
import Match from 'react-router/Match'; // eslint-disable-line
import {Row, Col} from 'react-bootstrap'; // eslint-disable-line

/* shared stripes components */
import Pane from '@folio/stripes-components/lib/Pane'; // eslint-disable-line
import Paneset from '@folio/stripes-components/lib/Paneset'; // eslint-disable-line
import PaneMenu from '@folio/stripes-components/lib/PaneMenu'; // eslint-disable-line
import Button from '@folio/stripes-components/lib/Button'; // eslint-disable-line
import Icon from '@folio/stripes-components/lib/Icon'; // eslint-disable-line
import MultiColumnListUsers from './lib/MultiColumnList'; // eslint-disable-line
import KeyValue from '@folio/stripes-components/lib/KeyValue'; // eslint-disable-line
import TextField from '@folio/stripes-components/lib/TextField'; // eslint-disable-line
import Checkbox from '@folio/stripes-components/lib/Checkbox'; // eslint-disable-line
import FilterPaneSearch from '@folio/stripes-components/lib/FilterPaneSearch'; // eslint-disable-line
import FilterControlGroup from '@folio/stripes-components/lib/FilterControlGroup'; // eslint-disable-line
import Select from '@folio/stripes-components/lib/Select'; // eslint-disable-line
import Layer from '@folio/stripes-components/lib/Layer'; // eslint-disable-line

import UserForm from './UserForm';
import ViewUser from './ViewUser';

class Users extends Component {
  static contextTypes = {
    router: PropTypes.object.isRequired,
  }

  static propTypes = {
    data: PropTypes.object.isRequired,
    pathname: PropTypes.string.isRequired,
    location: PropTypes.object.isRequired,
    mutator: PropTypes.object,
  };

  static manifest = {
    searchResults: [],
    /* detail: {
      fineHistory:[]
    } */
    user: {
      type: 'okapi',
      path: 'users',
      fetch: false,
    },
    users: {
      type: 'okapi',
      records: 'users',
      path: 'users?query=(username="?{query:-}*" or personal.first_name="?{query:-}*" or personal.last_name="?{query:-}*") ?{sort:+sortby} ?{sort:-}',
      staticFallback: { path: 'users' },
    },
  };

  constructor(props) {
    super(props);
    this.state = {
      // Search/Filter state
      activeFilter: true,
      inactiveFilter: false,
      searchTerm: '',
      sortOrder: '',
      addUserMode: false,
    };

    this.onClickAddNewUser = this.onClickAddNewUser.bind(this);
    this.onClickCloseNewUser = this.onClickCloseNewUser.bind(this);
    this.onChangeFilter = this.onChangeFilter.bind(this);
    this.onChangeSearch = this.onChangeSearch.bind(this);
    this.onClearSearch = this.onClearSearch.bind(this);
    this.onSortHandler = this.onSortHandler.bind(this);
    this.onClickItemHandler = this.onClickItemHandler.bind(this);
  }

  componentWillMount() {
    const resultData = [{ Name: 'Pete Sherman', Address: '391 W. Richardson St. Duarte, CA 91010', Fines: '$34.23' }];
    // const fineHistory = [{"Due Date": "11/12/2014", "Amount":"34.23", "Status":"Unpaid"}];
    this.props.mutator.searchResults.replace(resultData);
    // this.props.mutator.detail.replace({fineHistory: fineHistory});
  }

  // search Handlers...
  onChangeFilter(e) {
    const stateObj = {};
    stateObj[e.target.id] = !this.state[e.target.id];
    this.setState(stateObj);
  }

  onChangeSearch(e) {
    const query = e.target.value;
    console.log(`User searched for '${query}' at '${this.props.location.pathname}'`);

    this.setState({ searchTerm: query });
    this.updateSearchSort(query, this.state.sortOrder);
  }

  onClearSearch() {
    console.log('User cleared search');
    this.setState({ searchTerm: '' });
    this.context.router.transitionTo(this.props.location.pathname);
  }

  onSortHandler(heading) {
    const sortMap = {
      Name: 'personal.last_name, personal.first_name',
      Username: 'username',
      Email: 'personal.email',
    };
    const sortOrder = sortMap[heading];
    console.log('User sorted by', sortOrder);
    this.setState({ sortOrder });
    this.updateSearchSort(this.state.searchTerm, sortOrder);
  }

  onClickItemHandler(userId) {
    console.log('User clicked', userId, 'location = ', this.props.location);
    this.context.router.transitionTo(`/users/view/${userId}${this.props.location.search}`);
  }

  // end search Handlers

  // AddUser Handlers
  onClickAddNewUser() {
    console.log('add Clicked');
    this.setState({
      addUserMode: true,
    });
  }

  onClickCloseNewUser() {
    this.setState({
      addUserMode: false,
    });
  }
  // end AddUser Handlers

  updateSearchSort(query, sortOrder) {
    console.log(`updateSearchSort('${query}', '${sortOrder}')`);
    let transitionLoc = this.props.location.pathname;
    // if (sortOrder && !query) query = "cql.allRecords=1";
    if (query) transitionLoc += `?query=${query}`;
    if (sortOrder) {
      transitionLoc += query ? '&' : '?';
      transitionLoc += `sort=${sortOrder}`;
    }
    this.context.router.transitionTo(transitionLoc);
  }

  create(data) {
    this.props.mutator.user.POST(data);
  }

  render() {
    const { data, pathname } = this.props;
    if (!data.users) return <div />;
    const resultMenu = <PaneMenu><button><Icon icon="bookmark" /></button></PaneMenu>;
    const fineHistory = [{ 'Due Date': '11/12/2014', 'Amount': '34.23', 'Status': 'Unpaid' }]; // eslint-disable-line
    const displayUsers = data.users.reduce((results, user) => {
      results.push({
        id: user.id,
        Name: `${user.personal.last_name}, ${user.personal.first_name}`,
        Username: user.username,
        Email: user.personal.email,
      });
      return results;
    }, []);

    /* searchHeader is a 'custom pane header'*/
    const searchHeader = <FilterPaneSearch id="SearchField" onChange={this.onChangeSearch} onClear={this.onClearSearch} value={this.state.searchTerm} />;

    return (
      <Paneset>
        {/* Filter Pane */}
        <Pane defaultWidth="16%" header={searchHeader}>
          <FilterControlGroup label="Filters">
            <Checkbox
              id="activeFilter"
              label="Active"
              checked={this.state.activeFilter}
              onChange={this.onChangeFilter}
              marginBottom0
              hover
              fullWidth
              checkedIcon={<Icon icon="eye" />}
            />
            <Checkbox
              id="inactiveFilter"
              label="Inactive"
              checked={this.state.inactiveFilter}
              onChange={this.onChangeFilter}
              marginBottom0
              hover
              fullWidth
              checkedIcon={<Icon icon="eye" />}
            />
          </FilterControlGroup>
          <FilterControlGroup label="Actions">
            <Button fullWidth onClick={this.onClickAddNewUser}>Add User</Button>
          </FilterControlGroup>
        </Pane>

        {/* Results Pane */}
        <Pane defaultWidth="32%" paneTitle="Results" lastMenu={resultMenu}>
          <MultiColumnListUsers
            contentData={displayUsers}
            onClickItemHandler={this.onClickItemHandler}
            onSortHandler={this.onSortHandler}
          />
        </Pane>

        {/* Details Pane */}
        <Match pattern={`${pathname}/view/:userid`} component={ViewUser} />
        <Layer isOpen={this.state.addUserMode} label="Add New User Dialog">
          <UserForm
            onSubmit={(record) => { this.create(record); }}
            onCancel={this.onClickCloseNewUser}
          />
        </Layer>
      </Paneset>
    );
  }
}

export default Users;
<|endoftext|>


<commit_before><commit_msg>Remove empty file<commit_after><|endoftext|>


<commit_before>'use strict';

var assign            = require('es5-ext/object/assign')
  , forEach           = require('es5-ext/object/for-each')
  , startsWith        = require('es5-ext/string/#/starts-with')
  , toArray           = require('es5-ext/array/to-array')
  , d                 = require('d')
  , autoBind          = require('d/auto-bind')
  , memoize           = require('memoizee/plain')
  , isObservable      = require('observable-value/is-observable')
  , makeElement       = require('dom-ext/document/#/make-element')
  , castAttribute     = require('dom-ext/element/#/cast-attribute')
  , replaceContent    = require('dom-ext/element/#/replace-content')
  , resolveObservable = require('./resolve-observable')
  , DOMComposite      = require('../_composite')
  , htmlAttributes    = require('../_html-attributes')
  , setup             = require('../')

  , defineProperty = Object.defineProperty
  , getObservable, Fieldset;

getObservable = function (name) {
	return resolveObservable(this, name);
};

Fieldset = function (document, list/*, options*/) {
	var options = Object(arguments[2]);

	this.document = document;
	this.list = list;
	this.items = {};
	this.options = Object(options.control);
	this.customOptions = Object(options.controls);
	this.prepend = options.prepend;
	this.append = options.append;

	this.list = list.map(this.renderItem, this);
	if (isObservable(this.list)) this.list.on('change', this.reload);

	this.render();
	forEach(options, function (value, name) {
		if (!htmlAttributes[name] && !startsWith.call(name, 'data-')) return;
		castAttribute.call(this.dom, name, value);
	}, this);
	this.dom.classList.add('dbjs');
	this.dom._dbjsFieldset = this;

	this.reload();
};

Object.defineProperties(Fieldset.prototype, assign({
	render: d(function () {
		var el = makeElement.bind(this.document);
		this.dom = el('fieldset', this.domItems = el('ul'));
	}),
	renderItem: d(function (observable) {
		var options = this.getOptions(observable.ownDescriptor), field, dom, li;
		field = observable.toDOMInputComponent(this.document, options);
		this.items[observable.dbId] = field;
		dom = field.toDOM(this.document);
		if (dom.nodeName.toLowerCase() === 'li') return dom;
		li = this.document.createElement('li');
		li.appendChild(dom);
		return li;
	}),
	toDOM: d(function () { return this.dom; }),
	getOptions: d(DOMComposite.prototype.getOptions)
}, autoBind({
	reload: d(function () {
		replaceContent.call(this.domItems, this.prepend, this.list, this.append);
	})
})));

module.exports = exports = memoize(function (db) {
	var proto = setup(db).Base.prototype;

	defineProperty(db.Base, 'DOMFieldset', d(Fieldset));

	defineProperty(proto, 'toDOMFieldset', d(function (document/*, options*/) {
		var options = Object(arguments[1]), data, names;

		if (options.names != null) {
			names = options.names;
			if (!names.map) names = toArray(names);
			data = names.map(getObservable, this);
		} else {
			data = this.toSet('key').toArray().map(getObservable, this);
		}

		if (options.include) {
			throw new TypeError("`include` option is (postponed). Fix it");
		}

		return new db.Base.DOMFieldset(document, data, options);
	}));
}, { normalizer: require('memoizee/normalizers/get-1')() });

exports.Fieldset = Fieldset;
<commit_msg>Fix resolveObservable<commit_after>'use strict';

var assign          = require('es5-ext/object/assign')
  , forEach         = require('es5-ext/object/for-each')
  , startsWith      = require('es5-ext/string/#/starts-with')
  , toArray         = require('es5-ext/array/to-array')
  , d               = require('d')
  , autoBind        = require('d/auto-bind')
  , memoize         = require('memoizee/plain')
  , isObservable    = require('observable-value/is-observable')
  , makeElement     = require('dom-ext/document/#/make-element')
  , castAttribute   = require('dom-ext/element/#/cast-attribute')
  , replaceContent  = require('dom-ext/element/#/replace-content')
  , resolveProperty = require('dbjs/_setup/utils/resolve-property-path')
  , DOMComposite    = require('../_composite')
  , htmlAttributes  = require('../_html-attributes')
  , setup           = require('../')

  , defineProperty = Object.defineProperty
  , getObservable, Fieldset;

getObservable = function (name) {
	var result = resolveProperty(this, name);
	return result.object.getObservable(result.key);
};

Fieldset = function (document, list/*, options*/) {
	var options = Object(arguments[2]);

	this.document = document;
	this.list = list;
	this.items = {};
	this.options = Object(options.control);
	this.customOptions = Object(options.controls);
	this.prepend = options.prepend;
	this.append = options.append;

	this.list = list.map(this.renderItem, this);
	if (isObservable(this.list)) this.list.on('change', this.reload);

	this.render();
	forEach(options, function (value, name) {
		if (!htmlAttributes[name] && !startsWith.call(name, 'data-')) return;
		castAttribute.call(this.dom, name, value);
	}, this);
	this.dom.classList.add('dbjs');
	this.dom._dbjsFieldset = this;

	this.reload();
};

Object.defineProperties(Fieldset.prototype, assign({
	render: d(function () {
		var el = makeElement.bind(this.document);
		this.dom = el('fieldset', this.domItems = el('ul'));
	}),
	renderItem: d(function (observable) {
		var options = this.getOptions(observable.ownDescriptor), field, dom, li;
		field = observable.toDOMInputComponent(this.document, options);
		this.items[observable.dbId] = field;
		dom = field.toDOM(this.document);
		if (dom.nodeName.toLowerCase() === 'li') return dom;
		li = this.document.createElement('li');
		li.appendChild(dom);
		return li;
	}),
	toDOM: d(function () { return this.dom; }),
	getOptions: d(DOMComposite.prototype.getOptions)
}, autoBind({
	reload: d(function () {
		replaceContent.call(this.domItems, this.prepend, this.list, this.append);
	})
})));

module.exports = exports = memoize(function (db) {
	var proto = setup(db).Base.prototype;

	defineProperty(db.Base, 'DOMFieldset', d(Fieldset));

	defineProperty(proto, 'toDOMFieldset', d(function (document/*, options*/) {
		var options = Object(arguments[1]), data, names;

		if (options.names != null) {
			names = options.names;
			if (!names.map) names = toArray(names);
			data = names.map(getObservable, this);
		} else {
			data = this.toSet('key').toArray().map(getObservable, this);
		}

		if (options.include) {
			throw new TypeError("`include` option is (postponed). Fix it");
		}

		return new db.Base.DOMFieldset(document, data, options);
	}));
}, { normalizer: require('memoizee/normalizers/get-1')() });

exports.Fieldset = Fieldset;
<|endoftext|>


<commit_before>'use strict'

const { promisify } = require('util')

const Nodemon = require('nodemon')

const nodemonDevConfig = require('../../nodemon')
const nodemonDebugConfig = require('../../nodemon.debug')
const gulpExeca = require('../exec')

// We use this instead of requiring the application to test the CLI
const start = gulpExeca.bind(null, '../bin/autoserver.js', { cwd: 'examples' })

// eslint-disable-next-line fp/no-mutation
start.description = 'Start an example production server'

const dev = function() {
  return startNodemon(nodemonDevConfig)
}

// eslint-disable-next-line fp/no-mutation
dev.description = 'Start an example dev server in watch mode'

const debug = function() {
  return startNodemon(nodemonDebugConfig)
}

// eslint-disable-next-line fp/no-mutation
debug.description = 'Start an example dev server in debug mode'

const startNodemon = async function(config) {
  const nodemon = new Nodemon(config)

  // Otherwise Nodemon's log does not appear
  // eslint-disable-next-line no-restricted-globals
  nodemon.on('log', ({ colour }) => global.console.log(colour))

  await promisify(nodemon.on.bind(nodemon))('start')
}

module.exports = {
  start,
  dev,
  debug,
}
<commit_msg>Fix task name<commit_after>'use strict'

const { promisify } = require('util')

const Nodemon = require('nodemon')

const nodemonDevConfig = require('../../nodemon')
const nodemonDebugConfig = require('../../nodemon.debug')
const gulpExeca = require('../exec')

// We use this instead of requiring the application to test the CLI
const start = () => gulpExeca('../bin/autoserver.js', { cwd: 'examples' })

// eslint-disable-next-line fp/no-mutation
start.description = 'Start an example production server'

const dev = function() {
  return startNodemon(nodemonDevConfig)
}

// eslint-disable-next-line fp/no-mutation
dev.description = 'Start an example dev server in watch mode'

const debug = function() {
  return startNodemon(nodemonDebugConfig)
}

// eslint-disable-next-line fp/no-mutation
debug.description = 'Start an example dev server in debug mode'

const startNodemon = async function(config) {
  const nodemon = new Nodemon(config)

  // Otherwise Nodemon's log does not appear
  // eslint-disable-next-line no-restricted-globals
  nodemon.on('log', ({ colour }) => global.console.log(colour))

  await promisify(nodemon.on.bind(nodemon))('start')
}

module.exports = {
  start,
  dev,
  debug,
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var config = require('../config.js');
var plugins = require('gulp-load-plugins')();

gulp.task("livereload", function () {
    plugins.livereload.listen(config.livereloadPort);

    return gulp.watch(config.livereloadPaths)
        .on('change', plugins.livereload.changed);
});

gulp.task('watch', function () {
    gulp.watch(config.watchScripts, ["scripts:watch"]);
    gulp.watch(config.watchStyles, ["styles"]);
    gulp.watch(config.watchImages, ["images"]);
    gulp.watch(config.watchIcons, ["icons"]);
    gulp.watch(config.watchFonts, ["fonts"]);

    return gulp.start('livereload');
});<commit_msg>Bugfix<commit_after>var gulp = require('gulp');
var config = require('../config.js');
var plugins = require('gulp-load-plugins')();

gulp.task("livereload", function () {
    plugins.livereload.listen(config.livereloadPort);

    return gulp.watch(config.livereloadPaths)
        .on('change', plugins.livereload.changed);
});

gulp.task('watch', function () {
    gulp.watch(config.watchScripts, ["scripts:watch"]);
    gulp.watch(config.watchStyles, ["styles"]);
    gulp.watch(config.watchImages, ["images"]);
    gulp.watch(config.watchIcons, ["icons"]);
    gulp.watch(config.watchFonts, ["copy"]);

    return gulp.start('livereload');
});
<|endoftext|>


<commit_before>/**
 * Lecteur multimedia Intermezzo.
 * @author Doppelganger & $imon
 * @version 2.0
 */
new W.ScriptFile('usr/lib/intermezzo/jquery.jplayer.min.js');
new W.ScriptFile('usr/lib/webos/fullscreen.js');
new W.Stylesheet('usr/share/css/intermezzo/main.css');

var intermezzoProperties = $.webos.extend($.webos.properties.get('container'), {
	_name: 'intermezzo',
	options: {
		file: undefined
	},
	_translationsName: 'intermezzo',
	_create: function() {
		if (Webos.isInstanceOf(this.options.file, W.File)) {
			this.open(this.options.file);
		} else {
			this.loadEmpty();
		}
	},
	_loadProfile: function(type, callback) {
		callback = Webos.Callback.toCallback(callback);
		var that = this, t = this.translations();

		if (!type) {
			callback.error(new Webos.Callback.Result.error(t.get('Unknown driver')));
			return;
		}

		this.options.type = type;

		$.ajax({
			url: 'usr/lib/intermezzo/html/'+type+'.html',
			success: function(response) {
				that.element.html(response);
				callback.success();
				that._trigger('loadprofile');
			},
			error: function() {
				callback.error(new Webos.Callback.Result.error(t.get('Can\'t load media player\'s profile "${type}"', { type: type })));
			}
		});
	},
	_initPlayer: function(supplied, userCallback) {
		var that = this, t = this.translations();

		this.options._components.player = this.element.find('.jp-jplayer').jPlayer({
			swfPath: 'usr/lib/intermezzo/swf',
			supplied: supplied,
			solution: 'html,flash',
			cssSelectorAncestor: '#'+that.element.attr('id')+' .jp-'+that.options.type,
			ready: function() {
				var hideCursorTimeout, mousePosition = [];
				var cursorTimeoutFn = function(e) {
					that.element.find('.jp-video .jp-jplayer').addClass('cursor-none');
					hideCursorTimeout = undefined;
				};
				var mousemoveFn = function(e) {
					if (typeof mousePosition != 'undefined') {
						if (mousePosition[0] == e.pageX && mousePosition[1] == e.pageY) {
							return;
						}
					}
					if (typeof hideCursorTimeout != 'undefined') {
						 clearTimeout(hideCursorTimeout);
					}
					that.element.find('.jp-video .jp-jplayer').removeClass('cursor-none');
					hideCursorTimeout = setTimeout(cursorTimeoutFn, 5000);

					mousePosition = [e.pageX, e.pageY];
				};

				hideCursorTimeout = setTimeout(cursorTimeoutFn, 5000);
				that.element.find('.jp-video .jp-jplayer').mousemove(mousemoveFn);

				that.element.find('.jp-full-screen').click(function() {
					if (Webos.fullscreen.support) {
						that.element.find('.jp-video').requestFullScreen();
					} else {
						$('#header').animate({
							top: '-=25px'
						});
						$('#footer').animate({
							bottom: '-=25px'
						});
					}
				});

				that.element.find('.jp-restore-screen').click(function() {
					if (Webos.fullscreen.support) {
						Webos.fullscreen.cancel();
					} else {
						$('#header').animate({
							top: '+=25px'
						});
						$('#footer').animate({
							bottom: '+=25px'
						});
					}
				});

				that._trigger('ready');

				if (typeof userCallback != 'undefined') {
					userCallback();
				}
			},
			error: function(e) {
				var mess = t.get('An error has occurred with the multimedia player jPlayer');
				switch (e.jPlayer.error.type) {
					case $.jPlayer.error.FLASH:
						mess = t.get('An error occurred while inserting the video with Flash plugin');
						break;
					case $.jPlayer.error.FLASH_DISABLED:
						mess = t.get('An error has occurred with the Flash plugin, which has been disabled');
						break;
					case $.jPlayer.error.NO_SOLUTION:
						mess = t.get('Can\'t read the media, your browser is outdated');
						break;
					case $.jPlayer.error.NO_SUPPORT:
						mess = t.get('Can\'t read the media, file format not supported');
						break;
					case $.jPlayer.error.URL:
						mess = t.get('Can\'t read the media, the file path is invalid');
						break;
					case $.jPlayer.error.URL_NOT_SET:
						return;
						break;
					case $.jPlayer.error.VERSION:
						mess = t.get('Your Javascript and Flash version is not supported');
						break;
				}
				W.Error.trigger(mess, e.jPlayer.error.message+"\n"+e.jPlayer.error.hint);
			}
		});
	},
	play: function() {
		this.player().jPlayer('play');
	},
	open: function(file) {
		this.options.file = file;
		if (typeof this.options.file == 'undefined') {
			return;
		}
		var supported = true,
			fileObject = {},
			type = 'audio',
			supplied = '',
			filepath = this.options.file.get('realpath');

		switch (this.options.file.get('extension')) { // selon les types MIME, on cré une playlist différente
			case 'mp3':
				fileObject = {
					mp3: filepath
				};
				supplied = "mp3";
				type = 'audio';
			break;
			case 'oga':
				fileObject = {
					oga: filepath
				};
				supplied = "oga";
				type = 'audio';
			break;
			case 'ogg':
				fileObject = {
					ogv: filepath
				};
				supplied = "ogv";
				type = 'video';
			break;
			case 'ogv':
				fileObject = {
					ogv: filepath
				};
				supplied = "ogv";
				type = 'video';
			break;
			case 'mp4':
				fileObject = {
					mp4: filepath
				};
				supplied = "m4v";
				type = 'video';
			break;
			case 'm4v':
				fileObject = {
					m4v: filepath
				};
				supplied = "m4v";
				type = 'video';
			break;
			case 'm4a':
				fileObject = {
					m4a: filepath
				};
				supplied = "m4a";
				type = 'audio';
			break;
			case 'wav':
				fileObject = {
					wav: filepath
				};
				supplied = "wav";
			break;
			case 'webma':
				fileObject = {
					webma:filepath
				};
				supplied = "webma";
				type = 'audio';
			break;
			case 'webmv':
				fileObject = {
					webmv:filepath
				};
				supplied = "webmv";
				type = 'video';
			break;
			case 'webm':
				fileObject = {
					webmv:filepath
				};
				supplied = "webmv";
				type = 'video';
			break;
			default:
				supported = false;
		}

		this.options.type = type;

		var that = this, t = this.translations();

		this._loadProfile(type, function() {
			if (!supported) {
				W.Error.trigger(t.get('Can\'t open file "${basename}"', { basename: that.options.file.get('basename') }), t.get('Unsupported file type'));
				that.loadEmpty();
				return;
			}

			that._initPlayer(supplied, function() {
				that.player()
					.jPlayer('setMedia', fileObject)
					.jPlayer('play');
				that._trigger('play');
			});
		});
	},
	loadEmpty: function(callback) {
		var that = this;

		this._loadProfile('audio', function() {
			that._initPlayer('mp3', callback);
		});
	},
	player: function() {
		return this.options._components.player;
	}
});
$.webos.widget('intermezzo', intermezzoProperties);

$.webos.intermezzo = function(options) {
	return $('

').intermezzo(options);
};

// Application sous forme de classe
window.IntermezzoWindow = function IntermezzoWindow(options) {
	Webos.Observable.call(this);

	this.bind('translationsloaded', function() {
		var that = this, t = this._translations;

		this.window = $.w.window({
			title : t.get('Intermezzo multimedia player'),
			icon: new W.Icon('applications/intermezzo')
		});

		var headers = this.window.window('header');

		this._menu = $.w.menuWindowHeader().appendTo(headers);

		var fileItem = $.w.menuItem(t.get('File')).appendTo(this._menu);
		fileItemContent = fileItem.menuItem('content');

		$.w.menuItem(t.get('Open'))
			.click(function() {
				new NautilusFileSelectorWindow({
					parentWindow: that.window
				}, function(files) {
					if (files.length) {
						that.player.intermezzo('open', files[0]);
					}
				});
			})
			.appendTo(fileItemContent);

		$.w.menuItem(t.get('Quit'))
			.click(function() {
				that.window.window('close');
			})
			.appendTo(fileItemContent);

		this.player = $.webos.intermezzo({
			file: options.file
		});

		var resizeFn = function() {
			var windowsContent = that.window.window('content'),
				windowsWidth = windowsContent.innerWidth(),
				cssClass;

			if (windowsWidth < 480) {
				cssClass = '';
			} else if (windowsWidth < 640) {
				cssClass = 'jp-video-270p';
			} else {
				cssClass = 'jp-video-360p';
			}
			that.player.intermezzo('player').jPlayer('option', 'size', { cssClass: cssClass });
		};

		this.window.bind('windowresize', resizeFn);

		this.player.appendTo(this.window.window('content'));

		this.window.window('open');

		this.player.bind('intermezzoloadprofile', function() {
			that.window.window('center');
		});

		resizeFn();
		this.notify('ready');
	});

	Webos.TranslatedLibrary.call(this);
};
IntermezzoWindow.prototype = {
	_translationsName: 'intermezzo'
};
Webos.inherit(IntermezzoWindow, Webos.Observable);
Webos.inherit(IntermezzoWindow, Webos.TranslatedLibrary);<commit_msg>Fixed issue #123. Fixed a bug when opening Intermezzo without specifying a file to open.<commit_after>/**
 * Lecteur multimedia Intermezzo.
 * @author Doppelganger & $imon
 * @version 2.0
 */
new W.ScriptFile('usr/lib/intermezzo/jquery.jplayer.min.js');
new W.ScriptFile('usr/lib/webos/fullscreen.js');
new W.Stylesheet('usr/share/css/intermezzo/main.css');

var intermezzoProperties = $.webos.extend($.webos.properties.get('container'), {
	_name: 'intermezzo',
	options: {
		file: undefined
	},
	_translationsName: 'intermezzo',
	_create: function() {
		if (Webos.isInstanceOf(this.options.file, W.File)) {
			this.open(this.options.file);
		} else {
			this.loadEmpty();
		}
	},
	_loadProfile: function(type, callback) {
		callback = Webos.Callback.toCallback(callback);
		var that = this, t = this.translations();

		if (!type) {
			callback.error(new Webos.Callback.Result.error(t.get('Unknown driver')));
			return;
		}

		this.options.type = type;

		$.ajax({
			url: 'usr/lib/intermezzo/html/'+type+'.html',
			success: function(response) {
				that.element.html(response);
				callback.success();
				that._trigger('loadprofile');
			},
			error: function() {
				callback.error(new Webos.Callback.Result.error(t.get('Can\'t load media player\'s profile "${type}"', { type: type })));
			}
		});
	},
	_initPlayer: function(supplied, userCallback) {
		var that = this, t = this.translations();

		this.options._components.player = this.element.find('.jp-jplayer').jPlayer({
			swfPath: 'usr/lib/intermezzo/swf',
			supplied: supplied,
			solution: 'html,flash',
			cssSelectorAncestor: '#'+that.element.attr('id')+' .jp-'+that.options.type,
			ready: function() {
				var hideCursorTimeout, mousePosition = [];
				var cursorTimeoutFn = function(e) {
					that.element.find('.jp-video .jp-jplayer').addClass('cursor-none');
					hideCursorTimeout = undefined;
				};
				var mousemoveFn = function(e) {
					if (typeof mousePosition != 'undefined') {
						if (mousePosition[0] == e.pageX && mousePosition[1] == e.pageY) {
							return;
						}
					}
					if (typeof hideCursorTimeout != 'undefined') {
						 clearTimeout(hideCursorTimeout);
					}
					that.element.find('.jp-video .jp-jplayer').removeClass('cursor-none');
					hideCursorTimeout = setTimeout(cursorTimeoutFn, 5000);

					mousePosition = [e.pageX, e.pageY];
				};

				hideCursorTimeout = setTimeout(cursorTimeoutFn, 5000);
				that.element.find('.jp-video .jp-jplayer').mousemove(mousemoveFn);

				that.element.find('.jp-full-screen').click(function() {
					if (Webos.fullscreen.support) {
						that.element.find('.jp-video').requestFullScreen();
					} else {
						$('#header').animate({
							top: '-=25px'
						});
						$('#footer').animate({
							bottom: '-=25px'
						});
					}
				});

				that.element.find('.jp-restore-screen').click(function() {
					if (Webos.fullscreen.support) {
						Webos.fullscreen.cancel();
					} else {
						$('#header').animate({
							top: '+=25px'
						});
						$('#footer').animate({
							bottom: '+=25px'
						});
					}
				});

				that._trigger('ready');

				if (typeof userCallback != 'undefined') {
					userCallback();
				}
			},
			error: function(e) {
				var mess = t.get('An error has occurred with the multimedia player jPlayer');
				switch (e.jPlayer.error.type) {
					case $.jPlayer.error.FLASH:
						mess = t.get('An error occurred while inserting the video with Flash plugin');
						break;
					case $.jPlayer.error.FLASH_DISABLED:
						mess = t.get('An error has occurred with the Flash plugin, which has been disabled');
						break;
					case $.jPlayer.error.NO_SOLUTION:
						mess = t.get('Can\'t read the media, your browser is outdated');
						break;
					case $.jPlayer.error.NO_SUPPORT:
						mess = t.get('Can\'t read the media, file format not supported');
						break;
					case $.jPlayer.error.URL:
						mess = t.get('Can\'t read the media, the file path is invalid');
						break;
					case $.jPlayer.error.URL_NOT_SET:
						return;
						break;
					case $.jPlayer.error.VERSION:
						mess = t.get('Your Javascript and Flash version is not supported');
						break;
				}
				W.Error.trigger(mess, e.jPlayer.error.message+"\n"+e.jPlayer.error.hint);
			}
		});
	},
	play: function() {
		this.player().jPlayer('play');
	},
	open: function(file) {
		this.options.file = file;
		if (typeof this.options.file == 'undefined') {
			return;
		}
		var supported = true,
			fileObject = {},
			type = 'audio',
			supplied = '',
			filepath = this.options.file.get('realpath');

		switch (this.options.file.get('extension')) { // selon les types MIME, on cré une playlist différente
			case 'mp3':
				fileObject = {
					mp3: filepath
				};
				supplied = "mp3";
				type = 'audio';
			break;
			case 'oga':
				fileObject = {
					oga: filepath
				};
				supplied = "oga";
				type = 'audio';
			break;
			case 'ogg':
				fileObject = {
					ogv: filepath
				};
				supplied = "ogv";
				type = 'video';
			break;
			case 'ogv':
				fileObject = {
					ogv: filepath
				};
				supplied = "ogv";
				type = 'video';
			break;
			case 'mp4':
				fileObject = {
					mp4: filepath
				};
				supplied = "m4v";
				type = 'video';
			break;
			case 'm4v':
				fileObject = {
					m4v: filepath
				};
				supplied = "m4v";
				type = 'video';
			break;
			case 'm4a':
				fileObject = {
					m4a: filepath
				};
				supplied = "m4a";
				type = 'audio';
			break;
			case 'wav':
				fileObject = {
					wav: filepath
				};
				supplied = "wav";
			break;
			case 'webma':
				fileObject = {
					webma:filepath
				};
				supplied = "webma";
				type = 'audio';
			break;
			case 'webmv':
				fileObject = {
					webmv:filepath
				};
				supplied = "webmv";
				type = 'video';
			break;
			case 'webm':
				fileObject = {
					webmv:filepath
				};
				supplied = "webmv";
				type = 'video';
			break;
			default:
				supported = false;
		}

		this.options.type = type;

		var that = this, t = this.translations();

		this._loadProfile(type, function() {
			if (!supported) {
				W.Error.trigger(t.get('Can\'t open file "${basename}"', { basename: that.options.file.get('basename') }), t.get('Unsupported file type'));
				that.loadEmpty();
				return;
			}

			that._initPlayer(supplied, function() {
				that.player()
					.jPlayer('setMedia', fileObject)
					.jPlayer('play');
				that._trigger('play');
			});
		});
	},
	loadEmpty: function(callback) {
		var that = this;

		this._loadProfile('audio', function() {
			that._initPlayer('mp3', callback);
		});
	},
	player: function() {
		return this.options._components.player;
	}
});
$.webos.widget('intermezzo', intermezzoProperties);

$.webos.intermezzo = function(options) {
	return $('

').intermezzo(options);
};

// Application sous forme de classe
window.IntermezzoWindow = function IntermezzoWindow(options) {
	Webos.Observable.call(this);

	options = options || {};

	this.bind('translationsloaded', function() {
		var that = this, t = this._translations;

		this.window = $.w.window({
			title : t.get('Intermezzo multimedia player'),
			icon: new W.Icon('applications/intermezzo')
		});

		var headers = this.window.window('header');

		this._menu = $.w.menuWindowHeader().appendTo(headers);

		var fileItem = $.w.menuItem(t.get('File')).appendTo(this._menu);
		fileItemContent = fileItem.menuItem('content');

		$.w.menuItem(t.get('Open'))
			.click(function() {
				new NautilusFileSelectorWindow({
					parentWindow: that.window
				}, function(files) {
					if (files.length) {
						that.player.intermezzo('open', files[0]);
					}
				});
			})
			.appendTo(fileItemContent);

		$.w.menuItem(t.get('Quit'))
			.click(function() {
				that.window.window('close');
			})
			.appendTo(fileItemContent);

		this.player = $.webos.intermezzo({
			file: options.file
		});

		var resizeFn = function() {
			var windowsContent = that.window.window('content'),
				windowsWidth = windowsContent.innerWidth(),
				cssClass;

			if (windowsWidth < 480) {
				cssClass = '';
			} else if (windowsWidth < 640) {
				cssClass = 'jp-video-270p';
			} else {
				cssClass = 'jp-video-360p';
			}
			that.player.intermezzo('player').jPlayer('option', 'size', { cssClass: cssClass });
		};

		this.window.bind('windowresize', resizeFn);

		this.player.appendTo(this.window.window('content'));

		this.window.window('open');

		this.player.bind('intermezzoloadprofile', function() {
			that.window.window('center');
		});

		resizeFn();
		this.notify('ready');
	});

	Webos.TranslatedLibrary.call(this);
};
IntermezzoWindow.prototype = {
	_translationsName: 'intermezzo'
};
Webos.inherit(IntermezzoWindow, Webos.Observable);
Webos.inherit(IntermezzoWindow, Webos.TranslatedLibrary);<|endoftext|>


<commit_before>var gulp = require('gulp');

gulp.task('watch', ['setWatch', 'browserSync'], function() {
	gulp.watch('themes/**', ['styles']);
	// Note: The browserify task handles js recompiling with watchify
});
<commit_msg>rebuild when js changes<commit_after>var gulp = require('gulp');

gulp.task('watch', ['setWatch', 'browserSync'], function() {
	gulp.watch('themes/**', ['styles']);
	gulp.watch('lib/**', ['browserify']);
	// Note: The browserify task handles js recompiling with watchify
});
<|endoftext|>


<commit_before>/**
 *
 * @returns { {} }
 * @constructor
 */
FirebrandUserInteractionEvents = function () {
    /**
     * The object in which user events are stored
     * @type { { mouseMoveCount: number, touchCount: number, keyCount: number, scrollCount: number, clickCount: number, isFirstInteraction: boolean, previousRecord: {} } }
     */
    var userInteractionTracking = {

        //How many times a mouse event was registered
        mouseMoveCount: 0,

        //How many times a touchstart event was registered
        touchCount: 0,

        //How many times a keydown was registered
        keyCount: 0,

        //How many scroll events
        scrollCount: 0,

        //How many click events
        clickCount: 0,

        //A flag which is used to send off the first interaction immediately (in case the user leaves before the first time-step send)
        isFirstInteraction: true,

        //This object stores the previous values from the last send to GTM so we can compare if the user did anything between time-steps
        previousRecord: {}
    };

    /**
     * This function is checked every time an event is registered,
     * if the flag is true (as it was initialized)
     * - then we send a dataLayer push immediately before the user has a chance to exit
     * The rationale for this is to categorize users who immediately close the window as non-bots,
     * and also provide us a better bounce-rate/exit metric
     *
     * @param interactionType - the type of the first interaction
     */
    function sendFirstInteraction(interactionType) {
        if (userInteractionTracking.isFirstInteraction) {
            sendGTMUserEvents(interactionType, true);
            userInteractionTracking.isFirstInteraction = false;
        }
    }

    var $body = jQuery('body');

//Zero out empty record object
    userInteractionTracking.previousRecord = {
        touchCount: 0,
        mouseMoveCount: 0,
        keyCount: 0,
        scrollCount: 0,
        clickCount: 0
    };

    $body.on('mousemove', function () {
        userInteractionTracking.mouseMoveCount++;
        sendFirstInteraction('MouseMove');
    });

    /**
     * I'm counting touchstarts to give the approximate total number of swipes on the screen,
     * if you cared about the distance of those swipes you could track touchend as well (or instead)
     */
    $body.on('touchstart', function () {
        userInteractionTracking.touchCount++;
        sendFirstInteraction('Touch');
    });

    jQuery(window).on('scroll', function () {
        userInteractionTracking.scrollCount++;
        sendFirstInteraction('Scroll');
    });

    jQuery(document).keydown(function (event) {

        if (event.keyCode === 13) {
            userInteractionTracking.keyCount++;
            sendGTMUserEvents("Return")
        } else {
            userInteractionTracking.keyCount++;
            sendFirstInteraction('KeyDown');
        }
    });

    $body.click(function () {
        userInteractionTracking.clickCount++;
        sendFirstInteraction('Click');
    });

    window.setTimeout(function () {
        sendGTMUserEvents("5 seconds")
    }, 5000);

    window.setTimeout(function () {
        sendGTMUserEvents("19 seconds")
    }, 19000);

    window.setTimeout(function () {
        sendGTMUserEvents("39 seconds")
    }, 39000);

    window.setTimeout(function () {
        sendGTMUserEvents("67 seconds")
    }, 67000);

    /**
     * This function is fired every time we have a chunk of data we want to
     * send back to google analytics, via google tag manager's DataLayer push,
     *
     *
     * @param interactionType
     * @param firstInteraction
     */
    function sendGTMUserEvents(interactionType, firstInteraction) {

        /**
         * If it's not the user's first rodeo, set the first interaction flag to false
         */
        if (typeof firstInteraction === 'undefined') {
            firstInteraction = false;
        }

        var dataLayerPushObject = {
            "event": "GAEvent",
            "eventCategory": "UserInteractionEvent - v3",
            "eventAction": interactionType,
            "eventLabel": 'ActiveInteractionEvent',
            "nonInteraction": true
        };

        if (firstInteraction) {
            //Nothing to compare against for the first push
            dataLayer.push(dataLayerPushObject);

        } else {

            /**
             * If the current values match the old ones,
             * mark as inactive and push this result to GTM
             */

            if (userInteractionTracking.scrollCount === userInteractionTracking.previousRecord.scrollCount &&
                userInteractionTracking.keyCount === userInteractionTracking.previousRecord.keyCount &&
                userInteractionTracking.clickCount === userInteractionTracking.previousRecord.clickCount &&
                userInteractionTracking.mouseMoveCount === userInteractionTracking.previousRecord.mouseMoveCount &&
                userInteractionTracking.touchCount === userInteractionTracking.previousRecord.touchCount) {

                dataLayerPushObject.eventLabel = 'InactiveInteractionEvent';

                //Then Push non-interaction
                dataLayer.push(dataLayerPushObject);
            } else {
                //Otherwise push interaction event
                dataLayer.push(dataLayerPushObject);
            }
        }

        //Now that we're done with the current record...
        //let's tuck it away for the next comparison
        userInteractionTracking.previousRecord = {
            mouseMoveCount: userInteractionTracking.mouseMoveCount,
            touchCount: userInteractionTracking.touchCount,
            keyCount: userInteractionTracking.keyCount,
            scrollCount: userInteractionTracking.scrollCount,
            clickCount: userInteractionTracking.clickCount,
            isFirstInteraction: userInteractionTracking.isFirstInteraction,
        };
    }

    return {}
};

jQuery(document).ready(function () {
    if (typeof jQuery !== 'function') {
        console.warn('jQuery is not defined!');
    } else {
        FirebrandUserInteractionEvents();
    }
});<commit_msg>Add license and author documentation<commit_after>/**
 * @file Sends Google Analytics events when users interact with page or if they are inactive for specified periods.
 * @version 1.0
 * @author Firebrand LLC. https://firebrand.net
 * @license Apache-2.0
 */

/**
 *
 * @returns { {} }
 * @constructor
 */
FirebrandUserInteractionEvents = function () {
    /**
     * The object in which user events are stored
     * @type { { mouseMoveCount: number, touchCount: number, keyCount: number, scrollCount: number, clickCount: number, isFirstInteraction: boolean, previousRecord: {} } }
     */
    var userInteractionTracking = {

        //How many times a mouse event was registered
        mouseMoveCount: 0,

        //How many times a touchstart event was registered
        touchCount: 0,

        //How many times a keydown was registered
        keyCount: 0,

        //How many scroll events
        scrollCount: 0,

        //How many click events
        clickCount: 0,

        //A flag which is used to send off the first interaction immediately (in case the user leaves before the first time-step send)
        isFirstInteraction: true,

        //This object stores the previous values from the last send to GTM so we can compare if the user did anything between time-steps
        previousRecord: {}
    };

    /**
     * This function is checked every time an event is registered,
     * if the flag is true (as it was initialized)
     * - then we send a dataLayer push immediately before the user has a chance to exit
     * The rationale for this is to categorize users who immediately close the window as non-bots,
     * and also provide us a better bounce-rate/exit metric
     *
     * @param interactionType - the type of the first interaction
     */
    function sendFirstInteraction(interactionType) {
        if (userInteractionTracking.isFirstInteraction) {
            sendGTMUserEvents(interactionType, true);
            userInteractionTracking.isFirstInteraction = false;
        }
    }

    var $body = jQuery('body');

//Zero out empty record object
    userInteractionTracking.previousRecord = {
        touchCount: 0,
        mouseMoveCount: 0,
        keyCount: 0,
        scrollCount: 0,
        clickCount: 0
    };

    $body.on('mousemove', function () {
        userInteractionTracking.mouseMoveCount++;
        sendFirstInteraction('MouseMove');
    });

    /**
     * I'm counting touchstarts to give the approximate total number of swipes on the screen,
     * if you cared about the distance of those swipes you could track touchend as well (or instead)
     */
    $body.on('touchstart', function () {
        userInteractionTracking.touchCount++;
        sendFirstInteraction('Touch');
    });

    jQuery(window).on('scroll', function () {
        userInteractionTracking.scrollCount++;
        sendFirstInteraction('Scroll');
    });

    jQuery(document).keydown(function (event) {

        if (event.keyCode === 13) {
            userInteractionTracking.keyCount++;
            sendGTMUserEvents("Return")
        } else {
            userInteractionTracking.keyCount++;
            sendFirstInteraction('KeyDown');
        }
    });

    $body.click(function () {
        userInteractionTracking.clickCount++;
        sendFirstInteraction('Click');
    });

    window.setTimeout(function () {
        sendGTMUserEvents("5 seconds")
    }, 5000);

    window.setTimeout(function () {
        sendGTMUserEvents("19 seconds")
    }, 19000);

    window.setTimeout(function () {
        sendGTMUserEvents("39 seconds")
    }, 39000);

    window.setTimeout(function () {
        sendGTMUserEvents("67 seconds")
    }, 67000);

    /**
     * This function is fired every time we have a chunk of data we want to
     * send back to google analytics, via google tag manager's DataLayer push,
     *
     *
     * @param interactionType
     * @param firstInteraction
     */
    function sendGTMUserEvents(interactionType, firstInteraction) {

        /**
         * If it's not the user's first rodeo, set the first interaction flag to false
         */
        if (typeof firstInteraction === 'undefined') {
            firstInteraction = false;
        }

        var dataLayerPushObject = {
            "event": "GAEvent",
            "eventCategory": "UserInteractionEvent - v3",
            "eventAction": interactionType,
            "eventLabel": 'ActiveInteractionEvent',
            "nonInteraction": true
        };

        if (firstInteraction) {
            //Nothing to compare against for the first push
            dataLayer.push(dataLayerPushObject);

        } else {

            /**
             * If the current values match the old ones,
             * mark as inactive and push this result to GTM
             */

            if (userInteractionTracking.scrollCount === userInteractionTracking.previousRecord.scrollCount &&
                userInteractionTracking.keyCount === userInteractionTracking.previousRecord.keyCount &&
                userInteractionTracking.clickCount === userInteractionTracking.previousRecord.clickCount &&
                userInteractionTracking.mouseMoveCount === userInteractionTracking.previousRecord.mouseMoveCount &&
                userInteractionTracking.touchCount === userInteractionTracking.previousRecord.touchCount) {

                dataLayerPushObject.eventLabel = 'InactiveInteractionEvent';

                //Then Push non-interaction
                dataLayer.push(dataLayerPushObject);
            } else {
                //Otherwise push interaction event
                dataLayer.push(dataLayerPushObject);
            }
        }

        //Now that we're done with the current record...
        //let's tuck it away for the next comparison
        userInteractionTracking.previousRecord = {
            mouseMoveCount: userInteractionTracking.mouseMoveCount,
            touchCount: userInteractionTracking.touchCount,
            keyCount: userInteractionTracking.keyCount,
            scrollCount: userInteractionTracking.scrollCount,
            clickCount: userInteractionTracking.clickCount,
            isFirstInteraction: userInteractionTracking.isFirstInteraction,
        };
    }

    return {}
};

jQuery(document).ready(function () {
    if (typeof jQuery !== 'function') {
        console.warn('jQuery is not defined!');
    } else {
        FirebrandUserInteractionEvents();
    }
});<|endoftext|>


<commit_before>var Stream = require('stream'),
  fs = require('fs'),
  http = require('http'),
  GZipStream = require('./streams/gzipstream'),
  Collector = require('./streams/collector');

http.createServer(function(request, response) {
  var gzipper = new GZipStream(),
      collector = new Collector();

  fs.createReadStream('./large-file.txt')
    .pipe(gzipper)
    .pipe(collector);

  collector.on('end', function() {
    response.writeHead(200, {
      'Content-Encoding': 'gzip',
      'Content-Type': 'text/plain',
      'Content-Length': collector.getBytesWritten()
    });
    response.end(collector.getData());
  });
}).listen(8080);

console.log('Server listening on port 8080\n');
<commit_msg>revamp gzipper example 2. upload and write to file<commit_after>var fs = require('fs')
  , http = require('http')
  , formidable = require('formidable')
  , GZipStream = require('./streams/gzipstream');

http.createServer(function(request, response) {
  if (request.url == '/upload' && request.method.toLowerCase() == 'post') {
    var form = new formidable.IncomingForm();
    form.onPart = function(part) {

      // gzip the uploaded data and write to disk
      var zippedFile = fs.createWriteStream('./files/large-file.zip')
        , gzipper = new GZipStream();
      part.pipe(gzipper).pipe(zippedFile);

    }
    form.on('end', function() {
      response.setHeader('Content-Type', 'text/plain; charset=utf-8');
      response.end('We got the junk you uploaded. Thanks.');
    });
    return form.parse(request);
  }

  response.setHeader('Content-Type', 'text/html; charset=utf-8');
  fs.createReadStream('./upload-example-form.html').pipe(response);
}).listen(8080);

console.log('Server ' + process.pid + ' listening on port 8080\n');
<|endoftext|>


<commit_before>var Class = require('../utils/Class');
var NOOP = require('../utils/NOOP');
var EventDispatcher = require('../events/EventDispatcher');
var SoundEvent = require('./SoundEvent');
var SoundValueEvent = require('./SoundValueEvent');
/*!
 * @author Pavle Goloskokovic <pgoloskokovic@gmail.com> (http://prunegames.com)
 */
var BaseSoundManager = new Class({
    /**
     * The sound manager is responsible for playing back audio via Web Audio API or HTML Audio tag as fallback.
     * The audio file type and the encoding of those files are extremely important.
     * Not all browsers can play all audio formats.
     * There is a good guide to what's supported [here](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support).
     *
     * @class Phaser.Sound.BaseSoundManager
     * @constructor
     * @param {Phaser.Game} game - Reference to the current game instance.
     */
    initialize: function BaseSoundManager(game) {
        /**
         * Local reference to game.
         *
         * @readonly
         * @property {Phaser.Game} game
         */
        this.game = game;
        /**
         * Event dispatcher used to handle all sound manager related events.
         *
         * @readonly
         * @property {Phaser.Events.EventDispatcher} events
         */
        this.events = new EventDispatcher();
        /**
         * An array containing all added sounds.
         *
         * @private
         * @property {ISound[]} sounds
         */
        this.sounds = [];
        /**
         * Global mute setting.
         *
         * @property {boolean} mute
         */
        this.mute = false;
        /**
         * Global volume setting.
         *
         * @property {number} volume
         */
        this.volume = 1;
        /**
         * Global playback rate at which all the sounds will be played.
         * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
         * and 2.0 doubles the audio's playback speed.
         *
         * @property {number} rate
         */
        this.rate = 1;
        /**
         * Global detuning of all sounds in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
         * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
         *
         * @property {number} detune
         */
        this.detune = 0;
        /**
         * Flag indicating if sounds should be paused when game looses focus,
         * for instance when user switches to another tab/program/app.
         *
         * @property {boolean} pauseOnBlur
         */
        this.pauseOnBlur = true;
        game.events.on('ON_BLUR', function () {
            if (this.pauseOnBlur) {
                this.onBlur();
            }
        }.bind(this));
        game.events.on('ON_FOCUS', function () {
            if (this.pauseOnBlur) {
                this.onFocus();
            }
        }.bind(this));
        /**
         * Property that actually holds the value of global playback rate.
         *
         * @private
         * @property {number} _rate
         */
        this._rate = 1;
        /**
         * Property that actually holds the value of global detune.
         *
         * @private
         * @property {number} _detune
         */
        this._detune = 0;
    },
    /**
     * Adds a new sound into the sound manager.
     *
     * @override
     * @method Phaser.Sound.BaseSoundManager#add
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     * @returns {ISound} The new sound instance.
     */
    add: NOOP,
    /**
     * Adds a new audio sprite sound into the sound manager.
     *
     * @method Phaser.Sound.BaseSoundManager#addAudioSprite
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     * @returns {IAudioSpriteSound} The new audio sprite sound instance.
     */
    addAudioSprite: function (key, config) {
        var sound = this.add(key, config);
        /**
         * Local reference to 'spritemap' object form json file generated by audiosprite tool.
         *
         * @property {object} spritemap
         */
        sound.spritemap = this.game.cache.json.get(key).spritemap;
        for (var markerName in sound.spritemap) {
            if (!sound.spritemap.hasOwnProperty(markerName)) {
                continue;
            }
            var marker = sound.spritemap[markerName];
            sound.addMarker({
                name: markerName,
                start: marker.start,
                duration: marker.end - marker.start,
                config: config
            });
        }
        return sound;
    },
    /**
     * Enables playing sound on the fly without the need to keep a reference to it.
     * Sound will auto destroy once its playback ends.
     *
     * @method Phaser.Sound.BaseSoundManager#play
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig | ISoundMarker} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object.
     */
    play: function (key, extra) {
        var sound = this.add(key);
        sound.events.once('SOUND_ENDED', sound.destroy.bind(sound));
        if (extra) {
            if (extra.name) {
                sound.addMarker(extra);
                sound.play(extra.name);
            }
            else {
                sound.play(extra);
            }
        }
        else {
            sound.play();
        }
    },
    /**
     * Enables playing audio sprite sound on the fly without the need to keep a reference to it.
     * Sound will auto destroy once its playback ends.
     *
     * @method Phaser.Sound.BaseSoundManager#playAudioSprite
     * @param {string} key - Asset key for the sound.
     * @param {string} spriteName - The name of the sound sprite to play.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     */
    playAudioSprite: function (key, spriteName, config) {
        var sound = this.addAudioSprite(key);
        sound.events.once('SOUND_ENDED', sound.destroy.bind(sound));
        sound.play(spriteName, config);
    },
    /**
     * Removes a sound from the sound manager.
     * The removed sound is destroyed before removal.
     *
     * @method Phaser.Sound.BaseSoundManager#remove
     * @param {ISound} sound - The sound object to remove.
     * @returns {boolean} True if the sound was removed successfully, otherwise false.
     */
    remove: function (sound) {
        var index = this.sounds.indexOf(sound);
        if (index !== -1) {
            sound.destroy();
            this.sounds.splice(index, 1);
            return true;
        }
        return false;
    },
    /**
     * Removes all sounds from the sound manager that have an asset key matching the given value.
     * The removed sounds are destroyed before removal.
     *
     * @method Phaser.Sound.BaseSoundManager#removeByKey
     * @param {string} key - The key to match when removing sound objects.
     * @returns {number} The number of matching sound objects that were removed.
     */
    removeByKey: function (key) {
        var removed = 0;
        for (var i = this.sounds.length - 1; i >= 0; i--) {
            var sound = this.sounds[i];
            if (sound.key === key) {
                sound.destroy();
                this.sounds.splice(i, 1);
                removed++;
            }
        }
        return removed;
    },
    /**
     * Pauses all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#pauseAll
     */
    pauseAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.pause();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_PAUSE'));
    },
    /**
     * Resumes all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#resumeAll
     */
    resumeAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.resume();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_RESUME'));
    },
    /**
     * Stops all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#stopAll
     */
    stopAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.stop();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_STOP'));
    },
    /**
     * @override
     * @protected
     * @method Phaser.Sound.BaseSoundManager#onBlur
     */
    onBlur: NOOP,
    /**
     * @override
     * @protected
     * @method Phaser.Sound.BaseSoundManager#onFocus
     */
    onFocus: NOOP,
    /**
     * Update method called on every game step.
     * Removes destroyed sounds and updates every active sound in the game.
     *
     * @protected
     * @method Phaser.Sound.BaseSoundManager#update
     * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
     * @param {number} delta - The delta time elapsed since the last frame.
     */
    update: function (time, delta) {
        for (var i = this.sounds.length - 1; i >= 0; i--) {
            if (this.sounds[i].pendingRemove) {
                this.sounds.splice(i, 1);
            }
        }
        this.sounds.forEach(function (sound) {
            sound.update(time, delta);
        });
    },
    destroy: function () {
        this.game = null;
        this.events.destroy();
        this.events = null;
        this.forEachActiveSound(function (sound) {
            sound.destroy();
        });
        this.sounds = null;
    },
    /**
     * @private
     * @param {(value: ISound, index: number, array: ISound[]) => void} callbackfn
     * @param thisArg
     */
    forEachActiveSound: function (callbackfn, thisArg) {
        var _this = this;
        this.sounds.forEach(function (sound, index) {
            if (!sound.pendingRemove) {
                callbackfn.call(thisArg || _this, sound, index, _this.sounds);
            }
        });
    }
});
/**
 * Global playback rate.
 * @property {number} rate
 */
Object.defineProperty(BaseSoundManager.prototype, 'rate', {
    get: function () {
        return this._rate;
    },
    set: function (value) {
        this._rate = value;
        this.forEachActiveSound(function (sound) {
            sound.setRate();
        }, this);
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_RATE', value));
    }
});
/**
 * Global detune.
 * @property {number} detune
 */
Object.defineProperty(BaseSoundManager.prototype, 'detune', {
    get: function () {
        return this._detune;
    },
    set: function (value) {
        this._detune = value;
        this.forEachActiveSound(function (sound) {
            sound.setRate();
        }, this);
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_DETUNE', value));
    }
});
module.exports = BaseSoundManager;
<commit_msg>Added destroy method docs<commit_after>var Class = require('../utils/Class');
var NOOP = require('../utils/NOOP');
var EventDispatcher = require('../events/EventDispatcher');
var SoundEvent = require('./SoundEvent');
var SoundValueEvent = require('./SoundValueEvent');
/*!
 * @author Pavle Goloskokovic <pgoloskokovic@gmail.com> (http://prunegames.com)
 */
var BaseSoundManager = new Class({
    /**
     * The sound manager is responsible for playing back audio via Web Audio API or HTML Audio tag as fallback.
     * The audio file type and the encoding of those files are extremely important.
     * Not all browsers can play all audio formats.
     * There is a good guide to what's supported [here](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support).
     *
     * @class Phaser.Sound.BaseSoundManager
     * @constructor
     * @param {Phaser.Game} game - Reference to the current game instance.
     */
    initialize: function BaseSoundManager(game) {
        /**
         * Local reference to game.
         *
         * @readonly
         * @property {Phaser.Game} game
         */
        this.game = game;
        /**
         * Event dispatcher used to handle all sound manager related events.
         *
         * @readonly
         * @property {Phaser.Events.EventDispatcher} events
         */
        this.events = new EventDispatcher();
        /**
         * An array containing all added sounds.
         *
         * @private
         * @property {ISound[]} sounds
         */
        this.sounds = [];
        /**
         * Global mute setting.
         *
         * @property {boolean} mute
         */
        this.mute = false;
        /**
         * Global volume setting.
         *
         * @property {number} volume
         */
        this.volume = 1;
        /**
         * Global playback rate at which all the sounds will be played.
         * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
         * and 2.0 doubles the audio's playback speed.
         *
         * @property {number} rate
         */
        this.rate = 1;
        /**
         * Global detuning of all sounds in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
         * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
         *
         * @property {number} detune
         */
        this.detune = 0;
        /**
         * Flag indicating if sounds should be paused when game looses focus,
         * for instance when user switches to another tab/program/app.
         *
         * @property {boolean} pauseOnBlur
         */
        this.pauseOnBlur = true;
        game.events.on('ON_BLUR', function () {
            if (this.pauseOnBlur) {
                this.onBlur();
            }
        }.bind(this));
        game.events.on('ON_FOCUS', function () {
            if (this.pauseOnBlur) {
                this.onFocus();
            }
        }.bind(this));
        /**
         * Property that actually holds the value of global playback rate.
         *
         * @private
         * @property {number} _rate
         */
        this._rate = 1;
        /**
         * Property that actually holds the value of global detune.
         *
         * @private
         * @property {number} _detune
         */
        this._detune = 0;
    },
    /**
     * Adds a new sound into the sound manager.
     *
     * @override
     * @method Phaser.Sound.BaseSoundManager#add
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     * @returns {ISound} The new sound instance.
     */
    add: NOOP,
    /**
     * Adds a new audio sprite sound into the sound manager.
     *
     * @method Phaser.Sound.BaseSoundManager#addAudioSprite
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     * @returns {IAudioSpriteSound} The new audio sprite sound instance.
     */
    addAudioSprite: function (key, config) {
        var sound = this.add(key, config);
        /**
         * Local reference to 'spritemap' object form json file generated by audiosprite tool.
         *
         * @property {object} spritemap
         */
        sound.spritemap = this.game.cache.json.get(key).spritemap;
        for (var markerName in sound.spritemap) {
            if (!sound.spritemap.hasOwnProperty(markerName)) {
                continue;
            }
            var marker = sound.spritemap[markerName];
            sound.addMarker({
                name: markerName,
                start: marker.start,
                duration: marker.end - marker.start,
                config: config
            });
        }
        return sound;
    },
    /**
     * Enables playing sound on the fly without the need to keep a reference to it.
     * Sound will auto destroy once its playback ends.
     *
     * @method Phaser.Sound.BaseSoundManager#play
     * @param {string} key - Asset key for the sound.
     * @param {ISoundConfig | ISoundMarker} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object.
     */
    play: function (key, extra) {
        var sound = this.add(key);
        sound.events.once('SOUND_ENDED', sound.destroy.bind(sound));
        if (extra) {
            if (extra.name) {
                sound.addMarker(extra);
                sound.play(extra.name);
            }
            else {
                sound.play(extra);
            }
        }
        else {
            sound.play();
        }
    },
    /**
     * Enables playing audio sprite sound on the fly without the need to keep a reference to it.
     * Sound will auto destroy once its playback ends.
     *
     * @method Phaser.Sound.BaseSoundManager#playAudioSprite
     * @param {string} key - Asset key for the sound.
     * @param {string} spriteName - The name of the sound sprite to play.
     * @param {ISoundConfig} [config] - An optional config object containing default sound settings.
     */
    playAudioSprite: function (key, spriteName, config) {
        var sound = this.addAudioSprite(key);
        sound.events.once('SOUND_ENDED', sound.destroy.bind(sound));
        sound.play(spriteName, config);
    },
    /**
     * Removes a sound from the sound manager.
     * The removed sound is destroyed before removal.
     *
     * @method Phaser.Sound.BaseSoundManager#remove
     * @param {ISound} sound - The sound object to remove.
     * @returns {boolean} True if the sound was removed successfully, otherwise false.
     */
    remove: function (sound) {
        var index = this.sounds.indexOf(sound);
        if (index !== -1) {
            sound.destroy();
            this.sounds.splice(index, 1);
            return true;
        }
        return false;
    },
    /**
     * Removes all sounds from the sound manager that have an asset key matching the given value.
     * The removed sounds are destroyed before removal.
     *
     * @method Phaser.Sound.BaseSoundManager#removeByKey
     * @param {string} key - The key to match when removing sound objects.
     * @returns {number} The number of matching sound objects that were removed.
     */
    removeByKey: function (key) {
        var removed = 0;
        for (var i = this.sounds.length - 1; i >= 0; i--) {
            var sound = this.sounds[i];
            if (sound.key === key) {
                sound.destroy();
                this.sounds.splice(i, 1);
                removed++;
            }
        }
        return removed;
    },
    /**
     * Pauses all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#pauseAll
     */
    pauseAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.pause();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_PAUSE'));
    },
    /**
     * Resumes all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#resumeAll
     */
    resumeAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.resume();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_RESUME'));
    },
    /**
     * Stops all the sounds in the game.
     *
     * @method Phaser.Sound.BaseSoundManager#stopAll
     */
    stopAll: function () {
        this.forEachActiveSound(function (sound) {
            sound.stop();
        });
        this.events.dispatch(new SoundEvent(this, 'SOUND_STOP'));
    },
    /**
     * @override
     * @protected
     * @method Phaser.Sound.BaseSoundManager#onBlur
     */
    onBlur: NOOP,
    /**
     * @override
     * @protected
     * @method Phaser.Sound.BaseSoundManager#onFocus
     */
    onFocus: NOOP,
    /**
     * Update method called on every game step.
     * Removes destroyed sounds and updates every active sound in the game.
     *
     * @protected
     * @method Phaser.Sound.BaseSoundManager#update
     * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
     * @param {number} delta - The delta time elapsed since the last frame.
     */
    update: function (time, delta) {
        for (var i = this.sounds.length - 1; i >= 0; i--) {
            if (this.sounds[i].pendingRemove) {
                this.sounds.splice(i, 1);
            }
        }
        this.sounds.forEach(function (sound) {
            sound.update(time, delta);
        });
    },
    /**
     * Destroys all the sounds in the game and all associated events.
     *
     * @method Phaser.Sound.BaseSoundManager#destroy
     */
    destroy: function () {
        this.game = null;
        this.events.destroy();
        this.events = null;
        this.forEachActiveSound(function (sound) {
            sound.destroy();
        });
        this.sounds = null;
    },
    /**
     * @private
     * @param {(value: ISound, index: number, array: ISound[]) => void} callbackfn
     * @param thisArg
     */
    forEachActiveSound: function (callbackfn, thisArg) {
        var _this = this;
        this.sounds.forEach(function (sound, index) {
            if (!sound.pendingRemove) {
                callbackfn.call(thisArg || _this, sound, index, _this.sounds);
            }
        });
    }
});
/**
 * Global playback rate.
 * @property {number} rate
 */
Object.defineProperty(BaseSoundManager.prototype, 'rate', {
    get: function () {
        return this._rate;
    },
    set: function (value) {
        this._rate = value;
        this.forEachActiveSound(function (sound) {
            sound.setRate();
        }, this);
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_RATE', value));
    }
});
/**
 * Global detune.
 * @property {number} detune
 */
Object.defineProperty(BaseSoundManager.prototype, 'detune', {
    get: function () {
        return this._detune;
    },
    set: function (value) {
        this._detune = value;
        this.forEachActiveSound(function (sound) {
            sound.setRate();
        }, this);
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_DETUNE', value));
    }
});
module.exports = BaseSoundManager;
<|endoftext|>