function similar(s, t, f) {
if (!s || !t) {
return 0
}
var l = s.length > t.length ? s.length : t.length
var n = s.length
var m = t.length
var d = []
f = f || 3
var min = function (a, b, c) {
return a < b ? (a < c ? a : c) : (b < c ? b : c)
}
var i, j, si, tj, cost
if (n === 0) return m
if (m === 0) return n
for (i = 0; i <= n; i++) {
d[i] = []
d[i][0] = i
}
for (j = 0; j <= m; j++) {
d[0][j] = j
}
for (i = 1; i <= n; i++) {
si = s.charAt(i - 1)
for (j = 1; j <= m; j++) {
tj = t.charAt(j - 1)
if (si === tj) {
cost = 0
} else {
cost = 1
}
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)
}
}
let res = (1 - d[n][m] / l)
return res.toFixed(f)
}
document.write(JSON.stringify('XXX00000'.match(/^(X+)?(0+)?(X+)?(0+)?$/i)))
let customFormat = 'XXX000000XX'
customFormat = customFormat.toUpperCase()
let formatMatches = customFormat.match(/^(X+)?(0+)?(X+)?(0+)?$/i)
let formatString = '^'
if (formatMatches && formatMatches.length) {
for (var i = 1; i < formatMatches.length; i++) {
let part = formatMatches[i]
if (part && part.indexOf('X') != -1) {
formatString += '([A-Za-z]+[:|.])?[A-Z]{' + part.length + '}'
} else if (part && part.indexOf('0') != -1) {
formatString += '\\d{' + part.length + '}'
}
}
}
document.writeln(formatString)
let reg = new RegExp(formatString)
document.writeln(reg.test('SIU000123XE'))
let scan_rest = { "log_id": 226078132009692600, "words_result_num": 104, "words_result": [{ "location": { "width": 82, "top": 46, "left": 650, "height": 61 }, "words": "mix" }, { "location": { "width": 528, "top": 146, "left": 120, "height": 35 }, "words": "spate amF iB add , : 72094 snipers Accoun Number" }, { "location": { "width": 29, "top": 166, "left": 703, "height": 16 }, "words": "Not" }, { "location": { "width": 63, "top": 167, "left": 759, "height": 17 }, "words": "notable" }, { "location": { "width": 217, "top": 153, "left": 1074, "height": 25 }, "words": "- HIEN20296941" }, { "location": { "width": 343, "top": 186, "left": 119, "height": 21 }, "words": "Samsung Electronics Co . Ltd" }, { "location": { "width": 502, "top": 205, "left": 121, "height": 25 }, "words": "129 , Samsung-ro , Yeongtong-gu suwon 16677" }, { "location": { "width": 129, "top": 187, "left": 701, "height": 29 }, "words": "Air Waybill" }, { "location": { "width": 76, "top": 213, "left": 702, "height": 19 }, "words": "Issued by" }, { "location": { "width": 341, "top": 226, "left": 119, "height": 23 }, "words": "Gyeonggi-do South Korea C100" }, { "location": { "width": 208, "top": 235, "left": 846, "height": 18 }, "words": "HANARO TNS CO , LTD" }, { "location": { "width": 224, "top": 246, "left": 115, "height": 20 }, "words": "ITEL : 82-2-2255-0114" }, { "location": { "width": 487, "top": 268, "left": 756, "height": 19 }, "words": "RODEM BLDG395-85 SDOKYO-DONG MAEO-GULSEOU" }, { "location": { "width": 574, "top": 282, "left": 700, "height": 31 }, "words": "capit : 2 amPoL this Air Waybill are originals and have the same validity" }, { "location": { "width": 237, "top": 317, "left": 124, "height": 20 }, "words": "Consignee's Name and Address" }, { "location": { "width": 550, "top": 317, "left": 435, "height": 27 }, "words": "Consignee's Account Number Received in Good Order and Condition" }, { "location": { "width": 370, "top": 344, "left": 121, "height": 19 }, "words": "SHANGHAI SAMSUNG SEMICONDUCTON CO , LTD" }, { "location": { "width": 280, "top": 356, "left": 120, "height": 23 }, "words": "64 + WAREHOUSE , NO 99 HANCHENG" }, { "location": { "width": 400, "top": 373, "left": 119, "height": 20 }, "words": "WAIGAOQIAO FREE TRADE ZONE , SHANGHAI 200131" }, { "location": { "width": 183, "top": 390, "left": 120, "height": 20 }, "words": "SHANGHAI CHINA C6G0" }, { "location": { "width": 176, "top": 408, "left": 120, "height": 17 }, "words": "TEL : 86-21-23253526" }, { "location": { "width": 76, "top": 404, "left": 1065, "height": 20 }, "words": "( date / time )" }, { "location": { "width": 188, "top": 421, "left": 118, "height": 23 }, "words": "ATTN Jeffrey Chen" }, { "location": { "width": 173, "top": 441, "left": 120, "height": 16 }, "words": "TE 86-21-2325352" }, { "location": { "width": 286, "top": 478, "left": 126, "height": 19 }, "words": "Issuing Carrier's Agent Name and City" }, { "location": { "width": 167, "top": 481, "left": 693, "height": 18 }, "words": "Accounting Information" }, { "location": { "width": 230, "top": 522, "left": 124, "height": 21 }, "words": "HANARO TNS CO , LTD" }, { "location": { "width": 211, "top": 516, "left": 702, "height": 29 }, "words": "SAME AS CONSIGNEE" }, { "location": { "width": 144, "top": 582, "left": 126, "height": 19 }, "words": "Agent's lATA Code" }, { "location": { "width": 92, "top": 582, "left": 404, "height": 20 }, "words": "Account No" }, { "location": { "width": 379, "top": 597, "left": 700, "height": 27 }, "words": "CNE ID : USCI91310115729505281U" }, { "location": { "width": 142, "top": 622, "left": 127, "height": 16 }, "words": "17-3254700" }, { "location": { "width": 485, "top": 636, "left": 126, "height": 21 }, "words": "Airport of Departure ( Addr . of First Carrier ) and Requested Routing" }, { "location": { "width": 384, "top": 637, "left": 714, "height": 23 }, "words": "Reference Number Optional Shipping Informalion" }, { "location": { "width": 153, "top": 669, "left": 125, "height": 16 }, "words": "INCHEON KOREA" }, { "location": { "width": 21, "top": 688, "left": 125, "height": 16 }, "words": "To" }, { "location": { "width": 243, "top": 686, "left": 186, "height": 22 }, "words": "By First Carier Routing and Destination" }, { "location": { "width": 639, "top": 686, "left": 640, "height": 26 }, "words": "by Currency WT / VAL Other Declared Value for carage Declared Value for Customs" }, { "location": { "width": 159, "top": 704, "left": 748, "height": 25 }, "words": "Code coulPpDcodl" }, { "location": { "width": 24, "top": 723, "left": 195, "height": 16 }, "words": "KE" }, { "location": { "width": 155, "top": 742, "left": 183, "height": 19 }, "words": "Airport of Destination" }, { "location": { "width": 127, "top": 740, "left": 477, "height": 21 }, "words": "Requested Flight / Date" }, { "location": { "width": 117, "top": 744, "left": 705, "height": 16 }, "words": "mount of Insura" }, { "location": { "width": 346, "top": 730, "left": 920, "height": 32 }, "words": "Para me mmn ASPEE INYOTCE" }, { "location": { "width": 418, "top": 758, "left": 862, "height": 21 }, "words": "quested in accordance with the conditions thereof , indicale amount to" }, { "location": { "width": 126, "top": 774, "left": 122, "height": 17 }, "words": "PUDONG , CHINA" }, { "location": { "width": 54, "top": 784, "left": 405, "height": 11 }, "words": "anDO" }, { "location": { "width": 105, "top": 783, "left": 527, "height": 16 }, "words": "14MA2029" }, { "location": { "width": 37, "top": 787, "left": 736, "height": 21 }, "words": "NEE" }, { "location": { "width": 393, "top": 775, "left": 863, "height": 21 }, "words": "be insured in figures in box marked Amount of Insurance" }, { "location": { "width": 152, "top": 792, "left": 124, "height": 20 }, "words": "Handling Information" }, { "location": { "width": 507, "top": 824, "left": 116, "height": 21 }, "words": "COMMERCIAL INVOICE PACKING LIST ATTACHED" }, { "location": { "width": 29, "top": 851, "left": 1173, "height": 16 }, "words": "SCI" }, { "location": { "width": 43, "top": 899, "left": 129, "height": 15 }, "words": "No of" }, { "location": { "width": 199, "top": 902, "left": 212, "height": 20 }, "words": "Gross kgl Rate Class" }, { "location": { "width": 87, "top": 902, "left": 475, "height": 22 }, "words": "Chargeable" }, { "location": { "width": 37, "top": 918, "left": 807, "height": 15 }, "words": "Total" }, { "location": { "width": 222, "top": 907, "left": 997, "height": 19 }, "words": "Nature and Quantity of Goods" }, { "location": { "width": 53, "top": 926, "left": 209, "height": 19 }, "words": "Weight" }, { "location": { "width": 53, "top": 927, "left": 491, "height": 18 }, "words": "Weight" }, { "location": { "width": 80, "top": 926, "left": 635, "height": 19 }, "words": "Charge" }, { "location": { "width": 217, "top": 926, "left": 1000, "height": 22 }, "words": "( incl . Dimensions or Volume )" }, { "location": { "width": 78, "top": 966, "left": 513, "height": 19 }, "words": "29 . 0K" }, { "location": { "width": 137, "top": 969, "left": 753, "height": 17 }, "words": "AS ARRANGED" }, { "location": { "width": 113, "top": 974, "left": 963, "height": 19 }, "words": "CARTON OF" }, { "location": { "width": 66, "top": 1003, "left": 143, "height": 18 }, "words": "S.E. C" }, { "location": { "width": 519, "top": 997, "left": 533, "height": 29 }, "words": "DIMt 41x40x26 , cm / al . = 7 . 10757x43x27 , MEMORY IC" }, { "location": { "width": 302, "top": 1026, "left": 143, "height": 25 }, "words": "china , Shanghai Pu Dong Apt" }, { "location": { "width": 32, "top": 1024, "left": 540, "height": 17 }, "words": "cm /" }, { "location": { "width": 50, "top": 1027, "left": 606, "height": 13 }, "words": ": 1 . 03" }, { "location": { "width": 122, "top": 1048, "left": 143, "height": 19 }, "words": "Total Cart" }, { "location": { "width": 204, "top": 1042, "left": 548, "height": 22 }, "words": "s8k43x27cm / 1 . = 11 ) 223" }, { "location": { "width": 230, "top": 1044, "left": 938, "height": 19 }, "words": "INV NO : 9014800296" }, { "location": { "width": 183, "top": 1063, "left": 142, "height": 29 }, "words": "FREIGHT PREPAII" }, { "location": { "width": 55, "top": 1318, "left": 164, "height": 18 }, "words": "Prepaid" }, { "location": { "width": 47, "top": 1321, "left": 450, "height": 16 }, "words": "Collec" }, { "location": { "width": 109, "top": 1320, "left": 560, "height": 17 }, "words": "Other Charges" }, { "location": { "width": 137, "top": 1351, "left": 197, "height": 18 }, "words": "AS ARRANGEI" }, { "location": { "width": 114, "top": 1371, "left": 287, "height": 20 }, "words": "luation Charge" }, { "location": { "width": 231, "top": 1476, "left": 212, "height": 19 }, "words": "Total Other Charges Due Agent" }, { "location": { "width": 710, "top": 1478, "left": 558, "height": 20 }, "words": "Shipper certifies that the particulars on the face hereof are correct and that insofar as any part of the" }, { "location": { "width": 708, "top": 1494, "left": 558, "height": 22 }, "words": "consignment contains dangerous goods , such part is properly described by name and is in proper" }, { "location": { "width": 637, "top": 1512, "left": 557, "height": 21 }, "words": "condition for carriage by air according to the applicable Dangerous Goods Regulations" }, { "location": { "width": 241, "top": 1529, "left": 204, "height": 20 }, "words": "Total Other Charges Due Carrier" }, { "location": { "width": 181, "top": 1555, "left": 821, "height": 17 }, "words": "HANARO INS CO , LTD" }, { "location": { "width": 165, "top": 1578, "left": 759, "height": 17 }, "words": "AGENT FOR CARRIER" }, { "location": { "width": 134, "top": 1580, "left": 965, "height": 16 }, "words": "KOREAN AIRLINE" }, { "location": { "width": 289, "top": 1602, "left": 786, "height": 30 }, "words": "Signature of Shipper or his Agent" }, { "location": { "width": 37, "top": 1634, "left": 173, "height": 16 }, "words": "Total" }, { "location": { "width": 70, "top": 1635, "left": 210, "height": 32 }, "words": "KSD2AGE" }, { "location": { "width": 79, "top": 1649, "left": 268, "height": 18 }, "words": "RRANGED" }, { "location": { "width": 134, "top": 1635, "left": 362, "height": 22 }, "words": "A Total Collect" }, { "location": { "width": 426, "top": 1682, "left": 113, "height": 32 }, "words": "Curency Conversion Rates CC Charges in Dest Curency" }, { "location": { "width": 135, "top": 1684, "left": 604, "height": 21 }, "words": "14-MAY-2020" }, { "location": { "width": 42, "top": 1684, "left": 823, "height": 19 }, "words": "ICN" }, { "location": { "width": 179, "top": 1684, "left": 948, "height": 21 }, "words": "ueong Jeong In" }, { "location": { "width": 139, "top": 1715, "left": 556, "height": 20 }, "words": "Executed on ( date )" }, { "location": { "width": 64, "top": 1714, "left": 823, "height": 19 }, "words": "at ( place )" }, { "location": { "width": 262, "top": 1715, "left": 1002, "height": 20 }, "words": "Signature of Issuing Carrier or its Agent" }, { "location": { "width": 156, "top": 1743, "left": 139, "height": 21 }, "words": "For Carrier's Use onl" }, { "location": { "width": 147, "top": 1743, "left": 373, "height": 19 }, "words": "Charges at Destination" }, { "location": { "width": 162, "top": 1740, "left": 580, "height": 18 }, "words": "Total Collect Charges" }, { "location": { "width": 102, "top": 1768, "left": 169, "height": 19 }, "words": "al Destination" }, { "location": { "width": 330, "top": 1790, "left": 520, "height": 36 }, "words": "COPY 4 ( DELIVERY RECEIPT )" }] }
const EFFECTIVE_TITLES = [{ name: "shipper", text: "SHIPPER'S NAME AND ADDRESS", leftOffset: 40, titleHeight: 30, bottom: 200 }, { name: "consignee", text: "CONSIGNEE'S NAME AND ADDRESS", leftOffset: 40, titleHeight: 30, bottom: 200 }, { name: "agent", text: "ISSUING CARRIER'S AGENT NAME AND CITY", leftOffset: 40, titleHeight: 30, bottom: 200 }, { name: "goods", text: "NATURE AND QUANTITY OF GOODS", leftOffset: 320, titleHeight: 40, bottom: 350 }, { name: "oc", text: "OTHER CHARGES", leftOffset: 120, titleHeight: 40, bottom: 300 }]
let word_parties = scan_rest.words_result.map(i => { return i.words })
let titles = getEffectiveTitles(scan_rest.words_result)
// console.log(JSON.stringify(titles))
const mawb_reg = new RegExp(/^\d{11}$/)
const lowercase_reg = new RegExp(/[a-z]+/)
const zh_reg = new RegExp(/.*[\u4e00-\u9fa5]+.*$/)
const line_height = 40
const page_offset_right = 250
var horizon_mid_line = 500
var section_one_offset_v = 0
var section_two_offset_v = 0
var setction_three_offest_v = 0
var vertical_region = 500
function getEffectiveTitles(origin) {
let res = {}
let lastMatch = 0
for (var i in EFFECTIVE_TITLES) {
let item = origin.findIndex((o, idx) => { return idx > lastMatch && similar(o.words.toUpperCase(), EFFECTIVE_TITLES[i].text) > 0.72 })
if (item != -1) {
res[EFFECTIVE_TITLES[i].name] = origin[item]
lastMatch = item
}
}
return res
}
/*let collections = {shipper:{}, consignee:{}, goods:{}}
for(var i in titles){
document.write('<p style="font-size:10px;position:absolute;top:'+titles[i].location.top/2+'px;left:'+titles[i].location.left/2+'px;">' + titles[i].words+ '</p>')
let parties = []
if(collections[i]){
parties.push(i.toString())
console.log(parties)
if(parties.length > 0){
let contents = getEffectiveParties(parties, titles, scan_rest.words_result)
console.log(JSON.stringify(contents))
for(var c in contents[i]){
document.write('<p style="font-size:10px;position:absolute;top:'+contents[i][c].location.top/2+'px;left:'+contents[i][c].location.left/2+'px;">' + contents[i][c].words+ '</p>')
}
}
}
}
*/
let allResult = scan_rest.words_result
for (var i in allResult) {
document.write('<div class="main">')
document.write('<p style="font-size:10px;position:absolute;top:' + allResult[i].location.top / 2 + 'px;left:' + allResult[i].location.left / 2 + 'px;">' + allResult[i].words + '</p>')
document.write('</div>')
}
let parties = getEffectiveParties(['shipper', 'consignee', 'goods'], titles, scan_rest.words_result)
let customers = getCustomerInfo(parties)
console.log(JSON.stringify(customers))
/*
let anchor_no = getMawbNumber(word_parties)
document.write('<input type="text" value="' + anchor_no.value + '" /><br>')
scan_rest.words_result = getEffectiveParties(anchor_no.key, scan_rest.words_result)
let res = getCustomerInfo(scan_rest.words_result)
document.write('<textarea rows="5" cols="43">' + res.shipper + '</textarea><br>')
document.write('<textarea rows="5" cols="43">' + res.consignee + '</textarea>')
word_parties = scan_rest.words_result.map(i=>{ return i.words })
for(var i in word_parties){
document.write('<p style="position:absolute;top:'+scan_rest.words_result[i].location.top+'px;left:'+scan_rest.words_result[i].location.left+'px;">' + word_parties[i] + '</p>')
}
*/
function getMawbNumber(parties) {
for (var i in parties) {
let str = parties[i].replace(/ /g, '')
if (str.length && mawb_reg.test(str) && parseInt(str.substr(3, 7)) % 7 == parseInt(str.substr(10, 1))) {
return { key: i, value: str.slice(0, 3) + '-' + str.slice(3) }
}
}
return null
}
function getEffectiveParties(parties, titles, origin) {
let res = {}
let title, titleTop, leftOffset, titleHeight, bottom
for (var p in parties) {
let t = EFFECTIVE_TITLES.findIndex(o => { return o.name === parties[p] })
title = titles[parties[p]]
console.log(JSON.stringify(title))
if (!title) {
break
}
titleTop = title.location.top
leftOffset = EFFECTIVE_TITLES[t].leftOffset
titleHeight = EFFECTIVE_TITLES[t].titleHeight
let nextTitle = EFFECTIVE_TITLES[t + 1]
if (nextTitle && titles[nextTitle.name]) {
bottom = titles[nextTitle.name].location.top
} else {
bottom = title.location.top + titleHeight + EFFECTIVE_TITLES[t].bottom
}
res[parties[p]] = origin.filter(r => {
return Math.abs(r.location.left - title.location.left) < leftOffset && r.location.top > title.location.top && r.location.top < bottom
})
}
console.log(Object.keys(res))
return res
}
function getCustomerInfo(parties, model) {
let res = model ? model : { shipper: '', consignee: '', goods: '' }
for (var i in res) {
if (parties && parties.length) {
res[i] = parties[i].map(o => { return o.words ? o.words.replace(/\"/g, '') : '' }).join('\n')
}
}
return res
}
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
function isDateTime(str) {
return !isNaN(new Date(str))
}
// document.write("<p>"+ similar("Shipper's Name and Address", "Shipper's Name and Address")+"</p>")
.main{
width:100%;
height:100%;
margin:0;
padding:0;
}
.main-picture{
position: absolute;
z-index: -1;
left:0;
top:0;
}
console