This commit is contained in:
2025-08-18 23:06:34 +08:00
parent 0bc04fb659
commit ed18af0cad
1926 changed files with 275098 additions and 0 deletions

26
package/node_modules/sprintf-js/CONTRIBUTORS.md generated vendored Normal file
View File

@@ -0,0 +1,26 @@
Alexander Rose [@arose](https://github.com/arose)
Alexandru Mărășteanu [@alexei](https://github.com/alexei)
Andras [@andrasq](https://github.com/andrasq)
Benoit Giannangeli [@giann](https://github.com/giann)
Branden Visser [@mrvisser](https://github.com/mrvisser)
David Baird
daurnimator [@daurnimator](https://github.com/daurnimator)
Doug Beck [@beck](https://github.com/beck)
Dzmitry Litskalau [@litmit](https://github.com/litmit)
Fred Ludlow [@fredludlow](https://github.com/fredludlow)
Hans Pufal
Henry [@alograg](https://github.com/alograg)
Johnny Shields [@johnnyshields](https://github.com/johnnyshields)
Kamal Abdali
Matt Simerson [@msimerson](https://github.com/msimerson)
Maxime Robert [@marob](https://github.com/marob)
MeriemKhelifi [@MeriemKhelifi](https://github.com/MeriemKhelifi)
Michael Schramm [@wodka](https://github.com/wodka)
Nazar Mokrynskyi [@nazar-pc](https://github.com/nazar-pc)
Oliver Salzburg [@oliversalzburg](https://github.com/oliversalzburg)
Pablo [@ppollono](https://github.com/ppollono)
Rabehaja Stevens [@RABEHAJA-STEVENS](https://github.com/RABEHAJA-STEVENS)
Raphael Pigulla [@pigulla](https://github.com/pigulla)
rebeccapeltz [@rebeccapeltz](https://github.com/rebeccapeltz)
Stefan Tingström [@stingstrom](https://github.com/stingstrom)
Tim Gates [@timgates42](https://github.com/timgates42)

24
package/node_modules/sprintf-js/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of this software nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

14
package/node_modules/sprintf-js/bower.json generated vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "sprintf",
"description": "JavaScript sprintf implementation",
"version": "1.0.3",
"main": "src/sprintf.js",
"license": "BSD-3-Clause-Clear",
"keywords": ["sprintf", "string", "formatting"],
"authors": ["Alexandru Marasteanu <hello@alexei.ro> (http://alexei.ro/)"],
"homepage": "https://github.com/alexei/sprintf.js",
"repository": {
"type": "git",
"url": "git://github.com/alexei/sprintf.js.git"
}
}

20
package/node_modules/sprintf-js/demo/angular.html generated vendored Normal file
View File

@@ -0,0 +1,20 @@
<!doctype html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
<script src="../src/sprintf.js"></script>
<script src="../src/angular-sprintf.js"></script>
</head>
<body>
<pre>{{ "%+010d"|sprintf:-123 }}</pre>
<pre>{{ "%+010d"|vsprintf:[-123] }}</pre>
<pre>{{ "%+010d"|fmt:-123 }}</pre>
<pre>{{ "%+010d"|vfmt:[-123] }}</pre>
<pre>{{ "I've got %2$d apples and %1$d oranges."|fmt:4:2 }}</pre>
<pre>{{ "I've got %(apples)d apples and %(oranges)d oranges."|fmt:{apples: 2, oranges: 4} }}</pre>
<script>
angular.module("app", ["sprintf"])
</script>
</body>
</html>

4
package/node_modules/sprintf-js/dist/.gitattributes generated vendored Normal file
View File

@@ -0,0 +1,4 @@
#ignore all generated files from diff
#also skip line ending check
*.js -diff -text
*.map -diff -text

View File

@@ -0,0 +1,3 @@
/*! sprintf-js v1.1.3 | Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro> | BSD-3-Clause */
!function(){"use strict";angular.module("sprintf",[]).filter("sprintf",function(){return function(){return sprintf.apply(null,arguments)}}).filter("fmt",["$filter",function(t){return t("sprintf")}]).filter("vsprintf",function(){return function(t,n){return vsprintf(t,n)}}).filter("vfmt",["$filter",function(t){return t("vsprintf")}])}();
//# sourceMappingURL=angular-sprintf.min.js.map

3
package/node_modules/sprintf-js/dist/sprintf.min.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
/*! sprintf-js v1.1.3 | Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro> | BSD-3-Clause */
!function(){"use strict";var g={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function y(e){return function(e,t){var r,n,i,s,a,o,p,c,l,u=1,f=e.length,d="";for(n=0;n<f;n++)if("string"==typeof e[n])d+=e[n];else if("object"==typeof e[n]){if((s=e[n]).keys)for(r=t[u],i=0;i<s.keys.length;i++){if(null==r)throw new Error(y('[sprintf] Cannot access property "%s" of undefined value "%s"',s.keys[i],s.keys[i-1]));r=r[s.keys[i]]}else r=s.param_no?t[s.param_no]:t[u++];if(g.not_type.test(s.type)&&g.not_primitive.test(s.type)&&r instanceof Function&&(r=r()),g.numeric_arg.test(s.type)&&"number"!=typeof r&&isNaN(r))throw new TypeError(y("[sprintf] expecting number but found %T",r));switch(g.number.test(s.type)&&(c=0<=r),s.type){case"b":r=parseInt(r,10).toString(2);break;case"c":r=String.fromCharCode(parseInt(r,10));break;case"d":case"i":r=parseInt(r,10);break;case"j":r=JSON.stringify(r,null,s.width?parseInt(s.width):0);break;case"e":r=s.precision?parseFloat(r).toExponential(s.precision):parseFloat(r).toExponential();break;case"f":r=s.precision?parseFloat(r).toFixed(s.precision):parseFloat(r);break;case"g":r=s.precision?String(Number(r.toPrecision(s.precision))):parseFloat(r);break;case"o":r=(parseInt(r,10)>>>0).toString(8);break;case"s":r=String(r),r=s.precision?r.substring(0,s.precision):r;break;case"t":r=String(!!r),r=s.precision?r.substring(0,s.precision):r;break;case"T":r=Object.prototype.toString.call(r).slice(8,-1).toLowerCase(),r=s.precision?r.substring(0,s.precision):r;break;case"u":r=parseInt(r,10)>>>0;break;case"v":r=r.valueOf(),r=s.precision?r.substring(0,s.precision):r;break;case"x":r=(parseInt(r,10)>>>0).toString(16);break;case"X":r=(parseInt(r,10)>>>0).toString(16).toUpperCase()}g.json.test(s.type)?d+=r:(!g.number.test(s.type)||c&&!s.sign?l="":(l=c?"+":"-",r=r.toString().replace(g.sign,"")),o=s.pad_char?"0"===s.pad_char?"0":s.pad_char.charAt(1):" ",p=s.width-(l+r).length,a=s.width&&0<p?o.repeat(p):"",d+=s.align?l+r+a:"0"===o?l+a+r:a+l+r)}return d}(function(e){if(p[e])return p[e];var t,r=e,n=[],i=0;for(;r;){if(null!==(t=g.text.exec(r)))n.push(t[0]);else if(null!==(t=g.modulo.exec(r)))n.push("%");else{if(null===(t=g.placeholder.exec(r)))throw new SyntaxError("[sprintf] unexpected placeholder");if(t[2]){i|=1;var s=[],a=t[2],o=[];if(null===(o=g.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(s.push(o[1]);""!==(a=a.substring(o[0].length));)if(null!==(o=g.key_access.exec(a)))s.push(o[1]);else{if(null===(o=g.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");s.push(o[1])}t[2]=s}else i|=2;if(3===i)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");n.push({placeholder:t[0],param_no:t[1],keys:t[2],sign:t[3],pad_char:t[4],align:t[5],width:t[6],precision:t[7],type:t[8]})}r=r.substring(t[0].length)}return p[e]=n}(e),arguments)}function e(e,t){return y.apply(null,[e].concat(t||[]))}var p=Object.create(null);"undefined"!=typeof exports&&(exports.sprintf=y,exports.vsprintf=e),"undefined"!=typeof window&&(window.sprintf=y,window.vsprintf=e,"function"==typeof define&&define.amd&&define(function(){return{sprintf:y,vsprintf:e}}))}();
//# sourceMappingURL=sprintf.min.js.map

36
package/node_modules/sprintf-js/gruntfile.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
uglify: {
options: {
banner: "/*! <%= pkg.name %> | <%= pkg.author %> | <%= pkg.license %> */\n",
sourceMap: true
},
build: {
files: [
{
src: "src/sprintf.js",
dest: "dist/sprintf.min.js"
},
{
src: "src/angular-sprintf.js",
dest: "dist/angular-sprintf.min.js"
}
]
}
},
watch: {
js: {
files: "src/*.js",
tasks: ["uglify"]
}
}
})
grunt.loadNpmTasks("grunt-contrib-uglify")
grunt.loadNpmTasks("grunt-contrib-watch")
grunt.registerTask("default", ["uglify", "watch"])
}

35
package/node_modules/sprintf-js/package.json generated vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "sprintf-js",
"version": "1.1.3",
"description": "JavaScript sprintf implementation",
"author": "Alexandru Mărășteanu <hello@alexei.ro>",
"main": "src/sprintf.js",
"scripts": {
"test": "mocha test/*.js",
"pretest": "npm run lint",
"lint": "eslint .",
"lint:fix": "eslint --fix ."
},
"repository": {
"type": "git",
"url": "https://github.com/alexei/sprintf.js.git"
},
"license": "BSD-3-Clause",
"readmeFilename": "README.md",
"devDependencies": {
"benchmark": "^2.1.4",
"eslint": "^5.10.0",
"gulp": "^3.9.1",
"gulp-benchmark": "^1.1.1",
"gulp-eslint": "^5.0.0",
"gulp-header": "^2.0.5",
"gulp-mocha": "^6.0.0",
"gulp-rename": "^1.4.0",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.1",
"mocha": "^5.2.0"
},
"overrides": {
"graceful-fs": "^4.2.11"
}
}

24
package/node_modules/sprintf-js/src/angular-sprintf.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
/* global angular, sprintf, vsprintf */
!function() {
'use strict'
angular.
module('sprintf', []).
filter('sprintf', function() {
return function() {
return sprintf.apply(null, arguments)
}
}).
filter('fmt', ['$filter', function($filter) {
return $filter('sprintf')
}]).
filter('vsprintf', function() {
return function(format, argv) {
return vsprintf(format, argv)
}
}).
filter('vfmt', ['$filter', function($filter) {
return $filter('vsprintf')
}])
}(); // eslint-disable-line

231
package/node_modules/sprintf-js/src/sprintf.js generated vendored Normal file
View File

@@ -0,0 +1,231 @@
/* global window, exports, define */
!function() {
'use strict'
var re = {
not_string: /[^s]/,
not_bool: /[^t]/,
not_type: /[^T]/,
not_primitive: /[^v]/,
number: /[diefg]/,
numeric_arg: /[bcdiefguxX]/,
json: /[j]/,
not_json: /[^j]/,
text: /^[^\x25]+/,
modulo: /^\x25{2}/,
placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
key: /^([a-z_][a-z_\d]*)/i,
key_access: /^\.([a-z_][a-z_\d]*)/i,
index_access: /^\[(\d+)\]/,
sign: /^[+-]/
}
function sprintf(key) {
// `arguments` is not an array, but should be fine for this call
return sprintf_format(sprintf_parse(key), arguments)
}
function vsprintf(fmt, argv) {
return sprintf.apply(null, [fmt].concat(argv || []))
}
function sprintf_format(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
for (i = 0; i < tree_length; i++) {
if (typeof parse_tree[i] === 'string') {
output += parse_tree[i]
}
else if (typeof parse_tree[i] === 'object') {
ph = parse_tree[i] // convenience purposes only
if (ph.keys) { // keyword argument
arg = argv[cursor]
for (k = 0; k < ph.keys.length; k++) {
if (arg == undefined) {
throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
}
arg = arg[ph.keys[k]]
}
}
else if (ph.param_no) { // positional argument (explicit)
arg = argv[ph.param_no]
}
else { // positional argument (implicit)
arg = argv[cursor++]
}
if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
arg = arg()
}
if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
}
if (re.number.test(ph.type)) {
is_positive = arg >= 0
}
switch (ph.type) {
case 'b':
arg = parseInt(arg, 10).toString(2)
break
case 'c':
arg = String.fromCharCode(parseInt(arg, 10))
break
case 'd':
case 'i':
arg = parseInt(arg, 10)
break
case 'j':
arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
break
case 'e':
arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
break
case 'f':
arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
break
case 'g':
arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
break
case 'o':
arg = (parseInt(arg, 10) >>> 0).toString(8)
break
case 's':
arg = String(arg)
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 't':
arg = String(!!arg)
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'T':
arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'u':
arg = parseInt(arg, 10) >>> 0
break
case 'v':
arg = arg.valueOf()
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'x':
arg = (parseInt(arg, 10) >>> 0).toString(16)
break
case 'X':
arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
break
}
if (re.json.test(ph.type)) {
output += arg
}
else {
if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
sign = is_positive ? '+' : '-'
arg = arg.toString().replace(re.sign, '')
}
else {
sign = ''
}
pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
pad_length = ph.width - (sign + arg).length
pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
}
}
}
return output
}
var sprintf_cache = Object.create(null)
function sprintf_parse(fmt) {
if (sprintf_cache[fmt]) {
return sprintf_cache[fmt]
}
var _fmt = fmt, match, parse_tree = [], arg_names = 0
while (_fmt) {
if ((match = re.text.exec(_fmt)) !== null) {
parse_tree.push(match[0])
}
else if ((match = re.modulo.exec(_fmt)) !== null) {
parse_tree.push('%')
}
else if ((match = re.placeholder.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1
var field_list = [], replacement_field = match[2], field_match = []
if ((field_match = re.key.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = re.key_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
}
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
match[2] = field_list
}
else {
arg_names |= 2
}
if (arg_names === 3) {
throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
}
parse_tree.push(
{
placeholder: match[0],
param_no: match[1],
keys: match[2],
sign: match[3],
pad_char: match[4],
align: match[5],
width: match[6],
precision: match[7],
type: match[8]
}
)
}
else {
throw new SyntaxError('[sprintf] unexpected placeholder')
}
_fmt = _fmt.substring(match[0].length)
}
return sprintf_cache[fmt] = parse_tree
}
/**
* export to either browser or node.js
*/
/* eslint-disable quote-props */
if (typeof exports !== 'undefined') {
exports['sprintf'] = sprintf
exports['vsprintf'] = vsprintf
}
if (typeof window !== 'undefined') {
window['sprintf'] = sprintf
window['vsprintf'] = vsprintf
if (typeof define === 'function' && define['amd']) {
define(function() {
return {
'sprintf': sprintf,
'vsprintf': vsprintf
}
})
}
}
/* eslint-enable quote-props */
}(); // eslint-disable-line

82
package/node_modules/sprintf-js/test/test.js generated vendored Normal file
View File

@@ -0,0 +1,82 @@
var assert = require("assert"),
sprintfjs = require("../src/sprintf.js"),
sprintf = sprintfjs.sprintf,
vsprintf = sprintfjs.vsprintf
describe("sprintfjs", function() {
var pi = 3.141592653589793
it("should return formated strings for simple placeholders", function() {
assert.equal("%", sprintf("%%"))
assert.equal("10", sprintf("%b", 2))
assert.equal("A", sprintf("%c", 65))
assert.equal("2", sprintf("%d", 2))
assert.equal("2", sprintf("%i", 2))
assert.equal("2", sprintf("%d", "2"))
assert.equal("2", sprintf("%i", "2"))
assert.equal('{"foo":"bar"}', sprintf("%j", {foo: "bar"}))
assert.equal('["foo","bar"]', sprintf("%j", ["foo", "bar"]))
assert.equal("2e+0", sprintf("%e", 2))
assert.equal("2", sprintf("%u", 2))
assert.equal("4294967294", sprintf("%u", -2))
assert.equal("2.2", sprintf("%f", 2.2))
assert.equal("3.141592653589793", sprintf("%g", pi))
assert.equal("10", sprintf("%o", 8))
assert.equal("%s", sprintf("%s", "%s"))
assert.equal("ff", sprintf("%x", 255))
assert.equal("FF", sprintf("%X", 255))
assert.equal("Polly wants a cracker", sprintf("%2$s %3$s a %1$s", "cracker", "Polly", "wants"))
assert.equal("Hello world!", sprintf("Hello %(who)s!", {"who": "world"}))
})
it("should return formated strings for complex placeholders", function() {
// sign
assert.equal("2", sprintf("%d", 2))
assert.equal("-2", sprintf("%d", -2))
assert.equal("+2", sprintf("%+d", 2))
assert.equal("-2", sprintf("%+d", -2))
assert.equal("2", sprintf("%i", 2))
assert.equal("-2", sprintf("%i", -2))
assert.equal("+2", sprintf("%+i", 2))
assert.equal("-2", sprintf("%+i", -2))
assert.equal("2.2", sprintf("%f", 2.2))
assert.equal("-2.2", sprintf("%f", -2.2))
assert.equal("+2.2", sprintf("%+f", 2.2))
assert.equal("-2.2", sprintf("%+f", -2.2))
assert.equal("-2.3", sprintf("%+.1f", -2.34))
assert.equal("-0.0", sprintf("%+.1f", -0.01))
assert.equal("3.14159", sprintf("%.6g", pi))
assert.equal("3.14", sprintf("%.3g", pi))
assert.equal("3", sprintf("%.1g", pi))
assert.equal("-000000123", sprintf("%+010d", -123))
assert.equal("______-123", sprintf("%+'_10d", -123))
assert.equal("-234.34 123.2", sprintf("%f %f", -234.34, 123.2))
// padding
assert.equal("-0002", sprintf("%05d", -2))
assert.equal("-0002", sprintf("%05i", -2))
assert.equal(" <", sprintf("%5s", "<"))
assert.equal("0000<", sprintf("%05s", "<"))
assert.equal("____<", sprintf("%'_5s", "<"))
assert.equal("> ", sprintf("%-5s", ">"))
assert.equal(">0000", sprintf("%0-5s", ">"))
assert.equal(">____", sprintf("%'_-5s", ">"))
assert.equal("xxxxxx", sprintf("%5s", "xxxxxx"))
assert.equal("1234", sprintf("%02u", 1234))
assert.equal(" -10.235", sprintf("%8.3f", -10.23456))
assert.equal("-12.34 xxx", sprintf("%f %s", -12.34, "xxx"))
assert.equal('{\n "foo": "bar"\n}', sprintf("%2j", {foo: "bar"}))
assert.equal('[\n "foo",\n "bar"\n]', sprintf("%2j", ["foo", "bar"]))
// precision
assert.equal("2.3", sprintf("%.1f", 2.345))
assert.equal("xxxxx", sprintf("%5.5s", "xxxxxx"))
assert.equal(" x", sprintf("%5.1s", "xxxxxx"))
})
it("should return formated strings for callbacks", function() {
assert.equal("foobar", sprintf("%s", function() { return "foobar" }))
assert.equal(Date.now(), sprintf("%s", Date.now)) // should pass...
})
})