define( function() {
	return function( elem ) {

		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		var view = elem.ownerDocument.defaultView;

		if ( !view.opener ) {
			view = window;
		}

		return view.getComputedStyle( elem );
	};
} );

define( function() {
	return function( elem ) {

		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		var view = elem.ownerDocument.defaultView;

		if ( !view || !view.opener ) {
			view = window;
		}

		return view.getComputedStyle( elem );
	};
} );

CSS: Make sure elem.ownerDocument.defaultView is not null

Fixes gh-2866
Close gh-2867


var crawler = (function() {
    var that = {};

    that.accept = function(event) {
        update_status(event.target, '/crawling/accept/');
    };

    that.ignore = function(event) {
        update_status(event.target, '/crawling/ignore/');
    };

    function update_status(button, url_prefix) {
        var id = parseInt(button.id.split('-')[2]);
        var url = url_prefix + id + '/';
        $.post(url, {}, function() {
            var row = $('#result-' + id);
            row.remove();
        });
    }

    return that;
})();

var crawler = (function() {
    var that = {};

    that.accept = function(event) {
        update_status(event, '/crawling/accept/');
    };

    that.ignore = function(event) {
        update_status(event, '/crawling/ignore/');
    };

    function update_status(event, url_prefix) {
        function find_button(event) {
            var element;
            for (var i = 0; i < event.path.length; i += 1) {
                element = $(event.path[i]);
                if (element.prop('tagName') === 'BUTTON') {
                    return element;
                }
            }
        }

        var button = find_button(event);
        var id = parseInt(button.prop('id').split('-')[2]);
        var url = url_prefix + id + '/';
        $.post(url, {}, function() {
            var row = $('#result-' + id);
            row.remove();
        });
    }

    return that;
})();

Fix bug when clicking on icon

Fix bug when clicking on icon


Application.Services.factory('ProcessList',
                             ["Restangular", "pubsub", processListService]);
function processListService(Restangular, pubsub) {
    var service = {
        processes: {}
    };

    return {
        getProcesses: function(project_id){
            if (service.processes.hasOwnProperty(project_id)){
                return service.processes[project_id];
            } else {
                this.loadProcesses(project_id);
            }
        },

        loadProcesses: function (project_id) {
            Restangular.one('processes').one('project', project_id).getList().then(function(data){
                service.processes[project_id] = data;
            });
        }
    };

}

Application.Services.factory('ProcessList',
                             ["Restangular", "$q", processListService]);
function processListService(Restangular, $q) {
    var service = {
        processes: {}
    };

    return {
        getProcesses: function(project_id){
            var deffered = $q.defer();
            var pid = project_id;
            if (service.processes.hasOwnProperty(project_id)){
                deffered.resolve(service.processes[project_id]);
            } else {
                Restangular.one('processes').one('project', project_id)
                    .getList().then(function(processes){
                        service.processes[pid] = processes;
                        deffered.resolve(service.processes[pid]);
                    });
            }
            return deffered.promise;
        }
    };
}

Return promises. Fix missing return in else statement.


var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: {
    ui: [
      'webpack-dev-server/client?http://localhost:3001',
      'webpack/hot/only-dev-server',
      './lib/ui/main.js'
    ]
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    publicPath: '/dist/'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loaders: ['react-hot', 'babel']
    },{
      test: /\.json$/,
      loader: 'json'
    }]
  },
  resolve: {
    alias: {
      bacon: "baconjs"
    }
  },
  resolveLoader: { fallback: path.join(__dirname, "node_modules") },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ],
  externals: ['mdns']
}

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: {
    ui: [
      'webpack-dev-server/client?http://localhost:3001',
      'webpack/hot/only-dev-server',
      './lib/ui/main.js'
    ]
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    publicPath: '/dist/'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loaders: ['react-hot', 'babel']
    },{
      test: /\.json$/,
      loader: 'json'
    }]
  },
  resolve: {
    alias: {
      bacon: "baconjs"
    }
  },
  resolveLoader: { fallback: path.join(__dirname, "node_modules") },
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ],
  externals: ['mdns']
}

Remove vendor bundle from here as well

Remove vendor bundle from here as well


var common = require('./webpack.common.config.js');
var assign = require('object-assign');

module.exports = assign(common, {
    debug: true,
    devtool: 'eval'
});

var common = require('./webpack.common.config.js');
var assign = require('object-assign');

module.exports = assign(common, {
    debug: true,
    devtool: 'source-map'
});

Switch back to source-map for devtool

Switch back to source-map for devtool

[skip ci]


'use strict';
var alter = require('./alter');
var batoto = require('./batoto');
var kissmanga = require('./kissmanga');
var mangafox = require('./mangafox');

/**
 * Retrieves a series.
 * @param {string} address
 * @return {Series}
 */
module.exports = function (address) {
    var series = batoto(address) || kissmanga(address) || mangafox(address);
    if (series) {
        var populate = series.children;
        series.children = function ($) {
            var children = populate($);
            alter(children);
            return children;
        };
    }
    return series;
};

'use strict';
var alter = require('./alter');
var batoto = require('./batoto');
var kissmanga = require('./kissmanga');
var mangafox = require('./mangafox');
var providers = [batoto, kissmanga, mangafox];

/**
 * Retrieves a series.
 * @param {string} address
 * @return {Series}
 */
module.exports = function (address) {
    var series;
    providers.every(function (provider) {
        series = provider(address);
        return !Boolean(series);
    });
    if (series) {
        var populate = series.children;
        series.children = function ($) {
            var children = populate($);
            alter(children);
            return children;
        };
    }
    return series;
};

/**
 * Adds a provider.
 * @param {!Provider} provider
 */
module.exports.add = function (provider) {
    providers.push(provider);
};

Enable runtime addition of third party providers.


import React from 'react'
import shallowEqual from 'shallowequal'

export const withDomain = ({
  domainClass,
  mapPropsToArg,
  mapPropsToArgsArray = props => mapPropsToArg ? [mapPropsToArg(props)] : [],
  createDomain = props => new domainClass(...mapPropsToArgsArray(props)),  // eslint-disable-line new-cap
  propName = 'domain',
  shouldRecreateDomain = (currentProps, nextProps) =>
    ! shallowEqual(mapPropsToArgsArray(currentProps), mapPropsToArgsArray(nextProps)),
}) =>
  Component =>
    class DomainProvider extends React.Component {

      domain

      componentWillMount() {
        this.domain = createDomain(this.props)
      }

      componentWillUpdate(nextProps) {
        if (shouldRecreateDomain(this.props, nextProps)) {
          this.stop()
          this.domain = createDomain(nextProps)
        }
      }

      componentWillUnmount() {
        this.stop()
      }

      stop() {
        if (this.domain && typeof this.domain.stop === 'function') {
          this.domain.stop()
        }
      }

      render() {
        return React.createElement(Component, { ...this.props, [propName]: this.domain })
      }
    }

import React from 'react'
import shallowEqual from 'shallowequal'

export const withDomain = ({
  domainClass,
  mapPropsToArg,
  mapPropsToArgsArray = props => mapPropsToArg ? [mapPropsToArg(props)] : [],
  createDomain = props => new domainClass(...mapPropsToArgsArray(props)),  // eslint-disable-line new-cap
  propName = 'domain',
  shouldRecreateDomain = (currentProps, nextProps) =>
    ! shallowEqual(mapPropsToArgsArray(currentProps), mapPropsToArgsArray(nextProps)),
}) =>
  Component =>
    class DomainProvider extends React.Component {

      domain

      componentWillMount() {
        this.domain = createDomain(this.props)
      }

      componentWillUpdate(nextProps) {
        if (shouldRecreateDomain(this.props, nextProps)) {
          this.stop()
          this.domain = createDomain(nextProps)
        }
      }

      componentWillUnmount() {
        this.stop()
        this.domain = null
      }

      stop() {
        if (this.domain && typeof this.domain.stop === 'function') {
          this.domain.stop()
        }
      }

      render() {
        return React.createElement(Component, { ...this.props, [propName]: this.domain })
      }
    }

Set domain to null for safety

Set domain to null for safety


import React, { Component } from 'react';
import { Container, Content, List } from 'native-base';

import JobTypeCard from './jobTypeCard';
import GlobalStyle from '../../common/globalStyle';

// Temporary constants. These will be moved and implemented in another way in the future!
const EXAMPLE_IMAGE_URL = 'https://facebook.github.io/react/img/logo_og.png';
const JOB_TYPES = ['Snöskottning', 'Lövkrattning', 'Städning', 'Ogräsrensning'];

export default class ChooseJobTypeScreen extends Component {
  static navigationOptions = {
    title: 'Choose Job Type',
  };

  navigateToNextScreen = () => (
    this.props.navigation.navigate('CreateJobScreen')
  );

  renderRow = jobType => (
    <JobTypeCard
      title={jobType} subtitle={`Behöver du hjälp med ${jobType.toLowerCase()}?`}
      cover={EXAMPLE_IMAGE_URL} icon={EXAMPLE_IMAGE_URL}
      toNextScreen={() => this.navigateToNextScreen()}
    />
  );

  render() {
    return (
      <Container>
        <Content contentContainerStyle={GlobalStyle.padder}>
          <List dataArray={JOB_TYPES} renderRow={this.renderRow} />
        </Content>
      </Container>
    );
  }
}

import React, { Component, PropTypes } from 'react';
import { Container, Content, List } from 'native-base';
import { connect } from 'react-redux';
import JobTypeCard from './jobTypeCard';
import GlobalStyle from '../../common/globalStyle';
import { imageProp } from '../../common/propTypes';

const { shape, arrayOf, string } = PropTypes;

class ChooseJobTypeScreen extends Component {
  static navigationOptions = {
    title: 'Choose Job Type',
  };

  static propTypes = {
    jobTypes: shape({
      data: arrayOf(
        shape({
          title: string.isRequired,
          description: string.isRequired,
          icon: imageProp.isRequired,
          image: imageProp.isRequired,
        }).isRequired,
      ).isRequired,
    }).isRequired,
  };

  navigateToNextScreen = () => this.props.navigation.navigate('CreateJobScreen');

  renderRow = jobType => (
    <JobTypeCard
      title={jobType.title} subtitle={jobType.description}
      cover={jobType.image} icon={jobType.icon}
      toNextScreen={() => this.navigateToNextScreen()}
    />
  );

  render() {
    return (
      <Container>
        <Content contentContainerStyle={GlobalStyle.padder}>
          <List dataArray={this.props.jobTypes.data} renderRow={this.renderRow} />
        </Content>
      </Container>
    );
  }
}

const mapStateToProps = state => ({ jobTypes: state.jobTypes });

export default connect(mapStateToProps)(ChooseJobTypeScreen);

Make ChooseJobTypeScreen use data from Redux


"use strict";

angular.module("hikeio").
	directive("headerEntry", function() {
		return {
			scope: {
				align: "@",
				label: "@",
				url: "@"
			},
			compile: function(tplElm, tplAttr) {
				// Include link only if url is included (otherwise, on some browsers it implies /)
				if (!tplAttr.url) {
					var link = tplElm.children()[0];
					tplElm.empty();
					tplElm.append(link.children);
				}
			},

			template: "" +
				"
" +
					"

" +
					"
" +
						"{{label}}" +
					"
" +
					"

" +
				"
" +
			"",
			transclude: true
		};
	});

"use strict";

angular.module("hikeio").
	directive("headerEntry", function() {
		return {
			scope: {
				align: "@",
				label: "@",
				url: "@"
			},
			compile: function(tplElm, tplAttr) {
				// Include link only if url is included (otherwise, on some browsers it implies /)
				if (!tplAttr.url) {
					var link = tplElm.children()[0];
					tplElm.empty();
					tplElm.append(link.children);
				}
			},

			template: "" +
				"
" +
					"

" +
					"
" +
						"" +
					"
" +
					"

" +
				"
" +
			"",
			transclude: true
		};
	});

Use ng-bind instead of {{}} for header entry directive.


define([
  'Class', 'uri', 'bluebird',
  'map/services/DataService'
], function(Class, UriTemplate, Promise, ds) {

  'use strict';

  var GET_REQUEST_ID = 'GeostoreService:get',
      SAVE_REQUEST_ID = 'GeostoreService:save';

  var URL = window.gfw.config.GFW_API_HOST + '/geostore/{id}';

  var GeostoreService = Class.extend({

    get: function(id) {
      return new Promise(function(resolve, reject) {

      var url = new UriTemplate(URL).fillFromObject({id: id});

      ds.define(GET_REQUEST_ID, {
        cache: {type: 'persist', duration: 1, unit: 'days'},
        url: url,
        type: 'GET'
      });

      var requestConfig = {
        resourceId: GET_REQUEST_ID,
        success: function(response) {
          resolve(response.data);
        },
      };

      ds.request(requestConfig);

      });
    },

    save: function(geojson) {
      return new Promise(function(resolve, reject) {

      var url = new UriTemplate(URL).fillFromObject({});

      ds.define(SAVE_REQUEST_ID, {
        url: url,
        type: 'POST',
        contentType: 'application/json'
      });

      var requestConfig = {
        resourceId: SAVE_REQUEST_ID,
        data: JSON.stringify(geojson),
        success: function(response) {
          resolve(response.data.id);
        },
        error: reject
      };

      ds.request(requestConfig);

      });
    }

  });

  return new GeostoreService();

});

define([
  'Class', 'uri', 'bluebird',
  'map/services/DataService'
], function(Class, UriTemplate, Promise, ds) {

  'use strict';

  var GET_REQUEST_ID = 'GeostoreService:get',
      SAVE_REQUEST_ID = 'GeostoreService:save';

  var URL = window.gfw.config.GFW_API_HOST + '/api/geostore/{id}';

  var GeostoreService = Class.extend({

    get: function(id) {
      return new Promise(function(resolve, reject) {

      var url = new UriTemplate(URL).fillFromObject({id: id});

      ds.define(GET_REQUEST_ID, {
        cache: {type: 'persist', duration: 1, unit: 'days'},
        url: url,
        type: 'GET'
      });

      var requestConfig = {
        resourceId: GET_REQUEST_ID,
        success: function(response) {
          resolve(response.data);
        },
      };

      ds.request(requestConfig);

      });
    },

    save: function(geojson) {
      return new Promise(function(resolve, reject) {

      var url = new UriTemplate(URL).fillFromObject({});

      ds.define(SAVE_REQUEST_ID, {
        url: url,
        type: 'POST',
        contentType: 'application/json'
      });

      var requestConfig = {
        resourceId: SAVE_REQUEST_ID,
        data: JSON.stringify(geojson),
        success: function(response) {
          resolve(response.data.id);
        },
        error: reject
      };

      ds.request(requestConfig);

      });
    }

  });

  return new GeostoreService();

});

Use config for API url

Use config for API url


import React from 'react'
import { connect } from 'react-redux'
import _ from 'lodash'
import injectSheet from 'react-jss'

import ResourceCard from './resource-card'

const mapStateToProps = state => {
	return {
		pregnancyResourceCenters: state.miniApp.pregnancyResourceCenters,
	}
}

const ResourceListView = ({ classes, pregnancyResourceCenters }) => {
	return (

				Your search results have been arranged by closest distance to your
				location data.

				{_.map(pregnancyResourceCenters, prc => {
					return <ResourceCard key={prc._id} resource={prc} />
				})}

	)
}

const styles = {
	header: {
		padding: '30px 0px 30px 0px',
		'background-color': '#3d65f9',
		'font-size': '14px',
		color: '#99cccc',
		'text-align': 'center',
	},
}

const ResourceList = connect(mapStateToProps)(ResourceListView)

export default injectSheet(styles)(ResourceList)

import React from 'react'
import { connect } from 'react-redux'
import _ from 'lodash'
import injectSheet from 'react-jss'

import ResourceCard from './resource-card'
import LogoAndNavigation from '../logo-and-navigation'

const mapStateToProps = state => {
	return {
		pregnancyResourceCenters: state.miniApp.pregnancyResourceCenters,
	}
}

const ResourceListView = ({ classes, pregnancyResourceCenters }) => {
	return (

			<LogoAndNavigation />

				Your search results have been arranged by closest distance to your
				location data.

				{_.map(pregnancyResourceCenters, prc => {
					return <ResourceCard key={prc._id} resource={prc} />
				})}

	)
}

const styles = {
	header: {
		padding: '30px 0px 30px 0px',
		'background-color': '#3d65f9',
		'font-size': '14px',
		color: '#99cccc',
		'text-align': 'center',
	},
}

const ResourceList = connect(mapStateToProps)(ResourceListView)

export default injectSheet(styles)(ResourceList)

Add logo and navigation to results page

Add logo and navigation to results page


/**
 * This static UI function fills the given HTML <select> element with HTML
 * <option> elements that represent each found device.
 * A device type to filter is optional, the default is the video input type.
 */
VideoStream.UI.deviceSelector = function(selectElement, deviceType = VideoStream.DeviceType.VIDEO_INPUT){
	VideoStream.listDevices(deviceType)
	.then(function(devices){

		var genericText;
		switch(deviceType){
		case VideoStream.DeviceType.VIDEO_INPUT :
			genericText = VideoStream.UI.language['generic-camera'];
			break;
		case VideoStream.DeviceType.AUDIO_INPUT :
			genericText = VideoStream.UI.language['generic-audio-input'];
			break;
		default:
			genericText = VideoStream.UI.language['generic-input'];
		}

		for(var i = 0, genericIndex = 1; i < devices.length; i++){
			var label = devices[i].label === '' ? genericText + ' #' + (genericIndex++) : devices[i].label;

			var option = document.createElement('OPTION');
			option.setAttribute('value', i);
			var text = document.createTextNode(label);
			option.appendChild(text);
			selectElement.appendChild(option);
		}
	});
}

VideoStream.UI.language['generic-input'] = 'Generic Input';
VideoStream.UI.language['generic-camera'] = 'Generic Camera';
VideoStream.UI.language['generic-audio-input'] = 'Generic Audio Input';

/**
 * This static UI function fills the given HTML <select> element with HTML
 * <option> elements that represent each found device.
 * A device type to filter is optional, the default is the video input type.
 */
VideoStream.UI.deviceSelector = function(selectElement, deviceType = VideoStream.DeviceType.VIDEO_INPUT){
	VideoStream.listDevices(deviceType)
	.then(function(devices){

		var genericText;
		switch(deviceType){
		case VideoStream.DeviceType.VIDEO_INPUT :
			genericText = VideoStream.UI.language['generic-camera'];
			break;
		case VideoStream.DeviceType.AUDIO_INPUT :
			genericText = VideoStream.UI.language['generic-audio-input'];
			break;
		default:
			genericText = VideoStream.UI.language['generic-input'];
		}

		for(var i = 0, genericIndex = 1; i < devices.length; i++){
			var label = devices[i].label === '' ? genericText + ' #' + (genericIndex++) : devices[i].label;

			var option = document.createElement('OPTION');
			option.setAttribute('value', devices[i].deviceId);
			var text = document.createTextNode(label);
			option.appendChild(text);
			selectElement.appendChild(option);
		}
	});
}

VideoStream.UI.language['generic-input'] = 'Generic Input';
VideoStream.UI.language['generic-camera'] = 'Generic Camera';
VideoStream.UI.language['generic-audio-input'] = 'Generic Audio Input';

Write correct device id into value

Write correct device id into value


import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const { Object, RSVP } = Ember;
const { resolve } = RSVP;

moduleForComponent('school-vocabulary-manager', 'Integration | Component | school vocabulary manager', {
  integration: true
});

test('it renders', function(assert) {
  let vocabulary = Object.create({
    title: 'fake vocab',
    topLevelTerms: resolve([])
  });

  this.set('vocabulary', vocabulary);
  this.on('nothing', parseInt);
  this.render(hbs`{{school-vocabulary-manager
    vocabulary=vocabulary
    manageTerm=(action 'nothing')
    manageVocabulary=(action 'nothing')
  }}`);

  const all = '.breadcrumbs span:eq(0)';
  const vocab = '.breadcrumbs span:eq(1)';

  assert.equal(this.$(all).text().trim(), 'All Vocabularies');
  assert.equal(this.$(vocab).text().trim(), vocabulary.title);
});

import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const { Object, RSVP } = Ember;
const { resolve } = RSVP;

moduleForComponent('school-vocabulary-manager', 'Integration | Component | school vocabulary manager', {
  integration: true
});

test('it renders', function(assert) {
  let vocabulary = Object.create({
    title: 'fake vocab',
    terms: resolve([])
  });

  this.set('vocabulary', vocabulary);
  this.on('nothing', parseInt);
  this.render(hbs`{{school-vocabulary-manager
    vocabulary=vocabulary
    manageTerm=(action 'nothing')
    manageVocabulary=(action 'nothing')
  }}`);

  const all = '.breadcrumbs span:eq(0)';
  const vocab = '.breadcrumbs span:eq(1)';

  assert.equal(this.$(all).text().trim(), 'All Vocabularies');
  assert.equal(this.$(vocab).text().trim(), vocabulary.title);
});

Fix school vocal term manager test

Fix school vocal term manager test


import commitExcessActions from './commitExcessActions';

export function recompute(previousLiftedState, storeState, action, nextActionId = 1, isExcess) {
  const actionId = nextActionId - 1;
  const liftedState = { ...previousLiftedState };
  liftedState.stagedActionIds = [...liftedState.stagedActionIds, actionId];
  liftedState.actionsById = { ...liftedState.actionsById };
  if (action.type === 'PERFORM_ACTION') {
    liftedState.actionsById[actionId] = action;
  } else {
    liftedState.actionsById[actionId] = {
      action: action.action || action,
      timestamp: action.timestamp || Date.now(),
      type: 'PERFORM_ACTION'
    };
  }
  liftedState.nextActionId = nextActionId;
  liftedState.computedStates = [...liftedState.computedStates, { state: storeState }];
  liftedState.currentStateIndex++;

  if (isExcess) commitExcessActions(liftedState);

  return liftedState;
}

import commitExcessActions from './commitExcessActions';

export function recompute(previousLiftedState, storeState, action, nextActionId = 1, isExcess) {
  const actionId = nextActionId - 1;
  const liftedState = { ...previousLiftedState };

  if (liftedState.currentStateIndex === liftedState.stagedActionIds.length - 1) {
    liftedState.currentStateIndex++;
  }
  liftedState.stagedActionIds = [...liftedState.stagedActionIds, actionId];
  liftedState.actionsById = { ...liftedState.actionsById };
  if (action.type === 'PERFORM_ACTION') {
    liftedState.actionsById[actionId] = action;
  } else {
    liftedState.actionsById[actionId] = {
      action: action.action || action,
      timestamp: action.timestamp || Date.now(),
      type: 'PERFORM_ACTION'
    };
  }
  liftedState.nextActionId = nextActionId;
  liftedState.computedStates = [...liftedState.computedStates, { state: storeState }];

  if (isExcess) commitExcessActions(liftedState);

  return liftedState;
}

Fix `currentStateIndex` while time travelling


function PlayState(playerPos) {
    "use strict";

    var self = this;
    var charSprite = new Sprite("img/char_S0.png", function() {
        var charColl = new CollisionBody(charSprite.size);
        self.char = new Entity(playerPos, charColl, charSprite);
    });
}

// Subclass the GameState class.
PlayState.prototype = GameState.prototype;

PlayState.prototype.update = function (deltaTime) {
    "use strict";
}

PlayState.prototype.render = function (screen) {
    "use strict";

    this.char.render(screen);

    screen.renderText("Hello World!", new Vector2(5, 20));
    screen.renderText("This is OpenJGL Speaking.", new Vector2(5, 40), "#55F", "oblique small-caps bold 16px IndieFlower Lobster Serif");
}

PlayState.prototype.willAppear = function () {
    "use strict";

    Log.info("A Play State will soon appear.", this);
}

PlayState.prototype.willDisappear = function () {
    "use strict";

    Log.info("A Play State will soon disappear.", this);
}

PlayState.prototype.toString = function () {
    "use strict";
    return "PlayState";
}

function PlayState(playerPos) {
    "use strict";

    var self = this;
    var charSprite = new Sprite("img/char_S0.png", function() {
        var charColl = new CollisionBody(charSprite.size);
        self.char = new Entity(playerPos, charColl, charSprite);
    });
}

// Subclass the GameState class.
PlayState.prototype = GameState.prototype;

PlayState.prototype.update = function (deltaTime) {
    "use strict";
}

PlayState.prototype.render = function (screen) {
    "use strict";

    this.char.render(screen);

    screen.renderText("Hello World!", new Vector2(5, 20));
    screen.renderText("This is OpenJGL Speaking.", new Vector2(5, 40), 16, "#55F", "oblique small-caps bold IndieFlower Lobster Serif");
}

PlayState.prototype.willAppear = function () {
    "use strict";

    Log.info("A Play State will soon appear.", this);
}

PlayState.prototype.willDisappear = function () {
    "use strict";

    Log.info("A Play State will soon disappear.", this);
}

PlayState.prototype.toString = function () {
    "use strict";
    return "PlayState";
}

Update rendering for new renderText method


import Validator from 'validatorjs';

export default {
    props: {
        valid: {
            type: Boolean,
            default: true,
            twoWay: true
        },
        dirty: {
            type: Boolean,
            default: false,
            twoWay: true
        },
        hideValidationErrors: {
            type: Boolean,
            default: false
        },
        validationRules: String,
        validationMessages: Object
    },

    data() {
        return {
            validationError: ''
        };
    },

    events: {
        'ui-input::set-validity': function(valid, error, id) {
            // Abort if event isn't meant for this component
            if (!this.eventTargetsComponent(id)) {
                return;
            }

            this.setValidity(valid, error);
        }
    },

    methods: {
        validate() {
            if (!this.validationRules || !this.dirty) {
                return;
            }

            let data = {
                value: this.value
            };

            let rules = {
                value: this.validationRules
            };

            let validation = new Validator(data, rules, this.validationMessages);

            validation.setAttributeNames({ value: this.name.replace(/_/g, ' ') });

            this.setValidity(validation.passes(), validation.errors.first('value'));
        },

        setValidity(valid, error) {
            this.valid = valid;

            if (!valid && error && error.length) {
                this.validationError = error;
            }
        }
    }
};

import Validator from 'validatorjs';

export default {
    props: {
        valid: {
            type: Boolean,
            default: true,
            twoWay: true
        },
        dirty: {
            type: Boolean,
            default: false,
            twoWay: true
        },
        hideValidationErrors: {
            type: Boolean,
            default: false
        },
        validationRules: [String, Array],
        validationMessages: Object
    },

    data() {
        return {
            validationError: ''
        };
    },

    events: {
        'ui-input::set-validity': function(valid, error, id) {
            // Abort if event isn't meant for this component
            if (!this.eventTargetsComponent(id)) {
                return;
            }

            this.setValidity(valid, error);
        }
    },

    methods: {
        validate() {
            if (!this.validationRules || !this.dirty) {
                return;
            }

            let data = {
                value: this.value
            };

            let rules = {
                value: this.validationRules
            };

            let validation = new Validator(data, rules, this.validationMessages);

            validation.setAttributeNames({ value: this.name.replace(/_/g, ' ') });

            this.setValidity(validation.passes(), validation.errors.first('value'));
        },

        setValidity(valid, error) {
            this.valid = valid;

            if (!valid && error && error.length) {
                this.validationError = error;
            }
        }
    }
};

Update validation-rules prop to accept Array in addition to String


//from: https://github.com/auth0/jwt-decode/blob/master/lib/index.js
import { base64UrlDecode } from './-base64-url-decode';

export function jwt_decode(token) {
  if (typeof token !== 'string') {
    throw new Error('Invalid token specified');
  }

  return JSON.parse(base64UrlDecode(token.split('.')[1]));
}

//from: https://github.com/auth0/jwt-decode/blob/master/lib/index.js
import { base64UrlDecode } from './-base64-url-decode';

export function jwt_decode(token) {
  if (typeof token !== 'string') {
    throw new Error('Invalid token specified');
  }

  var tokenParts = token.split('.');
  if (tokenParts.length !== 3) {
    throw new Error('Invalid token specified');
  }

  return JSON.parse(base64UrlDecode(tokenParts[1]));
}

Validate token parts before decoding.

Validate token parts before decoding.


angular.module("app").controller("DiagnosticsDialogController",
				 function($scope, $mdDialog, roslib) {

  var OK = 0;
  var WARN = 1;
  var ERROR = 2;
  var STALE = 3;

  var diagnostics_callback = function(diagnostics) {
      $scope.diagnostics = diagnostics;
      console.log(diagnostics);
  };
  var diagnostics_sub = roslib.subscribe("/diagnostics_agg", "diagnostic_msgs/DiagnosticArray", diagnostics_callback);
  $scope.hide = function() {
    $mdDialog.hide();
  };
  $scope.cancel = function() {
    $mdDialog.cancel();
  };
  $scope.answer = function(answer) {
    $mdDialog.hide(answer);
  };
  $scope.statusLevelToColor = function(level) {
      if(level === OK) {
	  return "green";
      }
      else if(level === WARN) {
	  return "yellow";
      }
      else if(level === STALE) {
	  return "blue";
      }
      else {
	  return "red";
      }
  };
  $scope.statusLevelToSymbol = function(level) {
      if(level === OK) {
	  return "\u2714";
      }
      else if(level === WARN) {
	  return "\u2757";
      }
      else if(level === STALE) {
	  return "\u2753";
      }
      else {
	  return "\u2716";
      }
  };
});

angular.module("app").controller("DiagnosticsDialogController",
				 function($scope, $mdDialog, roslib) {

  var OK = 0;
  var WARN = 1;
  var ERROR = 2;
  var STALE = 3;

  var diagnostics_callback = function(diagnostics) {
      $scope.diagnostics = diagnostics;
      console.log(diagnostics);
  };
  var diagnostics_sub = roslib.subscribe("/diagnostics_agg", "diagnostic_msgs/DiagnosticArray", diagnostics_callback);
  $scope.hide = function() {
    $mdDialog.hide();
  };
  $scope.cancel = function() {
    $mdDialog.cancel();
  };
  $scope.answer = function(answer) {
    $mdDialog.hide(answer);
  };
  $scope.statusLevelToColor = function(level) {
      if(level === OK) {
	  return "green";
      }
      else if(level === WARN) {
	  return "orange";
      }
      else if(level === STALE) {
	  return "blue";
      }
      else {
	  return "red";
      }
  };
  $scope.statusLevelToSymbol = function(level) {
      if(level === OK) {
	  return "\u2714";
      }
      else if(level === WARN) {
	  return "\u2757";
      }
      else if(level === STALE) {
	  return "\u2753";
      }
      else {
	  return "\u2716";
      }
  };
});

Make diagnostics warning color more visible


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

var chai = require('chai');
var expect = chai.expect;

describe('capitalize', function() {
	it('capitalizes single words', function() {
		expect(capitalize('express')).to.equal('Express');
		expect(capitalize('cats')).to.equal('Cats');
	});

	it('makes the rest of the string lowercase', function() {
		expect(capitalize('javaScript')).to.equal('Javascript');
	});

	it('leaves empty strings alone', function() {
		expect(capitalize('')).to.equal('');
	});

	it('leaves strings with no words alone', function() {
		expect(capitalize(' ')).to.equal(' ');
		expect(capitalize('123')).to.equal('123');
	});

	it('capitalizes multiple-word strings', function() {
		expect(capitalize('what is Express')).to.equal('What is express');
		expect(capitalize('i love lamp')).to.equal('I love lamp');
	});

	it('leaves already-capitalized words alone', function() {
		expect(capitalize('Express')).to.equal('Express');
		expect(capitalize('Evan')).to.equal('Evan');
		expect(capitalize('Catman')).to.equal('Catman');
	});
});

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

var chai = require('chai');
var expect = chai.expect;

describe('capitalize', function() {
	it('capitalizes single words', function() {
		expect(capitalize('express')).to.equal('Express');
		expect(capitalize('cats')).to.equal('Cats');
	});

	it('makes the rest of the string lowercase', function() {
		expect(capitalize('javaScript')).to.equal('Javascript');
	});

	it('leaves empty strings alone', function() {
		expect(capitalize('')).to.equal('');
	});

	it('leaves strings with no words alone', function() {
		expect(capitalize(' ')).to.equal(' ');
		expect(capitalize('123')).to.equal('123');
	});

	it('capitalizes multiple-word strings', function() {
		expect(capitalize('what is Express')).to.equal('What is express');
		expect(capitalize('i love lamp')).to.equal('I love lamp');
	});

	it('leaves already-capitalized words alone', function() {
		expect(capitalize('Express')).to.equal('Express');
		expect(capitalize('Evan')).to.equal('Evan');
		expect(capitalize('Catman')).to.equal('Catman');
	});

	it('capitalizes String objects without changing their values', function() {
		var str = new String('who is JavaScript?');
		expect(capitalize(str)).to.equal('Who is javascript?');
		expect(str.valueOf()).to.equal('who is JavaScript?');
	});
});

Test for String Object and value mutation of the same


Add minimized version of updated script.


import React from 'react';
import styles from '../../css/app.css';
export default class Application extends React.Component {
	constructor( props, context ) {
		super( props, context );
	}
	render() {
		return (

Past ebin header placeholder

					{this.props.children}

 Footer placeholder

		);
	}
}

import React from 'react';
import styles from '../../css/app.css';
import {
	Link
}
from 'react-router';
export default class Application extends React.Component {
	constructor( props, context ) {
		super( props, context );
	}
	render() {
		return (

					<Link to="/">Past ebin</Link>

					{this.props.children}

 Footer placeholder

		);
	}
}

Add link back to home page to pastes, change h1 to just 'Past ebin'


import _ from 'lodash'
import axios from 'axios'
import moment from 'moment'
import Vue from 'vue'
import {assert, expect} from 'chai'
import moxios from 'moxios'

// Emulate browser globals
global._ = _;
global.axios = axios;
global.moment = moment;
global.Vue = Vue;

// Fail if there's an unhandled promise rejection warning.
process.on('unhandledRejection', (error, promise) => {
    console.error('Unhandled promise rejection', {error, promise})
    process.exit(1);
});

//
require('./Structures/Model.spec.js');
require('./Structures/Collection.spec.js')

//
require('./Validation/rule.spec.js')
require('./Validation/rules.spec.js')
require('./Validation/messages.spec.js')

//
require('./HTTP/ProxyResponse.spec.js')

//
require('./Errors/RequestError.spec.js')
require('./Errors/ResponseError.spec.js')
require('./Errors/ValidationError.spec.js')

import _ from 'lodash'
import axios from 'axios'
import moment from 'moment'
import Vue from 'vue'
import {assert, expect} from 'chai'
import moxios from 'moxios'

// Emulate browser globals
global._ = _;
global.axios = axios;
global.moment = moment;
global.Vue = Vue;

// Fail if there's an unhandled promise rejection warning.
process.on('unhandledRejection', (error, promise) => {
    console.error('Unhandled promise rejection', {error, promise})
    process.exit(1);
});

// Structures
require('./Structures/Model.spec.js');
require('./Structures/Collection.spec.js')

// Validation
require('./Validation/Rule.spec.js')
require('./Validation/Rules.spec.js')
require('./Validation/Messages.spec.js')

// HTTP
require('./HTTP/ProxyResponse.spec.js')

// Errors
require('./Errors/RequestError.spec.js')
require('./Errors/ResponseError.spec.js')
require('./Errors/ValidationError.spec.js')

Fix another path case inconsistency

Fix another path case inconsistency


var text = "hello,this is a bad sentence.";

var punctuation = ",.!;";

for (var i = 0; i < text.length; i++) {
  if (punctuation.indexOf(text[i]) > -1) {
    if ((text[i+1] != " ") && (i != text.length-1)) {
      console.log("Pedant: punctuation error at index " + (i+1) + ": " + text);
    }
  }
}

var text = "'The quick brown,fox jumped over the lazy dog, he said, as he noticed that he forgot to close the quote.";
var MAX_QUOTE_LENGTH = 20;

var punctuation = ",.!;";
var quotes = "\"\'";
for (var i = 0; i < text.length; i++) {

    // check for punctuation
    if (punctuation.indexOf(text[i]) > -1) {
        if ((text[i + 1] != " ") && (i != text.length - 1)) {
            console.log("punctuation error at index " + i + ":");
            var error = showPrettyError(text, i);
            console.log(error[0]);
            console.log(error[1]);
            console.log("====================");
        }
    }

    // check for missing quotes
    if (quotes.indexOf(text[i]) > -1) {
        var k = 0;
        for (j = 1; j < text.length; j++) {
            if (quotes.indexOf(text[j]) == -1) {
                k++;
            }
        }

        if (k > MAX_QUOTE_LENGTH) {
            console.log("max quote length of " + MAX_QUOTE_LENGTH + " exceeded at index " + j + " (quote started at index " + i + ") :");
            var error = showPrettyError(text, j);
            console.log(error[0]);
            console.log(error[1]);
            console.log("====================");
        }

    }
}

function showPrettyError(text, index) {
    var contextAmount = 8;
    var showContextSegment = "...";
    return [
        showContextSegment + text.substr(index - contextAmount, index + contextAmount) + showContextSegment,
        pad(Math.max(index + 1 - contextAmount, index + 1), "^", " ").substr(index - contextAmount - showContextSegment.length)
    ];

    //http://stackoverflow.com/a/15660515
    function pad(width, string, padding) {
        return (width <= string.length) ? string : pad(width, padding + string, padding);
    }

}

Check for missing closing quotes; print errors


var isFunction = require('lodash/lang/isFunction');
var dispatcher = require('focus').dispatcher;
module.exports = {
    /**
     * Register the cartridge.
     */
    _registerCartridge: function registerCartridge(){
      this.cartridgeConfiguration = this.cartridgeConfiguration || this.props.cartridgeConfiguration;
      if(!isFunction(this.cartridgeConfiguration)){
        this.cartridgeConfiguration = function cartridgeConfiguration(){
          return {};
        };
        console.warn(`
          Your detail page does not have any cartrige configuration, this is not mandarory but recommended.
          It should be a component attribute return by a function.
          function cartridgeConfiguration(){
            var cartridgeConfiguration = {
              summary: {component: "A React Component", props: {id: this.props.id}},
              cartridge: {component: "A React Component"},
              actions: {components: "react actions"}
            };
            return cartridgeConfiguration;
          }
        `);
      }
      var cartridgeConf = this.cartridgeConfiguration();
      dispatcher.handleViewAction({
        data: {
          cartridgeComponent: cartridgeConf.cartridge,
          summaryComponent: cartridgeConf.summary,
          actions: cartridgeConf.actions
        },
        type: 'update'
      });
    },
    componentWillMount: function pageMixinWillMount(){
      this._registerCartridge();
    }
};

var isFunction = require('lodash/lang/isFunction');
var dispatcher = require('focus').dispatcher;
var Empty = require('../../common/empty').component;
module.exports = {
    /**
     * Register the cartridge.
     */
    _registerCartridge: function registerCartridge(){
      this.cartridgeConfiguration = this.cartridgeConfiguration || this.props.cartridgeConfiguration;
      if(!isFunction(this.cartridgeConfiguration)){
        this.cartridgeConfiguration = function cartridgeConfiguration(){
          return {};
        };
        console.warn(`
          Your detail page does not have any cartrige configuration, this is not mandarory but recommended.
          It should be a component attribute return by a function.
          function cartridgeConfiguration(){
            var cartridgeConfiguration = {
              summary: {component: "A React Component", props: {id: this.props.id}},
              cartridge: {component: "A React Component"},
              actions: {components: "react actions"}
            };
            return cartridgeConfiguration;
          }
        `);
      }
      var cartridgeConf = this.cartridgeConfiguration();
      dispatcher.handleViewAction({
        data: {
          cartridgeComponent: cartridgeConf.cartridge || {component: Empty},
          summaryComponent: cartridgeConf.summary|| {component: Empty},
          actions: cartridgeConf.actions|| {primary: [], secondary: Empty},
          barContentLeftComponent: cartridgeConf.barLeft || {component: Empty}
        },
        type: 'update'
      });
    },
    componentWillMount: function pageMixinWillMount(){
      this._registerCartridge();
    }
};

[page] Add the cartrige left compoennt in the mixin.


import assert from "assert";
import { introspectStarwars } from './introspectStarwars';
import { initTemplateStringTransformer } from '../src/index';
import fs from 'fs';
import path from 'path';

// Uncomment the below to generate a new schema JSON
// describe("graphql", () => {
//   it("can introspect star wars", async () => {
//     const result = await introspectStarwars();
//
//     fs.writeFileSync(path.join(__dirname, "starwars.json"),
//       JSON.stringify(result, null, 2));
//
//     assert.ok(result.data);
//     assert.ok(result.data.__schema);
//   });
// });

describe("runtime query transformer", () => {
  it("can be initialized with an introspected query", async () => {
    const result = await introspectStarwars();
    const transformer = initTemplateStringTransformer(result.data);
  });

  it("can compile a Relay.QL query", () => {
    Relay.QL`
      query HeroNameQuery {
        hero {
          name
        }
      }
    `;
  });

  it("can transform a simple query", async () => {
    const result = await introspectStarwars();
    const transformer = initTemplateStringTransformer(result.data);
    const transformed = transformer(`
      query HeroNameQuery {
        hero {
          name
        }
      }
    `);

    const expected = Relay.QL`
      query HeroNameQuery {
        hero {
          name
        }
      }
    `;

    assert.deepEqual(transformed, expected);
  });
});

import assert from "assert";
import { introspectStarwars } from './introspectStarwars';
import { initTemplateStringTransformer } from '../src/index';
import fs from 'fs';
import path from 'path';

// Uncomment the below to generate a new schema JSON
// describe("graphql", () => {
//   it("can introspect star wars", async () => {
//     const result = await introspectStarwars();
//
//     fs.writeFileSync(path.join(__dirname, "starwars.json"),
//       JSON.stringify(result, null, 2));
//
//     assert.ok(result.data);
//     assert.ok(result.data.__schema);
//   });
// });

describe("runtime query transformer", () => {
  it("can be initialized with an introspected query", async () => {
    const result = await introspectStarwars();
    const transformer = initTemplateStringTransformer(result.data);
  });

  it("can compile a Relay.QL query", () => {
    Relay.QL`
      query HeroNameQuery {
        hero {
          name
        }
      }
    `;
  });

  it("can transform a simple query", async () => {
    const result = await introspectStarwars();
    const transformer = initTemplateStringTransformer(result.data);
    const transformed = transformer(`
      query HeroNameAndFriendsQuery {
        hero {
          id
          name
          friends {
            name
          }
        }
      }
    `);

    const expected = Relay.QL`
      query HeroNameAndFriendsQuery {
        hero {
          id
          name
          friends {
            name
          }
        }
      }
    `;

    assert.deepEqual(transformed, expected);
  });
});

Make query slightly more complex

Make query slightly more complex


/* ************************************************************************

   coretest

   Copyright:
     2010 Deutsche Telekom AG, Germany, http://telekom.com

 ************************************************************************ */

/* ************************************************************************

#asset(coretest/*)

************************************************************************ */

core.Env.define("application", "coretest.Application");

/**
 * Unify application class
 */
core.Class("coretest.Application",
{
  include : [unify.Application],

  members :
  {
    // overridden
    main : function()
    {
      // Call super class
      unify.Application.prototype.main.call(this);

      // Configure application
      document.title = "coretest";

      // Create view managers
      var MasterViewManager = new unify.view.ViewManager("master");

      // Register your view classes...
      MasterViewManager.register(coretest.view.Start, true);
      MasterViewManager.register(coretest.view.Test);
      MasterViewManager.register(coretest.view.OtherTest);

      // Add TabViews or SplitViews...
      var TabView = new unify.view.TabViewManager(MasterViewManager);
      TabView.register(coretest.view.Start);
      TabView.register(coretest.view.Test);

      // Add view manager (or SplitView or TabView) to the root
      this.add(TabView);
      //this.add(MasterViewManager);

      // Add at least one view manager to the navigation managment
      var Navigation = unify.view.Navigation.getInstance();
      Navigation.register(MasterViewManager);
      Navigation.init();
    },

    _getTheme : function() {
      return new unify.theme.Dark();
    }
  }
});

/* ************************************************************************

   coretest

   Copyright:
     2010 Deutsche Telekom AG, Germany, http://telekom.com

 ************************************************************************ */

/* ************************************************************************

#asset(coretest/*)

************************************************************************ */

/**
 * Unify application class
 */
core.Class("coretest.Application",
{
  include : [unify.Application],

  members :
  {
    // overridden
    main : function()
    {
      // Call super class
      unify.Application.prototype.main.call(this);

      // Configure application
      document.title = "coretest";

      // Create view managers
      var MasterViewManager = new unify.view.ViewManager("master");

      // Register your view classes...
      MasterViewManager.register(coretest.view.Start, true);
      MasterViewManager.register(coretest.view.Test);
      MasterViewManager.register(coretest.view.OtherTest);

      // Add TabViews or SplitViews...
      var TabView = new unify.view.TabViewManager(MasterViewManager);
      TabView.register(coretest.view.Start);
      TabView.register(coretest.view.Test);

      // Add view manager (or SplitView or TabView) to the root
      this.add(TabView);
      //this.add(MasterViewManager);

      // Add at least one view manager to the navigation managment
      var Navigation = unify.view.Navigation.getInstance();
      Navigation.register(MasterViewManager);
      Navigation.init();
    },

    _getTheme : function() {
      return new unify.theme.Dark();
    }
  }
});

Remove manual setting of application environment


import { get, set } from '@ember/object';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed, observer } from '@ember/object';
import { htmlSafe } from '@ember/string';
import C from 'ui/utils/constants';
import { on } from '@ember/object/evented';

export default Component.extend({
  intl:                service(),

  comparisonObserver: on('init', observer('model.metricRule.comparison', function() {
    if (get(this, 'model.metricRule.comparison') === get(this, 'hasValue')) {
      set(this, 'model.metricRule.thresholdValue', null)
    } else {
      set(this, 'model.metricRule.thresholdValue', 0)
    }
  })),

  verbStyles: computed('model._targetType', function() {
    const targetType = get(this, 'model._targetType');
    const arr = ['pod', 'workload', 'workloadSelector', 'node', 'nodeSelector']

    let out = '';

    if (arr.includes(targetType)) {
      out = `padding-top: 6px;`;
    }

    return htmlSafe(out);
  }),

  operatorContent: computed(function() {
    return Object.values(C.ALERTING_COMPARISON).map((value) => {
      return {
        label: get(this, 'intl').t(`alertPage.comparison.${ value }`),
        value,
      }
    })
  }),

  hasValue:            C.ALERTING_COMPARISON.HAS_VALUE,
  durationContent:     C.ALERT_DURATION,

});

import { get, set } from '@ember/object';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed, observer } from '@ember/object';
import { htmlSafe } from '@ember/string';
import C from 'ui/utils/constants';
import { on } from '@ember/object/evented';

export default Component.extend({
  intl:                service(),

  comparisonObserver: on('init', observer('model.metricRule.comparison', function() {
    if (get(this, 'model.metricRule.comparison') === get(this, 'hasValue')) {
      set(this, 'model.metricRule.thresholdValue', null)
    }
  })),

  verbStyles: computed('model._targetType', function() {
    const targetType = get(this, 'model._targetType');
    const arr = ['pod', 'workload', 'workloadSelector', 'node', 'nodeSelector']

    let out = '';

    if (arr.includes(targetType)) {
      out = `padding-top: 6px;`;
    }

    return htmlSafe(out);
  }),

  operatorContent: computed(function() {
    return Object.values(C.ALERTING_COMPARISON).map((value) => {
      return {
        label: get(this, 'intl').t(`alertPage.comparison.${ value }`),
        value,
      }
    })
  }),

  hasValue:            C.ALERTING_COMPARISON.HAS_VALUE,
  durationContent:     C.ALERT_DURATION,

});

Fix threshold is reset when edit alert rule

https://github.com/rancher/rancher/issues/22210


'use strict';

var expect = require('chai').expect,
    fs     = require('fs'),
    uncss  = require('../lib/uncss');

describe('Using globbing patterns', function () {

    it('should find both index pages in the directory and return the used CSS for both of them', function (done) {
        this.timeout(25000);

        uncss(['tests/glob/**/*.html'], function (err, output) {
            expect(err).to.be.null;
            expect(output).to.exist;
            expect(output).to.contain('h1');
            expect(output).to.contain('h2');
            expect(output).not.to.contain('h3');
            expect(output).not.to.contain('h4');
            expect(output).not.to.contain('h5');
            expect(output).not.to.contain('h6');
            done();
        });
    });
});

'use strict';

var expect = require('chai').expect,
    uncss  = require('../lib/uncss');

describe('Using globbing patterns', function () {

    it('should find both index pages in the directory and return the used CSS for both of them', function (done) {
        this.timeout(25000);

        uncss(['tests/glob/**/*.html'], function (err, output) {
            expect(err).to.be.null;
            expect(output).to.exist;
            expect(output).to.contain('h1');
            expect(output).to.contain('h2');
            expect(output).not.to.contain('h3');
            expect(output).not.to.contain('h4');
            expect(output).not.to.contain('h5');
            expect(output).not.to.contain('h6');
            done();
        });
    });
});

Remove fs from test dependencies.

Remove fs from test dependencies.


var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
//var models = require("./models");

var PORT = process.env.PORT || 3000;

//models.sequelize.sync().then(function () {

  io.on('connection', function(client) {
    console.log('Someone connected!');

    client.on('join', function(data) {
      if(data === 'This is your teacher speaking') {
        client.emit('greeting', 'Hiya, Teach!');
      } else{
        client.emit('greeting', 'Hello, student. Please wait for your instructor to open a new poll.');
      }
    });

    client.on('newPoll', function(data) {
      io.sockets.emit('openPoll', data);
    });

    client.on('disconnect', function(client) {
      console.log('Bye!\n');
    });
  });

  require('./config/routes.js')(app, express, io);

  server.listen(PORT, function (){
    console.log('listening on port', PORT);
  });

// };

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
//var models = require("./models");

var PORT = process.env.PORT || 3000;

//models.sequelize.sync().then(function () {
  require('./config/routes.js')(app, express, io);

  server.listen(PORT, function (){
    console.log('listening on port', PORT);
  });

// };

Remove socket test code, push io object to routes


'use strict'

var path = require('path')
var createTransform = require('./transform')

module.exports = function degreePlugin (browserify, options) {
  browserify.transform(createTransform(options.files.map(resolve)))

  function resolve (file) {
    return path.resolve(browserify.basedir || process.cwd(), file)
  }
}

'use strict'

var createTransform = require('./transform')

module.exports = function degreePlugin (browserify, options) {
  browserify.transform(createTransform(options.files.map(resolve)))

  function resolve (file) {
    return require.resolve(browserify.basedir || process.cwd(), file)
  }
}

Use require.resolve to turn partial filenames or '.' into full names


import { default as React } from 'react';
import en from './en';
import es from './es';

const locales = {en, es};

export default function translate(key) {
    return Component => {
        class TranslationComponent extends React.Component {

            componentWillMount() {
                let strings = locales[this.context.locale]['Framework7'];
                nekunoApp.params.modalTitle = strings.modalTitle;
                nekunoApp.params.modalButtonOk = strings.modalButtonOk;
                nekunoApp.params.modalButtonCancel = strings.modalButtonCancel;
            }

            render() {
                var strings = locales[this.context.locale][key];
                const merged = {
                    ...this.props.strings,
                    ...strings
                };
                if (strings) {
                    return <Component {...this.props} strings={merged} locale={this.context.locale}/>;
                } else {
                    return <Component {...this.props} locale={this.context.locale}/>;
                }

            }
        }

        TranslationComponent.contextTypes = {
            locale: React.PropTypes.string
        };

        return TranslationComponent;
    };
}

import { default as React } from 'react';
import en from './en';
import es from './es';

const locales = {en, es};

export default function translate(key) {
    return Component => {
        class TranslationComponent extends React.Component {

            componentWillMount() {
                let strings = locales[this.context.locale]['Framework7'];
                nekunoApp.params.modalTitle = strings.modalTitle;
                nekunoApp.params.modalButtonOk = strings.modalButtonOk;
                nekunoApp.params.modalButtonCancel = strings.modalButtonCancel;
            }

            // TranslationComponent receives ref from parent, so this is a wrapper to use children methods.
            getSelectedFilter() {
                let filter = null;
                Object.keys(this.refs).forEach(function(value){
                    if (typeof this.refs[value].getSelectedFilter === 'function'){
                        filter = this.refs[value].getSelectedFilter();
                    }
                }, this);

                return filter;
            }

            selectedFilterContains(a) {
                let contains = null;
                Object.keys(this.refs).forEach(function(value){
                    if (typeof this.refs[value].selectedFilterContains === 'function'){
                        contains = this.refs[value].selectedFilterContains(a);
                    }
                }, this);

                return contains;
            }

            render() {
                var strings = locales[this.context.locale][key];
                const merged = {
                    ...this.props.strings,
                    ...strings
                };
                if (strings) {
                    return <Component {...this.props} ref={Date.now()} strings={merged} locale={this.context.locale}/>;
                } else {
                    return <Component {...this.props} ref={Date.now()} locale={this.context.locale}/>;
                }

            }
        }

        TranslationComponent.contextTypes = {
            locale: React.PropTypes.string
        };

        return TranslationComponent;
    };
}

Access translated components by ref

QS-1001: Access translated components by ref


var PATH = require('path'),

    pjoin = PATH.join,
    presolve = PATH.resolve.bind(null, __dirname),

    PRJ_ROOT = presolve('../../'),

    PRJ_TECHS = presolve('../techs/');

exports.getTechs = function() {

    return {
        'bemjson.js'    : '',
        'bemdecl.js'    : 'bemdecl.js',
        'deps.js'       : 'deps.js',
        'js'            : 'js-i',
        'css'           : 'css',
        'ie.css'        : 'ie.css',
        'ie6.css'       : 'ie6.css',
        'ie7.css'       : 'ie7.css',
        'ie8.css'       : 'ie8.css',
        'ie9.css'       : 'ie9.css',

        'bemhtml'       : pjoin(PRJ_ROOT, 'bemhtml/.bem/techs/bemhtml.js'),
        'html'          : pjoin(PRJ_ROOT, 'bemhtml/.bem/techs/html.js')
    };

};

// Do not create any techs files during bundle creation by default
exports.defaultTechs = [];

var PATH = require('path'),

    pjoin = PATH.join,
    presolve = PATH.resolve.bind(null, __dirname),

    PRJ_ROOT = presolve('../../'),

    PRJ_TECHS = presolve('../techs/');

exports.getTechs = function() {

    return {
        'bemjson.js'    : '',
        'bemdecl.js'    : 'bemdecl.js',
        'deps.js'       : 'deps.js',
        'js'            : 'js-i',
        'css'           : 'css',
        'ie.css'        : 'ie.css',
        'ie6.css'       : 'ie6.css',
        'ie7.css'       : 'ie7.css',
        'ie8.css'       : 'ie8.css',
        'ie9.css'       : 'ie9.css',

        'bemhtml'       : pjoin(PRJ_ROOT, 'bemhtml/.bem/techs/bemhtml.js'),
        'html'          : pjoin(PRJ_ROOT, 'bemhtml/.bem/techs/bemjson2html.js')
    };

};

// Do not create any techs files during bundle creation by default
exports.defaultTechs = [];

Support rename html tech to bemjson2html


angular
    .module('app')
    .controller('apiController', [
        '$rootScope',
        '$scope',
        '$location',
        '$routeParams',
        'authService',
        'MARLINAPI_CONFIG',
        function($rootScope, $scope, $location, $routeParams, Auth, MARLINAPI_CONFIG) {

            $scope.documentationPage = function() {

                $scope.api_base = MARLINAPI_CONFIG.base_url;

            };

        }
    ]);

angular
    .module('app')
    .controller('apiController', [
        '$rootScope',
        '$scope',
        '$location',
        '$routeParams',
        'authService',
        'MARLINAPI_CONFIG',
        function($rootScope, $scope, $location, $routeParams, Auth, MARLINAPI_CONFIG) {

            $scope.documentationPage = function() {

                $scope.api_base = MARLINAPI_CONFIG.base_url.replace('api', 'public_api');

            };

        }

    ]);

Fix link to api and public api.

Fix link to api and public api.


import { directive } from 'lit-html/lit-html.js'

/*
 * Convert an RGB-Array into a Hex color
 */
export const rgbToHex = (value, defaultValue = '#000000') => directive(part => {
    // Is an RGB array
    if (Array.isArray(value) && value.length === 3) {
        const hex = `#${value.map(x => x.toString(16).padStart(2, '0')).join('')}`
        part.setValue(hex)
    // Is not an RGB array, so use the defaultValue
    } else {
        part.setValue(defaultValue)
    }
})

import { directive } from 'lit-html/lit-html.js'

/*
 * Convert an RGB-Array into a Hex color
 */
export const rgbToHex = directive((value, defaultValue = '#000000') => part => {
  // Is an RGB array
  if (Array.isArray(value) && value.length === 3) {
      const hex = `#${value.map(x => x.toString(16).padStart(2, '0')).join('')}`
      part.setValue(hex)
  // Is not an RGB array, so use the defaultValue
  } else {
      part.setValue(defaultValue)
  }
})

Convert to new lit-html standard

fix(directive): Convert to new lit-html standard


const {Record} = require('immutable');

const MonitorRecord = Record({
    id: null, // Block Id
    /** Present only if the monitor is sprite-specific, such as x position */
    spriteName: null,
    /** Present only if the monitor is sprite-specific, such as x position */
    targetId: null,
    opcode: null,
    value: null,
    params: null,
    mode: 'default',
    sliderMin: 0,
    sliderMax: 100,
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    visible: true
});

module.exports = MonitorRecord;

const {Record} = require('immutable');

const MonitorRecord = Record({
    id: null, // Block Id
    /** Present only if the monitor is sprite-specific, such as x position */
    spriteName: null,
    /** Present only if the monitor is sprite-specific, such as x position */
    targetId: null,
    opcode: null,
    value: null,
    params: null,
    mode: 'default',
    sliderMin: 0,
    sliderMax: 100,
    x: null, // (x: null, y: null) Indicates that the monitor should be auto-positioned
    y: null,
    width: 0,
    height: 0,
    visible: true
});

module.exports = MonitorRecord;

Update for auto-positioning monitors so that having just one of x or y be 0 (e.g. a monitor placed in the top right corner of the stage) does not result in the monitor being treated as a new monitor and get auto-positioned.


'use strict';

angular.module('kanbanBoardApp')
  .controller('BoardCtrl', ['$scope', 'Task', 'Project', 'Workspace', 'Tag', 'WORKSPACE_ID', 'PROJECT_ID', function ($scope, Task, Project, Workspace, Tag, WORKSPACE_ID, PROJECT_ID) {
    $scope.tags = [];
    var tagsLoaded = false;

    $scope.tagsLoaded = function () {
      return tagsLoaded;
    };

    $scope.loadTags = function () {
      Workspace.get({path: 'tags'}, function (response) {
        $scope.tags = response.data;
        tagsLoaded = true;
      });
    };

    $scope.getPointTags = function (tags) {
      return tags.filter( function (tag) {
        if (tag.name.match(/points/)) {
          return tag;
        }
      });
    };

    $scope.tagPointValue = function (tag) {
      return tag.name.replace(/[^\d+]/g, '');
    }
  }]);

'use strict';

angular.module('kanbanBoardApp')
  .controller('BoardCtrl', ['$scope', 'Task', 'Project', 'Workspace', 'Tag', 'WORKSPACE_ID', 'PROJECT_ID', function ($scope, Task, Project, Workspace, Tag, WORKSPACE_ID, PROJECT_ID) {
    $scope.tags = [];
    var tagsLoaded = false;

    $scope.tagsLoaded = function () {
      return tagsLoaded;
    };

    $scope.loadTags = function () {
      Workspace.get({path: 'tags'}, function (response) {
        $scope.tags = response.data;
        tagsLoaded = true;
      });
    };

    $scope.getPointTags = function (tags) {
      return tags.filter( function (tag) {
        if (tag.name.match(/points/)) {
          return tag;
        }
      });
    };

    $scope.tagPointValue = function (tag) {
      return parseInt(tag.name.replace(/[^\d+]/g, ''));
    }
  }]);

Return the point as a number.

Return the point as a number.


import builder from 'xmlbuilder';
import kebabCase from 'lodash/kebabCase';

// custom stringify options for xml builder
// just kebab-cases all attributes and tag names
const customStringifyOptions = {
    eleName(val = '') {
        return this.assertLegalChar(kebabCase(val));
    },

    attName(val = '') {
        return kebabCase(val);
    },
};

/**
 * Recursively turns jsx children into xml nodes
 * @param {Array} children
 * @param {XMLNode} node
 */
function renderNode(node, children = []) {
    Array.from(children).forEach(child => {
        if (child && child.tag) {
            node.ele(child.tag, child.props);
            renderNode(child.children, node);
            node.end();
        } else {
            node.text(child);
        }
    });
}

/**
 * Nested JSON to pretty string
 * @param {Object} data
 * @return {String}
 */
export default function renderToString({ tag, children }, options = {}) {
    if (tag !== 'speak') {
        throw new Error(`SSML must start with a 'speak' tag, currently '${tag}'`);
    }

    const xml = builder.create(tag, {
        stringify: customStringifyOptions,
        headless: true,
    });

    renderNode(xml, children);

    return xml.end(options);
}

import builder from 'xmlbuilder';
import kebabCase from 'lodash/kebabCase';

// custom stringify options for xml builder
// just kebab-cases all attributes and tag names
const customStringifyOptions = {
    eleName(val = '') {
        return this.assertLegalChar(kebabCase(val));
    },

    attName(val = '') {
        return kebabCase(val);
    },
};

/**
 * Recursively turns jsx children into xml nodes
 * @param {Array} children
 * @param {XMLNode} node
 */
function renderNode(node, children = []) {
    [...children].forEach(child => {
        if (child && child.tag) {
            node.ele(child.tag, child.props);
            renderNode(child.children, node);
            node.end();
        } else {
            node.text(child);
        }
    });
}

/**
 * Nested JSON to pretty string
 * @param {Object} data
 * @return {String}
 */
export default function renderToString({ tag, children }, options = {}) {
    if (tag !== 'speak') {
        throw new Error(`SSML must start with a 'speak' tag, currently '${tag}'`);
    }

    const xml = builder.create(tag, {
        stringify: customStringifyOptions,
        headless: true,
    });

    renderNode(xml, children);

    return xml.end(options);
}

Use a spread instead of Array.from

Use a spread instead of Array.from


'use strict';

const authentication = require('feathers-authentication');
const jwt = require('feathers-authentication-jwt');
<% if(strategies.indexOf('local') !== -1) { %>const local = require('feathers-authentication-local');<% } %>
<% if(oauthProviders.length){ %>const oauth2 = require('feathers-authentication-oauth2');<% } %>
<% oauthProviders.forEach(provider => { %>
const <%= provider.strategyName %> = require('<%= provider.module %>');
<% }); %>

module.exports = function() {
  const app = this;
  const config = app.get('authentication');

  // Set up authentication with the secret
  app.configure(authentication(config));
  app.configure(jwt());
  <% if(strategies.indexOf('local') !== -1) { %>
  app.configure(local());
  <% } %>
  <% oauthProviders.forEach(provider => { %>
  app.configure(oauth2(Object.assign({
    name: '<%= provider.name %>',
    Strategy: <%= provider.strategyName %>
  }, config.<%= provider.name %>)));
  <% }); %>

  // The `authentication` service is used to create a JWT.
  // The before `create` hook registers strategies that can be used
  // to create a new valid JWT (e.g. local or oauth2)
  app.service('authentication').hooks({
    before: {
      create: [
        authentication.hooks.authenticate(config.strategies)
      ],
      remove: [
        authentication.hooks.authenticate('jwt')
      ]
    }
  });
};

'use strict';

const authentication = require('feathers-authentication');
const jwt = require('feathers-authentication-jwt');
<% if(strategies.indexOf('local') !== -1) { %>const local = require('feathers-authentication-local');<% } %>
<% if(oauthProviders.length){ %>const oauth2 = require('feathers-authentication-oauth2');<% } %>
<% oauthProviders.forEach(provider => { %>
const <%= provider.strategyName %> = require('<%= provider.module %>');
<% }); %>

module.exports = function() {
  const app = this;
  const config = app.get('authentication');

  // Set up authentication with the secret
  app.configure(authentication(config));
  app.configure(jwt());
  <% if(strategies.indexOf('local') !== -1) { %>
  app.configure(local());
  <% } %>
  <% oauthProviders.forEach(provider => { %>
  app.configure(oauth2(Object.assign({
    name: '<%= provider.name %>',
    Strategy: <%= provider.strategyName %>,
    successRedirect: '/'
  }, config.<%= provider.name %>)));
  <% }); %>

  // The `authentication` service is used to create a JWT.
  // The before `create` hook registers strategies that can be used
  // to create a new valid JWT (e.g. local or oauth2)
  app.service('authentication').hooks({
    before: {
      create: [
        authentication.hooks.authenticate(config.strategies)
      ],
      remove: [
        authentication.hooks.authenticate('jwt')
      ]
    }
  });
};

Add a successRedirect by default

Add a successRedirect by default

It makes more sense to have a successRedirect by default.  This way the user doesn’t see naked JSON in the auth response.


module.exports = {
  server: function(primus, options) {
    primus.on('connection', function(spark) {
      spark.hostname = spark.request.headers.host.split(':')[0];
    });
  }
};

module.exports = {
  server: function(primus, options) {
    var url = require('url');
    primus.on('connection', function(spark) {
      spark.hostname = url.parse(
        spark.request.headers.origin ||
        spark.request.headers.host
      ).hostname;
    });
  }
};

Fix domain detection in ws request

Fix domain detection in ws request


var express = require('express');
var app = express();

app.get('/', function (req, res) {
	res.send('Destroy all humans!');
});

var server = app.listen(3000, function () {
	var port = server.address().port;
	console.log('Fired up at http://localhost:%s, baby', port);
});

var express = require('express');
var app = express();

app.get('/', function (req, res) {
	res.send('Destroy all humans!');
});

app.get('/game', function (req, res) {
	var game = {
		game: 'Destroy all humans!'
	};
	res.send(game);
});

var server = app.listen(3000, function () {
	var port = server.address().port;
	console.log('Fired up at http://localhost:%s, baby', port);
	console.log('Try http://localhost:%s/', port);
	console.log('Try http://localhost:%s/game', port);
});

Add route that responds with json

Add route that responds with json


var CELOS_USER = "celos";

var CELOS_DEFAULT_OOZIE = "http://admin1.ny7.collective-media.net:11000/oozie";

var CELOS_DEFAULT_HDFS = "hdfs://nameservice1";

var NAME_NODE = CELOS_DEFAULT_HDFS;

var JOB_TRACKER = "admin1.ny7.collective-media.net:8032";

var HIVE_METASTORE = "thrift://admin1.ny7.collective-media.net:9083";

var CELOS_DEFAULT_OOZIE_PROPERTIES = {
    "user.name": CELOS_USER,
    "jobTracker" : JOB_TRACKER,
    "nameNode" : CELOS_DEFAULT_HDFS,
    "hiveMetastore": HIVE_METASTORE,
    "oozie.use.system.libpath": "true"
};

var CELOS_USER = "celos";

var CELOS_DEFAULT_OOZIE = "http://oozie002.ny7.collective-media.net:11000/oozie";

var CELOS_DEFAULT_HDFS = "hdfs://nameservice1";

var NAME_NODE = CELOS_DEFAULT_HDFS;

var JOB_TRACKER = "admin1.ny7.collective-media.net:8032";

var HIVE_METASTORE = "thrift://hive-meta.ny7.collective-media.net:9803";

var CELOS_DEFAULT_OOZIE_PROPERTIES = {
    "user.name": CELOS_USER,
    "jobTracker" : JOB_TRACKER,
    "nameNode" : CELOS_DEFAULT_HDFS,
    "hiveMetastore": HIVE_METASTORE,
    "oozie.use.system.libpath": "true"
};

Update Oozie and Hive URLs.

Update Oozie and Hive URLs.


import toolbox from 'sw-toolbox';

/* global process */
toolbox.options.debug = (process.env.NODE_ENV !== 'production');

toolbox.precache([
  '/service-worker.js',
  '/index.html',
  '/app.js',
  '/web-worker.js',
  '/manifest.json',
]);

/* global Request */
toolbox.router.get('/(.*)', (request, values, options) => {
  return toolbox.networkFirst(request, values, options).catch(() => {
    return toolbox.cacheOnly(new Request('/index.html'), values, options);
  });
}, {
  origin: /localhost:8080$/,
});

toolbox.router.any('/(.*)', toolbox.networkOnly, {
  origin: /localhost:3000$/,
});

toolbox.router.get('/(.*)', toolbox.cacheFirst, {
  origin: /\.(googleapis|gstatic)\.com$/,
  cache: {
    name: 'googleapis',
  },
});

(sw => {
  sw.addEventListener('activate', event => {
    event.waitUntil(self.clients.claim());
  });
})(self); /* global self */

import toolbox from 'sw-toolbox';

const { Request, Response } = self; /* global self */

const statics = [
  '/service-worker.js',
  '/index.html',
  '/app.js',
  '/web-worker.js',
  '/manifest.json',
];
const exts = statics.map(name => name.slice(name.lastIndexOf('.')));
const extRegex = new RegExp(`(${exts.join('|')})$`, 'i');

// Cache static assets.
toolbox.precache(statics);

// Enable debug mode and suppress sockjs-node request errors.
if (process.env.NODE_ENV !== 'production') { /* global process */
  toolbox.options.debug = true;

  toolbox.router.get('/sockjs-node/*', (request, values, options) => {
    return toolbox.networkOnly(request, values, options)
                  .catch(() => new Response());
  });
}

// Redirect SPA subroute requests to index.
toolbox.router.get('/*', (request, values, options) => {
  // Do not redirect static asset requests.
  if (request.url.match(extRegex)) {
    // TODO: Maybe use `fastest` when in production for faster app startup?
    return toolbox.networkFirst(request, values, options)
                  .catch(() => new Response());
  }

  // TODO: Maybe use `fastest` here? Why rely on the server for route redirects?
  return toolbox.networkFirst(request, values, options).catch(() => {
    return toolbox.cacheOnly(new Request('/index.html'), values, options)
                  .catch(() => new Response());
  });
}, {
  origin: /localhost:8080$/,
  cache: {
    name: 'statics',
  },
});

// Cache Google fonts and icons.
// TODO: Maybe use `cacheFirst` with additional `cache.maxAgeSeconds` here in
// order to not fire off network requests to Google on every startup?
toolbox.router.get('/*', toolbox.fastest, {
  origin: /\.(googleapis|gstatic)\.com$/,
  cache: {
    name: 'googleapis',
  },
});

Change some service worker caching behavior. * Ignore socket requests when in development. * Use fastest for google assets. * Add some todos to think about.


export default {
    getReadWidget:   () => '<ma-choices-column values="::entry.listValues[field.name()]"></ma-choices-column>',
    getLinkWidget:   () => '<ma-reference-many-link-column ids="::value" values="::entry.listValues[field.name()]" field="::field"></ma-reference-many-link-column>',
    getFilterWidget: () => '<ma-reference-many-field field="::field" value="value" datastore="::datastore"></reference-many-field-field>',
    getWriteWidget:  () => '<ma-reference-many-field field="::field" value="value" datastore="::datastore"></ma-reference-many-field>'
};

export default {
    getReadWidget:   () => '<ma-choices-column values="::entry.listValues[field.name()]"></ma-choices-column>',
    getLinkWidget:   () => '<ma-reference-many-link-column ids="::value" values="::entry.listValues[field.name()]" field="::field"></ma-reference-many-link-column>',
    getFilterWidget: () => '<ma-reference-many-field field="::field" value="value" datastore="::datastore"></ma-reference-many-field>',
    getWriteWidget:  () => '<ma-reference-many-field field="::field" value="value" datastore="::datastore"></ma-reference-many-field>'
};

Fix wrong closing tag in reference_many filter

Refs #905


'use strict';

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

function compile( ctor ) {
	var name;
	var str;

	name = ctor.match( /^(\w*)Array$/ )[ 1 ];
	name = name + 'DataArray';

	str = '';
	str += '(function create(){';
	str += '"use strict";';
	str += 'class '+name+' extends '+ctor+'{';
	str += 'constructor(x){';
	str += 'super(x);';
	str += '}';
	str += '}';
	str += 'return '+name+';';
	str += '})();';
	return str;
}

var ctors;
var fcn;
var i;

ctors = [
	'Int8Array',
	'Uint8Array',
	'Uint8ClampedArray',
	'Int16Array',
	'Uint16Array',
	'Int32Array',
	'Uint32Array',
	'Float32Array',
	'Float64Array',
	'Array'
];

for ( i = 0; i < ctors.length; i++ ) {
	fcn = evil( compile( ctors[i] ) );
	console.log( fcn.toString() );
}

'use strict';

var hasClass = require( '@stdlib/utils/detect-class-support' )();
var evil = require( './../lib' );

function compile( ctor ) {
	var name;
	var str;

	name = ctor.match( /^(\w*)Array$/ )[ 1 ];
	name = name + 'DataArray';

	str = '';
	str += '(function create(){';
	str += '"use strict";';

	if ( hasClass ) {
		str += 'class '+name+' extends '+ctor+'{';
		str += 'constructor(x){';
		str += 'super(x);';
		str += '}';
		str += '}';
	} else {
		str += 'function '+name+'(){';
		str += 'if (!(this instanceof '+name+')){';
		str += 'return new '+name+'();';
		str += '}';
		str += 'ctor.call(this);';
		str += 'return this;';
		str += '}';
		str += name+'.prototype = Object.create('+ctor+'.prototype);';
		str += name+'.prototype.constructor = '+name+';';
	}
	str += 'return '+name+';';
	str += '})();';
	return str;
}

var ctors;
var fcn;
var i;

ctors = [
	'Int8Array',
	'Uint8Array',
	'Uint8ClampedArray',
	'Int16Array',
	'Uint16Array',
	'Int32Array',
	'Uint32Array',
	'Float32Array',
	'Float64Array',
	'Array'
];

for ( i = 0; i < ctors.length; i++ ) {
	fcn = evil( compile( ctors[i] ) );
	console.log( fcn.toString() );
}

Fix example to work on Node v1 and earlier


import DockerContainer from './DockerContainer.js'
import { checkDockerDaemon } from '../../../utils/index.js'

export default class DockerRunner {
  #codeDir = null
  #container = null

  constructor(funOptions, env, dockerOptions) {
    const {
      codeDir,
      functionKey,
      handler,
      runtime,
      layers,
      provider,
    } = funOptions

    this.#codeDir = codeDir
    if (
      dockerOptions.hostServicePath &&
      this.#codeDir === funOptions.servicePath
    ) {
      this.#codeDir = dockerOptions.hostServicePath
    }
    this.#container = new DockerContainer(
      env,
      functionKey,
      handler,
      runtime,
      layers,
      provider,
      dockerOptions,
    )
  }

  cleanup() {
    if (this.#container) {
      return this.#container.stop()
    }

    return undefined
  }

  // context will be generated in container
  async run(event) {
    // FIXME TODO this should run only once -> static private
    await checkDockerDaemon()

    if (!this.#container.isRunning) {
      await this.#container.start(this.#codeDir)
    }

    return this.#container.request(event)
  }
}

import DockerContainer from './DockerContainer.js'
import { checkDockerDaemon } from '../../../utils/index.js'

export default class DockerRunner {
  #codeDir = null
  #container = null

  constructor(funOptions, env, dockerOptions) {
    const {
      codeDir,
      functionKey,
      handler,
      runtime,
      layers,
      provider,
      servicePath,
    } = funOptions

    this.#codeDir = codeDir
    if (
      dockerOptions.hostServicePath &&
      this.#codeDir.startsWith(servicePath)
    ) {
      this.#codeDir = this.#codeDir.replace(
        servicePath,
        dockerOptions.hostServicePath,
      )
    }
    this.#container = new DockerContainer(
      env,
      functionKey,
      handler,
      runtime,
      layers,
      provider,
      dockerOptions,
    )
  }

  cleanup() {
    if (this.#container) {
      return this.#container.stop()
    }

    return undefined
  }

  // context will be generated in container
  async run(event) {
    // FIXME TODO this should run only once -> static private
    await checkDockerDaemon()

    if (!this.#container.isRunning) {
      await this.#container.start(this.#codeDir)
    }

    return this.#container.request(event)
  }
}

Fix code dir for docker container

Fix code dir for docker container


import React from 'react';
import PropTypes from 'prop-types';
import { createPortal } from 'react-dom';
import { canUseDOM } from './utils';

class Portal extends React.Component {
  componentWillUnmount() {
    if (this.defaultNode) {
      document.body.removeChild(this.defaultNode);
    }
    this.defaultNode = null;
  }

  render() {
    if (!canUseDOM) {
      return null;
    }
    if (!this.props.node && !this.defaultNode) {
      this.defaultNode = document.createElement('div');
      document.body.appendChild(this.defaultNode);
    }
    return createPortal(
      this.props.children,
      this.props.node || this.defaultNode
    );
  }
}

Portal.propTypes = {
  children: PropTypes.node.isRequired,
  node: PropTypes.any
};

export default Portal;

import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { canUseDOM } from './utils';

class Portal extends React.Component {
  componentWillUnmount() {
    if (this.defaultNode) {
      document.body.removeChild(this.defaultNode);
    }
    this.defaultNode = null;
  }

  render() {
    if (!canUseDOM) {
      return null;
    }
    if (!this.props.node && !this.defaultNode) {
      this.defaultNode = document.createElement('div');
      document.body.appendChild(this.defaultNode);
    }
    return ReactDOM.createPortal(
      this.props.children,
      this.props.node || this.defaultNode
    );
  }
}

Portal.propTypes = {
  children: PropTypes.node.isRequired,
  node: PropTypes.any
};

export default Portal;

Fix portal import from react-dom

Fix portal import from react-dom


// function to create the singleton options object that can be shared
// throughout an application
function createurlQueryConfig() {
  // default options
  return {
    // add in generated URL change handlers based on a urlPropsQueryConfig if provided
    addUrlChangeHandlers: true,

    // add in `props.params` from react-router to the url object
    addRouterParams: true,

    // use this history if no history is specified
    history: {
      push() {
        // eslint-disable-next-line
        console.error('No history provided to react-url-query. Please provide one via configureUrlQuery.');
      },
      replace() {
        // eslint-disable-next-line
        console.error('No history provided to react-url-query. Please provide one via configureUrlQuery.');
      },
    },

    // reads in location from react-router-redux if available and passes it
    // to the reducer in the urlQueryMiddleware
    readLocationFromStore(state) {
      if (state && state.routing) {
        return state.routing.locationBeforeTransitions;
      }

      return undefined;
    },
  };
}

export default createurlQueryConfig();

// function to create the singleton options object that can be shared
// throughout an application
function createurlQueryConfig() {
  // default options
  return {
    // add in generated URL change handlers based on a urlPropsQueryConfig if provided
    addUrlChangeHandlers: true,

    // add in `props.params` from react-router to the url object
    addRouterParams: true,

    // function to specify change handler name (onChange<PropName>)
    changeHandlerName: propName => `onChange${propName[0].toUpperCase()}${propName.substring(1)}`,

    // use this history if no history is specified
    history: {
      push() {
        // eslint-disable-next-line
        console.error('No history provided to react-url-query. Please provide one via configureUrlQuery.');
      },
      replace() {
        // eslint-disable-next-line
        console.error('No history provided to react-url-query. Please provide one via configureUrlQuery.');
      },
    },

    // reads in location from react-router-redux if available and passes it
    // to the reducer in the urlQueryMiddleware
    readLocationFromStore(state) {
      if (state && state.routing) {
        return state.routing.locationBeforeTransitions;
      }

      return undefined;
    },
  };
}

export default createurlQueryConfig();

Add default value for changeHandlerName to config


const { resolve, join } = require("path");
const { IgnorePlugin } = require("webpack");
const path = require("path");

const moduleRoot = resolve(__dirname, "..");
const outputPath = join(moduleRoot, "dist");

module.exports = {
  mode: "production",
  entry: join(moduleRoot, "src", "index.js"),
  target: "node",
  devtool: "source-map",
  output: {
    path: outputPath,
    filename: "index.js",
    library: "truffle-hdwallet-provider",
    libraryTarget: "umd",
    umdNamedDefine: true
  },
  externals: ["fs", "bindings", "any-promise"],
  resolve: {
    alias: {
      // eth-block-tracker is es6 but automatically builds an es5 version for us on install. thanks eth-block-tracker!
      "eth-block-tracker": "eth-block-tracker/dist/es5/index.js",

      // replace native `scrypt` module with pure js `js-scrypt`
      "scrypt": "js-scrypt",

      // replace native `secp256k1` with pure js `elliptic.js`
      "secp256k1": "secp256k1/elliptic.js",

      // fix websocket require path
      "websocket": path.resolve(__dirname, "../")
    }
  },
  plugins: [
    // ignore these plugins completely
    new IgnorePlugin(/^(?:electron|ws)$/)
  ]
};

const { resolve, join } = require("path");
const { IgnorePlugin } = require("webpack");
const path = require("path");

const moduleRoot = resolve(__dirname, "..");
const outputPath = join(moduleRoot, "dist");

module.exports = {
  mode: "production",
  entry: join(moduleRoot, "src", "index.js"),
  target: "node",
  devtool: "source-map",
  output: {
    path: outputPath,
    filename: "index.js",
    library: "truffle-hdwallet-provider",
    libraryTarget: "umd",
    umdNamedDefine: true
  },
  externals: ["fs", "bindings", "any-promise", "websocket"],
  resolve: {
    alias: {
      // eth-block-tracker is es6 but automatically builds an es5 version for us on install. thanks eth-block-tracker!
      "eth-block-tracker": "eth-block-tracker/dist/es5/index.js",

      // replace native `scrypt` module with pure js `js-scrypt`
      "scrypt": "js-scrypt",

      // replace native `secp256k1` with pure js `elliptic.js`
      "secp256k1": "secp256k1/elliptic.js",
    }
  },
  plugins: [
    // ignore these plugins completely
    new IgnorePlugin(/^(?:electron|ws)$/)
  ]
};

Mark websocket as external for webpack

Mark websocket as external for webpack


// on click of a tag, it should be toggled - either added to or removed from an internal tracking
// array and its style changed.
//
// When the internal array changes, it should write out a new tag list to the hidden input

(function($) {
  $(document).ready(function() {
    // TODO this line assumes one tag field and that it is named as 'tags' -
    // this is too fragile
    $(".taggit-labels").closest("div").each(function(i) {
      var inputs = $(this).find(".taggit-labels + input")[0];
      var tagItems = $(this).find("ul.tags li");
      var tagList = inputs.value.split(", ");
      tagItems.click(function() {
        var tagList = inputs.value.split(", ");
        var tagName = $(this).attr("data-tag-name");

        // Tag names need to be quotes if they contain commas or quotation marks
        if(tagName.indexOf(",") != -1 || tagName.indexOf(" ") != -1) {
          tagName = "\"" + tagName + "\"";
        }

        var index = $.inArray(tagName, tagList);
        // Add the selected tag to the list of tags if it wasn't there previously
        // and remove it if it was present.
        if(index == -1) {
          $(this).toggleClass("selected");
          tagList.push(tagName);
        } else {
           $(this).toggleClass("selected");
           tagList.splice(index, 1);
        }

        // Refresh the tag list
        $(inputs).attr("value", tagList.join(", "));
      });
    });
  });
})(django.jQuery);

// on click of a tag, it should be toggled - either added to or removed from an internal tracking
// array and its style changed.
//
// When the internal array changes, it should write out a new tag list to the hidden input

(function($) {
  $(document).ready(function() {
    $(".taggit-labels").closest("div").each(function(i) {
      var inputs = $(this).find(".taggit-labels + input")[0];
      var tagItems = $(this).find("ul.tags li");
      var tagList = inputs.value.split(", ");
      tagItems.click(function() {
        var tagList = inputs.value.split(", ");
        var tagName = $(this).attr("data-tag-name");

        // Tag names need to be quotes if they contain commas or quotation marks
        if(tagName.indexOf(",") != -1 || tagName.indexOf(" ") != -1) {
          tagName = "\"" + tagName + "\"";
        }

        var index = $.inArray(tagName, tagList);
        // Add the selected tag to the list of tags if it wasn't there previously
        // and remove it if it was present.
        if(index == -1) {
          $(this).toggleClass("selected");
          tagList.push(tagName);
        } else {
           $(this).toggleClass("selected");
           tagList.splice(index, 1);
        }

        // Refresh the tag list
        $(inputs).attr("value", tagList.join(", "));
      });
    });
  });
})(django.jQuery);

Remove comment about former functionality


import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { primary } from '@artsy/reaction-force/dist/Assets/Fonts'

const propTypes = {
  title: PropTypes.string,
  href: PropTypes.string,
  image: PropTypes.object
}

const Container = styled.div`
  position: relative;
  overflow: hidden;
`

const GeneLink = styled.a`
  position: absolute;
  left: 1em;
  bottom: 1em;
  text-decoration: none;

  color: white;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.7);

  ${primary.style} font-size: 13px;
  line-height: 1.33em;
  font-weight: bold;
`

const GeneImage = styled.img`width: 90%;`

const FeaturedGene = ({ title, href, image: { url: imageSrc } }) => {
  return (
    <Container>
      <GeneLink href={href}>{title}</GeneLink>
      <GeneImage src={imageSrc} />
    </Container>
  )
}

FeaturedGene.propTypes = propTypes

export default FeaturedGene

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { primary } from '@artsy/reaction-force/dist/Assets/Fonts'

const propTypes = {
  title: PropTypes.string,
  href: PropTypes.string,
  image: PropTypes.object
}

const Container = styled.div`
  position: relative;
  width: 95%;
  overflow: hidden;
`

const GeneLink = styled.a`
  position: absolute;
  left: 1em;
  bottom: 1em;
  text-decoration: none;

  color: white;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.7);

  ${primary.style} font-size: 13px;
  line-height: 1.33em;
  font-weight: bold;
`

const GeneImage = styled.img`width: 100%;`

const FeaturedGene = ({ title, href, image: { url: imageSrc } }) => {
  return (
    <Container>
      <GeneLink href={href}>{title}</GeneLink>
      <GeneImage src={imageSrc} />
    </Container>
  )
}

FeaturedGene.propTypes = propTypes

export default FeaturedGene

Fix long featured gene captions which were overflowing thumbs


var expect = require('chai').expect;
var request = require('request');
var server = require('../server').server;

var connection;

describe('Server', function() {
  describe('presence', function() {

    beforeEach(function() {
      connection = server.listen(3000)
    });

    afterEach(function() {
      connection.close();
    });

    it('should have no users logged in', function() {
      expect(server.get('users')).to.be.empty;
    });

    it('should have foo logged in', function(done) {
      request.post('http://localhost:3000/signin', {form: {nick: 'foo'}}, function() {
        expect(server.get('users')).to.eql(['foo'])
        done();
      });
    });

    it('should have no users logged in', function(done) {
      request.post('http://localhost:3000/signin', {form: {nick: 'foo'}}, function() {
        request.post('http://localhost:3000/signout', {form: {nick: 'foo'}}, function() {
          expect(server.get('users')).to.be.empty;
          done();
        });
      });
    });
  });
});

var expect = require('chai').expect;
var request = require('request');
var server = require('../server').server;

var connection;

describe('Server', function() {
  describe('presence', function() {

    beforeEach(function() {
      connection = server.listen(3000);
    });

    afterEach(function() {
      connection.close();
    });

    it('should have no users logged in', function() {
      expect(server.get('users')).to.be.empty;
    });

    it('should have foo logged in', function(done) {
      request.post('http://localhost:3000/signin', {form: {nick: 'foo'}}, function() {
        expect(server.get('users')).to.eql(['foo']);
        done();
      });
    });

    it('should have no users logged in', function(done) {
      request.post('http://localhost:3000/signin', {form: {nick: 'foo'}}, function() {
        request.post('http://localhost:3000/signout', {form: {nick: 'foo'}}, function() {
          expect(server.get('users')).to.be.empty;
          done();
        });
      });
    });
  });
});

Fix a couple of minor syntax errors in the test


var prince = require("prince");
var open = require('open');
var fs = require('fs');

var SHOULD_OPEN = true;

fs.exists('dist/prince.log', function(exists) {
  if(exists) {
    console.log('[Prince] Deleting old log...');
    fs.unlink('dist/prince.log', function()
    {
      render();
    });
  }
  else
  {
    render();
  }
});

function render()
{
  console.log("[Prince] Generating PDF...")
  prince()
    .inputs("dist/index.html")
    .output("dist/index.pdf")
    .option("javascript")
    .option("log", "dist/prince.log")
    .execute()
    .then(function () {
      fs.readFile('dist/prince.log', 'utf8', function (err,data) {
        if (err) throw err;
        console.log(data);
        console.log("[Prince] Success!");
        if (SHOULD_OPEN)
        {
          open('file://' + __dirname + "/dist/index.pdf", function (err) {
            if (err) throw err;
            console.log("[Open] Browser window closed.");
          });
        }
      });
    }, function (error) {
      console.log("[Prince] ERROR: ", util.inspect(error));
    });
}

const prince = require("prince");
const open = require('open');
const fs = require('fs');
const exec = require('child_process').exec;

var SHOULD_OPEN = true;

fs.exists('dist/prince.log', function(exists) {
  if(exists) {
    console.log('[Prince] Deleting old log...');
    fs.unlink('dist/prince.log', function()
    {
      render();
    });
  }
  else
  {
    render();
  }
});

function render()
{
  console.log("[Prince] Generating PDF...")
  prince()
    .inputs("dist/index.html")
    .output("dist/index.pdf")
    .option("javascript")
    .option("log", "dist/prince.log")
    .execute()
    .then(function () {
      fs.readFile('dist/prince.log', 'utf8', function (err,data) {
        if (err) throw err;
        console.log(data);
        console.log("[Prince] Success!");
        rmPages(function()
        {
          if (SHOULD_OPEN)
          {
            open('file://' + __dirname + "/dist/output.pdf", function (err) {
              if (err) throw err;
              console.log("[Open] Browser window closed.");
            });
          }
        });
      });
    }, function (error) {
      console.log("[Prince] ERROR: ", util.inspect(error));
    });
}

function rmPages(cb)
{
  console.log("[PDFToolkit] Modifying PDF...");
  const child = exec('pdftk dist/index.pdf cat 3-end output dist/output.pdf dont_ask allow AllFeatures drop_xfa',
    (error, stdout, stderr) => {
    console.log(`[PDFToolkit] ${stdout}\r\n${stderr}`);
    if (error !== null) {
      throw error;
    }
    cb();
  });
}

Remove first two pages on build :)

Remove first two pages on build :)