var commandAndEvents = require('./command-and-events'),
    actions          = require('../static/actions/rgb-led.json'),
    system           = commandAndEvents.create(actions);

module.exports.create = commandAndEvents.create(actions, 'rgb-led');

var commandAndEvents = require('./command-and-events'),
    actions          = require('../static/actions/rgb-led.json'),
    system           = commandAndEvents.create(actions);

module.exports = commandAndEvents.create(actions, 'rgb-led');

Fix export of RGBLED command object


"use strict";

var redis = require('redis');

class redisWrapper {
	constructor(options, readyCallback) {
		this.conString = options.connectionString;
		this.redis = redis.createClient(this.conString);
	}

	insertClient(clientInfo, batchId) {
		// For the current redis use case, we don't care about client sightings -
		// only account sightings, since they have the juice that we want to send
		// to the visualiser
	}

	insertAccount(accountInfo, batchId) {
	    this.redis.publish("steam-update", JSON.stringify({
			steamid: accountInfo.steamId,
			gameid: accountInfo.gameid,
			gamename: accountInfo.gameextrainfo
	    }));
	}
}

module.exports = redisWrapper;

"use strict";

var redis = require('redis');

class redisWrapper {
	constructor(options, readyCallback) {
		this.conString = options.connectionString;
		this.redis = redis.createClient(this.conString);
	}

	insertClient(clientInfo, batchId) {
		// For the current redis use case, we don't care about client sightings -
		// only account sightings, since they have the juice that we want to send
		// to the visualiser
	}

	insertAccount(accountInfo, batchId) {
	    this.redis.publish("steam-update", JSON.stringify({
			steamid: accountInfo.steamid,
			gameid: accountInfo.gameid,
			gamename: accountInfo.gameextrainfo
	    }));
	}
}

module.exports = redisWrapper;

Update case of vars to match steam API


// NOVA JavaScript
// Author: shadowfacts
$(document).ready(function() {
	$(".nova-use-id").each(function (i) {
		$(this).text(i + 1);
	})

	$('.nova-slider').slick({
		centerMode: true,
		centerPadding: '60px',
		slidesToShow: 3,
		autoplay: true,
		autplaySpeed: 8000,
		appendArrows: '.nova-slider-controls',
		prevArrow: 'Previous',
		nextArrow: 'Next',
		responsive: [
			{
				breakpoint: 768,
				settings: {
					arrows: false,
					centerMode: true,
					centerPadding: '40px',
					slidesToShow: 3
				}
			},
			{
				breakpoint: 480,
				settings: {
					arrows: false,
					centerMode: true,
					centerPadding: '40px',
					slidesToShow: 3
				}
			}
		]
	});
});

// NOVA JavaScript
// Author: shadowfacts
$(document).ready(function() {
	$(".nova-use-id").each(function (i) {
		$(this).text(i + 1);
	})

	$('.nova-slider').slick({
		centerMode: true,
		centerPadding: '60px',
		slidesToShow: 3,
		autoplay: true,
		autplaySpeed: 8000,
		appendArrows: '.nova-slider-controls',
		prevArrow: 'Previous',
		nextArrow: 'Next',
		responsive: [
			{
				breakpoint: 768,
				settings: {
					arrows: false,
					centerMode: true,
					centerPadding: '40px',
					slidesToShow: 3
					slidesToScroll: 1
				}
			},
			{
				breakpoint: 480,
				settings: {
					arrows: false,
					centerMode: true,
					centerPadding: '40px',
					slidesToShow: 3
					slidesToScroll: 1
				}
			}
		]
	});
});

Fix responsive shit for the carousel


var MutationTable = function ()
{
    var element

    function detailFormatter(index, row, element)
    {
        var impact = row[4]
        var affected_sites_count = row[5]
        html = 'Impact: ' + impact + '
'
        html += '# of affected sites: ' + affected_sites_count + '
'
        if(affected_sites_count != 0)
        {
            html += 'Closest affected site(s):
' + row[6] + '
'
        }
        if(impact == 'network-rewiring')
        {
            var row_element = $('#' + row[0] + row[2])
            var meta = JSON.parse($(row_element).data('metadata').slice(2, -2).replace(/'/g, '"'))
            html += MIMP_image_from_meta(meta.MIMP)
        }
        return html
    }

    function getMutationRow(mutation_id)
    {
        return $('#' + mutation_id)
    }

    var publicSpace = {
        init: function(table_element)
        {
            element = table_element
            element.bootstrapTable({
                detailFormatter: detailFormatter
            })
        },
        expandRow: function(mutation_id)
        {
            element.bootstrapTable(
                'expandRow',
                getMutationRow(mutation_id).data('index')
            )
        }
    }

    return publicSpace
}

var MutationTable = function ()
{
    var element

    function detailFormatter(index, row, element)
    {
        var impact = row[4]
        var affected_sites_count = row[5]
        html = 'Impact: ' + impact + '
'
        html += '# of affected sites: ' + affected_sites_count + '
'
        if(affected_sites_count != 0)
        {
            html += 'Closest affected site(s):
' + row[6] + '
'
        }
        if(impact == 'network-rewiring')
        {
            var row_element = $('#' + row[0] + row[2])
            var meta = JSON.parse($(row_element).data('metadata').slice(2, -2).replace(/'/g, '"'))
            html += MIMP_image_from_meta(meta.MIMP)
        }
        return html
    }

    function getMutationRow(mutation_id)
    {
        return $('#' + mutation_id)
    }

    var publicSpace = {
        init: function(table_element)
        {
            element = table_element
            element.bootstrapTable({
                detailFormatter: detailFormatter
            })
            if(window.location.hash)
            {
                publicSpace.expandRow(window.location.hash.substring(1))
            }
        },
        expandRow: function(mutation_id)
        {
            element.bootstrapTable(
                'expandRow',
                getMutationRow(mutation_id).data('index')
            )
        }
    }

    return publicSpace
}

Expand selected mutation's row on load


(function (window) {

    'use strict';

    var $ = window.jQuery;
    var Modernizr = window.Modernizr;
    var moment = window.moment;

    function renderMoment() {
        $('.moment').text(moment().format('YYYY-MM-DD HH:mm:ss'));
        setTimeout(renderMoment, 1000);
    }

    renderMoment();

    if (Modernizr.localstorage) {
        $('.localstorage-support').text('Your browser supports localStorage!');
    }
    if (Modernizr.history) {
        $('.history-support').text('Your browser supports History API!');
    }
    if (Modernizr.touch) {
        $('.touch-support').text('Your browser supports Touch Events!');
    }

}(window));

Fix indentation of JS file


const h = require('virtual-dom/h');

module.exports = function (data) {
  return h('div', {className: 'new-player'}, [
    h('form', {method: 'post', action: '/new-player/' + data}, [
      h('label', [
        'Enter your name:',
        h('input', {type: 'text', name: 'name'})
      ]),
      h('button', {type: 'submit'}, 'Join Game!')
    ])
  ]);
};

const h = require('virtual-dom/h');

module.exports = function (data) {
  return h('div', {className: 'new-player'}, [
    h('form', {method: 'post', action: '/new-player/' + data.gameID}, [
      h('label', [
        'Enter your name:',
        h('input', {type: 'text', name: 'name'})
      ]),
      h('button', {type: 'submit'}, 'Join Game!')
    ])
  ]);
};

Use object instead of string


import expect from 'expect'
import React from 'react'
import {render, unmountComponentAtNode} from 'react-dom'

import Zeitline from 'src/'

describe('Zeitline', () => {
  let node

  beforeEach(() => {
    node = document.createElement('div')
  })

  afterEach(() => {
    unmountComponentAtNode(node)
  })

  it('have a svg node', () => {
    render(<Zeitline/>, node, () => {
      expect(node.innerHTML).toContain('svg')
    })
  })
})

import expect from 'expect'
import React from 'react'
import {render, unmountComponentAtNode} from 'react-dom'

import Zeitline from 'src/'

describe('Zeitline', () => {
  let node

  beforeEach(() => {
    node = document.createElement('div')
  })

  afterEach(() => {
    unmountComponentAtNode(node)
  })

  it('have a svg node', () => {
    render(<Zeitline/>, node, () => {
      expect(node.innerHTML).toContain('svg')
    })
  })

  it('have two events', () => {
    render(<Zeitline data={[
      {date: new Date('30 Jun 2017'), label: 'first'},
      {date: new Date('10 Jul 2017'), label: 'second'},
    ]}/>, node, () => {
      expect(node.querySelectorAll('.event-group').length).toEqual(2)
    })
  })

  it('have no more svg node', () => {
    render(<Zeitline/>, node, () => {
      unmountComponentAtNode(node);
      expect(node.innerHTML).toEqual('')
    })
  })
})

Test unmount and data events


import Service, { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
import RSVP from 'rsvp';

export default Service.extend({
  session: service('session'),
  store: service(),

  load() {
    let userId = this.get('session.data.authenticated.profile.barberscore_id');
    if (!isEmpty(userId)) {
      return this.get('store').findRecord('user', userId).catch(err => {
        alert(err.errors[0].detail)
        return RSVP.resolve()
      }).then((user) => {
        return this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

import Service, { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
import RSVP from 'rsvp';

export default Service.extend({
  session: service('session'),
  store: service(),

  load() {
    let accountId = this.get('session.data.authenticated.profile.sub');
    if (!isEmpty(accountId)) {
      return this.get('store').query('user', {
        'account_id': accountId,
      }).then(function(users) {
        return users.get('firstObject');
      }).catch(err => {
        alert(err.errors[0].detail)
        return RSVP.resolve()
      }).then((user) => {
        return this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

Update Current user dialog to access sub


import * as React from "react";

/**
 * Container Component for BuildSnapshots.
 *
 * @param {*} props input property containing an array of build data to be
 * rendered through BuildSnapshot.
 */
export const BuildSnapshotContainer = (props) => {
    return (
        <div>
            snapshot container.
        </div>
    )
}

import * as React from "react";

/**
 * Container Component for BuildSnapshots.
 *
 * @param {*} props input property containing an array of build data to be
 * rendered through BuildSnapshot.
 */
export const BuildSnapshotContainer = (props) => {
    return (
        <div>
            snapshot container.
        </div>
    );
}

Add semi-colon at end of return statement


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

import { add1Action } from './actions';
import styles from './styles';
import Random from './components/Random';

class Home extends Component {
  static contextTypes = {
    store: PropTypes.object,
  };
  handlePress = () => {
    const {
      dispatch,
    } = this.context.store;
    const action = add1Action(50);
    if (action) {
      dispatch(action);
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.*.js
        </Text>
        <Random />
        <Button onPress={this.handlePress}>Dispatch worker action</Button>
      </View>
    );
  }
}

export default Home;

import React, {
  Component,
  PropTypes,
} from 'react';
import {
  TouchableHighlight,
  View,
  Text,
} from 'react-native';

import { add1Action } from './actions';
import styles from './styles';
import Random from './components/Random';

class Home extends Component {
  static contextTypes = {
    store: PropTypes.object,
  };
  handlePress = () => {
    const {
      dispatch,
    } = this.context.store;
    const action = add1Action(50);
    if (action) {
      dispatch(action);
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.*.js
        </Text>
        <Random />
        <TouchableHighlight onPress={this.handlePress}>
          <Text>{'Dispatch worker action'}</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

export default Home;

Switch to more visible touchablehighlight


/* eslint babel/semi: "error" */
export AttachmentsController from './controllers/api/v1/AttachmentsController';
export BookmarkletController from './controllers/api/v1/BookmarkletController';
export CommentsController from './controllers/api/v1/CommentsController';
export FeedFactoriesController from './controllers/api/v1/FeedFactoriesController';
export GroupsController from './controllers/api/v1/GroupsController';
export PasswordsController from './controllers/api/v1/PasswordsController';
export PostsController from './controllers/api/v1/PostsController';
export SessionController from './controllers/api/v1/SessionController';
export UsersController from './controllers/api/v1/UsersController';

export GroupsControllerV2 from './controllers/api/v2/GroupsController';
export RequestsControllerV2 from './controllers/api/v2/RequestsController';
export UsersControllerV2 from './controllers/api/v2/UsersController';
export StatsControllerV2 from './controllers/api/v2/StatsController';
export ArchivesStatsControllerV2 from './controllers/api/v2/ArchivesStatsController';
export SearchController from './controllers/api/v2/SearchController';
export EventsController from './controllers/api/v2/EventsController';
export CommentLikesController from './controllers/api/v2/CommentLikesController';

/* eslint babel/semi: "error" */
export AttachmentsController from './controllers/api/v1/AttachmentsController';
export CommentsController from './controllers/api/v1/CommentsController';
export FeedFactoriesController from './controllers/api/v1/FeedFactoriesController';
export GroupsController from './controllers/api/v1/GroupsController';
export PasswordsController from './controllers/api/v1/PasswordsController';
export PostsController from './controllers/api/v1/PostsController';
export SessionController from './controllers/api/v1/SessionController';
export UsersController from './controllers/api/v1/UsersController';

export GroupsControllerV2 from './controllers/api/v2/GroupsController';
export RequestsControllerV2 from './controllers/api/v2/RequestsController';
export UsersControllerV2 from './controllers/api/v2/UsersController';
export StatsControllerV2 from './controllers/api/v2/StatsController';
export ArchivesStatsControllerV2 from './controllers/api/v2/ArchivesStatsController';
export SearchController from './controllers/api/v2/SearchController';
export EventsController from './controllers/api/v2/EventsController';
export CommentLikesController from './controllers/api/v2/CommentLikesController';

Remove unused export of BookmarkletController


import React from 'react';
import VideoListItem from './video_list_item';

const VideoList = (props) => {
    const videoItems = props.videos.map((video) => {
        return <VideoListItem video = { video }/>
    });

    return (
        <ul className="col-md-4 list-group">
            { videoItems }
        </ul>
    );
};

export default VideoList;

import React from 'react';
import VideoListItem from './video_list_item';

const VideoList = (props) => {

    // use .map instead of iterating through an array --> helper functions ES6
    const videoItems = props.videos.map((video) => {
        return <VideoListItem video = { video }/>
    });

    return (
        <ul className="col-md-4 list-group">
            { videoItems }
        </ul>
    );
};

export default VideoList;

Use map fnct v any helper fncts instead of any loops


import * as ExifParser from "exif-parser";
import Utils from "../Utils.js";

/**
 * Image operations.
 *
 * @author tlwr [toby@toby.codes]
 * @copyright Crown Copyright 2017
 * @license Apache-2.0
 *
 * @namespace
 */
const Image = {
    runEXIF(input, args) {
        try {
            let bytes = Uint8Array.from(input);
            let parser = ExifParser.create(bytes.buffer);
            let result = parser.parse();

            let lines = [];
            for (let tagName in result.tags) {
                let value = result.tags[tagName];
                lines.push(`${tagName}: ${value}`);
            }

            let numTags = lines.length;
            lines.unshift(`Found ${numTags} tags.\n`);
            return lines.join("\n");
        } catch (err) {
            throw "Could not extract EXIF data from image: " + err;
        }
    },
};

export default Image;

import * as ExifParser from "exif-parser";
import Utils from "../Utils.js";

/**
 * Image operations.
 *
 * @author tlwr [toby@toby.codes]
 * @copyright Crown Copyright 2017
 * @license Apache-2.0
 *
 * @namespace
 */
const Image = {
    runEXIF(input, args) {
        try {
            const bytes = Uint8Array.from(input);
            const parser = ExifParser.create(bytes.buffer);
            const result = parser.parse();

            let lines = [];
            for (let tagName in result.tags) {
                let value = result.tags[tagName];
                lines.push(`${tagName}: ${value}`);
            }

            const numTags = lines.length;
            lines.unshift(`Found ${numTags} tags.\n`);
            return lines.join("\n");
        } catch (err) {
            throw "Could not extract EXIF data from image: " + err;
        }
    },
};

export default Image;

Change let to const in "Extract EXIF"


const fs = require("fs")
const glob = require("glob")
const path = require("path")
const reactDocs = require("react-docgen")
const {toCode} = require("./utils")

module.exports = function () {
  const callback = this.async()
  const resource = this.request.split("!").pop()
  const directory = path.dirname(resource)

  glob(`${directory}/**/*[^.test].jsx`, (err, files) => {
    if (err) {
      return callback(err)
    }

    const docs = files.reduce((acc, file) => {
      const contents = fs.readFileSync(file, {encoding: "utf8"})
      const componentInfo = reactDocs.parse(contents)
      componentInfo.path = file
      componentInfo.module = `require('${file}')`
      acc.push(componentInfo)
      return acc
    }, [])

    return callback(null, `module.exports = ${toCode(docs)}`)
  })
}

const fs = require("fs")
const glob = require("glob")
const path = require("path")
const reactDocs = require("react-docgen")
const {toCode} = require("./utils")

module.exports = function () {
  const callback = this.async()
  const resource = this.request.split("!").pop()
  const directory = path.dirname(resource)

  glob(`${directory}/**/*[^.test].jsx`, (err, files) => {
    if (err) {
      return callback(err)
    }

    const docs = files.map((file) => {
      const contents = fs.readFileSync(file, {encoding: "utf8"})
      const componentInfo = reactDocs.parse(contents)
      componentInfo.path = file
      componentInfo.module = `require('${file}')`
      return componentInfo
    })

    return callback(null, `module.exports = ${toCode(docs)}`)
  })
}

Use `map` instead of `reduce`


orion.users.configure({
  // Allow users to create accounts, but don't give them any admin permissions
  forbidClientAccountCreation: false,
  defaultPermissions: ['files.upload', 'entity.dreams.personal', 'entity.recipes.personal', 'entity.activities.personal'],

  // Set home route path to root (user is redirected here after sign out)
  homeRoutePath: '/'
})

// Configure sign in route to use default sign in template (without this, the Orion Admin login template would be used)
AccountsTemplates.configureRoute('signIn');

orion.users.configure({
  // Allow users to create accounts, but don't give them any admin permissions
  forbidClientAccountCreation: false,
  defaultPermissions: ['files.upload', 'entity.dreams.personal', 'entity.recipes.personal', 'entity.activities.personal'],

  // Set home route path to root (user is redirected here after sign out)
  homeRoutePath: '/'
})

// Configure sign in route to use default sign in template (without this, the Orion Admin login template would be used)
AccountsTemplates.configureRoute('signIn', {

  // Unfortunately, AccountsTemplates routes are not added to the Router object before our manual routes in router.js, so we have to use a path that does not conflict with the slug routing for content pages defined there
  path: '/users/accounts/sign-in'
});

Fix routing conflict between sign-in and slug-based content pages


const isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
const event = isTouch ? 'touchstart' : 'click'

const directive = {
  instances: []
}

directive.onEvent = function (event) {
  directive.instances.forEach(({ el, fn }) => {
    if (event.target !== el && !el.contains(event.target)) {
      fn && fn(event)
    }
  })
}

directive.bind = function (el) {
  directive.instances.push({ el, fn: null })
  if (directive.instances.length === 1) {
    document.addEventListener(event, directive.onEvent)
  }
}

directive.update = function (el, binding) {
  if (typeof binding.value !== 'function') {
    throw new Error('Argument must be a function')
  }
  const instance = directive.instances.find(i => i.el === el)
  instance.fn = binding.value
}

directive.unbind = function (el) {
  const instanceIndex = directive.instances.findIndex(i => i.el === el)
  directive.instances.splice(instanceIndex, 1)
  if (directive.instances.length === 0) {
    document.removeEventListener(event, directive.onEvent)
  }
}

export default directive

const isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0))
const event = isTouch ? 'touchstart' : 'click'

const directive = {
  instances: []
}

directive.onEvent = function (event) {
  directive.instances.forEach(({ el, fn }) => {
    if (event.target !== el && !el.contains(event.target)) {
      fn && fn(event)
    }
  })
}

directive.bind = function (el) {
  directive.instances.push({ el, fn: null })
  if (directive.instances.length === 1) {
    document.addEventListener(event, directive.onEvent)
  }
}

directive.update = function (el, binding) {
  if (typeof binding.value !== 'function') {
    throw new Error('Argument must be a function')
  }
  const instance = directive.instances.find(i => i.el === el)
  instance.fn = binding.value
}

directive.unbind = function (el) {
  const instanceIndex = directive.instances.findIndex(i => i.el === el)
  directive.instances.splice(instanceIndex, 1)
  if (directive.instances.length === 0) {
    document.removeEventListener(event, directive.onEvent)
  }
}

export default directive

Remove semicolon to match lint guidelines


import { getDescription } from 'graphql/utilities/buildASTSchema';
import produceType from './produceType';

export const buildFieldConfigArgumentMap = (fieldAST, types) =>
  fieldAST.arguments.reduce((map, inputValueAST) => {
    const type = produceType(inputValueAST.type, types);
    const defaultValue = inputValueAST.defaultValue;
    const description = getDescription(inputValueAST);
    const argumentConfig = { type };
    if (defaultValue !== null) argumentConfig.defaultValue = type.parseLiteral(defaultValue);
    if (description) argumentConfig.description = description;
    return { ...map, [inputValueAST.name.value]: argumentConfig };
  }, {});

export default function buildFieldConfigMap(objectAST, configMap = {}, types) {
  return objectAST.fields.reduce((map, fieldAST) => {
    const name = fieldAST.name.value;
    const config = configMap[name] || {};
    const type = produceType(fieldAST.type, types);
    const args = buildFieldConfigArgumentMap(fieldAST, types);
    const description = getDescription(fieldAST);
    const fieldConfig = { type };
    if (Object.keys(args).length) fieldConfig.args = args;
    if ('resolve' in config) fieldConfig.resolve = config.resolve;
    if ('deprecationReason' in config) fieldConfig.deprecationReason = config.deprecationReason;
    if (description) fieldConfig.description = description;
    return { ...map, [name]: fieldConfig };
  }, {});
}

import { getDescription } from 'graphql/utilities/buildASTSchema';
import { getNamedType } from 'graphql/type';
import produceType from './produceType';

export const buildFieldConfigArgumentMap = (fieldAST, types) =>
  fieldAST.arguments.reduce((map, inputValueAST) => {
    const type = produceType(inputValueAST.type, types);
    const defaultValue = inputValueAST.defaultValue;
    const description = getDescription(inputValueAST);
    const argumentConfig = { type };
    if (defaultValue !== null) {
      argumentConfig.defaultValue = getNamedType(type).parseLiteral(defaultValue);
    }
    if (description) argumentConfig.description = description;
    return { ...map, [inputValueAST.name.value]: argumentConfig };
  }, {});

export default function buildFieldConfigMap(objectAST, configMap = {}, types) {
  return objectAST.fields.reduce((map, fieldAST) => {
    const name = fieldAST.name.value;
    const config = configMap[name] || {};
    const type = produceType(fieldAST.type, types);
    const args = buildFieldConfigArgumentMap(fieldAST, types);
    const description = getDescription(fieldAST);
    const fieldConfig = { type };
    if (Object.keys(args).length) fieldConfig.args = args;
    if ('resolve' in config) fieldConfig.resolve = config.resolve;
    if ('deprecationReason' in config) fieldConfig.deprecationReason = config.deprecationReason;
    if (description) fieldConfig.description = description;
    return { ...map, [name]: fieldConfig };
  }, {});
}

Fix enum literal value parsing


import React, { Component } from 'react'

//class-based component (ES6)
class SearchBar extends Component {
  render() { //method definition in ES6
    return <input onChange={this.onInputChange} />;
  }

  onInputChange(event) {
    console.log(event.target.value);
  }
}

export default SearchBar;

import React, { Component } from 'react'

//class-based component (ES6)
class SearchBar extends Component {
  render() { //method definition in ES6
    return <input onChange={event => console.log(event.target.value)} />;
  }

}

export default SearchBar;

Refactor to ES6 arrow functions to make things a bit more concise


#!/usr/bin/env node
const program = require('commander');
const pkg = require('../package.json');
// eslint-disable-next-line import/no-unresolved
const addCommands = require('../lib/commands');

// Begin command-line argument configuration
program
  .usage('[option | command]')
  .description('Each command has its own -h (--help) option.')
  .version(pkg.version, '-v, --version');

// Add all the commands
addCommands(program);

// Display help and exit if unknown arguments are provided
program.on('*', () => program.help());

// Initiate the parser
program.parse(process.argv);

// Display help and exit if no arguments are provided
if (!process.argv.slice(2).length) {
  program.help();
}

#!/usr/bin/env node
require('source-map-support/register');
const program = require('commander');
const pkg = require('../package.json');
// eslint-disable-next-line import/no-unresolved
const addCommands = require('../lib/commands');

// Begin command-line argument configuration
program
  .usage('[option | command]')
  .description('Each command has its own -h (--help) option.')
  .version(pkg.version, '-v, --version');

// Add all the commands
addCommands(program);

// Display help and exit if unknown arguments are provided
program.on('*', () => program.help());

// Initiate the parser
program.parse(process.argv);

// Display help and exit if no arguments are provided
if (!process.argv.slice(2).length) {
  program.help();
}

Enable source-map-support in entry point


const { isEmpty } = require('lodash')
const logger = require('../config/logger')

module.exports = (queryParam) => (req, res, next) => {
  const { features } = res.locals
  res.locals.isLayoutTesting = false
  const layoutTestingFeature = Object.keys(features).filter((feature) =>
    feature.includes('layoutTesting')
  )

  layoutTestingFeature.length > 1 &&
    logger.warn(
      'You can ONLY have one "layoutTesting" feature flag set at a time otherwise only the first one in the list will be used. Deactivate or remove one from Django admin.'
    )

  if (!isEmpty(layoutTestingFeature)) {
    const {
      dit_team: { id },
    } = res.locals.user
    const [featureFlag] = layoutTestingFeature
    const [, teamId] = featureFlag.split(':')
    res.locals.isLayoutTesting = teamId === id
    if (res.locals.isLayoutTesting && isEmpty(req.query)) {
      return res.redirect(`${req.originalUrl}?layoutTesting=${queryParam}`)
    }
    next()
  }
}

const { isEmpty } = require('lodash')
const logger = require('../config/logger')

module.exports = (queryParam) => (req, res, next) => {
  const { features } = res.locals
  res.locals.isLayoutTesting = false
  const layoutTestingFeature = Object.keys(features).filter((feature) =>
    feature.includes('layoutTesting')
  )

  layoutTestingFeature.length > 1 &&
    logger.warn(
      'You can ONLY have one "layoutTesting" feature flag set at a time otherwise only the first one in the list will be used. Deactivate or remove one from Django admin.'
    )

  if (!isEmpty(layoutTestingFeature)) {
    const {
      dit_team: { id },
    } = res.locals.user
    const [featureFlag] = layoutTestingFeature
    const [, teamId] = featureFlag.split(':')
    res.locals.isLayoutTesting = teamId === id
    if (res.locals.isLayoutTesting && isEmpty(req.query)) {
      return res.redirect(`${req.originalUrl}?layoutTesting=${queryParam}`)
    }
    next()
  } else {
    next()
  }
}

Replace missing callback from condition


Modify files in v7 static package.


const withPlugins = require('next-compose-plugins')
const optimizedImages = require('next-optimized-images')
const withCSS = require('@zeit/next-css')

const nextConfig = {
  target: 'serverless',
  exportPathMap: function() {
    return {
      '/': { page: '/' },
    }
  },
}
module.exports = withPlugins(
  [
    [withCSS, {}],
    [
      optimizedImages,
      {
        optimizeImagesInDev: true,
      },
    ],
  ],
  nextConfig,
)

const withPlugins = require('next-compose-plugins')
const optimizedImages = require('next-optimized-images')
const withCSS = require('@zeit/next-css')

const nextConfig = {
  target: 'server',
  exportPathMap: function() {
    return {
      '/': { page: '/' },
    }
  },
}
module.exports = withPlugins(
  [
    [withCSS, {}],
    [
      optimizedImages,
      {
        optimizeImagesInDev: true,
      },
    ],
  ],
  nextConfig,
)

Set next target to server


'use strict';

/**
 * Module dependencies
 */
import * as mongo from 'mongodb';
import User from '../../models/user';
import serialize from '../../serializers/user';

/**
 * Show a user
 *
 * @param {Object} params
 * @param {Object} reply
 * @param {Object} me
 * @return {void}
 */
module.exports = async (params, reply, me) =>
{
	// Init 'user_id' parameter
	let userId = params.user_id;
	if (userId === undefined || userId === null || userId === '') {
		userId = null;
	}

	// Init 'username' parameter
	let username = params.username;
	if (username === undefined || username === null || username === '') {
		username = null;
	}

	if (userId === null && username === null) {
		return reply(400, 'user_id or username is required', 'EMPTY_QUERY');
	}

	// Lookup user
	const user = userId !== null
		? await User.findOne({ _id: new mongo.ObjectID(userId) })
		: await User.findOne({ username });

	if (user === null) {
		return reply(404, 'user not found');
	}

	// Send response
	reply(await serialize(user, me));
};

'use strict';

/**
 * Module dependencies
 */
import * as mongo from 'mongodb';
import User from '../../models/user';
import serialize from '../../serializers/user';

/**
 * Show a user
 *
 * @param {Object} params
 * @param {Object} reply
 * @param {Object} me
 * @return {void}
 */
module.exports = async (params, reply, me) =>
{
	// Init 'id' parameter
	let userId = params.id;
	if (userId === undefined || userId === null || userId === '') {
		userId = null;
	}

	// Init 'username' parameter
	let username = params.username;
	if (username === undefined || username === null || username === '') {
		username = null;
	}

	if (userId === null && username === null) {
		return reply(400, 'id or username is required', 'EMPTY_QUERY');
	}

	// Lookup user
	const user = userId !== null
		? await User.findOne({ _id: new mongo.ObjectID(userId) })
		: await User.findOne({ username });

	if (user === null) {
		return reply(404, 'user not found');
	}

	// Send response
	reply(await serialize(user, me));
};

Rename user_id to id parameter


TC.control = TC.control || {};

if (!TC.control.TabContainer) {
    TC.syncLoadJS(TC.apiLocation + 'TC/control/TabContainer');
}

TC.control.DataLoader = function () {
    const self = this;

    TC.control.TabContainer.apply(self, arguments);

    self.controlOptions = [
        {
            name: 'externalWMS',
            title: 'addWMS',
            options: {
                suggestions: self.options.wmsSuggestions
            }
        },
        {
            name: 'fileImport',
            options: {
                enableDragAndDrop: self.options.enableDragAndDrop
            }
        }
    ];
    self.defaultSelection = 0;
};

TC.inherit(TC.control.DataLoader, TC.control.TabContainer);

(function () {
    var ctlProto = TC.control.DataLoader.prototype;

    ctlProto.register = function (map) {
        const self = this;
        self.title = self.getLocaleString('addMaps');
        return TC.control.TabContainer.prototype.register.call(self, map);
    };

})();

TC.control = TC.control || {};

if (!TC.control.TabContainer) {
    TC.syncLoadJS(TC.apiLocation + 'TC/control/TabContainer');
}

TC.control.DataLoader = function () {
    const self = this;

    TC.control.TabContainer.apply(self, arguments);

    self.controlOptions = [
        {
            name: 'externalWMS',
            title: 'addWMS',
            options: {
                suggestions: self.options.wmsSuggestions
            }
        },
        {
            name: 'fileImport',
            options: {
                enableDragAndDrop: self.options.enableDragAndDrop
            }
        }
    ];
    self.defaultSelection = 0;
};

TC.inherit(TC.control.DataLoader, TC.control.TabContainer);

(function () {
    const ctlProto = TC.control.DataLoader.prototype;

    ctlProto.register = function (map) {
        const self = this;
        self.title = self.getLocaleString('addMaps');
        return new Promise(function (resolve, reject) {
            TC.control.TabContainer.prototype.register.call(self, map).then(ctl => {
                ctl.div.classList.add(self.CLASS + '-datldr');
                resolve(ctl);
            });
        })
    };

})();

Add control specific CSS class


AutoForm.hooks({
  'guestbook--add_entry_form': {
    onSuccess: function (formType, result) {
      $.notify({
      	message: 'Thank you ! Your entry will be shown after the admin validated it.',
        icon: 'glyphicon glyphicon-warning-sign'
      },{
      	type: 'success'
      });
      Router.go('Guestbook');
    },
    onError: function (formType, error) {
      $.notify({
      	message: error.message,
        icon: 'glyphicon glyphicon-warning-sign'
      },{
      	type: 'danger'
      });
      Router.go('Guestbook');
    }
  }
});

AutoForm.hooks({
  'guestbook--add_entry_form': {
    onSuccess: function (formType, result) {
      $.notify({
      	message: 'Thank you ! Your entry will be shown after the admin validated it.',
        icon: 'glyphicons glyphicons-ok'
      },{
      	type: 'success'
      });
      Router.go('Guestbook');
    },
    onError: function (formType, error) {
      $.notify({
      	message: error.message,
        icon: 'glyphicon glyphicon-warning-sign'
      },{
      	type: 'danger'
      });
      Router.go('Guestbook');
    }
  }
});

Fix glyphicon to 'OK' and success.


const path = require("path");
const webpack = require("webpack");

module.exports = {
  resolve: {
    extensions: [".js"]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.(wsz|mp3)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              emitFile: true,
              name: "[path][name]-[hash].[ext]"
            }
          }
        ]
      }
    ],
    noParse: [/jszip\.js$/]
  },
  plugins: [
    new webpack.DefinePlugin({
      SENTRY_DSN: JSON.stringify(
        "https://c8c64ef822f54240901bc64f88c234d8@sentry.io/146022"
      )
    })
  ],
  entry: {
    winamp: ["./js/index.js"],
    skinExplorer: "./js/skinExplorer.js"
  },
  output: {
    filename: "[name].js",
    publicPath: "/built/",
    path: path.resolve(__dirname, "built")
  }
};

const path = require("path");
const webpack = require("webpack");

module.exports = {
  devtool: "source-map",
  resolve: {
    extensions: [".js"]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.(wsz|mp3)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              emitFile: true,
              name: "[path][name]-[hash].[ext]"
            }
          }
        ]
      }
    ],
    noParse: [/jszip\.js$/]
  },
  plugins: [
    new webpack.DefinePlugin({
      SENTRY_DSN: JSON.stringify(
        "https://c8c64ef822f54240901bc64f88c234d8@sentry.io/146022"
      )
    })
  ],
  entry: {
    winamp: ["./js/index.js"],
    skinExplorer: "./js/skinExplorer.js"
  },
  output: {
    filename: "[name].js",
    publicPath: "/built/",
    path: path.resolve(__dirname, "built")
  }
};

Add source maps in dev


const path = require('path');
const webpack = require('webpack');
const BabiliPlugin = require('babili-webpack-plugin');

const isProd = process.env.NODE_ENV === 'PRODUCTION';

const outputFilename = isProd ? 'react-layout-transition.min.js' : 'react-layout-transition.js';

module.exports = {
    devtool: !isProd ? 'source-map' : '',
    entry: path.resolve(__dirname, 'src/index.ts'),
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: outputFilename,
        library: 'ReactLayoutTransition',
        libraryTarget: 'umd',
    },
    externals: {
        'react': {
            commonjs: 'react',
            commonjs2: 'react',
            root: 'React',
        },
    },
    module: {
        rules: [
            {
                test: /\.tsx|ts?$/,
                loader: 'awesome-typescript-loader',
                exclude: path.resolve(__dirname, 'node_modules'),
            },
        ],
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    plugins: isProd ? [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production'),
        }),
        new BabiliPlugin({}, {
            removeComments: true,
        }),
    ] : [],
};

const path = require('path');
const webpack = require('webpack');
const MinifyPlugin = require("babel-minify-webpack-plugin");

const isProd = process.env.NODE_ENV === 'PRODUCTION';

const outputFilename = isProd ? 'react-layout-transition.min.js' : 'react-layout-transition.js';

module.exports = {
    devtool: !isProd ? 'source-map' : '',
    entry: path.resolve(__dirname, 'src/index.ts'),
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: outputFilename,
        library: 'ReactLayoutTransition',
        libraryTarget: 'umd',
    },
    externals: {
        'react': {
            commonjs: 'react',
            commonjs2: 'react',
            root: 'React',
        },
    },
    module: {
        rules: [
            {
                test: /\.tsx|ts?$/,
                loader: 'awesome-typescript-loader',
                exclude: path.resolve(__dirname, 'node_modules'),
            },
        ],
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    plugins: isProd ? [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production'),
        }),
        new MinifyPlugin({}, {
            removeComments: true,
        }),
    ] : [],
};

Change to minify-plugin from babili


import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

import styles from 'molecules/formfields/shared/formfields.module.scss';

function DateField(props) {
  const {
    className,
    children,
    label,
    focused
  } = props;

  const baseClassName = classnames(
    styles['datefield'],
    { [styles.focused]: focused },
    className
  );

  const childClassName = classnames(
    styles['datefield-input'],
    { [styles['datefield-input-focused']]: focused }
  );

  return (

      {label}

        { React.Children.map(children,
          child =>

              { child }

        )}

  );
}

DateField.propTypes = {
  /**
   * This prop will add a new className to any inherent classNames
   * provided in the component's index.js file.
   */
  className: PropTypes.string,
  /**
   * Label.
   */
  label: PropTypes.string,
  /**
   * Whether or not the date field is focused
   */
  focused: PropTypes.bool
};

export default DateField;

import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

import styles from 'molecules/formfields/shared/formfields.module.scss';

function DateField(props) {
  const {
    className,
    children,
    label,
    focused,
    error
  } = props;

  const baseClassName = classnames(
    styles['datefield'],
    { [styles.focused]: focused },
    { [styles.hasError]: !!error },
    className
  );

  const childClassName = classnames(
    styles['datefield-input'],
    { [styles['datefield-input-focused']]: focused }
  );

  return (

        {label}

          { React.Children.map(children,
            child =>

                { child }

          )}

      {error &&

{ error }

      }

  );
}

DateField.propTypes = {
  /**
   * This prop will add a new className to any inherent classNames
   * provided in the component's index.js file.
   */
  className: PropTypes.string,
  /**
   * Label.
   */
  label: PropTypes.string,
  /**
   * Whether or not the date field is focused
   */
  focused: PropTypes.bool,
  /**
   * Any errors for the date form
   */
  error: PropTypes.string
};

export default DateField;

Add error state to DateFieldw


'use strict';

angular.module('myApp.controllers', []).

  controller('ExBasicCtrl', [function() {
    // You were expecting maybe The Adams Family?
  }])

  // That's all folks
  ;

'use strict';

angular.module('myApp.controllers', [])

  // That's all folks
  ;

Remove extra junk from examples


/* Copyright 2011 the Melange authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Mario Ferraro
 */

(function() {
  var template_name = "survey_template";

  melange[template_name] = function(_self, context) {
  };

  melange[template_name].prototype = new melange.templates._baseTemplate();
  melange[template_name].prototype.constructor = melange[template_name];
  melange[template_name].apply(
    melange[template_name],
    [melange[template_name],melange[template_name].prototype.context]
  );
}());

/* Copyright 2011 the Melange authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Mario Ferraro
 */

(function() {
  var template_name = "survey";

  melange.template[template_name] = function(_self, context) {
  };

  melange.template[template_name].prototype = new melange.templates._baseTemplate();
  melange.template[template_name].prototype.constructor = melange.template[template_name];
  melange.template[template_name].apply(
    melange.template[template_name],
    [melange.template[template_name], melange.template[template_name].prototype.context]
  );
}());

Make the skeleton survey script use the new melange.template namespace.


/**
 * Bootstraps and starts the http server
 */

'use strict';

/**
 * Module dependencies
 * @private
 */
var connect = require('connect');
var http = require('http');
var morgan = require('morgan');
var qs = require('qs');

var parse = require('./parse');
var calculate = require('./calculate');

/**
 * Configure connect app and start http server
 */

module.exports = function() {
  var app = connect();

  // Log all incoming requests to the console
  app.use(morgan('common'));

  app.use('/calculate', function(req, res, next) {
    if(req.method === 'GET') {
      var params = qs.parse(req.url.substring(2));
      parse(params.expression, function(err, firstNumber, operator, secondNumber) {
        if(err) {
          res.statusCode = 422;
          return res.end(err);
        }

        var result = calculate(firstNumber, operator, secondNumber);
        res.end(result + '');
      });

    }
  });
  // Create server and listen on port 3000
  http.createServer(app).listen(3000);

  return app;
};

/**
 * Bootstraps and starts the http server
 */

'use strict';

/**
 * Module dependencies
 * @private
 */
var connect = require('connect');
var http = require('http');
var morgan = require('morgan');
var qs = require('qs');

var parse = require('./parse');
var calculate = require('./calculate');

/**
 * Configure connect app and start http server
 */

module.exports = function() {
  var app = connect();

  // Log all incoming requests to the console
  app.use(morgan('common'));

  app.use('/calculate', function(req, res) {
    if(req.method === 'GET') {
      var params = qs.parse(req.url.substring(2));
      parse(params.expression, function(err, firstNum, operator, secondNum) {
        if(err) {
          res.statusCode = 422;
          return res.end(err);
        }

        var result = calculate(firstNum, operator, secondNum);
        res.end(result + '');
      });

    }
  });
  // Create server and listen on port 3000
  http.createServer(app).listen(3000);

  return app;
};

Fix line too long error


<script>
const getUserRankAndScore = function() {
    const currentUserName = '{{ current_user.name }}' || null;
    let def = $.Deferred();
    $.ajax({
        url: '/leaderboard/',
        dataType: 'json',
        contentType: 'application/json',
        data: '{}'
    }).done(function(data) {
        for (let user of data.top_users) {
            if (user.name == currentUserName) {
                def.resolve([user.rank, user.score]);
            }
        }
        def.resolve(null);
    });
    return def;
}
</script>

<script>
const getUserRankAndScore = function() {
    const currentUserName = '{{ current_user.name }}' || null;
    let def = $.Deferred();
    $.ajax({
        url: '/leaderboard/',
        dataType: 'json',
        contentType: 'application/json',
        data: '{}'
    }).done(function(data) {
        for (let user of data.top_users) {
            if (user.name == currentUserName) {
                def.resolve({
                    rank: user.rank,
                    score: user.score
                });
            }
        }
        def.resolve(null);
    });
    return def;
}
</script>

Update user rank and score function


const program = require('commander')
const loadInit = require('./init')
const loadStart = require('./start')
const { spawnSync } = require('child_process')

module.exports = function startCli (server) {
  program.version(getVersion())

  loadInit(program)
  loadStart(program, server)

  program.parse(process.argv)
  if (program.args.length === 0) program.help()
}

function getVersion () {
  try {
    // Obtain version from git
    const options = { cwd: __dirname, encoding: 'utf8' }
    const { stdout } = spawnSync('git', ['describe', '--tags'], options)
    return stdout.trim()
  } catch (e) {
    // Obtain version from package.json
    const { version } = require('../package.json')
    return version
  }
}

const program = require('commander')
const loadInit = require('./init')
const loadStart = require('./start')
const { spawnSync } = require('child_process')
const path = require('path')

module.exports = function startCli (server) {
  program.version(getVersion())

  loadInit(program)
  loadStart(program, server)

  program.parse(process.argv)
  if (program.args.length === 0) program.help()
}

function getVersion () {
  try {
    // Obtain version from git
    const options = { cwd: __dirname, encoding: 'utf8' }
    const { stdout } = spawnSync('git', ['describe', '--tags'], options)
    return stdout.trim()
  } catch (e) {
    // Obtain version from package.json
    const { version } = require(path.join(__dirname, '../../package.json'))
    return version
  }
}

Fix require of package.json for global installs


var scripty = require('../../index')
var fs = require('fs')
var intercept = require('intercept-stdout')
var assert = require('assert')
var _ = require('lodash')

var stdout, stopIntercept
module.exports = {
  beforeEach: function () {
    stdout = ''
    stopIntercept = intercept(function (text) {
      stdout += text
    })
  },
  outputAndRunScript: function () {
    fs.writeFileSync('scripts/fake/helloworld',
      '#!/bin/bash\n' +
      'WORLD="World"\n' +
      'echo "Hello, $WORLD!"'
    )

    scripty('fake:helloworld')

    assert(_.includes(stdout, '> echo Hello, $WORLD!'), 'prints script')
    assert(_.includes(stdout, 'Hello, World!'), 'prints output')
  },
  afterEach: function () {
    stopIntercept()
  }
}

var scripty = require('../../index')
var fs = require('fs')
var intercept = require('intercept-stdout')
var assert = require('assert')
var _ = require('lodash')

var stdout, stderr, stopIntercept
module.exports = {
  beforeEach: function () {
    stdout = ''
    stderr = ''
    stopIntercept = intercept(function (text) {
      stdout += text
    }, function (text) {
      stderr += text
    })
  },
  outputAndRunScript: function () {
    fs.writeFileSync('scripts/fake/helloworld',
      '#!/bin/bash\n' +
      'WORLD="World"\n' +
      'echo "Hello, $WORLD!"'
    )

    scripty('fake:helloworld')

    assert(_.includes(stdout, '> echo Hello, $WORLD!'), 'prints script')
    assert(_.includes(stdout, 'Hello, World!'), 'prints output')
  },
  noScriptFound: function () {
    scripty('fake:noscriptfound')

    assert(_.includes(stderr,
      'Error: scripty - no script found for npm lifecycle "fake:noscriptfound"'
    ))
  },
  afterEach: function () {
    stopIntercept()
  }
}

Add a second integration test for the error case.


/*
  Created by 'myth' on July 3. 2015

  CognacTime is licenced under the MIT licence.
*/

var log = require('./logging')
var util = require('../client/util')

// Start by defining the container object
function iowrapper (io) {

  this.connections = []
  this.io = io

  io.on('connection', function (socket) {
    log.info('Client connected: ' + socket.id)

    io.emit('stats', { users: io.engine.clientsCount })

    socket.on('message', function (data) {
      log.info('Received message: ' + data)
    })

    socket.on('fetch', function (data) {
      log.info('Received query: ' + util.repr(data))
    })

    socket.on('disconnect', function () {
      log.info('Client disconnected: ' + socket.id)
    })
  })
}

module.exports = iowrapper

/*
  Created by 'myth' on July 3. 2015

  CognacTime is licenced under the MIT licence.
*/

var log = require('./logging')
var util = require('../client/util')

// Start by defining the container object
function iowrapper (io) {

  this.connections = []
  this.io = io

  io.on('connection', function (socket) {
    log.info('Client connected: ' + socket.id)

    io.emit('stats', { users: io.engine.clientsCount })

    socket.on('message', function (data) {
      log.info('Received message: ' + data)
    })

    socket.on('fetch', function (data) {
      log.info('Received query: ' + util.repr(data))
    })

    socket.on('disconnect', function () {
      log.info('Client disconnected: ' + socket.id)
      io.emit('stats', { users: io.engine.clientsCount })
    })
  })
}

module.exports = iowrapper

Add userstats emit to disconnect


(function () {
    angular
        .module('GVA.Common')
        .directive('truncatedText', truncatedText);

    truncatedText.$inject = ['$parse'];

    function truncatedText($parse) {

        function truncateText(text, limit) {

            var words = text.split(' ');

            var truncatedtext = words.reduce(function (prev, curr) {
                if (curr.length + prev.length >= limit) {
                    return prev;
                } else {
                    return prev + ' ' + curr;
                }
            });

            return truncatedtext;
        }

        function link(scope, element, attrs) {

            activate();

            function activate() {

                scope.maxChars = parseInt(scope.maxChars) || 160;
                scope.fullText = '';
                scope.truncatedText = '';

                scope.$watch('ngModel', function () {
                    scope.fullText = scope.ngModel;
                    scope.truncatedText = truncateText(scope.fullText, scope.maxChars);
                    scope.truncated = scope.fullText !== scope.truncatedText;
                });
            }
        }

        return {
            restrict: 'A',
            scope: {
                ngModel: '=',
                maxChars: '@',
            },
            link: link,
            template: '{{fullText}}' +
                      '{{truncatedText}}' +
                      '... Show More'
        };
    }
})();

(function () {
    angular
        .module('GVA.Common')
        .directive('truncatedText', truncatedText);

    truncatedText.$inject = ['$parse'];

    function truncatedText($parse) {

        function truncateText(text, limit) {

            var words = text.split(' ');

            var truncatedtext = words.reduce(function (prev, curr) {
                if (curr.length + prev.length >= limit) {
                    return prev;
                } else {
                    return prev + ' ' + curr;
                }
            });

            return truncatedtext;
        }

        function link(scope, element, attrs) {

            activate();

            function activate() {

                scope.maxChars = parseInt(scope.maxChars) || 160;
                scope.fullText = '';
                scope.truncatedText = '';

                scope.$watch('ngModel', function () {
                    scope.fullText = scope.ngModel;
                    if (scope.fullText) {
                        scope.truncatedText = truncateText(scope.fullText, scope.maxChars);
                        scope.truncated = scope.fullText !== scope.truncatedText;
                    } else {
                        scope.truncated = false;
                    }
                });
            }
        }

        return {
            restrict: 'A',
            scope: {
                ngModel: '=',
                maxChars: '@',
            },
            link: link,
            template: '{{fullText}}' +
                      '{{truncatedText}}' +
                      '... Show More'
        };
    }
})();

Fix for text truncation where null or undefined descriptions are used.


//setup connection
var client = new Client("demo_test_username", 'http://localhost', 8000);
client.addMessageListener(function(msg)
{
	//TODO Your code here!
	//message recieved
	console.log(JSON.stringify(msg));
});

client.addConnectListener(function(args)
{
	//TODO Your code here!
	//message recieved
	console.log('Client Connected.');
	document.getElementById("status").innerHTML = 'Connected to Server.';
	document.getElementById("status_img").src = 'images/green_circle.png';
});

client.addDisconnectListener(function(args)
{
	//TODO Your code here!
	//message recieved
	console.log('Client Disconnected.');
	document.getElementById("status").innerHTML = 'Disconnected.';
	document.getElementById("status_img").src = 'images/red_circle.png';
});

client.addErrorListener(function(err)
{
	//TODO Your code here!
	//message recieved
	console.log('Error!' + err);
});

//TODO Your code here!

//send a message demo
var message = new Message("hello");
message.addField('num1', 55);
message.addField('num2', 450);
message.deliverToSelf = true;
client.sendMessage(message);

//setup connection
var client = new Client("demo_test_username", 'http://localhost', 8000);
client.addMessageListener(function(msg)
{
	//TODO Your code here!
	//message recieved
	console.log(JSON.stringify(msg));
});

client.addConnectListener(function(args)
{
	//TODO Your code here!
	//connection established
	console.log('Client Connected.');
	document.getElementById("status").innerHTML = 'Connected to Server.';
	document.getElementById("status_img").src = 'images/green_circle.png';
});

client.addDisconnectListener(function(args)
{
	//TODO Your code here!
	//Disconnected event
	console.log('Client Disconnected.');
	document.getElementById("status").innerHTML = 'Disconnected.';
	document.getElementById("status_img").src = 'images/red_circle.png';
});

client.addErrorListener(function(err)
{
	//TODO Your code here!
	//Error recieved
	console.log('Error!' + err);
});

//TODO Your code here!

//send a message demo
var message = new Message("hello");
message.addField('num1', 55);
message.addField('num2', 450);
message.deliverToSelf = true;
client.sendMessage(message);

Update comments in event signatures


// DecentCMS (c) 2014 Bertrand Le Roy, under MIT. See LICENSE.txt for licensing details.
'use strict';

/**
 * @description
 * This handler registers itself as an Express middleware that
 * redirects all requests with a trailing slash.
 * This ensures that content items have a single URL.
 */
var PreventTrailingSlashRouteHandler = {
  service: 'middleware',
  feature: 'prevent-trailing-slash',
  routePriority: 0,
  scope: 'shell',
  register: function registerTrailingSlashMiddleware(scope, context) {
    context.expressApp.register(PreventTrailingSlashRouteHandler.routePriority, function bindTrailingSlashMiddleware(app) {
      app.get('*', function trailingSlashMiddleware(request, response, next) {
        var p = request.path;
        if (p.length > 1 && p[p.length - 1] === '/') {
          response.redirect(301, p.substr(0, p.length - 1));
        }
        next();
      });
    });
  }
};

module.exports = PreventTrailingSlashRouteHandler;

// DecentCMS (c) 2014 Bertrand Le Roy, under MIT. See LICENSE.txt for licensing details.
'use strict';

/**
 * @description
 * This handler registers itself as an Express middleware that
 * redirects all requests with a trailing slash.
 * This ensures that content items have a single URL.
 */
var PreventTrailingSlashRouteHandler = {
  service: 'middleware',
  feature: 'prevent-trailing-slash',
  routePriority: 0,
  scope: 'shell',
  register: function registerTrailingSlashMiddleware(scope, context) {
    context.expressApp.register(PreventTrailingSlashRouteHandler.routePriority, function bindTrailingSlashMiddleware(app) {
      app.get('*', function trailingSlashMiddleware(request, response, next) {
        var p = request.path;
        if (p.length > 1 && p[p.length - 1] === '/') {
          response.redirect(301, p.substr(0, p.length - 1));
          return;
        }
        next();
      });
    });
  }
};

module.exports = PreventTrailingSlashRouteHandler;

Stop processing after trailing slash handler has redirected.


module.exports = {
    getDetails:function(id,callback){
        callback({});
    },
    query:function(qo,callback){
        var query=qo.query,area=qo.area;
        let path = "/api/v2/search/?q="+encodeURIComponent(query);

        if(area){
            path += `latitude=${area.lat}&longitude=${area.lon}&distance=${area.distance}`;
        }

        https.get({
            path:path,
            hostname:"www.aliss.org",
            method:"GET",
            headers:{
                'Accept':'application/json'
            }
        },function(res){
            console.log('Status '+res.statusCode);
            console.log('Headers '+JSON.stringify(res.headers));
            let data='';
            res.on('data',function(chunk){
                data+=chunk;
            });
            res.on('end',function(){
                try{
                    callback(JSON.parse(data));
                }
                catch(err){
                    console.error('ALISS error: '+err);
                }
            });
        });
    }
};

module.exports = {
    getDetails:function(id,callback){
        callback({});
    },
    query:function(qo,callback){
        var query=qo.query,area=qo.area;
        let path = "/api/v2/search/?q="+encodeURIComponent(query);

        if(area){
            path += `&latitude=${area.lat}&longitude=${area.lon}&distance=${area.distance}`;
        }

        https.get({
            path:path,
            hostname:"www.aliss.org",
            method:"GET",
            headers:{
                'Accept':'application/json'
            }
        },function(res){
            console.log('Status '+res.statusCode);
            console.log('Headers '+JSON.stringify(res.headers));
            let data='';
            res.on('data',function(chunk){
                data+=chunk;
            });
            res.on('end',function(){
                try{
                    callback(JSON.parse(data));
                }
                catch(err){
                    console.error('ALISS error: '+err);
                }
            });
        });
    }
};

Add missing '&' to area query in Aliss


import { UIDatabase } from '../database';

/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

export const selectCurrentPrescriber = ({ prescriber }) => {
  const { currentPrescriber } = prescriber;
  return currentPrescriber;
};

export const selectPrescriberName = ({ prescriber }) => {
  const currentPrescriber = selectCurrentPrescriber({ prescriber });
  return `${currentPrescriber?.firstName} ${currentPrescriber?.lastName}`.trim();
};

export const selectSortedAndFilteredPrescribers = ({ prescriber }) => {
  const { searchTerm, sortKey, isAscending } = prescriber;

  const queryString = 'firstName CONTAINS[c] $0 OR lastName CONTAINS[c] $0';
  const newData = UIDatabase.objects('Prescriber')
    .filtered(queryString, searchTerm)
    .sorted(sortKey, isAscending);

  return newData;
};

Add Prescriber selector for fetching data


$(function () {
  $("#guess").click(function () {
    getCurrent(function (pos) {
      $.ajax({
        type: 'GET',
        url: '/bathrooms/nearby',
        data: {search: 'true', lat: pos.coords.latitude, long: pos.coords.longitude},
        success: function(data, textStatus) {
          $('#nearby').html(data);
        }
      });

      $('.currentLocationButton').removeClass('currentLocationButtonLocating');
      guessPosition(pos.coords, function (results) {
        if(results && results.length > 0){
          console.log(results);
          var addressArray = results[0].address_components;
          $("#bathroom_street").val(addressArray[0].long_name + " " + addressArray[1].long_name);
          $("#bathroom_city").val(addressArray[3].long_name);
          $("#bathroom_state").val(addressArray[5].long_name);
          $("#bathroom_country").find("option[value='" + addressArray[6].long_name + "'']").prop('selected', true);
          $("#bathroom_name").val(results[0].formatted_address);
        }
      });
    })
  });
});

$(function () {
  $("#guess").click(function () {
    getCurrent(function (pos) {
      $.ajax({
        type: 'GET',
        url: '/bathrooms/nearby',
        data: {search: 'true', lat: pos.coords.latitude, long: pos.coords.longitude},
        success: function(data, textStatus) {
          $('#nearby').html(data);
        }
      });

      $('.currentLocationButton').removeClass('currentLocationButtonLocating');
      guessPosition(pos.coords, function (results) {
        if(results && results.length > 0){
          var addressArray = results[0].address_components;
          $("#bathroom_street").val(addressArray[0].long_name + " " + addressArray[1].long_name);
          $("#bathroom_city").val(addressArray[3].long_name);
          $("#bathroom_state").val(addressArray[5].long_name);
          $("#bathroom_country").find("option[value='" + addressArray[6].long_name + "'']").prop('selected', true);
          $("#bathroom_name").val(results[0].formatted_address);
        }
      });
    })
  });
});

Remove logging statement of geocoding results


// Copies files not processed by requirejs optimization from source to dist so other tasks can process them
module.exports = {
  dist: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        '*.{ico,png,txt}',
        '.htaccess',
        '*.html',
        'bower_components/**/*',
        'views/alien4cloud-templates.js',
        'js-lib/**/*',
        'images/**/*',
        'scripts/**/*',
        'data/**/*',
        'api-doc/**/*',
        'version.json',
      ]
    }, {
      expand: true,
      cwd: '.tmp/images',
      dest: '<%= yeoman.dist %>/images',
      src: ['generated/*']
    }, {
      expand: true,
      flatten: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>/images',
      src: ['bower_components/angular-tree-control/images/*']
    }]
  },
  bower: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        'bower_components/es5-shim/es5-shim.min.js',
        'bower_components/json3/lib/json3.min.js',
        'bower_components/requirejs/require.js',
        'bower_components/font-awesome/**/*'
      ]
    }]
  }
};

// Copies files not processed by requirejs optimization from source to dist so other tasks can process them
module.exports = {
  dist: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        '*.{ico,png,txt}',
        '.htaccess',
        '*.html',
        'bower_components/**/*',
        'views/alien4cloud-templates.js',
        'js-lib/**/*',
        'images/**/*',
        'scripts/**/*',
        'data/**/*',
        'api-doc/**/*',
        'version.json',
      ]
    }, {
      expand: true,
      cwd: '.tmp/images',
      dest: '<%= yeoman.dist %>/images',
      src: ['generated/*']
    }, {
      expand: true,
      flatten: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>/images',
      src: ['bower_components/angular-tree-control/images/*']
    }]
  },
  bower: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        'bower_components/es5-shim/es5-shim.min.js',
        'bower_components/json3/lib/json3.min.js',
        'bower_components/requirejs/require.js',
        'bower_components/font-awesome/**/*',
        'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/**/*',
        'bower_components/roboto-fontface/**/*'
      ]
    }]
  }
};

Fix build to add back the roboto font and bootstrap fonts.


const browser     = require('browser-sync');
const config      = require('../../config');
const gulp        = require('gulp');
const handleError = require('../../utilities/handleError');
const path        = require('path');
const sass        = require('gulp-sass');
const sourcemaps  = require('gulp-sourcemaps');

/**
 * HyperBolts ϟ (https://hyperbolts.io)
 *
 * Copyright © 2015-present Pace IT Systems Ltd.
 * All rights reserved.
 *
 * @author  Pace IT Systems Ltd
 * @license MIT
 */

module.exports = paths => () => gulp.src(paths.src)

    // Compile
    .pipe(sourcemaps.init())
    .pipe(sass({
        includePaths: [
            path.join(process.cwd(), 'node_modules'),
            process.cwd()
        ]
    }))
        .on('error', handleError)
    .pipe(sourcemaps.write())

    // Output
    .pipe(gulp.dest(
        path.resolve(config.base, paths.dest)
    ))

    // Reload browser
    .pipe(browser.reload({
        stream: true
    }));

const browser     = require('browser-sync');
const config      = require('../../config');
const gulp        = require('gulp');
const handleError = require('../../utilities/handleError');
const path        = require('path');
const sass        = require('gulp-sass');
const sourcemaps  = require('gulp-sourcemaps');

/**
 * HyperBolts ϟ (https://hyperbolts.io)
 *
 * Copyright © 2015-present Pace IT Systems Ltd.
 * All rights reserved.
 *
 * @author  Pace IT Systems Ltd
 * @license MIT
 */

module.exports = paths => () => gulp.src(paths.src)

    // Compile
    .pipe(sourcemaps.init())
    .pipe(sass({
        includePaths: paths.includePaths || [
            path.join(process.cwd(), 'node_modules'),
            process.cwd()
        ]
    }))
        .on('error', handleError)
    .pipe(sourcemaps.write())

    // Output
    .pipe(gulp.dest(
        path.resolve(config.base, paths.dest)
    ))

    // Reload browser
    .pipe(browser.reload({
        stream: true
    }));

Support configuring style include paths


Handlebars.registerHelper('select_list', function(select_options, id) {
  var template = HandlebarsTemplates['recipes/foods_select'];

  var list = $.map(select_options, function(e) {
    if (id === e.id){
      e.selected = "selected";
      return e;
    } else {
      return e;
    }
  });

  return new Handlebars.SafeString(template(list));
});

Handlebars.registerHelper('num', function(number) {
  return number.toFixed(1).toLocaleString();
});

Handlebars.registerHelper('title', function(string) {
  return string.titleize();
});

Handlebars.registerHelper('select_list', function(select_options, id) {
  var template = HandlebarsTemplates['recipes/foods_select'];

  var list = $.map(select_options, function(e) {
    if (id === e.id){
      return {id: e.id, unique_name: e.unique_name, selected: "selected"}
    } else {
      return {id: e.id, unique_name: e.unique_name}
    }
  });

  return new Handlebars.SafeString(template(list));
});

Handlebars.registerHelper('num', function(number) {
  return number.toFixed(1).toLocaleString();
});

Handlebars.registerHelper('title', function(string) {
  return string.titleize();
});

Fix bug causing multiple food selected to be selected


$(document).ready(function() {
  $switcherFieldGroup = $("#request_personal_switch");

  if ($switcherFieldGroup.length) {
    // If an error is showing they must have selected 'no'
    // so set this and don't hide the form.
    if ($(".errorExplanation").length) {
      $("#request_personal_switch_no").prop("checked", true);
    } else {
      $switcherFieldGroup.addClass("personal_request_switcher_focused");

      $("#request_personal_switch_no").click(function(e) {
        $switcherFieldGroup.removeClass("personal_request_switcher_focused");
      });

      $("#request_personal_switch_yes").click(function(e) {
        $switcherFieldGroup.addClass("personal_request_switcher_focused");
      });
    }
  }
});

$(document).ready(function() {
  $switcherFieldGroup = $("#request_personal_switch");
  $formSubmitButton = $("#request_form input[type='submit']")[0];

  if ($switcherFieldGroup.length) {
    // If an error is showing they must have selected 'no'
    // so set this and don't hide the form.
    if ($(".errorExplanation").length) {
      $("#request_personal_switch_no").prop("checked", true);
    } else {
      $switcherFieldGroup.addClass("personal_request_switcher_focused");
      $formSubmitButton.disabled = true;
    }

    $("#request_personal_switch_no").click(function(e) {
      $switcherFieldGroup.removeClass("personal_request_switcher_focused");
      $formSubmitButton.disabled = false;
    });

    $("#request_personal_switch_yes").click(function(e) {
      $switcherFieldGroup.addClass("personal_request_switcher_focused");
      $formSubmitButton.disabled = true;
    });
  }
});

Disable form submitting when personal request selected


// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueResource from 'vue-resource'
Vue.use(VueResource)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueResource from 'vue-resource'
Vue.use(VueResource)

Vue.config.productionTip = false

Vue.filter('formatDate', function (value) {
  if (value) {
    var date = new Date(String(value))
    return date.toLocaleDateString() + ' at ' + date.toLocaleTimeString()
  }
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

Add a filter for the dates


/**
 * Lazysizes
 *
 * Lazy loader class for (responsive) images
 * https://github.com/aFarkas/lazysizes
 */

var lazysizes = {

	/**
	 * Init lazysizes
	 */
	init: function() {
		document.addEventListener('lazyriasmodifyoptions', function(e) {
			// If pixel ratio > 1.4 set (resrc) jpg quality to a lower percentage
			e.detail.quality = (window.devicePixelRatio || 1) > 1.4 ? 65 : 60;
		});
		document.addEventListener('lazybeforeunveil', function(e){
			// Replace default `data-src` placeholder {width} and {quality} with calculated values
			var src = e.target.getAttribute('data-src');
			if(!src) { return; }
			e.target.setAttribute('data-src', src.replace(/s=w(\d+)/, 's=w{width}').replace(/o=(\d+)/, 'o={quality}'));
			// // Basic support for background images (for without bgset plugin)
			// var bg = e.target.getAttribute('data-bg');
			// if(bg) {
			// 	e.target.style.backgroundImage = 'url(' + bg + ')';
			// 	e.target.removeAttribute('data-bg');
			// }
		});
	},
};

/**
 * Lazysizes
 *
 * Lazy loader class for (responsive) images
 * https://github.com/aFarkas/lazysizes
 */

var lazysizes = {

	/**
	 * Init lazysizes
	 */
	init: function() {
		document.addEventListener('lazyriasmodifyoptions', function(e) {
			// If pixel ratio > 1.4 set (resrc) jpg quality to a lower percentage
			e.detail.quality = (window.devicePixelRatio || 1) > 1.4 ? 65 : 60;
		});
		document.addEventListener('lazybeforeunveil', function(e){
			// Replace default `data-src/bgset` placeholder width and quality
			// values, with the by lazyizes calculated {width} and {quality} values
			var srcAttr = 'data-src';
			var src = e.target.getAttribute(srcAttr);
			if(!src) {
				srcAttr = 'data-bgset';
				src = e.target.getAttribute(srcAttr);
				if(!src) { return; }
			}
			e.target.setAttribute(srcAttr, src.replace(/s=w(\d+)/, 's=w{width}').replace(/o=(\d+)/, 'o={quality}'));

			// // Basic support for background images (for without bgset plugin)
			// var bg = e.target.getAttribute('data-bg');
			// if(bg) {
			// 	e.target.style.backgroundImage = 'url(' + bg + ')';
			// 	e.target.removeAttribute('data-bg');
			// }
		});
	},
};

Add code to replace not only `data-src`, but also `data-bgset` lazysizes width and quality values with calculated ones.


import NodePatcher from './NodePatcher';
import type { Node, ParseContext, Editor } from './types';

export default class MemberAccessOpPatcher extends NodePatcher {
  constructor(node: Node, context: ParseContext, editor: Editor, expression: NodePatcher) {
    super(node, context, editor);
    this.expression = expression;
  }

  patch() {
    this.expression.patch();
  }
}

import NodePatcher from './NodePatcher';
import type { Node, ParseContext, Editor } from './types';

export default class MemberAccessOpPatcher extends NodePatcher {
  constructor(node: Node, context: ParseContext, editor: Editor, expression: NodePatcher) {
    super(node, context, editor);
    this.expression = expression;
  }

  patch() {
    this.expression.patch();
    if (this.hasImplicitDot()) {
      this.insert(this.expression.after, '.');
    }
  }

  hasImplicitDot(): boolean {
    return !this.expression.hasTokenAfter('.');
  }

  getMemberName(): string {
    return this.node.memberName;
  }
}

Add support for `@a` shorthand `this`.


Astro.eventManager.on('beforeInit', function() {
  var doc = this;

  // Object for storing references of related objects.
  doc._references = {};
});

// Reset _references object if object is saved
Astro.eventManager.on('afterSave', function(e) {
  var relations = this.constructor.getRelations();
  if (!relations) {
    return;
  }

  var mongoSet = e.target._modifiers['$set'];
  if (!mongoSet) {
    return;
  }

  // Check if _references must be reset
  var mustResetReferences = _.any(relations, function(relationDefinition, relationName) {
    // Check if relation.local will be updated on database
    return !!mongoSet[relationDefinition.local];
  }, this);

  if (mustResetReferences) {
    this._references = {};
  }
});

Reset _references if object is saved


import React from 'react';

class HeaderImg extends React.Component {
  render() {
    const style = {
      width: '100%',
      height: '500px',
      clear: 'both',
      margin: '0',
      textAlign: 'center',
      overflow: 'hidden'
    };

    const src = 'https://wordanddeedindia.imgix.net/images/child.jpg?fit=crop&crop=faces';

    return (

    );
  }
}

export default HeaderImg;

import React from 'react';

class HeaderImg extends React.Component {
  render() {
    const style = {
      width: '100%',
      height: '500px',
      position: 'absolute',
      zIndex: '-1000';
      textAlign: 'center',
      overflow: 'hidden'
    };

    const src = 'https://wordanddeedindia.imgix.net/images/child.jpg?fit=crop&crop=faces';

    return (

    );
  }
}

export default HeaderImg;

Move Header Image back with z-index


var HeatTransformator = (function () {
    'use strict';

    function fetchChart(data, totals) {
        var chart,
            subChart,
            totals = (totals || []);

        for (chart in data) {
            subChart = data[chart];

            if (subChart.length) {
                totals.push({
                    type: chart,
                    name: I18n.t("charts." + chart),
                    area: true,
                    values: { total: LoadSlicer.slice(subChart, 0) }
                });
            } else {
                fetchChart(subChart, totals);
            }
        };

        return totals;
    }

    return {
        transform: function (data, week) {
            return fetchChart(data);
        }
    }
}());

var HeatTransformator = (function () {
    'use strict';

    function fetchChart(data, totals) {
        var chart,
            subChart,
            totals = (totals || []);

        for (chart in data) {
            if (data.hasOwnProperty(chart)) {
                subChart = data[chart];

                if (subChart.length && subChart.length > 0) {
                    totals.push({
                        type: chart,
                        name: I18n.t("charts." + chart),
                        area: true,
                        values: { total: LoadSlicer.slice(subChart, 0) }
                    });
                } else {
                    fetchChart(subChart, totals);
                }
            }
        };

        return totals;
    }

    return {
        transform: function (data, week) {
            return fetchChart(data);
        }
    }
}());

Fix heat transformator for IE11


import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'landing-page',
      component: require('@/components/LandingPage')
    },
    {
      path: '/new',
      name: 'new',
      component: require('@/components/NewReportSetup')
    },
    {
      path: '/report',
      name: 'report',
      component: require('@/components/Report')
    },
    {
      path: '/load',
      name: 'load',
      component: require('@/components/Load')
    },
    {
      path: '/config',
      name: 'config',
      component: require('@/components/Config'),
      children: [
        { path: '', redirect: 'sites' },
        { path: 'sites', component: require('@/components/Config/Sites') },
        { path: 'email', component: require('@/components/Config/Email') }
      ]
    }
  ]
})

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'landing-page',
      component: require('@/components/LandingPage')
    },
    {
      path: '/new',
      name: 'new',
      component: require('@/components/NewReportSetup')
    },
    {
      path: '/report',
      name: 'report',
      component: require('@/components/Report')
    },
    {
      path: '/load',
      name: 'load',
      component: require('@/components/Load')
    },
    {
      path: '/config',
      component: require('@/components/Config'),
      children: [
        { path: '', name: 'config', redirect: 'sites' },
        { path: 'sites', component: require('@/components/Config/Sites') },
        { path: 'email', component: require('@/components/Config/Email') }
      ]
    }
  ]
})

Fix default child route naming


(function() {
  'use strict';

  angular
    .module('app.waitList')
    .controller('WaitListController', WaitListController);

  function WaitListController() {
    var vm = this;

    vm.parties = [1, 2, 3, 4];

    vm.addParty = addParty;

    function addParty() {
      vm.parties.push('another');
    }
  }

})();

(function() {
  'use strict';

  angular
    .module('app.waitList')
    .controller('WaitListController', WaitListController);

  WaitListController.$inject = ['$firebaseArray'];

  function WaitListController($firebaseArray) {
    var vm = this;

    var fireParties = new Firebase('https://waitandeat-v2-demo.firebaseio.com/parties');
    vm.parties  = $firebaseArray(fireParties);
    vm.addParty = addParty;

    function addParty() {
      vm.parties.$add('another');
    }
  }

})();

Use firebase data instead of simply array.


import { getResourcePath } from './resources'
import { scope } from '../../lib/util'
import _ from 'lodash'

export default (context, inject) => {
  const { $axios, error, app, req, redirect } = context
  const logout = () => {
    const url = '/logout'
    if (process.client) {
      location.href = url
    } else {
      redirect(url)
    }
  }
  let resourcePath
  if (process.server) {
    if (req.user && req.user.token) {
      $axios.setToken(req.user.token, 'bearer')
    } else {
      $axios.setToken(null)
    }
  }
  const $resource = (options = {}) => {
    return $axios.$get(resourcePath, {
      params: {
        include_post_raw: 1,
        include_directed_posts: 0,
        include_message_raw: 1,
        ...options
      }
    })
  }
  inject('resource', $resource)
  app.router.beforeEach((to, from, next) => {
    resourcePath = getResourcePath(to)
    next()
  })
  $axios.onError(err => {
    const code = parseInt(err.response && err.response.status)
    if (code === 401) {
      // clear session
      // don't use `redirect`
      logout()
    } else if (code === 404) {
      // ignore 404
    } else {
      if (process.server) {
        error({
          statusCode: code,
          message: err.message
        })
      } else if (process.client) {
        app.$toast.error(err.response.data.meta.error_message || err.message)
        const serverScope = err.response.headers['x-oauth-scopes'].split(',')
        const clientScope = scope.split(' ')
        if (_.difference(clientScope, serverScope).length) {
          logout()
        }
      }
    }
  })
}

import { getResourcePath } from './resources'

export default (context, inject) => {
  const { $axios, error, app } = context
  let resourcePath
  const $resource = (options = {}) => {
    return $axios.$get(resourcePath, {
      params: {
        include_post_raw: 1,
        include_directed_posts: 0,
        include_message_raw: 1,
        ...options
      }
    })
  }
  inject('resource', $resource)
  app.router.beforeEach((to, from, next) => {
    resourcePath = getResourcePath(to)
    next()
  })
  $axios.onError(err => {
    const code = parseInt(err.response && err.response.status)
    if (process.server) {
      error({
        statusCode: code,
        message: err.message
      })
    } else {
      app.$toast.error(err.response.data.meta.error_message || err.message)
    }
  })
}

Fix axios configuration in accordance with auth module


const Quill = require('quill')

const initializeQuillEditor = function () {
  let transcriptEditor = new Quill('.transcript-editor', {
    modules: {
      toolbar: true  // Include button in toolbar
    },
    theme: 'snow'
  })
  return (transcriptEditor)
}

module.exports = initializeQuillEditor()

const Quill = require('quill')

const initializeQuillEditor = function () {
  let transcriptEditor = new Quill('.transcript-editor', {
    modules: {
      toolbar: true  // Include button in toolbar
    },
    theme: 'snow',
    placeholder: 'Transcribe away...'
  })
  return (transcriptEditor)
}

module.exports = initializeQuillEditor()

Add placeholder text to editor


var Crypto = require('crypto');

// Map configuration object

/// API: Create MapConfig from configuration object
//
/// @param obj js MapConfiguration object
///
function MapConfig(cfg) {
  // TODO: check configuration ?
  this._cfg = cfg;
}

var o = MapConfig.prototype;

o._md5 = function(s) {
  return Crypto.createHash('md5').update(s).digest('hex');
};

/// API: Get serialized version of this MapConfig
o.serialize = function() {
  return JSON.stringify(this._cfg);
};

/// API: Get identifier for this MapConfig
o.id = function() {
  return this._md5(this.serialize());
}

/// API: Get configuration object of this MapConfig
o.obj = function() {
  return this._cfg;
}

module.exports = MapConfig;

var Crypto = require('crypto');

// Map configuration object

/// API: Create MapConfig from configuration object
//
/// @param obj js MapConfiguration object
///
function MapConfig(cfg) {
  // TODO: check configuration ?
  this._cfg = cfg;
}

var o = MapConfig.prototype;

o._md5 = function(s) {
  return Crypto.createHash('md5').update(s).digest('hex');
};

/// API: Get serialized version of this MapConfig
o.serialize = function() {
  return JSON.stringify(this._cfg);
};

/// API: Get identifier for this MapConfig
o.id = function() {
  return this._md5(this.serialize());
}

/// API: Get configuration object of this MapConfig
o.obj = function() {
  return this._cfg;
}

/// API: Get type string of given layer
//
/// @param num layer index (0-based)
/// @returns a type string, as read from the layer
///
o.layerType = function(num) {
  var lyr = this._cfg.layers[num];
  if ( ! lyr ) return undefined;
  var typ = lyr.type;
  if ( ! typ || typ == 'cartodb' ) typ = 'mapnik';
  // TODO: check validity of other types ?
  return typ;
}

module.exports = MapConfig;

Add layerType method to MapConfig class


require.config({
  paths: {
    text: 'lib/require-text',
    css: 'lib/require-css',

    jquery: 'lib/jquery',

    underscore: 'lib/underscore',
    'underscore.crunch': 'lib/underscore.crunch',

    backbone: 'lib/backbone',

    marked: 'lib/marked',
    'marked.highlight': 'lib/marked.highlight',

    moment: 'lib/moment',

    highlight: 'lib/highlight',

    "disqus.embed": '//livingwithdjango.disqus.com/embed',
    "disqus.count": '//livingwithdjango.disqus.com/count'
  },

  shim: {
    highlight: {
      deps: ['css!style/highlight.css'],
      exports: 'hljs'
    }
  }
});

require(
  [
    'backbone', 'models', 'views', 'css!style/main.css'
  ], function(B, M, V) {
    new (B.Router.extend({
      routes: {'': 'list', '!/': 'list', '!/*src': 'entry'},
      list: function() { new V.List(); },
      entry: function(src) { new V.Entry({model: new M.Entry({src: src})}); }
    }));

    B.history.start({root: '/living-with-django/'});
  }
);

require.config({
  paths: {
    text: 'lib/require-text',
    css: 'lib/require-css',

    jquery: 'lib/jquery',

    underscore: 'lib/underscore',
    'underscore.crunch': 'lib/underscore.crunch',

    backbone: 'lib/backbone',

    marked: 'lib/marked',
    'marked.highlight': 'lib/marked.highlight',

    moment: 'lib/moment',

    highlight: 'lib/highlight',

    'disqus.embed': '//livingwithdjango.disqus.com/embed',
    'disqus.count': '//livingwithdjango.disqus.com/count'
  },

  shim: {
    highlight: {
      deps: ['css!style/highlight.css'],
      exports: 'hljs'
    }
  }
});

require(
  [
    'backbone', 'models', 'views', 'css!style/main.css'
  ], function(B, M, V) {
    new (B.Router.extend({
      routes: {'': 'list', '!/': 'list', '!/*src': 'entry'},
      list: function() { new V.List(); },
      entry: function(src) { new V.Entry({model: new M.Entry({src: src})}); }
    }));

    B.history.start({root: '/living-with-django/'});
  }
);

Replace double quotes with single quotes.


import superagent from 'superagent'

export default {
  getProductions (callback) {
    superagent
      .get('/api/data/projects/all')
      .end((err, res) => {
        callback(err, res.body)
      })
  }
}

import superagent from 'superagent'

export default {
  getProductions (callback) {
    superagent
      .get('/api/data/projects/all')
      .end((err, res) => {
        callback(err, res.body)
      })
  },

  getProductionStatus (callback) {
    superagent
      .get('/api/data/project_status')
      .end((err, res) => {
        callback(err, res.body)
      })
  },

  newProduction (production, callback) {
    const data = {
      name: production.name,
      project_status_id: production.project_status_id
    }
    superagent
      .post(`/api/data/projects/`)
      .send(data)
      .end((err, res) => {
        callback(err, res.body)
      })
  },

  updateProduction (production, callback) {
    const data = {
      name: production.name,
      project_status_id: production.project_status_id
    }
    superagent
      .put(`/api/data/projects/${production.id}`)
      .send(data)
      .end((err, res) => {
        callback(err, res.body)
      })
  },

  deleteProduction (production, callback) {
    superagent
      .del(`/api/data/projects/${production.id}`)
      .end((err, res) => {
        callback(err, res.body)
      })
  }
}

Add helpers to manage production data through API


/*!
 * Start Bootstrap - Freelancer Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('body').on('click', '.page-scroll a', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Floating label headings for the contact form
$(function() {
    $("body").on("input propertychange", ".floating-label-form-group", function(e) {
        $(this).toggleClass("floating-label-form-group-with-value", !! $(e.target).val());
    }).on("focus", ".floating-label-form-group", function() {
        $(this).addClass("floating-label-form-group-with-focus");
    }).on("blur", ".floating-label-form-group", function() {
        $(this).removeClass("floating-label-form-group-with-focus");
    });
});

// Highlight the top nav as scrolling occurs
$('body').scrollspy({
    target: '.navbar-fixed-top'
})

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

}

/*!
 * Start Bootstrap - Freelancer Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('body').on('click', '.page-scroll a', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Floating label headings for the contact form
$(function() {
    $("body").on("input propertychange", ".floating-label-form-group", function(e) {
        $(this).toggleClass("floating-label-form-group-with-value", !! $(e.target).val());
    }).on("focus", ".floating-label-form-group", function() {
        $(this).addClass("floating-label-form-group-with-focus");
    }).on("blur", ".floating-label-form-group", function() {
        $(this).removeClass("floating-label-form-group-with-focus");
    });
});

// Highlight the top nav as scrolling occurs
$('body').scrollspy({
    target: '.navbar-fixed-top'
});

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

Fix syntax error in js


// mongodb-driver-test.js
//
// Testing the mongodb driver
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
    vows = require('vows'),
    databank = require('databank'),
    Databank = databank.Databank,
    MongoDatabank = require('../lib/index');

Databank.register('mongodb', MongoDatabank);

var params = {host: 'localhost',
              port: 27017,
              mktmp: true,
              checkSchema: true};

var suite = databank.DriverTest('mongodb', params);

suite['export'](module);

// mongodb-driver-test.js
//
// Testing the mongodb driver
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
    vows = require('vows'),
    databank = require('databank'),
    Databank = databank.Databank,
    MongoDatabank = require('../lib/index');

Databank.register('mongodb', MongoDatabank);

var params = {host: 'localhost',
              port: 27017,
              dbname: 'test',
              checkSchema: true};

var suite = databank.DriverTest('mongodb', params);

suite['export'](module);

Revert "use mktmp in driver tests"


import React from 'react';
import PropTypes from 'prop-types';
import Popover from './Popover';
import BaseText from '../../utils/rnw-compat/BaseText';
import OverlayPropTypes from '../../utils/OverlayPropTypes';
import useOverlay from '../../hooks/useOverlay';

export default function injectPopover(Component) {
  const propTypes = {
    tooltip: PropTypes.shape({
      title: PropTypes.string,
      content: PropTypes.string.isRequired,
      ...OverlayPropTypes,
    }),
  };

  function OverlayPopover(props) {
    const {
      popover: {
        title,
        content,
        delay,
        trigger = 'click',
        placement = 'right',
        fallbackPlacement,
      },
      ...elementProps
    } = props;

    const target = <Component {...elementProps} />;

    const template = (
      <Popover>
        {title && <Popover.Header>{title}</Popover.Header>}
        <Popover.Body>
          <BaseText essentials={{}}>{content}</BaseText>
        </Popover.Body>
      </Popover>
    );

    return useOverlay(target, template, {
      delay,
      trigger,
      placement,
      fallbackPlacement,
    });
  }

  OverlayPopover.displayName = 'Overlay(Popover)';
  OverlayPopover.propTypes = propTypes;

  return OverlayPopover;
}

import React from 'react';
import PropTypes from 'prop-types';
import Popover from './Popover';
import OverlayPropTypes from '../../utils/OverlayPropTypes';
import useOverlay from '../../hooks/useOverlay';

export default function injectPopover(Component) {
  const propTypes = {
    tooltip: PropTypes.shape({
      title: PropTypes.string,
      content: PropTypes.string.isRequired,
      ...OverlayPropTypes,
    }),
  };

  function OverlayPopover(props) {
    const {
      popover: {
        title,
        content,
        delay,
        trigger = 'click',
        placement = 'right',
        fallbackPlacement,
      },
      ...elementProps
    } = props;

    const target = <Component {...elementProps} />;

    const template = (
      <Popover>
        {title && <Popover.Header>{title}</Popover.Header>}
        <Popover.Body>{content}</Popover.Body>
      </Popover>
    );

    return useOverlay(target, template, {
      delay,
      trigger,
      placement,
      fallbackPlacement,
    });
  }

  OverlayPopover.displayName = 'Overlay(Popover)';
  OverlayPopover.propTypes = propTypes;

  return OverlayPopover;
}

Remove unnecessary BaseText from popover