import styled from "styled-components";
import { AppColors } from "../../util/constants";

export const Header = styled.span`
  color: ${AppColors.Highlight};
  font-weight: 600;
  font-size: 0.9em;
  margin: 0 0.65em 0 0;
`;

import styled from "styled-components";
import { AppColors } from "../../util/constants";
import { TextButton } from "../ui/text-button";

export const Header = styled(TextButton)`
  color: ${AppColors.Highlight};
  padding: 0.25em 0.75em 0.25em 0;
  cursor: default;
`;

Fix sizing issue with title


import _ from 'lodash';
import { FETCH_POSTS, FETCH_POST } from '../actions';

export default function(state = {}, action) {
  switch (action.type) {
    case FETCH_POST:
      return { ...state, [action.payload.data.id]: action.payload.data }
    case FETCH_POSTS:
      return _.mapKeys(action.payload.data, 'id');
    default:
      return state;
  }
}

import _ from 'lodash';
import { FETCH_POSTS, FETCH_POST, DELETE_POST } from '../actions';

export default function(state = {}, action) {
  switch (action.type) {
    case DELETE_POST:
      return _.omit(state, action.payload);
    case FETCH_POST:
      return { ...state, [action.payload.data.id]: action.payload.data }
    case FETCH_POSTS:
      return _.mapKeys(action.payload.data, 'id');
    default:
      return state;
  }
}

Update Redux state upon post deletion


import geolocationService from './geolocationService';
import hospitalService from './hospitalService';
import feedService from './feedService';
import staticsService from './staticsService';

export {
  geolocationService,
  hospitalService,
  feedService,
  staticsService,
};

import geolocationService from './geolocationService';
import hospitalService from './hospitalService';
import feedService from './feedService';

export {
  geolocationService,
  hospitalService,
  feedService,
};

Fix server URL to point to the outside


import React, { useState } from 'react'
import Dictaphone from './Dictaphone'

const DictaphoneWidgetB = () => {
  const [message, setMessage] = useState('')
  const commands = [
    {
      command: '* is my name',
      callback: (name) => setMessage(`Hi ${name}!`),
      matchInterim: true
    },
    {
      command: 'My top sports are * and *',
      callback: (sport1, sport2) => setMessage(`#1: ${sport1}, #2: ${sport2}`)
    },
    {
      command: 'Goodbye',
      callback: () => setMessage('So long!'),
      matchInterim: true
    }
  ]

  return (

Dictaphone B

{message}

      <Dictaphone commands={commands} />

  )
}

export default DictaphoneWidgetB

import React, { useState } from 'react'
import Dictaphone from './Dictaphone'

const DictaphoneWidgetB = () => {
  const [message, setMessage] = useState('')
  const commands = [
    {
      command: '* is my name',
      callback: (name) => setMessage(`Hi ${name}!`),
      matchInterim: true
    },
    {
      command: 'My top sports are * and *',
      callback: (sport1, sport2) => setMessage(`#1: ${sport1}, #2: ${sport2}`)
    },
    {
      command: 'Goodbye',
      callback: () => setMessage('So long!'),
      matchInterim: true
    },
    {
      command: 'Pass the salt (please)',
      callback: () => setMessage('My pleasure')
    }
  ]

  return (

Dictaphone B

{message}

      <Dictaphone commands={commands} />

  )
}

export default DictaphoneWidgetB

Add extra command to example


'use strict';

let path = require('path');
let fs = require('fs');
let pkg = require('../package.json');

let output = './build/src/';
pkg.main = path.relative(output, pkg.main);
pkg.typings = path.relative(output, pkg.typings);
fs.writeFileSync(output + 'package.json', JSON.stringify(pkg));

'use strict';

let path = require('path');
let fs = require('fs');
let child_process = require('child_process');
let pkg = require('../package.json');

let output = './build/src/';
pkg.main = path.relative(output, pkg.main);
pkg.typings = path.relative(output, pkg.typings);
try {
    updateVersion2gitTag(pkg);
} catch (e) { }
fs.writeFileSync(output + 'package.json', JSON.stringify(pkg));

// Will throw if not on a tag
function updateVersion2gitTag(pkg) {
    let tag = child_process.execSync('git describe --tag').toString().trim();
    pkg.version = tag;
}

Update package version to git tag before deploy


HighFidelity.PodcastNewController = Ember.ObjectController.extend({
    isAdding: false,

    rssURL: '',

    actions: {
        create: function(url) {
            if (url) {
                if (!url.match(/^http[s]?:\/\//i)) {
                  url = 'http://' + url;
                }

                this.set('rssURL', url);
            }

            if (!this.get('rssURL') || !this.get('rssURL').length) {
                return;
            }

            this.set('isAdding', true);

            HighFidelity.Podcast.createFromController(this, this.get('rssURL'));
        }
    }
});

HighFidelity.PodcastNewController = Ember.ObjectController.extend({
    isAdding: false,

    rssURL: '',

    actions: {
        create: function(url) {
            if (url) {
                this.set('rssURL', url);
            }

            if (!this.get('rssURL') || !this.get('rssURL').length) {
                return;
            }

            // If the URL entered doesn't have a protocol attached, make
            // sure one is added so we don't get an error (#43).
            if (!this.get('rssURL').match(/^http[s]?:\/\//i)) {
                this.set('rssURL', 'http://' + this.get('rssURL'));
            }

            this.set('isAdding', true);

            HighFidelity.Podcast.createFromController(this, this.get('rssURL'));
        }
    }
});

Check the controller variable rather than argument


import React, {PropTypes, Component} from 'react'
import Dropdown from 'shared/components/Dropdown'

import {showDatabases} from 'shared/apis/metaQuery'
import showDatabasesParser from 'shared/parsing/showDatabases'

class DatabaseDropdown extends Component {
  constructor(props) {
    super(props)
    this.state = {
      databases: [],
    }
  }

  componentDidMount() {
    const {source} = this.context
    const {database, onSelectDatabase} = this.props
    const proxy = source.links.proxy
    showDatabases(proxy).then(resp => {
      const {databases} = showDatabasesParser(resp.data)
      this.setState({databases})
      const selected = databases.includes(database) ? database : databases[0] || 'No databases'
      onSelectDatabase({text: selected})
    })
  }

  render() {
    const {databases} = this.state
    const {database, onSelectDatabase} = this.props

    return (
      <Dropdown
        items={databases.map(text => ({text}))}
        selected={database}
        onChoose={onSelectDatabase}
      />
    )
  }
}

const {func, shape, string} = PropTypes

DatabaseDropdown.contextTypes = {
  source: shape({
    links: shape({
      proxy: string.isRequired,
    }).isRequired,
  }).isRequired,
}

DatabaseDropdown.propTypes = {
  database: string,
  onSelectDatabase: func.isRequired,
}

export default DatabaseDropdown

Fix irregular whitespace linter error.


$(function(){
  $(".toc-level-0 .toc-level-0 > a").click(function() {
    $(this).parent().find('> ol').slideToggle();

    return false;
  });

  $(function(){
    $('.anchorable-toc').each(function(){
      var toc = $(this),
      id = toc.attr('id'),
      href = "#" + id,
      anchor = '';

      toc.prepend(anchor);
    });
  });
});

$(function(){
  $(".toc-level-0 .toc-level-0 > a").click(function() {
    $(this).parent().find('> ol').slideToggle(200);

    return false;
  });

  $(function(){
    $('.anchorable-toc').each(function(){
      var toc = $(this),
      id = toc.attr('id'),
      href = "#" + id,
      anchor = '';

      toc.prepend(anchor);
    });
  });
});

Make the TOC slide snappier


(function(Modules) {
  "use strict";

  var queues = {};
  var dd = new diffDOM();

  var getRenderer = $component => response => dd.apply(
    $component.get(0),
    dd.diff($component.get(0), $(response[$component.data('key')]).get(0))
  );

  var getQueue = resource => (
    queues[resource] = queues[resource] || []
  );

  var flushQueue = function(queue, response) {
    while(queue.length) queue.shift()(response);
  };

  var clearQueue = queue => (queue.length = 0);

  var poll = function(renderer, resource, queue, interval, form) {

    if (document.visibilityState !== "hidden" && queue.push(renderer) === 1) $.ajax(
      resource,
      {
        'method': form ? 'post' : 'get',
        'data': form ? $('#' + form).serialize() : {}
      }
    ).done(
      response => {
        flushQueue(queue, response);
        if (response.stop === 1) {
          poll = function(){};
        }
      }
    ).fail(
      () => poll = function(){}
    );

    setTimeout(
      () => poll.apply(window, arguments), interval
    );
  };

  Modules.UpdateContent = function() {

    this.start = component => poll(
      getRenderer($(component)),
      $(component).data('resource'),
      getQueue($(component).data('resource')),
      ($(component).data('interval-seconds') || 1.5) * 1000,
      $(component).data('form')
    );

  };

})(window.GOVUK.Modules);

(function(global) {
  "use strict";

  var queues = {};
  var dd = new global.diffDOM();

  var getRenderer = $component => response => dd.apply(
    $component.get(0),
    dd.diff($component.get(0), $(response[$component.data('key')]).get(0))
  );

  var getQueue = resource => (
    queues[resource] = queues[resource] || []
  );

  var flushQueue = function(queue, response) {
    while(queue.length) queue.shift()(response);
  };

  var clearQueue = queue => (queue.length = 0);

  var poll = function(renderer, resource, queue, interval, form) {

    if (document.visibilityState !== "hidden" && queue.push(renderer) === 1) $.ajax(
      resource,
      {
        'method': form ? 'post' : 'get',
        'data': form ? $('#' + form).serialize() : {}
      }
    ).done(
      response => {
        flushQueue(queue, response);
        if (response.stop === 1) {
          poll = function(){};
        }
      }
    ).fail(
      () => poll = function(){}
    );

    setTimeout(
      () => poll.apply(window, arguments), interval
    );
  };

  global.GOVUK.Modules.UpdateContent = function() {

    this.start = component => poll(
      getRenderer($(component)),
      $(component).data('resource'),
      getQueue($(component).data('resource')),
      ($(component).data('interval-seconds') || 1.5) * 1000,
      $(component).data('form')
    );

  };

})(window);

Make global explicit in module scope


import Mixin from '@ember/object/mixin';
import { uuid } from 'ember-cli-uuid';

export function generateIdForRecord() {
  return uuid();
}

export default Mixin.create({ generateIdForRecord });

import Ember from 'ember';
import { uuid } from 'ember-cli-uuid';

export function generateIdForRecord() {
  return uuid();
}

export default Ember.Mixin.create({ generateIdForRecord });

Revert new modules api usage in addon core code to maximize backwards compatibility


/* eslint-disable no-console */

const debug = (...args) => console.log('[Service Worker]', ...args);

const isCacheableRequest = request =>
    request.method === 'GET' &&
    !new URL(request.url).search.match(/[?&]nocache[&$]/);

self.addEventListener('install', () => debug('Installed'));

self.addEventListener('activate', () => debug('Activated'));

let nextFetchId = 1;

self.addEventListener('fetch', event => {
    const fetchId = nextFetchId++;
    const fetchDebug = (...args) => debug('[Fetch #' + fetchId + ']', ...args);

    fetchDebug(event.request);

    if (!isCacheableRequest(event.request)) {
        fetchDebug('Ignored (marked as not cacheable)');
        return;
    }

    event.respondWith(
        fetch(event.request).then(
            response => {
                fetchDebug(response);
                const responseClone = response.clone();
                caches.open('v1').then(cache =>
                    cache.put(event.request, responseClone).
                        then(() => fetchDebug('Cached'))
                );
                return response;
            },
            error => {
                debug(error);
                return caches.match(event.request).then(cachedResponse => {
                    debug('Cached response', cachedResponse);
                    return cachedResponse || error;
                });
            }
        )
    );
});

/* eslint-disable no-console */

const debug = (...args) => console.log('[Service Worker]', ...args);

const isCacheableRequest = request =>
    request.method === 'GET' &&
    !new URL(request.url).search.match(/[?&]nocache[&$]/);

self.addEventListener('install', () => debug('Installed'));

self.addEventListener('activate', () => debug('Activated'));

let nextFetchId = 1;

self.addEventListener('fetch', event => {
    const fetchId = nextFetchId++;
    const fetchDebug = (...args) => debug('[Fetch #' + fetchId + ']', ...args);

    fetchDebug(event.request);

    if (!isCacheableRequest(event.request)) {
        fetchDebug('Ignored (marked as not cacheable)');
        return;
    }

    event.respondWith(
        fetch(event.request).then(
            response => {
                fetchDebug(response);
                const responseClone = response.clone();
                caches.open('v1').then(cache =>
                    cache.put(event.request, responseClone).
                        then(() => fetchDebug('Cached'))
                );
                return response;
            },
            error => {
                fetchDebug(error);
                return caches.match(event.request).then(cachedResponse => {
                    fetchDebug('Cached response', cachedResponse);
                    return cachedResponse || error;
                });
            }
        )
    );
});

Fix not using right debugging method


/* eslint-disable max-len */
exports.extensions = {
  supported: [
    { icon: 'bower', extensions: ['bower_components'] },
    { icon: 'dist', extensions: ['dist', 'out', 'export'] },
    { icon: 'git', extensions: ['git', 'github'] },
    { icon: 'haxelib', extensions: ['haxelib'] },
    { icon: 'node', extensions: ['node_modules'] },
    { icon: 'meteor', extensions: ['meteor'] },
    { icon: 'src', extensions: ['src', 'source'] },
    { icon: 'test', extensions: ['tests', 'test', '__tests__', '__test__'] },
    { icon: 'typings', extensions: ['typings'] },
    { icon: 'vscode', extensions: ['vscode'] }
  ],
  parse: function () {
    var s = this.replace(/\./g, '_');
    if ((/^\d/).test(s)) return 'n' + s;
    return s;
  }
};

/* eslint-disable max-len */
exports.extensions = {
  supported: [
    { icon: 'bower', extensions: ['bower_components'] },
    { icon: 'dist', extensions: ['dist', 'out', 'export'] },
    { icon: 'git', extensions: ['git', 'github'] },
    { icon: 'haxelib', extensions: ['haxelib'] },
    { icon: 'node', extensions: ['node_modules'] },
    { icon: 'meteor', extensions: ['meteor'] },
    { icon: 'src', extensions: ['src', 'source', 'sources'] },
    { icon: 'test', extensions: ['tests', 'test', '__tests__', '__test__'] },
    { icon: 'typings', extensions: ['typings'] },
    { icon: 'vscode', extensions: ['vscode'] }
  ],
  parse: function () {
    var s = this.replace(/\./g, '_');
    if ((/^\d/).test(s)) return 'n' + s;
    return s;
  }
};

Support 'sources' in plural as 'src' folder


var classLayout = {
	'Paper.js': ['global paper scope:_global_'],
	'Basic Types': ['Point', 'Size', 'Rectangle', 'Matrix'],
	'Items': ['Item', 'Layer', 'Group', 'Raster', 'PlacedSymbol'],
	'Paths': ['Path', 'CompoundPath', 'Segment', 'Curve', 'PathStyle', 'ruler',
		'CurveLocation'],
	'Tools': ['Tool', 'ToolEvent', 'Key', 'KeyEvent'],
	'Projects': ['Project', 'View', 'Symbol'],
	'Colors': ['Color', 'RGBColor', 'GrayColor', 'HSBColor'],
	'Gradients': ['GradientColor', 'Gradient', 'GradientStop'],
	'Typography': ['TextItem', 'PointText', {
		'Style': ['CharacterStyle', 'ParagraphStyle']
	}]
};

var classLayout = {
	'Paper.js': ['Global Scope:_global_'],
	'Basic Types': ['Point', 'Size', 'Rectangle', 'Matrix'],
	'Items': ['Item', 'Layer', 'Group', 'Raster', 'PlacedSymbol'],
	'Paths': ['Path', 'CompoundPath', 'Segment', 'Curve', 'PathStyle', 'ruler',
		'CurveLocation'],
	'Tools': ['Tool', 'ToolEvent', 'Key', 'KeyEvent'],
	'Projects': ['Project', 'View', 'Symbol'],
	'Colors': ['Color', 'RGBColor', 'GrayColor', 'HSBColor'],
	'Gradients': ['GradientColor', 'Gradient', 'GradientStop'],
	'Typography': ['TextItem', 'PointText', {
		'Style': ['CharacterStyle', 'ParagraphStyle']
	}]
};

Rename _global_ to Global Scope.


$('#propose_submit').click(function(event){
    event.preventDefault();
    $('#tos-dialog').dialog({width: '500px'});
    $('#agree').click(function(){
        $('#propose-topic').submit();
    });
    $('#cancel').click(function(){
        $('#tos-dialog').dialog('close');
    });
});

$('#propose_submit').click(function(event){
    event.preventDefault();
    $('#tos-dialog').dialog({width: '50%', modal: true, height: 600});
    $('#agree').click(function(){
        $('#propose-topic').submit();
    });
    $('#cancel').click(function(){
        $('#tos-dialog').dialog('close');
    });
});

Improve ToS Agreement on Topic submission


import swfobject from 'swfobject';

const TIMEOUT = 1000;
const ID = '__flash_detector';
const CALLBACK = `${ID}_call`;

function clear(el) {
  document.body.removeChild(el);
  delete window[CALLBACK];
}

/**
 * Detects if Adobe Flash is actually alive in a browser
 * @param {string} swfPath - The path to FlashDetector.swf
 * @param {number} [timeout=TIMEOUT(1000)] The milliseconds of your detection timeout
 * @returns {Promise} Returns a Promise object which is resolved only when Flash plugin is alive
 */
export function detectFlash(swfPath, timeout = TIMEOUT) {
  return new Promise((resolve, reject) => {
    if (!navigator.plugins['Shockwave Flash']) {
      reject();
      return;
    }
    const el = document.createElement('DIV');
    const wrapper = el.cloneNode();

    el.id = ID;
    wrapper.appendChild(el);
    document.body.appendChild(wrapper);

    const timeoutId = setTimeout(() => {
      clear(wrapper, el.id);
      reject();
    }, timeout);

    window[CALLBACK] = function callbackFromFlashDetector() {
      clearTimeout(timeoutId);
      setTimeout(() => clear(wrapper), 0);
      resolve();
    };

    swfobject.embedSWF(swfPath, el.id, '0', '0', '10.0.0');
  });
}

export default detectFlash;

import swfobject from 'swfobject';

const TIMEOUT = 1000;
const ID = '__flash_detector';
const CALLBACK = `${ID}_call`;

function clear(el) {
  document.body.removeChild(el);
  delete window[CALLBACK];
}

/**
 * Detects if Adobe Flash is actually alive in a browser
 * @param {string} swfPath - The path to FlashDetector.swf
 * @param {number} [timeout=TIMEOUT(1000)] The milliseconds of your detection timeout
 * @returns {Promise} Returns a Promise object which is resolved only when Flash plugin is alive
 */
export function detectFlash(swfPath, timeout = TIMEOUT) {
  return new Promise((resolve, reject) => {
    if (!navigator.plugins['Shockwave Flash']) {
      reject();
      return;
    }
    const el = document.createElement('DIV');
    const wrapper = el.cloneNode();

    el.id = ID;
    wrapper.appendChild(el);
    document.body.appendChild(wrapper);

    const timeoutId = setTimeout(() => {
      clear(wrapper, el.id);
      reject();
    }, timeout);

    window[CALLBACK] = function callbackFromFlashDetector() {
      clearTimeout(timeoutId);
      setTimeout(() => clear(wrapper), 0);
      resolve();
    };

    swfobject.embedSWF(swfPath, el.id, '10', '10', '10.0.0');
  });
}

export default detectFlash;

Fix not execution flash object


/**
 * Tabbar Icon
 *
    <TabIcon icon={'search'} selected={false} />
 *
 * React Native Starter App
 * https://github.com/mcnamee/react-native-starter-app
 */
import React from 'react';
import PropTypes from 'prop-types';
import { Icon } from 'react-native-elements';

import { AppColors } from '@theme/';

/* Component ==================================================================== */
const TabIcon = ({ icon, selected }) => (
  <Icon
    name={icon}
    size={26}
    color={selected ? AppColors.tabbar.iconSelected : AppColors.tabbar.iconDefault}
  />
);

TabIcon.propTypes = { icon: PropTypes.string.isRequired, selected: PropTypes.bool };
TabIcon.defaultProps = { icon: 'search', selected: false };

/* Export Component ==================================================================== */
export default TabIcon;

/**
 * Tabbar Icon
 *
    <TabIcon icon={'search'} selected={false} />
 *
 * React Native Starter App
 * https://github.com/mcnamee/react-native-starter-app
 */
import React from 'react';
import PropTypes from 'prop-types';
import { Icon } from 'react-native-elements';

import { AppColors } from '@theme/';

/* Component ==================================================================== */
const TabIcon = ({ icon, selected, type }) => (
  <Icon
    type={type}
    name={icon}
    size={26}
    color={selected ? AppColors.tabbar.iconSelected : AppColors.tabbar.iconDefault}
  />
);

TabIcon.propTypes = { icon: PropTypes.string.isRequired, selected: PropTypes.bool, type: PropTypes.string };
TabIcon.defaultProps = { icon: 'search', selected: false, type: null };

/* Export Component ==================================================================== */
export default TabIcon;

Add props 'type' for tabicon


/**
 * @class Denkmal_Component_EventAdd
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_EventAdd = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_EventAdd',

  events: {
    'click .addSimilar': 'addSimilar'
  },

  childrenEvents: {
    'Denkmal_Form_EventAdd success.Create': function() {
      this.$('.Denkmal_Form_EventAdd .preview').hide();
      this.$('.Denkmal_Form_EventAdd .formWrapper').slideUp();
      this.$('.formSuccess').slideDown();
    }
  },

  addSimilar: function() {
    this.$('.Denkmal_Form_EventAdd .preview').show();
    this.$('.Denkmal_Form_EventAdd .formWrapper').slideDown();
    this.$('.formSuccess').slideUp();
  }
});

/**
 * @class Denkmal_Component_EventAdd
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_EventAdd = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_EventAdd',

  events: {
    'click .addSimilar': 'addSimilar'
  },

  childrenEvents: {
    'Denkmal_Form_EventAdd success.Create': function() {
      this.$('.Denkmal_Form_EventAdd .preview').hide();
      this.$('.Denkmal_Form_EventAdd .formWrapper').slideUp();
      this.$('.formSuccess').slideDown();
    }
  },

  addSimilar: function() {
    this.findChild('Denkmal_Form_EventAdd').getField('urls').setValue('');

    this.$('.Denkmal_Form_EventAdd .preview').show();
    this.$('.Denkmal_Form_EventAdd .formWrapper').slideDown();
    this.$('.formSuccess').slideUp();
  }
});

Clear "urls" field when submitting similar event


if (typeof define === 'undefined' && typeof importScripts !== 'undefined')
  importScripts('lib/require.js');

var string_split = /(\w+)(\s\w+){0,1}$/

require(
    ['worker_console', 'x_protocol', 'endianbuffer']
  , function (console, x_protocol, EndianBuffer) {
      var buffer = null
        , clients = {}
        , server = null;

      var socket = null;
      addEventListener('message', function (event) {
        switch (event.data.cmd) {
          case 'connect':
            if (server)
              return postMessage({ cmd: 'error', message: 'Server exists!' });
            var socket = new WebSocket('ws://' + event.data.address, 'x11-proxy');
            socket.binaryType = 'arraybuffer';
            server = new x_protocol.XProtocolServer(socket, function () {
              server = null;
            });
          break;
          case 'disconnect':
            if (! server)
              return postMessage({ cmd: 'error', message: 'not connected' })
            socket.close();
          break;
          case 'message':
            if (! server)
              return postMessage({ cmd: 'error', message: 'not connected' })
            if (! server.clients[event.data.id])
              throw new Error('Invalid client! Disconnected?');
            server.serverMessage(event.data);
          break;
        }
      });
    }
)

if (typeof define === 'undefined' && typeof importScripts !== 'undefined')
  importScripts('lib/require.js');

var string_split = /(\w+)(\s\w+){0,1}$/

window = self;

require(
    ['worker_console', 'x_protocol', 'endianbuffer']
  , function (console, x_protocol, EndianBuffer) {
      self.console = console;
      var buffer = null
        , clients = {}
        , server = null;

      var socket = null;
      self.addEventListener('message', function (event) {
        switch (event.data.cmd) {
          case 'connect':
            if (server)
              return postMessage({ cmd: 'error', message: 'Server exists!' });
            var socket = new WebSocket('ws://' + event.data.address, 'x11-proxy');
            socket.binaryType = 'arraybuffer';
            server = new x_protocol.XProtocolServer(socket, function () {
              postMessage({ cmd: 'close' })
              server = null;
            });
          break;
          case 'disconnect':
            if (! server)
              return postMessage({ cmd: 'error', message: 'not connected' })
            socket.close();
          break;
          case 'message':
            if (! server)
              return postMessage({ cmd: 'error', message: 'not connected' })
            if (! server.clients[event.data.id])
              throw new Error('Invalid client! Disconnected?');
            server.serverMessage(event.data);
          break;
        }
      });
    }
)

Fix for chrome developer tools console


(function() {
    "use strict";

    angular
        .module('VinculacionApp')
        .controller('ProjectsController', ProjectsController);

    ProjectsController.$inject = ['projects', 'toaster'];

    function ProjectsController (projects, toaster) {
        var vm = this;

        vm.projects = [];
        vm.removeProjectClicked = removeProjectClicked;

        function removeProjectClicked (project, index) {
            if (confirm("Esta seguro de borrar el proyecto: " +
                project.Name + "?"))
            removeProject(project, index);
        }

        function removeProject (project, index) {
            vm.projects.splice(index, 1);

            projects.deleteProject(project.Id,
                removeProjectSucces, removeProjectFail);
        }

        function removeProjectSucces () {
            console.log("Success");
        }

        function removeProjectFail () {
            toaster.pop(
                {
                    type: 'error',
                    title: 'Error',
                    body: 'No se pudo borrar el proyecto.'
                }
            );
        }

        projects.getProjects(
            function(response) {
                console.log(response);
                for(var obj in response.data) {
                    vm.projects.push(response.data[obj])
                }
            },
            function(response) {
                toaster.pop(
                    {
                        type: 'error',
                        title: 'Error',
                        body: 'No se ha podido obtener los proyectos deseados.'
                    }
                );
            }
        );
    }

})();

(function() {
    "use strict";

    angular
        .module('VinculacionApp')
        .controller('ProjectsController', ProjectsController);

    ProjectsController.$inject = ['projects', 'toaster'];

    function ProjectsController (projects, toaster) {
        var vm = this;
        var deleteIndex = -1;

        vm.projects = [];
        vm.removeProjectClicked = removeProjectClicked;

        function removeProjectClicked (project, index) {
            if (confirm("Esta seguro de borrar el proyecto: " +
                project.Name + "?"))
            removeProject(project, index);
        }

        function removeProject (project, index) {
            deleteIndex = index;

            projects.deleteProject(project.Id,
                removeProjectSucces, removeProjectFail);
        }

        function removeProjectSucces () {
            vm.projects.splice(deleteIndex, 1);
        }

        function removeProjectFail () {
            toaster.pop(
                {
                    type: 'error',
                    title: 'Error',
                    body: 'No se pudo borrar el proyecto.'
                }
            );
        }

        projects.getProjects(
            function(response) {
                console.log(response);
                for(var obj in response.data) {
                    vm.projects.push(response.data[obj])
                }
            },
            function(response) {
                toaster.pop(
                    {
                        type: 'error',
                        title: 'Error',
                        body: 'No se ha podido obtener los proyectos deseados.'
                    }
                );
            }
        );
    }

})();

Delete project only on success


require('./analytics');

require('core-js/es5');
require('core-js/es6');

const $ = require('jquery');
const stageConfigs = require('./stages.json');
const Game = require('./game');

$(document).ready(() => {
	new Game(stageConfigs);

	$('.modal').each((index, element) => {
		const $modal = $(element);
		$modal.find('.close').click(() => {
			$modal.remove();
		});
	});
});

require('./analytics');

require('core-js/es5');
require('core-js/es6');

const querystring = require('querystring');
const $ = require('jquery');
const stageConfigs = require('./stages.json');
const Game = require('./game');

// parse GET parameters of the location
const params = querystring.parse(location.href.slice(1));

if (params.fx === 'off') {
	$.fx.off = true;
}

$(document).ready(() => {
	new Game(stageConfigs);

	$('.modal').each((index, element) => {
		const $modal = $(element);
		$modal.find('.close').click(() => {
			$modal.remove();
		});
	});
});

Add fx=off option to disable animations


var
    _ = require('lodash')
    ;

var
    flatten = require('./flatten')
    ;

//Some structural examples

var objInput = {
    number: 44,
    bool: true,
    string: "foobar",
    object: {child:true},
    array: ['chi', 'ld'],
    buffer: new Buffer("buffer")
};

console.log(flatten.flatten(objInput));

var arrInput = [44,true,"foobar",{child:true},['chi', 'ld'],new Buffer("buffer")];

console.log(flatten.flatten(arrInput));

var deep = {
    a: {
        b: {
            c:true
        }
    }
};

console.log(flatten.flatten(deep));

var circular = {
    child: {
    }
};
circular.child.parent = circular;

console.log(flatten.flatten(circular));

var multiref = {
    buff: new Buffer("very loong")
};
multiref.a = multiref.buff;
multiref.b = {b: multiref.buff};

console.log(flatten.flatten(multiref));

Add example for multiple references


'use strict';

var mysql = require('mysql');
var fmt = require('util').format;

function execute(query, opts, done) {
  try {
    var conn = mysql.createConnection(opts);
    conn.connect();
    conn.query(query, function (err) {
      done(err);
    });
    conn.end();
  } catch (err) {
    done(err);
  }
}

module.exports = function (opts) {
  return {
    create: function (name, done) {
      execute(fmt('CREATE DATABASE %s;', name), opts, done);
    },
    drop: function (name, done) {
      execute(fmt('DROP DATABASE IF EXISTS %s;', name), opts, done);
    }
  };
};

'use strict';

var mysql = require('mysql');
var fmt = require('util').format;

function execute(query, opts, done) {
  try {
    var conn = mysql.createConnection(opts);
    conn.connect();
    conn.query(query, function (err) {
      done(err);
    });
    conn.end();
  } catch (err) {
    done(err);
  }
}

module.exports = function (opts) {
  return {
    create: function (name, done) {
      execute(fmt('CREATE DATABASE IF NOT EXISTS `%s`;', name), opts, done);
    },
    drop: function (name, done) {
      execute(fmt('DROP DATABASE IF EXISTS %s;', name), opts, done);
    }
  };
};

Add support for db name with dash


/*global meiosis, meiosisRiot*/
(function() {
  var initialModel = { counter: 0 };

  var receive = function(model, proposal) {
    return { counter: model.counter + proposal.add };
  };

  meiosisRiot.renderer("app").intoId(document, "riotApp").then(function(resolved) {
    var Meiosis = meiosis.init();

    var actions = function(propose) {
      return {
        onInc: function() {
          propose({ add: 3 });
        },
        onDecr: function() {
          propose({ add: -3 });
        }
      };
    };

    var ready = function(actions) {
      resolved.tags[0].tags["counter"].update({actions: actions});
    };

    var Main = Meiosis.createComponent({
      initialModel: initialModel,
      actions: actions,
      receive: receive,
      ready: ready
    });

    Meiosis.run(resolved.render, Main);
  });
})();

/*global meiosis, meiosisRiot*/
(function() {
  var initialModel = { counter: 0 };

  var receive = function(model, proposal) {
    return { counter: model.counter + proposal.add };
  };

  var actions = function(propose) {
    return {
      onInc: function() {
        propose({ add: 3 });
      },
      onDecr: function() {
        propose({ add: -3 });
      }
    };
  };

  meiosisRiot.renderer("app").intoId(document, "riotApp").then(function(resolved) {
    var Meiosis = meiosis.init();

    var ready = function(actions) {
      resolved.tags[0].tags["counter"].update({actions: actions});
    };

    var Main = Meiosis.createComponent({
      initialModel: initialModel,
      actions: actions,
      receive: receive,
      ready: ready
    });

    Meiosis.run(resolved.render, Main);
  });
})();

Update Riot and Vue examples.


$(document).ready(function() {
   $('pre.r').next().each(function(index) {
      if($(this).is("pre") & $(this).attr("class") == undefined)
         $(this).addClass("r-output");
   });
});

$(document).ready(function() {
   $('pre.r').next().each(function(index) {
      if($(this).is("pre") & $(this).attr("class") == undefined) {
        $(this).addClass("r-output");
        $(this).addClass("nohighlight");
      }
   });
});

Remove automatic highlighting of R output


import { Window } from '../Util';
import _each from 'lodash/each';

export default class Share {

    /**
     * Share Constructor.
     *
     * @param   {String}  selector
     */
    constructor(selector = 'data-social') {
        this.networks = {};
        this.selector = selector;
    }

    /**
     * Register a (or multiple) new network.
     *
     * @param   {String}  network
     * @param   {Object}  instance
     */
    register(network, instance) {
        if (typeof network === 'object') {
            return network.forEach((n, i) => this.register(n, i));
        }

        this.networks[network] = instance;

        return this;
    }

    /**
     * Boot the map of social media networks.
     */
    boot() {
        _each(this.networks, (Instance, network) => {
            this.networks[network] = new Instance(this);
        });

        this.registerEvents();
    }

    /**
     * Register the click event.
     */
    registerEvents() {
        const elements = document.querySelectorAll(`[${this.selector}]`);

        _each(elements, element => {
            element.addEventListener('click', () => this.onClick(element));
        });
    }

    /**
     * Open the sharing window.
     *
     * @param   {String}  element
     */
    onClick(element) {
        const network = this.networks[element.getAttribute(this.selector)];

        Window.open(network.url);
    }
}

import { Window } from '../Util';
import _each from 'lodash/each';

export default class Share {

    /**
     * Share Constructor.
     *
     * @param   {String}  selector
     */
    constructor(selector = 'data-social') {
        this.networks = {};
        this.selector = selector;
    }

    /**
     * Register a (or multiple) new network.
     *
     * @param   {String}  network
     * @param   {Object}  instance
     */
    register(network, instance) {
        if (typeof network === 'object') {
            return network.forEach((n, i) => this.register(n, i));
        }

        this.networks[network] = instance;

        return this;
    }

    /**
     * Boot the map of social media networks.
     */
    boot() {
        _each(this.networks, (Instance, network) => {
            this.networks[network] = new Instance(this);
        });

        this.registerEvents();
    }

    /**
     * Register the click event.
     */
    registerEvents() {
        const elements = document.querySelectorAll(`[${this.selector}]`);

        _each(elements, element => {
            element.addEventListener('click', () => this.onClick(element));
        });
    }

    /**
     * Open the sharing window.
     *
     * @param   {String}  element
     */
    onClick(element) {
        const network = this.networks[element.getAttribute(this.selector)];

        if (network) {
            Window.open(network.url);
        }

    }
}

Add Check if the network exists


import Job from '../components/Job';

class JobContainer extends React.Component {
  constructor(props) {
    super();
  }

  render() {
    let jobs = this.props.jobs.map(function(job) {
      let canShow = true;

      for (let type in this.props.selectedTags) {
        for (let tag in this.props.selectedTags[type]) {
          if (this.props.selectedTags[type][tag]) {
            if (Array.isArray(job[type])) {
              if (job[type].indexOf(tag) < 0) {
                canShow = false;
              }
            } else if (job[type] !== tag) {
              canShow = false;
            }
          }
        }
      }

      if (canShow) {
        return (
          <Job jobData={job.data} />
        );
      }
    }.bind(this));

    return (
      <div className="col-xs-12 col-sm-12 col-md-9 pull-left">
        {jobs}
      </div>
    );
  }
}

export default JobContainer;

import Job from '../components/Job';

class JobContainer extends React.Component {
  constructor(props) {
    super();
  }

  render() {
    let jobs = this.props.jobs.map(function(job) {
      let canShow = true;

      for (let type in this.props.selectedTags) {
        let typeCanShow = false;

        let typeAllDisabled = true;

        for (let tag in this.props.selectedTags[type]) {
          if (this.props.selectedTags[type][tag]) {
            typeAllDisabled = false;

            if (Array.isArray(job[type])) {
              if (job[type].indexOf(tag) >= 0) {
                typeCanShow = true;
              }
            } else if (job[type] === tag) {
              typeCanShow = true;
            }
          }
        }

        if (!(typeCanShow || typeAllDisabled)) {
          canShow = false;
        }
      }

      if (canShow) {
        return (
          <Job jobData={job.data} />
        );
      }
    }.bind(this));

    return (
      <div className="col-xs-12 col-sm-12 col-md-9 pull-left">
        {jobs}
      </div>
    );
  }
}

export default JobContainer;

Fix bug in filtering algorithm.


var React = require('react');
var Events = require('../utils/events');
var Dom = require('../utils/dom');

module.exports = {

  //When the component mounts, listen to click events and check if we need to
  //Call the componentClickAway function.
  componentDidMount: function() {
    if (!this.manuallyBindClickAway) this._bindClickAway();
  },

  componentWillUnmount: function() {
    this._unbindClickAway();
  },

  _checkClickAway: function(e) {
    var el = React.findDOMNode(this);

    // Check if the target is inside the current component
    if (e.target != el &&
        !Dom.isDescendant(el, e.target) &&
        document.documentElement.contains(e.target)) {
      if (this.componentClickAway) this.componentClickAway();
    }
  },

  _bindClickAway: function() {
    Events.on(document, 'click', this._checkClickAway);
  },

  _unbindClickAway: function() {
    Events.off(document, 'click', this._checkClickAway);
  }

};

var React = require('react');
var Events = require('../utils/events');
var Dom = require('../utils/dom');

module.exports = {

  //When the component mounts, listen to click events and check if we need to
  //Call the componentClickAway function.
  componentDidMount: function() {
    if (!this.manuallyBindClickAway) this._bindClickAway();
  },

  componentWillUnmount: function() {
    this._unbindClickAway();
  },

  _checkClickAway: function(e) {
    var el = React.findDOMNode(this);

    // Check if the target is inside the current component
    if (e.target != el &&
        !Dom.isDescendant(el, e.target) &&
        document.documentElement.contains(e.target)) {
      if (this.componentClickAway) this.componentClickAway();
    }
  },

  _bindClickAway: function() {
    // On touch-enabled devices, both events fire, and the handler is called twice,
    // but it's fine since all operations for which the mixin is used
    // are idempotent.
    Events.on(document, 'mouseup', this._checkClickAway);
    Events.on(document, 'touchend', this._checkClickAway);
  },

  _unbindClickAway: function() {
    Events.off(document, 'mouseup', this._checkClickAway);
    Events.off(document, 'touchend', this._checkClickAway);
  }

};

Fix 300ms delay for ClickAwayable


define('routes_api', [], function() {
    // List API routes here.
    // E.g.:
    // {
    //     "route": "/foo/bar/{0}",
    //     "another_route": "/foo/bar/{0}/asdf"
    // }
    return {
        'fxa-login': '/api/v2/account/fxa-login/',
        'login': '/api/v2/account/login/',
        'logout': '/api/v2/account/logout/',
        'search': '/api/v1/apps/search/suggest/non-public/?cache=1&vary=0',
        'site-config': '/api/v2/services/config/site/?serializer=commonplace',
        'permissions': '/api/v2/account/operators/',
        'feed-shelves': '/api/v2/feed/shelves/',
        'feed-shelves-list': '/api/v2/transonic/feed/shelves/?limit=5',
        'feed-shelf': '/api/v2/feed/shelves/{0}/',
        'feed-shelf-publish': '/api/v2/feed/shelves/{0}/publish/',
        'feed-shelf-mine': '/api/v2/account/shelves/',
    };
});

define('routes_api', [], function() {
    // List API routes here.
    // E.g.:
    // {
    //     "route": "/foo/bar/{0}",
    //     "another_route": "/foo/bar/{0}/asdf"
    // }
    return {
        'fxa-login': '/api/v2/account/fxa-login/',
        'login': '/api/v2/account/login/',
        'logout': '/api/v2/account/logout/',
        'search': '/api/v1/apps/search/non-public/?cache=1&vary=0',
        'site-config': '/api/v2/services/config/site/?serializer=commonplace',
        'permissions': '/api/v2/account/operators/',
        'feed-shelves': '/api/v2/feed/shelves/',
        'feed-shelves-list': '/api/v2/transonic/feed/shelves/?limit=5',
        'feed-shelf': '/api/v2/feed/shelves/{0}/',
        'feed-shelf-publish': '/api/v2/feed/shelves/{0}/publish/',
        'feed-shelf-mine': '/api/v2/account/shelves/',
    };
});

Change to new search api


import { blobToArrayBuffer } from 'blob-util'

import db from 'src/pouchdb'

async function showPage(pageId) {
    // Read the html file from the database.
    const blob = await db.getAttachment(pageId, 'frozen-page.html')

    // Replace the document contents.
    try {
        // We assume utf-8 encoding. TODO: read encoding from document.
        const html = new TextDecoder('utf-8').decode(await blobToArrayBuffer(blob))
        // Strip the <html>...</html> tags because we set innerHTML.
        const innerHTML = html.match(/[^]*?<html[^]*?>([^]*)<\/html[^]*?>/i)[1]
        document.documentElement.innerHTML = innerHTML
    } catch (err) {
        // Alternatively, use a blob URL (downside: the url is very temporary).
        const blobUrl = URL.createObjectURL(blob)
        window.location = blobUrl
    }
}

const pageId = new URL(window.location).searchParams.get('page')
showPage(pageId)

import { blobToArrayBuffer } from 'blob-util'

import db from 'src/pouchdb'

async function showPage(pageId) {
    // Read the html file from the database.
    const blob = await db.getAttachment(pageId, 'frozen-page.html')

    // Replace the document contents.
    try {
        // We assume utf-8 encoding. TODO: read encoding from document.
        const html = new TextDecoder('utf-8').decode(await blobToArrayBuffer(blob))
        // Strip the <html>...</html> tags because we set innerHTML.
        const innerHTML = html.match(/[^]*?<html[^]*?>([^]*)<\/html[^]*?>/i)[1]
        document.documentElement.innerHTML = innerHTML

        // Pragmatic workaround for Chromium, which appears to inject values for
        // these two properties (with font-family: 75%, for some reason?)
        if (document.head !== undefined) {
            const styleEl = document.createElement('style')
            styleEl.innerHTML = `body {
                font-size: inherit;
                font-family: inherit;
            }`
            document.head.insertAdjacentElement('afterbegin', styleEl)
        }
    } catch (err) {
        // Alternatively, use a blob URL (downside: the url is very temporary).
        const blobUrl = URL.createObjectURL(blob)
        window.location = blobUrl
    }
}

const pageId = new URL(window.location).searchParams.get('page')
showPage(pageId)

Work around for Chromium's injected stylesheet.


module.exports = function(
  $stateProvider,
  $urlRouterProvider,
  $urlMatcherFactoryProvider
) {
  // Disable ui-router strict mode
  $urlMatcherFactoryProvider.strictMode(false);

  // Render 404 when no routes are matched
  $urlRouterProvider.otherwise('/404');

  $stateProvider
    .state('root', {
      abstract: true,
      templateUrl: 'app/templates/default.html',
      resolve: {
        loadEndpoints: function ($rootScope, API, $q) {
          $rootScope.apiLoaded = false;
          var deferred = $q.defer();
          var gapiInterval = window.setInterval(function() {
            if ($rootScope.apiLoaded) {
              window.clearInterval(gapiInterval);
              return;
            }

            gapi.client.load(API.NAME, API.VERSION, function (data) {
              $rootScope.apiLoaded = true;
              deferred.resolve();
            }, API.URL);
          }, 200);

          return deferred.promise;
        }
      }
    })
    .state('404', {
      url: '/404',
      templateUrl: 'app/templates/404.html'
    });
};

module.exports = function(
  $stateProvider,
  $urlRouterProvider,
  $urlMatcherFactoryProvider
) {
  // Disable ui-router strict mode
  $urlMatcherFactoryProvider.strictMode(false);

  // Render 404 when no routes are matched
  $urlRouterProvider.otherwise('/404');

  $stateProvider
    .state('root', {
      abstract: true,
      templateUrl: 'app/templates/default.html',
      resolve: {
        loadEndpoints: function ($rootScope, API, $q) {
          $rootScope.apiLoaded = false;
          var deferred = $q.defer();
          var gapiInterval = window.setInterval(function() {
            if ($rootScope.apiLoaded) {
              window.clearInterval(gapiInterval);
              return;
            }

            gapi.client.load(API.NAME, API.VERSION, function (data) {
              $rootScope.apiLoaded = true;
              deferred.resolve();
            }, API.URL);
          }, 200);

          return deferred.promise;
        }
      }
    })
    .state('404', {
      url: '/404',
      controller : function (AppService) {
        AppService.setPageTitle('Página não encontrada');
      },
      templateUrl: 'app/templates/404.html'
    });
};

Add page title to error page


export default [
  {id: 1, name: 'joliss', twitter: "joliss"},
  {id: 2, name: 'igort', twitter: "igort"},
  {id: 3, name: 'tchak', twitter: "tchak"},
  {id: 4, name: 'wecc', twitter: "wecc"},
  {id: 5, name: 'bmac', twitter: "bmac"},
  {id: 6, name: 'teddyzeenny', twitter: "teddyzeenny"},
  {id: 7, name: 'zencocoon', twitter: "sebgrosjean"}
];

export default [
  {id: 1, name: 'joliss', twitter: "joliss"},
  {id: 2, name: 'igort', twitter: "terzicigor"},
  {id: 3, name: 'tchak', twitter: "tchak13"},
  {id: 4, name: 'wecc', twitter: "ChristofferP"},
  {id: 5, name: 'bmac', twitter: "BezoMaxo"},
  {id: 6, name: 'teddyzeenny', twitter: "teddyzeenny"},
  {id: 7, name: 'zencocoon', twitter: "sebgrosjean"}
];

Use proper Twitter handles in fixture <3


import React from 'react'
import Modal from 'app/components/modal'
import Flash from 'app/flash'
import i18n from 'app/utils/i18n'
import rpc from 'app/rpc'

class CreateDashboard extends React.Component{
  handleCreateDashboard(){
    const props = this.props
    let name = this.refs.name.value
    rpc.call("dashboard.create", {
      project: props.project,
      name: name
    }).then( () => props.onClose() )
    .catch( e => {
      console.error(e)
      Flash.error("Could not create the dashboard. Check the logs.")
    })
  }
  render(){
    const props = this.props
    return (
      <Modal>

Create new dashboard

              {i18n("Dashboard name")}
              <input type="text" className="input" ref="name" placeholder={i18n("Monitoring, tools...")}/>

            <button className="ui button yellow" onClick={this.handleCreateDashboard}>
              {i18n("Create dashboard")}
            </button>

      </Modal>
    )
  }
}

export default CreateDashboard

import React from 'react'
import Modal from 'app/components/modal'
import Flash from 'app/flash'
import i18n from 'app/utils/i18n'
import rpc from 'app/rpc'

class CreateDashboard extends React.Component{
  handleCreateDashboard(){
    const props = this.props
    let name = this.refs.name.value
    rpc.call("dashboard.create", {
      project: props.project,
      name: name
    }).then( () => props.onClose() )
    .catch( e => {
      console.error(e)
      Flash.error("Could not create the dashboard. Check the logs.")
    })
  }
  render(){
    const props = this.props
    return (
      <Modal>

Create new dashboard

              {i18n("Dashboard name")}
              <input type="text" className="input" ref="name" placeholder={i18n("Monitoring, tools...")}/>

            <button className="ui button yellow" onClick={this.handleCreateDashboard.bind(this)}>
              {i18n("Create dashboard")}
            </button>

      </Modal>
    )
  }
}

export default CreateDashboard

Fix create dashboard not working


const gulp = require('gulp');
const replace = require('gulp-replace');

const Builder = require('systemjs-builder');

const conf = require('../conf/gulp.conf');

gulp.task('systemjs', systemjs);
gulp.task('systemjs:html', updateIndexHtml);

function systemjs(done) {
  const builder = new Builder('./', 'jspm.config.js');

  builder.buildStatic(
    <%- entry %>,
    conf.path.tmp('index.js')
  ).then(() => done(), done);
}

function updateIndexHtml() {
  return gulp.src(conf.path.src('index.html'))
    .pipe(replace(
      /<script[\s\S]*script>/,
      `<script src="index.js"></script>`
    ))
    .pipe(gulp.dest(conf.path.tmp()));
}

const gulp = require('gulp');
const replace = require('gulp-replace');

const Builder = require('systemjs-builder');

const conf = require('../conf/gulp.conf');

gulp.task('systemjs', systemjs);
gulp.task('systemjs:html', updateIndexHtml);

function systemjs(done) {
  const builder = new Builder('./', 'jspm.config.js');
  builder.config({
    paths: {
      "github:*": "jspm_packages/github/*",
      "npm:*": "jspm_packages/npm/*"
    },
    packageConfigPaths: [
      'npm:@*/*.json',
      'npm:*.json',
      'github:*/*.json'
    ]
  });
  builder.buildStatic(
    <%- entry %>,
    conf.path.tmp('index.js')
  ).then(() => done(), done);
}

function updateIndexHtml() {
  return gulp.src(conf.path.src('index.html'))
    .pipe(replace(
      /<script[\s\S]*script>/,
      `<script src="index.js"></script>`
    ))
    .pipe(gulp.dest(conf.path.tmp()));
}

Add jspm_packages paths to builder config


var crypto = require("crypto");

module.exports = function(length) {
    var uid = "";
    while (uid.length <= length) {
        uid += crypto
            .randomBytes(256)
            .toString("base64")
            .replace(/[^a-zA-Z0-9]/g, "");
    }
    return uid.slice(0, length);
};

var crypto = require("crypto");

module.exports = function(length) {
    var uid = "";
    while (uid.length <= length) {
        uid += crypto
            .randomBytes(256)
            .toString("base64")
            .replace(/[^a-zA-Z0-9]/g, "");
    }
    // HACK: make sure unique id is never syntactically valid JavaScript
    // See http://balpha.de/2013/02/plain-text-considered-harmful-a-cross-domain-exploit/
    uid = "9c" +uid.slice(0, length - 2);
    return uid;
};

Make sure generated tokens are never valid JavaScript


'use strict';

var randn = require( './../lib' );

var seed;
var rand;
var i;

// Generate pseudorandom numbers...
console.log( '\nseed: %d', randn.SEED );
for ( i = 0; i < 100; i++ ) {
	console.log( randn() );
}

// Create a new pseudorandom number generator...
seed = 1234;
rand = randn.factory( seed );
console.log( '\nseed: %d', seed );
for ( i = 0; i < 100; i++ ) {
	console.log( rand() );
}

// Create another pseudorandom number generator using a previous seed...
rand = randn.factory( randn.SEED );
console.log( '\nseed: %d', randn.SEED );
for ( i = 0; i < 100; i++ ) {
	console.log( rand() );
}

'use strict';

var randn = require( './../lib' );

var seed;
var rand;
var i;

// Generate pseudorandom numbers...
console.log( '\nseed: %d', randn.SEED );
for ( i = 0; i < 100; i++ ) {
	console.log( randn() );
}

// Create a new pseudorandom number generator...
seed = 1234;
rand = randn.factory({
	'seed': seed
});
console.log( '\nseed: %d', seed );
for ( i = 0; i < 100; i++ ) {
	console.log( rand() );
}

// Create another pseudorandom number generator using a previous seed...
rand = randn.factory({
	'seed': randn.SEED
});
console.log( '\nseed: %d', randn.SEED );
for ( i = 0; i < 100; i++ ) {
	console.log( rand() );
}

Fix fcn invocation with seed option


import { useRef, useEffect } from 'react';
import getModifiedProps from '../../utils/getModifiedProps';

export default function useModifiedProps(props) {
  const ref = useRef();
  useEffect(() => {
    ref.current = props;
  });
  return getModifiedProps(ref.current, props);
}

import { useRef, useEffect, useDebugValue } from 'react';
import getModifiedProps from '../../utils/getModifiedProps';

export default function useModifiedProps(props) {
  const ref = useRef();
  useEffect(() => {
    ref.current = props;
  });
  const modifiedProps = getModifiedProps(ref.current, props);

  useDebugValue(modifiedProps ? 'Modified' : 'Not modified');

  return modifiedProps;
}

Add debug value to useModifiedProps


// Deps
var express = require('express');
var bodyParser = require('body-parser');

// Config:
var port = process.env.PORT || 8000;
var root = __dirname + '/';
var sendFileConfig = { root: root };

// App:
var app = express();
app.use(bodyParser.urlencoded());

app.get('/', function (req, res) {
  res.sendFile('index.html', sendFileConfig);
});

app.post('/custom-sidebar', function (req, res) {
  setTimeout(function () {
    res.send(
      '<pre>' +
      JSON.stringify(req.body, null, '  ') +
      '</pre>'
    );
  }, 500);
});

// Server:
var server = app.listen(port, function () {
  console.log('Listening on %s', port);
});
server.on('error', function (e) {
  if (e.code === 'EADDRINUSE') {
    console.error('Error listening on %s', port);
  } else {
    console.error(e);
  }
});

// Deps
var crypto = require('crypto');
var express = require('express');
var bodyParser = require('body-parser');

// Config:
var port = process.env.PORT || 8000;
var root = __dirname + '/';
var sendFileConfig = { root: root };
var secret = '123abc';

// App:
var app = express();
var bodyParserMiddleware = bodyParser.urlencoded({
  verify: function (req, res, buf, encoding) {

    // Get hash of message using shared secret:
    var hasher = crypto.createHmac('sha1', secret);
    hasher.update(buf.toString());
    var hash = hasher.digest('base64');

    // Compare hash to Acuity signature:
    if (hash !== req.header('X-Acuity-Signature')) {
      throw new Error('This message was forged!');
    }
  }
});

app.get('/', function (req, res) {
  res.sendFile('index.html', sendFileConfig);
});

app.post('/custom-sidebar', bodyParserMiddleware, function (req, res) {
  setTimeout(function () {
    res.send(
      '<pre>' +
      JSON.stringify(req.body, null, '  ') +
      '</pre>'
    );
  }, 500);
});

// Server:
var server = app.listen(port, function () {
  console.log('Listening on %s', port);
});
server.on('error', function (e) {
  if (e.code === 'EADDRINUSE') {
    console.error('Error listening on %s', port);
  } else {
    console.error(e);
  }
});

Add signing to custom-sidebar integration.


import generateFramework from '../generators/framework/generateFramework';
import generateTemplateEngine from '../generators/template-engine/generateTemplateEngine';
import generateCssFramework from '../generators/css-framework/generateCssFramework';
import generateCssPreprocessor from '../generators/css-preprocessor/generateCssPreprocessor';
import generateCssBuildOptions from '../generators/css-build-options/generateCssBuildOptions';
import generateDatabase from '../generators/database/generateDatabase';
import generateAuthentication from '../generators/authentication/generateAuthentication';
import generateJsFramework from '../generators/js-framework/generateJsFramework';
import { walkAndRemoveComments, prepare, cleanup } from '../generators/utils';

async function download(req, res) {
  let params = await prepare(req.body);
  try {
    await generateFramework(params);
    await generateTemplateEngine(params);
    await generateCssFramework(params);
    await generateCssPreprocessor(params);
    await generateCssBuildOptions(params);
    await generateDatabase(params);
    await generateAuthentication(params);
    await generateJsFramework(params);
    await walkAndRemoveComments(params);
  } catch (e) {
    throw Error(e);
  }
  res.end();
}

export default download;

import generateFramework from '../generators/framework/generateFramework';
import generateTemplateEngine from '../generators/template-engine/generateTemplateEngine';
import generateCssFramework from '../generators/css-framework/generateCssFramework';
import generateCssPreprocessor from '../generators/css-preprocessor/generateCssPreprocessor';
import generateCssBuildOptions from '../generators/css-build-options/generateCssBuildOptions';
import generateDatabase from '../generators/database/generateDatabase';
import generateAuthentication from '../generators/authentication/generateAuthentication';
import generateJsFramework from '../generators/js-framework/generateJsFramework';
import { walkAndRemoveComments, prepare, cleanup } from '../generators/utils';

async function download(req, res) {
  let params = await prepare(req.body);
  try {
    await generateFramework(params);
    await generateTemplateEngine(params);
    await generateCssFramework(params);
    await generateCssPreprocessor(params);
    await generateCssBuildOptions(params);
    await generateDatabase(params);
    await generateAuthentication(params);
    await generateJsFramework(params);
    await walkAndRemoveComments(params);
    res.end();
  } catch (err) {
    console.info(err.stack);
    console.info(params);
    res.status(500).send(err.message);
  }

}

export default download;

Return error message and print stack trace via try/catch


'use strict';
var sess;

/* GET forgotpassword page. */
exports.getForgot = function(req, res) {
    sess=req.session;
    sess.url = '/';
    sess.user = null;
    sess.title = 'MangaDB: Forgot Password';
    res.render('forgot', {
        title: sess.title,
        url: sess.url
    });
};

/* GET reset password page. */
exports.getReset = function(req, res) {
    sess=req.session;
    sess.url = '/';
    sess.user = null;
    sess.title = 'MangaDB: Reset Password';
    res.render('reset', {
        title: sess.title,
        url: sess.url
    });
};

/* HANDLE PASSWORD RECOVERY */
exports.postForgot = function(req, res) {
    sess=req.session;
    sess.url = '/';
    sess.user = null;
    sess.title = 'MangaDB: Reset Password';
};

/* HANDLE RESET ACTIONS */
exports.postReset = function(req, res) {
    sess=req.session;
    sess.url = '/';
    sess.user = null;
    sess.title = 'MangaDB: Reset Password';
};

Add post method for forgot and reset


(function () {
  angular
    .module("ng-geocoder")
    .factory("ngGeocoderService", ngGeocoderService);

  ngGeocoderService.$inject = ["$q"];

  function ngGeocoderService ($q) {
    var geocoder = new google.maps.Geocoder();
    var service  = {
      "geocodeById": geocodeById,
      "geocodeByQuery": geocodeByQuery
    }

    return service;

    function handleReply (defer, results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        return defer.resolve(results);
      } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
        return defer.resolve([]);
      } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
        return defer.reject("Over query limit");
      } else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
        return defer.reject("Request denied");
      }

      return defer.reject("Unknown error");
    }

    function geocodeById (place_id) {
      return geocode({ "place_id": query });
    }

    function geocodeByQuery (query) {
      return geocode({ "address": query });
    }

    function geocode (options) {
      var defer = $q.defer();

      geocoder.geocode(options, function (results, status) {
        handleReply(defer, results, status);
      });

      return defer.promise;
    }
  }
})();

(function () {
  angular
    .module("ng-geocoder")
    .factory("ngGeocoderService", ngGeocoderService);

  ngGeocoderService.$inject = ["$q"];

  function ngGeocoderService ($q) {
    var geocoder = new google.maps.Geocoder();
    var service  = {
      "geocodeById": geocodeById,
      "geocodeByQuery": geocodeByQuery
    }

    return service;

    function handleReply (defer, results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        return defer.resolve(results);
      } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
        return defer.resolve([]);
      } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
        return defer.reject("Over query limit");
      } else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
        return defer.reject("Request denied");
      }

      return defer.reject("Unknown error");
    }

    function geocodeById (placeId) {
      return geocode({ "placeId": placeId });
    }

    function geocodeByQuery (query) {
      return geocode({ "address": query });
    }

    function geocode (options) {
      var defer = $q.defer();

      geocoder.geocode(options, function (results, status) {
        handleReply(defer, results, status);
      });

      return defer.promise;
    }
  }
})();

Fix placeId params on geocoder request options


$(document).ready(() => {
	if (typeof window.reloadBaj === 'undefined') {
		console.error('alchemists-boiteajeux: reloadBaj is undefined');
		return;
	}

	var gameId = '0';
	var interval;
	var reload = window.reloadBaj;
	var self = document.getElementById('alc-notifier');

	for (var part of window.location.search.slice(1).split('&')) {
		if (part.startsWith('id=')) {
			gameId = part.slice(3);
			break;
		}
	}

	self.addEventListener('alc-interval', event => {
		clearInterval(interval);

		if (event.detail.action == 'start') {
			interval = setInterval(reload, event.detail.delayMS);
		}
	});

	self.dispatchEvent(new CustomEvent('alc-notifier-ready', {
		detail: {
			'game-id': gameId,
			'waiting-text': window.TXT_ALC_ACTION_ATTENDRE
		}
	}));
});

$(document).ready(() => {
	if (typeof window.reloadBaj === 'undefined') {
		console.error('Alchemists Notifier: reloadBaj is undefined, unable to continue');
		return;
	}

	var gameId = '0';
	var interval;
	var reload = window.reloadBaj;
	var self = document.getElementById('alc-notifier');

	for (var part of window.location.search.slice(1).split('&')) {
		if (part.startsWith('id=')) {
			gameId = part.slice(3);
			break;
		}
	}

	self.addEventListener('alc-interval', event => {
		clearInterval(interval);

		if (event.detail.action == 'start') {
			interval = setInterval(reload, event.detail.delayMS);
		}
	});

	self.dispatchEvent(new CustomEvent('alc-notifier-ready', {
		detail: {
			'game-id': gameId,
			'waiting-text': window.TXT_ALC_ACTION_ATTENDRE
		}
	}));
});

Improve error message when reloadBaj is undefined.


// This is the JS embedded in the page that will host the iFrame
// It assumes that there is no jQuery, just a modern browser.

// when we're good to go
window.onload = function() {
  // find the div
  var embedDiv = document.getElementById('swarmize-embedded-form');

  // extract token from data attribute
  var token = embedDiv.dataset.swarmizeToken;

  // insert an iFrame containing the embed
  if(window.location.hostname == 'localhost') {
    var origin = window.location.origin
  } else {
    var origin = 'http://cdn.swarmize.com';
  }
  embedDiv.innerHTML = "<iframe src='" + origin + "/swarms/"+token+"/embed' width='460' height='400' frameBorder='0' seamless='seamless'></iframe>";

  var iframe = embedDiv.getElementsByTagName('iframe')[0];

  respondToMessage = function(e) {
    var chunks = e.data.split("|");

    // when the form changes size, update the height of the iFrame
    if(chunks[0] == 'swarmizeSetHeight') {
      var height = chunks[1];
      iframe.setAttribute('height', height);
    }

    // when the form is submitted, scroll top the top of the iFrame
    if(chunks[0] == 'swarmizeFormSuccess') {
      window.scrollTo(0,iframe.offsetTop);
    }
  }

  // listen out for the message event.
  window.addEventListener('message', respondToMessage, false);
}

// This is the JS embedded in the page that will host the iFrame
// It assumes that there is no jQuery, just a modern browser.

// when we're good to go
window.onload = function() {
  // find the div
  var embedDiv = document.getElementById('swarmize-embedded-form');

  // extract token from data attribute
  var token = embedDiv.dataset.swarmizeToken;

  // insert an iFrame containing the embed
  if(window.location.hostname == 'localhost') {
    var origin = window.location.origin
  } else {
    var origin = 'http://cdn.swarmize.com';
  }
  embedDiv.innerHTML = "<iframe src='" + origin + "/swarms/"+token+"/embed' width='460' height='400' frameBorder='0' seamless='seamless'></iframe>";

  var iframe = embedDiv.getElementsByTagName('iframe')[0];

  iframe.setAttribute('width', '100%');

  respondToMessage = function(e) {
    var chunks = e.data.split("|");

    // when the form changes size, update the height of the iFrame
    if(chunks[0] == 'swarmizeSetHeight') {
      var height = chunks[1];
      iframe.setAttribute('height', height);
    }

    // when the form is submitted, scroll top the top of the iFrame
    if(chunks[0] == 'swarmizeFormSuccess') {
      window.scrollTo(0,iframe.offsetTop);
    }
  }

  // listen out for the message event.
  window.addEventListener('message', respondToMessage, false);
}

Set iFrame width to 100%


'use strict';
var util = require('util');
var zepto = require('zepto-browserify');
var Controller = require('./controller');
var Model = require('./model');

var $ = zepto.$;

function main() {
  var controller = new EntriesController({
    el: $('#animus .animus-view'),
  });
}

function EntriesController() {
  this.constructor.super_.apply(this, arguments);
}
util.inherits(EntriesController, Controller);

EntriesController.prototype.attach = function(el) {
  var _this = this;
  this.constructor.super_.prototype.attach.call(this, el);
  this.$el('input.animus-new-entry-input').on('keydown', function(evt) {
    _this.onKeydownNewEntry(evt);
  });
};

EntriesController.prototype.onKeydownNewEntry = function(evt) {
  console.log(evt.keyCode);
};

function Entry() {
  this.createdAt = new Date();
  this._super.constructor.apply(this, arguments);
}
util.inherits(Entry, Model);

if(!module.parent) {
  main();
}

'use strict';
var util = require('util');
var zepto = require('zepto-browserify');
var Controller = require('./controller');
var Model = require('./model');

var $ = zepto.$;

function main() {
  var controller = new EntriesController({
    el: $('#animus .animus-view'),
  });
}

function EntriesController() {
  this.constructor.super_.apply(this, arguments);
}
util.inherits(EntriesController, Controller);

EntriesController.prototype.attach = function(el) {
  var _this = this;
  this.constructor.super_.prototype.attach.call(this, el);
  this.$el('input.animus-new-entry-input').on('keydown', function(evt) {
    _this.onKeydownNewEntry(evt);
  });
};

EntriesController.prototype.onKeydownNewEntry = function(evt) {
  console.log(evt.keyCode);
};

function Entry() {
  this.createdAt = new Date();
  this._super.constructor.apply(this, arguments);
}
util.inherits(Entry, Model);

if(!module.parent) {
  $(function() {
    main();
  });
}

Fix main invocation on the browser


var slice = [].slice

function Operation (operation, vargs) {
    vargs || (vargs = [])
    if (typeof operation == 'function') {
        this.operation = operation
        this.method = 'apply'
        this.object = null
        this.vargs = vargs
    } else {
        this.object = operation.object
        this.vargs = (operation.vargs || []).concat(vargs)
        if (typeof operation.method == 'string') {
            this.operation = this
            this.method = '_named'
            this._name = operation.method
        } else {
            this.operation = operation.method
            this.method = 'apply'
        }
    }
}

Operation.prototype._vargs = function (args, vargs) {
    if (vargs == null) {
        return this.vargs.concat(args)
    }
    return args.concat(this.vargs.concat(vargs))
}

Operation.prototype.apply = function (args, vargs) {
    return this.operation[this.method](this.object, this._vargs(args, vargs))
}

Operation.prototype._named = function (object, args, vargs) {
    return object[this._name].apply(object, this._vargs(args, vargs))
}

module.exports = Operation

var slice = [].slice

function Operation (operation, vargs) {
    vargs || (vargs = [])
    if (typeof operation == 'function') {
        this.operation = operation
        this.method = 'apply'
        this.object = null
        this.vargs = vargs
    } else {
        this.object = operation.object
        this.vargs = (operation.vargs || []).concat(vargs)
        if (typeof operation.method == 'string') {
            this.operation = this
            this.method = '_named'
            this._name = operation.method
        } else {
            this.operation = operation.method
            this.method = 'apply'
        }
    }
}

Operation.prototype._vargs = function (args, vargs) {
    if (vargs == null) {
        return this.vargs.concat(args)
    }
    return args.concat(this.vargs.concat(vargs))
}

Operation.prototype.apply = function (args, vargs) {
    return this.operation[this.method](this.object, this._vargs(args, vargs))
}

Operation.prototype._named = function (object, vargs) {
    return object[this._name].apply(object, vargs)
}

module.exports = Operation

Fix invocation of named function helper.


App.ObjectPanel = Ext.extend(Ext.Panel, {
	border: false
	,iconCls: 'icon-tab-object'
	,closable: true
	,layout: 'vbox'
	,initComponent: function(){
		this.items = [
			{border:true,margins:"5 5 5 5",frame:true,layout:'fit',bodyStyle:'padding:5px;',html:"Object ID: " + this.oid}
			,new App.TagValuesGrid({oid: this.oid, flex: 1})
		];
		this.title = 'Object ' + this.oid;
		App.ObjectPanel.superclass.initComponent.call(this);
	}
});

Ext.reg('app.objectpanel', App.ObjectPanel);

App.ObjectPanel = Ext.extend(Ext.Panel, {
	border: false
	,iconCls: 'icon-tab-object'
	,closable: true
	,layout: 'vbox'
	,initComponent: function(){
		this.items = [
			{border:true,margins:"5 5 5 5",frame:true,layout:'fit',bodyStyle:'padding:5px;',html:"Object ID: " + this.oid}
			,new App.TagValuesGrid({oid: this.oid, flex: 1})
		];
		this.title = 'Object ' + this.oid.split('-')[0];
		this.tabTip = this.oid;

		App.ObjectPanel.superclass.initComponent.call(this);
	}
	,afterRender: function(){
		App.ObjectPanel.superclass.afterRender.apply(this, arguments);

		Ext.Ajax.request({
			url: App.Config.base_remote + 'gettagvalue'
			,params: {oid: this.oid, tag: "fluiddb/about"}
			,scope: this
			,success: function(a){
				this.items.items[0].update("Object ID: " + this.oid + "

About: " + a.responseText);
				this.doLayout();
			}
		});

	}

});

Ext.reg('app.objectpanel', App.ObjectPanel);

Use short UUID for tab title and display about tag


module.exports = function toSquareMeters(space, space_units) {
    if (space === "") {
        return 0;
    }
    space = parseFloat(space.replace(",", "."));

    if (space_units === "м²" || space_units === "") {
        return space;
    } else if (space_units === "га") {
        return space * 10000;
    } else if (space_units === "соток") {
        return space * 100;
    }
};

module.exports = function toSquareMeters(space, space_units) {
    if (space === "" || typeof space === "undefined") {
        return 0;
    }
    space = parseFloat(space.replace(",", "."));

    if (space_units === "м²" || space_units === "") {
        return space;
    } else if (space_units === "га") {
        return space * 10000;
    } else if (space_units === "соток") {
        return space * 100;
    }
};

Update toSquareMeters helper undefined fix


app.controller('LoginController', ['$scope', '$mdDialog', '$firebaseAuth', 'AuthFactory', function($scope, $mdDialog, $firebaseAuth, AuthFactory){
  console.log('login controller is running');
  var auth = $firebaseAuth();
  var self = this;

  self.isLoggedIn = AuthFactory.userStatus.isLoggedIn;
  console.log(self.isLoggedIn);

  self.logIn = function(userType) {
    console.log('logging user in');
    console.log(userType);
    AuthFactory.logIn(userType).then(function(response){
      console.log('Logged In: ', AuthFactory.userStatus.isLoggedIn);
    })
    .then(function(){
      // TODO This isn't working because user type isn't set in time
      if(AuthFactory.userStatus.newUser === false && AuthFactory.userStatus.userType == 'mentor') {
        console.log('duh');
        self.cancel();
      }
    });
  };

  self.logOut = function() {
    console.log('logging user out');
    AuthFactory.logOut();
  };

  self.cancel = function() {
    $mdDialog.cancel();
  };

}]);

app.controller('LoginController', ['$scope', '$mdDialog', '$firebaseAuth', 'AuthFactory', function($scope, $mdDialog, $firebaseAuth, AuthFactory){
  console.log('login controller is running');
  var auth = $firebaseAuth();
  var self = this;

  self.isLoggedIn = AuthFactory.userStatus.isLoggedIn;
  console.log(self.isLoggedIn);

  self.logIn = function(userType) {
    console.log('logging user in');
    console.log(userType);
    AuthFactory.logIn(userType).then(function(response){
      console.log('Logged In: ', AuthFactory.userStatus.isLoggedIn);
    })
    .then(function(){
      // TODO This isn't working because user type isn't set in time
      if(AuthFactory.userStatus.newUser === false && AuthFactory.userStatus.userType == 'mentor') {
        console.log('duh');
        self.cancel();
      }
      setTimeout(firstTimeMentor, 1000);
    });
  };

  function firstTimeMentor() {
    console.log('and here, AuthFactory.userStatus.newUser: ', AuthFactory.userStatus);
    if (AuthFactory.userStatus.newUser === true && AuthFactory.userStatus.userType == 'mentor') {
      alert('fill out yer profile');
    }
  }

  self.logOut = function() {
    console.log('logging user out');
    AuthFactory.logOut();
  };

  self.cancel = function() {
    $mdDialog.cancel();
  };

}]);

Add delayed popup when mentor logs in for the first time


import React from 'react';
import { View, Button } from 'react-native';

/*
Developer screen.
Provides access to components during development.
*/
export default class DeveloperScreen extends React.Component {
  static navigationOptions = {
    tabBar: {
      label: 'Developer',
    },
    title: 'Developer',
  };

  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Button onPress={() => navigate('SampleScreen')} title="Go to the sample screen" />
        <Button onPress={() => navigate('MakePaymentScreen')} title="Pay your order" />
      </View>
    );
  }
}

import React from 'react';
import { View, Button } from 'react-native';

/*
Developer screen.
Provides access to components during development.
*/
export default class DeveloperScreen extends React.Component {
  static navigationOptions = {
    tabBar: {
      label: 'Developer',
    },
    title: 'Developer',
  };

  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Button onPress={() => navigate('SampleScreen')} title="Go to the sample screen" />
        <Button onPress={() => navigate('MakePaymentScreen')} title="Pay your order" />
        <Button onPress={() => navigate('ChooseJobTypeScreen')} title="Go to choose job type screen" />
      </View>
    );
  }
}

Add navigation to choose job type screen from developer screen


/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2014
//
// memstore.js
//

function formatLongInt(n) {
    return (n|0).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

function formatQuantLabel(v) {
    var t = '' + v;
    var dot = t.indexOf('.');
    if (dot < 0) {
        return t;
    } else {
        var dotThreshold = 2;
        if (t.substring(0, 1) == '-') {
            ++dotThreshold;
        }

        if (dot >= dotThreshold) {
            return t.substring(0, dot);
        } else {
            return t.substring(0, dot + 2);
        }
    }
}

if (typeof(module) !== 'undefined') {
    module.exports = {
        formatLongInt: formatLongInt,
        formatQuantLabel: formatQuantLabel
    };
}

/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2014
//
// numformats.js
//

function formatLongInt(n) {
    return (n|0).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

function formatQuantLabel(v) {
    var t = '' + v;
    var dot = t.indexOf('.');
    if (dot < 0) {
        return t;
    } else {
        var dotThreshold = 2;
        if (t.substring(0, 1) == '-') {
            ++dotThreshold;
        }

        if (dot >= dotThreshold) {
            return t.substring(0, dot);
        } else {
            return t.substring(0, dot + 2);
        }
    }
}

if (typeof(module) !== 'undefined') {
    module.exports = {
        formatLongInt: formatLongInt,
        formatQuantLabel: formatQuantLabel
    };
}

Correct the module name in the header comment


/* globals AFRAME THREE */
AFRAME.registerBrush('single-sphere',
  {
    init: function (color, width) {
      this.material = new THREE.MeshStandardMaterial({
        color: this.data.color,
        roughness: 0.6,
        metalness: 0.2,
        side: THREE.FrontSide,
        shading: THREE.SmoothShading
      });
      this.geometry = new THREE.SphereGeometry(0.5, 16, 16);
      this.mesh = new THREE.Mesh(this.geometry, this.material);
      this.object3D.add(this.mesh);
      this.mesh.visible = false
    },
    addPoint: function (position, orientation, pointerPosition, pressure, timestamp) {
      if (!this.firstPoint) {
        this.firstPoint = pointerPosition.clone();
        this.mesh.position.set(this.firstPoint.x, this.firstPoint.y, this.firstPoint.z)
      }
      this.mesh.visible = true
      var distance = this.firstPoint.distanceTo(pointerPosition) * 2;
      this.mesh.scale.set(distance, distance, distance);
      return true;
    }
  },
  {thumbnail: 'brushes/thumb_single_sphere.png', spacing: 0.0}
);

/* globals AFRAME THREE */
AFRAME.registerBrush('single-sphere',
  {
    init: function (color, width) {
      this.material = new THREE.MeshStandardMaterial({
        color: this.data.color,
        roughness: 0.6,
        metalness: 0.2,
        side: THREE.FrontSide,
        shading: THREE.SmoothShading
      });
      this.geometry = new THREE.IcosahedronGeometry(0.5, 2);
      this.mesh = new THREE.Mesh(this.geometry, this.material);
      this.object3D.add(this.mesh);
      this.mesh.visible = false
    },
    addPoint: function (position, orientation, pointerPosition, pressure, timestamp) {
      if (!this.firstPoint) {
        this.firstPoint = pointerPosition.clone();
        this.mesh.position.set(this.firstPoint.x, this.firstPoint.y, this.firstPoint.z)
      }
      this.mesh.visible = true
      var distance = this.firstPoint.distanceTo(pointerPosition) * 2;
      this.mesh.scale.set(distance, distance, distance);
      return true;
    }
  },
  {thumbnail: 'brushes/thumb_single_sphere.png', spacing: 0.0}
);

Use icosahedron instead of sphere for less faces


define([
  'client/client_bootstrap',
  'extensions/controllers/dashboard'
],
function (bootstrap, DashboardController) {
  describe('client bootstrap', function () {

    var config;
    beforeEach(function () {
      spyOn(DashboardController.prototype, 'render');
      config = {
        'page-type': 'dashboard'
      };
    });

    it('instantiates a controller from config data', function () {
      var controller = bootstrap(config);

      expect(controller instanceof DashboardController).toBe(true);
      expect(controller.render).toHaveBeenCalled();
    });

    it('executes page preprocessors', function () {
      var originalPreprocessors = bootstrap.preprocessors;
      bootstrap.preprocessors = [
        jasmine.createSpy(),
        jasmine.createSpy()
      ];

      bootstrap(config);
      expect(bootstrap.preprocessors[0]).toHaveBeenCalled();
      expect(bootstrap.preprocessors[1]).toHaveBeenCalled();

      bootstrap.preprocessors = originalPreprocessors;
    });
  });
});

define([
  'client/client_bootstrap',
  'client/controllers/dashboard'
],
function (bootstrap, DashboardController) {
  describe('client bootstrap', function () {

    var config;
    beforeEach(function () {
      spyOn(DashboardController.prototype, 'render');
      config = {
        'page-type': 'dashboard'
      };
    });

    it('instantiates a controller from config data', function () {
      var controller = bootstrap(config);

      expect(controller instanceof DashboardController).toBe(true);
      expect(controller.render).toHaveBeenCalled();
    });

    it('executes page preprocessors', function () {
      var originalPreprocessors = bootstrap.preprocessors;
      bootstrap.preprocessors = [
        jasmine.createSpy(),
        jasmine.createSpy()
      ];

      bootstrap(config);
      expect(bootstrap.preprocessors[0]).toHaveBeenCalled();
      expect(bootstrap.preprocessors[1]).toHaveBeenCalled();

      bootstrap.preprocessors = originalPreprocessors;
    });
  });
});

Fix target of dashboard controller tests


import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'

import * as c from './constants'
import * as auth from './auth'

function receiveTodos (state = [], action) {
  switch (action.type) {
    case c.RECEIVE_TODO_LIST:
      return action.data
    case c.RECEIVE_TODO:
      let existingItem = false
      let newState =
        state.map(function (todo) {
          if (todo.id === action.data.id) {
            existingItem = true
            return action.data
          } else {
            return todo
          }
        })
      if (!existingItem) {
        return state.concat(action.data)
      }
      return newState
    default:
      return state
  }
}

const filterReducer = (state = 'active', { type, data }) => {
  if (type === c.SET_FILTER) {
    return data
  }
  return state
}

const notifyReducer = (state = null, { type, data }) => {
  if (type === c.NOTIFY_SET) {
    return data
  } else if (type === c.NOTIFY_DISMISS) {
    return null
  }
  return state
}

const rootReducer = combineReducers({
  user: auth.userReducer,
  filter: filterReducer,
  routing: routerReducer,
  todos: receiveTodos,
  notification: notifyReducer
})

export default rootReducer

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'

import * as c from './constants'
import * as auth from './auth'

function receiveTodos (state = [], action) {
  switch (action.type) {
    case c.RECEIVE_TODO_LIST:
      return action.data
    case c.RECEIVE_TODO:
      let existingItem = false
      let newState =
        state.map(function (todo) {
          if (todo.id === action.data.id) {
            existingItem = true
            return action.data
          } else {
            return todo
          }
        })
      if (!existingItem) {
        return state.concat(action.data)
      }
      return newState
    default:
      return state
  }
}

const filterReducer = (state = 'active', { type, data }) => {
  if (type === c.SET_FILTER) {
    return data
  }
  return state
}

const notifyReducer = (state = null, { type, data }) => {
  if (type === c.NOTIFY_SET) {
    return data
  } else if (type === c.NOTIFY_DISMISS) {
    return null
  }
  return state
}

const appReducer = combineReducers({
  user: auth.userReducer,
  filter: filterReducer,
  routing: routerReducer,
  todos: receiveTodos,
  notification: notifyReducer
})

const rootReducer = (state, action) => {
  // Reset redux state if the user logged out.
  //
  // This state reset is required.  Otherwise logging in as user X, logging
  // out and logging in as user Y will show user Y data from the previously
  // logged in user X.
  if (action.type === auth.USER_LOGGED_OUT) {
    state = undefined
  }
  return appReducer(state, action)
}

export default rootReducer

Reset redux state on log out


(function construct() {
  'use strict';

  angular.module('OMDBApp')
    .directive('navbarTop', function() {
      return {
      templateUrl: 'app/components/navbar-top/navbar-top.html',
      link: link,
      controller: controller,
      controllerAs: 'navbar_top_vm'
    }
  })

  function link ($scope, $element) {
    angular.element($element).find('.navbar-nav li').click(function(){
      angular.element(this).addClass('active');
      angular.element(this).parent().children('li').not(this).removeClass('active');
    });
  }

  /** @ngInject */
  function controller ($log, $translate, $state, AVALIABLE_LANGUAGES, LANGUAGES_TRANSLATION_KEYS) {
    $log.info('NavBarController initialized on date: %s', new Date().toISOString());
    var vm = this;
    vm.avaliableLanguages = AVALIABLE_LANGUAGES;
    vm.mapLanguageTranslationByKey = LANGUAGES_TRANSLATION_KEYS;
    vm.switchLanguage = switchLanguage;

    function switchLanguage (language) {
      $translate.use(language);
      return $state.reload();
    }
  }

})();

(function construct() {
  'use strict';

  angular.module('OMDBApp')
    .directive('navbarTop', navbarTopDirective);

  /** @ngInject */
  function navbarTopDirective ($window) {
    return {
      templateUrl: 'app/components/navbar-top/navbar-top.html',
      link: link($window),
      controller: controller,
      controllerAs: 'navbar_top_vm'
    };
  }

  /** @ngInject */
  function link ($window) {
    return function ($scope, $element) {
      var pageUrl = $window.location.href.substr($window.location.href.lastIndexOf('/')+1)
      var $ = angular.element($element)
      $.find('.navbar-nav li').click(function(){
        angular.element(this).addClass('active');
        angular.element(this).parent().children('li').not(this).removeClass('active');
      });
      $.find('.navbar-nav li a').each(function () {
        var menuItem = angular.element(this);
        if (menuItem.attr('href').indexOf(pageUrl) !== -1) {
          return menuItem.click();
        }
      })
    }
  }

  /** @ngInject */
  function controller ($log, $translate, $state, AVALIABLE_LANGUAGES, LANGUAGES_TRANSLATION_KEYS) {
    $log.info('NavBarController initialized on date: %s', new Date().toISOString());
    var vm = this;
    vm.avaliableLanguages = AVALIABLE_LANGUAGES;
    vm.mapLanguageTranslationByKey = LANGUAGES_TRANSLATION_KEYS;
    vm.switchLanguage = switchLanguage;

    function switchLanguage (language) {
      $translate.use(language);
      return $state.reload();
    }
  }

})();

Refactor navbar top to setup menu active item by url


Package.describe({
  name: 'angular-scss-compiler',
  version: '0.3.3',
  summary: 'Angular Scss Compiler Package',
  git: 'https://github.com/Urigo/angular-meteor/tree/master/atmosphere-packages/angular-scss-compiler',
  documentation: null
});

Npm.depends({
  'node-sass': '4.9.2'
});

Package.onUse(function (api) {
  api.versionsFrom('1.6');
  api.use([
    'ecmascript'
  ], 'server');
  api.mainModule('index.js', 'server');
});

Package.describe({
  name: 'angular-scss-compiler',
  version: '0.3.3',
  summary: 'Angular Scss Compiler Package',
  git: 'https://github.com/Urigo/angular-meteor/tree/master/atmosphere-packages/angular-scss-compiler',
  documentation: null
});

Npm.depends({
  'node-sass': '4.10.0'
});

Package.onUse(function (api) {
  api.versionsFrom('1.6');
  api.use([
    'ecmascript'
  ], 'server');
  api.mainModule('index.js', 'server');
});

Update dependency node-sass to v4.10.0


module.exports = {
    "sourceMaps": true,
    "presets": [
        ["@babel/preset-env", {
            "targets": [
                "last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions"
            ],
        }],
        "@babel/preset-typescript",
        "@babel/preset-flow",
        "@babel/preset-react"
    ],
    "plugins": [
        ["@babel/plugin-proposal-decorators", {decoratorsBeforeExport: true}],
        "@babel/plugin-proposal-export-default-from",
        "@babel/plugin-proposal-numeric-separator",
        "@babel/plugin-proposal-class-properties",
        "@babel/plugin-proposal-object-rest-spread",
        "@babel/plugin-transform-flow-comments",
        "@babel/plugin-syntax-dynamic-import",
        "@babel/plugin-transform-runtime"
    ]
};

module.exports = {
    "sourceMaps": true,
    "presets": [
        ["@babel/preset-env", {
            "targets": [
                "last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions"
            ],
        }],
        "@babel/preset-typescript",
        "@babel/preset-flow",
        "@babel/preset-react"
    ],
    "plugins": [
        ["@babel/plugin-proposal-decorators", {legacy: true}],
        "@babel/plugin-proposal-export-default-from",
        "@babel/plugin-proposal-numeric-separator",
        "@babel/plugin-proposal-class-properties",
        "@babel/plugin-proposal-object-rest-spread",
        "@babel/plugin-transform-flow-comments",
        "@babel/plugin-syntax-dynamic-import",
        "@babel/plugin-transform-runtime"
    ]
};

Switch back to legacy decorators


import Emitter from '../emitter'

import { get, inherit } from '../utils'

import { getKeyPaths, getKeyStrings } from '../key-path'

export default function Query(id, keys) {
  Emitter.call(this)

  this.id = id
  this.keyPaths = getKeyPaths(keys)
}

Query.getId = function(keyPaths) {
  return 'query:' + getKeyStrings(getKeyPaths(keyPaths))
}

inherit(Query, Emitter, {
  extract(state) {
    let length = this.keyPaths.length
    let values = Array(length)

    for (var i = 0; i < length; i++) {
      values[i] = get(state, this.keyPaths[i])
    }

    return values
  },

  trigger(state) {
    let values = this.extract(state)

    this._emit('change', ...values)
  },

  isAlone() {
    return this._events.length <= 0
  }
})

import Emitter from '../emitter'
import { get } from '../utils'
import { getKeyPaths, getKeyStrings } from '../key-path'

/**
 * @fileoverview Leaf nodes of the comparison tree are queries. A
 * grouping of data subscriptions.
 */
class Query extends Emitter {
  static getId(keyPaths) {
    return 'query:' + getKeyStrings(getKeyPaths(keyPaths))
  }

  constructor(id, keys) {
    super()

    this.id = id
    this.keyPaths = getKeyPaths(keys)
  }

  extract(state) {
    let length = this.keyPaths.length
    let values = Array(length)

    for (var i = 0; i < length; i++) {
      values[i] = get(state, this.keyPaths[i])
    }

    return values
  }

  trigger(state) {
    let values = this.extract(state)

    this._emit('change', ...values)
  }

  isAlone() {
    return this._events.length <= 0
  }
}

export default Query

Convert CompareTree Query into an ES6 class


'use strict';

/**
* Typed array constructor which returns a typed array representing an array of 8-bit unsigned integers in the platform byte order.
*
* @module @stdlib/array/uint8
*
* @example
* var ctor = require( '@stdlib/array/uint8' );
*
* var arr = new ctor( 10 );
* // returns <Uint8Array>
*/

// MODULES //

var hasUint8ArraySupport = require( '@stdlib/utils/detect-uint8array-support' );

// MAIN //

var ctor;
if ( hasUint8ArraySupport() ) {
	ctor = require( './uint8array.js' );
} else {
	ctor = require( './polyfill.js' );
}

// EXPORTS //

module.exports = ctor;

'use strict';

/**
* Typed array constructor which returns a typed array representing an array of 8-bit unsigned integers in the platform byte order.
*
* @module @stdlib/array/uint8
*
* @example
* var ctor = require( '@stdlib/array/uint8' );
*
* var arr = new ctor( 10 );
* // returns <Uint8Array>
*/

// MODULES //

var hasUint8ArraySupport = require( '@stdlib/utils/detect-uint8array-support' );
var builtin = require( './uint8array.js' );
var polyfill = require( './polyfill.js' );

// MAIN //

var ctor;
if ( hasUint8ArraySupport() ) {
	ctor = builtin;
} else {
	ctor = polyfill;
}

// EXPORTS //

module.exports = ctor;

Refactor to avoid dynamic module resolution


import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchPost } from '../actions';

class PostsShow extends Component {
  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.fetchPost(id);
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return
Loading...
;
    }

    return (

{post.title}

Categories: {post.categories}

{post.content}

    );
  }
}

function mapStateToProps({ posts }, ownProps) {
  return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost })(PostsShow);

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { fetchPost } from '../actions';

class PostsShow extends Component {
  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.fetchPost(id);
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return
Loading...
;
    }

    return (

        <Link to="/">Back To Index</Link>

{post.title}

Categories: {post.categories}

{post.content}

    );
  }
}

function mapStateToProps({ posts }, ownProps) {
  return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost })(PostsShow);

Add link to go back to index


var express = require('express');
var router = express.Router();

// Lấy danh sách events
var eventController = require('../../controllers/api/EventController');
router.route('/events').get(eventController.getEventForClient);

// Lấy danh sách award của eventController
var awardController = require('../../controllers/api/AwardController');
router.route('/events/:event_id/awards').get(awardController.getAllOfEventClient);

// Lấy danh sach locations
var locationController = require('../../controllers/api/LocationController');
router.route('/locations').get(locationController.getLocationForClient);

module.exports = router;

var express = require('express');
var router = express.Router();

// Lấy danh sách events
var eventController = require('../../controllers/api/EventController');
router.route('/events').get(eventController.getEventForClient);

// Lấy danh sách award của eventController
var awardController = require('../../controllers/api/AwardController');
router.route('/events/:event_id/awards').get(awardController.getAllOfEventClient);

var taskController = require('../../controllers/api/TaskController');
router.route('/events/:event_id/awards').get(taskController.getAllOfEvent);

// Lấy danh sach locations
var locationController = require('../../controllers/api/LocationController');
router.route('/locations').get(locationController.getLocationForClient);

module.exports = router;

Add router get all tasks


var base = require('./base.js');

exports.assemble = {
    addSchedule:
        function (parameters) {
            var userEventEntry = {
                availability: JSON.stringify(parameters.availability),
                Users_id: parameters.usersid,
                Events_id: parameters.eventsid
            };

            base.dbInsert('userevents', userEventEntry);

            return JSON.stringify({
                msgType: 'updateSchedule',
                status: 'complete'
            });
        },
   viewUser:
        function (parameters) {
            var userReadInfo = {
                Users_id: parameters.usersid
            };

            base.dbSelect('assemble' , 'users' , userReadInfo);

            return JSON.stringify({
                msgType: 'readuser',
                status: 'read'
            });

        };

var base = require('./base.js');

exports.assemble = {
    addSchedule:
        function (parameters) {
            var userEventEntry = {
                availability: JSON.stringify(parameters.availability),
                Users_id: parameters.usersid,
                Events_id: parameters.eventsid
            };

            base.dbInsert('userevents', userEventEntry);

            return JSON.stringify({
                msgType: 'updateSchedule',
                status: 'complete'
            });
        },
   viewUser:
        function (parameters) {
            var userReadInfo = {
                Users_id: parameters.usersid
            };

            response = base.dbSelect('assemble' , 'users' , userReadInfo);

            return JSON.stringify({
                msgType: 'readuser',
                data: response,
                status: 'read'
            });

        };

Add data: response to be manipulated in front end