diff --git a/src/extractors/czechrailways.js b/src/extractors/czechrailways.js index 74e5692..2f2fb80 100644 --- a/src/extractors/czechrailways.js +++ b/src/extractors/czechrailways.js @@ -1,155 +1,155 @@ /* Copyright (c) 2017 Volker Krause Copyright (c) 2018 Daniel Vrátil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ function isHeaderOrFooter(line) { return line.search(/(Jízdní řád( a rezervace)?|Jízdenku lze použít po stejné trase|Jízdní doklad zakoupený u obchodníka)/) >= 0; } function createSeat(res) { if (!res.reservedTicket) res.reservedTicket = JsonLd.newObject("Ticket"); if (!res.reservedTicket.ticketedSeat) res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); } function parseSeat(res, text) { var coach = text.match(/(\s+)(\d+)/); var idx = 0; if (coach) { createSeat(res); res.reservedTicket.ticketedSeat.seatSection = coach[2]; idx = coach.index + coach[1].length + coach[2].length; } var seat = text.substr(idx).match(/\s+(\d+)/); if (seat) { createSeat(res); res.reservedTicket.ticketedSeat.seatNumber = seat[1]; } } // There's no validity year anywhere in the ticket, so we take the purchase date and // if the trip month and day are after the purchase month and day we assume the // the ticket will become valid the same year it was purchased, otherwise we assume // the ticket is for next year. // This fails when you buy the ticket more than a year ahead of the trip, but I doubt // you can even do that with Czech Railways... function detectYear(tripDate, purchaseDate) { var tripDay = parseInt(tripDate[1]); var tripMonth = parseInt(tripDate[2]); var purchaseDay = parseInt(purchaseDate[2]); var purchaseMonth = parseInt(purchaseDate[3]); var purchaseYear = parseInt(purchaseDate[4]); if ((purchaseMonth < tripMonth) || - (purchaseMonth == tripMonth) && (purchaseDay <= tripDay)) { + (purchaseMonth === tripMonth) && (purchaseDay <= tripDay)) { return purchaseYear; } else { return purchaseYear + 1; } } function parseDeparture(res, line, purchaseDate) { res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); var station = line.match(/^(.+?) /); if (!station) return; var idx = station.index + station[0].length; res.reservationFor.departureStation.name = station[1]; var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); if (dt) { idx += dt.index + dt[0].length; res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); } var trainId = line.substr(idx).match(/([a-zA-Z]+ [0-9a-zA-Z]+)/); if (trainId) { idx += trainId.index + trainId[0].length res.reservationFor.trainNumber = trainId[1]; } parseSeat(res, line.substr(idx)); } function parseArrival(res, line, purchaseDate) { res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); var station = line.match(/^(.+?) /); if (!station) return; var idx = station.index + station[0].length; res.reservationFor.arrivalStation.name = station[1]; var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); if (dt) { idx += dt.index + dt[0].length; res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); } } function parseLegs(text, purchaseDate) { var reservations = new Array(); var lines = text.split('\n'); var depIdx = 1, arrIdx = 2; while (depIdx < lines.length) { // stop when reaching the footer or the next itinerary header if (isHeaderOrFooter(lines[depIdx])) return reservations; var res = JsonLd.newObject("TrainReservation"); res.reservationFor = JsonLd.newObject("TrainTrip"); arrIdx = depIdx + 1; parseDeparture(res, lines[depIdx], purchaseDate); parseArrival(res, lines[arrIdx], purchaseDate); depIdx = arrIdx + 1; // Find the next leg while (lines[depIdx].startsWith(" ")) { depIdx += 1; } reservations.push(res); } return reservations; } function main(text) { var reservations = new Array(); var pos = 0; var purchaseDate = text.match(/([d|D]atum platby|UZP): ([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})/) while (true) { // find itinerary headers var header = text.substr(pos).match(/Timetable( and Reservations)?/); if (!header) break; var idx = header.index + header[0].length; var timetableHeader = text.substr(pos + idx).match(/(Místo \/ Seat \/ Sitzplatz)/) idx = idx + timetableHeader.index + timetableHeader[0].length; reservations = reservations.concat(parseLegs(text.substr(pos + idx), purchaseDate)); if (idx == 0) break; pos += idx + 1; } var bookingRef = text.match(/Kód transakce:\s*([A-Z0-9]{6})\n/); for (var i = 0; bookingRef && i < reservations.length; ++i) reservations[i].reservationNumber = bookingRef[1]; return reservations; } diff --git a/src/extractors/deutschebahn.js b/src/extractors/deutschebahn.js index 0ae1917..fb5be11 100644 --- a/src/extractors/deutschebahn.js +++ b/src/extractors/deutschebahn.js @@ -1,188 +1,188 @@ /* Copyright (c) 2017 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ function isHeaderOrFooter(line) { return line.search(/(Ihre Reiseverbindung|Wichtige Nutzungshinweise|Hinweise:|Seite \d \/ \d)/) >= 0; } function parseSeat(res, text) { var coach = text.match(/Wg. (\d+)/); if (coach) res.reservedTicket.ticketedSeat.seatSection = coach[1]; var seat = text.match(/Pl. (\d+)/); if (seat) res.reservedTicket.ticketedSeat.seatNumber = seat[1]; } function parseDeparture(res, line, year, compact) { res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); var station = line.match(/^(.+?) /); if (!station) return; var idx = station.index + station[0].length; res.reservationFor.departureStation.name = station[1]; var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. +ab ([0-9]{2}:[0-9]{2})/); if (dt) { idx += dt.index + dt[0].length; res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + year + ' ' + dt[3], "dd MM yyyy hh:mm", "de"); } var platform = line.substr(idx).match(/^ {1,3}(.*?)(?=( | IC|$))/); if (platform) { idx += platform.index + platform[0].length; res.reservationFor.departurePlatform = platform[1]; } var trainId = line.substr(idx).match(compact ? / +([^,]*?)(?=(,|$))/ : / +(.*?)(?=( |$))/); if (trainId) { idx += trainId.index + trainId[0].length res.reservationFor.trainNumber = trainId[1]; } parseSeat(res, line.substr(idx)); } function parseArrival(res, line, year) { res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); var station = line.match(/^(.+?) /); if (!station) return; var idx = station.index + station[0].length; res.reservationFor.arrivalStation.name = station[1]; var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. +an ([0-9]{2}:[0-9]{2})/); if (dt) { idx += dt.index + dt[0].length; res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + year + ' ' + dt[3], "dd MM yyyy hh:mm", "de"); } var platform = line.substr(idx).match(/^ {1,3}(.*?)(?=( | IC|$))/); if (platform) { idx += platform.index + platform[0].length; res.reservationFor.arrivalPlatform = platform[1]; } parseSeat(res, line.substr(idx)); } function parseLegs(text, year, compact) { var reservations = new Array(); var lines = text.split('\n'); for (var i = 0; compact && i < lines.length; ++i) lines[i] = lines[i].substr(6); var depIdx = 0, arrIdx = 1; while (depIdx < lines.length) { var res = JsonLd.newObject("TrainReservation"); res.reservationFor = JsonLd.newObject("TrainTrip"); res.reservedTicket = JsonLd.newObject("Ticket"); res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); // stop when reaching the footer or the next itinerary header if (isHeaderOrFooter(lines[depIdx])) return reservations; arrIdx = depIdx + 1; while (arrIdx < lines.length && lines[arrIdx].startsWith(' ')) // line continuations for departure, we still need to handle that correctly ++arrIdx; parseDeparture(res, lines[depIdx], year, compact); parseArrival(res, lines[arrIdx], year); depIdx = arrIdx + 1; while (depIdx < lines.length && lines[depIdx].startsWith(' ') && !isHeaderOrFooter(lines[depIdx])) // line continuations for arrival, dito ++depIdx; reservations.push(res); } return reservations; } function parseText(text) { // used by unit tests return parseTicket(text, null); } function parseTicket(text, uic918ticket) { var reservations = new Array(); var pos = 0; var returnResIndex = 0; while (true) { // find itinerary headers var header = text.substr(pos).match(/Ihre Reiseverbindung[\S ]+(Hin|Rück)fahrt am [0-9]{2}.[0-9]{2}.([0-9]{4}).*\n/); if (!header) break; var idx = header.index + header[0].length; var year = header[2]; // determine ticket type var domesticHeader = text.substr(pos + idx).match(/ Reservierung\n/); var intlHeader = text.substr(pos + idx).match(/(Produkte\/Reservierung|Fahrt\/Reservierung).*\n/); if (domesticHeader) { idx += domesticHeader.index + domesticHeader[0].length; reservations = reservations.concat(parseLegs(text.substr(pos + idx), year, false)); } else if (intlHeader) { idx += intlHeader.index + intlHeader[0].length; reservations = reservations.concat(parseLegs(text.substr(pos + idx), year, true)); } else { break; } // for outward journeys we have station ids from the UIC 918-3 code - if (uic918ticket && header[1] == "Hin") { + if (uic918ticket && header[1] === "Hin") { reservations[0].reservationFor.departureStation.identifier = uic918ticket.outboundDepartureStationId; reservations[reservations.length - 1].reservationFor.arrivalStation.identifier = uic918ticket.outboundArrivalStationId; returnResIndex = reservations.length; } else { // propagate station ids from outward to return journey for (var i = returnResIndex; i < reservations.length; ++i) { for (var j = 0; j < returnResIndex; ++j) { - if (reservations[i].reservationFor.departureStation.name == reservations[j].reservationFor.arrivalStation.name) + if (reservations[i].reservationFor.departureStation.name === reservations[j].reservationFor.arrivalStation.name) reservations[i].reservationFor.departureStation.identifier = reservations[j].reservationFor.arrivalStation.identifier; - if (reservations[i].reservationFor.arrivalStation.name == reservations[j].reservationFor.departureStation.name) + if (reservations[i].reservationFor.arrivalStation.name === reservations[j].reservationFor.departureStation.name) reservations[i].reservationFor.arrivalStation.identifier = reservations[j].reservationFor.departureStation.identifier; } } } if (idx == 0) break; pos += idx; } // international tickets have the booking reference somewhere on the side, so we don't really know // where it is relative to the itinerary var bookingRef = text.match(/Auftragsnummer:\s*([A-Z0-9]{6})\n/); for (var i = 0; i < reservations.length; ++i) reservations[i].reservationNumber = bookingRef[1]; return reservations; } function parsePdf(pdf) { // try to find the UIC918.3 barcode var images = pdf.pages[0].imagesInRect(0.6, 0, 1, 1); var barcode = null; var uic918ticket = null; for (var i = 0; i < images.length && !barcode; ++i) { - if (images[i].width == images[i].height) { + if (images[i].width === images[i].height) { barcode = Barcode.decodeAztecBinary(images[i]); uic918ticket = Barcode.decodeUic9183(barcode); break; } } console.log(barcode, uic918ticket, !barcode); var reservations = parseTicket(pdf.text, uic918ticket); for (var i = 0; i < reservations.length && barcode; ++i) { reservations[i].reservedTicket.ticketToken = "aztecbin:" + Barcode.toBase64(barcode); reservations[i].underName = JsonLd.toJson(uic918ticket.person); } return reservations; } diff --git a/src/extractors/regiojet.js b/src/extractors/regiojet.js index bb384e7..8e39fb0 100644 --- a/src/extractors/regiojet.js +++ b/src/extractors/regiojet.js @@ -1,217 +1,217 @@ /* Copyright (c) 2017 Volker Krause Copyright (c) 2018 Daniel Vrátil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ var regExMap = new Array(); regExMap["cs_CZ"] = new Array(); regExMap["cs_CZ"]["ticketId"] = /Elektronická jízdenka č\.\s+([0-9]+)/; regExMap["cs_CZ"]["singleTripHeader"] = /Cesta/; regExMap["cs_CZ"]["thereTripHeader"] = /Cesta tam/; regExMap["cs_CZ"]["returnTripHeader"] = /Cesta zpět/; regExMap["cs_CZ"]["columns"] = [ /Datum/, /Zastávka\/Přestup/, /Příjezd/, /Odjezd/, /Nást\./, /Spoj/, /Vůz\/sedadla/ ]; regExMap["cs_CZ"]["date"] = /([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{2})/; regExMap["en_US"] = new Array(); regExMap["en_US"]["ticketId"] = /Electronic ticket\s+([0-9]+)/; regExMap["en_US"]["singleTripHeader"] = /Route/; regExMap["en_US"]["thereTripHeader"] = /Route there/; regExMap["en_US"]["returnTripHeader"] = /Route back/; regExMap["en_US"]["columns"] = [ /Date/, /Station\/Transfer/, /Arrival/, /Departure/, /Platf\./, /Connection/, /Coach\/Seats/ ]; regExMap["en_US"]["date"] = /([0-9]{2})\/([0-9]{2})\/([0-9]{2})/; function padDigit(s) { while (s.length < 2) { s = '0' + s; } return s; } function parseDate(date, time, locale) { var d = date.match(regExMap[locale]["date"]); var t = time.match(/([0-9]{1,2}):([0-9]{1,2})/); if (!d || !t) { return null; } return JsonLd.toDateTime(padDigit(d[1]) + "." + padDigit(d[2]) + ".20" + d[3] + " " + padDigit(t[1]) + ":" + padDigit(t[2]), "dd.MM.yyyy HH:mm", locale); } var Columns = Object.freeze({ Date: 0, Station: 1, ArrivalTime: 2, DepartureTime: 3, Platform: 4, Connection: 5, Seat: 6, ColumnCount: 7 }); function columnValue(line, columns, column, locale) { var start = columns.match(regExMap[locale]["columns"][column]); if (!start) { return ""; } if (column < Columns.ColumnCount - 1) { var end = columns.match(regExMap[locale]["columns"][column + 1]); if (!end) { return ""; } return line.substr(start.index, end.index - start.index).trim(); } else { return line.substr(start.index).trim(); } } function parseTrip(trip, locale) { var text = trip.split("\n") var columns = text[0]; var reservations = new Array(); var transportType = "Bus"; for (var i = 1; i < text.length; i++) { // Skip the destination arrival part, we already populated it as part // of completing the previous departure line if (i < text.length - 1 && !text[i + 1]) { break; } var connection = columnValue(text[i], columns, Columns.Connection, locale); var number = null; var name = null; if (connection) { var split = connection.lastIndexOf("(") name = connection.substr(0, split - 1); number = connection.substr(split + 1, connection.length - split - 2); transportType = number.match(/RJ [0-9]+/) ? "Train" : "Bus"; } var res = JsonLd.newObject(transportType + "Reservation"); res.reservationFor = JsonLd.newObject(transportType + "Trip"); if (transportType == "Bus") { if (number) { res.reservationFor.busNumber = number; } if (name) { res.reservationFor.busName = name; } } else if (transportType == "Train") { if (number) { res.reservationFor.trainNumber = number; } if (name) { res.reservationFor.trainName = name; } } var arrivalTime = columnValue(text[i + 1], columns, Columns.ArrivalTime, locale); var arrivalDate = columnValue(text[i + 1], columns, Columns.Date, locale); if (!arrivalTime) { arrivalTime = columnValue(text[i], columns, Columns.ArrivalTime, locale); } if (!arrivalDate) { arrivalDate = columnValue(text[i], columns, Columns.Date, locale); } if (arrivalDate && arrivalTime) { res.reservationFor.arrivalStation = JsonLd.newObject(transportType + "Station"); res.reservationFor.arrivalStation.name = columnValue(text[i+1], columns, Columns.Station, locale); res.reservationFor.arrivalTime = parseDate(arrivalDate, arrivalTime, locale); } var departureTime = columnValue(text[i], columns, Columns.DepartureTime, locale); var departure = ""; - if (departureTime != "") { + if (departureTime !== "") { departure = text[i]; } else if (i > 0) { departure = text[i - 1]; departureTime = columnValue(departure, columns, Columns.DepartureTime, locale); } if (departure) { res.reservationFor.departureStation = JsonLd.newObject(transportType + "Station"); res.reservationFor.departureStation.name = columnValue(departure, columns, Columns.Station, locale); res.reservationFor.departureTime = parseDate(columnValue(departure, columns, Columns.Date, locale), departureTime, locale); var platform = columnValue(departure, columns, Columns.Platform, locale); if (platform) { res.reservationFor.departurePlatform = platform; } // seats are always bound to departur var seat = columnValue(departure, columns, Columns.Seat, locale); if (seat) { var r = seat.match(/([0-9]+)\/([0-9]+)/); res.reservedTicket = JsonLd.newObject("Ticket"); res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); if (r) { res.reservedTicket.ticketedSeat.seatSection = r[1]; res.reservedTicket.ticketedSeat.seatNumber = r[2]; } else { res.reservedTicket.ticketedSeat.seatNumber = seat; } } } reservations.push(res); } return reservations; } function main(text) { var reservations = new Array(); for (var locale in regExMap) { var ticketId = text.match(regExMap[locale]["ticketId"]); if (!ticketId) { continue; } var resUrl = text.match(/http(s)?:\/\/jizdenky\.(regiojet|studentagency)\.cz\/OnlineTicket\?pam1=[0-9]+\&pam2=[0-9]+/) var returnHeader = text.match(regExMap[locale]["returnTripHeader"]); - var isReturn = (returnHeader != null); + var isReturn = (returnHeader !== null); var routeHeader = text.match(regExMap[locale][isReturn ? "thereTripHeader" : "singleTripHeader"]); if (!routeHeader) { break; } var trip = text.substr(routeHeader.index + routeHeader[0].length + 1); var newRes = parseTrip(trip, locale); - if (newRes.length == 0) { + if (newRes.length === 0) { break; } reservations = reservations.concat(newRes); if (isReturn) { trip = text.substr(returnHeader.index + returnHeader[0].length + 1); reservations = reservations.concat(parseTrip(trip, locale)); } for (var i = 0; i < reservations.length; ++i) { reservations[i].reservationNumber = ticketId[1]; if (resUrl) { reservations[i].modifyReservationUrl = resUrl[0]; } } // No need to scan any further locales break; } return reservations; } diff --git a/src/extractors/sncf.js b/src/extractors/sncf.js index c39415b..33d7af9 100644 --- a/src/extractors/sncf.js +++ b/src/extractors/sncf.js @@ -1,128 +1,128 @@ /* Copyright (c) 2017 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ function parseText(text) { var reservations = new Array(); var bookingRef = text.match(/DOSSIER VOYAGE : +([A-Z0-9]{6})/); var pos = 0; while (true) { var header = text.substr(pos).match(/ +Départ \/ Arrivée.*\n/); if (!header) break; var index = header.index + header[0].length; var res = JsonLd.newObject("TrainReservation"); res.reservedTicket = JsonLd.newObject("Ticket"); res.reservationNumber = bookingRef[1]; res.reservationFor = JsonLd.newObject("TrainTrip"); var depLine = text.substr(pos + index).match(/\n {2,3}([\w -]+?) +(\d{2}\/\d{2}) à (\d{2}h\d{2})/); if (!depLine) break; index += depLine.index + depLine[0].length; res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); res.reservationFor.departureStation.name = depLine[1]; res.reservationFor.departureTime = JsonLd.toDateTime(depLine[2] + " " + depLine[3], "dd/MM hh'h'mm", "fr"); var arrLine = text.substr(pos + index).match(/\n {2,3}([\w -]+?) +(\d{2}\/\d{2}) à (\d{2}h\d{2})/); if (!arrLine) break; index += arrLine.index + arrLine[0].length; res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); res.reservationFor.arrivalStation.name = arrLine[1]; res.reservationFor.arrivalTime = JsonLd.toDateTime(arrLine[2] + " " + arrLine[3], "dd/MM hh'h'mm", "fr"); // parse seat, train number, etc from the text for one leg // since the stations are vertically centered, the stuff we are looking for might be at different // positions relative to them var legText = text.substring(pos + header.index + header[0].length, pos + index); var trainNumber = legText.match(/TRAIN N° ?(\d{3,4})/); if (trainNumber) res.reservationFor.trainNumber = trainNumber[1]; var seatRes = legText.match(/(VOITURE|COACH) (\d+) - PLACE (\d+)/); if (seatRes) { res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); res.reservedTicket.ticketedSeat.seatSection = seatRes[2]; res.reservedTicket.ticketedSeat.seatNumber = seatRes[3]; } reservations.push(res); if (index == 0) break; pos += index; } return reservations; } function parsePdf(pdf) { var reservations = new Array(); for (var i = 0; i < pdf.pageCount; ++i) { var page = pdf.pages[i]; // barcode format: // 'i0CV' // 6x PNR // 9x document id // '1211' // dd/MM/yyyy birthdate // 2x 5x gare & connextion ids of the first leg // 5x train number first leg // dd/MM travel date // 18x client id // 19x family name // 19x given name // 1x class // 4x stuff // '1' to indicate a second leg, '0' otherwise // 2x 5x gare & connexion ids for the second leg // 5x train number second leg var barcode = null; var images = page.imagesInRect(0.75, 0, 1, 0.75); for (var j = 0; j < images.length && !barcode; ++j) { if (Math.abs(images[j].width - images[j].height) < 10) {// almost square barcode = Barcode.decodeAztec(images[j]); - if (barcode.substr(0, 4).toUpperCase() != "I0CV") + if (barcode.substr(0, 4).toUpperCase() !== "I0CV") barcode = null; } } var underName = null; if (barcode) { var underName = JsonLd.newObject("Person"); underName.familyName = barcode.substring(73, 91).trim(); underName.givenName = barcode.substring(92, 110).trim(); } var legs = parseText(page.text); for (var j = 0; j < legs.length; ++j) { if (barcode) { legs[j].underName = underName; legs[j].reservedTicket.ticketToken = "aztecCode:" + barcode; legs[j].reservationFor.departureStation.identifier = "sncf:" + barcode.substr(j == 0 ? 33 : 116, 5); legs[j].reservationFor.arrivalStation.identifier = "sncf:" + barcode.substr(j == 0 ? 38 : 121, 5); } reservations.push(legs[j]); } } return reservations; }