User:Chieftain Alex/API javascripts

From Guild Wars 2 Wiki
Jump to: navigation, search
<div id="apidata">[[File:Mediawiki loading animation.gif]]</div>
Mediawiki loading animation.gif (nothing is loading until you paste a script from below into your javascript scratchpad)

Achievements[edit]

/* GW2 API query tool for achievements */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th></tr>';
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];
        result += '<tr><td>'+id+'</td><td>'+name+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible achievement IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/achievements').done(function (ids) {

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/achievements?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Achievements rewarding mastery points[edit]

/* GW2 API query tool for mastery achievements */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Mastery ID</th></tr>';
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];

        // Filter for mastery point achievements only
        if ('rewards' in val) {
            $.each(val.rewards, function(i, v) {
                if ('type' in v && v.type == 'Mastery') {
                    var mid = v.id;
                    result += '<tr><td>'+id+'</td><td>'+name+'</td><td>'+mid+'</td></tr>';
                }
            });
        }
    });
    result += '</table>';
    return result;
}

// Fetch all the possible achievement IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/achievements').done(function (ids) {

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/achievements?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Account achievements[edit]

/* GW2 API query tool for account achievements */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var columns = Object.keys(data[0]);
    var result = '<p>'+data.length+' results returned from the API.</p>' + '\n<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible achievement IDs
(function fetchAPIData() {
    var token = ''; // token goes here
    $.getJSON('https://api.guildwars2.com/v2/account/achievements?access_token='+token).done(function (data) {

        // Write to console
        console.log(data);

        // Write to document
        $('#apidata').html(makeTableHTML(data));
    });
})();

Colors and dyes[edit]

/* GW2 API query tool for colors and dyes */
// This tool is a bit more complex than the others because we need to fetch all of the dye item names too.
// Plus some dyes don't have items (i.e. the default dyes)

// Function to convert an object variable into a table
function makeTableHTML(data, item_data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Color ID</th><th>Color Name</th><th>Dye item id</th><th>Dye item name</th></tr>';
    $.each(data, function(index, val) {
        var item_name = '';
        if (typeof item_data[val['item']] != 'undefined'){
            item_name = item_data[val['item']]['name'];
        }
        result += '<tr><td>'+val['id']+'</td><td>'+val['name']+'</td><td>'+val['item']+'</td><td>'+item_name+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible colour and dye IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/colors').done(function (ids) {
        console.log('Number of colors: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/colors?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate the api results into data, and collect the dye item ids
            var data = {}, item_ids = [];
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                    item_ids.push(val['item']);
                });
            });

          console.log(data);
          console.log(item_ids);

            // Do further requests
            var morepromises = [];
            for (var i=0; i<item_ids.length; i+=maxsize) {
                var current_ids = item_ids.slice(i,i+maxsize).join(',');
                var promise = $.getJSON('https://api.guildwars2.com/v2/items?ids='+current_ids);
                morepromises.push(promise);
            }
            $.when.apply($,morepromises).done(function() {
              console.log('finished morepromises');
                var morenewarguments = {};
                if ( morepromises.length > 1 ) {
                    morenewarguments = arguments;
                } else {
                    morenewarguments[0] = arguments;
                }
                var item_data = {};
                $.each(morenewarguments, function(index, element){
                    $.each(element[0], function(key, val){
                        item_data[val['id']] = val;
                    });
                });

                // Write to console
                console.log(item_data);

                // Write to document
                $('#apidata').html(makeTableHTML(data, item_data));
            });
        });
    });
})();

Events[edit]

// Function to convert an object variable into a table
function makeTableHTML(data) {
    var columns = Object.keys(data[0]);
    var result = '<p>'+data.length+' results returned from the API.</p>' + '\n<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Function to convert local event coordinate system into continent coordinate system
function recalc_coords(continent_rect, map_rect, coords){
	return [
		Math.round(continent_rect[0][0]+(continent_rect[1][0]-continent_rect[0][0])*(coords[0]-map_rect[0][0])/(map_rect[1][0]-map_rect[0][0])),
		Math.round(continent_rect[0][1]+(continent_rect[1][1]-continent_rect[0][1])*(1-(coords[1]-map_rect[0][1])/(map_rect[1][1]-map_rect[0][1])))
	]
}

// Retrieve the maps API (required for continent_rect and map_rect)
$.getJSON('https://api.guildwars2.com/v1/maps.json').done(function(mapsv1){
  var map_event_details = {};

  // Retrieve the event_details API
  $.getJSON('https://api.guildwars2.com/v1/event_details.json').done(function(data){
    $.each(data['events'], function(k, v) {
      // Save map id for later usage
      var n = v.map_id; // map number

      // Calculate new location and overwrite old coordinate system
      //  also check if event map exists in maps API (e.g. Labyrinthine Cliffs does not)
      if (n in mapsv1['maps']) {
        var newcenter = recalc_coords(mapsv1['maps'][n]['continent_rect'], mapsv1['maps'][n]['map_rect'], v.location.center);
        newcenter.push(v.location.center[2]);
        v.location.center = newcenter;
      } else {
        // console.log('Did not find map_id '+n+' within mapsv1 object');
      }

      // Add event id
      v.id = k;

      // Remove keys we didn't want
      delete v.map_id;

      // Check if map exists in object, if not create it.
      if (!(n in map_event_details)) {
        map_event_details[n] = { "name": "", "events": [] };
      }

      // Add the name if the map exists in the maps API.
      if (n in mapsv1['maps']) {
        map_event_details[n]['name'] = mapsv1['maps'][n]['map_name'];
      }
      map_event_details[n]['events'].push(v);
    });
    // console.log(map_event_details);

    // Print available events for the desired map
    var map_id_required = 1195;
    $('#apidata').html('<h2>' + map_event_details[map_id_required]['name'] + '</h2>\n'
                       + makeTableHTML(map_event_details[map_id_required]['events'])
                       + '\n<p' + 're>' + JSON.stringify(map_event_details[map_id_required]['events']) + '</pr' + 'e>');
  });
});

Items[edit]

/* GW2 API query tool for items - note this is a hideously large query, be kind to the api servers and don't use this more than you have to! */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th></tr>';
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];
        result += '<tr><td>'+id+'</td><td>'+name+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible itemsIDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/items').done(function (ids) {
        console.log('Number of items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/items?lang=en&ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            // console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Items unlocking recipes[edit]

/* GW2 API query tool for items - note this is a hideously large query, be kind to the api servers and don't use this more than you have to! */
// Function to convert an object variable into a table
function makeTableHTML(item_data, recipe_data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Source recipe ID</th><th>Source name</th><th>P/S</th><th>Taught recipe ID</th><th>Taught recipe output item ID</th><th>Taught recipe output item name</th></tr>';
    $.each(item_data, function(index, val) {
        if (!('details' in val)) {
          return;
        }
        if (!('recipe_id' in val.details)) {
          return;
        }

        var id = val['id'];
        var name = val['name'];
        result += '<tr><td>'+id+'</td><td>'+name+'</td><td>Primary</td><td>'+ val.details.recipe_id +'</td>';
        if (val.details.recipe_id in recipe_data) {
          result += '<td>' + recipe_data[val.details.recipe_id].output_item_id +'</td>';
          if (recipe_data[val.details.recipe_id].output_item_id in item_data) {
            result += '<td>'+ item_data[recipe_data[val.details.recipe_id].output_item_id].name +'</td>';
          } else {
            result += '<td>'+ '?' +'</td>';
          }
        } else {
          result += '<td>' + '?' +'</td><td>'+ '?' +'</td>';
        }
        result += '</tr>';

        if ('extra_recipe_ids' in val.details) {
          $.each(val.details.extra_recipe_ids, function(i, v){
            result += '<tr><td>'+id+'</td><td>'+name+'</td><td>Secondary</td><td>'+ v +'</td>';
            if (v in recipe_data) {
              result += '<td>' + recipe_data[v].output_item_id +'</td>';
              if (recipe_data[v].output_item_id in item_data) {
                result += '<td>'+ item_data[recipe_data[v].output_item_id].name +'</td>';
              } else {
                result += '<td>'+ '?' +'</td>';
              }
            } else {
              result += '<td>' + '?' +'</td><td>'+ '?' +'</td></tr>';
            }
            result += '</tr>';
          });
        }
    });
    result += '</table>';
    return result;
}

// Removes duplicates, blanks and undefined, then sorts. Usage: a.unique()
Array.prototype.unique = function() {
    return this.filter(function (el, i, self) {
        return self.indexOf(el) === i;
    });
};

// Fetch all the possible itemsIDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/items').done(function (ids) {
        // ITEM START
        console.log('Number of items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/items?lang=en&ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {};
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // RECIPE START
            // Acquire unlocked recipe ids from items
            var recipe_ids = [];
            $.each(data, function(key, val){
                if ('details' in val && 'recipe_id' in val.details) {
                  recipe_ids.push(val.details.recipe_id);
                  if ('extra_recipe_ids' in val.details) {
                    recipe_ids.push(val.details.extra_recipe_ids);
                  }
                }
            });

            // Flatten recipe ids and remove duplicates
            recipe_ids = $.map(recipe_ids, function(v){ return v; }).unique();
            console.log('Number of recipes: ' + recipe_ids.length);

            // Query API until all the recipe_ids have been requested
            var promises2 = [];
            for (var i=0; i<recipe_ids.length; i+=maxsize) {
                var current_recipe_ids = recipe_ids.slice(i,i+maxsize).join(',');
                var promise2 = $.getJSON('https://api.guildwars2.com/v2/recipes?lang=en&ids='+current_recipe_ids);
                promises2.push(promise2);
            }

            // Wait until all the GET requests have finished
            $.when.apply($,promises2).done(function() {
                // Ensure data is an object
                var newarguments2 = {};
                if ( promises2.length > 1 ) {
                    newarguments2 = arguments;
                } else {
                    newarguments2[0] = arguments;
                }

                // Concatenate data into data
                var recipe_data = {}
                $.each(newarguments2, function(index, element){
                    $.each(element[0], function(key, val){
                        recipe_data[val['id']] = val;
                    });
                });

                // Write to console
                // console.log(recipe_data);

                // Write to document
                $('#apidata').html(makeTableHTML(data, recipe_data));
            });
            // RECIPE END
        });
        // ITEM END
    });
})();

Item stats[edit]

/* GW2 API query tool for item stats */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Stats</th></tr>';
    var attributenames = {
      'AgonyResistance': 'Agony_Resistance',
      'BoonDuration': 'Concentration',
      'ConditionDamage': 'Condition_Damage',
      'ConditionDuration': 'Expertise',
      'CritDamage': 'Ferocity',
      'Healing': 'Healing_Power',
      'Power': 'Power',
      'Precision': 'Precision',
      'Toughness': 'Toughness',
      'Vitality': 'Vitality'
    };
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];
        var sumvalue = 0;
        var summultiplier = 0;
        var stats = $.map(val['attributes'], function(v){
          summultiplier += v.multiplier;
          sumvalue += v.value;
          // Print contribution to stat equation only if non-zero
          var eqn = [];
          if (v.multiplier != 0) { eqn.push('(n * ' + v.multiplier + ')'); }
          if (v.value != 0) { eqn.push(v.value); }
          return attributenames[v.attribute] + ': ' + eqn.join(' + ');
        }).join(', ');
        // var stats = JSON.stringify(val['attributes']);

        // Only print non-blank names, non-blank stats, and non-zero totals
        if ( (name.length > 3) && (stats.length > 3) && ((summultiplier + sumvalue) > 0) ) {
            result += '<tr><td>'+id+'</td><td>'+name+'</td><td>'+stats+'</td></tr>';
        }
    });
    result += '</table>';
    return result;
}

// Fetch all the possible item stat IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/itemstats').done(function (ids) {

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/itemstats?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Item ids to selectable prefixes[edit]

/* GW2 API query tool for item stat select options */
// Function to convert an object variable into a table
function makeTableHTML(data, itemstats) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Prefixes</th></tr>';
    $.each(data, function(index, val) {
        var prefixids = val['details']['stat_choices'];
        var prefixnames = [];
        $.each(prefixids, function(i,prefixid) {
            prefixnames.push(itemstats[prefixid]['name'])
        });
        prefixnames.sort(function(a,b) {
            return a > b;
        })
        result += '<tr><td>' + val['id'] + '</td><td>' + val['name'] + '</td><td>' + '{{prefix selection|'+prefixnames.join(', ')+'}}' + '</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible stats and the required item details
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/itemstats?ids=all').done(function (itemstatstemp) {
        var itemstats = {};
        $.each(itemstatstemp, function(k,v) {
            v.name = v.name.replace("'s","");
            itemstats[v.id] = v;
        });

        // Write to console
        console.log(itemstats);
        console.log('Number of item stat prefixes: ' + itemstats.length);

        // Item ids we want
        var ids = [30704,30689];
        console.log('Number of items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/items?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data by id
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data, itemstats));
        });
    });
})();

Maps[edit]

/* GW2 API query tool for maps */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var columns = Object.keys(data[0]);
    var result = '<p>'+data.length+' results returned from the API.</p>' + '\n<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible map IDs via "?ids=all"
(function fetchAPIData() {
    // Query API until all the ids have been requested
    $.getJSON('https://api.guildwars2.com/v2/maps?ids=all').done(function (data) {

        // Write to document
        $('#apidata').html(makeTableHTML(data));
    });
})();

Map details[edit]

/* GW2 API query tool for locations within one map using v2/continents and v2/maps */
// Get information for one map within continent 1, from all floors
var usermapid = 1211;

// Function to convert an object variable into a table
function makeTableHTML(data) {
    var first = Object.keys(data);
    if (first.length > 0) { first = first[1] } else { return '(none)' };
    var columns = Object.keys(data[first]);
    var result = '<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Query
$.getJSON('https://api.guildwars2.com/v2/maps?ids=all', function(maps){
  // Rearrange metadata info by map id
  var data = {};
  $.each(maps, function(i,v){
    data[v.id] = v;
    data[v.id]['points_of_interest'] = {};
    data[v.id]['mastery_points'] = {};
    data[v.id]['sectors'] = {};
  });

  // Get detailed information
  $.getJSON('https://api.guildwars2.com/v2/continents/1/floors?ids=all', function(continentsdata){
    $.each(continentsdata, function(fi,floorv){
      $.each(floorv['regions'], function(ri, regionv){
        $.each(regionv['maps'], function(mi, mapv){
          var mapid = mapv.id;
          if (!(mapid == usermapid)) {
            return
          }
          $.each(mapv['points_of_interest'], function(pi, poiv){
            if (!(poiv.id in data[mapid]['points_of_interest'])) {
              data[mapid]['points_of_interest'][poiv.id] = poiv;
            }
          });
          $.each(mapv['mastery_points'], function(mi, mv){
            if (!(mv.id in data[mapid]['mastery_points'])) {
              data[mapid]['mastery_points'][mv.id] = mv;
            }
          });
          $.each(mapv['sectors'], function(si, sv){
            if (!(sv.id in data[mapid]['sectors'])) {
              data[mapid]['sectors'][sv.id] = sv;
            }
          });
        });
      });
    });

    // Remove maps without any points of interest
    $.each(data, function(k,v){
      if (Object.keys(v['points_of_interest']).length === 0) {
        delete data[k];
      }
    });

    // Display results
    $('#apidata').html( '<h3>Landmarks</h3>\n' + makeTableHTML(data[usermapid]['points_of_interest'])
                    + '\n<h3>Mastery points</h3>\n' + makeTableHTML(data[usermapid]['mastery_points'])
                    + '\n<h3>Sectors</h3>\n' + makeTableHTML(data[usermapid]['sectors']) );
  });
});

Zones in different languages[edit]

/* GW2 API query tool for map ids in different langages */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>EN Name</th><th>DE Name</th><th>ES Name</th><th>FR Name</th></tr>';
    var ids = Object.keys(data['en']);
    $.each(ids, function(index, id) {
        result += '<tr><td>' + id + '</td><td>' + data['en'][id]['name'] + '</td><td>' + data['de'][id]['name'] + '</td><td>' + data['es'][id]['name'] + '</td><td>' + data['fr'][id]['name'] + '</td></tr>';
    });
    result += '</table>';
    return result;
}

// Query API until all the languages have been requested
var zones = {}, langs = ['en', 'de', 'es', 'fr'], promises = [];
$.each(langs, function(li, lang){
  zones[lang] = {};
  promises.push( $.getJSON('https://api.guildwars2.com/v2/maps?ids=all&lang='+lang) );
});

// Wait until all the GET requests have finished
$.when.apply($,promises).done(function() {
  $.each(arguments, function(i,v){
    var thislang = langs[i];
    $.each(v[0], function(i,v){
        zones[thislang][v.id] = v;
    });
  });
  console.log(zones);

  // Display results
  $('#apidata').html( makeTableHTML(zones) );
});

Areas in different languages[edit]

/* GW2 API query tool for sector ids (aka, areas) in different langages */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>EN Name</th><th>DE Name</th><th>ES Name</th><th>FR Name</th></tr>';
    var ids = Object.keys(data['en']);
    $.each(ids, function(index, id) {
        result += '<tr><td>' + id + '</td><td>' + data['en'][id]['name'] + '</td><td>' + data['de'][id]['name'] + '</td><td>' + data['es'][id]['name'] + '</td><td>' + data['fr'][id]['name'] + '</td></tr>';
    });
    result += '</table>';
    return result;
}

// Query API until all the languages have been requested
var sectors = {}, langs = ['en', 'de', 'es', 'fr'], promises = [];
$.each(langs, function(li, lang){
  sectors[lang] = {};
  promises.push( $.getJSON('https://api.guildwars2.com/v2/continents/1/floors?ids=all&lang='+lang) );
});

// Wait until all the GET requests have finished
$.when.apply($,promises).done(function() {
  $.each(arguments, function(i,v){
    var thislang = langs[i];
    $.each(v[0], function(bi,floorv){
      $.each(floorv['regions'], function(ri, regionv){
        $.each(regionv['maps'], function(mi, mapv){
          $.each(mapv['sectors'], function(si, sv){
            if (!(sv.id in sectors[thislang] )) {
              sectors[thislang][sv.id] = sv;
            }
          });
        });
      });
    });
  });
  // console.log(sectors);

  // Display results
  $('#apidata').html( makeTableHTML(sectors) );
});

Minis[edit]

/* GW2 API query tool for minis */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Order</th><th>Item id</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr><td>' + val['id'] + '</td><td>' + val['name'] + '</td><td>' + val['order'] + '</td><td>' + val['item_id'] + '</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible miniature IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/minis').done(function (ids) {
        console.log('Number of minis: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/minis?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Mount skins[edit]

/* GW2 API query tool for mount skins */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var firstindex = Object.keys(data)[0];
    var columns = Object.keys(data[firstindex]);
    var result = '<p>'+Object.keys(data).length+' results returned from the API.</p>' + '\n<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible mount skin IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/mounts/skins').done(function (ids) {
        console.log('Number of skins: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/mounts/skins?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Outfits[edit]

/* GW2 API query tool for outfits */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Unlock item id</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr><td>' + val['id'] + '</td><td>' + val['name'] + '</td><td>' + val['unlock_items'][0] + '</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible miniature IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/outfits?ids=all').done(function (data) {
        console.log('Number of minis: ' + data.length);

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
    });
})();

Profession explorer[edit]

var prof = 'Revenant';

/* GW2 API query tool for traits */
console.clear();

// Function to convert an object variable into a table
function makeTableHTML(sortarray, tdata, specdata, prof) {
    var result = '<table class="table '+prof.toLowerCase()+'" style="margin-bottom:0px;"><tr><th>ID</th><th>Spec</th><th>Tier</th><th>Sort</th>'
               + '<th>I</th><th>Name</th><th>Description</th>'
                +'</tr>';
    var prev_spec = '', this_spec = '';
    $.each(sortarray, function(index, val) {
        this_spec = specdata[val[1]]['name'];
        //var id = val['id'], name = val['name'], position = val['order'] + 1;
        //result += '<tr><td>'+id+'</td><td>'+name+'</td><td>'+position+'</td></tr>';
        var r = '<tr class="' + (this_spec == prev_spec ? '' : 'line-top') + '"><td>'+val[0]+'</td><td>'+specdata[val[1]]['name']+'</td><td>'+val[2]+'</td><td>'+val[3]+'</td>'
                + '<td><img style="width:64px; height: 64px; background-color: #000;" src="'+tdata[val[0]]['icon']+'"></img></td><td>'+tdata[val[0]]['name']+'</td><td>'+tdata[val[0]]['description']+'</td>'
                +'</tr>';
        prev_spec = specdata[val[1]]['name'];
        result += r
    });
    result += '</table>';
    return result;
}

// Fetch all the possible trait IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/professions/'+prof).done(function (profdata) {
console.log('profdata: ',profdata);
        // Collate ids
        var skillids = [];
        $.each(profdata['weapons'], function(i,v){
          $.each(v['skills'], function(ii,vv){
            skillids.push(vv.id);
          });
        });
        $.each(profdata['skills'], function(i,v){
          skillids.push(v.id);
        });

        // Get skill details
        $.getJSON('https://api.guildwars2.com/v2/skills?ids='+skillids.join(',')).done(function(sdata){
            var skill_data = {}
            $.each(sdata, function(k,v){
               skill_data[v.id] = v;
            });

            console.log('skills: ', skill_data);
            $.getJSON('https://api.guildwars2.com/v2/specializations?ids='+profdata['specializations'].join(',')).done(function (specdata) {
                var specs = {};
                $.each(specdata, function(i,v){
                    specs[v.id] = v;
                });

                // Collate ids
                var traitids = [];
                $.each(specs, function(i,v){
                   $.each(v.minor_traits, function(ii,vv){
                       traitids.push(vv);
                   });
                   $.each(v.major_traits, function(ii,vv){
                       traitids.push(vv);
                   });
                });

                // Get trait details
                $.getJSON('https://api.guildwars2.com/v2/traits?ids='+traitids.join(',')).done(function(tdata){
                    var trait_data = {}
                    $.each(tdata, function(k,v){
                       trait_data[v.id] = v;
                    });
                  console.log(trait_data);

                    var trait_sort = [];
                    $.each(trait_data, function(k,v){
                        var pos = v.order || 0;
                        if (v.slot == 'Major') { pos += 1; }
                        trait_sort.push( [v.id, v.specialization, v.tier, pos] );
                    });

                    trait_sort.sort(function(a,b){
                        return a[1] - b[1] || a[2] - b[2] || a[3] - b[3];
                    });

                    // console.log('traits: ', trait_data, ', trait sort: ', trait_sort);
                    var text = '<h2>Traits</h2>\n';
                    text += makeTableHTML(trait_sort, trait_data, specs, prof);

                    // Weapon skills
                    var prev_wep = '';
                    text += '<h2>Weapon skills</h2>\n';
                    text += '<table class="table '+prof.toLowerCase()+'"><tr><th>ID</th><th>Weapon</th><th>Slot</th><th>Icon</th><th>Name</th><th>Description</th></tr>';
                    $.each(profdata['weapons'], function(weapontype,weaponobj){
                      $.each(weaponobj['skills'], function(i,v){
                        var this_wep = weapontype;
                        text += '<tr class="' + (this_wep == prev_wep ? '' : 'line-top') + '">'
                          + '<td>'+v.id+'</td>'
                          + '<td>'+weapontype+'</td>'
                          + '<td>'+v.slot+'</td>'
                          + '<td><img style="width:64px; height: 64px; background-color: #000;" src="'+skill_data[v.id]['icon']+'"></img></td>'
                          + '<td>'+skill_data[v.id]['name']+'</td>'
                          + '<td>'+skill_data[v.id]['description']+'</td>'
                          +'</tr>';
                        prev_wep = weapontype;
                      });
                    });
                    text += '</table>\n';

                    // Heal/Utility/Elite skills
                    text += '<h2>Non-weapon skills</h2>\n';
                    text += '<table class="table '+prof.toLowerCase()+'"><tr><th>ID</th><th>Type</th><th>Icon</th><th>Name</th><th>Description</th></tr>';
                    $.each(profdata['skills'], function(i,v){
                        text += '<tr>'
                          + '<td>'+v.id+'</td>'
                          + '<td>'+v.type+'</td>'
                          + '<td><img style="width:64px; height: 64px; background-color: #000;" src="'+skill_data[v.id]['icon']+'"></img></td>'
                          + '<td>'+skill_data[v.id]['name']+'</td>'
                          + '<td>'+skill_data[v.id]['description']+'</td>'
                          +'</tr>';
                    });
                    text += '</table>\n';

                    $('#apidata').html(text)
                });
            });
        });
    });
})();

Recipes[edit]

/* GW2 API query tool for recipes - note this is a large query, don't use this more than you have to! */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Recipe ID</th><th>Type</th><th>Disciplines</th><th>Rating</th><th>Output item ID</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr><td>'+val['id']+'</td><td>'+val['type']+'</td><td>'+JSON.stringify(val['disciplines'])+'</td><td>'+val['min_rating']+'</td><td>'+val['output_item_id']+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible recipe IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/recipes').done(function (ids) {
        console.log('Number of recipes: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/recipes?lang=en&ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            // console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Recipes for given recipe ids[edit]

/* GW2 API query tool for recipe sheet items */
// Function to convert an object variable into a table
function makeTableHTML(recipe_data, item_data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;">'
    +'<tr><th>Recipe ID</th><th>Crafted item</th><th>Ingredients</th></tr>';

    $.each(recipe_data, function(i,recipe){
      result += '<tr>'+ '<td>'+recipe.id+'</td>';
      if (recipe.output_item_id in item_data) {
        result += '<td>'+ item_data[recipe.output_item_id].name +'</td>'
      } else {
        result += '<td>(unknown item name)</td>'
      }
      var c = $.map(recipe.ingredients, function(v){
        return v.count + ' ' + (v.item_id in item_data ? item_data[v.item_id].name : '(unknown item name)' );
      });
      result += '<td>'+ c.join('<br>') +'</td>'
      result += '</tr>';
    })

    result += '</table>';
    return result;
}

// Removes duplicates, blanks and undefined, then sorts. Usage: a.unique()
Array.prototype.unique = function() {
    return this.filter(function (el, i, self) {
        return self.indexOf(el) === i;
    });
};

// Fetch all the possible itemsIDs
(function fetchAPIData() {
        // recipe_sheet_ids
        var ids = [89262,89226,89173,89165,89205,89166,89270,89147,89130,89139,89187,89250];
      
        // ITEM START
        console.log('Number of recipe sheet items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/items?lang=en&ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {};
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // RECIPE START
            // Acquire unlocked recipe ids from items
            var recipe_ids = [];
            $.each(data, function(key, val){
                if ('details' in val && 'recipe_id' in val.details) {
                  recipe_ids.push(val.details.recipe_id);
                  if ('extra_recipe_ids' in val.details) {
                    recipe_ids.push(val.details.extra_recipe_ids);
                  }
                }
            });

            // Flatten recipe ids and remove duplicates
            recipe_ids = $.map(recipe_ids, function(v){ return v; }).unique();
            console.log('Number of recipes: ' + recipe_ids.length);

            // Query API until all the recipe_ids have been requested
            var promises2 = [];
            for (var i=0; i<recipe_ids.length; i+=maxsize) {
                var current_recipe_ids = recipe_ids.slice(i,i+maxsize).join(',');
                var promise2 = $.getJSON('https://api.guildwars2.com/v2/recipes?lang=en&ids='+current_recipe_ids);
                promises2.push(promise2);
            }

            // Wait until all the GET requests have finished
            $.when.apply($,promises2).done(function() {
                // Ensure data is an object
                var newarguments2 = {};
                if ( promises2.length > 1 ) {
                    newarguments2 = arguments;
                } else {
                    newarguments2[0] = arguments;
                }

                // Concatenate data into data
                var recipe_data = {}
                $.each(newarguments2, function(index, element){
                    $.each(element[0], function(key, val){
                        recipe_data[val['id']] = val;
                    });
                });

                // Write to console
                console.log(recipe_data);

                // Scan through recipes, dig out all item ids
                var item_ids = [];
                $.each(recipe_data, function(i,v){
                  item_ids.push(v.output_item_id);
                  $.each(v.ingredients, function(ii,vv){
                    item_ids.push(vv.item_id);
                  });
                });

                // Remove duplicates
                item_ids = item_ids.unique();

                // Get more item ids
                // Query API until all the ids have been requested
                var promises3 = [];
                for (var i=0; i<item_ids.length; i+=maxsize) {
                    var current_ids = item_ids.slice(i,i+maxsize).join(',');
                    var promise3 = $.getJSON('https://api.guildwars2.com/v2/items?lang=en&ids='+current_ids);
                    promises3.push(promise3);
                }
                // Wait until all the GET requests have finished
                $.when.apply($,promises3).done(function() {
                    // Ensure data is an object
                    var newarguments3 = {};
                    if ( promises3.length > 1 ) {
                        newarguments3 = arguments;
                    } else {
                        newarguments3[0] = arguments;
                    }
                    // Concatenate data into data
                    var item_data = {}
                    $.each(newarguments3, function(index, element){
                        $.each(element[0], function(key, val){
                            item_data[val['id']] = val;
                        });
                    });

                    // Write to console
                    console.log(item_data);

                    // Write to document
                    $('#apidata').html(makeTableHTML(recipe_data, item_data));
                });
            });
            // RECIPE END
        });
        // ITEM END
})();

Recipes for given input item ids[edit]

/* GW2 API query tool for recipes using given item ids - see line marked "inputitemids" */
// Function to convert an object variable into a table
function makeTableHTML(data, itemdata, inputitemids) {
    var result = '<table class="table mech1" style="margin-bottom:0px;">'
                  +'<tr><th>Recipe ID</th><th>Type</th><th>Disciplines</th><th>Output item ID</th>'
                  // +'<th>Input item ID 1</th><th>Input item ID 2</th><th>Input item ID 3</th><th>Input item ID 4</th>'
                  +'<th>Output item name</th>'+'<th>Output item level</th>'+'<th>Output item rarity</th>'
                  +'<th>Input item name 1</th><th>Input item name 2</th><th>Input item name 3</th><th>Input item name 4</th>'
                +'</tr>';
    $.each(data, function(index, val) {

        // Shuffle the array sequence until the input item is at the beginning
        $.each(val['ingredients'], function(i, v){
          var n = inputitemids.indexOf(v.item_id)
          if ( n > -1 ){
            val['ingredients'].splice(i,1);
            val['ingredients'].unshift(v);
          }
        });

        // Add a fourth element if necessary to maintain table width
        if (val['ingredients'].length < 4) {
          val['ingredients'].push({'item_id': -1});
        };

        // Figure out the row
        result += '<tr><td>'+val['id']+'</td><td>'+val['type']+'</td><td>'+JSON.stringify(val['disciplines'])+'</td>'+'<td>'+val['output_item_id']+'</td>'
                   //+ $.map(val['ingredients'], function(v){ return '<td>' + v.item_id + '</td>' }).join('')
                   + '<td>'+ ( itemdata.hasOwnProperty(val['output_item_id']) ? itemdata[val['output_item_id']]['name']   : '' ) +'</td>'
                   + '<td>'+ ( itemdata.hasOwnProperty(val['output_item_id']) ? itemdata[val['output_item_id']]['level']  : '' ) +'</td>'
                   + '<td>'+ ( itemdata.hasOwnProperty(val['output_item_id']) ? itemdata[val['output_item_id']]['rarity'] : '' ) +'</td>'
                   + $.map(val['ingredients'], function(v){
                       if ( itemdata.hasOwnProperty(v.item_id) ){
                         return '<td>' + itemdata[v.item_id]['name'] + '</td>'
                       } else {
                         return '<td>' + '' + '</td>'
                       }
                     }).join('')
                 +'</tr>';
    });
    result += '</table>';
    return result;
}

// Removes duplicates, blanks and undefined, then sorts. Usage: a.unique()
Array.prototype.unique = function() {
    return this.filter(function (el, i, self) {
        return self.indexOf(el) === i;
    });
};

// Fetch all the relevant recipe IDs
(function fetchAPIData() {

    // QUERY GROUP 1
    // Weapon inscriptions
    var inputitemids = [38429, 38430, 38431, 38433, 38432, 86685, 38434];

    // Make recipe enquiries
    var promises = [], maxsize = 1;
    for (var i=0; i<inputitemids.length; i+=maxsize) {
        var current_ids = inputitemids.slice(i,i+maxsize).join(',');
        var promise = $.getJSON('https://api.guildwars2.com/v2/recipes/search?input='+current_ids);
        promises.push(promise);
    }

    $.when.apply($,promises).done(function() {
        // Ensure data is an object
        var newarguments = {};
        if ( promises.length > 1 ) {
            newarguments = arguments;
        } else {
            newarguments[0] = arguments;
        }

        // Concatenate data into data
        var recipeids = [];
        $.each(newarguments, function(index, element){
            $.each(element[0], function(key, val){
                recipeids.push(val);
            });
        });

        // QUERY GROUP 2
        console.log('Number of recipes: ' + recipeids.length);

        // Query API until all the ids have been requested
        var promises2 = [], maxsize = 200;
        for (var i=0; i<recipeids.length; i+=maxsize) {
            var current_ids = recipeids.slice(i,i+maxsize).join(',');
            var promise2 = $.getJSON('https://api.guildwars2.com/v2/recipes?lang=en&ids='+current_ids);
            promises2.push(promise2);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises2).done(function() {
            // Ensure data is an object
            var newarguments2 = {};
            if ( promises2.length > 1 ) {
                newarguments2 = arguments;
            } else {
                newarguments2[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments2, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Now collate item ids so we can look their details up.
            var itemids = [];
            $.each(data, function(index, val) {
                itemids.push(val['output_item_id']);
                $.each(val['ingredients'], function(i,v){
                  itemids.push(v.item_id);
                });
            });

            // Remove duplicates (e.g. axe hafts)
            itemids.unique();

            // QUERY GROUP 3
            console.log('Number of items: ' + itemids.length);

            // Query API until all the ids have been requested
            var promises3 = [], maxsize = 200;
            for (var i=0; i<itemids.length; i+=maxsize) {
                var current_ids = itemids.slice(i,i+maxsize).join(',');
                var promise3 = $.getJSON('https://api.guildwars2.com/v2/items?lang=en&ids='+current_ids);
                promises3.push(promise3);
            }

            // Wait until all the GET requests have finished
            $.when.apply($,promises3).done(function() {
                // Ensure data is an object
                var newarguments3 = {};
                if ( promises3.length > 1 ) {
                    newarguments3 = arguments;
                } else {
                    newarguments3[0] = arguments;
                }

                // Concatenate data into data
                var itemdata = {}
                $.each(newarguments3, function(index, element){
                    $.each(element[0], function(key, val){
                        itemdata[val['id']] = val;
                    });
                });

                // Write to document
                $('#apidata').html(makeTableHTML(data, itemdata, inputitemids));
            });
        });
    });
})();

Skins[edit]

/* GW2 API query tool for skins - another long and cruel query for the api */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var firstindex = Object.keys(data)[0];
    var columns = Object.keys(data[firstindex]);
    var result = '<p>'+Object.keys(data).length+' results returned from the API.</p>' + '\n<table class="table mech1" style="margin-bottom:0px;" rules="all"><tr>';
    $.each(columns, function(i,v) { result += '<th>' + v + '</th>' });
    result += '</tr>';
    $.each(data, function(i,v) {
        result += '<tr>';
        $.each(columns, function(ii,vv){
          if (typeof v[vv] == 'object') {
            result += '<td>' + JSON.stringify(v[vv]) + '</td>';
          } else {
            result += '<td>' + v[vv] + '</td>';
          }
        });
        result += '</tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible skin IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/skins').done(function (ids) {
        console.log('Number of skins: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/skins?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Skill challenges[edit]

/* GW2 API query tool for skill challenges - another long and cruel query for the api */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1"><tr><th>SC Coords</th><th>SC ID</th><th>Map ID</th><th>Map Name</th><th>Region ID</th><th>Region Name</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr>'
                     + '<td>'+JSON.stringify(val['coords'])+'</td>'
                     + '<td>'+val['skill_challenge_id']+'</td>'
                     + '<td>'+val['map_id']+'</td><td>'+val['map_name']+'</td>'
                     + '<td>'+val['region_id']+'</td><td>'+val['region_name']+'</td>'
                 +'</tr>';
    });
    result += '</table>';
    return result;
}

var tabledata = [];
$.getJSON('https://api.guildwars2.com/v2/continents/2/floors?ids=all').done(function(data){
  console.log('done fetching.');
  //console.log(data);
  $.each(data, function(i,v){
    $.each(v['regions'], function(regionindex,regionvalue){
      //console.log('scanning region '+regionindex);
      $.each(regionvalue['maps'], function (mapindex, mapvalue){
        //console.log('scanning map '+mapindex);
        $.each(mapvalue['skill_challenges'], function (scindex, scvalue){
          var entry = { "skill_challenge_id": scvalue.id, "coords": scvalue.coord, "map_id": mapindex, "map_name": mapvalue.name, "region_id": regionindex, "region_name": regionvalue.name };
          tabledata.push(entry);
        });
      });
    });
  });
  console.log(tabledata);
  $('#apidata').html(makeTableHTML(tabledata));
});

Skills[edit]

/* GW2 API query tool for skills */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Spec</th></tr>';
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];
        var spec = val['specialization'] || '';
        result += '<tr><td>'+id+'</td><td>'+name+'</td><td>'+spec+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible trait IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/skills').done(function (ids) {

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/skills?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Specializations[edit]

/* GW2 API query tool for skins - another long and cruel query for the api */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Spec ID</th><th>Name</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr><td>'+val['id']+'</td><td>'+val['name']+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible skin IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/specializations?ids=all').done(function (tempdata) {
        var data = {};
        $.each(tempdata, function(i,v){
            data[v.id] = v;
        });

        // Write to console
        console.log(data);

        // Write to document
        $('#apidata').html(makeTableHTML(data));
    });
})();

Traits[edit]

/* GW2 API query tool for traits */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>ID</th><th>Name</th><th>Order</th></tr>';
    $.each(data, function(index, val) {
        var id = val['id'];
        var name = val['name'];
        var position = val['order'] + 1;
        result += '<tr><td>'+id+'</td><td>'+name+'</td><td>'+position+'</td></tr>';
    });
    result += '</table>';
    return result;
}

// Fetch all the possible trait IDs
(function fetchAPIData() {
    $.getJSON('https://api.guildwars2.com/v2/traits').done(function (ids) {

        // Query API until all the ids have been requested
        var promises = [], maxsize = 200;
        for (var i=0; i<ids.length; i+=maxsize) {
            var current_ids = ids.slice(i,i+maxsize).join(',');
            var promise = $.getJSON('https://api.guildwars2.com/v2/traits?ids='+current_ids);
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Ensure data is an object
            var newarguments = {};
            if ( promises.length > 1 ) {
                newarguments = arguments;
            } else {
                newarguments[0] = arguments;
            }

            // Concatenate data into data
            var data = {}
            $.each(newarguments, function(index, element){
                $.each(element[0], function(key, val){
                    data[val['id']] = val;
                });
            });

            // Write to console
            console.log(data);

            // Write to document
            $('#apidata').html(makeTableHTML(data));
        });
    });
})();

Other snippers[edit]

Wiki - API - All categories[edit]

/* GW2W API query tool for all categories as the generator with additional properties */
console.log('User pressed run. Starting queries for Special:Categories');
var continue_param = '';

// Wrapper function to return the results once complete
function apiWrapper (config, callbackfunction) {
    // Fetch all the pages
    function apiQuery (config, token) {
        var url = config.baseurl;
        if (token) {
            url += '&' + config.continue + '=' + token;
        }
        $.getJSON(url).done(function(data){
            // Add results to stack
            config.tempresultsarray.push(data['query'][config.output]);

            // Get further results if available
            if (data['continue']) {
                if (continue_param == data['continue'][config.continue]) {
                  // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set.
                  return;
                }
                continue_param = data['continue'][config.continue];
                console.log(continue_param);

                // Make next query
                apiQuery(config, data['continue'][config.continue]);
            } else {
                // Flatten data from nested arrays to one array of result objects
                config.resultsarray = $.map(config.tempresultsarray, function(v) {
                    return v;
                });
                console.log('Query complete.');

                // Call the next function
                callbackfunction(config);
            }
        });
    }
    apiQuery(config);
}

// Function to convert an object variable into a table
function makeTableHTML(config) {
    var data = config.resultsarray;
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>Categories</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr>';
        // Add english page title
        result += '<td>'+val['title']+'</td>';
    
        // Add categories
        if (typeof val['categories'] !== 'undefined'){
            result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ')  + '</td>';
        } else {
            result += '<td>...</td>';
        }
        result += '</tr>\n';
    });
    result += '</table>';
    $('#mw-content-text').html('<pre'+'>' + result + '</'+'pre>');
}

// ------------ Notes -----------------------
// We're using a generator here, so all the parameters usually used from action=query have a "g" on the front of it.
// Generators allow you to extract additional properties not normally available from "list=allpages".
// The output format is dumb from generators, you need to set "formatversion=2" to make it use an array like every other endpoint.
// Generators are dumb; the limits need to be set for each of the individual props too. These limits should be higher than that
//   set for the actual generator. 4x higher seems to be the sweetspot. (e.g. gaplimit=1000, cllimit=4000)
// Admins and bots have limits of 5000 as well as no throttling. Regular users have limits of 500.

// Make the request
apiWrapper({
  baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allcategories&gaclimit=1000' + '&prop=categories&cllimit=5000',
  output: 'pages',
  continue: 'gaccontinue',
  tempresultsarray: [],
  resultsarray: []
}, makeTableHTML);

Wiki - API - All pages[edit]

/* GW2W API query tool for all pages */

// Setup
var redirectfilter = 'nonredirects'; // all, redirects
var languagelinkfilter = 'all'; // withlanglinks, withoutlanglinks
var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=allpages&aplimit=500&apfilterredir='+redirectfilter+'&apfilterlanglinks='+languagelinkfilter;
var datadrop = [];

// Function to concatenate all data
function processdata (datadrop) {
    var contribs = [];
    $.each(datadrop, function(k,v){
        $.each(v, function(kk,vv){
            contribs.push(vv);
        });
    });
    $('#mw-content-text').html(makeTableHTML(contribs));
}

// Function to convert an object variable into a table
function makeTableHTML( data ) {
        var result = '<table class="table mech1"><tbody>'
                    +'<tr><th>Pageid</th><th>Name</th></tr>';
        $.each(data, function(k, v) {
                result += '<tr id="'+v['revid']+'">'
                          +'<td>'+v['pageid']+'</td><td>'+v['title']+'</td>'
                         +'</tr>';
        });
        result += "</tbody></table>";
        return result;
}

// Fetch all the pages
function apiQuery (token,startkey) {
    var url = baseurl;
    if (startkey) {
     url += '&apfrom=' + startkey;
    }
    if (token) {
     url += '&apcontinue=' + token;
    }
    // console.log(url);
    $.getJSON(url).done(function(data){
        datadrop.push(data['query']['allpages']);

        if (data['continue']) {
            apiQuery(data['continue']['apcontinue']);
        } else {
            console.log('Query complete.');
            processdata(datadrop);
        }
    });
}

console.log('User pressed run. Starting queries for Special:AllPages');
//apiQuery(null,'Z');
apiQuery();

Wiki - API - All pages (v2)[edit]

/* GW2W API query tool for all pages */
console.log('User pressed run. Starting queries for Special:AllPages');

// Wrapper function to return the results once complete
function apiWrapper (config, callbackfunction) {
    // Fetch all the pages
    function apiQuery (config, token) {
        var url = config.baseurl;
        if (token) {
            url += '&' + config.continue + '=' + token;
        }
        $.getJSON(url).done(function(data){
            // Add results to stack
            config.tempresultsarray.push(data['query'][config.output]);

            // Get further results if available
            if (data['continue']) {
                apiQuery(config, data['continue'][config.continue]);
            } else {
                // Flatten data from nested arrays to one array of result objects
                config.resultsarray = $.map(config.tempresultsarray, function(v) {
                    return v;
                });
                console.log('Query complete.');

                // Call the next function
                callbackfunction(config);
            }
        });
    }
    apiQuery(config);
}

// Function to convert an object variable into a table
function makeTableHTML (config) {
    var data = config.resultsarray;

    // Generate table html
    var result = '<table class="table mech1"><tbody>';
    if (data.length > 0) {
        var columns = Object.keys(data[0]);
        result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>';
        result += $.map(data, function(v) {
            return '<tr>' + $.map(columns, function(c) {
                return '<td>' + v[c] + '</td>';
            }).join('') + '</tr>';
        }).join('\n');
    }
    result += '</tbody></table>';
    $('#mw-content-text').html(result);
}

// Make request
apiWrapper({
  baseurl: 'https://wiki.guildwars2.com/api.php?format=json&action=query&list=allpages&aplimit=500&apfilterredir=nonredirects&apfilterlanglinks=all',
  output: 'allpages',
  continue: 'apcontinue',
  tempresultsarray: [],
  resultsarray: []
}, makeTableHTML);

Wiki - API - Generator example (all pages, categories and interwikis)[edit]

/* GW2W API query tool for all pages as the generator with additional properties */
console.log('User pressed run. Starting queries for Special:AllPages');
var continue_param = '';

// Wrapper function to return the results once complete
function apiWrapper (config, callbackfunction) {
    // Fetch all the pages
    function apiQuery (config, token) {
        var url = config.baseurl;
        if (token) {
            url += '&' + config.continue + '=' + token;
        }
        $.getJSON(url).done(function(data){
            // Add results to stack
            config.tempresultsarray.push(data['query'][config.output]);

            // Get further results if available
            if (data['continue']) {
                if (continue_param == data['continue'][config.continue]) {
                  // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set.
                  return;
                }
                continue_param = data['continue'][config.continue];
                console.log(continue_param);

                // Make next query
                apiQuery(config, data['continue'][config.continue]);
            } else {
                // Flatten data from nested arrays to one array of result objects
                config.resultsarray = $.map(config.tempresultsarray, function(v) {
                    return v;
                });
                console.log('Query complete.');

                // Call the next function
                callbackfunction(config);
            }
        });
    }
    apiQuery(config);
}

// Function to convert an object variable into a table
function makeTableHTML(config) {
    var data = config.resultsarray;
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>DE page</th><th>ES page</th><th>FR page</th><th>Categories</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr>';
        // Add english page title
        result += '<td>'+val['title']+'</td>';
        if (typeof val['langlinks'] !== 'undefined'){
            // Placeholder with all interwiki language keys
            var resultobj = { de: '', es: '', fr: '' };

            // Go through each interwiki on the page and add them into the object
            $.map(val['langlinks'], function(v){
                resultobj[v['lang']] = v['title'];
            });

            // Add to the results
            result += $.map(resultobj, function(v){
                return '<td>' + v + '</td>';
            }).join('');
        } else {
            result += '<td>...</td><td>...</td><td>...</td>';
        }
        if (typeof val['categories'] !== 'undefined'){
            result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ')  + '</td>';
        } else {
            result += '<td>...</td>';
        }
        result += '</tr>\n';
    });
    result += '</table>';
    $('#mw-content-text').html(result);
}

// ------------ Notes -----------------------
// We're using a generator here, so all the parameters usually used from action=query have a "g" on the front of it.
// Generators allow you to extract additional properties not normally available from "list=allpages".
// The output format is dumb from generators, you need to set "formatversion=2" to make it use an array like every other endpoint.
// Generators are dumb; the limits need to be set for each of the individual props too. These limits should be higher than that
//   set for the actual generator. 4x higher seems to be the sweetspot. (e.g. gaplimit=1000, lllimit=4000, cllimit=4000)
// Admins and bots have limits of 5000 as well as no throttling. Regular users have limits of 500.

// Make the request
apiWrapper({
  baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allpages&gapfilterredir=nonredirects&gapfilterlanglinks=all&gaplimit=1000' + '&prop=categories|langlinks&lllimit=5000&cllimit=5000',
  output: 'pages',
  continue: 'gapcontinue',
  tempresultsarray: [],
  resultsarray: []
}, makeTableHTML);

Wiki - API - Generator for images[edit]

/* GW2W API query tool for all pages as the generator with additional properties */
console.log('User pressed run. Starting queries for Special:AllPages');
var continue_param = '';

// Wrapper function to return the results once complete
function apiWrapper (config, callbackfunction) {
    // Fetch all the pages
    function apiQuery (config, token) {
        var url = config.baseurl;
        if (token) {
            url += '&' + config.continue + '=' + token;
        } else {
            // for testing with a large offset
            // url += '&' + config.continue + '=' + 'Zaan_Ruinbringer.jpg';
        }
        $.getJSON(url).done(function(data){
            // Add results to stack
            config.tempresultsarray.push(data['query'][config.output]);

            // Get further results if available
            if (data['continue']) {
                if (continue_param == data['continue'][config.continue]) {
                  // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set.
                  return;
                }
                continue_param = data['continue'][config.continue];
                console.log(continue_param);

                // Make next query
                apiQuery(config, data['continue'][config.continue]);
            } else {
                // Flatten data from nested arrays to one array of result objects
                config.resultsarray = $.map(config.tempresultsarray, function(v) {
                    return v;
                });
                console.log('Query complete.');

                // Call the next function
                callbackfunction(config);
            }
        });
    }
    apiQuery(config);
}

// Function to convert an object variable into a table
function makeTableHTML(config) {
    var data = config.resultsarray;
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Title</th><th>Height (px)</th><th>Width (px)</th><th>Size (Kb)</th><th>Uploader</th><th>Timestamp</th><th>Categories</th></tr>';
    $.each(data, function(index, val) {
        result += '<tr>';
        // Add english page title
        result += '<td>'+val['title']+'</td>';

        // Add image metadata
        if (typeof val['imageinfo'] !== 'undefined' && val.imageinfo.length > 0){
            var h = val.imageinfo[0].height || 0, w = val.imageinfo[0].width || 0, s = val.imageinfo[0].size || 0, u = val.imageinfo[0].user || '', t = val.imageinfo[0].timestamp || '';
            result += '<td>'+h+'</td><td>'+w+'</td><td>'+(s/1024).toFixed(1)+'</td><td>'+u+'</td><td>'+t.replace('Z','').replace('T',' ') +'</td>';
        } else {
            result += '<td>...</td><td>...</td><td>...</td><td>...</td><td>...</td>';
        }

        // Add categories
        if (typeof val['categories'] !== 'undefined'){
            result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ')  + '</td>';
        } else {
            result += '<td>...</td>';
        }
        result += '</tr>\n';
    });
    result += '</table>';
    $('#mw-content-text').html(result);
}

// Make the request
apiWrapper({
  baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allpages&gapfilterredir=nonredirects&gapfilterlanglinks=all&gapnamespace=6&gaplimit=1000' + '&prop=categories|imageinfo&iiprop=size|user|timestamp&iilimit=5000&cllimit=5000',
  output: 'pages',
  continue: 'gapcontinue',
  tempresultsarray: [],
  resultsarray: []
}, makeTableHTML);

Wiki - API - Namespaces[edit]

/* GW2W API query tool for Mediawiki namespaces statistics */

// Function to convert an object variable into a table
function makeTableHTML( data ) {
        var result = '<table class="table mech1"><tbody>'+'<tr><th>Namespace ID</th><th>Name</th></tr>';
        $.each(data, function(k, v) {
            result += '<tr>'+'<td>'+v['id']+'</td><td>'+v['canonical']+'</td>'+'</tr>';
        });
        result += "</tbody></table>";
        return result;
}

// Fetch all the namespaces
function apiQuery () {
    // console.log(url);
    $.getJSON('https://wiki.guildwars2.com/api.php?action=query&format=json&meta=siteinfo&siprop=namespaces').done(function(data){
        $('#mw-content-text').html(makeTableHTML(data['query']['namespaces']));
    });
}
apiQuery();

Wiki - API - Image metadata[edit]

/* GW2W API query tool for image metadata. You're supposed to be able to query not using names, but I dunno how to convert filenames to page numbers. */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Image title</th><th>Size</th><th>Width</th><th>Height</th><th>User</th></tr>';
    $.each(data, function(index, val) {
        if (typeof val['imageinfo'] !== 'undefined'){
            result += '<tr><td>'+val['title']+'</td>'
                +'<td>'+val['imageinfo'][0]['size']+'</td>'
                +'<td>'+val['imageinfo'][0]['width']+'</td>'
                +'<td>'+val['imageinfo'][0]['height']+'</td>'
                +'<td>'+val['imageinfo'][0]['user']+'</td>'
              +'</tr>';
        }
    });
    result += '</table>';
    return result;
}

// Fetch all the possible itemsIDs
(function fetchAPIData() {

var ids = ["File:Master Blaster.jpg","File:Master Blaster.png","File:Moonshank.jpg"];

        console.log('Number of items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&prop=imageinfo&iiprop=size|user&titles=';
        var lines = [[]], maxlength = 1800, j = 0, running_total = 0;
        for (var i=0; i<ids.length; i++) {
            if ((running_total + ids[i].length) >= maxlength) {
                j += 1;
                lines.push([]);
                running_total = 0;
            }
            running_total += 1 + ids[i].length;
            lines[j].push(ids[i]);
        }
        for (var k=0; k<lines.length; k++) {
            var promise = $.getJSON(baseurl + lines[k].join('|') );
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            var newarguments = {};
            if ( promises.length > 1 ) { newarguments = arguments; } else { newarguments[0] = arguments; }

            console.log(newarguments);
            var alldata = [];
            $.each(newarguments, function(i,v){
              $.each(v[0]['query']['pages'], function(ii,vv){
                alldata.push(vv);
              });
            });

            // Write to document
            $('#apidata').html(makeTableHTML(alldata));
        });

})();

Wiki - API - Interwikis[edit]

/* GW2W API query tool for image metadata. You're supposed to be able to query not using names, but I dunno how to convert filenames to page numbers. */
// Function to convert an object variable into a table
function makeTableHTML(data) {
    var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>DE page</th><th>ES page</th><th>FR page</th></tr>';
    $.each(data, function(index, val) {
        if (typeof val['langlinks'] !== 'undefined'){
            // Add english page title
            result += '<tr>' + '<td>'+val['title']+'</td>';

            // Placeholder with all interwiki language keys
            var resultobj = { de: '', es: '', fr: '' };

            // Go through each interwiki on the page and add them into the object
            $.map(val['langlinks'], function(v){
                resultobj[v['lang']] = v['*'];
            });

            // Add to the results
            result += $.map(resultobj, function(v){
                return '<td>' + v + '</td>';
            }).join('\n');
            result += '</tr>';
        } else {
            result += '<tr>' + '<td>'+val['title']+'</td><td>...</td><td>...</td><td>...</td></tr>';
        }
    });
    result += '</table>';
    return result;
}

// Fetch all the possible itemsIDs
(function fetchAPIData() {

var ids = ["Main Page","Charr","Asura"];

        console.log('Number of items: ' + ids.length);

        // Query API until all the ids have been requested
        var promises = [], baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&prop=langlinks&lllimit=500&titles=';
        var lines = [[]], maxlength = 1800, j = 0, running_count = 0, running_total = 0;
        for (var i=0; i<ids.length; i++) {
            if ((running_total + ids[i].length) >= maxlength || running_count > 500) {
                j += 1;
                lines.push([]);
                running_count = 0;
                running_total = 0;
            }
            running_count += 1;
            running_total += 1 + ids[i].length;
            lines[j].push(ids[i]);
        }
        for (var k=0; k<lines.length; k++) {
            var promise = $.getJSON(baseurl + lines[k].join('|') );
            promises.push(promise);
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            var newarguments = {};
            if ( promises.length > 1 ) { newarguments = arguments; } else { newarguments[0] = arguments; }

            console.log(newarguments);
            var alldata = [];
            $.each(newarguments, function(i,v){
              $.each(v[0]['query']['pages'], function(ii,vv){
                alldata.push(vv);
              });
            });

            // Write to document
            $('#apidata').html(makeTableHTML(alldata));
        });

})();

Wiki - API - SMW single result (via template)[edit]

/* GW2W API query tool for SMW results */
function apiQuery () {
    mw.loader.using('mediawiki.api.parse', function () {
        var query = '[[Has equipment supertype::Weapon]] [[Has appearance::+]]';
        var parameters = 'Has weapon type';
        var firstquery = '{{User:Chieftain Alex/Templates/SMW query|mode=1|query='+query+'}}';

        var api = new mw.Api();
        api.parse(firstquery).done(function (resulttext) {

            // Find the output token
            var pattern = /\<div class\="apiresults"\>(\d+)\<\/div\>/;
            var m = resulttext.match(pattern);
            console.log('regexp', m);

            // Check something matched
            if (!m) {
                console.log('No regular expression matched, quitting.')
                return;
            }

            // Convert match from text into a number.
            var n = Number(m[1]);
            if (n == 0) {
                console.log('Zero results found, quitting.');
            } else {
                console.log(n, ' results found, querying...');

                // Check if n > 5000 -- SMW bug won't let us get more results than this
                if (n > 5000) {
                  console.log('Truncating results to 5000 (SMW bug)');
                  n = 5000;
                }

                // Repeat query n/500 times until done
                var promises = [];
                for (var i=0; i<n; i+=500) {
                    var furtherquery = '{{User:Chieftain Alex/Templates/SMW query|mode=2|query='+query+'|parameters='+parameters+'|offset='+i+'}}';
                    promises.push(api.parse(furtherquery));
                }

                // Wait until all the GET requests have finished
                $.when.apply($,promises).done(function() {
                    // Concatenate the api results
                    var table = $.map(arguments, function(v) { return v; }).join('\n');

                    // Write to document
                    $('#apidata').html(table);

                    // Now copy the output to excel, then remove duplicates including table headings.
                    console.log('Batch query complete.');
                });
            }
        });
    });
}
apiQuery();

Wiki - API - SMW result misc inputs (via template)[edit]

/* GW2W API query tool for SMW results for miscellaneous page inputs */
function apiQuery () {
    mw.loader.using('mediawiki.api.parse', function () {
        var parameters = 'Has game id#;Has context';
        var pages = ["Precise Strike","Tail Wind","Loud Whistle"];

        var api = new mw.Api();

        // Break the list of pages down into a url almost 2000 characters long.
        var lines = [[]], maxlength = 1800, j = 0, running_count = 0, running_total = 0;
        for (var i=0; i<pages.length; i++) {
            if ((running_total + pages[i].length) >= maxlength || running_count > 200) {
                j += 1;
                lines.push([]);
                running_count = 0;
                running_total = 0;
            }
            running_count += 1;
            running_total += 3 + pages[i].length;
            lines[j].push(pages[i]);
        }
        // Submit each request, result is returned as a table.
        var promises = [];
        for (var k=0; k<lines.length; k++) {
            var current_pages = lines[k].join(';');
            var parsetext = '{{User:Chieftain Alex/Templates/SMW query misc|pages='+current_pages+'|parameters='+parameters+'}}';
            promises.push(api.parse(parsetext));
        }

        // Wait until all the GET requests have finished
        $.when.apply($,promises).done(function() {
            // Concatenate the api results
            var table = $.map(arguments, function(v) { return v; }).join('\n');

            // Write to document
            $('#apidata').html(table);

            // Now copy the output to excel, then remove duplicates including table headings.
            console.log('Batch query complete.');
        });
    });
}
apiQuery();

Wiki - API - SMW recipes[edit]

/* GW2W API SMW query tool for recipes */

// Setup
var baseurl = 'https://wiki.guildwars2.com/api.php?action=ask&format=json&query='
var query = encodeURIComponent('[[Has recipe source::Mystic forge]]|?Has output quantity|?Has item data object|?Has output game id|?Has ingredient with id|limit=500|link=none');
var datadrop = [];

// Function to concatenate all data
function processdata (datadrop) {
    var a = $.map(datadrop, function(v){ return v; });
    $('#apidata').html('<pre'+'></pre'+'>');
    $('#apidata pre').text(JSON.stringify(a, null, 2)
                          .replace(new RegExp("\n(  ){4}", "g")," ")
                          .replace(new RegExp("\n(  ){3}\}", "g")," }")
                         );
    console.log('Query and formatting complete.');
}

// Fetch all the recipes
function apiQuery (token) {
    var url = baseurl+query;
    if (token) {
     url += encodeURIComponent('|offset=') + token
    }
    // console.log(url);
    $.getJSON(url).done(function(rawdata){
        // Streamline results prior to storage
        var data = $.map(rawdata['query']['results'], function(v){
            var w = v.printouts;
            return {
                'wiki_page': v.fulltext, // only available if '|mainlabel=-' is not added.
                'output_item_id': (w['Has output game id'].length > 0 ? w['Has output game id'][0] : null),
                'output_item_count': w['Has output quantity'][0],
                'output_item_wikiname': w['Has item data object'][0]['fulltext'],
                'ingredients': $.map(w['Has ingredient with id'], function(x){
                    return {
                        'item_id': (x['Has ingredient id']['item'].length > 0 ? x['Has ingredient id']['item'][0] : null),
                        'count': (x['Has ingredient quantity']['item'].length > 0 ? x['Has ingredient quantity']['item'][0] : null ),
                        'wikiname': (x['Has ingredient name']['item'].length > 0 ? x['Has ingredient name']['item'][0]['fulltext'] : null )
                    }
                })
            }
        });
        datadrop.push(data);

        if (rawdata['query-continue-offset']) {
            apiQuery(rawdata['query-continue-offset']);
        } else {
            processdata(datadrop);
        }
    });
}

console.log('User pressed run. Starting SMW queries...');
apiQuery();

Wiki - API - Template parameter check[edit]

/* GW2W API query tool for Template parameters */
function apiQuery () {
    mw.loader.using('mediawiki.api.parse', function () {
        var template = 'Achievement table row';
        var parameters = 'name:page';
        var firstquery = '{{User:Chieftain Alex/Templates/Parameter check|mode=1|template='+template+'}}';

        var api = new mw.Api();
        api.parse(firstquery).done(function (resulttext) {

            // Find the output token
            var pattern = /\<div class\="apiresults"\>(\d+)\<\/div\>/;
            var m = resulttext.match(pattern);
            console.log('regexp', m);

            // Check something matched
            if (!m) {
                console.log('No regular expression matched, quitting.')
                return;
            }

            // Convert match from text into a number.
            var n = Number(m[1]);
            if (n == 0) {
                console.log('Zero results found, quitting.');
            } else {
                console.log(n, ' results found, querying...');

                // Repeat query n/500 times until done
                var promises = [];
                for (var i=0; i<n; i+=500) {
                    var furtherquery = '{{User:Chieftain Alex/Templates/Parameter check|mode=2|template='+template+'|parameters='+parameters+'|offset='+i+'}}';
                    promises.push(api.parse(furtherquery));
                }

                // Wait until all the GET requests have finished
                $.when.apply($,promises).done(function() {
                    // Concatenate the api results
                    var table = $.map(arguments, function(v) { return v; }).join('\n');

                    // Write to document
                    $('#apidata').html(table);

                    // Now copy the output to excel, then remove duplicates including table headings.
                    console.log('Batch query complete.');
                });
            }
        });
    });
}
apiQuery();

Wiki - API - Unused images[edit]

Currently broken following MW "upgrade".

/* GW2W API query tool for Special:UnusedImages */
// Setup
var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=querypage&qppage=Unusedimages&qplimit=500';
var datadrop = [];

// Function to concatenate all data
function processdata (datadrop) {
    var contribs = [];
    $.each(datadrop, function(k,v){
        $.each(v, function(kk,vv){
            contribs.push(vv);
        });
    });
    $('#mw-content-text').html(makeTableHTML(contribs));
    $('#apitable').tablesorter();
}

// Function to convert an object variable into a table
function makeTableHTML( data ) {
        var result = '<p>Query returned '+data.length+' results:</p>\n'
            +'<table id="apitable" class="table mech1"><tbody><tr><th>Title</th><th>Timestamp</th></tr>';
        $.each(data, function(k, v) {
            var filename = v['title'].replace(/"/g, "'");
            // <td>'+v['databaseResult']['img_user_text']+'</td><td>'+v['databaseResult']['img_description'].replace(/(?:\r\n|\r|\n|\<br \/\>|\<br\>)/g, ' ')+'</td>
            result += '<tr><td>'+'<a href="/wiki/'+filename+'" title="'+filename+'">'+filename+'</a>'+'</td><td>'+v['timestamp']+'</td></tr>';
        });
        result += "</tbody></table>";
        return result;
}

// Fetch all the contributions
function apiQuery (token) {
    var url = baseurl;
    if (token) {
     url += '&qpoffset=' + token
    }
    // console.log(url);
    $.getJSON(url).done(function(data){
        datadrop.push(data['query']['querypage']['results']);

        if (data['continue']) {
            apiQuery(data['continue']['qpoffset']);
        } else {
            console.log('Query complete.');
            processdata(datadrop);
        }
    });
}

RLQ.push(function () {
    // Load the table after loading the required mediawiki resource module
    mw.loader.using( 'jquery.tablesorter', function () {
        console.log('User pressed run. Starting queries for Special:UnusedImages');
        apiQuery();
    });
});

Wiki - API - User contributions[edit]

/* GW2W API query tool for contribution statistics */
// Useful reference link: https://wiki.guildwars2.com/api.php?action=query&meta=siteinfo&siprop=namespaces

// Setup
var user = 'Darqbot';
var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=usercontribs&uclimit=500&ucdir=newer&ucuser=' + user;
var datadrop = [];

// Function to concatenate all data
function processdata (datadrop) {
    var contribs = [];
    $.each(datadrop, function(k,v){
        $.each(v, function(kk,vv){
            contribs.push(vv);
        });
    });
    $('#mw-content-text').html(makeTableHTML(contribs));
}

// Function to convert an object variable into a table
function makeTableHTML( data ) {
        var result = '<table class="table mech1"><tbody>'
                    +'<tr><th>Namespace</th><th>Timestamp</th><th>Size</th><th>Title</th></tr>';
        $.each(data, function(k, v) {
                result += '<tr id="'+v['revid']+'">'
                          +'<td>'+v['ns']+'</td><td>'+v['timestamp']+'</td><td>'+v['size']+'</td><td>'+v['title']+'</td>'
                         +'</tr>';
        });
        result += "</tbody></table>";
        return result;
}

// Fetch all the contributions
function apiQuery (token) {
    var url = baseurl;
    if (token) {
     url += '&uccontinue=' + token
    }
    // console.log(url);
    $.getJSON(url).done(function(data){
        datadrop.push(data['query']['usercontribs']);

        if (data['continue']) {
            apiQuery(data['continue']['uccontinue']);
        } else {
            console.log('Query complete.');
            processdata(datadrop);
        }
    });
}

console.log('User pressed run. Starting queries for User:' + user + '...');
apiQuery();

Wiki - Unlock generator (for Widget:Guaranteed Wardrobe Unlock)[edit]

/* GW2W tool to turn someone else's json into a useable widget object for [[Widget:Guaranteed Wardrobe Unlock]] */

// http://immortius.net.au/wardrobe-unlock-analyser/data/content.json
var p = ;

// Look-up between immortius and sensible endpoints
var converter = {
  "armor": "skins",
  "weapon": "skins",
  "back": "skins",
  "minis": "minis",
  "finishers": "finishers",
  "mail": "mailcarriers",
  "outfits": "outfits",
  "gliders": "gliders",
  "dyes": "dyes",
  "tool": "skins"
};

// Ids and names
var unlockdetails = {
  "skins": {},
  "minis": {},
  "finishers": {},
  "mailcarriers": {},
  "outfits": {},
  "gliders": {},
  "dyes": {}
};

// Script to make it into the wiki widget
var x;
$.map(p.items, function(t){
  x = converter(t.id);
  $.map(t.groups, function(v){
    $.map(v.content, function(w){
      unlockdetails[x][w.id] = w.name;
    });
  });
});

// Paste back to page
$('#apidata').text(JSON.stringify(unlockdetails));

Wiki - ChatLinkSearch tabler (for Special:Search)[edit]

/* GW2W tool to turn the verbose output of the chatlinksearch script into something you can copy into excel */
var listitems = $('.gw2w-chat-link-search ul li');
var tabletext = '<table><tr><th>id</th></tr>';
$.each(listitems, function(k,v){
  tabletext += '<tr>' + '<td>' + v.attributes['data-gameid']['nodeValue'] + '</td>' + '</tr>';
});
tabletext += '</table>';
$('.gw2w-chat-link-search').html(tabletext);

Wiki - Whitespace hunting[edit]

var a = $('#wpTextbox1').val();
var position = a.indexOf(String.fromCharCode(160));
if ( position !== -1 ) {
    console.log('Position of non-breaking space character: ', position);
    console.log( a.substr(0,position), '<<<nbsp>>>' );
} else {
    console.log('Did not find non-breaking space')
}

Reddit - API - Weekly questions thread statistics[edit]

/* Reddit API query tool for post count */
// Setup
var baseurl = 'https://www.reddit.com/r/Guildwars2/search.json?q=title%3Aquestions+thread+author%3AIntigo+OR+author%3AAutoModerator&restrict_sr=on&count=25&sort=new&t=all';
var datadrop = [];

// Function to concatenate all data
function processdata (datadrop) {
    var dump = [];
    $.each(datadrop, function(kk,vv){
        $.each(vv, function(k,v){
            if (  v.data.title.indexOf('Weekly /r/GuildWars2 Question Thread') > -1 ) {
                var date = new Date(v.data.created_utc*1000);
                dump.push({ title: v.data.title, count: v.data.num_comments, date: date });
            }
        });
    });
    $('#apidata').html(makeTableHTML(dump));
}

// Function to convert an object variable into a table
function makeTableHTML ( data ) {
        var result = '<table class="table mech1"><tbody>'
                    +'<tr><th>Date</th><th>Title</th><th>Comment count</th></tr>';
        $.each(data, function(k, v) {
            result += '<tr>'
                       +'<td>'+ pad(v['date'].getUTCDate()) + '/' + pad(v['date'].getUTCMonth()+1) + '/' + v['date'].getUTCFullYear() + '</td>'
                       +'<td>'+v['title']+'</td>'
                       +'<td>'+v['count']+'</td>'
                     +'</tr>';
        });
        result += "</tbody></table>";
        return result;
}

// Function to pad numbers into character strings with leading zeroes
function pad (s) {
    return (s < 10 ? '0' : '') + s;
}

// Fetch all the threads
function apiQuery (qc, token) {
    qc = qc + 1;
    var url = baseurl;
    if (token) {
     url += '&after=' + token
    }
    $.getJSON(url).done(function(data){
        datadrop.push(data['data']['children']);

        if (qc > 8) {
                console.log('Query max count reached.');
                processdata(datadrop);
        } else {
            if ('after' in data['data'] && data['data']['after'] !== null) {
                apiQuery(qc, data['data']['after']);
            } else {
                console.log('Query complete.');
                processdata(datadrop);
            }
        }
    });
}

console.log('User pressed run. Starting queries.');
apiQuery(0);

Miscellaneous - Chatlinks to IDs[edit]

/** window.atob & window.btoa polyfill
 * WTFPLv2 – https://github.com/davidchambers/Base64.js
 */
!function(){function t(t){this.message=t}var e=this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=new Error,t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-a%1*8)){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),e.length%4==1)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(-2*a&6)):0)n=r.indexOf(n);return c})}();

// Decode chatlinks into type and ids
function decodeChatLink(code) {
    var binary = window.atob(code);
    var octets = new Array(binary.length);
    for (var i = 0; i < binary.length; i++) {
        octets[i] = binary.charCodeAt(i);
    }
    var type;
    var id = octets[2] << 8 | octets[1];
    if (octets[0] == 2) {
        type = 'item';
        id = octets[3] << 8 | octets[2];
        id = (octets.length > 4 ? octets[4] << 16 : 0) | id;
    }
    else if (octets[0] == 4 ) { type = 'location'; }
    else if (octets[0] == 6 ) { type = 'skill';    }
    else if (octets[0] == 7 ) { type = 'trait';    }
    else if (octets[0] == 9 ) { type = 'recipe';   }
    else if (octets[0] == 10) { type = 'skin';     }
    else if (octets[0] == 11) { type = 'outfit';   }
    else                      { type = 'unknown'   }
    var outputobject = {
        code: code,
        octets: octets,
        binary: binary,
        type: type,
        id: id
    };
    return outputobject;
}

//
(function chatlinksToIDs () {
    var rawtext = $('#inputrawtext');
    rawtext = rawtext.html().replace("&","&");

    // Regular expression matching
    var expr = /\[&([A-Za-z0-9+/]+=*)\]/g;
    var match, onlychatlinks = [], internalchatlinks = [], internalIDs = [], outputIDs = [];
    while ((match = expr.exec(rawtext))) {
        onlychatlinks.push(match[0]);
        internalchatlinks.push(match[1]);
    }

    // Take each matched expression, and decode it
    $.each(internalchatlinks, function(i,v){
        internalIDs.push(decodeChatLink(v));
    });

    // Only interested in the ids here
    $.each(internalIDs, function(i,v){
        outputIDs.push(v.id);
    });

    // Print results
    $('#outputchatlinks').html(JSON.stringify(onlychatlinks));
    $('#outputids').html(outputIDs.length + ' ids found.<br>' + JSON.stringify(outputIDs));
})();

Miscellaneous - Unique keys in object[edit]

// Find all possible keys for an object of depth 1
var obj = {};

var uniquekeys = [];
$.each(obj, function(i, v){
  $.each(Object.keys(v), function(ii, vv){
    if (uniquekeys.indexOf(vv) == -1) {
      uniquekeys.push(vv);
    }
  });
});
console.log(JSON.stringify(uniquekeys));

Miscellaneous - Remove dead files from galleries[edit]

// Use this whilst using "show preview" on [[User:Darqam/Dat_Icons]]

// Find all gallery elements
var gallery_elements = $('.gallerybox .thumb');

// Gather elements with no child elements (i.e. text only with no images)
var empty_gallery_elements = $.map(gallery_elements, function(v){
  if (v.childElementCount == 0) {
    return v;
  }
});

// Collate the moved file names
var moved_file_names = $.map(empty_gallery_elements, function(v){
  return v.childNodes[0].textContent;
});

// Get the editing box text content
var editing_box_text_lines = $('#wpTextbox1').text().split('\n');

// Scan through editing box lines for moved files
var editing_box_text_lines_new = $.map(editing_box_text_lines, function(v){
  // Compare left-hand side of any pipe elements with the whole array of moved file names
  var lhs = v.split('|')[0].trim().replace('File:','');
  if (moved_file_names.indexOf( lhs ) == -1 ) {
    return v;
  }
});

// Update text-box content without moved files
$('#wpTextbox1').text( editing_box_text_lines_new.join('\n') );
$("#wpTextbox1").fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100);

console.log('Files removed from textbox: ', moved_file_names.length );