UNPKG

pip-webui

Version:

HTML5 UI for LOB applications

1,316 lines (1,120 loc) 290 kB
// Chance.js 1.0.3 // http://chancejs.com // (c) 2013 Victor Quinn // Chance may be freely distributed or modified under the MIT license. (function () { // Constants var MAX_INT = 9007199254740992; var MIN_INT = -MAX_INT; var NUMBERS = '0123456789'; var CHARS_LOWER = 'abcdefghijklmnopqrstuvwxyz'; var CHARS_UPPER = CHARS_LOWER.toUpperCase(); var HEX_POOL = NUMBERS + "abcdef"; // Cached array helpers var slice = Array.prototype.slice; // Constructor function Chance (seed) { if (!(this instanceof Chance)) { return seed == null ? new Chance() : new Chance(seed); } // if user has provided a function, use that as the generator if (typeof seed === 'function') { this.random = seed; return this; } if (arguments.length) { // set a starting value of zero so we can add to it this.seed = 0; } // otherwise, leave this.seed blank so that MT will receive a blank for (var i = 0; i < arguments.length; i++) { var seedling = 0; if (Object.prototype.toString.call(arguments[i]) === '[object String]') { for (var j = 0; j < arguments[i].length; j++) { // create a numeric hash for each argument, add to seedling var hash = 0; for (var k = 0; k < arguments[i].length; k++) { hash = arguments[i].charCodeAt(k) + (hash << 6) + (hash << 16) - hash; } seedling += hash; } } else { seedling = arguments[i]; } this.seed += (arguments.length - i) * seedling; } // If no generator function was provided, use our MT this.mt = this.mersenne_twister(this.seed); this.bimd5 = this.blueimp_md5(); this.random = function () { return this.mt.random(this.seed); }; return this; } Chance.prototype.VERSION = "1.0.3"; // Random helper functions function initOptions(options, defaults) { options || (options = {}); if (defaults) { for (var i in defaults) { if (typeof options[i] === 'undefined') { options[i] = defaults[i]; } } } return options; } function testRange(test, errorMessage) { if (test) { throw new RangeError(errorMessage); } } /** * Encode the input string with Base64. */ var base64 = function() { throw new Error('No Base64 encoder available.'); }; // Select proper Base64 encoder. (function determineBase64Encoder() { if (typeof btoa === 'function') { base64 = btoa; } else if (typeof Buffer === 'function') { base64 = function(input) { return new Buffer(input).toString('base64'); }; } })(); // -- Basics -- /** * Return a random bool, either true or false * * @param {Object} [options={ likelihood: 50 }] alter the likelihood of * receiving a true or false value back. * @throws {RangeError} if the likelihood is out of bounds * @returns {Bool} either true or false */ Chance.prototype.bool = function (options) { // likelihood of success (true) options = initOptions(options, {likelihood : 50}); // Note, we could get some minor perf optimizations by checking range // prior to initializing defaults, but that makes code a bit messier // and the check more complicated as we have to check existence of // the object then existence of the key before checking constraints. // Since the options initialization should be minor computationally, // decision made for code cleanliness intentionally. This is mentioned // here as it's the first occurrence, will not be mentioned again. testRange( options.likelihood < 0 || options.likelihood > 100, "Chance: Likelihood accepts values from 0 to 100." ); return this.random() * 100 < options.likelihood; }; /** * Return a random character. * * @param {Object} [options={}] can specify a character pool, only alpha, * only symbols, and casing (lower or upper) * @returns {String} a single random character * @throws {RangeError} Can only specify alpha or symbols, not both */ Chance.prototype.character = function (options) { options = initOptions(options); testRange( options.alpha && options.symbols, "Chance: Cannot specify both alpha and symbols." ); var symbols = "!@#$%^&*()[]", letters, pool; if (options.casing === 'lower') { letters = CHARS_LOWER; } else if (options.casing === 'upper') { letters = CHARS_UPPER; } else { letters = CHARS_LOWER + CHARS_UPPER; } if (options.pool) { pool = options.pool; } else if (options.alpha) { pool = letters; } else if (options.symbols) { pool = symbols; } else { pool = letters + NUMBERS + symbols; } return pool.charAt(this.natural({max: (pool.length - 1)})); }; // Note, wanted to use "float" or "double" but those are both JS reserved words. // Note, fixed means N OR LESS digits after the decimal. This because // It could be 14.9000 but in JavaScript, when this is cast as a number, // the trailing zeroes are dropped. Left to the consumer if trailing zeroes are // needed /** * Return a random floating point number * * @param {Object} [options={}] can specify a fixed precision, min, max * @returns {Number} a single floating point number * @throws {RangeError} Can only specify fixed or precision, not both. Also * min cannot be greater than max */ Chance.prototype.floating = function (options) { options = initOptions(options, {fixed : 4}); testRange( options.fixed && options.precision, "Chance: Cannot specify both fixed and precision." ); var num; var fixed = Math.pow(10, options.fixed); var max = MAX_INT / fixed; var min = -max; testRange( options.min && options.fixed && options.min < min, "Chance: Min specified is out of range with fixed. Min should be, at least, " + min ); testRange( options.max && options.fixed && options.max > max, "Chance: Max specified is out of range with fixed. Max should be, at most, " + max ); options = initOptions(options, { min : min, max : max }); // Todo - Make this work! // options.precision = (typeof options.precision !== "undefined") ? options.precision : false; num = this.integer({min: options.min * fixed, max: options.max * fixed}); var num_fixed = (num / fixed).toFixed(options.fixed); return parseFloat(num_fixed); }; /** * Return a random integer * * NOTE the max and min are INCLUDED in the range. So: * chance.integer({min: 1, max: 3}); * would return either 1, 2, or 3. * * @param {Object} [options={}] can specify a min and/or max * @returns {Number} a single random integer number * @throws {RangeError} min cannot be greater than max */ Chance.prototype.integer = function (options) { // 9007199254740992 (2^53) is the max integer number in JavaScript // See: http://vq.io/132sa2j options = initOptions(options, {min: MIN_INT, max: MAX_INT}); testRange(options.min > options.max, "Chance: Min cannot be greater than Max."); return Math.floor(this.random() * (options.max - options.min + 1) + options.min); }; /** * Return a random natural * * NOTE the max and min are INCLUDED in the range. So: * chance.natural({min: 1, max: 3}); * would return either 1, 2, or 3. * * @param {Object} [options={}] can specify a min and/or max * @returns {Number} a single random integer number * @throws {RangeError} min cannot be greater than max */ Chance.prototype.natural = function (options) { options = initOptions(options, {min: 0, max: MAX_INT}); testRange(options.min < 0, "Chance: Min cannot be less than zero."); return this.integer(options); }; /** * Return a random string * * @param {Object} [options={}] can specify a length * @returns {String} a string of random length * @throws {RangeError} length cannot be less than zero */ Chance.prototype.string = function (options) { options = initOptions(options, { length: this.natural({min: 5, max: 20}) }); testRange(options.length < 0, "Chance: Length cannot be less than zero."); var length = options.length, text = this.n(this.character, length, options); return text.join(""); }; // -- End Basics -- // -- Helpers -- Chance.prototype.capitalize = function (word) { return word.charAt(0).toUpperCase() + word.substr(1); }; Chance.prototype.mixin = function (obj) { for (var func_name in obj) { Chance.prototype[func_name] = obj[func_name]; } return this; }; /** * Given a function that generates something random and a number of items to generate, * return an array of items where none repeat. * * @param {Function} fn the function that generates something random * @param {Number} num number of terms to generate * @param {Object} options any options to pass on to the generator function * @returns {Array} an array of length `num` with every item generated by `fn` and unique * * There can be more parameters after these. All additional parameters are provided to the given function */ Chance.prototype.unique = function(fn, num, options) { testRange( typeof fn !== "function", "Chance: The first argument must be a function." ); var comparator = function(arr, val) { return arr.indexOf(val) !== -1; }; if (options) { comparator = options.comparator || comparator; } var arr = [], count = 0, result, MAX_DUPLICATES = num * 50, params = slice.call(arguments, 2); while (arr.length < num) { var clonedParams = JSON.parse(JSON.stringify(params)); result = fn.apply(this, clonedParams); if (!comparator(arr, result)) { arr.push(result); // reset count when unique found count = 0; } if (++count > MAX_DUPLICATES) { throw new RangeError("Chance: num is likely too large for sample set"); } } return arr; }; /** * Gives an array of n random terms * * @param {Function} fn the function that generates something random * @param {Number} n number of terms to generate * @returns {Array} an array of length `n` with items generated by `fn` * * There can be more parameters after these. All additional parameters are provided to the given function */ Chance.prototype.n = function(fn, n) { testRange( typeof fn !== "function", "Chance: The first argument must be a function." ); if (typeof n === 'undefined') { n = 1; } var i = n, arr = [], params = slice.call(arguments, 2); // Providing a negative count should result in a noop. i = Math.max( 0, i ); for (null; i--; null) { arr.push(fn.apply(this, params)); } return arr; }; // H/T to SO for this one: http://vq.io/OtUrZ5 Chance.prototype.pad = function (number, width, pad) { // Default pad to 0 if none provided pad = pad || '0'; // Convert number to a string number = number + ''; return number.length >= width ? number : new Array(width - number.length + 1).join(pad) + number; }; // DEPRECATED on 2015-10-01 Chance.prototype.pick = function (arr, count) { if (arr.length === 0) { throw new RangeError("Chance: Cannot pick() from an empty array"); } if (!count || count === 1) { return arr[this.natural({max: arr.length - 1})]; } else { return this.shuffle(arr).slice(0, count); } }; // Given an array, returns a single random element Chance.prototype.pickone = function (arr) { if (arr.length === 0) { throw new RangeError("Chance: Cannot pickone() from an empty array"); } return arr[this.natural({max: arr.length - 1})]; }; // Given an array, returns a random set with 'count' elements Chance.prototype.pickset = function (arr, count) { if (count === 0) { return []; } if (arr.length === 0) { throw new RangeError("Chance: Cannot pickset() from an empty array"); } if (count < 0) { throw new RangeError("Chance: count must be positive number"); } if (!count || count === 1) { return [ this.pickone(arr) ]; } else { return this.shuffle(arr).slice(0, count); } }; Chance.prototype.shuffle = function (arr) { var old_array = arr.slice(0), new_array = [], j = 0, length = Number(old_array.length); for (var i = 0; i < length; i++) { // Pick a random index from the array j = this.natural({max: old_array.length - 1}); // Add it to the new array new_array[i] = old_array[j]; // Remove that element from the original array old_array.splice(j, 1); } return new_array; }; // Returns a single item from an array with relative weighting of odds Chance.prototype.weighted = function (arr, weights, trim) { if (arr.length !== weights.length) { throw new RangeError("Chance: length of array and weights must match"); } // scan weights array and sum valid entries var sum = 0; var val; for (var weightIndex = 0; weightIndex < weights.length; ++weightIndex) { val = weights[weightIndex]; if (val > 0) { sum += val; } } if (sum === 0) { throw new RangeError("Chance: no valid entries in array weights"); } // select a value within range var selected = this.random() * sum; // find array entry corresponding to selected value var total = 0; var lastGoodIdx = -1; var chosenIdx; for (weightIndex = 0; weightIndex < weights.length; ++weightIndex) { val = weights[weightIndex]; total += val; if (val > 0) { if (selected <= total) { chosenIdx = weightIndex; break; } lastGoodIdx = weightIndex; } // handle any possible rounding error comparison to ensure something is picked if (weightIndex === (weights.length - 1)) { chosenIdx = lastGoodIdx; } } var chosen = arr[chosenIdx]; trim = (typeof trim === 'undefined') ? false : trim; if (trim) { arr.splice(chosenIdx, 1); weights.splice(chosenIdx, 1); } return chosen; }; // -- End Helpers -- // -- Text -- Chance.prototype.paragraph = function (options) { options = initOptions(options); var sentences = options.sentences || this.natural({min: 3, max: 7}), sentence_array = this.n(this.sentence, sentences); return sentence_array.join(' '); }; // Could get smarter about this than generating random words and // chaining them together. Such as: http://vq.io/1a5ceOh Chance.prototype.sentence = function (options) { options = initOptions(options); var words = options.words || this.natural({min: 12, max: 18}), punctuation = options.punctuation, text, word_array = this.n(this.word, words); text = word_array.join(' '); // Capitalize first letter of sentence text = this.capitalize(text); // Make sure punctuation has a usable value if (punctuation !== false && !/^[\.\?;!:]$/.test(punctuation)) { punctuation = '.'; } // Add punctuation mark if (punctuation) { text += punctuation; } return text; }; Chance.prototype.syllable = function (options) { options = initOptions(options); var length = options.length || this.natural({min: 2, max: 3}), consonants = 'bcdfghjklmnprstvwz', // consonants except hard to speak ones vowels = 'aeiou', // vowels all = consonants + vowels, // all text = '', chr; // I'm sure there's a more elegant way to do this, but this works // decently well. for (var i = 0; i < length; i++) { if (i === 0) { // First character can be anything chr = this.character({pool: all}); } else if (consonants.indexOf(chr) === -1) { // Last character was a vowel, now we want a consonant chr = this.character({pool: consonants}); } else { // Last character was a consonant, now we want a vowel chr = this.character({pool: vowels}); } text += chr; } if (options.capitalize) { text = this.capitalize(text); } return text; }; Chance.prototype.word = function (options) { options = initOptions(options); testRange( options.syllables && options.length, "Chance: Cannot specify both syllables AND length." ); var syllables = options.syllables || this.natural({min: 1, max: 3}), text = ''; if (options.length) { // Either bound word by length do { text += this.syllable(); } while (text.length < options.length); text = text.substring(0, options.length); } else { // Or by number of syllables for (var i = 0; i < syllables; i++) { text += this.syllable(); } } if (options.capitalize) { text = this.capitalize(text); } return text; }; // -- End Text -- // -- Person -- Chance.prototype.age = function (options) { options = initOptions(options); var ageRange; switch (options.type) { case 'child': ageRange = {min: 1, max: 12}; break; case 'teen': ageRange = {min: 13, max: 19}; break; case 'adult': ageRange = {min: 18, max: 65}; break; case 'senior': ageRange = {min: 65, max: 100}; break; case 'all': ageRange = {min: 1, max: 100}; break; default: ageRange = {min: 18, max: 65}; break; } return this.natural(ageRange); }; Chance.prototype.birthday = function (options) { options = initOptions(options, { year: (new Date().getFullYear() - this.age(options)) }); return this.date(options); }; // CPF; ID to identify taxpayers in Brazil Chance.prototype.cpf = function () { var n = this.n(this.natural, 9, { max: 9 }); var d1 = n[8]*2+n[7]*3+n[6]*4+n[5]*5+n[4]*6+n[3]*7+n[2]*8+n[1]*9+n[0]*10; d1 = 11 - (d1 % 11); if (d1>=10) { d1 = 0; } var d2 = d1*2+n[8]*3+n[7]*4+n[6]*5+n[5]*6+n[4]*7+n[3]*8+n[2]*9+n[1]*10+n[0]*11; d2 = 11 - (d2 % 11); if (d2>=10) { d2 = 0; } return ''+n[0]+n[1]+n[2]+'.'+n[3]+n[4]+n[5]+'.'+n[6]+n[7]+n[8]+'-'+d1+d2; }; // CNPJ: ID to identify companies in Brazil Chance.prototype.cnpj = function () { var n = this.n(this.natural, 12, { max: 12 }); var d1 = n[11]*2+n[10]*3+n[9]*4+n[8]*5+n[7]*6+n[6]*7+n[5]*8+n[4]*9+n[3]*2+n[2]*3+n[1]*4+n[0]*5; d1 = 11 - (d1 % 11); if (d1<2) { d1 = 0; } var d2 = d1*2+n[11]*3+n[10]*4+n[9]*5+n[8]*6+n[7]*7+n[6]*8+n[5]*9+n[4]*2+n[3]*3+n[2]*4+n[1]*5+n[0]*6; d2 = 11 - (d2 % 11); if (d2<2) { d2 = 0; } return ''+n[0]+n[1]+'.'+n[2]+n[3]+n[4]+'.'+n[5]+n[6]+n[7]+'/'+n[8]+n[9]+n[10]+n[11]+'-'+d1+d2; }; Chance.prototype.first = function (options) { options = initOptions(options, {gender: this.gender(), nationality: 'en'}); return this.pick(this.get("firstNames")[options.gender.toLowerCase()][options.nationality.toLowerCase()]); }; Chance.prototype.gender = function () { return this.pick(['Male', 'Female']); }; Chance.prototype.last = function (options) { options = initOptions(options, {nationality: 'en'}); return this.pick(this.get("lastNames")[options.nationality.toLowerCase()]); }; Chance.prototype.israelId=function(){ var x=this.string({pool: '0123456789',length:8}); var y=0; for (var i=0;i<x.length;i++){ var thisDigit= x[i] * (i/2===parseInt(i/2) ? 1 : 2); thisDigit=this.pad(thisDigit,2).toString(); thisDigit=parseInt(thisDigit[0]) + parseInt(thisDigit[1]); y=y+thisDigit; } x=x+(10-parseInt(y.toString().slice(-1))).toString().slice(-1); return x; }; Chance.prototype.mrz = function (options) { var checkDigit = function (input) { var alpha = "<ABCDEFGHIJKLMNOPQRSTUVWXYXZ".split(''), multipliers = [ 7, 3, 1 ], runningTotal = 0; if (typeof input !== 'string') { input = input.toString(); } input.split('').forEach(function(character, idx) { var pos = alpha.indexOf(character); if(pos !== -1) { character = pos === 0 ? 0 : pos + 9; } else { character = parseInt(character, 10); } character *= multipliers[idx % multipliers.length]; runningTotal += character; }); return runningTotal % 10; }; var generate = function (opts) { var pad = function (length) { return new Array(length + 1).join('<'); }; var number = [ 'P<', opts.issuer, opts.last.toUpperCase(), '<<', opts.first.toUpperCase(), pad(39 - (opts.last.length + opts.first.length + 2)), opts.passportNumber, checkDigit(opts.passportNumber), opts.nationality, opts.dob, checkDigit(opts.dob), opts.gender, opts.expiry, checkDigit(opts.expiry), pad(14), checkDigit(pad(14)) ].join(''); return number + (checkDigit(number.substr(44, 10) + number.substr(57, 7) + number.substr(65, 7))); }; var that = this; options = initOptions(options, { first: this.first(), last: this.last(), passportNumber: this.integer({min: 100000000, max: 999999999}), dob: (function () { var date = that.birthday({type: 'adult'}); return [date.getFullYear().toString().substr(2), that.pad(date.getMonth() + 1, 2), that.pad(date.getDate(), 2)].join(''); }()), expiry: (function () { var date = new Date(); return [(date.getFullYear() + 5).toString().substr(2), that.pad(date.getMonth() + 1, 2), that.pad(date.getDate(), 2)].join(''); }()), gender: this.gender() === 'Female' ? 'F': 'M', issuer: 'GBR', nationality: 'GBR' }); return generate (options); }; Chance.prototype.name = function (options) { options = initOptions(options); var first = this.first(options), last = this.last(options), name; if (options.middle) { name = first + ' ' + this.first(options) + ' ' + last; } else if (options.middle_initial) { name = first + ' ' + this.character({alpha: true, casing: 'upper'}) + '. ' + last; } else { name = first + ' ' + last; } if (options.prefix) { name = this.prefix(options) + ' ' + name; } if (options.suffix) { name = name + ' ' + this.suffix(options); } return name; }; // Return the list of available name prefixes based on supplied gender. // @todo introduce internationalization Chance.prototype.name_prefixes = function (gender) { gender = gender || "all"; gender = gender.toLowerCase(); var prefixes = [ { name: 'Doctor', abbreviation: 'Dr.' } ]; if (gender === "male" || gender === "all") { prefixes.push({ name: 'Mister', abbreviation: 'Mr.' }); } if (gender === "female" || gender === "all") { prefixes.push({ name: 'Miss', abbreviation: 'Miss' }); prefixes.push({ name: 'Misses', abbreviation: 'Mrs.' }); } return prefixes; }; // Alias for name_prefix Chance.prototype.prefix = function (options) { return this.name_prefix(options); }; Chance.prototype.name_prefix = function (options) { options = initOptions(options, { gender: "all" }); return options.full ? this.pick(this.name_prefixes(options.gender)).name : this.pick(this.name_prefixes(options.gender)).abbreviation; }; Chance.prototype.ssn = function (options) { options = initOptions(options, {ssnFour: false, dashes: true}); var ssn_pool = "1234567890", ssn, dash = options.dashes ? '-' : ''; if(!options.ssnFour) { ssn = this.string({pool: ssn_pool, length: 3}) + dash + this.string({pool: ssn_pool, length: 2}) + dash + this.string({pool: ssn_pool, length: 4}); } else { ssn = this.string({pool: ssn_pool, length: 4}); } return ssn; }; // Return the list of available name suffixes // @todo introduce internationalization Chance.prototype.name_suffixes = function () { var suffixes = [ { name: 'Doctor of Osteopathic Medicine', abbreviation: 'D.O.' }, { name: 'Doctor of Philosophy', abbreviation: 'Ph.D.' }, { name: 'Esquire', abbreviation: 'Esq.' }, { name: 'Junior', abbreviation: 'Jr.' }, { name: 'Juris Doctor', abbreviation: 'J.D.' }, { name: 'Master of Arts', abbreviation: 'M.A.' }, { name: 'Master of Business Administration', abbreviation: 'M.B.A.' }, { name: 'Master of Science', abbreviation: 'M.S.' }, { name: 'Medical Doctor', abbreviation: 'M.D.' }, { name: 'Senior', abbreviation: 'Sr.' }, { name: 'The Third', abbreviation: 'III' }, { name: 'The Fourth', abbreviation: 'IV' }, { name: 'Bachelor of Engineering', abbreviation: 'B.E' }, { name: 'Bachelor of Technology', abbreviation: 'B.TECH' } ]; return suffixes; }; // Alias for name_suffix Chance.prototype.suffix = function (options) { return this.name_suffix(options); }; Chance.prototype.name_suffix = function (options) { options = initOptions(options); return options.full ? this.pick(this.name_suffixes()).name : this.pick(this.name_suffixes()).abbreviation; }; Chance.prototype.nationalities = function () { return this.get("nationalities"); }; // Generate random nationality based on json list Chance.prototype.nationality = function () { var nationality = this.pick(this.nationalities()); return nationality.name; }; // -- End Person -- // -- Mobile -- // Android GCM Registration ID Chance.prototype.android_id = function () { return "APA91" + this.string({ pool: "0123456789abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_", length: 178 }); }; // Apple Push Token Chance.prototype.apple_token = function () { return this.string({ pool: "abcdef1234567890", length: 64 }); }; // Windows Phone 8 ANID2 Chance.prototype.wp8_anid2 = function () { return base64( this.hash( { length : 32 } ) ); }; // Windows Phone 7 ANID Chance.prototype.wp7_anid = function () { return 'A=' + this.guid().replace(/-/g, '').toUpperCase() + '&E=' + this.hash({ length:3 }) + '&W=' + this.integer({ min:0, max:9 }); }; // BlackBerry Device PIN Chance.prototype.bb_pin = function () { return this.hash({ length: 8 }); }; // -- End Mobile -- // -- Web -- Chance.prototype.avatar = function (options) { var url = null; var URL_BASE = '//www.gravatar.com/avatar/'; var PROTOCOLS = { http: 'http', https: 'https' }; var FILE_TYPES = { bmp: 'bmp', gif: 'gif', jpg: 'jpg', png: 'png' }; var FALLBACKS = { '404': '404', // Return 404 if not found mm: 'mm', // Mystery man identicon: 'identicon', // Geometric pattern based on hash monsterid: 'monsterid', // A generated monster icon wavatar: 'wavatar', // A generated face retro: 'retro', // 8-bit icon blank: 'blank' // A transparent png }; var RATINGS = { g: 'g', pg: 'pg', r: 'r', x: 'x' }; var opts = { protocol: null, email: null, fileExtension: null, size: null, fallback: null, rating: null }; if (!options) { // Set to a random email opts.email = this.email(); options = {}; } else if (typeof options === 'string') { opts.email = options; options = {}; } else if (typeof options !== 'object') { return null; } else if (options.constructor === 'Array') { return null; } opts = initOptions(options, opts); if (!opts.email) { // Set to a random email opts.email = this.email(); } // Safe checking for params opts.protocol = PROTOCOLS[opts.protocol] ? opts.protocol + ':' : ''; opts.size = parseInt(opts.size, 0) ? opts.size : ''; opts.rating = RATINGS[opts.rating] ? opts.rating : ''; opts.fallback = FALLBACKS[opts.fallback] ? opts.fallback : ''; opts.fileExtension = FILE_TYPES[opts.fileExtension] ? opts.fileExtension : ''; url = opts.protocol + URL_BASE + this.bimd5.md5(opts.email) + (opts.fileExtension ? '.' + opts.fileExtension : '') + (opts.size || opts.rating || opts.fallback ? '?' : '') + (opts.size ? '&s=' + opts.size.toString() : '') + (opts.rating ? '&r=' + opts.rating : '') + (opts.fallback ? '&d=' + opts.fallback : '') ; return url; }; /** * #Description: * =============================================== * Generate random color value base on color type: * -> hex * -> rgb * -> rgba * -> 0x * -> named color * * #Examples: * =============================================== * * Geerate random hex color * chance.color() => '#79c157' / 'rgb(110,52,164)' / '0x67ae0b' / '#e2e2e2' / '#29CFA7' * * * Generate Hex based color value * chance.color({format: 'hex'}) => '#d67118' * * * Generate simple rgb value * chance.color({format: 'rgb'}) => 'rgb(110,52,164)' * * * Generate Ox based color value * chance.color({format: '0x'}) => '0x67ae0b' * * * Generate graiscale based value * chance.color({grayscale: true}) => '#e2e2e2' * * * Return valide color name * chance.color({format: 'name'}) => 'red' * * * Make color uppercase * chance.color({casing: 'upper'}) => '#29CFA7' * * @param [object] options * @return [string] color value */ Chance.prototype.color = function (options) { function gray(value, delimiter) { return [value, value, value].join(delimiter || ''); } function rgb(hasAlpha) { var rgbValue = (hasAlpha) ? 'rgba' : 'rgb'; var alphaChanal = (hasAlpha) ? (',' + this.floating({min:0, max:1})) : ""; var colorValue = (isGrayscale) ? (gray(this.natural({max: 255}), ',')) : (this.natural({max: 255}) + ',' + this.natural({max: 255}) + ',' + this.natural({max: 255})); return rgbValue + '(' + colorValue + alphaChanal + ')'; } function hex(start, end, withHash) { var simbol = (withHash) ? "#" : ""; var expression = (isGrayscale ? gray(this.hash({length: start})) : this.hash({length: end})); return simbol + expression; } options = initOptions(options, { format: this.pick(['hex', 'shorthex', 'rgb', 'rgba', '0x', 'name']), grayscale: false, casing: 'lower' }); var isGrayscale = options.grayscale; var colorValue; if (options.format === 'hex') { colorValue = hex.call(this, 2, 6, true); } else if (options.format === 'shorthex') { colorValue = hex.call(this, 1, 3, true); } else if (options.format === 'rgb') { colorValue = rgb.call(this, false); } else if (options.format === 'rgba') { colorValue = rgb.call(this, true); } else if (options.format === '0x') { colorValue = '0x' + hex.call(this, 2, 6); } else if(options.format === 'name') { return this.pick(this.get("colorNames")); } else { throw new RangeError('Invalid format provided. Please provide one of "hex", "shorthex", "rgb", "rgba", "0x" or "name".'); } if (options.casing === 'upper' ) { colorValue = colorValue.toUpperCase(); } return colorValue; }; Chance.prototype.domain = function (options) { options = initOptions(options); return this.word() + '.' + (options.tld || this.tld()); }; Chance.prototype.email = function (options) { options = initOptions(options); return this.word({length: options.length}) + '@' + (options.domain || this.domain()); }; Chance.prototype.fbid = function () { return parseInt('10000' + this.natural({max: 100000000000}), 10); }; Chance.prototype.google_analytics = function () { var account = this.pad(this.natural({max: 999999}), 6); var property = this.pad(this.natural({max: 99}), 2); return 'UA-' + account + '-' + property; }; Chance.prototype.hashtag = function () { return '#' + this.word(); }; Chance.prototype.ip = function () { // Todo: This could return some reserved IPs. See http://vq.io/137dgYy // this should probably be updated to account for that rare as it may be return this.natural({min: 1, max: 254}) + '.' + this.natural({max: 255}) + '.' + this.natural({max: 255}) + '.' + this.natural({min: 1, max: 254}); }; Chance.prototype.ipv6 = function () { var ip_addr = this.n(this.hash, 8, {length: 4}); return ip_addr.join(":"); }; Chance.prototype.klout = function () { return this.natural({min: 1, max: 99}); }; Chance.prototype.semver = function (options) { options = initOptions(options, { include_prerelease: true }); var range = this.pickone(["^", "~", "<", ">", "<=", ">=", "="]); if (options.range) { range = options.range; } var prerelease = ""; if (options.include_prerelease) { prerelease = this.weighted(["", "-dev", "-beta", "-alpha"], [50, 10, 5, 1]); } return range + this.rpg('3d10').join('.') + prerelease; }; Chance.prototype.tlds = function () { return ['com', 'org', 'edu', 'gov', 'co.uk', 'net', 'io', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bm', 'bn', 'bo', 'bq', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cu', 'cv', 'cw', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'ss', 'st', 'su', 'sv', 'sx', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'za', 'zm', 'zw']; }; Chance.prototype.tld = function () { return this.pick(this.tlds()); }; Chance.prototype.twitter = function () { return '@' + this.word(); }; Chance.prototype.url = function (options) { options = initOptions(options, { protocol: "http", domain: this.domain(options), domain_prefix: "", path: this.word(), extensions: []}); var extension = options.extensions.length > 0 ? "." + this.pick(options.extensions) : ""; var domain = options.domain_prefix ? options.domain_prefix + "." + options.domain : options.domain; return options.protocol + "://" + domain + "/" + options.path + extension; }; // -- End Web -- // -- Location -- Chance.prototype.address = function (options) { options = initOptions(options); return this.natural({min: 5, max: 2000}) + ' ' + this.street(options); }; Chance.prototype.altitude = function (options) { options = initOptions(options, {fixed: 5, min: 0, max: 8848}); return this.floating({ min: options.min, max: options.max, fixed: options.fixed }); }; Chance.prototype.areacode = function (options) { options = initOptions(options, {parens : true}); // Don't want area codes to start with 1, or have a 9 as the second digit var areacode = this.natural({min: 2, max: 9}).toString() + this.natural({min: 0, max: 8}).toString() + this.natural({min: 0, max: 9}).toString(); return options.parens ? '(' + areacode + ')' : areacode; }; Chance.prototype.city = function () { return this.capitalize(this.word({syllables: 3})); }; Chance.prototype.coordinates = function (options) { return this.latitude(options) + ', ' + this.longitude(options); }; Chance.prototype.countries = function () { return this.get("countries"); }; Chance.prototype.country = function (options) { options = initOptions(options); var country = this.pick(this.countries()); return options.full ? country.name : country.abbreviation; }; Chance.prototype.depth = function (options) { options = initOptions(options, {fixed: 5, min: -10994, max: 0}); return this.floating({ min: options.min, max: options.max, fixed: options.fixed }); }; Chance.prototype.geohash = function (options) { options = initOptions(options, { length: 7 }); return this.string({ length: options.length, pool: '0123456789bcdefghjkmnpqrstuvwxyz' }); }; Chance.prototype.geojson = function (options) { return this.latitude(options) + ', ' + this.longitude(options) + ', ' + this.altitude(options); }; Chance.prototype.latitude = function (options) { options = initOptions(options, {fixed: 5, min: -90, max: 90}); return this.floating({min: options.min, max: options.max, fixed: options.fixed}); }; Chance.prototype.longitude = function (options) { options = initOptions(options, {fixed: 5, min: -180, max: 180}); return this.floating({min: options.min, max: options.max, fixed: options.fixed}); }; Chance.prototype.phone = function (options) { var self = this, numPick, ukNum = function (parts) { var section = []; //fills the section part of the phone number with random numbers. parts.sections.forEach(function(n) { section.push(self.string({ pool: '0123456789', length: n})); }); return parts.area + section.join(' '); }; options = initOptions(options, { formatted: true, country: 'us', mobile: false }); if (!options.formatted) { options.parens = false; } var phone; switch (options.country) { case 'fr': if (!options.mobile) { numPick = this.pick([ // Valid zone and département codes. '01' + this.pick(['30', '34', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '53', '55', '56', '58', '60', '64', '69', '70', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83']) + self.string({ pool: '0123456789', length: 6}), '02' + this.pick(['14', '18', '22', '23', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '40', '41', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '56', '57', '61', '62', '69', '72', '76', '77', '78', '85', '90', '96', '97', '98', '99']) + self.string({ pool: '0123456789', length: 6}), '03' + this.pick(['10', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '39', '44', '45', '51', '52', '54', '55', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90']) + self.string({ pool: '0123456789', length: 6}), '04' + this.pick(['11', '13', '15', '20', '22', '26', '27', '30', '32', '34', '37', '42', '43', '44', '50', '56', '57', '63', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '88', '89', '90', '91', '92', '93', '94', '95', '97', '98']) + self.string({ pool: '0123456789', length: 6}), '05' + this.pick(['08', '16', '17', '19', '24', '31', '32', '33', '34', '35', '40', '45', '46', '47', '49', '53', '55', '56', '57', '58', '59', '61', '62', '63', '64', '65', '67', '79', '81', '82', '86', '87', '90', '94']) + self.string({ pool: '0123456789', length: 6}), '09' + self.string({ pool: '0123456789', length: 8}), ]); phone = options.formatted ? numPick.match(/../g).join(' ') : numPick; } else { numPick = this.pick(['06', '07']) + self.string({ pool: '0123456789', length: 8}); phone = options.formatted ? numPick.match(/../g).join(' ') : numPick; } break; case 'uk': if (!options.mobile) { numPick = this.pick([ //valid area codes of major cities/counties followed by random numbers in required format. { area: '01' + this.character({ pool: '234569' }) + '1 ', sections: [3,4] }, { area: '020 ' + this.character({ pool: '378' }), sections: [3,4] }, { area: '023 ' + this.character({ pool: '89' }), sections: [3,4] }, { area: '024 7', sections: [3,4] }, { area: '028 ' + this.pick(['25','28','37','71','82','90','92','95']), sections: [2,4] }, { area: '012' + this.pick(['04','08','54','76','97','98']) + ' ', sections: [5] }, { area: '013' + this.pick(['63','64','84','86']) + ' ', sections: [5] }, { area: '014' + this.pick(['04','20','60','61','80','88']) + ' ', sections: [5] }, { area: '015' + this.pick(['24','27','62','66']) + ' ', sections: [5] }, { area: '016' + this.pick(['06','29','35','47','59','95']) + ' ', sections: [5] }, { area: '017' + this.pick(['26','44','50','68']) + ' ', sections: [5] }, { area: '018' + this.pick(['27','37','84','97']) + ' ', sections: [5] }, { area: '019' + this.pick(['00','05','35','46','49','63','95']) + ' ', sections: [5] } ]); phone = options.formatted ? ukNum(numPick) : ukNum(numPick).replace(' ', '', 'g'); } else { numPick = this.pick([ { area: '07' + this.pick(['4','5','7','8','9']), sections: [2,6] }, { area: '07624 ', sections: [6] } ]); phone = options.formatted ? ukNum(numPick) : ukNum(numPick).replace(' ', ''); } break; case 'us': var areacode = this.areacode(options).toString(); var exchange = this.natural({ min: 2, max: 9 }).toString() + this.natural({ min: 0, max: 9 }).toString() + this.natural({ min: 0, max: 9 }).toString(); var subscriber = this.natural({ min: 1000, max: 9999 }).toString(); // this could be random [0-9]{4} phone = options.formatted ? areacode + ' ' + exchange + '-' + subscriber : areacode + exchange + subscriber; } return phone; }; Chance.prototype.posta