<commit_before>const CopyWebpackPlugin = require('copy-webpack-plugin')
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin')
const HtmlInsertTagWebpackPlugin = require('html-insert-tag-webpack-plugin')
const path = require('path')
const plugins = require('./webpack.plugins')
const webpack = require('webpack')
const rules = require('./webpack.rules')

rules.push({
  test: /\.css$/,
  use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
})

module.exports = {
  module: {
    rules,
  },
  plugins: [
    ...plugins,
    new webpack.DefinePlugin({
      'process.type': '"renderer"',
    }),
    new HtmlInsertTagWebpackPlugin([
      {
        tagName: 'base',
        inject: {
          tagName: 'head',
          location: 'after',
        },
        attributes: {
          href: 'stencila://rse',
        },
      },
    ]),
    new CspHtmlWebpackPlugin(
      {
        'base-uri': "'self' stencila://rse",
        'default-src': 'stencila://rse',
        'script-src': ["'self'"],
        'img-src': ["'self'", 'data:', 'local:'],
        'style-src': [
          "'self'",
          "'unsafe-inline'",
          'https://unpkg.com/',
          'https://fonts.googleapis.com/',
        ],
        'connect-src': "'self'",
        'font-src': [
          "'self'",
          'https://fonts.gstatic.com/',
          'https://unpkg.com/',
        ],
      },
      {
        hashEnabled: {
          'script-src': true,
          'style-src': true,
        },
        nonceEnabled: {
          'script-src': true,
          'style-src': false,
        },
      }
    ),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'www', 'build'),
          to: 'build',
        },
        {
          from: path.resolve(__dirname, 'www', 'assets'),
          to: 'assets',
        },
      ],
    }),
  ],
  resolve: {
    mainFields: ['browser', 'module', 'main'],
    extensions: ['.js', '.mjs', '.ts', '.css'],
  },
}
<commit_msg>fix(Build): Fix loading of manifest.json in production builds<commit_after>const CopyWebpackPlugin = require('copy-webpack-plugin')
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin')
const HtmlInsertTagWebpackPlugin = require('html-insert-tag-webpack-plugin')
const path = require('path')
const plugins = require('./webpack.plugins')
const webpack = require('webpack')
const rules = require('./webpack.rules')

rules.push({
  test: /\.css$/,
  use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
})

module.exports = {
  module: {
    rules,
  },
  plugins: [
    ...plugins,
    new webpack.DefinePlugin({
      'process.type': '"renderer"',
    }),
    new HtmlInsertTagWebpackPlugin([
      {
        tagName: 'base',
        inject: {
          tagName: 'head',
          location: 'after',
        },
        attributes: {
          href: 'stencila://rse',
        },
      },
    ]),
    new CspHtmlWebpackPlugin(
      {
        'base-uri': "'self' stencila://rse",
        'default-src': 'stencila://rse',
        'script-src': ["'self'"],
        'img-src': ["'self'", 'data:', 'local:'],
        'style-src': [
          "'self'",
          "'unsafe-inline'",
          'https://unpkg.com/',
          'https://fonts.googleapis.com/',
        ],
        'connect-src': "'self'",
        'font-src': [
          "'self'",
          'https://fonts.gstatic.com/',
          'https://unpkg.com/',
        ],
      },
      {
        hashEnabled: {
          'script-src': true,
          'style-src': true,
        },
        nonceEnabled: {
          'script-src': true,
          'style-src': false,
        },
      }
    ),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'www', 'build'),
          to: 'build',
        },
        {
          from: path.resolve(__dirname, 'www', 'assets'),
          to: 'assets',
        },
        {
          from: path.resolve(__dirname, 'www', 'manifest.json'),
          to: '.',
        },
      ],
    }),
  ],
  resolve: {
    mainFields: ['browser', 'module', 'main'],
    extensions: ['.js', '.mjs', '.ts', '.css'],
  },
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import Pusher from 'pusher-js';
import DocumentTitle from 'react-document-title';
import MediaDetail from './MediaDetail';
import MediaUtil from './MediaUtil';
import MediaChecklist from './MediaChecklist';
import { Tags } from '../source';
import Annotations from './Annotations';
import config from 'config';
import { pageTitle } from '../../helpers';
import CheckContext from '../../CheckContext';
import Tasks from '../task/Tasks';
import CreateTask from '../task/CreateTask';
import { bemClass, bemClassFromMediaStatus, safelyParseJSON, getStatus, getStatusStyle } from '../../helpers';
import ContentColumn from '../layout/ContentColumn';
import MediaStatus from './MediaStatus';
import MdInfoOutline from 'react-icons/lib/md/info-outline';
import Tooltip from 'rc-tooltip';

class MediaComponent extends Component {
  getContext() {
    const context = new CheckContext(this).getContextStore();
    return context;
  }

  setCurrentContext() {
    const context = new CheckContext(this);
    if (!context.getContextStore().project) {
      context.setContextStore({
        project: this.props.media.project,
      });
    }
    this.props.relay.setVariables({ contextId: this.getContext().project.dbid });
  }

  componentDidMount() {
    this.setCurrentContext();
    this.scrollToAnnotation();
    this.subscribe();
  }

  componentDidUpdate() {
    this.setCurrentContext();
    this.scrollToAnnotation();
  }

  scrollToAnnotation() {
    if (window.location.hash != '') {
      let id = window.location.hash.replace(/^#/, ''),
        element = document.getElementById(id);
      if (element.scrollIntoView != undefined) {
        element.scrollIntoView();
      }
    }
  }

  subscribe() {
    const pusher = this.getContext().pusher;
    if (pusher) {
      const that = this;
      pusher.subscribe(this.props.media.pusher_channel).bind('media_updated', (data) => {
        const annotation = JSON.parse(data.message);
        if (annotation.annotated_id === that.props.media.dbid) {
          that.props.relay.forceFetch();
        }
      });
    }
  }

  unsubscribe() {
    const pusher = this.getContext().pusher;
    if (pusher) {
      pusher.unsubscribe(this.props.media.pusher_channel);
    }
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    if (this.props.relay.variables.contextId === null) {
      return null;
    }

    const media = this.props.media;
    const data = JSON.parse(media.embed);
    media.url = media.media.url;
    media.quote = media.media.quote;
    media.embed_path = media.media.embed_path;
    const userOverrides = safelyParseJSON(media.overridden);
    const primaryHeading = (userOverrides && userOverrides.title) ?
        MediaUtil.title(media, data, this.props.intl) : MediaUtil.attributedType(media, data, this.props.intl);
    const status = getStatus(this.props.media.verification_statuses, media.last_status);

    return (
      <DocumentTitle title={pageTitle(MediaUtil.title(media, data, this.props.intl), false, this.getContext().team)}>

{primaryHeading}

                <MediaStatus media={media} readonly={this.props.readonly} />

            <ContentColumn wide className='media__expanded-column-wrapper'>
              <ContentColumn className='media__media-column'>
                <MediaDetail media={media} />
                <CreateTask media={media} />
              </ContentColumn>
              <ContentColumn className='media__tasks-column'>

<FormattedMessage id="mediaComponent.verificationTasks" defaultMessage="Verification tasks" />

                  {media.tasks.edges.filter((t) => { return !!t.node.first_response; }).length}/{media.tasks.edges.length} <FormattedMessage id="mediaComponent.resolved" defaultMessage="resolved" />
                  <CreateTask media={media} plusIcon/>

                <Tasks tasks={media.tasks.edges} media={media} />
              </ContentColumn>
            </ContentColumn>

          <ContentColumn>
            <Tooltip placement="bottom" trigger={['click']} overlay={<MediaChecklist/>} overlayClassName="">

                <FormattedMessage id="mediaComponent.verificationTimeline" defaultMessage="Verification Timeline" />
                <MdInfoOutline/>

            </Tooltip>
          </ContentColumn>
          <Annotations annotations={media.log.edges} annotated={media} annotatedType="ProjectMedia" />

      </DocumentTitle>
    );
  }
}

MediaComponent.propTypes = {
  intl: intlShape.isRequired,
};

MediaComponent.contextTypes = {
  store: React.PropTypes.object,
};

export default injectIntl(MediaComponent);
<commit_msg>Different approach #5889<commit_after>import React, { Component, PropTypes } from 'react';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import Pusher from 'pusher-js';
import DocumentTitle from 'react-document-title';
import MediaDetail from './MediaDetail';
import MediaUtil from './MediaUtil';
import MediaChecklist from './MediaChecklist';
import { Tags } from '../source';
import Annotations from './Annotations';
import config from 'config';
import { pageTitle } from '../../helpers';
import CheckContext from '../../CheckContext';
import Tasks from '../task/Tasks';
import CreateTask from '../task/CreateTask';
import { bemClass, bemClassFromMediaStatus, safelyParseJSON, getStatus, getStatusStyle } from '../../helpers';
import ContentColumn from '../layout/ContentColumn';
import MediaStatus from './MediaStatus';
import MdInfoOutline from 'react-icons/lib/md/info-outline';
import Tooltip from 'rc-tooltip';

class MediaComponent extends Component {
  getContext() {
    const context = new CheckContext(this).getContextStore();
    return context;
  }

  setCurrentContext() {
    const project = this.getContext().project || this.props.media.project;
    this.props.relay.setVariables({ contextId: project.dbid });
  }

  componentDidMount() {
    this.setCurrentContext();
    this.scrollToAnnotation();
    this.subscribe();
  }

  componentDidUpdate() {
    this.setCurrentContext();
    this.scrollToAnnotation();
  }

  scrollToAnnotation() {
    if (window.location.hash != '') {
      let id = window.location.hash.replace(/^#/, ''),
        element = document.getElementById(id);
      if (element.scrollIntoView != undefined) {
        element.scrollIntoView();
      }
    }
  }

  subscribe() {
    const pusher = this.getContext().pusher;
    if (pusher) {
      const that = this;
      pusher.subscribe(this.props.media.pusher_channel).bind('media_updated', (data) => {
        const annotation = JSON.parse(data.message);
        if (annotation.annotated_id === that.props.media.dbid) {
          that.props.relay.forceFetch();
        }
      });
    }
  }

  unsubscribe() {
    const pusher = this.getContext().pusher;
    if (pusher) {
      pusher.unsubscribe(this.props.media.pusher_channel);
    }
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    if (this.props.relay.variables.contextId === null) {
      return null;
    }

    const media = this.props.media;
    const data = JSON.parse(media.embed);
    media.url = media.media.url;
    media.quote = media.media.quote;
    media.embed_path = media.media.embed_path;
    const userOverrides = safelyParseJSON(media.overridden);
    const primaryHeading = (userOverrides && userOverrides.title) ?
        MediaUtil.title(media, data, this.props.intl) : MediaUtil.attributedType(media, data, this.props.intl);
    const status = getStatus(this.props.media.verification_statuses, media.last_status);

    return (
      <DocumentTitle title={pageTitle(MediaUtil.title(media, data, this.props.intl), false, this.getContext().team)}>

{primaryHeading}

                <MediaStatus media={media} readonly={this.props.readonly} />

            <ContentColumn wide className='media__expanded-column-wrapper'>
              <ContentColumn className='media__media-column'>
                <MediaDetail media={media} />
                <CreateTask media={media} />
              </ContentColumn>
              <ContentColumn className='media__tasks-column'>

<FormattedMessage id="mediaComponent.verificationTasks" defaultMessage="Verification tasks" />

                  {media.tasks.edges.filter((t) => { return !!t.node.first_response; }).length}/{media.tasks.edges.length} <FormattedMessage id="mediaComponent.resolved" defaultMessage="resolved" />
                  <CreateTask media={media} plusIcon/>

                <Tasks tasks={media.tasks.edges} media={media} />
              </ContentColumn>
            </ContentColumn>

          <ContentColumn>
            <Tooltip placement="bottom" trigger={['click']} overlay={<MediaChecklist/>} overlayClassName="">

                <FormattedMessage id="mediaComponent.verificationTimeline" defaultMessage="Verification Timeline" />
                <MdInfoOutline/>

            </Tooltip>
          </ContentColumn>
          <Annotations annotations={media.log.edges} annotated={media} annotatedType="ProjectMedia" />

      </DocumentTitle>
    );
  }
}

MediaComponent.propTypes = {
  intl: intlShape.isRequired,
};

MediaComponent.contextTypes = {
  store: React.PropTypes.object,
};

export default injectIntl(MediaComponent);
<|endoftext|>


<commit_before>/**
* direcitve.diGameBoard Module
*
* Description
*/
angular.module('direcitve.diGameBoard', [
    'service.GridService',
    'directive.diPiece'
])
.controller('GameBoardCtrl', [
    '$scope',
    'GridService',
function (
    $scope,
    GridService
){
    $scope.getGridService = function getGridService() {
        return GridService.getGridService();
    };

    $scope.getFilledClass = function getFilledClass(cell) {
        if (cell.filled) {
            var pieceClass = '';
            switch(cell.shape) {
                case 0: pieceClass = 'dy-L-filled';
                    break;
                case 1: pieceClass = 'dy-O-filled';
                    break;
                case 2: pieceClass = 'dy-I-filled';
                    break;
                case 3: pieceClass = 'dy-T-filled';
                    break;
                case 4: pieceClass = 'dy-J-filled';
                    break;
                case 5: pieceClass = 'dy-S-filled';
                    break;
                case 6: pieceClass = 'dy-Z-filled';
                    break;
            }
            return pieceClass;
        }
    };
}])
.directive('diGameBoard', [
function(
){
    var GameBoard = {};

    GameBoard.controller = 'GameBoardCtrl';

    GameBoard.templateUrl = 'directives/diGameBoard/diGameBoard.tpl.html';

    GameBoard.restrict = 'A';

    GameBoard.scope = true;

    GameBoard.link = function link(scope, element, attrs) {};

    return GameBoard;
}]);<commit_msg>add replace option in the diGameBoard<commit_after>/**
* direcitve.diGameBoard Module
*
* Description
*/
angular.module('direcitve.diGameBoard', [
    'service.GridService',
    'directive.diPiece'
])
.controller('GameBoardCtrl', [
    '$scope',
    'GridService',
function (
    $scope,
    GridService
){
    $scope.getGridService = function getGridService() {
        return GridService.getGridService();
    };

    $scope.getFilledClass = function getFilledClass(cell) {
        if (cell.filled) {
            var pieceClass = '';
            switch(cell.shape) {
                case 0: pieceClass = 'dy-L-filled';
                    break;
                case 1: pieceClass = 'dy-O-filled';
                    break;
                case 2: pieceClass = 'dy-I-filled';
                    break;
                case 3: pieceClass = 'dy-T-filled';
                    break;
                case 4: pieceClass = 'dy-J-filled';
                    break;
                case 5: pieceClass = 'dy-S-filled';
                    break;
                case 6: pieceClass = 'dy-Z-filled';
                    break;
            }
            return pieceClass;
        }
    };
}])
.directive('diGameBoard', [
function(
){
    var GameBoard = {};

    GameBoard.controller = 'GameBoardCtrl';

    GameBoard.templateUrl = 'directives/diGameBoard/diGameBoard.tpl.html';

    GameBoard.restrict = 'A';

    GameBoard.scope = true;

    GameBoard.replace = true;

    GameBoard.link = function link(scope, element, attrs) {};

    return GameBoard;
}]);<|endoftext|>


<commit_before>import { makeStyles } from '@material-ui/core'
import React from 'react'

import { Button } from 'src/components/buttons'
import { H1, P } from 'src/components/typography'
import { ReactComponent as BitcoinLogo } from 'src/styling/logos/icon-bitcoin-colour.svg'
import { ReactComponent as BitcoinCashLogo } from 'src/styling/logos/icon-bitcoincash-colour.svg'
import { ReactComponent as DashLogo } from 'src/styling/logos/icon-dash-colour.svg'
import { ReactComponent as EthereumLogo } from 'src/styling/logos/icon-ethereum-colour.svg'
import { ReactComponent as LitecoinLogo } from 'src/styling/logos/icon-litecoin-colour.svg'
import { ReactComponent as MoneroLogo } from 'src/styling/logos/icon-monero-colour.svg'
import { ReactComponent as TetherLogo } from 'src/styling/logos/icon-tether-colour.svg'
import { ReactComponent as ZCashLogo } from 'src/styling/logos/icon-zcash-colour.svg'

const styles = {
  logo: {
    maxHeight: 80,
    maxWidth: 200
  },
  title: {
    margin: [[24, 0, 32, 0]]
  },
  text: {
    margin: 0
  },
  button: {
    marginTop: 'auto',
    marginBottom: 58
  },
  modalContent: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: [[0, 42]],
    flex: 1
  }
}

const useStyles = makeStyles(styles)

const getLogo = code => {
  switch (code) {
    case 'BTC':
      return BitcoinLogo
    case 'BCH':
      return BitcoinCashLogo
    case 'DASH':
      return DashLogo
    case 'ETH':
      return EthereumLogo
    case 'LTC':
      return LitecoinLogo
    case 'ZEC':
      return ZCashLogo
    case 'USDT':
      return TetherLogo
    case 'XMR':
      return MoneroLogo
    default:
      return null
  }
}

const WizardSplash = ({ code, name, onContinue }) => {
  const classes = useStyles()
  const Logo = getLogo(code)

  return (

      <Logo className={classes.logo} />

Enable {name}

        You are about to enable {name} on your system. This will allow you to
        use this cryptocurrency on your machines. To be able to do that, you’ll
        have to set up all the necessary 3rd party services.

      <Button className={classes.button} onClick={onContinue}>
        Start configuration
      </Button>

  )
}

export default WizardSplash
<commit_msg>chore: remove USDT from WizardSplash<commit_after>import { makeStyles } from '@material-ui/core'
import React from 'react'

import { Button } from 'src/components/buttons'
import { H1, P } from 'src/components/typography'
import { ReactComponent as BitcoinLogo } from 'src/styling/logos/icon-bitcoin-colour.svg'
import { ReactComponent as BitcoinCashLogo } from 'src/styling/logos/icon-bitcoincash-colour.svg'
import { ReactComponent as DashLogo } from 'src/styling/logos/icon-dash-colour.svg'
import { ReactComponent as EthereumLogo } from 'src/styling/logos/icon-ethereum-colour.svg'
import { ReactComponent as LitecoinLogo } from 'src/styling/logos/icon-litecoin-colour.svg'
import { ReactComponent as MoneroLogo } from 'src/styling/logos/icon-monero-colour.svg'
import { ReactComponent as ZCashLogo } from 'src/styling/logos/icon-zcash-colour.svg'

const styles = {
  logo: {
    maxHeight: 80,
    maxWidth: 200
  },
  title: {
    margin: [[24, 0, 32, 0]]
  },
  text: {
    margin: 0
  },
  button: {
    marginTop: 'auto',
    marginBottom: 58
  },
  modalContent: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: [[0, 42]],
    flex: 1
  }
}

const useStyles = makeStyles(styles)

const getLogo = code => {
  switch (code) {
    case 'BTC':
      return BitcoinLogo
    case 'BCH':
      return BitcoinCashLogo
    case 'DASH':
      return DashLogo
    case 'ETH':
      return EthereumLogo
    case 'LTC':
      return LitecoinLogo
    case 'ZEC':
      return ZCashLogo
    case 'XMR':
      return MoneroLogo
    default:
      return null
  }
}

const WizardSplash = ({ code, name, onContinue }) => {
  const classes = useStyles()
  const Logo = getLogo(code)

  return (

      <Logo className={classes.logo} />

Enable {name}

        You are about to enable {name} on your system. This will allow you to
        use this cryptocurrency on your machines. To be able to do that, you’ll
        have to set up all the necessary 3rd party services.

      <Button className={classes.button} onClick={onContinue}>
        Start configuration
      </Button>

  )
}

export default WizardSplash
<|endoftext|>


<commit_before>/**********************************************************************
*
*
* XXX wikiword filter seems to act up on /
* XXX BUG? /test/wikiword -- produces nested links...
*
*
* XXX ROADMAP:
* 	- run in browser
* 		- basics, loading 							-- DONE
* 		- test localStorage / sessionStorage 		-- DONE
* 		- test pouch								-- DONE
* 		- render page								-- DONE
* 		- navigation
* 			- hash/anchor							-- DONE
* 			- service worker
* 				...handle relative urls (???)
* 		- migrate bootstrap
* 		- store topology
* 	- WikiWord										-- DONE
* 	- markdown										-- DONE??
* 	- pwa
* 	- archive old code
* 	- update docs
* 	- refactor and cleanup
* 		- module structure							-- DONE
* 	- pack as electron app (???)
*
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Architecture:
* 	store
* 	page
* 	renderer
*
* Modules:
* 	page				- base pages and page APIs (XXX should this be in lib???)
* 	parser				- pWiki macro parser (XXX should this be in lib???)
* 	store				- stores
* 		base			- memory store and store utils
*		file			- file storage
*		localstorage	- localStorage / sessionStorage stores
*		pouchdb			-
* 		...
* 	filter				- page filters
* 		base			- base filters incl. wikiword
* 		markdown		- markdown renderer
* 		...
* 	pwiki2				- main cli / node entry point
* 	browser				- browser entry point
* 	pwiki2-test			- testing and experimenting (XXX move to test.js)
*
*
* Q: can we make this a single module with +/- some plugins??
* 	...this would make things quite a bit simpler but will negate the
* 	use of high level libs like types...
*
*
* XXX weaknesses to review:
* 		- <store>.paths() as an index...
* 			+ decouples the search logic from the store backend
* 			- requires the whole list of pages to be in memory
* 				...need to be independent of the number of pages if at
* 				all possible -- otherwise this will hinder long-term use...
* 		-
* TODO:
* 	- <page>.then() -- resolve when all pending write operations done ???
* 	- an async REPL???
* 	- custom element???
*
*
*
***********************************************************************
*
* XXX might be a good idea to try signature based security:
* 		- sign changes
* 		- sign sync session
* 		- refuse changes with wrong signatures
* 		- public keys available on client and on server
* 			- check signatures localy
* 			- check signatures remotely
* 		- private key available only with author
* 		- keep both the last signed and superceding unsigned version
* 		- on sync ask to overwrite unsigned with signed
* 		- check if we can use the same mechanics as ssh...
* 		- in this view a user in the system is simply a set of keys and
* 			a signature (a page =))
*
* XXX pages into lib/page ???
*
* XXX add action to reset overloaded (bootstrap) pages...
* 		- per page
* 		- global
*
* XXX need to think about search -- page function argument syntax???
*
* XXX might need to get all the links (macro-level) from a page...
* 		...would be useful for caching...
*
* XXX .__paths__(..) may be a bottleneck...
* 		need to either think of a way around it or cache the path index
* 		in a sync way...
*
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
(function(require){ var module={} // make module AMD/node compatible...
/*********************************************************************/

// XXX
//var object = require('lib/object')
var object = require('ig-object')
var types = require('ig-types')

var pwpath = require('./pwiki/path')
var page = require('./pwiki/page')

var basestore = require('./pwiki/store/base')

//var localstoragestore = require('./store/localstorage')
// XXX for some reason this does not run quietly in browser
//var pouchdbstore = require('./store/pouchdb')
//var filestore = require('./store/file')

//---------------------------------------------------------------------
// Basic setup...
//
//
// Store topology:
//
// 		root (BaseStore) ---next--- main (MetaStore)
// 										|
// 										+-- System/... (BaseStore)
//
// Alternative store topology:
//
// 		root (BaseStore) ---next--- main (MetaStore)
// 			System/... (static)
//
//

var store =
module.store =
	//BaseStore.nest()
	// XXX clone...
	{ __proto__: basestore.BaseStore }
		.nest({ __proto__: basestore.MetaStore })

// XXX note sure how to organize the system actions -- there can be two
// 		options:
// 			- a root ram store with all the static stuff and nest the rest
// 			- a nested store (as is the case here)
// XXX nested system store...
store.update('System',
	Object.create(basestore.BaseStore).load(page.System))

// NOTE: in general the root wiki api is simply a page instance.
// XXX not yet sure how to organize the actual client -- UI, hooks, .. etc
var pwiki =
module.pwiki =
	page.Page('/', '/', store)

//---------------------------------------------------------------------
// comandline...

if(typeof(__filename) != 'undefined'
		&& __filename == (require.main || {}).filename){

}

/**********************************************************************
* vim:set ts=4 sw=4 nowrap :                        */ return module })
<commit_msg>notes...<commit_after>/**********************************************************************
*
*
* XXX wikiword filter seems to act up on /
* XXX BUG? /test/wikiword -- produces nested links...
*
*
* XXX ROADMAP:
* 	- run in browser
* 		- basics, loading 							-- DONE
* 		- test localStorage / sessionStorage 		-- DONE
* 		- test pouch								-- DONE
* 		- render page								-- DONE
* 		- navigation
* 			- hash/anchor							-- DONE
* 			- service worker
* 				...handle relative urls (???)
* 		- editor and interactivity
* 		- migrate bootstrap
* 		- store topology
* 	- WikiWord										-- DONE
* 	- markdown										-- DONE??
* 	- pwa
* 	- cli
* 		- basic wiki manipulations (1:1 methods)
* 		- import/export/sync
* 		- introspection/repl
* 	- archive old code
* 	- update docs
* 	- refactor and cleanup
* 		- module structure							-- DONE
* 	- pack as electron app (???)
*
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Architecture:
* 	store
* 	page
* 	renderer
*
* Modules:
* 	page				- base pages and page APIs (XXX should this be in lib???)
* 	parser				- pWiki macro parser (XXX should this be in lib???)
* 	store				- stores
* 		base			- memory store and store utils
*		file			- file storage
*		localstorage	- localStorage / sessionStorage stores
*		pouchdb			-
* 		...
* 	filter				- page filters
* 		base			- base filters incl. wikiword
* 		markdown		- markdown renderer
* 		...
* 	pwiki2				- main cli / node entry point
* 	browser				- browser entry point
* 	pwiki2-test			- testing and experimenting (XXX move to test.js)
*
*
* Q: can we make this a single module with +/- some plugins??
* 	...this would make things quite a bit simpler but will negate the
* 	use of high level libs like types...
*
*
* XXX weaknesses to review:
* 		- <store>.paths() as an index...
* 			+ decouples the search logic from the store backend
* 			- requires the whole list of pages to be in memory
* 				...need to be independent of the number of pages if at
* 				all possible -- otherwise this will hinder long-term use...
* 		-
* TODO:
* 	- <page>.then() -- resolve when all pending write operations done ???
* 	- an async REPL???
* 	- custom element???
*
*
*
***********************************************************************
*
* XXX might be a good idea to try signature based security:
* 		- sign changes
* 		- sign sync session
* 		- refuse changes with wrong signatures
* 		- public keys available on client and on server
* 			- check signatures localy
* 			- check signatures remotely
* 		- private key available only with author
* 		- keep both the last signed and superceding unsigned version
* 		- on sync ask to overwrite unsigned with signed
* 		- check if we can use the same mechanics as ssh...
* 		- in this view a user in the system is simply a set of keys and
* 			a signature (a page =))
*
* XXX pages into lib/page ???
*
* XXX add action to reset overloaded (bootstrap) pages...
* 		- per page
* 		- global
*
* XXX need to think about search -- page function argument syntax???
*
* XXX might need to get all the links (macro-level) from a page...
* 		...would be useful for caching...
*
* XXX .__paths__(..) may be a bottleneck...
* 		need to either think of a way around it or cache the path index
* 		in a sync way...
*
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
(function(require){ var module={} // make module AMD/node compatible...
/*********************************************************************/

// XXX
//var object = require('lib/object')
var object = require('ig-object')
var types = require('ig-types')

var pwpath = require('./pwiki/path')
var page = require('./pwiki/page')

var basestore = require('./pwiki/store/base')

//var localstoragestore = require('./store/localstorage')
// XXX for some reason this does not run quietly in browser
//var pouchdbstore = require('./store/pouchdb')
//var filestore = require('./store/file')

//---------------------------------------------------------------------
// Basic setup...
//
//
// Store topology:
//
// 		root (BaseStore) ---next--- main (MetaStore)
// 										|
// 										+-- System/... (BaseStore)
//
// Alternative store topology:
//
// 		root (BaseStore) ---next--- main (MetaStore)
// 			System/... (static)
//
//

var store =
module.store =
	//BaseStore.nest()
	// XXX clone...
	{ __proto__: basestore.BaseStore }
		.nest({ __proto__: basestore.MetaStore })

// XXX note sure how to organize the system actions -- there can be two
// 		options:
// 			- a root ram store with all the static stuff and nest the rest
// 			- a nested store (as is the case here)
// XXX nested system store...
store.update('System',
	Object.create(basestore.BaseStore).load(page.System))

// NOTE: in general the root wiki api is simply a page instance.
// XXX not yet sure how to organize the actual client -- UI, hooks, .. etc
var pwiki =
module.pwiki =
	page.Page('/', '/', store)

//---------------------------------------------------------------------
// comandline...

if(typeof(__filename) != 'undefined'
		&& __filename == (require.main || {}).filename){

}

/**********************************************************************
* vim:set ts=4 sw=4 nowrap :                        */ return module })
<|endoftext|>


<commit_before>/*
 * @author   Lucy Linder <lucy.derlin@gmail.com>
 * @date     February 2016
 * @context  Thymio Captain
 *
 * Copyright 2016 BlueMagic. All rights reserved.
 * Use of this source code is governed by an Apache 2 license
 * that can be found in the LICENSE file.
 */
(function(){

    /**
     * @ngdoc controller
     * @name thymioCaptain.app.MainCtrl
     *
     * @description
     * Main controller
     */
    angular
        .module( 'thymioCaptain.app' )
        .controller( 'MainCtrl', MainCtrl );

    // --------------------------

    function MainCtrl( $rootScope, ModalService, RestService, Action, History ){

        var self = this;

        self.actions = Action.actionsList();  // default actions available

        $rootScope.program = [];  // the program (set in the init())

        self.progState = 0;  // zero if in sync with the saved program
        self.notes = "";
        self.savedNotes = ""; // last saved notes

        _getCardId();    //TODO
        //self.cardId = "test";
        self.cardIdParam = {cardId: self.cardId}; //TODO

        _init();

        //##------------ functions

        self.canUndo = historyCanUndo;
        self.canRedo = historyCanRedo;
        self.undo = historyUndo;
        self.redo = histroyRedo;

        self.notesDirty = isNotesFieldDirty;

        self.save = saveCardInfos;
        self.upload = uploadProgram;
        self.run = runProgram;
        self.stop = stopProgram;

        self.dial = showRunStopDialog;

        self.contentLoaded = updateMdl;

        /* *****************************************************************
         * implementation
         * ****************************************************************/

        //##------------init

        function _init(){
            RestService.getCardData( self.cardIdParam, function( data ){
                $rootScope.program = Action.fromJson( data.program );
                _initNotes( data.notes );
                _initHistory();
                _addConfirmDialogOnClose();
                console.log( "Initialisation done: ", data );
                updateMdl();
            }, _log );
        }

        function _initNotes( notes ){
            self.notes = self.savedNotes = notes;
            updateMdl();
        }

        function _initHistory(){
            // progState == 0 only if the displayed program matches
            // the one saved in the cloud.
            var h = History.watch( 'program' );
            h.addChangeHandler( 'ch', function(){
                self.progState++;
            } );
            h.addUndoHandler( 'uh', function(){
                self.progState--;
            } );
            h.addRedoHandler( 'rh', function(){
                self.progState++;
            } );
        }

        function _addConfirmDialogOnClose(){
            // add confirmation dialog on close
            $( window ).bind( 'beforeunload', function(){
                    if( self.progState != 0 ) return 'Attention! Certains de tes changements ne sont pas' +
                        ' sauvegardés. En quittant la page, ces derniers seront perdus!';
                }
            );
        }

        function updateMdl(){
            console.log( "update mdl" );
            componentHandler.upgradeAllRegistered();
            if( self.notes )
                $( '#notesArea' ).addClass( "is-dirty" );
        }

        //##------------ drag and drop

        self.actionsDdConfig = {
            containment: '.grid-right',
            clone      : true
        };

        self.programDdConfig = {
            containment    : 'body',
            allowDuplicates: true
        };

        //##------------undo/redo

        function historyUndo(){
            History.undo( 'program' );
        }

        function histroyRedo(){
            History.redo( 'program' );
        }

        function historyCanRedo(){
            return History.canRedo( 'program' );
        }

        function historyCanUndo(){
            return History.canUndo( 'program' );
        }

        function isNotesFieldDirty(){
            return self.notes != self.savedNotes;
        }

        //##------------ rest

        function saveCardInfos(){
            RestService.setCardData( self.cardIdParam, {notes: self.notes, program: _createProg()}, function(){
                showToast( 'Programme sauvé!' );
                self.savedNotes = self.notes;
                self.progState = 0;
            }, function(){
                showToast( 'ERREUR: le programme n\'a pu être sauvé' );
            } );  // TODO errors
        }

        function uploadProgram(){
            if( $rootScope.program.length == 0 ){
                showMessageDialog( "Pas de programme", "Il faut d'abord que tu écrives un programme... " );
            }else{
                if( self.progState != 0 ){
                    // save prog before upload
                    RestService.setCardData( self.cardIdParam, {notes: self.notes, program: _createProg()}, function(){
                        self.progState = 0;
                        self.savedNotes = self.notes;
                        _uploadProgram();

                    }, function(){
                        showToast( 'ERREUR: le programme n\'a pu être sauvé' );
                    } );  // TODO errors

                }else{
                    _uploadProgram();
                }
            }
        }

        function _uploadProgram(){
            RestService.upload( self.cardIdParam, showRunStopDialog,
                function(){
                    showMessageDialog( "Pas de Thymio", "Tu n'as pas encore de Thymio attribué. Demande de l'aide à un" +
                        " animateur et réessaie." );
                } );
        }

        function runProgram(){
            RestService.run( self.cardIdParam, _log, _log );
        }

        function stopProgram(){
            RestService.stop( self.cardIdParam, _log, _log );
        }

        //##------------ dialogs and toasts

        function showMessageDialog( title, msg ){
            showDialog( {
                title   : title,
                text    : msg,
                positive: {
                    title: 'Ok'
                }
            } );
        }

        function showRunStopDialog(){
            ModalService.showModal( {
                templateUrl: 'runDialogTemplate.html',
                controller : "DefaultModalController",
                inputs     : {
                    attrs: {run: runProgram, stop: stopProgram}
                }

            } );
        }

        function showToast( message ){
            $( '.mdl-js-snackbar' )[0].MaterialSnackbar.showSnackbar(
                {
                    message: message,
                    timeout: 2000
                }
            );
        }

        //##------------ utils

        function _createProg(){
            var prog = [];
            angular.forEach( $rootScope.program, function( action ){
                prog.push( action.toJson() );
            } );
            return prog;
        }

        function _log( o ){
            console.log( o );
        }

        function _getCardId(){
            var m = window.location.pathname.match( '.*start/([^/#\?]*).*' );
            if( m && m.length > 1 ){
                self.cardId = m[1];
            }else{
                $( 'body' ).html( "ERREUR: pas de cardId. ACCES INTERDIT" );
            }
        }

    }

    /* *****************************************************************
     * modal
     * ****************************************************************/

    function ModalCtrl(){}

}());<commit_msg>Use DerlinModal<commit_after>/*
 * @author   Lucy Linder <lucy.derlin@gmail.com>
 * @date     February 2016
 * @context  Thymio Captain
 *
 * Copyright 2016 BlueMagic. All rights reserved.
 * Use of this source code is governed by an Apache 2 license
 * that can be found in the LICENSE file.
 */
(function(){

    /**
     * @ngdoc controller
     * @name thymioCaptain.app.MainCtrl
     *
     * @description
     * Main controller
     */
    angular
        .module( 'thymioCaptain.app' )
        .controller( 'MainCtrl', MainCtrl );

    // --------------------------

    function MainCtrl( $rootScope, ModalService, RestService, Action, History ){

        var self = this;

        self.actions = Action.actionsList();  // default actions available

        $rootScope.program = [];  // the program (set in the init())

        self.progState = 0;  // zero if in sync with the saved program
        self.notes = "";
        self.savedNotes = ""; // last saved notes

        _getCardId();    //TODO
        //self.cardId = "test";
        self.cardIdParam = {cardId: self.cardId}; //TODO

        _init();

        //##------------ functions

        self.canUndo = historyCanUndo;
        self.canRedo = historyCanRedo;
        self.undo = historyUndo;
        self.redo = histroyRedo;

        self.notesDirty = isNotesFieldDirty;

        self.save = saveCardInfos;
        self.upload = uploadProgram;
        self.run = runProgram;
        self.stop = stopProgram;

        self.dial = showRunStopDialog;

        self.contentLoaded = updateMdl;

        /* *****************************************************************
         * implementation
         * ****************************************************************/

        //##------------init

        function _init(){
            RestService.getCardData( self.cardIdParam, function( data ){
                $rootScope.program = Action.fromJson( data.program );
                _initNotes( data.notes );
                _initHistory();
                _addConfirmDialogOnClose();
                console.log( "Initialisation done: ", data );
                updateMdl();
            }, _log );
        }

        function _initNotes( notes ){
            self.notes = self.savedNotes = notes;
            updateMdl();
        }

        function _initHistory(){
            // progState == 0 only if the displayed program matches
            // the one saved in the cloud.
            var h = History.watch( 'program' );
            h.addChangeHandler( 'ch', function(){
                self.progState++;
            } );
            h.addUndoHandler( 'uh', function(){
                self.progState--;
            } );
            h.addRedoHandler( 'rh', function(){
                self.progState++;
            } );
        }

        function _addConfirmDialogOnClose(){
            // add confirmation dialog on close
            $( window ).bind( 'beforeunload', function(){
                    if( self.progState != 0 ) return 'Attention! Certains de tes changements ne sont pas' +
                        ' sauvegardés. En quittant la page, ces derniers seront perdus!';
                }
            );
        }

        function updateMdl(){
            console.log( "update mdl" );
            componentHandler.upgradeAllRegistered();
            if( self.notes )
                $( '#notesArea' ).addClass( "is-dirty" );
        }

        //##------------ drag and drop

        self.actionsDdConfig = {
            containment: '.grid-right',
            clone      : true
        };

        self.programDdConfig = {
            containment    : 'body',
            allowDuplicates: true
        };

        //##------------undo/redo

        function historyUndo(){
            History.undo( 'program' );
        }

        function histroyRedo(){
            History.redo( 'program' );
        }

        function historyCanRedo(){
            return History.canRedo( 'program' );
        }

        function historyCanUndo(){
            return History.canUndo( 'program' );
        }

        function isNotesFieldDirty(){
            return self.notes != self.savedNotes;
        }

        //##------------ rest

        function saveCardInfos(){
            RestService.setCardData( self.cardIdParam, {notes: self.notes, program: _createProg()}, function(){
                showToast( 'Programme sauvé!' );
                self.savedNotes = self.notes;
                self.progState = 0;
            }, function(){
                showToast( 'ERREUR: le programme n\'a pu être sauvé' );
            } );  // TODO errors
        }

        function uploadProgram(){
            if( $rootScope.program.length == 0 ){
                ModalService.showModal({
                    framework: "mdl",
                    title: "Pas de programme",
                    text: "Il faut d'abord que tu écrives un programme...",
                    cancelable: true
                });
            }else{
                if( self.progState != 0 ){
                    // save prog before upload
                    RestService.setCardData( self.cardIdParam, {notes: self.notes, program: _createProg()}, function(){
                        self.progState = 0;
                        self.savedNotes = self.notes;
                        _uploadProgram();

                    }, function(){
                        showToast( 'ERREUR: le programme n\'a pu être sauvé' );
                    } );  // TODO errors

                }else{
                    _uploadProgram();
                }
            }
        }

        function _uploadProgram(){
            RestService.upload( self.cardIdParam, showRunStopDialog,
                function(){
                    ModalService.showModal({
                        framework: "mdl",
                        title: "Pas de Thymio",
                        text: "Tu n'as pas encore de Thymio attribué. Demande de l'aide à un" +
                        " animateur et réessaie.",
                        cancelable: true
                    });
                } );
        }

        function runProgram(){
            RestService.run( self.cardIdParam, _log, _log );
        }

        function stopProgram(){
            RestService.stop( self.cardIdParam, _log, _log );
        }

        //##------------ dialogs and toasts

        function showRunStopDialog(){
            ModalService.showModal( {
                templateUrl: 'runDialogTemplate.html',
                controller : "DefaultModalController",
                inputs     : {
                    attrs: {run: runProgram, stop: stopProgram}
                }

            } );
        }

        function showToast( message ){
            $( '.mdl-js-snackbar' )[0].MaterialSnackbar.showSnackbar(
                {
                    message: message,
                    timeout: 2000
                }
            );
        }

        //##------------ utils

        function _createProg(){
            var prog = [];
            angular.forEach( $rootScope.program, function( action ){
                prog.push( action.toJson() );
            } );
            return prog;
        }

        function _log( o ){
            console.log( o );
        }

        function _getCardId(){
            var m = window.location.pathname.match( '.*start/([^/#\?]*).*' );
            if( m && m.length > 1 ){
                self.cardId = m[1];
            }else{
                $( 'body' ).html( "ERREUR: pas de cardId. ACCES INTERDIT" );
            }
        }

    }

    /* *****************************************************************
     * modal
     * ****************************************************************/

    function ModalCtrl(){}

}());<|endoftext|>


<commit_before>'use strict';

module.exports = function (GQL) {
  return {
    name: 'Group',
    interfaces: ['Node'],
    nodeId: id => GQL.options.DB.getGroup(id),
    isTypeOf: obj => obj instanceof GQL.options.DB.Group,
    fields: {
      id: { type: 'Int' },
      name: { type: 'String' },
      members: {
        type: '@User',
        resolve: (group, args) => {
          return group.members;
        }
      }
    },
    queries: {
      group: require('./queries/group')
    }
  };
};
<commit_msg>Small code reordering<commit_after>'use strict';

module.exports = function (GQL) {
  return {
    name: 'Group',
    interfaces: ['Node'],
    nodeId: id => GQL.options.DB.getGroup(id),
    isTypeOf: obj => obj instanceof GQL.options.DB.Group,
    fields: {
      id: { type: 'Int' },
      name: { type: 'String' },
      members: {
        type: '@User',
        resolve: (group, args) => group.members
      }
    },
    queries: {
      group: require('./queries/group')
    }
  };
};
<|endoftext|>


<commit_before>window.showCrosswalkPI = function() {
    var headers = {
        0: "hs_id",
        1: "cnae_id"
    }

    var loadingCrosswalkPI = dataviva.ui.loading('.crosswalk-pi .crosswalk-pi-wrapper');
    loadingCrosswalkPI.text(dataviva.dictionary['loading'] + "...");

    var ProductIndustryTable = function () {
        this.tableId = '#crosswalk-pi-table';

        this.table = $(this.tableId).DataTable({
            "ajax": {
                "url": "/help/crosswalk/pi",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        return dataviva.hs[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        for(i=0; i<row[1].length; i++){
                            if(dataviva.cnae[ row[1][i] ])
                                result += (i != 0 ? '
' : '') + dataviva.cnae[row[1][i]].name.truncate(40) + ' (' + row[1][i] + ')';
                        }
                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkPI.show();
                $('.crosswalk-pi .crosswalk-pi-wrapper .crosswalk-pi-content').show();
                loadingCrosswalkPI.hide();
            }
        });
    };
    window.productIndustry = new ProductIndustryTable(loadingCrosswalkPI.hide());
};

window.showCrosswalkIP = function() {
    var headers = {
        0: "cnae_id",
        1: "hs_id"
    }

    var loadingCrosswalkIP = dataviva.ui.loading('.crosswalk-ip .crosswalk-ip-wrapper');
    loadingCrosswalkIP.text(dataviva.dictionary['loading'] + "...");

    var IndustryProductTable = function () {
        this.tableId = '#crosswalk-ip-table';

        this.table = $(this.tableId).DataTable({
            "ajax": {
                "url": "/help/crosswalk/ip",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        if (dataviva.cnae[row[0]]){
                            return dataviva.cnae[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                        }
                        else{
                            return '-';
                        }

                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        $.each(row[1], function(i, value) {
                            if(dataviva.hs[ value ])
                                result += (i != 0 ? '
' : '') + dataviva.hs[value].name.truncate(40) + ' (' + value + ')';
                        });
                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkIP.show();
                $('.crosswalk-ip .crosswalk-ip-wrapper .crosswalk-ip-content').show();
                loadingCrosswalkIP.hide();
            }
        });
    };
    window.industryProduct = new IndustryProductTable(loadingCrosswalkIP.hide());
};

window.showCrosswalkOC = function() {
    var headers = {
        0: "cbo_id",
        1: "course_hedu_id"
    }

    var loadingCrosswalkOC = dataviva.ui.loading('.crosswalk-oc .crosswalk-oc-wrapper');
    loadingCrosswalkOC.text(dataviva.dictionary['loading'] + "...");

    var OccupationCourseTable = function () {
        this.tableId = '#crosswalk-oc-table';

        this.table = $(this.tableId).DataTable({
            "ajax": {
                "url": "/help/crosswalk/oc",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                            return dataviva.cbo[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        $.each(row[1], function(i, value) {
                            if(dataviva.course_hedu[ value ])
                                result += (i != 0 ? '
' : '') + dataviva.course_hedu[value].name.truncate(40) + ' (' + value + ')';
                            else
                                result += (i != 0 ? '
' : '') + dataviva.course_sc[value.substr(1,5)].name.truncate(40) + ' (' + value.substr(1,5) + ')';
                        });

                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkOC.show();
                $('.crosswalk-oc .crosswalk-oc-wrapper .crosswalk-oc-content').show();
                loadingCrosswalkOC.hide();
            }
        });
    };
    window.occupationCourse = new OccupationCourseTable(loadingCrosswalkOC.hide());
};

window.showCrosswalkCO = function() {
    var headers = {
        0: "course_hedu_id",
        1: "cbo_id"
    }

    var loadingCrosswalkCO = dataviva.ui.loading('.crosswalk-co .crosswalk-co-wrapper');
    loadingCrosswalkCO.text(dataviva.dictionary['loading'] + "...");

    var CourseOccupationTable = function () {
        this.tableId = '#crosswalk-co-table';

        this.table = $(this.tableId).DataTable({
            "ajax": {
                "url": "/help/crosswalk/co",
                "dataSrc": "data",
                "cache": true
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        if(row[0].match(/^[0-9]+$/)){
                           return dataviva.course_sc[row[0].substr(1,5)].name.truncate(40) + ' (' + row[0].substr(1,5) + ')';
                        }
                        else if (dataviva.course_hedu[row[0]]){
                            return dataviva.course_hedu[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                        }
                        else{
                            return row[0];
                        }
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        for(i=0; i<row[1].length; i++){
                            if(dataviva.cbo[ row[1][i] ])
                                result += (i != 0 ? '
' : '') + dataviva.cbo[row[1][i]].name.truncate(40) + ' (' + row[1][i] + ')';
                        }
                        return result != '' ? result : "-";
                    }
                },
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkCO.show();
                $('.crosswalk-co .crosswalk-co-wrapper .crosswalk-co-content').show();
                loadingCrosswalkCO.hide();
            }
        });
    };
    window.courseOccupation = new CourseOccupationTable(loadingCrosswalkCO.hide());
};

$('.product-industry').on('click', function(){
    dataviva.requireAttrs(['hs', 'cnae'], function() {
        if(!window.productIndustry){
            showCrosswalkPI();
        }
    });
});

$('.industry-product').on('click', function(){
    dataviva.requireAttrs(['hs', 'cnae'], function() {
        if(!window.industryProduct){
            showCrosswalkIP();
        }
    });
});

$('.occupation-course').on('click', function(){

    dataviva.requireAttrs(['course_sc', 'cbo', 'course_hedu'], function() {
        if(!window.occupationCourse){
            showCrosswalkOC();
        }
    });
});

$('.course-occupation').on('click', function(){
    dataviva.requireAttrs(['course_sc', 'cbo', 'course_hedu'], function() {
         if(!window.courseOccupation){
            showCrosswalkCO();
        }
    });
});
<commit_msg>Adds download button to crosswalks datatables<commit_after>window.showCrosswalkPI = function() {
    var headers = {
        0: "hs_id",
        1: "cnae_id"
    }

    var loadingCrosswalkPI = dataviva.ui.loading('.crosswalk-pi .crosswalk-pi-wrapper');
    loadingCrosswalkPI.text(dataviva.dictionary['loading'] + "...");

    var ProductIndustryTable = function () {
        this.tableId = '#crosswalk-pi-table';

        this.table = $(this.tableId).DataTable({
            dom: 'Bfti',
            "buttons": [
                {
                    extend: 'csvHtml5',
                    text: '',
                    filename: 'dataviva-help-crosswalk-pi'
                }
            ],
            "ajax": {
                "url": "/help/crosswalk/pi",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        return dataviva.hs[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        for(i=0; i<row[1].length; i++){
                            if(dataviva.cnae[ row[1][i] ])
                                result += (i != 0 ? '
' : '') + dataviva.cnae[row[1][i]].name.truncate(40) + ' (' + row[1][i] + ')';
                        }
                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkPI.show();
                $('.crosswalk-pi .crosswalk-pi-wrapper .crosswalk-pi-content').show();
                loadingCrosswalkPI.hide();
            }
        });
    };
    window.productIndustry = new ProductIndustryTable(loadingCrosswalkPI.hide());
};

window.showCrosswalkIP = function() {
    var headers = {
        0: "cnae_id",
        1: "hs_id"
    }

    var loadingCrosswalkIP = dataviva.ui.loading('.crosswalk-ip .crosswalk-ip-wrapper');
    loadingCrosswalkIP.text(dataviva.dictionary['loading'] + "...");

    var IndustryProductTable = function () {
        this.tableId = '#crosswalk-ip-table';

        this.table = $(this.tableId).DataTable({
            dom: 'Bfti',
            "buttons": [
                {
                    extend: 'csvHtml5',
                    text: '',
                    filename: 'dataviva-help-crosswalk-ip'
                }
            ],
            "ajax": {
                "url": "/help/crosswalk/ip",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        if (dataviva.cnae[row[0]]){
                            return dataviva.cnae[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                        }
                        else{
                            return '-';
                        }

                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        $.each(row[1], function(i, value) {
                            if(dataviva.hs[ value ])
                                result += (i != 0 ? '
' : '') + dataviva.hs[value].name.truncate(40) + ' (' + value + ')';
                        });
                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkIP.show();
                $('.crosswalk-ip .crosswalk-ip-wrapper .crosswalk-ip-content').show();
                loadingCrosswalkIP.hide();
            }
        });
    };
    window.industryProduct = new IndustryProductTable(loadingCrosswalkIP.hide());
};

window.showCrosswalkOC = function() {
    var headers = {
        0: "cbo_id",
        1: "course_hedu_id"
    }

    var loadingCrosswalkOC = dataviva.ui.loading('.crosswalk-oc .crosswalk-oc-wrapper');
    loadingCrosswalkOC.text(dataviva.dictionary['loading'] + "...");

    var OccupationCourseTable = function () {
        this.tableId = '#crosswalk-oc-table';

        this.table = $(this.tableId).DataTable({
            dom: 'Bfti',
            "buttons": [
                {
                    extend: 'csvHtml5',
                    text: '',
                    filename: 'dataviva-help-crosswalk-oc'
                }
            ],
            "ajax": {
                "url": "/help/crosswalk/oc",
                "dataSrc": "data",
                "cache": true,
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                            return dataviva.cbo[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        $.each(row[1], function(i, value) {
                            if(dataviva.course_hedu[ value ])
                                result += (i != 0 ? '
' : '') + dataviva.course_hedu[value].name.truncate(40) + ' (' + value + ')';
                            else
                                result += (i != 0 ? '
' : '') + dataviva.course_sc[value.substr(1,5)].name.truncate(40) + ' (' + value.substr(1,5) + ')';
                        });

                        return result != '' ? result : "-";
                    }
                }
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkOC.show();
                $('.crosswalk-oc .crosswalk-oc-wrapper .crosswalk-oc-content').show();
                loadingCrosswalkOC.hide();
            }
        });
    };
    window.occupationCourse = new OccupationCourseTable(loadingCrosswalkOC.hide());
};

window.showCrosswalkCO = function() {
    var headers = {
        0: "course_hedu_id",
        1: "cbo_id"
    }

    var loadingCrosswalkCO = dataviva.ui.loading('.crosswalk-co .crosswalk-co-wrapper');
    loadingCrosswalkCO.text(dataviva.dictionary['loading'] + "...");

    var CourseOccupationTable = function () {
        this.tableId = '#crosswalk-co-table';

        this.table = $(this.tableId).DataTable({
            dom: 'Bfti',
            "buttons": [
                {
                    extend: 'csvHtml5',
                    text: '',
                    filename: 'dataviva-help-crosswalk-co'
                }
            ],
            "ajax": {
                "url": "/help/crosswalk/co",
                "dataSrc": "data",
                "cache": true
            },
            "order": [],
            "columns": [
                {
                    render: function (data, type, row, meta){
                        if(row[0].match(/^[0-9]+$/)){
                           return dataviva.course_sc[row[0].substr(1,5)].name.truncate(40) + ' (' + row[0].substr(1,5) + ')';
                        }
                        else if (dataviva.course_hedu[row[0]]){
                            return dataviva.course_hedu[row[0]].name.truncate(40) + ' (' + row[0] + ')';
                        }
                        else{
                            return row[0];
                        }
                    }
                },
                {
                    render: function (data, type, row, meta){
                        result = '';
                        for(i=0; i<row[1].length; i++){
                            if(dataviva.cbo[ row[1][i] ])
                                result += (i != 0 ? '
' : '') + dataviva.cbo[row[1][i]].name.truncate(40) + ' (' + row[1][i] + ')';
                        }
                        return result != '' ? result : "-";
                    }
                },
            ],
            "deferRender": true,
            "language": dataviva.datatables.language,
            "scrollY": 500,
            "scrollX": true,
            "scrollCollapse": true,
            "scroller": true,
            initComplete: function () {
                loadingCrosswalkCO.show();
                $('.crosswalk-co .crosswalk-co-wrapper .crosswalk-co-content').show();
                loadingCrosswalkCO.hide();
            }
        });
    };
    window.courseOccupation = new CourseOccupationTable(loadingCrosswalkCO.hide());
};

$('.product-industry').on('click', function(){
    dataviva.requireAttrs(['hs', 'cnae'], function() {
        if(!window.productIndustry){
            showCrosswalkPI();
        }
    });
});

$('.industry-product').on('click', function(){
    dataviva.requireAttrs(['hs', 'cnae'], function() {
        if(!window.industryProduct){
            showCrosswalkIP();
        }
    });
});

$('.occupation-course').on('click', function(){

    dataviva.requireAttrs(['course_sc', 'cbo', 'course_hedu'], function() {
        if(!window.occupationCourse){
            showCrosswalkOC();
        }
    });
});

$('.course-occupation').on('click', function(){
    dataviva.requireAttrs(['course_sc', 'cbo', 'course_hedu'], function() {
         if(!window.courseOccupation){
            showCrosswalkCO();
        }
    });
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var paths = require('../paths');
var typedoc = require('gulp-typedoc');
var typedocExtractor = require('gulp-typedoc-extractor');
var runSequence = require('run-sequence');

gulp.task('doc-generate', function(){
  return gulp.src([paths.output + '*.d.ts', paths.doc + '/core-js.d.ts', './jspm_packages/npm/*/*.d.ts'])
    .pipe(typedoc({
      target: 'es6',
      includeDeclarations: true,
      json: paths.doc + '/api.json',
      name: paths.packageName + '-docs',
      mode: 'modules',
      excludeExternals: true,
      ignoreCompilerErrors: false,
      version: true
    }));
});

gulp.task('doc-extract', function(){
  return gulp.src([paths.doc + '/api.json'])
    .pipe(typedocExtractor(paths.output + 'amd/' + paths.packageName))
    .pipe(gulp.dest(paths.doc));
});

gulp.task('doc', function(callback){
  return runSequence(
    'doc-generate',
    'doc-extract',
    callback
  );
});
<commit_msg>chore(build): working on docs generation<commit_after>var gulp = require('gulp');
var paths = require('../paths');
var typedoc = require('gulp-typedoc');
var typedocExtractor = require('gulp-typedoc-extractor');
var runSequence = require('run-sequence');

gulp.task('doc-generate', function(){
  return gulp.src([paths.output + '*.d.ts', paths.doc + '/core-js.d.ts', './jspm_packages/npm/*/*.d.ts'])
    .pipe(typedoc({
      target: 'es6',
      includeDeclarations: true,
      json: paths.doc + '/api.json',
      name: paths.packageName + '-docs',
      mode: 'modules',
      excludeExternals: true,
      ignoreCompilerErrors: false,
      version: true
    }));
});

gulp.task('doc-extract', function(){
  return gulp.src([paths.doc + '/api.json'])
    .pipe(typedocExtractor(paths.packageName))
    .pipe(gulp.dest(paths.doc));
});

gulp.task('doc', function(callback){
  return runSequence(
    'doc-generate',
    'doc-extract',
    callback
  );
});
<|endoftext|>


<commit_before>(function() {
  const Cc = Components.classes;
  const Ci = Components.interfaces;

  var prefs = Cc["@mozilla.org/preferences-service;1"]
                    .getService(Ci.nsIPrefBranch);
  var env = Cc["@mozilla.org/process/environment;1"]
                    .getService(Ci.nsIEnvironment);

  if (!(prefs.getBoolPref('extensions.torbirdy.startup_folder'))) {
    window.loadStartFolder = function() {
      var startupFolder = GetMsgFolderFromUri("mailbox://nobody@Local%20Folders");
      if (startupFolder) {
        if (window.gFolderTreeView) {
          gFolderTreeView.selectFolder(startupFolder);
        }
      }
    };
  }

  window.TorBirdy = {
    onLoad: function() {
      var infoRun = "extensions.torbirdy.info_run";
      if (prefs.getBoolPref(infoRun)) {
        window.open("chrome://castironthunderbirdclub/content/firstruninfo.xul",
                    "FirstRunWindow",
                    "chrome, dialog, centerscreen, resizable=no");
        prefs.setBoolPref(infoRun, false);
      }

      // Set the time zone to UTC if the preference is true.
      if (prefs.getBoolPref("extensions.torbirdy.timezone")) {
        env.set('TZ', 'UTC');
      }

      // Check if we are running Whonix.
      var whonix = false;
      if (env.exists("WHONIX")) {
        whonix = true;
      }

      var myPanel = document.getElementById("torbirdy-my-panel");
      var strbundle = document.getElementById("torbirdy-strings-overlay");

      // If all other preferences have been set in `components/torbirdy.js'
      if (prefs.getBoolPref("extensions.torbirdy.protected")) {
        var type = prefs.getIntPref("extensions.torbirdy.proxy");
        myPanel.style.color = "green";

        // Tor.
        if (type === 0) {
          myPanel.label = strbundle.getString("torbirdy.enabled.tor");
        }
        // JonDo/Whonix.
        if (type === 1) {
          if (prefs.getIntPref("extensions.torbirdy.proxy.type") === 0) {
            myPanel.label = strbundle.getString("torbirdy.enabled.jondo");
          }
          if (prefs.getIntPref("extensions.torbirdy.proxy.type") === 1) {
            myPanel.label = strbundle.getString("torbirdy.enabled.whonix");
          }
        }
        // Custom.
        if (type === 2) {
          myPanel.label = strbundle.getString("torbirdy.enabled.custom");
        }
        // Whonix.
        if (whonix && prefs.getBoolPref("extensions.torbirdy.whonix_run")) {
          myPanel.label = strbundle.getString("torbirdy.enabled.whonix");
          org.torbirdy.prefs.setProxyWhonix();
        }
        // Transparent Torification.
        if (type === 3) {
          myPanel.label = strbundle.getString("torbirdy.enabled.torification");
          myPanel.style.color = "red";
        }
        prefs.setBoolPref("extensions.torbirdy.whonix_run", false);
      }
      else {
        myPanel.label = strbundle.getString("torbirdy.enabled.disabled");
        myPanel.style.color = "red";
      }
    }
  };

})();

window.addEventListener("load", function() { TorBirdy.onLoad(); }, false);
<commit_msg>Fix bug #7776 that did not preserve the Message Pane setting<commit_after>(function() {
  const Cc = Components.classes;
  const Ci = Components.interfaces;

  var prefs = Cc["@mozilla.org/preferences-service;1"]
                    .getService(Ci.nsIPrefBranch);
  var env = Cc["@mozilla.org/process/environment;1"]
                    .getService(Ci.nsIEnvironment);

  if (!(prefs.getBoolPref('extensions.torbirdy.startup_folder'))) {
    if (window.gFolderTreeView) {
      gFolderTreeView.selectFolder = function() { return; }
    }
  };

  window.TorBirdy = {
    onLoad: function() {
      var infoRun = "extensions.torbirdy.info_run";
      if (prefs.getBoolPref(infoRun)) {
        window.open("chrome://castironthunderbirdclub/content/firstruninfo.xul",
                    "FirstRunWindow",
                    "chrome, dialog, centerscreen, resizable=no");
        prefs.setBoolPref(infoRun, false);
      }

      // Set the time zone to UTC if the preference is true.
      if (prefs.getBoolPref("extensions.torbirdy.timezone")) {
        env.set('TZ', 'UTC');
      }

      // Check if we are running Whonix.
      var whonix = false;
      if (env.exists("WHONIX")) {
        whonix = true;
      }

      var myPanel = document.getElementById("torbirdy-my-panel");
      var strbundle = document.getElementById("torbirdy-strings-overlay");

      // If all other preferences have been set in `components/torbirdy.js'
      if (prefs.getBoolPref("extensions.torbirdy.protected")) {
        var type = prefs.getIntPref("extensions.torbirdy.proxy");
        myPanel.style.color = "green";

        // Tor.
        if (type === 0) {
          myPanel.label = strbundle.getString("torbirdy.enabled.tor");
        }
        // JonDo/Whonix.
        if (type === 1) {
          if (prefs.getIntPref("extensions.torbirdy.proxy.type") === 0) {
            myPanel.label = strbundle.getString("torbirdy.enabled.jondo");
          }
          if (prefs.getIntPref("extensions.torbirdy.proxy.type") === 1) {
            myPanel.label = strbundle.getString("torbirdy.enabled.whonix");
          }
        }
        // Custom.
        if (type === 2) {
          myPanel.label = strbundle.getString("torbirdy.enabled.custom");
        }
        // Whonix.
        if (whonix && prefs.getBoolPref("extensions.torbirdy.whonix_run")) {
          myPanel.label = strbundle.getString("torbirdy.enabled.whonix");
          org.torbirdy.prefs.setProxyWhonix();
        }
        // Transparent Torification.
        if (type === 3) {
          myPanel.label = strbundle.getString("torbirdy.enabled.torification");
          myPanel.style.color = "red";
        }
        prefs.setBoolPref("extensions.torbirdy.whonix_run", false);
      }
      else {
        myPanel.label = strbundle.getString("torbirdy.enabled.disabled");
        myPanel.style.color = "red";
      }
    }
  };

})();

window.addEventListener("load", function() { TorBirdy.onLoad(); }, false);
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var mbus = require('mbus');

// define some state mappings to simplify the events we generate
var stateMappings = {
  completed: 'connected'
};

// define the events that we need to watch for peer connection
// state changes
var peerStateEvents = [
  'signalingstatechange',
  'iceconnectionstatechange',
];

/**
  ### rtc-tools/monitor

  ```
  monitor(pc, targetId, signaller, parentBus) => mbus
  ```

  The monitor is a useful tool for determining the state of `pc` (an
  `RTCPeerConnection`) instance in the context of your application. The
  monitor uses both the `iceConnectionState` information of the peer
  connection and also the various
  [signaller events](https://github.com/rtc-io/rtc-signaller#signaller-events)
  to determine when the connection has been `connected` and when it has
  been `disconnected`.

  A monitor created `mbus` is returned as the result of a
  [couple](https://github.com/rtc-io/rtc#rtccouple) between a local peer
  connection and it's remote counterpart.

**/
module.exports = function(pc, targetId, signaller, parentBus) {
  var monitor = mbus('', parentBus);
  var state;

  function checkState() {
    var newState = getMappedState(pc.iceConnectionState);

    // flag the we had a state change
    monitor('statechange', pc, newState);

    // if the active state has changed, then send the appopriate message
    if (state !== newState) {
      monitor(newState);
      state = newState;
    }
  }

  function handleClose() {
    monitor('closed');
  }

  function handlePeerLeave(peerId) {
    // if the peer leaving is not the peer we are connected to
    // then we aren't interested
    if (peerId !== targetId) {
      return;
    }

    // trigger a closed event
    monitor('closed');
  }

  pc.addEventListener('close', handleClose);
  peerStateEvents.forEach(function(evtName) {
    pc.addEventListener(evtName, checkState);
  });

  monitor.stop = function() {
    pc.removeEventListener('close', handleClose);
    peerStateEvents.forEach(function(evtName) {
      pc.removeEventListener(evtName, checkState);
    });

    // remove the peer:leave listener
    if (signaller && typeof signaller.removeListener == 'function') {
      signaller.removeListener('peer:leave', handlePeerLeave);
    }
  };

  monitor.checkState = checkState;

  // if we haven't been provided a valid peer connection, abort
  if (! pc) {
    return monitor;
  }

  // determine the initial is active state
  state = getMappedState(pc.iceConnectionState);

  // if we've been provided a signaller, then watch for peer:leave events
  if (signaller && typeof signaller.on == 'function') {
    signaller.on('peer:leave', handlePeerLeave);
  }

  return monitor;
};

/* internal helpers */

function getMappedState(state) {
  return stateMappings[state] || state;
}
<commit_msg>Use on event handlers for monitoring rather than addEventListener - ref #33<commit_after>/* jshint node: true */
'use strict';

var mbus = require('mbus');

// define some state mappings to simplify the events we generate
var stateMappings = {
  completed: 'connected'
};

// define the events that we need to watch for peer connection
// state changes
var peerStateEvents = [
  'signalingstatechange',
  'iceconnectionstatechange',
];

/**
  ### rtc-tools/monitor

  ```
  monitor(pc, targetId, signaller, parentBus) => mbus
  ```

  The monitor is a useful tool for determining the state of `pc` (an
  `RTCPeerConnection`) instance in the context of your application. The
  monitor uses both the `iceConnectionState` information of the peer
  connection and also the various
  [signaller events](https://github.com/rtc-io/rtc-signaller#signaller-events)
  to determine when the connection has been `connected` and when it has
  been `disconnected`.

  A monitor created `mbus` is returned as the result of a
  [couple](https://github.com/rtc-io/rtc#rtccouple) between a local peer
  connection and it's remote counterpart.

**/
module.exports = function(pc, targetId, signaller, parentBus) {
  var monitor = mbus('', parentBus);
  var state;

  function checkState() {
    var newState = getMappedState(pc.iceConnectionState);

    // flag the we had a state change
    monitor('statechange', pc, newState);

    // if the active state has changed, then send the appopriate message
    if (state !== newState) {
      monitor(newState);
      state = newState;
    }
  }

  function handleClose() {
    monitor('closed');
  }

  function handlePeerLeave(peerId) {
    // if the peer leaving is not the peer we are connected to
    // then we aren't interested
    if (peerId !== targetId) {
      return;
    }

    // trigger a closed event
    monitor('closed');
  }

  pc.onclose = handleClose;
  peerStateEvents.forEach(function(evtName) {
    pc['on' + evtName] = checkState;
  });

  monitor.stop = function() {
    pc.onclose = null;
    peerStateEvents.forEach(function(evtName) {
      pc['on' + evtName] = null;
    });

    // remove the peer:leave listener
    if (signaller && typeof signaller.removeListener == 'function') {
      signaller.removeListener('peer:leave', handlePeerLeave);
    }
  };

  monitor.checkState = checkState;

  // if we haven't been provided a valid peer connection, abort
  if (! pc) {
    return monitor;
  }

  // determine the initial is active state
  state = getMappedState(pc.iceConnectionState);

  // if we've been provided a signaller, then watch for peer:leave events
  if (signaller && typeof signaller.on == 'function') {
    signaller.on('peer:leave', handlePeerLeave);
  }

  return monitor;
};

/* internal helpers */

function getMappedState(state) {
  return stateMappings[state] || state;
}
<|endoftext|>


<commit_before>/*
 * Video.js Hotkeys
 * https://github.com/ctd1500/videojs-hotkeys
 *
 * Copyright (c) 2015 Chris Dougherty
 * Licensed under the Apache-2.0 license.
 */

'use strict';
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define('videojs_hotkeys', ['videojs'], function(videojs) { factory(root, videojs); });
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = factory(root, require('videojs'));
  } else {
    factory(root, root.videojs);
  }

})(this, function(window, videojs) {
    window['videojs_hotkeys'] = {version: "0.2.8"};

    var hotkeys = function(options) {
      var player = this;
      var pEl = player.el();
      var def_options = {
        volumeStep: 0.1,
        seekStep: 5,
        enableMute: true,
        enableFullscreen: true,
        enableNumbers: true,
        enableJogStyle: false,
        alwaysCaptureHotkeys: false,
        playPauseKey: playPauseKey,
        rewindKey: rewindKey,
        forwardKey: forwardKey,
        volumeUpKey: volumeUpKey,
        volumeDownKey: volumeDownKey,
        muteKey: muteKey,
        fullscreenKey: fullscreenKey,
        customKeys: {}
      };

      const cPlay = 1,
        cRewind = 2,
        cForward = 3,
        cVolumeUp = 4,
        cVolumeDown = 5,
        cMute = 6,
        cFullscreen = 7;

      // Use built-in merge function from Video.js v5.0+ or v4.4.0+
      var mergeOptions = videojs.mergeOptions || videojs.util.mergeOptions;
      options = mergeOptions(def_options, options || {});

      var volumeStep = options.volumeStep,
        seekStep = options.seekStep,
        enableMute = options.enableMute,
        enableFull = options.enableFullscreen,
        enableNumbers = options.enableNumbers,
        enableJogStyle = options.enableJogStyle,
        alwaysCaptureHotkeys = options.alwaysCaptureHotkeys;

      // Set default player tabindex to handle keydown and doubleclick events
      if (!pEl.hasAttribute('tabIndex')) {
        pEl.setAttribute('tabIndex', '-1');
      }

      if (alwaysCaptureHotkeys) {
        player.one('play', function() {
          pEl.focus(); // Fixes the .vjs-big-play-button handing focus back to body instead of the player
        });
      }

      player.on('play', function() {
        // Fix allowing the YouTube plugin to have hotkey support.
        var ifblocker = pEl.querySelector('.iframeblocker');
        if (ifblocker && ifblocker.style.display === '') {
          ifblocker.style.display = "block";
          ifblocker.style.bottom = "39px";
        }
      });

      var keyDown = function keyDown(event) {

        var ewhich = event.which, curTime;
        var ePreventDefault = event.preventDefault;
        // When controls are disabled, hotkeys will be disabled as well
        if (player.controls()) {

          // Don't catch keys if any control buttons are focused, unless alwaysCaptureHotkeys is true
          var activeEl = document.activeElement;
          if (alwaysCaptureHotkeys ||
              activeEl == pEl ||
              activeEl == pEl.querySelector('.vjs-tech') ||
              activeEl == pEl.querySelector('.vjs-control-bar') ||
              activeEl == pEl.querySelector('.iframeblocker')) {

            switch (checkKeys(event, player)) {

              // Spacebar toggles play/pause
              case cPlay:
                ePreventDefault();
                if (alwaysCaptureHotkeys) {
                  // Prevent control activation with space
                  event.stopPropagation();
                }

                if (player.paused()) {
                  player.play();
                } else {
                  player.pause();
                }
                break;

              // Seeking with the left/right arrow keys
              case cRewind: // Seek Backward
                ePreventDefault();
                curTime = player.currentTime() - seekStep;
                // The flash player tech will allow you to seek into negative
                // numbers and break the seekbar, so try to prevent that.
                if (player.currentTime() <= seekStep) {
                  curTime = 0;
                }
                player.currentTime(curTime);
                break;
              case cForward: // Seek Forward
                ePreventDefault();
                player.currentTime(player.currentTime() + seekStep);
                break;

              // Volume control with the up/down arrow keys
              case cVolumeDown:
                ePreventDefault();
                if (!enableJogStyle) {
                  player.volume(player.volume() - volumeStep);
                } else {
                  curTime = player.currentTime() - 1;
                  if (player.currentTime() <= 1) {
                    curTime = 0;
                  }
                  player.currentTime(curTime);
                }
                break;
              case cVolumeUp:
                ePreventDefault();
                if (!enableJogStyle) {
                  player.volume(player.volume() + volumeStep);
                } else {
                  player.currentTime(player.currentTime() + 1);
                }
                break;

              // Toggle Mute with the M key
              case cMute:
                if (enableMute) {
                  player.muted(!player.muted());
                }
                break;

              // Toggle Fullscreen with the F key
              case  cFullscreen:
                if (enableFull) {
                  if (player.isFullscreen()) {
                    player.exitFullscreen();
                  } else {
                    player.requestFullscreen();
                  }
                }
                break;

              default:
                // Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%
                if ((ewhich > 47 && ewhich < 59) || (ewhich > 95 && ewhich < 106)) {
                  if (enableNumbers) {
                    var sub = 48;
                    if (ewhich > 95) {
                      sub = 96;
                    }
                    var number = ewhich - sub;
                    ePreventDefault();
                    player.currentTime(player.duration() * number * 0.1);
                  }
                }

                // Handle any custom hotkeys
                for (var customKey in options.customKeys) {
                  var customHotkey = options.customKeys[customKey];
                  // Check for well formed custom keys
                  if (customHotkey && customHotkey.key && customHotkey.handler) {
                    // Check if the custom key's condition matches
                    if (customHotkey.key(event)) {
                      ePreventDefault();
                      customHotkey.handler(player, options);
                    }
                  }
                }
            }
          }
        }
      };

      var doubleClick = function doubleClick(event) {

        // When controls are disabled, hotkeys will be disabled as well
        if (player.controls()) {

          // Don't catch clicks if any control buttons are focused
          var activeEl = event.relatedTarget || event.toElement || document.activeElement;
          if (activeEl == pEl ||
              activeEl == pEl.querySelector('.vjs-tech') ||
              activeEl == pEl.querySelector('.iframeblocker')) {

            if (enableFull) {
              if (player.isFullscreen()) {
                player.exitFullscreen();
              } else {
                player.requestFullscreen();
              }
            }
          }
        }
      };

      var checkKeys = function checkKeys(e, player) {
        // Allow some modularity in defining custom hotkeys

        // Play/Pause check
        if (options.playPauseKey(e, player)) {
          return cPlay;
        }

        // Seek Backward check
        if (options.rewindKey(e, player)) {
          return cRewind;
        }

        // Seek Forward check
        if (options.forwardKey(e, player)) {
          return cForward;
        }

        // Volume Up check
        if (options.volumeUpKey(e, player)) {
          return cVolumeUp;
        }

        // Volume Down check
        if (options.volumeDownKey(e, player)) {
          return cVolumeDown;
        }

        // Mute check
        if (options.muteKey(e, player)) {
          return cMute;
        }

        // Fullscreen check
        if (options.fullscreenKey(e, player)) {
          return cFullscreen;
        }
      };

      function playPauseKey(e) {
        // Space bar
        return (e.which === 32);
      }

      function rewindKey(e) {
        // Left Arrow
        return (e.which === 37);
      }

      function forwardKey(e) {
        // Right Arrow
        return (e.which === 39);
      }

      function volumeUpKey(e) {
        // Up Arrow
        return (e.which === 38);
      }

      function volumeDownKey(e) {
        // Down Arrow
        return (e.which === 40);
      }

      function muteKey(e) {
        // M key
        return (e.which === 77);
      }

      function fullscreenKey(e) {
        // F key
        return (e.which === 70);
      }

      player.on('keydown', keyDown);
      player.on('dblclick', doubleClick);

      return this;
    };

    videojs.plugin('hotkeys', hotkeys);
});
<commit_msg>Updating UMD support<commit_after>/*
 * Video.js Hotkeys
 * https://github.com/ctd1500/videojs-hotkeys
 *
 * Copyright (c) 2015 Chris Dougherty
 * Licensed under the Apache-2.0 license.
 */

'use strict';
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([], factory.bind(this, root, root.videojs));
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = factory(root, root.videojs);
  } else {
    factory(root, root.videojs);
  }

})(this, function(window, videojs) {
    window['videojs_hotkeys'] = { version: "0.2.8" };

    var hotkeys = function(options) {
      var player = this;
      var pEl = player.el();
      var def_options = {
        volumeStep: 0.1,
        seekStep: 5,
        enableMute: true,
        enableFullscreen: true,
        enableNumbers: true,
        enableJogStyle: false,
        alwaysCaptureHotkeys: false,
        playPauseKey: playPauseKey,
        rewindKey: rewindKey,
        forwardKey: forwardKey,
        volumeUpKey: volumeUpKey,
        volumeDownKey: volumeDownKey,
        muteKey: muteKey,
        fullscreenKey: fullscreenKey,
        customKeys: {}
      };

      const cPlay = 1,
        cRewind = 2,
        cForward = 3,
        cVolumeUp = 4,
        cVolumeDown = 5,
        cMute = 6,
        cFullscreen = 7;

      // Use built-in merge function from Video.js v5.0+ or v4.4.0+
      var mergeOptions = videojs.mergeOptions || videojs.util.mergeOptions;
      options = mergeOptions(def_options, options || {});

      var volumeStep = options.volumeStep,
        seekStep = options.seekStep,
        enableMute = options.enableMute,
        enableFull = options.enableFullscreen,
        enableNumbers = options.enableNumbers,
        enableJogStyle = options.enableJogStyle,
        alwaysCaptureHotkeys = options.alwaysCaptureHotkeys;

      // Set default player tabindex to handle keydown and doubleclick events
      if (!pEl.hasAttribute('tabIndex')) {
        pEl.setAttribute('tabIndex', '-1');
      }

      if (alwaysCaptureHotkeys) {
        player.one('play', function() {
          pEl.focus(); // Fixes the .vjs-big-play-button handing focus back to body instead of the player
        });
      }

      player.on('play', function() {
        // Fix allowing the YouTube plugin to have hotkey support.
        var ifblocker = pEl.querySelector('.iframeblocker');
        if (ifblocker && ifblocker.style.display === '') {
          ifblocker.style.display = "block";
          ifblocker.style.bottom = "39px";
        }
      });

      var keyDown = function keyDown(event) {

        var ewhich = event.which, curTime;
        var ePreventDefault = event.preventDefault;
        // When controls are disabled, hotkeys will be disabled as well
        if (player.controls()) {

          // Don't catch keys if any control buttons are focused, unless alwaysCaptureHotkeys is true
          var activeEl = document.activeElement;
          if (alwaysCaptureHotkeys ||
              activeEl == pEl ||
              activeEl == pEl.querySelector('.vjs-tech') ||
              activeEl == pEl.querySelector('.vjs-control-bar') ||
              activeEl == pEl.querySelector('.iframeblocker')) {

            switch (checkKeys(event, player)) {

              // Spacebar toggles play/pause
              case cPlay:
                ePreventDefault();
                if (alwaysCaptureHotkeys) {
                  // Prevent control activation with space
                  event.stopPropagation();
                }

                if (player.paused()) {
                  player.play();
                } else {
                  player.pause();
                }
                break;

              // Seeking with the left/right arrow keys
              case cRewind: // Seek Backward
                ePreventDefault();
                curTime = player.currentTime() - seekStep;
                // The flash player tech will allow you to seek into negative
                // numbers and break the seekbar, so try to prevent that.
                if (player.currentTime() <= seekStep) {
                  curTime = 0;
                }
                player.currentTime(curTime);
                break;
              case cForward: // Seek Forward
                ePreventDefault();
                player.currentTime(player.currentTime() + seekStep);
                break;

              // Volume control with the up/down arrow keys
              case cVolumeDown:
                ePreventDefault();
                if (!enableJogStyle) {
                  player.volume(player.volume() - volumeStep);
                } else {
                  curTime = player.currentTime() - 1;
                  if (player.currentTime() <= 1) {
                    curTime = 0;
                  }
                  player.currentTime(curTime);
                }
                break;
              case cVolumeUp:
                ePreventDefault();
                if (!enableJogStyle) {
                  player.volume(player.volume() + volumeStep);
                } else {
                  player.currentTime(player.currentTime() + 1);
                }
                break;

              // Toggle Mute with the M key
              case cMute:
                if (enableMute) {
                  player.muted(!player.muted());
                }
                break;

              // Toggle Fullscreen with the F key
              case  cFullscreen:
                if (enableFull) {
                  if (player.isFullscreen()) {
                    player.exitFullscreen();
                  } else {
                    player.requestFullscreen();
                  }
                }
                break;

              default:
                // Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%
                if ((ewhich > 47 && ewhich < 59) || (ewhich > 95 && ewhich < 106)) {
                  if (enableNumbers) {
                    var sub = 48;
                    if (ewhich > 95) {
                      sub = 96;
                    }
                    var number = ewhich - sub;
                    ePreventDefault();
                    player.currentTime(player.duration() * number * 0.1);
                  }
                }

                // Handle any custom hotkeys
                for (var customKey in options.customKeys) {
                  var customHotkey = options.customKeys[customKey];
                  // Check for well formed custom keys
                  if (customHotkey && customHotkey.key && customHotkey.handler) {
                    // Check if the custom key's condition matches
                    if (customHotkey.key(event)) {
                      ePreventDefault();
                      customHotkey.handler(player, options);
                    }
                  }
                }
            }
          }
        }
      };

      var doubleClick = function doubleClick(event) {

        // When controls are disabled, hotkeys will be disabled as well
        if (player.controls()) {

          // Don't catch clicks if any control buttons are focused
          var activeEl = event.relatedTarget || event.toElement || document.activeElement;
          if (activeEl == pEl ||
              activeEl == pEl.querySelector('.vjs-tech') ||
              activeEl == pEl.querySelector('.iframeblocker')) {

            if (enableFull) {
              if (player.isFullscreen()) {
                player.exitFullscreen();
              } else {
                player.requestFullscreen();
              }
            }
          }
        }
      };

      var checkKeys = function checkKeys(e, player) {
        // Allow some modularity in defining custom hotkeys

        // Play/Pause check
        if (options.playPauseKey(e, player)) {
          return cPlay;
        }

        // Seek Backward check
        if (options.rewindKey(e, player)) {
          return cRewind;
        }

        // Seek Forward check
        if (options.forwardKey(e, player)) {
          return cForward;
        }

        // Volume Up check
        if (options.volumeUpKey(e, player)) {
          return cVolumeUp;
        }

        // Volume Down check
        if (options.volumeDownKey(e, player)) {
          return cVolumeDown;
        }

        // Mute check
        if (options.muteKey(e, player)) {
          return cMute;
        }

        // Fullscreen check
        if (options.fullscreenKey(e, player)) {
          return cFullscreen;
        }
      };

      function playPauseKey(e) {
        // Space bar
        return (e.which === 32);
      }

      function rewindKey(e) {
        // Left Arrow
        return (e.which === 37);
      }

      function forwardKey(e) {
        // Right Arrow
        return (e.which === 39);
      }

      function volumeUpKey(e) {
        // Up Arrow
        return (e.which === 38);
      }

      function volumeDownKey(e) {
        // Down Arrow
        return (e.which === 40);
      }

      function muteKey(e) {
        // M key
        return (e.which === 77);
      }

      function fullscreenKey(e) {
        // F key
        return (e.which === 70);
      }

      player.on('keydown', keyDown);
      player.on('dblclick', doubleClick);

      return this;
    };

    videojs.plugin('hotkeys', hotkeys);
});
<|endoftext|>