diff --git a/apihub-root/lightweight-pwa/css/main.css b/apihub-root/lightweight-pwa/css/main.css
new file mode 100644
index 0000000..b90558a
--- /dev/null
+++ b/apihub-root/lightweight-pwa/css/main.css
@@ -0,0 +1,288 @@
+@media only screen and (min-device-width: 480px) and (max-device-width: 3000px) {
+ body {
+ padding: 0;
+ max-width: 414px;
+ margin-right: auto;
+ margin-left: auto;
+ background-image: url("./../images/background.jpg");
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: cover;
+ }
+
+ .page-header {
+ font-size: 2rem;
+ }
+
+ .page-content .title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ margin-top: 24px;
+ }
+
+ .page-content .welcome-text {
+ margin-top: 8px;
+ font-size: 1rem;
+ }
+
+ .page-content .wizard-steps {
+ display: flex;
+ justify-content: space-around;
+ font-size: 1rem;
+ margin-top: 97px;
+ flex-grow: 1;
+ }
+
+ .scan-button {
+ margin-bottom: 30px;
+ }
+
+ .scan-button button {
+ display: flex;
+ justify-content: center;
+ width: 270px;
+ position: relative;
+ margin-left: auto;
+ margin-right: auto;
+ background: #02272F;;
+ border-radius: 40px;
+ text-transform: capitalize;
+ padding: 12px;
+ font-size: 1rem;
+ color: #fff;
+ line-height: 40px;
+ }
+
+ .scan-image {
+ margin-right: 20px;
+ margin-top: 7px;
+ width: 25px;
+ }
+
+ #leaflet-content {
+ text-align: start;
+ margin: 25px 0px;
+ font-size: 0.7rem;
+ }
+
+ #leaflet-content h5 {
+ font-size: 1.3rem;
+ }
+
+ #leaflet-content table {
+ display: block;
+ overflow-x: auto;
+ }
+
+ #leaflet-content img {
+ width: 100%;
+ }
+
+ .leaflet-link {
+ color: #4f4edf;;
+ text-decoration: underline;
+ }
+}
+
+@media only screen and (max-device-width: 480px) {
+ body {
+ margin: 0;
+ }
+
+ .page-header {
+ font-size: 4rem;
+ }
+
+ .page-content .title {
+ font-size: 5rem;
+ font-weight: 700;
+ margin-top: 24px;
+ }
+
+ .page-content .welcome-text {
+ margin-top: 8px;
+ font-size: 2rem;
+ }
+
+ .page-content .wizard-steps {
+ display: flex;
+ justify-content: space-around;
+ font-size: 2rem;
+ margin-top: 97px;
+ flex-grow: 1;
+ }
+
+ .scan-button {
+ margin-bottom: 100px;
+ }
+
+ .scan-button button {
+ display: flex;
+ justify-content: center;
+ width: 60%;
+ position: relative;
+ margin-left: auto;
+ margin-right: auto;
+ background: #02272F;;
+ border-radius: 65px;
+ text-transform: capitalize;
+ padding: 20px;
+ font-size: 3rem;
+ color: #fff;
+ line-height: 100px;
+ }
+
+ .scan-image {
+ margin-right: 20px;
+ margin-top: 20px;
+ width: 55px;
+ }
+
+ #leaflet-content {
+ text-align: start;
+ margin: 25px;
+ font-size: 0.7rem;
+ }
+
+ #leaflet-content h5 {
+ font-size: 2rem;
+ }
+
+ #leaflet-content table {
+ display: block;
+ overflow-x: auto;
+ }
+
+ #leaflet-content img {
+ width: 100%;
+ }
+
+ .leaflet-link {
+ color: #4f4edf;;
+ text-decoration: underline;
+ }
+}
+
+body {
+ font-family: Nunito, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-size: 1rem;
+ padding: 0;
+ width: 100%;
+}
+
+.mobile-container {
+ margin: 0 auto;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.25);
+ background: #02272F;
+}
+
+.page-header {
+ background: #02272F;
+ color: white;
+ min-height: 97px;
+ display: flex;
+ justify-content: center;
+ height: 10%;
+}
+
+.page-header span {
+ align-self: center;
+}
+
+.page-content {
+ background: #FAFAFA;
+ height: 90%;
+ border-top-right-radius: 40px;
+ border-top-left-radius: 40px;
+ position: relative;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ overflow-y: auto;
+ padding: 0px 25px;
+}
+
+.page-content.scan-page {
+ background: none;
+ overflow-y: hidden;
+ padding: 0px;
+}
+
+.welcome-container {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ justify-content: center;
+}
+
+.page-content .app-image {
+ content: url("./../images/app_icon.svg");
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.page-content .wizard-steps .step-item {
+ display: flex;
+ flex-direction: column;
+ max-width: 30%;
+}
+
+.page-content .wizard-steps .step-item .step-title {
+ font-weight: 700;
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+.wizard-steps .step1 .step-icon {
+ content: url("./../images/wizard_step1.svg");
+ width: 100%;
+}
+
+.wizard-steps .step2 .step-icon {
+ content: url("./../images/wizard_step2.svg");
+ width: 100%;
+}
+
+.wizard-steps .step3 .step-icon {
+ content: url("./../images/wizard_step3.svg");
+ width: 100%;
+}
+
+
+/*
+.leaflet-accordion-item-content {
+ visibility: hidden;
+ margin-right: 5px;
+ font-size: 1rem;
+ height: fit-content;
+}
+
+.leaflet-accordion-item-content.active {
+ height: fit-content;
+ visibility: visible;
+ max-height: 100%;
+ font-size: 1rem;
+}
+
+.leaflet-accordion-item-content:before {
+ content: "\002b";
+ font-weight: 900;
+ margin-right: 5px;
+ visibility: visible;
+ right: 0px;
+ position: relative;
+ top: -38px;
+ float: right;
+ font-size: 35px;
+}
+
+.leaflet-accordion-item-content.active:before {
+ content: '\2212';
+ visibility: visible;
+ font-size: 35px;
+}
+
+
diff --git a/apihub-root/lightweight-pwa/environment.js b/apihub-root/lightweight-pwa/environment.js
new file mode 100644
index 0000000..404b612
--- /dev/null
+++ b/apihub-root/lightweight-pwa/environment.js
@@ -0,0 +1,4 @@
+export default {
+ "epiDomain": "epi",
+ "leafletWebApiUrl": "http://localhost:8080/leaflets"
+}
diff --git a/apihub-root/lightweight-pwa/html/error.html b/apihub-root/lightweight-pwa/html/error.html
new file mode 100644
index 0000000..7c7505d
--- /dev/null
+++ b/apihub-root/lightweight-pwa/html/error.html
@@ -0,0 +1 @@
+Error !!!!
diff --git a/apihub-root/lightweight-pwa/html/index.html b/apihub-root/lightweight-pwa/html/index.html
new file mode 100644
index 0000000..f9aeb72
--- /dev/null
+++ b/apihub-root/lightweight-pwa/html/index.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to Pharmaledger
+
+ An app created to help you inquire about new or prescribed medications
+
+
+
+
+
+
+
STEP 1
+
Locate data matrix code.
+
+
+
+
STEP 2
+
Scan data matrix code.
+
+
+
+
STEP 3
+
Track your medicine info.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apihub-root/lightweight-pwa/html/leaflet.html b/apihub-root/lightweight-pwa/html/leaflet.html
new file mode 100644
index 0000000..dd7df6f
--- /dev/null
+++ b/apihub-root/lightweight-pwa/html/leaflet.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apihub-root/lightweight-pwa/html/scan.html b/apihub-root/lightweight-pwa/html/scan.html
new file mode 100644
index 0000000..aaf7f70
--- /dev/null
+++ b/apihub-root/lightweight-pwa/html/scan.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
diff --git a/apihub-root/lightweight-pwa/images/app_icon.svg b/apihub-root/lightweight-pwa/images/app_icon.svg
new file mode 100644
index 0000000..d38444c
--- /dev/null
+++ b/apihub-root/lightweight-pwa/images/app_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/apihub-root/lightweight-pwa/images/background.jpg b/apihub-root/lightweight-pwa/images/background.jpg
new file mode 100644
index 0000000..71aa01a
Binary files /dev/null and b/apihub-root/lightweight-pwa/images/background.jpg differ
diff --git a/apihub-root/lightweight-pwa/images/img.png b/apihub-root/lightweight-pwa/images/img.png
new file mode 100644
index 0000000..5dabf4d
Binary files /dev/null and b/apihub-root/lightweight-pwa/images/img.png differ
diff --git a/apihub-root/lightweight-pwa/images/login.png b/apihub-root/lightweight-pwa/images/login.png
new file mode 100644
index 0000000..e69de29
diff --git a/apihub-root/lightweight-pwa/images/scan_icon.svg b/apihub-root/lightweight-pwa/images/scan_icon.svg
new file mode 100644
index 0000000..995b0a3
--- /dev/null
+++ b/apihub-root/lightweight-pwa/images/scan_icon.svg
@@ -0,0 +1,9 @@
+
diff --git a/apihub-root/lightweight-pwa/images/wizard_step1.svg b/apihub-root/lightweight-pwa/images/wizard_step1.svg
new file mode 100644
index 0000000..9b68b17
--- /dev/null
+++ b/apihub-root/lightweight-pwa/images/wizard_step1.svg
@@ -0,0 +1,35 @@
+
diff --git a/apihub-root/lightweight-pwa/images/wizard_step2.svg b/apihub-root/lightweight-pwa/images/wizard_step2.svg
new file mode 100644
index 0000000..4cf0d7f
--- /dev/null
+++ b/apihub-root/lightweight-pwa/images/wizard_step2.svg
@@ -0,0 +1,45 @@
+
diff --git a/apihub-root/lightweight-pwa/images/wizard_step3.svg b/apihub-root/lightweight-pwa/images/wizard_step3.svg
new file mode 100644
index 0000000..57e8b5e
--- /dev/null
+++ b/apihub-root/lightweight-pwa/images/wizard_step3.svg
@@ -0,0 +1,21 @@
+
diff --git a/apihub-root/lightweight-pwa/js/controllers/LeafletController.js b/apihub-root/lightweight-pwa/js/controllers/LeafletController.js
new file mode 100644
index 0000000..db015ac
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/controllers/LeafletController.js
@@ -0,0 +1,59 @@
+import XMLDisplayService from "../services/XMLDisplayService/XMLDisplayService.js"
+import environment from "../../environment.js";
+import {goToPage} from "../utils/utils.js"
+
+function LeafletController() {
+ this.getLeaflet = function () {
+ let leafletApiUrl = environment.leafletWebApiUrl + "/" + environment.epiDomain;
+ let userLanguage = window.navigator.language.slice(0, 2);
+ let leafletLang = userLanguage || "en";
+ const queryString = window.location.search;
+ const urlParams = new URLSearchParams(queryString);
+ let gtin = urlParams.get("gtin");
+ let batch = urlParams.get("batch");
+ let fetchUrl = batch ? `${leafletApiUrl}?leaflet_type=leaflet&lang=${leafletLang}>in=${gtin}&batch=${batch}` : `${leafletApiUrl}?leaflet_type=leaflet&lang=${leafletLang}>in=${gtin}`
+
+ fetch(fetchUrl)
+ .then(response => {
+ console.log("------- response", response);
+ response.json().then(result => {
+ console.log(result);
+ let xmlService = new XMLDisplayService("#leaflet-content");
+ let resultDocument = xmlService.getHTMLFromXML(result.pathBase, result.xmlContent);
+ let leafletImages = resultDocument.querySelectorAll("img");
+ for (let image of leafletImages) {
+ image.setAttribute("src", result.leafletImages[image.getAttribute("src")]);
+ }
+ let sectionsElements = resultDocument.querySelectorAll(".leaflet-accordion-item");
+ let htmlContent = "";
+ sectionsElements.forEach(section => {
+ htmlContent = htmlContent + section.innerHTML;
+ })
+ document.querySelector("#leaflet-content").innerHTML = htmlContent;
+ let leafletLinks = document.querySelectorAll(".leaflet-link");
+ xmlService.activateLeafletInnerLinks(leafletLinks);
+ this.handleLeafletAccordion();
+ }).catch((err) => {
+ goToPage("error.html")
+ });
+ })
+ .catch((error) => {
+ console.error('Error:', error);
+ goToPage("error.html")
+ });
+ };
+ this.handleLeafletAccordion = function () {
+ let accordionItems = document.querySelectorAll(".leaflet-accordion-item-content");
+ accordionItems.forEach(accItem => {
+ accItem.addEventListener("click", (evt) => {
+ evt.target.classList.toggle("active");
+ })
+ })
+ }
+}
+
+const leafletController = new LeafletController();
+leafletController.getLeaflet();
+
+
+
diff --git a/apihub-root/lightweight-pwa/js/controllers/MainController.js b/apihub-root/lightweight-pwa/js/controllers/MainController.js
new file mode 100644
index 0000000..c11186d
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/controllers/MainController.js
@@ -0,0 +1,13 @@
+import ScanService, {SCANNER_STATUS} from "../services/ScanService.js";
+import {goToPage} from "../utils/utils.js"
+import interpretGS1scan from "../utils/interpretGS1scan/interpretGS1scan.js";
+
+function MainController() {
+ this.scanHandler = async function () {
+ goToPage("scan.html")
+ }
+}
+
+const mainController = new MainController();
+
+window.mainController = mainController;
diff --git a/apihub-root/lightweight-pwa/js/controllers/ScanController.js b/apihub-root/lightweight-pwa/js/controllers/ScanController.js
new file mode 100644
index 0000000..ff7a943
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/controllers/ScanController.js
@@ -0,0 +1,86 @@
+import {convertFromISOtoYYYY_HM, goToPage} from "../utils/utils.js";
+import interpretGS1scan from "../utils/interpretGS1scan/interpretGS1scan.js";
+import ScanService from "../services/ScanService.js";
+
+function ScanController() {
+ this.init = async function () {
+ let placeHolderElement = document.querySelector("#scanner-placeholder");
+ this.scanService = new ScanService(placeHolderElement);
+ try {
+ await this.scanService.setup();
+ } catch (err) {
+ this.redirectToError(err);
+ }
+ await this.startScanning();
+ }
+
+ this.redirectToError = function (err) {
+ console.log("Error on scanService ", err);
+ goToPage("error.html")
+ }
+
+
+ this.startScanning = async function () {
+ this.scanInterval = setInterval(() => {
+ this.scanService.scan().then(result => {
+ if (!result) {
+ return;
+ }
+ console.log("Scan result:", result);
+ this.scanService.stop();
+ clearInterval(this.scanInterval);
+
+ this.processGS1Fields(this.parseGS1Code(result.text));
+ }).catch(err => {
+ console.log("Caught", err);
+ });
+ }, 100);
+ }
+
+ this.parseGS1Code = function (scannedBarcode) {
+ let gs1FormatFields;
+ try {
+ gs1FormatFields = interpretGS1scan.interpretScan(scannedBarcode);
+ } catch (e) {
+ this.redirectToError(e);
+ return;
+ }
+
+ return this.parseGs1Fields(gs1FormatFields.ol);
+ }
+
+ this.parseGs1Fields = function (orderedList) {
+ const gs1Fields = {};
+ const fieldsConfig = {
+ "GTIN": "gtin",
+ "BATCH/LOT": "batchNumber",
+ "SERIAL": "serialNumber",
+ "USE BY OR EXPIRY": "expiry"
+ };
+
+ orderedList.map(el => {
+ let fieldName = fieldsConfig[el.label];
+ gs1Fields[fieldName] = el.value;
+ })
+
+ if (gs1Fields.expiry) {
+ gs1Fields.expiry = convertFromISOtoYYYY_HM(gs1Fields.expiry);
+ }
+
+ return gs1Fields;
+ }
+
+ this.processGS1Fields = function (gs1Fields) {
+ console.log("ta da ---------- >>>>> ", gs1Fields);
+ let domainName = "epi";
+ /* let gtinSSI = createGTIN_SSI(domainName, undefined, gs1Fields.gtin, gs1Fields.batchNumber);
+ let leafletXmlService = new XMLDisplayService(null, gtinSSI, {}, "leaflet");
+ let response = leafletXmlService.getHtmlForLanguage("en");
+ console.log("------- response", response);*/
+ goToPage(`leaflet.html?gtin=${gs1Fields.gtin}&batch=${gs1Fields.batchNumber}`)
+
+ }
+}
+
+const scanController = new ScanController();
+scanController.init();
diff --git a/apihub-root/lightweight-pwa/js/services/ScanService.js b/apihub-root/lightweight-pwa/js/services/ScanService.js
new file mode 100644
index 0000000..0c6f034
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/services/ScanService.js
@@ -0,0 +1,157 @@
+import Scanner from "./../../lib/zxing-wrapper/scanner.js";
+
+const SCANNER_STATUS = {
+ INITIALIZING: 'Initializing scanner...',
+ SETTING: 'Pending the access rights for the video cameras + DOM manipulations...',
+ ACTIVE: 'Video streaming is active, scanning is now available...',
+ DONE: 'Decoding is done!',
+ NO_CAMERAS: 'There are no cameras available!',
+ PERMISSION_DENIED: 'Access to the camera was denied!'
+}
+
+function createOverlay([x, y, w, h], canvasDimensions) {
+ const canvas = document.createElement("canvas");
+ canvas.id = "overlay";
+ canvas.width = canvasDimensions.width;
+ canvas.height = canvasDimensions.height;
+ canvas.style.position = "absolute";
+ canvas.style.top = "50%";
+ canvas.style.left = "50%";
+ canvas.style.transform = "translate(-50%, -50%)";
+
+ const context = canvas.getContext("2d");
+ context.lineWidth = 6;
+ context.strokeStyle = "rgb(255, 255, 255)";
+ context.fillStyle = "rgba(0, 0, 0, 0.5)";
+
+ const r = 20;
+
+ const clearBackdrop = (x, y, w, h, r) => {
+ context.save();
+ context.beginPath();
+
+ context.moveTo(x + r, y);
+ context.lineTo(x + w - r, y);
+ context.quadraticCurveTo(x + w, y, x + w, y + r);
+ context.lineTo(x + w, y + h - r);
+ context.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
+ context.lineTo(x + r, y + h);
+ context.quadraticCurveTo(x, y + h, x, y + h - r);
+ context.lineTo(x, y + r);
+ context.quadraticCurveTo(x, y, x + r, y);
+
+ context.clip();
+ context.clearRect(x, y, w, h);
+ context.restore();
+ };
+
+ const drawBackdrop = (x, y, w, h) => {
+ context.fillRect(x, y, w, h);
+ };
+
+ const drawCorners = (x, y, w, h) => {
+ const p = [
+ new Path2D("M53 3H19C10.1634 3 3 8.84767 3 16.0612V43"),
+ new Path2D("M53 43L53 15.8C53 8.73072 45.6904 3 36.6735 3L3 3"),
+ new Path2D("M3 43L37 43C45.8366 43 53 37.1523 53 29.9388L53 3"),
+ new Path2D("M3 3L3 30.2C3 37.2693 10.3096 43 19.3265 43L53 43"),
+ ];
+
+ // dimensions of Path2D
+ const d = {
+ l: context.lineWidth,
+ w: 50,
+ h: 40,
+ };
+
+ context.translate(x, y);
+ context.stroke(p[0]);
+
+ context.translate(w - d.w - d.l, 0);
+ context.stroke(p[1]);
+
+ context.translate(0, h - d.h - d.l);
+ context.stroke(p[2]);
+
+ context.translate(d.w + d.l - w, 0);
+ context.stroke(p[3]);
+
+ context.resetTransform();
+ };
+
+ drawBackdrop(0, 0, canvasDimensions.width, canvasDimensions.height);
+
+ clearBackdrop(x, y, w, h, r);
+
+ drawCorners(x, y, w, h);
+
+ return canvas;
+}
+
+function switchFacingMode(facingMode) {
+ switch (facingMode) {
+ case "environment":
+ return "user";
+ default:
+ return "environment";
+ }
+}
+
+class ScanService {
+ constructor(domElement) {
+ this._status = SCANNER_STATUS.INITIALIZING;
+ this._facingMode = null;
+
+ this.scanner = new Scanner(domElement);
+
+ // TODO: remove this changeWorker call when possible
+ this.scanner.changeWorker("../lib/zxing-wrapper/worker/zxing-0.18.6-worker.js");
+
+ this.scanner.drawOverlay = (centralPoints, canvasDimensions) => {
+ return createOverlay(centralPoints, canvasDimensions);
+ }
+
+ Object.defineProperty(this, 'status', {
+ get: () => this._status,
+ set: (status) => {
+ this._status = status;
+ this.onStatusChanged(this._status);
+ }
+ });
+ }
+
+ async setup() {
+ this.status = SCANNER_STATUS.SETTING;
+ this._facingMode = switchFacingMode(this._facingMode);
+
+ try {
+ await this.scanner.setup({
+ facingMode: this._facingMode,
+ useBasicSetup: false
+ });
+ this.status = SCANNER_STATUS.ACTIVE;
+ } catch (error) {
+ if (error.name === 'NotAllowedError') {
+ this.status = SCANNER_STATUS.PERMISSION_DENIED;
+ return;
+ }
+ throw error;
+ }
+ }
+
+ async scan() {
+ return await this.scanner.scan();
+ }
+
+ stop() {
+ this.scanner.shutDown();
+ }
+
+ onStatusChanged(status) {
+ console.log(`Status has changed to "${status}"`);
+ }
+}
+export default ScanService
+export {
+ SCANNER_STATUS
+}
diff --git a/apihub-root/lightweight-pwa/js/services/XMLDisplayService/XMLDisplayService.js b/apihub-root/lightweight-pwa/js/services/XMLDisplayService/XMLDisplayService.js
new file mode 100644
index 0000000..5ce8d5c
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/services/XMLDisplayService/XMLDisplayService.js
@@ -0,0 +1,230 @@
+const xslContent = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Highlights of prescribing information
+
+
+
+
+
+
+
+
+
+
+
+
+`
+
+class XMLDisplayService {
+ constructor(containerIdSelector) {
+ this.containerIdSelector = containerIdSelector;
+ }
+
+ activateLeafletInnerLinks = function (leafletLinks) {
+ for (let link of leafletLinks) {
+ let linkUrl = link.getAttribute("linkUrl");
+ if (linkUrl.slice(0, 1) === "#") {
+ link.addEventListener("click", () => {
+ document.getElementById(linkUrl.slice(1)).scrollIntoView();
+ });
+ }
+ }
+ }
+
+ getHTMLFromXML = function (pathBase, xmlContent) {
+ let xsltProcessor = new XSLTProcessor();
+ xsltProcessor.setParameter(null, "resources_path", "");
+ let parser = new DOMParser();
+
+ let xmlDoc = parser.parseFromString(xmlContent, "text/xml");
+
+ let xslDoc = parser.parseFromString(xslContent, "text/xml");
+
+ xsltProcessor.importStylesheet(xslDoc);
+
+ let resultDocument = xsltProcessor.transformToFragment(xmlDoc, document);
+ return resultDocument;
+ }
+
+ searchInHtml = function (searchQuery) {
+ let domElement = document.querySelector(this.containerIdSelector);
+ let cleanHtml = domElement.innerHTML.replace(/(|<\/mark>)/gim, '');
+ domElement.innerHTML = cleanHtml;
+ if (searchQuery === "") {
+ return
+ }
+ const regex = new RegExp(searchQuery, 'gi');
+ try {
+ let domNode = domElement.parentElement.ownerDocument.evaluate(`.//*[text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),"${searchQuery}")]]`, domElement).iterateNext();
+ domNode.closest("leaflet-section").open();
+ let text = domNode.innerHTML;
+ const newText = text.replace(regex, '$&');
+ domNode.innerHTML = newText;
+ domNode.scrollIntoView({block: "nearest"});
+ window.scroll(0, domNode.getBoundingClientRect().height);
+ } catch (e) {
+ // not found should not throw error just skip and wait for new input
+ }
+ }
+}
+
+export default XMLDisplayService;
diff --git a/apihub-root/lightweight-pwa/js/services/XMLDisplayService/leafletXSL.js b/apihub-root/lightweight-pwa/js/services/XMLDisplayService/leafletXSL.js
new file mode 100644
index 0000000..1dbe31e
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/services/XMLDisplayService/leafletXSL.js
@@ -0,0 +1,179 @@
+const xslContent = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Highlights of prescribing information
+
+
+
+
+
+
+
+
+
+
+
+
+`
+
+export {
+ xslContent
+}
diff --git a/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/GS1DigitalLinkToolkit.js b/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/GS1DigitalLinkToolkit.js
new file mode 100644
index 0000000..210c802
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/GS1DigitalLinkToolkit.js
@@ -0,0 +1,5739 @@
+export default class GS1DigitalLinkToolkit {
+
+ // constructor sets up various data resources shared by multiple methods
+ constructor() {
+
+ // list of all GS1 Application Identifiers as defined in GS1 General Specifications v18
+ const aitable = [{
+ "title": "Serial Shipping Container Code (SSCC) ",
+ "label": "SSCC",
+ "shortcode": "sscc",
+ "ai": "00",
+ "format": "N18",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{18})"
+ }, {
+ "title": "Global Trade Item Number (GTIN)",
+ "label": "GTIN",
+ "shortcode": "gtin",
+ "ai": "01",
+ "format": "N14",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "qualifiers": ["22", "10", "21"],
+ "regex": "(\\d{12,14}|\\d{8})"
+ }, {
+ "title": "GTIN of contained trade items",
+ "label": "CONTENT",
+ "ai": "02",
+ "format": "N14",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{14})"
+ }, {
+ "title": "Batch or lot number",
+ "label": "BATCH/LOT",
+ "shortcode": "lot",
+ "ai": "10",
+ "format": "X..20",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x7E]{0,20})"
+ }, {
+ "title": "Production date (YYMMDD)",
+ "label": "PROD DATE",
+ "ai": "11",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Due date (YYMMDD)",
+ "label": "DUE DATE",
+ "ai": "12",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Packaging date (YYMMDD)",
+ "label": "PACK DATE",
+ "ai": "13",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Best before date (YYMMDD)",
+ "label": "BEST BEFORE or BEST BY",
+ "ai": "15",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Sell by date (YYMMDD)",
+ "label": "SELL BY",
+ "ai": "16",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Expiration date (YYMMDD)",
+ "label": "USE BY OR EXPIRY",
+ "shortcode": "exp",
+ "ai": "17",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Internal product variant",
+ "label": "VARIANT",
+ "ai": "20",
+ "format": "N2",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{2})"
+ }, {
+ "title": "Serial number",
+ "label": "SERIAL",
+ "shortcode": "ser",
+ "ai": "21",
+ "format": "X..20",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x7E]{0,20})"
+ }, {
+ "title": "Consumer product variant",
+ "label": "CPV",
+ "shortcode": "cpv",
+ "ai": "22",
+ "format": "X..20",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Additional product identification assigned by the manufacturer",
+ "label": "ADDITIONAL ID",
+ "ai": "240",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Customer part number",
+ "label": "CUST. PART NO.",
+ "ai": "241",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Made-to-Order variation number",
+ "label": "MTO VARIANT",
+ "ai": "242",
+ "format": "N..6",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,6})"
+ }, {
+ "title": "Packaging component number",
+ "label": "PCN",
+ "ai": "243",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Secondary serial number",
+ "label": "SECONDARY SERIAL",
+ "ai": "250",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x7E]{0,30})"
+ }, {
+ "title": "Reference to source entity",
+ "label": "REF. TO SOURCE ",
+ "ai": "251",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Global Document Type Identifier (GDTI)",
+ "label": "GDTI",
+ "shortcode": "gdti",
+ "ai": "253",
+ "format": "N13+X..17",
+ "type": "I",
+ "fixedLength": false,
+ "checkDigit": "13",
+ "regex": "(\\d{13})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,17})"
+ }, {
+ "title": "GLN extension component",
+ "label": "GLN EXTENSION COMPONENT",
+ "shortcode": "glnx",
+ "ai": "254",
+ "format": "X..20",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Global Coupon Number (GCN)",
+ "label": "GCN",
+ "shortcode": "gcn",
+ "ai": "255",
+ "format": "N13+N..12",
+ "type": "I",
+ "fixedLength": false,
+ "checkDigit": "13",
+ "regex": "(\\d{13})(\\d{0,12})"
+ }, {
+ "title": "Variable count of items (variable measure trade item)",
+ "label": "VAR. COUNT",
+ "ai": "30",
+ "format": "N..8",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,8})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3100",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3101",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3102",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3103",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3104",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, kilograms (variable measure trade item)",
+ "label": "NET WEIGHT (kg)",
+ "ai": "3105",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3110",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3111",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3112",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3113",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3114",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres (variable measure trade item)",
+ "label": "LENGTH (m)",
+ "ai": "3115",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3120",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3121",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3122",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3123",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3124",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres (variable measure trade item)",
+ "label": "WIDTH (m)",
+ "ai": "3125",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3130",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3131",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3132",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3133",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3134",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres (variable measure trade item)",
+ "label": "HEIGHT (m)",
+ "ai": "3135",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3140",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3141",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3142",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3143",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3144",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres (variable measure trade item)",
+ "label": "AREA (m^2)",
+ "ai": "3145",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3150",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3151",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3152",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3153",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3154",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, litres (variable measure trade item)",
+ "label": "NET VOLUME (l)",
+ "ai": "3155",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3160",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3161",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3162",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3163",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3164",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic metres (variable measure trade item)",
+ "label": "NET VOLUME (m^3)",
+ "ai": "3165",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3200",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3201",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3202",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3203",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3204",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, pounds (variable measure trade item)",
+ "label": "NET WEIGHT (lb)",
+ "ai": "3205",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3210",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3211",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3212",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3213",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3214",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches (variable measure trade item)",
+ "label": "LENGTH (in)",
+ "ai": "3215",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3220",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3221",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3222",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3223",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3224",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet (variable measure trade item)",
+ "label": "LENGTH (ft)",
+ "ai": "3225",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3230",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3231",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3232",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3233",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3234",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards (variable measure trade item)",
+ "label": "LENGTH (yd)",
+ "ai": "3235",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3240",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3241",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3242",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3243",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3244",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches (variable measure trade item)",
+ "label": "WIDTH (in)",
+ "ai": "3245",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3250",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3251",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3252",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3253",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3254",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet (variable measure trade item)",
+ "label": "WIDTH (ft)",
+ "ai": "3255",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3260",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3261",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3262",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3263",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3264",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yards (variable measure trade item)",
+ "label": "WIDTH (yd)",
+ "ai": "3265",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3270",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3271",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3272",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3273",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3274",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches (variable measure trade item)",
+ "label": "HEIGHT (in)",
+ "ai": "3275",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3280",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3281",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3282",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3283",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3284",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet (variable measure trade item)",
+ "label": "HEIGHT (ft)",
+ "ai": "3285",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3290",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3291",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3292",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3293",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3294",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards (variable measure trade item)",
+ "label": "HEIGHT (yd)",
+ "ai": "3295",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3300",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3301",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3302",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3303",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3304",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, kilograms",
+ "label": "GROSS WEIGHT (kg)",
+ "ai": "3305",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3310",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3311",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3312",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3313",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3314",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, metres",
+ "label": "LENGTH (m), log",
+ "ai": "3315",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3320",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3321",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3322",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3323",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3324",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, metres",
+ "label": "WIDTH (m), log",
+ "ai": "3325",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3330",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3331",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3332",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3333",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3334",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, metres",
+ "label": "HEIGHT (m), log",
+ "ai": "3335",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3340",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3341",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3342",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3343",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3344",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square metres",
+ "label": "AREA (m^2), log",
+ "ai": "3345",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3350",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3351",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3352",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3353",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3354",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, litres",
+ "label": "VOLUME (l), log",
+ "ai": "3355",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3360",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3361",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3362",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3363",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3364",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic metres",
+ "label": "VOLUME (m^3), log",
+ "ai": "3365",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3370",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3371",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3372",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3373",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3374",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Kilograms per square metre",
+ "label": "KG PER m^2",
+ "ai": "3375",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3400",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3401",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3402",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3403",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3404",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic weight, pounds",
+ "label": "GROSS WEIGHT (lb)",
+ "ai": "3405",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3410",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3411",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3412",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3413",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3414",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, inches",
+ "label": "LENGTH (in), log",
+ "ai": "3415",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3420",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3421",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3422",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3423",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3424",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, feet",
+ "label": "LENGTH (ft), log",
+ "ai": "3425",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3430",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3431",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3432",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3433",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3434",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Length or first dimension, yards",
+ "label": "LENGTH (yd), log",
+ "ai": "3435",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3440",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3441",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3442",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3443",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3444",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, inches",
+ "label": "WIDTH (in), log",
+ "ai": "3445",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3450",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3451",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3452",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3453",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3454",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, feet",
+ "label": "WIDTH (ft), log",
+ "ai": "3455",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3460",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3461",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3462",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3463",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3464",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Width, diameter, or second dimension, yard",
+ "label": "WIDTH (yd), log",
+ "ai": "3465",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3470",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3471",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3472",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3473",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3474",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, inches",
+ "label": "HEIGHT (in), log",
+ "ai": "3475",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3480",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3481",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3482",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3483",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3484",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, feet",
+ "label": "HEIGHT (ft), log",
+ "ai": "3485",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3490",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3491",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3492",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3493",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3494",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Depth, thickness, height, or third dimension, yards",
+ "label": "HEIGHT (yd), log",
+ "ai": "3495",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3500",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3501",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3502",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3503",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3504",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches (variable measure trade item)",
+ "label": "AREA (in^2)",
+ "ai": "3505",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3510",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3511",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3512",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3513",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3514",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet (variable measure trade item)",
+ "label": "AREA (ft^2)",
+ "ai": "3515",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3520",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3521",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3522",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3523",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3524",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards (variable measure trade item)",
+ "label": "AREA (yd^2)",
+ "ai": "3525",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3530",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3531",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3532",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3533",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3534",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square inches",
+ "label": "AREA (in^2), log",
+ "ai": "3535",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3540",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3541",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3542",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3543",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3544",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square feet",
+ "label": "AREA (ft^2), log",
+ "ai": "3545",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3550",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3551",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3552",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3553",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3554",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Area, square yards",
+ "label": "AREA (yd^2), log",
+ "ai": "3555",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3560",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3561",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3562",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3563",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3564",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight, troy ounces (variable measure trade item)",
+ "label": "NET WEIGHT (t oz)",
+ "ai": "3565",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3570",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3571",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3572",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3573",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3574",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net weight (or volume), ounces (variable measure trade item)",
+ "label": "NET VOLUME (oz)",
+ "ai": "3575",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3600",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3601",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3602",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3603",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3604",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, quarts (variable measure trade item)",
+ "label": "NET VOLUME (qt)",
+ "ai": "3605",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3610",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3611",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3612",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3613",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3614",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, gallons U.S. (variable measure trade item)",
+ "label": "NET VOLUME (gal.)",
+ "ai": "3615",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3620",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3621",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3622",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3623",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3624",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, quarts",
+ "label": "VOLUME (qt), log",
+ "ai": "3625",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3630",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3631",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3632",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3633",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3634",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, gallons U.S.",
+ "label": "VOLUME (gal.), log",
+ "ai": "3635",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3640",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3641",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3642",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3643",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3644",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic inches (variable measure trade item)",
+ "label": "VOLUME (in^3) ",
+ "ai": "3645",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3650",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3651",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3652",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3653",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3654",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic feet (variable measure trade item)",
+ "label": "VOLUME (ft^3) ",
+ "ai": "3655",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3660",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3661",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3662",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3663",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3664",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Net volume, cubic yards (variable measure trade item)",
+ "label": "VOLUME (yd^3) ",
+ "ai": "3665",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3670",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3671",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3672",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3673",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3674",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic inches",
+ "label": "VOLUME (in^3), log",
+ "ai": "3675",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3680",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3681",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3682",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3683",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3684",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic feet",
+ "label": "VOLUME (ft^3), log",
+ "ai": "3685",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3690",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3691",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3692",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3693",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3694",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Logistic volume, cubic yards",
+ "label": "VOLUME (yd^3), log",
+ "ai": "3695",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Count of trade items",
+ "label": "COUNT",
+ "ai": "37",
+ "format": "N..8",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,8})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3900",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3901",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3902",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3903",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3904",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3905",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3906",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3907",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3908",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable or Coupon value, local currency",
+ "label": "AMOUNT",
+ "ai": "3909",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3910",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3911",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3912",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3913",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3914",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3915",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3916",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3917",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3918",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code",
+ "label": "AMOUNT",
+ "ai": "3919",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3920",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3921",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3922",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3923",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3924",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3925",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3926",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3927",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3928",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable, single monetary area (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3929",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3930",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3931",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3932",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3933",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3934",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3935",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3936",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3937",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3938",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Applicable amount payable with ISO currency code (variable measure trade item)",
+ "label": "PRICE",
+ "ai": "3939",
+ "format": "N..15",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,15})"
+ }, {
+ "title": "Percentage discount of a coupon",
+ "label": "PRCNT OFF",
+ "ai": "3940",
+ "format": "N4",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{4})"
+ }, {
+ "title": "Percentage discount of a coupon",
+ "label": "PRCNT OFF",
+ "ai": "3941",
+ "format": "N4",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{4})"
+ }, {
+ "title": "Percentage discount of a coupon",
+ "label": "PRCNT OFF",
+ "ai": "3942",
+ "format": "N4",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{4})"
+ }, {
+ "title": "Percentage discount of a coupon",
+ "label": "PRCNT OFF",
+ "ai": "3943",
+ "format": "N4",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{4})"
+ }, {
+ "title": "Customer's purchase order number",
+ "label": "ORDER NUMBER",
+ "ai": "400",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Global Identification Number for Consignment (GINC)",
+ "label": "GINC",
+ "shortcode": "ginc",
+ "ai": "401",
+ "format": "X..30",
+ "type": "I",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Global Shipment Identification Number (GSIN)",
+ "label": "GSIN",
+ "shortcode": "gsin",
+ "ai": "402",
+ "format": "N17",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{17})"
+ }, {
+ "title": "Routing code",
+ "label": "ROUTE",
+ "ai": "403",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Ship to - Deliver to Global Location Number",
+ "label": "SHIP TO LOC",
+ "ai": "410",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Bill to - Invoice to Global Location Number",
+ "label": "BILL TO ",
+ "ai": "411",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Purchased from Global Location Number",
+ "label": "PURCHASE FROM",
+ "ai": "412",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Ship for - Deliver for - Forward to Global Location Number",
+ "label": "SHIP FOR LOC",
+ "ai": "413",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Identification of a physical location - Global Location Number",
+ "label": "LOC No",
+ "shortcode": "gln",
+ "ai": "414",
+ "format": "N13",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "qualifiers": ["254"],
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Global Location Number of the invoicing party",
+ "label": "PAY TO",
+ "shortcode": "payto",
+ "ai": "415",
+ "format": "N13",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "GLN of the production or service location",
+ "label": "PROD/SERV LOC",
+ "ai": "416",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "regex": "(\\d{13})"
+ }, {
+ "title": "Ship to - Deliver to postal code within a single postal authority",
+ "label": "SHIP TO POST",
+ "ai": "420",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Ship to - Deliver to postal code with ISO country code",
+ "label": "SHIP TO POST",
+ "ai": "421",
+ "format": "N3+X..9",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,9})"
+ }, {
+ "title": "Country of origin of a trade item",
+ "label": "ORIGIN",
+ "ai": "422",
+ "format": "N3",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{3})"
+ }, {
+ "title": "Country of initial processing",
+ "label": "COUNTRY - INITIAL PROCESS.",
+ "ai": "423",
+ "format": "N3+N..12",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,12})"
+ }, {
+ "title": "Country of processing",
+ "label": "COUNTRY - PROCESS.",
+ "ai": "424",
+ "format": "N3",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{3})"
+ }, {
+ "title": "Country of disassembly",
+ "label": "COUNTRY - DISASSEMBLY",
+ "ai": "425",
+ "format": "N3+N..12",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})(\\d{0,12})"
+ }, {
+ "title": "Country covering full process chain",
+ "label": "COUNTRY - FULL PROCESS",
+ "ai": "426",
+ "format": "N3",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{3})"
+ }, {
+ "title": "Country subdivision Of origin",
+ "label": "ORIGIN SUBDIVISION",
+ "ai": "427",
+ "format": "X..3",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,3})"
+ }, {
+ "title": "NATO Stock Number (NSN)",
+ "label": "NSN",
+ "ai": "7001",
+ "format": "N13",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{13})"
+ }, {
+ "title": "UN/ECE meat carcasses and cuts classification",
+ "label": "MEAT CUT",
+ "ai": "7002",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Expiration date and time",
+ "label": "EXPIRY TIME",
+ "shortcode": "expdt",
+ "ai": "7003",
+ "format": "N10",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{10})"
+ }, {
+ "title": "Active potency",
+ "label": "ACTIVE POTENCY",
+ "ai": "7004",
+ "format": "N..4",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{0,4})"
+ }, {
+ "title": "Catch area",
+ "label": "CATCH AREA",
+ "ai": "7005",
+ "format": "X..12",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,12})"
+ }, {
+ "title": "First freeze date ",
+ "label": "FIRST FREEZE DATE",
+ "ai": "7006",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Harvest date",
+ "label": "HARVEST DATE",
+ "ai": "7007",
+ "format": "N6..12",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{6,12})"
+ }, {
+ "title": "Species for fishery purposes",
+ "label": "AQUATIC SPECIES",
+ "ai": "7008",
+ "format": "X..3",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,3})"
+ }, {
+ "title": "Fishing gear type",
+ "label": "FISHING GEAR TYPE",
+ "ai": "7009",
+ "format": "X..10",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,10})"
+ }, {
+ "title": "Production method",
+ "label": "PROD METHOD",
+ "ai": "7010",
+ "format": "X..2",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,2})"
+ }, {
+ "title": "Refurbishment lot ID",
+ "label": "REFURB LOT",
+ "ai": "7020",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Functional status",
+ "label": "FUNC STAT",
+ "ai": "7021",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Revision status",
+ "label": "REV STAT",
+ "ai": "7022",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Global Individual Asset Identifier (GIAI) of an assembly",
+ "label": "GIAI - ASSEMBLY",
+ "ai": "7023",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 0",
+ "ai": "7030",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 1",
+ "ai": "7031",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 2",
+ "ai": "7032",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 3",
+ "ai": "7033",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 4",
+ "ai": "7034",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 5",
+ "ai": "7035",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 6",
+ "ai": "7036",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 7",
+ "ai": "7037",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 8",
+ "ai": "7038",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "Number of processor with ISO Country Code",
+ "label": "PROCESSOR # 9",
+ "ai": "7039",
+ "format": "X..27",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{3})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,27})"
+ }, {
+ "title": "National Healthcare Reimbursement Number (NHRN) - Germany PZN",
+ "label": "NHRN PZN",
+ "ai": "710",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "National Healthcare Reimbursement Number (NHRN) - France CIP",
+ "label": "NHRN CIP",
+ "ai": "711",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "National Healthcare Reimbursement Number (NHRN) - Spain CN",
+ "label": "NHRN CN",
+ "ai": "712",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "National Healthcare Reimbursement Number (NHRN) - Brasil DRN",
+ "label": "NHRN DRN",
+ "ai": "713",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "National Healthcare Reimbursement Number (NHRN) - Portugal AIM",
+ "label": "NHRN AIM",
+ "ai": "714",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Certification reference # 0",
+ "label": "CERT # 0",
+ "ai": "7230",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 1",
+ "label": "CERT # 1",
+ "ai": "7231",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 2",
+ "label": "CERT # 2",
+ "ai": "7232",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 3",
+ "label": "CERT # 3",
+ "ai": "7233",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 4",
+ "label": "CERT # 4",
+ "ai": "7234",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 5",
+ "label": "CERT # 5",
+ "ai": "7235",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 6",
+ "label": "CERT # 6",
+ "ai": "7236",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 7",
+ "label": "CERT # 7",
+ "ai": "7237",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 8",
+ "label": "CERT # 8",
+ "ai": "7238",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Certification reference # 9",
+ "label": "CERT # 9",
+ "ai": "7239",
+ "format": "X2+X..28",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{2,30})"
+ }, {
+ "title": "Roll products (width, length, core diameter, direction, splices)",
+ "label": "DIMENSIONS",
+ "ai": "8001",
+ "format": "N14",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{14})"
+ }, {
+ "title": "Cellular mobile telephone identifier",
+ "label": "CMT No",
+ "ai": "8002",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Global Returnable Asset Identifier (GRAI)",
+ "label": "GRAI",
+ "shortcode": "grai",
+ "ai": "8003",
+ "format": "N14+X..16",
+ "type": "I",
+ "fixedLength": false,
+ "checkDigit": "13",
+ "regex": "(\\d{14})([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,16})"
+ }, {
+ "title": "Global Individual Asset Identifier (GIAI)",
+ "label": "GIAI",
+ "shortcode": "giai",
+ "ai": "8004",
+ "format": "X..30",
+ "type": "I",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Price per unit of measure",
+ "label": "PRICE PER UNIT",
+ "ai": "8005",
+ "format": "N6",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{6})"
+ }, {
+ "title": "Identification of an individual trade item piece",
+ "label": "ITIP",
+ "shortcode": "itip",
+ "ai": "8006",
+ "format": "N14+N2+N2",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "14",
+ "qualifiers": ["22", "10", "21"],
+ "regex": "(\\d{14})(\\d{2})(\\d{2})"
+ }, {
+ "title": "International Bank Account Number (IBAN) ",
+ "label": "IBAN",
+ "ai": "8007",
+ "format": "X..34",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,34})"
+ }, {
+ "title": "Date and time of production",
+ "label": "PROD TIME",
+ "ai": "8008",
+ "format": "N8+N..4",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "(\\d{8})(\\d{0,4})"
+ }, {
+ "title": "Optically Readable Sensor Indicator",
+ "label": "OPT SEN",
+ "ai": "8009",
+ "format": "X..50",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,50})"
+ }, {
+ "title": "Component/Part Identifier (CPID)",
+ "label": "CPID",
+ "shortcode": "cpid",
+ "ai": "8010",
+ "format": "Y..30",
+ "type": "I",
+ "fixedLength": false,
+ "qualifiers": ["8011"],
+ "regex": "([\\x23\\x2D\\x2F\\x30-\\x39\\x41-\\x5A]{0,30})"
+ }, {
+ "title": "Component/Part Identifier serial number (CPID SERIAL)",
+ "label": "CPID SERIAL",
+ "shortcode": "cpsn",
+ "ai": "8011",
+ "format": "N..12",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "(\\d{0,12})"
+ }, {
+ "title": "Software version",
+ "label": "VERSION",
+ "ai": "8012",
+ "format": "X..20",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,20})"
+ }, {
+ "title": "Global Model Number (GMN)",
+ "label": "GMN (for medical devices, the default, global data title is BUDI-DI )",
+ "ai": "8013",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Global Service Relation Number - Provider",
+ "label": "GSRN - PROVIDER",
+ "shortcode": "gsrnp",
+ "ai": "8017",
+ "format": "N18",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "qualifiers": ["8019"],
+ "regex": "(\\d{18})"
+ }, {
+ "title": "Global Service Relation Number - Recipient",
+ "label": "GSRN - RECIPIENT",
+ "shortcode": "gsrn",
+ "ai": "8018",
+ "format": "N18",
+ "type": "I",
+ "fixedLength": true,
+ "checkDigit": "L",
+ "qualifiers": ["8019"],
+ "regex": "(\\d{18})"
+ }, {
+ "title": "Service Relation Instance Number (SRIN)",
+ "label": "SRIN",
+ "shortcode": "srin",
+ "ai": "8019",
+ "format": "N..10",
+ "type": "Q",
+ "fixedLength": false,
+ "regex": "(\\d{0,10})"
+ }, {
+ "title": "Payment slip reference number",
+ "label": "REF No",
+ "ai": "8020",
+ "format": "X..25",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,25})"
+ }, {
+ "title": "Identification of pieces of a trade item contained in a logistics unit",
+ "label": "ITIP CONTENT",
+ "ai": "8026",
+ "format": "N14+N2+N2",
+ "type": "D",
+ "fixedLength": true,
+ "checkDigit": "14",
+ "regex": "(\\d{14})(\\d{2})(\\d{2})"
+ }, {
+ "title": "Coupon code identification for use in North America",
+ "ai": "8110",
+ "format": "X..70",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,70})"
+ }, {
+ "title": "Loyalty points of a coupon",
+ "label": "POINTS",
+ "ai": "8111",
+ "format": "N4",
+ "type": "D",
+ "fixedLength": true,
+ "regex": "(\\d{4})"
+ }, {
+ "title": "Paperless coupon code identification for use in North America",
+ "ai": "8112",
+ "format": "X..70",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,70})"
+ }, {
+ "title": "Extended Packaging URL ",
+ "label": "PRODUCT URL",
+ "ai": "8200",
+ "format": "X..70",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,70})"
+ }, {
+ "title": "Information mutually agreed between trading partners",
+ "label": "INTERNAL",
+ "ai": "90",
+ "format": "X..30",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,30})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "91",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "92",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "93",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "94",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "95",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "96",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "97",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "98",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }, {
+ "title": "Company internal information",
+ "label": "INTERNAL",
+ "ai": "99",
+ "format": "X..90",
+ "type": "D",
+ "fixedLength": false,
+ "regex": "([\\x21-\\x22\\x25-\\x2F\\x30-\\x39\\x41-\\x5A\\x5F\\x61-\\x7A]{0,90})"
+ }];
+
+ // Element Strings with predefined length using GS1 Application Identifiers, as defined in GS1 Gen Specs - see Figure 7.8.4-2 of GS1 Gen Specs v18 at https://www.gs1.org/docs/barcodes/GS1_General_Specifications.pdf
+ const fixedLengthTable={"00":20,"01":16,"02":16,"03":16,"04":18,"11":8,"12":8,"13":8,"14":8,"15":8,"16":8,"17":8,"18":8,"19":4,"20":4,"31":10,"32":10,"33":10,"34":10,"35":10,"36":10,"41":16};
+
+ // tableP indicates for any initial two digits, what is the total length of the numeric AI key, e.g. "80":4 --> all AI keys beginning with 80 are four digit AI keys, 80xx
+ const tableP = {"00":2,"01":2,"02":2,"10":2,"11":2,"12":2,"13":2,"15":2,"16":2,"17":2,"20":2,"21":2,"22":2,"23":3,"24":3,"25":3,"30":2,"31":4,"32":4,"33":4,"34":4,"35":4,"36":4,"37":2,"39":4,"40":3,"41":3,"42":3,"70":4,"71":3,"72":4,"80":4,"81":4,"82":4,"90":2,"91":2,"92":2,"93":2,"94":2,"95":2,"96":2,"97":2,"98":2,"99":2};
+
+ // tableF indicates the expected format for the value of each AI.
+
+ const tableF={"00":[{"E":"N","L":"18"}],"01":[{"E":"N","L":"14"}],"02":[{"E":"N","L":"14"}],"10":[{"E":"X","M":"20"}],"11":[{"E":"N","L":"6"}],"12":[{"E":"N","L":"6"}],"13":[{"E":"N","L":"6"}],"15":[{"E":"N","L":"6"}],"16":[{"E":"N","L":"6"}],"17":[{"E":"N","L":"6"}],"20":[{"E":"N","L":"2"}],"21":[{"E":"X","M":"20"}],"22":[{"E":"X","M":"20"}],"240":[{"E":"X","M":"30"}],"241":[{"E":"X","M":"30"}],"242":[{"E":"N","M":"6"}],"243":[{"E":"X","M":"20"}],"250":[{"E":"X","M":"30"}],"251":[{"E":"X","M":"30"}],"253":[{"E":"N","L":"13"},{"E":"X","M":"17"}],"254":[{"E":"X","M":"20"}],"255":[{"E":"N","L":"13"},{"E":"N","M":"12"}],"30":[{"E":"N","M":"8"}],"3100":[{"E":"N","L":"6"}],"3101":[{"E":"N","L":"6"}],"3102":[{"E":"N","L":"6"}],"3103":[{"E":"N","L":"6"}],"3104":[{"E":"N","L":"6"}],"3105":[{"E":"N","L":"6"}],"3110":[{"E":"N","L":"6"}],"3111":[{"E":"N","L":"6"}],"3112":[{"E":"N","L":"6"}],"3113":[{"E":"N","L":"6"}],"3114":[{"E":"N","L":"6"}],"3115":[{"E":"N","L":"6"}],"3120":[{"E":"N","L":"6"}],"3121":[{"E":"N","L":"6"}],"3122":[{"E":"N","L":"6"}],"3123":[{"E":"N","L":"6"}],"3124":[{"E":"N","L":"6"}],"3125":[{"E":"N","L":"6"}],"3130":[{"E":"N","L":"6"}],"3131":[{"E":"N","L":"6"}],"3132":[{"E":"N","L":"6"}],"3133":[{"E":"N","L":"6"}],"3134":[{"E":"N","L":"6"}],"3135":[{"E":"N","L":"6"}],"3140":[{"E":"N","L":"6"}],"3141":[{"E":"N","L":"6"}],"3142":[{"E":"N","L":"6"}],"3143":[{"E":"N","L":"6"}],"3144":[{"E":"N","L":"6"}],"3145":[{"E":"N","L":"6"}],"3150":[{"E":"N","L":"6"}],"3151":[{"E":"N","L":"6"}],"3152":[{"E":"N","L":"6"}],"3153":[{"E":"N","L":"6"}],"3154":[{"E":"N","L":"6"}],"3155":[{"E":"N","L":"6"}],"3160":[{"E":"N","L":"6"}],"3161":[{"E":"N","L":"6"}],"3162":[{"E":"N","L":"6"}],"3163":[{"E":"N","L":"6"}],"3164":[{"E":"N","L":"6"}],"3165":[{"E":"N","L":"6"}],"3200":[{"E":"N","L":"6"}],"3201":[{"E":"N","L":"6"}],"3202":[{"E":"N","L":"6"}],"3203":[{"E":"N","L":"6"}],"3204":[{"E":"N","L":"6"}],"3205":[{"E":"N","L":"6"}],"3210":[{"E":"N","L":"6"}],"3211":[{"E":"N","L":"6"}],"3212":[{"E":"N","L":"6"}],"3213":[{"E":"N","L":"6"}],"3214":[{"E":"N","L":"6"}],"3215":[{"E":"N","L":"6"}],"3220":[{"E":"N","L":"6"}],"3221":[{"E":"N","L":"6"}],"3222":[{"E":"N","L":"6"}],"3223":[{"E":"N","L":"6"}],"3224":[{"E":"N","L":"6"}],"3225":[{"E":"N","L":"6"}],"3230":[{"E":"N","L":"6"}],"3231":[{"E":"N","L":"6"}],"3232":[{"E":"N","L":"6"}],"3233":[{"E":"N","L":"6"}],"3234":[{"E":"N","L":"6"}],"3235":[{"E":"N","L":"6"}],"3240":[{"E":"N","L":"6"}],"3241":[{"E":"N","L":"6"}],"3242":[{"E":"N","L":"6"}],"3243":[{"E":"N","L":"6"}],"3244":[{"E":"N","L":"6"}],"3245":[{"E":"N","L":"6"}],"3250":[{"E":"N","L":"6"}],"3251":[{"E":"N","L":"6"}],"3252":[{"E":"N","L":"6"}],"3253":[{"E":"N","L":"6"}],"3254":[{"E":"N","L":"6"}],"3255":[{"E":"N","L":"6"}],"3260":[{"E":"N","L":"6"}],"3261":[{"E":"N","L":"6"}],"3262":[{"E":"N","L":"6"}],"3263":[{"E":"N","L":"6"}],"3264":[{"E":"N","L":"6"}],"3265":[{"E":"N","L":"6"}],"3270":[{"E":"N","L":"6"}],"3271":[{"E":"N","L":"6"}],"3272":[{"E":"N","L":"6"}],"3273":[{"E":"N","L":"6"}],"3274":[{"E":"N","L":"6"}],"3275":[{"E":"N","L":"6"}],"3280":[{"E":"N","L":"6"}],"3281":[{"E":"N","L":"6"}],"3282":[{"E":"N","L":"6"}],"3283":[{"E":"N","L":"6"}],"3284":[{"E":"N","L":"6"}],"3285":[{"E":"N","L":"6"}],"3290":[{"E":"N","L":"6"}],"3291":[{"E":"N","L":"6"}],"3292":[{"E":"N","L":"6"}],"3293":[{"E":"N","L":"6"}],"3294":[{"E":"N","L":"6"}],"3295":[{"E":"N","L":"6"}],"3300":[{"E":"N","L":"6"}],"3301":[{"E":"N","L":"6"}],"3302":[{"E":"N","L":"6"}],"3303":[{"E":"N","L":"6"}],"3304":[{"E":"N","L":"6"}],"3305":[{"E":"N","L":"6"}],"3310":[{"E":"N","L":"6"}],"3311":[{"E":"N","L":"6"}],"3312":[{"E":"N","L":"6"}],"3313":[{"E":"N","L":"6"}],"3314":[{"E":"N","L":"6"}],"3315":[{"E":"N","L":"6"}],"3320":[{"E":"N","L":"6"}],"3321":[{"E":"N","L":"6"}],"3322":[{"E":"N","L":"6"}],"3323":[{"E":"N","L":"6"}],"3324":[{"E":"N","L":"6"}],"3325":[{"E":"N","L":"6"}],"3330":[{"E":"N","L":"6"}],"3331":[{"E":"N","L":"6"}],"3332":[{"E":"N","L":"6"}],"3333":[{"E":"N","L":"6"}],"3334":[{"E":"N","L":"6"}],"3335":[{"E":"N","L":"6"}],"3340":[{"E":"N","L":"6"}],"3341":[{"E":"N","L":"6"}],"3342":[{"E":"N","L":"6"}],"3343":[{"E":"N","L":"6"}],"3344":[{"E":"N","L":"6"}],"3345":[{"E":"N","L":"6"}],"3350":[{"E":"N","L":"6"}],"3351":[{"E":"N","L":"6"}],"3352":[{"E":"N","L":"6"}],"3353":[{"E":"N","L":"6"}],"3354":[{"E":"N","L":"6"}],"3355":[{"E":"N","L":"6"}],"3360":[{"E":"N","L":"6"}],"3361":[{"E":"N","L":"6"}],"3362":[{"E":"N","L":"6"}],"3363":[{"E":"N","L":"6"}],"3364":[{"E":"N","L":"6"}],"3365":[{"E":"N","L":"6"}],"3370":[{"E":"N","L":"6"}],"3371":[{"E":"N","L":"6"}],"3372":[{"E":"N","L":"6"}],"3373":[{"E":"N","L":"6"}],"3374":[{"E":"N","L":"6"}],"3375":[{"E":"N","L":"6"}],"3400":[{"E":"N","L":"6"}],"3401":[{"E":"N","L":"6"}],"3402":[{"E":"N","L":"6"}],"3403":[{"E":"N","L":"6"}],"3404":[{"E":"N","L":"6"}],"3405":[{"E":"N","L":"6"}],"3410":[{"E":"N","L":"6"}],"3411":[{"E":"N","L":"6"}],"3412":[{"E":"N","L":"6"}],"3413":[{"E":"N","L":"6"}],"3414":[{"E":"N","L":"6"}],"3415":[{"E":"N","L":"6"}],"3420":[{"E":"N","L":"6"}],"3421":[{"E":"N","L":"6"}],"3422":[{"E":"N","L":"6"}],"3423":[{"E":"N","L":"6"}],"3424":[{"E":"N","L":"6"}],"3425":[{"E":"N","L":"6"}],"3430":[{"E":"N","L":"6"}],"3431":[{"E":"N","L":"6"}],"3432":[{"E":"N","L":"6"}],"3433":[{"E":"N","L":"6"}],"3434":[{"E":"N","L":"6"}],"3435":[{"E":"N","L":"6"}],"3440":[{"E":"N","L":"6"}],"3441":[{"E":"N","L":"6"}],"3442":[{"E":"N","L":"6"}],"3443":[{"E":"N","L":"6"}],"3444":[{"E":"N","L":"6"}],"3445":[{"E":"N","L":"6"}],"3450":[{"E":"N","L":"6"}],"3451":[{"E":"N","L":"6"}],"3452":[{"E":"N","L":"6"}],"3453":[{"E":"N","L":"6"}],"3454":[{"E":"N","L":"6"}],"3455":[{"E":"N","L":"6"}],"3460":[{"E":"N","L":"6"}],"3461":[{"E":"N","L":"6"}],"3462":[{"E":"N","L":"6"}],"3463":[{"E":"N","L":"6"}],"3464":[{"E":"N","L":"6"}],"3465":[{"E":"N","L":"6"}],"3470":[{"E":"N","L":"6"}],"3471":[{"E":"N","L":"6"}],"3472":[{"E":"N","L":"6"}],"3473":[{"E":"N","L":"6"}],"3474":[{"E":"N","L":"6"}],"3475":[{"E":"N","L":"6"}],"3480":[{"E":"N","L":"6"}],"3481":[{"E":"N","L":"6"}],"3482":[{"E":"N","L":"6"}],"3483":[{"E":"N","L":"6"}],"3484":[{"E":"N","L":"6"}],"3485":[{"E":"N","L":"6"}],"3490":[{"E":"N","L":"6"}],"3491":[{"E":"N","L":"6"}],"3492":[{"E":"N","L":"6"}],"3493":[{"E":"N","L":"6"}],"3494":[{"E":"N","L":"6"}],"3495":[{"E":"N","L":"6"}],"3500":[{"E":"N","L":"6"}],"3501":[{"E":"N","L":"6"}],"3502":[{"E":"N","L":"6"}],"3503":[{"E":"N","L":"6"}],"3504":[{"E":"N","L":"6"}],"3505":[{"E":"N","L":"6"}],"3510":[{"E":"N","L":"6"}],"3511":[{"E":"N","L":"6"}],"3512":[{"E":"N","L":"6"}],"3513":[{"E":"N","L":"6"}],"3514":[{"E":"N","L":"6"}],"3515":[{"E":"N","L":"6"}],"3520":[{"E":"N","L":"6"}],"3521":[{"E":"N","L":"6"}],"3522":[{"E":"N","L":"6"}],"3523":[{"E":"N","L":"6"}],"3524":[{"E":"N","L":"6"}],"3525":[{"E":"N","L":"6"}],"3530":[{"E":"N","L":"6"}],"3531":[{"E":"N","L":"6"}],"3532":[{"E":"N","L":"6"}],"3533":[{"E":"N","L":"6"}],"3534":[{"E":"N","L":"6"}],"3535":[{"E":"N","L":"6"}],"3540":[{"E":"N","L":"6"}],"3541":[{"E":"N","L":"6"}],"3542":[{"E":"N","L":"6"}],"3543":[{"E":"N","L":"6"}],"3544":[{"E":"N","L":"6"}],"3545":[{"E":"N","L":"6"}],"3550":[{"E":"N","L":"6"}],"3551":[{"E":"N","L":"6"}],"3552":[{"E":"N","L":"6"}],"3553":[{"E":"N","L":"6"}],"3554":[{"E":"N","L":"6"}],"3555":[{"E":"N","L":"6"}],"3560":[{"E":"N","L":"6"}],"3561":[{"E":"N","L":"6"}],"3562":[{"E":"N","L":"6"}],"3563":[{"E":"N","L":"6"}],"3564":[{"E":"N","L":"6"}],"3565":[{"E":"N","L":"6"}],"3570":[{"E":"N","L":"6"}],"3571":[{"E":"N","L":"6"}],"3572":[{"E":"N","L":"6"}],"3573":[{"E":"N","L":"6"}],"3574":[{"E":"N","L":"6"}],"3575":[{"E":"N","L":"6"}],"3600":[{"E":"N","L":"6"}],"3601":[{"E":"N","L":"6"}],"3602":[{"E":"N","L":"6"}],"3603":[{"E":"N","L":"6"}],"3604":[{"E":"N","L":"6"}],"3605":[{"E":"N","L":"6"}],"3610":[{"E":"N","L":"6"}],"3611":[{"E":"N","L":"6"}],"3612":[{"E":"N","L":"6"}],"3613":[{"E":"N","L":"6"}],"3614":[{"E":"N","L":"6"}],"3615":[{"E":"N","L":"6"}],"3620":[{"E":"N","L":"6"}],"3621":[{"E":"N","L":"6"}],"3622":[{"E":"N","L":"6"}],"3623":[{"E":"N","L":"6"}],"3624":[{"E":"N","L":"6"}],"3625":[{"E":"N","L":"6"}],"3630":[{"E":"N","L":"6"}],"3631":[{"E":"N","L":"6"}],"3632":[{"E":"N","L":"6"}],"3633":[{"E":"N","L":"6"}],"3634":[{"E":"N","L":"6"}],"3635":[{"E":"N","L":"6"}],"3640":[{"E":"N","L":"6"}],"3641":[{"E":"N","L":"6"}],"3642":[{"E":"N","L":"6"}],"3643":[{"E":"N","L":"6"}],"3644":[{"E":"N","L":"6"}],"3645":[{"E":"N","L":"6"}],"3650":[{"E":"N","L":"6"}],"3651":[{"E":"N","L":"6"}],"3652":[{"E":"N","L":"6"}],"3653":[{"E":"N","L":"6"}],"3654":[{"E":"N","L":"6"}],"3655":[{"E":"N","L":"6"}],"3660":[{"E":"N","L":"6"}],"3661":[{"E":"N","L":"6"}],"3662":[{"E":"N","L":"6"}],"3663":[{"E":"N","L":"6"}],"3664":[{"E":"N","L":"6"}],"3665":[{"E":"N","L":"6"}],"3670":[{"E":"N","L":"6"}],"3671":[{"E":"N","L":"6"}],"3672":[{"E":"N","L":"6"}],"3673":[{"E":"N","L":"6"}],"3674":[{"E":"N","L":"6"}],"3675":[{"E":"N","L":"6"}],"3680":[{"E":"N","L":"6"}],"3681":[{"E":"N","L":"6"}],"3682":[{"E":"N","L":"6"}],"3683":[{"E":"N","L":"6"}],"3684":[{"E":"N","L":"6"}],"3685":[{"E":"N","L":"6"}],"3690":[{"E":"N","L":"6"}],"3691":[{"E":"N","L":"6"}],"3692":[{"E":"N","L":"6"}],"3693":[{"E":"N","L":"6"}],"3694":[{"E":"N","L":"6"}],"3695":[{"E":"N","L":"6"}],"37":[{"E":"N","M":"8"}],"3900":[{"E":"N","M":"15"}],"3901":[{"E":"N","M":"15"}],"3902":[{"E":"N","M":"15"}],"3903":[{"E":"N","M":"15"}],"3904":[{"E":"N","M":"15"}],"3905":[{"E":"N","M":"15"}],"3906":[{"E":"N","M":"15"}],"3907":[{"E":"N","M":"15"}],"3908":[{"E":"N","M":"15"}],"3909":[{"E":"N","M":"15"}],"3910":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3911":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3912":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3913":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3914":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3915":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3916":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3917":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3918":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3919":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3920":[{"E":"N","M":"15"}],"3921":[{"E":"N","M":"15"}],"3922":[{"E":"N","M":"15"}],"3923":[{"E":"N","M":"15"}],"3924":[{"E":"N","M":"15"}],"3925":[{"E":"N","M":"15"}],"3926":[{"E":"N","M":"15"}],"3927":[{"E":"N","M":"15"}],"3928":[{"E":"N","M":"15"}],"3929":[{"E":"N","M":"15"}],"3930":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3931":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3932":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3933":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3934":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3935":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3936":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3937":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3938":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3939":[{"E":"N","L":"3"},{"E":"N","M":"15"}],"3940":[{"E":"N","L":"4"}],"3941":[{"E":"N","L":"4"}],"3942":[{"E":"N","L":"4"}],"3943":[{"E":"N","L":"4"}],"400":[{"E":"X","M":"30"}],"401":[{"E":"X","M":"30"}],"402":[{"E":"N","L":"17"}],"403":[{"E":"X","M":"30"}],"410":[{"E":"N","L":"13"}],"411":[{"E":"N","L":"13"}],"412":[{"E":"N","L":"13"}],"413":[{"E":"N","L":"13"}],"414":[{"E":"N","L":"13"}],"415":[{"E":"N","L":"13"}],"416":[{"E":"N","L":"13"}],"420":[{"E":"X","M":"20"}],"421":[{"E":"N","L":"3"},{"E":"X","M":"9"}],"422":[{"E":"N","L":"3"}],"423":[{"E":"N","L":"3"},{"E":"N","M":"12"}],"424":[{"E":"N","L":"3"}],"425":[{"E":"N","L":"3"},{"E":"N","M":"12"}],"426":[{"E":"N","L":"3"}],"427":[{"E":"X","M":"3"}],"7001":[{"E":"N","L":"13"}],"7002":[{"E":"X","M":"30"}],"7003":[{"E":"N","L":"10"}],"7004":[{"E":"N","M":"4"}],"7005":[{"E":"X","M":"12"}],"7006":[{"E":"N","L":"6"}],"7007":[{"E":"N","L":"6"},{"E":"N","M":"6"}],"7008":[{"E":"X","M":"3"}],"7009":[{"E":"X","M":"10"}],"7010":[{"E":"X","M":"2"}],"7020":[{"E":"X","M":"20"}],"7021":[{"E":"X","M":"20"}],"7022":[{"E":"X","M":"20"}],"7023":[{"E":"X","M":"30"}],"7030":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7031":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7032":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7033":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7034":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7035":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7036":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7037":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7038":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"7039":[{"E":"N","L":"3"},{"E":"X","M":"27"}],"710":[{"E":"X","M":"20"}],"711":[{"E":"X","M":"20"}],"712":[{"E":"X","M":"20"}],"713":[{"E":"X","M":"20"}],"714":[{"E":"X","M":"20"}],"7230":[{"E":"X","M":"30"}],"7231":[{"E":"X","M":"30"}],"7232":[{"E":"X","M":"30"}],"7233":[{"E":"X","M":"30"}],"7234":[{"E":"X","M":"30"}],"7235":[{"E":"X","M":"30"}],"7236":[{"E":"X","M":"30"}],"7237":[{"E":"X","M":"30"}],"7238":[{"E":"X","M":"30"}],"7239":[{"E":"X","M":"30"}],"8001":[{"E":"N","L":"14"}],"8002":[{"E":"X","M":"20"}],"8003":[{"E":"N","L":"14"},{"E":"X","M":"16"}],"8004":[{"E":"X","M":"30"}],"8005":[{"E":"N","L":"6"}],"8006":[{"E":"N","L":"18"}],"8007":[{"E":"X","M":"24"}],"8008":[{"E":"N","L":"8"},{"E":"N","M":"4"}],"8009":[{"E":"X","M":"50"}],"8010":[{"E":"X","M":"30"}],"8011":[{"E":"N","M":"12"}],"8012":[{"E":"X","M":"20"}],"8013":[{"E":"X","M":"30"}],"8017":[{"E":"N","L":"18"}],"8018":[{"E":"N","L":"18"}],"8019":[{"E":"N","M":"10"}],"8020":[{"E":"X","M":"25"}],"8026":[{"E":"N","L":"18"}],"8110":[{"E":"X","M":"70"}],"8111":[{"E":"N","L":"4"}],"8112":[{"E":"X","M":"70"}],"8200":[{"E":"X","M":"70"}],"90":[{"E":"X","M":"30"}],"91":[{"E":"X","M":"90"}],"92":[{"E":"X","M":"90"}],"93":[{"E":"X","M":"90"}],"94":[{"E":"X","M":"90"}],"95":[{"E":"X","M":"90"}],"96":[{"E":"X","M":"90"}],"97":[{"E":"X","M":"90"}],"98":[{"E":"X","M":"90"}],"99":[{"E":"X","M":"90"}]};
+
+
+ // tableOpt contains optimisations for pre-defined sequences of GS1 Application Identifiers
+ // we'll initially use 0A-0F through 9A-9F to keep Ah - Eh unallocated and reserve Fh for support for non-GS1 keys from the URI query string
+ const tableOpt = {"0A":["01","22"],"0B":["01","10"],"0C":["01","21"],"0D":["01","17"],"0E":["01","7003"],"0F":["01","30"],"1A":["01","10","21","17"],"1B":["01","15"],"1C":["01","11"],"1D":["01","16"],"1E":["01","91"],"1F":["01","10","15"],"2A":["01","3100"],"2B":["01","3101"],"2C":["01","3102"],"2D":["01","3103"],"2E":["01","3104"],"2F":["01","3105"],"3A":["01","3200"],"3B":["01","3201"],"3C":["01","3202"],"3D":["01","3203"],"3E":["01","3204"],"3F":["01","3205"],"9A":["8010","8011"],"9B":["8017","8019"],"9C":["8018","8019"],"9D":["414","254"],"A0":["01","3920"],"A1":["01","3921"],"A2":["01","3922"],"A3":["01","3923"],"A4":["01","3924"],"A5":["01","3925"],"A6":["01","3926"],"A7":["01","3927"],"A8":["01","3928"],"A9":["01","3929"],"C0":["255","3900"],"C1":["255","3901"],"C2":["255","3902"],"C3":["255","3903"],"C4":["255","3904"],"C5":["255","3905"],"C6":["255","3906"],"C7":["255","3907"],"C8":["255","3908"],"C9":["255","3909"],"CA":["255","3940"],"CB":["255","3941"],"CC":["255","3942"],"CD":["255","3943"]}
+
+
+ // safeBase64Alphabet is a modified URI-safe Base64 alphabet used in the compression methods for converting the binary string to/from an alphanumeric representation that contains no characters that are restricted in URIs
+ const safeBase64Alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+ const hexAlphabet="0123456789ABCDEF";
+
+ const regexAllNum=new RegExp("^[0-9]+$");
+ const regexHexLower=new RegExp("^[0-9a-f]+$");
+ const regexHexUpper=new RegExp("^[0-9A-F]+$");
+ const regexSafe64=new RegExp("^[A-Za-z0-9_-]+$");
+
+ const tableOptReverse={};
+ let tableOptKeys = Object.keys(tableOpt);
+ for (let i in tableOptKeys) {
+ tableOptReverse[JSON.stringify(tableOpt[tableOptKeys[i]].sort())]=tableOptKeys[i];
+ }
+
+ const aiRegex={};
+ const aiShortCode={};
+ const aiQualifiers={};
+ const aiCheckDigitPosition={};
+
+ for (let a in aitable) {
+ if (aitable[a] !== undefined) {
+
+ aiRegex[aitable[a].ai] = new RegExp("^"+aitable[a].regex+"$");
+
+ if (aitable[a].shortcode !== undefined) {
+ aiShortCode[aitable[a].ai] = aitable[a].shortcode;
+ }
+
+ if (aitable[a].qualifiers !== undefined) {
+ aiQualifiers[aitable[a].ai] = aitable[a].qualifiers;
+ }
+
+ if (aitable[a].checkDigit !== undefined) {
+ aiCheckDigitPosition[aitable[a].ai] = aitable[a].checkDigit;
+ }
+ }
+ }
+
+
+
+ function getIdentifiers(ai) {
+ return ai.type == "I";
+ }
+
+ function getQualifiers(ai) {
+ return ai.type == "Q";
+ }
+
+ function getDataAttributes(ai) {
+ return ai.type == "D";
+ }
+
+ function getFixedLength(ai) {
+ return ai.fixedLength == true;
+ }
+
+ function getVariableLength(ai) {
+ return ai.fixedLength == false;
+ }
+
+ function getMatchesKeyword(keyword) {
+ return function(ai) {
+ return ai.title.indexOf(keyword) > -1;
+ }
+ }
+
+ function getMatchesAI(num) {
+ return function(el) {
+ return el.ai == num;
+ }
+ }
+
+ function byLength(length) {
+ return function(element) {
+ return element.ai.length == length;
+ }
+ }
+
+
+
+ function getAIs(list) {
+ let rv=[];
+ for (let i in list) {
+ rv.push(list[i].ai);
+ }
+ return rv;
+ }
+
+
+
+
+ const identifiers=aitable.filter(getIdentifiers);
+ const qualifiers=aitable.filter(getQualifiers);
+ const dataAttributes=aitable.filter(getDataAttributes);
+ const fixedLength=aitable.filter(getFixedLength);
+ const variableLength=aitable.filter(getVariableLength);
+
+
+ const identifierMap={};
+ for (let i in identifiers) {
+ identifierMap[identifiers[i].ai]=identifiers[i];
+ }
+
+ const qualifierMap={};
+ for (let q in qualifiers) {
+ if (qualifiers[q] !== undefined) {
+ qualifierMap[qualifiers[q].ai]=qualifiers[q];
+ }
+ }
+
+ const attributeMap={};
+ for (let a in dataAttributes) {
+ if (dataAttributes[a] !== undefined) {
+ attributeMap[dataAttributes[a].ai]=dataAttributes[a];
+ }
+ }
+
+
+ const fixedLengthMap={};
+ for (let f in fixedLength) {
+ if (fixedLength[f] !== undefined) {
+ fixedLengthMap[fixedLength[f].ai]=fixedLength[f];
+ }
+ }
+
+ const variableLengthMap={};
+ for (let v in variableLength) {
+ if (variableLength[v] !== undefined) {
+ variableLengthMap[variableLength[v].ai]=variableLength[v];
+ }
+ }
+
+ const aiMaps={}
+ aiMaps.identifiers=Object.keys(identifierMap);
+ aiMaps.qualifiers=Object.keys(qualifierMap);
+ aiMaps.dataAttributes=Object.keys(attributeMap);
+ aiMaps.fixedLength=Object.keys(fixedLengthMap);
+ aiMaps.variableLength=Object.keys(variableLengthMap);
+
+
+ // TODO - not yet making checks on invalid and mandatory associations of GS1 Application Identifiers
+
+ // from GS1 Gen Specs Figure 4.14.1-1. Invalid pairs of element strings
+ // this table is symmetrical
+ const invalidAssociations=[
+ {"rule":"All occurrences of GTIN SHALL have one value. It is for example not allowed to include GTINs of other packaging levels.","condition1":"01","condition2":["01"]},
+ {"rule":"GTIN of contained trade items is intended to list the trade items contained in a logistic unit, and SHALL NOT be used to identify the contents of a trade item","condition1":"02","condition2":["01"]},
+ {"rule":"The count of units contained SHALL only be used with GTIN of contained trade items.","condition1":"37","condition2":["01"]},
+ {"rule":"A trade item SHALL NOT be identified as a coupon.","condition1":"255","condition2":["01"]},
+ {"rule":"Only one ship to postal code SHALL be applied on the same physical entity","condition1":"420","condition2":["421"]},
+ {"rule":"Country of origin, initial processing, processing, or disassembly SHALL NOT be used in combination with country of full porcessing, since this would lead to ambiguous data.","condition1":"426","condition2":["422","423","424","425"]},
+ {"rule":"The element strings coupon value, percentage discount of a coupon and loyalty points of a coupon SHALL NOT be applied in combination.","condition1":"390\d","condition2":["394\d","8111"]},
+ {"rule":"Only one amount patable element string SHALL be applied on a payment slip.","condition1":"391\d","condition2":["390\d"]},
+ {"rule":"Only one amount payable element string SHALL be applied on a variable measure trade item.","condition1":"392\d","condition2":["393\d"]},
+ {"rule":"The element strings percentage discount of a coupon and the loyalty points of a coupon SHALL NOT be applied in combination.","condition1":"394\d","condition2":["8111"]},
+ {"rule":"The GTIN SHALL NOT be used in combination with the identification of an individual trade item piece. The GTIN of the trade item to which the individual trade item piece belongs is contained in the element string","condition1":"8006","condition2":["01"]},
+ {"rule":"Only one Global Service Relation Number (recipient of provider) SHALL be applied at one time for identification of an individual in a given service relationship","condition1":"8018","condition2":["8017"]},
+ ];
+
+ // need to also have mandatory association table and forbidden association table from GS1 Gen Specs
+
+ // from Figure 4.14.2-1. Mandatory association of element strings
+ // this table is not symmetrical - it's one-way, given condition, require OR, AND, XOR to be satisfied where specified
+ const mandatoryAssociations=[
+ {"designation":"GTIN of a variable measure trade item scanned at POS","rule":"The GTIN of a variable measure trade item scanned at POS SHALL occur in combination with: * variable count of items; or * a trade measure ; Note: Master data will be needed to determine whether the GTIN represents a variable measure trade item scanned at POS. Also see the note below this table.","condition":["01"],"conditionN1":"0","OR":["30","3\d{3}"]},
+
+ {"designation":"GTIN of a variable measure trade item not scanned at POS","rule":"The GTIN of a variable measure trade item not scanned at POS SHALL occur in combination with: * variable count of items; or * a trade measure; or * the dimensions of a roll product. Note: The first position of the GTIN is '9' for such trade items. Also see the note below this table.","condition":["01","02"],"conditionN1":"9","OR":["30","3\d{3}","8001"]},
+ {"designation":"GTIN of a custom trade item.","rule":"The GTIN of a custom trade item SHALL be used in combination with the Made-to-Order variation number. Note: The first position of the GTIN is '9' for such trade items.","condition":["01"],"conditionN1":"9","EXACTLY":["242"]},
+
+ {"designation":"GTIN of contained trade items","rule":"The GTIN of contained trade items SHALL occur in combination with an SSCC and the count of the trade items.","condition":["02"],"AND":["00","37"]},
+ {"designation":"Batch/lot number","rule":"Batch/lot number SHALL occur in combination with: * a GTIN; or * a GTIN of contained trade items; or * the identification of an individual trade item piece.","condition":["10"],"XOR":["01","02","8006"]},
+ {"designation":"Production date, packaging date, best before date, sell by date, expiration date (of a trade item)","rule":"These dates SHALL occur in combination with: * a GTIN; or * a GTIN of contained trade items; or * the identification of an individual trade item piece.","condition":["11","13","15","16","17"],"XOR":["01","02","8006"]},
+
+ {"designation":"Due date","rule":"The due date SHALL occur in combination with the payment slip reference number and the GLN of the invoicing party","condition":["12"],"AND":["8020","415"]},
+
+ {"designation":"Expiration date (of a coupon)","rule":"The expiration date of a coupon SHALL occur in combination with the GCN.","condition":["17"],"EXACTLY":["255"]},
+
+ {"designation":"","rule":"","condition":["20"],"XOR":["01","02","8006"]},
+ {"designation":"","rule":"","condition":["21"],"XOR":["01","8006"]},
+
+ {"designation":"","rule":"","condition":["22"],"EXACTLY":["01"]},
+ {"designation":"","rule":"","condition":["240"],"XOR":["01","02","8006"]},
+ {"designation":"","rule":"","condition":["241"],"XOR":["01","02","8006"]},
+
+ // *** 242 rule has N1=9 condition on 01,02,8006
+
+ {"designation":"","rule":"","condition":["243"],"EXACTLY":["01"]},
+
+ {"designation":"","rule":"","condition":["250"],"AND":["21"],"XOR":["01","8006"]},
+
+ {"designation":"","rule":"","condition":["251"],"XOR":["01","8006"]},
+
+ {"designation":"","rule":"","condition":["254"],"EXACTLY":["414"]},
+
+ {"designation":"","rule":"","condition":["30"],"XOR":["01","02"]},
+ {"designation":"","rule":"","condition":["3\d{3}"],"XOR":["01","02"]},
+ {"designation":"","rule":"","condition":["3\d{3}"],"OR":["00","01"]},
+ {"designation":"","rule":"","condition":["337\d"],"EXACTLY":["01"]},
+ {"designation":"","rule":"","condition":["37"],"EXACTLY":["02"]},
+ {"designation":"","rule":"","condition":["390\d"],"AND":["8020","415"]},
+ {"designation":"","rule":"","condition":["390\d"],"EXACTLY":["255"]},
+
+
+
+ ];
+
+
+ const shortCodeToNumeric = {};
+ for(let key in aiShortCode){
+ shortCodeToNumeric[aiShortCode[key]] = key;
+ }
+
+ // exposed as public variables that can be accessed by methods
+ this.aitable = aitable;
+ this.aiCheckDigitPosition = aiCheckDigitPosition;
+ this.aiRegex = aiRegex;
+ this.aiMaps = aiMaps;
+ this.aiShortCode = aiShortCode;
+ this.aiQualifiers = aiQualifiers;
+ this.shortCodeToNumeric = shortCodeToNumeric;
+ this.tableP = tableP;
+ this.tableF = tableF;
+ this.tableOpt = tableOpt;
+ this.tableOptReverse = tableOptReverse;
+ this.safeBase64Alphabet = safeBase64Alphabet;
+ this.hexAlphabet = hexAlphabet;
+
+ this.AIsByLength=[];
+ for (let i=2; i<=4; i++) {
+ this.AIsByLength[i] =getAIs(aitable.filter(byLength(i)));
+ }
+
+ this.groupSeparator= String.fromCharCode(29);
+
+ this.regexAllNum = regexAllNum;
+ this.regexHexLower = regexHexLower;
+ this.regexHexUpper = regexHexUpper;
+ this.regexSafe64 = regexSafe64;
+
+ }
+
+
+ numberOfLengthBits(maxLength) {
+ return Math.ceil(Math.log(maxLength)/Math.log(2)+0.01);
+ }
+
+ numberOfValueBits(valueLength) {
+ return Math.ceil(valueLength*Math.log(10)/Math.log(2)+0.01);
+ }
+
+
+ // calculate the expected GS1 Check Digit for a given AI
+ // e.g. calculateCheckDigit('01','01234567890128');
+ calculateCheckDigit(ai,gs1IDValue) {
+ let counter=0;
+ let reversed="";
+ let total=0;
+ let l;
+ if (this.aiCheckDigitPosition[ai] == "L") {
+ l = gs1IDValue.length;
+ } else {
+ l = parseInt(this.aiCheckDigitPosition[ai]);
+ }
+ let multiplier;
+ for (let i=l-2; i>=0; i--) {
+ let d=gs1IDValue.substring(i,(i+1));
+ if ((counter % 2) == 0) {
+ multiplier=3;
+ } else {
+ multiplier=1;
+ }
+ total+=(d*multiplier);
+ counter++;
+ }
+ let expectedCheckDigit=(10-(total%10))%10;
+ return expectedCheckDigit;
+ }
+
+ // returns true if the GS1 Check Digit is valid (or not applicable)
+ // throws an error if an invalid check digit is present
+ // e.g. verifyCheckDigit('01','01234567890128');
+ verifyCheckDigit(ai,gs1IDValue) {
+ let expectedCheckDigit;
+ let rv=true;
+
+ let checkDigitPosition=this.aiCheckDigitPosition[ai];
+ if (checkDigitPosition !== undefined) {
+ expectedCheckDigit = this.calculateCheckDigit(ai,gs1IDValue);
+ if (checkDigitPosition == "L") {
+ checkDigitPosition=gs1IDValue.length;
+ } else {
+ checkDigitPosition=parseInt(checkDigitPosition);
+ }
+ let actualCheckDigit = parseInt(gs1IDValue.charAt(checkDigitPosition-1));
+
+ if (actualCheckDigit !== expectedCheckDigit) {
+ rv=false;
+ throw new Error("INVALID CHECK DIGIT: An invalid check digit was found for the primary identification key ("+ai+")"+gs1IDValue+" ; the correct check digit should be "+expectedCheckDigit+" at position "+checkDigitPosition);
+ }
+
+ }
+ return rv;
+ }
+
+ // tests the syntax of a value against the regular expression (expected format)
+ // throws an error when invalid syntax is detected
+ // e.g. verifySyntax('01','01234567890128');
+ verifySyntax(ai,value) {
+ if ((ai !== null) && (this.regexAllNum.test(ai))) {
+ if (!(this.aiRegex[ai].test(value))) {
+ throw "SYNTAX ERROR: invalid syntax for value of ("+ai+")"+value;
+ }
+ }
+ }
+
+ // method to percent-encode all reserved characters mentioned in the GS1 Digital Link standard
+ percentEncode(input) {
+ let charsToEscape="#/%&+,!()*':;<=>?";
+ let escaped=[];
+ for (let i=0; i -1) {
+ escaped.push("%"+testChar.charCodeAt(0).toString(16).toUpperCase());
+ } else {
+ escaped.push(testChar);
+ }
+ }
+ return escaped.join("");
+ }
+
+ // method to percent-decode all percent-encoded characters
+ percentDecode(input) {
+ return decodeURIComponent(input);
+ }
+
+ padToLength(input,requiredLength) {
+ if (input.length < requiredLength) {
+ input="0".repeat(requiredLength-input.length)+input;
+ }
+ return input;
+ }
+
+
+ bin2base64(binstr) {
+ let rv="";
+ if (binstr.length%6 > 0) {
+ let numberRightPadZeros = 6 - (binstr.length % 6);
+ binstr+= "0".repeat(numberRightPadZeros);
+ }
+ let numChar = (binstr.length)/6;
+ for (let i=0; i -1) {
+ // the first two digits are within the array of GS1 Application Identifiers of defined fixed length
+
+ // extract the AI and value to the buffer
+ let l = fixedLengths[firstTwoDigits];
+ buffer.push(elementStrings.substr(cursor,l));
+ cursor+=l;
+
+ // if the next character is the group separator, move past it
+ if (elementStrings.substr(cursor,1) == gs) {
+ cursor++;
+ }
+
+
+ } else {
+ // the first two digits are not within the array of GS1 Application Identifiers of defined fixed length
+
+ // if string contains group separator
+ let gsloc = elementStrings.substr(cursor).indexOf(gs);
+ if (gsloc > -1) {
+ // extract the AI and value up to the group separator to the buffer
+ buffer.push(elementStrings.substr(cursor).substr(0,gsloc));
+ cursor+=gsloc;
+ cursor++;
+
+ } else {
+ // extract the AI and value to the buffer
+ buffer.push(elementStrings.substr(cursor));
+ cursor=elementStringsLength;
+ }
+
+ }
+
+ } while (cursor < elementStringsLength);
+
+
+ // process the buffer;
+
+ let obj={};
+ let aiCandidate="";
+ let matched=false;
+ for (let i=0; i -1) {
+ obj[aiCandidate] = el.substr(k);
+ matched=true;
+ }
+ }
+
+ if (!matched) {
+ throw new Error("No matching GS1 AI found for "+el);
+ }
+ }
+
+ return obj;
+ // }
+ }
+
+ // this method converts an associative array of GS1 Application Identifiers and their values into a GS1 Digital Link URI
+ // set useShortText = true if you wish to use alphabetic mnemonic short names, e.g. /gtin/ instead of /01/
+ // set uriStem to a value e.g. 'https://example.org' if you wish to use a specific domain name
+ // setting uriStem to null, undefined or "" defaults to 'https://id.gs1.org' as the reference domain
+ buildGS1digitalLink(gs1AIarray,useShortText,uriStem,nonGS1keyvaluePairs) {
+ let identifiers=[];
+ let qualifiers=[];
+ let attributes=[];
+ let fixedLengthValues=[];
+ let variableLengthValues=[];
+ let otherKeys=[];
+
+ let valid=true;
+ let path="";
+ let queryStringArray=[];
+ let queryString="";
+ let webURI="";
+ let canonicalStem="https://id.gs1.org";
+ let rv={};
+
+ // Need to remove unwanted trailing slash
+ if ((uriStem !== undefined) && (uriStem !== null) && (uriStem !== "") && (uriStem.endsWith("/"))) {
+ uriStem=uriStem.substr(0,uriStem.length-1)+path+queryString;
+ }
+
+
+ for (let a in gs1AIarray) {
+ let other=true;
+ if (this.aiMaps.identifiers.includes(a)) {
+ identifiers.push(a);
+ other=false;
+ }
+ if (this.aiMaps.qualifiers.includes(a)) {
+ qualifiers.push(a);
+ other=false;
+ }
+ if (this.aiMaps.dataAttributes.includes(a)) {
+ attributes.push(a);
+ other=false;
+ }
+ if (this.aiMaps.fixedLength.includes(a)) {
+ fixedLengthValues.push(a);
+ other=false;
+ }
+ if (this.aiMaps.variableLength.includes(a)) {
+ variableLengthValues.push(a);
+ other=false;
+ }
+ if (other) {
+ otherKeys.push(a);
+ }
+ }
+
+ // Start building Web URI path expression
+ // need exactly one identifier key
+
+ if (identifiers.length !== 1) {
+ valid=false;
+ throw new Error("The element string should contain exactly one primary identification key - it contained "+identifiers.length+" "+JSON.stringify(identifiers)+"; please check for a syntax error");
+ } else {
+
+ this.verifySyntax(identifiers[0],gs1AIarray[identifiers[0]]);
+
+
+ this.verifyCheckDigit(identifiers[0],gs1AIarray[identifiers[0]]);
+
+
+
+ if (useShortText) {
+ // Using short text names
+ if (this.aiShortCode[identifiers[0]] !== undefined) {
+ path="/"+this.aiShortCode[identifiers[0]]+"/"+this.percentEncode(gs1AIarray[identifiers[0]]);
+ } else {
+ path="/"+identifiers[0]+"/"+this.percentEncode(gs1AIarray[identifiers[0]]);
+ }
+ } else {
+ // Using numeric AIs
+ path="/"+identifiers[0]+"/"+this.percentEncode(gs1AIarray[identifiers[0]]);
+ }
+
+ // append any data qualifiers in the expected order, as specified in this.aiQualifiers[identifiers[0]]
+
+ if (this.aiQualifiers[identifiers[0]] !== undefined) {
+ for (let j in this.aiQualifiers[identifiers[0]]) {
+ let q=this.aiQualifiers[identifiers[0]][j]
+ if (qualifiers.includes(q)) {
+
+ if (useShortText) {
+ // Using short text names
+ if (this.aiShortCode[q] !== undefined) {
+ path+="/"+this.aiShortCode[q]+"/"+this.percentEncode(gs1AIarray[q]);
+ } else {
+ path+="/"+q+"/"+this.percentEncode(gs1AIarray[q]);
+ }
+ } else {
+ // Using numeric AIs
+ path+="/"+q+"/"+this.percentEncode(gs1AIarray[q]);
+ }
+
+ }
+ }
+ }
+
+ // if there are any data attributes, we need to add these to the query string
+
+ if (attributes.length >0) {
+
+ for (let k in attributes) {
+ let a=attributes[k];
+
+ if (useShortText) {
+ // Using short text names
+ if (this.aiShortCode[a] !== undefined) {
+ queryStringArray.push(this.aiShortCode[a]+"="+this.percentEncode(gs1AIarray[a]));
+ } else {
+ queryStringArray.push(a+"="+this.percentEncode(gs1AIarray[a]));
+ }
+ } else {
+ // Using numeric AIs
+ queryStringArray.push(a+"="+this.percentEncode(gs1AIarray[a]));
+ }
+ }
+ queryString="?"+queryStringArray.join("&");
+
+
+ }
+
+ if ((uriStem == null) || (uriStem == "")) {
+ // prepare a canonical Web URI
+ webURI=canonicalStem+path+queryString;
+ } else {
+ webURI=uriStem+path+queryString;
+ }
+
+ if (otherKeys.length > 0) {
+ let queryStringArray=[];
+ for (let iok in otherKeys) {
+ queryStringArray.push(otherKeys[iok]+"="+gs1AIarray[otherKeys[iok]]);
+ }
+ if (queryString== "") {
+ webURI+="?"+queryStringArray.join("&");
+ } else {
+ webURI+="&"+queryStringArray.join("&");
+ }
+ }
+
+ if ( (nonGS1keyvaluePairs !== {}) && (Object.keys(nonGS1keyvaluePairs).length > 0) ) {
+ let queryStringArray=[];
+ let keys=Object.keys(nonGS1keyvaluePairs);
+ for (let iok in keys) {
+ let key=keys[iok];
+ queryStringArray.push(key+"="+nonGS1keyvaluePairs[key]);
+ }
+ if (queryString== "") {
+ webURI+="?"+queryStringArray.join("&");
+ } else {
+ webURI+="&"+queryStringArray.join("&");
+ }
+ }
+
+
+ }
+
+
+ return webURI;
+ }
+
+
+ // new method that converts a flat associative array of GS1 Application Identifiers and their values into a more structured object in which the primary identification key, key qualifiers, data attributes and other key=value pairs from the URI string are clearly identified as such.
+ buildStructuredArray(gs1AIarray,otherArray) {
+ let keys=["identifiers","qualifiers","dataAttributes"];
+ let map={};
+ map.identifiers=[];
+ map.qualifiers=[];
+ map.dataAttributes=[];
+ map.other=[];
+
+ let valid=true;
+ let path="";
+ let queryStringArray=[];
+ let rv={};
+
+ for (let a in gs1AIarray) {
+ let b={};
+ b[a]=gs1AIarray[a];
+ let other=true;
+
+ for (let k in keys) {
+ if (this.aiMaps[keys[k]].includes(a)) {
+ map[keys[k]].push(b);
+ other=false;
+ }
+ }
+
+ if (other) {
+ map.other.push(b);
+ }
+ }
+
+ for (let a in otherArray) {
+ let b={};
+ b[a]=otherArray[a];
+ map.other.push(b);
+ }
+
+ // need exactly one identifier key
+ if (map.identifiers.length !== 1) {
+ valid=false;
+ throw new Error("The element string should contain exactly one primary identification key - it contained "+map.identifiers.length+" "+JSON.stringify(map.identifiers)+"; please check for a syntax error");
+ } else {
+ this.verifySyntax(map.identifiers[0],gs1AIarray[map.identifiers[0]]);
+ this.verifyCheckDigit(map.identifiers[0],gs1AIarray[map.identifiers[0]]);
+ }
+ return map;
+ }
+
+
+ analyseURI(gs1DigitalLinkURI,extended) {
+ let rv={};
+
+ rv.fragment="";
+ let fi = gs1DigitalLinkURI.indexOf("#");
+
+ let beforeFragment = gs1DigitalLinkURI;
+
+ if (fi > -1) {
+ rv.fragment = gs1DigitalLinkURI.substr(1+fi);
+ beforeFragment = gs1DigitalLinkURI.substr(0,fi);
+ }
+
+ rv.queryString="";
+
+ let beforeQueryString = beforeFragment;
+ let qs=beforeFragment.indexOf("?");
+ if (qs> -1) {
+ rv.queryString = beforeFragment.substr(1+qs);
+ beforeQueryString = beforeFragment.substr(0,qs);
+ }
+
+ // disregard any trailing forward slash
+ let bql = beforeQueryString.length;
+ if (beforeQueryString.substr(bql-1,1)== "/") {
+ beforeQueryString = beforeQueryString.substr(0,bql-1);
+ }
+
+ let cursor=0;
+ if (beforeQueryString.indexOf("http://") == 0) { cursor=7 }
+ if (beforeQueryString.indexOf("https://") == 0) { cursor=8 }
+
+ let protocol=beforeQueryString.substr(0,cursor);
+ let afterProtocol = beforeQueryString.substr(cursor);
+
+ let firstSlashOfAllPath = afterProtocol.indexOf("/");
+
+ let pathInfo = afterProtocol.substr(1+firstSlashOfAllPath);
+
+ rv.uriPathInfo="/"+pathInfo;
+
+ let domain = afterProtocol.substr(0,firstSlashOfAllPath);
+
+ let pathComponents=pathInfo.split("/");
+
+
+ // iterate through pathComponents to find the path component corresponding to a primary GS1 ID key
+ let relevantPathComponents=[];
+ let uriStemPathComponents=[];
+ let pcr=pathComponents.reverse();
+ let pcl=pathComponents.length;
+ let pci=pcl;
+ let searching=true;
+ let numericPrimaryIdentifier="";
+ for (let i in pcr) {
+ let numkey="";
+ let pcc = pcr[i];
+ if (this.regexAllNum.test(pcc)) {
+ numkey=pcc;
+ } else {
+ if (this.shortCodeToNumeric.hasOwnProperty(pcc)) {
+ numkey=this.shortCodeToNumeric[pcc];
+ }
+ }
+
+ if ((numkey !== "") && searching) {
+ if (this.aiMaps.identifiers.indexOf(numkey) > -1) {
+ searching=false;
+ pci=pcl-i;
+ numericPrimaryIdentifier = numkey;
+ relevantPathComponents=pcr.slice(0,(parseInt(i)+1)).reverse();
+ uriStemPathComponents=pcr.slice(parseInt(i)+1).reverse();
+ }
+ }
+ }
+
+ if (relevantPathComponents.length > 0) {
+ rv.pathComponents = "/"+relevantPathComponents.join("/");
+ } else {
+ rv.pathComponents= "";
+ }
+
+ if (uriStemPathComponents.length > 0) {
+ rv.uriStem = protocol+domain+"/"+uriStemPathComponents.join("/");
+ } else {
+ rv.uriStem=protocol+domain;
+ }
+
+
+ // if semicolon was used as delimiter between key=value pairs, replace with ampersand as delimiter
+ rv.queryString = rv.queryString.replace(new RegExp(";", 'g'),"&");
+
+
+ // process URI path information
+ let pathCandidates={};
+ let pathElements = pathInfo.split("/");
+ let l = pathElements.length;
+ let pathElementIndex=l-2;
+ while (pathElementIndex >= 0) {
+ pathCandidates[pathElements[pathElementIndex]]=this.percentDecode(pathElements[1+pathElementIndex]);
+ pathElementIndex-=2;
+ }
+
+ let queryStringCandidates={};
+ if (rv.queryString !== "") {
+
+ let pairs = rv.queryString.split("&");
+ for (let i=0; i 0) && ((relevantPathComponents.length % 2) == 0)) {
+ if (this.aiRegex[numericPrimaryIdentifier].test(relevantPathComponents[1])) {
+ rv.detected = "uncompressed GS1 Digital Link";
+
+ rv.uncompressedPath = "/"+relevantPathComponents.join("/");
+
+
+ if (extended) {
+ let extracted = this.extractFromGS1digitalLink(gs1DigitalLinkURI);
+ let gs1AIarray = extracted.GS1;
+ let otherArray = extracted.other;
+ let structuredArray = this.buildStructuredArray(gs1AIarray,otherArray);
+ rv.structuredOutput=structuredArray;
+ rv.elementStringsOutput=this.gs1digitalLinkToGS1elementStrings(gs1DigitalLinkURI,true);
+ }
+ }
+ }
+
+ if ((relevantPathComponents.length == 3) && (this.regexSafe64.test(relevantPathComponents[2]))) {
+ if (this.aiRegex[numericPrimaryIdentifier].test(relevantPathComponents[1])) {
+ rv.detected = "partially compressed GS1 Digital Link";
+ rv.uncompressedPath = "/"+relevantPathComponents.slice(0,2).join("/");
+ rv.compressedPath = relevantPathComponents[2];
+
+ if (extended) {
+ let extracted = this.extractFromCompressedGS1digitalLink(gs1DigitalLinkURI);
+ let gs1AIarray = extracted.GS1;
+ let otherArray = extracted.other;
+ let structuredArray = this.buildStructuredArray(gs1AIarray,otherArray);
+ rv.structuredOutput=structuredArray;
+ rv.elementStringsOutput=this.gs1compressedDigitalLinkToGS1elementStrings(gs1DigitalLinkURI,true);
+ }
+ }
+ }
+
+ if ((rv.detected == "") && (this.regexSafe64.test(pcr[0])) && (protocol !== "")) {
+ rv.detected = "fully compressed GS1 Digital Link";
+ rv.uncompressedPath="";
+ rv.compressedPath=pcr[0];
+
+ if (extended) {
+ let extracted = this.extractFromCompressedGS1digitalLink(gs1DigitalLinkURI);
+ let gs1AIarray = extracted.GS1;
+ let otherArray = extracted.other;
+ let structuredArray = this.buildStructuredArray(gs1AIarray,otherArray);
+ rv.structuredOutput=structuredArray;
+ rv.elementStringsOutput=this.gs1compressedDigitalLinkToGS1elementStrings(gs1DigitalLinkURI,true);
+ }
+ }
+
+ return rv;
+ }
+
+
+ // this method converts a GS1 Digital Link URI into an associative array of GS1 Application Identifiers and their values
+ // it is the inverse function of buildGS1gs1DigitalLinkURI(gs1AIarray,useShortText,uriStem)
+ extractFromGS1digitalLink(gs1DigitalLinkURI) {
+ // initialise internal variables
+ let obj={};
+ let rv={};
+
+ // extract path info and query string from URI and parse these to extract AI key:value pairs
+// let s=this.analyseURI(gs1DigitalLinkURI,false);
+
+
+ let s=this.analyseURI(gs1DigitalLinkURI,false);
+ let queryString=s.queryString;
+ let uriPathInfo=s.uriPathInfo;
+ let pathCandidates = s.pathCandidates;
+ let queryStringCandidates = s.queryStringCandidates;
+ let nonGS1queryStringCandidates={};
+
+ // merge pathCandidates and queryStringCandidates into a combined associative array, candidates
+ let candidates = Object.assign({},pathCandidates, queryStringCandidates);
+
+ // process candidates;
+ for (let k in candidates) {
+ if (candidates.hasOwnProperty(k)) {
+ if (!(this.regexAllNum.test(k))) {
+ // for keys that are not all-numeric, attempt to convert to all-numeric AI equivalent
+ if (this.shortCodeToNumeric.hasOwnProperty(k)) {
+ let numkey = this.shortCodeToNumeric[k];
+ candidates[numkey]=candidates[k];
+ delete candidates[k];
+ } else {
+ // or otherwise remove from candidates map if it doesn't relate to a GS1 Application Identifier
+ nonGS1queryStringCandidates[k]=candidates[k];
+ delete candidates[k];
+
+ }
+ }
+ }
+ }
+
+ for (let k in candidates) {
+ if (candidates.hasOwnProperty(k)) {
+ this.verifySyntax(k,candidates[k]);
+ this.verifyCheckDigit(k,candidates[k]);
+ obj[k] = padGTIN(k,candidates[k]);
+ }
+ }
+
+ rv.GS1=obj;
+ rv.other=nonGS1queryStringCandidates;
+
+ return rv;
+
+
+
+ function padGTIN(ai,value) {
+ // always pad the value of any GTIN [ AI (01) or (02) ] to 14 digits in element string representation
+ let newvalue=value;
+ if ((ai == "01") || (ai == "(01)") || (ai == "02") || (ai == "(02)")) {
+ if (value.length==8) { newvalue = '000000'+value; }
+ if (value.length==12) { newvalue = '00'+value; }
+ if (value.length==13) { newvalue = '0'+value; }
+ }
+ return newvalue;
+ }
+
+
+ }
+
+
+
+ // this method converts a GS1 Digital Link URI into an associative array of GS1 Application Identifiers and their values
+ // it is the inverse function of buildGS1gs1DigitalLinkURI(gs1AIarray,useShortText,uriStem)
+ extractFromCompressedGS1digitalLink(gs1DigitalLinkURI) {
+ // initialise internal variables
+ let objGS1={};
+ let objOther={};
+ let rv={};
+
+ // set cursor to 0 = start reading from the left-most part of the gs1 Digital Link URI provided as input
+ let s=this.analyseURI(gs1DigitalLinkURI,false);
+
+ let queryString=s.queryString;
+ let uriPathInfo=s.uriPathInfo;
+ let candidates=s.pathCandidates;
+ let queryStringCandidates = s.queryStringCandidates;
+ let nonGS1queryStringCandidates={};
+
+ if (queryString !== "") {
+ // if semicolon was used as delimiter between key=value pairs, replace with ampersand as delimiter
+ queryString = queryString.replace(new RegExp(";", 'g'),"&");
+
+ let firstFragment = queryString.indexOf("#");
+ if (firstFragment > -1) {
+ queryString = queryString.substring(0,firstFragment);
+ }
+
+ let pairs = queryString.split("&");
+ for (let i=0; i -1) {
+ elementStrings = elementStringsPush(elementStrings,"("+qualifiersForPrimary[qindex]+")",gs1AIarray[qualifiersForPrimary[qindex]],"");
+
+ }
+ }
+ }
+
+ // append any found attributes to the elementStrings array
+ let sortedAttributes = attributes.sort();
+ for (let a in sortedAttributes) {
+ elementStrings = elementStringsPush(elementStrings, "("+attributes[a]+")",gs1AIarray[attributes[a]],"");
+ }
+ }
+
+ } else {
+ // if brackets=false, concatenate defined-length AIs first, then variable-length AIs
+ // identify which AIs in gs1AIarray are defined fixed length
+
+ let fixedLengthPrimaryIdentifier=[];
+ let fixedLengthValuesOther=fixedLengthValues.slice(0);;
+
+
+ for (let i in fixedLengthValuesOther) {
+ if (identifiers.indexOf(fixedLengthValuesOther[i]) > -1) {
+ fixedLengthPrimaryIdentifier.push(fixedLengthValuesOther[i]);
+ fixedLengthValuesOther.splice(i,1);
+ }
+ }
+
+ for (let i in fixedLengthPrimaryIdentifier) {
+ elementStrings = elementStringsPush(elementStrings,fixedLengthPrimaryIdentifier[i],gs1AIarray[fixedLengthPrimaryIdentifier[i]],"");
+
+ }
+
+ for (let i in fixedLengthValuesOther) {
+ elementStrings = elementStringsPush(elementStrings,fixedLengthValuesOther[i],gs1AIarray[fixedLengthValuesOther[i]],"");
+ }
+
+ for (let i in variableLengthValues) {
+ let gs="";
+ if (i<(variableLengthValues.length-1)) {
+ gs=this.groupSeparator;
+ }
+ elementStrings = elementStringsPush(elementStrings,variableLengthValues[i],gs1AIarray[variableLengthValues[i]],gs);
+ }
+
+ }
+
+ return elementStrings.join("");
+
+
+ function elementStringsPush(elementStrings,ai,value,gs) {
+ let newvalue=value;
+ // always pad the value of any GTIN [ AI (01) or (02) ] to 14 digits in element string representation
+ if ((ai == "01") || (ai == "(01)") || (ai == "02") || (ai == "(02)")) {
+ if (value.length==8) { newvalue = '000000'+value; }
+ if (value.length==12) { newvalue = '00'+value; }
+ if (value.length==13) { newvalue = '0'+value; }
+ }
+ elementStrings.push(ai+newvalue+gs);
+ return elementStrings;
+ }
+
+ }
+
+
+
+
+ // translate a string of concatenated GS1 element strings into a GS1 Digital Link URI
+ gs1ElementStringsToGS1DigitalLink(elementString,useShortText,uriStem) {
+ return this.buildGS1digitalLink(this.extractFromGS1elementStrings(elementString),useShortText,uriStem,{});
+ }
+
+ // translate a GS1 Digital Link URI into a string of concatenated GS1 element strings
+ gs1digitalLinkToGS1elementStrings(digitalLinkURI,brackets) {
+ return this.buildGS1elementStrings(this.extractFromGS1digitalLink(digitalLinkURI).GS1,brackets);
+ }
+
+ // translate a GS1 Digital Link URI into a string of concatenated GS1 element strings
+ gs1compressedDigitalLinkToGS1elementStrings(digitalLinkURI,brackets) {
+ return this.buildGS1elementStrings(this.extractFromCompressedGS1digitalLink(digitalLinkURI).GS1,brackets);
+ }
+
+
+ handleEncodings(enc,lengthBits,charstr,binstr) {
+ // creates a binary string fragment that starts with a 3-digit encoding indicator, any lengthBits specified (empty string "" if not required for a fixed-length value) and then the actual value of charstr in binaryEncodingOfGS1AIKey
+ // calls buildBinaryValue() when encoding the value in binary
+ switch (enc) {
+ case 0:
+ // handle all-numeric encoding
+ let binLength=this.numberOfValueBits(charstr.length);
+ let binValue=parseInt(charstr).toString(2);
+ binValue=this.padToLength(binValue,binLength);
+ binstr+='000'+lengthBits+binValue;
+ break;
+
+ case 1:
+ binstr+='001'+lengthBits+this.buildBinaryValue(charstr.toUpperCase(),4,this.hexAlphabet);
+ break;
+
+ case 2:
+ binstr+='010'+lengthBits+this.buildBinaryValue(charstr.toUpperCase(),4,this.hexAlphabet);
+ break;
+
+ case 3:
+ binstr+='011'+lengthBits+this.buildBinaryValue(charstr,6,this.safeBase64Alphabet);
+ break;
+
+ case 4:
+ binstr+='100'+lengthBits+this.buildBinaryValue(charstr,7,null);
+ break;
+ }
+ return binstr;
+ }
+
+ buildBinaryValue(charstr, n, alphabet) {
+ // this method converts a string charstr into binary, using n bits per character and decoding from the supplied alphabet or from ASCII when n=7
+ // this is almost the inverse method to buildString
+ let binValue="";
+ let binLength=n*charstr.length;
+ for (let i=0; i8) {
+
+ let h1=this.binstrToHex(binstr.substr(cursor,4));
+ let h2=this.binstrToHex(binstr.substr(4+cursor,4));
+ let h3="";
+ let h4="";
+ let ai="";
+
+ let h1h2=""+h1+h2;
+ cursor+=8;
+
+ let d1=parseInt(h1,16);
+ let d2=parseInt(h2,16);
+
+ // check if h1h2 is within the range 00-99
+ if ((d1>=0) && (d2>=0) && (d1<=9) && (d2<=9)) {
+
+ // check if h1h2 has entry in table P
+ if (this.tableP.hasOwnProperty(h1h2)) {
+ let l=this.tableP[h1h2];
+
+ if (l==2) { ai=h1h2; }
+ if ((l==3) || (l==4)) {
+ h3=this.binstrToHex(binstr.substr(cursor,4));
+ cursor+=4;
+ let d3=parseInt(h3,16);
+ if (d3>9) {
+ throw new Error("GS1 Application Identifier keys should be all-numeric; "+h1h2+h3+" is not all-numeric");
+ }
+ ai=h1h2+h3;
+ }
+ if (l==4) {
+ let h4=this.binstrToHex(binstr.substr(cursor,4));
+ cursor+=4;
+ ai=h1h2+h3+h4;
+ let d4=parseInt(h4,16);
+ if (d4>9) {
+ throw new Error("GS1 Application Identifier keys should be all-numeric; "+h1h2+h3+h4+" is not all-numeric");
+ }
+ }
+
+ let tmp=this.decodeBinaryValue(ai,gs1AIarray,binstr,cursor);
+ gs1AIarray=tmp.gs1AIarray;
+ cursor=tmp.cursor;
+
+ } else {
+
+ throw new Error("Fail: Unsupported AI (reserved range) - no entry in tableP; h1h2="+h1h2);
+ }
+
+
+ } else {
+
+ // h1h2 is outside 00-99, using some hex characters
+
+ if (this.tableOpt.hasOwnProperty(h1h2)) {
+ // we found an optimisation for h1h2
+
+ let seq=this.tableOpt[h1h2];
+ for (let i in seq) {
+ let ai=seq[i];
+ let tmp=this.decodeBinaryValue(ai,gs1AIarray,binstr,cursor);
+ gs1AIarray=tmp.gs1AIarray;
+ cursor=tmp.cursor;
+ }
+
+ } else {
+
+ if (h1=="F") {
+ // handle decompression of non-GS1 key=value pairs
+ let bitsIncludingF = binstr.substr(cursor-8,11);
+ let keyLength=parseInt(binstr.substr(cursor-4,7),2);
+ cursor+=3; // 3 extra bits beyond h2
+
+ let keyBits=binstr.substr(cursor,6*keyLength);
+ cursor+=6*keyLength;
+
+ let key="";
+ for (let i=0; i 0)
+
+
+ }
+
+
+ // encode binary string for any optimised values from tableOpt first
+ for (let i in optimisations) {
+ let key=optimisations[i];
+ binstr+=this.binaryEncodingOfGS1AIKey(key);
+ let optArray=this.tableOpt[key];
+ for (let i in optArray) {
+ let k=optArray[i];
+ binstr+=this.binaryEncodingOfValue(gs1AIarray,k);
+ }
+ }
+
+
+ // then append this further by encoding binary string values for any other AI key=value pairs for which no optimisations were found
+ for (let i in akeysa) {
+ let key=akeysa[i];
+ if (gs1AIarray.hasOwnProperty(key)) {
+ binstr+=this.binaryEncodingOfGS1AIKey(key);
+ binstr+=this.binaryEncodingOfValue(gs1AIarray,key);
+ }
+ }
+
+ // then if any non-GS1 key=value pairs were also to be compressed, also compress those and append to the binary string
+ // note that hex value F ('1111') is used as a flag (as a reserved value of h1) to indicate that what follows is a compressed binary representation of a non-GS1 key=value pair
+ // we permit key lengths up to 128 characters only from the URI-safe base64 alphabet (A-Z a-z 0-9 hyphen and underscore)
+ if (Object.keys(nonGS1keyvaluePairs).length > 0) {
+ for (let key in nonGS1keyvaluePairs) {
+ let lengthBits = (key.length).toString(2);
+ lengthBits=this.padToLength(lengthBits,7);
+ binstr+="1111"; // 'F' (flag for foreign keys)
+ binstr+=lengthBits;
+ let binKey="";
+ for (let i=0; imax) {
+ maxkey=i;
+ max=candidatesFromTableOpt[i];
+ }
+ }
+ return maxkey;
+ }
+
+ function removeOptimisedKeysFromAIlist(akeysa,v) {
+ for (let i in v) {
+ let ind=akeysa.indexOf(v[i]);
+ if (ind > -1) {
+ akeysa.splice(ind, 1);
+ }
+ }
+ return akeysa;
+ }
+
+ }
+
+ binaryEncodingOfGS1AIKey(key) {
+ // construct binary encoding of AI key as sequence of 4-bit digits
+ // this is now modified to also support hex values of key
+ let binAI="";
+ for (let i=0; i 0) {
+ queryString="?"+akv.join("&");
+ }
+ }
+
+ // Need to remove unwanted trailing slash
+ if ((uriStem !== undefined) && (uriStem !== null) && (uriStem !== "") && (uriStem.endsWith("/"))) {
+ uriStem=uriStem.substr(0,uriStem.length);
+ }
+
+ path="/"+this.bin2base64(this.compressGS1AIarrayToBinary(gs1AIarray,useOptimisations,(compressOtherKeyValuePairs ? nonGS1keyvaluePairs : {})));
+
+ if ((uriStem == null) || (uriStem == "")) {
+ // prepare a canonical Web URI
+ webURI=canonicalStem+path+queryString;
+ } else {
+ webURI=uriStem+path+queryString;
+ }
+
+ return webURI;
+ }
+
+
+ decompressGS1DigitalLink(compressedDigitalLinkURI,useShortText,uriStem) {
+ let extracted = this.extractFromCompressedGS1digitalLink(compressedDigitalLinkURI);
+ let gs1AIarray = extracted.GS1;
+ let otherArray = extracted.other;
+ // TODO do something with otherArray to add it to the URI query string
+ let uncompressedDL = this.buildGS1digitalLink(gs1AIarray,useShortText,uriStem,otherArray);
+ // return uncompressedDL;
+ return uncompressedDL;
+ }
+
+ decompressGS1DigitalLinkToStructuredArray(compressedDigitalLinkURI) {
+ let extracted = this.extractFromCompressedGS1digitalLink(compressedDigitalLinkURI);
+ let gs1AIarray = extracted.GS1;
+ let otherArray = extracted.other;
+ let structuredArray = this.buildStructuredArray(gs1AIarray,otherArray);
+ return structuredArray;
+ }
+
+
+ compressGS1DigitalLink(digitalLinkURI,useShortText,uriStem,uncompressedPrimary,useOptimisations,compressOtherKeyValuePairs) {
+ // extract query string
+ let firstQuestionMark = digitalLinkURI.indexOf("?");
+ let queryString="";
+ let nonGS1keyvaluePairs={};
+ if (firstQuestionMark > -1) {
+ queryString = digitalLinkURI.substr(1+firstQuestionMark);
+ }
+ if (queryString !== "") {
+ // if semicolon was used as delimiter between key=value pairs, replace with ampersand as delimiter
+ queryString = queryString.replace(new RegExp(";", 'g'),"&");
+
+ let firstFragment = queryString.indexOf("#");
+ if (firstFragment > -1) {
+ queryString = queryString.substring(0,firstFragment);
+ }
+
+ let pairs = queryString.split("&");
+ for (let i=0; i -1) {
+ idArray[keys[i]] = gs1AIarray[keys[i]];
+ } else {
+ nonIDarray[keys[i]] = gs1AIarray[keys[i]];
+ }
+ }
+ }
+ rv.ID=idArray;
+ rv.nonID=nonIDarray;
+ return rv;
+ }
+
+}
diff --git a/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/LICENCE b/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/LICENCE
new file mode 100644
index 0000000..e730051
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/utils/GS1DigitalLinkToolkit/LICENCE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2019 GS1 AISBL
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/LICENSE b/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/LICENSE
new file mode 100644
index 0000000..f49a4e1
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/interpretGS1scan.js b/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/interpretGS1scan.js
new file mode 100644
index 0000000..857de40
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/utils/interpretGS1scan/interpretGS1scan.js
@@ -0,0 +1,261 @@
+/*
+ A set of functions for interpreting the string of data in various GS1 formats, as found in barcodes of different types
+ It depends on the GS1 Digital Link toolkit
+ If there are no errors, the interpretScan function returns an object as follows
+
+ AIbrackets: The equivalent GS1 element string in human-readable AI syntax
+ AIfnc1: The equivalent GS1 element string in AI syntax with FNC1 (as used in barcodes)
+ dl: The equivalent GS1 Digital Link URL (on id.gs1.org)
+ ol: An ordered array of objects parsed/interpreted from the input string:
+ ai: the GS1 Application Identifier
+ label: what that AI is used for
+ value: the value
+
+ The order for the ol list matches that found in a GS1 Digital Link URI
+ - primary identifier
+ - any applicable qualifiers
+ - any data attributes
+ - any non-GS1 AIs and their values
+
+ Simply pass the string to be interpreted to the interpretScan() function.
+
+ It can handle any of the 3 formats:
+ - Human readable AI syntax
+ - Pure AI syntax
+ - GS1 Digital Link
+
+ If the input string cannot be interpreted, i.e. it's not a valid GS1 string, then the returned object
+ has a value for errmsg which is the system error message.
+
+*/
+
+/* This first mini function tests the incoming string against the monster regular expression that assesses whether the incoming string is plausibly a GS1 DL URI
+It DOES NOT guarantee that a true response *is* is GS1 DL URI, but will reject a lot that it knows to be false.
+This RegEx is included in version 1.2 of Digital Link: URI Syntax. All improvements welcome.
+
+The initial pattern matches the structure of a URL (http or https) including the little-used but possible inclusion of passwords and port numbers.
+
+^https?:(\/\/((([^\/?#]*)@)?([^\/?#:]*)(:([^\/?#]*))?))?
+
+Next we want to test for the presence of a path component containing a primary key (which may follow aribitrary other path segments). This can be either in its numeric form or its convenience string equivalent. We further want to test that the path segment following the primary key:
+
+• Is a string beginning with at least 4 digits.
+• Is followed optionally zero or more repetitions of:
+ o a literal forward slash;
+ o one or more characters of which none are a literal forward slash;
+ o another literal forward slash;
+ o one or more characters of which none are a literal forward slash.
+
+Furthermore:
+
+• A trailing forward slash is allowed at the end of the URI path info (strictly speaking forbidden by the ABNF grammar for DL but is tolerable)
+• Anything following the path is within the structure of a URL with a query string and fragment identifier.
+
+These rules are expressed in the following pattern
+
+([^?#]*)(\/(01|gtin|8006|itip|8013|gmn|8010|cpid|414|gln|417|party|8017|gsrnp|8018|gsrn|255|gcn|00|sscc|253|gdti|401|ginc|402|gsin|8003|grai|8004|giai)\/)(\d{4}[^\/]+)(\/[^/]+\/[^/]+)?[/]?(\?([^?\n]*))?(#([^\n]*))?
+
+A final complexity is that a GS1 DL URI may be compressed [DL-Compression]. The path of a compressed GS1 DL URI will:
+
+• Contain at least 10 characters from the base 64 safe set (digits, upper and lower case Latin letters, _ -)
+• No other characters (including path separators, querystrings and fragments)
+
+These features are tested by
+
+\/[0-9A-Za-z_-]{10,}$
+
+Therefore, the path of a GS1 DL URI will match either of the previous two patterns.
+
+Concatenating these gives the full RegEx.
+*/
+
+import GS1DigitalLinkToolkit from "../GS1DigitalLinkToolkit/GS1DigitalLinkToolkit.js";
+
+const plausibleGs1DlUriRegEx = /^https?:(\/\/((([^\/?#]*)@)?([^\/?#:]*)(:([^\/?#]*))?))?((([^?#]*)(\/(01|gtin|8006|itip|8013|gmn|8010|cpid|414|gln|417|party|8017|gsrnp|8018|gsrn|255|gcn|00|sscc|253|gdti|401|ginc|402|gsin|8003|grai|8004|giai)\/)(\d{4}[^\/]+)(\/[^/]+\/[^/]+)?[/]?(\?([^?\n]*))?(#([^\n]*))?)|(\/[0-9A-Za-z_-]{10,}$))/;
+
+const plausibleCompressedGs1DlUriRegEx = /^https?:(\/\/((([^\/?#]*)@)?([^\/?#:]*)(:([^\/?#]*))?))?\/[0-9A-Za-z_-]{10,}$/;
+
+const gs1Url = 'https://id.gs1.orgx';
+
+
+function isPlausibleGs1DlUri(s) {
+ return plausibleGs1DlUriRegEx.test(s);
+}
+
+
+function interpretScan(scan) {
+ function throwError(message){
+ throw {
+ message,
+ dlOrderedAIlist
+ }
+ }
+ let re = /\((\d{2,4}?)\)/g;
+ const toBeReplaced = [];
+ const toBeRemoved = [];
+ const matches = scan.matchAll(re);
+ for (const match of matches) {
+ toBeReplaced.push(match.index);
+ toBeRemoved.push(match.index + match[0].length - 1);
+ }
+ let newScan = [...scan];
+ toBeReplaced.forEach(index => newScan.splice(index, 1, String.fromCharCode(29)));
+ for (let i = toBeRemoved.length -1; i >= 0; i--){
+ newScan.splice(toBeRemoved[i],1);
+ }
+ scan = newScan.join('');
+ let gtinRE = /^(\d{8})$|^(\d{12,14})$/;
+ let e, gs1DigitalLinkURI, gs1ElementStrings, gs1Array, primaryKey, AIstringBrackets, AIstringFNC1, errmsg, gs1dlt;
+ let dlOrderedAIlist = [];
+ let dateAIs = ['11', '12', '13', '15', '17'];
+
+ if (e = scan.match(gtinRE)) { // So we just have a GTIN (from an EAN/UPC probably)
+ scan = '(01)' + scan;
+ } else if (scan.indexOf(String.fromCharCode(29)) == 0) {
+ scan = scan.substring(1);
+ }
+ try {
+ gs1dlt = new GS1DigitalLinkToolkit();
+ if (isPlausibleGs1DlUri(scan)) {
+ if (plausibleCompressedGs1DlUriRegEx.test(scan)) {
+ scan = gs1dlt.decompressGS1DigitalLink(scan,false, gs1Url); // Decompress if it's likely to be compressed
+ }
+ try {
+ gs1ElementStrings = gs1dlt.gs1digitalLinkToGS1elementStrings(scan, true);
+ gs1DigitalLinkURI = scan;
+ } catch(err) {
+ throwError(err.message);
+ }
+ } else {
+ try {
+ gs1DigitalLinkURI = gs1dlt.gs1ElementStringsToGS1DigitalLink(scan, false, gs1Url);
+ } catch(err) {
+ throwError(err.message);
+ }
+ }
+ // console.log('We have a DL of ' + gs1DigitalLinkURI);
+ } catch(err) {
+ throwError(err.message);
+ }
+
+ // Whatever the input, we have a DL or an error. If an error, the value of gs1DigitalLinkURI is undefined
+ if (gs1DigitalLinkURI == undefined) {
+ throwError(errmsg);
+ } else {
+ try {
+ gs1Array = gs1dlt.extractFromGS1digitalLink(gs1DigitalLinkURI);
+ } catch(err) {
+ throwError(err.message);
+ }
+
+ // Want to find the primary identifier
+ // We'll use the aitable
+ let done = []; // Use this to keep track of what we've done
+ for (let i in gs1Array.GS1) {
+ if (gs1dlt.aitable.find(x => x.ai === i).type === 'I') {
+ primaryKey = i;
+ dlOrderedAIlist.push(getAIElement(i, gs1dlt, gs1Array.GS1, dateAIs));
+ done.push(i);
+ }
+ }
+ if (gs1dlt.aiQualifiers[primaryKey] !== undefined) {
+ gs1dlt.aiQualifiers[primaryKey].forEach(function(i) {
+ if (gs1Array.GS1[i] !== undefined) {
+ dlOrderedAIlist.push(getAIElement(i, gs1dlt, gs1Array.GS1, dateAIs));
+ done.push(i);
+ }
+ });
+ }
+ //console.log(dlOrderedAIlist); // These are the ones we have already got. We need to get the rest but these can be in any order
+ for (let i in gs1Array.GS1) {
+ if (!done.includes(i)) {
+ dlOrderedAIlist.push(getAIElement(i, gs1dlt, gs1Array.GS1, dateAIs));
+ done.push(i);
+ }
+ }
+ for (let i in gs1Array.other) { // These are the non-GS1 elements that can occur in a DL URI. We don't know the labels
+ if (!dlOrderedAIlist.includes(i)) {
+ let temp = {};
+ temp['ai'] = i;
+ temp['value'] = gs1Array.other[i];
+ dlOrderedAIlist.push(temp);
+ done.push(i);
+ }
+ }
+ let returnObject = sortElementString(gs1Array.GS1);
+ returnObject['ol'] = dlOrderedAIlist;
+ returnObject['dl'] = gs1DigitalLinkURI;
+ return returnObject;
+ }
+}
+
+
+function getAIElement(e, gs1dlt, values, dateAIs) {
+ let ro = {};
+ ro['ai'] = e;
+ ro['label'] = gs1dlt.aitable.find(x => x.ai === e).label;
+ ro['value'] = dateAIs.includes(e) ? gs1ToISO(values[e]) : values[e];
+ return ro;
+}
+
+
+function sortElementString(a) {
+ // This creates two GS1 element string versions of the given array, one with brackets, one with FNC1
+ // Order is:
+ // Primary key
+ // Fixed length
+ // The rest
+
+ let gs1dlt = new GS1DigitalLinkToolkit();
+ let sortedBrackets = '';
+ let sortedFNC1 = '';
+// const FNC1 = String.fromCharCode(29);
+ const FNC1 = gs1dlt.groupSeparator;
+ for (let i in a) { // Look for the primary key
+ if (gs1dlt.aitable.find(x => x.ai == i).type == 'I') {
+ sortedBrackets = '(' + i + ')' + a[i];
+ sortedFNC1 = FNC1 + i + a[i];
+ }
+ }
+ for (let i in a) { // Look for fixed length AIs
+ if ((sortedBrackets.indexOf('('+ i + ')') == -1) && (gs1dlt.aitable.find(x => x.ai == i).fixedLength == true)) {
+ sortedBrackets += '(' + i + ')' + a[i];
+ sortedFNC1 += i + a[i];
+ }
+ }
+ for (let i in a) { // Everything else
+ if (sortedBrackets.indexOf('('+ i + ')') == -1) {
+ sortedBrackets += '(' + i + ')' + a[i];
+ sortedFNC1 += i + a[i] + FNC1;
+ }
+ }
+ if (sortedFNC1.lastIndexOf(FNC1) == sortedFNC1.length -1) { sortedFNC1 = sortedFNC1.substring(0, sortedFNC1.length -1)}
+ return {'AIbrackets' : sortedBrackets, 'AIfnc1' : sortedFNC1}
+}
+function gs1ToISO(gs1Date) {
+ let rv="";
+ let regexDate= new RegExp("^\\d{6}$");
+ if (gs1Date !== undefined && regexDate.test(gs1Date)) {
+ let doubleDigits = gs1Date.split(/(\d{2})/);
+ let year=parseInt(doubleDigits[1]);
+ let currentYear=new Date().getFullYear().toString();
+ let currentLastYY=parseInt(currentYear.substr(-2));
+ let currentFirstYY=parseInt(currentYear.substr(0,2));
+ let diff=year-currentLastYY;
+ let fullyear=currentFirstYY.toString()+year.toString();
+ if (diff >=51 && diff <= 99) {
+ fullyear=(currentFirstYY-1).toString()+year.toString();
+ }
+ if (diff >= -99 && diff <= -50) {
+ fullyear=(currentFirstYY+1).toString()+year.toString();
+ }
+ if (fullyear !== undefined) {
+ rv = fullyear + '-' + doubleDigits[3] + '-' + doubleDigits[5];
+ }
+ }
+ return rv;
+}
+
+export default {
+ interpretScan
+}
diff --git a/apihub-root/lightweight-pwa/js/utils/utils.js b/apihub-root/lightweight-pwa/js/utils/utils.js
new file mode 100644
index 0000000..cb499b5
--- /dev/null
+++ b/apihub-root/lightweight-pwa/js/utils/utils.js
@@ -0,0 +1,25 @@
+const monthNames = ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+];
+
+function convertFromISOtoYYYY_HM(dateString, useFullMonthName, separator) {
+ const splitDate = dateString.split('-');
+ const month = parseInt(splitDate[1]);
+ let separatorString = "-";
+ if (typeof separator !== "undefined") {
+ separatorString = separator;
+ }
+ if (useFullMonthName) {
+ return `${splitDate[2]} ${separatorString} ${monthNames[month - 1]} ${separatorString} ${splitDate[0]}`;
+ }
+ return `${splitDate[2]} ${separatorString} ${monthNames[month - 1].slice(0, 3)} ${separatorString} ${splitDate[0]}`;
+}
+function goToPage(urlFragment) {
+ let url = window.location.href.replace(/\/[^\/]*$/, '/' + urlFragment);
+ window.location.replace(url);
+}
+
+export {
+ convertFromISOtoYYYY_HM,
+ goToPage
+}
diff --git a/octopus.json b/octopus.json
index 6cfdfa1..8b077cf 100644
--- a/octopus.json
+++ b/octopus.json
@@ -1,1228 +1,1240 @@
{
- "workDir": ".",
- "dependencies": [
- {
- "name": "webcardinal/bundle",
- "src": "https://github.com/webcardinal/webcardinal-all-release",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd webcardinal && npm install"
- }
- ]
- },
- {
- "name": "cardinal",
- "src": "http://github.com/privatesky/cardinal.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd cardinal && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd cardinal && npm run build"
- }
- ]
- },
- {
- "name": "privatesky",
- "src": "http://github.com/privatesky/privatesky.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd privatesky && npm install"
- }
- ]
- },
- {
- "name": "build privatesky",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd privatesky && npm run build"
- }
- ]
- },
- {
- "name": "leaflet-ssapp",
- "src": "https://github.com/PharmaLedger-IMI/leaflet-ssapp.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd leaflet-ssapp && npm install"
- }
- ]
- },
- {
- "name": "demiurge",
- "src": "https://github.com/OpenDSU/demiurge.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd demiurge && npm install"
- }
- ]
- },
- {
- "name": "apihub-root/demiurge-wallet/loader",
- "src": "http://github.com/privatesky/web-dossier-loader.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/demiurge-wallet/loader && npm install"
- },
- {
- "type": "copy",
- "src": "apihub-root/demiurge-wallet/loader/loader-config.local.json-template",
- "target": "apihub-root/demiurge-wallet/loader/loader-config.local.json",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "apihub-root/leaflet-wallet/loader",
- "src": "http://github.com/privatesky/trust-loader.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/leaflet-wallet/loader && npm install"
- },
- {
- "type": "copy",
- "src": "apihub-root/leaflet-wallet/loader/loader-config.local.json-template",
- "target": "apihub-root/leaflet-wallet/loader/loader-config.local.json",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "apihub-root/dsu-fabric-wallet/loader",
- "src": "http://github.com/privatesky/trust-loader.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm run build"
- }
- ]
- },
- {
- "name": "themes/citrus-theme",
- "src": "http://github.com/privatesky/citrus-theme.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd themes/citrus-theme && npm install"
- }
- ]
- },
- {
- "name": "themes/clear-sky-theme",
- "src": "http://github.com/privatesky/clear-sky-theme.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd themes/clear-sky-theme && npm install"
- }
- ]
- },
- {
- "name": "themes/epi-theme",
- "src": "https://github.com/PharmaLedger-IMI/epi-theme.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd themes/epi-theme && npm install"
- }
- ]
- },
- {
- "name": "dossier-explorer-wallet-prototype",
- "src": "https://github.com/PrivateSky/dossier-explorer-wallet-prototype.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd dossier-explorer-wallet-prototype && npm install"
- }
- ]
- },
- {
- "name": "apihub-root/dsu-explorer/loader",
- "src": "https://github.com/PrivateSky/trust-loader.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/dsu-explorer/loader && npm install"
- },
- {
- "type": "copy",
- "src": "apihub-root/dsu-explorer/loader/loader-config.local.json-template",
- "target": "apihub-root/dsu-explorer/loader/loader-config.local.json",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "gtin-resolver",
- "src": "https://github.com/PharmaLedger-IMI/gtin-resolver.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd gtin-resolver && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd gtin-resolver && npm run build"
- }
- ]
- },
- {
- "name": "dfm-reporting",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm install"
- }
- ]
- },
- {
- "name": "gtin-dsu-wizard",
- "src": "https://github.com/PharmaLedger-IMI/gtin-dsu-wizard.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd gtin-dsu-wizard && npm install"
- }
- ]
- },
- {
- "name": "themes/blue-fluorite-theme",
- "src": "https://github.com/PrivateSky/blue-fluorite-theme.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd themes/blue-fluorite-theme && npm install"
- }
- ]
- },
- {
- "name": "dossier-explorer-ssapp",
- "src": "https://github.com/PrivateSky/dossier-explorer-ssapp.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd dossier-explorer-ssapp && npm install"
- }
- ]
- },
- {
- "name": "express-demo",
- "src": "https://github.com/PharmaLedger-IMI/express-demo",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd express-demo && npm install"
- }
- ]
- },
- {
- "name": "ethadapter",
- "src": "https://github.com/PharmaLedger-IMI/ethadapter",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "echo \"manualy run cd ethadapter && npm install\""
- },
- {
- "type": "execute",
- "cmd": "echo \"manualy run cd ethadapter/EthAdapter && npm install\""
- },
- {
- "type": "execute",
- "cmd": "echo \"manualy run cd ethadapter/SmartContracts && npm install\""
- }
- ]
- },
- {
- "name": "dsu-fabric-ssapp",
- "src": "https://github.com/PharmaLedger-IMI/dsu-fabric-ssapp.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd dsu-fabric-ssapp && npm install"
- }
- ]
- }
- ],
- "patch": [
- {
- "name": "trust-loader-config",
- "actions": [
- {
- "type": "copy",
- "src": "./trust-loader-config",
- "target": "./apihub-root",
- "options": {
- "overwrite": true,
- "ignoreErrors": true
- }
- }
- ]
- }
- ],
- "postinstall": [
- {
- "name": "trust-loader-config",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patch\""
- }
- ]
- },
- {
- "name": "copy-bundles",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd apihub-root/leaflet-wallet/loader && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/dsu-explorer/loader && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd apihub-root/demiurge-wallet/loader && npm install"
- },
- {
- "type": "copy",
- "src": "./privatesky/psknode/bundles/webshims.js",
- "target": "./apihub-root/bundles/webshims.js",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copy",
- "src": "./privatesky/psknode/bundles/loaderBoot.js",
- "target": "./apihub-root/bundles/loaderBoot.js",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "gtin-resolver-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd gtin-resolver && npm run build"
- }
- ]
- },
- {
- "name": "dfm-reporting",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm run build"
- }
- ]
- }
- ],
- "dsu-explorer-build": [
- {
- "name": "blue-fluorite-theme-wallet-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd themes/blue-fluorite-theme && npm run build-dossier"
- }
- ]
- },
- {
- "name": "dossier-explorer-wallet-prototype-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd dossier-explorer-wallet-prototype && npm run build"
- },
- {
- "type": "copySeed",
- "src": "./dossier-explorer-wallet-prototype/seed",
- "target": "./apihub-root/external-volume/wallets/dsu-explorer/wallet-patch/seed",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "dsu-explorer_bind_to_dossier-explorer-ssapp",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd dossier-explorer-ssapp && npm run build"
- },
- {
- "type": "copySeed",
- "src": "./dossier-explorer-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/dsu-explorer/apps-patch/dossier-explorer-ssapp/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "execute",
- "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/dsu-explorer/apps-patch/dossier-explorer-ssapp/readme"
- }
- ]
- }
- ],
- "epi-ssapps-and-wallets-build": [
- {
- "name": "cardinal-wallet-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd cardinal && npm run build-dossier"
- }
- ]
- },
- {
- "name": "webcardinal-wallet-build",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd webcardinal && npm run build"
- }
- ]
- },
- {
- "name": "citrus-theme-wallet-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd themes/citrus-theme && npm run build-dossier"
- }
- ]
- },
- {
- "name": "clear-sky-theme-wallet-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd themes/clear-sky-theme && npm run build-dossier"
- }
- ]
- },
- {
- "name": "epi-theme-wallet-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd themes/epi-theme && npm run build-dossier"
- }
- ]
- },
- {
- "name": "leaflet-wallet_bind_to_leaflet-ssapp",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd leaflet-ssapp && npm run build"
- },
- {
- "type": "copySeed",
- "src": "./leaflet-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copySeed",
- "src": "./leaflet-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/leaflet-wallet/wallet-patch/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "execute",
- "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/readme"
- }
- ]
- },
- {
- "name": "demiurge-wallet_bind_to_demiurge",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd demiurge && npm run build"
- },
- {
- "type": "copySeed",
- "src": "./demiurge/seed",
- "target": "./apihub-root/external-volume/wallets/demiurge-wallet/apps-patch/demiurge/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copySeed",
- "src": "./demiurge/seed",
- "target": "./apihub-root/external-volume/wallets/demiurge-wallet/wallet-patch/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "execute",
- "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/demiurge-wallet/apps-patch/demiurge/readme"
- }
- ]
- },
- {
- "name": "dsu-fabric-wallet_bind_to_dsu-fabric-ssapp",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd dsu-fabric-ssapp && npm run build"
- },
- {
- "type": "copySeed",
- "src": "./dsu-fabric-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/dsu-fabric-wallet/apps-patch/dsu-fabric-ssapp/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copySeed",
- "src": "./dsu-fabric-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/dsu-fabric-wallet/wallet-patch/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "execute",
- "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/dsu-fabric-wallet/apps-patch/dsu-fabric-ssapp/readme"
- }
- ]
- }
- ],
- "ssapps-and-wallets-build": [
- {
- "name": "gtin-resolver-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd gtin-resolver && npm run build"
- }
- ]
- },
- {
- "name": "dfm-reporting",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm run build"
- }
- ]
- },
- {
- "name": "dfm-native-integration-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd acdc/native-integration && npm run build",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "copy",
- "src": "./acdc/native-integration/build/bundles/default/camera.js",
- "target": "./apihub-root/leaflet-wallet/loader/camera.js",
- "options": {
- "overwrite": true,
- "ignoreErrors": true
- }
- }
- ]
- },
- {
- "name": "epi-ssapps-and-wallets-build",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js epi-ssapps-and-wallets-build\""
- }
- ]
- }
- ],
- "build": [
- {
- "name": "build-all",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js ssapps-and-wallets-build\""
- },
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js dsu-explorer-build\""
- },
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js postbuild\""
- }
- ]
- }
- ],
- "postbuild": [
- {
- "name": "patching trust loaders configs",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js postinstall\""
- }
- ]
- },
- {
- "name": "leaflet-wallet-loader-build",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd apihub-root/leaflet-wallet/loader && npm run build"
- }
- ]
- }
- ],
- "install-mobile": [
- {
- "name": "mobile/scan-app/android",
- "src": "https://github.com/PrivateSky/android-edge-agent",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && npm install"
- }
- ]
- },
- {
- "name": "mobile/scan-app/ios",
- "src": "https://github.com/PharmaLedger-IMI/ios-edge-agent",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/ios/PSKNodeServer && carthage bootstrap"
- },
- {
- "type": "execute",
- "cmd": "echo \"Continue with ipa builds\""
- }
- ]
- }
- ],
- "build-android-apk": [
- {
- "name": "install NDK",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && gradlew.bat -b ndk.gradle installNDK",
- "os": "win32",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && ./gradlew -b ndk.gradle installNDK",
- "os": "linux",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && ./gradlew -b ndk.gradle installNDK",
- "os": "darwin",
- "options": {
- "ignoreErrors": true
- }
- }
- ]
- },
- {
- "name": "build APK",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && gradlew.bat assembleRelease",
- "os": "win32",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && ./gradlew assembleRelease",
- "os": "linux",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "execute",
- "cmd": "cd mobile/scan-app/android && ./gradlew assembleRelease",
- "os": "darwin",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "execute",
- "cmd": "echo \"APK should be in mobile/scan-app/android/app/build/outputs/apk/release\" "
- }
- ]
- }
- ],
- "prepare-build-mobile": [
- {
- "name": "prebuild",
- "actions": [
- {
- "type": "execute",
- "cmd": "npm run clean"
- },
- {
- "type": "execute",
- "cmd": "cd webcardinal && npm run build"
- },
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm run build"
- },
- {
- "type": "copy",
- "src": "./reporting-service/build/bundles/acdc.js",
- "target": "./leaflet-ssapp/code/scripts/bundles/acdc.js",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "execute",
- "cmd": "cd acdc/native-integration && npm run build",
- "options": {
- "ignoreErrors": true
- }
- }
- ]
- }
- ],
- "build-ssapps-and-configure-apihub-mobile": [
- {
- "name": "prebuild",
- "actions": [
- {
- "type": "execute",
- "cmd": "npm run build leaflet-ssapp"
- },
- {
- "type": "copySeed",
- "src": "./leaflet-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copySeed",
- "src": "./leaflet-ssapp/seed",
- "target": "./apihub-root/external-volume/wallets/leaflet-wallet/wallet-patch/seed",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copy",
- "src": "./trust-loader-config",
- "target": "./apihub-root",
- "options": {
- "overwrite": true
- }
- }
- ]
- }
- ],
- "build-mobile": [
- {
- "name": "prepare-phase",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js prepare-build-mobile\""
- },
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js build-ssapps-and-configure-apihub-mobile\""
- }
- ]
- },
- {
- "name": "prepare-phase",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patching-mobile\""
- }
- ]
- }
- ],
- "patching-mobile": [
- {
- "name": "build-android-app",
- "actions": [
- {
- "type": "remove",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project"
- },
- {
- "type": "copy",
- "src": "bin/MobileServerLauncher.js",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/MobileServerLauncher.js"
- },
- {
- "type": "copy",
- "src": "privatesky/psknode/bundles/pskWebServer.js",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/pskWebServer.js"
- },
- {
- "type": "copy",
- "src": "privatesky/psknode/bundles/nodeBoot.js",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/nodeBoot.js"
- },
- {
- "type": "copy",
- "src": "apihub-root/internal-volume",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/internal-volume"
- },
- {
- "type": "copy",
- "src": "apihub-root/external-volume",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/external-volume"
- },
- {
- "type": "copy",
- "src": "./acdc/native-integration/build/bundles/default/camera.js",
- "target": "./apihub-root/leaflet-wallet/loader/camera.js",
- "options": {
- "overwrite": true,
- "ignoreErrors": true
- }
- },
- {
- "type": "copy",
- "src": "apihub-root/leaflet-wallet",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app"
- },
- {
- "type": "remove",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app/loader/node_modules"
- },
- {
- "type": "remove",
- "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app/loader/.git"
- },
- {
- "type": "copy",
- "src": "mobile/config/scan-app/android",
- "target": "mobile/scan-app/android",
- "options": {
- "overwrite": true
- }
- }
- ]
- },
- {
- "name": "build-ios-app",
- "actions": [
- {
- "type": "remove",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject"
- },
- {
- "type": "copy",
- "src": "bin/MobileServerLauncher.js",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/MobileServerLauncher.js"
- },
- {
- "type": "copy",
- "src": "privatesky/psknode/bundles/pskWebServer.js",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/pskWebServer.js"
- },
- {
- "type": "copy",
- "src": "privatesky/psknode/bundles/nodeBoot.js",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/nodeBoot.js"
- },
- {
- "type": "copy",
- "src": "apihub-root/internal-volume",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/internal-volume"
- },
- {
- "type": "copy",
- "src": "apihub-root/external-volume",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/external-volume"
- },
- {
- "type": "copy",
- "src": "./acdc/native-integration/build/bundles/ios/camera.js",
- "target": "./apihub-root/leaflet-wallet/loader/camera.js",
- "options": {
- "overwrite": true,
- "ignoreErrors": true
- }
- },
- {
- "type": "copy",
- "src": "apihub-root/leaflet-wallet",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app"
- },
- {
- "type": "remove",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app/loader/node_modules"
- },
- {
- "type": "remove",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app/loader/.git"
- },
- {
- "type": "copy",
- "src": "mobile/config/scan-app/ios",
- "target": "mobile/scan-app/ios",
- "options": {
- "overwrite": true
- }
- },
- {
- "type": "copy",
- "src": "mobile/scan-app/ios/nativeBridge.js",
- "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/nativeBridge.js",
- "options": {
- "overwrite": true
- }
- }
- ]
- }
- ],
- "install-acf-ssapps": [
- {
- "name": "delayv-auth-feat-ssapp",
- "src": "https://github.com/asaccool/acdc-authentication-feature-59k3",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd delayv-auth-feat-ssapp && npm install"
- }
- ]
- },
- {
- "name": "acdc-authentication-feature-template",
- "src": "https://github.com/PharmaLedger-IMI/acdc-authentication-feature-template",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd acdc-authentication-feature-template && npm install"
- }
- ]
- },
- {
- "name": "truemedhemo-auth-feat-ssapp",
- "src": "https://github.com/resilient-research-development/acdc-authentication-feature-template",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd truemedhemo-auth-feat-ssapp && npm install"
- }
- ]
- }
- ],
- "install-dfm": [
- {
- "name": "acdc",
- "src": "https://github.com/PharmaLedger-IMI/acdc-components.git",
- "actions": [
- {
- "type": "smartClone",
- "target": ".",
- "collectLog": false
- },
- {
- "type": "execute",
- "cmd": "cd acdc && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd acdc/backoffice-backend && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd acdc/backoffice-frontend && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd acdc/reporting-service && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd acdc/native-integration && npm install"
- },
- {
- "type": "execute",
- "cmd": "cd acdc/pdm-web-components && npm install"
- }
- ]
- },
- {
- "name": "dfm-reporting",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm run build"
- }
- ]
- }
- ],
- "build-dfm": [
- {
- "name": "dfm-reporting",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd reporting-service && npm run build"
- }
- ]
- },
- {
- "name": "dfm-native-integration-build",
- "src": "",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd acdc/native-integration && npm run build",
- "options": {
- "ignoreErrors": true
- }
- },
- {
- "type": "copy",
- "src": "./acdc/native-integration/build/bundles/default/camera.js",
- "target": "./apihub-root/leaflet-wallet/loader/camera.js",
- "options": {
- "overwrite": true,
- "ignoreErrors": true
- }
- }
- ]
- },
- {
- "name": "build-pdm-web-components",
- "actions": [
- {
- "type": "execute",
- "cmd": "cd acdc/pdm-web-components && npm run ionic:build"
- }
- ]
- }
- ],
- "build-acf-ssapps": [
- {
- "name": "build-dfm",
- "actions": [
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js build-dfm\""
- },
- {
- "type": "execute",
- "cmd": "cd delayv-auth-feat-ssapp && npm run build"
- },
- {
- "type": "execute",
- "cmd": "cd truemedhemo-auth-feat-ssapp && npm run build"
- },
- {
- "type": "execute",
- "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patching-mobile\""
- }
- ]
- }
- ]
+ "workDir": ".",
+ "dependencies": [
+ {
+ "name": "webcardinal/bundle",
+ "src": "https://github.com/webcardinal/webcardinal-all-release",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd webcardinal && npm install"
+ }
+ ]
+ },
+ {
+ "name": "cardinal",
+ "src": "http://github.com/privatesky/cardinal.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd cardinal && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd cardinal && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "privatesky",
+ "src": "http://github.com/privatesky/privatesky.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd privatesky && npm install"
+ }
+ ]
+ },
+ {
+ "name": "build privatesky",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd privatesky && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "leaflet-ssapp",
+ "src": "https://github.com/PharmaLedger-IMI/leaflet-ssapp.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd leaflet-ssapp && npm install"
+ }
+ ]
+ },
+ {
+ "name": "demiurge",
+ "src": "https://github.com/OpenDSU/demiurge.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd demiurge && npm install"
+ }
+ ]
+ },
+ {
+ "name": "apihub-root/demiurge-wallet/loader",
+ "src": "http://github.com/privatesky/web-dossier-loader.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/demiurge-wallet/loader && npm install"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/demiurge-wallet/loader/loader-config.local.json-template",
+ "target": "apihub-root/demiurge-wallet/loader/loader-config.local.json",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "apihub-root/leaflet-wallet/loader",
+ "src": "http://github.com/privatesky/trust-loader.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/leaflet-wallet/loader && npm install"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/leaflet-wallet/loader/loader-config.local.json-template",
+ "target": "apihub-root/leaflet-wallet/loader/loader-config.local.json",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "apihub-root/dsu-fabric-wallet/loader",
+ "src": "http://github.com/privatesky/trust-loader.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "themes/citrus-theme",
+ "src": "http://github.com/privatesky/citrus-theme.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd themes/citrus-theme && npm install"
+ }
+ ]
+ },
+ {
+ "name": "themes/clear-sky-theme",
+ "src": "http://github.com/privatesky/clear-sky-theme.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd themes/clear-sky-theme && npm install"
+ }
+ ]
+ },
+ {
+ "name": "themes/epi-theme",
+ "src": "https://github.com/PharmaLedger-IMI/epi-theme.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd themes/epi-theme && npm install"
+ }
+ ]
+ },
+ {
+ "name": "dossier-explorer-wallet-prototype",
+ "src": "https://github.com/PrivateSky/dossier-explorer-wallet-prototype.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd dossier-explorer-wallet-prototype && npm install"
+ }
+ ]
+ },
+ {
+ "name": "apihub-root/dsu-explorer/loader",
+ "src": "https://github.com/PrivateSky/trust-loader.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/dsu-explorer/loader && npm install"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/dsu-explorer/loader/loader-config.local.json-template",
+ "target": "apihub-root/dsu-explorer/loader/loader-config.local.json",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "gtin-resolver",
+ "src": "https://github.com/PharmaLedger-IMI/gtin-resolver.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd gtin-resolver && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd gtin-resolver && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "dfm-reporting",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm install"
+ }
+ ]
+ },
+ {
+ "name": "gtin-dsu-wizard",
+ "src": "https://github.com/PharmaLedger-IMI/gtin-dsu-wizard.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd gtin-dsu-wizard && npm install"
+ }
+ ]
+ },
+ {
+ "name": "themes/blue-fluorite-theme",
+ "src": "https://github.com/PrivateSky/blue-fluorite-theme.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd themes/blue-fluorite-theme && npm install"
+ }
+ ]
+ },
+ {
+ "name": "dossier-explorer-ssapp",
+ "src": "https://github.com/PrivateSky/dossier-explorer-ssapp.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd dossier-explorer-ssapp && npm install"
+ }
+ ]
+ },
+ {
+ "name": "express-demo",
+ "src": "https://github.com/PharmaLedger-IMI/express-demo",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd express-demo && npm install"
+ }
+ ]
+ },
+ {
+ "name": "ethadapter",
+ "src": "https://github.com/PharmaLedger-IMI/ethadapter",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "echo \"manualy run cd ethadapter && npm install\""
+ },
+ {
+ "type": "execute",
+ "cmd": "echo \"manualy run cd ethadapter/EthAdapter && npm install\""
+ },
+ {
+ "type": "execute",
+ "cmd": "echo \"manualy run cd ethadapter/SmartContracts && npm install\""
+ }
+ ]
+ },
+ {
+ "name": "dsu-fabric-ssapp",
+ "src": "https://github.com/PharmaLedger-IMI/dsu-fabric-ssapp.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd dsu-fabric-ssapp && npm install"
+ }
+ ]
+ },
+ {
+ "name": "zxing-wrapper",
+ "src": "http://github.com/webcardinal/zxing-wrapper.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": "./apihub-root/lightweight-pwa/lib",
+ "collectLog": false,
+ "commit": "e9ec10b58d9ad3c9c07d3868ecf8f918aa440d9c"
+ }
+ ]
+ }
+ ],
+ "patch": [
+ {
+ "name": "trust-loader-config",
+ "actions": [
+ {
+ "type": "copy",
+ "src": "./trust-loader-config",
+ "target": "./apihub-root",
+ "options": {
+ "overwrite": true,
+ "ignoreErrors": true
+ }
+ }
+ ]
+ }
+ ],
+ "postinstall": [
+ {
+ "name": "trust-loader-config",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patch\""
+ }
+ ]
+ },
+ {
+ "name": "copy-bundles",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/leaflet-wallet/loader && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/dsu-fabric-wallet/loader && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/dsu-explorer/loader && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/demiurge-wallet/loader && npm install"
+ },
+ {
+ "type": "copy",
+ "src": "./privatesky/psknode/bundles/webshims.js",
+ "target": "./apihub-root/bundles/webshims.js",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "./privatesky/psknode/bundles/loaderBoot.js",
+ "target": "./apihub-root/bundles/loaderBoot.js",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "gtin-resolver-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd gtin-resolver && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "dfm-reporting",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm run build"
+ }
+ ]
+ }
+ ],
+ "dsu-explorer-build": [
+ {
+ "name": "blue-fluorite-theme-wallet-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd themes/blue-fluorite-theme && npm run build-dossier"
+ }
+ ]
+ },
+ {
+ "name": "dossier-explorer-wallet-prototype-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd dossier-explorer-wallet-prototype && npm run build"
+ },
+ {
+ "type": "copySeed",
+ "src": "./dossier-explorer-wallet-prototype/seed",
+ "target": "./apihub-root/external-volume/wallets/dsu-explorer/wallet-patch/seed",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "dsu-explorer_bind_to_dossier-explorer-ssapp",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd dossier-explorer-ssapp && npm run build"
+ },
+ {
+ "type": "copySeed",
+ "src": "./dossier-explorer-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/dsu-explorer/apps-patch/dossier-explorer-ssapp/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/dsu-explorer/apps-patch/dossier-explorer-ssapp/readme"
+ }
+ ]
+ }
+ ],
+ "epi-ssapps-and-wallets-build": [
+ {
+ "name": "cardinal-wallet-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd cardinal && npm run build-dossier"
+ }
+ ]
+ },
+ {
+ "name": "webcardinal-wallet-build",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd webcardinal && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "citrus-theme-wallet-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd themes/citrus-theme && npm run build-dossier"
+ }
+ ]
+ },
+ {
+ "name": "clear-sky-theme-wallet-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd themes/clear-sky-theme && npm run build-dossier"
+ }
+ ]
+ },
+ {
+ "name": "epi-theme-wallet-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd themes/epi-theme && npm run build-dossier"
+ }
+ ]
+ },
+ {
+ "name": "leaflet-wallet_bind_to_leaflet-ssapp",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd leaflet-ssapp && npm run build"
+ },
+ {
+ "type": "copySeed",
+ "src": "./leaflet-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copySeed",
+ "src": "./leaflet-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/leaflet-wallet/wallet-patch/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/readme"
+ }
+ ]
+ },
+ {
+ "name": "demiurge-wallet_bind_to_demiurge",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd demiurge && npm run build"
+ },
+ {
+ "type": "copySeed",
+ "src": "./demiurge/seed",
+ "target": "./apihub-root/external-volume/wallets/demiurge-wallet/apps-patch/demiurge/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copySeed",
+ "src": "./demiurge/seed",
+ "target": "./apihub-root/external-volume/wallets/demiurge-wallet/wallet-patch/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/demiurge-wallet/apps-patch/demiurge/readme"
+ }
+ ]
+ },
+ {
+ "name": "dsu-fabric-wallet_bind_to_dsu-fabric-ssapp",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd dsu-fabric-ssapp && npm run build"
+ },
+ {
+ "type": "copySeed",
+ "src": "./dsu-fabric-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/dsu-fabric-wallet/apps-patch/dsu-fabric-ssapp/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copySeed",
+ "src": "./dsu-fabric-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/dsu-fabric-wallet/wallet-patch/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "echo Use this folder template in order to customize the application instance by adding configuration, pages etc. > ./apihub-root/external-volume/wallets/dsu-fabric-wallet/apps-patch/dsu-fabric-ssapp/readme"
+ }
+ ]
+ }
+ ],
+ "ssapps-and-wallets-build": [
+ {
+ "name": "gtin-resolver-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd gtin-resolver && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "dfm-reporting",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "dfm-native-integration-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd acdc/native-integration && npm run build",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "./acdc/native-integration/build/bundles/default/camera.js",
+ "target": "./apihub-root/leaflet-wallet/loader/camera.js",
+ "options": {
+ "overwrite": true,
+ "ignoreErrors": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "epi-ssapps-and-wallets-build",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js epi-ssapps-and-wallets-build\""
+ }
+ ]
+ }
+ ],
+ "build": [
+ {
+ "name": "build-all",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js ssapps-and-wallets-build\""
+ },
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js dsu-explorer-build\""
+ },
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js postbuild\""
+ }
+ ]
+ }
+ ],
+ "postbuild": [
+ {
+ "name": "patching trust loaders configs",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js postinstall\""
+ }
+ ]
+ },
+ {
+ "name": "leaflet-wallet-loader-build",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd apihub-root/leaflet-wallet/loader && npm run build"
+ }
+ ]
+ }
+ ],
+ "install-mobile": [
+ {
+ "name": "mobile/scan-app/android",
+ "src": "https://github.com/PrivateSky/android-edge-agent",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && npm install"
+ }
+ ]
+ },
+ {
+ "name": "mobile/scan-app/ios",
+ "src": "https://github.com/PharmaLedger-IMI/ios-edge-agent",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/ios/PSKNodeServer && carthage bootstrap"
+ },
+ {
+ "type": "execute",
+ "cmd": "echo \"Continue with ipa builds\""
+ }
+ ]
+ }
+ ],
+ "build-android-apk": [
+ {
+ "name": "install NDK",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && gradlew.bat -b ndk.gradle installNDK",
+ "os": "win32",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && ./gradlew -b ndk.gradle installNDK",
+ "os": "linux",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && ./gradlew -b ndk.gradle installNDK",
+ "os": "darwin",
+ "options": {
+ "ignoreErrors": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "build APK",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && gradlew.bat assembleRelease",
+ "os": "win32",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && ./gradlew assembleRelease",
+ "os": "linux",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "cd mobile/scan-app/android && ./gradlew assembleRelease",
+ "os": "darwin",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "echo \"APK should be in mobile/scan-app/android/app/build/outputs/apk/release\" "
+ }
+ ]
+ }
+ ],
+ "prepare-build-mobile": [
+ {
+ "name": "prebuild",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "npm run clean"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd webcardinal && npm run build"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm run build"
+ },
+ {
+ "type": "copy",
+ "src": "./reporting-service/build/bundles/acdc.js",
+ "target": "./leaflet-ssapp/code/scripts/bundles/acdc.js",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/native-integration && npm run build",
+ "options": {
+ "ignoreErrors": true
+ }
+ }
+ ]
+ }
+ ],
+ "build-ssapps-and-configure-apihub-mobile": [
+ {
+ "name": "prebuild",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "npm run build leaflet-ssapp"
+ },
+ {
+ "type": "copySeed",
+ "src": "./leaflet-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/leaflet-wallet/apps-patch/leaflet-ssapp/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copySeed",
+ "src": "./leaflet-ssapp/seed",
+ "target": "./apihub-root/external-volume/wallets/leaflet-wallet/wallet-patch/seed",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "./trust-loader-config",
+ "target": "./apihub-root",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ }
+ ],
+ "build-mobile": [
+ {
+ "name": "prepare-phase",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js prepare-build-mobile\""
+ },
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js build-ssapps-and-configure-apihub-mobile\""
+ }
+ ]
+ },
+ {
+ "name": "prepare-phase",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patching-mobile\""
+ }
+ ]
+ }
+ ],
+ "patching-mobile": [
+ {
+ "name": "build-android-app",
+ "actions": [
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project"
+ },
+ {
+ "type": "copy",
+ "src": "bin/MobileServerLauncher.js",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/MobileServerLauncher.js"
+ },
+ {
+ "type": "copy",
+ "src": "privatesky/psknode/bundles/pskWebServer.js",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/pskWebServer.js"
+ },
+ {
+ "type": "copy",
+ "src": "privatesky/psknode/bundles/nodeBoot.js",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/nodeBoot.js"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/internal-volume",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/internal-volume"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/external-volume",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/external-volume"
+ },
+ {
+ "type": "copy",
+ "src": "./acdc/native-integration/build/bundles/default/camera.js",
+ "target": "./apihub-root/leaflet-wallet/loader/camera.js",
+ "options": {
+ "overwrite": true,
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/leaflet-wallet",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app"
+ },
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app/loader/node_modules"
+ },
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/android/app/src/main/assets/nodejs-project/apihub-root/app/loader/.git"
+ },
+ {
+ "type": "copy",
+ "src": "mobile/config/scan-app/android",
+ "target": "mobile/scan-app/android",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "build-ios-app",
+ "actions": [
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject"
+ },
+ {
+ "type": "copy",
+ "src": "bin/MobileServerLauncher.js",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/MobileServerLauncher.js"
+ },
+ {
+ "type": "copy",
+ "src": "privatesky/psknode/bundles/pskWebServer.js",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/pskWebServer.js"
+ },
+ {
+ "type": "copy",
+ "src": "privatesky/psknode/bundles/nodeBoot.js",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/nodeBoot.js"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/internal-volume",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/internal-volume"
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/external-volume",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/external-volume"
+ },
+ {
+ "type": "copy",
+ "src": "./acdc/native-integration/build/bundles/ios/camera.js",
+ "target": "./apihub-root/leaflet-wallet/loader/camera.js",
+ "options": {
+ "overwrite": true,
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "apihub-root/leaflet-wallet",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app"
+ },
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app/loader/node_modules"
+ },
+ {
+ "type": "remove",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/app/loader/.git"
+ },
+ {
+ "type": "copy",
+ "src": "mobile/config/scan-app/ios",
+ "target": "mobile/scan-app/ios",
+ "options": {
+ "overwrite": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "mobile/scan-app/ios/nativeBridge.js",
+ "target": "mobile/scan-app/ios/PSKNodeServer/PSKNodeServer/nodejsProject/apihub-root/nativeBridge.js",
+ "options": {
+ "overwrite": true
+ }
+ }
+ ]
+ }
+ ],
+ "install-acf-ssapps": [
+ {
+ "name": "delayv-auth-feat-ssapp",
+ "src": "https://github.com/asaccool/acdc-authentication-feature-59k3",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd delayv-auth-feat-ssapp && npm install"
+ }
+ ]
+ },
+ {
+ "name": "acdc-authentication-feature-template",
+ "src": "https://github.com/PharmaLedger-IMI/acdc-authentication-feature-template",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc-authentication-feature-template && npm install"
+ }
+ ]
+ },
+ {
+ "name": "truemedhemo-auth-feat-ssapp",
+ "src": "https://github.com/resilient-research-development/acdc-authentication-feature-template",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd truemedhemo-auth-feat-ssapp && npm install"
+ }
+ ]
+ }
+ ],
+ "install-dfm": [
+ {
+ "name": "acdc",
+ "src": "https://github.com/PharmaLedger-IMI/acdc-components.git",
+ "actions": [
+ {
+ "type": "smartClone",
+ "target": ".",
+ "collectLog": false
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/backoffice-backend && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/backoffice-frontend && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/reporting-service && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/native-integration && npm install"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd acdc/pdm-web-components && npm install"
+ }
+ ]
+ },
+ {
+ "name": "dfm-reporting",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm run build"
+ }
+ ]
+ }
+ ],
+ "build-dfm": [
+ {
+ "name": "dfm-reporting",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd reporting-service && npm run build"
+ }
+ ]
+ },
+ {
+ "name": "dfm-native-integration-build",
+ "src": "",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd acdc/native-integration && npm run build",
+ "options": {
+ "ignoreErrors": true
+ }
+ },
+ {
+ "type": "copy",
+ "src": "./acdc/native-integration/build/bundles/default/camera.js",
+ "target": "./apihub-root/leaflet-wallet/loader/camera.js",
+ "options": {
+ "overwrite": true,
+ "ignoreErrors": true
+ }
+ }
+ ]
+ },
+ {
+ "name": "build-pdm-web-components",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "cd acdc/pdm-web-components && npm run ionic:build"
+ }
+ ]
+ }
+ ],
+ "build-acf-ssapps": [
+ {
+ "name": "build-dfm",
+ "actions": [
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js build-dfm\""
+ },
+ {
+ "type": "execute",
+ "cmd": "cd delayv-auth-feat-ssapp && npm run build"
+ },
+ {
+ "type": "execute",
+ "cmd": "cd truemedhemo-auth-feat-ssapp && npm run build"
+ },
+ {
+ "type": "execute",
+ "cmd": "node ./node_modules/octopus/scripts/setEnv --file=../../../env.json \"node ./bin/octopusRun.js patching-mobile\""
+ }
+ ]
+ }
+ ]
}