diff --git a/discogs_importer.user.js b/discogs_importer.user.js index 81ad84a..10cba88 100644 --- a/discogs_importer.user.js +++ b/discogs_importer.user.js @@ -1,593 +1,962 @@ // ==UserScript== + // @name Import Discogs releases to MusicBrainz -// @version 2011-05-24_02 + +// @version 2011-05-25_01 + // @namespace http://userscripts.org/users/22504 + // @include http://*musicbrainz.org/release/add + // @include http://*musicbrainz.org/release/*/add + // @include http://*musicbrainz.org/release/*/edit + // @include http://*.discogs.com/*release/* + // @exclude http://*.discogs.com/*release/*?f=xml* + // @exclude http://www.discogs.com/release/add + // @require http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js + // ==/UserScript== + + // Script Update Checker + // -- http://userscripts.org/scripts/show/20145 + var version_scriptNum = 36376; // Change this to the number given to the script by userscripts.org (check the address bar) -var version_timestamp = 1306238657649; // Used to differentiate one version of the script from an older one. Use the (new Date()).getTime() function to get a value for this. + +var version_timestamp = 1306279616598; // Used to differentiate one version of the script from an older one. Use the (new Date()).getTime() function to get a value for this. + try { + function updateCheck(forced) {if((forced)||(parseInt(GM_getValue("lastUpdate", "0")) + 86400000 <= (new Date().getTime()))) {try {GM_xmlhttpRequest({method: "GET",url: "http://userscripts.org/scripts/review/" + version_scriptNum + "?" + new Date().getTime(),headers: {'Cache-Control': 'no-cache'},onload: function(xhrResponse) {GM_setValue("lastUpdate", new Date().getTime() + ""); var rt = xhrResponse.responseText.replace(/ ?/gm, " ").replace(/
  • /gm, "\n").replace(/<[^>]*>/gm, ""); var scriptName = (/@name\s*(.*?)\s*$/m.exec(rt))[1]; GM_setValue("targetScriptName", scriptName); if (parseInt(/version_timestamp\s*=\s*([0-9]+)/.exec(rt)[1]) > version_timestamp) {if (confirm("There is an update available for the Greasemonkey script \"" + scriptName + ".\"\nWould you like to go to the install page now?")) {GM_openInTab("http://userscripts.org/scripts/show/" + version_scriptNum);}} else if (forced) {alert("No update is available for \"" + scriptName + ".\"");}}});} catch (err) {if (forced) {alert("An error occurred while checking for updates:\n" + err);}}}} GM_registerMenuCommand(GM_getValue("targetScriptName", "???") + " - Manual Update Check", function() {updateCheck(true);}); updateCheck(false); + } catch(e) {} + + // Discogs API KEY (you may need to replace with yours if you encounter limit issues) + var discogsApiKey = "84b3bec008"; + + $(document).ready(function(){ + + // On Musicbrainz website + if (window.location.href.match(/(musicbrainz\.org)/)) { + + $add_disc_dialog = $('div.add-disc-dialog'); - $add_disc_dialog.find('div.tabs ul.tabs').append('
  • Discogs import
  • '); + + //$add_disc_dialog.find('div.tabs ul.tabs').append('
  • Discogs import
  • '); + + var innerHTML = ''; - $add_disc_dialog.find('div.add-disc-tab:last').after(innerHTML); + + //$add_disc_dialog.find('div.add-disc-tab:last').after(innerHTML); + + // On Discogs website + } else { + // Discogs Webservice URL + var discogsWsUrl = window.location.href.replace(/http:\/\/(www\.|)discogs\.com\/(.*\/|)release\//, 'http://discogs.com/release/') + "?f=xml&api_key=" + discogsApiKey; + mylog(discogsWsUrl); + + /* Main function */ + + GM_xmlhttpRequest({ + method: "GET", + url: discogsWsUrl, + headers: { + "User-Agent":"monkeyagent", + "Accept":"text/monkey,text/xml", + }, + onload: function(response) { + var xmldoc = new DOMParser().parseFromString(response.responseText,"text/xml"); + var release = parseDiscogsRelease(xmldoc); + insertLink(release); + } + }); + } + + }); + + + + // Analyze Discogs data and return a release object + function parseDiscogsRelease(xmldoc) { + var release = new Object(); + release.discs = []; + + // Compute artist(s) name(s) - release.artist = cookArtistName(getXPathVal(xmldoc, "//release/artists/artist/*[name()='name' or name()='join']", false)); - release.artist = release.artist.replace(/ \(\d+\)$/, ""); + + release.artist_credits = new Array(); + $(xmldoc).find("release artists artist").each(function() { + var $artist = $(this); + var ac = { name: $artist.find("name").text(), anv: $artist.find("anv").text(), join: " " + $artist.find("join").text() + " "}; + //ac.name = ac.name.replace(/ \(\d+\)$/, ""); + release.artist_credits.push(ac); + }); + + // Grab release title + release.title = getXPathVal(xmldoc, "//release/title", true); + + // Grab release event information + var releasedate = getXPathVal(xmldoc, "//release/released", true); + if (typeof releasedate != "undefined" && releasedate != "") { + var tmp = releasedate.split('-'); if (tmp[0] != "undefined" && tmp[0] != "") { + + release.year = parseInt(tmp[0], 10); - + + if (tmp[1] != "undefined" && tmp[1] != "") { + release.month = parseInt(tmp[1], 10); + if (tmp[2] != "undefined" && tmp[2] != "") { + release.day = parseInt(tmp[2], 10); + } + } + } - } - release.label = getXPathVal(xmldoc, "//release/labels/label/@name", true); - release.catno = getXPathVal(xmldoc, "//release/labels/label/@catno", true); + } + + release.labels = new Array(); + $(xmldoc).find("release labels label").each(function() { + release.labels.push( { name: $(this).attr('name'), catno: $(this).attr('catno') } ); + }); + release.format = MediaTypes[getXPathVal(xmldoc, "//release/formats/format/@name", true)]; + // Special handle of vinyl 7", 10" and 12" + $(xmldoc).find("release formats descriptions description").each(function() { + var desc = $(this).text(); + if (desc.match(/7"|10"|12"/)) release.format = MediaTypes[desc]; + }); + + release.country = Countries[ getXPathVal(xmldoc, "//release/country", true) ]; + + // Grab tracks + var tracks = []; + var trackNodes = getXPathVal(xmldoc, "//tracklist/track", false); + + for (var i = 0; i < trackNodes.snapshotLength; i++) { + var track = new Object(); + var trackNode = trackNodes.snapshotItem(i); + + track.title = trackNode.getElementsByTagName("title").item(0).textContent; + track.duration = trackNode.getElementsByTagName("duration").item(0).textContent; + + // Track artist + var trackArtist = cookArtistName(getXPathVal(xmldoc, ".//artists//*[name()='name' or name()='join']", false, trackNode)); + trackArtist = trackArtist.replace(/ \(\d+\)$/, ""); + + if (trackArtist != "") + track.artist = trackArtist; + + // Track position and release number + var trackPosition = trackNode.getElementsByTagName("position").item(0).textContent; + var releaseNumber = 1; + + // Skip special tracks + if (trackPosition.toLowerCase().match("^(video|mp3)")) { + trackPosition = ""; + } + + // Remove "CD" prefix + trackPosition = trackPosition.replace(/^CD/i, ""); + // Multi discs e.g. 1.1 or 1-1 + var tmp = trackPosition.match(/^(\d+)(?=(-|\.)\d*)/); + if (tmp && tmp[0]) { + releaseNumber = tmp[0]; + } else { + // Vinyls disc numbering: A1, B3, ... + tmp = trackPosition.match(/^([A-Za-z])\d*/); + if (tmp && tmp[0] && tmp[0] != "V") { + var code = tmp[0].charCodeAt(0); + // A-Z + if (65 <= code && code <= 90) { + code = code - 65; + } else if (97 <= code && code <= 122) { + // a-z + code = code - (65 + 32); + } + releaseNumber = (code-code%2)/2+1; } + } + + // Create release if needed + if( !release.discs[releaseNumber-1] ) { + release.discs.push(new Object()); + release.discs[releaseNumber-1].tracks = []; + } + + // Trackposition is empty e.g. for release title + if (trackPosition != "" && trackPosition != null) + release.discs[releaseNumber-1].tracks.push(track); + } + mylog(release); + return release; + } + + // Insert links in Discogs page + function insertLink(release) { + + var mbUI = document.createElement('div'); + mbUI.innerHTML = "

    MusicBrainz

    "; + mbUI.className = "section"; + + var mbContentBlock = document.createElement('div'); + mbContentBlock.className = "section_content"; + mbUI.appendChild(mbContentBlock); + + // Form parameters + var parameters = buildFormParameters(release); + + // Build form + var innerHTML = '
    '; + parameters.forEach(function(parameter) { - innerHTML += ''; + var value = parameter.value + ""; + + innerHTML += ""; + }); + innerHTML += ''; + innerHTML += '
    '; + + var totaltracks = 0; + for (var i=0; i < release.discs.length; i++) { + totaltracks += release.discs[i].tracks.length; + } - innerHTML += ' ('; + var releaseartist = ""; + for (var i=0; i < release.artist_credits.length; i++) { + var ac = release.artist_credits[i]; + releaseartist += ac.name; + if (typeof ac.join != 'undefined' && ac.join != "") { + releaseartist += ac.join; + } + } + + innerHTML += ' ('; + innerHTML += "Search in MusicBrainz)"; + + mbContentBlock.innerHTML = innerHTML; + + var prevNode = document.body.querySelector("div.section.ratings"); + prevNode.parentNode.insertBefore(mbUI, prevNode); + + } + + function appendParameter(parameters, paramName, paramValue) { + parameters.push( { name: paramName, value: paramValue } ); + } + + function luceneEscape(string) { + + return encodeURIComponent(string.replace(/\-|\/|\(\)/, "")); + + } + // Helper function: compute url for a release object + function buildFormParameters(release) { + + // Form parameters + var parameters = new Array(); + + appendParameter(parameters, 'name', release.title); + + // Date + country + appendParameter(parameters, 'country', release.country); + if (!isNaN(release.year) && release.year != 0) { appendParameter(parameters, 'date.year', release.year); }; + if (!isNaN(release.month) && release.month != 0) { appendParameter(parameters, 'date.month', release.month); }; + if (!isNaN(release.day) && release.day != 0) { appendParameter(parameters, 'date.day', release.day); }; + + // Label + catnos - // TODO: Handle multiple labels & catnos - if (typeof release.catno != 'undefined' && release.catno != "none") { - appendParameter(parameters, 'labels.0.catalog_number', release.catno); + + for (var i=0; i < release.labels.length; i++) { + var label = release.labels[i]; + appendParameter(parameters, 'labels.'+i+'.name', label.name); + if (typeof label.catno != 'undefined' && label.catno != "none") { + + appendParameter(parameters, 'labels.'+i+'.catalog_number', label.catno); + + } + } - appendParameter(parameters, 'labels.0.name', release.label); + + // Release Artist credits - // TODO: Handle multiple artists - appendParameter(parameters, 'artist_credit.names.0.name', release.artist); - //appendParameter(parameters, 'artist_credit.names.0.join_phrase', release.label); + + for (var i=0; i < release.artist_credits.length; i++) { + var ac = release.artist_credits[i]; + appendParameter(parameters, 'artist_credit.names.'+i+'.name', ac.anv); + appendParameter(parameters, 'artist_credit.names.'+i+'.artist.name', ac.name); + + appendParameter(parameters, 'artist_credit.names.'+i+'.join_phrase', ac.join); + } + // Mediums + for (var i=0; i < release.discs.length; i++) { + var disc = release.discs[i]; + appendParameter(parameters, 'mediums.'+i+'.format', release.format); - // FIXME: i or i+1? + appendParameter(parameters, 'mediums.'+i+'.position', i); + // TODO: Disc title + // appendParameter(parameters, 'mediums.'+i+'.name', release.format); + + // Tracks + for (var j=0; j < disc.tracks.length; j++) { + var track = disc.tracks[j]; + appendParameter(parameters, 'mediums.'+i+'.track.'+j+'.name', track.title); + var tracklength = (typeof track.duration != 'undefined' && track.duration != '') ? track.duration : "?:??"; + appendParameter(parameters, 'mediums.'+i+'.track.'+j+'.length', tracklength); + + // TODO: Handle multiple artists + if (typeof track.artist != "undefined" && track.artist != "") { + appendParameter(parameters, 'mediums.'+i+'.track.'+j+'.artist_credit.names.0.name', track.artist); + } + } + + } + + // Edit note + appendParameter(parameters, 'edit_note', 'From ' + window.location.href.replace(/http:\/\/(www\.|)discogs\.com\/(.*\/|)release\//, 'http://discogs.com/release/')); + + return parameters; + } + + // Helper function: get data from a given XPATH + getXPathVal = function (xmldoc, xpathExpression, wantSingleNode, rootNode) { + if (arguments.length == 3) rootNode = xmldoc; + if (wantSingleNode) { + var nodeval = xmldoc.evaluate(xpathExpression, rootNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + return (nodeval != null) ? nodeval.textContent : ""; + } else { + return xmldoc.evaluate(xpathExpression, rootNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + } + } + + // Helper function: compute artist name from a XPATH resultNodes + function cookArtistName(nodes) { + var artistName = ""; + + var isLastItemJoinWord = false; + for (var i = 0; i < nodes.snapshotLength; i++) { + var node = nodes.snapshotItem(i); + + if (node.localName != "join" && i != 0 && !isLastItemJoinWord) { + artistName += ", "; + } + + if (node.localName == "join") { + isLastItemJoinWord = true; + } else { + isLastItemJoinWord = false; + } + + artistName += (i == 0 ? "" : " ") + node.textContent; + mylog(i + " - " + artistName); + } + return artistName; + } + + function mylog(obj) { + var DEBUG = true; - if (DEBUG) { + + if (DEBUG && unsafeWindow.console) { + unsafeWindow.console.log(obj); + } + } + + // Reference Discogs <-> MusicBrainz map + var MediaTypes = new Array(); -MediaTypes["8-Track Cartridge"] = 9; -MediaTypes["Acetate"] = 7; -MediaTypes["Betamax"] = 13; -MediaTypes["Blu-ray"] = 13; -MediaTypes["Blu-ray-R"] = 13; -MediaTypes["Cassette"] = 8; -MediaTypes["CD"] = 1; -MediaTypes["CDr"] = 1; -MediaTypes["CDV"] = 1; -MediaTypes["Cylinder"] = 14; -MediaTypes["DAT"] = 11; -MediaTypes["Datassette"] = 13; -MediaTypes["DCC"] = 16; -MediaTypes["DVD"] = 2; -MediaTypes["DVDr"] = 2; -MediaTypes["Edison Disc"] = 7; -MediaTypes["File"] = 12; -MediaTypes["Flexi-disc"] = 7; + +MediaTypes["8-Track Cartridge"] = "Cartridge"; + +MediaTypes["Acetate"] = "Vinyl"; + +MediaTypes["Betamax"] = "Betamax"; + +MediaTypes["Blu-ray"] = "Blu-ray"; + +MediaTypes["Blu-ray-R"] = "Blu-ray"; + +MediaTypes["Cassette"] = "Cassette"; + +MediaTypes["CD"] = "CD"; + +MediaTypes["CDr"] = "CD"; + +MediaTypes["CDV"] = "CD"; + +MediaTypes["Cylinder"] = "Wax Cylinder"; + +MediaTypes["DAT"] = "DAT"; + +MediaTypes["Datassette"] = "Other"; + +MediaTypes["DCC"] = "DCC"; + +MediaTypes["DVD"] = "DVD"; + +MediaTypes["DVDr"] = "DVD"; + +MediaTypes["Edison Disc"] = "Vinyl"; + +MediaTypes["File"] = "Digital Media"; + +MediaTypes["Flexi-disc"] = "Vinyl"; + MediaTypes["Floppy Disk"] = 12; -MediaTypes["HD DVD"] = 13; -MediaTypes["HD DVD-R"] = 13; -MediaTypes["Hybrid"] = 13; -MediaTypes["Laserdisc"] = 5; -MediaTypes["Memory Stick"] = 13; -MediaTypes["Microcassette"] = 13; -MediaTypes["Minidisc"] = 6; -MediaTypes["MVD"] = 13; -MediaTypes["Reel-To-Reel"] = 10; -MediaTypes["SelectaVision"] = 13; -MediaTypes["Shellac"] = 7; -MediaTypes["UMD"] = 13; -MediaTypes["VHS"] = 13; -MediaTypes["Video 2000"] = 13; -MediaTypes["Vinyl"] = 7; + +MediaTypes["HD DVD"] = "HD-DVD"; + +MediaTypes["HD DVD-R"] = "HD-DVD"; + +MediaTypes["Hybrid"] = "Other"; + +MediaTypes["Laserdisc"] = "LaserDisc"; + +MediaTypes["Memory Stick"] = "Digital Media"; + +MediaTypes["Microcassette"] = "Other"; + +MediaTypes["Minidisc"] = "MiniDisc"; + +MediaTypes["MVD"] = "Other"; + +MediaTypes["Reel-To-Reel"] = "Reel-to-reel"; + +MediaTypes["SelectaVision"] = "Other"; + +MediaTypes["Shellac"] = "Vinyl"; + +MediaTypes["UMD"] = "UMD"; + +MediaTypes["VHS"] = "VHS"; + +MediaTypes["Video 2000"] = "Other"; + +MediaTypes["Vinyl"] = "Vinyl"; +MediaTypes['7"'] = '7" Vinyl'; +MediaTypes['10"'] = '10" Vinyl'; +MediaTypes['12"'] = '12" Vinyl'; + + + var Countries = new Array(); +Countries["Afghanistan"] = "AF"; +Countries["Albania"] = "AL"; +Countries["Algeria"] = "DZ"; +Countries["American Samoa"] = "AS"; +Countries["Andorra"] = "AD"; +Countries["Angola"] = "AO"; +Countries["Anguilla"] = "AI"; +Countries["Antarctica"] = "AQ"; +Countries["Antigua and Barbuda"] = "AG"; +Countries["Argentina"] = "AR"; +Countries["Armenia"] = "AM"; +Countries["Aruba"] = "AW"; +Countries["Australia"] = "AU"; +Countries["Austria"] = "AT"; +Countries["Azerbaijan"] = "AZ"; +Countries["Bahamas"] = "BS"; +Countries["Bahrain"] = "BH"; +Countries["Bangladesh"] = "BD"; +Countries["Barbados"] = "BB"; +Countries["Belarus"] = "BY"; +Countries["Belgium"] = "BE"; +Countries["Belize"] = "BZ"; +Countries["Benin"] = "BJ"; +Countries["Bermuda"] = "BM"; +Countries["Bhutan"] = "BT"; +Countries["Bolivia"] = "BO"; +Countries["Croatia"] = "HR"; +Countries["Botswana"] = "BW"; +Countries["Bouvet Island"] = "BV"; +Countries["Brazil"] = "BR"; +Countries["British Indian Ocean Territory"] = "IO"; +Countries["Brunei Darussalam"] = "BN"; +Countries["Bulgaria"] = "BG"; +Countries["Burkina Faso"] = "BF"; +Countries["Burundi"] = "BI"; +Countries["Cambodia"] = "KH"; +Countries["Cameroon"] = "CM"; +Countries["Canada"] = "CA"; +Countries["Cape Verde"] = "CV"; +Countries["Cayman Islands"] = "KY"; +Countries["Central African Republic"] = "CF"; +Countries["Chad"] = "TD"; +Countries["Chile"] = "CL"; +Countries["China"] = "CN"; +Countries["Christmas Island"] = "CX"; +Countries["Cocos (Keeling) Islands"] = "CC"; +Countries["Colombia"] = "CO"; +Countries["Comoros"] = "KM"; +Countries["Congo"] = "CG"; +Countries["Cook Islands"] = "CK"; +Countries["Costa Rica"] = "CR"; +Countries["Virgin Islands, British"] = "VG"; +Countries["Cuba"] = "CU"; +Countries["Cyprus"] = "CY"; +Countries["Czech Republic"] = "CZ"; +Countries["Denmark"] = "DK"; +Countries["Djibouti"] = "DJ"; +Countries["Dominica"] = "DM"; +Countries["Dominican Republic"] = "DO"; +Countries["Ecuador"] = "EC"; +Countries["Egypt"] = "EG"; +Countries["El Salvador"] = "SV"; +Countries["Equatorial Guinea"] = "GQ"; +Countries["Eritrea"] = "ER"; +Countries["Estonia"] = "EE"; +Countries["Ethiopia"] = "ET"; +Countries["Falkland Islands (Malvinas)"] = "FK"; +Countries["Faroe Islands"] = "FO"; +Countries["Fiji"] = "FJ"; +Countries["Finland"] = "FI"; Countries["France"] = "FR"; -Countries["Germany"] = 81; -Countries["US"] = 222; -Countries["UK"] = 221; -Countries["Afghanistan"] = 1; -Countries["Albania"] = 2; -Countries["Algeria"] = 3; -Countries["American Samoa"] = 4; -Countries["Andorra"] = 5; -Countries["Angola"] = 6; -Countries["Anguilla"] = 7; -Countries["Antarctica"] = 8; -Countries["Antigua & Barbuda"] = 9; -Countries["Argentina"] = 10; -Countries["Armenia"] = 11; -Countries["Aruba"] = 12; -Countries["Australia"] = 13; -Countries["Austria"] = 14; -Countries["Azerbaijan"] = 15; -Countries["Bahamas, The"] = 16; -Countries["Bahrain"] = 17; -Countries["Bangladesh"] = 18; -Countries["Barbados"] = 19; -Countries["Belarus"] = 20; -Countries["Belgium"] = 21; -Countries["Belize"] = 22; -Countries["Benin"] = 23; -Countries["Bermuda"] = 24; -Countries["Bhutan"] = 25; -Countries["Bolivia"] = 26; -Countries["Bosnia & Herzegovina"] = 27; -Countries["Botswana"] = 28; -Countries["Bouvet Island"] = 29; -Countries["Brazil"] = 30; -Countries["British Indian Ocean Territory"] = 31; -Countries["Brunei"] = 32; -Countries["Bulgaria"] = 33; -Countries["Burkina Faso"] = 34; -Countries["Burma"] = 146; -Countries["Burundi"] = 35; -Countries["Cambodia"] = 36; -Countries["Cameroon"] = 37; -Countries["Canada"] = 38; -Countries["Cape Verde"] = 39; -Countries["Cayman Islands"] = 40; -Countries["Central African Republic"] = 41; -Countries["Chad"] = 42; -Countries["Chile"] = 43; -Countries["China"] = 44; -Countries["Christmas Island"] = 45; -Countries["Cocos (Keeling) Islands"] = 46; -Countries["Colombia"] = 47; -Countries["Comoros"] = 48; -Countries["Congo, Democratic Republic of the"] = 236; -Countries["Congo, Republic of the"] = 49; -Countries["Cook Islands"] = 50; -Countries["Costa Rica"] = 51; -Countries["Croatia"] = 53; -Countries["Cuba"] = 54; -Countries["Cyprus"] = 55; -Countries["Czechoslovakia"] = 245; -Countries["Czech Republic"] = 56; -Countries["Denmark"] = 57; -Countries["Djibouti"] = 58; -Countries["Dominican Republic"] = 60; -Countries["East Timor"] = 61; -Countries["Ecuador"] = 62; -Countries["Egypt"] = 63; -Countries["El Salvador"] = 64; -Countries["Equatorial Guinea"] = 65; -Countries["Eritrea"] = 66; -Countries["Estonia"] = 67; -Countries["Ethiopia"] = 68; -Countries["Europe"] = 241; -Countries["Falkland Islands"] = 69; -Countries["Faroe Islands"] = 70; -Countries["Fiji"] = 71; -Countries["Finland"] = 72; -Countries["French Guiana"] = 75; -Countries["French Polynesia"] = 76; -Countries["French Southern & Antarctic Lands"] = 77; -Countries["Gabon"] = 78; -Countries["Gambia, The"] = 79; -Countries["Gaza Strip"] = 249; -Countries["Georgia"] = 80; -Countries["German Democratic Republic (GDR)"] = 244; -Countries["Ghana"] = 82; -Countries["Gibraltar"] = 83; -Countries["Greece"] = 84; -Countries["Greenland"] = 85; -Countries["Grenada"] = 86; -Countries["Guadeloupe"] = 87; -Countries["Guam"] = 88; -Countries["Guatemala"] = 89; -Countries["Guernsey"] = 251; -Countries["Guinea-Bissau"] = 91; -Countries["Guinea"] = 90; -Countries["Guyana"] = 92; -Countries["Haiti"] = 93; -Countries["Heard Island and McDonald Islands"] = 94; -Countries["Holy See (Vatican City)"] = 227; -Countries["Honduras"] = 95; -Countries["Hong Kong"] = 96; -Countries["Hungary"] = 97; -Countries["Iceland"] = 98; -Countries["India"] = 99; -Countries["Indonesia"] = 100; -Countries["Iran"] = 101; -Countries["Iraq"] = 102; -Countries["Ireland"] = 103; -Countries["Israel"] = 104; -Countries["Italy"] = 105; -Countries["Ivory Coast"] = 52; -Countries["Jamaica"] = 106; -Countries["Japan"] = 107; -Countries["Jersey"] = 253; -Countries["Jordan"] = 108; -Countries["Kazakhstan"] = 109; -Countries["Kenya"] = 110; -Countries["Kiribati"] = 111; -Countries["Kuwait"] = 114; -Countries["Kyrgyzstan"] = 115; -Countries["Laos"] = 116; -Countries["Latvia"] = 117; -Countries["Lebanon"] = 118; -Countries["Lesotho"] = 119; -Countries["Liberia"] = 120; -Countries["Libya"] = 121; -Countries["Liechtenstein"] = 122; -Countries["Lithuania"] = 123; -Countries["Luxembourg"] = 124; -Countries["Macau"] = 125; -Countries["Macedonia"] = 126; -Countries["Madagascar"] = 127; -Countries["Malawi"] = 128; -Countries["Malaysia"] = 129; -Countries["Maldives"] = 130; -Countries["Mali"] = 131; -Countries["Malta"] = 132; -Countries["Man, Isle of"] = 252; -Countries["Marshall Islands"] = 133; -Countries["Martinique"] = 134; -Countries["Mauritania"] = 135; -Countries["Mauritius"] = 136; -Countries["Mayotte"] = 137; -Countries["Mexico"] = 138; -Countries["Micronesia, Federated States of"] = 139; -Countries["Moldova"] = 140; -Countries["Monaco"] = 141; -Countries["Mongolia"] = 142; -Countries["Montenegro"] = 247; -Countries["Montserrat"] = 143; -Countries["Morocco"] = 144; -Countries["Mozambique"] = 145; -Countries["Namibia"] = 147; -Countries["Nauru"] = 148; -Countries["Nepal"] = 149; -Countries["Netherlands Antilles"] = 151; -Countries["Netherlands"] = 150; -Countries["New Caledonia"] = 152; -Countries["New Zealand"] = 153; -Countries["Nicaragua"] = 154; -Countries["Niger"] = 155; -Countries["Nigeria"] = 156; -Countries["Niue"] = 147; -Countries["Norfolk Island"] = 158; -Countries["Northern Mariana Islands"] = 159; -Countries["North Korea"] = 112; -Countries["Norway"] = 160; -Countries["Oman"] = 161; -Countries["Pakistan"] = 162; -Countries["Palau"] = 163; -Countries["Panama"] = 164; -Countries["Papua New Guinea"] = 165; -Countries["Paraguay"] = 166; -Countries["Peru"] = 167; -Countries["Philippines"] = 168; -Countries["Pitcairn Islands"] = 169; -Countries["Poland"] = 170; -Countries["Portugal"] = 171; -Countries["Puerto Rico"] = 172; -Countries["Qatar"] = 173; -Countries["Reunion"] = 174; -Countries["Romania"] = 175; -Countries["Russia"] = 176; -Countries["Rwanda"] = 177; -Countries["Saint Helena"] = 196; -Countries["Saint Kitts and Nevis"] = 178; -Countries["Saint Lucia"] = 179; -Countries["Saint Pierre and Miquelon"] = 197; -Countries["Saint Vincent and the Grenadines"] = 180; -Countries["Samoa"] = 181; -Countries["San Marino"] = 182; -Countries["Sao Tome and Principe"] = 183; -Countries["Saudi Arabia"] = 184; -Countries["Senegal"] = 185; -Countries["Serbia and Montenegro"] = 242; -Countries["Serbia"] = 254; -Countries["Seychelles"] = 186; -Countries["Sierra Leone"] = 187; -Countries["Singapore"] = 188; -Countries["Slovakia"] = 189; -Countries["Slovenia"] = 190; -Countries["Solomon Islands"] = 191; -Countries["Somalia"] = 192; -Countries["South Africa"] = 193; -Countries["South Georgia and the South Sandwich Islands"] = 248; -Countries["South Korea"] = 113; -Countries["Spain"] = 194; -Countries["Sri Lanka"] = 195; -Countries["Sudan"] = 198; -Countries["Suriname"] = 199; -Countries["Svalbard"] = 200; -Countries["Swaziland"] = 201; -Countries["Sweden"] = 202; -Countries["Switzerland"] = 203; -Countries["Syria"] = 204; -Countries["Taiwan"] = 205; -Countries["Tajikistan"] = 206; -Countries["Tanzania"] = 207; -Countries["Thailand"] = 208; -Countries["Togo"] = 209; -Countries["Tokelau"] = 210; -Countries["Tonga"] = 211; -Countries["Trinidad & Tobago"] = 212; -Countries["Tunisia"] = 213; -Countries["Turkey"] = 214; -Countries["Turkmenistan"] = 215; -Countries["Turks and Caicos Islands"] = 216; -Countries["Tuvalu"] = 217; -Countries["Uganda"] = 218; -Countries["Ukraine"] = 219; -Countries["United Arab Emirates"] = 220; -Countries["Uruguay"] = 224; -Countries["USSR"] = 243; -Countries["Uzbekistan"] = 225; -Countries["Vanuatu"] = 226; -Countries["Vatican City"] = 227; -Countries["Venezuela"] = 228; -Countries["Vietnam"] = 229; -Countries["Wallis and Futuna"] = 232; -Countries["West Bank"] = 249; -Countries["Western Sahara"] = 233; -Countries["Yemen"] = 234; -Countries["Yugoslavia"] = 235; -Countries["Zambia"] = 237; -Countries["Zimbabwe"] = 238; +Countries["French Guiana"] = "GF"; +Countries["French Polynesia"] = "PF"; +Countries["French Southern Territories"] = "TF"; +Countries["Gabon"] = "GA"; +Countries["Gambia"] = "GM"; +Countries["Georgia"] = "GE"; +Countries["Germany"] = "DE"; +Countries["Ghana"] = "GH"; +Countries["Gibraltar"] = "GI"; +Countries["Greece"] = "GR"; +Countries["Greenland"] = "GL"; +Countries["Grenada"] = "GD"; +Countries["Guadeloupe"] = "GP"; +Countries["Guam"] = "GU"; +Countries["Guatemala"] = "GT"; +Countries["Guinea"] = "GN"; +Countries["Guinea-Bissau"] = "GW"; +Countries["Guyana"] = "GY"; +Countries["Haiti"] = "HT"; +Countries["Virgin Islands, U.S."] = "VI"; +Countries["Honduras"] = "HN"; +Countries["Hong Kong"] = "HK"; +Countries["Hungary"] = "HU"; +Countries["Iceland"] = "IS"; +Countries["India"] = "IN"; +Countries["Indonesia"] = "ID"; +Countries["Wallis and Futuna"] = "WF"; +Countries["Iraq"] = "IQ"; +Countries["Ireland"] = "IE"; +Countries["Israel"] = "IL"; +Countries["Italy"] = "IT"; +Countries["Jamaica"] = "JM"; +Countries["Japan"] = "JP"; +Countries["Jordan"] = "JO"; +Countries["Kazakhstan"] = "KZ"; +Countries["Kenya"] = "KE"; +Countries["Kiribati"] = "KI"; +Countries["Kuwait"] = "KW"; +Countries["Kyrgyzstan"] = "KG"; +Countries["Lao People's Democratic Republic"] = "LA"; +Countries["Latvia"] = "LV"; +Countries["Lebanon"] = "LB"; +Countries["Lesotho"] = "LS"; +Countries["Liberia"] = "LR"; +Countries["Libyan Arab Jamahiriya"] = "LY"; +Countries["Liechtenstein"] = "LI"; +Countries["Lithuania"] = "LT"; +Countries["Luxembourg"] = "LU"; +Countries["Montserrat"] = "MS"; +Countries["Macedonia, The Former Yugoslav Republic of"] = "MK"; +Countries["Madagascar"] = "MG"; +Countries["Malawi"] = "MW"; +Countries["Malaysia"] = "MY"; +Countries["Maldives"] = "MV"; +Countries["Mali"] = "ML"; +Countries["Malta"] = "MT"; +Countries["Marshall Islands"] = "MH"; +Countries["Martinique"] = "MQ"; +Countries["Mauritania"] = "MR"; +Countries["Mauritius"] = "MU"; +Countries["Mayotte"] = "YT"; +Countries["Mexico"] = "MX"; +Countries["Micronesia, Federated States of"] = "FM"; +Countries["Morocco"] = "MA"; +Countries["Monaco"] = "MC"; +Countries["Mongolia"] = "MN"; +Countries["Mozambique"] = "MZ"; +Countries["Myanmar"] = "MM"; +Countries["Namibia"] = "NA"; +Countries["Nauru"] = "NR"; +Countries["Nepal"] = "NP"; +Countries["Netherlands"] = "NL"; +Countries["Netherlands Antilles"] = "AN"; +Countries["New Caledonia"] = "NC"; +Countries["New Zealand"] = "NZ"; +Countries["Nicaragua"] = "NI"; +Countries["Niger"] = "NE"; +Countries["Nigeria"] = "NG"; +Countries["Niue"] = "NU"; +Countries["Norfolk Island"] = "NF"; +Countries["Northern Mariana Islands"] = "MP"; +Countries["Norway"] = "NO"; +Countries["Oman"] = "OM"; +Countries["Pakistan"] = "PK"; +Countries["Palau"] = "PW"; +Countries["Panama"] = "PA"; +Countries["Papua New Guinea"] = "PG"; +Countries["Paraguay"] = "PY"; +Countries["Peru"] = "PE"; +Countries["Philippines"] = "PH"; +Countries["Pitcairn"] = "PN"; +Countries["Poland"] = "PL"; +Countries["Portugal"] = "PT"; +Countries["Puerto Rico"] = "PR"; +Countries["Qatar"] = "QA"; +Countries["Reunion"] = "RE"; +Countries["Romania"] = "RO"; +Countries["Russian Federation"] = "RU"; +Countries["Rwanda"] = "RW"; +Countries["Saint Kitts and Nevis"] = "KN"; +Countries["Saint Lucia"] = "LC"; +Countries["Saint Vincent and The Grenadines"] = "VC"; +Countries["Samoa"] = "WS"; +Countries["San Marino"] = "SM"; +Countries["Sao Tome and Principe"] = "ST"; +Countries["Saudi Arabia"] = "SA"; +Countries["Senegal"] = "SN"; +Countries["Seychelles"] = "SC"; +Countries["Sierra Leone"] = "SL"; +Countries["Singapore"] = "SG"; +Countries["Slovenia"] = "SI"; +Countries["Solomon Islands"] = "SB"; +Countries["Somalia"] = "SO"; +Countries["South Africa"] = "ZA"; +Countries["Spain"] = "ES"; +Countries["Sri Lanka"] = "LK"; +Countries["Sudan"] = "SD"; +Countries["Suriname"] = "SR"; +Countries["Swaziland"] = "SZ"; +Countries["Sweden"] = "SE"; +Countries["Switzerland"] = "CH"; +Countries["Syrian Arab Republic"] = "SY"; +Countries["Tajikistan"] = "TJ"; +Countries["Tanzania, United Republic of"] = "TZ"; +Countries["Thailand"] = "TH"; +Countries["Togo"] = "TG"; +Countries["Tokelau"] = "TK"; +Countries["Tonga"] = "TO"; +Countries["Trinidad and Tobago"] = "TT"; +Countries["Tunisia"] = "TN"; +Countries["Turkey"] = "TR"; +Countries["Turkmenistan"] = "TM"; +Countries["Turks and Caicos Islands"] = "TC"; +Countries["Tuvalu"] = "TV"; +Countries["Uganda"] = "UG"; +Countries["Ukraine"] = "UA"; +Countries["United Arab Emirates"] = "AE"; +Countries["UK"] = "GB"; +Countries["US"] = "US"; +Countries["United States Minor Outlying Islands"] = "UM"; +Countries["Uruguay"] = "UY"; +Countries["Uzbekistan"] = "UZ"; +Countries["Vanuatu"] = "VU"; +Countries["Vatican City State (Holy See)"] = "VA"; +Countries["Venezuela"] = "VE"; +Countries["Viet Nam"] = "VN"; +Countries["Western Sahara"] = "EH"; +Countries["Yemen"] = "YE"; +Countries["Zambia"] = "ZM"; +Countries["Zimbabwe"] = "ZW"; +Countries["Taiwan"] = "TW"; +Countries["[Worldwide]"] = "XW"; +Countries["Europe"] = "XE"; +Countries["Soviet Union (historical, 1922-1991)"] = "SU"; +Countries["East Germany (historical, 1949-1990)"] = "XG"; +Countries["Czechoslovakia (historical, 1918-1992)"] = "XC"; +Countries["Congo, The Democratic Republic of the"] = "CD"; +Countries["Slovakia"] = "SK"; +Countries["Bosnia and Herzegovina"] = "BA"; +Countries["Korea (North), Democratic People's Republic of"] = "KP"; +Countries["Korea (South), Republic of"] = "KR"; +Countries["Montenegro"] = "ME"; +Countries["South Georgia and the South Sandwich Islands"] = "GS"; +Countries["Palestinian Territory"] = "PS"; +Countries["Macao"] = "MO"; +Countries["Timor-Leste"] = "TL"; +Countries["<85>land Islands"] = "AX"; +Countries["Guernsey"] = "GG"; +Countries["Isle of Man"] = "IM"; +Countries["Jersey"] = "JE"; +Countries["Serbia"] = "RS"; +Countries["Saint Barthélemy"] = "BL"; +Countries["Saint Martin"] = "MF"; +Countries["Moldova"] = "MD"; +Countries["Yugoslavia (historical, 1918-2003)"] = "YU"; +Countries["Serbia and Montenegro (historical, 2003-2006)"] = "CS"; +Countries["Côte d'Ivoire"] = "CI"; +Countries["Heard Island and McDonald Islands"] = "HM"; +Countries["Iran, Islamic Republic of"] = "IR"; +Countries["Saint Pierre and Miquelon"] = "PM"; +Countries["Saint Helena"] = "SH"; +Countries["Svalbard and Jan Mayen"] = "SJ";