Enhanced Barter

This userscript aims to enhance your experience at barter.vg

目前為 2017-07-30 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Enhanced Barter
// @icon         https://bartervg.com/imgs/ico/barter/favicon-32x32.png
// @namespace    Royalgamer06
// @author       Royalgamer06
// @version      0.9.2
// @description  This userscript aims to enhance your experience at barter.vg
// @include      https://barter.vg/*
// @include      https://www.steamtrades.com/user/*?do=postcomments&message=*
// @connect      steamcommunity.com
// @connect      store.steampowered.com
// @connect      steamtrades.com
// @connect      royalgamer06.ga
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
// @homepageURL  https://github.com/Royalgamer06/EnhancedBarter/
// @supportURL   https://github.com/Royalgamer06/EnhancedBarter/issues
// ==/UserScript==

this.$ = this.jQuery = jQuery.noConflict(true);
$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || "");
        } else {
            o[this.name] = this.value || "";
        }
    });
    return o;
};
$.fn.zip = function(s) {
    var o = $(s);
    return this.map(function(i, e) {
        return $(e).add($(o[i]));
    });
};
var myuid, mysid;
$(document).ready(function() {
    if (location.host == "barter.vg") {
        myuid = $("#signin").attr("href").split("/")[4];
        mysid = $("abbr+ a:has(.icon)").length > 0 ? $("abbr+ a:has(.icon)").attr("href").split("/")[4] : 0;
        unsafeWindow.cancelOffers = cancelOffers;
        unsafeWindow.remindPendingOffers = remindPendingOffers;
        unsafeWindow.remindCompletedOffers = remindCompletedOffers;
        unsafeWindow.showIgnored = fixIgnored;
        unsafeWindow.showIgnored = showIgnored;
        unsafeWindow.findIgnored = findIgnored;
        unsafeWindow.syncLibrary = syncLibrary;
        unsafeWindow.extendExpiry = extendExpiry;
        unsafeWindow.massSendOffers = massSendOffers;
        unsafeWindow.massSendMutualOffers = massSendMutualOffers;
        unsafeWindow.removeOwnedGamesFromPending = removeOwnedGamesFromPending;
        $("[name=offer_message]").removeAttr("maxlength");
        if (location.href.indexOf("/u/") > -1) {
            if (location.href.indexOf("/o/") > -1) {
                if (location.href.indexOf(myuid) > -1 && $("input[value='Completed Offer']").length > 0) {
                    console.log("Found 'Completed Offer'");
                    $("input[value='Completed Offer']").click(function(ev) {
                        ev.preventDefault();
                        var steamid = $("a[href*='/steamcommunity.com/profiles/']:not([href*=" + mysid + "])").attr("href").split("/")[4];
                        var name = $("th:contains('Next Step')+ > a[href*='/steamcommunity.com/profiles/']").text().replace(" on Steam", "");
                        var msg = "+REP " + name + " is an amazing trader, recommended! We successfully completed this trade: " + location.href + ". Thanks a lot for the trade!";
                        leaveFeedback(this, msg, steamid);
                    });
                } else if (location.href.indexOf(myuid) > -1 && $(".activity").length > 0) {
                    $(".activity").first().before("<br><strong>Or...  </strong><input id=automatedoffer type=submit value='Begin Automated Offer'></input><input id=removeowned type=submit value='Remove Owned Games From Pending Offers' style='float:right;'></input>");
                    $("#automatedoffer").click(function() {
                        var offering = prompt("Offering:", "Exact Game Title");
                        var offering_to_group = prompt("Make offer to group:", "wishlist, unowned").split(",").map(Function.prototype.call, String.prototype.trim); //tradable, wishlist, unowned, library, blacklist
                        var want_from_group = prompt("I want:", "wishlist, unowned").split(",").map(Function.prototype.call, String.prototype.trim); //tradable, wishlist, unowned, library
                        var ratio = prompt("Ratio of offering against want:", "all:1");
                        var expire_days = parseInt(prompt("Days until offer expires:", "15"));
                        var trading_cards_only = confirm("Do you only want games with trading cards?");
                        var unbundled_only = confirm("Do you only want unbundled games?");
                        var exclude_givenaway = confirm("Do you want to exclude given away (free) games?");
                        //var exclude_combined = confirm("Do you want to exclude combined games (bundles, packs)?");
                        var exclude_rating_lower_than = parseInt(prompt("Minimum rating:", "0"));
                        if (exclude_rating_lower_than === null || isNaN(exclude_rating_lower_than) || !isFinite(exclude_rating_lower_than)) {
                            exclude_rating_lower_than = false;
                        }
                        var exclude_title_containing = prompt("Exclude games containing the term(s):", "DLC, pack");
                        if (exclude_title_containing !== null && exclude_title_containing !== "") {
                            exclude_title_containing = exclude_title_containing.split(",").map(Function.prototype.call, String.prototype.trim);
                        } else {
                            exclude_title_containing = false;
                        }
                        if (confirm("Are you sure you want to send this automated offer?")) {
                            console.log("Sending mass offers...", offering, offering_to_group, want_from_group, ratio, expire_days, trading_cards_only, unbundled_only, exclude_givenaway, exclude_rating_lower_than, exclude_title_containing);
                            massSendOffers(offering, offering_to_group, want_from_group, ratio, expire_days, trading_cards_only, unbundled_only, exclude_givenaway, exclude_rating_lower_than, exclude_title_containing);
                            alert("Initiated process of sending automated offers!\nCheck the javascript console (F12) for details.\nPlease don't close this tab until all offers have finished sending.");
                        }
                    });
                    $("#removeowned").click(function() {
                        if (confirm("Are you sure you want to remove owned games from pending offers?")) {
                            removeOwnedGamesFromPending();
                            alert("Initiated process of removing owned games from pending offers!\nCheck the javascript console (F12) for details.\nPlease don't close this tab until all offers have finished updating.");
                        }
                    });
                }
                /*$("#offerHeader > tbody > tr:nth-child(1)").append('<button style="float: right; height: 100%;" id="switchsides">Switch Sides</button>');
                $("#switchsides").click(function() {
                    var rem = $("#main > h1 > a:nth-child(2)").attr("href").split("/")[4];
                    var uids = [];
                    $("#offerHeader > tbody > tr > td:nth-child(2) > strong > a").each(function() {
                        uids.push(this.href.split("/")[4]);
                    });
                    uids.splice($.inArray(rem, uids), 1);
                    var uid = uids[0];
                    console.log(location.href.split(rem)[0] + uid + location.href.split(rem)[1]);
                    //location.href = location.href.split(rem)[0] + uid + location.href.split(rem)[1];
                });*/
                //$("select[name=expire_days] > option[selected=selected]").html("1000");
                [3, 7].forEach(function(i) {
                    $("#exchanges > fieldset:nth-child(" + i + ")").append('<input type="submit" value="Invert all checkboxes" style="width:100%;height:2em;margin-bottom:.7em;" id="checkall' + i + '">');
                    $("#checkall" + i).on("click", function() {
                        $("#exchanges > fieldset:nth-child(" + i + ") input[type=checkbox]").each(function() {
                            this.checked = !this.checked;
                        });
                        return false;
                    });
                    $("#exchanges > fieldset:nth-child(" + i + ")").append('<input type="submit" value="Enable disabled tradables" style="width:100%;height:2em;margin-bottom:.7em;" id="enable' + i + '">');
                    $("#enable" + i).on("click", function(ev) {
                        ev.preventDefault();
                        if (confirm("Are you sure you want to enable disabled tradables? Make sure the other party is okay with this!")) {
                            setTimeout(function() {
                                $("#exchanges > fieldset:nth-child(" + i + ") input[disabled]").each(function() {
                                    this.removeAttribute("disabled");
                                    this.removeAttribute("title");
                                    this.name = "add_to_offer_1[]";
                                    this.id = $(this).find("+").attr("for");
                                    this.value = $(this).parent().find("a").attr("href").split("/")[4] + "," + $(this).find("+").attr("for").replace("edit", "");
                                });
                            }, 0);
                        }
                        $("#enable").hide();
                    });
                });
            } else if ($("#profileStats").length > 0) {
                /*if ($("form[action*='/o/']").length === 0) {
                    var profileid = location.href.split("/")[4];
                    var uid = parseInt(profileid, 16);
                    GM_setValue("ignored", GM_getValue("ignored", "") + profileid + ",");
                    $("#profileStats").after('<form action="/u/' + myuid + '/o/" method="POST" class="inline" style="margin:0em 3em 0 0;"><p><input type="hidden" name="to_user_id" value="' + uid + '"><input type="hidden" name="offer_setup" value="1"><input type="submit" value="Send offer on Barter.vg (Ignored)" id="offerButton"></p></form>');
                }*/
            }
        } else if (location.href.indexOf("/i/") > -1) {
            Array.from(document.getElementById("swishlist").parentNode.getElementsByTagName("a")).forEach(function(a) {
                a.setAttribute("href", a.href.replace("w/m/", "") + "t/f/");
                a.setAttribute("target", "_blank");
                a.onclick = function() {
                    this.parentNode.parentNode.removeChild(this.parentNode);
                };
            });
        }
    } else if (location.host == "www.steamtrades.com" && getURIParam("do") == "postcomments") {
        var steamid = getURIParam("steamid");
        var msg = applySentenceCase(getURIParam("message").replace(/\+/g, ' '));
        var profile_id = $("[name=profile_id]").val();
        var xsrf_token = $("[name=xsrf_token]").val();
        if (profile_id !== undefined) {
            var obj = { do: "review_insert", xsrf_token: xsrf_token, profile_id: profile_id, rating: 1, description: msg };
            console.log(obj);
            $.ajax({
                url: "https://www.steamtrades.com/ajax.php",
                method: "POST",
                data: obj,
                success: function() {
                    unsafeWindow.close();
                }
            });
        } else {
            console.log("Already left feedback previously");
            unsafeWindow.close();
        }
    }
});

function syncLibrary(callback) {
    $.post("/u/" + myuid + "/l/", { sync_list: "↻ Sync List", type: 1 });
    var v = parseInt(GM_getValue("dsudv", 1));
    v++;
    GM_setValue("dsudv", v);
    GM_xmlhttpRequest({
        method: "GET",
        url: "http://store.steampowered.com/dynamicstore/userdata/?v=" + v,
        onload: function(response) {
            var json = JSON.parse(response.responseText);
            var ownedApps = json.rgOwnedApps;
            $.post("/u/" + myuid + "/l/e/", { bulk_AppIDs: ownedApps.join(","), add_AppIDs: "+ Add AppIDs", action: "Edit", change_attempted: 1, add_from: "AppIDs" }, function() {
                if (callback) callback();
            });
        }
    });
}

function fixIgnored() {
    var y = $.unique(GM_getValue("ignored").split(","));
    y.splice( $.inArray(myuid, y), 1 );
    GM_setValue("ignored", y.join(","));
}

function showIgnored() {
    fixIgnored();
    console.log(GM_getValue("ignored").slice(0, -1).split(","));
}

function findIgnored() {
    $.get("/u/" + myuid + "/o/", function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        var users = [];
        $("[href*='/u/']", data).each(function() {
            let url = this.href;
            if (/^https?:\/\/barter\.vg\/u\/[a-zA-Z0-9]{1,5}\/$/.test(url) && $.inArray(url, users) == -1) {
                $.get(url, function(data) {
                    data = data.replace(/src="[^"]*"/ig, "");
                    var ignored = $.unique(GM_getValue("ignored", "").split(","));
                    if ($("form[action*='/o/']", data).length === 0 && $.inArray(url.split("/")[4], ignored) == -1 && url.split("/")[4] !== myuid) {
                        GM_setValue("ignored", ignored.join(",") + url.split("/")[4] + ",");
                    }
                });
            }
        });
    });
}

function remindPendingOffers() {
    var reminder = "Hey, I saw that you looked at the offer. Would you please be so kind and respond to it as well? I'd appreciate that very much! Thank you!";
    $("tr.active [title*=Opened]+:contains('pending')").each(function() {
        $.post(this.href, { offer_message: reminder, offer_setup: 3 });
    });
    /*var msg = "Hello, I sent you an trade offer on barter. Could you please take a look and respond? I would appreciate that! Thank you!";
    var steamids = [];
    var ajaxDone = 0;
    $.post("/u/" + myuid + "/o/", { filter_by_status: "pending" }, function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        var count = $(".active:contains('pending')", data).length;
        $($(".active:contains('pending')", data).get().reverse()).each(function() {
            let url = $(this).find("td+ td a").attr("href");
            $.get(url, function(data) {
                data = data.replace(/src="[^"]*"/ig, "");
                var id = $("abbr+ a", data).attr("href").split("/")[4];
                steamids.push(id);
            }).always(function() {
                ajaxDone++;
                if (ajaxDone == count) {
                    postSteamComment(msg, steamids);
                }
            });
        });
    });*/
}

function remindCompletedOffers() {
    var steammsg = "Hello, please mark our trade as complete on barter. I would appreciate that! Thank you!";
    var bartermsg = "Hello, please mark our trade as complete. I would appreciate that! Thank you!";
    var steamids = [];
    var ajaxDone = 0;
    $.post("/u/" + myuid + "/o/", { filter_by_status: "completed" }, function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        var count = $(".active:contains('completed'):not(.completed)", data).length;
        $($(".active:contains('completed'):not(.completed)", data).get().reverse()).each(function() {
            let url = $(this).find("td+ td a").attr("href");
            $.post(url, { offer_message: bartermsg, offer_setup: 3 });
            /*$.get(url, function(data) {
                data = data.replace(/src="[^"]*"/ig, "");
                var id = $("abbr+ a", data).attr("href").split("/")[4];
                steamids.push(id);
            }).always(function() {
                ajaxDone++;
                if (ajaxDone == count) {
                    postSteamComment(steammsg, steamids);
                }
            });*/
        });
    });
}

function leaveFeedback(elem, msg, steamid) {
    $(elem).val("Completing trade, sending feedback and syncing library...").attr("disabled", true);
    $.post($(elem).parents("form").attr("action"), $(elem).parents("form").serializeObject());
    var steamids = [steamid];
    //postSteamComment(msg, steamids);
    postSteamTradesComment(msg, steamid);
    setPostTradeClipboard();
    syncLibrary(function() {
        location.reload();
    });
}

function setPostTradeClipboard() {
    var uids = [];
    $("#offerHeader > tbody > tr > td:nth-child(2) > strong > a").each(function() {
        uids.push(this.href.split("/")[4]);
    });
    uids.splice($.inArray(myuid, uids), 1);
    var uid = uids[0];
    var tradelink = location.href.split(myuid)[0] + uid + location.href.split(myuid)[1];
    var sgprofile = "https://www.steamtrades.com/user/" + mysid;
    var msg = "Thanks for the trade!\nI completed the trade on barter.vg and left feedback on your steamtrades profile.\nIf you haven't done so already, could you please do the same?\n" + tradelink + "\n" + sgprofile;
    GM_setClipboard(msg);
}

function postSteamTradesComment(msg, steamid, callback) {
    //$("body").append("<iframe src='https://www.steamtrades.com/user/" + steamid + "?do=postcomments&message=" + msg + "' style='display: none;' />");
    window.open("https://www.steamtrades.com/user/" + steamid + "?do=postcomments&message=" + msg, "_blank");
}

function massSendOffers(want_name, offering_to_group, want_from_group, ratio, expire_days, trading_cards_only, unbundled_only, exclude_givenaway, exclude_rating_lower_than, exclude_title_containing) {
    if (!want_name) return alert("No argument \"want_name\". Example: \"The Forest\"");
    $.getJSON("/u/" + myuid + "/t/json/", function(mytradables) {
        var offering = false;
        for (var platformid in mytradables.by_platform) {
            for (var tradeid in mytradables.by_platform[platformid]) {
                let tradable = mytradables.by_platform[platformid][tradeid];
                if ((tradable.title ? tradable.title.toLowerCase() === want_name.toLowerCase() : false) ||
                    (tradable.title_alt ? tradable.title_alt.toLowerCase() === want_name.toLowerCase() : false) ||
                    (tradable.title_formatted ? tradable.title_formatted.toLowerCase() === want_name.toLowerCase() : false) ||
                    (tradable.title_extra ? tradable.title_extra.toLowerCase() === want_name.toLowerCase() : false)) {
                    console.log("Tradable:", tradable);
                    offering = tradable.item_id + "," + tradeid;
                    break;
                }
            }
        }
        if (!offering) return alert("Could not find tradable!\nPlease provide a more accurate name of your tradable and make sure this item is in your tradables list.");
        syncLibrary(function() {
            GM_xmlhttpRequest({
                method: "GET",
                url: "https://royalgamer06.ga/barter/json.php",
                onload: function(response) {
                    var optins = JSON.parse(response.responseText);
                    $.getJSON("/i/" + offering.split(",")[0] + "/json2/", function(gameinfo) {
                        /*
                    TODO:
                     - Add platform exclusion support
                     - Add tag exclusion support
                     - Add tradable-wishlist-ratio support
                     - Add multi-offerings support
                     - Add better UI
                     */

                        //SETUP
                        offering_to_group = offering_to_group ? offering_to_group : ["wishlist"]; //tradable, wishlist, library, blacklist
                        want_from_group = want_from_group ? want_from_group.filter(function(group) { return !!group.toLowerCase().match(/^(tradable|wishlist|unowned|library)$/g); }) : ["wishlist"]; //tradable, wishlist, library, blacklist, unowned
                        ratio = ratio ? ratio.toLowerCase().trim() : "all:1";
                        ratio = ratio.replace(/all/g, "0").split(":");
                        expire_days = expire_days ? expire_days : 1000;
                        trading_cards_only = typeof trading_cards_only !== "undefined" ? trading_cards_only : false;
                        unbundled_only = typeof unbundled_only !== "undefined" ? unbundled_only : false;
                        exclude_givenaway = typeof exclude_givenaway !== "undefined" ? exclude_givenaway : false;
                        //exclude_combined = typeof exclude_combined !== "undefined" ? exclude_combined : false;
                        exclude_rating_lower_than = exclude_rating_lower_than ? exclude_rating_lower_than : 0;
                        exclude_title_containing = exclude_title_containing ? new RegExp(exclude_title_containing.join("|"), "gi") : new RegExp(".^");
                        //EXECUTION
                        offering_to_group.forEach(function(group) {
                            group = group.toLowerCase();
                            for (var userid in gameinfo.users[group]) {
                                let uid = parseInt(userid);
                                let user = gameinfo.users[group][uid];
                                if ((optins.hasOwnProperty(user.steam_id64) ? optins[user.steam_id64] : true) &&
                                    user.tradeable_count >= parseInt(ratio[1])) {
                                    $.getJSON("/u/" + uid.toString(16) + "/t/f/" + myuid + "/json/", function(tradable_groups) {
                                        $.getJSON("/u/" + uid.toString(16) + "/t/json/", function(tradables) {
                                            var ato2 = [];
                                            for (var platformid in tradables.by_platform) {
                                                for (var tradeid in tradables.by_platform[platformid]) {
                                                    let tradable = tradables.by_platform[platformid][tradeid];
                                                    if (isInWantGroup(tradable_groups, want_from_group, tradable.item_id) &&
                                                        tradable.extra > 0 &&
                                                        (trading_cards_only ? tradable.cards > 0 : true) &&
                                                        (unbundled_only ? tradable.bundles_all === 0 : true) &&
                                                        (exclude_givenaway ? tradable.givenaway === 0: true) &&
                                                        (tradable.reviews_positive ? tradable.reviews_positive > exclude_rating_lower_than : true) &&
                                                        !((tradable.title ? !!tradable.title.match(exclude_title_containing) : false) ||
                                                          (tradable.title_alt ? !!tradable.title_alt.match(exclude_title_containing) : false) ||
                                                          (tradable.title_formatted ? !!tradable.title_formatted.match(exclude_title_containing) : false) ||
                                                          (tradable.title_extra ? !!tradable.title_extra.match(exclude_title_containing) : false))) {
                                                        ato2.push(tradable.item_id + "," + tradeid);
                                                    }
                                                }
                                            }
                                            //console.log(ato2);
                                            if (ato2.length >= parseInt(ratio[1])) {
                                                $.post("/u/" + myuid + "/o/", { to_user_id: uid, offer_setup: 1 }, function(data) {
                                                    data = data.replace(/src="[^"]*"/ig, "");
                                                    if ($("#offer", data).length > 0) {
                                                        let url = $("#offer", data).attr("action").split("#")[0];
                                                        $.post(url, { offer_setup: [3, 2, 2], "add_to_offer_1[]": offering, "add_to_offer_2[]": ato2, add_to_offer: "+ Add to Offer" }, function() {
                                                            $.post(url, { offer_setup: [3, 2, 2, 3], from_and_or: parseInt(ratio[0]), to_and_or: parseInt(ratio[1]), expire_days: expire_days, counter_preference: 1, propose_offer: "Finish and Propose Offer" });
                                                        });
                                                    }
                                                });
                                            }
                                        });
                                    });
                                }
                            }
                        });
                    });
                }
            });
        });
    });
}

function isInWantGroup(tradable_groups, want_from_group, item_id) {
    var isInWantGroup = false;
    want_from_group.forEach(function(group) {
        if ($.inArray(item_id, tradable_groups[group]) > -1) {
            isInWantGroup = true;
        }
    });
    return isInWantGroup;
}

function massSendMutualOffers(ratio, expire_days, trade_game, only_offer_trade_game) {
    ratio = ratio ? ratio : "all:1";
    ratio = ratio.replace(/all/g, "0").split(":");
    expire_days = expire_days ? expire_days : 1000;
    trade_game = trade_game ? trade_game : 0;
    only_offer_trade_game = only_offer_trade_game ? only_offer_trade_game : false;
    syncLibrary();
    console.log(ratio, expire_days, trade_game, only_offer_trade_game);
    $.post("/u/" + myuid + "/t/m/?", { tradeGame: trade_game, tradeUser: -2, expandAll: "on", openNewTab: "on", findMatches: "Mutual Matches" }, function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        console.log($("#mutualMatches tr:has([name=offer_setup])", data).zip("#mutualMatches tr:has([href*='/i/'])", data));
        $("#mutualMatches tr:has([name=offer_setup])", data).zip($("#mutualMatches tr:has([href*='/i/'])", data)).each(function() {
            console.log(this);
            let form = $(this).find("form:has([name=offer_setup])");
            console.log(form);
            let offering = [];
            if (only_offer_trade_game) {
                offering.push(trade_game);
            } else {
                $(this).find(".mh > a").each(function() {
                    offering.push(this.href.split("/")[4]);
                });
            }
            console.log(offering);
            let want = [];
            $(this).find(".mw > a").each(function() {
                want.push(this.href.split("/")[4]);
            });
            console.log(want);
            console.log($(form).attr("action"));
            console.log($(form).serializeObject());
            $.post($(form).attr("action"), $(form).serializeObject(), function(data) {
                data = data.replace(/src="[^"]*"/ig, "");
                let url = $("#offerForm", data).attr("action").split("#")[0];
                console.log(url);
                let ato1 = [];
                $(offering).each(function() {
                    ato1.push($("#exchanges > fieldset:nth-child(3) input[value*='" + this + ",']", data).val());
                });
                console.log(ato1);
                let ato2 = [];
                $(want).each(function() {
                    ato2.push($("#exchanges > fieldset:nth-child(7) input[value*='" + this + ",']", data).val());
                });
                console.log(ato2);
                $.post(url, { offer_setup: [3, 2, 2], "add_to_offer_1[]": ato1, "add_to_offer_2[]": ato2, add_to_offer: "+ Add to Offer" }, function() {
                    $.post(url, { offer_setup: [3, 2, 2, 3], from_and_or: parseInt(ratio[0]), to_and_or: parseInt(ratio[1]), expire_days: expire_days, counter_preference: 1, propose_offer: "Finish and Propose Offer" });
                });
            });
        });
    });
}

function cancelOffers(searchquery) {
    $.get("/u/" + myuid + "/o/", function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        if (!searchquery) return alert("No argument \"searchquery\". Example: \"creating\"");
        $("tr:has(:contains('"  + searchquery + "'))", data).each(function() {
            $.post($(this).find("a[href*='/u/" + myuid + "/o/']")[0].href, { offer_setup: 3, cancel_offer:"☒ Cancel Offer" });
        });
    });
}

function extendExpiry(expire_days) { //Old solution: SHOULD UPDATE THIS!
    $.post("/u/" + myuid + "/o/", { filter_by_status: "pending" }, function(data) {
        data = data.replace(/src="[^"]*"/ig, "");
        $(".active a:contains('pending')", data).each(function() {
            let url = this.href;
            $.post(url, { offer_setup: 3, edit_offer: "✐ Edit Offer" }, function(data) {
                data = data.replace(/src="[^"]*"/ig, "");
                var formdata = $("[name=propose_offer]", data).parents("form").serializeObject();
                formdata.expire_days = expire_days ? expire_days : 1000;
                formdata.propose_offer = "Finish and Propose Offer";
                $.post(url, formdata);
            });
        });
    });
}


function removeOwnedGamesFromPending() {
    syncLibrary(function() {
        $.post("/u/" + myuid + "/o/", { filter_by_status: "pending" }, function(data) {
            data = data.replace(/src="[^"]*"/ig, "");
            $(".active a:contains('pending')", data).each(function() {
                let url = this.href;
                $.post(url, { offer_setup: 3, edit_offer: "✐ Edit Offer" }, function(data) {
                    data = data.replace(/src="[^"]*"/ig, "");
                    var formdata = $("[name=propose_offer]", data).parents("form").serializeObject();
                    to_remove = [];
                    $(".bold+ li , div~ .tradables .tradables_items_list li:nth-child(1)", data).each(function() {
                        if ($(this).find("[alt*=avatar]:first").nextUntil("[alt*=avatar]").text().indexOf("library") > -1) {
                            to_remove.push($(this).find("[name='checked[]']").val());
                        }
                    });
                    if (to_remove.length > 0) {
                        if ($(".bold+ li , div+ .tradables .tradables_items_list li:nth-child(1)", data).length <= to_remove.length) {
                            $.post(url, { offer_setup: 3, cancel_offer:"☒ Cancel Offer" });
                        } else {
                            formdata.remove_offer_items = "➖ Remove Selected Tradables";
                            formdata["checked[]"] = to_remove;
                            $.post(url, formdata, function() {
                                formdata.propose_offer = "Finish and Propose Offer";
                                $.post(url, formdata);
                            });
                        }
                    } else {
                        formdata.propose_offer = "Finish and Propose Offer";
                        $.post(url, formdata);
                    }
                });
            });
        });
    });
}

function getURIParam(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split("&"),
        sParameterName,
        i;
    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split("=");
        if (sParameterName[0].toLowerCase() === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
    return false;
}

function applySentenceCase(str) {
    return str.replace(/.+?[\.\?\!](\s|$)/g, function (txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1);
    });
}