Multi-OCH Helper

nopremium.pl and premiumize.me. Inserts a direct download link on several one-click-hosters and some container/folder providers.

当前为 2016-03-07 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Multi-OCH Helper
// @namespace   cuzi
// @oujs:author cuzi
// @description nopremium.pl and premiumize.me. Inserts a direct download link on several one-click-hosters and some container/folder providers.
// @homepageURL https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper
// @icon        https://greasyfork.org/system/screenshots/screenshots/000/003/479/original/icon.png
// @version     14

// @include     data:text/html;MultiOCH*

// @include     /^https:\/\/www\.nopremium\.pl\/files.*$/
// @include     /^https:\/\/www\.premiumize\.me\/services\/?$/
// @include     /^https:\/\/www\.premiumize\.me\/downloader.*$/

// @include     http://download.serienjunkies.org/*
// @include     /^https?:\/\/(www\.)?filecrypt.cc\/Container\/\w+\.html.*$/
// @include     http*filecrypt.cc/helper.html*
// @include     /^http:\/\/www\.firedrive\.com\/share\/(\w|-)+$/
// @include     http://linkcrypt.ws/dir/*
// @include     http://linksave.in/*
// @include     /^http:\/\/ncrypt\.in\/folder\-\w+$/
// @include     http*://*uploaded.net/folder/*
// @include     http*://*uploaded.net/f/*
// @include     http*://rapidgator.net/folder/*
// @include     http://www.relink.us/view.php?id=*
// @include     https://safelinking.net/p/*
// @include     http://linkshield.org/p/*
// @include     http://share-links.biz/*

// @include     /^http:\/\/180upload\.com\/\w+$/
// @include     /^https?:\/\/(www\.)?1fichier\.com\/\?.+$/
// @include     /^http:\/\/www\.(2|4)shared\.com\/[a-z]+\/\w+\/?(.+\.html)?$/
// @include     /^https?:\/\/(www\.)?bayfiles\.(net|com)\/file\/\w+\/.+$/
// @include     /^http:\/\/billionuploads\.com\/\w+$/
// @include     /^http:\/\/bitshare\.com\/files\/\w+\/.+\.html$/
// @include     /^https?:\/\/(www\.)?catshare\.net\/.+$/
// @include     /^https?:\/\/www\.cwtv\.com\/cw-video\/.+$/
// @include     /^http:\/\/www\.datafile\.com\/d\/\w+.*$/
// @include     /^https?:\/\/www\.dailymotion\.com\/video\/\w+.*$/
// @include     /^https?:\/\/(www\.)?devilshare\.net\/view\/\w+\/?.*$/
// @include     http://filecloud.io/download.html
// @include     /^http:\/\/filecloud\.io\/\w+(\/.*)?$/
// @include     /^http:\/\/(www\.)?filefactory\.com\/file\/.+$/
// @include     /^http:\/\/(www\.)?filefactory\.com\/stream\/.+$/
// @include     /^https?:\/\/www.filemonkey.in\/file\/.+$/
// @include     /^https?:\/\/fileom\.com\/\w+.*$/
// @include     /^https?\:\/\/(www\.)?fileparadox\.(in|com)\/\w+.*$/
// @include     /^http:\/\/www\.firedrive\.com\/file\/\w+$/
// @include     /^http:\/\/freakshare\.com\/files\/\w+\/.+\.html$/
// @include     /^http:\/\/dl\.free\.fr\/\w+$/
// @include     /^https?:\/\/(www\.)?gboxes\.com\/.+$/
// @include     /^https?\:\/\/(www\.)?hitfile\.net\/\w+.*$/
// @include     /^http:\/\/hugefiles\.net\/\w+\/?.*$/
// @include     /^https?:\/\/www\.kingfiles\.net\/\w+.*$/
// @include     /^https?:\/\/(\w+\.)?letitbit\.net\/download\/(\w|\.)+\/.*$/
// @include     /^https?:\/\/www\.mediafire\.com\/?\?.+$/
// @include     /^https?:\/\/www\.mediafire\.com\/download\/.+$/
// @include     /^https:\/\/mega\.co\.nz\/\#\!\w+!*(\w|-)*$/
// @include     /^https?:\/\/netload.in\/\w+\/(\w|-|\.)+$/
// @include     /^https?:\/\/netload.in\/(\w|-|\.)+\.htm$/
// @include     /^https?:\/\/www\.oboom\.com\/\w+.*$/
// @include     /^http:\/\/rapidgator\.net\/file\/.+$/
// @include     /^http:\/\/rg\.to\/file\/\w+\/.+\.html$/
// @include     https://rapidshare.com/download/*
// @include     /^https?:\/\/(\w+\.)?rapidu\.net\/\w+.*$/
// @include     /^http:\/\/www\.share-online\.biz\/dl\/\w+$/
// @include     /^https?\:\/\/(www\.)?rockfile\.eu\/\w+.*$/
// @include     /^http:\/\/www\.sockshare\.com\/file\/\w+$/
// @include     /^https?:\/\/soundcloud.com\/(\w|-)+\/(\w|-)+$/
// @include     /^https?:\/\/(www\.)?storbit\.net\/file\/.+$/
// @include     /^http:\/\/streamcloud\.eu\/\w+$/
// @include     /^https?:\/\/streamin\.to\/.+$/
// @include     /^http:\/\/turbobit\.net\/\w+.*\.html$/
// @include     /^http:\/\/www\.tusfiles\.net\/\w+$/
// @include     /^http:\/\/(www\.)?uploadboy\.com\/\w+\.html$/
// @include     /^https?:\/\/uploaded\.(net|to)\/file\/.+$/
// @include     /^http:\/\/uploadrocket\.net\/\w+(\/|\w|-|\.)+\.html?$/
// @include     /^http:\/\/ul\.to\/.+$/
// @include     /^http:\/\/uppit\.com\/\w+(\/.*)?$/
// @include     /^http:\/\/uptobox.com\/\w+$/
// @include     /^https?:\/\/vimeo\.com\/(.+\/)?\d+\/?$/
// @include     /^http:\/\/\w+.vip-file.com\/downloadlib\/.*$/
// @include     /^https?:\/\/www\.youtube\.com\/watch(\?v=|\/).+$/
// @include     /^http:\/\/xerver\.co\/\w+.*$/
// @include     /^http:\/\/www\d*\.zippyshare\.com\/v\/\d+\/file\.html$/

// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js
// @require     https://greasyfork.org/scripts/13883-aes-js/code/aesjs.js
// @grant       GM_registerMenuCommand
// @grant       GM_xmlhttpRequest
// @grant       GM_openInTab
// @grant       GM_setClipboard
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_deleteValue
// @grant       GM_listValues
// @grant       unsafeWindow
// ==/UserScript==
"use strict";


// And to keep for myself whatever I may find? - Certainly. For yourself, and any friends you want to share with you.

// This program inserts a download link on One-Click-Hosters and a few folder services.
// If you click on the button, the current website address (or the links on the relink website) will be sent to nopremium.pl and you'll receive a nopremium.pl download link.
//
// Standard actions for the button are
// * left mouse click:                      copy the link to the clipboard
// * middle/wheel click:                    start download of the link
// * right mouse click:                     open the nopremium.pl website and insert the link in the text box
// * hovering the mouse over the button:    open a menu with all the above option
//

const s_myname = "Multi-OCH Helper";
const h_myname = "Multi-OCH Helper Highlight links";

const config = {
  position : [["bottom","top"],["left","right"]],
  position_desc : ['vertical','horizontal'],
  position_quest : 'Position of the Button. If you use "'+h_myname+'" this has to be set to bottom left',
  leftClick : ["clipboard","download","showLinks","openWebsite","menu","sendToJD","none"],
  leftClick_desc : ["Copy link to clipboard","Direct download","Show links like on website","Open the multihoster website","Show the extended menu","Send links to JDownloader","Do nothing"],
  leftClick_quest : "Action on left mouse click on button",
  middleClick : ["download","clipboard","showLinks","openWebsite","menu","sendToJD","none"],
  middleClick_desc : ["Direct download","Copy link to clipboard","Show links like on website","Open the multihoster website","Show the extended menu","Send links to JDownloader","Do nothing"],
  middleClick_quest : "Action on middle mouse/wheel click on button",
  rightClick : ["openWebsite","clipboard","showLinks","download","menu","sendToJD","none"],
  rightClick_desc : ["Show links like on website","Copy link to clipboard","Direct download","Open the multihoster website","Show the extended menu","Send links to JDownloader","Do nothing"],
  rightClick_quest : "Action on right mouse click on button",
  mouseOver : ["menu","clipboard","download","showLinks","openWebsite","sendToJD","none"],
  mouseOver_desc : ["Show the extended menu","Copy link to clipboard","Direct download","Show links like on website","Open the multihoster website","Send links to JDownloader","Do nothing"],
  mouseOver_quest : "Action on mouse hover over button",
  mouseOverDelay : 'int',
  mouseOverDelay_range : [0,700,3000],
  mouseOverDelay_quest : "Mouse hover time before action is executed.",
  mouseOverDelay_suffix : "milliseconds",
  newTab : 'bool',
  newTab_desc : ["Open in a new tab","Open in the same window"],
  newTab_quest : "Should websites be opened in a new tab?",
  updateHosterStatusInterval : 'int',
  updateHosterStatusInterval_range : [1,168,9999],
  updateHosterStatusInterval_quest : "How often should the status of the hosters be updated?",
  updateHosterStatusInterval_prefix : "Every",
  updateHosterStatusInterval_suffix : "hours",
  jDownloaderSupport : 'bool',
  jDownloaderSupport_desc : ["Show JDownloader button if JDownloader is runnning","Never show JDownloader button"],
  jDownloaderSupport_quest : ["Show a JDownloader button in the menu?"],

};
var settings = {};
// Load settings
var savedsettings = JSON.parse(GM_getValue("settings","{}")); // e.g. {  position : [0,1], newTab : 1  }
for(var key in config) {
  if(key in savedsettings) { // Saved
    if(config[key] == 'int') { // Int
      settings[key] = parseInt(savedsettings[key],10);
    } else if(config[key] == 'bool') { // Bool
      settings[key] = (savedsettings[key]=="true"||savedsettings[key]===true);
    } else if(Array.isArray(savedsettings[key])) { // Nested array
      settings[key] = [];
      for(var i = 0; i < savedsettings[key].length; i++) {
        settings[key].push(savedsettings[key][i]);
      }
    } else { // Array
      settings[key] = savedsettings[key];
    }
  } else { // Default
    if(config[key] == 'int') { // Int
      settings[key] = config[key+"_range"][1];
    }else if(config[key] == 'bool') { // Bool
      settings[key] = true;
    } else if(Array.isArray(config[key][0])) { // Nested array defaults to first value for each array
      settings[key] = [];
      for(var i = 0; i < config[key].length; i++) {
        settings[key].push(config[key][i][0]);
      }
    } else {
      settings[key] = config[key][0]; // Array defaults to first value
    }
  }
}

var JDOWNLOADER = "http://127.0.0.1:9666/";
var SHAREBIZ_CNL2_URL = "http://share-links.biz/get/cnl2/";
var SHAREBIZ_RSDF_URL = "http://share-links.biz/get/rsdf/";
var SHAREBIZ_DLC_URL = "http://share-links.biz/get/dlc/";
var DCRYPTIT_UPLOAD_URL = "http://dcrypt.it/decrypt/upload";
var DCRYPTIT_CONTAINERLINK_URL = "http://dcrypt.it/decrypt/container";
var POSATIV_URL = "http://posativ.org/decrypt/rsdf";
var RELINKUS_GETFILE = "http://www.relink.us/frame.php?";
var SPINNERCSS =   "/* http://www.designcouch.com/home/why/2013/05/23/dead-simple-pure-css-loading-spinner/*/\
  .ochspinner {\
    height:16px;\
    width:16px;\
    margin:0px auto;\
    position:relative;\
    -webkit-animation: rotation .6s infinite linear;\
    -moz-animation: rotation .6s infinite linear;\
    -o-animation: rotation .6s infinite linear;\
    animation: rotation .6s infinite linear;\
    border-left:6px solid rgba(0,174,239,.15);\
    border-right:6px solid rgba(0,174,239,.15);\
    border-bottom:6px solid rgba(0,174,239,.15);\
    border-top:6px solid rgba(0,174,239,.8);\
    border-radius:100%;\
  }\
  @-webkit-keyframes rotation {\
    from {-webkit-transform: rotate(0deg);}\
    to {-webkit-transform: rotate(359deg);}\
  }\
  @-moz-keyframes rotation {\
    from {-moz-transform: rotate(0deg);}\
    to {-moz-transform: rotate(359deg);}\
  }\
  @-o-keyframes rotation {\
    from {-o-transform: rotate(0deg);}\
    to {-o-transform: rotate(359deg);}\
  }\
  \
  @keyframes rotation {\
    from {transform: rotate(0deg);}\
    to {transform: rotate(359deg);}\
  }\
";
var LOADINGBARBG = "background: #b4e391;\
background: -moz-linear-gradient(top,  #b4e391 0%, #61c419 50%, #b4e391 100%);\
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));\
background: -webkit-linear-gradient(top,  #b4e391 0%,#61c419 50%,#b4e391 100%);\
background: -o-linear-gradient(top,  #b4e391 0%,#61c419 50%,#b4e391 100%);\
background: linear-gradient(to bottom,  #b4e391 0%,#61c419 50%,#b4e391 100%);"



var show_oneclick_button = false;
var show_oneclick_link = "";
var show_oneclick_FromHighlighScript_allLinks = false;
var show_oneclick_FromHighlighScript_allLinks_loc = false;
var show_oneclick_FromHighlighScript_allLinks_links = "";
var show_oneclick_FromHighlighScript_selectedLinks = false;
var show_oneclick_FromHighlighScript_selectedLinks_loc = false;
var show_oneclick_FromHighlighScript_selectedLinks_links = "";

var links_beforeSelection = false;


var multi = {
  'premiumize.me' : new (function() {
    var self = this;
    this.key = 'premiumize.me';
    this.name = 'premiumize';
    this.homepage =  'https://www.premiumize.me/';
    this.status = JSON.parse(GM_getValue(this.key+"_status","{}"));

    this.updateStatusURL = 'https://www.premiumize.me/services';
    this.updateStatusURLpattern = /https:\/\/www\.premiumize\.me\/services\/?/;
    this.lastUpdate = new Date(GM_getValue(this.key+"_status_time",0));
    this.updateDownloadProgressInterval = 500;

    this.updateStatus = function() { // Update list of online hosters
      if(document.location.href.match(this.updateStatusURL)) {
        // Read and save current status of all hosters
        this.status = {};
        $(".table.table-condensed tr>td:first-child").each(function() {
          var text = $(this).text();
          if(text.match(/^\s*[0-9a-z-]+\.\w{0,3}\s*$/)) {
            var name = text.match(/^\s*([0-9a-z-]+)\.\w{0,3}\s*$/)[1];
            self.status[name] = true;
          }
        });
        GM_setValue(this.key+"_status",JSON.stringify(this.status));
        GM_setValue(this.key+"_status_time",""+(new Date()));
      } else {
        alert(s_myname+"\n\nError: wrong update URL");
      }
    };
    this.isOnline = function(hostername) {
      return hostername in this.status && this.status[hostername];
    };

    this.getOpenWebsiteURL = function(urls) {
      // Return a link to the premiumize.me website that will insert the links
      var url = this.homepage+"downloader?link:"+encodeURIComponent(urls.join("\n"));
      return url;
    };

    this.checkLink = function(url,cb) { // check whether the link is supported and online
      var host = url.match(/https?:\/\/(.+?)\//)[1];
      var hoster = host.split(".");
      hoster.pop();
      hoster = hoster.pop().replace("-","");
      cb(this.isOnline(hoster));
    };

    this.getResults = function(urls,cb) {
      // cb($node,linkNumber) -- $node contains the result, linkNumber is the number of links that should be online i.e. number of hashes
      alert("This function does not work for "+this.name);
    };
    
    
    
    this._notLoggedIn = false;
    
    this.getLinks = function(urls,cb) {
      showConfirm("fairPointsWarning","You will be charged premiumize fair points for generating "+(urls.length>1?("<b>"+urls.length+"</b> files"):("<b>one</b> file"))+"!<br><br>Generate links?",function() { this._getLinks(urls, cb); },function() { setStatus("Operation canceled!",0); cb([],-1); },self);
    };
    
    this._getLinks = function(urls,cb) {

      var N = urls.length;
      var downloadLinks = [];
      var errors = [];
      for(var i = 0; i < urls.length; i++) {
        this._getSingleLink(urls[i], function(downloadlink, originallink) {
          if(downloadlink) {
            downloadLinks.push(downloadlink);
          } else {
            errors.push(originallink);
          }
        });
      }
      
      var checkprogress = function() {
        if(self._notLoggedIn) {
                          
          // Stop checking and open premiumize homepage
          setStatus(self.name+" error: Not logged in!",0);
          GM_openInTab(self.homepage);
          cb([], -1);
          return;
        }

        if(N == downloadLinks.length+errors.length) { // All finished
          cb(downloadLinks);
          if(errors.length > 0) { // Errors occured
            alert("Errors occured\n"+errors.length+" links failed:\n\n"+errors.join("\n"));
          }
        } else { // not finished yet
          window.setTimeout(checkprogress, self.updateDownloadProgressInterval);
        }
      };
      window.setTimeout(checkprogress, 2*N*self.updateDownloadProgressInterval);
    };
    
    
    this._getSingleLink = function(url, cb) {
      GM_xmlhttpRequest({
        method: "POST",
        url: self.homepage+"api/transfer/create",
        data: "src="+encodeURIComponent(url)+"&seed=2or48h",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control" : "no-cache",
          "Referer" : "https://www.premiumize.me/downloader"
        },
        onload: function(response) {
          var result = JSON.parse(response.responseText);
          if(result["status"] != "success") {
            if("message" in result && !self._notLoggedIn) {
              setStatus(result["message"],-1);
              if(~result["message"].indexOf("log")) {
                self._notLoggedIn = true;
              }
            }
            cb(false, url);
          } else {
            cb(result.location, url);
          }
        }
      });
    
    };
    
    
  })(),
  
  
  'nopremium.pl' : new (function() {
    var self = this;
    this.config = {
      'mode' : ['transfer','premium','none'],
      'mode_desc' : ['Transfer User (Pakiety Transferowe)','Premium User (Konta Premium)','No account'],
      'mode_quest' : 'What kind of account do you have at nopremium.pl',
      'downloadmode' : ['direct','server'],
      'downloadmode_desc' : ['Direct download (TRYB SZYBKIEGO POBIERANIA)','Downloading via NoPremium.pl server (TRYB POBIERANIA NA SERWERY)'], 
      'downloadmode_quest' : ['Which download mode do you want to use?']
    };
    this.key = 'nopremium.pl';
    this.name = 'NoPremium.pl';
    this.homepage =  'https://www.nopremium.pl/';
    this.status = JSON.parse(GM_getValue(this.key+"_status","{}"));
    var mapHosterName = function(name) {return name.replace("-","")};

    this.updateStatusURL = 'https://www.nopremium.pl/files';
    this.updateStatusURLpattern =/https?:\/\/www\.nopremium\.pl\/files\/?/;
    this.lastUpdate = new Date(GM_getValue(this.key+"_status_time",0));
    this.updateDownloadProgressInterval = 5000;

    this.settings = {};
    this.loadSettings = function() {
      // Load settings, use first value as default
      var savedsettings = JSON.parse(GM_getValue(this.key+"_settings","{}"));

      for(var key in this.config) {
         if(key.endsWith("desc") || key.endsWith("range") || key.endsWith("quest") || key.endsWith("prefix") || key.endsWith("suffix")) {
           continue;
         }
        if(key in savedsettings) { // Saved
          if(this.config[key] == 'int') { // Int
            this.settings[key] = parseInt(savedsettings[key],10);
          }else if(config[key] == 'bool') { // Bool
            this.settings[key] = savedsettings[key]=="true"||savedsettings[key]===true;
          } else if(Array.isArray(savedsettings[key])) { // Nested array
            this.settings[key] = [];
            for(var i = 0; i < savedsettings[key].length; i++) {
              this.settings[key].push(savedsettings[key][i]);
            }
          } else { // Array
            this.settings[key] = savedsettings[key];
          }
        } else { // Default
          if(this.config[key] == 'int') { // Int
            this.settings[key] = this.config[key+"_range"][1];
        } else if(config[key] == 'bool') { // Bool
            this.settings[key] = true;
          } else if(Array.isArray(this.config[key][0])) { // Nested array defaults to first value for each array
            this.settings[key] = [];
            for(var i = 0; i < this.config[key].length; i++) {
              this.settings[key].push(this.config[key][i][0]);
            }
          } else {
            this.settings[key] = this.config[key][0]; // Array defaults to first value
          }
        }
      }
    };

    this.loadSettings(); // Load settings

    this.updateStatus = function() { // Update list of online hosters
      if(document.location.href.match(this.updateStatusURL)) {
        // Read and save current status of all hosters
        this.status = {};
        $("#servers a[title]").each(function() {
          var name = mapHosterName(this.title);
          self.status[name] = true;
        });
        GM_setValue(this.key+"_status",JSON.stringify(this.status));
        GM_setValue(this.key+"_status_time",""+(new Date()));
      } else {
        alert(s_myname+"\n\nError: wrong update URL");
      }
    };
    this.isOnline = function(hostername) {
      return hostername in this.status && this.status[hostername];
    };

    this.getOpenWebsiteURL = function(urls) {
      // Return a link to the nopremium.pl website that will insert the links
      var url = this.homepage+"files?link:"+encodeURIComponent(urls.join("\n"));
      return url;
    };

    var getHashs = function(urls,cb,silent) {
      // cb(hashes,sizestring)
      setStatus("Sending "+(urls.length===1?"one link":(urls.length+" links")),-1);
      GM_xmlhttpRequest({
        method: "POST",
        url: self.homepage+"files",
        data: "watchonline=&session="+(Math.round(Math.random()*1234567))+"&links="+encodeURIComponent(urls.join("\n")),
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control" : "no-cache",
          "Referer" : "https://www.nopremium.pl/files"
        },
        onload: function(response) {
          if(response.responseText.indexOf('<input type="text" name="login" placeholder="Login"/>') != -1) {
            setStatus(self.name+" error: Not logged in!",0);
            GM_openInTab(self.homepage);
            return cb([],-1);
          }
          
          var hashes = [];
          // Find hashes
          var re = /name\=\"hash(\d+)\" value\=\"(\w+)\"/g; //<input type="checkbox" id="hash0" name="hash0" value="fab3c41988" onclick="UpdateCounter();" c
          var ma;
          while(ma = re.exec(response.responseText)) {
            hashes.push(ma[2]);
          }
          // Find errors
          if((ma = response.responseText.match(/Pliki nieprzetworzone \((\d+)\)/)) && !silent) {
            addStatus("Error: "+(parseInt(ma[1],10)===1?("One file is offline or unsupported"):(ma[1]+" files are offline or unsupported")),0);
          }


          // Find size
          var size = "0 Byte";
          if(response.responseText.indexOf('id="countSize"') !== -1) {
            ma = response.responseText.split('id="countSize"')[1].match(/value="(\d+.?\d*) (\w+)"/); // <input type="text" name="countSize" id="countSize" style="width:80px;" readonly="readonly" value="1.38 GB">
            size = ma[1]+" "+ma[2];
          }

          setStatus(self.name+" identified "+(hashes.length===1?"one online file":(hashes.length+" online files")),-1);

          cb(hashes,size);
        }
      });
    };


    this.checkLink = function(url,cb) { // check whether the link is supported and online
      // cb(boolresult)
      return getHashs([url],function(hashes,size) {
          cb(hashes.length === 1);
      },true);
    };

    this.getResults = function(urls,cb,hashes) {
      // cb($node,linkNumber) -- $node contains the result, linkNumber is the number of links that should be online i.e. number of hashes
      // Get download links from nopremium.pl and show the usual info about the file, that is normally shown on nopremium.pl

      if(typeof hashes == "undefined") {
        // 1. Get hashes and show transfer warning
        getHashs(urls,function(hashes,size) {
          if(settings.mode == 'transfer') {
            showConfirm("transferWarning","You will be charged <b>"+size+"</b> 'Transfer' for generating "+(hashes.length>1?("<b>"+hashes.length+"</b> files"):("<b>one</b> file"))+"!<br><br>Generate links?",function() { this.getResults(urls,cb,hashes); },null,self);
          } else if(hashes.length > 0) {
            self.getResults(urls,cb,hashes);
          } else if(size === -1) { // Error was already handled (probably not logged in)
            cb(false,0);
          } else { // No files found
            setStatus("No online/available files",0);
            cb(false,0);
          }
        });
        return;
      }

      // 2. Work with hashes
      var $resultContainer = $("<div></div>").attr('id','generated-links');
      var mode = self.settings.downloadmode == 'direct'?0:1; // 0 -> direct , 1  ->  via server
      GM_xmlhttpRequest({
        method: "POST",
        url: self.homepage+"files",
        data: "insert=1&mode="+mode+"&hh=0&hash[]="+hashes.join("&hash[]=")+"&",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control" : "no-cache",
          "Referer" : "https://www.nopremium.pl/files"
        },
        onload: function(response) {
          GM_xmlhttpRequest({
            method: "POST",
            url: self.homepage+"files",
            data: "loadfiles=1",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
              "Cache-Control" : "no-cache",
              "Referer" : "https://www.nopremium.pl/files"
            },
            onload: function(response) {
              if(mode === 0) {
                $resultContainer.append($("<div></div>").append(response.responseText).find("#fastFilesArea"));
              } else {
                $resultContainer.append($("<div></div>").append(response.responseText).find("#downloadFilesArea"));
              }
              $resultContainer.find("input[type=checkbox]").remove();
              cb($resultContainer,hashes.length);
            }
          });


        }
      });

    };
    this.getLinks = function(urls,cb) {
      // cb(downloadlinks)
      
      if(this.settings.downloadmode == "direct") {
        return this._getDirectLinks(urls,cb);
      } else {
        return this._getServerLinks(urls,cb);
      }

    };
    
    this._getDirectLinks = function(urls,cb) {
      // Get Direct download links
    
      this.getResults(urls,function($node,N) {

        if(!$node || N < 1) {
          cb(false);
          return;
        }


        var text = $node.html();

        /*
        <td>16-08-2014 20:22</td>
        <td class="dlBox"><a href="http://direct.nopremium.pl/9091456/7895ca02bfcb2c2e43806f1079b7ff069129e/result.file"><img src="https://www.nopremium.pl/images/download_ico.png" alt="Sciagnij" title="Sciagnij"></a></td>
        */
        var files = [];
        var re = /\<td\>(\d+)\-(\d+)\-(\d+) (\d+)\:(\d+)\<\/td\>(\s|\n)+\<td class\=\"dlBox\"\>\<a href\=\"(.*?)\"/gm;
        var m; // wholeString, 16,08,2014,20,37,#newline#,http://direct.nopremium.pl/9091456/7895ca02bfcb2c2e43806f1079b7ff069129e/result.file
          while (m = re.exec(text)) {
            if(m[7].indexOf("//direct.nopremium.pl") === -1) {
              continue; // Skip files via server, only use direct download links
            }
            var d = new Date(m[3], m[2], m[1], m[4], m[5], 0, 0);
            files.push([d,m[7]]);
         }

        if(files.length === 0) {
          alert(s_myname+"\n\nAn error occured.\nCould not find download links in response.");
          cb(false);
          return;
        }
        // Find youngest files by comparing their ids
        var pattern = /\.pl\/(\d+)\//;
        files.sort(function(a, b) {
          var x = a[1].match(pattern)[1];
          var y = a[1].match(pattern)[1];
          return x>y ? -1 : x<y ? 1 : 0;
        });
        

        var result = [];
        for(var i = 0; i < N; i++) {
          result.push(files[i][1]);
          cacheLink([urls[i]],files[i][0],[files[i][1]],self.key); // CACHE single URLs
        }

        cacheLink(urls,new Date(),result,self.key); // CACHE all URLs

        cb(result);

      });
    
    
    
    };
    
    this._getServerLinks = function(urls,cb) {
    
    
      this.getResults(urls,function($node,N) {
        if(N == 0) {
          cb(false);
        } else {
          self._getProgress(cb,$node,N);
        }
      });
    
    };
    
    this._getProgress = function(cb,$node,N,ids) {
      GM_xmlhttpRequest({
        method: "POST",
        url: self.homepage+"files",
        data: "downloadprogress=1",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control" : "no-cache",
          "Referer" : "https://www.nopremium.pl/files"
        },
        onerror: function() {
          self._getProgressBlocked = false;
        },
        onload: function(response) {
          self._getProgressBlocked = false;
          
          var data = JSON.parse(response.responseText);
          
           data.StandardFiles.sort(function(a, b) {
            var x = new Date(a.insert_date.split("-").join("/"));
            var y = new Date(b.insert_date.split("-").join("/"));
            return x>y ? -1 : x<y ? 1 : 0;
          });
          
          var result = [];
          var runnning = [];
          var percent = 0;
          var progess = [];

          if(!ids) {          // First run: Find the correct files: just use the first N files
            ids = [];
            for(var i = 0; i < data.StandardFiles.length &&  i < N; i++) {
              ids.push(data.StandardFiles[i].id)
              if(data.StandardFiles[i].status == "finish") {
                result.push(data.StandardFiles[i].download_url);
                progess.push(100);
                percent += 100;
              } else {
                runnning.push(data.StandardFiles[i]);
                if(parseInt(data.StandardFiles[i].status,10) > 0) {
                  progess.push(parseInt(data.StandardFiles[i].status,10));
                  percent += parseInt(data.StandardFiles[i].status,10);
                }
              }
            }
          } else {          // Consecutive runs: Use the ids from first run
            for(var i = 0; i < data.StandardFiles.length; i++) {
              if(ids.indexOf(data.StandardFiles[i].id) == -1) continue; 
              if(data.StandardFiles[i].status == "finish") {
                result.push(data.StandardFiles[i].download_url);
                progess.push(100);
                percent += 100;
              } else {
                runnning.push(data.StandardFiles[i]);
                if(parseInt(data.StandardFiles[i].status,10) > 0) {
                  progess.push(parseInt(data.StandardFiles[i].status,10));
                  percent += parseInt(data.StandardFiles[i].status,10);
                }
              }
            }
          }         
          
          
          /*
          Regarding caching in server mode:
            If you add a file, that is already on the server (or currently downloading), you will not be charged additional bandwith - therefore caching is not necessary at the moment.
          */
          
          if(result.length === N) {
            setStatus((result.length===1?"One file":(result.length+" files"))+" downloaded to server",1);
            cb(result);
          } else {
            // Waiting
            percent = percent/N;
            //setStatus('Download '+result.length+'/'+N+' ('+Math.floor(percent)+'%)\n<span title="'+round(percent,2)+'%" style="display:block; width:120px; height:18px; background:white; border:1px solid black; border-radius:5px;"><span style="display:block; border-radius:5px; height:18px; width:'+Math.ceil(percent*1.2)+'px; '+LOADINGBARBG+'"> </span></span>',-1);
            var dotheight = N > 2?2:4;
            var h = 'Download '+result.length+'/'+N+' ('+Math.floor(percent)+'%)\n<div style="display:block; width:130px; height:auto; background:white; border:1px solid black; border-radius:5px; padding:2px; ">';
            for(var i = 0;  i < N; i++) {
              if(progess[i]) {
                h += '<span style="display:block; width:'+Math.ceil(progess[i]*1.2)+'px; height:1px; background:white; border-top:'+dotheight+'px dotted green; margin-bottom:1px;"></span>';
              } else {
                h += '<span style="display:block; width:0x; height:1px; background:white; border-top:'+dotheight+'px dotted silver; margin-bottom:1px;"></span>';
              }
            
            }
            h += '</div>';
            
            setStatus(h);
            showOnlyStatus();
            
            window.setTimeout(function() {
              self._getProgress(cb,$node,N,ids);
            },self.updateDownloadProgressInterval);
          }
          
        }
      }); 
        
    };
    
    
    
  })(),


};



var debridprovider = Object.keys(multi);
var currentdebrid = GM_getValue("currentdebrid",debridprovider[0]);

for(var key in multi) {
  if(multi[key] == currentdebrid) continue;
  GM_registerMenuCommand(s_myname+" - Switch to "+multi[key].name, (function(key) { return function() {
    if(!confirm(s_myname+"\n\nSet multi-download provider:\n"+multi[key].name)) return;

    GM_setValue("currentdebrid",key);
    currentdebrid = key;
    document.location.reload();
  }})(key)
  );
}
GM_registerMenuCommand(s_myname+" - Delete cached links", function() {
  if(!confirm(s_myname+"\n\nReally delete cached links?")) return;

  GM_setValue("cachedDownloadLinks","{}")

  alert(s_myname+"\n\nCache is empty!");
});
GM_registerMenuCommand(s_myname+" - Restore dialogs and warnings", function() {
  if(!confirm(s_myname+"\n\nReally restore all dialogs and warnings?")) return;

  GM_setValue("dialogs","[]");

  alert(s_myname+"\n\nDialogs and warnings restored");
});



function round(f,p) {
  // Round f to p places after the comma
  return parseFloat(parseFloat(f).toFixed(p));
}

function popUp(id,cb_close,thisArg,doNotCloseOnOutsideClick) {
  // Remove window scrolling
  $(document.body).css("overflow","hidden");
  var zi = getNextZIndex();
  var id = id?id:("popup"+(new Date).getTime());
  var $par = $('<div style="position:absolute; top:0px;"></div>').attr("id",id).appendTo(document.body);
  var $background = $('<div style="position:fixed; top:0px; left:0px; right:0px; bottom:0px; background:black; opacity:0.5; z-index:'+(zi++)+'"></div>').appendTo($par);
  var $div = $('<div style="position:fixed; top:50px; left:100px; overflow:auto; z-index:'+(zi++)+'; background:#E6E6E6; color:Black; border:#B555C5 2px solid;border-radius:5px; padding:10px; font-family: "Ubuntu",Arial,Sans-Serif"></div>').css('maxHeight',window.innerHeight-100).css('maxWidth',window.innerWidth-200).appendTo($par);

  var close = function() {
    $par.remove();
    if(cb_close) cb_close.call(thisArg);
    // Restore scrolling
    $(document.body).css("overflow","initial");

  };

  if(!doNotCloseOnOutsideClick) {
    $background.click(close);
  }


 return {"node": $div, "close": close};
}




function configForm($form,c,s,formid) {
  for(var key in c) {

    if(key.endsWith("desc") || key.endsWith("range") || key.endsWith("quest") || key.endsWith("prefix") || key.endsWith("suffix")) {
      continue;
    }

    var $p = $("<p>").appendTo($form);

    if(c[key+"_quest"]) {
      $p.append(c[key+"_quest"]);
    } else {
      $p.append(key);
    }

    $p.append("<br>");

    if(c[key+"_prefix"]) {
      $p.append(c[key+"_prefix"]+" ");
    }
    if(c[key] == 'int') { // Int
      var $input = $('<input type="number">').addClass("form_"+formid).data("key",key).data("parse","int").val(s[key]).appendTo($p);
      if(c[key+"_range"]) {
        $input.prop("min",c[key+"_range"][0]);
        $input.prop("max",c[key+"_range"][2]);
        $input.prop("title",c[key+"_range"][0]+" - "+c[key+"_range"][2]);
      }
    } else if(c[key] == 'bool') { // Bool

      var $select = $('<select></select>').addClass("form_"+formid).data("key",key).data("parse","bool").appendTo($p);

      var $optionYes = $('<option></option>').val("true").appendTo($select);
      if(c[key+"_desc"]) {
        $optionYes.html(c[key+"_desc"][0]);
      } else {
        $optionYes.html("Yes");
      }
      if(s[key]) {
        $optionYes[0].selected = true;
      }

      var $optionNo = $('<option></option>').val("false").appendTo($select);
      if(c[key+"_desc"]) {
        $optionNo.html(c[key+"_desc"][1]);
      } else {
        $optionNo.html("No");
      }
      if(!s[key]) {
        $optionNo[0].selected = true;
      }
    } else if(Array.isArray(c[key][0])) { // Nested array
      for(var j = 0; j < c[key].length; j++) {
        if(c[key+"_desc"] && !Array.isArray(c[key+"_desc"][j])) {
          $p.append(c[key+"_desc"][j]+": ");
        }

        var $select = $('<select></select>').addClass("form_"+formid).data("key",key).data("index",j).appendTo($p);
        for(var i = 0; i < c[key][j].length; i++) {
          var $option = $('<option></option>').val(c[key][j][i]).appendTo($select);
          if(c[key+"_desc"] && Array.isArray(c[key+"_desc"][0])) {
            $option.html(c[key+"_desc"][j][i]);
          } else {
            $option.html(c[key][j][i]);
          }
          if(s[key][j] == c[key][j][i])
            $option[0].selected = true;

        }
        $p.append("<br>");
      }

    } else { // Array

      var $select = $('<select></select>').addClass("form_"+formid).data("key",key).appendTo($p);
      for(var i = 0; i < c[key].length; i++) {
        var $option = $('<option></option>').val(c[key][i]).appendTo($select);
        if(c[key+"_desc"]) {
          $option.html(c[key+"_desc"][i]);
        } else {
          $option.html(c[key][i]);
        }
        if(s[key] == c[key][i])
          $option[0].selected = true;
      }

    }

    if(c[key+"_suffix"]) {
      $p.append(" "+c[key+"_suffix"]);
    }

  }

}

function saveSettings(ev) {
  var $body = ev.data;
  var $form = $body.find(".form");

  // Save preferred hoster:
  currentdebrid = $form.find('.debridhoster').val();

  // Save options:
  var newsettings = { 'general' : {} };
  for(var key in multi) {
    newsettings[key] = {};
  }

  $form.find('*[class^=form_]').each(function() {
    var $this = $(this);
    var namespace = $this.prop("class").split("_",2)[1];
    var key = $this.data("key");
    var index = $this.data("index");
    var value = $this.val();
    var parse = $this.data("parse");
    if(typeof index != 'undefined') { // Nested Array
      if(!Array.isArray(newsettings[namespace][key])) {
        newsettings[namespace][key] = [];
      }
      newsettings[namespace][key][index] = value;
    } else { // Normal

      if(parse == 'int') {
        value = parseInt(value,10);
      } else if(parse == 'bool') {
        value = (value == "true");
      }
      newsettings[namespace][key] = value;
    }
  });


  GM_setValue("setup",true);
  GM_setValue("currentdebrid",currentdebrid);
  GM_setValue("settings",JSON.stringify(newsettings.general));
  for(var key in multi) {
    GM_setValue(key+"_settings",JSON.stringify(newsettings[key]));
  }

  alert(s_myname+"\n\nSettings were successfully saved!");
  document.location.reload();
}


function aboutMe() {
  var popup = popUp("multiochhelper_about",null,null,true);
  var $popup = popup.node;
  var $frame = $('<iframe width="'+(window.innerWidth-250)+'" height="'+(window.innerHeight-150)+'" style="border:0">').appendTo($popup);
  $frame.bind('load', function(e) {

      var $body = $($frame[0].contentDocument.getElementsByTagName('body')[0]);

      $body.css("fontFamily","Ubuntu,Arial,Sans-Serif");

      $('<div style="position:fixed; top:0px; right:5px; cursor:pointer; color:White; background:#b555c5; border: 1px solid White; border-radius:3px; padding:0px; font-weight:bold ; " title="Close menu">X</span>').click(function() { if(confirm("Settings will NOT be saved!")) popup.close(); }).appendTo($body);

      $body.append("<h2>"+s_myname+"</h2>");
      $("<a>").appendTo($body).attr('target','_blank').css("fontSize","small").html("https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper").attr('href',"https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper");

      var $form = $("<div class=\"form\">").appendTo($body);

      // General options
      $form.append("<h3>Settings</h3>");
      configForm($form,config,settings,"general");

      // Preferred multihoster
      var $p = $("<p>").appendTo($form);
      $p.append("Preferred multihoster:<br>");
      var $select = $('<select></select>').addClass("debridhoster").appendTo($p);
      for(var key in multi) {
        var $option = $('<option></option>').val(key).appendTo($select);
        $option.html(multi[key].name);
        $option[0].selected = key == currentdebrid;
      }

      // Options for multihosters
      for(var key in multi) {
        $("<h3>").appendTo($form).html(multi[key].name);
        $("<a>").appendTo($form).css("fontSize","small").attr('target','_blank').html(multi[key].homepage).attr('href',multi[key].homepage);
        if(multi[key].config) {
          configForm($form,multi[key].config,multi[key].settings,key);
        } else {
          $("<p>").appendTo($form).text("No settings available for this service.");
        }
      }

      $form.append("<br>");

      $('<input type="button">').val("Cancel").click(function() { if(confirm("Settings will NOT be saved!")) popup.close(); }).appendTo($form);
      $('<input type="button">').val("Save").click($body,saveSettings).appendTo($form);



      $form.append("<h3>Other options</h3>");

      $('<input type="button">').val("Clear cache ("+ humanBytes(GM_getValue("cachedDownloadLinks","{}").length-2)+")").appendTo($form).click(function() {
        if(!confirm(s_myname+"\n\nReally delete cached links?")) return;

        GM_setValue("cachedDownloadLinks","{}");

        this.value = "Clear cache ("+ humanBytes(GM_getValue("cachedDownloadLinks","{}").length-2)+")";
        alert(s_myname+"\n\nCache is empty!");
      });

      $form.append("<br>");
      $form.append("<br>");

      $('<input type="button">').val("Restore dialogs and warnings").appendTo($form).click(function() {
        if(!confirm(s_myname+"\n\nReally restore all dialogs and warnings?")) return;

        GM_setValue("dialogs","[]");

        alert(s_myname+"\n\nDialogs and warnings restored");
      });


      $('<div>\
      <br>\
      <br>\
      <h3>Known issues:</h3>\
      <ul>\
      <li>nopremium.pl sometimes omits a few links in folders</li>\
      <li>In Firefox the script sometimes does not work if the "Accept thid-parts cookies" policy is set to "Never".<br>\
      To resolve this problem open the Firefox options and go to the tab "Privacy". Set the "Accept thid-parts cookies" to "From visited" or "Always"<br>\
      Close and re-open Firefox. Log out and then log in your nopremium.pl account. Everything should work fine now.</li>\
      </ul>\
      <br>\
      <h3>dcrypt.it</h3>\
      This script uses an unrelated, external service to decrypt *.dlc files:<br>\
      <a href="http://dcrypt.it/">http://dcrypt.it/</a>.\
      </div><br><br><br>').appendTo($body);

      $('<input type="button">').val("Debug info").appendTo($body).click(inspectGMvalues);

  });
  $frame.attr("src","about:blank");
}


function inspectGMvalues() {
  var iv;
  var popup = popUp("multiochhelper_inspectGM",function() {
    clearInterval(iv);
  });
  var $popup = popup.node;
  var $frame = $('<iframe width="'+(window.innerWidth-250)+'" height="'+(window.innerHeight-150)+'" style="border:0">').appendTo($popup);
  $frame.bind('load', function(e) {
      $($frame[0].contentDocument.getElementsByTagName('head')[0]).append('<style type="text/css">'+SPINNERCSS+'</style>');

      var $body = $($frame[0].contentDocument.getElementsByTagName('body')[0]);
      $body.append("<h2>"+s_myname+"</h2>");

      var keys = GM_listValues();
      if(keys.length && typeof keys[0] == "undefined") { // Firefox 35+ workaround
        keys = cloneInto(GM_listValues(), window);
      }

      var $table = $('<table>').appendTo($body);
      var $tr = $('<tr>').appendTo($table);
      $('<th>').html("Key").appendTo($tr);
      $('<th>').html("Value").appendTo($tr);
      $('<th>').html("Type").appendTo($tr);
      $('<th>').html("").appendTo($tr);


      var deleteValue = function(ev) {
        var key = $(this).data("key");
        GM_deleteValue(key);
        $(this).parent().parent().remove();
      };

      var total = 0;
      for(var i = 0; i < keys.length; i++) {
        var value = GM_getValue(keys[i]);
        var svalue = ""+value;
        var len = 1;
        if(typeof value == "undefined") {
          svalue = "undefined";
        } else if(typeof value == 'string') {
          len = value.length;
        }
        total += len;
        var $tr = $('<tr>').appendTo($table);
        $('<td>').html(keys[i]).appendTo($tr);
        $('<td>').append($('<input type="text" style="width:600px">').val(svalue)).appendTo($tr);
        $('<td>').append(""+(typeof value)+(typeof value == "string"?("("+len+")"):"")).appendTo($tr);
        $('<td>').append($('<input type="button">').val("Delete").data("key",keys[i]).click(deleteValue)).appendTo($tr);
      }

      var $tr = $('<tr>').appendTo($table);
      $('<th>').html("Total").appendTo($tr);
      $('<th>').html(keys.length).appendTo($tr);
      $('<th>').html("approx. "+humanBytes(total)).appendTo($tr);

      var $reload = $('<div>').appendTo($body);
      var $loader = $('<div style="display:inline-block;width:20px; height:20px;" class="ochspinner"></div>').appendTo($reload);
      $reload.append(" Reload in ");
      var $timer = $('<span style="pointer:cursor;" title="Click to reload now"></span>').html("20 seconds").click(function() { this.innerHTML = 0; }).appendTo($reload);
      iv = window.setInterval(function() {
        var s = parseInt($timer.html(),10);
        if(s === 0) {
          clearInterval(iv);
          popup.close();
          inspectGMvalues();
        } else {
          s--;
          $timer.html(s+" seconds");
        }
      },1000);

  });
}




function hexToBytes(s) {
  return s.match(/([0-9a-fA-F]{2})/g).map(function(v) { 
    return parseInt(v,16); 
  });
}

function stringToBytes(s) {
  return s.split("").map(function(v) {
    return v.charCodeAt(0);
  });
}

function bytesToString(a) {
  return String.fromCharCode.apply(String,a)
}

function addCSSHead(body) {
  var style = document.createElement('style');
  style.type = 'text/css';
  style.innerHTML = body;
  document.head.appendChild(style);
}

function humanBytes(bytes, precision) {
  // http://stackoverflow.com/a/18650828
 bytes = parseInt(bytes,10);
 if(bytes === 0) return '0 Byte';
 var k = 1024;
 var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
 var i = Math.floor(Math.log(bytes) / Math.log(k));
 return parseFloat((bytes / Math.pow(k, i)).toPrecision(2)) + ' ' + sizes[i];
}


function GM_xmlhttpRequestBinary(obj) {
  var sep = "-----987564176415";
  var res = "";
  var bytestring = function(s) {
    for(var i = 0; i < s.length; i++) {
      var v = s.charCodeAt(i);
      if(v > 255) {
        GM_log("This is strange: "+s[i]+" => "+v);
      } else {
        res += s[i];
      }
    }
    return res;
  }

  var lines = [];
  for (var name in obj.data) {
    if (obj.data.hasOwnProperty(name)) {
      lines.push('--' + sep);
      var body = 'Content-Disposition: form-data; name="' + name + '"';
      if (typeof(obj.data[name]) == 'object') {
        var value = bytestring(obj.data[name].value);
        if (obj.data[name].filename)
          body += '; filename="' + obj.data[name].filename + '"';
        lines.push(body);
        lines.push('Content-type: application/force-download');
      } else {
        var value = obj.data[name];
        lines.push(body);
      }
      lines.push('');
      lines.push(value);
    }
  }
  lines.push('--' + sep + '--');

  var newdata = lines.join('\r\n');

  obj['binary'] = true;
  obj['headers'] = {
      "Content-Type": 'multipart/form-data; boundary=' + sep,
      "Content-Length": newdata.length
    };
  obj['data'] = newdata;
  return GM_xmlhttpRequest(obj);
}

function getNextZIndex() {
  // Calculate: max(zIndex) + 1
  var zIndexMax = 0;
  try {
    $('div').each(function () {
      var z = parseInt($(this).css('z-index'),10);
      if (z > zIndexMax) {
        zIndexMax = z;
      }
    });
  } catch(e) {} finally {
    if(zIndexMax < 2000) {
      zIndexMax = 2000;
    }
    return zIndexMax + 1;
  };
}

function showConfirm(id,text,cb_yes,cb_no,thisArg) {
  // Skip
  var dialogs = JSON.parse(GM_getValue("dialogs","[]"));
  if(dialogs.indexOf(id) !== -1) {
    cb_yes.call(thisArg);
    return;
  }

  var popup = popUp("confirm"+id,function(){},thisArg);
  var $div = popup.node;
  $div.append(text);
  $div.append("<br>");
  var $yes = $('<input type="button" value="Yes">').click(function() {
    popup.close();
    cb_yes.call(thisArg);
  }).appendTo($div);

  var $no = $('<input type="button" value="No">').click(function() {
    popup.close();
    if(cb_no) {
      cb_no.call(thisArg);
    }
  }).appendTo($div);

  $div.append("<br>");

  var $remember = $('<input type="checkbox" value="remember">').click(function() {
    if(this.checked) {
      var dialogs = JSON.parse(GM_getValue("dialogs","[]"));
      if(dialogs.indexOf(id) === -1) {
        dialogs.push(id);
        GM_setValue("dialogs",JSON.stringify(dialogs));
      }
    } else {
      var dialogs = JSON.parse(GM_getValue("dialogs","[]"));
      if(dialogs.indexOf(id) !== -1) {
        dialogs.splice(dialogs.indexOf(id), 1);
        GM_setValue("dialogs",JSON.stringify(dialogs));
      }
    }
  }).appendTo($div);
  $div.append(' Always "Yes". Do not show this message again!');
}


function setStatus(text,success) {
  var $statustext = $('#multiochhelper_status_text');
  if(!$statustext) {
    alert(s_myname+"\n\n"+text);
    return;
  }
  $statustext.html("");
  addStatus(text,success);
}

function addStatus(text,success) {
  var $statustext = $('#multiochhelper_status_text');
  if(!$statustext.length) {
    alert(s_myname+"\n\n"+text);
    return;
  }
  $statustext.parent().show();
  if($statustext.html() != "") {
    $statustext.append("<br>");
  }
  $statustext.append(text);
  if(success === 1) {
     $statustext.css("color","#33FF99");
  } else if(success === 0) {
     $statustext.css("color","orange");
  } else if(success === -1) {
     $statustext.css("color","cyan");
  } else {
     $statustext.css("color","white");
  }
}

function showOnlyStatus() {
  var $status = $('#multiochhelper_status');
  $status.siblings().not("#multiochhelper_status").remove();
}

function getMultiOCHWebsiteURL(links) {
  return multi[currentdebrid].getOpenWebsiteURL(links);
}

function openWebsite(links,cb) {
  // Call cb() and navigate to the website
  if(!links) {
    cb(false);
    return;
  }

  if(cb) {
    cb();
  }
  var url = getMultiOCHWebsiteURL(links);

  if(settings.newTab) {
    if(typeof GM_openInTab == "undefined") {
      window.open(url);
    } else {
      GM_openInTab(url);
    }
  } else {
    document.location.href = url;
  }
}

function useCache(urls,cb) {
  urls = ""+urls;
  var cachedDownloadLinks = JSON.parse(GM_getValue("cachedDownloadLinks","{}")); // [datestring,downloadlink,multihoster]
  if(urls in cachedDownloadLinks) {
    if(confirm(s_myname+"\n\nLink was found in cache.\nUse cached link?\n\nFrom: "+(new Date(cachedDownloadLinks[urls][0]))+"\nWith: "+cachedDownloadLinks[urls][2]+"\n"+cachedDownloadLinks[urls][1].join("\n"))) {
      cb(cachedDownloadLinks[urls][1]);
      return true;
    }
  }
  return false;
}
function cacheLink(urls,datetime,downloadLinks,multihoster) {
  if(!Array.isArray(downloadLinks)) {
    var parts = downloadLinks.split("\n");
    downloadLinks = [];
    for(var i = 0; i < parts.length; i++) {
      if($.trim(parts[i])) {
        downloadLinks.push($.trim(parts[i]));
      }
    }
  }
  if(downloadLinks.length === 0) return;

  urls = ""+urls;
  var cachedDownloadLinks = JSON.parse(GM_getValue("cachedDownloadLinks","{}"));
  cachedDownloadLinks[urls] = [datetime,downloadLinks,multihoster];
  GM_setValue("cachedDownloadLinks",JSON.stringify(cachedDownloadLinks));
}

function generateLinks(urls,cb) {
  // Check cache
  if(useCache(urls,cb)) {
    return;
  }

  multi[currentdebrid].getLinks(urls,cb);
}


function download(urls,cb) {
  // Get one/first download link and open it immediately/start download
  if(urls.length > 1) {
    alert(s_myname+"\n\nOnly the first link will be opened!");
  }

  generateLinks(urls,function(result, code) {
    if(cb) cb();
    if(result && result[0]) {
      addStatus("Opening download...",-1);
      var oldlocation = document.location.href;
      document.location.href = result[0];
      if(oldlocation == document.location.href) { // Changing location was blocked by sandboxed iframe
        //GM_openInTab(result);
        top.location.href = result[0];
      }
    } else if(!code) {
      addStatus("An error occured: No downloadlink to open",0);
    }
  });
}

function clipboard(urls,cb) {

  // Get download links and copy them into clipboard

  generateLinks(urls,function(result) {
    if(result) {
      try {
        GM_setClipboard(result.join("\r\n"));
        setStatus("Copied to clipboard",1);
      } catch(e) {
         setStatus("Clipboard not supported by this browser",0);
         alert(result.join("\n"));
      };
    } else {
      setStatus("An error occured: No downloadlinks found",0);
    }
    if(cb) cb();
  });
}

function sendToJD(urls,cb) {

  // Get download links and send them to JDownloader
  generateLinks(urls,function(result) {
    if(result) {
      setStatus("Waiting for JDownloader",-1);
      
      // Comment should be the original page in case of multiple links
      var comment = urls[0];
      if(urls.length > 1) {
        if(show_oneclick_FromHighlighScript_allLinks_loc) {
          comment = show_oneclick_FromHighlighScript_allLinks_loc;
        } else if(show_oneclick_FromHighlighScript_selectedLinks_loc) {
          comment = show_oneclick_FromHighlighScript_allLinks_loc;
        } else {
          comment = document.location.href;
        }
      }
      
      GM_xmlhttpRequest({
        method: "POST",
        url: JDOWNLOADER+"flash/add",
        headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Referer" : s_myname
        },
        //data: "source="+encodeURIComponent(s_myname)+"&urls="+encodeURIComponent(result.join("\r\n")), // Moved "source" to Referer
        data: "comment="+encodeURIComponent(comment)+"&urls="+encodeURIComponent(result.join("\r\n")), // See ExternInterfaceImpl.java
        onload: function (resp){
          if(cb) cb();
          if(resp.responseText.startsWith("success")) {
            setStatus("Sent to JDownloader",1);
          } else {
            setStatus("JDownloader rejected the request",0);
          }
        },
        onerror: function(resp) {
          if(cb) cb();
          setStatus("JDownloader is not running",0);
        }


      });

    } else {
      if(cb) cb();
      addStatus("No links to send",0);

    }
  });
}




function showLinks(urls,cb,append,n) {
  var popup = popUp("showLinks");
  var $div = popup.node;
  var $loader = $('<div style="width:20px; height:20px;" class="ochspinner"></div>').appendTo($div);

  var $frame = $('<iframe width="900" height="500" style="border:0">').appendTo($div);
  $frame.bind('load', function(e) {
      $($frame[0].contentDocument.getElementsByTagName('head')[0]).append('<link rel="stylesheet" href="https://www.nopremium.pl/css/style.css" type="text/css" />');
      var $body = $($frame[0].contentDocument.getElementsByTagName('body')[0]);
      multi[currentdebrid].getResults(urls,function($node) {
        $loader.remove();
        $body.append($node);
        $body.find("a").each(function() {
          // Open links in new window
          this.setAttribute("target","_blank");
        });
        if(cb) cb();
      });

  });
  $frame.attr("src","about:blank");
}


function decryptClickNLoad(cb,jk,crypted_base64) {
  // Get all the links by decrypting the Click'n'Load form
  // return False for any error
  // return True, run cb() and open the menu if Click'n'Load was successfully decoded
  
  if(!crypted_base64 && !(document.getElementsByName('crypted').length && document.getElementsByName('jk').length)) {
    return false; // Click'n'Load not avaiblabe
  }
  
  setStatus("Trying to decrypt Click'n'Load",-1);
  
  try {
    // Key/IV
    if(!jk) {
      jk = document.getElementsByName('jk')[0].value;
    }
    if(jk.indexOf("return") != -1) {
      jk = eval(jk+"; f();");
    }

    var key = hexToBytes(jk);
    var iv = key.slice(0);
    
    // Text
    if(!crypted_base64) {
      crypted_base64 = document.getElementsByName('crypted')[0].value;
    }
    var crypted_string = atob(crypted_base64);
    var crypted_bytes = stringToBytes(crypted_string);
  
    // Decrypt
    var text_bytes = slowAES.decrypt(crypted_bytes,slowAES.modeOfOperation.CBC,key,iv); 
    var text = bytesToString(text_bytes);
    
    text = text.replace("\r","");

    var splitted = text.split("\n");
    
    var links = [];
    for(var i = 0; i < splitted.length; i++) {
      // Remove any line that is not a http link
      var t = $.trim(splitted[i])
      if(t && t.substring(0,4) == "http") {
        links.push(t);
      }
    }
         
    var N = links.length;

    if(N === 0) {
      return false; // Click'n'Load probably failed, try another method...
    }
    
    if(cb) {
      cb();
    }
    menu(links);
    setStatus("Found "+(N===1?"one link":(N+" links")),1);
    return true;
  } catch(e) {
    alert("Click'N'Load failed:\n"+e);
    return false;  // Click'n'Load probably failed, try another method...
  }


  /*
  // Get all the links by decrypting the Click'n'Load form 
  if(!document.getElementsByName('crypted').length || !document.getElementsByName('jk').length) {
    if(cb) {
      cb();
    }
    return;
  }
  
  setStatus("Trying linkdecrypter.com",-1);
  var crypted = document.getElementsByName('crypted')[0].value;
  var jk = document.getElementsByName('jk')[0].value;

  GM_xmlhttpRequest( {
    method: "POST",
    url: "http://linkdecrypter.com/api/?t=cnl2",
    data: 'crypted=' + encodeURIComponent(crypted) + '&jk=' + encodeURIComponent(btoa(jk)),
    headers: {
      "User-agent": "Mozilla/5.0 (X11;U;Linux i686;es-ES;rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8", 
      "Accept": "application/atom+xml,application/xml,text/xml", 
      "Content-type" : "application/x-www-form-urlencoded"
    },
    onload: function(response) {
      if(cb) {
        cb();
      }
      var N = response.responseText.split("\n").length;
      if(!response.responseText || response.responseText.indexOf("ERROR(CNL2)") !== -1 ||  N === 0) {
        setStatus("An error occurred while handling the response of linkdecrypter.com",0);
      } else {
        menu(response.responseText);
        setStatus("Found "+(N===1?"one link":(N+" links")),1);
      }
    }
  });
  */
}

function getAllSerienjunkiesLinks(cb) {
  // Get all download links from a serienjunkies.org download page (i.e. the page right after the captcha)
  var urls = []; // [  [partnumber0,link0]  ,  [partnumber1,link1]  ,  .... ]
  var total = 0;

  var rap = document.getElementById('rap');
  var table = rap.getElementsByTagName('table')[0];
  var forms = table.getElementsByTagName('form');

  var j = 1; // part number, in order to make sure that sorting of the links is the same as on the page.
             // This is only a fallback in case there is no visible part number in the actual downloadlink/filename.
  for(var i = 0; i < forms.length; i++) {
    var url = forms[i].action;
    if(url.indexOf('mirror') !== -1 || url.indexOf('firstload') !== -1 ) {
      continue;
    }
    GM_xmlhttpRequest({
      method: "GET",
      url: url,
      onload: function (j){
        return function (response) {
          var loc = response.finalUrl; // Actual link after posible redirections
          if(response.finalUrl.match(/part*(\d+)\./)) { // Try to guess part number
            var part = response.finalUrl.match(/part*(\d+)\./)[1];
            urls.push([parseInt(part,10),loc]);
          } else { // fallback part number
            urls.push([j,loc]);
          }
          setStatus("Decrypting: "+urls.length+"/"+total, total === urls.length?1:-1);
          if(total === urls.length) {
            // Got all links
            cb(urls);
          }
        }
      }(j)
    });
    j++;
  }
  total = j-1;

};

function getSerienjunkiesLinks(cb) {
  // Get all the links from the page
  getAllSerienjunkiesLinks(function(urls) {
    if(cb) {
      cb();
    }

    urls = urls.sort(function(a,b) {
      if (a[0] > b[0]) return 1;
      else if (a[0] < b[0]) return -1;
      return 0;
    });

    var alllinks = '';
    for(var i = 0; i < urls.length; ++i) {
      alllinks += urls[i][1]+"\n";
    }
    menu(alllinks);
  });

}

function reverseString(s) {
  return s.split("").reverse().join("");
}

function getShareBizLinks(cb,noClickNLoad) {
  // Decide whether to use the Click'n'Load, the dlc or the rsdf container

  // Try Click'n'Load
  if($("#swfcontainer") && !noClickNLoad) {
  

  
    var secret = $("#swfcontainer")[0].data.split("code=").pop();
    GM_xmlhttpRequest({
      method: "GET",
      url: SHAREBIZ_CNL2_URL+secret,
      onload: function (resp){
        var parts = resp.responseText.split(";;");
        
        var jk = "var a;"+reverseString(atob(parts[1])); // Strict mode
        var crypt = reverseString(atob(parts[2]));
        
        GM_setClipboard(resp.responseText);
        
        if(!decryptClickNLoad(cb,jk,crypt)) {
          // Click'n'Load did not work, try the containers:
          getShareBizLinks(cb,true);
        }
      }
    });
    return;
  }

  
  var cbutton = false;
  // Look for rsdf
  $('#cf img.pntr').each(function(){
    if($(this).attr('onclick').indexOf("'rsdf'") != -1) {
      cbutton = $(this);
    }
  });
  if(!cbutton) {
    // Now look for dlc
    $('#cf img.pntr').each(function(){
      if($(this).attr('onclick').indexOf("'dlc'") != -1) {
        cbutton = $(this);
      }
    });
    if(!cbutton) {
      if(cb) {
        cb();
      }
      setStatus("Could not find a container button",0);
      return;
    } else {
      // use dlc button
      getShareBizLinksDLC(cb);
    }
  } else {
    // use rsdf button
    getShareBizLinksRSDF(cb);
  }
}

function getShareBizLinksRSDF(cb) {
  // Get all the links by decrypting the rsdf container

  var cbutton = false;
  $('#cf img.pntr').each(function(){
    if($(this).attr('onclick').indexOf("'rsdf'") != -1) {
      cbutton = $(this);
    }
  });
  if(!cbutton) {
    if(cb) {
      cb();
    }
    setStatus("Could not find rsdf button",0);
    return;
  }

  var onclickstr = cbutton.attr('onclick'); // javascript:_get('VXlsd3B3QU80VU13UGRCN1lSbEJrMUYzYy8wZlVLVklNVFBHTG1BWkM4bz0=', 0, 'ccf');
  var lnk = onclickstr.match(/get\('(\S+)'/)[1];

  setStatus("Retrieving rsdf container",-1);

  var url = SHAREBIZ_RSDF_URL+lnk;

  GM_xmlhttpRequest({
    method: "GET",
    url: url,
    onload: function (resp){
      var data = resp.responseText;
      setStatus("Decrypting rsdf container",-1);
      GM_xmlhttpRequest({
        method: "POST",
        url: POSATIV_URL,
        headers: {
        "Content-Type": "application/x-www-form-urlencoded"
        },
        data: "data="+data,
        onload: function (resp){

          if(cb) {
            cb();
          }

          var urls = resp.responseText.split("\n");

          var alllinks = '';
          for(var i = 0; i < urls.length; ++i) {
            alllinks += $.trim(urls[i])+"\n";
          }
          menu(alllinks);
          setStatus("Found "+(urls.length===1?"one link":(urls.length+" links")),1);
        }
      });

    }
  });
}

function getShareBizLinksDLC(cb) {
  // Get all the links by sending the DLC container to http://dcrypt.it/

  var cbutton = false;
  $('#cf img.pntr').each(function(){
    if($(this).attr('onclick').indexOf("'dlc'") != -1) {
      cbutton = $(this);
    }
  });
  if(!cbutton) {
    if(cb) {
      cb();
    }
    setStatus("Could not find dlc button",0);
    return;
  }

  var onclickstr = cbutton.attr('onclick'); // javascript:_get('VXlsd3B3QU80VU13UGRCN1lSbEJrMUYzYy8wZlVLVklNVFBHTG1BWkM4bz0=', 0, 'ccf');
  var lnk = onclickstr.match(/get\('(\S+)'/)[1];

  setStatus("Retrieving dlc container",-1);

  var url = SHAREBIZ_DLC_URL+lnk;

  GM_xmlhttpRequest( {
    method: "GET",
    url: url,
    binary: true,
    overrideMimeType: 'text/plain; charset=x-user-defined',
    onload: function(resp) {
      setStatus("Decrypting dlc container via dcrypt.it",-1);
      GM_xmlhttpRequestBinary({
        method: 'POST',
        url: DCRYPTIT_UPLOAD_URL,
        onload:function(resp) {
          if(cb) {
            cb();
          }
          try {
            var obj = JSON.parse(resp.responseText.replace("<textarea>","").replace("</textarea>",""));

            if(obj.success) {
              obj.success.links.shift(); // Discard first link, it always has the same value
              var alllinks = '';
              for(var i = 0; i < obj.success.links.length; ++i) {
                alllinks += $.trim(obj.success.links[i])+"\n";
              }
              menu(alllinks);
              setStatus("Found "+(obj.success.links.length===1?"one link":(obj.success.links.length+" links")),1);
            } else {
              setStatus("No links found in dlc container",0);
            }
          } catch(e) {
            alert(e);
            setStatus("An error occurred while handling the response of dcrypt.it",0);
          }
        },
        data : {
          'dlcfile' : {
            'value': resp.responseText,
            'filename': 'test.dlc'
          }
        }


      });

    }
  } );

}

function getLinkSaveInLinks(cb) {
  // Get all the links by sending the DLC container URL to http://dcrypt.it/

  if($('#container_loading').css('display') != 'none') {
    if(cb) {
      cb();
    }
    alert(s_myname+'\n\nSorry.\nYou are too quick for this website.\n\nPlease be patient until the container has loaded.');
    return;
  }

  var lnk = document.getElementById('dlc_link').href;

  setStatus("Decrypting dlc container via dcrypt.it",-1);
  GM_xmlhttpRequest({
    method: "POST",
    url: DCRYPTIT_CONTAINERLINK_URL,
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    data: "link="+encodeURIComponent(lnk),
    onload: function (resp){
      if(cb) {
        cb();
      }
      try {

        var obj = JSON.parse(resp.responseText);

        if(obj.success) {
          obj.success.links.shift(); // Discard first link, it always has the value "http://linksave.in"
          var alllinks = '';
          for(var i = 0; i < obj.success.links.length; ++i) {
            alllinks += $.trim(obj.success.links[i])+"\n";
          }

          menu(alllinks); 
          setStatus("Found "+(obj.success.links.length===1?"one link":(obj.success.links.length+" links")),1);
        } else {
          setStatus("No links found in dlc container",0);
        }
      } catch(e) {
        alert(e);
        setStatus("An error occurred while handling the response of dcrypt.it",0);
      }
    }
  });

}

function getLinkcryptWsLinks(cb) {
  // Get all the links by sending the DLC container to http://dcrypt.it/
  
  if(decryptClickNLoad(cb)) { // Try Click'n'Load first, then fallback to DLC
    return;
  }
  

  var cbutton = false;
  $('#ad_cont a').each(function(){
    if($(this).html().indexOf("dlc.png") != -1) {
      cbutton = $(this);
    }
  });
  if(!cbutton) {
    setStatus("Could not find dlc button or Click'n'Load",-1);
    if(cb) {
      cb();
    }
    return;
  }

  var url = cbutton.attr('href');

  GM_xmlhttpRequest( {
    method: "GET",
    url: url,
    binary: true,
    overrideMimeType: 'text/plain; charset=x-user-defined',
    onload: function(resp) {
      setStatus("Decrypting dlc container via dcrypt.it",-1);
      GM_xmlhttpRequestBinary({
        method: 'POST',
        url: DCRYPTIT_UPLOAD_URL,
        onload:function(resp) {
          if(cb) {
            cb();
          }
          try {
            var obj = JSON.parse(resp.responseText.replace("<textarea>","").replace("</textarea>",""));

            if(obj.success) {
              obj.success.links.shift(); // Discard first link, it always has the same value
              var alllinks = '';
              for(var i = 0; i < obj.success.links.length; ++i) {
                alllinks += $.trim(obj.success.links[i])+"\n";
              }
              menu(alllinks);
              setStatus("Found "+(obj.success.links.length===1?"one link":(obj.success.links.length+" links")),1);
            } else {
              setStatus("No links found in dlc container",0);
            }
          } catch(e) {
            alert(e);
            setStatus("An error occurred while handling the response of dcrypt.it",0);
          }
        },
        data : {
          'dlcfile' : {
            'value': resp.responseText,
            'filename': 'test.dlc'
          }
        }

      });

    }
  } );
}

function getLinkcryptWsLinks2(cb) {
  // Get all the links by decrypting the Click'n'Load form
  var r = decryptClickNLoad(cb);
  if(!r) { 
    setStatus("Could not find Click'n'Load",-1);
    if(cb) {
      cb();
    }
  }
}

function getFilecryptcc(jddata, cb) {
  // Get all the links by decrypting the Click'n'Load form
  var field_jk = jddata[0];
  var field_crypted = jddata[1];
  
  var r = decryptClickNLoad(cb,field_jk,field_crypted);
  if(!r) { 
    setStatus("Could not find Click'n'Load",-1);
    if(cb) {
      cb();
    }
  }
}


function getNCryptLinks(cb) {
  // Get all the links by sending the DLC container URL to http://dcrypt.it/


  // Get the currently selected mirror
  var mirrorid = false;
  for(var i = 0; i < 100; i++) {
    var div = document.getElementById('mirror_'+i);
    if(div && div.style.display != 'none') {
      mirrorid = i;
      break;
    }
  }
  if(mirrorid === false) {
    if(cb) {
      cb();
    }
    alert(s_myname+'\n\nSorry.\nPlease select a mirror first.');
    return;
  }

  var cbutton = false;
  $('#mirror_'+mirrorid+'_container a').each(function(){
    if($(this).html().indexOf("dlc.png") != -1) {
      cbutton = $(this);
    }
  });
  if(!cbutton) {
    if(cb) {
      cb();
    }
    setStatus("Could not find dlc button",0);
    return;
  }

  var lnk = "http://ncrypt.in"+cbutton.attr('href');

  setStatus("Decrypting dlc container via dcrypt.it",-1);
  GM_xmlhttpRequest({
    method: "POST",
    url: DCRYPTIT_CONTAINERLINK_URL,
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    data: "link="+encodeURIComponent(lnk),
    onload: function (resp){
      if(cb) {
        cb();
      }

      try {

        var obj = JSON.parse(resp.responseText);

        if(obj.success) {
          obj.success.links.shift(); // Discard first link, it always has the value "http://linksave.in"
          var alllinks = '';
          for(var i = 0; i < obj.success.links.length; ++i) {
            alllinks += $.trim(obj.success.links[i])+"\n";
          }
          menu(alllinks);
          setStatus("Found "+(obj.success.links.length===1?"one link":(obj.success.links.length+" links")),1);
        } else {
          setStatus("No links found in dlc container",0);
        }
      } catch(e) {
        alert(e);
        setStatus("An error occurred while handling the response of dcrypt.it",0);
      }
    }
  });

}

function getRelinkUsLinks(cb) {
  // Get all the links by following each link

  var cryptic_urls = [];
  $('#links a.submit').each(function(){
    if(this.getAttribute('onclick'))
      cryptic_urls.push(RELINKUS_GETFILE + this.getAttribute('onclick').split("'")[1]);
  });

  var captcha_info = false;
  var captcha_holder = $('<div style="position:absolute; top:10px; right:10px; overflow:auto; height:80%"></div>').appendTo(document.body);

  var urls = [];
  var total = 0;

  var j = 1;
  for(var i = 0; i < cryptic_urls.length; i++) {
    GM_xmlhttpRequest({
      method: "GET",
      url: cryptic_urls[i],
      onload: function (j){
        return function (response) {
          var loc = response.finalUrl; // Actual link after posible redirections
          if(response.responseText.indexOf('iframe') != -1) {
            loc = response.responseText.split('src="')[1].split('"')[0];
            urls.push(loc);
          } else {
            if(!captcha_info) {
              captcha_info = true;
              alert(s_myname+"\n\nSorry, this page is protected with captchas.\n\
              The captchas will appear in the RIGHT TOP corner.");
            }

            var div = $(response.responseText).appendTo(captcha_holder);
            div.css('marginTop','20px');
            div.css('marginLeft','auto');
            div.css('left','auto');
            div.css('top','auto');
            div.css('right','auto');
            div.css('position','relative');
            var form = $('form',div);
            $("input[type=image]",div).click(function(e) {
              e.preventDefault();
              var posX = $(this).offset().left;
              var posY = $(this).offset().top;
              var x = e.pageX - posX;
              var y = e.pageY - posY;
              $(this.parentNode.parentNode).remove();
              var data = form.serialize()+"&button.x="+x+"&button.y="+y;
              GM_xmlhttpRequest({
                method: "POST",
                url: "http://www.relink.us/frame.php",
                data : data,
                headers: {
                  "Host" : "www.relink.us",
                  "Referer" : response.finalUrl,
                  "Content-Type" : "application/x-www-form-urlencoded",
                  "Cache-Control" : "no-cache"
                },
                onload: function (r) {
                  if(r.responseText.indexOf('iframe') != -1) {
                    loc = r.responseText.split('src="')[1].split('"')[0];
                    urls.push(loc);
                  } else {
                    alert(s_myname+"\n\nAn error occured:\nCould not get link.");
                  }

                  setStatus("Decrypting: "+urls.length+"/"+total,-1);
                  if(total === urls.length) {
                    // Got all links
                    cb();
                    menu(urls);
                    setStatus("Found "+(total===1?"one link":(total+" links")),1);
                  }

                }
              });


            });


          }
          setStatus("Decrypting: "+urls.length+"/"+total,-1);
          if(total === urls.length) {
            // Got all links
            cb();
            menu(urls);
            setStatus("Found "+(total===1?"one link":(total+" links")),1);
          }
        }
      }(j)
    });
    j++;
  }
  total = j-1;

};


function getSafeLinkingNetLinks(cb) {
  // Get all the links by following each link

  var cryptic_urls = [];
  $('div.links-container.result-form a.result-a').each(function(){
    if(this.getAttribute('href') && this.getAttribute('href').indexOf('/d/') != -1)
      cryptic_urls.push(this.getAttribute('href'));
  });

  var urls = [];
  var total = 0;

  var j = 1;
  for(var i = 0; i < cryptic_urls.length; i++) {
    GM_xmlhttpRequest({
      method: "GET",
      url: cryptic_urls[i],
      onload: function (j){
        return function (response) {
          var loc = response.finalUrl; // Actual link after posible redirections
          urls.push(loc);
          setStatus("Decrypting: "+urls.length+"/"+total,-1);
          if(total === urls.length) {
            // Got all links
            cb();
            menu(urls);
            setStatus("Found "+(total===1?"one link":(total+" links")),1);
          }
        }
      }(j)
    });
    j++;
  }
  total = j-1;
};


var linkSelectorFilter = {
  _filter : function(key) {
    var a = Array.prototype.slice.call(arguments,1);
    return function() {
      linkSelectorFilter[key].apply(linkSelectorFilter,a);
    }
  },

  all : function(trs) {
    for(var i = 0; i < trs.length; i++) {
      trs[i]["$check"].prop('checked', true);
    }
  },
  none : function(trs) {
    for(var i = 0; i < trs.length; i++) {
      trs[i]["$check"].prop('checked', false);
    }
  },
  flip : function(trs) {
    for(var i = 0; i < trs.length; i++) {
      trs[i]["$check"].prop('checked',!trs[i]["$check"].prop('checked'));
    }
  },
  
  has : function(trs,$inp_filter) {
    var s = $inp_filter.val();
    for(var i = 0; i < trs.length; i++) {
      if(trs[i].link.indexOf(s) != -1) {
        trs[i]["$check"].prop('checked',!trs[i]["$check"].prop('checked'));
      }
    }
  
  },
  
  host : function(trs,$sel_host) {
    var h = $sel_host.val();
    
    for(var i = 0; i < trs.length; i++) {
      if(trs[i].host == h) {
        trs[i]["$check"].prop('checked',!trs[i]["$check"].prop('checked'));
      }
    }
  
  },
  
  fromto : function(trs,$table,$thead,$th) {
    var _self = this;
  
    for(var i = 0; i < trs.length; i++) {
      trs[i].$check.prop('disabled',true);
    }
    $table.find("td").hover(function() { 
      $(this).parent().find("td").each(function(i,e) { 
        $(e).css("background","PaleGreen");
      });
    },function() { 
      $(this).parent().find("td").each(function(i,e) { 
        $(e).css("background","");
      });
    });
    $thead.find("th").css('display','none');
    $th.css("display","");
    $th.html("Select from where to start");
    
    $table.find("td").click(function() {
      var from = $(this.parentNode).data("index");
      $(this).parent().find("td").css("background","PaleGreen");
      $table.find("td").unbind('click mouseenter mouseleave');
      $th.html("Select where to stop");

      $table.find("td").hover(function() { 
        var to = $(this.parentNode).data("index");
        $table.find("td").each(function(i,e) { 
          var $e = $(e); 
          var j = $e.parent().data("index"); 
          if(j > from && j <= to) {
            $e.css("background","DarkSeaGreen");
          } else if(j > from && j > to) {
            $e.css("background","");
          }
        });
        if($(this).parent().data("index") > from) $(this).parent().find("td").css("background","PaleGreen");
      });
      $table.find("td").filter(function(i,e) { return $(e.parentNode).data("index") > from;  }).click(function() {        
        var to = $(this.parentNode).data("index")+1;
        
        $table.find("td").unbind('click mouseenter mouseleave');
        $(this).parent().find("td").css("background","PaleGreen");
        $table.find("td").each(function(i,e) { 
          var $e = $(e); 
          var j = $e.parent().data("index"); 
          if(j < from || j >= to) {
            $e.css("display","none");
          } 
        });
        
        
        var ntrs = trs.slice(from,to);
        for(var i = 0; i < ntrs.length; i++) {
          ntrs[i].$check.prop('disabled',false);
        }
        
        $th.html("Select ");
        $("<button>").appendTo($th).text("all").click(_self._filter("all",ntrs));
        $("<button>").appendTo($th).text("none").click(_self._filter("none",ntrs));
        $("<button>").appendTo($th).text("flip").click(_self._filter("flip",ntrs));
        $("<button>").appendTo($th).text("return to all links").click(function() {
          $table.find("td").each(function(i,e) {
            var $e = $(e);
            $e.css("display","");
            $e.css("background","");
          });
          $thead.find("th").css("display","");
          $th.css("display","none");
          $th.html("");
          for(var i = 0; i < trs.length; i++) {
            trs[i].$check.prop('disabled',false);
          }
        });
        $th[0].scrollIntoView();
        
        return false;
      });
      
    
    
    });
  },
  
  every : function(trs,$table,$thead,$th) {
    var _self = this;
  
    for(var i = 0; i < trs.length; i++) {
      trs[i].$check.prop('disabled',true);
    }
    $table.find("td").hover(function() { 
      $(this).parent().find("td").each(function(i,e) { 
        $(e).css("background","PaleGreen");
      });
    },function() { 
      $(this).parent().find("td").each(function(i,e) { 
        $(e).css("background","");
      });
    });
    $thead.find("th").css('display','none');
    $th.css("display","");
    $th.html("Select from where to start");
    
    $table.find("td").click(function() {
      var from = $(this.parentNode).data("index");
      $(this).parent().find("td").css("background","PaleGreen");
      $table.find("td").unbind('click mouseenter mouseleave');
      $th.html("Select next");

      $table.find("td").hover(function() {
        var to = $(this.parentNode).data("index");
        var diff = to-from;
        if(to < from+2) {
          $table.find("td").filter(function(i,e) { return $(e.parentNode).data("index") > from+1;  }).css("background","");
        } else {
          $table.find("td").filter(function(i,e) { return $(e.parentNode).data("index") > from+1;  }).each(function(i,e) {
            var j = $(this.parentNode).data("index");
            if((j-from) % diff === 0 && j > from+1) {
              $(this).css("background","PaleGreen");
            } else {
              $(this).css("background","");
            }
          });
          $(this).parent().find("td").css("background","DarkSeaGreen");
        }
      }).click(function() {        
        var to = $(this.parentNode).data("index");
        
        if(to < from+2) return false;
        
        $(this).parent().find("td").css("background","PaleGreen");
        
        var diff = to-from;
        
        
        $table.find("td").unbind('click mouseenter mouseleave');

        $table.find("td").each(function(i,e) { 
          var $e = $(e); 
          var j = $e.parent().data("index"); 
          if((j-from) % diff !== 0 || j < from) {
            $e.css("display","none");
          } 
        });
        
        var ntrs = [];
        for(var i = 0; i < trs.length; i++) {
          if((i-from) % diff === 0 && i >= from) {
            trs[i].$check.prop('disabled',false);
            ntrs.push(trs[i]);
          }
        }
        
        $th.html("Select ");
        $("<button>").appendTo($th).text("all").click(_self._filter("all",ntrs));
        $("<button>").appendTo($th).text("none").click(_self._filter("none",ntrs));
        $("<button>").appendTo($th).text("flip").click(_self._filter("flip",ntrs));
        $("<button>").appendTo($th).text("return to all links").click(function() {
          $table.find("td").each(function(i,e) {
            var $e = $(e);
            $e.css("display","");
            $e.css("background","");
          });
          $thead.find("th").css("display","");
          $th.css("display","none");
          $th.html("");
          for(var i = 0; i < trs.length; i++) {
            trs[i].$check.prop('disabled',false);
          }
        });
        $th[0].scrollIntoView();
        
        return false;
      });
      
    
    
    });
  },
   


};


function linkSelector(links) {
  var filter = function(key) {
    var a = Array.prototype.slice.call(arguments,1);
    return function() {
      linkSelectorFilter[key].apply(linkSelectorFilter,a);
    }
  };
  
  var trs = [];
  
  var selectedLinks = [];
  // Coyp array and remove empty elements
  for(var i = 0,t; i < links.length; i++) {
    if(t = $.trim(links[i])) {
      selectedLinks.push(t);
    }
  }
  
  
  var allLinks;
  if(links_beforeSelection == false) {
    links_beforeSelection = links.slice(0); // Save all links for later selections
  }
  allLinks = links_beforeSelection.slice(0);
  
  var popup = popUp("linkSelector");
  var $div = popup.node;
  var $loader = $('<div style="width:20px; height:20px;" class="ochspinner"></div>').appendTo($div);
  $div.css("overflow","none");
  var $frame = $('<iframe style="border:0">').appendTo($div);
  $frame.attr('width',window.innerWidth-190);
  $frame.attr('height',window.innerHeight-120);
  $frame.bind('load', function(e) {
    var $body = $($frame[0].contentDocument.getElementsByTagName('body')[0]);
    
    var $main = $("<div>").appendTo($body);
  
    var $table = $("<table>").appendTo($main);
    var $thead = $("<thead>").appendTo($table);
    
    var $tr0 = $("<tr>").appendTo($thead);
    var $th0 = $("<th>").appendTo($tr0).attr("colspan",2);
    var $tr1 = $("<tr>").appendTo($thead);
    var $th1 = $("<th>").appendTo($tr1).attr("colspan",2);
    var $tr2 = $("<tr>").appendTo($thead);
    var $th2 = $("<th>").appendTo($tr2).attr("colspan",2);
    var $tr3 = $("<tr>").appendTo($thead);
    var $th3 = $("<th>").appendTo($tr3).attr("colspan",2);
    var $tr4 = $("<tr>").appendTo($thead);
    var $th4 = $("<th>").appendTo($tr4).attr("colspan",2);
    
    $("<span>Select: <span>").appendTo($th0);
    $("<button>").appendTo($th0).text("all").click(filter("all",trs));
    $("<button>").appendTo($th0).text("none").click(filter("none",trs));
    $("<button>").appendTo($th0).text("flip").click(filter("flip",trs));

    $("<button>").appendTo($th1).text("Select from ... to ...").click(filter("fromto",trs,$table,$thead,$th4));
    $("<button>").appendTo($th1).text("Select every ...").click(filter("every",trs,$table,$thead,$th4));;

    $("<span> Filter:<span>").appendTo($th2);
    var $inp_filter = $("<input>").appendTo($th2).attr("type","text");
    $("<button>").appendTo($th2).text("Flip with filter").click(filter("has",trs,$inp_filter));

    $("<span> Host filter:<span>").appendTo($th3);
    var $sel_host = $("<select>").appendTo($th3);
    $("<button>").appendTo($th3).text("Flip with host filter").click(filter("has",trs,$sel_host));
    
    
    
    var allhosts = [];
    for(var i = 0; i < allLinks.length; i++) {
      var $tr = $("<tr>").data("index",i).appendTo($table);
      var $td0 = $("<td>").appendTo($tr);
      var $check = $("<input>").appendTo($td0).attr("type","checkbox").attr("id","link_checkbox_"+i).prop('checked', selectedLinks.indexOf(allLinks[i]) != -1);
      var $td1 = $("<td>").appendTo($tr);
      $("<label>").attr("for","link_checkbox_"+i).text(allLinks[i]).css("font-family","monospace").appendTo($td1);
      
      var host = allLinks[i].split("/")[2].replace(/^www\./,"");
      if(allhosts.indexOf(host) == -1) {
        allhosts.push(host);
      }
      
      trs.push({"$tr":$tr,"$check":$check,"link":allLinks[i],"host":host});
    }
    
    for(var i = 0; i< allhosts.length; i++) {
      $("<option>").val(allhosts[i]).text(allhosts[i]).appendTo($sel_host);
    }
    
    var $apply = $("<button>").appendTo($main).text("Apply").click(function() {
      var nlinks = [];
      for(var i = 0; i < trs.length; i++) {
        if(trs[i]["$check"].prop('checked')) {
          nlinks.push(trs[i].link);
        }
      }
      if(nlinks.length === 0) {
        alert("No links selected?!");
        return;
      }
      menu(nlinks);
      setStatus((nlinks.length===1?"One link":(nlinks.length+" links"))+" selected",1);
      popup.close();
    });

    $loader.remove();
  });
  $frame.attr("src","about:blank");
}


function menu(links) {
  // normalize links:
  if(!Array.isArray(links)) {
    var parts = links.split("\n");
    links = [];
    for(var i = 0; i < parts.length; i++) {
      if($.trim(parts[i])) {
        links.push($.trim(parts[i]));
      }
    }
  }



  var $entry;
  var $c = $("#multiochhelper ul");
  $c.html("");

  var $select = $("<select>");
  var host = links[0].match(/https?:\/\/(.+?)\//)[1];
  var hoster = host.split(".");
  hoster.pop();
  hoster = hoster.pop().replace("-","");
  $.each(multi, function(key,val) {
    var $option = $('<option></option>').val(key).html(val.name).appendTo($select);
    if(key == currentdebrid) {
      $option[0].selected = true;
    }
    if(multi[key].isOnline(hoster)) {
      $option.css('color','green');
    } else {
      $option.css('color','#F00');
    }
  });
  $entry = menuentry($select);
  $select.bind("change",function(ev) {
    var $this = $(this);
    // Change hoster
    currentdebrid = $this.val();

    // Check general support
    if(multi[currentdebrid].isOnline(hoster)) {
      // Check first link for support on this multi hoster
      multi[currentdebrid].checkLink(links[0],function(result) {
        if(!result) {
          alert(s_myname+"\n\n"+host+" is not supported by this hoster or the file is offline.\n\nChecked: "+links[0]);
        }
      });
    } else {
      alert(s_myname+"\n\n"+host+" is not supported by "+multi[currentdebrid].name);
    }

    // Add "Remember" checkbox
    if(!$this.parent().find("#remember").length) {
      var $div = $("<div>");
      var $check = $('<input id="remember" type="checkbox" value="remember" title="Remember selection">').click(function() {
        if(this.checked) {
          currentdebrid = $select.val();
          GM_setValue("currentdebrid",currentdebrid);
          setStatus("Switched to "+multi[currentdebrid].name,1);
          $div.remove();
        }
      });
      $div.append($check).append("Remember");
      $this.parent().append($div);
    }
  });

  $entry = menuentry("Direct download");
  $entry.click(function() { mouse("download",links); });

  $entry = menuentry("Copy to clipboard");
  $entry.click(function() { mouse("clipboard",links); });

  if(settings.jDownloaderSupport) {
    $entry = menuentry("Send to JDownloader");
    $entry.attr("id","multiochhelperjdbutton");
    $entry.hide();
    $entry.click(function() { mouse("sendToJD",links); });
    GM_xmlhttpRequest({
      method : 'GET',
      url: JDOWNLOADER+"flash/",
      onload: function (resp){
        if(resp.responseText.startsWith("JDownloader")) {
          $("#multiochhelperjdbutton").show();
        }
      }
    });
}

  if(!show_oneclick_FromHighlighScript_allLinks) {
    $entry = menuentry("Show generated links");
    $entry.click(function() { mouse("showLinks",links); });
  }

  $entry = menuentry("Show extracted links");
  $entry.click(function() { alert(links.join("\n")); });

  if(!show_oneclick_FromHighlighScript_allLinks && (links.length > 1 || links_beforeSelection !== false)) {
    $entry = menuentry("Select links");
    $entry.click(function() { linkSelector(links); });
  }
  
  if(!show_oneclick_FromHighlighScript_allLinks) {
    $entry = menuentry();
    var $a = $('<a style="color:white !important;">Open Website</a>').attr("href",getMultiOCHWebsiteURL(links)).appendTo($entry);
  }

  if(show_oneclick_FromHighlighScript_allLinks && show_oneclick_FromHighlighScript_allLinks_links) {
    $entry = $(menuentry("Use all links on page..."));
    $entry.click(function() {
      // Switch to all links instead of one
      var links = show_oneclick_FromHighlighScript_allLinks_links;
      show_oneclick_FromHighlighScript_allLinks_links = "";
      menu(links);
      $("#multiochhelper div:empty:not(:first)").remove();
      setStatus("All links!",1);
    });
  }
  

  if(show_oneclick_FromHighlighScript_selectedLinks && show_oneclick_FromHighlighScript_selectedLinks_links) {
    $entry = $(menuentry("Use selected links..."));
    $entry.click(function() {
      // Switch to selected links instead of one
      var links = show_oneclick_FromHighlighScript_selectedLinks_links;
      show_oneclick_FromHighlighScript_selectedLinks_links = "";
      menu(links);
      $("#multiochhelper div:empty:not(:first)").remove();
      setStatus("Using selected links!",1);
    });
  }
  
  

  if(!show_oneclick_FromHighlighScript_allLinks) {
    $entry = menuentry($('<span style="cursor:default; color:silver">Userscript menu</span>').click(function(ev) { ev.stopPropagation(); aboutMe(); })).css("cursor","default");
    $('<span style="cursor:pointer; color:White; border: 1px solid White; border-radius:3px; padding:0px; margin-left:20px; font-weight:bold ; " title="Close menu">X</span>').click(function() {$("#multiochhelper").remove();}).appendTo($entry);
  }
}


function loader() {
  // Show an animation, return function to remove the loader
  $("#multiochhelper_status_loader").parent().show();
  var $div = $('<div class="ochspinner"></div>').appendTo($("#multiochhelper_status_loader"));
  return function() {
    $div.remove();
  };
}

function mouse(action,linkText) {
  // decide what to do after a mouse click
  var removeImg = loader();
  if(action == "download") {
    download(linkText,removeImg);
  } else if(action == "showLinks") {
    showLinks(linkText,removeImg);
  } else if(action == "openWebsite") {
    openWebsite(linkText);
  } else if(action == "clipboard") {
    clipboard(linkText,removeImg);
  } else if(action == "menu") {
    removeImg();
    menu(linkText);
  } else if(action == "sendToJD") {
    sendToJD(linkText,removeImg);
  }




}

function menuentry(html) {
  var $li = $("<li>");
  if(html) {
    $li.append(html);
  }
  $li.appendTo("#multiochhelper ul");
  return $li;
}

function button(label) {
  addCSSHead('\
  #multiochhelper,#multiochhelper * {\
    font-family:Sans-Serif !important;\
    padding:0px; margin:0px;\
  }\
  #multiochhelper a, #multiochhelper a:link,#multiochhelper a:visited {\
    text-decoration:underline !important;\
    color:#3788e8 !important;\
    font-style:none !important;\
  }\
  #multiochhelper a:hover {\
    text-decoration:none !important;\
    color:#3788e8 !important;\
    font-style:none !important;\
  }\
  #multiochhelper ul li,#multiochhelper_status {\
    margin:1px 1px;\
    padding:1px 5px;\
    font-size:13px;\
    text-shadow:0 -1px 0 #333333;\
    color:White;\
    cursor:pointer;\
    border:1px solid #8B3D92;\
    background-color:#B555C5;\
    background:-moz-linear-gradient(center top , #B555C5, #8B3D92);\
    list-style:none outside;\
  }\
  #multiochhelper select,#multiochhelper input {\
    border-radius:0;\
    box-shadow:none;\
    text-shadow:none;\
    border:none;\
    background:white;\
    color:black;\
  }\
  \
  '+SPINNERCSS);

  // div container
  var zi = getNextZIndex();
  var $div = $("<div>").appendTo(document.body);
  $div.attr("id","multiochhelper");
  $div.attr("style",'z-index:'+zi+'; position:fixed; background:#E6E6E6; color:Black; border:#B555C5 2px solid;border-radius:5px; padding:3px;');
  if(settings.position[0] == "top") {
    $div.css('top',"0%");
  } else {
    $div.css('bottom',"0%");
  }
  if(settings.position[1] == "left") {
    $div.css('left',"0%");
  } else {
    $div.css('right',"0%");
  }
  // Status
  var $status = $("<div>").appendTo($div).hide();
  $status.attr("id","multiochhelper_status");
  var $loader = $("<span>").appendTo($status);
  $loader.attr("id","multiochhelper_status_loader");
  var $statustext = $("<span>").appendTo($status);
  $statustext.attr("id","multiochhelper_status_text");

  var $ul = $("<ul>").appendTo($div);

  // Button
  var $entry = menuentry(label?label:(multi[currentdebrid].name.charAt(0).toUpperCase() + multi[currentdebrid].name.slice(1)));

  $ul.append($entry);

  return $entry
}

// Update hoster status
if(GM_getValue("setup",false)) {
  var updatinghosters = false;
  for(var key in multi) {
    if(multi[key].updateStatusURLpattern.test(document.location.href)) { //  usually in this is true in the iframe which is defined below
      multi[key].updateStatus();
      updatinghosters = true;
      break;
    }
  }
}

// Create iframes to check hoster status:
if(!updatinghosters && GM_getValue("setup",false)) {
  var now = new Date();
  for(var key in multi) {
    if((now - multi[key].lastUpdate) > (settings.updateHosterStatusInterval*60*60*1000) ) {
      var $iframe = $("<iframe>").appendTo(document.body);
      $iframe.bind("load",function() {
        var frame = this;
        window.setTimeout(function() { $(frame).remove(); },3000);
      });
      $iframe.attr("src",multi[key].updateStatusURL);
    }
  }
}

// Setup
if(!updatinghosters) {
  if(!GM_getValue("setup",false)) {
    aboutMe();
    if(!confirm(s_myname+" Setup\n\nPlease take some time to configure "+s_myname+" and then save the settings!\n\nPress cancel to continue with the default configuration!")) {
      GM_setValue("setup",true);
      alert(s_myname+"\n\nDefault settings will be used.");
      document.location.reload();
    }
  }
}

if(document.location.href.indexOf("nopremium.pl") != -1) {
  // nopremium.pl Website
  if(document.location.search.substring(0,6) == "?link:") {
    // Insert link on nopremium.pl
    $('#filesList').val(decodeURIComponent(document.location.search.substring(6)));
  }
} else if(document.location.href.indexOf("www.premiumize.me") != -1) {
  // premiumize.me Website
  if(document.location.search.substring(0,6) == "?link:") {
    // Insert link on nopremium.pl
    $("textarea").val(decodeURIComponent(document.location.search.substring(6)));
  }
} else if(document.location.href.indexOf("download.serienjunkies.org") != -1) {
  // Serienjunkies
  if(!document.getElementById('CINPUT')) { // if not on captcha page
    var $b = button("Decrypt links");
    $b.click(function(ev) {
      var removeImg = loader();
      getSerienjunkiesLinks(removeImg);
    });
  }
} else if (document.location.href == "http://filecloud.io/download.html") {
  // filecloud.io
  if(unsafeWindow.__currentUrl) {
    show_oneclick_button = true;
    show_oneclick_link = decodeURIComponent(unsafeWindow.__currentUrl);
  }
} else if (document.location.href.indexOf("share-links.biz") != -1) {
  // share-links.biz folder
  if(!document.getElementById('captchamap') && document.getElementById('cf')) { // if not on captcha page
    var $b = button("Decrypt links (via dcrypt.it)");
    $b.click(function(ev) {
      var removeImg = loader();
      getShareBizLinks(removeImg);
    });
  }
} else if (document.location.href.indexOf("linksave.in") != -1) {
  // linksave.in folder
  if(document.getElementById('dlc_link')) { // if not on captcha page
    var $b = button("Decrypt links (via dcrypt.it)");
    $b.click(function(ev) {
      var removeImg = loader();
      getLinkSaveInLinks(removeImg);
    });
  }
} else if (document.location.href.indexOf("filecrypt.cc") != -1) {
  // filecrypt.cc folder
  if(document.location.href.indexOf("helper.html") != -1) { // if not on captcha page  
    unsafeWindow.close = function() {}; // Prevent popup from beeing closed
    window.addEventListener('message',function filecryptmessage(event) {
      if (event.data && typeof(event.data) == 'object') {
        window.removeEventListener("message",filecryptmessage); // Prevent further messages from creating several buttons
        var $b = button("Decrypting...");
        var removeImg = loader();
        getFilecryptcc(event.data, removeImg);
      }
    });
  } else if(document.location.href.indexOf("Container") != -1) { // if not on captcha page
    var $b = button("Please open the Click'n'Load Popup");
    $b.click(function() {
      $("#cnl_btn").click();
    });
  }

} else if (document.location.href.substring(7,19) == "linkcrypt.ws") {
  // linkcrypt.ws folder
  if(document.getElementById('container_check') || document.getElementById('ad_cont')) { // If containers are present
    var $b = button("Decrypt links (via dcrypt.it)");
    $b.click(function(ev) {
      var removeImg = loader();
      getLinkcryptWsLinks(removeImg);
    });
  } else if(document.querySelector("form[id^=f]")) {
    var $b = button("Decrypt links (via dcrypt.it)");
    $b.click(function(ev) {
      var removeImg = loader();
      getLinkcryptWsLinks2(removeImg);
    });
  } else {
    var $b = button("Select hoster first!");
    $b.click(function(ev) {});
  }
}  else if (document.location.href.substring(7,16) == "ncrypt.in") {
  // nCrypt.in folder
  if(document.getElementById('main') && document.getElementById('main').innerHTML.indexOf("Securitycheck:") === -1) { // If not on captcha page
    var $b = button("Decrypt links (via dcrypt.it)");
    $b.click(function(ev) {
      var removeImg = loader();
      getNCryptLinks(removeImg);
    });
  }
}  else if (document.location.href.substring(7,20) == "www.relink.us") {
  // relink.us folder
  if(document.getElementById('container_tabs')) {
    var $b = button("Decrypt links");
    $b.click(function(ev) {
      var removeImg = loader();
      getRelinkUsLinks(removeImg);
    });
  }
}  else if (document.location.href.substring(8,23) == "safelinking.net" || document.location.host == "linkshield.org") {
  // safelinking.net and linkshield.org folder
  if(!document.getElementById('captcha-wrapper')) {
    var $b = button("Decrypt links");
    $b.click(function(ev) {
      var removeImg = loader();
      getSafeLinkingNetLinks(removeImg);
    });
  }
} else if (document.location.href.indexOf(".firedrive.com/share/") != -1) {
  // firedrive.com folder
  show_oneclick_button = true;
  show_oneclick_link = "";
  $("a.pf_item_link:visible").each(function() {
    show_oneclick_link += decodeURIComponent(this.href)+"\n";
  });
} else if (document.location.href.indexOf("uploaded.net/folder/") != -1 || document.location.href.indexOf("uploaded.net/f/") != -1) {
  // Uploaded folder
  show_oneclick_button = true;
  show_oneclick_link = "";
  $("#fileList a.file").each(function() {
    show_oneclick_link += decodeURIComponent(this.href)+"\n";
  });
} else if (document.location.href.indexOf("rapidgator.net/folder/") != -1) {
  // Rapidgator folder
  show_oneclick_button = true;
  show_oneclick_link = "";
  $("#grid tbody a").each(function() {
    show_oneclick_link += decodeURIComponent(this.href)+"\n";
  });
} else if(document.location.protocol == "data:" && document.location.href.substring(0,23) == "data:text/html;MultiOCH") {
   // Iframe for a X-Frame-Options website
  show_oneclick_button = true;
  show_oneclick_link = decodeURIComponent(document.getElementById("link").value);
} else {
   // One click hoster website
  show_oneclick_button = true;
  show_oneclick_link = decodeURIComponent(document.location.href);
}
if(show_oneclick_button) {
  var mouseOverAvailable = true;

  // Split links into array
  var splitted = show_oneclick_link.split("\n");
  var show_oneclick_link = [];
  for(var i = 0; i < splitted.length; i++) {
    if($.trim(splitted[i])) {
      show_oneclick_link.push($.trim(splitted[i]));
    }
  }

  var $b = button();

  $b.bind("mousedown",
  function(ev) {
    mouseOverAvailable = false;
    if(ev.which === 3) { // Right click
      mouse(settings.rightClick,show_oneclick_link);
    }
    else if(ev.which === 2) { // Middle click
      mouse(settings.middleClick,show_oneclick_link);
    }
    else if(ev.which === 1) { // Left click {
      mouse(settings.leftClick,show_oneclick_link);
    }
  });
  if(settings.mouseOver != 'none') {
    var ti = false;
    $b.on({
      'mouseover': function() {
        if(!mouseOverAvailable)
          return;
        ti = setTimeout(function(){
          if(!mouseOverAvailable)
            return;
          mouseOverAvailable = false;
          mouse(settings.mouseOver,show_oneclick_link);
        }, settings.mouseOverDelay);
      },
      'mouseout' : function(){
        if(ti !== false) clearTimeout(ti);
      }
    });
  }
  // Prevent context menu on right click
  var preventDefault = function(e) { e.preventDefault();};
  if(settings.rightClick != 'none') {
    $b[0].addEventListener('contextmenu', preventDefault , false);
  }
}

// Handle messages from the highlight script
window.addEventListener("message", function(e){
  if(typeof e.data != "object" || ! ("iAm" in e.data) || e.data.iAm != "Unrestrict.li") {
    return;
  }

  switch(e.data.type) {
    case "alllinks":
      if(show_oneclick_FromHighlighScript_allLinks) {
        return;
      }
      show_oneclick_FromHighlighScript_allLinks = true;
      show_oneclick_FromHighlighScript_allLinks_loc = e.data.loc;
      show_oneclick_FromHighlighScript_allLinks_links = e.data.links.join("\n");
      if($("#multiochhelper ul li").length > 1) { // Menu already opened
        menu(show_oneclick_link);
      }
      break;
    case "selectedlinks":
      if(show_oneclick_FromHighlighScript_selectedLinks) {
        return;
      }
      show_oneclick_FromHighlighScript_selectedLinks = true;
      show_oneclick_FromHighlighScript_selectedLinks_loc = e.data.loc;
      show_oneclick_FromHighlighScript_selectedLinks_links = e.data.links.join("\n");
      if($("#multiochhelper ul li").length > 1) { // Menu already opened
        menu(show_oneclick_link);
      }
      break;
  } 


}, true);