├── .eslintrc.json ├── .github └── workflows │ └── lint-test.yml ├── .gitignore ├── README.md ├── example.js ├── index.js ├── lib ├── findTicket.js ├── parse.js ├── queryTicket.js └── requestBackend.js ├── package-lock.json ├── package.json └── test ├── index.js ├── ticket-456800002504-2023-07-10-erika-musterfrau.json └── ticket-XXXXXX-2023-05-12-erika-musterman.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parserOptions": { 8 | "ecmaVersion": "latest", 9 | "sourceType": "module" 10 | }, 11 | "rules": { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/lint-test.yml: -------------------------------------------------------------------------------- 1 | name: lint & test 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | lint-test: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | node-version: ['16', '18', '20'] 17 | 18 | steps: 19 | - name: checkout 20 | uses: actions/checkout@v4 21 | - name: setup Node v${{ matrix.node-version }} 22 | uses: actions/setup-node@v3 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | - run: npm install 26 | 27 | - run: npm run lint 28 | - run: npm test 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | 76 | # parcel-bundler cache (https://parceljs.org/) 77 | .cache 78 | 79 | # Next.js build output 80 | .next 81 | 82 | # Nuxt.js build / generate output 83 | .nuxt 84 | dist 85 | 86 | # Gatsby files 87 | .cache/ 88 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 89 | # https://nextjs.org/blog/next-9-1#public-directory-support 90 | # public 91 | 92 | # vuepress build output 93 | .vuepress/dist 94 | 95 | # Serverless directories 96 | .serverless/ 97 | 98 | # FuseBox cache 99 | .fusebox/ 100 | 101 | # DynamoDB Local files 102 | .dynamodb/ 103 | 104 | # TernJS port file 105 | .tern-port 106 | 107 | # Editor directories and files 108 | .idea 109 | .vscode 110 | *.suo 111 | *.ntvs* 112 | *.njsproj 113 | *.sln 114 | *.sw? 115 | *.sublime-project 116 | *.sublime-workspace 117 | yarn.lock 118 | jsconfig.json 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # db-tickets 2 | A library to retrieve ticket information from Deutsche Bahn by providing ticket number and last name. 3 | 4 | ## How to use 5 | 6 | ```sh 7 | npm install db-tickets 8 | ``` 9 | 10 | ```js 11 | import queryTicket from 'db-tickets' 12 | queryTicket('W7KHTA', 'Mustermann').then((response) => console.log(response)) 13 | ``` 14 | 15 | ```json 16 | { 17 | "order": { 18 | "ticketNumber": "W7KHTA", 19 | "bookingDate": "2023-01-21T12:30:03", 20 | "validFrom": "2023-01-21T00:00:00", 21 | "validUntil": "2023-01-21T23:59:59", 22 | "journeyStart": "2023-01-21T12:40:00", 23 | "firstName": "Max", 24 | "lastName": "Mustermann", 25 | "text": "Einfache Fahrt, Regio120 Ticket, 2. Kl., 1 Erw., Jena/Leipzig#", 26 | "class": "S2" 27 | }, 28 | "journey": { 29 | "type": "journey", 30 | "id": "51451984", 31 | "legs": [ 32 | { 33 | "origin": { 34 | "type": "station", 35 | "id": "8011956", 36 | "name": "Jena Paradies", 37 | "location": { 38 | "type": "location", 39 | "longitude": 11.587464, 40 | "latitude": 50.924853 41 | } 42 | }, 43 | "destination": { 44 | "type": "station", 45 | "id": "8010205", 46 | "name": "Leipzig Hbf", 47 | "location": { 48 | "type": "location", 49 | "longitude": 12.382066, 50 | "latitude": 51.345467 51 | } 52 | }, 53 | "line": { 54 | "type": "line", 55 | "id": "C0-0.0", 56 | "name": "RE 4986", 57 | "mode": "train" 58 | }, 59 | "departure": "2023-01-21T12:40:00+01:00", 60 | "departurePlatform": "2", 61 | "arrival": "2023-01-21T13:52:00+01:00", 62 | "arrivalPlatform": "9", 63 | "mode": "train", 64 | "public": true 65 | } 66 | ], 67 | "price": { 68 | "amount": "18.60", 69 | "currency": "EUR" 70 | } 71 | } 72 | } 73 | ``` 74 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | import queryTicket from './index.js' 2 | import util from 'util' 3 | 4 | // request data with ticket number and lastname 5 | const ticketNumber = process.env.TICKET_NR || 'XXXXXX' 6 | const lastname = process.env.LAST_NAME || 'Mustermann' 7 | 8 | const data = await queryTicket(ticketNumber, lastname) 9 | // console.log(util.inspect(data, false, null)) 10 | console.log(JSON.stringify(data)) 11 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * db-tickets 3 | * ISC Licensed 4 | */ 5 | 6 | import {queryTicket as rqorderdetails} from './lib/queryTicket.js' 7 | import findTicket from './lib/findTicket.js' 8 | 9 | /** 10 | * queryTicket function, returns the ticket data based on the ticket number and last name. handles both old and new ticket system 11 | * @param string | DB ticket number (ticket number up 12 digits or 6 characters) 12 | * @param lastName | last name of purchaser 13 | * @return Promise | fulfills with an object that contains the ticket data 14 | */ 15 | const queryTicket = async (ticketNumber, lastName) => { 16 | //create a null kwid variable 17 | let kwid = null 18 | if (ticketNumber.length > 5) { 19 | const order = await findTicket(ticketNumber, lastName) 20 | //extract the kwid from the order object 21 | kwid = order.kwid 22 | } 23 | const ticketData = await rqorderdetails(ticketNumber, lastName, kwid) 24 | return ticketData 25 | } 26 | 27 | 28 | export default queryTicket 29 | -------------------------------------------------------------------------------- /lib/findTicket.js: -------------------------------------------------------------------------------- 1 | import { requestBackend } from './requestBackend.js' 2 | /** 3 | * findTicket function 4 | * @param string | DB ticket number (Auftragsnummer 12 digits) 5 | * @param lastName | last name of purchaser 6 | * @return Promise | fulfills with an object that contains the ticket data 7 | */ 8 | export const findTicket = async (ticketNumber, lastName) => { 9 | //make a request to the endpoint with the following body: 10 | // 11 | const reqBody = '' 12 | + '' 13 | + '' 14 | return requestBackend(reqBody).then(json => { 15 | const data = json.rporderheadlist 16 | 17 | const _order = data['orderheadlist'][0]['orderhead'][0]['$'] 18 | return _order}) 19 | } 20 | 21 | 22 | export default findTicket -------------------------------------------------------------------------------- /lib/parse.js: -------------------------------------------------------------------------------- 1 | const modeCodes = { 2 | T: 'train' 3 | // todo: letters for other modes 4 | } 5 | 6 | const date = (_date) => { 7 | // merge date fields 8 | let date = new Date(_date['dt'].slice(0, 10)) 9 | const t = _date['t'].split(':') 10 | date.setHours(t[0], t[1]) 11 | 12 | // convert to extended ISO 8601 with timezone 13 | const tzOffset = -date.getTimezoneOffset() 14 | const diff = tzOffset >= 0 ? '+' : '-' 15 | const pad = n => `${Math.floor(Math.abs(n))}`.padStart(2, '0') 16 | return date.getFullYear() + 17 | '-' + pad(date.getMonth() + 1) + 18 | '-' + pad(date.getDate()) + 19 | 'T' + pad(date.getHours()) + 20 | ':' + pad(date.getMinutes()) + 21 | ':' + pad(date.getSeconds()) + 22 | diff + pad(tzOffset / 60) + 23 | ':' + pad(tzOffset % 60) 24 | } 25 | 26 | const coordinate = (_coordinate) => { 27 | return parseFloat(_coordinate.slice(0,2) + '.' + _coordinate.slice(2)) 28 | } 29 | 30 | // follows FPTF Line, https://github.com/public-transport/friendly-public-transport-format/blob/master/spec/readme.md#line 31 | const line = (_train) => { 32 | return { 33 | type: 'line', // required 34 | id: _train['$']['tid'], // unique, required 35 | name: _train['$']['tn'], // official non-abbreviated name, required 36 | mode: modeCodes[_train['$']['type']], // see section on modes, required 37 | 38 | // seems like stops are not part of the data 39 | // routes: [], // array of route ids or route objects 40 | 41 | // operator: '123456', // operator id or operator object 42 | } 43 | } 44 | 45 | // follows FPTF Station, https://github.com/public-transport/friendly-public-transport-format/blob/master/spec/readme.md#station 46 | const station = (_station) => { 47 | 48 | // the longitudes and latitudes are optional in _station 49 | // if they are not present, the longitude and longitude should not be included in the locaton object 50 | let location = {} 51 | if (('x' in _station) && ('y' in _station)) { 52 | location = { 53 | type: 'location', 54 | longitude: coordinate(_station['x'][0]), 55 | latitude: coordinate(_station['y'][0]) 56 | } 57 | } else { 58 | location = { 59 | type: 'location', 60 | } 61 | } 62 | 63 | 64 | return { 65 | type: 'station', 66 | id: _station['nr'][0], 67 | name: _station['n'][0], 68 | location: location 69 | } 70 | } 71 | 72 | // follows 'legs' in FPTF Journey, https://github.com/public-transport/friendly-public-transport-format/blob/master/spec/readme.md#journey 73 | const parseLegs = (_trainList) => { 74 | 75 | let legs = [] 76 | 77 | for (let i in _trainList) { 78 | legs.push({ 79 | 80 | origin: station(_trainList[i]['dep'][0]), 81 | 82 | destination: station(_trainList[i]['arr'][0]), 83 | 84 | line: line(_trainList[i]), 85 | 86 | departure: date(_trainList[i]['dep'][0]['$']), 87 | 88 | ...('ptf' in _trainList[i]['dep'][0]) && { departurePlatform: _trainList[i]['dep'][0]['ptf'][0] }, 89 | 90 | arrival: date(_trainList[i]['arr'][0]['$']), 91 | 92 | ...('ptf' in _trainList[i]['arr'][0]) && { arrivalPlatform: _trainList[i]['arr'][0]['ptf'][0] }, 93 | 94 | mode: modeCodes[_trainList[i]['$']['type']], 95 | 96 | public: true, 97 | 98 | // operator: '', 99 | }) 100 | } 101 | 102 | return legs 103 | } 104 | 105 | // takes the base64 encoded httext field and extracts the ticket price 106 | const price = (_httext) => { 107 | let c = atob(_httext.replace(/\r?\n|\r/g, "")) 108 | 109 | let price=null; 110 | price = c.match(/Gesamtpreis:\s*\d{0,2},\d{0,2}\s*EUR/g) 111 | //when Gesamtpreis is not found search again but with html tags, because thats what the new ticket layout gives in the new systems 112 | if (!price) { 113 | const regexPrice = /Gesamtpreis: <\/span>([\d,]+,\d{2})<\/span>/; 114 | const matchPrice = c.match(regexPrice); 115 | if (matchPrice && matchPrice[1]) { 116 | price = matchPrice[1]; 117 | } 118 | }else{ 119 | price=price[0]; 120 | } 121 | price = price.match(/\d{0,2},\d{0,2}/g) 122 | price = price[0].replace(',', '.') 123 | 124 | return parseFloat(price).toPrecision(4) 125 | } 126 | 127 | export { parseLegs, price } 128 | -------------------------------------------------------------------------------- /lib/queryTicket.js: -------------------------------------------------------------------------------- 1 | import { parseLegs, price } from './parse.js' 2 | import requestBackend from './requestBackend.js'; 3 | 4 | /** 5 | * parseTicket 6 | * 7 | * @param string | ticket API response body, JSON-decoded 8 | * @return object | the ticket data 9 | */ 10 | const parseTicket = (json) => { 11 | const data = json.rporderdetails 12 | 13 | // selectors 14 | const _order = data['order'][0]['$'] 15 | const _tck = data['order'][0]['tcklist']?.[0]['tck'][0] 16 | const _ticket = _tck?.['mtk'][0] 17 | let _encoded_price = _tck['htdata'][0]['ht'][0]['_'] 18 | //if _tck['htdata'][0]['ht'][0]['_'] starts with data:image/png;base64, then it is a old ticket, we need to check for that 19 | if(_encoded_price.startsWith('data:image/png;base64,')){ 20 | _encoded_price = _tck['htdata'][0]['ht'][1]['_'] // revert back to the old price format 21 | } 22 | 23 | const _price = _tck ? { 24 | amount: price(_encoded_price), 25 | currency: 'EUR' 26 | }: undefined 27 | 28 | return { 29 | // doesn't follow a standard by now and just dumps some info 30 | order: { 31 | ticketNumber: _order['on'], 32 | bookingDate: _order['cdt'], 33 | validFrom: _order['vfrom'], 34 | validUntil: _order['vto'], 35 | journeyStart: _order['sdt'], 36 | firstName: _ticket?.['reisender_vorname'][0], 37 | lastName: _ticket?.['reisender_nachname'][0], 38 | text: _ticket?.['txt'][0], 39 | class: _ticket?.['nvplist'][0]['nvp'][3]['_'] // could be wrong 40 | }, 41 | 42 | // follows FPTF Journey, https://github.com/public-transport/friendly-public-transport-format/blob/master/spec/readme.md#journey 43 | journey: { 44 | type: 'journey', 45 | id: _order['cid'], // unique, required, use cid as id here? 46 | legs: parseLegs(data['order'][0]['schedulelist'][0]['out'][0]['trainlist'][0]['train']), 47 | price: _price 48 | }, 49 | 50 | ...(data['order'][0]['schedulelist'][0]['ret'] && { returnJourney: { 51 | type: 'journey', 52 | id: _order['cid'], // unique, required, ! same as outward journey? 53 | legs: parseLegs(data['order'][0]['schedulelist'][0]['ret'][0]['trainlist'][0]['train']), 54 | price: _price 55 | }}) 56 | } 57 | } 58 | 59 | /** 60 | * queryTicket function 61 | * 62 | * @param string | DB ticket number (Auftragsnummer) 63 | * @param lastName | last name of purchaser 64 | * @param kwid | kwid of the ticket (only needed for tickets from the new system) 65 | * @return Promise | fulfills with an object that contains the ticket data 66 | */ 67 | const queryTicket = async (ticketNumber, lastName,kwid=null) => { 68 | 69 | let reqBody = ` ` 70 | 71 | return await requestBackend(reqBody) 72 | .then(json => { 73 | return parseTicket(json) 74 | }) 75 | } 76 | 77 | export { 78 | parseTicket, 79 | queryTicket, 80 | } 81 | -------------------------------------------------------------------------------- /lib/requestBackend.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | import { parseString } from 'xml2js' 3 | 4 | const endpoint = 'https://fahrkarten.bahn.de/mobile/dbc/xs.go?' 5 | 6 | /** 7 | * requestBackend function, that is used to make a request to the backend 8 | * @param string | body of the request 9 | * @return Promise | fulfills with an object that contains the data from the request 10 | */ 11 | export const requestBackend = async (reqBody) => { 12 | return fetch(endpoint, { 13 | method: 'POST', 14 | headers: { 15 | 'User-Agent': 'github.com/public-transport/db-tickets', 16 | 'Accept-Language': 'de-DE,de;q=0.9' 17 | }, 18 | body: reqBody 19 | }).then(response => { 20 | if (!response.ok) { 21 | const err = new HTTPResponseError(response) 22 | err.url = endpoint 23 | err.requestBody = reqBody 24 | throw err 25 | } 26 | return response.text() 27 | }).then(body => { 28 | return new Promise((resolve, reject) => parseString(body, (err, result) => { 29 | if (err) { 30 | reject(err) 31 | } 32 | else { 33 | resolve(result) 34 | } 35 | })) 36 | }).then(json => { 37 | if (json['rperror']) { 38 | throw new XMLRPCError(json['rperror']['error']) 39 | } 40 | return json 41 | }) 42 | } 43 | class HTTPResponseError extends Error { 44 | constructor(response, ...args) { 45 | super(`HTTP Error Response: ${response.status} ${response.statusText}`, ...args) 46 | this.response = response 47 | } 48 | } 49 | 50 | class XMLRPCError extends Error { 51 | constructor(response, ...args) { 52 | super(`XML Error Response: 53 | ${response[0]['$']['nr']} 54 | ${response[0]['txt'][0]}`, ...args) 55 | this.response = response 56 | } 57 | } 58 | export default requestBackend -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "db-tickets", 3 | "version": "1.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "db-tickets", 9 | "version": "1.1.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "node-fetch": "^3.2.8", 13 | "xml2js": "^0.6.2" 14 | }, 15 | "devDependencies": { 16 | "eslint": "^8.20.0" 17 | }, 18 | "engines": { 19 | "node": ">=16" 20 | } 21 | }, 22 | "node_modules/@aashutoshrathi/word-wrap": { 23 | "version": "1.2.6", 24 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", 25 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", 26 | "dev": true, 27 | "engines": { 28 | "node": ">=0.10.0" 29 | } 30 | }, 31 | "node_modules/@eslint-community/eslint-utils": { 32 | "version": "4.4.0", 33 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 34 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 35 | "dev": true, 36 | "dependencies": { 37 | "eslint-visitor-keys": "^3.3.0" 38 | }, 39 | "engines": { 40 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 41 | }, 42 | "peerDependencies": { 43 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 44 | } 45 | }, 46 | "node_modules/@eslint-community/regexpp": { 47 | "version": "4.8.0", 48 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", 49 | "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", 50 | "dev": true, 51 | "engines": { 52 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 53 | } 54 | }, 55 | "node_modules/@eslint/eslintrc": { 56 | "version": "2.1.2", 57 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", 58 | "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", 59 | "dev": true, 60 | "dependencies": { 61 | "ajv": "^6.12.4", 62 | "debug": "^4.3.2", 63 | "espree": "^9.6.0", 64 | "globals": "^13.19.0", 65 | "ignore": "^5.2.0", 66 | "import-fresh": "^3.2.1", 67 | "js-yaml": "^4.1.0", 68 | "minimatch": "^3.1.2", 69 | "strip-json-comments": "^3.1.1" 70 | }, 71 | "engines": { 72 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 73 | }, 74 | "funding": { 75 | "url": "https://opencollective.com/eslint" 76 | } 77 | }, 78 | "node_modules/@eslint/js": { 79 | "version": "8.49.0", 80 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", 81 | "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", 82 | "dev": true, 83 | "engines": { 84 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 85 | } 86 | }, 87 | "node_modules/@humanwhocodes/config-array": { 88 | "version": "0.11.11", 89 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", 90 | "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", 91 | "dev": true, 92 | "dependencies": { 93 | "@humanwhocodes/object-schema": "^1.2.1", 94 | "debug": "^4.1.1", 95 | "minimatch": "^3.0.5" 96 | }, 97 | "engines": { 98 | "node": ">=10.10.0" 99 | } 100 | }, 101 | "node_modules/@humanwhocodes/module-importer": { 102 | "version": "1.0.1", 103 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 104 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 105 | "dev": true, 106 | "engines": { 107 | "node": ">=12.22" 108 | }, 109 | "funding": { 110 | "type": "github", 111 | "url": "https://github.com/sponsors/nzakas" 112 | } 113 | }, 114 | "node_modules/@humanwhocodes/object-schema": { 115 | "version": "1.2.1", 116 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 117 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 118 | "dev": true 119 | }, 120 | "node_modules/@nodelib/fs.scandir": { 121 | "version": "2.1.5", 122 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 123 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 124 | "dev": true, 125 | "dependencies": { 126 | "@nodelib/fs.stat": "2.0.5", 127 | "run-parallel": "^1.1.9" 128 | }, 129 | "engines": { 130 | "node": ">= 8" 131 | } 132 | }, 133 | "node_modules/@nodelib/fs.stat": { 134 | "version": "2.0.5", 135 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 136 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 137 | "dev": true, 138 | "engines": { 139 | "node": ">= 8" 140 | } 141 | }, 142 | "node_modules/@nodelib/fs.walk": { 143 | "version": "1.2.8", 144 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 145 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 146 | "dev": true, 147 | "dependencies": { 148 | "@nodelib/fs.scandir": "2.1.5", 149 | "fastq": "^1.6.0" 150 | }, 151 | "engines": { 152 | "node": ">= 8" 153 | } 154 | }, 155 | "node_modules/acorn": { 156 | "version": "8.10.0", 157 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", 158 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", 159 | "dev": true, 160 | "bin": { 161 | "acorn": "bin/acorn" 162 | }, 163 | "engines": { 164 | "node": ">=0.4.0" 165 | } 166 | }, 167 | "node_modules/acorn-jsx": { 168 | "version": "5.3.2", 169 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 170 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 171 | "dev": true, 172 | "peerDependencies": { 173 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 174 | } 175 | }, 176 | "node_modules/ajv": { 177 | "version": "6.12.6", 178 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 179 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 180 | "dev": true, 181 | "dependencies": { 182 | "fast-deep-equal": "^3.1.1", 183 | "fast-json-stable-stringify": "^2.0.0", 184 | "json-schema-traverse": "^0.4.1", 185 | "uri-js": "^4.2.2" 186 | }, 187 | "funding": { 188 | "type": "github", 189 | "url": "https://github.com/sponsors/epoberezkin" 190 | } 191 | }, 192 | "node_modules/ansi-regex": { 193 | "version": "5.0.1", 194 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 195 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 196 | "dev": true, 197 | "engines": { 198 | "node": ">=8" 199 | } 200 | }, 201 | "node_modules/ansi-styles": { 202 | "version": "4.3.0", 203 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 204 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 205 | "dev": true, 206 | "dependencies": { 207 | "color-convert": "^2.0.1" 208 | }, 209 | "engines": { 210 | "node": ">=8" 211 | }, 212 | "funding": { 213 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 214 | } 215 | }, 216 | "node_modules/argparse": { 217 | "version": "2.0.1", 218 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 219 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 220 | "dev": true 221 | }, 222 | "node_modules/balanced-match": { 223 | "version": "1.0.2", 224 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 225 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 226 | "dev": true 227 | }, 228 | "node_modules/brace-expansion": { 229 | "version": "1.1.11", 230 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 231 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 232 | "dev": true, 233 | "dependencies": { 234 | "balanced-match": "^1.0.0", 235 | "concat-map": "0.0.1" 236 | } 237 | }, 238 | "node_modules/callsites": { 239 | "version": "3.1.0", 240 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 241 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 242 | "dev": true, 243 | "engines": { 244 | "node": ">=6" 245 | } 246 | }, 247 | "node_modules/chalk": { 248 | "version": "4.1.2", 249 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 250 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 251 | "dev": true, 252 | "dependencies": { 253 | "ansi-styles": "^4.1.0", 254 | "supports-color": "^7.1.0" 255 | }, 256 | "engines": { 257 | "node": ">=10" 258 | }, 259 | "funding": { 260 | "url": "https://github.com/chalk/chalk?sponsor=1" 261 | } 262 | }, 263 | "node_modules/color-convert": { 264 | "version": "2.0.1", 265 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 266 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 267 | "dev": true, 268 | "dependencies": { 269 | "color-name": "~1.1.4" 270 | }, 271 | "engines": { 272 | "node": ">=7.0.0" 273 | } 274 | }, 275 | "node_modules/color-name": { 276 | "version": "1.1.4", 277 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 278 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 279 | "dev": true 280 | }, 281 | "node_modules/concat-map": { 282 | "version": "0.0.1", 283 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 284 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 285 | "dev": true 286 | }, 287 | "node_modules/cross-spawn": { 288 | "version": "7.0.3", 289 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 290 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 291 | "dev": true, 292 | "dependencies": { 293 | "path-key": "^3.1.0", 294 | "shebang-command": "^2.0.0", 295 | "which": "^2.0.1" 296 | }, 297 | "engines": { 298 | "node": ">= 8" 299 | } 300 | }, 301 | "node_modules/data-uri-to-buffer": { 302 | "version": "4.0.1", 303 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", 304 | "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", 305 | "engines": { 306 | "node": ">= 12" 307 | } 308 | }, 309 | "node_modules/debug": { 310 | "version": "4.3.4", 311 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 312 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 313 | "dev": true, 314 | "dependencies": { 315 | "ms": "2.1.2" 316 | }, 317 | "engines": { 318 | "node": ">=6.0" 319 | }, 320 | "peerDependenciesMeta": { 321 | "supports-color": { 322 | "optional": true 323 | } 324 | } 325 | }, 326 | "node_modules/deep-is": { 327 | "version": "0.1.4", 328 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 329 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 330 | "dev": true 331 | }, 332 | "node_modules/doctrine": { 333 | "version": "3.0.0", 334 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 335 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 336 | "dev": true, 337 | "dependencies": { 338 | "esutils": "^2.0.2" 339 | }, 340 | "engines": { 341 | "node": ">=6.0.0" 342 | } 343 | }, 344 | "node_modules/escape-string-regexp": { 345 | "version": "4.0.0", 346 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 347 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 348 | "dev": true, 349 | "engines": { 350 | "node": ">=10" 351 | }, 352 | "funding": { 353 | "url": "https://github.com/sponsors/sindresorhus" 354 | } 355 | }, 356 | "node_modules/eslint": { 357 | "version": "8.49.0", 358 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", 359 | "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", 360 | "dev": true, 361 | "dependencies": { 362 | "@eslint-community/eslint-utils": "^4.2.0", 363 | "@eslint-community/regexpp": "^4.6.1", 364 | "@eslint/eslintrc": "^2.1.2", 365 | "@eslint/js": "8.49.0", 366 | "@humanwhocodes/config-array": "^0.11.11", 367 | "@humanwhocodes/module-importer": "^1.0.1", 368 | "@nodelib/fs.walk": "^1.2.8", 369 | "ajv": "^6.12.4", 370 | "chalk": "^4.0.0", 371 | "cross-spawn": "^7.0.2", 372 | "debug": "^4.3.2", 373 | "doctrine": "^3.0.0", 374 | "escape-string-regexp": "^4.0.0", 375 | "eslint-scope": "^7.2.2", 376 | "eslint-visitor-keys": "^3.4.3", 377 | "espree": "^9.6.1", 378 | "esquery": "^1.4.2", 379 | "esutils": "^2.0.2", 380 | "fast-deep-equal": "^3.1.3", 381 | "file-entry-cache": "^6.0.1", 382 | "find-up": "^5.0.0", 383 | "glob-parent": "^6.0.2", 384 | "globals": "^13.19.0", 385 | "graphemer": "^1.4.0", 386 | "ignore": "^5.2.0", 387 | "imurmurhash": "^0.1.4", 388 | "is-glob": "^4.0.0", 389 | "is-path-inside": "^3.0.3", 390 | "js-yaml": "^4.1.0", 391 | "json-stable-stringify-without-jsonify": "^1.0.1", 392 | "levn": "^0.4.1", 393 | "lodash.merge": "^4.6.2", 394 | "minimatch": "^3.1.2", 395 | "natural-compare": "^1.4.0", 396 | "optionator": "^0.9.3", 397 | "strip-ansi": "^6.0.1", 398 | "text-table": "^0.2.0" 399 | }, 400 | "bin": { 401 | "eslint": "bin/eslint.js" 402 | }, 403 | "engines": { 404 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 405 | }, 406 | "funding": { 407 | "url": "https://opencollective.com/eslint" 408 | } 409 | }, 410 | "node_modules/eslint-scope": { 411 | "version": "7.2.2", 412 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 413 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 414 | "dev": true, 415 | "dependencies": { 416 | "esrecurse": "^4.3.0", 417 | "estraverse": "^5.2.0" 418 | }, 419 | "engines": { 420 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 421 | }, 422 | "funding": { 423 | "url": "https://opencollective.com/eslint" 424 | } 425 | }, 426 | "node_modules/eslint-visitor-keys": { 427 | "version": "3.4.3", 428 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 429 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 430 | "dev": true, 431 | "engines": { 432 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 433 | }, 434 | "funding": { 435 | "url": "https://opencollective.com/eslint" 436 | } 437 | }, 438 | "node_modules/espree": { 439 | "version": "9.6.1", 440 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 441 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 442 | "dev": true, 443 | "dependencies": { 444 | "acorn": "^8.9.0", 445 | "acorn-jsx": "^5.3.2", 446 | "eslint-visitor-keys": "^3.4.1" 447 | }, 448 | "engines": { 449 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 450 | }, 451 | "funding": { 452 | "url": "https://opencollective.com/eslint" 453 | } 454 | }, 455 | "node_modules/esquery": { 456 | "version": "1.5.0", 457 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 458 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 459 | "dev": true, 460 | "dependencies": { 461 | "estraverse": "^5.1.0" 462 | }, 463 | "engines": { 464 | "node": ">=0.10" 465 | } 466 | }, 467 | "node_modules/esrecurse": { 468 | "version": "4.3.0", 469 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 470 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 471 | "dev": true, 472 | "dependencies": { 473 | "estraverse": "^5.2.0" 474 | }, 475 | "engines": { 476 | "node": ">=4.0" 477 | } 478 | }, 479 | "node_modules/estraverse": { 480 | "version": "5.3.0", 481 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 482 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 483 | "dev": true, 484 | "engines": { 485 | "node": ">=4.0" 486 | } 487 | }, 488 | "node_modules/esutils": { 489 | "version": "2.0.3", 490 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 491 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 492 | "dev": true, 493 | "engines": { 494 | "node": ">=0.10.0" 495 | } 496 | }, 497 | "node_modules/fast-deep-equal": { 498 | "version": "3.1.3", 499 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 500 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 501 | "dev": true 502 | }, 503 | "node_modules/fast-json-stable-stringify": { 504 | "version": "2.1.0", 505 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 506 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 507 | "dev": true 508 | }, 509 | "node_modules/fast-levenshtein": { 510 | "version": "2.0.6", 511 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 512 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 513 | "dev": true 514 | }, 515 | "node_modules/fastq": { 516 | "version": "1.15.0", 517 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 518 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 519 | "dev": true, 520 | "dependencies": { 521 | "reusify": "^1.0.4" 522 | } 523 | }, 524 | "node_modules/fetch-blob": { 525 | "version": "3.2.0", 526 | "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", 527 | "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", 528 | "funding": [ 529 | { 530 | "type": "github", 531 | "url": "https://github.com/sponsors/jimmywarting" 532 | }, 533 | { 534 | "type": "paypal", 535 | "url": "https://paypal.me/jimmywarting" 536 | } 537 | ], 538 | "dependencies": { 539 | "node-domexception": "^1.0.0", 540 | "web-streams-polyfill": "^3.0.3" 541 | }, 542 | "engines": { 543 | "node": "^12.20 || >= 14.13" 544 | } 545 | }, 546 | "node_modules/file-entry-cache": { 547 | "version": "6.0.1", 548 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 549 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 550 | "dev": true, 551 | "dependencies": { 552 | "flat-cache": "^3.0.4" 553 | }, 554 | "engines": { 555 | "node": "^10.12.0 || >=12.0.0" 556 | } 557 | }, 558 | "node_modules/find-up": { 559 | "version": "5.0.0", 560 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 561 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 562 | "dev": true, 563 | "dependencies": { 564 | "locate-path": "^6.0.0", 565 | "path-exists": "^4.0.0" 566 | }, 567 | "engines": { 568 | "node": ">=10" 569 | }, 570 | "funding": { 571 | "url": "https://github.com/sponsors/sindresorhus" 572 | } 573 | }, 574 | "node_modules/flat-cache": { 575 | "version": "3.1.0", 576 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", 577 | "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", 578 | "dev": true, 579 | "dependencies": { 580 | "flatted": "^3.2.7", 581 | "keyv": "^4.5.3", 582 | "rimraf": "^3.0.2" 583 | }, 584 | "engines": { 585 | "node": ">=12.0.0" 586 | } 587 | }, 588 | "node_modules/flatted": { 589 | "version": "3.2.7", 590 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", 591 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", 592 | "dev": true 593 | }, 594 | "node_modules/formdata-polyfill": { 595 | "version": "4.0.10", 596 | "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", 597 | "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", 598 | "dependencies": { 599 | "fetch-blob": "^3.1.2" 600 | }, 601 | "engines": { 602 | "node": ">=12.20.0" 603 | } 604 | }, 605 | "node_modules/fs.realpath": { 606 | "version": "1.0.0", 607 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 608 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 609 | "dev": true 610 | }, 611 | "node_modules/glob": { 612 | "version": "7.2.3", 613 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 614 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 615 | "dev": true, 616 | "dependencies": { 617 | "fs.realpath": "^1.0.0", 618 | "inflight": "^1.0.4", 619 | "inherits": "2", 620 | "minimatch": "^3.1.1", 621 | "once": "^1.3.0", 622 | "path-is-absolute": "^1.0.0" 623 | }, 624 | "engines": { 625 | "node": "*" 626 | }, 627 | "funding": { 628 | "url": "https://github.com/sponsors/isaacs" 629 | } 630 | }, 631 | "node_modules/glob-parent": { 632 | "version": "6.0.2", 633 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 634 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 635 | "dev": true, 636 | "dependencies": { 637 | "is-glob": "^4.0.3" 638 | }, 639 | "engines": { 640 | "node": ">=10.13.0" 641 | } 642 | }, 643 | "node_modules/globals": { 644 | "version": "13.21.0", 645 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", 646 | "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", 647 | "dev": true, 648 | "dependencies": { 649 | "type-fest": "^0.20.2" 650 | }, 651 | "engines": { 652 | "node": ">=8" 653 | }, 654 | "funding": { 655 | "url": "https://github.com/sponsors/sindresorhus" 656 | } 657 | }, 658 | "node_modules/graphemer": { 659 | "version": "1.4.0", 660 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 661 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 662 | "dev": true 663 | }, 664 | "node_modules/has-flag": { 665 | "version": "4.0.0", 666 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 667 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 668 | "dev": true, 669 | "engines": { 670 | "node": ">=8" 671 | } 672 | }, 673 | "node_modules/ignore": { 674 | "version": "5.2.4", 675 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", 676 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", 677 | "dev": true, 678 | "engines": { 679 | "node": ">= 4" 680 | } 681 | }, 682 | "node_modules/import-fresh": { 683 | "version": "3.3.0", 684 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 685 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 686 | "dev": true, 687 | "dependencies": { 688 | "parent-module": "^1.0.0", 689 | "resolve-from": "^4.0.0" 690 | }, 691 | "engines": { 692 | "node": ">=6" 693 | }, 694 | "funding": { 695 | "url": "https://github.com/sponsors/sindresorhus" 696 | } 697 | }, 698 | "node_modules/imurmurhash": { 699 | "version": "0.1.4", 700 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 701 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 702 | "dev": true, 703 | "engines": { 704 | "node": ">=0.8.19" 705 | } 706 | }, 707 | "node_modules/inflight": { 708 | "version": "1.0.6", 709 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 710 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 711 | "dev": true, 712 | "dependencies": { 713 | "once": "^1.3.0", 714 | "wrappy": "1" 715 | } 716 | }, 717 | "node_modules/inherits": { 718 | "version": "2.0.4", 719 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 720 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 721 | "dev": true 722 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 723 | "dev": true 724 | }, 725 | "node_modules/is-extglob": { 726 | "version": "2.1.1", 727 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 728 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 729 | "dev": true, 730 | "engines": { 731 | "node": ">=0.10.0" 732 | } 733 | }, 734 | "node_modules/is-glob": { 735 | "version": "4.0.3", 736 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 737 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 738 | "dev": true, 739 | "dependencies": { 740 | "is-extglob": "^2.1.1" 741 | }, 742 | "engines": { 743 | "node": ">=0.10.0" 744 | } 745 | }, 746 | "node_modules/is-path-inside": { 747 | "version": "3.0.3", 748 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 749 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 750 | "dev": true, 751 | "engines": { 752 | "node": ">=8" 753 | } 754 | }, 755 | "node_modules/isexe": { 756 | "version": "2.0.0", 757 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 758 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 759 | "dev": true 760 | }, 761 | "node_modules/js-yaml": { 762 | "version": "4.1.0", 763 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 764 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 765 | "dev": true, 766 | "dependencies": { 767 | "argparse": "^2.0.1" 768 | }, 769 | "bin": { 770 | "js-yaml": "bin/js-yaml.js" 771 | } 772 | }, 773 | "node_modules/json-buffer": { 774 | "version": "3.0.1", 775 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 776 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 777 | "dev": true 778 | }, 779 | "node_modules/json-schema-traverse": { 780 | "version": "0.4.1", 781 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 782 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 783 | "dev": true 784 | }, 785 | "node_modules/json-stable-stringify-without-jsonify": { 786 | "version": "1.0.1", 787 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 788 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 789 | "dev": true 790 | }, 791 | "node_modules/keyv": { 792 | "version": "4.5.3", 793 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", 794 | "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", 795 | "dev": true, 796 | "dependencies": { 797 | "json-buffer": "3.0.1" 798 | } 799 | }, 800 | "node_modules/levn": { 801 | "version": "0.4.1", 802 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 803 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 804 | "dev": true, 805 | "dependencies": { 806 | "prelude-ls": "^1.2.1", 807 | "type-check": "~0.4.0" 808 | }, 809 | "engines": { 810 | "node": ">= 0.8.0" 811 | } 812 | }, 813 | "node_modules/locate-path": { 814 | "version": "6.0.0", 815 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 816 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 817 | "dev": true, 818 | "dependencies": { 819 | "p-locate": "^5.0.0" 820 | }, 821 | "engines": { 822 | "node": ">=10" 823 | }, 824 | "funding": { 825 | "url": "https://github.com/sponsors/sindresorhus" 826 | } 827 | }, 828 | "node_modules/lodash.merge": { 829 | "version": "4.6.2", 830 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 831 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 832 | "dev": true 833 | }, 834 | "node_modules/minimatch": { 835 | "version": "3.1.2", 836 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 837 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 838 | "dev": true, 839 | "dependencies": { 840 | "brace-expansion": "^1.1.7" 841 | }, 842 | "engines": { 843 | "node": "*" 844 | } 845 | }, 846 | "node_modules/ms": { 847 | "version": "2.1.2", 848 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 849 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 850 | "dev": true 851 | }, 852 | "node_modules/natural-compare": { 853 | "version": "1.4.0", 854 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 855 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 856 | "dev": true 857 | }, 858 | "node_modules/node-domexception": { 859 | "version": "1.0.0", 860 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 861 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 862 | "funding": [ 863 | { 864 | "type": "github", 865 | "url": "https://github.com/sponsors/jimmywarting" 866 | }, 867 | { 868 | "type": "github", 869 | "url": "https://paypal.me/jimmywarting" 870 | } 871 | ], 872 | "engines": { 873 | "node": ">=10.5.0" 874 | } 875 | }, 876 | "node_modules/node-fetch": { 877 | "version": "3.3.2", 878 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", 879 | "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", 880 | "dependencies": { 881 | "data-uri-to-buffer": "^4.0.0", 882 | "fetch-blob": "^3.1.4", 883 | "formdata-polyfill": "^4.0.10" 884 | }, 885 | "engines": { 886 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 887 | }, 888 | "funding": { 889 | "type": "opencollective", 890 | "url": "https://opencollective.com/node-fetch" 891 | } 892 | }, 893 | "node_modules/once": { 894 | "version": "1.4.0", 895 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 896 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 897 | "dev": true, 898 | "dependencies": { 899 | "wrappy": "1" 900 | } 901 | }, 902 | "node_modules/optionator": { 903 | "version": "0.9.3", 904 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", 905 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", 906 | "dev": true, 907 | "dependencies": { 908 | "@aashutoshrathi/word-wrap": "^1.2.3", 909 | "deep-is": "^0.1.3", 910 | "fast-levenshtein": "^2.0.6", 911 | "levn": "^0.4.1", 912 | "prelude-ls": "^1.2.1", 913 | "type-check": "^0.4.0" 914 | }, 915 | "engines": { 916 | "node": ">= 0.8.0" 917 | } 918 | }, 919 | "node_modules/p-limit": { 920 | "version": "3.1.0", 921 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 922 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 923 | "dev": true, 924 | "dependencies": { 925 | "yocto-queue": "^0.1.0" 926 | }, 927 | "engines": { 928 | "node": ">=10" 929 | }, 930 | "funding": { 931 | "url": "https://github.com/sponsors/sindresorhus" 932 | } 933 | }, 934 | "node_modules/p-locate": { 935 | "version": "5.0.0", 936 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 937 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 938 | "dev": true, 939 | "dependencies": { 940 | "p-limit": "^3.0.2" 941 | }, 942 | "engines": { 943 | "node": ">=10" 944 | }, 945 | "funding": { 946 | "url": "https://github.com/sponsors/sindresorhus" 947 | } 948 | }, 949 | "node_modules/parent-module": { 950 | "version": "1.0.1", 951 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 952 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 953 | "dev": true, 954 | "dependencies": { 955 | "callsites": "^3.0.0" 956 | }, 957 | "engines": { 958 | "node": ">=6" 959 | } 960 | }, 961 | "node_modules/path-exists": { 962 | "version": "4.0.0", 963 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 964 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 965 | "dev": true, 966 | "engines": { 967 | "node": ">=8" 968 | } 969 | }, 970 | "node_modules/path-is-absolute": { 971 | "version": "1.0.1", 972 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 973 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 974 | "dev": true, 975 | "engines": { 976 | "node": ">=0.10.0" 977 | } 978 | }, 979 | "node_modules/path-key": { 980 | "version": "3.1.1", 981 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 982 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 983 | "dev": true, 984 | "engines": { 985 | "node": ">=8" 986 | } 987 | }, 988 | "node_modules/prelude-ls": { 989 | "version": "1.2.1", 990 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 991 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 992 | "dev": true, 993 | "engines": { 994 | "node": ">= 0.8.0" 995 | } 996 | }, 997 | "node_modules/punycode": { 998 | "version": "2.3.0", 999 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", 1000 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", 1001 | "dev": true, 1002 | "engines": { 1003 | "node": ">=6" 1004 | } 1005 | }, 1006 | "node_modules/queue-microtask": { 1007 | "version": "1.2.3", 1008 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1009 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1010 | "dev": true, 1011 | "funding": [ 1012 | { 1013 | "type": "github", 1014 | "url": "https://github.com/sponsors/feross" 1015 | }, 1016 | { 1017 | "type": "patreon", 1018 | "url": "https://www.patreon.com/feross" 1019 | }, 1020 | { 1021 | "type": "consulting", 1022 | "url": "https://feross.org/support" 1023 | } 1024 | ] 1025 | }, 1026 | "node_modules/resolve-from": { 1027 | "version": "4.0.0", 1028 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1029 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1030 | "dev": true, 1031 | "engines": { 1032 | "node": ">=4" 1033 | } 1034 | }, 1035 | "node_modules/reusify": { 1036 | "version": "1.0.4", 1037 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1038 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1039 | "dev": true, 1040 | "engines": { 1041 | "iojs": ">=1.0.0", 1042 | "node": ">=0.10.0" 1043 | } 1044 | }, 1045 | "node_modules/rimraf": { 1046 | "version": "3.0.2", 1047 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1048 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1049 | "dev": true, 1050 | "dependencies": { 1051 | "glob": "^7.1.3" 1052 | }, 1053 | "bin": { 1054 | "rimraf": "bin.js" 1055 | }, 1056 | "funding": { 1057 | "url": "https://github.com/sponsors/isaacs" 1058 | } 1059 | }, 1060 | "node_modules/run-parallel": { 1061 | "version": "1.2.0", 1062 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1063 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1064 | "dev": true, 1065 | "funding": [ 1066 | { 1067 | "type": "github", 1068 | "url": "https://github.com/sponsors/feross" 1069 | }, 1070 | { 1071 | "type": "patreon", 1072 | "url": "https://www.patreon.com/feross" 1073 | }, 1074 | { 1075 | "type": "consulting", 1076 | "url": "https://feross.org/support" 1077 | } 1078 | ], 1079 | "dependencies": { 1080 | "queue-microtask": "^1.2.2" 1081 | } 1082 | }, 1083 | "node_modules/sax": { 1084 | "version": "1.2.4", 1085 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 1086 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 1087 | }, 1088 | "node_modules/shebang-command": { 1089 | "version": "2.0.0", 1090 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1091 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1092 | "dev": true, 1093 | "dependencies": { 1094 | "shebang-regex": "^3.0.0" 1095 | }, 1096 | "engines": { 1097 | "node": ">=8" 1098 | } 1099 | }, 1100 | "node_modules/shebang-regex": { 1101 | "version": "3.0.0", 1102 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1103 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1104 | "dev": true, 1105 | "engines": { 1106 | "node": ">=8" 1107 | } 1108 | }, 1109 | "node_modules/strip-ansi": { 1110 | "version": "6.0.1", 1111 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1112 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1113 | "dev": true, 1114 | "dependencies": { 1115 | "ansi-regex": "^5.0.1" 1116 | }, 1117 | "engines": { 1118 | "node": ">=8" 1119 | } 1120 | }, 1121 | "node_modules/strip-json-comments": { 1122 | "version": "3.1.1", 1123 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1124 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1125 | "dev": true, 1126 | "engines": { 1127 | "node": ">=8" 1128 | }, 1129 | "funding": { 1130 | "url": "https://github.com/sponsors/sindresorhus" 1131 | } 1132 | }, 1133 | "node_modules/supports-color": { 1134 | "version": "7.2.0", 1135 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1136 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1137 | "dev": true, 1138 | "dependencies": { 1139 | "has-flag": "^4.0.0" 1140 | }, 1141 | "engines": { 1142 | "node": ">=8" 1143 | } 1144 | }, 1145 | "node_modules/text-table": { 1146 | "version": "0.2.0", 1147 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1148 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1149 | "dev": true 1150 | }, 1151 | "node_modules/type-check": { 1152 | "version": "0.4.0", 1153 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1154 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1155 | "dev": true, 1156 | "dependencies": { 1157 | "prelude-ls": "^1.2.1" 1158 | }, 1159 | "engines": { 1160 | "node": ">= 0.8.0" 1161 | } 1162 | }, 1163 | "node_modules/type-fest": { 1164 | "version": "0.20.2", 1165 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 1166 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 1167 | "dev": true, 1168 | "engines": { 1169 | "node": ">=10" 1170 | }, 1171 | "funding": { 1172 | "url": "https://github.com/sponsors/sindresorhus" 1173 | } 1174 | }, 1175 | "node_modules/uri-js": { 1176 | "version": "4.4.1", 1177 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1178 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1179 | "dev": true, 1180 | "dependencies": { 1181 | "punycode": "^2.1.0" 1182 | } 1183 | }, 1184 | "node_modules/web-streams-polyfill": { 1185 | "version": "3.2.1", 1186 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", 1187 | "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", 1188 | "engines": { 1189 | "node": ">= 8" 1190 | } 1191 | }, 1192 | "node_modules/which": { 1193 | "version": "2.0.2", 1194 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1195 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1196 | "dev": true, 1197 | "dependencies": { 1198 | "isexe": "^2.0.0" 1199 | }, 1200 | "bin": { 1201 | "node-which": "bin/node-which" 1202 | }, 1203 | "engines": { 1204 | "node": ">= 8" 1205 | } 1206 | }, 1207 | "node_modules/wrappy": { 1208 | "version": "1.0.2", 1209 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1210 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1211 | "dev": true 1212 | }, 1213 | "node_modules/xml2js": { 1214 | "version": "0.6.2", 1215 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", 1216 | "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", 1217 | "dependencies": { 1218 | "sax": ">=0.6.0", 1219 | "xmlbuilder": "~11.0.0" 1220 | }, 1221 | "engines": { 1222 | "node": ">=4.0.0" 1223 | } 1224 | }, 1225 | "node_modules/xmlbuilder": { 1226 | "version": "11.0.1", 1227 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 1228 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 1229 | "engines": { 1230 | "node": ">=4.0" 1231 | } 1232 | }, 1233 | "node_modules/yocto-queue": { 1234 | "version": "0.1.0", 1235 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1236 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1237 | "dev": true, 1238 | "engines": { 1239 | "node": ">=10" 1240 | }, 1241 | "funding": { 1242 | "url": "https://github.com/sponsors/sindresorhus" 1243 | } 1244 | } 1245 | } 1246 | } 1247 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "name": "db-tickets", 4 | "version": "1.1.0", 5 | "description": "A library to retrieve ticket information from Deutsche Bahn", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "node test/index.js", 9 | "lint": "./node_modules/.bin/eslint --fix --ext .js lib", 10 | "prepublishOnly": "npm run lint && npm test" 11 | }, 12 | "author": "envake", 13 | "contributors": [ 14 | "krmax44 ", 15 | "arnebr (https://github.com/arnebr)", 16 | "Jannis R " 17 | ], 18 | "license": "ISC", 19 | "dependencies": { 20 | "node-fetch": "^3.2.8", 21 | "xml2js": "^0.6.2" 22 | }, 23 | "devDependencies": { 24 | "eslint": "^8.20.0" 25 | }, 26 | "engines": { 27 | "node": ">=16" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { readFileSync } from 'node:fs' 3 | import { deepStrictEqual } from 'node:assert'; 4 | import { parseTicket } from '../lib/queryTicket.js' 5 | 6 | const PATH_456800002504 = 'ticket-456800002504-2023-07-10-erika-musterfrau.json' 7 | const TICKET_456800002504 = readFileSync( 8 | fileURLToPath(new URL(PATH_456800002504, import.meta.url).href), 9 | { encoding: 'utf8' }, 10 | ); 11 | const PATH_XXXXXX = 'ticket-XXXXXX-2023-05-12-erika-musterman.json' 12 | const TICKET_XXXXXX = readFileSync( 13 | fileURLToPath(new URL(PATH_XXXXXX, import.meta.url).href), 14 | { encoding: 'utf8' }, 15 | ); 16 | 17 | { 18 | const ticket = JSON.parse(TICKET_456800002504) 19 | 20 | const parsed = parseTicket(ticket) 21 | deepStrictEqual(parsed, { 22 | order: { 23 | ticketNumber: '456800002504', 24 | bookingDate: '2023-07-10T17:01:51', 25 | validFrom: '2023-07-23T00:00:00', 26 | validUntil: '2023-07-24T10:00:00', 27 | journeyStart: '2023-07-23T00:00:00', 28 | firstName: 'Erika', 29 | lastName: 'Musterfrau', 30 | text: 'Super Sparpreis, 2. Kl., Büchen/Berlin Hbf (tief)', 31 | class: 'S2' 32 | }, 33 | journey: { 34 | type: 'journey', 35 | id: undefined, // todo: fix this 36 | legs: [ 37 | { 38 | origin: { 39 | type: 'station', 40 | id: '8000058', 41 | name: 'Büchen', 42 | location: { type: 'location' }, 43 | }, 44 | destination: { 45 | type: 'station', 46 | id: '8098160', 47 | name: 'Berlin Hbf (tief)', 48 | location: { type: 'location' }, 49 | }, 50 | line: { 51 | type: 'line', 52 | id: '1', 53 | name: 'ICE 509', 54 | mode: 'train', 55 | }, 56 | departure: '2023-07-23T10:45:00+00:00', 57 | arrival: '2023-07-23T12:20:00+00:00', 58 | arrivalPlatform: '1', 59 | mode: 'train', 60 | public: true, 61 | } 62 | ], 63 | price: { 64 | amount: '35.90', 65 | currency: 'EUR', 66 | }, 67 | }, 68 | }) 69 | 70 | console.info('ok parseTicket works with 456800002504') 71 | const ticket_xxxxx = JSON.parse(TICKET_XXXXXX) 72 | 73 | const parsed_xxxxx = parseTicket(ticket_xxxxx) 74 | deepStrictEqual(parsed_xxxxx, { 75 | order: { 76 | ticketNumber: 'XXXXXX', 77 | bookingDate: '2023-05-12T23:57:51', 78 | validFrom: '2023-05-14T00:00:00', 79 | validUntil: '2023-05-15T23:59:59', 80 | journeyStart: '2023-05-14T13:38:00', 81 | firstName: 'Erika', 82 | lastName: 'Musterman', 83 | text: 'Einfache Fahrt, Flexpreis, 2. Kl., 1 Erw., BC 50, Berlin+City/Hamburg+City#', 84 | class: 'S2' 85 | }, 86 | journey: { 87 | type: 'journey', 88 | id: '12922018', 89 | legs: [ 90 | { 91 | origin: { 92 | type: 'station', 93 | id: '8098160', 94 | name: 'Berlin Hbf (tief)', 95 | location: { 96 | latitude: 52.525589, 97 | longitude: 13.369549, 98 | type: 'location' 99 | }, 100 | }, 101 | destination: { 102 | type: 'station', 103 | id: '8002553', 104 | name: 'Hamburg-Altona', 105 | location: { 106 | latitude: 53.552697, 107 | longitude: 99.35175, 108 | type: 'location' 109 | }, 110 | }, 111 | line: { 112 | type: 'line', 113 | id: 'C0-0.0', 114 | name: 'ICE 1600', 115 | mode: 'train' 116 | }, 117 | departure: '2023-05-14T13:38:00+00:00', 118 | departurePlatform: '8', 119 | arrival: '2023-05-14T15:39:00+00:00', 120 | arrivalPlatform: '6', 121 | mode: 'train', 122 | public: true 123 | } 124 | ], 125 | price: { amount: '42.90', currency: 'EUR' } 126 | } 127 | } 128 | ) 129 | 130 | console.info('ok parseTicket works with XXXXXX') 131 | } 132 | -------------------------------------------------------------------------------- /test/ticket-456800002504-2023-07-10-erika-musterfrau.json: -------------------------------------------------------------------------------- 1 | { 2 | "rporderdetails": { 3 | "$": { 4 | "version": "2.0" 5 | }, 6 | "rpheader": [ 7 | { 8 | "$": { 9 | "tnr": "", 10 | "ts": "2023-09-11T18:40:35" 11 | } 12 | } 13 | ], 14 | "order": [ 15 | { 16 | "$": { 17 | "cdt": "2023-07-10T17:01:51", 18 | "ddt": "2024-07-23T09:00:00+02:00", 19 | "fkat": "5", 20 | "kwid": "ced723bf-48f2-4706-8a7d-000000ed402d", 21 | "ldt": "2023-07-10T17:01:51", 22 | "on": "456800002504", 23 | "pg": "2", 24 | "sdt": "2023-07-23T00:00:00", 25 | "version": "17", 26 | "vfrom": "2023-07-23T00:00:00", 27 | "vto": "2023-07-24T10:00:00", 28 | "zweg": "99" 29 | }, 30 | "txt": [ 31 | "Büchen - Berlin Hbf (tief)" 32 | ], 33 | "schedulelist": [ 34 | { 35 | "out": [ 36 | { 37 | "$": { 38 | "posnr": "1" 39 | }, 40 | "txt": [ 41 | "Büchen 10:45 - Berlin Hbf (tief) 12:20" 42 | ], 43 | "trainlist": [ 44 | { 45 | "train": [ 46 | { 47 | "$": { 48 | "tid": "1", 49 | "tn": "ICE 509", 50 | "type": "T" 51 | }, 52 | "zugnr": [ 53 | "509" 54 | ], 55 | "gat": [ 56 | "ICE" 57 | ], 58 | "dep": [ 59 | { 60 | "$": { 61 | "dt": "2023-07-23T00:00:00", 62 | "t": "10:45:00" 63 | }, 64 | "n": [ 65 | "Büchen" 66 | ], 67 | "nr": [ 68 | "8000058" 69 | ] 70 | } 71 | ], 72 | "arr": [ 73 | { 74 | "$": { 75 | "dt": "2023-07-23T00:00:00", 76 | "t": "12:20:00" 77 | }, 78 | "n": [ 79 | "Berlin Hbf (tief)" 80 | ], 81 | "nr": [ 82 | "8098160" 83 | ], 84 | "ptf": [ 85 | "1" 86 | ] 87 | } 88 | ] 89 | } 90 | ] 91 | } 92 | ] 93 | } 94 | ] 95 | } 96 | ], 97 | "tcklist": [ 98 | { 99 | "tck": [ 100 | { 101 | "$": { 102 | "posnr": "2" 103 | }, 104 | "htdata": [ 105 | { 106 | "ht": [ 107 | { 108 | "_": "PCFET0NUWVBFIGh0bWwKICBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgo8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+PGhlYWQ+PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPjwvbWV0YT48bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWluaW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8iPjwvbWV0YT48c3R5bGUgeG1sbnM9IiIgdHlwZT0idGV4dC9jc3MiPgogICAgYm9keSB7CiAgICAgICAgd29yZC1icmVhazogYnJlYWstd29yZDsKICAgICAgICBtYXJnaW46IDA7CiAgICAgICAgcGFkZGluZzogMDsKICAgIH0KCiAgICBpbWcgewogICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7CiAgICAgICAgLXdlYmtpdC10b3VjaC1jYWxsb3V0OiBub25lOwogICAgfQoKICAgIC5pbmxpbmUtdGV4dCB7CiAgICAgICAgd2hpdGUtc3BhY2U6IHByZS13cmFwOwogICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgIH0KCiAgICAuaW5saW5lLXRleHQtZG9udC1icmVhayB7CiAgICB9CgogICAgLmJsb2NrLWNvbnRhaW5lciB7CiAgICAgICAgd2hpdGUtc3BhY2U6IHByZS13cmFwOwogICAgICAgIG1heC13aWR0aDogMTAwJTsKICAgIH0KCiAgICAuYmxvY2sgewogICAgICAgIG1heC13aWR0aDogMTAwJTsKICAgIH0KCiAgICAjdGlja2V0YmFyY29kZSB7CiAgICAgICAgd2lkdGg6IDEwMCU7CiAgICAgICAgaW1hZ2UtcmVuZGVyaW5nOiBjcmlzcC1lZGdlczsKICAgICAgICBpbWFnZS1yZW5kZXJpbmc6IHBpeGVsYXRlZDsKICAgIH0KCiAgICAjYm90dG9tTG9nb0hhbmR5ewogICAgICAgIHdpZHRoOiAxMDAlOwogICAgICAgIGhlaWdodDogMTVtbQogICAgfQoKICAgICNib3R0b21Mb2dvVG91cmlzdGlrewogICAgICAgIHdpZHRoOiAxMDAlOwogICAgICAgIGhlaWdodDogN21tCiAgICB9CgogICAgI3NpY2h0cHJ1ZWZtZXJrbWFsIHsKICAgICAgICB3aWR0aDogMTAwJTsKICAgIH0KCiAgICAjbm9BbmltYXRpb25Mb2dvIHsKICAgICAgICBkaXNwbGF5Om5vbmU7CiAgICB9CgogICAgI2FuaW1hdGlvbkxvZ28gewogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICBhbmltYXRpb246IG1vdmVMb2dvIDMwcyBpbmZpbml0ZTsKICAgICAgICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBsaW5lYXI7CiAgICB9CgogICAgQGtleWZyYW1lcyBtb3ZlTG9nbyB7CiAgICAgICAgZnJvbSB7bGVmdDogLTI1bW07fQogICAgICAgIHRvIHtsZWZ0OiAxMDAlO30KICAgIH0KPC9zdHlsZT48c2NyaXB0IHhtbG5zPSIiPjwvc2NyaXB0Pjx0aXRsZT5EZXV0c2NoZSBCYWhuIEhhbmR5dGlja2V0PC90aXRsZT48L2hlYWQ+PGJvZHk+PGRpdiBzdHlsZT0iZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7IGZvbnQtc2l6ZTogMS4wZW07Ij48ZGl2IHZhbGlnbj0idG9wIj48YSBuYW1lPSJCYXJjb2RlIj48L2E+PGRpdj48aW1nIHNyYz0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFWd0FBQUZjQVFBQUFBQ3NiVHVCQUFBQ3ZVbEVRVlI0QWRYWXAyR0FSeGpHNEpjWmFnVHZ2MFUyOENwaWdVcm5sLzVaK0NGL3VicFNDOGxWQ05TR0RGbzJXTFJET0EwWERHSk13TlZFM1RUSk0zZ0dBbFVrbTRIWkdNQmk2bllHNjNRV1pMbVZWWlZyak5iU0xkMlBQZlF2NHcxZWJMdUQ3U254RGg0K2ZaUnhCa084NEsvMENxNzFrcllyR0pBWDNMeUM1K3liWWZYcDUxZnY0T2xITDNFSFI2K1R6Q0hNeXdPYVovQ0twd2ZrRXQ0K25qQmV3Zm4yZ0s0ejJBVTlCR2R3K1lhM1hjRTgycHBYY0kyM245OWR3Ulk4V08wTUp1eWhyK0VWYkw1OWxEeUVnWmNIbEozQjVndFd2WU8vMy80NTllTUpzeXZZclJmOFZWN0JHVDMwdzlnVjdQUUZPNzJDMi9PUGRBYjdpSXRkd2EzZUxwM3lDcFo0d2RIK1pheXVWanAvanhtYkRaeUx0ckFZRFdEU3FHUk1hbU5HYzJld3BMWU1GbXUvMTFwdU9xWDBDZzZqTlpjNFhGWFNBZ3BYUTNjRkErUmlwaEM2YlJaT0tGTmRaN0NNMFZZVm9sWXFGQnNOeE9ZVnZDWEQ1UnhqNnFaazJ3YmJxanlEWGF3R2k1RFVWUGNyakkwUXVZUGZPNFBIc0tRU0dXb3FFU1prR3QzQndwWUdEWnU2YWRXTUt0ZTZneHZab0NSTHJkUllrekpXdURQWWFvVGxiT2kyaWN5TmtUTHFEdVozUHhtU3E4b3hHbTRiTGZRT0pzUmFxdUIralpwSXJhRnhCNnZGeU1tZ0ZvSkJnZ05XdWlzWTFFR05Wc01sTmN4Vk5RZm9GYnpSUTBxN2d1a0paN3VEdDk2Nmc5cytYeVNIOE9pbFZYZHdiM2lIc0srOFBJUDFDYXFIOEY3d3JGM0IyVXZLdklLSkY0eTFLM2pzOHdXM085aDR3c2daek9pdG5jSGhpMlRnRmJ6eCtDTjVCb3M5SkxJcnVKN3diR2V3Ni9NSmIxN0JzQmRzc1N2WXJZY1lPNE0zbno1S20xZHc5SUpwbmNIZmNmOWNmZmJFMngzTUN4M2pES1k5WVQyRTdmTUpkd2YzMWxLdllNZWJwbDNCK0xab1RzN2c2UXVPUElOZFQxYjVDNWdLVjVoTi9oQlVhZmtYY0Z0dFk3YmxCcHRNVWZyZGIzVUdLeXVYQ3pReElsQ01MWEp6Vi9CUGNrUDg4TFVwemUwQUFBQUFTVVZPUks1Q1lJST0iIGFsdD0iVGlja2V0IEJhcmNvZGUiIGlkPSJ0aWNrZXRiYXJjb2RlIj48L2ltZz48L2Rpdj48ZGl2IHN0eWxlPSJib3JkZXItdG9wLWNvbG9yOiBibGFjazsgYm9yZGVyLXRvcC1zdHlsZTogc29saWQ7IGJvcmRlci10b3Atd2lkdGg6IDAuMm1tOyBtYXJnaW4tdG9wOiAxLjBleDsiPjxzcGFuPiZuYnNwOzwvc3Bhbj48c3Bhbj48L3NwYW4+PC9kaXY+PGEgbmFtZT0iVGlja2V0aW5oYWJlciI+PC9hPjxkaXY+PHNwYW4+RXJpa2E8L3NwYW4+PHNwYW4+IDwvc3Bhbj48c3Bhbj5NdXN0ZXJmcmF1PC9zcGFuPjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtd2VpZ2h0OiA3MDA7IG1hcmdpbi10b3A6IDIuMG1tOyI+PHNwYW4+Q0lWIDEwODA8L3NwYW4+PC9kaXY+PGRpdiBzdHlsZT0ibWFyZ2luLXRvcDogMS4wZXg7Ij48L2Rpdj48YSBuYW1lPSJHdWVsdGlna2VpdCI+PC9hPjxkaXYgc3R5bGU9Im1hcmdpbi10b3A6IDEuMGV4OyI+PGEgbmFtZT0iR3VlbHRpZ2tlaXRIZWFkZXIiPjwvYT48ZGl2IHN0eWxlPSJmb250LXNpemU6IDEyLjBwdDsgZm9udC13ZWlnaHQ6IDcwMDsgdGV4dC1kZWNvcmF0aW9uOiBuby11bmRlcmxpbmU7Ij48c3Bhbj5Hw7xsdGlna2VpdDwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPklDRTwvc3Bhbj48c3Bhbj4gPC9zcGFuPjxzcGFuPkZhaHJrYXJ0ZTwvc3Bhbj48c3Bhbj4gKDwvc3Bhbj48c3Bhbj5FaW5mYWNoZSBGYWhydDwvc3Bhbj48c3Bhbj4pPC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+U3VwZXIgU3BhcnByZWlzPC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+PC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+Mi4gS2xhc3NlPC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+MTwvc3Bhbj48c3Bhbj4gPC9zcGFuPjxzcGFuPlBlcnNvbiAoMjctNjQgSmFocmUpPC9zcGFuPjxzcGFuPiBtaXQgPC9zcGFuPjxzcGFuPjEgQkMyNTwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPlZvbjogPC9zcGFuPjxzcGFuPjIzLjA3LjIwMjMsIDAwOjAwIFVocjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkJpczogPC9zcGFuPjxzcGFuPjI0LjA3LjIwMjMsIDEwOjAwIFVocjwvc3Bhbj48L2Rpdj48L2Rpdj48YSBuYW1lPSJWZXJiaW5kdW5nMiI+PC9hPjxkaXYgc3R5bGU9Im1hcmdpbi10b3A6IDEuMGV4OyI+PGRpdiBzdHlsZT0iZm9udC1zaXplOiAxMi4wcHQ7IGZvbnQtd2VpZ2h0OiA3MDA7IHRleHQtZGVjb3JhdGlvbjogbm8tdW5kZXJsaW5lOyI+PHNwYW4+VmVyYmluZHVuZzwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkLDvGNoZW48L3NwYW4+PHNwYW4+IC0gPC9zcGFuPjxzcGFuPkJlcmxpbjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPlp1Z2JpbmR1bmc6PC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+SUNFIDUwOTwvc3Bhbj48c3Bhbj4sICA8L3NwYW4+PHNwYW4+MTA6NDUgVWhyPC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4+VmlhOiAmbHQ7MTA4MCZndDsoTFdMKk5FVUQqTkFVL1VFKlNBVypTREwqV1VNKSpCU1A8L3NwYW4+PC9kaXY+PC9kaXY+PGEgbmFtZT0iQnVjaHVuZ3NkZXRhaWxzIj48L2E+PGRpdiBzdHlsZT0ibWFyZ2luLXRvcDogMS4wZXg7Ij48YSBuYW1lPSJCdWNodW5nc2RldGFpbHNIZWFkZXIiPjwvYT48ZGl2IHN0eWxlPSJmb250LXNpemU6IDEyLjBwdDsgZm9udC13ZWlnaHQ6IDcwMDsgdGV4dC1kZWNvcmF0aW9uOiBuby11bmRlcmxpbmU7Ij48c3Bhbj5CdWNodW5nc2RldGFpbHM8L3NwYW4+PC9kaXY+PGRpdj48c3Bhbj5HZWJ1Y2h0IGFtOiA8L3NwYW4+PHNwYW4+MTAuMDcuMjAyMyB1bSAxNzowMSBVaHI8L3NwYW4+PC9kaXY+PGRpdj48c3Bhbj5BdWZ0cmFncy1OcjogPC9zcGFuPjxzcGFuPjQ1NjgwMDAwMjUwNDwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkdlc2FtdHByZWlzOiA8L3NwYW4+PHNwYW4+MzUsOTA8L3NwYW4+PHNwYW4+IDwvc3Bhbj48c3Bhbj7igqw8L3NwYW4+PC9kaXY+PC9kaXY+PGRpdiBzdHlsZT0ibWFyZ2luLXRvcDogMS4wZXg7Ij48ZGl2IHN0eWxlPSJmb250LXNpemU6IDEyLjBwdDsgZm9udC13ZWlnaHQ6IDcwMDsgdGV4dC1kZWNvcmF0aW9uOiBuby11bmRlcmxpbmU7Ij48c3Bhbj5Lb25kaXRpb25lbjwvc3Bhbj48L2Rpdj48ZGl2PjxkaXY+PHNwYW4+WnVnYmluZHVuZzogR2lsdCBudXIgZsO8ciBlaW5nZXRyYWdlbmUgWsO8Z2U8L3NwYW4+PC9kaXY+PC9kaXY+PGRpdiBzdHlsZT0ibWFyZ2luLXRvcDogMS4wZXg7Ij48ZGl2PjxzcGFuPk51ciBnw7xsdGlnIG1pdCBhbXRsaWNoZW4gTGljaHRiaWxkYXVzd2Vpcy4gRGllc2VyIGlzdCBiZWkgZGVyIEtvbnRyb2xsZSB2b3J6dXplaWdlbjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkJlaSBGYWhya2FydGVuIG1pdCBCYWhuQ2FyZC1SYWJhdHQgemVpZ2VuIFNpZSBiaXR0ZSB6dXPDpHR6bGljaCBJaHJlIGfDvGx0aWdlIEJhaG5DYXJkIHZvcjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkVzIGdlbHRlbiBkaWUgQmVmw7ZyZGVydW5nc2JlZGluZ3VuZ2VuIGRlciBEQiBBRzwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuPkJlaSBlaW5lciB6dSBlcndhcnRlbmRlbiBWZXJzcMOkdHVuZyBhYiAyMCBNaW51dGVuIGFtIFppZWxiYWhuaG9mIElocmVyIEZhaHJrYXJ0ZSBpc3QgZGllIFp1Z2JpbmR1bmcgSWhyZXIgRmFocnQgb2huZSBiZXNvbmRlcmUgQmVzY2hlaW5pZ3VuZyBhdWZnZWhvYmVuPC9zcGFuPjwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbi10b3A6IDEuMGV4OyI+PGRpdj48c3Bhbj5TdG9ybmllcnVuZyBhdXNnZXNjaGxvc3Nlbjwvc3Bhbj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IHN0eWxlPSJtYXJnaW4tdG9wOiAxLjBleDsiPjxkaXYgc3R5bGU9ImZvbnQtc2l6ZTogMTAuMHB0OyB0ZXh0LWFsaWduOiBsZWZ0OyI+PHNwYW4+VGlja2V0Y29kZTogPC9zcGFuPjxzcGFuPjgxTDdXVzZaPC9zcGFuPjwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9ImJvcmRlci1ib3R0b20tY29sb3I6IGJsYWNrOyBib3JkZXItYm90dG9tLXN0eWxlOiBzb2xpZDsgYm9yZGVyLWJvdHRvbS13aWR0aDogMC4xbW07IG1hcmdpbi10b3A6IDEuMGV4OyI+PHNwYW4+Jm5ic3A7PC9zcGFuPjwvZGl2PjxkaXY+PGltZyBzcmM9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBVXdBQUFFV0NBQUFBQUFvRVBFU0FBQVJ6a2xFUVZSNEFleloxMS9xVGg3RzhmM1R0L2ZlTDdmZGJPOTd0ZVZKQ0NJMm1tQVhrRU1Ua0Y0bGVmYndIWkl3RkgvaVVmQ0M5NDBWbWRjbnlUaVRmSTZ2WnVmVll1N3NZdTVpN21MdVl0YlRyaDQvelM2bTg5UFB1Njc0YVhZeG81L2Z4WHl0bU9QdjdXSytXc3k5eis5aXZsYk13VGRlTSthZ1ArVDJqUHZEdFY4eGZzMlkvL244WXN4NlpzR0lNeDR1RGcwQW9YaTY3dEExeXArR01CRk9sV3h1bVAxd2s1QjNONDZ1bXZRVU12Tnk5RGlsdUFYQWloY2RMbWhscHB3MVlyYS9zaVJtR2dzNjlOUU80TnNyVURocEU3NWduaHZrVkpNbVprUzduRHJDdkgyNmFpRzRRbFc2Rmw0NVhpUG1QejYvWmt6bkNwb1VKeDVQb0VzNTNKZ2M1cGpWejQ1NWgxbDMxSlh3Z3BqVkwwNGFmdkVMejQ3cHBMQXNaZ3p6cnJjWUUyYmpzMklXb05NdkpXZi9KVEYvSnczLzlwVm54N3pCc3BobExHcHZNU1pDOXRNeDJ5WjBwamJjRDNoQnpMd2svRXJyMlRFZnNEVG1NYWFDQnhhbXpyY1pFN21uWTBZd0wwTGZPUGlTbUwrVWhQL2hjMk02WVNpaGRMM2ZyOTlGVmN3aEZLdEtPZ1ZqMm5Xek1jMUVybHk2dGpCMThHVE1HcFJRdG53WGdsS2pKNDBYeEx5V2d0OGNMSThaVzF3YUZhR2NqYW4wenM1bXhuYlBpVnNvd3czR0RLVFZBRWZlTmRMM1kxNHVMSTFpMDdKRGtxTjlpQmhkdzhCTFl2NWNDb2E0UEdhV0N3NGhUdWtiKzQyREZJTk5UNW81SklkZWlDQ1VpaGR6Y1NCRFkrWjNXSUV3aHB5NmxOWHltakVURXZENzQyZkhiRUZZSStvS0VGRXFGa1NURzFJc1Uyalh4WWVWTWIzeEJoMU9PTlArQlNvOVNWMWVMNmI5QXdrWTQ3TmpwbGVzZXU0aDRsVDJJTHJjaGdhVTdCTXhVeEJKS2ttSTFPeFBvNC9yeFF4THY1L3orVEdQVjF5L0xZZ2pDc2ZBaEdGekd3WlFjay9FREh1OVJSWWlUTkhHUkd1OW1NTnZTYi9yMVRFN3BXem1RM1ZFbDYwcVdaem5XQ3FmK3RVNnhBbTNvZytsNU1kc05ZcVpUS0ZoYzJvTTVaN0t2ZFl0cGs3YTlXSkM4djJTSzJNYVVDSVZLbTJJR0VlWll4UFlUOVU0ZFFGeElja2pFSGx1UlIxSzI0OXBRSmlwRGtVSCtxVGVuSDNKZzd5aXQxN003bGNsWDJGRlRFMXNPSHNFei9NQnVKMzdGQU1MSWxHcGw0OGhEaHh1eFEyRTVhaVlHdU5Hdmx1RjBxUFNnMUwxcHJKTHJoZnpYMUx2RDN4T1RPd1BabllhRm56QkZrWE5oRzZ2eTYydzkveUxSSThwVHAyWjFmS1F5aEJLMFQxaEFzUDFZdGEvTkluM3BZZm54Y1NSN1IxMFhYQkEwUXhENktmczVtV2dkUFNZbm1zNUtmUk9ZeWc1ZDR1WDVub3gveWp4L3NWbnhwUy9mNGtsWWxTY0MzaU1ITGVrWVVDY2MwVk1OTWtzRkp1SzdhK204bktDak5lTFdaU2JibC90UEJrekdJQW44RWllWXhsMWNyZFBNQ3M1NERZTTlpQkNqMXJNa0g3d00xQWNLZzZVRE1meStqelhpL2tiYVFldWpCbjUwSGJJWVg1djVvYmZHYWFNOUlDdEJHYjJsdmNMYzJhYm16YzZnRERxZEdPYXlYS2ZaT2ZhOERmdG1SVm5aa2I5Sk95c0dWUHFmWHU0SW1iMnFzK3A0YUYvUk04eGxaSGplUUpoMm1UVGdISWNQWFJyRHJocDlvay8rU21Kbk5laWJucjd6THNWYytiZEtPQXRQOWVPK2VPL3VMNzRlZVZYa3k5Nm5OVTFJQUwrbkduWjJyM05PcDBEaUpNK3lmWStSSW9iNXNTZnZKUDZBVXFTZVNpUHBOWXRmeTNuQTllUHVWcURtaVNVQWRQZWhTMmNBRVNlRllpOVJ5MS9uNXQxQmlYbWNCazdDSEhJTXBUQjNBNjBiTXE1OFpZeEMxQmEzckc5MVI5WHBabUN5T2o1YzF0WnJlTjR6T1ZPSVlLc2U4c25mVWRVTnlZL3ppaTNVRzQvZmo1NHRaZzE3MnF1UUs4VWc3am1nYjQ5eTIvak9zOUJDWSs0d2hXRXliNjJEdkhucTc2QjVacXZGdlBCZStzTzlGMTNBdUtHaHI2anFHN2hUa2NKU3FqUFZhN2RtSTRKVWRTdlBkTjUrNWdsN3k4NjV0SXpNMnRER2VuNUQ3ZzVOUVBDNm5DbEZJUkZua0JjNjVXUCtmWXhML3lIS2hGOUVBY1FKUWRLVDcrbGRjaU5hUWE4NStXcmhkeGh1ZlVpRkY3Yk40bDVXYUZ2RlBDV1JzeG9POGl4QWRGbVFMOC9lT3VOZFVPNlFRaWpTazIwUzE4RlN0TDdOMkNNdENkQ3RaZkd6S1kxWC82OFlrMitHQ2NSNzNES1NjQXYySVV3MVNES0VKYWpQMmZ6bmdlZmNVTUdJU2dsNmt6ajVuRitwNGtQL2xPZm05bXJQT2lzRlhNMWZRZVVsRHVUc2pKdlJUQ1ZkeThJTjlPajMrd2NTbm54a2RZR2VHOW83TSs0bk1RRUFsZFN3aW03TGRIMyt4bEZra1hEbTd4S00vSlFDaDgvSDMxaVRNQTRpa1pEY0ZuajJVc2xYcWtYdy81aHEyRHFyRnEvVDNpajNuQk0zYW5FbkxCT29wRUFYQWwrNUMyQ3d0RXdGRU1mcnI1by8rU1l1anVLeU5KQk8vdFlGT2Y3aUtrejJ0NEtYM2ZEamNXTU9CUzl3Tktidy9kWVlIYmVaY3dzaFgwQTNZRzlzWmhISTA1VkRjd0tOUDNkaGE3STl4anpnbE85b0g1TzlQaEdNYXRIMENYSDlOUXMrRUl0VG1YbUlwZjVEbUptOXFBeGMvVDB3dkNGdTN5VG1LSnhzUWRQN0lHekJtZUdXK3htVEU4bmFmb3BMd2Q4RHpGcGwwNU5QK1c1ZHZyWmFRdUtkV3R6blpqcjY1U3Z6NU94ODV2eWtQT0d4YXRVOVB5MmFsTXpybWJQVDZQSjg3c0htKytIM2N4Zm5zY1Q1OW1hdmZDanlzMTU5T3ltWXYrZmZUc3BBQUNFQVJpR2YxVTRBeEdjMjFJSitmZlZpS3JXdFMyWU1HSENGRXlZTUw4TUprekJoQWtUcG1EQ2hDbVlNR0hDRkV5WU1BVVRKa3lZZ2dsenhDZ0tKa3lZTUNjNzl3RGx1QnBIQVR5RHRURnMxN1p0MjdadDI3WnQyN1p0MjdzMVJuV1QreWI1MHZlMXl6bDZTSHVQb3Y4OXA3OWFjY1N3WG9DNUwxOFFTZWFQSU9uU1NJRTJ2VFg0V2FabHpmU0c0eGU0eG1HdFZEOVZzM0Q0SWRaK2lXc3F2QUJ6YTlveXJkcng2ZXF5NmRWU2lkby9sOEtJaE15NkdIN2hRUWFteGs5NVZxYjZ5V2tPYnFhcmM5VHNGWmg3ZnJ5WXY4Wk1rN2FGc0dkVzVpUzE0NDY1TStpVURWNkdlZUZNOUpXVnhpdm5UQVR6eFk0YlZsaHZ6WnAxMXNpNU1GTjNsei9uQUxaaXAvU3htS2VPeHdBNGVjb0VQSjgzWU00REd5NTBpRC8rb2dXNHNXRHE4U2hPckR3NUtQRzRzMmJTVGd2cHNDUXgyOVp0RUwvSWw4Ymx2d3FZOTNLVmY4dCtLY25rek9NZmRNTWhZaWJibjNGVk5IQTMvZmE4dFJTb1hlVWJnSnAxRmRnZEhGSThNR0NUYVZBSUV6SkNieDZhTUdsR3YwcXZXVkxaV3M0RWQxU1RkbHBJaHlXRTJXdjFSajVQN1dpYklNOHFKU3RpM3NsUjZSMkhHU0hIcmJnb0cyTVFNUk8vcWRGRUNjekkrcmFZTzZhamNEMGx0QzByZmlWMzgyVXBwNnU1bTluYXFNWEtuVUZYSGVJaUxaUWtKa095S0FwdEEvaUhOb0o1TUh1MWp4eHdkbjgwWU03ZFJTdGlKbnl6S093cDZ5elhWZU9CYWN4UitCUHcrYkpKd0l3dVVPd0xnT0ZCenpsU1NURDVSVm9vVGN6MVgzVjh6QnphNXYwRUVUTkhBbVorSkRsdjA1S0JCZjNjTUo5bldoWjlPLzB1c3djbUJpY0k2cjVMeFVMQWZKYXB5cXdsUzVhMFRYRFJUaW9KSnI5SUMrbXdSQjh6eTN4eFlmclZMNXoycmhNNFZjSS9UOHRsSVc2WXFOTlFPVFg3TzFETWNyVVZjSnpwbUlyeEgya1FNQy9JNU1WSzhybGlJNVVFazEra2hYUlk4cGdWdjl6TDBFQUpZNzdRQjA1WWMzZDF3MXdlZXE5a0R5M0JyQnpyRVptemh1RGh1RkUzNEtTTngzeWVxWi9PbzVKaTBrSTZMSG5NVmlwTVNMd3U1bkhHWVhyZ3F0ejlsdmttYzZORWV5MENacGVjSDRHejRUVVVWM1B1TXdPbnd6ZWJlRXhUa1Z5ZkFRekw4LzRIVEZwSWg2V0UyV1RNUkNGZldVOU1ZOG5RcC9wOFdZNi8zNU0zb01FNzltOU1OUFFQL2dBQmMyR0tvZGQzNVVwU1cyRXNXdXFxNlVXalZQZWQrME1tUHJOdlNqUG8yYWY1S2NjYmY3eGwwa0xYc0JTZnpaazdUazlNSEFwcHB6bFp4bzlKZjJSYThsWnFpcms2ZFE4dHdZeHFGOGhrVzFxL29RS1hDc1EycE5sbWdxcHhRQmV0YzNVUXd5U2VaTUFQbUtDRmROaHJQalhpbm4xd0FBbzlpNTlHOTg1R0ZreVBUdHcwQ2dkcFRCd1FkZnVLbHYxOUlSMldCdWEvSHgrbUQ5T0g2Y3YvR3ZNdmR1aUNBQUFZZ0FGUS85UjdocnRCQkdRaVU2Wk1tY2lVZVI2Wk1tVWlVNlpNbWNpVUtST1pNbVVpVTZaTW1jaVVLUk9aTW1YS1JLWk1tY2lVS1ZNbU1tWEtSS1pNbVRLUktWTW1NbVhLUktaTW1US1JLVk1tTW1YS2xJbE1tVEtSS1ZPbVRHVEtsSWxNbVRLUktWT21UR1RLbElsTW1USmxJbE9tVEdUS2xDa1RtVEpsSWxPbVRKbklsQ2tUbVRKbElsT21USm5JbENrVG1USmx5a1NtVEpuSWxDbFRKakpsWm9uVm1XR1lsc3pTdm5tb1NhdnlBUGorciszL1QrKzlnMTBSeFFia1BLc2JKSzdPR2Jjd1g1bjNxVTZOTHlGQVpuZFNvaXp5VWlnRFcwd3JpcXlzT3dzRTI4bXl5SXBTOWhiZUhlelFWbVdlNzBWbE8xRm1wZWpzNjhyODlQOExBaGFHS21LT3ZBY2ZYZUlUWEhoaGpBVm5DSzgwQktSbU94U3pMdVZIVlU1RVpjM3hpWHBIcDJFTDlvVXl1M1FibUFWSHo5bEtQT0xEa2hHNGVoZGsxdEVtcWdZY1U4SldrdW5OWkJac1MrTG1lcmNKYjRDWmltMVI3NEJNenJaVXppWDFIRTNoWkxJTVk5akdGMm1xMk1ISGQxRW1rekJqRTBaSmJEaVpHRVMyRzdTTjJWUHlkMUltVzhaWXNDM2liV1VtV2JaSzR0YlB3THpyVzN4dThCS3o3UG91eHd2OWpzamthWlp4T3NZYXIrSXNjZUcrbmN4ODJUQ01MaFhiaDh2MDBkbjhiYkc3S0xGT2tudHJnc3VNUGFwRkpoZkRzcXhIdmpUaDNaUmFVMU41dFBnU3BaUzVMRlBXQkpUSkh5NXN3ZklSa053YjBZbk5jQU93UnNFQkVreUdHZXNzQjBMSEI0c2VaOEo1MEpFM3hwSHp0NXFOQU5nQncyV1phRytQb2VyOGRPZk9HVWl5R2xsWGhUaTlseHBmRmdxM05IZEF5Q1pZNmRiNTM3TUZReVowL3lZeWdWQ3QweU9qdFRwQmgyeGhvbUVuRUl5QnU1M2FNYkVMUzVEUnh1SWxBc2hVN2hNdHg0bENLb0MwYnFBWCt1QXlYYTVGSXh4UzRuU21TZUhjcGdGazltNFdURmlUcVV3Qkc1bGQwR2xPaHp6V2NJUnc5WXJUKzJqeGlYQXlCNVMwelV5QjgzMmd3UlVRa29ZZTFpN0oxQzQ5NkIzcXQ1Zlo0anJqNHExcHJhbWhJQnQ3dkd3Z0pPaUtwUmIyS1hDYUQ1c2FQNkd6K1dtNVVPUE5TaW4xcThrczNBSlVNNXB5T0Zzd1pTTkRZdE1RbHZMeTBjdEdXTW9WRGRCbHF1S3owbk9iZHBUNTlXL0lKNDhlZjN5NG9CSlFEVi9YZFc0Mzh4L25lYW9CWUl4UmVXQnN6aGJLaTNXZ2NIUE5BUFhXaXZrbW5pZnpDM1BRejVUQ0NkWEpPdDRsT2FqYmRGVTc0RE5wbHBBT1NEQXdJbHBnOHNhNUdMaDdVbTQ4V2J5dFpVK3R6c3I4YVhiSERtVFdqR1hOK0tDeWpWQlQ2OGxrdFlZeDl5ZTk0b3dTalJBZWsyeFdqSlR4UW1rQW1BUkQ5TEhNcFpERloyV3FlV0ovT2g3Sm5JazhROXlnVEFxdWlXUEtmQW9OZ1NGbnh0aVFKVEttelN5VUNZaVR1ZFRWOXFSTStIV1c5K2NGbVpSNnB3Tk15ajE1dG9FYk1kQ3ltZTV1YzQ0emN5bW5rVDBwYzVoVDg1UCtTcG1KZmRJRXBLVnhpSmxQcHVFMm9LanhRS2JBcFdoSFpvTkg1UHFrVFBoenR2ZnJkVEpqN2EySDBVNXA3UGxXOGdTQm9SdWdha2NtRnZqRDFSeFBiOXljbERrdEF0dHJaR2JHUHlhV0xkOG1vT2F1YWF4UzNNNEZoelRVZG1VS3ZJL2RUWHZuM2xLZGxBbHMxdmZEZjh2TU9sZ1lzVW9hbVhMRzRxTDM2eVdtZzgxdVdqY0hmNTRUbWJ5Y3FMeGg3eTM5NHZta1RQTUYranVRS1NjbFpkTVpRS3czNkJUdXo1c2VtekRCSWNlWlZlWTR0RksyZzlOaU43MWtSYnpsY3prNEtSUGkyZCszeHpKaFMrcEdrREpTZlJqR1RXVTJuc3lEenFha2kxYnMzOHg0VXFiOWFoYVlYUyt6ZHBXSG91Z3VLY0tTZE10cExpL0lMSEUxSXQySDByL01Uc3FFZkJiNGxiMWE1dWdhR3BTV05qQTVscVJBdElvTytIRm0wbmdqT3ZndFdZL1VTWm53N1d3d3ZsWW0rZVVNc1RRNGI2S040VnFaaFJ0ZVEzNE9PcENKRVhaa2NkZGtPWTNQeWhTendjLzF2c3hjZWhoU3FrdUxvMWlXWHYrb0k3bGh3c2xrdkRhTHk1UTVOVTVtSlZjYXY2MGRHKzhuNjN6ekcrSlptZkREclBDZlhabVVpZjVWU1Z6M1dnOHlXeW9OMXBlbzg3YkVVZGdtTzg4YnBVVGtqbXdISjZDWWRBOWpxU1NtWUU5THhYbVo3YXp3MC9FcW1SZ0ZwU1JCUndsM1R3U1Z1YVc1S0JNeXRpWGJIS1BPeTRSZlpvZS9YeTBUeEs1TXhaNHkzbEptYkMvTEhQbkZ2ek5ybmlXelcvb2RuMXd0RTRvOW1aRHZkQlJ1S0pNUGNGa210THVaN0loUHlVVCtXQ3hlTHhPcVBaa20zVHEyTjVUSk96aVdTWGJxaUFTS2VwYk04ZE96TXFGUDJFclVZdEhtL3FNTmhLUXJPQ2wvRTF5UWlmVHgrbUFIVzVKVE1wRi9kbVFPOGdrR1BQb3FtV1BJNng0Y3BpbVc4SkpDV1FpTTdVWCsrTzFpQUVjcnQvaWpyUExvWWVEemRpL0o4QTF3UnFiK25NaDhJVm9idUIxV205UHZzSy82cnl2Umtjdzc1MlhhTDE5TjVsMG1aSzhuOHk0VHZuazltWGVaUTQxb09NOWQ1cDI3ekx2TXU4dzdkNWtCK0JjZmZEWCtRcGpwS1FBQUFBQkpSVTVFcmtKZ2dnPT0iIGFsdD0iU2ljaHRwcnVlZm1lcmttYWwiIGlkPSJzaWNodHBydWVmbWVya21hbCI+PC9pbWc+PC9kaXY+PGEgbmFtZT0iX2xhc3QtYmxvY2siPjwvYT48ZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjwvYm9keT48L2h0bWw+", 109 | "$": { 110 | "name": "httext", 111 | "pos": "1", 112 | "type": "text/html;base64" 113 | } 114 | } 115 | ] 116 | } 117 | ], 118 | "mtk": [ 119 | { 120 | "$": { 121 | "dir": "1", 122 | "status": "8" 123 | }, 124 | "txt": [ 125 | "Super Sparpreis, 2. Kl., Büchen/Berlin Hbf (tief)" 126 | ], 127 | "zb": [ 128 | "N" 129 | ], 130 | "iss": [ 131 | "80" 132 | ], 133 | "reisender_vorname": [ 134 | "Erika" 135 | ], 136 | "reisender_nachname": [ 137 | "Musterfrau" 138 | ], 139 | "nvplist": [ 140 | { 141 | "nvp": [ 142 | { 143 | "_": "-------", 144 | "$": { 145 | "name": "k_erm_db" 146 | } 147 | }, 148 | { 149 | "_": "1", 150 | "$": { 151 | "name": "anzerw" 152 | } 153 | }, 154 | { 155 | "_": "0", 156 | "$": { 157 | "name": "anzkind" 158 | } 159 | }, 160 | { 161 | "_": "S2", 162 | "$": { 163 | "name": "klasse" 164 | } 165 | }, 166 | { 167 | "_": "8", 168 | "$": { 169 | "name": "status" 170 | } 171 | } 172 | ] 173 | } 174 | ] 175 | } 176 | ] 177 | } 178 | ] 179 | } 180 | ], 181 | "posinfolist": [ 182 | { 183 | "posinfo": [ 184 | { 185 | "$": { 186 | "dir": "1", 187 | "dirlabel": "none", 188 | "posnr": "2", 189 | "shownr": "1002", 190 | "state": "8", 191 | "type": "TCK", 192 | "typeinfo": "0", 193 | "vfo": "2023-07-23T00:00:00", 194 | "vto": "2023-07-24T10:00:00" 195 | }, 196 | "childlist": [ 197 | { 198 | "posinfo": [ 199 | { 200 | "$": { 201 | "dir": "1", 202 | "dirlabel": "none", 203 | "posnr": "1", 204 | "shownr": "1100", 205 | "state": "8", 206 | "type": "EVA", 207 | "typeinfo": "0", 208 | "vfo": "2023-07-23T10:45:00", 209 | "vto": "2023-07-23T12:20:00" 210 | }, 211 | "childlist": [ 212 | "" 213 | ] 214 | } 215 | ] 216 | } 217 | ] 218 | } 219 | ] 220 | } 221 | ] 222 | } 223 | ] 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /test/ticket-XXXXXX-2023-05-12-erika-musterman.json: -------------------------------------------------------------------------------- 1 | { 2 | "rporderdetails": { 3 | "$": { 4 | "version": "2.0" 5 | }, 6 | "rpheader": [ 7 | { 8 | "$": { 9 | "tnr": "", 10 | "ts": "2023-09-12T08:38:02" 11 | } 12 | } 13 | ], 14 | "order": [ 15 | { 16 | "$": { 17 | "cdt": "2023-05-12T23:57:51", 18 | "cid": "12922018", 19 | "ddt": "2024-07-12T23:57:51", 20 | "fkat": "5", 21 | "hkey": "dc6cc67efa0f0019ed8e305525ba28f2", 22 | "ldt": "2023-05-12T23:57:51", 23 | "on": "XXXXXX", 24 | "pg": "1", 25 | "sdt": "2023-05-14T13:38:00", 26 | "version": "18", 27 | "vfrom": "2023-05-14T00:00:00", 28 | "vto": "2023-05-15T23:59:59", 29 | "zweg": "1" 30 | }, 31 | "schedulelist": [ 32 | { 33 | "out": [ 34 | { 35 | "$": { 36 | "posnr": "1" 37 | }, 38 | "txt": [ 39 | "Berlin Hbf (tief) 13:38 - Hamburg-Altona 15:39" 40 | ], 41 | "tp": [ 42 | { 43 | "depn": [ 44 | "Berlin+City" 45 | ], 46 | "arrn": [ 47 | "Hamburg+City" 48 | ] 49 | } 50 | ], 51 | "trainlist": [ 52 | { 53 | "train": [ 54 | { 55 | "$": { 56 | "tid": "C0-0.0", 57 | "tn": "ICE 1600", 58 | "type": "T" 59 | }, 60 | "zugnr": [ 61 | "1600" 62 | ], 63 | "gat": [ 64 | "ICE" 65 | ], 66 | "sci": [ 67 | "Y" 68 | ], 69 | "dep": [ 70 | { 71 | "$": { 72 | "dt": "2023-05-14T00:00:00", 73 | "t": "13:38:00" 74 | }, 75 | "n": [ 76 | "Berlin Hbf (tief)" 77 | ], 78 | "nr": [ 79 | "8098160" 80 | ], 81 | "ebhf_name": [ 82 | "Berlin Hbf (tief)" 83 | ], 84 | "ebhf_nr": [ 85 | "8098160" 86 | ], 87 | "ptf": [ 88 | "8" 89 | ], 90 | "plz": [ 91 | "10557" 92 | ], 93 | "x": [ 94 | "13369549" 95 | ], 96 | "y": [ 97 | "52525589" 98 | ] 99 | } 100 | ], 101 | "arr": [ 102 | { 103 | "$": { 104 | "dt": "2023-05-14T00:00:00", 105 | "t": "15:39:00" 106 | }, 107 | "n": [ 108 | "Hamburg-Altona" 109 | ], 110 | "nr": [ 111 | "8002553" 112 | ], 113 | "ebhf_name": [ 114 | "Hamburg-Altona" 115 | ], 116 | "ebhf_nr": [ 117 | "8002553" 118 | ], 119 | "ptf": [ 120 | "6" 121 | ], 122 | "plz": [ 123 | "22765" 124 | ], 125 | "x": [ 126 | "9935175" 127 | ], 128 | "y": [ 129 | "53552697" 130 | ] 131 | } 132 | ] 133 | } 134 | ] 135 | } 136 | ] 137 | } 138 | ] 139 | } 140 | ], 141 | "tcklist": [ 142 | { 143 | "tck": [ 144 | { 145 | "$": { 146 | "posnr": "2" 147 | }, 148 | "htdata": [ 149 | { 150 | "ht": [ 151 | { 152 | "_": "data:image/png;base64,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", 153 | "$": { 154 | "name": "barcode", 155 | "pos": "1", 156 | "type": "image/png;base64" 157 | } 158 | }, 159 | { 160 | "_": "PHA+RnJhdcKgIEVyaWthIE11c3Rlcm1hbjxici8+Cjxici8+CklDRSBGYWhya2FydGUsIEZsZXhwcmVpcyAoRWluZmFjaGUgRmFocnQpPGJyLz4KRmFocnRhbnRyaXR0IGFtIDE0LjA1LjIwMjM8YnIvPgpDaXR5IGFtIDE0LjA1LjIzPGJyLz4KPGJyLz4KS2xhc3NlOiAyLCBFcncuOiAxLCBtaXQgMcKgQkM1MDxici8+CkhpbmZhaHJ0OiBCZXJsaW4rQ2l0eSAtIEhhbWJ1cmcrQ2l0eSwgbWl0IElDRTxici8+Cjxici8+CsOcYmVyOiBWSUE6IEJTUCooV1VNKlNETCpTQVcqVUUqSEFSL1dCRSpMV0wpPGJyLz4KPGJyLz4KTnVyIGfDvGx0aWcgbWl0IGFtdGxpY2hlbSBMaWNodGJpbGRhdXN3ZWlzICh6LkIuIFBlcnNvbmFsYXVzd2VpcykuIERpZXNlciBpc3QgYmVpIGRlciBLb250cm9sbGUgdm9yenV6ZWlnZW4uPGJyLz4KQmVpIEZhaHJrYXJ0ZW4gbWl0IEJhaG5DYXJkLVJhYmF0dCB6ZWlnZW4gU2llIGJpdHRlIHp1c8OkdHpsaWNoIElocmUgZ8O8bHRpZ2UgQmFobkNhcmQgdm9yLjxici8+Cjxici8+ClN0b3JubyBrb3N0ZW5mcmVpIGJpcyAxIFRhZyB2b3IgMS4gR2VsdHVuZ3N0YWcuPGJyLz4KPGJyLz4KQXVmdHJhZ3MtTnI6IFhYWFhYWDxici8+Ckdlc2FtdHByZWlzOiA0Miw5MCBFVVI8YnIvPgpHZWJ1Y2h0IGFtIDEyLjA1LjIwMjMgdW0gMjM6NTcgVWhyPGJyLz4KPC9wPg==", 161 | "$": { 162 | "name": "httext", 163 | "pos": "2", 164 | "type": "text/html;base64" 165 | } 166 | }, 167 | { 168 | "_": "\n\t\tbody {\n\t\t\tfont-family: sans-serif;\n\t\t\tfont-size: 16px;\n\t\t\tfont-size: 1rem;\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.barcode img,\n\t\t.sichtmerkmal img {\n\t\t\twidth: 90%;\n\t\t}\n\n\t\tp.AngebotBezeichnung,\n\t\t.httext {\n\t\t\tpadding-left: 1em;\n\t\t\tpadding-right: 1em;\n\t\t\ttext-align: left;\n\t\t\tline-height: 1.1;\n\t\t\tword-break: break-word;\n\t\t}\n\n\t\t.httext h4 {\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 1.1rem;\n\t\t}\n\n\t\tp.CityMobilTarifangaben {\n\t\t\tmargin: 0 1em;\n\t\t\tpadding-left: 0;\n\t\t\tpadding-right: 0;\n\t\t\tfont-weight: bold;\n\t\t}\n\t\t\n\t\t.ShtAngebotbezeichnung {\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 1.1rem;\n\t\t}\n\t\t\n\t\t.OsaIPSIProduktbezeichnung {\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 1.1rem;\n\t\t}\n\t\t\n\t\t.OsaIPSIKondition {\n\t\t\tfont-size: 0.8rem;\n\t\t}\n\t", 169 | "$": { 170 | "name": "htstyle", 171 | "pos": "2", 172 | "type": "text/css" 173 | } 174 | }, 175 | { 176 | "_": "data:image/png;base64,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", 177 | "$": { 178 | "name": "sichtmerkmal", 179 | "pos": "10", 180 | "type": "image/png;base64" 181 | } 182 | } 183 | ] 184 | } 185 | ], 186 | "mtk": [ 187 | { 188 | "$": { 189 | "dir": "1", 190 | "status": "8" 191 | }, 192 | "txt": [ 193 | "Einfache Fahrt, Flexpreis, 2. Kl., 1 Erw., BC 50, Berlin+City/Hamburg+City#" 194 | ], 195 | "zb": [ 196 | "N" 197 | ], 198 | "iss": [ 199 | "80" 200 | ], 201 | "tkey": [ 202 | "XXXXXX-5" 203 | ], 204 | "ot_nr_hin": [ 205 | "800000048" 206 | ], 207 | "reisender_vorname": [ 208 | "Erika" 209 | ], 210 | "reisender_nachname": [ 211 | "Musterman" 212 | ], 213 | "bc": [ 214 | { 215 | "rbs": [ 216 | "50" 217 | ], 218 | "anz": [ 219 | "1" 220 | ] 221 | } 222 | ], 223 | "nvplist": [ 224 | { 225 | "nvp": [ 226 | { 227 | "_": "1 BC 50", 228 | "$": { 229 | "name": "k_erm_db" 230 | } 231 | }, 232 | { 233 | "_": "1", 234 | "$": { 235 | "name": "anzerw" 236 | } 237 | }, 238 | { 239 | "_": "0", 240 | "$": { 241 | "name": "anzkind" 242 | } 243 | }, 244 | { 245 | "_": "S2", 246 | "$": { 247 | "name": "klasse" 248 | } 249 | }, 250 | { 251 | "_": "NP", 252 | "$": { 253 | "name": "preisartcodedb" 254 | } 255 | }, 256 | { 257 | "_": "Berlin Hbf (tief)", 258 | "$": { 259 | "name": "tpevahstart" 260 | } 261 | }, 262 | { 263 | "_": "Hamburg-Altona", 264 | "$": { 265 | "name": "tpevahziel" 266 | } 267 | }, 268 | { 269 | "_": "8", 270 | "$": { 271 | "name": "status" 272 | } 273 | }, 274 | { 275 | "_": "Berlin+City", 276 | "$": { 277 | "name": "citystart" 278 | } 279 | }, 280 | { 281 | "_": "Hamburg+City", 282 | "$": { 283 | "name": "cityziel" 284 | } 285 | } 286 | ] 287 | } 288 | ] 289 | } 290 | ] 291 | } 292 | ] 293 | } 294 | ], 295 | "posinfolist": [ 296 | { 297 | "posinfo": [ 298 | { 299 | "$": { 300 | "dir": "1", 301 | "dirlabel": "none", 302 | "posnr": "2", 303 | "shownr": "1002", 304 | "state": "8", 305 | "type": "TCK", 306 | "typeinfo": "0", 307 | "vfo": "2023-05-14T00:00:00", 308 | "vto": "2023-05-15T23:59:59" 309 | }, 310 | "childlist": [ 311 | { 312 | "posinfo": [ 313 | { 314 | "$": { 315 | "dir": "1", 316 | "dirlabel": "none", 317 | "posnr": "1", 318 | "shownr": "1100", 319 | "state": "8", 320 | "type": "EVA", 321 | "typeinfo": "0", 322 | "vfo": "2023-05-14T13:38:00", 323 | "vto": "2023-05-14T16:22:00" 324 | }, 325 | "childlist": [ 326 | "" 327 | ] 328 | } 329 | ] 330 | } 331 | ] 332 | } 333 | ] 334 | } 335 | ], 336 | "txt": [ 337 | "Berlin Hbf (tief) - Hamburg-Altona" 338 | ] 339 | } 340 | ] 341 | } 342 | } --------------------------------------------------------------------------------