Comparing version 1.0.1 to 1.1.0
@@ -6,2 +6,8 @@ #!/usr/bin/env node | ||
const ENCODINGS = new Map(); | ||
ENCODINGS.set('auto', mode.auto); | ||
ENCODINGS.set('numeric', mode.numeric); | ||
ENCODINGS.set('alphanumeric', mode.alphaNumeric); | ||
ENCODINGS.set('iso-8859-1', mode.iso8859_1); | ||
const TEXT_FORMATS = new Map(); | ||
@@ -24,3 +30,3 @@ TEXT_FORMATS.set('text-ansi-invert', { on: '\u001B[7m \u001B[0m' }); | ||
const FLAGS = [ | ||
{ id: 'encoding', name: 'encoding', short: 'e', type: 'enum', values: ['mixed', 'auto', 'numeric', 'alphanumeric', 'iso-8859-1'], def: 'mixed', info: 'Set the encoding type for the content' }, | ||
{ id: 'encoding', name: 'encoding', short: 'e', type: 'enum', values: [...ENCODINGS.keys()], def: 'auto', info: 'Set the encoding type for the content' }, | ||
{ id: 'minCor', name: 'min-correction', short: 'c', type: 'enum', values: [...Object.keys(correction)], def: 'min', info: 'Set the minimum error correction level' }, | ||
@@ -38,23 +44,2 @@ { id: 'maxCor', name: 'max-correction', short: 'C', type: 'enum', values: [...Object.keys(correction)], def: 'max', info: 'Set the maximum error correction level' }, | ||
function encode(type, content) { | ||
switch (type.toLowerCase()) { | ||
case 'numeric': | ||
return mode.numeric(content); | ||
case 'alphanumeric': | ||
return mode.alphaNumeric(content); | ||
case 'iso-8859-1': | ||
return mode.iso8859_1(content); | ||
case 'auto': | ||
case 'mixed': // TODO | ||
if (/^[0-9]*$/.test(content)) { | ||
return mode.numeric(content); | ||
} | ||
if (/^[0-9A-Z $%*+./:-]*$/.test(content)) { | ||
return mode.alphaNumeric(content); | ||
} | ||
return mode.iso8859_1(content); | ||
default: throw new Error('Unknown encoding type'); | ||
} | ||
} | ||
try { | ||
@@ -68,4 +53,9 @@ const args = parseArgs(FLAGS, process.argv); | ||
const content = args.rest; | ||
const encoded = encode(args.encoding, content); | ||
const encoding = ENCODINGS.get(args.encoding.toLowerCase()); | ||
if (!encoding) { | ||
throw new Error('Unknown encoding type'); | ||
} | ||
const encoded = encoding(content); | ||
const tm0 = Date.now(); | ||
@@ -106,3 +96,1 @@ const code = generate(encoded, { | ||
// lean-qr -cQ -m1 'http://en.m.wikipedia.org' | ||
// mode.multi(mode.iso8859_1('https://en.wikipedia.org/wiki/'), mode.numeric('12345') |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("lean-qr",[],e):"object"==typeof exports?exports["lean-qr"]=e():t["lean-qr"]=e()}(global,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){t.exports=n(1)},function(t,e,n){"use strict";n.r(e),n.d(e,"correction",(function(){return s})),n.d(e,"mode",(function(){return u})),n.d(e,"generate",(function(){return S}));function r(t){const e=t>>18,n=t>>12&63,r=t>>5&127;return{capBits:8*(n*r+e*(r+1)),groups:e?[[n,r],[e,r+1]]:[[n,r]],ecsize:31&t}}const o=[{id:1,v:[4711,5194,5871,6676,7578,10386,10708,11320,11934,534674,18996,535448,19834,278142,285430,285784,1318268,286494,1064508,1326460,1068700,1846780,1331006,1076926,1084762,568924,1085278,2637502,1867422,2645630,843390,73342,335486,1629822,1888062,3698494,1122142,4738910,1134270,1654494].map(r)},{id:0,v:[4618,5008,5530,9234,9592,17264,17394,533718,537750,279930,1054302,550038,296118,1328408,1332536,816572,304604,1086842,2897306,3421498,71002,71132,3687932,3696060,3442172,1127900,878012,6043068,1922492,2700796,7611868,6071772,5563868,6088156,6866428,8939004,3790300,8443356,2000380,8201724].map(r)},{id:3,v:[4525,4822,8754,8986,532978,17016,1057234,541270,1065492,549496,1065692,1589914,1082008,1356308,1856286,586360,3936988,332508,1118906,1372958,1643228,4223774,3715870,4240158,5796638,1688284,6849278,8143646,9704190,6615838,434974,9216798,5100318,2016030,3830558,2810654,2822942,3867422,5944094,9052958].map(r)},{id:2,v:[4401,4636,8630,16688,532854,16892,278970,541146,1065368,549372,2109848,1077724,1098102,1356184,1880472,3420670,4465116,4989404,4231610,2683388,1651230,139704,3736062,647710,3498494,1184286,7389694,8172030,6894078,6648318,7434750,9253374,12104190,504350,10838526,16785918,12157438,8561150,17605118,16073214].map(r)}],s={min:0,L:0,M:1,Q:2,H:3,max:3},i=t=>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".indexOf(t);var u={multi:(...t)=>(e,n)=>t.forEach(t=>t(e,n)),numeric:t=>(e,n)=>{e.push(1,4),e.push(t.length,n<10?10:n<27?12:14);let r=0;for(;r<t.length-2;r+=3)e.push(Number(t.substr(r,3)),10);r<t.length-1?e.push(Number(t.substr(r,2)),7):r<t.length&&e.push(Number(t.substr(r,1)),4)},alphaNumeric:t=>(e,n)=>{e.push(2,4),e.push(t.length,n<10?9:n<27?11:13);let r=0;for(;r<t.length-1;r+=2)e.push(45*i(t[r])+i(t[r+1]),11);r<t.length&&e.push(i(t[r]),6)},iso8859_1:t=>(e,n)=>{e.push(4,4),e.push(t.length,n<10?8:16);for(let n=0;n<t.length;++n)e.push(t.codePointAt(n),8)}};class l{constructor(t){this.bytes=new Uint8Array(t),this.bits=0}push(t,e){for(let n=e,r=8-(7&this.bits);n>0;n-=r,r=8)this.bytes[this.bits>>>3]|=t<<r>>>n,this.bits+=Math.min(n,r)}padByte(){this.bits=this.bits+7&-8}}class f{constructor({size:t,d:e}){this.size=t,this.d=new Uint8Array(e||t*t)}get(t,e){return!!(1&this.d[e*this.size+t])}masked(t,e){return 2&this.d[e*this.size+t]}set(t,e,n,r=1){this.d[e*this.size+t]=2*r|!!n}inv(t,e){this.d[e*this.size+t]^=1}toString({on:t="##",off:e=" ",lf:n="\n",padX:r=4,padY:o=4}={}){const s=(e.repeat(this.size+2*r)+n).repeat(o),i=e.repeat(r);let u=s;for(let r=0;r<this.size;++r){u+=i;for(let n=0;n<this.size;++n)u+=this.get(n,r)?t:e;u+=i+n}return u+s}toImageData(t,{on:e=4278190080,off:n=0}={}){const r=t.createImageData(this.size,this.size),o=new Uint32Array(r.data.buffer);o.fill(n);for(let t=0;t<this.size*this.size;++t)o[t]=1&this.d[t]?e:n;return r}toCanvas(t,{padX:e=4,padY:n=4,...r}={}){t.width=this.size+2*e,t.height=this.size+2*n;const o=t.getContext("2d"),s=this.toImageData(o,r);o.putImageData(s,e,n)}}var c=[(t,e)=>!(1&(t^e)),(t,e)=>!(1&e),t=>!(t%3),(t,e)=>!((t+e)%3),(t,e)=>!(1&(Math.floor(t/3)^Math.floor(e/2))),(t,e)=>!((t&e&1)+t*e%3),(t,e)=>!((t&e&1)+t*e%3&1),(t,e)=>!((1&(t^e))+t*e%3&1)];const a=new Uint8Array(512);a[0]=1;for(let t=0,e=1;t<255;a[++t]=e)a[e+256]=t,e*=2,256&e&&(e^=285);const h=t=>a[t%255],p=t=>a[t+256];function d(t,e){const n=new Uint8Array(t.length+e.length-1);for(let r=0;r<t.length;++r)for(let o=0;o<e.length;++o)n[r+o]^=h(t[r]+e[o]);return n.map(p)}function g(t,e){const n=new Uint8Array(t.length+e.length-1);n.set(t,0);for(let r=0;r<t.length;++r)if(n[r]){const t=p(n[r]);for(let o=0;o<e.length;++o)n[r+o]^=h(e[o]+t)}return n.slice(t.length)}const m=[[0],[0,0]];for(let t=1,e=m[1];t<30;++t){const n=d(e,[0,t]);m.push(n),e=n}function b(t,e,n){let r=e;const o=Math.max(...n.map(t=>t.length));for(let e=0;e<o;++e)n.forEach(n=>{e<n.length&&(t[r++]=n[e])});return r}function z(t,{groups:e,ecsize:n}){const r=[],o=[];let s=0,i=0;e.forEach(([e,u])=>{for(let i=0;i<e;++i,s+=u){const e=t.slice(s,s+u);r.push(e),o.push(g(e,m[n]))}i+=e*(u+n)});const u=new Uint8Array(i),l=b(u,0,r);return b(u,l,o),u}function y(t,e,n){let r=t<<n-1;for(let t=1073741824;t;t>>>=1)r&t&&(r^=e*(t>>>n-1));return r}function v(t,e,n,r,o,s){for(let i=n;i<o;++i)for(let n=e;n<r;++n)t.set(n,i,s)}function w(t,e,n){v(t,e-3,n-3,e+4,n+4,1),v(t,e-2,n-2,e+3,n+3,0),v(t,e-1,n-1,e+2,n+2,1)}function x(t,e,n){v(t,e-2,n-2,e+3,n+3,1),v(t,e-1,n-1,e+2,n+2,0),t.set(e,n,1)}function M(t){const e=t.size,n=[];for(let r=e-2,o=e,s=-1;r>=0;r-=2){for(5===r&&(r=4);o+=s,-1!==o&&o!==e;)t.masked(r+1,o)||n.push([r+1,o]),t.masked(r,o)||n.push([r,o]);s*=-1}return n}function I(t,e,n){e.forEach(([e,r],o)=>t.set(e,r,n[o>>3]<<(7&o)&128,0))}function j(t,e,n,r){for(let n=0;n<t.size;++n)for(let r=0;r<t.size;++r)e(r,n)&&!t.masked(r,n)&&t.inv(r,n);const o=r<<3|n,s=21522^(o<<10|y(o,1335,11));let i=16384;for(let e=0;e<7;++e){const n=s&i;t.set(6===e?7:e,8,n),t.set(8,t.size-e-1,n),i>>>=1}for(let e=0;e<8;++e){const n=s&i;t.set(8,(e>1?7:8)-e,n),t.set(t.size-8+e,8,n),i>>>=1}}function E(t,e,n){for(let r=0;r<t.size;++r){let o=e,s=e;for(let e=0;e<t.size;++e)o=n(o,t.get(e,r)),s=n(s,t.get(r,e))}}function O(t){return function(t){let e=0;return E(t,[0,void 0],([t,n],r)=>r!==n?[1,r]:(4===t?e+=3:t>4&&++e,[t+1,n])),e}(t)+3*function(t){let e=0;for(let n=0;n<t.size-1;++n){let r=t.get(n,0),o=t.get(n+1,0)===r;for(let s=1;s<t.size;++s){const i=t.get(n,s),u=t.get(n+1,s)===i;e+=o&&u&&r===i,r=i,o=u}}return e}(t)+40*function(t){let e=0;return E(t,0,(t,n)=>{const r=(t>>>1|2098176)&(3047517^(n?0:-1));return 2049&r&&++e,r}),e}(t)+function(t){let e=0;for(let n=0;n<t.size;++n)for(let r=0;r<t.size;++r)e+=t.get(r,n);return 10*Math.floor(20*Math.abs(e/(t.size*t.size)-.5))}(t)}const A=new Map;function N(t){if(!A.has(t)){const e=new f({size:4*t+17});!function(t,e){const n=4*e+17;w(t,3,3),w(t,n-4,3),w(t,3,n-4),v(t,0,7,9,9,0),v(t,7,0,9,7,0),v(t,n-8,7,n,9,0),v(t,n-8,0,n-7,7,0),v(t,7,n-8,9,n,0),v(t,0,n-8,7,n-7,0),t.set(8,n-8,1);for(let e=8;e<n-8;++e)t.set(e,6,!(1&e)),t.set(6,e,!(1&e));if(e>=2){const r=Math.floor(e/7)+1,o=2*Math.ceil((n-13)/r/2-.25),s=[6];for(let t=r;t-- >0;)s.push(n-7-t*o);for(let e=0;e<=r;++e)for(let n=0;n<=r;++n)0===e&&0===n||0===e&&n===r||e===r&&0===n||x(t,s[e],s[n])}if(e>=7){const r=e<<12|y(e,7973,13);let o=1<<17;for(let e=6;e-- >0;)for(let s=0;s<3;++s){const i=r&o;t.set(e,n-9-s,i),t.set(n-9-s,e,i),o>>>=1}}}(e,t),A.set(t,{code:e,path:M(e)})}const e=A.get(t);return{code:new f(e.code),path:e.path}}function P(t,e){let n=null,r=Number.POSITIVE_INFINITY;return c.forEach((o,s)=>{const i=new f(t);j(i,o,s,e.id);const u=O(i);u<r&&(n=i,r=u)}),n}function S(t,{minCorrectionLevel:e=s.min,maxCorrectionLevel:n=s.max,minVersion:r=1,maxVersion:i=40,mask:u=null}={}){if(n<e)throw new Error("Invalid correction level range");if(i<r)throw new Error("Invalid version range");let f=0;for(let s=r;s<=i;++s){if(o[e].v[s-1].capBits<f)continue;const r=new l(2956);t(r,s),f=r.bits;for(let t=n;t>=e;--t){const e=o[t],n=e.v[s-1];if(n.capBits<f)continue;for(r.push(0,4),r.padByte();r.bits<n.capBits;)r.push(60433,16);const{code:i,path:l}=N(s);return I(i,l,z(r.bytes,n)),null!==u?(j(i,c[u],u,e.id),i):P(i,e)}}throw new Error("Too much data")}}])})); | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("lean-qr",[],e):"object"==typeof exports?exports["lean-qr"]=e():t["lean-qr"]=e()}(global,(function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var s=e[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,r),s.l=!0,s.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)r.d(n,s,function(e){return t[e]}.bind(null,s));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){t.exports=r(1)},function(t,e,r){"use strict";r.r(e),r.d(e,"correction",(function(){return o})),r.d(e,"mode",(function(){return f})),r.d(e,"generate",(function(){return B}));const n=t=>{const e=t>>18,r=t>>12&63,n=t>>5&127;return{capBits:8*(r*n+e*(n+1)),groups:e?[[r,n],[e,n+1]]:[[r,n]],ecsize:31&t}},s=[{id:1,v:[4711,5194,5871,6676,7578,10386,10708,11320,11934,534674,18996,535448,19834,278142,285430,285784,1318268,286494,1064508,1326460,1068700,1846780,1331006,1076926,1084762,568924,1085278,2637502,1867422,2645630,843390,73342,335486,1629822,1888062,3698494,1122142,4738910,1134270,1654494].map(n)},{id:0,v:[4618,5008,5530,9234,9592,17264,17394,533718,537750,279930,1054302,550038,296118,1328408,1332536,816572,304604,1086842,2897306,3421498,71002,71132,3687932,3696060,3442172,1127900,878012,6043068,1922492,2700796,7611868,6071772,5563868,6088156,6866428,8939004,3790300,8443356,2000380,8201724].map(n)},{id:3,v:[4525,4822,8754,8986,532978,17016,1057234,541270,1065492,549496,1065692,1589914,1082008,1356308,1856286,586360,3936988,332508,1118906,1372958,1643228,4223774,3715870,4240158,5796638,1688284,6849278,8143646,9704190,6615838,434974,9216798,5100318,2016030,3830558,2810654,2822942,3867422,5944094,9052958].map(n)},{id:2,v:[4401,4636,8630,16688,532854,16892,278970,541146,1065368,549372,2109848,1077724,1098102,1356184,1880472,3420670,4465116,4989404,4231610,2683388,1651230,139704,3736062,647710,3498494,1184286,7389694,8172030,6894078,6648318,7434750,9253374,12104190,504350,10838526,16785918,12157438,8561150,17605118,16073214].map(n)}],o={min:0,L:0,M:1,Q:2,H:3,max:3},i=t=>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".indexOf(t),l=t=>(e,r)=>{e.push(1,4),e.push(t.length,r<10?10:r<27?12:14);let n=0;for(;n<t.length-2;n+=3)e.push(Number(t.substr(n,3)),10);n<t.length-1?e.push(Number(t.substr(n,2)),7):n<t.length&&e.push(Number(t.substr(n,1)),4)},u=t=>(e,r)=>{e.push(2,4),e.push(t.length,r<10?9:r<27?11:13);let n=0;for(;n<t.length-1;n+=2)e.push(45*i(t[n])+i(t[n+1]),11);n<t.length&&e.push(i(t[n]),6)},a=t=>(e,r)=>{e.push(4,4),e.push(t.length,r<10?8:16);for(let r=0;r<t.length;++r)e.push(t.codePointAt(r),8)},c=t=>t.reduce((t,e)=>!t||e.e<t.e?e:t);l.reg=/[0-9]/,l.est=(t,e)=>4+(e<10?10:e<27?12:14)+10*t.length/3,u.reg=/[0-9A-Z $%*+./:-]/,u.est=(t,e)=>4+(e<10?9:e<27?11:13)+5.5*t.length,a.reg=/[\u0000-\u00FF]/,a.est=(t,e)=>4+(e<10?8:16)+8*t.length;var f={auto:(t,{modes:e=[l,u,a]}={})=>(r,n)=>{let s=[{c:0,e:0}];[...t].forEach((r,o)=>{if(s=e.filter(t=>t.reg.test(r)).map(e=>c(s.map(r=>{const s={c:e,p:r.c===e?r.p:r,s:r.c===e?r.s:o};return s.v=t.substring(s.s,o+1),s.e=s.p.e+Math.ceil(e.est(s.v,n)),s}))),!s.length)throw new Error("Unencodable")});const o=[];for(let t=c(s);t.c;t=t.p)o.unshift(t.c(t.v));o.forEach(t=>t(r,n))},multi:(...t)=>(e,r)=>t.forEach(t=>t(e,r)),numeric:l,alphaNumeric:u,iso8859_1:a};class h{constructor(t){this.bytes=new Uint8Array(t),this.bits=0}push(t,e){for(let r=e,n=8-(7&this.bits);r>0;r-=n,n=8)this.bytes[this.bits>>>3]|=t<<n>>>r,this.bits+=Math.min(r,n)}}class p{constructor({size:t,d:e}){this.size=t,this.d=new Uint8Array(e||t*t)}get(t,e){return!!(1&this.d[e*this.size+t])}masked(t,e){return 2&this.d[e*this.size+t]}set(t,e,r,n=1){this.d[e*this.size+t]=2*n|!!r}inv(t,e){this.d[e*this.size+t]^=1}toString({on:t="##",off:e=" ",lf:r="\n",padX:n=4,padY:s=4}={}){const o=(e.repeat(this.size+2*n)+r).repeat(s),i=e.repeat(n);let l=o;for(let n=0;n<this.size;++n){l+=i;for(let r=0;r<this.size;++r)l+=this.get(r,n)?t:e;l+=i+r}return l+o}toImageData(t,{on:e=4278190080,off:r=0}={}){const n=t.createImageData(this.size,this.size),s=new Uint32Array(n.data.buffer);s.fill(r);for(let t=0;t<this.size*this.size;++t)s[t]=1&this.d[t]?e:r;return n}toCanvas(t,{padX:e=4,padY:r=4,...n}={}){t.width=this.size+2*e,t.height=this.size+2*r;const s=t.getContext("2d"),o=this.toImageData(s,n);s.putImageData(o,e,r)}}var d=[(t,e)=>!(1&(t^e)),(t,e)=>!(1&e),t=>!(t%3),(t,e)=>!((t+e)%3),(t,e)=>!(1&(Math.floor(t/3)^Math.floor(e/2))),(t,e)=>!((t&e&1)+t*e%3),(t,e)=>!((t&e&1)+t*e%3&1),(t,e)=>!((1&(t^e))+t*e%3&1)];const g=new Uint8Array(512);g[0]=1;for(let t=0,e=1;t<255;g[++t]=e)g[e+256]=t,e*=2,256&e&&(e^=285);const m=t=>g[t%255],b=t=>g[t+256],v=(t,e)=>{const r=new Uint8Array(t.length+e.length-1);for(let n=0;n<t.length;++n)for(let s=0;s<e.length;++s)r[n+s]^=m(t[n]+e[s]);return r.map(b)},z=(t,e)=>{const r=new Uint8Array(t.length+e.length-1);r.set(t,0);for(let n=0;n<t.length;++n)if(r[n]){const t=b(r[n]);for(let s=0;s<e.length;++s)r[n+s]^=m(e[s]+t)}return r.slice(t.length)},y=[[0],[0,0]];for(let t=1,e=y[1];t<30;++t){const r=v(e,[0,t]);y.push(r),e=r}const w=(t,e,r)=>{let n=e;const s=Math.max(...r.map(t=>t.length));for(let e=0;e<s;++e)r.forEach(r=>{e<r.length&&(t[n++]=r[e])});return n};var x=(t,{groups:e,ecsize:r})=>{const n=[],s=[];let o=0,i=0;e.forEach(([e,l])=>{for(let i=0;i<e;++i,o+=l){const e=t.slice(o,o+l);n.push(e),s.push(z(e,y[r]))}i+=e*(l+r)});const l=new Uint8Array(i),u=w(l,0,n);return w(l,u,s),l};const M=(t,e,r)=>{let n=t<<r-1;for(let t=1073741824;t;t>>>=1)n&t&&(n^=e*(t>>>r-1));return n},E=(t,e,r,n,s,o)=>{for(let i=r;i<s;++i)for(let r=e;r<n;++r)t.set(r,i,o)},j=(t,e,r)=>{E(t,e-3,r-3,e+4,r+4,1),E(t,e-2,r-2,e+3,r+3,0),E(t,e-1,r-1,e+2,r+2,1)},A=(t,e,r)=>{E(t,e-2,r-2,e+3,r+3,1),E(t,e-1,r-1,e+2,r+2,0),t.set(e,r,1)},O=t=>{const e=t.size,r=[];for(let n=e-2,s=e,o=-1;n>=0;n-=2){for(5===n&&(n=4);s+=o,-1!==s&&s!==e;)t.masked(n+1,s)||r.push([n+1,s]),t.masked(n,s)||r.push([n,s]);o*=-1}return r},U=(t,e,r)=>{e.forEach(([e,n],s)=>t.set(e,n,r[s>>3]<<(7&s)&128,0))},I=(t,e,r,n)=>{for(let r=0;r<t.size;++r)for(let n=0;n<t.size;++n)e(n,r)&&!t.masked(n,r)&&t.inv(n,r);const s=n<<3|r,o=21522^(s<<10|M(s,1335,11));let i=16384;for(let e=0;e<7;++e){const r=o&i;t.set(6===e?7:e,8,r),t.set(8,t.size-e-1,r),i>>>=1}for(let e=0;e<8;++e){const r=o&i;t.set(8,(e>1?7:8)-e,r),t.set(t.size-8+e,8,r),i>>>=1}},P=(t,e,r)=>{for(let n=0;n<t.size;++n){let s=e,o=e;for(let e=0;e<t.size;++e)s=r(s,t.get(e,n)),o=r(o,t.get(n,e))}};var S=t=>(t=>{let e=0;return P(t,[0],([t,r],n)=>n!==r?[1,n]:(4===t?e+=3:t>4&&++e,[t+1,r])),e})(t)+3*(t=>{let e=0;for(let r=1;r<t.size;++r){let n=t.get(r-1,0),s=t.get(r,0)===n;for(let o=1;o<t.size;++o){const i=t.get(r-1,o),l=t.get(r,o)===i;e+=s&&l&&n===i,n=i,s=l}}return e})(t)+40*(t=>{let e=0;return P(t,0,(t,r)=>{const n=(t>>>1|2098176)&(3047517^(r?0:-1));return 2049&n&&++e,n}),e})(t)+(t=>{let e=0;for(let r=0;r<t.size;++r)for(let n=0;n<t.size;++n)e+=t.get(n,r);return 10*Math.floor(20*Math.abs(e/(t.size*t.size)-.5))})(t);const _=[],k=t=>{let e=_[t];if(!e){const r=new p({size:4*t+17});((t,e)=>{const r=4*e+17;j(t,3,3),j(t,r-4,3),j(t,3,r-4),E(t,0,7,9,9,0),E(t,7,0,9,7,0),E(t,r-8,7,r,9,0),E(t,r-8,0,r-7,7,0),E(t,7,r-8,9,r,0),E(t,0,r-8,7,r-7,0),t.set(8,r-8,1);for(let e=8;e<r-8;++e)t.set(e,6,!(1&e)),t.set(6,e,!(1&e));if(e>=2){const n=Math.floor(e/7)+1,s=2*Math.ceil((r-13)/n/2-.25),o=[6];for(let t=n;t-- >0;)o.push(r-7-t*s);for(let e=0;e<=n;++e)for(let r=0;r<=n;++r)!e&&!r||!e&&r===n||e===n&&!r||A(t,o[e],o[r])}if(e>=7){const n=e<<12|M(e,7973,13);let s=1<<17;for(let e=6;e-- >0;)for(let o=0;o<3;++o){const i=n&s;t.set(e,r-9-o,i),t.set(r-9-o,e,i),s>>>=1}}})(r,t),_[t]=e=[r,O(r)]}return[new p(e[0]),e[1]]};var B=(t,{minCorrectionLevel:e=o.min,maxCorrectionLevel:r=o.max,minVersion:n=1,maxVersion:i=40,mask:l=null}={})=>{if(r<e)throw new Error("Invalid correction level range");if(i<n)throw new Error("Invalid version range");"string"==typeof t&&(t=f.auto(t));let u=0;for(let o=n;o<=i;++o){if(s[e].v[o-1].capBits<u)continue;const n=new h(2956);t(n,o),u=n.bits;for(let t=r;t>=e;--t){const e=s[t],r=e.v[o-1];if(r.capBits<u)continue;for(n.push(0,4),n.bits=n.bits+7&-8;n.bits<r.capBits;)n.push(60433,16);const[i,a]=k(o);return U(i,a,x(n.bytes,r)),null!==l?(I(i,d[l],l,e.id),i):d.map((t,r)=>{const n=new p(i);return I(n,t,r,e.id),n.s=S(n),n}).reduce((t,e)=>!t||e.s<t.s?e:t)}}throw new Error("Too much data")}}])})); | ||
//# sourceMappingURL=index.js.map |
@@ -19,3 +19,2 @@ declare module 'lean-qr' { | ||
push(value: number, bits: number): void; | ||
padByte(): void; | ||
} | ||
@@ -51,8 +50,18 @@ | ||
export type Mode = (data: Bitmap1D, version: number) => void; | ||
export interface ModeFactory { | ||
(value: string): Mode; | ||
reg: RegExp; | ||
est(value: string, version: number): number; | ||
} | ||
interface ModeAutoOptions { | ||
modes?: ReadonlyArray<ModeFactory>; | ||
} | ||
export const mode: { | ||
auto(value: string, options?: ModeAutoOptions): Mode, | ||
multi(...modes: Mode[]): Mode, | ||
numeric(value: string): Mode, | ||
alphaNumeric(value: string): Mode, | ||
iso8859_1(value: string): Mode, | ||
numeric: ModeFactory, | ||
alphaNumeric: ModeFactory, | ||
iso8859_1: ModeFactory, | ||
}; | ||
@@ -69,3 +78,3 @@ | ||
export const generate: (data: Mode, options?: { | ||
interface GenerateOptions { | ||
minCorrectionLevel?: correction; | ||
@@ -76,3 +85,5 @@ maxCorrectionLevel?: correction; | ||
mask?: null | Mask; | ||
}) => Bitmap2D; | ||
} | ||
export const generate: (data: Mode | string, options?: GenerateOptions) => Bitmap2D; | ||
} |
{ | ||
"name": "lean-qr", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "minimal QR code generation", | ||
@@ -5,0 +5,0 @@ "files": [ |
# Lean QR | ||
Minimal library for generating QR codes in the browser and server-side. | ||
Minimal library for generating QR Codes in the browser and server-side. | ||
Optimised for code size while maintaining decent performance. | ||
Less than 10kB uncompressed (less than 4kB compressed). | ||
Less than 10kB uncompressed (~4kB compressed). | ||
@@ -21,5 +21,5 @@ You can see it in action at <https://qr.davidje13.com/> | ||
```javascript | ||
import { mode, generate } from 'lean-qr'; | ||
import { generate } from 'lean-qr'; | ||
const code = generate(mode.alphaNumeric('LEAN-QR LIBRARY')); | ||
const code = generate('LEAN-QR LIBRARY'); | ||
@@ -36,5 +36,5 @@ process.stdout.write(code.toString({ | ||
```javascript | ||
import { mode, generate } from 'lean-qr'; | ||
import { generate } from 'lean-qr'; | ||
const code = generate(mode.alphaNumeric('LEAN-QR LIBRARY')); | ||
const code = generate('LEAN-QR LIBRARY'); | ||
@@ -54,2 +54,11 @@ code.toCanvas(document.getElementById('my-canvas')); | ||
By default, the optimal encoding mode is chosen to minimise the resulting | ||
image size (this includes switching modes part way through a message if | ||
it reduces the size). If you want to specify an explicit mode, you can: | ||
```javascript | ||
import { mode, generate } from 'lean-qr'; | ||
const code = generate(mode.alphaNumeric('LEAN-QR LIBRARY')); | ||
``` | ||
| mode | bits / char | charset | | ||
@@ -61,2 +70,9 @@ |---------------------|------------:|-------------------| | ||
Note that if you specify a mode explicitly, it is your responsibility to | ||
ensure the content you are encoding conforms to the accepted character | ||
set. If you provide mismatched content, the resulting QR Code will likely | ||
be malformed. | ||
### `multi` | ||
`mode.multi` enables switching modes during a message, for example: | ||
@@ -72,2 +88,20 @@ | ||
### `auto` | ||
`mode.auto` will pick the optimal combination of modes for the message. | ||
This is used by default if you provide a plain string to `generate`, but | ||
you can also use it explicitly to get more control: | ||
```javascript | ||
const code = generate(mode.auto('FOOBAR', { | ||
modes: [mode.numeric, mode.iso8859_1], // exclude alphaNumeric mode | ||
})); | ||
``` | ||
You can omit the `modes` argument to default to the standard modes. | ||
You can also provide your own custom modes, and `auto` will consider | ||
them alongside the built-in modes (see below for details). | ||
### Custom modes | ||
Other modes are not currently supported, but it is possible to write | ||
@@ -80,3 +114,2 @@ custom modes: | ||
data.push(0b101010, 6); // value, bits (supports up to 24-bits) | ||
data.padByte(); // pad with 0s until the next byte boundary | ||
}; | ||
@@ -87,15 +120,29 @@ | ||
If you want your custom mode to be compatible with `auto`, you need to | ||
provide a pair of properties: | ||
```javascript | ||
// a RegExp which matches all characters that your mode can encode | ||
myMode.reg = /[0-9a-zA-Z]/; | ||
// a function which estimates the number of bits required for an input | ||
// (fractional results will be rounded up) | ||
myMode.est = (value, version) => (12 + value.length * 8); | ||
``` | ||
For example the implementation of `iso8859_1`: | ||
```javascript | ||
const iso8859_1 = (value) => { | ||
const bytes = new TextEncoder('iso-8859-1').encode(value); | ||
return (data, version) => { | ||
data.push(0b0100, 4); | ||
data.push(bytes.length, version < 10 ? 8 : 16); | ||
for (let i = 0; i < bytes.length; ++i) { | ||
data.push(bytes[i], 8); | ||
} | ||
}; | ||
const iso8859_1 = (value) => (data, version) => { | ||
data.push(0b0100, 4); | ||
data.push(value.length, version < 10 ? 8 : 16); | ||
for (let i = 0; i < value.length; ++i) { | ||
data.push(value.codePointAt(i), 8); | ||
} | ||
}; | ||
iso8859_1.reg = /[\u0000-\u00FF]/; | ||
iso8859_1.est = (value, version) => ( | ||
4 + (version < 10 ? 8 : 16) + | ||
value.length * 8 | ||
); | ||
``` | ||
@@ -146,3 +193,3 @@ | ||
ISO 18004 requires masks be chosen according to a specific algorithm which | ||
is designed to maximize readability by QR code readers. This is done by | ||
is designed to maximize readability by QR Code readers. This is done by | ||
default, however if you would like to specify a particular mask, you can: | ||
@@ -258,3 +305,3 @@ | ||
The values of `on` and `off` should be in 0xAABBGGRR format. | ||
The values of `on` and `off` should be in `0xAABBGGRR` format. | ||
@@ -261,0 +308,0 @@ ### `toImageData(context[, options])` |
Sorry, the diff of this file is not supported yet
76114
333
294