<commit_before>// @flow
import { WIDE_BAR, NARROW_BAR, WIDE_SPACE, NARROW_SPACE } from "../Core/Characters"
import type {DiscreteSymbologySymbol} from "../Core/Characters"
import type {Barcode} from "../Core/Barcode"

// See https://en.wikipedia.org/wiki/Code_39
export const Mapping = {}
const BaseMapping = {}
const Bars = [
	[
		// 1
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 2
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 3
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 4
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 5
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 6
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 7
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
	],
	[
		// 8
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
	[
		// 9
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
	[
		// 10
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
]
const Spaces = [
	[
		// +0
		NARROW_SPACE,
		WIDE_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
	],
	[
		// +10
		NARROW_SPACE,
		NARROW_SPACE,
		WIDE_SPACE,
		NARROW_SPACE,
	],
	[
		// +20
		NARROW_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
		WIDE_SPACE,
	],
	[
		// +30
		WIDE_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
	],
]

function populate() {
	// Numbers
	for (let i = 1; i <= 9; i++) {
		BaseMapping[i.toString()] = [i - 1, 0]
	}
	BaseMapping["0"] = [9, 0]

	// A-J
	for (let i = "A".charCodeAt(0); i <= "J".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "A".charCodeAt(0), 1]
	}
	// K-T
	for (let i = "K".charCodeAt(0); i <= "T".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "K".charCodeAt(0), 2]
	}
	// U-Z
	for (let i = "U".charCodeAt(0); i <= "Z".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "U".charCodeAt(0), 3]
	}

	BaseMapping["-"] = [6, 3]
	BaseMapping["."] = [7, 3]
	BaseMapping[" "] = [8, 3]
	BaseMapping["*"] = [9, 3]
}

function map() {
	for (const key of Object.keys(BaseMapping)) {
		const bar = BaseMapping[key][0]
		const space = BaseMapping[key][1]

		const reduction = []

		for (let i = 0; i < Spaces[space].length; i++) {
			reduction.push(Bars[bar][i])
			reduction.push(Spaces[space][i])
		}
		reduction.push(Bars[bar][Bars[bar].length - 1])

		Mapping[key] = reduction.join("")
	}
}

populate()
map()

Mapping["+"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

Mapping["/"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

Mapping["$"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
].join("")

Mapping["%"] = [
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

export function encodeCode39(text: string, fallbackChar: string = "-"): Barcode<DiscreteSymbologySymbol> {
	if (!Mapping.hasOwnProperty(fallbackChar)) {
		fallbackChar = "-"
	}

	const encoded = (
		Mapping["*"] +
		NARROW_SPACE +
		text
			.toUpperCase()
			.split("")
			.map(it => (Mapping[it] ? Mapping[it] : Mapping[fallbackChar]))
			.map(it => it + NARROW_SPACE)
			.join("") +
		Mapping["*"]
	)

	return {
		encoded,
		plainTextContent: text,
	}
}
<commit_msg>Make Code39 return a Barcode<DiscreteSymbologySymbol><commit_after>// @flow
import { WIDE_BAR, NARROW_BAR, WIDE_SPACE, NARROW_SPACE } from "../Core/Characters"
import type { DiscreteSymbologySymbol } from "../Core/Characters"
import type { Barcode } from "../Core/Barcode"

// See https://en.wikipedia.org/wiki/Code_39
export const Mapping = {}
const BaseMapping = {}
const Bars = [
	[
		// 1
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 2
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 3
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 4
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
	],
	[
		// 5
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 6
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
	],
	[
		// 7
		NARROW_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
	],
	[
		// 8
		WIDE_BAR,
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
	[
		// 9
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
	[
		// 10
		NARROW_BAR,
		NARROW_BAR,
		WIDE_BAR,
		WIDE_BAR,
		NARROW_BAR,
	],
]
const Spaces = [
	[
		// +0
		NARROW_SPACE,
		WIDE_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
	],
	[
		// +10
		NARROW_SPACE,
		NARROW_SPACE,
		WIDE_SPACE,
		NARROW_SPACE,
	],
	[
		// +20
		NARROW_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
		WIDE_SPACE,
	],
	[
		// +30
		WIDE_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
		NARROW_SPACE,
	],
]

function populate() {
	// Numbers
	for (let i = 1; i <= 9; i++) {
		BaseMapping[i.toString()] = [i - 1, 0]
	}
	BaseMapping["0"] = [9, 0]

	// A-J
	for (let i = "A".charCodeAt(0); i <= "J".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "A".charCodeAt(0), 1]
	}
	// K-T
	for (let i = "K".charCodeAt(0); i <= "T".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "K".charCodeAt(0), 2]
	}
	// U-Z
	for (let i = "U".charCodeAt(0); i <= "Z".charCodeAt(0); i++) {
		BaseMapping[String.fromCharCode(i)] = [i - "U".charCodeAt(0), 3]
	}

	BaseMapping["-"] = [6, 3]
	BaseMapping["."] = [7, 3]
	BaseMapping[" "] = [8, 3]
	BaseMapping["*"] = [9, 3]
}

function map() {
	for (const key of Object.keys(BaseMapping)) {
		const bar = BaseMapping[key][0]
		const space = BaseMapping[key][1]

		const reduction = []

		for (let i = 0; i < Spaces[space].length; i++) {
			reduction.push(Bars[bar][i])
			reduction.push(Spaces[space][i])
		}
		reduction.push(Bars[bar][Bars[bar].length - 1])

		Mapping[key] = reduction.join("")
	}
}

populate()
map()

Mapping["+"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

Mapping["/"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

Mapping["$"] = [
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
].join("")

Mapping["%"] = [
	NARROW_BAR,
	NARROW_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
	WIDE_SPACE,
	NARROW_BAR,
].join("")

export function encodeCode39(text: string, fallbackChar: string = "-"): Barcode<DiscreteSymbologySymbol> {
	if (!Mapping.hasOwnProperty(fallbackChar)) {
		fallbackChar = "-"
	}

	const encoded =
		Mapping["*"] +
		NARROW_SPACE +
		text
			.toUpperCase()
			.split("")
			.map(it => (Mapping[it] ? Mapping[it] : Mapping[fallbackChar]))
			.map(it => it + NARROW_SPACE)
			.join("") +
		Mapping["*"]

	return {
		encoded,
		plainTextContent: text,
	}
}
<|endoftext|>


<commit_before>// DEPENDENCIES ===============================================================================

var gulp = require('gulp');
var gutil = require('gulp-util');
var bower = require('gulp-bower');
var tsd = require('gulp-tsd');
var ts = require('gulp-typescript');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var watch = require('gulp-watch');
var pipe = require('multipipe');
var less = require('gulp-less');
var mirror = require('gulp-mirror');
var rename = require('gulp-rename');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var livereload = require('gulp-livereload');
var tslint = require('gulp-tslint');
var inject = require('gulp-inject');
var uglify = require('gulp-uglify');
var minifyCSS = require('gulp-minify-css');
var gzip = require('gulp-gzip');
var stripDebug = require('gulp-strip-debug');

// CONSTANTS ===============================================================================

var paths = {
    bower: {
        jquery: './bower_components/jquery/dist/**/*.{js,map}'
    },
    source: {
        typescripts: '../src/main/resources/META-INF/resources/butterfaces-ts/**/*.ts',
        less: '../src/main/resources/META-INF/resources/butterfaces-less/*.less'
    },
    destination: {
        standard: '../src/main/resources/META-INF/resources//butterfaces-dist',
        bower: '../src/main/webapp/dist/bower'
    }
};

// DIST GOALS ===============================================================================

gulp.task('dist:_clean', function (cb) {
    del(paths.destination.standard, {force: true}, cb);
});

gulp.task('dist:_bower', function () {
    // https://github.com/bower/bower/issues/1019#issuecomment-52700170
    return bower({force: false})
        .pipe(gulp.dest('bower_components/'));
});

gulp.task('dist:_tslint', ['dist:_bower'], function () {
    return gulp.src(paths.source.typescripts)
        .pipe(tslint())
        .pipe(tslint.report('verbose'));
});

gulp.task('dist:_copyLibsToDist', ['dist:_bower'], function () {
    return gulp.src([
            './bower_components/jquery/dist/jquery.js',
            './bower_components/jquery/dist/jquery.min.js'
        ])
        .pipe(gulp.dest(paths.destination.standard + '/js/lib'));
});

//gulp.task('dist:_typescript', ['dist:_tslint', 'dist:_copyLibsToDist', 'dev:_tsd'], function () {
//gulp.task('dist:_typescript', ['dist:_tslint', 'dist:_copyLibsToDist', "dist:_copyFontsToDist"], function () {
gulp.task('dist:_typescript', ['dist:_tslint', 'dist:_copyLibsToDist'], function () {
    var tsResult = gulp.src(paths.source.typescripts)
        .pipe(ts({
            noImplicitAny: true
        }));

    return tsResult.js
        .pipe(concat('butterfaces.js'))
        .pipe(stripDebug())
        .pipe(mirror(
            pipe(
                rename(function (path) {
                    path.basename += ".min";
                }),
                uglify()
            )
        ))
        .pipe(gulp.dest(paths.destination.standard + '-js'));
});

gulp.task('dist:_less', function () {
    return gulp.src([paths.source.less])
        .pipe(less())
        .pipe(postcss([autoprefixer({browsers: ['> 2%']})]))
        .pipe(mirror(
            pipe(
                rename(function (path) {
                    path.basename += ".min";
                }),
                minifyCSS()
            )
        ))
        .pipe(gulp.dest(paths.destination.standard + '-css'));
});

gulp.task('dist:_compileRessources', ['dist:_less', 'dist:_typescript']);

gulp.task('gz-css-dist', ['dist:_compileRessources'], function () {
    return gulp.src([paths.destination.standard + '-css/**/*', paths.destination.standard + '-js/**/*', "!dist/**/*.gz"], {base: '.'})
            .pipe(gzip())
            .pipe(gulp.dest('.'));
});

// MAIN GOALS ===============================================================================

gulp.task('dist:build', ['dist:_compileRessources']);

gulp.task('default', ['dist:build']);<commit_msg>BUT-425 split typescript bundle and single<commit_after>// DEPENDENCIES ===============================================================================

var gulp = require('gulp');
var gutil = require('gulp-util');
var bower = require('gulp-bower');
var tsd = require('gulp-tsd');
var ts = require('gulp-typescript');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var watch = require('gulp-watch');
var pipe = require('multipipe');
var less = require('gulp-less');
var mirror = require('gulp-mirror');
var rename = require('gulp-rename');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var livereload = require('gulp-livereload');
var tslint = require('gulp-tslint');
var inject = require('gulp-inject');
var uglify = require('gulp-uglify');
var minifyCSS = require('gulp-minify-css');
var gzip = require('gulp-gzip');
var stripDebug = require('gulp-strip-debug');

// CONSTANTS ===============================================================================

var paths = {
    bower: {
        jquery: './bower_components/jquery/dist/**/*.{js,map}'
    },
    source: {
        typescripts: '../src/main/resources/META-INF/resources/butterfaces-ts/**/*.ts',
        less: '../src/main/resources/META-INF/resources/butterfaces-less/*.less'
    },
    destination: {
        standard: '../src/main/resources/META-INF/resources//butterfaces-dist',
        bower: '../src/main/webapp/dist/bower'
    }
};

// DIST GOALS ===============================================================================

gulp.task('dist:_clean', function (cb) {
    del(paths.destination.standard, {force: true}, cb);
});

gulp.task('dist:_bower', function () {
    // https://github.com/bower/bower/issues/1019#issuecomment-52700170
    return bower({force: false})
        .pipe(gulp.dest('bower_components/'));
});

gulp.task('dist:_tslint', ['dist:_bower'], function () {
    return gulp.src(paths.source.typescripts)
        .pipe(tslint())
        .pipe(tslint.report('verbose'));
});

gulp.task('dist:_copyLibsToDist', ['dist:_bower'], function () {
    return gulp.src([
            './bower_components/jquery/dist/jquery.js',
            './bower_components/jquery/dist/jquery.min.js'
        ])
        .pipe(gulp.dest(paths.destination.standard + '/js/lib'));
});

gulp.task('dist:_typescript_bundle', ['dist:_tslint', 'dist:_copyLibsToDist'], function () {
    var tsResult = gulp.src(paths.source.typescripts)
        .pipe(ts({
            noImplicitAny: true
        }));

    return tsResult.js
        .pipe(concat('butterfaces.js'))
        .pipe(stripDebug())
        .pipe(mirror(
            pipe(
                rename(function (path) {
                    path.basename += ".min";
                }),
                uglify()
            )
        ))
        .pipe(gulp.dest(paths.destination.standard + '-js'));
});

gulp.task('dist:_typescript_single', ['dist:_tslint', 'dist:_copyLibsToDist'], function () {
    var tsResult = gulp.src(paths.source.typescripts)
        .pipe(ts({
            noImplicitAny: true
        }));

    return tsResult.js
        .pipe(stripDebug())
        .pipe(mirror(
            pipe(
                rename(function (path) {
                    path.basename += ".min";
                }),
                uglify()
            )
        ))
        .pipe(gulp.dest(paths.destination.standard + '-js'));
});

gulp.task('dist:_less', function () {
    return gulp.src([paths.source.less])
        .pipe(less())
        .pipe(postcss([autoprefixer({browsers: ['> 2%']})]))
        .pipe(mirror(
            pipe(
                rename(function (path) {
                    path.basename += ".min";
                }),
                minifyCSS()
            )
        ))
        .pipe(gulp.dest(paths.destination.standard + '-css'));
});

gulp.task('dist:_compileRessources', ['dist:_less', 'dist:_typescript_bundle', 'dist:_typescript_single']);

gulp.task('gz-css-dist', ['dist:_compileRessources'], function () {
    return gulp.src([paths.destination.standard + '-css/**/*', paths.destination.standard + '-js/**/*', "!dist/**/*.gz"], {base: '.'})
            .pipe(gzip())
            .pipe(gulp.dest('.'));
});

// MAIN GOALS ===============================================================================

gulp.task('dist:build', ['dist:_compileRessources']);

gulp.task('default', ['dist:build']);<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redex/LICENSE

export function create(config, logger, context) {

   const that = {
   };

   function serviceLine(service) {
      logger.warn('service', service);
      if (service.status) {
         return '' + service.status + ' ' + service.name;
      } else {
         return service.name;
      }
   }

   async getReport() {
      let none = [], ok = [], critical = [], other = [];
      for (let [name, service] of context.stores.service.services) {
         if (!service.status) {
            none.push(service.name);
         } else if (service.status === 'OK') {
            ok.push(service.name);
         } else if (service.status === 'WARN') {
            critical.push(service.name);
         } else {
            lines.push(serverLine(service));
         }
      }
      return { none, ok, critical, other };
   }

   const those = {
      async getPublic() {
         return await getReport();
      },
      async start() {
         logger.info('started');
      },
      async end() {
      },
      async serviceReport() {
         let lines = [];
         let report = getReport();
         if (report.critical.length) {
            lines.push('WARN: ' + report.critical.join(' '));
         }
         if (report.ok.length) {
            lines.push('OK: ' + report.ok.join(' '));
         }
         if (report.none.length) {
            report.none.forEach(name => {
               lines.push('Unchecked: ' + report.none.join(' '));
            });
         }
         return lines;
      }
   };
   return those;
}
<commit_msg>update<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redex/LICENSE

export function create(config, logger, context) {

   const that = {
   };

   function serviceLine(service) {
      logger.warn('service', service);
      if (service.status) {
         return '' + service.status + ' ' + service.name;
      } else {
         return service.name;
      }
   }

   async function getReport() {
      let none = [], ok = [], critical = [], other = [];
      for (let [name, service] of context.stores.service.services) {
         if (!service.status) {
            none.push(service.name);
         } else if (service.status === 'OK') {
            ok.push(service.name);
         } else if (service.status === 'WARN') {
            critical.push(service.name);
         } else {
            lines.push(serverLine(service));
         }
      }
      return { none, ok, critical, other };
   }

   const those = {
      async getPublic() {
         return await getReport();
      },
      async start() {
         logger.info('started');
      },
      async end() {
      },
      async serviceReport() {
         let lines = [];
         let report = getReport();
         if (report.critical.length) {
            lines.push('WARN: ' + report.critical.join(' '));
         }
         if (report.ok.length) {
            lines.push('OK: ' + report.ok.join(' '));
         }
         if (report.none.length) {
            report.none.forEach(name => {
               lines.push('Unchecked: ' + report.none.join(' '));
            });
         }
         return lines;
      }
   };
   return those;
}
<|endoftext|>


<commit_before>const BotModule = require('../BotModule');

const messages = {
    boost: "<@{discordId}> Thanks for boosting!\nIf you would like to claim your in-game rank, please private message {upgrader} on the forums with the title \"Nitro role\" as well as your Discord Username and Discriminator ({username}#{discriminator})\n<{link}>"
}

module.exports = BotModule.extend({
    config: null,
    i18n: null,
    dependencies: {
        'config': 'config',
        'i18n': 'i18n'
    },

    initialize: function (dependencyGraph) {
        this._super(dependencyGraph);

        this.discordClient.on('guildMemberUpdate', this.checkNewBoost.bind(this));
    },

    /**
     * @param {GuildMember} oldMember
     * @param {GuildMember} newMember
     */
    checkNewBoost: function (oldMember, newMember) {
        if (oldMember.premiumSinceTimestamp !== null || newMember.premiumSinceTimestamp === null) {
            // If they were already premium, or they are not premium now - they didn't just get premium.
            // This is intended to be the inverse of `if (old.timestamp === null && new.timestamp !== null)`
            // in early to support an early exit
            return;
        }

        newMember.guild.channels.find(this.config.nitro.channel).send(
            this.i18n.__mf(
                messages.boost,
                {
                    discordId: newMember.user.id,
                    upgrader: this.config.nitro.manualUpgradeStaffer,
                    username: newMember.user.username,
                    discriminator: newMember.user.discriminator,
                    link: 'https://shotbow.net/forum/conversations/add?to=' + this.config.nitro.manualUpgradeStaffer
                }
            )
        )
    }
});
<commit_msg>Correct bug in booster thanking<commit_after>const BotModule = require('../BotModule');

const messages = {
    boost: "<@{discordId}> Thanks for boosting!\nIf you would like to claim your in-game rank, please private message {upgrader} on the forums with the title \"Nitro role\" as well as your Discord Username and Discriminator ({username}#{discriminator})\n<{link}>"
}

module.exports = BotModule.extend({
    config: null,
    i18n: null,
    dependencies: {
        'config': 'config',
        'i18n': 'i18n'
    },

    initialize: function (dependencyGraph) {
        this._super(dependencyGraph);

        this.discordClient.on('guildMemberUpdate', this.checkNewBoost.bind(this));
    },

    /**
     * @param {GuildMember} oldMember
     * @param {GuildMember} newMember
     */
    checkNewBoost: function (oldMember, newMember) {
        if (oldMember.premiumSinceTimestamp !== null || newMember.premiumSinceTimestamp === null) {
            // If they were already premium, or they are not premium now - they didn't just get premium.
            // This is intended to be the inverse of `if (old.timestamp === null && new.timestamp !== null)`
            // in early to support an early exit
            return;
        }

        newMember.guild.channels.cache.find(this.config.nitro.channel).send(
            this.i18n.__mf(
                messages.boost,
                {
                    discordId: newMember.user.id,
                    upgrader: this.config.nitro.manualUpgradeStaffer,
                    username: newMember.user.username,
                    discriminator: newMember.user.discriminator,
                    link: 'https://shotbow.net/forum/conversations/add?to=' + this.config.nitro.manualUpgradeStaffer
                }
            )
        )
    }
});
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'backbone',
    'jquery',
    'underscore',
    'find/app/page/search/filters/parametric/numeric-widget',
    'parametric-refinement/prettify-field-name',
    'parametric-refinement/selected-values-collection',
    'i18n!find/nls/bundle',
    'text!find/templates/app/page/search/filters/parametric/numeric-parametric-field-view.html'
], function (Backbone, $, _, numericWidget, prettifyFieldName, SelectedParametricValuesCollection, i18n, template) {
    "use strict";
    const DEFAULT_TARGET_NUMBER_OF_BUCKETS = 30;
    const GRAPH_HEIGHT = 110;
    const UPDATE_DEBOUNCE_WAIT_TIME = 1000;

    function getData(numericFieldValuesWithCount) {
        //noinspection JSUnresolvedFunction
        let minValue = Math.floor(_.first(numericFieldValuesWithCount).value);
        //noinspection JSUnresolvedFunction
        let maxValue = Math.ceil(_.last(numericFieldValuesWithCount).value);
        let bucketSize = Math.ceil((maxValue - minValue + 1) / DEFAULT_TARGET_NUMBER_OF_BUCKETS);
        let buckets = [];
        let valueIndex = 0;
        numericFieldValuesWithCount.forEach(function (valueAndCount) {
            let relativeValue = Math.floor(valueAndCount.value - minValue);
            while (valueIndex < relativeValue) {
                let currentBucketIndex = Math.floor(valueIndex / bucketSize);
                let value = minValue + valueIndex;
                if (buckets[currentBucketIndex]) {
                    buckets[currentBucketIndex].maxValue = value;
                } else {
                    buckets[currentBucketIndex] = {
                        count: 0,
                        minValue: value,
                        maxValue: value,
                        maxContinuousValue: value
                    };
                }

                valueIndex++;
            }

            let currentBucketIndex = Math.floor(valueIndex / bucketSize);
            let value = minValue + valueIndex;
            if (buckets[currentBucketIndex]) {
                buckets[currentBucketIndex].count += valueAndCount.count;
                buckets[currentBucketIndex].maxValue = value;
                buckets[currentBucketIndex].maxContinuousValue = valueAndCount.value;
            } else {
                buckets[currentBucketIndex] = {
                    count: valueAndCount.count,
                    minValue: value,
                    maxValue: value,
                    maxContinuousValue: valueAndCount.value
                };
            }
        });

        //noinspection JSUnresolvedFunction
        var counts = _.pluck(buckets, 'count');
        return {
            maxCount: Math.max.apply(Math, counts),
            minCount: Math.min.apply(Math, counts),
            bucketSize: bucketSize,
            buckets: buckets
        };
    }

    function resetSelectedParametricValues(selectedParametricValues, fieldName) {
        let existingRestrictions = selectedParametricValues.where({field: fieldName});
        existingRestrictions.forEach(function (model) {
            selectedParametricValues.remove(model);
        });
    }

    return Backbone.View.extend({
        className: 'animated fadeIn',
        template: _.template(template),

        events: {
            'click .numeric-parametric-no-min': function () {
                //noinspection JSUnresolvedVariable
                let $minInput = this.$minInput;
                //noinspection JSUnresolvedFunction
                this.executeCallbackWithoutRestrictions(function (result) {
                    //noinspection JSUnresolvedFunction
                    let minValue = Math.floor(_.first(result.values).value);
                    if (minValue !== $minInput.val()) {
                        $minInput.val(minValue);
                        $minInput.trigger('change');
                    }
                });
            },
            'click .numeric-parametric-no-max': function () {
                //noinspection JSUnresolvedVariable
                let $maxInput = this.$maxInput;
                //noinspection JSUnresolvedFunction
                this.executeCallbackWithoutRestrictions(function (result) {
                    //noinspection JSUnresolvedFunction
                    let maxValue = Math.ceil(_.last(result.values).value);
                    if (maxValue !== $maxInput.val()) {
                        $maxInput.val(maxValue);
                        $maxInput.trigger('change');
                    }
                });
            },
            'click .numeric-parametric-reset': function () {
                //noinspection JSUnresolvedVariable
                resetSelectedParametricValues(this.selectedParametricValues, this.fieldName);
            },
            'change .numeric-parametric-min-input': function () {
                //noinspection JSUnresolvedFunction,JSUnresolvedVariable
                this.updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, this.$minInput.val(), this.$maxInput.val());
            },
            'change .numeric-parametric-max-input': function () {
                //noinspection JSUnresolvedFunction,JSUnresolvedVariable
                this.updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, this.$minInput.val(), this.$maxInput.val());
            }
        },

        initialize: function (options) {
            this.queryModel = options.queryModel;
            this.selectedParametricValues = options.selectedParametricValues;
            this.viewWidth = options.viewWidth;
            this.fieldName = this.model.id;
            this.widget = numericWidget({
                graphHeight: GRAPH_HEIGHT
            });
        },

        render: function () {
            //noinspection JSUnresolvedVariable,JSUnresolvedFunction
            this.$el.empty().append(this.template({
                i18n: i18n,
                fieldName: prettifyFieldName(this.model.get('name')),
                id: _.uniqueId('numeric-parametric-field')
            }));

            //noinspection JSUnresolvedFunction
            this.$minInput = this.$('.numeric-parametric-min-input');
            //noinspection JSUnresolvedFunction
            this.$maxInput = this.$('.numeric-parametric-max-input');

            function roundInputNumber(x1) {
                return Math.round(x1 * 10) / 10;
            }

            //noinspection JSUnresolvedFunction
            this.executeCallbackWithoutRestrictions(_.bind(function (result) {
                let data = getData(result.values);

                //noinspection JSUnresolvedFunction
                let minValue = Math.floor(+_.first(result.values).value);
                //noinspection JSUnresolvedFunction
                let maxValue = Math.ceil(+_.last(result.values).value);

                //noinspection JSUnresolvedFunction
                this.$minInput.val(minValue);
                //noinspection JSUnresolvedFunction
                this.$maxInput.val(maxValue);

                //noinspection JSUnresolvedFunction
                let updateCallback = _.bind(function (x1, x2) {
                    // rounding to one decimal place
                    this.$minInput.val(roundInputNumber(x1));
                    this.$maxInput.val(roundInputNumber(x2));
                }, this);
                //noinspection JSUnresolvedFunction
                let selectionCallback = _.bind(function (x1, x2) {
                    let min = x1 || minValue;
                    let max = x2 || maxValue;
                    this.updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, min, max);
                }, this);
                //noinspection JSUnresolvedFunction
                let graph = this.widget.drawGraph({
                    chart: this.$('.chart')[0],
                    data: data,
                    updateCallback: updateCallback,
                    selectionCallback: selectionCallback,
                    xRange: this.viewWidth,
                    yRange: GRAPH_HEIGHT,
                    tooltip: i18n['search.numericParametricFields.tooltip']
                });

                this.selectedParametricValues.where({
                    field: this.fieldName
                }).forEach(function (restriction) {
                    let range = restriction.get('range');
                    if (range) {
                        //noinspection JSUnresolvedFunction
                        this.$minInput.val(roundInputNumber(range[0]));
                        //noinspection JSUnresolvedFunction
                        this.$maxInput.val(roundInputNumber(range[1]));

                        graph.selectionRect.init(graph.chart, GRAPH_HEIGHT, graph.scale.barWidth(range[0]));
                        graph.selectionRect.update(graph.scale.barWidth(range[1]));
                        graph.selectionRect.focus();
                    }
                }, this);
            }, this));
        },

        updateRestrictions: function (selectedParametricValues, fieldName, min, max) {
            resetSelectedParametricValues(selectedParametricValues, fieldName);
            selectedParametricValues.add({
                field: fieldName,
                range: [min, max]
            });
        },

        updateRestrictionsAfterDelay: function (selectedParametricValues, fieldName, min, max) {
            //noinspection JSUnresolvedFunction
            _.debounce(this.updateRestrictions, UPDATE_DEBOUNCE_WAIT_TIME)(selectedParametricValues, fieldName, min, max);
        },

        executeCallbackWithoutRestrictions: function (callback) {
            let fieldName = this.fieldName;
            let otherRestrictions = this.selectedParametricValues.filter(function (model) {
                return model.get('field') !== fieldName;
            });
            let clonedCollection = new SelectedParametricValuesCollection(otherRestrictions);
            $.ajax({
                    url: '../api/public/parametric/numeric',
                    traditional: true,
                    data: {
                        fieldNames: [fieldName],
                        databases: this.queryModel.get('indexes'),
                        queryText: this.queryModel.get('queryText'),
                        fieldText: clonedCollection.toFieldTextNode(),
                        minDate: this.queryModel.getIsoDate('minDate'),
                        maxDate: this.queryModel.getIsoDate('maxDate'),
                        stateTokens: this.queryModel.get('stateMatchIds')
                    }
                })
                .success(function (result) {
                    callback.apply(this, result);
                });
        }
    });
});<commit_msg>FIND-12 Numeric field search widget :: remove range restriction entirely when removing selection rectangle [rev. alex.scown]<commit_after>/*
 * Copyright 2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'backbone',
    'jquery',
    'underscore',
    'find/app/page/search/filters/parametric/numeric-widget',
    'parametric-refinement/prettify-field-name',
    'parametric-refinement/selected-values-collection',
    'i18n!find/nls/bundle',
    'text!find/templates/app/page/search/filters/parametric/numeric-parametric-field-view.html'
], function (Backbone, $, _, numericWidget, prettifyFieldName, SelectedParametricValuesCollection, i18n, template) {
    "use strict";
    const DEFAULT_TARGET_NUMBER_OF_BUCKETS = 30;
    const GRAPH_HEIGHT = 110;
    const UPDATE_DEBOUNCE_WAIT_TIME = 1000;

    function getData(numericFieldValuesWithCount) {
        //noinspection JSUnresolvedFunction
        let minValue = Math.floor(_.first(numericFieldValuesWithCount).value);
        //noinspection JSUnresolvedFunction
        let maxValue = Math.ceil(_.last(numericFieldValuesWithCount).value);
        let bucketSize = Math.ceil((maxValue - minValue + 1) / DEFAULT_TARGET_NUMBER_OF_BUCKETS);
        let buckets = [];
        let valueIndex = 0;
        numericFieldValuesWithCount.forEach(function (valueAndCount) {
            let relativeValue = Math.floor(valueAndCount.value - minValue);
            while (valueIndex < relativeValue) {
                let currentBucketIndex = Math.floor(valueIndex / bucketSize);
                let value = minValue + valueIndex;
                if (buckets[currentBucketIndex]) {
                    buckets[currentBucketIndex].maxValue = value;
                } else {
                    buckets[currentBucketIndex] = {
                        count: 0,
                        minValue: value,
                        maxValue: value,
                        maxContinuousValue: value
                    };
                }

                valueIndex++;
            }

            let currentBucketIndex = Math.floor(valueIndex / bucketSize);
            let value = minValue + valueIndex;
            if (buckets[currentBucketIndex]) {
                buckets[currentBucketIndex].count += valueAndCount.count;
                buckets[currentBucketIndex].maxValue = value;
                buckets[currentBucketIndex].maxContinuousValue = valueAndCount.value;
            } else {
                buckets[currentBucketIndex] = {
                    count: valueAndCount.count,
                    minValue: value,
                    maxValue: value,
                    maxContinuousValue: valueAndCount.value
                };
            }
        });

        //noinspection JSUnresolvedFunction
        var counts = _.pluck(buckets, 'count');
        return {
            maxCount: Math.max.apply(Math, counts),
            minCount: Math.min.apply(Math, counts),
            bucketSize: bucketSize,
            buckets: buckets
        };
    }

    function resetSelectedParametricValues(selectedParametricValues, fieldName) {
        let existingRestrictions = selectedParametricValues.where({field: fieldName});
        existingRestrictions.forEach(function (model) {
            selectedParametricValues.remove(model);
        });
    }

    function updateRestrictions(selectedParametricValues, fieldName, min, max) {
        resetSelectedParametricValues(selectedParametricValues, fieldName);
        selectedParametricValues.add({
            field: fieldName,
            range: [min, max]
        });
    }

    function updateRestrictionsAfterDelay(selectedParametricValues, fieldName, min, max) {
        //noinspection JSUnresolvedFunction
        _.debounce(function (selectedParametricValues, fieldName, min, max) {
            if (min && max) {
                updateRestrictions(selectedParametricValues, fieldName, min, max)
            } else {
                resetSelectedParametricValues(selectedParametricValues, fieldName);
            }
        }, UPDATE_DEBOUNCE_WAIT_TIME)(selectedParametricValues, fieldName, min, max);
    }

    return Backbone.View.extend({
        className: 'animated fadeIn',
        template: _.template(template),

        events: {
            'click .numeric-parametric-no-min': function () {
                //noinspection JSUnresolvedVariable
                let $minInput = this.$minInput;
                //noinspection JSUnresolvedFunction
                this.executeCallbackWithoutRestrictions(function (result) {
                    //noinspection JSUnresolvedFunction
                    let minValue = Math.floor(_.first(result.values).value);
                    if (minValue !== $minInput.val()) {
                        $minInput.val(minValue);
                        $minInput.trigger('change');
                    }
                });
            },
            'click .numeric-parametric-no-max': function () {
                //noinspection JSUnresolvedVariable
                let $maxInput = this.$maxInput;
                //noinspection JSUnresolvedFunction
                this.executeCallbackWithoutRestrictions(function (result) {
                    //noinspection JSUnresolvedFunction
                    let maxValue = Math.ceil(_.last(result.values).value);
                    if (maxValue !== $maxInput.val()) {
                        $maxInput.val(maxValue);
                        $maxInput.trigger('change');
                    }
                });
            },
            'click .numeric-parametric-reset': function () {
                //noinspection JSUnresolvedVariable
                resetSelectedParametricValues(this.selectedParametricValues, this.fieldName);
            },
            'change .numeric-parametric-min-input': function () {
                //noinspection JSUnresolvedVariable
                updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, this.$minInput.val(), this.$maxInput.val());
            },
            'change .numeric-parametric-max-input': function () {
                //noinspection JSUnresolvedVariable
                updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, this.$minInput.val(), this.$maxInput.val());
            }
        },

        initialize: function (options) {
            this.queryModel = options.queryModel;
            this.selectedParametricValues = options.selectedParametricValues;
            this.viewWidth = options.viewWidth;
            this.fieldName = this.model.id;
            this.widget = numericWidget({
                graphHeight: GRAPH_HEIGHT
            });
        },

        render: function () {
            //noinspection JSUnresolvedVariable,JSUnresolvedFunction
            this.$el.empty().append(this.template({
                i18n: i18n,
                fieldName: prettifyFieldName(this.model.get('name')),
                id: _.uniqueId('numeric-parametric-field')
            }));

            //noinspection JSUnresolvedFunction
            this.$minInput = this.$('.numeric-parametric-min-input');
            //noinspection JSUnresolvedFunction
            this.$maxInput = this.$('.numeric-parametric-max-input');

            function roundInputNumber(x1) {
                return Math.round(x1 * 10) / 10;
            }

            //noinspection JSUnresolvedFunction
            this.executeCallbackWithoutRestrictions(_.bind(function (result) {
                let data = getData(result.values);

                //noinspection JSUnresolvedFunction
                let minValue = Math.floor(+_.first(result.values).value);
                //noinspection JSUnresolvedFunction
                let maxValue = Math.ceil(+_.last(result.values).value);

                //noinspection JSUnresolvedFunction
                this.$minInput.val(minValue);
                //noinspection JSUnresolvedFunction
                this.$maxInput.val(maxValue);

                //noinspection JSUnresolvedFunction
                let updateCallback = _.bind(function (x1, x2) {
                    // rounding to one decimal place
                    this.$minInput.val(roundInputNumber(x1));
                    this.$maxInput.val(roundInputNumber(x2));
                }, this);
                //noinspection JSUnresolvedFunction
                let selectionCallback = _.bind(function (x1, x2) {
                    updateRestrictionsAfterDelay(this.selectedParametricValues, this.fieldName, x1, x2);
                }, this);
                //noinspection JSUnresolvedFunction
                let graph = this.widget.drawGraph({
                    chart: this.$('.chart')[0],
                    data: data,
                    updateCallback: updateCallback,
                    selectionCallback: selectionCallback,
                    xRange: this.viewWidth,
                    yRange: GRAPH_HEIGHT,
                    tooltip: i18n['search.numericParametricFields.tooltip']
                });

                this.selectedParametricValues.where({
                    field: this.fieldName
                }).forEach(function (restriction) {
                    let range = restriction.get('range');
                    if (range) {
                        //noinspection JSUnresolvedFunction
                        this.$minInput.val(roundInputNumber(range[0]));
                        //noinspection JSUnresolvedFunction
                        this.$maxInput.val(roundInputNumber(range[1]));

                        graph.selectionRect.init(graph.chart, GRAPH_HEIGHT, graph.scale.barWidth(range[0]));
                        graph.selectionRect.update(graph.scale.barWidth(range[1]));
                        graph.selectionRect.focus();
                    }
                }, this);
            }, this));
        },

        executeCallbackWithoutRestrictions: function (callback) {
            let fieldName = this.fieldName;
            let otherRestrictions = this.selectedParametricValues.filter(function (model) {
                return model.get('field') !== fieldName;
            });
            let clonedCollection = new SelectedParametricValuesCollection(otherRestrictions);
            $.ajax({
                    url: '../api/public/parametric/numeric',
                    traditional: true,
                    data: {
                        fieldNames: [fieldName],
                        databases: this.queryModel.get('indexes'),
                        queryText: this.queryModel.get('queryText'),
                        fieldText: clonedCollection.toFieldTextNode(),
                        minDate: this.queryModel.getIsoDate('minDate'),
                        maxDate: this.queryModel.getIsoDate('maxDate'),
                        stateTokens: this.queryModel.get('stateMatchIds')
                    }
                })
                .success(function (result) {
                    callback.apply(this, result);
                });
        }
    });
});<|endoftext|>


<commit_before>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';

import './GridItem.css';

export default class GridItem extends Component {

    static Mode = {
        NORMAL: 'normal',
        CHECKBOX: 'checkbox',
        RADIO: 'radio'
    };

    constructor(props) {

        super(props);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = this::this.checkboxChangeHandler;
        this.radioChangeHandler = this::this.radioChangeHandler;
        this.touchTapHandler = this::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        const {mode} = this.props;

        switch (mode) {
            case GridItem.Mode.CHECKBOX:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case GridItem.Mode.RADIO:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {
                index, className, style, itemColWidth, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, mode, renderer, itemRenderer, readOnly,
                onMouseEnter, onMouseLeave
            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                <div className={'grid-item-wrapper'}
                     style={itemColWidth ? {width: `${itemColWidth}%`} : null}>

                        {
                            mode === GridItem.Mode.CHECKBOX ?
                                <Checkbox className="grid-item-checkbox"
                                          value={checked}
                                          disabled={disabled || isLoading}/>
                                :
                                null
                        }

                        {
                            mode === GridItem.Mode.RADIO ?

                                :
                                null
                        }

                        {
                            isLoading && loadingIconPosition === 'left' ?

                                    <CircularLoading className="button-loading-icon"
                                                     size="small"/>

                                :
                                (
                                    iconCls ?
                                        <i className={`button-icon button-icon-left ${iconCls}`}
                                           aria-hidden="true">
                                        :
                                        null
                                )
                        }

                        {
                            itemRenderer && typeof itemRenderer === 'function' ?
                                itemRenderer(data, index)
                                :
                                (
                                    renderer && typeof renderer === 'function' ?
                                        renderer(data, index)
                                        :
                                        (
                                            desc ?

                                                        {text}

                                                        {desc}

                                                :
                                                text
                                        )
                                )
                        }

                        {
                            isLoading && loadingIconPosition === 'right' ?
                                <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                                 size="small"/>
                                :
                                (
                                    rightIconCls ?
                                        <i className={`button-icon button-icon-right ${rightIconCls}`}
                                           aria-hidden="true">
                                        :
                                        null
                                )
                        }

                        {
                            disableTouchRipple || readOnly ?
                                null
                                :
                                <TouchRipple ref="touchRipple"
                                             className={disabled || isLoading ? 'hidden' : ''}
                                             displayCenter={rippleDisplayCenter}/>
                        }

            </TipProvider>
        );

    }
};

GridItem.propTypes = {

    index: PropTypes.number,

    /**
     * The CSS class name of the grid button.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the grid button.
     */
    style: PropTypes.object,

    /**
     * The theme of the grid button.
     */
    theme: PropTypes.oneOf(Object.keys(Theme).map(key => Theme[key])),

    /**
     *
     */
    itemColWidth: PropTypes.number,

    /**
     *
     */
    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),

    /**
     * The text value of the grid button. Type can be string or number.
     */
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

    /**
     * The grid item's display text. Type can be string, number or bool.
     */
    text: PropTypes.any,

    /**
     * The desc value of the grid button. Type can be string or number.
     */
    desc: PropTypes.string,

    /**
     * If true, the grid button will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * If true,the button will be have loading effect.
     */
    isLoading: PropTypes.bool,

    /**
     * If true,the element's ripple effect will be disabled.
     */
    disableTouchRipple: PropTypes.bool,

    /**
     * Use this property to display an icon. It will display on the left.
     */
    iconCls: PropTypes.string,

    /**
     * Use this property to display an icon. It will display on the right.
     */
    rightIconCls: PropTypes.string,

    /**
     *
     */
    tip: PropTypes.string,

    /**
     *
     */
    tipPosition: PropTypes.oneOf(Util.enumerateValue(TipProvider.Position)),

    /**
     *
     */
    rippleDisplayCenter: PropTypes.bool,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    itemRenderer: PropTypes.func,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     *
     */
    checked: PropTypes.bool,

    /**
     *
     */
    mode: PropTypes.oneOf(Util.enumerateValue(GridItem.Mode)),

    /**
     *
     */
    readOnly: PropTypes.bool,

    /**
     * Callback function fired when a grid item touch-tapped.
     */
    onTouchTap: PropTypes.func,

    /**
     *
     */
    onSelect: PropTypes.func,

    /**
     *
     */
    onDeselect: PropTypes.func,

    /**
     *
     */
    onMouseEnter: PropTypes.func,

    /**
     *
     */
    onMouseLeave: PropTypes.func

};

GridItem.defaultProps = {

    index: 0,

    className: '',
    style: null,

    theme: Theme.DEFAULT,

    itemColWidth: 100,

    data: '',
    value: '',
    text: '',
    desc: '',

    disabled: false,
    isLoading: false,

    disableTouchRipple: false,

    iconCls: '',
    rightIconCls: '',

    tip: '',
    tipPosition: TipProvider.Position.BOTTOM,

    rippleDisplayCenter: false,

    checked: false,

    mode: GridItem.Mode.NORMAL,

    readOnly: false

};<commit_msg>optimize GridItem<commit_after>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';

import './GridItem.css';

export default class GridItem extends Component {

    static Mode = {
        NORMAL: 'normal',
        CHECKBOX: 'checkbox',
        RADIO: 'radio'
    };

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        const {mode} = this.props;

        switch (mode) {
            case GridItem.Mode.CHECKBOX:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case GridItem.Mode.RADIO:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {
                index, className, style, itemColWidth, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, mode, renderer, itemRenderer, readOnly,
                onMouseEnter, onMouseLeave
            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                <div className={'grid-item-wrapper'}
                     style={itemColWidth ? {width: `${itemColWidth}%`} : null}>

                        {
                            mode === GridItem.Mode.CHECKBOX ?
                                <Checkbox className="grid-item-checkbox"
                                          value={checked}
                                          disabled={disabled || isLoading}/>
                                :
                                null
                        }

                        {
                            mode === GridItem.Mode.RADIO ?

                                :
                                null
                        }

                        {
                            isLoading && loadingIconPosition === 'left' ?

                                    <CircularLoading className="button-loading-icon"
                                                     size="small"/>

                                :
                                (
                                    iconCls ?
                                        <i className={`button-icon button-icon-left ${iconCls}`}
                                           aria-hidden="true">
                                        :
                                        null
                                )
                        }

                        {
                            itemRenderer && typeof itemRenderer === 'function' ?
                                itemRenderer(data, index)
                                :
                                (
                                    renderer && typeof renderer === 'function' ?
                                        renderer(data, index)
                                        :
                                        (
                                            desc ?

                                                        {text}

                                                        {desc}

                                                :
                                                text
                                        )
                                )
                        }

                        {
                            isLoading && loadingIconPosition === 'right' ?
                                <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                                 size="small"/>
                                :
                                (
                                    rightIconCls ?
                                        <i className={`button-icon button-icon-right ${rightIconCls}`}
                                           aria-hidden="true">
                                        :
                                        null
                                )
                        }

                        {
                            disableTouchRipple || readOnly ?
                                null
                                :
                                <TouchRipple ref="touchRipple"
                                             className={disabled || isLoading ? 'hidden' : ''}
                                             displayCenter={rippleDisplayCenter}/>
                        }

            </TipProvider>
        );

    }
};

GridItem.propTypes = {

    index: PropTypes.number,

    /**
     * The CSS class name of the grid button.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the grid button.
     */
    style: PropTypes.object,

    /**
     * The theme of the grid button.
     */
    theme: PropTypes.oneOf(Object.keys(Theme).map(key => Theme[key])),

    /**
     *
     */
    itemColWidth: PropTypes.number,

    /**
     *
     */
    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),

    /**
     * The text value of the grid button. Type can be string or number.
     */
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

    /**
     * The grid item's display text. Type can be string, number or bool.
     */
    text: PropTypes.any,

    /**
     * The desc value of the grid button. Type can be string or number.
     */
    desc: PropTypes.string,

    /**
     * If true, the grid button will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * If true,the button will be have loading effect.
     */
    isLoading: PropTypes.bool,

    /**
     * If true,the element's ripple effect will be disabled.
     */
    disableTouchRipple: PropTypes.bool,

    /**
     * Use this property to display an icon. It will display on the left.
     */
    iconCls: PropTypes.string,

    /**
     * Use this property to display an icon. It will display on the right.
     */
    rightIconCls: PropTypes.string,

    /**
     *
     */
    tip: PropTypes.string,

    /**
     *
     */
    tipPosition: PropTypes.oneOf(Util.enumerateValue(TipProvider.Position)),

    /**
     *
     */
    rippleDisplayCenter: PropTypes.bool,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    itemRenderer: PropTypes.func,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     *
     */
    checked: PropTypes.bool,

    /**
     *
     */
    mode: PropTypes.oneOf(Util.enumerateValue(GridItem.Mode)),

    /**
     *
     */
    readOnly: PropTypes.bool,

    /**
     * Callback function fired when a grid item touch-tapped.
     */
    onTouchTap: PropTypes.func,

    /**
     *
     */
    onSelect: PropTypes.func,

    /**
     *
     */
    onDeselect: PropTypes.func,

    /**
     *
     */
    onMouseEnter: PropTypes.func,

    /**
     *
     */
    onMouseLeave: PropTypes.func

};

GridItem.defaultProps = {

    index: 0,

    className: '',
    style: null,

    theme: Theme.DEFAULT,

    itemColWidth: 100,

    data: '',
    value: '',
    text: '',
    desc: '',

    disabled: false,
    isLoading: false,

    disableTouchRipple: false,

    iconCls: '',
    rightIconCls: '',

    tip: '',
    tipPosition: TipProvider.Position.BOTTOM,

    rippleDisplayCenter: false,

    checked: false,

    mode: GridItem.Mode.NORMAL,

    readOnly: false

};<|endoftext|>


<commit_before>/**
 * @file ListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

export default class ListItem extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        switch (this.props.selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {

                index, className, style, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, renderer, itemRenderer, readOnly,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onMouseEnter, onMouseLeave

            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                            <Radio className="list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        disableTouchRipple || readOnly ?
                            null
                            :
                            <TouchRipple ref="touchRipple"
                                         className={disabled || isLoading ? 'hidden' : ''}
                                         displayCenter={rippleDisplayCenter}/>
                    }

            </TipProvider>
        );

    }
};

ListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    rippleDisplayCenter: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func

};

ListItem.defaultProps = {

    index: 0,

    className: null,
    style: null,
    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    data: null,
    value: null,
    text: null,
    desc: null,

    disabled: false,
    isLoading: false,
    disableTouchRipple: false,
    rippleDisplayCenter: false,
    checked: false,
    readOnly: false,

    iconCls: null,
    rightIconCls: null,

    tip: null,
    tipPosition: Position.BOTTOM,

    radioUncheckedIconCls: '',
    radioCheckedIconCls: '',
    checkboxUncheckedIconCls: 'fa fa-square-o',
    checkboxCheckedIconCls: 'fa fa-check-square',
    checkboxIndeterminateIconCls: 'fa fa-minus-square'

};<commit_msg>optimize ListItem<commit_after>/**
 * @file ListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

export default class ListItem extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        switch (this.props.selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {

                index, className, style, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, renderer, itemRenderer, readOnly,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onMouseEnter, onMouseLeave

            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                            <Radio className="list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        disableTouchRipple || readOnly ?
                            null
                            :
                            <TouchRipple ref="touchRipple"
                                         className={disabled || isLoading ? 'hidden' : ''}
                                         displayCenter={rippleDisplayCenter}/>
                    }

            </TipProvider>
        );

    }
};

ListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    rippleDisplayCenter: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func

};

ListItem.defaultProps = {

    index: 0,

    className: null,
    style: null,
    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    data: null,
    value: null,
    text: null,
    desc: null,

    disabled: false,
    isLoading: false,
    disableTouchRipple: false,
    rippleDisplayCenter: false,
    checked: false,
    readOnly: false,

    iconCls: null,
    rightIconCls: null,

    tip: null,
    tipPosition: Position.BOTTOM,

    radioUncheckedIconCls: null,
    radioCheckedIconCls: null,
    checkboxUncheckedIconCls: 'fa fa-square-o',
    checkboxCheckedIconCls: 'fa fa-check-square',
    checkboxIndeterminateIconCls: 'fa fa-minus-square'

};<|endoftext|>


<commit_before>import {error} from '../util/msgs.js';
import * as actionTypes from '../constants/actionTypes';
import * as validator from '../util/validation';
import { ANAX_URL_BASE, IP_API_URL_BASE } from '../constants/configuration';

export function deviceFormSubmit(deviceForm) {
  return function(dispatch) {
    // N.B. we leave the registration of the 'location' service to the next page for now; should probably be here in the future
    // TODO: fix the API to accept floats and not strings

    return fetch(`${ANAX_URL_BASE}/service/attribute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        id: 'location',
        short_type: 'location',
        label: 'Registered Location Facts',
        publishable: false,
        mappings: {
          lat: String(deviceForm.fields.location.latitude),
          lon: String(deviceForm.fields.location.longitude),
          user_provided_coords: deviceForm.fields.location.user_provided_coords,
          use_gps: deviceForm.fields.motion.usegps
        }
      })
    })
    .then((response) => {
      if (!response.ok) {
        throw error(response, 'Error saving location information in anax.');
      } else {
        return response.json();
      }
    });
  };
}

export function deviceFormFieldChange(segment, fieldName, value) {

  return function(dispatch) {
    return dispatch({
      type: actionTypes.DEVICE_FORM_UPDATE,
      segment: segment,
      fieldName: fieldName,
      value: value
    });
  }
}

export function deviceFormMultiFieldChange(segment, updateObj) {
  return function(dispatch) {
    return dispatch({
      type: actionTypes.DEVICE_FORM_MULTI_UPDATE,
      updateObj: updateObj
    });
  }
}
<commit_msg>add blockchain enablement api wrapper<commit_after>import {error} from '../util/msgs.js';
import * as actionTypes from '../constants/actionTypes';
import * as validator from '../util/validation';
import { ANAX_URL_BASE, IP_API_URL_BASE } from '../constants/configuration';

export function deviceFormSubmit(deviceForm) {
  return function(dispatch) {
    // N.B. we leave the registration of the 'location' service to the next page for now; should probably be here in the future
    // TODO: fix the API to accept floats and not strings

    return fetch(`${ANAX_URL_BASE}/service/attribute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        id: 'location',
        short_type: 'location',
        label: 'Registered Location Facts',
        publishable: false,
        mappings: {
          lat: String(deviceForm.fields.location.latitude),
          lon: String(deviceForm.fields.location.longitude),
          user_provided_coords: deviceForm.fields.location.user_provided_coords,
          use_gps: deviceForm.fields.motion.usegps
        }
      })
    })
    .then((response) => {
      if (!response.ok) {
        throw error(response, 'Error saving location information in anax.');
      } else {
        return response.json();
      }
    });
  };
}

export function deviceFormSubmitBlockchain(deviceForm) {
  return function(dispatch) {
    let protocols = [{Basic:[]}];
    if (deviceForm.fields.blockchain.usebc) {
      protocols = [
        {
          "Citizen Scientist": [
            {
              "name": "bluehorizon",
              "type": "ethereum"
            }
          ]
        }
      ];
    }
    return fetch(`${ANAX_URL_BASE}/service/attribute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        id: 'agreementprotocol',
        short_type: 'agreementprotocol',
        label: 'Agreement Protocols',
        publishable: true,
        mappings: {
          protocols
        }
      })
    })
    .then((response) => {
      if (!response.ok) {
        throw error(response, 'Error saving Blockchain configuration in anax.');
      } else {
        return response.json();
      }
    });
  }
}

export function deviceFormFieldChange(segment, fieldName, value) {

  return function(dispatch) {
    return dispatch({
      type: actionTypes.DEVICE_FORM_UPDATE,
      segment: segment,
      fieldName: fieldName,
      value: value
    });
  }
}

export function deviceFormMultiFieldChange(segment, updateObj) {
  return function(dispatch) {
    return dispatch({
      type: actionTypes.DEVICE_FORM_MULTI_UPDATE,
      updateObj: updateObj
    });
  }
}
<|endoftext|>


<commit_before>module.exports  = function(Promise, Service, AccountModel, UserService, async, config, _, $PermissionService, $RoleService) {
  return Service.extend({

    model: AccountModel,

    create: function(data, options) {
      var create      = this._super
        , service     = this
        , account     = null
        , permissions = []
        , role        = null
        , user        = null;

      options = options || {};

      return new Promise(function(resolve, reject) {
        async.waterfall(
          [
            function startTransaction(callback) {
              service
                .transaction(options)
                .then(function() {
                  callback(null);
                })
                .catch(callback);
            },

            function createAccount(callback) {
              var accountData = {
                name:       data.company,
                email:      data.email,
                active:     $RoleService !== null ? (!config[ 'clever-roles' ].account.requireConfirmation ? true : false) : true
              };

              if (data.subDomain) {
                accountData.subDomain = data.subDomain;
              } else if (data.domain) {
                accountData.subDomain = data.domain.replace('http://', '').replace('www.', '').split('.')[ 0 ];
              }

              create
                .apply(service, [ accountData, options ])
                .then(function(_account) {
                  account = _account;
                  callback(null);
                })
                .catch(callback);
            },

            function findDefaultPermissions(callback) {
              if ($PermissionService !== null) {
                $PermissionService
                  .findAll({
                    where: {
                      AccountId: null,
                      systemPermission: true
                    }
                  }, options)
                  .then(callback.bind(null, null))
                  .catch(callback);
              } else {
                callback(null, null);
              }
            },

            function createDefaultPermissions(defaultPermissions, callback) {
              if ($PermissionService !== null) {
                async.forEach(
                  defaultPermissions,
                  function createDefaultPermission(defaultPermission, done) {
                    $PermissionService
                      .create({
                        AccountId:          account.id,
                        action:             defaultPermission.action,
                        description:        defaultPermission.description,
                        systemPermission:   true
                      }, options)
                      .then(function(permission) {
                        permissions.push(permission);
                        done(null);
                      })
                      .catch(done);
                  },
                  callback
                 );
              } else {
                callback(null);
              }
            },

            function findDefaultRoles(callback) {
              if ($RoleService !== null) {
                $RoleService
                  .findAll({
                    where: {
                      AccountId:  null,
                      systemRole: true
                    }
                  }, options)
                  .then(callback.bind(null, null))
                  .catch(callback);
              } else {
                callback(null, null);
              }
            },

            function createDefaultRoles(defaultRoles, callback) {
              if ($RoleService !== null) {
                async.forEach(
                  defaultRoles,
                  function createDefaultRole(defaultRole, done) {
                    var rolePermissions = [];

                    if (defaultRole.Permissions) {
                      defaultRole.Permissions.forEach(function(rolePermission) {
                        var defaultPermission = _.findWhere(permissions, { action: rolePermission.action });
                        if (defaultPermission) {
                          rolePermissions.push(defaultPermission.id);
                        }
                      });
                    }

                    $RoleService
                      .create({
                        AccountId:      account.id,
                        systemRole:     true,
                        name:           defaultRole.name,
                        description:    defaultRole.description,
                        Permissions:    rolePermissions
                      }, options)
                      .then(function(_role) {
                        // For now we get the first role and assign the user to that role
                        if (role === null) {
                          role = _role;
                        }
                        done(null);
                      })
                      .catch(done);
                  },
                  callback
                 );
              } else {
                callback(null);
              }
            },

            function createUser(callback) {
              var userData = {
                AccountId:      account.id,
                title:          data.title || null,
                firstname:      data.firstname,
                lastname:       data.lastname,
                email:          data.email,
                username:       data.username || data.email,
                password:       data.password,
                phone:          data.phone || null,

                // Implement user options!
                active:         true,
                confirmed:      config[ 'clever-accounts' ].emailConfirmation === true ? false : true,

                // Is this actually needed?
                hasAdminRight:  false
              };

              if ($RoleService !== null && role) {
                userData.RoleId =  role;
              }

              UserService
                .create(userData, options)
                .then(function(_user) {
                  user = _user;
                  callback(null);
                })
                .catch(callback);
            },

            function authenticateUser(callback) {
              if (config[ 'clever-accounts' ].emailConfirmation === true) {
                options.transaction.commit().then(function() {
                  UserService
                  .authenticate({
                    email       : user.email,
                    password    : user.password
                  }, options)
                  .then(function(_user) {
                    user = _user;
                    callback(null);
                  })
                  .catch(callback);
                });
              } else {
                options.transaction.commit().done(callback.bind(null, null)).catch(callback);
              }
            }
          ],
          function createComplete(err) {
            if (err === null || typeof err === 'undefined') {
              resolve(user);
            } else {
              options
              .transaction
              .rollback()
              .done(function() {
                reject(err);
              })
              .catch(function(additionalErr) {
                reject(additionalErr + ' was caused by ' + err);
              });
            }
          }
         );
      });
    }
  });
};
<commit_msg>refactor(service): Split up into more modular event based signup flow<commit_after>module.exports = function(Promise, Service, AccountModel, config, UserService, _) {
  return Service.extend({

    model: AccountModel,

    create: function(values, queryOptions) {
      var createAccount = this._super;

      queryOptions  = queryOptions || {};

      values.name   = values.firstName + ' ' + values.lastName;
      values.active = !config[ 'clever-accounts' ].requireConfirmation ? true : false;

      if (values.subDomain) {
        values.subDomain = values.subDomain;
      } else if (values.domain) {
        values.subDomain = values.domain.replace('http://', '').replace('www.', '').split('.')[0];
      }

      return new Promise(function(resolve, reject) {
        var account;

        this
          .transaction(queryOptions)
          .then(this.callback(function() {
            return createAccount.apply(this, [values, queryOptions]);
          }))
          .then(function(_account) {
            account = _account
            var userData = _.extend({}, {
              AccountId     : account.id,
              title         : values.title || null,
              firstName     : values.firstName,
              lastName      : values.lastName,
              email         : values.email,
              username      : values.username || values.email,
              password      : values.password,
              phone         : values.phone || null,

              active        : true,
              confirmed     : config['clever-accounts'].emailConfirmation === true ? false : true,

              hasAdminRight : false
            });

            if (account.Roles && account.Roles.length) {
              userData.Role = account.Roles[0];
            }

            return UserService.create(userData, queryOptions);
          })
          .then(function(user) {
            return queryOptions.transaction.commit();
          })
          .then(function() {
            resolve(account);
          })
          .catch(function(err) {
            queryOptions
              .transaction
              .rollback()
              .then(reject.bind(null, err))
              .catch(reject);
          });
      }
      .bind(this));
    }
  });
};
<|endoftext|>