master
1function(context, A)
2{
3 // s:#s.company.access, p: {username:"", process:""}
4
5 //space is \ u0020 or 32
6 //tab is \ u0009 or 9 tab is also 4 char
7 //top fill is \ u2580 or 9600
8 //bottom fill is \ u2584 or 9604
9 //full fill is \ u2588 or 9608
10
11
12
13 let L = #s.scripts.lib();
14
15 let start = 0;
16 let qrs = [];
17
18 let M = [[1,0],[0,1],[1,1],[0,0]];
19
20 let mask = [
21 (r,c,b) => (r+c)%2?b:~b+2, //000
22 (r,c,b) => r%2?b:~b+2, //001
23 (r,c,b) => c%3?b:~b+2, //010
24 (r,c,b) => (r+c)%3?b:~b+2, //011
25 (r,c,b) => (~~(r/2)+~~(c/3))%2?b:~b+2, //100
26 (r,c,b) => ((r*c)%2)+((r*c)%3)?b:~b+2, //101
27 (r,c,b) => ((r*c)%2)+((r*c)%3)%2?b:~b+2,//110
28 (r,c,b) => ((r+c)%2)+((r*c)%3)%2?b:~b+2 //111
29 ];
30
31 // mask_alt is an alternative masking solution that reduces char count at the expense of computation
32 // m = mask index (based on binary encoding)
33 // r = pixel row
34 // c = pixel col
35 // b = bit (1 or 0)
36 // returns 1 or 0 based on if the r,c,m combo returns true, then the bit was masked and needs to be inverted
37 //let mask_alt = (m,r,c,b)=>([(r+c)%2,r%2,c%3,(r+c)%3,(~~(r/2)+~~(c/3))%2,((r*c)%2)+((r*c)%3),((r*c)%2)+((r*c)%3)%2,((r+c)%2)+((r*c)%3)%2])[m]?b:~b+2;
38
39 let getBin = (arr)=>arr.reduce((x,b)=>(x<<1)|b,0);
40
41 //let lineNum = 0;
42 //let pad = (i,n=3) => '0'.repeat(n - i.toString().length) + i.toString();
43
44 A.s.call(A.p)
45 .replace(/[\w`]/g, '') //remove color
46 .replace(/\t/g,' ') //replace tabs w/ spaces
47 .split('\n') //split lines
48 .filter(l=>l.length > 0 && l.charCodeAt(0) != 200 && l.charCodeAt(0) != 60) //remove lines that are not qr related
49 //find the breaks
50 .forEach((l,i,arr)=>{
51 //detect the last line of a qr code. the assumption is that a completely empty line can only be the last line.
52 //so in other words, no bottom fill or full fill characters in the last line of the qr code string
53 if(!!!l.match(/[\u2588\u2584]/)) {
54 qrs.push(
55 //slice out the individual qr code lines
56 arr.slice(start,i+1)
57 //reduce it to array of array of 1 and 0
58 //remember each line is equivalent to 2 lines of qr code
59 .reduce((qr, l, x)=>{
60 let x0 = x*2,
61 x1 = x0+1;
62 //setup new sub arrays
63 qr[x0] = [];
64 qr[x1] = [];
65
66 //map each character to the top and bottom bit for the 2 rows..
67 for(let ci = 0, t=3,b=3; ci < l.length; ci++) {
68 let cc = l.charCodeAt(ci);
69 if(cc>=9600)
70 [t,b] = M[(cc-9600)/4];
71 else if(cc==32)
72 [t,b] = M[3];
73 else
74 [t,b] = M[0]; //seems to work best to assume junk characters as t=1, b=0 => Error correction should fix it
75 qr[x0].push(t);
76 qr[x1].push(b);
77 }
78 return qr;
79 },[])
80 );
81 start = i+1;
82 }
83 });
84
85 //trim the last line since we know it is blank
86 qrs = qrs.map(qr=>qr.slice(0,qr.length-1));
87
88 //get qr code version (based on size)
89 let version = qrs.map(qr=>(qr[0].length - 17)/4),
90 darkPx = version.map(v=>[8,4*v+9]);
91
92 qrs[1][0][7] = 0;
93 qrs[1][3][48] = 1;
94 qrs[1][5][46] = 1;
95
96 let qr = qrs[1].map(l=>l.map(c=>c?'\u2588':' ').join(''));
97
98 let t = `
99
100${qr.join('\n')}
101
102`;
103
104 //t = `${qrs[0].length} ${qrs[1].length}`
105
106 return t;
107}
108
109
110
111/// TEST CODE
112//blackcore.member_access {username:"shareef_j", process:"order_qrs"}
113// RESULT #0
114// {
115// "id":"ikw4uy",
116// "user":"notused",
117// "packing_notes":"1 unit",
118// "enj":"6t11do"
119// }
120
121