Greasy Fork is available in English.

Maknyos AutoIn

Auto click to a link mostly for download purpose, iframe killer. Supported hosts: zippyshare, mediafire, sendspace, uptobox, cloud.mail.ru, adf.ly, and many more...

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name           Maknyos AutoIn
// @namespace      http://userscripts.org/scripts/show/91629
// @icon           https://github.com/idoenk/maknyos-autoin/raw/master/assets/img/icon-60x60.png
// @version        3.9.42
// @description    Auto click to a link mostly for download purpose, iframe killer. Supported hosts: zippyshare, mediafire, sendspace, uptobox, cloud.mail.ru, adf.ly, and many more...
// @homepageURL    https://greasyfork.org/scripts/97
// @require        https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @author         Idx
// @grant          GM_log
// @include        http*://*.zippyshare.com/v/*/*
// @include        http*://*.dfpan.com/fs/*
// @include        http*://*.dfpan.com/file/down/*
// @include        http*://*.4shared.com/*/*/*
// @include        http*://*.mediafire.com/*/*/*
// @include        http*://*.sendspace.com/file/*
// @include        http*://*uptobox.com/*
// @include        http*://*.yimuhe.com/file-*
// @include        http*://*.yimuhe.com/down-*
// @include        http*://*howfile.com/file/*
// @include        http*://*uppit.com/*/*
// @include        http*://*clicknupload.org/*
// @include        http*://*sendmyway.com/*
// @include        http*://*tusfiles.net/*
// @include        http*://*.dropbox.com/s/*
// @include        http*://*.solidfiles.com/v/*
// @include        http*://*yadi.sk/i/*
// @include        http*://*yadi.sk/d/*
// @include        http*://*.datafilehost.com/d/*
// @include        http*://*userscloud.com/*
// @include        http*://*hulkload.com/*
// @include        http*://*up2me.net/*
// @include        http*://app.box.com/*
// @include        http*://*dailyuploads.net/*
// @include        http*://rgho.st/*
// @include        http*://*uplod.org/*
// @include        http*://*.upload.ee/files/*
// @include        http*://*uploads.to/*
// @include        http*://*uploadbank.com/*
// @include        http*://*drop.me/*
// @include        http*://*jzrputtbut.net/*
// @include        http*://dropapk.com/*
// @include        http*://*suprafiles.org/*
// @include        http*://*cloudyfiles.org/*
// @include        http*://*megadrive.co/*
// @include        http*://*douploads.com/*
// @include        http*://*file-upload.com/*
// @include        http*://*topddl.net/file/*
// @include        http*://*.up-4ever.com/*
// @include        http*://*3rbup.com/*
// @include        http*://*9xupload.me/*
// @include        http*://*samaup.com/*
// @include        http*://*bdnupload.com/*
// @include        http*://*indishare.me/*
// @include        http*://ako.am/*
// @include        http*://rapidgator.net/file/*
// @include        http*://*filefactory.com/file/*
// @include        http*://dl.free.fr/getfile.pl?file=*
// @include        http*://up.top4top.net/*
// @include        http*://cloud.mail.ru/public/*
// @include        http*://drive.google.com/file/*
// @include        http*://docs.google.com/uc*
// @include        http*://my.pcloud.com/publink/*
// @include        http*://minhateca.com.br/*
// @include        http*://bc.vc/*
// @include        http*://sh.st/*
// @include        http*://adf.ly/*
// @include        http*://adfoc.us/*
// @include        http*://filescdn.com/*
// @include        http*://gen.lib.rus.ec/*
// @include        http*://libgen.io/*
// @include        http*://libgen.me/*
// @include        http*://b-ok.org/*

// ==/UserScript==



(function() {
  var gvar = function(){};
  gvar.__DEBUG__ = !1;

  function MaknyosHelper(baseURI){
    this.baseURI = baseURI;
    this.domain  = null;
    gvar.isFF    = !1;

    if("function" !== typeof GM_log || (gvar.isFF = (navigator.userAgent.indexOf('Firefox') !== -1)) ){
      GM_log = function(_msg) {
        try {
          unsafeWindow.console.log('GM_log: '+_msg)
        }
        catch(e){}
      };

      try {
        GM_log('GM_log function GM_log rewriten');
      }
      catch(e){}
    }

    this.action  = new Actions();
  }
  MaknyosHelper.prototype = {
    matchDomain: function(){
      var domain = this.baseURI.match(/^https?:\/\/([^\/]+)\//);
      if(domain)
        this.domain=domain[1];
      return this;
    },

    matchAction: function(){
      if(this.domain)
        this.action.find(this.domain);
      return this;
    },

    invokeAction: function(){
      if(this.action.invoked){
        if(!this.action.noBaseClean)
          this.action.baseCleanUp();
        this.action.invoked();
      }
      return this;
    },
  };


  function Actions(){
    this.invoked=null;
    this.noBaseClean=null;
  }
  Actions.prototype = {
    find: function(domain){
      this.clog('Actions:find, domain='+domain);

      var isMatch, pattern;
      
      for(var key in this.patterns){
        pattern = this.patterns[key];
        this.clog('pattern-check: '+pattern.rule+' vs '+domain);
        isMatch = typeof pattern.rule === 'string' ? pattern.rule == domain : pattern.rule.test(domain);
        if(isMatch){
          this.invoked = pattern.run;
          this.noBaseClean = !isUndefined(pattern.noBaseClean) && pattern.noBaseClean;
          return;
        }
      }
    },

    get_href: function(){
      return location.href;
    },
    set_href: function(x){
      location.href = x;
    },

    parse_handle_href: function(x){
      var cucok, href;
      if( "string" == typeof x )
        href = x;
      else if( "object" == typeof x )
        href = x.getAttribute("href");

      if( href && /\/handle\?/.test(href) ){
        href = href.replace('&', '&');
        if( cucok = /\&?fl=((?:f|ht)tps?[^\&]+)/i.exec(href) )
          href = decodeURIComponent(cucok[1]);
        else
          this.clog("parsing fail on href, missing param `fl=`");
      }
      return href;
    },

    /**
     * Try find form to submit of given button element
     * If it fail, just click that button anyway
     */
    trySumbit: function(button, cb_before){
      var tform = null,
          el    = null
      ;
      if (!button)
        return !1;

      if (button.nodeName != 'FORM')
        tform = this.closest(button, 'form');

      if( 'function' === typeof cb_before )
        cb_before(tform);

      if( tform ){
        if( el = g('[name="referer"]', tform) )
          el.value = '';

        if( button.nodeName != 'FORM' && button.getAttribute('name') ){
          el = document.createElement('input');
          el.setAttribute('type', 'hidden');
          el.setAttribute('name', button.getAttribute('name'));
          if( button.value )
            el.value = button.value;
          else if(button.textContent)
            el.value = button.textContent;

          tform.appendChild(el);
        }

        tform.submit();
      }
      else{
        this.clog('Inside trySumbit: form not found. Clicking button..');
        
        SimulateMouse(button, "click", true);
      }
    },

    // do waitwhat -> thenwhat
    waitforit: function(waitwhat, thenwhat, delay){
      var ME = this,
          stoWait = null,
          itry    = 0,
          maxtry  = 10,
          thenwhatwrap = function(r){
            ME.clog('callback waiting element, doing thenwhatwrap..');
            ('function' == typeof thenwhat ) &&
              thenwhat(r);
          };
      
      if( !delay )
        delay = 0;
      delay = parseInt( delay );

      ME.clog('waiting for element..');
      if('function' == typeof waitwhat){
        var waitwrap = function(){
          ME.clog('['+itry+']: inside waitwrap..');
          itry++;
          var r_ = null;
          if( r_ = waitwhat() ){
            stoWait && clearTimeout( stoWait )
            thenwhatwrap( r_ );
          }
          else{
            if( itry < maxtry )
              stoWait = setTimeout(waitwrap, delay+1000);
            else{

              ME.clog('waitforit failed...');
            }
          }
        };
        stoWait = setTimeout(waitwrap, delay+1000);
      }
      else
        thenwhatwrap();
    },

    observer_init_: function(ev){
      var ME = this,
          params = ME.param_observe
      ;
      ME.clog('inside observer_init_..');
      ME.clog(ME.param_observe);
      
      if( ev.type == params.event ){
        
        ME.clog('ahoy this match event...'+ev.type)
      }
    },
    observe: function(element, params){
      var ME = this,
          config = {}
      ;
      if( !(params && params.callback) ){
        ME.clog('missing required params');
        return !1;
      }

      // create an observer instance
      var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
      var observer = new MutationObserver(function(mutations) {
        var BreakException = {};
        try{
          mutations.forEach(function(mutation) {
            // var $el = $(mutation.target);
            // if( is_observed ) throw BreakException;

            if( 'function' == typeof params.callback )
              params.callback( mutation.target );
          });
        }catch(e){

          if(e!==BreakException) throw e;
        }
      });
       
      // configuration of the observer:
      config = $.extend({
        attributes: true,
        childList: true,
        characterData: true
      }, params.config);
      ME.clog(config);
      
      // pass in the target node, as well as the observer options
      observer.observe(element, config);
       
      // later, you can stop observing
      // observer.disconnect();
      gvar.observer = observer;
    },

    injectBodyStyle: function(stylesString){
      var style = document.createElement("style");
      style.appendChild( document.createTextNode(stylesString) );
      document.body.appendChild(style);
    },
    injectBodyScript: function(scriptFunc){
      var script = document.createElement("script");
      script.textContent = "(" + scriptFunc.toString() + ")();";
      document.body.appendChild(script);
    },

    // load url to an iframe
    frameload: function(url){
      var body, cb_fn, idfrm = 'xMNyFrame';
      var iframe = document.createElement('iframe');
      
      if( g('#'+idfrm) )
        g('#'+idfrm).removeChild();

      iframe.setAttribute('id', idfrm);
      iframe.setAttribute('title', "iFrame of "+idfrm+"; src="+url);
      iframe.setAttribute('style', 'position:absolute; z-index:999999; '+(gvar.__DEBUG__ ? 'border:1px solid #000; left:0; top:0; width:100%;' : 'border:0; height:0; width:0; left:-9999; bottom:9999'));
      iframe.setAttribute('src', url);

      body = g('body');
      if( gvar.__DEBUG__ )
        body.insertBefore(iframe, body.firstChild);
      else
        g('body').appendChild(iframe);


      if( gvar.__DEBUG__ ){
        if( g('#'+idfrm) )
          this.clog("iframe created, src="+url);
        else
          this.clog("error while creating iframe");
      }
    },
    // resize capcay
    rezCapcay: function(target, dims){
      if(!target) return;
      if(dims.length){
        var styleStr='';
        dims[0] && (styleStr += 'width:'+dims[0]+'px;');
        dims[1] && (styleStr += 'height:'+dims[1]+'px;');
        target.setAttribute('style', styleStr);
      }
    },

    disableWindowOpen: function(){
      if(unsafeWindow){
        unsafeWindow.open = function(){};
      }

      if(window){
        window.open = function(){};
      }
    },

    // get codes of simple capcay code
    scrap_simplecapcay: function(el_code){
      var $code = $(el_code);
      var codes=[], thecodes = [];
      var $trycode = $code.closest("td").prev();
      if( $trycode.length ){
        $trycode.find(">div > span").each(function(){
          var $me = $(this);
          var pl = $me.css("paddingLeft").replace('px','');
          thecodes.push({
            'id': pl,
            'val': $me.text()
          })
        });

        thecodes.sort(function(a,b) {
          return a.id - b.id;
        });
        for(var i=0, iL=thecodes.length; i<iL; i++)
          codes.push( thecodes[i].val );

        if( codes.length )
          $code.val( codes.join("") );
      }

      return codes;
    },

    scrapScriptsByRegex: function(pattern, parent){
      // must be ( match instanceof RegExp )

      if( 'undefined' == typeof parent )
        parent = document;

      var scripts = parent.getElementsByTagName('script'),
          cucok = null,
          inner = ''
      ;
      for( var i = 0; i < scripts.length; i++ ){
        if( inner = scripts[i].innerHTML ){
          this.clog(inner);
          if( cucok = pattern.exec(inner) )
            break;
        }
      }
      return cucok;
    },

    // basic cleanup document from anoying things
    // eg. iframe, onclick body, etc
    baseCleanUp: function(){
      this.clog("killing frames..");
      this.killframes();

      this.clog("killing click events.");
      this.killevents(null, 'click');
      this.killevents(null, 'mousedown');

      this.clog("killing onbeforeunload events.");
      this.killunload();
    },

    // brutaly kill frames
    killframes: function(par){
      !par && (par = document);
      var o = par.getElementsByTagName('iframe');
      for(var i=o.length-1;i>=0;i--)
        o[i].parentNode.removeChild(o[i]);

      o = gAll('.ad'+'sbygo'+'ogle');
      for(var i=o.length-1;i>=0;i--)
        o[i].parentNode.removeChild(o[i]);

      this.clog("killframes done");
    },

    killevents: function(par, type, handle){
      !type && (type = 'click');
      !par && (par = document);
      !handle && (handle = function(){});
      var o = par.getElementsByTagName('*');
      for(var i=o.length-1;i>=0;i--){
        if ( o[i].removeEventListener ) {
          o[i].removeAttribute("on"+type);
          //W3C Standard    
          o[i].removeEventListener( type, handle, true );
        }
      }
      this.clog("killevents done");
    },

    killunload: function(){
      window.onbeforeunload = null;
      window.onunload = null;
      unsafeWindow.onbeforeunload = null;
    },

    hidefixed: function(orAbsolute){
      var style = document.createElement("style"),
          css = ''
            +'body>*[style*="fixed"]'
            +(orAbsolute ? ',body>*[style*="absolute"]' : '')
            +'{display: none!important;}';
      style.textContent = css;
      document.body.insertBefore(style, document.body.firstChild);
    },

    isVisible: function (ele) {
      // this.clog("visibility-test; clientWidth="+ele.clientWidth+'; clientHeight='+ele.clientHeight+'; opacity='+ele.style.opacity+'; visibility='+ele.style.visibility+'; offsetParent='+ele.offsetParent);
      return true &&
        // ele.clientWidth !== 0 &&
        // ele.clientHeight !== 0 &&
        ele.offsetParent !== null &&
        ele.style.opacity !== 0 &&
        ele.style.visibility !== 'hidden';
    },

    isInIframe: function () {
      try {
        return window.self !== window.top;
      } catch (e) {
        return true;
      }
    },

    hasClass: function(cName, ele){
      if(!cName || !ele) return;
      var clss = (ele.getAttribute('class')||'').split(' ');
      return (clss.indexOf(cName) != -1);
    },

    // get nearest parent element matching selector
    closest: function (el, selector) {
      var parent, matchesFn;

      // find vendor prefix
      ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
        if (typeof document.body[fn] == 'function') {
          matchesFn = fn;
          return true;
        }
        return false;
      });

      // traverse parents
      while (el) {
        parent = el.parentElement;
        if (parent && parent[matchesFn](selector)) {
          return parent;
        }
        el = parent;
      }

      return null;
    },

    show_alert: function(msg, force) {
      if(arguments.callee.counter) {
        arguments.callee.counter++
      }else {
        arguments.callee.counter = 1
      }

      if("function" == typeof GM_log){
        GM_log("(" + arguments.callee.counter + ") " + (typeof msg == "object" ? ">>" : msg));
        if( typeof msg == "object" )
          GM_log( msg );
      }
      else{
        console && console.log && console.log(msg);
      }
      if( force == 0 )
        return
    },
    clog: function(x){
      if( !gvar.__DEBUG__ )
        return
      this.show_alert(x);
    }
  };
  Actions.prototype.patterns = {

    sendspace: {
      rule: /sendspace\.com/,
      run: function(){
        this.clog('inside sendspace');
        g('#download_button') && SimulateMouse(g('#download_button'), "click", true);
      }
    },

    zippyshare: {
      rule: /zippyshare\.com/,
      run: function(){
        this.clog('inside zippyshare');
        var btn = g("#dlbutton");

        // failover, just incase
        if( !btn ) {
          btn = g("[alt*=Download]");
          if( btn )
            btn = btn.parentNode;
          else
            btn = g(".download");

          if( btn )
            btn = btn.parentNode;
        }

        if( btn ) {
          this.waitforit(function(){

            return /(?:\.zippyshare\.com)?\/d\/.+/.test( btn.getAttribute("href") );
          }, function(){

            btn && SimulateMouse(btn, "click", true);
          });
        }
        else{

          this.clog('missing: download button');
        }
      }
    },

    mediafire: {
      rule: /mediafire\.com/,
      noBaseClean: true,
      run: function(){

        var that = this,
            dcg, selector, btn, nbtn
        ;

        if( dcg = g("#docControlGroup") ){
          selector = './/a[contains(@target,"_blank")]';
          selector = xp(selector, dcg, true);
          selector && that.set_href(selector.getAttribute('href'))
        }
        else if( dcg = g('#recaptcha_widget_div') ){
          var recapcay = g('.g-recaptcha', dcg),
              site_key = recapcay.getAttribute('data-sitekey')
          ;

          if('function' === typeof $ && site_key){

            $('.g-recaptcha', dcg)
              .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));

            // recaptcha-rebuilder
            var scriptHandler = function(_site_key){
              return (function(win, $){

                if("undefined" !== typeof grecaptcha){
                  grecaptcha.render("maknyos-recaptcha", {
                    sitekey: "___SITEKEY___",
                    callback: function(){ $(".dl_startlink > a").trigger("click") }
                  });
                }
                else{

                  console.log('grecaptcha undefined');
                }
              })(window, $);
            };
            scriptHandler = scriptHandler.toString();
            scriptHandler = scriptHandler.replace(/___SITEKEY___/, site_key);
            that.injectBodyScript(scriptHandler);

            var cssString = ''
              +'#form_captcha .captchaPromo:before { content: "Click to download"; font-size: 1.2em; color: #ccc; position: absolute; top: 6px; left: -20px; margin-top: -30px;}'
              +'.nonpro_adslayout #form_captcha .captchaPromo, .freeAccount .pro #form_captcha .captchaPromo{ background-size: 275%; background-position-y: -110px; }'
            ;
            that.injectBodyStyle(cssString);
          }
        } else {

          that.waitforit(function(){
            return g('.download_link a');
          }, function(){
            btn = g('.download_link a');
            nbtn = document.createElement('a');
            nbtn.setAttribute('href', btn.getAttribute('href'));
            nbtn.setAttribute('onclick', 'location.href=this.href; return !1');
            nbtn.innerHTML = btn.innerHTML;
            btn.parentNode.replaceChild(nbtn, btn);

            SimulateMouse(nbtn, "click", true);
          }, 100);
        }
      }
    },

    uptobox: {
      rule: /uptobox\.com/,
      run: function(){

        var that        = this
            waitStr     = null,
            waitFor     = !1,
            countdown   = g('#timeLeft'),
            btnDownload = g('#btn_download')
        ;

        // force download link with https based on its parent protocol
        var prefilter_uptobox_https = function(href_){
          var prot = location.protocol;
          if( location.protocol == 'https:' && !/https:/i.test(href_) ){
            href_ = href_.replace(/^http\:/i, 'https:');
            
            that.clog('https download-link='+href_);
          }
          return href_;
        };
        

        if( countdown ){
          scripts = document.getElementsByTagName( 'script' );
          for( var i = 0; i < scripts.length; ++i ) {
            if( cucok = /\bcountdownNum\s*=\s*(\d+)/.exec(scripts[i].innerHTML)) {
              waitFor = Math.floor(parseInt( cucok[1] ) / 3);
              break;
            }
          }

          if( waitFor ){
            this.waitforit(function(){

              var disabled = btnDownload.getAttribute('disabled');
              return ('undefined' != typeof disabled && disabled ? !1 : btnDownload);
            }, function(el){

              SimulateMouse(el, "click", true);
            }, waitFor * 1000);
          }
        }
        else{
          // is the timeleft timer simply not activated
          if( btnDownload ){

            SimulateMouse(btnDownload, "click", true, prefilter_uptobox_https);
          }
          else{
            btnDownload = g('#countdown_str');
            if( btnDownload ){
              this.clog('disabled='+btnDownload.getAttribute('disabled'));
              if( !btnDownload.getAttribute('disabled') ){

                // do downoad
              }
              else{
                waitStr = String(g('#countdown_str').textContent).replace(/[\s\W]/g,'').toLowerCase();
                if( cucok = /(?:[a-zA-Z]+)?(\d+)(?:[a-zA-Z]+)?/.exec(waitStr) ){

                  this.waitforit(function(){

                    return g('#btn_download');
                  }, function(el){

                    SimulateMouse(el, "click", true, prefilter_uptobox_https);
                  }, parseInt(cucok[1] * 1000));

                }
              }
            }
            else if( g('.button_upload') ){
              // take-care of fake exe download
              var link, rlink, el = g('.button_upload');
              if( link = el.parentNode ){
                rlink = getParameterByName("prod"+"uct_d"/*fo*/+"ownloa"+"d_url", link.getAttribute("href"));
                
                // hiding the-arse
                if( rlink ){
                  rlink = 'http://blankrefer.com/?'+rlink;
                  this.frameload(rlink);
                }
                else{
                  // last-resort, key may changed.
                  SimulateMouse(link, "click", true, prefilter_uptobox_https);
                }
              }

            }else{

              this.clog('tpl-changed, mismatch element');
            }
          }
        }
      }
    },

    howfile: {
      rule: /howfile\.com/,
      run: function(){
        this.clog('inside howfile');
        this.waitforit(function(){

          return xp('//a[contains(.,"Download")]', null, true);
        }, function(){

          var btnDownload = xp('//a[contains(@href, "/downfile/")]', g("#downloadtable"), true);
          btnDownload && SimulateMouse(btnDownload, "click", true);
        }, 234);
      }
    },

    uppit: {
      rule: /uppit\.com/,
      run: function(){
        this.clog('inside uppit');
        var countdown = g('#countdown');
        var cucok, waitFor, scripts;
        if( countdown ){
          scripts = document.getElementsByTagName( 'script' );
          for( var i = 0; i < scripts.length; ++i ) {
            if( cucok = /\bcount\s*=\s*(\d+)/.exec(scripts[i].innerHTML)) {
              waitFor = parseInt(cucok[1]);
              break;
            }
          }

          if( waitFor ){

            this.waitforit(function(){
              return !g('#countdown');
            }, function(){
              SimulateMouse(g('#btn_download'), "click", true);
            }, waitFor * 1000);
          }
        }
        else{
          SimulateMouse(g('.m-btn'), "click", true);
        }
      }
    },

    tusfiles: {
      rule: /tusfiles\.net/,
      run: function(){
        var that    = this,
            maxTry  = 3,
            iTry    = 0,
            sTryStop = null,
            btnDl    = null
        ;
        var cb_pagestop = function(){
          var el = null;

          if( el = g('[name=quick]') ){
            el.removeAttribute('checked');
            el.parentNode.removeChild(el);
          }

          if( el = g('[name=F1]') )
            el.submit();
        };

        if( btnDl = g('[name=F1]') ){

          sTryStop = setInterval(function(){
            window.stop();
            iTry++;

            if( iTry > maxTry ){
              sTryStop && clearInterval( sTryStop );
              if("function" == typeof cb_pagestop)
                cb_pagestop()
            }
          }, 10);
        }
        else{

          that.clog('Not download page or missing download button');
        }
      }
    },

    sendmyway: {
      rule: /sendmyway\.com/,
      run: function(){
        this.clog('inside sendmyway');
        var dd, adcopy = g('#adcopy_response'),
            btnDownload = g('#download_link'),
            btnFreeDownload = g('.btn-free.dl_btn')
        ;
        if( !adcopy && !btnDownload ){
          this.clog('adad adcopy');
          btnFreeDownload && SimulateMouse(btnFreeDownload, "click", true);
        }
        else{
          if( !btnDownload ){
            adcopy.focus();
          }
          else{
            dd = g('#direct_download');
            btnDownload = g('#download_link', dd);
            this.frameload(btnDownload.getAttribute('href'))
          }
        }
      }
    },

    box: {
      rule: /app\.box\.com/,
      run: function(){
        var that = this;

        this.waitforit(function(){
          var $pcw = $('.preview-content-wrapper'),
              $phr = $('.preview-header-right'),
              $btn1 = xp('.//button[contains(@data-type, "download-btn")]', $phr.get(0), true),
              $btn2 = xp('.//button[contains(.,"Download")]', $pcw.get(0), true);

          return ($btn1 && $btn2 ? $btn1 : null);
        }, function(btnDl){

          setTimeout(function(){
            btnDl && SimulateMouse(btnDl, "click", true);
          }, 3456);
        }, 100);
      }
    },

    dropbox: {
      rule: /dropbox\.com/,
      run: function(){
        var that = this;

        this.waitforit(function(){
          var parent = g('.react-title-bar');

          return xp('.//button[contains(.,"Download")]', parent, true);
        }, function(btn){
          if (btn){
            btn && SimulateMouse(btn, "click", true);
          }
          else{
            
            this.clog('dropbox: missing download button, page may changed');
          }
        }, 234);
      }
    },

    solidfiles: {
      rule: /solidfiles\.com/,
      run: function(){
        var that  = this,
            $bc   = g('.box-content:first-child'),
            btnDownload
        ;
        that.clog('inside solidfiles, '+that.get_href());

        setTimeout(function(){
          that.killframes();
          that.disableWindowOpen();
        }, 123);

        if( btnDownload = g('[type=submit]', g('form.ng-pristine')) ){
          setTimeout(function(){
            SimulateMouse(btnDownload, "click", true)
          }, 125);
        }
        else {
          if( $bc.textContent.indexOf('downloading') == -1 )
            this.clog('solidfiles: missing download button, page may changed');
        }
      }
    },

    yadi: {
      rule: /yadi\.sk/,
      run: function(){
        var that = this,
            api_url = location.protocol+'//'+location.hostname+'/public-api-desktop/download-url';

        that.clog('inside yadi, '+that.get_href());
        this.waitforit(function(){

          return el = xp('//button[contains(@class,"button2") and contains(.,"ownloa")]', null, true);
        }, function(btnDownload){
          that.clog(btnDownload);

          if( btnDownload ){

            // models-client json
            var json = g('#store-prefetch').innerHTML,
                pdata = {"hash": "", "sk": ""};

            if( json ){
              try{
                json = JSON.parse(json)
              }catch(e){ json = null; }
            }

            if( json ){
              var fields = ['environment', 'resources'],
                  firstKey = null,
                  item = null;

              for(var key in json){

                if(fields.indexOf(key) === -1)
                  continue;

                item = json[key];
                switch(key){
                  case "environment":
                    if('undefined' != typeof item['sk']){
                      pdata['sk'] = item['sk'];
                      continue;
                    }
                  break

                  case "resources":
                    firstKey = Object.keys(item)[0];
                    if(firstKey && 'undefined' != typeof item[firstKey]['hash']){
                      pdata['hash'] = item[firstKey]['hash'];
                      continue;
                    }
                  break
                }
              }
              // end: for json

              setTimeout(function(){
                that.clog('Prepping XHR...');

                // xhr
                $.ajax({
                  type: 'POST',
                  url: api_url,
                  contentType: 'text/plain',
                  dataType: 'json',
                  data: JSON.stringify(pdata)
                })
                .done(function(ret){
                  that.clog('on DONE');
                  
                  that.clog(ret)
                  if (ret && ret.data && ret.data.url){

                    that.frameload( ret.data.url );
                  }
                  else{

                    that.clog('yadi: missing download data.url');
                  }
                })
                .fail(function(r){
                  that.clog('on FAIL');
                })
                .always(function(r){
                  that.clog('on ALWAYS');
                  that.clog(r);
                });
              }, 1200);
            }
            else{

              that.clog('yadi: missing models-clients');
            }
          }
          else{

            that.clog('yadi: missing download button, page may changed');
          }
        }, 100);
      }
    },

    datafilehost: {
      rule: /datafilehost\.com/,
      run: function(){
        var that, btnDownload;
        that = this;

        that.clog('inside datafilehost, '+that.get_href());
        setTimeout(function(){ that.killframes() }, 123);

        // pick selector dat relevant and exist on several browsers
        if( btnDownload = xp('//a[contains(@href,"/get.php?") or contains(@class,"ownloa")]', null, true) )
          setTimeout(function(){

            if( href = that.parse_handle_href( btnDownload.getAttribute("href") ) )
              btnDownload.setAttribute("href", href);

            SimulateMouse(btnDownload, "click", true)
          }, 125);
        else
          this.clog('datafilehost: missing download button, page may changed');
      }
    },

    userscloud: {
      rule: /userscloud\.com/,
      run: function(){
        var that = this,
            btnDl = null,
            tform = null,
            btn_selector = '//button[contains(@id, "ownlo") and not(contains(@disabled,"disabled"))]'
        ;
        that.clog('inside userscloud, '+that.get_href());
        setTimeout(function(){ that.killframes() }, 456);

        if( g('.innerTB') ){
          if( btnDl = xp(btn_selector, null, true) ){
            setTimeout(function(){

              tform = that.closest(btnDl, 'form');
              if( tform ){

                tform.submit()
              }
              else{

                SimulateMouse( btnDl, "click", true);
              }
            }, 345);
          }
          else if( btnDl = g('#dl_link a') ){
            // Final link

            that.set_href(btnDl.getAttribute('href'));
          }
          else{

            that.clog('Missing download button');
          }
        }
        else{

          that.clog('Not download page');
        }
      }
    },

    hulkload: {
      rule: /hulkload\.com|up2me\.net/,
      run: function(){
        var that = this,
            btnDl = null;

        that.clog('inside hulkload, '+that.get_href());

        if (!$('.filepanelag').length){
          that.clog('Now download page');
          return !1;
        }

        // cleanup page 
        setTimeout(function(){ 
          that.killframes();

          $('[class*="adscent"]').remove();
        }, 1100);

        btnDl = $('#direct_link');
        if (btnDl.length){

          btnDl = btnDl.get(0);
          SimulateMouse( btnDl, "click", true);
        }
        else{
          // count down with captcha..
          that.clog('Please wait then insert captcha');
        }
      }
    },

    dailyuploads: {
      rule: /dailyuploads\.net/,
      run: function(){
        var that  = this,
            recapcay  = g('.g-recaptcha'),
            site_key = null,
            form = null,
            btnDl = null,
            par = null
        ;

        // Final-page
        if ((par = g('.inner')) &&  xp('//h2[contains(text(),"Link Generated")]', par, true)){
          btnDl = g('a[href*=".dailyuploads.net"]', par);
          if( btnDl ){

            setTimeout(function(){
              SimulateMouse(btnDl, "click", true);
            }, 1235)
          }
          else{

            that.clog('Missing download button');
          }
        }
        else{
          // Init page
          form = g('form[name=F1]');
          btnDl = g('[name=fs_download_file]');

          if ($('#chkIsAdd').is(':checked'))
            $('#chkIsAdd').trigger('click');

          if (recapcay){
            site_key = recapcay.getAttribute('data-sitekey');
            that.clog('Recapcay found, site_key: '+site_key);

            $(recapcay)
              .replaceWith($('<div id="maknyos-recaptcha" data-sitekey="'+site_key+'"></div>'));


            // Incase of grecaptcha lib properly loaded
            setTimeout(function(){

              // recaptcha-rebuilder
              var scriptHandler = function(_site_key){
                return (function(win, $){

                  if("undefined" !== typeof grecaptcha){
                    grecaptcha.render("maknyos-recaptcha", {
                      sitekey: "___SITEKEY___",
                      callback: function(){
                        var $par = null;
                        if ($('#chkIsAdd').is(':checked'))
                          $('#chkIsAdd').trigger('click');

                        $par = $('#chkIsAdd').closest('div');
                        $par.find('button:visible').trigger("click")
                      }
                    });
                  }
                  else{

                    console.log('grecaptcha undefined');
                  }
                })(window, $);
              };
              scriptHandler = scriptHandler.toString();
              scriptHandler = scriptHandler.replace(/___SITEKEY___/, site_key);
              that.injectBodyScript(scriptHandler);
            }, 567);
          }
          else if(form || btnDl){
            that.clog('Recapcay not found, direct submitting..');

            if (form)
              that.trySumbit(form);
            else if (btnDl)
              that.trySumbit(btnDl);
            else
              that.clog('Missing download button');
          }
          else{

            that.clog('Not a download page');
          }
        }
      }
    },

    rgho: {
      rule: /rgho\.st/,
      run: function(){
        var that = this,
            href = '',
            btn_selector = '//a[contains(@href,"/download/") and contains(text(),"ownload")]';

        if( btnDl = xp(btn_selector, null, true) ){
          href = btnDl.getAttribute('href');

          if( href )
            that.set_href( href );
          else
            SimulateMouse(btnDl, "click", true);
        }else{

          this.clog('rgho: missing wrapper button, page may changed');
        }
      }
    },

    uploadee: {
      rule: /upload\.ee/,
      run: function(){
        var wrapBox = g('.textbody:last-child'),
            btnDl = null
        ;
        if( wrapBox ){
          btnDl = g('a[href*="/download/"]', wrapBox);
          if( btnDl )
            SimulateMouse(btnDl, "click", true);
          else
            this.clog('uploadee: missing download button, page may changed');
        }
        else{

          this.clog('uploadee: missing wrapper button, page may changed');
        }
      }
    },

    bcvc: {
      rule: /bc\.vc/,
      noBaseClean: true,
      run: function(){
        var that = this,
            loc = location.href,
            btnSel = '#skip_btt'
        ;

        if( loc.indexOf('#') == -1 ){
          top.location.href = loc+'#';
          location.reload();
          return !1;
        }
        else{
          if('function' === typeof window['IFrameLoaded'])
            window['IFrameLoaded']();

          try{
            $('body>iframe')
              .css('position','absolute')
              .css('width',0)
              .css('height',0)
              .css('left','-999999px')
            ;
          }catch(e){}

          (function wait2Click(){
          
            that.waitforit(function(){

              return g(btnSel);
            }, function(){

              SimulateMouse(g(btnSel), "click", true);
            }, 567);
          })();
        }
      }
    },

    shst: {
      rule: /sh\.st/,
      run: function(){
        var that = this,
            scripts = document.getElementsByTagName( 'script' ),
            cbu = null, si = null,
            cucok, cbName
        ;
        for( var i = 0; i < scripts.length; ++i ) {
          innerScript = scripts[i].innerHTML;
          if( !innerScript ) continue;

          if( null === cbu && (cucok = /callbackUrl\s*:\s*[\'\"]([^\'\"]+)/i.exec(innerScript)) )
            cbu = cucok[1];

          if( null === si && (cucok = /sessionId\s*:\s*[\'\"]([^\'\"]+)/i.exec(innerScript)) )
            si = cucok[1];

          if( cbu != null && si != null)
            break;
        }

        if( cbu && si && 'function' == typeof reqwest ){
          cbName = 'mkycb_'+String(Math.random()).replace(/0\./,'');

          that.waitforit(function(){
            var btn = g("#skip_button");
            return that.isVisible(btn) && that.hasClass('show', btn);
          }, function(){

            reqwest({
              url: cbu+'?',
              method: 'get',
              data: {
                adSessionId: si,
                adbd: 1,
                callback: cbName,
              },
              type: 'jsonp',
              success: function(ret){
                if( ret && ret.destinationUrl )
                  location.href = ret.destinationUrl;
              },
              timeout: 1e4,
              error: function(e){ that.clog( e ) }
            });

            var scriptHandler = function(){
              return (function(win){
                win["__cbName__"] = function(ret){
                  var btn = document.getElementById("skip_button");
                  btn.textContent = 'Redirecting...';

                  if(ret && ret.destinationUrl)
                    location.href = ret.destinationUrl;

                  setTimeout(function(){
                    btn.setAttribute('disabled', 'disabled');
                  }, 200)
                };
              })(window);
            };
            scriptHandler = scriptHandler.toString();
            scriptHandler = scriptHandler.replace(/__cbName__/i, cbName);

            that.injectBodyScript(scriptHandler);
          }, 345);
        }
        else{

          that.clog('Missing callbackUrl | sessionId'+('undefined' == typeof reqwest ? ' | reqwest is Undefined' : ''));
        }
      }
    },

    adfly: {
      rule: /adf\.ly/,
      noBaseClean: true,
      run: function(){
        var that = this,
            lpath = location.pathname,
            id    = '#home',
            ndv   = '',
            link  = ''
        ;
        that.clog(location.href);

        if( /\/ad\/locked/.test(lpath) ){
          return that.waitforit(function(){
            var el = g('#continue');
            return (that.isVisible(el) ? el : !1);
          }, function(cnt){
            that.clog(cnt);
            return setTimeout(function(){
              SimulateMouse(g('a', cnt), "click", true);
            });
          });
        }
        //https://adf.ly/redirecting/aHR0cDovL3d3dy5tZWRpYWZpcmUuY29tLz83ajczODR3NjdiM3RyOXE=
        else if( /\/redirecting\/\w+/.test(lpath) ){
          that.clog('inside redirecting page...');
          if( (link = g('a')) ){
            that.set_href( link.getAttribute('href') );
            return !1;
          }
        }
        else if( !g(id) || !/\/\w+$/.test(lpath) ) {

          that.clog('['+location.href+']:: Not a redirecter page..');
          return !1;
        }

        var continuum = function(ndv){
          // stage-1
          if( ndv ){
            var poluted = ndv.indexOf('!HiT'+'o'+'mmy'),
                a = '',
                b = ''
            ;
            if (poluted >= 0) 
              ndv = ndv.substring(0, poluted);

            for (var i = 0; i < ndv.length; ++i) {
              if (i % 2 === 0) {
                a = a + ndv.charAt(i);
              } else {
                b = ndv.charAt(i) + b;
              }
            }
            ndv = atob(a + b);
            ndv = ndv.substr(2);
            if( location.hash )
              ndv += location.hash;

            that.set_href( ndv );

            that.clog('stage-1: found link: '+ndv);
            return !1;
          }
          else{

            that.clog('stage-1: FAIL');
          }



          // stage-2 (failover)
          var elck = g('#cookie_notice'),
              skipSel = '#top span img[src*=sk'+'ip_'+'ad]'
          ;
          if( elck )
            elck.parentNode.removeChild( elck );


          that.waitforit(function(){
            var btn = g(skipSel), href;
            if( btn ){
              btn = btn.parentNode;
              href = btn.getAttribute('href');
            }
            return href && /^((?:(?:ht|f)tps?\:\/\/){1}\S+)/.test(href);
          }, function(){
            var btn = g(skipSel).parentNode,
                href = btn.getAttribute('href')
            ;
            if( href )
              location.href = href;
            else
              that.clog('Unable get redirect link');
          }, 345);
        };

        that.killunload();
        that.killevents(null, 'click');
        that.killevents(null, 'mousedown');
        that.injectBodyStyle('iframe{visibility:hidden!important;}');



        // wait to find these elements
        that.clog('finding ndv');
        var ping_url = location.protocol+'//'+location.hostname+'/callback/',
            id = $('#adReporter').find('[name="lt"]').val()
        ;
        if( id ){
          ping_url += id;

          return $.post(ping_url, {hithere:(new Date().getTime())}, function(){
            return $.get(location.href, function(ret){
              var patterns = [
                    /var\s+eu\s+=\s+'(?!false)(.+)'/,
                    /var\s+ysmm\s+=\s+'(.+)'/
                  ],
                  cucok = null
              ;
              if( cucok = patterns[0].exec(ret) ){
                that.clog('patterns[0]');
                cucok = cucok[1];
              }
              else if( cucok = patterns[1].exec(ret) ){
                that.clog('patterns[1]');
                cucok = cucok[1];
              }
              return continuum( cucok );
            });
          });
        }
        else{

          continuum( null );
        }
      }
    },

    adfocus: {
      rule: /adfoc\.us/,
      run: function(){
        var that = this,
            id = '#interstitial',
            skipSel = '#showSkip >a'
        ;
        if( !g(id) ){
          that.clog('['+location.href+']:: Not a redirecter page..');
          return !1;
        }

        that.waitforit(function(){
          var btn = g(skipSel), href = null;
          if( btn )
            href = btn.getAttribute('href');

          return href && /^((?:(?:ht|f)tps?\:\/\/){1}\S+)/.test(href);
        }, function(){
          var btn = g(skipSel),
              href = (btn ? btn.getAttribute('href') : null)
          ;
          if( href )
            location.href = href;
          else
            that.clog('Unable get redirect link');
        }, 345);
      }
    },

    mypcloudcom: {
      rule: /my\.pcloud\.com/,
      run: function(){
        var that = this,
            btn_selector = '//div[contains(@class,"button") and contains(text(),"ownload")]'
        ;

        if( xp(btn_selector, g('.button-area'), true) ){
          var scriptHandler = function(_site_key){
            return (function(win, $){

              var gvar          = gvar||{},
                  btn_selector  = '.button-area > .button.greenbut',
                  g             = ___func_g___,
                  frameload     = ___func_frameload___,
                  SimulateMouse = ___func_simulatemouse___
              ;


              if('undefined' != typeof publinkData && publinkData.downloadlink){
                
                frameload( publinkData.downloadlink );
              }
              else{
                console.log('publinkData undefined');

                SimulateMouse( $(btn_selector).first().get(0), "click", true );
              }
            })(window, $);
          };
          scriptHandler = scriptHandler.toString();
          scriptHandler = scriptHandler.replace(/___func_simulatemouse___/, SimulateMouse.toString());
          scriptHandler = scriptHandler.replace(/___func_g___/, g.toString());
          scriptHandler = scriptHandler.replace(/___func_frameload___/, that.frameload.toString());
          
          that.injectBodyScript(scriptHandler);
        }
        else{
          that.clog('mypcloudcom: missing button element, page may changed');
        }
      }
    },

    uploadrocket: {
      rule: /uploadrocket\.net/,
      run: function(){
        var that = this,
            form = g('[name=freeorpremium]'),
            btnDl = null, href
        ;
        if( form )
          btnDl = g('[name=method_isfree]', form);

        if( form && btnDl ){

          SimulateMouse(btnDl, "click", true);
        }
        else if( btnDl = g('#btn_download') ){
          var blah = g('#glasstop');
          blah.parentNode.removeChild( blah );

          that.clog('insert captcha...');
          g('[name=adcopy_response]').focus();

          btnDl.removeAttribute('disabled');
        }
        else{
          btnDl = xp('//a[contains(.,"rect Downlo")]', null, true);
          if( btnDl ){
            href = btnDl.getAttribute('href');
            if( href )
              that.set_href( href );
            else
              SimulateMouse(btnDl, "click", true);
          }
          else{
            
            that.clog('uploadrocket: missing download button, page may changed');
          }
        }
      }
    },

    uplodorg: {
      rule: /(uplod\.org)/,
      run: function(){
        var that   = this,
            el     = null,
            tform  = g('#myDownloadForm'),
            btnDl  = g('.downloadbtn:not([name])'),
            recapcay = g('.g-recaptcha', tform),
            site_key = null,
            href   = ''
        ;
        if( tform || btnDl ){
          if( el = g('a[href*="apploading.mobi"]') )
            el.parentNode.removeChild( el );

          if( el = g('#chkIsAdd') )
            el.checked = false;

          if (recapcay){

            if (site_key = recapcay.getAttribute('data-sitekey')){

              $(recapcay)
                .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));

              if( g('#maknyos-recaptcha') ){
                that.clog('g-recaptcha tampered');
                that.waitforit(function(){

                  return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
                }, function(gr){
                  
                  gr.render("maknyos-recaptcha", {
                    sitekey: site_key,
                    callback: function(){
                      if( tform ){

                        tform.submit();
                      }
                      else{

                        $(btnDl).trigger('click');
                      }
                    }
                  });
                });
              }
              else{

                that.clog('tampering g-recaptcha FAILED');
              }
            }
          }
          else{

            if( tform ){

              tform.submit();
            }
            else{
              
              SimulateMouse(btnDl, "click", true);
            }
          }
        }
        else{
          if( el = g('.fileInfo') ){
            // # Stage 2
            if( btnDl = g('.btn-download', el) ){
              href = btnDl.getAttribute('href');
              if( href )
                that.set_href( href );
              else
                SimulateMouse(btnDl, "click", true);
            }
          }
          else{

            that.clog('Not download page');
          }
        }
      }
    },

    uploadsto: {
      rule: /uploads\.to/,
      run: function(){
        var that      = this,
            gtable    = g('.table'),
            recapcay  = g('.g-recaptcha', gtable),
            site_key  = null,
            btnCheck  = null,
            tform     = null,
            btnDl     = g("#method_free")
        ;
        if( recapcay && g('#method_free') ){
          site_key = recapcay.getAttribute('data-sitekey')

          if('function' === typeof $ && site_key){

            $(recapcay)
              .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));

            if( g('#maknyos-recaptcha') ){
              that.clog('g-recaptcha tampered');
              that.waitforit(function(){

                return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
              }, function(gr){
                
                gr.render("maknyos-recaptcha", {
                  sitekey: site_key,
                  callback: function(){ $("#method_free").trigger("click") }
                });
              });
            }
            else{
              that.clog('tampering g-recaptcha FAILED');
            }
          }
          else{

            that.clog('Error: site_key or jQuery is not defined');
          }
        }
        else{
          if( btnDl ){
            // # Stage 1, incase no recapcay
            SimulateMouse( btnDl, "click", true);
          }
          else if( btnDl = g('#btn_download') ){
            // # Stage 2
            
            if( btnCheck = g('#chkIsAdd') )
              btnCheck.checked = false;

            tform = that.closest(btnDl, 'form');
            if( tform )
              tform.submit();
            else
              SimulateMouse( btnDl, "click", true);
          }
          else if( btnDl = g('.btn.btn-primary[href*="downlod.me"]') ){
            that.clog('Stage 3');

            // # Stage 3
            SimulateMouse( btnDl, "click", true);
          }
          else{

            that.clog('Not download page or missing download button [Stage-?], page may changed');
          }
        }
      }
    },

    cloudmailru: {
      rule: /cloud\.mail\.ru/,
      run: function(){
        var that    = this;

        that.waitforit(function(){
          var toolbar = g('#toolbar');

          // return g('.b-toolbar__btn_download');
          return g('[data-name="download"]', toolbar);
        }, function(btn){

          var layers = g('.layers'),
              param_observe = {
                config: {
                  attributes: false,
                  childList: true,
                  subtree: true,
                  characterData: false
                },
                callback: function(e){
                  var $dialog = $(e);
                  if( $dialog && $dialog.length )
                  setTimeout(function(){
                    $dialog.find(".b-checkbox").trigger('click');
                    $dialog.find(".btn.btn_main").trigger('click');
                    if( gvar.observer )
                      gvar.observer.disconnect();
                  }, 123)
                }
              }
          ;
          that.observe(layers, param_observe);
          SimulateMouse(btn, "click", true);
        }, 345);
      }
    },

    gdrive: {
      rule: /drive\.google\.com|docs\.google\.com/,
      run: function(){
        var that  = this,
            loc   = that.get_href()
        ;

        if( /drive.google.com/.test( loc ) ){
          gvar.stoRedirectGDrive = null;

          var $wrapper    = $('.drive-viewer'),
              id_timer    = 'maknyos-gd-timer',
              countdown   = 4,
              $btn_cancel = $('<a href="javascript:;" class="drive-viewer-dark-button goog-inline-block drive-viewer-button drive-viewer-button-clear-border btn-cancelredirect">cancel</a>');
          ;
          $btn_cancel.click(function(e){
            if( gvar.stoRedirectGDrive )
              clearInterval( gvar.stoRedirectGDrive );

            $('#'+id_timer).parent().remove();
            e.preventDefault();
            that.clog('Redirect plan canceled..');
          });
          $wrapper.prepend(''
            +'<div class="drive-viewer-toolstrip-name timer-autodownload" style="position:absolute; z-index: 10; top:9px; right: 260px; width: auto;">'
            + 'Redirecting <span id="'+id_timer+'">in (X) </span>...'
            +'</div>'
          );
          $wrapper.find(".timer-autodownload").append( $btn_cancel );

          // stInterval
          gvar.stoRedirectGDrive = setInterval(function(){
            var $tgt = $('#'+id_timer),
                count = $tgt.data('count')
            ;
            if( !(count && !isNaN(count)) && count != 0 )
              $tgt.data('count', countdown);
            
            count = parseInt( $tgt.data('count') );
            if( count > 0 ){
              count = (count - 1);
              $tgt.text( 'in ('+count+') ' );
              $tgt.data('count', count);
            }
            else{
              clearInterval( gvar.stoRedirectGDrive );
              $tgt.text('');

              var id = (function(url){
                    var ret = null, cucok;
                    if( cucok = /\/file\/d\/([^\/]+)/i.exec(url) )
                      ret = cucok[1];

                    return ret;
                  })( loc ),
                  href = location.protocol+'//docs.google.com/uc?id='+id+'&export=download'
              ;
              if( id ){

                that.clog('opening href:'+href);
                that.set_href( href );
              }
            }
          }, 1000);
        }
        else{

          that.clog('Force Downloading ....');
          SimulateMouse(g('#uc-download-link'), "click", true);
        }
      }
    },

    "e-book:genlib": {
      rule: /gen\.lib\.rus\.ec|libgen\.io|(|\w+\.)bookfi\.net|b-ok\.org/,
      run: function(){
        var that      = this,
            pathname  = location.pathname,
            host      = location.hostname,
            matchLoc  = ['foreignfiction','search.php','book'],
            imgdl, btnDl, form, rows, healLinks, href
        ;
        if (that.isInIframe()){

          that.clog('Exiting script, soz it loaded in iframe..');
        }


        healLinks = function(){
          var $parent = $('table.c');
          if( !$parent.length || !$parent.html() ){
            if( $parent.length )
              $parent = $('table[rules="cols"]');
            else
              $parent = $('table');
          }

          setTimeout(function(){
            $('a[href*="ads.php"], a[href*="book/index"], a[href*="libgen.me"], a[href*="bookzz.org"], a[href*="bookfi.net"]', $parent).each(function(){
              var $me = $(this),
                  href = $me.attr('href')
              ;
              $me.html(''
                +'<strong>'+$me.text()+'</strong>'
              );
              if( /ads\.php/.test(href) ){
                href = href.replace('ads.php', 'get.php');
                $me.attr('href', href);
                $me.on('click', function(e){
                  e.preventDefault();
                  $(this).addClass('opened');
                  window.open(this, href.replace(/\W/g,''));
                  return !1;
                });
              }
              else{
                $me.on('click', function(e){
                  e.preventDefault();
                  $(this).addClass('opened');
                  window.open(this, href);
                  return !1;
                });
              }
            });

            that.clog('Links healed');
          }, 10);
        };
        var cssString = ''
          +'a#mlink:link{color: #1a0dab;text-decoration:none;}'
          +'a#mlink:link>strong{font-weight:normal;}'
          +'a#mlink:hover{text-decoration:underline;}'
          +'a#mlink:visited,a#mlink.opened{color: #609;}'
          +'a#mlink:visited>strong,a#mlink.opened>strong{font-weight:bold;}'
        ;

        host = host.replace(/^w{3}\./, '');
        that.clog('host: '+host);
        that.clog('pathname: '+pathname);

        switch(host){
          case "libgen.io":
            that.clog('pathname='+pathname);
            if( /\/ads\.php/.test(pathname) ){
              btnDl = g('[href*="get.php?md5"]');
              if( btnDl )
                SimulateMouse(btnDl, "click", true);
              else
                that.clog('Missing download button')
            }
            else{

              that.injectBodyStyle(cssString);
              healLinks();
            }
          break;

          case "b-ok.org":
          case "en.bookfi.net":

            rows = gAll('.resItemBox');
            form = g('#searchForm');

            that.clog('Row count='+(rows && rows.length ? rows.length : 0));
            that.clog(rows);

            if( rows && rows.length == 1 ){

              if( btnDl = g('.ddownload', rows[0]) ){
                try{

                  if (href = btnDl.getAttribute('href'))
                    that.set_href(href);
                }catch(e){
                  
                  SimulateMouse(btnDl, "click", true);
                }
              }
              else
                that.clog('Missing download button');
            }
            else if(/\/book\/\w+/i.test(pathname) ){
              if( btnDl = xp('//a[contains(.,"ownloa") and contains(@href,"/dl/")]', null, true) ){
                try{

                  if (href = btnDl.getAttribute('href'))
                    that.set_href(href);
                }catch(e){
                  
                  SimulateMouse(btnDl, "click", true);
                }
              }
              else
                that.clog('Missing download button');
            }
          break;


          // gen.lib.rus.ec
          default:
            var unsupported = true;
            for(var i=0, iL=matchLoc.length; i<iL; i++){
              if( pathname.indexOf('/'+matchLoc[i]) !== -1 ){
                unsupported = false;
                break;
              }
            }

            if( unsupported ){
              that.clog('Exiting, location not supported, '+pathname);
              return !1
            }
            that.injectBodyStyle(cssString);
            healLinks();
          break;
        };
      }
    },

    filescdn: {
      rule: /filescdn\.com/,
      run: function(){
        var that  = this,
            btnDl = null,
            tform = null
        ;
        if( btnDl = g('#btn_download') ){

          tform = that.closest(btnDl, 'form');
          if( tform ){

            tform.submit()
          }
          else{

            SimulateMouse( btnDl, "click", true);
          }
        }
        else if( btnDl = xp('//a[(contains(.,"ownloa") and contains(.,"irect")) or contains(.,"eady!")]', null, true) ){

          SimulateMouse( btnDl, "click", true );
        }
        else{

          that.clog('Not download page')
        }
      }
    },

    uploadbank: {
      rule: /uploadbank\.com/,
      run: function(){
        var that     = this,
            cont     = g('#container'),
            recapcay = g('.g-recaptcha', cont),
            site_key = null,
            btnDl    = null
        ;

        if( recapcay ){
          site_key = recapcay.getAttribute('data-sitekey')

          if('function' === typeof $ && site_key){

            $(recapcay)
              .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));

            if( g('#maknyos-recaptcha') )
              that.clog('g-recaptcha tampered');
            else
              that.clog('tampering g-recaptcha FAILED');

            that.waitforit(function(){

              return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
            }, function(gr){
              
              gr.render("maknyos-recaptcha", {
                sitekey: site_key,
                callback: function(){ $("#downloadbtn").trigger("click") }
              });
            });
          }
          else{

            that.clog('Error: site_key or jQuery is not defined');
          }
        }
        else if( btnDl = g('#downloadbtn') ){

          SimulateMouse( btnDl, "click", true );
        }
        else if( btnDl = g('img[src*="downloadbutton"]') ){

          btnDl = btnDl.parentNode;
          SimulateMouse( btnDl, "click", true );
        }
        else{

          that.clog('Not download page or missing download button');
        }
      }
    },

    top4top: {
      rule: /top4top\.net/,
      run: function(){
        var that  = this,
            parent = g('#url'),
            btnDl = null, 
            scripts, inner, cucok, gotit
        ;
        if( parent ){
          btnDl = g('a', parent);
          scripts = document.getElementsByTagName( 'script' );
          gotit = !1;
          for( var i = 0; i < scripts.length; ++i ) {
            inner = scripts[i].innerHTML;
            if( !inner ) continue;
            if( inner.indexOf('timer') === -1 ) continue;

            if( cucok = /<a\shref=['"]([^'"]+)/.exec(inner) ){
              btnDl = document.createElement('a');
              btnDl.setAttribute('href', cucok[1]);

              gotit = true;
              setTimeout(function(){
                SimulateMouse( btnDl, "click", true );
              }, 100);
              break;
            }
          }
          // end: for

          if( !gotit )
          this.waitforit(function(){
            return g('.download', parent);
          }, function(el){
            btnDl = g('a', el);
            if( btnDl )
              SimulateMouse( btnDl, "click", true );
          }, 100);
        }
      }
    },

    dropme: {
      rule: /drop\.me/,
      run: function(){
        var that  = this;

        return this.waitforit(function(){

          return g('form[name="myFile"]');
        }, function(el){
          if( el )
            return el.submit();
        }, 100);
      }
    },

    dropapk: {
      rule: /dropapk\.com/,
      run: function(){
        var that  = this;

        if( g('div[id*="ez-downloa"]') || g('div[class*="gez-downloa"]') ){
        
          return that.waitforit(function(){
            var sel = '#downloadbtn',
                el  = null,
                daform = null
            ;

            if( !g(sel) ){
              if( g('img[src*="down_final.png"]') )
                sel = 'img[src*="down_final.png"]';
              else
                sel = '[type="submit"][name="method_free"]';
            }
            that.clog('sel='+sel);
            
            if( sel )
              return g(sel, null, true);
          }, function(el){
            var hid = null;

            if( el ) {
              if( el.nodeName == 'IMG' ){

                SimulateMouse(el.parentNode, "click", true);
              }
              else{

                if( el.nodeName == 'INPUT' ){
                  hid = document.createElement('input')
                  hid.setAttribute('type', 'hidden');
                  hid.setAttribute('name', el.getAttribute('name'));
                  hid.setAttribute('value', el.getAttribute('value'));
                }

                daform = that.closest(el, 'form');
                if( daform ){
                  if( hid )
                    daform.appendChild( hid );
                  daform.submit();
                }
                else{

                  SimulateMouse(el, "click", true);
                }
              }
            }
          }, 100);
        }
        else{

          that.clog('Not download page');
        }
      }
    },

    /**
     * Applied for these hosts:
     *  cloudyfiles.org
     *  suprafiles.org
     *  megadrive.co
     */
    suprafiles:{
      rule: /suprafiles\.org|cloudyfiles\.org|megadrive\.co/,
      run: function(){
        var that = this,
            btnDownload = g('[type="submit"][name="method_free"]',null,true),
            recapcay  = g('.g-recaptcha'),
            site_key = null,
            form = null,
            cont = null,
            lite_hostname = null,
            el   = null
        ;
        that.clog(recapcay);

        // # 1
        if( btnDownload ){
          that.clog('#1');

          that.trySumbit( btnDownload );
        }
        else{
          if( form = g('form[name="F1"]') ){
            // # 2
            that.clog('#2');

            if( recapcay ){
              site_key = recapcay.getAttribute('data-sitekey');
              that.clog('Recapcay found, site_key: '+site_key);

              $(recapcay)
                .replaceWith($('<div id="maknyos-recaptcha" data-sitekey="'+site_key+'"></div>'));

              // Incase of grecaptcha lib properly loaded
              setTimeout(function(){

                // recaptcha-rebuilder
                var scriptHandler = function(_site_key){
                  return (function(win, $){

                    if("undefined" !== typeof grecaptcha){
                      grecaptcha.render("maknyos-recaptcha", {
                        sitekey: "___SITEKEY___",
                        callback: function(){
                          var theform = document.querySelector('form[name=F1]');
                          if (theform)
                            theform.submit();
                        }
                      });
                    }
                    else{

                      console.log('grecaptcha undefined');
                    }
                  })(window, $);
                };
                scriptHandler = scriptHandler.toString();
                scriptHandler = scriptHandler.replace(/___SITEKEY___/, site_key);
                that.injectBodyScript(scriptHandler);
              }, 567);
            }
            else{
              that.clog('Recapcay not found, directly submitting..');

              form.submit();
            }
          }
          else{
            // # 3
            that.clog('#3');
            cont = g('#container');
            lite_hostname = (location.hostname+'').replace(/^w{3}\./,'');

            if( cont && (el = g('a[href*="'+lite_hostname+'"]', cont)) ){
              
              SimulateMouse(el, "click", true);
            }
            else{

              that.clog('Not download page');
            }
          }
        }
      }
    },

    publicopera: {
      rule: /public\.upera\.co/,
      run: function(){
        var that    = this, 
            section = g('.hbox'),
            anyform = null,
            btnDl   = null
        ;

        if( section ) {
          anyform = g('form');
            
          // # stage-1
          if( anyform ){

            anyform.submit();
          }

          // # stage-2
          else{
            btnDl = xp('//*[contains(@class,"btn") and contains(.,"ownloa")]', null, true);
            if( !btnDl ){
              btnDl = xp('.//a[contains(@href,"upera.co") and last()]', g('.panel', section), true);
            }
            
            if( btnDl )
              SimulateMouse(btnDl, "click", true);
          }
        }
        else{

          that.clog("Not a download page");
          return !1;
        }
      }
    },

    fileupload: {
      rule: /file-upload\.com/,
      run: function(){
        var that = this,
            recapcay  = g('.g-recaptcha'),
            site_key  = null,
            countdown = null,
            btnDl     = null,
            tform     = g('form[name=F1]'),
            cb_countdown = function(){}
        ;
        if( btnDl = g('[type="submit"][name="method_free"]', null, true) ){
          // # Stage 1

          that.trySumbit( btnDl );
        }
        else if( btnDl = g('#download-btn', tform) ){
          // # Stage 3

          SimulateMouse(btnDl, "click", true);
        }
        else{
          // # Stage 2

          $('#downloadbtn')
            .css('font-size', '2em');

          cb_countdown = function(){
            var btnDl_ = g('#downloadbtn', tform);

            if( recapcay ){
              
              that.waitforit(function(){

                return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
              }, function(gr){
                
                if (!$('#maknyos-recaptcha').html()){

                  gr.render("maknyos-recaptcha", {
                    sitekey: recapcay.getAttribute('data-sitekey'),
                    callback: function(){

                      return that.trySumbit( btnDl_ );
                    }
                  });
                }
                else{

                  that.trySumbit( btnDl_ );
                }
              });
            }
            else if( btnDl_ ){

              SimulateMouse( btnDl_, "click", true );
            }
            else{

              that.clog('Missing download button')
            }
          };


          // is there recapcay, early tampered dom g-recaptcha
          if( recapcay ){
            site_key = recapcay.getAttribute('data-sitekey')

            if('function' === typeof $ && site_key){

              $(recapcay)
                .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));

              if( g('#maknyos-recaptcha') )
                that.clog('g-recaptcha tampered');
              else
                that.clog('tampering g-recaptcha FAILED');

              that.waitforit(function(){

                return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
              }, function(gr){
                
                gr.render("maknyos-recaptcha", {
                  sitekey: site_key,
                  callback: function(){
                    $('#maknyos-recaptcha').attr('data-checked', !0);

                    var countdown_ = g('#countdown .seconds');
                    if (countdown_)
                    if ((parseInt(countdown_.textContent)-1) <= 0){

                      return cb_countdown();
                    }
                  }
                });
              });
            }
          }


          countdown = g('#countdown .seconds');
          if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
            countdown = Math.floor(countdown / 3);

            that.waitforit(function(){

              var cnt = g('#countdown .seconds');
              return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
            }, function(){
              
              cb_countdown();
            }, countdown * 1000);
          }
          else{

            // remove disabled
            if( btnDl = g('#downloadbtn', tform) ){
              btnDl.disabled = false;

              if( recapcay )
                cb_countdown();
              else
                that.trySumbit( btnDl );
            }

            if( !g('.page-wrap') ){

              that.clog('Not download page');
            }
          }
        }
      }
    },

    topddl: {
      rule: /topddl\.net/,
      run: function(){
        var that = this,
            btnDownload = g('#btn-download',null,true)
        ;
        if( btnDownload ){

          SimulateMouse(btnDownload, "click", true);
        }
        else if( (btnDownload = g('.btn.btn-success',null,true)) ){

          btnDownload.innerHTML = '<i class="fa fa-google"></i> Login to Download File..';
          try{
            $(btnDownload).removeClass('btn-success').addClass('btn-danger');
          }catch(e){}
        }
        else{

          that.clog('Button download not found, page may changed.');
        }
      }
    },

    douploads: {
      rule: /douploads\.com/,
      run: function(){
        var that = this,
            btnCheck  = null,
            btnDl     = null,
            countdown = g('#countdown'),
            cb_countdown = function(){}
        ;
        if( btnDl = g('#downloadbtn') ){
          if( btnCheck = g('#chkIsAdd') )
            btnCheck.checked = false;

          cb_countdown = function(){
            tform = that.closest(btnDl, 'form');
            if( tform ){

              tform.submit()
            }
            else{

              SimulateMouse( btnDl, "click", true);
            }
          };

          countdown = g('#countdown .seconds');
          if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
            countdown = Math.floor(countdown / 3);

            that.waitforit(function(){

              var cnt = g('#countdown .seconds');
              return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
            }, function(){
              
              cb_countdown();
            }, countdown * 1000);
          }
          else{

            cb_countdown()
          }
        }
        else if( btnDl = g('#direct_link a[href*="douploads.com"]') ){

          SimulateMouse( btnDl, "click", true );
        }
        else{

          if( g('.directlinkpage') || g('.downloadfile1') )
            that.clog('missing download button')
          else
            that.clog('Not download page')
        }
      }
    },

    dfpan: {
      rule: /dfpan\.com/,
      noBaseClean: true,
      run: function(){
        var that = this,
            el        = null,
            tform     = null,
            wrap      = null,
            vth       = null,
            btnDl     = null,
            waitFor   = !1,
            unit      = '',
            interval  = g('#interval_div')
        ;
        that.killframes();
        that.killevents(null, 'mousedown');

        if( btnDl = g('#inputDownWait>.slow_button') ){

          if( !that.isVisible(interval) ){

            that.clog(btnDl);
            SimulateMouse( btnDl, "click", true );

            setTimeout(function(){
              vth = g('#vcode_th');
              if( vth && that.isVisible(vth) ){
                if( wrap = g('td>div', vth) ){
                  el = document.createElement('p');
                  el.style.color = '#d00';
                  el.innerHTML = 'Press ENTER to continue<br/><small>You may need to wait 30 seconds before download started</small>';
                  wrap.appendChild( el );
                }

                setTimeout(function(){
                  g('[type=text]', vth).focus();
                }, 0);
                btnDl.style.backgroundColor = '#3b8ccc';
              }
              else{

                that.clog('vcode is not visible');
              }

            }, 567);
          }
          else{
            that.clog('Download interupted with interval');
            btnDl.disabled = "disabled";

            if( waitFor = g('#down_interval_tag') ){
              unit = waitFor.parentNode.textContent.trim();
              unit = unit.replace(/\s*/g,'');
              unit = unit.replace(/\d+-/g,'');

              waitFor = parseInt( waitFor.textContent );
              if( /minut/.test(unit) )
                waitFor = (waitFor * 60);
              else if( /hour/.test(unit) )
                waitFor = (waitFor * 60 * 60);

              waitFor = (waitFor + 3);

              this.waitforit(function(){
                var int = g('#interval_div');
                return that.isVisible(int) ? !1 : true;
              }, function(){
                
                location.href = location.href;
              }, waitFor * 1000);
            }
          }
        }
        else if( btnDl = g('#downbtn > a:first-child') ){

          SimulateMouse( btnDl, "click", true );
        }
        else{

          that.clog('Not download page or missing download button')
        }
      }
    },

    yimuhe: {
      rule: /yimuhe\.com/,
      noBaseClean: true,
      run: function(){
        var that  = this,
            el    = null,
            el_ch = null,
            tform = null,
            btnDl = null
        ;
        that.killframes();
        that.killevents(null, 'mousedown');

        if( g('.sharp .w630') ){
          if( btnDl = g('a[href*=down-]', g('.sharp .w630')) ){

            SimulateMouse( btnDl, "click", true );
          }
          else{

            that.clog('Missing download button');
          }
        }
        else if( g('.sharp .w632') ){
          if( el = g('#download') )
            el.style.backgroundColor = '#f0f0f0';

          if( btnDl = gAll('.download>a') ){
            btnDl = btnDl[0];

            btnDl.style.backgroundColor = '#ccc';
            btnDl.style.borderColor = '#999';
            btnDl.style.verticalAlign = 'top';
            btnDl.style.position = 'relative';
            btnDl.style.display = 'inline-block';
            btnDl.setAttribute('title', 'DOWNLOAD');

            el_ch = document.createElement('abbr');
            el_ch.style.position = 'absolute';
            el_ch.style.left = '0';
            el_ch.style.bottom = '0';
            el_ch.style.width = '100%';
            el_ch.style.backgroundColor = 'rgba(60, 132, 137, 0.98)';
            el_ch.style.color = '#fff';
            el_ch.style.lineHeight = '1.2';
            el_ch.innerText = 'DOWNLOAD';
            btnDl.appendChild(el_ch);
          }

          el = g('#loading');
          if( el && that.isVisible(el) ){
            var wrap_waitfor = function(btn){
              that.clog('inside wrap_waitfor..');
              that.waitforit(function(){
                var dl = g('#download');
                return (that.isVisible(dl) ? true : !1);
              }, function(){
                that.clog('inside callbak of wrap_waitfor');
                that.clog(btn);

                
                SimulateMouse( btn, "click", true );
              });
            };

            that.waitforit(function(){
              var el_ = g('#loading');
              return (el_ && that.isVisible(el_) ? !1 : g('.yzm #code'));
            }, function(el__){

              if( el__ ){
                if('undefined' != typeof $){
                  $(el__).on('keydown', function(e){
                    that.clog('keydown='+$(this).val()+'; e.keyCode='+e.keyCode);
                    if( e.keyCode === 13 && btnDl )
                      wrap_waitfor(btnDl);
                  });
                }
                setTimeout(function(){
                  el__.focus();
                }, 0);
              }
              else{
                that.clog('Missing input code');
                if( tform = g('form', g('.yzm')) )
                  tform.submit();
              }
            }, 567);
          }
          else{

            that.clog('throbber element not found, page may changed');
          }
        }
        else if( /\/n_dd\.php/.test(location.pathname) ){
          if( btnDl = g('#downs') ){

            btnDl.innerText = 'DOWNLOAD';
            if('function' === typeof $){

              $('.kuan, .ggao').css('visibility', 'hidden');
              btnDl.style.position = 'absolute';
              btnDl.style.zIndex = '999999';
              btnDl.style.display = 'block';
              btnDl.style.fontSize = '2.5em';
              btnDl.style.lineHeight = '2em';
            }

            setTimeout(function(){
              SimulateMouse( btnDl, "click", true );
            }, 123);
          }
          else{

            that.clog('Missing download button');
          }
        }
        else{

          that.clog('Not download page');
        }
      }
    },

    // alias for: linkbucks?
    jzrputtbut: {
      rule: /jzrputtbut\.net/,
      noBaseClean: true,
      run: function(){
        var that  = this;
        that.killevents(null, 'mousedown');

        // iframe handler
        var o = document.getElementsByTagName('iframe');
        for(var i=o.length-1; i>=0; i--){
          o[i].style.position = 'absolute';
          o[i].style.left = '-999999px';
          o[i].style.top = '-999999px';
        }

        that.waitforit(function(){
          var timer = g('#timer');
          return (that.isVisible(timer) ? !1 : g('#skiplink'));
        }, function(el){
          if( el )
            SimulateMouse( el, "click", true );
        }, 100);
      }
    },

    up4ever: {
      rule: /up-4ever\.com/,
      noBaseClean: true,
      run: function(){
        var that     = this,
            recapcay = g('.g-recaptcha'),
            site_key = null,
            btnDl    = null,
            el       = null,
            hs       = null,
            countdown = null,
            cb_countdown = function(){}
        ;
        setTimeout(function(){
          $('#adblock_detected').val(0);
          $("#hiddensection").show();
        }, 1555);


        el = g('#hiddensection2');
        if( el )
          el.parentNode.removeChild(el);

        if( btnDl = g('[type="submit"][name="method_free"]', null, true) ){
          // # Stage 1

          that.trySumbit( btnDl );
        }
        else if( btnDl = g('#btn_downloadLink') ){
          // # Stage 3

          that.killframes();
          this.killevents(null, 'click');
          SimulateMouse(btnDl, "click", true);
        }
        else{
          // # Stage 2
          hs = g('#hiddensection');
          
          cb_countdown = function(){
            $(hs).show();
            if( recapcay ){
              
              that.waitforit(function(){

                return ('undefined' == typeof grecaptcha ? !1 : grecaptcha);
              }, function(gr){


                $('.alert-waiting').remove();
                gr.render("maknyos-recaptcha", {
                  sitekey: recapcay.getAttribute('data-sitekey'),
                  callback: function(){ $("#downloadbtn").trigger("click") }
                });

                var btnDl_ = g('#downloadbtn');
                if( btnDl_ && 'undefined' != typeof $)
                  $(btnDl_).prev().remove();
              });
            }
            else if( btnDl = g('#downloadbtn') ){

              SimulateMouse( btnDl, "click", true );
            }
            else{

              that.clog('Missing download button')
            }
          };


          // is there recapcay, early tampered dom g-recaptcha
          if( recapcay ){
            site_key = recapcay.getAttribute('data-sitekey')

            if( site_key ){

              $(recapcay)
                .replaceWith($('<div id="maknyos-recaptcha" data-bijikuda="1" data-sitekey="'+site_key+'"></div>'));
              $(hs).prev().replaceWith($('<div class="alert alert-success alert-waiting"><h3 style="text-align:center;">Wait For it...</h3></div>'));

              if( g('#maknyos-recaptcha') )
                that.clog('g-recaptcha tampered');
              else
                that.clog('tampering g-recaptcha FAILED');
            }
          }

          $(hs).show();
          countdown = g('#countdown .seconds');
          if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
            countdown = Math.floor(countdown / 3);

            that.waitforit(function(){

              that.killframes();
              $(hs).show();
              var cnt = g('#countdown .seconds');
              return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
            }, function(){

              cb_countdown();
            }, countdown * 1000);
          }
          else{
            that.clog('countdown not found.');

            // remove disabled
            if( btnDl = g('#downloadbtn') ){
              btnDl.disabled = false;

              if( recapcay )
                cb_countdown();
              else
                SimulateMouse(btnDl, "click", true);
            }
            else{

              that.clog('Not download page');
            }
          }
        }
        // end: stage-2
      }
    },

    '3rbup': {
      rule: /\b3rbup\.com/,
      run: function(){
        var that      = this,
            btnDl     = null,
            countdown = null,
            cdown_sel = '.download-timer-seconds',
            dltimer   = g('.download-timer')
        ;

        if( dltimer ){
          if( countdown = g(cdown_sel) ){
            that.waitforit(function(){
              var eltimer = g(cdown_sel);

              return (eltimer ? !1 : g('.btn', dltimer));
            }, function(link){

              if( link.getAttribute('href') ){

                that.set_href( link.getAttribute('href') );
              }
              else{

                SimulateMouse(btn, "click", true);
              }
            });
          }
          else if( btnDl = g('.btn', dltimer) ){

            SimulateMouse(btnDl, "click", true);
          }
          else{

            that.clog('Not download page');
          }
        }
        else if( btnDl = g('a[href*="download_token"]') ){

          SimulateMouse(btnDl, "click", true);
        }
        else{

          that.clog('Missing download link');
        }
      }
    },

    megadrive: {
      rule: /megadrive\.co/,
      run: function(){
        var that  = this,
            btnDl = g('[type="submit"][name="method_free"]', null, true)
        ;

        // # 1
        if( btnDl ){

          that.trySumbit( btnDl );
        }
        else if( btnDl = g('#downloadbtn') ){

          that.trySumbit( btnDl );
        }
        else{

          that.clog('Not download page or missing download button');
        }
      }
    },

    samaupcom: {
      rule: /samaup\.com/,
      run: function(){
        var that  = this,
            btnCheck  = null,
            btnDl     = null,
            countdown = g('#countdown'),
            cb_countdown = function(){}
        ;
        if( btnDl = g('#downloadbtn') ){
          if( btnCheck = g('#chkIsAdd') )
            btnCheck.checked = false;

          cb_countdown = function(){
            tform = that.closest(btnDl, 'form');
            if( tform ){

              tform.submit()
            }
            else{

              SimulateMouse( btnDl, "click", true);
            }
          };

          countdown = g('#countdown .seconds');
          if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
            countdown = Math.floor(countdown / 3);

            that.waitforit(function(){

              var cnt = g('#countdown .seconds');
              return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
            }, function(){
              
              cb_countdown();
            }, countdown * 1000);
          }
          else{

            cb_countdown()
          }
        }
        else if( btnDl = g('.downloadbtn a[href*="samaup.com"]') ){

          SimulateMouse( btnDl, "click", true );
        }
        else{

          that.clog('Not download page OR missing download button')
        }
      }
    },

    akoam: {
      rule: /ako\.am/,
      run: function(){
        var that  = this,
            url   = that.get_href(),
            pdata = {},
            parDT = null,
            dlGotIt = null
        ;

        if( parDT = g('.download_timer') ){

          // which-ever done earlier, try xhr first
          $.post(url, pdata, function(ret){
            if( ret ){
              try{

                ret = JSON.parse(ret);
              }catch(e){
                that.clog('Fail parsing JSON');
              }
            }

            if( ret && ret.direct_link ){
              dlGotIt = true;
              var $el = $('<a '+(ret.hash_data ? 'hash-data="'+ret.hash_data+'"':'')+' class="download_buttonX" style="color: #ff0000; border: 5px solid #ff0000;" href="'+ret.direct_link+'">DOWNLOAD</a>');

              $('<div id="wrapfdl" style="position:absolute; top: 0; left:0; color: #ddd; background-color:rgba(34, 34, 34, 0.89); padding: 10px 0; text-align: center; width: 100%;"></div>')
                .appendTo( $(parDT) );
              $('#wrapfdl').html( $el );

              $el = $('#wrapfdl').find('.download_buttonX');
              if( $el.length )
                SimulateMouse($el.get(0) , "click", true );
            }
            else{
              that.clog('XHR Failed.')
              that.clog(ret);
            }
          });

          // inline we keep on waiting..
          that.waitforit(function(){

            var btn = g('#timerHolder .download_button');
            return btn ? btn : null;
          }, function(el){
            
            if( !dlGotIt )
              SimulateMouse( el, "click", true );
          }, 1000);
        }
        else{

          that.clog('Not download page, or missing element: .download_timer');
        }
      }
    },

    rapidgator: {
      rule: /rapidgator\.net/,
      run: function(){
        var that  = this,
            el    = null,
            dlBtn = null
        ;
        if( el = g('.btn-free.link') ){

          SimulateMouse( el, "click", true );
        }
        else if( dlBtn = g('.btn-download') ){

          SimulateMouse( dlBtn, "click", true );
        }
        else{

          that.clog('Missing download button');
        }
      }
    },

    filefactory: {
      rule: /filefactory\.com/,
      run: function(){
        var that  = this,
            el    = null,
            delay = 0,
            dlBtn = null
        ;
        if( el = g('#file-download-free-action-slow') ){
          delay = parseInt( g('#countdown_clock').getAttribute('data-delay') );
          SimulateMouse( el, "click", true );
          if( delay ){
            setTimeout(function(){
              // inline we keep on waiting..
              that.waitforit(function(){

                var btn = g('#file-download-free-action-start');
                return btn ? btn : null;
              }, function(el){
                
                SimulateMouse( el, "click", true );
              }, 1000);

            }, delay * 1000);
          }
          else if( dlBtn = g('#file-download-free-action-start') ){

            SimulateMouse( dlBtn, "click", true );
          }
          else{

            that.clog('Missing download button');
          }
        }
        else{
          // #file-download-free-action-start
          that.clog('Missing download button');
        }
      }
    },

    dlfree: {
      rule: /dl\.free\.fr/,
      run: function(){
        var that  = this,
            el    = g('.form-button')
        ;
        if( el ){

          that.trySumbit( el );
        }
        else{

          that.clog('Missing download button');
        }
      }
    },

    '4shared':{
      rule: /4shared\.com/,
      run: function(){
        var that  = this,
            el    = null,
            rgx   = /^\/(\w+)\//,
            cucok = rgx.exec(location.pathname),
            url   = that.get_href()
        ;
        if( !(cucok && cucok.length > 1) )
          return !1;

        if( cucok[1] == 'folder' ){
          that.clog('Do nothing on folder page');
          return !1;
        }

        if( cucok[1] != 'get' ){
          rgx = new RegExp("^/"+cucok[1]+"/");
          url = location.pathname.replace(rgx, "/get/");
          url = location.protocol+'//'+location.hostname+url;
          that.set_href( url );
          return !1;
        }

        // Good-togo
        if( el = g('.freeDownloadButton') ){

          that.trySumbit( el );
          setTimeout(function(){
            if( g('.p_window') && document.hidden )
              alert('Please login to continue download');
          }, 456);
        }
        else{

          that.clog('Not a download page or missing download button');
        }
      }
    },

    bdnupload: {
      rule: /bdnupload\.com/,
      run: function(){
        var that  = this,
            btnDl = null,
            pSel = g('#pSel'),
            host = location.hostname,
            wrapper = 'b'
        ;

        that.hidefixed();

        if( btnDl = g('[type="submit"][name="method_free"]',null,true) ){

          that.trySumbit( btnDl );
        }
        else if( xp('//'+wrapper+'[contains(text(),"Link Generated")]', pSel, true) ){

          host = host.replace(/^w{3}\./, '');
          btnDl = g('a[href*=".'+host+'"]')

          if (!btnDl)
            btnDl = g('#direct_link>a');

          if( btnDl ){

            that.trySumbit( btnDl );
          }
          else{

            that.clog('Missing download button');
          }
        }
        else if( btnDl = g('#btn_download,#downloadbtn') ){

          that.trySumbit( btnDl );
        }
        else{
          
          that.clog('Not download page or missing download button');
        }


        // if( btnDl = g('#downloadbtn') ){

        //   cb_countdown = function(){
        //     that.trySumbit( btnDl );
        //   };

        //   countdown = g('#countdown .seconds');
        //   if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
        //     countdown = Math.floor(countdown / 3);

        //     that.waitforit(function(){

        //       var cnt = g('#countdown .seconds');
        //       return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
        //     }, function(){
              
        //       cb_countdown();
        //     }, countdown * 1000);
        //   }
        //   else{

        //     cb_countdown()
        //   }
        // }
        // else if( btnDl = g('img[alt*="o Download"]') ){
          
        //   SimulateMouse( btnDl.parentNode, "click", true );
        // }
        // else{

        //   that.clog('Not download page OR missing download button')
        // }
      }
    },

    '9xupload': {
      rule: /9xupload\.me/,
      run: function(){
        var that  = this,
            btnDl = null,
            par = g('#container>table')
        ;
        if( btnDl = g('#downloadbtn') ){

          that.trySumbit( btnDl );
        }
        else if( xp('//*[contains(text(),"d Link Generated")]', g('table', par), true) ){
          if( btnDl = g('a[href*=".'+location.hostname+'"]', par) ){

            that.trySumbit( btnDl );
          }
          else{
            that.clog('Missing download button');
          }
        }
        else{
          
          that.clog('Not download page or Missing download button');
        }
      }
    },

    indishare: {
      rule: /indishare\.me/,
      run: function(){
        var that  = this,
            btnDl = null,
            elxp  = null,
            countdown = 0,
            par = g('.content_mdl'),
            cb_countdown = function(){}
        ;
        that.hidefixed();

        if( btnDl = g('#btn_download') ){
          cb_countdown = function(){

            that.trySumbit( btnDl );
          };

          countdown = g('#countdown_str span');
          if( countdown && (countdown = (parseInt(countdown.textContent)-1) ) ){
            countdown = Math.floor(countdown / 3);

            that.waitforit(function(){

              var cnt = g('#countdown_str span');
              return ((parseInt(cnt.textContent)-1) > 0 ? !1 : true);
            }, function(){
              
              cb_countdown();
            }, countdown * 1000);
          }
          else{

            setTimeout(function(){
              cb_countdown()
            }, 5 * 1000);
          }
        }
        else if( par && (elxp = xp('//h1[contains(text(),"Link Generated")]', par, true)) ){
          if( btnDl = g('a>img[src*="'+location.hostname+'"]', elxp.parentNode) ){

            btnDl = btnDl.parentNode;
            that.trySumbit( btnDl );
          }
          else{
            that.clog('Missing download button');
          }
        }
        else{
          
          that.clog('Not download page or Missing download button');
        }
      }
    },

    minhatecacom: {
      rule: /minhateca\.com\.br/,
      run: function(){
        var that  = this,
            btnDl = null,
            wrapper  = g('#fileDetails')
        ;
        if( !wrapper ){
          that.clog('Not download page');
          return !1;
        }

        // Good togo
        if( (btnDl = g('.greenActionButton', wrapper)) ){

          // doin xhr
          var pdata = {},
              el  = null,
              url = location.protocol+'//'+location.hostname+'/action/License/Download',
              tokenfield = '__RequestVerificationToken',
              defaultAct = function(button){

                SimulateMouse(button, "click", true); 
              }
          ;
          if( el = g('[name="'+tokenfield+'"]') ) {

            pdata[tokenfield] = el.value;
            if( el = g('[name="FileId"]') )
              pdata.fileId = el.value;

            $.post(url, pdata, function(ret){
              that.clog(ret);

              if( ret && ret.redirectUrl ){

                setTimeout(function(){

                  that.frameload( ret.redirectUrl );
                }, 1324);
              }
              else{

                that.clog('Bad response of XHR, failing over...');
                defaultAct(btnDl);
              }
            });
          }
          else{
            that.clog('Mehh, failover. just do click button');
            defaultAct(btnDl);
          }
        }
        else{

          that.clog('Missing download button');
        }
      }
    },

    clicknuploadorg: {
      rule: /clicknupload\.org/,
      noBaseClean: true,
      run: function(){
        var that  = this,
            btnDl = g('[type="submit"][name="method_free"]',null,true),
            parent = null,
            cucok = null
        ;

        if( btnDl ){

          that.trySumbit( btnDl );
        }
        else if( btnDl = g('#downloadbtn') ){

          parent = btnDl.parentNode;
          if( parent.nodeName == 'FORM' ){

            that.trySumbit( btnDl );
          }
          else{
            if( !/https?\:/.test(btnDl.getAttribute('href')) && btnDl.getAttribute('onClick') ){
              if( cucok = /(https?\:[^\'\"]+)/.exec(btnDl.getAttribute('onClick')) ){
                
                that.set_href( cucok[1] );
              }
              else{

                that.clog('Something went wrong while getting download link');
              }
            }
            else{

              SimulateMouse( btnDl, "click", true );
            }
          }
        }
        else{

          that.clog('Not downlaod page');
        }
      }
    }
  };
  // end of patterns


  var MNy = new MaknyosHelper(document.baseURI);
  MNy.matchDomain().matchAction().invokeAction();

  // lil-helpers
  function isDefined(x) { return!(x == null && x !== null) }
  function isUndefined(x) { return x == null && x !== null }
  function SimulateMouse(elem, event, preventDef, prefilter) {
    if(typeof elem != "object")
      return;

    // is it an a element? try with iframe loader
    var is_error = null,
      href = (elem && elem.getAttribute ? elem.getAttribute("href") : null);

    // make sure it's link, not some sumthin like: "javascript:;"
    if( href && /^((?:(?:ht|f)tps?\:\/\/){1}\S+)/.test(href) ){
      try{
        if('function' == typeof prefilter)
          href = prefilter( href );

        if( typeof href === "string" && href ){

          // is the direct-link is not Mixed Content with https of parent location
          var rgx = new RegExp("^"+location.protocol);
          if( !rgx.test(href) ){

            is_error = true;
          }
          else{

            MNy.action.clog("SimulateMouse trying href loaded to iFrame");
            MNy.action.frameload(href);
            is_error = false;
          }
        }
        else{

          if( href )
            is_error = false;
          else
            is_error = true;
        }
      }catch(e){ is_error = true }
    }
    else{
      MNy.action.clog("Element is either not link or invalid format. href="+href);
    }
    

    // failover, just click dat button
    if( is_error || is_error === null ){
      MNy.action.clog("SimulateMouse-click with MouseEvents");
      var evObj = document.createEvent("MouseEvents");
      preventDef = isDefined(preventDef) && preventDef ? true : false;
      evObj.initEvent(event, preventDef, true);
      try {
        elem.dispatchEvent(evObj)
      }catch(e) {}
    }
  }
  function getParameterByName(name, the_url) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    if( isUndefined(the_url) )
      the_url = location.search;
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
     results = regex.exec(the_url);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  }
  function g(x, par){
    !par && (par = document);
    return ('string' == typeof x ? par.querySelector(x) : x);
  }
  function gAll(x, par){
    !par && (par = document);
    return ('string' == typeof x ? par.querySelectorAll(x) : x);
  }
  function xp(q, root, single) {
    if(root && typeof root == "string") {
      root = $D(root, null, true);
      if(!root) {
        return null
      }
    }
    if(!q) {
      return false
    }
    if(typeof q == "object") {
      return q
    }
    root = root || document;
    if(q[0] == "#") {
      return root.getElementById(q.substr(1));
    }else {
      if(q[0] == "/" || q[0] == "." && q[1] == "/") {
        if(single) {
          return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
        }
        return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
      }else {
        if(q[0] == ".") {
          return root.getElementsByClassName(q.substr(1))
        }
      }
    }
    return root.getElementsByTagName(q)
  }
})();
/* eof. */