Subversion Repositories munaweb

Rev

Rev 6 | Rev 10 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
<!DOCTYPE html>
2
<html lang="en">
3
 
4
<head>
5
    <title>Export eBay Listings to Shopify</title>
6
    <meta charset="UTF-8">
7
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
9
    <link rel="icon" href="favicon.ico" type="image/x-icon">
10
 
11
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
12
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
13
    <link rel="stylesheet" href="css/style.css">
14
    <link rel="stylesheet" href="css/tablesorter.theme.blue.css">
15
    <script src="js/XMLWriter.js"></script>
16
    <script src="js/lodash.min.js"></script>
17
    <script src="js/XMLparse.js"></script>
18
    <script src="js/muna-tools.js"></script>
19
    <script src="js/jquery.js"></script>
20
    <script src="js/jquery.tablesorter.min.js"></script>
21
    <script src="js/jquery.tablesorter.widgets.js"></script>
22
    <script src="js/jquery.parser-input-select.js"></script>
23
</head>
24
 
25
<body onload="return initConfig();">
26
    <div class="w3-main">
27
        <div class="w3-container w3-padding w3-margin w3-card-4">
28
            <div class="w3-container w3-gray" style="height:100px">
29
                <img class="w3-image" src="images/MUNA%20-%20Logo%20100x100.png" alt="MUNA Trading Logo" style="height:100px">
30
                <p id="connected" class="w3-xxlarge w3-right">Export eBay Listings to Shopify
31
                    <input id="login" type="button" class="w3-btn w3-large w3-green w3-margin w3-round-large w3-ripple w3-right w3-hide" onclick="eBayLogin();" value="Login" />
6 - 32
                </p>
2 - 33
            </div>
34
 
35
            <div class="w3-row">
36
                <div>
37
                    <form id="searchForm" class="w3-container w3-light-grey w3-padding w3-small" onsubmit="return getListings();">
38
                        <div id="form1div" class="w3-container w3-card-2 w3-cell w3-padding w3-hide">
39
                            <p>
40
                                <input id="completedList" class="w3-radio" type="radio" style="height:1em" name="rptType" value="completedList" checked>
41
                                <label for="completedList">Completed Listings</label>
42
                            </p>
43
                            <p>
44
                                <input id="liveList" class="w3-radio" type="radio" style="height:1em" name="rptType" value="liveList">
45
                                <label for="liveList">Live Listings</label>
46
                            </p>
47
                            <input id="startButton" type="button" class="w3-btn w3-large w3-red w3-margin w3-round-large w3-ripple" onclick="getListings();" value="Start" />
6 - 48
                        </div>
2 - 49
                        <div id="form2div" class="w3-container w3-card-2 w3-cell w3-padding w3-hide">
50
                            <input id="downloadButton" type="button" class="w3-btn w3-large w3-black w3-margin w3-round-large w3-ripple" onclick="downloadListings()" value="Download CSV" />
6 - 51
                        </div>
2 - 52
                    </form>
53
                </div>
54
                <div id="progressBarDiv" class="w3-container w3-padding w3-margin w3-card-4 w3-hide">
6 - 55
                    <h2 id="progressBarHeader"></h2>
2 - 56
                    <div class="w3-light-grey">
57
                        <div id="progressBar" class="w3-container w3-green w3-center" style="width:0%">0%</div>
58
                    </div>
59
                </div>
60
                <div id="results" class="w3-container w3-padding w3-card-4 w3-hide"></div>
61
                <div id="csv" class="w3-container w3-padding w3-card-4 w3-hide"></div>
62
                <div id="logging" class="w3-container w3-padding"></div>
63
            </div>
64
        </div>
65
 
66
        <footer class="w3-container w3-center w3-border-top w3-margin">
67
            Copyright &#169; 2018 MUNA Trading. All rights reserved.
68
        </footer>
69
 
70
    </div>
71
 
72
    <script>
73
 
74
// Globals
75
var tableName = 'exportTable';
76
var tableSorterName = 'selectTable';
77
var liveListing;
78
var maxPagesToProcess = 0;
79
var pagesToProcess = 0;
80
var pagesProcessed = 0;
81
var maxNotesToAdd = 0;
82
var notesToAdd = 0;
83
var notesAdded = 0;
84
var html = [];
85
 
86
// Initialize Configuration Variables
87
function initConfig() {
88
    var x = document.getElementById("form1div");
89
    if (x.className.indexOf("w3-show") == -1) {
90
        x.className += " w3-show";
91
    }
92
 
93
    eBayAuthToken = readCookie();
94
    if (eBayAuthToken.length > 0) {
95
        connected();
96
    }
97
 
98
    if (eBayAuthTokenFlag === false) {
99
        x = document.getElementById("login");
100
        if (x.className.indexOf("w3-show") == -1) {
101
            x.className += " w3-show";
102
        }
103
    }
104
}
105
 
106
function connected() {
107
    var x;
108
 
109
    eBayAuthTokenFlag = true;
110
    document.getElementById("connected").innerHTML += " (Connected)";
111
 
112
    x = document.getElementById("startButton");
113
    x.className = x.className.replace(" w3-red", " w3-black");
114
 
115
    x = document.getElementById("login");
116
    x.className = x.className.replace(" w3-show", "");
117
 
118
    x = document.getElementById("results");
119
    x.innerHTML = "";
120
    x.className = x.className.replace(" w3-show", "");
121
    x.className = x.className.replace(" process-errors", "");
122
}
123
 
124
function requireNewLogin() {
125
    var x = document.getElementById("startButton");
126
    x.className = x.className.replace(" w3-black", " w3-red ");
127
}
128
 
129
function downloadListings() {
130
    var noteList = [];
131
    var table = document.getElementById(tableSorterName);
132
 
133
    maxPagesToProcess = 0;
134
    pagesToProcess = 0;
135
    pagesProcessed = 0;
136
 
137
    initProgressBar("Downloading Selected Items");
138
 
139
    var x = document.getElementById("results");
140
    x.innerHTML = '';
141
    x.className = x.className.replace("process-errors", "");
142
    if (x.className.indexOf("w3-show") == -1) {
143
        x.className += " w3-show";
144
    }
145
    x.innerHTML = '<p><strong>Downloading Listings...</strong></p>';
146
 
147
    document.getElementById("csv").innerHTML = '';
148
 
149
    tableStart();
150
    for (var i = 2; i < table.rows.length; i++) {
151
        if (table.rows[i].cells[0].children[0].checked) {
152
            ++maxPagesToProcess;
153
            ++pagesToProcess;
154
            noteList.push(table.rows[i].cells[3].innerHTML);
155
            eBaySearch(table.rows[i].cells[3].innerHTML);
156
 
157
            table.deleteRow(i--);
158
        }
159
    }
160
 
161
    function checkpagesToProcess() {
162
        if (pagesToProcess > 0) {
163
            window.setTimeout(checkpagesToProcess, 100); // wait 100 milliseconds
164
        } else {
165
            tableEnd();
7 - 166
            tableSorterUpdateCounters(tableSorterName);
2 - 167
            endProgressBar();
168
            exportTableToCSV(tableName, 'import.csv');
169
            addNotes(noteList);
170
        }
171
    }
172
 
173
    checkpagesToProcess();
174
}
175
 
176
function addNotes(noteList) {
177
    var i, x;
178
 
179
    maxNotesToAdd = 0;
180
    notesToAdd = 0;
181
    notesAdded = 0;
182
 
183
    if (!liveListing) {
184
        initProgressBar('Adding Notes to Ended Listings');
185
 
186
        for (i = 0; i < noteList.length; i++) {
187
            ++maxNotesToAdd;
188
            ++notesToAdd;
189
            addNote(noteList[i]);
190
        }
191
    }
192
 
193
    function checkNotesToAdd() {
194
        if (notesToAdd > 0) {
195
            window.setTimeout(checkNotesToAdd, 100); // wait 100 milliseconds
196
        } else {
197
            endProgressBar();
198
 
199
            x = document.getElementById("results");
200
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
201
            if (!x.className.includes("process-errors")) {
202
                setTimeout(function() {
203
                    x.className = x.className.replace(" w3-show", "");
204
                }, 3000);
205
            }
206
        }
207
    }
208
 
209
    checkNotesToAdd();
210
}
211
 
212
function tableStart() {
213
    document.getElementById("csv").innerHTML = '';
214
    html = [];
215
 
216
    html.push('<h3>Shopify Import</h3>');
217
    html.push('<div class="w3-responsive">');
218
    html.push('<table id="' + tableName + '">');
219
    html.push('<thead>');
220
    html.push('<tr>');
221
 
222
    html.push(tableHeader('Handle'));
223
    html.push(tableHeader('Title'));
224
    html.push(tableHeader('Body (HTML)'));
225
    html.push(tableHeader('Vendor'));
226
    html.push(tableHeader('Type'));
227
    html.push(tableHeader('Tags'));
228
    html.push(tableHeader('Published'));
229
    html.push(tableHeader('Variant SKU'));
230
    html.push(tableHeader('Variant Inventory Tracker'));
231
    html.push(tableHeader('Variant Inventory Quantity'));
232
    html.push(tableHeader('Variant Inventory Policy'));
233
    html.push(tableHeader('Variant Fulfillment Service'));
234
    html.push(tableHeader('Variant Price'));
235
    html.push(tableHeader('Variant Requires Shipping'));
236
    html.push(tableHeader('Variant Taxable'));
237
    html.push(tableHeader('Variant Barcode'));
238
    html.push(tableHeader('Image Src'));
239
    html.push(tableHeader('Image Position'));
240
    html.push(tableHeader('Image Alt Text'));
241
    html.push(tableHeader('Variant Grams'));
242
    html.push(tableHeader('Variant Weight Unit'));
243
 
244
    html.push('</tr>');
245
    html.push('</thead>');
246
    html.push('<tbody>');
247
}
248
 
249
function tableEntry(JsonObj) {
250
    var i, n, barcode, handle;
251
    var tags = [];
252
    var ConditionDescription = JsonObj.ConditionDescription;
253
    var ConditionID = JsonObj.ConditionID;
254
    var CurrentPrice = JsonObj.SellingStatus.CurrentPrice;
255
    var CurrentPriceValue = CurrentPrice === undefined ? 0.00 : Number(CurrentPrice.text);
256
    var price = CurrentPriceValue;
257
    var Description = JsonObj.Description;
258
    var userDescription;
259
    var ItemID = JsonObj.ItemID;
260
    var ItemSpecifics = JsonObj.ItemSpecifics;
6 - 261
    var PictureURL = getJsonArray(JsonObj.PictureDetails.PictureURL);
2 - 262
    var PrimaryCategoryName = JsonObj.PrimaryCategory.CategoryName;
263
    var Quantity = JsonObj.Quantity;
264
    var SKU = JsonObj.SKU;
265
    var ProductListingDetails = JsonObj.ProductListingDetails;
266
    var weightInGrams = 0;
267
    var categoryName = PrimaryCategoryName;
268
 
269
    var Title = JsonObj.Title;
270
 
271
    if (Number(ConditionID) === 1000) {
272
        tags.push("Condition: Brand New");
273
    } else {
274
        tags.push("Condition: Preowned");
275
    }
276
 
277
    n = (SKU === undefined ? 0 : SKU.indexOf(" - "));
278
    if (n > 0) {
279
        barcode = SKU.substr(n + 3);
280
        barcode = barcode.substr(barcode.indexOf(" ") + 1);
281
        handle = 'B' + barcode;
282
        barcode = '\'' + barcode;
283
        SKU = SKU.substr(0, n);
284
    } else {
285
        if (categoryName.indexOf("Books") != -1 && ProductListingDetails && ProductListingDetails.ISBN && isNumeric(ProductListingDetails.ISBN)) {
286
            barcode = '\'' + ProductListingDetails.ISBN;
287
            handle = 'B' + ProductListingDetails.ISBN;
288
        } else if (ProductListingDetails && ProductListingDetails.UPC && isNumeric(ProductListingDetails.UPC)) {
289
            barcode = '\'' + ProductListingDetails.UPC;
290
            handle = 'B' + ProductListingDetails.UPC;
291
        } else if (ProductListingDetails && ProductListingDetails.ProductReferenceID && isNumeric(ProductListingDetails.ProductReferenceID)) {
292
            barcode = 'R' + ProductListingDetails.ProductReferenceID;
293
            handle = barcode;
294
        } else {
295
            barcode = 'H' + Title.hashCode();
296
            handle = barcode;
297
        }
298
    }
299
 
300
    userDescription = extractDescription(Description);
301
    if (ItemSpecifics && PrimaryCategoryName.indexOf('DVD') < 0) {
302
        userDescription += '<p>';
303
        var first = true;
304
        for (i = 0; i < ItemSpecifics.length; i++) {
305
            if (ItemSpecifics[i].Name != 'All returns accepted' &&
306
                ItemSpecifics[i].Name != 'Item must be returned within' &&
307
                ItemSpecifics[i].Name != 'Refund will be given as' &&
308
                ItemSpecifics[i].Name != 'Return policy details' &&
309
                ItemSpecifics[i].Name != 'Restocking Fee' &&
310
                ItemSpecifics[i].Name != 'Return shipping will be paid by') {
311
                userDescription += (first ? '' : '<br/>') + ItemSpecifics[i].Name + ': ' + ItemSpecifics[i].Value;
312
                first = false;
313
            }
314
        }
315
        userDescription += '</p>';
316
    }
317
 
318
    if (ConditionDescription &&
319
        (userDescription.indexOf('Please view all actual images.') < 0 && userDescription.indexOf('mint condition') < 0)) {
320
        userDescription += '<p>' + ConditionDescription + '</p>';
321
    }
322
 
323
    if (categoryName.indexOf("CDs") != -1) {
324
        categoryName = 'Music CDs';
325
        price = 4.95;
326
    } else if (categoryName.indexOf("Movies") != -1) {
327
        categoryName = 'Movies';
328
        price = 4.95;
329
    } else if (categoryName.indexOf("Books") != -1) {
330
        categoryName = 'Books';
331
        price = 5.95;
332
    } else if (categoryName.indexOf("Trading Cards") != -1) {
333
        if (categoryName.indexOf("Baseball") != -1) {
334
            tags.push('Trading Cards: Baseball');
335
        } else if (categoryName.indexOf("Football") != -1) {
336
            tags.push('Trading Cards: Football');
337
        } else if (categoryName.indexOf("Basketball") != -1) {
338
            tags.push('Trading Cards: Basketball');
339
        } else if (categoryName.indexOf("Soccer") != -1) {
340
            tags.push('Trading Cards: Soccer');
341
        } else if (categoryName.indexOf("Ice Hockey") != -1) {
342
            tags.push('Trading Cards: Ice Hockey');
343
        } else if (categoryName.indexOf("Auto Racing") != -1) {
344
            tags.push('Trading Cards: Auto Racing');
345
        }
346
        categoryName = 'Trading Cards';
347
        price = 1.99;
348
    }
349
    tags.push(categoryName);
350
 
351
    if (liveListing) {
352
        tags.push('_eBay Live');
353
 
354
        price = round((CurrentPriceValue * 0.80), 1) + 0.05; // always end with 5
355
        if (categoryName.indexOf("CDs") != -1 && price < 4.95) {
356
            price = 4.95;
357
        } else if (categoryName.indexOf("Movies") != -1 && price < 4.95) {
358
            price = 4.95;
359
        } else if (categoryName.indexOf("Books") != -1 && price < 5.95) {
360
            price = 5.95;
361
        } else if (categoryName.indexOf("Trading Cards") != -1 && price < 1.99) {
362
            price = 1.99;
363
        }
364
    }
365
 
366
    if (JsonObj.ShippingPackageDetails !== undefined) {
367
        if (JsonObj.ShippingPackageDetails.WeightMajor !== undefined) {
368
            weightInGrams += (Number(JsonObj.ShippingPackageDetails.WeightMajor.text) * 453.5);
369
        }
370
 
371
        if (JsonObj.ShippingPackageDetails.WeightMinor !== undefined) {
372
            weightInGrams += (Number(JsonObj.ShippingPackageDetails.WeightMinor.text) * 28.3);
373
        }
374
    }
375
 
376
    html.push('<tr>');
377
 
378
    html.push(tableCell(handle));
379
    html.push(tableCell(Title));
380
    html.push(tableCell(escapeHtml(userDescription)));
381
    html.push(tableCell("MUNA Trading"));
382
    html.push(tableCell(categoryName));
383
    html.push(tableCell(tags.join(',')));
384
    html.push(tableCell("TRUE"));
385
    html.push(tableCell((SKU !== undefined ? SKU : "")));
386
    html.push(tableCell("shopify"));
387
    html.push(tableCell(Quantity));
388
    html.push(tableCell("deny"));
389
    html.push(tableCell("manual"));
390
    html.push(tableCell(price));
391
    html.push(tableCell("TRUE"));
392
    html.push(tableCell("TRUE"));
393
    html.push(tableCell(barcode));
6 - 394
    html.push(tableCell(PictureURL[0].substr(0, PictureURL[0].lastIndexOf('/') + 1) + '$_57.JPG'));
2 - 395
    html.push(tableCell(1));
396
    html.push(tableCell(Title + " Image 1"));
397
    html.push(tableCellHidden(ItemID));
398
    html.push(tableCell(Math.floor(weightInGrams)));
399
    html.push(tableCell("oz"));
400
    html.push(tableCellHidden(ItemID));
401
 
402
    html.push('</tr>');
403
 
6 - 404
    for (i = 1; i < PictureURL.length; i++) {
405
        html.push('<tr>');
2 - 406
 
6 - 407
        html.push(tableCell(handle));
408
        html.push(tableCell(""));
409
        html.push(tableCell(""));
410
        html.push(tableCell(""));
411
        html.push(tableCell(""));
412
        html.push(tableCell(""));
413
        html.push(tableCell(""));
414
        html.push(tableCell(""));
415
        html.push(tableCell(""));
416
        html.push(tableCell(""));
417
        html.push(tableCell(""));
418
        html.push(tableCell(""));
419
        html.push(tableCell(""));
420
        html.push(tableCell(""));
421
        html.push(tableCell(""));
422
        html.push(tableCell(""));
423
        html.push(tableCell(PictureURL[i].substr(0, PictureURL[i].lastIndexOf('/') + 1) + '$_57.JPG'));
424
        html.push(tableCell(i + 1));
425
        html.push(tableCell(Title + " Image " + (i + 1)));
426
        html.push(tableCell(""));
427
        html.push(tableCell(""));
428
        html.push(tableCellHidden(ItemID));
2 - 429
 
6 - 430
        html.push('</tr>');
2 - 431
    }
432
}
433
 
434
function extractDescription(str) {
435
    var startText = "<!-- *************** Place description here ****************** -->";
436
    var startPos = str.indexOf(startText) + startText.length;
437
    var endPos = str.lastIndexOf("<!-- *************** Place description here ****************** -->");
438
    var userDescription = str.substr(startPos, endPos - startPos);
439
    var parser = new DOMParser();
440
    var htmlDoc = parser.parseFromString(userDescription, "text/html");
441
 
442
    return ((htmlDoc.getElementsByTagName('div')[0] !== undefined ? htmlDoc.getElementsByTagName('div')[0].innerHTML : userDescription));
443
}
444
 
445
function tableEnd() {
446
    html.push('</tbody>');
447
    html.push('</table>');
448
    html.push('</div>');
449
 
450
    document.getElementById("csv").innerHTML = html.join('');
451
}
452
 
453
function addNote(itemId) {
454
    var i;
455
    var xml;
456
 
457
    var xw = new XMLWriter('UTF-8', '1.0');
458
    var xhr = new XMLHttpRequest();
459
 
460
    if (!createAddXMLNote(xw, xhr, 'SetUserNotesRequest', 'SetUserNotes', itemId)) {
461
        return;
462
    }
463
 
464
    xml = xw.flush();
465
    xw.close();
466
 
467
    xhr.onload = function() {
468
        var obj = XMLparse(xhr.responseXML);
469
 
470
        var returnCode = obj.Ack;
471
 
472
        var x = document.getElementById("results");
473
        if (x.className.indexOf("w3-show") == -1) {
474
            x.className += " w3-show";
475
        }
476
 
477
        if (returnCode == 'Success' || (returnCode == 'Warning' && obj.Errors.ErrorCode == '21917108')) {
478
            x.innerHTML += '<p>' + itemId + ': <strong>' + returnCode + '</strong></p>';
479
 
480
            if (returnCode == 'Warning') {
481
                x.innerHTML += "<p>" + obj.Errors.SeverityCode + " (" + obj.Errors.ErrorCode + "): " + escapeHtml(obj.Errors.LongMessage) + "</p>";
482
            }
483
        } else {
484
            x.className += " process-errors";
485
            x.innerHTML += '<p class="w3-red">' + itemId + ': <strong>' + returnCode + ':</strong></p>';
486
 
6 - 487
            var errors = getJsonArray(obj.Errors);
2 - 488
            x.innerHTML += "<p>";
6 - 489
            for (i = 0; i < errors.length; i++) {
490
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 491
            }
6 - 492
 
2 - 493
            x.innerHTML += "</p>";
494
        }
495
 
496
        if (obj.Message) {
497
            x.innerHTML += obj.Message;
498
        }
499
 
500
        --notesToAdd;
501
        ++notesAdded;
502
 
503
        updateProgressBar(maxNotesToAdd, notesAdded);
504
    };
505
 
506
    xhr.send(xml);
507
}
508
 
509
function createAddXMLNote(xw, xhr, xmlrequest, callname, itemId) {
510
    var today = new Date();
511
    var todayYYYYMMDD = today.toISOString().slice(0, 10);
512
 
513
    xw.writeStartDocument();
514
    xw.writeStartElement(xmlrequest);
515
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
516
 
517
    xw.writeStartElement('RequesterCredentials');
518
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
519
    xw.writeEndElement(); /* RequesterCredentials */
520
 
521
    xw.writeElementString('ItemID', itemId);
522
    xw.writeElementString('Action', 'AddOrUpdate');
523
    xw.writeElementString('NoteText', 'Exported to Shopify on ' + todayYYYYMMDD);
524
 
525
    xw.writeElementString('ErrorLanguage', 'en_US');
526
    xw.writeElementString('Version', configeBayTradingVersion);
527
    xw.writeElementString('WarningLevel', configWarningLevel);
528
 
529
    xw.writeEndElement(); /* xmlrequest */
530
    xw.writeEndDocument();
531
 
532
    xhr.open('POST', configProxyUrl, true);
533
    xhr.setRequestHeader('Content-Type', 'text/xml');
534
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
535
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
536
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
537
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
538
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
539
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
540
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
541
 
542
    return true;
543
}
544
 
545
function eBaySearch(itemId) {
546
    var i;
547
    var xml;
548
 
549
    var xw = new XMLWriter('UTF-8', '1.0');
550
    var xhr = new XMLHttpRequest();
551
 
552
    if (!createAddXMLSearch(xw, xhr, 'GetItemRequest', 'GetItem', itemId)) {
553
        return;
554
    }
555
 
556
    xml = xw.flush();
557
    xw.close();
558
 
559
    xhr.onload = function() {
560
        var obj = XMLparse(xhr.responseXML);
561
 
562
        var returnCode = obj.Ack;
563
 
564
        var x = document.getElementById("results");
565
        if (x.className.indexOf("w3-show") == -1) {
566
            x.className += " w3-show";
567
        }
568
 
569
        if (returnCode == 'Success') {
570
            tableEntry(obj.Item);
571
        } else {
572
            x.className += " process-errors";
573
            x.innerHTML += '<p class="w3-red">' + itemId + ': <strong>' + returnCode + ':</strong></p>';
574
 
6 - 575
            var errors = getJsonArray(obj.Errors);
2 - 576
            x.innerHTML += "<p>";
6 - 577
            for (i = 0; i < errors.length; i++) {
578
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 579
            }
6 - 580
 
2 - 581
            x.innerHTML += "</p>";
582
        }
583
 
584
        --pagesToProcess;
585
        ++pagesProcessed;
586
 
587
        updateProgressBar(maxPagesToProcess, pagesProcessed);
588
    };
589
 
590
    xhr.send(xml);
591
}
592
 
593
function createAddXMLSearch(xw, xhr, xmlrequest, callname, itemId) {
594
 
595
    xw.writeStartDocument();
596
    xw.writeStartElement(xmlrequest);
597
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
598
 
599
    xw.writeStartElement('RequesterCredentials');
600
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
601
    xw.writeEndElement(); /* RequesterCredentials */
602
 
603
    xw.writeElementString('ItemID', itemId);
604
    xw.writeElementString('IncludeItemSpecifics', 'true');
605
    xw.writeElementString('DetailLevel', 'ReturnAll');
606
 
607
    xw.writeElementString('ErrorLanguage', 'en_US');
608
    xw.writeElementString('Version', configeBayTradingVersion);
609
    xw.writeElementString('WarningLevel', configWarningLevel);
610
 
611
    xw.writeEndElement(); /* xmlrequest */
612
    xw.writeEndDocument();
613
 
614
    xhr.open('POST', configProxyUrl, true);
615
    xhr.setRequestHeader('Content-Type', 'text/xml');
616
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
617
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
618
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
619
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
620
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
621
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
622
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
623
 
624
    return true;
625
}
626
 
627
function getListings() {
628
    var x;
629
 
630
    if (eBayAuthTokenFlag === false) {
631
        return;
632
    }
633
 
634
    document.getElementById("logging").innerHTML = '';
635
 
636
    x = document.getElementById("results");
637
    if (x.className.indexOf("w3-show") == -1) {
638
        x.className += " w3-show";
639
    }
640
    x.className = x.className.replace("process-errors", "");
641
    x.innerHTML = '<p><strong>Retrieving Listings...</strong></p>';
642
 
643
    initProgressBar('Getting Items for Export (1/2)');
644
 
645
    liveListing = (getRadioValue('rptType') == 'liveList');
646
    tableSorterStart();
647
    maxPagesToProcess = 1;
648
    pagesToProcess = 1;
649
    pagesProcessed = 0;
650
    eBaySorterSearch(1);
651
 
652
    function checkpagesToProcess() {
653
        if (pagesToProcess > 0) {
654
            window.setTimeout(checkpagesToProcess, 100); // wait 100 milliseconds
655
        } else {
656
            tableSorterEnd();
657
            endProgressBar();
658
            // fillSorterListings(); is now in tableSorterEnd()
659
        }
660
    }
661
 
662
    checkpagesToProcess();
663
}
664
 
665
function tableSorterStart() {
666
    document.getElementById("logging").innerHTML = '';
667
    html = [];
668
 
669
    html.push('<h3>Items for Export</h3>');
670
    html.push('<p>Showing <span id="filtered-rows">0</span> of <span id="total-rows">0</span> / <span id="selected-rows">0</span> selected.</p>');
671
    html.push('<div class="w3-responsive">');
672
    html.push('<table id="' + tableSorterName + '" class="tablesorter">');
673
    html.push('<thead>');
674
    html.push('<tr>');
675
 
6 - 676
    html.push(tableHeaderCheckbox());
2 - 677
    html.push(tableHeader('Image'));
678
    html.push(tableHeader('Title'));
679
    html.push(tableHeader('Item Id'));
680
    html.push(tableHeader('SKU'));
681
    html.push(tableHeader('Category'));
682
    html.push(tableHeader('Format'));
683
    html.push(tableHeader('Price'));
684
    html.push(tableHeader('Quantity'));
685
    html.push(tableHeader('Views'));
686
    html.push(tableHeader('Watchers'));
687
    html.push(tableHeader(liveListing ? 'Start Date' : 'End Date'));
688
    html.push(tableHeader('Note'));
689
 
690
    html.push('</tr>');
691
    html.push('</thead>');
692
    html.push('<tbody>');
693
}
694
 
695
function tableSorterEntry(JsonObj) {
696
    var i;
697
    var image;
698
    var title;
699
    var itemId;
700
    var sku;
701
    var format;
702
    var price;
703
    var quantity;
704
    var views;
705
    var watchers;
706
    var listingDate;
707
    var privateNote;
708
    var ebayNote;
709
    var relisted;
710
 
711
    for (i = 0; i < JsonObj.length; i++) {
712
        image = getJsonValue(JsonObj[i].PictureDetails).replace('http:', 'https:');
713
        title = getJsonValue(JsonObj[i].Title);
714
        itemId = getJsonValue(JsonObj[i].ItemID);
715
        sku = getJsonValue(JsonObj[i].SKU);
716
        format = getJsonValue(JsonObj[i].ListingType);
717
        if (format == 'Chinese') {
718
            format = 'Auction';
719
            price = getJsonValue(JsonObj[i].StartPrice.text);
720
        } else {
721
            format = 'Fixed Price';
722
            price = getJsonValue(JsonObj[i].BuyItNowPrice.text);
723
        }
724
        quantity = getJsonValue(JsonObj[i].QuantityAvailable);
725
        views = '';
726
        watchers = getJsonValue(JsonObj[i].WatchCount);
727
        watchers = (watchers.length === 0 ? "0" : watchers);
728
        listingDate = getJsonValue(JsonObj[i].ListingDetails).substr(0, 10);
729
        privateNote = getJsonValue(JsonObj[i].PrivateNotes);
730
        ebayNote = getJsonValue(JsonObj[i].eBayNotes);
731
        relisted = getJsonValue(JsonObj[i].Relisted);
732
 
733
        if (!liveListing) {
734
            if (privateNote.startsWith("Exported to ") || relisted == 'true' || privateNote.startsWith("Sold via ") || privateNote.startsWith("Relisted As New Item")) {
735
                continue;
736
            }
737
        }
738
 
739
        html.push('<tr>');
740
 
741
        html.push(tableCellCheckbox());
742
        html.push(tableCell('<img class="w3-image" src="' + image + '" alt="Gallery Image" style="max-height:100px;max-width:100px;">'));
743
        html.push(tableCell(title));
744
        html.push(tableCell(itemId));
745
        html.push(tableCell(sku));
746
        html.push(tableCellLabel('Category' + itemId));
747
        html.push(tableCell(format));
748
        html.push(tableCell('$' + price));
749
        html.push(tableCell(quantity));
750
        html.push(tableCellLabel('Views' + itemId));
751
        html.push(tableCell(watchers));
752
        html.push(tableCell(listingDate));
753
        html.push(tableCell(privateNote + ' ' + ebayNote));
754
 
755
        html.push('</tr>');
756
    }
757
}
758
 
759
function tableSorterEnd() {
760
    html.push('</tbody>');
761
    html.push('</table>');
762
    html.push('</div>');
763
 
764
    document.getElementById("logging").innerHTML = html.join('');
765
 
766
    $(function() {
767
        $("#" + tableSorterName).on('tablesorter-initialized', function() {
768
 
769
            // class name to add on tr when checkbox is checked
770
            var highlightClass = 'checked',
771
                // resort the table after the checkbox is modified?
772
                resort = true,
773
                $table = $(this),
774
                c = this.config,
775
                wo = c && c.widgetOptions,
776
                // include sticky header checkbox; if installed
777
                $sticky = c && wo.$sticky || '',
778
                doChecky = function(c, col) {
779
                    $table
780
                        .children('tbody')
781
                        .children('tr:visible')
782
                        .children('td:nth-child( ' + (parseInt(col, 10) + 1) + ' )')
783
                        .find('input[type=checkbox]')
784
                        .each(function() {
785
                            this.checked = c;
786
                            $(this).trigger('change');
787
                        });
788
                };
789
 
790
            $table
791
                .children('tbody')
792
                .on('change', 'input[type=checkbox]', function() {
793
                    // ignore change if updating all rows
794
                    if ($table[0].ignoreChange) {
795
                        return;
796
                    }
797
                    var $this = $(this);
798
                    $this.closest('tr').toggleClass(highlightClass, this.checked);
799
                    $this.trigger('updateCell', [$this.closest('td'), resort]);
800
 
801
                    // handle header
7 - 802
                    var rowCount = $('#' + tableSorterName + ' tbody tr').length;
2 - 803
                    var checkedCount = $('#' + tableSorterName + ' tbody .checked').length;
804
                    var ua = window.navigator.userAgent;
805
                    if (checkedCount === 0) {
806
                        $table.add($sticky).find('thead input[type=checkbox]').prop('checked', false);
807
                        $table.add($sticky).find('thead input[type=checkbox]').prop('indeterminate', false);
808
                    } else if (checkedCount === rowCount) {
809
                        $table.add($sticky).find('thead input[type=checkbox]').prop('checked', true);
810
                        $table.add($sticky).find('thead input[type=checkbox]').prop('indeterminate', false);
811
                    } else {
812
                        $table.add($sticky).find('thead input[type=checkbox]').prop('checked', !(ua.indexOf('Trident/') > -1 || ua.indexOf('Edge/') > -1));
813
                        $table.add($sticky).find('thead input[type=checkbox]').prop('indeterminate', true);
814
                    }
815
                    $('#selected-rows').html(checkedCount);
816
                })
817
                .end()
818
                .add($sticky)
819
                .find('thead input[type=checkbox]')
820
                // Click on checkbox in table header to toggle all inputs
821
                .on('change', function() {
822
                    // prevent updateCell for every cell
823
                    $table[0].ignoreChange = true;
824
                    var c = this.checked,
825
                        col = $(this).closest('th').attr('data-column');
826
                    doChecky(c, col);
827
                    // update main & sticky header
828
 
829
                    $table.children('tbody').children('tr:visible').toggleClass(highlightClass, c);
830
                    // update all at once
831
                    $table[0].ignoreChange = false;
832
                    $table.trigger('update', [resort]);
833
 
834
                    // handle header
7 - 835
                    var rowCount = $('#' + tableSorterName + ' tbody tr').length;
2 - 836
                    var checkedCount = $('#' + tableSorterName + ' tbody .checked').length;
837
                    var ua = window.navigator.userAgent;
838
                    if (checkedCount === 0) {
839
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('checked', false);
840
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('indeterminate', false);
841
                    } else if (checkedCount === rowCount) {
842
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('checked', true);
843
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('indeterminate', false);
844
                    } else {
845
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('checked', !(ua.indexOf('Trident/') > -1 || ua.indexOf('Edge/') > -1));
846
                        $table.add($sticky).find('th[data-column=' + col + '] input[type=checkbox]').prop('indeterminate', true);
847
                    }
848
                    $('#selected-rows').html(checkedCount);
849
                })
850
                .on('mouseup', function() {
851
                    return false;
852
                });
853
 
854
        });
855
 
856
        $("#" + tableSorterName).tablesorter({
857
            theme: "blue",
858
            widgets: ["zebra", "stickyHeaders", "filter"],
859
            headers: {
860
                0: {
861
                    sorter: "checkbox"
862
                },
863
                1: {
864
                    sorter: false,
865
                    filter: false
866
                }
867
            },
868
            initialized: function() {
869
                fillSorterListings();
870
            }
871
        });
872
 
873
        $("#" + tableSorterName).bind('filterInit filterEnd', function(event, data) {
874
            $('#filtered-rows').html(data.filteredRows);
875
            $('#total-rows').html(data.totalRows);
876
        });
877
    });
878
}
879
 
880
function eBaySorterSearch(pageNo) {
881
    var i;
882
    var xml;
883
 
884
    var xw = new XMLWriter('UTF-8', '1.0');
885
    var xhr = new XMLHttpRequest();
886
 
887
    if (!createSorterAddXMLSearch(xw, xhr, 'GetMyeBaySelling', pageNo)) {
888
        return;
889
    }
890
 
891
    xml = xw.flush();
892
    xw.close();
893
 
894
    xhr.onload = function() {
895
        var obj = XMLparse(xhr.responseXML);
896
 
897
        var returnCode = obj.Ack;
898
 
899
        var objArray = (liveListing ? obj.ActiveList : obj.UnsoldList);
900
 
901
        var x = document.getElementById("results");
902
 
903
        if (returnCode == 'Success') {
904
            tableSorterEntry(objArray.ItemArray);
905
 
906
            if (Number(objArray.PaginationResult.TotalNumberOfPages) > pageNo) {
907
                maxPagesToProcess = Number(objArray.PaginationResult.TotalNumberOfPages);
908
                ++pagesToProcess;
909
                eBaySorterSearch(pageNo + 1);
910
            }
911
 
912
            updateProgressBar(maxPagesToProcess, pagesProcessed);
913
        } else {
914
            x.className += " process-errors";
915
            x.innerHTML += '<p class="w3-red">' + obj.CorrelationID + ': <strong>' + returnCode + ':</strong></p>';
6 - 916
            var errors = getJsonArray(obj.Errors);
2 - 917
            x.innerHTML += "<p>";
6 - 918
            for (i = 0; i < errors.length; i++) {
919
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 920
            }
6 - 921
 
2 - 922
            x.innerHTML += "</p>";
923
        }
924
 
925
        --pagesToProcess;
926
        ++pagesProcessed;
927
 
928
        updateProgressBar(maxPagesToProcess, pagesProcessed);
929
    };
930
 
931
    xhr.send(xml);
932
}
933
 
934
function createSorterAddXMLSearch(xw, xhr, callname, pageNo) {
935
 
936
    xw.writeStartDocument();
937
    xw.writeStartElement(callname + "Request");
938
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
939
 
940
    xw.writeStartElement('RequesterCredentials');
941
    xw.writeElementString('eBayAuthToken', eBayAuthToken);
942
    xw.writeEndElement(); /* RequesterCredentials */
943
 
944
    xw.writeElementString('DetailLevel', 'ReturnAll');
945
    xw.writeStartElement('DeletedFromSoldList');
946
    xw.writeElementString('Include', 'false');
947
    xw.writeEndElement(); /* DeletedFromSoldList */
948
    xw.writeStartElement('DeletedFromUnsoldList');
949
    xw.writeElementString('Include', 'false');
950
    xw.writeEndElement(); /* DeletedFromUnsoldList */
951
    xw.writeStartElement('ScheduledList');
952
    xw.writeElementString('Include', 'false');
953
    xw.writeEndElement(); /* ScheduledList */
954
    xw.writeStartElement('SellingSummary');
955
    xw.writeElementString('Include', 'false');
956
    xw.writeEndElement(); /* SellingSummary */
957
    xw.writeStartElement('SoldList');
958
    xw.writeElementString('Include', 'false');
959
    xw.writeEndElement(); /* SoldList */
960
 
961
    xw.writeStartElement(liveListing ? 'UnsoldList' : 'ActiveList');
962
    xw.writeElementString('Include', 'false');
963
    xw.writeEndElement(); /* ActiveList */
964
 
965
    xw.writeStartElement(liveListing ? 'ActiveList' : 'UnsoldList');
966
    xw.writeElementString('Include', 'true');
967
    xw.writeElementString('IncludeNotes', 'true');
968
    xw.writeStartElement('Pagination');
969
    xw.writeElementString('EntriesPerPage', '200');
970
    xw.writeElementString('PageNumber', '' + pageNo);
971
    xw.writeEndElement(); /* Pagination*/
972
    xw.writeEndElement(); /* UnsoldList> */
973
    xw.writeElementString('OutputSelector', 'BuyItNowPrice');
974
    xw.writeElementString('OutputSelector', 'eBayNotes');
975
    xw.writeElementString('OutputSelector', 'ItemID');
976
    xw.writeElementString('OutputSelector', liveListing ? 'ActiveList.ItemArray.Item.ListingDetails.StartTime' : 'UnsoldList.ItemArray.Item.ListingDetails.EndTime');
977
    xw.writeElementString('OutputSelector', 'ListingType');
978
    xw.writeElementString('OutputSelector', 'PrivateNotes');
979
    xw.writeElementString('OutputSelector', 'QuantityAvailable');
980
    xw.writeElementString('OutputSelector', 'PictureDetails');
981
    xw.writeElementString('OutputSelector', 'Relisted');
982
    xw.writeElementString('OutputSelector', 'SKU');
983
    xw.writeElementString('OutputSelector', 'Title');
984
    xw.writeElementString('OutputSelector', 'StartPrice');
985
    xw.writeElementString('OutputSelector', 'WatchCount');
986
    xw.writeElementString('OutputSelector', 'PaginationResult');
987
 
988
    xw.writeElementString('ErrorLanguage', 'en_US');
989
    xw.writeElementString('Version', configeBayTradingVersion);
990
    xw.writeElementString('WarningLevel', configWarningLevel);
991
 
992
    xw.writeEndElement(); /* xmlrequest */
993
    xw.writeEndDocument();
994
 
995
    xhr.open('POST', configProxyUrl, true);
996
    xhr.setRequestHeader('Content-Type', 'text/xml');
997
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
998
    xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
999
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
1000
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
1001
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
1002
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
1003
    xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
1004
 
1005
    return true;
1006
}
1007
 
1008
function fillSorterListings() {
1009
    var i;
1010
    var x = document.getElementById(tableSorterName);
1011
    var fillList = [];
1012
    var maxItems = 20;
1013
 
1014
    listingsToFill = 0;
1015
    maxListingsToFill = 0;
1016
    listingsFilled = 0;
1017
 
1018
    initProgressBar('Filling Listing Information (2/2)');
1019
 
1020
    for (i = 2; i < x.rows.length; i++) {
1021
        fillList.push(x.rows[i].cells[3].innerHTML);
1022
    }
6 - 1023
 
1024
    for (i = 0;
1025
        (i * maxItems) < fillList.length; i++) {
2 - 1026
        ++listingsToFill;
1027
        ++maxListingsToFill;
1028
        fillSorterListing(fillList.slice(i * maxItems, (i + 1) * maxItems));
1029
    }
1030
 
1031
    function checkListingsToFill() {
1032
        if (listingsToFill > 0) {
1033
            window.setTimeout(checkListingsToFill, 100); // wait 100 milliseconds
1034
        } else {
1035
            $("#" + tableSorterName).trigger("update");
1036
 
1037
            endProgressBar();
1038
 
1039
            x = document.getElementById("form1div");
1040
            x.className = x.className.replace(" w3-show", "");
1041
            x = document.getElementById("form2div");
1042
            x.className += " w3-show";
1043
 
1044
            x = document.getElementById("results");
1045
            x.innerHTML += '<p><strong>Report Finished!</strong></p>';
1046
            if (!x.className.includes("process-errors")) {
1047
                setTimeout(function() {
1048
                    x.className = x.className.replace(" w3-show", "");
1049
                }, 3000);
1050
            }
1051
        }
1052
    }
1053
 
1054
    checkListingsToFill();
1055
}
1056
 
1057
function fillSorterListing(itemIdList) {
1058
    var i;
1059
    var xml;
1060
 
1061
    var xw = new XMLWriter('UTF-8', '1.0');
1062
    var xhr = new XMLHttpRequest();
1063
 
1064
    if (!createSorterFillXMLSearch(xw, xhr, 'GetMultipleItems', itemIdList)) {
1065
        return;
1066
    }
1067
 
1068
    xml = xw.flush();
1069
    xw.close();
1070
 
1071
    xhr.onload = function() {
1072
        var obj = XMLparse(xhr.responseXML);
1073
 
1074
        var returnCode = obj.Ack;
1075
 
1076
        var x = document.getElementById("results");
1077
 
1078
        if (returnCode == 'Success') {
1079
            for (i = 0; i < obj.Item.length; i++) {
1080
                var itemId = getJsonValue(obj.Item[i].ItemID);
1081
                document.getElementById("Views" + itemId).innerHTML = getJsonValue(obj.Item[i].HitCount);
1082
                document.getElementById("Category" + itemId).innerHTML = getJsonValue(obj.Item[i].PrimaryCategoryName);
6 - 1083
            }
2 - 1084
        } else {
1085
            x.className += " process-errors";
1086
            x.innerHTML += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
1087
 
6 - 1088
            var errors = getJsonArray(obj.Errors);
2 - 1089
            x.innerHTML += "<p>";
6 - 1090
            for (i = 0; i < errors.length; i++) {
1091
                x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
2 - 1092
            }
6 - 1093
 
2 - 1094
            x.innerHTML += "</p>";
1095
        }
1096
 
1097
        --listingsToFill;
1098
        ++listingsFilled;
1099
        updateProgressBar(maxListingsToFill, listingsFilled);
1100
    };
1101
 
1102
    xhr.send(xml);
1103
}
1104
 
1105
function createSorterFillXMLSearch(xw, xhr, callname, itemIdList) {
1106
    var i;
6 - 1107
 
2 - 1108
    xw.writeStartDocument();
1109
    xw.writeStartElement(callname + "Request");
1110
    xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
1111
 
1112
    for (i = 0; i < itemIdList.length; i++) {
1113
        xw.writeElementString('ItemID', itemIdList[i]);
1114
    }
1115
 
1116
    xw.writeElementString('ErrorLanguage', 'en_US');
1117
    xw.writeElementString('Version', configeBayShoppingVersion);
1118
    xw.writeElementString('WarningLevel', configWarningLevel);
1119
 
1120
    xw.writeEndElement(); /* xmlrequest */
1121
    xw.writeEndDocument();
1122
 
1123
    xhr.open('POST', configProxyUrl, true);
1124
    xhr.setRequestHeader('Content-Type', 'text/xml');
1125
    xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
1126
    xhr.setRequestHeader('X-EBAY-API-VERSION', configeBayShoppingVersion);
1127
    xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
1128
    xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
1129
    xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
1130
    xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
1131
    xhr.setRequestHeader('X-EBAY-API-REQUEST-ENCODING', 'XML');
1132
    xhr.setRequestHeader('X-Proxy-URL', configeBayShopping);
1133
 
1134
    return true;
1135
}
1136
 
1137
    </script>
1138
 
1139
</body>
1140
</html>