UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

752 lines (612 loc) 21.2 kB
import { Encoding } from './encoding'; import deepExtend from '../../common/deep-extend'; import inArray from '../../common/in-array'; const numberRegex = /^\d+$/; const alphanumericRegex = /^[a-z0-9]+$/i; const extend = Object.assign; export class State128 { constructor(encoding) { this.encoding = encoding; this.initProperties(); } initProperties() { } addStart() { } is() { } isCode() { return false; } move() { } pushState() { } } export class State128AB extends State128 { constructor(encoding, states) { super(encoding); this.states = states; this._initMoves(states); } initProperties() { super.initProperties(); deepExtend(this, { FNC4: "FNC4", SHIFT: 98 }); } addStart() { this.encoding.addPattern(this.START); } is(value, index) { let code = value.charCodeAt(index); return this.isCode(code); } move(encodingState) { let idx = 0; while (!this._moves[idx].call(this, encodingState) && idx < this._moves.length) { idx++; } } pushState(encodingState) { let states = this.states, value = encodingState.value, maxLength = value.length, code; if (inArray("C", states)) { let numberMatch = value.substr(encodingState.index).match(/\d{4,}/g); if (numberMatch) { maxLength = value.indexOf(numberMatch[0], encodingState.index); } } while ((code = encodingState.value.charCodeAt(encodingState.index)) >= 0 && this.isCode(code) && encodingState.index < maxLength) { this.encoding.addPattern(this.getValue(code)); encodingState.index++; } } _initMoves(states) { this._moves = []; if (inArray(this.FNC4, states)) { this._moves.push(this._moveFNC); } if (inArray(this.shiftKey, states)) { this._moves.push(this._shiftState); } this._moves.push(this._moveState); } _moveFNC(encodingState) { if (encodingState.fnc) { encodingState.fnc = false; return encodingState.previousState === this.key; } } _shiftState(encodingState) { if (encodingState.previousState === this.shiftKey && (encodingState.index + 1 >= encodingState.value.length || this.encoding[this.shiftKey].is(encodingState.value, encodingState.index + 1))) { this.encoding.addPattern(this.SHIFT); encodingState.shifted = true; return true; } } _moveState() { this.encoding.addPattern(this.MOVE); return true; } } const states128 = {}; states128.A = class State128A extends State128AB { initProperties() { super.initProperties(); extend(this, { key: "A", shiftKey: "B", MOVE: 101, START: 103 }); } isCode(code) { return 0 <= code && code < 96; } getValue(code) { if (code < 32) { return code + 64; } return code - 32; } }; states128.B = class State128B extends State128AB { initProperties() { super.initProperties(); extend(this, { key: "B", shiftKey: "A", MOVE: 100, START: 104 }); } isCode(code) { return 32 <= code && code < 128; } getValue(code) { return code - 32; } }; states128.C = class State128C extends State128 { initProperties() { super.initProperties(); extend(this, { key: "C", MOVE: 99, START: 105 }); } addStart() { this.encoding.addPattern(this.START); } is(value, index) { let next4 = getSubstring(value, index, 4); return (index + 4 <= value.length || value.length === 2) && numberRegex.test(next4); } move() { this.encoding.addPattern(this.MOVE); } pushState(encodingState) { let code; while ((code = getSubstring(encodingState.value, encodingState.index, 2)) && numberRegex.test(code) && code.length === 2) { this.encoding.addPattern(parseInt(code, 10)); encodingState.index += 2; } } getValue(code) { return code; } }; states128.FNC4 = class State128FNC4 extends State128 { constructor(encoding, states) { super(encoding); this._initSubStates(states); } initProperties() { super.initProperties(); extend(this, { key: "FNC4", dependentStates: ["A", "B"] }); } addStart(encodingState) { let code = encodingState.value.charCodeAt(0) - 128, subState = this._getSubState(code); this.encoding[subState].addStart(); } is(value, index) { let code = value.charCodeAt(index); return this.isCode(code); } isCode(code) { return 128 <= code && code < 256; } pushState(encodingState) { let subState = this._initSubState(encodingState), encoding = this.encoding, length = subState.value.length; let code; encodingState.index += length; if (length < 3) { for (; subState.index < length; subState.index++) { code = subState.value.charCodeAt(subState.index); subState.state = this._getSubState(code); if (subState.previousState !== subState.state) { subState.previousState = subState.state; encoding[subState.state].move(subState); } encoding.addPattern(encoding[subState.state].MOVE); encoding.addPattern(encoding[subState.state].getValue(code)); } } else { if (subState.state !== subState.previousState) { encoding[subState.state].move(subState); } this._pushStart(subState); encoding.pushData(subState, this.subStates); if (encodingState.index < encodingState.value.length) { this._pushStart(subState); } } encodingState.fnc = true; encodingState.state = subState.state; } _pushStart(subState) { this.encoding.addPattern(this.encoding[subState.state].MOVE); this.encoding.addPattern(this.encoding[subState.state].MOVE); } _initSubState(encodingState) { const subState = { value: this._getAll(encodingState.value, encodingState.index), index: 0 }; subState.state = this._getSubState(subState.value.charCodeAt(0)); subState.previousState = encodingState.previousState === this.key ? subState.state : encodingState.previousState; return subState; } _initSubStates(states) { this.subStates = []; for (let i = 0; i < states.length; i++) { if (inArray(states[i], this.dependentStates)) { this.subStates.push(states[i]); } } } _getSubState(code) { for (let i = 0; i < this.subStates.length; i++) { if (this.encoding[this.subStates[i]].isCode(code)) { return this.subStates[i]; } } } _getAll(value, index) { let code; let result = ""; let i = index; while ((code = value.charCodeAt(i++)) && this.isCode(code)) { result += String.fromCharCode(code - 128); } return result; } }; states128.FNC1 = class States128FNC1 extends State128 { constructor(encoding, states) { super(encoding); this.states = states; } initProperties() { super.initProperties(); extend(this, { key: "FNC1", startState: "C", startAI: "(", endAI: ")", dependentStates: ["C", "B"], applicationIdentifiers: { "22": { max: 29, type: "alphanumeric" }, "402": { length: 17 }, "7004": { max: 4, type: "alphanumeric" }, "242": { max: 6, type: "alphanumeric" }, "8020": { max: 25, type: "alphanumeric" }, "703": { min: 3, max: 30, type: "alphanumeric" }, "8008": { min: 8, max: 12, type: "alphanumeric" }, "253": { min: 13, max: 17, type: "alphanumeric" }, "8003": { min: 14, max: 30, type: "alphanumeric" }, multiKey: [{ ids: ["15", "17", "8005", "8100"], ranges: [ [11, 13], [310, 316], [320, 336], [340, 369] ], type: { length: 6 } }, { ids: ["240", "241", "250", "251", "400", "401", "403", "7002", "8004", "8007", "8110"], ranges: [[90 - 99]], type: { max: 30, type: "alphanumeric" } }, { ids: ["7001"], ranges: [[410, 414]], type: { length: 13 } }, { ids: ["10", "21", "254", "420", "8002"], type: { max: 20, type: "alphanumeric" } }, { ids: ["00", "8006", "8017", "8018"], type: { length: 18 } }, { ids: ["01", "02", "8001"], type: { length: 14 } }, { ids: ["422"], ranges: [ [424, 426] ], type: { length: 3 } }, { ids: ["20", "8102"], type: { length: 2 } }, { ids: ["30", "37"], type: { max: 8, type: "alphanumeric" } }, { ids: ["390", "392"], type: { max: 15, type: "alphanumeric" } }, { ids: ["421", "423"], type: { min: 3, max: 15, type: "alphanumeric" } }, { ids: ["391", "393"], type: { min: 3, max: 18, type: "alphanumeric" } }, { ids: ["7003", "8101"], type: { length: 10 } }] }, START: 102 }); } addStart() { this.encoding[this.startState].addStart(); } is() { return inArray(this.key, this.states); } pushState(encodingState) { let encoding = this.encoding, value = encodingState.value.replace(/\s/g, ""), regexSeparators = new RegExp("[" + this.startAI + this.endAI + "]", "g"), index = encodingState.index, subState = { state: this.startState }, current, nextStart, separatorLength; encoding.addPattern(this.START); const trueCondition = true; while (trueCondition) { subState.index = 0; separatorLength = value.charAt(index) === this.startAI ? 2 : 0; current = separatorLength > 0 ? this.getBySeparator(value, index) : this.getByLength(value, index); if (current.ai.length) { nextStart = index + separatorLength + current.id.length + current.ai.length; } else { nextStart = value.indexOf(this.startAI, index + 1); if (nextStart < 0) { if (index + current.ai.max + current.id.length + separatorLength < value.length) { throw new Error("Separators are required after variable length identifiers"); } nextStart = value.length; } } subState.value = value.substring(index, nextStart).replace(regexSeparators, ""); this.validate(current, subState.value); encoding.pushData(subState, this.dependentStates); if (nextStart >= value.length) { break; } index = nextStart; if (subState.state !== this.startState) { encoding[this.startState].move(subState); subState.state = this.startState; } if (!current.ai.length) { encoding.addPattern(this.START); } } encodingState.index = encodingState.value.length; } validate(current, value) { let code = value.substr(current.id.length), ai = current.ai; if (!ai.type && !numberRegex.test(code)) { throw new Error("Application identifier " + current.id + " is numeric only but contains non numeric character(s)."); } if (ai.type === "alphanumeric" && !alphanumericRegex.test(code)) { throw new Error("Application identifier " + current.id + " is alphanumeric only but contains non alphanumeric character(s)."); } if (ai.length && ai.length !== code.length) { throw new Error("Application identifier " + current.id + " must be " + ai.length + " characters long."); } if (ai.min && ai.min > code.length) { throw new Error("Application identifier " + current.id + " must be at least " + ai.min + " characters long."); } if (ai.max && ai.max < code.length) { throw new Error("Application identifier " + current.id + " must be at most " + ai.max + " characters long."); } } getByLength(value, index) { let id; let applicationIdentifier; for (let i = 2; i <= 4; i++) { id = getSubstring(value, index, i); applicationIdentifier = this.getApplicationIdentifier(id) || this.getApplicationIdentifier(id.substring(0, id.length - 1)); if (applicationIdentifier) { return { id: id, ai: applicationIdentifier }; } } this.unsupportedAIError(id); } unsupportedAIError(id) { throw new Error("'" + id + "' is not a supported Application Identifier"); } getBySeparator(value, index) { let start = value.indexOf(this.startAI, index), end = value.indexOf(this.endAI, start), id = value.substring(start + 1, end), ai = this.getApplicationIdentifier(id) || this.getApplicationIdentifier(id.substr(id.length - 1)); if (!ai) { this.unsupportedAIError(id); } return { ai: ai, id: id }; } getApplicationIdentifier(id) { let applicationIdentifier = this.applicationIdentifiers, multiKey = applicationIdentifier.multiKey; if (applicationIdentifier[id]) { return applicationIdentifier[id]; } for (let i = 0; i < multiKey.length; i++) { if (multiKey[i].ids && inArray(id, multiKey[i].ids)) { return multiKey[i].type; } else if (multiKey[i].ranges) { let ranges = multiKey[i].ranges; for (let j = 0; j < ranges.length; j++) { if (ranges[j][0] <= id && id <= ranges[j][1]) { return multiKey[i].type; } } } } } }; export class Code128Base extends Encoding { constructor(options) { super(options); this._initStates(); } initProperties() { super.initProperties(); extend(this, { characterMap: [ 212222, 222122, 222221, 121223, 121322, 131222, 122213, 122312, 132212, 221213, 221312, 231212, 112232, 122132, 122231, 113222, 123122, 123221, 223211, 221132, 221231, 213212, 223112, 312131, 311222, 321122, 321221, 312212, 322112, 322211, 212123, 212321, 232121, 111323, 131123, 131321, 112313, 132113, 132311, 211313, 231113, 231311, 112133, 112331, 132131, 113123, 113321, 133121, 313121, 211331, 231131, 213113, 213311, 213131, 311123, 311321, 331121, 312113, 312311, 332111, 314111, 221411, 431111, 111224, 111422, 121124, 121421, 141122, 141221, 112214, 112412, 122114, 122411, 142112, 142211, 241211, 221114, 413111, 241112, 134111, 111242, 121142, 121241, 114212, 124112, 124211, 411212, 421112, 421211, 212141, 214121, 412121, 111143, 111341, 131141, 114113, 114311, 411113, 411311, 113141, 114131, 311141, 411131, 211412, 211214, 211232, 2331112 ], STOP: 106 }); } _initStates() { for (let i = 0; i < this.states.length; i++) { this[this.states[i]] = new states128[this.states[i]](this, this.states); } } initValue(value, width, height) { this.pattern = []; this.value = value; this.width = width; this.height = height; this.checkSum = 0; this.totalUnits = 0; this.index = 0; this.position = 1; } addData() { let encodingState = { value: this.value, index: 0, state: "" }; if (this.value.length === 0) { return; } encodingState.state = encodingState.previousState = this.getNextState(encodingState, this.states); this.addStart(encodingState); this.pushData(encodingState, this.states); this.addCheckSum(); this.addStop(); this.setBaseUnit(); } pushData(encodingState, states) { const trueCondition = true; while (trueCondition) { this[encodingState.state].pushState(encodingState); if (encodingState.index >= encodingState.value.length) { break; } if (!encodingState.shifted) { encodingState.previousState = encodingState.state; encodingState.state = this.getNextState(encodingState, states); this[encodingState.state].move(encodingState); } else { let temp = encodingState.state; encodingState.state = encodingState.previousState; encodingState.previousState = temp; encodingState.shifted = false; } } } addStart(encodingState) { this[encodingState.state].addStart(encodingState); this.position = 1; } addCheckSum() { this.checksum = this.checkSum % 103; this.addPattern(this.checksum); } addStop() { this.addPattern(this.STOP); } setBaseUnit() { this.baseUnit = this.width / (this.totalUnits + this.quietZoneLength); } addPattern(code) { const pattern = this.characterMap[code].toString(); let value; for (let i = 0; i < pattern.length; i++) { value = parseInt(pattern.charAt(i), 10); this.pattern.push(value); this.totalUnits += value; } this.checkSum += code * this.position++; } getNextState(encodingState, states) { for (let i = 0; i < states.length; i++) { if (this[states[i]].is(encodingState.value, encodingState.index)) { return states[i]; } } this.invalidCharacterError(encodingState.value.charAt(encodingState.index)); } } export class Code128a extends Code128Base { initProperties() { super.initProperties(); extend(this, { name: "Code 128 A", states: ["A"] }); } } export class Code128b extends Code128Base { initProperties() { super.initProperties(); extend(this, { name: "Code 128 B", states: ["B"] }); } } export class Code128c extends Code128Base { initProperties() { super.initProperties(); extend(this, { name: "Code 128 C", states: ["C"] }); } } export class Code128 extends Code128Base { initProperties() { super.initProperties(); extend(this, { name: "Code 128", states: ["C", "B", "A", "FNC4"] }); } } export class CodeGS1128 extends Code128Base { initProperties() { super.initProperties(); extend(this, { name: "Code GS1-128", states: ["FNC1", "C", "B"] }); } } function getSubstring(value, index, count) { return value.substring(index, index + count); }