String.prototype.capitalize = function() {
  return this.slice(0,1).toUpperCase() + this.slice(1);
};

String.prototype.escape_html = function() {
  this.replace(/&/g, '&amp;'); 
  this.replace(/"/g, '&quot;'); 
  this.replace(/>/g, '&gt;'); 
  this.replace(/</g, '&lt;'); 
  return this;
};


(function () { 

    Astrology.activate_runners = function () {
        var template = Astrology.templates[Astrology.controller][Astrology.action];
        var blocks = template.blocks;
        var mixins = template.mixins;
        for (var i = 0; i < blocks.length; i = i + 1) {
            Astrology.runners.blocks[blocks[i]](); 
        }
        for (var j = 0; j < mixins.length; j = j + 1) {
            Astrology.runners.mixins[mixins[j]](); 
        } 
    };

})();
// This lib implements Omniture tracking. Just usual wrapper around iv_doTracking.
(function() { 

  Astrology.tracking = function(tracking_code) {
    iv_doTracking(tracking_code, '', 's_iv.eVar13');
  };

})();


// This lib moves ads banners to their correct place. <script> tags are not moved.
(function ($) { 

    function generate_src_for_iframe_banner(iframe, ord) {
        var src = iframe.src;
        var src_with_updated_ord = src.replace(/ord=\d+/, 'ord=' + ord);
        return src_with_updated_ord;
    }


    Astrology.move_banner = function (placement, source) {
        $(placement).append($(source).children().not('script'));
    };


    Astrology.move_iframe_banner = function (placement, source) {
        var placement_dom = $(placement);
        var iframe = $(source + " iframe");
        var ad_image = iframe.contents().find(source).children().not("script").clone();
        placement_dom.append(ad_image);
        //$(placement).append($(source + " iframe").contents().find(source).children().not("script").clone());
        // Sometimes ads add additional elements near iframe, we need to move them too
        $(placement).append($(source).children().not("iframe"));
    };

    Astrology.clear_banner = function (name) {
        $('.b-ads_' + name).empty();
    };

    Astrology.refresh_the_banner = function (name, ord) {
        var iframe = $('#mps_banners_' + name + ' iframe');
        iframe.get(0).src = generate_src_for_iframe_banner(iframe.get(0), ord);
        iframe.load(function () {
            Astrology.clear_banner(name);
            Astrology.move_iframe_banner('.b-ads_' + name, '#mps_banners_' + name);
        });
    };

    Astrology.refresh_banners = function () {
        // Ord should be random 10-digits number, same for all banners on the page
        // and it should be changed after every page reloading
        var ord = Math.floor(Math.random() * 10000000000);
        if (Astrology.delayed_banners) {
            $(".mps_banners").each(function () {
                var banner = this.id.match(/mps_banners_([\w_]+)/)[1];
                Astrology.refresh_the_banner(banner, ord);
            });
        } else {
            $(".b-ads_iframe").each(function () {
                this.src = generate_src_for_iframe_banner(this, ord);
            });
        }
        Astrology.update_omniture();
    };


})(jQuery);

// Implements API for storing data into cookie. Usage:
//
// == In Javascript:
//
// var foo = Astrology.cookies.data.foo;   // get value 
// Astrology.cookies.data.foo = 'bar';     // set value 
// Astrology.cookies.save();               // Save value after setting (otherwise, it just will be 
//                                         // stay in 'data' property, but not in cookie)
// Astrology.cookies.init();               // Reload all data from cookie to 'data' property
//
// == In Ruby (in controller):
//
// result = json_cookies        // get values (Astrology.cookies.data)
// result['foo'] = 'bar'        // set values
// self.json_cookies = result   // Save value after setting
;(function($) {

  Astrology.cookies = {
    _defaults: {
      expires_in: 360 * 10,
      domain: ".astrology.com",
      path: '/'
    },
    
    data: {},

    init: function() {
      // Clear old cookies, when we set them on current domain (e.g., 'www.astrology.com') instead of
      // '.astrology.com'. It is set at 07.04.2010, we can remove this after some period
      document.cookie = 'json_cookies=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
      // .*? - lazy algorithm
      var cookie_match = document.cookie.match(/json_cookies=(.*?)(;|$)/);
      if(cookie_match) {
        var json_data = cookie_match[1];
        // Use double encoding and decoding, because Rails inserts unescaped '+' instead
        // of escaped symbol when jsoning value, and decodeURIComponent doesn't
        // decode this '+'. But if we apply additional URI encoding on Rails-side before
        // jsoning, it encodes correctly. So, this is just hack.
        this.data = $.parseJSON(decodeURIComponent(decodeURIComponent(json_data)));
      };
    },

    // Options is optional hash with parameters:
    //   * expires_in: default is 3600 days
    //   * path: default is '/'
    //   * domain: default is '.astrology.com'
    save: function(given_options) {
      var options = $.extend({}, this._defaults, given_options);
      var expiration_date = new Date();
      expiration_date.setDate(expiration_date.getDate() + options.expires_in);
      var expiration_date = expiration_date.toUTCString();
      document.cookie = 'json_cookies=' + encodeURIComponent(encodeURIComponent($.toJSON(this.data))) + '; expires=' + expiration_date + '; path=' + options.path + '; domain=' + options.domain;
    }
  };

  Astrology.cookies.init();
 
})(jQuery);
/*global iv_setBusinessProps */
(function () { 

    Astrology.update_omniture = function () {
        iv_setBusinessProps();
    };

})();

/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
* 
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* hoverIntent is currently available for use in all personal or commercial 
* projects under both MIT and GPL licenses. This means that you can choose 
* the license that best suits your project, and use it accordingly.
* 
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
* 
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*	sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
*	interval: 100,   // number = milliseconds of polling interval
*	over: showNav,  // function = onMouseOver callback (required)
*	timeout: 0,   // number = milliseconds delay before onMouseOut function call
*	out: hideNav    // function = onMouseOut callback (required)
* });
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($) {
	$.fn.hoverIntent = function(f,g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? { over: f, out: g } : f );

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).unbind("mousemove",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

			// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	};
})(jQuery); 
(function() {

  Astrology.templates = {
    'sessions': {
      'new': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'cacheclear': {
      'index': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'singles': {
      'solutions_inventory': {
        mixins: [  ],
        blocks: [ 'astro_header' ]
      }
    },
    'quizzes': {
      'show': {
        mixins: [ 'tracking', 'tabs', 'clear_inputs' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'quiz' ]
      }
    },
    'search': {
      'index': {
        mixins: [ 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'details': {
      'article': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'validations', 'max_length' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'comments' ]
      },
      'love_match': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'tarot': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'signs': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'match_com' ]
      },
      'horoscopes': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'video_horoscope' ]
      },
      'authors': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'yearly': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'video_horoscope' ]
      }
    },
    'products': {
      'show': {
        mixins: [ 'clear_inputs', 'tabs', 'validations', 'tracking', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'profile_product' ]
      },
      'index': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'topic': {
      'work_money': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'validations' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'love_sex': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'validations' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'love_match', 'match_com' ]
      },
      'mind_body': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'validations' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'home_family': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'validations' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'dreams': {
      'letters': {
        mixins: [ 'tabs', 'clear_inputs', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'dreams_search' ]
      },
      'categories': {
        mixins: [ 'tabs', 'clear_inputs', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'dreams_search' ]
      },
      'show': {
        mixins: [ 'tabs', 'clear_inputs', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'dreams_search' ]
      },
      'index': {
        mixins: [ 'tabs', 'clear_inputs', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'dreams_search' ]
      }
    },
    'match_com': {
      'index': {
        mixins: [ 'validations' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'match_com' ]
      }
    },
    'chartwheel': {
      'index': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice', 'chartwheel_example' ]
      }
    },
    'horoscopes': {
      'show': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'video_horoscope', 'match_com' ]
      },
      'index': {
        mixins: [ 'tabs', 'validations', 'poll_form', 'clear_inputs', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'horoscopes_horoscopes', 'scopes_slider', 'game_fortune', 'chartwheel', 'match_com' ]
      }
    },
    'users': {
      'new': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'forgot': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'reset': {
        mixins: [  ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'psychics': {
      'index': {
        mixins: [ 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'psychics_categories', 'psychics_listings' ]
      }
    },
    'slideshows': {
      'show': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'slideshow' ]
      }
    },
    'syndications': {
      'twitter': {
        mixins: [ 'tabs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'syndication_twitter' ]
      },
      'widgets': {
        mixins: [ 'tabs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'mobile': {
        mixins: [ 'tabs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'rss': {
        mixins: [ 'tabs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      }
    },
    'divination': {
      'mayan': {
        mixins: [ 'tabs', 'validations', 'poll_buttons', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'popup_birthdate_changer', 'hero' ]
      },
      'fengshui': {
        mixins: [ 'tabs', 'validations', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'popup_birthdate_changer', 'hero', 'bagua_board' ]
      },
      'zener_cards': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice' ]
      },
      'tarot': {
        mixins: [ 'tabs', 'validations', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune' ]
      },
      'chinese': {
        mixins: [ 'tabs', 'validations', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'popup_birthdate_changer', 'hero', 'love_match' ]
      },
      'vedic': {
        mixins: [ 'tabs', 'validations', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'popup_birthdate_changer', 'love_match', 'hero' ]
      },
      'numerology': {
        mixins: [ 'tabs', 'validations', 'clear_inputs', 'tracking' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_balloon', 'popup_birthdate_changer', 'hero' ]
      }
    },
    'home': {
      'index_translate': {
        mixins: [ 'clear_inputs', 'tabs', 'validations', 'poll_buttons', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'mood_meter', 'popup_birthdate_changer', 'wheel' ]
      },
      'index': {
        mixins: [ 'clear_inputs', 'tabs', 'validations', 'poll_buttons', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'game_fortune', 'mood_meter', 'popup_birthdate_changer', 'wheel' ]
      }
    },
    'archives': {
      'index': {
        mixins: [ 'tabs' ],
        blocks: [ 'astro_header', 'archives' ]
      }
    },
    'blogs': {
      'show': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'redirector' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'blogs_navigation' ]
      },
      'index': {
        mixins: [ 'tabs', 'clear_inputs', 'tracking', 'tooltip' ],
        blocks: [ 'astro_header', 'hat', 'notice', 'blogs_carousel', 'blogs_navigation' ]
      }
    }
  };

})();
// This lib adds omniture tracking function to jQuery namespace. There are 2 methods
// jQuery.m_tracking
// jQuery.fn.m_tracking
// 
// First one is used in other JS scripts, e.g. when we need to track moving of slider.
// Second one is used for tracking clicks not in JS, applying to different blocks.
;Astrology.runners.mixins.tracking = function() {
  jQuery('.m-tracking').m_tracking();
};

(function($) {
  
  var classes = {
    self: 'm-tracking',
    target: 'm-tracking_target',
    code: 'm-tracking_code'
  };
  
  // Tries to find tracking code within given block
  // and send it to Omniture tracking function.
  $.m_tracking = function(block, text) {
    text = text || block.find('.' + classes.code).text(); 
    if(text) { Astrology.tracking(text) };
  };


  $.fn.m_tracking = function() {
    return this.each(function() {
      var self = $(this);
      var text = self.find('.' + classes.code).text(); 
      var target = self.find('.' + classes.target);
      target.click(function() {
        if(text) { Astrology.tracking(text) };
        return true;
      });
    });
  };

})(jQuery);


// Implements maxlength attribute of <textarea> tag.
//
// Usage:
// - form_tag("#", :class => "m-max_length") do
//   %fieldset.m-max-length.m-max-length_3000
//     %textarea.m-max-length_target
//     .m-max-length_count
//
;Astrology.runners.mixins.max_length = function() {
  jQuery('.m-max-length_3000').m_max_length({"max_length": "3000"});
};

(function($) {
  
  var classes = {
    self: 'm-max-length',
    target: 'm-max-length_target',
    count: 'm-max-length_count'
  };
  
    
  $.fn.m_max_length = function(options) {
    var opts = $.extend({}, $.fn.m_max_length.defaults, options);
    return this.each(function() {
      var self = $(this);
      init_maxlength(self, opts);
    });
  };


  function init_maxlength(self, opts) {
    var target = self.find("." + classes.target);
    // Use usual JavaScript, not jQuery for improving performance
    var count_wrapper = self.find("." + classes.count).get(0);
    var characters_left = get_characters_left(self, opts, target.get(0));
    target.bind('keydown keypress keyup',function(e) {
      var text = this.value;
      if(text.length > opts.max_length) { 
        this.value = text.substr(0, opts.max_length);
      };
      characters_left = get_characters_left(self, opts, this);
      show_characters_left(self, opts, count_wrapper, characters_left);
    });
    show_characters_left(self, opts, count_wrapper, characters_left);
  };


  function show_characters_left(self, opts, count_wrapper, characters_left) {
    count_wrapper.innerHTML = opts.text + characters_left;
  };


  function get_characters_left(self, opts, target) {
    return opts.max_length - target.value.length;
  }


  $.fn.m_max_length.defaults = {
    max_length: 3000,
    text: "Characters left: " // текст в конце строки информера
  };


})(jQuery);


// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.mixins.clear_inputs = function() {
  jQuery('.m-clear-inputs').m_clear_inputs();
};

(function($) {
  
  var classes = {
    self: 'm-clear-inputs',
    description: 'm-clear-inputs_description'
  };
  
  $.fn.m_clear_inputs = function(options) {
    var opts = $.extend({}, $.fn.m_clear_inputs.defaults, options);
    
    return this.each(function() {
      var self = $(this);
      var parent = self.parent();
      parent.css('position', 'relative');
      var label = get_label(this, parent, opts.text);
      var klass = self.attr('class').match(/(m-clear-inputs[a-zA-Z_\-]*)/)[1] + '_label';
      label
        .css('position', 'absolute')
        .css('left', opts.left + 'px')
        .css('top', opts.top + 'px')
        .css('z-index', 1)
        .css('display', 'block');
      label.addClass(klass);
      if(self.val() != '') { label.hide(); };
      label.click(function() { label.hide(); self.focus(); });
      self.focus(function() { label.hide(); });
      self.blur(function() { if(this.value == "") { label.show(); } });
    });
  };
  
  
  function get_label(input, parent, text) {
    var label = parent.find('label.' + classes.description);
    if(label.size() == 0) {
      label = $('<label class="' + classes.description + '">' + text + '</label>');
      parent.append(label);
    };
    return label;
  }
  

  $.fn.m_clear_inputs.defaults = {
    top: 5,
    left: 5,
    text: 'Default label'
  };

})(jQuery);
// Implements redirection on changing of select_tag to URL from select box'es value.
//
// It is compatible with m-tracking mixin, so if you put .m-tracking_code block with tracking
// info into m-redirector block, it will send that tracking code on changing the select box. It 
// is optional stuff.
//
// Usage:
// - form_tag("#", :class => "m-redirector") do
//   %fieldset
//     %select.m-redirector_select
//       %option{ :value => "http://www.astrology.com/some/url/here" } Text
//       %option{ :value => "http://www.astrology.com/some/other/url/here" } Other Text
//     .m-redirector_spinner
//     .m-tracking_code some:tracking:code
//
;Astrology.runners.mixins.redirector = function() {
  jQuery('.m-redirector').m_redirector();
};

(function($) {
  
  var classes = {
    self: 'm-redirector',
    select: 'm-redirector_select',
    spinner: 'm-redirector_spinner'
  };
  
    
  $.fn.m_redirector = function() {
    return this.each(function() {
      var self = $(this);
      init_select(self);
    });
  };


  function init_select(self) {
    var select = self.find('.' + classes.select);
    select.change(function() { 
      var value = $(this).val();
      if(value == "") { return false; };
      $.m_tracking(self);
      self.find('.' + classes.spinner).css('display', 'inline-block');
      window.location.href = value;
      return false;
    });
  };

})(jQuery);

// .m-tooltip_square
//   .m-tooltip_square_target Move mouse here to see the tooltip
//   .m-tooltip_square_source Tooltip content
//
// .m-tooltip_round
//   .m-tooltip_round_target Move mouse here to see the tooltip
//   .m-tooltip_round_source
//     .m-tooltip_round_popup_left 
//     .m-tooltip_round_popup_right Tooltip content

;Astrology.runners.mixins.tooltip = function() {
  jQuery('.m-tooltip_square').m_tooltip({type: 'square'});
  jQuery('.m-tooltip_round').m_tooltip({type: 'round', x_offset: 35, y_offset: 10});
};

(function($) {
  
  var classes = {
    self: 'm-tooltip',
    target: 'target',
    source: 'source',
    popup: 'popup'
  };
  
  $.fn.m_tooltip = function(options) {
    var opts = $.extend({}, $.fn.m_tooltip.defaults, options);
    return this.each(function() {
      var self = $(this);
      var target = self.find('.' + classes.self + "_" + opts.type + "_" + classes.target);
      var source = self.find('.' + classes.self + "_" + opts.type + "_" + classes.source);
      var tooltip = $("<div class='" + classes.self + "_" + opts.type + "_" + classes.popup + "'></div>");
      $('#js').append(tooltip);
      target.mouseover(function(e) {
        tooltip.html(source.html());
        var left_value = e.pageX + opts.x_offset - tooltip.width();
        var top_value = e.pageY + opts.y_offset;
        tooltip.css({left: left_value + 'px', top: top_value + 'px'});
        tooltip.show();
      });
      target.mousemove(function(e) {
        var left_value = e.pageX + opts.x_offset - tooltip.width();
        var top_value = e.pageY + opts.y_offset;
        tooltip.css({left: left_value + 'px', top: top_value + 'px'});
      });
      target.mouseout(function() {
        tooltip.hide();
      });
    });
  };

  $.fn.m_tooltip.defaults = {
    y_offset: 20,
    x_offset: 20
  };

})(jQuery);

// Allows to add validators to form elements. 
//
// * m-validations class should be assigned to form.
// * m-validations_element (several types, see below), m-validations_validate_your-validator-type 
//     should be assigned to div containing validated element.
//     For allowable your-validator-type values, check 'validations' variable below
// * m-validations_error (optional), it should contain error you want to show if element is invalid
// * m-validations_border (optional), it may be assigned to div you want to have red border if element is invalid
//
// m-validations_element can be m-validations_element_on-submit and m-validations_element_all
// (validation will be run only after submitting the form or after submitting and blur)
//
// == Example
// - form_tag("#", :class => "m-validations") do
//     .m-validations_element_on-submit.m-validations_validate_not-empty
//         .m-validations_border
//             %em.m-validations_error This field should be filled
//             = text_field_tag(:name, "John")
Astrology.runners.mixins.validations = function () {
    jQuery('.m-validations').m_validations();
};

(function ($) {
    
    var classes = {
        self: 'm-validations',
        element: 'm-validations_element',
        'type': 'm-validations_type',
        'name': 'm-validations_name',
        border: 'm-validations_border',
        border_wrong_place: 'm-validations_border_wrong-place',
        invalid_border: 'm-validations_invalid-border',
        accurate_place: 'm-validations_accurate-place',
        accurate_place_field: 'm-validations_accurate-place_field',
        error: 'm-validations_error',
        spinner: 'm-validations_spinner'
    };


    function show_error(self, name, type) {
        self.find('.' + classes.border + '_' + name).addClass(classes.invalid_border);
        self.find('.' + classes.error + '_' + name + '_' + type).show();
    }


    function hide_error(self, name, type) {
        self.find('.' + classes.error + '_' + name + '_' + type).hide();
        if (self.find('.' + classes.error + ' li:visible').size() === 0) {
            self.find('.' + classes.border + '_' + name).removeClass(classes.invalid_border);
        }
    }


    function handle_error(self, valid_condition, name, type) {
        if (valid_condition) {
            hide_error(self, name, type);
            return true;
        } else {
            show_error(self, name, type);
            return false;
        }
    }


    // Add your validation rules to here:
    var local_validations = {
        'not-empty': function (self, opts, element, name) {
            var input = element.find(':input:eq(0)');
            var match = true;
            input.each(function () { 
                if (!this.disabled) {
                    match = match && $(this).val().toString() !== ""; 
                }
            });
            return handle_error(self, match, name, 'not-empty');
        },

        'not-empty_if-us': function (self, opts, element, name) {
            var input = element.find(':input:eq(0)');
            var num = input.attr("id").match(/.*(\d+)$/);
            num = (num ? num[1] : 1);
            if (self.find("#user_birth_country_" + num).val().toString() === "US") { 
                var match = true;
                input.each(function () { 
                    if (!this.disabled) {
                        match = match && $(this).val().toString() !== ""; 
                    }
                });
                return handle_error(self, match, name, 'not-empty_if-us');
            } else {
                return handle_error(self, true, name, 'not-empty_if-us');
            }
        },

        'password-length': function (self, opts, element, name) {
            var input = element.find(':input:eq(0)');
            if (input.val().toString() !== "") {
                var match = (input.val().toString().length >= 4 && input.val().toString().length <= 40);
                return handle_error(self, match, name, 'password-length');
            } else {
                return handle_error(self, true, name, 'password-length');
            }
        },

        'confirmation': function (self, opts, element, name) {
            var password = self.find('.' + classes.name + '_password input');
            var password_confirmation = element.find(':input:eq(0)');
            if (password.val().toString() !== "") {
                var match = (password.val().toString() === password_confirmation.val().toString());
                return handle_error(self, match, name, 'confirmation');
            } else {
                return handle_error(self, true, name, 'confirmation');
            }
        },

        'correct-email-format': function (self, opts, element, name) {
            var input = element.find(':input:eq(0)');
            // This huge regexp is taken from http://xyfer.blogspot.com/2005/01/javascript-regexp-email-validator.html
            var reg_exp = /^(("[\w\-\s]+")|([\w\-]+(?:\.[\w\-]+)*)|("[\w\-\s]+")([\w\-]+(?:\.[\w\-]+)*))(@((?:[\w\-]+\.)*\w[\w\-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i;
            var match = true;
            input.each(function () { 
                if (!this.disabled) {
                    match = match && $(this).val().match(reg_exp);
                }
            });
            return handle_error(self, match, name, 'correct-email-format');
        },

        'correct-date': function (self, opts, element, name) {
            var input = element.find(':input');
            var day;
            var month;
            var year;
            var match;
            input.each(function () {
                var that = $(this);
                var name = that.attr('name');
                if (name.match(/\(3i\)/)) { 
                    day = that.val(); 
                } else if (name.match(/\(2i\)/)) { 
                    month = that.val() - 1; 
                } else if (name.match(/\(1i\)/)) { 
                    year = that.val(); 
                }
            });
            try {
                var date = new Date(year, month, day);
                match = (
                    parseInt(date.getFullYear(), 10) === parseInt(year, 10) && 
                    parseInt(date.getMonth(), 10) === parseInt(month, 10) && 
                    parseInt(date.getDate(), 10) === parseInt(day, 10)
                );
            } catch (exception) {
                match = false;
            }
            return handle_error(self, match, name, 'correct-date');
        }
    };

    var remote_validations = {
        'unique-email_condition': function (self, element) {
            var input = element.find(':input:eq(0)').get(0);
            var uuid = self.find('#user_uuid').val();
            if (input && input.value.toString() !== "") {
                return [ true, { email: input.value, uuid: uuid } ];
            } else {
                hide_error(self, 'email', 'unique-email');
                return [ false, {} ];
            }
        },

        'unique-email': function (self, opts, element, name, data) {
            return handle_error(self, (data.email_exists === "false"), name, 'unique-email');
        },

        'unique-nick_condition': function (self, element) {
            var input = element.find(':input:eq(0)').get(0);
            var uuid = self.find('#user_uuid').val();
            if (input && input.value.toString() !== "") {
                return [ true, { nick: input.value, uuid: uuid } ];
            } else {
                hide_error(self, 'nick', 'unique-nick');
                return [ false, {} ];
            }
        },

        'unique-nick': function (self, opts, element, name, data) {
            return handle_error(self, (data.nick_exists === "false"), name, 'unique-nick');
        },

        'existed-email_condition': function (self, element) {
            var input = element.find(':input:eq(0)').get(0);
            if (input && input.value.toString() !== "") {
                return [ true, { email: input.value } ];
            } else {
                hide_error(self, 'email', 'existed-email');
                return [ false, {} ];
            }
        },

        'existed-email': function (self, opts, element, name, data) {
            return handle_error(self, (data.email_exists !== "false"), name, 'existed-email');
        },

        'correct-password_condition': function (self, element) {
            var email = self.find('.' + classes.name + '_email input');
            var password = element.find(':input:eq(0)');
            if (email.val().toString() !== "" && password.val().toString() !== "") {
                return [ true, { email: email.val(), password: password.val() } ];
            } else {
                hide_error(self, 'password', 'correct-password');
                return [ false, {} ];
            }
        },

        'correct-password': function (self, opts, element, name, data) {
            return handle_error(self, (data.password_correct === "true"), name, 'correct-password');
        },

        // This validation is more complex than other validations. It requres some
        // additional markup and special divs for error and additional select box.
        //
        // == Example ==
        // .m-validations_element.m-validations_validate_correct-country
        //     .m-validations_error_correct-country (error messages will be shown here)
        //     .m-validations_correct-country (additional select box will be shown here)
        //     / Here should be city, state and country inputs, maybe with other validations
        //     = hidden_field_tag(:latitude1, "", :class => "latitude")
        //     = hidden_field_tag(:longitude1, "", :class => "longitude")
        //
        'correct-place_condition': function (self, element) {
            var city = element.find(".city");
            var state = element.find(".state");
            var country = element.find(".country");
            var number = city.attr("id").match(/(\d+)$/)[1];
            var condition = (city.val().toString() !== "" && country.val().toString() !== "");
            if (country.val().toString() === "US") {
                condition = condition && state.val().toString() !== "";
            }
            var accurate_place_select_box = self.find("#user_accurate_place_" + number);
            if (accurate_place_select_box.size() !== 0) {
                var place_was_changed = element.data("city") !== element.find(".city").val();
                place_was_changed = place_was_changed || element.data("state") !== element.find(".state").val();
                place_was_changed = place_was_changed || element.data("country") !== element.find(".country").val();
                if (place_was_changed) {
                    hide_error(self, 'accurate-place_' + number, 'multiple-locations');
                    accurate_place_select_box.remove();
                    element.find("." + classes.name + "_accurate-place_" + number).hide();
                } else {
                    condition = false;
                }
            }
            if (condition) {
                var year = self.find("#user_birth_date_" + number + "_1i_");
                var month = self.find("#user_birth_date_" + number + "_2i_");
                var day = self.find("#user_birth_date_" + number + "_3i_");
                var birthdate = month.val() + "/" + day.val() + "/" + year.val();
                return [ true, { city: city.val(), state: state.val(), country: country.val(), birthdate: birthdate } ];
            } else {
                return [ false, {} ];
            }
        },

        'correct-place': function (self, opts, element, name, data) {
            // Auxiliary functions - START
            function get_accurate_place_string(json) {
                var value = [ json.city ];
                value.push(json.place_id);
                value.push(json.state);
                value.push(json.county);
                value.push(json.country);
                value.push(json.latitude_str);
                value.push(json.longitude_str);
                value.push(json.latitude_dec);
                value.push(json.longitude_dec);
                value.push(json.timezone);
                return value.join(";");
            }

            function accurate_place_id(number) {
                return "user_accurate_place_" + number;
            }

            function accurate_place_name(number) {
                return "user[accurate_place_" + number + "]";
            }

            function get_select_box_text(json) {
                var text = json.city;
                if (json.county) { 
                    text += " (" + json.county + ")"; 
                }
                if (json.state) { 
                    text += ", " + json.state; 
                }
                text += ", " + json.country;
                return text;
            }

            function remember_place_entered_by_user(element) {
                var city = element.find(".city").val();
                var state = element.find(".state").val();
                var country = element.find(".country").val();
                element.data("city", city);
                element.data("state", state);
                element.data("country", country);
            }

            function create_select_box_with_accurate_places(self, element, json, number) {
                remember_place_entered_by_user(element);
                var id = accurate_place_id(number);
                var name = accurate_place_name(number);
                var select_box = $("<select name='" + name + "' id='" + id + "'></select>");
                element.find("." + classes.accurate_place_field).append(select_box);
                if (json.data.length > 0) {
                    for (var i = 0; i < json.data.length; i = i + 1) {
                        var text = get_select_box_text(json.data[i]);
                        var value = get_accurate_place_string(json.data[i]);
                        select_box.append('<option value="' + value + '">' + text + '</option>');
                    }
                    show_error(self, 'accurate-place_' + number, 'multiple-locations');
                }
                element.find("." + classes.name + "_accurate-place_" + number).show();
            }


            function json_status_is_okay(json) {
                return parseInt(json.status, 10) === 0;
            }

            function validate_birth_place_from_atlas(self, element, json) {
                var number = element.find(".city").attr("id").match(/(\d+)$/)[1];
                var result = false;
                if (json_status_is_okay(json)) {
                    handle_error(self, json.data, "correct-place_" + number, "wrong-place");
                    if (json.data) {
                        if (json.data.length > 1) {
                            create_select_box_with_accurate_places(self, element, json, number);
                        } else {
                            result = true;
                        }
                    }
                } else {
                    alert("We are sorry that we are currently experiencing a minor system glitch and are unable to complete this transaction. Please try running this reading a little later..");
                }
                return result;
            }
            // Auxiliary functions - END

            // Main code of validation itself
            return validate_birth_place_from_atlas(self, element, data);

        }
    };


    function get_types(element_classes) {
        var types = [];
        var type_reg_exp = new RegExp(classes.type + '_([\\w\\-]+)');
        $.each(element_classes, function () {
            var match = this.match(type_reg_exp); 
            if (match) {
                types.push(match[1]);
            }
        });
        return types;
    }


    function get_name(element_classes) {
        var name = null;
        var name_reg_exp = new RegExp(classes.name + '_([\\w\\-]+)');
        $.each(element_classes, function () {
            var match = this.match(name_reg_exp); 
            if (match) {
                name = match[1];
            }
        });
        return name;
    }


    function iterate_through_every_type_of_every_element(elements, callback) {
        $.each(elements, function () {
            var element = $(this);
            var element_classes = element.attr('class').split(" ");
            var name = get_name(element_classes);
            var types = get_types(element_classes);
            if (types.length > 0) {
                $.each(types, function () {
                    callback(element, name, this);
                });
            }
        });
    }


    function validate_locally(self, opts, elements) {
        var overall_result = true;
        iterate_through_every_type_of_every_element(elements, function (element, name, type) {
            if (local_validations[type]) {
                var result = local_validations[type](self, opts, element, name);
                overall_result = overall_result && result;
            }
        });
        return overall_result;
    }


    function make_remote_call(self, opts, params) {
        var spinner = self.find('.' + classes.spinner);
        spinner.show();
        var result = null;
        $.ajax({
            type: "GET",
            url: "/user/remote_validations.js", 
            data: params,
            dataType: 'json',
            async: false,
            success: function (json) {
                result = json;
            }
        });
        spinner.hide();
        return result;
    }


    function get_params_for_remote_call(self, opts, elements) {
        var should_make_remote_call = false;
        var params = {};
        iterate_through_every_type_of_every_element(elements, function (element, name, type) {
            if (remote_validations[type + "_condition"]) {
                var result = remote_validations[type + "_condition"](self, element);
                if (result[0]) {
                    should_make_remote_call = true;
                    var named_params = {};
                    named_params[name + "_" + type] = result[1];
                    params = $.extend({}, params, named_params);
                }
            }
        });
        return [ should_make_remote_call, params ];
    }

        
    function validate_remotely(self, opts, elements) {
        var overall_result = true;
        var function_result = get_params_for_remote_call(self, opts, elements);
        var should_make_remote_call = function_result[0];
        var params = function_result[1];
        if (should_make_remote_call) {
            var call_result = make_remote_call(self, opts, params);
            iterate_through_every_type_of_every_element(elements, function (element, name, type) {
                if (remote_validations[type]) {
                    var data = call_result[name + "_" + type];
                    if (data) {
                        var result = remote_validations[type](self, opts, element, name, data);
                        overall_result = overall_result && result;
                    }
                }
            });
        }
        return overall_result;
    }


    function validate_all(self, opts) {
        var elements = self.find('.' + classes.element);
        var local_result = validate_locally(self, opts, elements);
        var remote_result = validate_remotely(self, opts, elements);
        return local_result && remote_result;
    }
    
    
    $.fn.m_validations = function (options) {
        var opts = $.extend({}, $.fn.m_validations.defaults, options);
        return this.each(function () {
            var self = $(this);
            self.submit(function () { 
                return validate_all(self, opts); 
            });
        });
    };


    $.m_validations_validate_all = function (self, opts) {
        opts = opts || {};
        return validate_all(self, opts); 
    };


    $.fn.m_validations.defaults = {
    };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.mixins.poll_buttons = function() {
  jQuery('.m-poll_buttons').m_poll_buttons();
};
;Astrology.runners.mixins.poll_form = function() {
  jQuery('.m-poll_form').m_poll_form();
};

(function($) {
  
  var classes = {
    buttons: 'm-poll_buttons',
    button: 'm-poll_button',
    questions: 'm-poll_questions',
    results: 'm-poll_results',
    result: 'm-poll_result',
    gfx: 'm-poll_result_gfx',
    spinner: 'm-poll_spinner'
  };
  
  $.fn.m_poll_buttons = function() {
    return this.each(function() {
      var self = $(this);
      var buttons = self.find('.' + classes.button);
      var spinner = self.find('.' + classes.spinner);
      buttons.click(function() {
        var url = $(this).attr('href');
        var id = url.match(/(\d+)$/)[1];
        spinner.show();
        $.ajax({
          type: "POST",
          url: url + ".js", 
          data: { 'authenticity_token': Astrology.AUTH_TOKEN }, 
          dataType: 'json',
          success: function(data) {
            spinner.hide();
            show_results(self, id, data);
          },
          error: function(response) {
            alert("Sorry, can't vote for now - server error");
          }
        });
        return false;
      });
    });
  };

  $.fn.m_poll_form = function() {
    return this.each(function() {
      var self = $(this);
      var questions = self.find('.' + classes.questions);
      var spinner = self.find('.' + classes.spinner);
      var form = questions.find('form');
      form.submit(function() {
        var id = form.find(':radio').fieldValue()[0];
        spinner.show();
        if(!form.get(0).action.match(/\.js$/)) { form.get(0).action += '.js'; }; 
        form.ajaxSubmit({
          dataType: 'json',
          success: function(data) {
            spinner.hide();
            show_results(self, id, data);
            set_width_of_gfx(self, data);
          }
        });
        return false;
      });
    });
  };


  function show_results(self, id, data) {
    var results = self.find('.' + classes.results);
    var questions = self.find('.' + classes.questions);
    results.show();
    questions.hide();
    results.find('.' + classes.result + "_" + id).parent().addClass('selected');
    var percents = vote_percents(data);
    for(var i = 0; i < percents.length; i++) {
      var choice_dom = results.find('.' + classes.result + '_' + percents[i].choice_id);
      choice_dom.text(percents[i].percents);
    };
  };


  function set_width_of_gfx(self, data) {
    var results = self.find('.' + classes.results);
    var percents = vote_percents(data);
    for(var i = 0; i < percents.length; i++) {
      var gfx = results.find('.' + classes.gfx + '_' + percents[i].choice_id);
      gfx.css('width', percents[i].percents);
    };
  };


  function vote_percents(data) {
    var overall_number_of_votes = 0;
    for(var i = 0; i < data.length; i++) { overall_number_of_votes += parseInt(data[i].table.votes); };
    var percents = [];
    for(var i = 0; i < data.length; i++) { 
      var choice = data[i].table;
      var value = "0%";
      if(overall_number_of_votes > 0) {
        value = Math.round((choice.votes * 100) / overall_number_of_votes).toString() + "%";
      };
      percents.push({percents: value, choice_id: choice.choice_id})
    };
    return percents;
  };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.mixins.tabs = function() {
  jQuery('.m-tabs').m_tabs();
};

(function($) {
  
  var classes = {
    self: 'm-tabs', 
    tab_headers: 'm-tabs_headers',
    tabs: 'm-tabs_tabs',
    tab: 'm-tabs_tab',
    link: 'm-tabs_link',
    active: 'active'
  };
  
  $.fn.m_tabs = function() {
    return this.each(function() {
      var self = $(this);
      init_tabs(self);
    });
  };

  function init_tabs(self) {
    var tab_headers = self.find('.' + classes.tab_headers);
    var tab_links = tab_headers.find('.' + classes.link); 
    var tabs = self.find('.' + classes.tabs);
    var first_tab = tabs.find('.' + classes.tab + ':eq(0)');
    tabs.find('.' + classes.tab).hide();
    first_tab.show();
    tab_links.click(function() {
      change_tab(self, tabs, $(this));
      return false;
    });
  };

  function change_tab(self, tabs, link) {
    var tab_regexp = new RegExp(classes.link + "_([a-zA-Z0-9_\-]+)");
    var match = link.attr('class').match(tab_regexp); 
    if(match) {
      var id = match[1];
      tabs.find('.' + classes.tab).hide();
      tabs.find('.' + id).show();
      self.find('.' + classes.link).removeClass(classes.active);
      link.addClass(classes.active);
    };
  };


})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.video_horoscope = function() {
  jQuery('#b-video-horoscope').b_video_horoscope();
};

(function($) {
  
  var classes = {
    signs_select: 'b-video-horoscope_signs-select'
  };

    
  $.fn.b_video_horoscope = function() {
    return this.each(function() {
      var self = $(this);
      init_sign_select(self);
    });
  };


  function init_sign_select(self) {
    var sign = self.find('.' + classes.signs_select + ' select');
    sign.change(function() { 
      var value = $(this).val();
      if(value == "") { return false; };
      playOneVideo(video_ids[value]);
      return false;
    });
  };


})(jQuery);




 



;Astrology.runners.blocks.love_match = function() {
  jQuery('#b-love-match').b_love_match();
};

(function($) {
  
  var classes = {
    select: 'b-love-match_select',
    sign: 'b-love-match_sign',
    buttons: 'b-love-match_buttons'
  };

    
  $.fn.b_love_match = function() {
    return this.each(function() {
      var self = $(this);
      init_sign_select(self, 1);
      init_sign_select(self, 2);
    });
  };

  
  function init_sign_select(self, number) {
    var select = self.find('.' + classes.select + number);
    var sign = self.find('.' + classes.sign + number);
    var button = self.find('.' + classes.buttons + ' a');
    select.change(function() {
      var value = $(this).val();

      if(button.size() > 0) {
        var href = button.attr('href');
        if(number == 1) {
          //http://new.astrology.com:3000/chinese-match-horse-horse/2-d-chmt-horse_horse
          button.attr('href', href.replace(/(\w+)-(\w+)\/2-d-(\w+)-(\w+)_(\w+)/, value + "-$2/2-d-$3-" + value + "_$5"));
        } else {
          button.attr('href', href.replace(/(\w+)-(\w+)\/2-d-(\w+)-(\w+)_(\w+)/, "$1-" + value + "/2-d-$3-$4_" + value));
        };
      };

      if(sign.size() > 0) {
        var src = sign.attr('src');
        sign.attr('src', src.replace(/(\w+)\.(gif|jpg)/, value + ".$2")); 
      };

    });
  };

 
})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;(function($) {
  
  var classes = {
    self: 'b-sign',
    image: 'b-sign_image',
    signs: 'b-sign_signs',
    current: 'b-sign_current'
  };


  $.fn.b_sign_change_western_sign = function(sign) {
    var self = $(this);
    var icon_url = "/images/framework/block/sign/" + sign + ".jpg";
    self.find('.' + classes.image).attr('src', icon_url);
    var signs = self.find('.' + classes.signs);
    signs.find('span').removeClass('selected');
    signs.find('.' + classes.signs + "_" + sign).addClass('selected');
    self.find('.' + classes.current).text(sign.toString().capitalize());
  };

})(jQuery);

/**
*	jQuery.notice_add() and jQuery.notice_remove()
*	These functions create and remove growl-like notices
*		
*   Copyright (c) 2009 Tim Benniks
*
*	Permission is hereby granted, free of charge, to any person obtaining a copy
*	of this software and associated documentation files (the "Software"), to deal
*	in the Software without restriction, including without limitation the rights
*	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*	copies of the Software, and to permit persons to whom the Software is
*	furnished to do so, subject to the following conditions:
*
*	The above copyright notice and this permission notice shall be included in
*	all copies or substantial portions of the Software.
*
*	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*	THE SOFTWARE.
*	
*	@author 	Tim Benniks <tim@timbenniks.com>
* 	@copyright  2009 timbenniks.com
*	@version    $Id: jquery.notice.js 1 2009-01-24 12:24:18Z timbenniks $
*
*       (modified by Anton Astashov)
*
**/

;Astrology.runners.blocks.notice = function() {
  jQuery('.b-notice').b_notice();
}

;(function($) {
  
  $.fn.b_notice = function() {
    this.each(function() {
      var self = $(this);
      self.appendTo($('body'));
      var items = self.find('.' + classes.item);
      items.each(function() { 
        var item = $(this);
        var close = $('<div class="' + classes.close + '">x</div>');
        item.append(close);
        close.click(function() { $.notice_remove(item); });
        if(item.hasClass(classes.notice)) {
          setTimeout(
            function() {
              $.notice_remove(item);
            }, 
            5000
          );
        };
      });
    })
  };

  var classes = {
    wrap: 'b-notice',
    item: 'b-notice_item',
    notice: 'notice',
    error: 'error',
    item_wrapper: 'b-notice_item_wrapper',
    close: 'b-notice_item_close'
  };
  
  $.notice_add = function(options) {	
    var defaults = {
      inEffect: {opacity: 'show'}, // in effect
      inEffectDuration: 600, // in effect duration in miliseconds
      stayTime: 5000, // time in miliseconds before the item has to disappear
      text: '', // content of the item
      stay: false, // should the notice item stay or not?
      type: 'notice' // could also be error, succes
    };

    // declare varaibles
    var options, noticeWrapAll, noticeItemOuter, noticeItemInner, noticeItemClose;

    options = $.extend({}, defaults, options);
    noticeWrapAll = (!$('.' + classes.wrap).length) ? $('<div></div>').addClass(classes.wrap).appendTo('body') : $('.' + classes.wrap);
    noticeItemOuter = $('<div></div>').addClass(classes.item_wrapper);
    noticeItemInner = $('<div></div>').hide().addClass(classes.item + ' ' + options.type).appendTo(noticeWrapAll).html('<p>'+options.text+'</p>').animate(options.inEffect, options.inEffectDuration).wrap(noticeItemOuter);
    noticeItemClose = $('<div></div>').addClass(classes.close).prependTo(noticeItemInner).html('x').click(function() { $.notice_remove(noticeItemInner) });

    // hmmmz, zucht
    if(navigator.userAgent.match(/MSIE 6/i)) {
      noticeWrapAll.css({top: document.documentElement.scrollTop});
    }

    if(!options.stay) {
      setTimeout(
        function() {
          $.notice_remove(noticeItemInner);
        },
        options.stayTime
      );
    }

    return noticeItemInner;
  };

  $.notice_remove = function(obj) {
    obj.animate({opacity: '0'}, 600, function() {
      obj.parent().animate({height: '0px'}, 300, function() {
        obj.parent().remove();
      });
    });
  };

})(jQuery);
// Scopes slider. 
;Astrology.runners.blocks.scopes_slider = function() {
  jQuery('#b-scopes-slider').b_scopes_slider();
};

(function($) {
 
  var raw_width_of_element = 165;
  var margin_of_element = 20;
  var width_of_element = raw_width_of_element + margin_of_element;
  var number_of_visible_elements = 4;

  var classes = {
    self: 'b-scopes-slider',
    edit: 'b-scopes-slider_gallery_edit',
    edit_button: 'b-scopes-slider_edit-button',
    tooltip: 'b-scopes-slider_gallery_tooltip',
    list: 'b-scopes-slider_gallery_list',
    item: 'b-scopes-slider_gallery_list_item',
    item_header: 'b-scopes-slider_gallery_list_item_header',
    item_header_title: 'b-scopes-slider_gallery_list_item_header_title',
    item_content: 'b-scopes-slider_gallery_list_item_content',
    item_tooltip: 'b-scopes-slider_gallery_list_item_header_tooltip',
    popup: 'b-scopes-slider_gallery_popup',
    popup_wrapper: 'b-scopes-slider_gallery_popup_wrapper',
    prev: 'b-scopes-slider_gallery_prev',
    next: 'b-scopes-slider_gallery_next',
    delete_button: 'b-scopes-slider_delete',
    save: 'b-scopes-slider_save',
    cancel: 'b-scopes-slider_cancel',
    opened: 'b-scopes-slider_opened',
    remove: 'b-scopes-slider_gallery_remove',
    remove_title: 'b-scopes-slider_gallery_remove_title',
    remove_okay: 'b-scopes-slider_gallery_remove_okay',
    read_more: 'b-scopes-slider_gallery_list_item_content_more'
  };

  var trackings = {
    next: 'ast:horoscopes:slider-next',
    prev: 'ast:horoscopes:slider-prev',
    more: 'ast:horoscopes:slider-readmore',
    open: 'ast:horoscopes:slider-panel',
    edit: 'ast:horoscopes:slider-edit',
    close: 'ast:horoscopes:slider-closescope'
  };
  
  $.fn.b_scopes_slider = function(options) {
    return this.each(function() {
      var self = $(this);
      init_self(self);
      init_slider(self);
      init_edit(self);
      save_edit(self);
      init_popups(self);
      init_tooltip(self);
      init_trackings(self);

      var shown_items = visible_items(self);
      if(shown_items.size() > 0) {
        var shown_item = shown_items.filter(':eq(1)');
        if(shown_item.size() > 0) {
          open_popup(self, shown_item);
        } else {
          shown_item = shown_items.filter(':eq(0)');
          open_popup(self, shown_item);
        };
      };
    });
  };


  function init_self(self) {
    self.data("gallery_position", 0);
    self.data("processing", false);
  };


  function init_slider(self) {
    var list = self.find('.' + classes.list);
    toggle_arrows(self, list);
    self.find('.' + classes.next).click(function() { 
      move_list(self, list, 1, 'right'); 
      $.m_tracking(null, trackings.next);
      return false; 
    });
    self.find('.' + classes.prev).click(function() { 
      move_list(self, list, 1, 'left'); 
      $.m_tracking(null, trackings.prev);
      return false; 
    });
  };


  function visible_items(self, list) {
    var list = list || self.find('.' + classes.list);
    var items = list.children('.' + classes.item + ':visible');
    var offset = parseInt(list.css('left'));
    var first_item = -offset / width_of_element;
    visible_items = items.slice(first_item, first_item + 4);
    return visible_items;
  };


  function init_popups(self) {
    self.find('.' + classes.item_header).click(function() {
      $.m_tracking(null, trackings.open);
      open_popup(self, $(this).parent()); return false;
    });
    self.find('.' + classes.item_header + ' .' + classes.delete_button).click(function() {
      remove_item(self, $(this).closest('.' + classes.item)); return false;
    });
  };


  function init_edit(self) {
    var edit = self.find('.' + classes.edit);
    self.find('.' + classes.edit_button).click(function() { 
      $.m_tracking(null, trackings.edit);
      open_edit(self); 
      return false; 
    });
    edit.find('.' + classes.delete_button).click(function() { close_edit(self); return false; });
    edit.find('.' + classes.cancel).click(function() { close_edit(self); return false; });
    edit.find('form').submit(function() { save_edit(self); close_edit(self); return false; });
  };


  function init_tooltip(self) {
    self.find('.' + classes.item_header + ' .' + classes.delete_button).hover(
      function() { show_tooltip(self, $(this).closest('.' + classes.item)); },
      function() { hide_tooltip(self, $(this).closest('.' + classes.item)); }
    );
  };

  // Not all trackings are initialized there. Some of them are placed inside of other
  // functions. Look for m_tracking method calls
  function init_trackings(self) {
    self.find('.' + classes.read_more).click(function() { $.m_tracking(null, trackings.more); return false; });
  }


  function move_list(self, list, number, direction, callback) {
    if(self.data("processing") == false) {
      var popup = self.find('.' + classes.popup);
      var opened_item = self.find('.' + classes.opened);
      close_popup(self, popup, function() {
        self.data("processing", true);
        var move_value = width_of_element * number;
        var left = (direction == 'left' ? '+' : '-') + '=' + move_value + 'px';
        list.animate({left: left}, "fast", "swing", function() {
          toggle_arrows(self, $(this));
          var number_of_items = list.children('.' + classes.item + ':visible').not('.cloned').size();
          if(parseInt(list.css('left')) >= 0) {
            list.css('left', -((number_of_items) * width_of_element).toString() + "px");
          } else if(parseInt(list.css('left')) <= -((number_of_items + 4) * width_of_element)) {
            list.css('left', -(4 * width_of_element).toString() + "px");
          };
          self.data("processing", false);
          if(opened_item.size() > 0) {
            next_item = (direction == 'left' ? opened_item.prev() : opened_item.next());
            open_popup(self, next_item);
          };
        });
      });
    };
  };


  function make_list_continuous(self, list, current_left) {
    list.children('.cloned').remove();
    var items = list.children('.' + classes.item + ':visible');
    if(items.size() > 4) {
      var cloned_start = items.slice(0, 4).clone();
      var cloned_end = items.slice(-4).clone();
      cloned_start.addClass('cloned');
      cloned_end.addClass('cloned');
      list.prepend(cloned_end);
      list.append(cloned_start);
      if(current_left) {
        list.css('left', current_left + "px");
      } else {
        list.css('left', (-width_of_element * 4).toString() + "px");
      };
    } else {
      list.css('left', "0");
    };
    toggle_arrows(self, list);
  };


  function open_popup(self, item) {
    if(self.data("processing") == false) {
      var popup = self.find('.' + classes.popup);
      var popup_wrapper = popup.find('.' + classes.popup_wrapper);
      // At first, close currently opened window (if it is presented)
      close_popup(self, popup, function() {
        // Then, continue to open current window
        self.data("processing", true);
        popup_wrapper.empty()
        popup.show();
        item.addClass(classes.opened);
        var content = item.find('.' + classes.item_content);
        var new_content = content.clone().appendTo(popup_wrapper).css("opacity", 0);
        var left = (width_of_element / 2) + (width_of_element * get_index_of_item(self, item));
        popup.css("left", left + "px").css("top", "120px");
        popup.animate({width: "410px", height: "240px", top: "-=120px", left: "-=205px"}, "fast", "swing", function() {
          new_content.animate({opacity: 1}, "fast", "linear", function() {
            self.data("processing", false);
            popup.find('.' + classes.delete_button).click(function() {
              $.m_tracking(null, trackings.close);
              close_popup(self, popup); 
              return false;
            });
          });
        });
      });
    };
  };


  function close_popup(self, popup, callback) {
    if(self.data("processing") == false) {
      self.data("processing", true);
      if(popup.is(':visible')) {
        var popup_wrapper = popup.find('.' + classes.popup_wrapper);
        var content = popup_wrapper.children('.' + classes.item_content);
        content.animate({opacity: 0}, "fast", "linear", function() {
          popup.animate({width: "0px", height: "0px", top: "+=120px", left: "+=205px"}, "fast", "swing", function() {
            popup.hide();
            self.find('.' + classes.opened).removeClass(classes.opened);
            self.data("processing", false);
            if(callback) { callback.call(popup); };
          });
        });
      } else {
        if(callback) { callback.call(popup); };
      };
    };
  };


  function open_edit(self) {
    if(self.data("processing") == false) {
      var popup = self.find('.' + classes.popup);
      close_popup(self, popup, function() {
        self.data("processing", true);
        var edit = self.find('.' + classes.edit);
        edit.css('opacity', 0).show().animate({'opacity': 1}, "fast", "linear", function() {
          self.data("processing", false);
        });
      });
    };
  };


  function close_edit(self, callback) {
    if(self.data("processing") == false) {
      self.data("processing", true);
      self.find('.' + classes.edit).animate({'opacity': 0}, "fast", "linear", function() { 
        $(this).hide(); 
        self.data("processing", false);
        if(callback) { callback.call(self); };
      });
    };
  };


  function save_edit(self) {
    var indexes = [];
    var selected_horoscopes_selector = self.find(':input:checked').map(function() { 
      var index = this.id.match(/selected_horoscope_(\d+)/)[1]; 
      indexes.push(index);
      return "." + classes.item + "_" + index
    }).get().join(", ");
    Astrology.cookies.data.horoscopes = indexes;
    Astrology.cookies.save();
    var list = self.find('.' + classes.list);
    list.find('.' + classes.item).css('opacity', 0).css('width', 0).hide();
    list.find(selected_horoscopes_selector).css('opacity', 1).css('width', raw_width_of_element + "px").show();
    make_list_continuous(self, list)
  };


  function show_tooltip(self, item) {
    var tooltip = self.find('.' + classes.tooltip);
    var item_tooltip = item.find('.' + classes.item_tooltip);
    var left = (width_of_element - 65) + (width_of_element * get_index_of_item(self, item));
    tooltip.empty().html(item_tooltip.html());
    tooltip.css('opacity', 0).css('left', left + "px").show().animate({'opacity': 1}, "fast");
  };


  function hide_tooltip(self, item) {
    var tooltip = self.find('.' + classes.tooltip);
    tooltip.animate({'opacity': 0}, "fast", "linear", function() { $(this).hide(); });
  };


  function remove_item(self, item) {
    show_remove_confirmation(self, item, function() {
      hide_item(self, item, function() {
        var list = self.find('.' + classes.list);

        var index = item.attr('class').match(new RegExp(classes.item + "_(\\d+)"))[1]; 
        Astrology.cookies.data.horoscopes = remove_item_from_array(Astrology.cookies.data.horoscopes, index);
        Astrology.cookies.save();
        self.find('#selected_horoscope_' + index).get(0).checked = false;

        var current_left = parseInt(list.css('left'));
        make_list_continuous(self, list, current_left);
      });
    });
  };


  function hide_item(self, item, callback) {
    item.animate({'opacity': 0, 'width': 0}, "fast", "linear", function() { 
      $(this).hide(); 
      if(callback) { callback.call(self); };
    });
  };


  function show_remove_confirmation(self, item, callback) {
    var header_title = item.find('.' + classes.item_header_title);
    var remove_window = self.find('.' + classes.remove);
    var remove_title = remove_window.find('.' + classes.remove_title);
    var left = -50 + width_of_element * get_index_of_item(self, item);
    remove_title.text(header_title.text());
    remove_window.css('opacity', 0).css('left', left).show().animate({'opacity': 1}, "fast", "linear", function() {
      var that = $(this);
      that.find('.' + classes.delete_button).click(function() { hide_remove_confirmation(self); return false; });
      that.find('.' + classes.cancel).click(function() { hide_remove_confirmation(self); return false; });
      that.find('.' + classes.remove_okay).click(function() { 
        hide_remove_confirmation(self, function() { 
          if(callback) { callback.call(item); };
        });
        return false; 
      });
    });
  };


  function hide_remove_confirmation(self, callback) {
    self.find('.' + classes.remove).animate({'opacity': 0}, "fast", "linear", function() { 
      $(this).hide(); 
      // Actually, argument (self) is not important here, just want to assign 'this' to something. 
      if(callback) { callback.call(self); };
    });
  };


  function toggle_arrows(self, list) {
    var next = self.find('.' + classes.next);
    var prev = self.find('.' + classes.prev);
    var not_cloned_items = list.children('.' + classes.item + ':visible').not('.cloned');
    if(not_cloned_items.size() > 4) {
      prev.show();
      next.show();
    } else {
      prev.hide();
      next.hide();
    };
  };


  function get_index_of_item(self, item) {
    var list = self.find('.' + classes.list);
    var items = list.children('.' + classes.item + ':visible');
    var index = items.index(item);
    var left = parseInt(list.css('left'));
    return (left / width_of_element) + index;
  };

  function remove_item_from_array(array, value) {
    var new_array = []; 
    for(var i = 0; i < array.length; i++) {
      if(array[i] != value) {
        new_array.push(array[i]);
      };
    };
    return new_array;
  };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.archives = function() {
  jQuery('#b-archives').b_archives();
};

(function($) {

  var classes = {
    self: 'b-archives',
    link_individual: 'b-read_more_link_',
    link_global: 'b-read_more_link',
    content_global: 'b-read_more_content',
    content: 'b-read_more_content_'
  };

  $.fn.b_archives = function() {
    var self = $(this);
    self.find("." + classes.link_global).each(function() {
      var link = $(this);
      link.mouseover (function () {
        self.find("." + classes.content_global).hide();
        self.find("." + classes.content + link.attr('class').split(" ")[1].toString().split("_")[3]).show();
      });
    });
    self.find("." + classes.content_global).each(function() {
      var link = $(this);
      link.mouseleave (function () {
        self.find("." + classes.content + link.attr('class').split(" ")[1].toString().split("_")[3]).hide();
      });
    });
  };

})(jQuery);// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.wheel = function() {
  jQuery('#b-wheel').b_wheel();
};

(function($) {
  
  var classes = {
    self: 'b-wheel',
    wheel: 'b-wheel_wheel',
    date_container: 'b-wheel_date-container',
    date_tooltip: 'b-wheel_date-container_tooltip',
    tooltip: 'b-wheel_tooltip',
    birthday_change: 'b-wheel_birthday-change',
    label: 'b-wheel_label'
  };

  var distances = [
    [360,60,120,180,240,300],
    [300,360,60,120,180,240],
    [240,300,360,60,120,180],
    [180,240,300,360,60,120],
    [120,180,240,300,360,60],
    [60,120,180,240,300,360]
  ];

  var coordinates = [ 
    [ 212, 120, 70, 80 ],
    [ 168, 40, 70, 80 ],
    [ 75, 34, 70, 80 ],
    [ 30, 115, 70, 80 ],
    [ 76, 193, 70, 80 ],
    [ 166, 198, 70, 80 ]
  ];

  $.fn.b_wheel = function(options) {
    var opts = $.extend({}, $.fn.b_wheel.defaults, options);
    return this.each(function() {
      var self = $(this);
      init_variables(self, opts);
      init_wheel(self);
      init_birthday_changing(self);
      init_random_spinning(self, self.data("wheel"));
      set_index(self, self.data("wheel"), 0);
    });
  };


  $.fn.b_wheel_rotate_random = function(time, easing) {
    var wheel_length = 6;
    var index = Math.round(Math.random() * (wheel_length - 1));
    this.b_wheel_rotate(index, time, easing);
  };


  $.fn.b_wheel_rotate = function(index, time, easing) {
    var self = this;
    var wheel = self.data('wheel');
    var time = time || 2000;
    var easing = easing || ">"; 
    wheel.selected_icon_bg.hide();
    wheel.selected_icon_set.hide();
    wheel.icon_set.show();
    var angle = distances[self.data("selected_index")][index];
    if(!self.data("is_wheel_running")) {
      self.data("is_wheel_running", true);
      var angle_with_cycles = angle + self.data("wheel_cycles");
      self.data("current_rotation", wheel.image.rotate());
      
      wheel.image.animate(
        { rotation: [wheel.image.rotate() + angle_with_cycles, 156, 156] },
        time,
        easing,
        function() { finish_animation(self, wheel, index); }
      );
      wheel.icon_set.animate(
        { rotation: [wheel.image.rotate() + angle_with_cycles, 156, 156] }, 
        time, 
        easing
      );				
    };
    wheel.raphael.safari();
    $.m_tracking(self);
  };


  function init_variables(self, opts) {
    self.data("is_wheel_running", false);
    self.data("current_rotation", null);
    self.data("selected_index", 0);
    self.data("selected_sign", 0);
    self.data("wheel", {});
    self.data("western_sign", self.parent().parent().find('.b-horoscopes').b_horoscopes_get_western_sign());
    self.data("chinese_sign", self.parent().parent().find('.b-horoscopes').b_horoscopes_get_chinese_sign());
    self.data("wheel_cycles", opts.wheel_cycles);
    var data = [
      {
        name: 'daily-overview', 
        image: "western/western_" + self.data("western_sign"), 
        tooltip: "Horoscope", 
        selected_coordinates: [ 212, 120, 70, 80 ] 
      },
      {
        name: 'daily-singles',
        image: "other/love",
        tooltip: "LoveScope",
        selected_coordinates: [ 212, 120, 70, 80 ]
      },
      {
        name: 'daily-finance',
        image: "other/career",
        tooltip: "FinanceScope",
        selected_coordinates: [ 212, 120, 70, 80 ]
      },
      {
        name: 'daily-chinese',
        image: "chinese/chinese_" + self.data("chinese_sign"),
        tooltip: "ChineseScope",
        selected_coordinates: [ 212, 120, 70, 80 ]
      },
      {
        name: 'daily-home-and-garden',
        image: "other/homeandgarden",
        tooltip: "HomeScope",
        selected_coordinates: [ 212, 120, 70, 80 ]
      },
      {
        name: 'yearly-overview',
        image: "other/yearly",
        tooltip: Astrology.display_year + " Horoscope",
        selected_coordinates: [ 212, 120, 70, 80 ]
      }
    ];
    // If given (by route) sign is chinese sign, then we need to set default state of the wheel to daily-chinese
    // I.e., we need to reorder data array - daily-chinese should be the first element of the array.
    if(Astrology.selected_signs == 'chinese') {
      for(var i = 0; i <= 2; i++) { 
        var item = data.shift();
        data.push(item);
      };
    };
    self.data("wheel_data", data);
  };


  function init_wheel(self) {
    var wheel_dom = self.find("." + classes.wheel).get(0);
    var wheel = {};
    wheel.raphael = Raphael(wheel_dom, 320, 320);
    wheel.image = wheel.raphael.image("/images/framework/block/wheel/wheelImage.png", 0, 0, 312, 312);	
    wheel.selected_icon_bg = init_selected_icon_bg(wheel);
    wheel.icon_set = init_icon_set(self, wheel, self.data("western_sign"), self.data("chinese_sign"));
    wheel.selected_icon_set = init_selected_icon_set(self, wheel, self.data("western_sign"), self.data("chinese_sign"));
    var circle_pointer = wheel.raphael.image("/images/framework/block/wheel/circlePointer.png", 104, 105, 113, 103);
    
    self.data("wheel", wheel);
  };

  
  function init_random_spinning(self, wheel) {
    var label = self.find('.' + classes.label);
    label.click(function() { 
      self.b_wheel_rotate_random();
      Astrology.refresh_banners();
      return false;
    });
  };

  function init_birthday_changing(self) {
    var tooltip = self.find("." + classes.date_tooltip);
    var date_container = self.find("." + classes.date_container);
    date_container.hover(function() { tooltip.fadeIn(); }, function() { tooltip.fadeOut(); });
  };


  function init_selected_icon_bg(wheel) {
    var selected_icon_bg = wheel.raphael.image("/images/framework/block/wheel/selected.png", 155, 83, 146, 148);
    selected_icon_bg.hide();
    return selected_icon_bg;
  };


  function init_icon_set(self, wheel, western_sign, chinese_sign) {
    var icon_set = wheel.raphael.set();
    images = []
    $.each(self.data("wheel_data"), function(index) {
      var coords = coordinates[index];
      images.push(wheel.raphael.image("/images/framework/block/wheel/" + this['image'] + ".png", coords[0], coords[1], coords[2], coords[3]));
    });
    icon_set.push(images[0], images[1], images[2], images[3], images[4], images[5]);
    var tooltip = $('.' + classes.tooltip);
    $(icon_set).each(function(index) {
      icon_set[index].click(function() {
        self.b_wheel_rotate(index);
        Astrology.refresh_banners();
      });
      icon_set[index].mouseover(function() {
        tooltip.text(self.data("wheel_data")[index]['tooltip']);
        tooltip.show(); 
      });
      icon_set[index].mousemove(function(icon) {
        var left_offset = -120;
        var top_offset = 12;
        var left = (icon.pageX || icon.clientX) + left_offset + 'px';
        var top = (icon.pageY || icon.clientY) + top_offset + 'px';
        tooltip.css({ left: left, top: top });
      });
      icon_set[index].mouseout(function() {
        tooltip.hide(); 
      });
    });
    return icon_set;
  };


  function init_selected_icon_set(self, wheel, western_sign, chinese_sign) {
    var selected_icon_set = wheel.raphael.set();
    images = []
    $.each(self.data("wheel_data"), function() {
      var coord = this['selected_coordinates'];
      images.push(wheel.raphael.image("/images/framework/block/wheel/" + this['image'] + "_lit.png", coord[0], coord[1], coord[2], coord[3]));
    });
    selected_icon_set.push(images[0], images[1], images[2], images[3], images[4], images[5]);
    selected_icon_set.hide();
    return selected_icon_set;
  };


  function finish_animation(self, wheel, index) {	
    set_index(self, wheel, index);
    self.data("is_wheel_running", false);
    change_to_selected_horoscope(self, index);
  };

  function set_index(self, wheel, index) {
    wheel.selected_icon_bg.show();
    wheel.icon_set[index].hide();
    wheel.selected_icon_set[index].show();
    self.data("selected_index", index);
  };

  function change_to_selected_horoscope(self, index) {
    var name = self.data("wheel_data")[index]['name'];
    self.parent().parent().find('.b-horoscopes').b_horoscopes_set_current_horoscope(name);
  };
 

  $.fn.b_wheel.defaults = {
    // set to 360 * (number of desired rotations)
    wheel_cycles: 360 * 2
  };

})(jQuery);




;Astrology.runners.blocks.blogs_carousel = function() {
  jQuery('#b-blogs_carousel').b_blogs_carousel();
};

(function($) {

  var classes = {
    prev: "b-blogs_carousel_prev",
    next: "b-blogs_carousel_next",
    items: "b-blogs_carousel_items",
    item: "b-blogs_carousel_item",
    blogs_hero: "b-blogs_hero"
  };

  $.fn.b_blogs_carousel = function(options) {
    var opts = $.extend({}, $.fn.b_blogs_carousel.defaults, options);
    return this.each(function() {
      var self = $(this);
      var list = self.find('.' + classes.items);
      self.pngFix();
      make_list_continuous(self, opts, list);
      init_slider(self, opts, list);
    });
  };


  function init_slider(self, opts, list) {
    self.find('.' + classes.next).click(function() { 
      move_list(self, opts, list, 'right'); 
      return false; 
    });
    self.find('.' + classes.prev).click(function() { 
      move_list(self, opts, list, 'left'); 
      return false; 
    });
  };


  function move_list(self, opts, list, direction) {
    if(self.data("processing") == false) {
      self.data("processing", true);
      var items = list.find('.' + classes.item).not('.cloned');
      var move_value = items.width();
      var left = (direction == 'left' ? '+' : '-') + '=' + move_value + 'px';
      list.animate({left: left}, "fast", "swing", function() {
        if(parseInt(list.css('left')) >= 0) {
          list.css('left', -(items.size() * items.width()).toString() + "px");
        } else if(parseInt(list.css('left')) <= -((items.size() + opts.visible_items) * items.width())) {
          list.css('left', -(opts.visible_items * items.width()).toString() + "px");
        };
        var middle = Math.round(opts.visible_items / 2);
        var index = Math.round(-(parseInt(list.css('left')) / items.width())) + middle;
        var current = list.find('.' + classes.item + ':eq(' + (index - 1) + ')');
        var nid = current.attr('id').match(/b-blogs_carousel_(\d+)/)[1];
        $.b_blogs_hero_show(nid);
        self.data("processing", false);
      });
    };
  };


  function make_list_continuous(self, opts, list) {
    list.children('.cloned').remove();
    var items = list.find('.' + classes.item);
    var cloned_start = items.slice(0, opts.visible_items).clone();
    var cloned_end = items.slice(-opts.visible_items).clone();
    cloned_start.addClass('cloned');
    cloned_end.addClass('cloned');
    list.prepend(cloned_end);
    list.append(cloned_start);
    var index = $.b_blogs_hero_visible_index();
    list.css('width', items.width() * list.find('.' + classes.item).size());
    list.css('left', (-items.width() * (opts.visible_items + index - Math.ceil(opts.visible_items/2))).toString() + "px");
    self.data("processing", false);
  };


  $.fn.b_blogs_carousel.defaults = {
    visible_items: 7
  };

})(jQuery);

(function($) {

  var classes = {
    self: 'b-blogs_hero',
    content: "b-blogs_hero_content"
  };

  $.b_blogs_hero_show = function(nid) {
    $('.' + classes.content).hide();
    $('#' + classes.self + '_' + nid).show();
  }

  $.b_blogs_hero_visible_index = function() {
    var element = $('.' + classes.content + ':visible');
    return $('.' + classes.content).index(element) + 1;
  };

})(jQuery);

;Astrology.runners.blocks.blogs_navigation = function() {
  jQuery('#b-blogs_navigation').b_blogs_navigation();
};

(function($) {

  var classes = {
    jump_form: "b-blogs_navigation_form"
  };


  $.fn.b_blogs_navigation = function(options) {
    return this.each(function() {
      var self = $(this);
      $('.' + classes.jump_form + ' select').change(function() { 
        var value = $(this).val();
        window.location.href = value;
        return false;
      });
    });
  };


})(jQuery);



;Astrology.runners.blocks.dreams_search = function() {
  jQuery('#b-dreams_search').b_dreams_search();
};

(function($) {

  var classes = {
    self: 'b-dreams_search',
    form: 'b-dreams_search_form',
    lightbox: 'b-dreams_search_lightbox',
    lightbox_close: 'b-dreams_search_lightbox_wrapper_close',
    search_input: 'b-dreams_search_form_text',
    spinner: 'b-dreams_search_spinner',
    item: 'b-dreams_letters_column_list_item'
  };

  $.fn.b_dreams_search = function() {
    return this.each(function() {
      var self = $(this);
      var lightbox = self.find('.' + classes.lightbox);
      var search_input = self.find('.' + classes.search_input);
      init_form_submitting(self, search_input, lightbox);
      init_hide_as_you_type(self, search_input);
      init_lightbox_close(self, lightbox);
    });
  };


  function init_form_submitting(self, search_input, lightbox) {
    var spinner = self.find('.' + classes.spinner);
    var form = self.find('.' + classes.form);
    form.submit(function() {
      spinner.show();
      $.ajax({
        type: "POST",
        url: "/dreams/search.js",
        data: { query: search_input.val() },
        success: function(data) { 
          window.location.href = data;
        },
        error: function() {
          spinner.hide();
          $('body').append(lightbox);
          lightbox.show();
          return false;
        }
      });
      return false;
    });
  };


  function init_hide_as_you_type(self, search_input) {
    var items = $.b_dreams_letters_items();
    if(items.size() > 0) {
      search_input.keyup(function() { hide_unmatched_dreams(search_input, items); });
    };
    hide_unmatched_dreams(search_input, items);
  };

  
  function hide_unmatched_dreams(search_input, items) {
    var value = search_input.val();
    items.show();
    items.each(function() {
      var that = $(this);
      var title = that.find('a').text();
      if(!title.match(new RegExp(value, 'i'))) {
        that.hide();
      };
    });
    $.b_dreams_letters_hide_empty_groups();
  };


  function init_lightbox_close(self, lightbox) {
    var lightbox_close = lightbox.find('.' + classes.lightbox_close);
    lightbox_close.click(function() {
      lightbox.hide();
      self.append(lightbox);
      return false;
    });
  };

})(jQuery);




(function($) {

  var classes = {
    group: 'b-dreams_letters_column_group',
    item: 'b-dreams_letters_column_list_item'
  };

  $.b_dreams_letters_items = function() {
    return $('.' + classes.item);
  };

  $.b_dreams_letters_hide_empty_groups = function() {
    var groups = $('.' + classes.group);
    groups.show();
    groups.each(function() {
      if($(this).find('.' + classes.item + ":visible").size() == 0) {
        $(this).hide();
      };
    });
  };

})(jQuery);




;Astrology.runners.blocks.quiz = function() {
  jQuery('#b-quiz').b_quiz();
};

(function($) {
  
  var classes = {
    form: 'b-quiz_content_form',
    question: 'b-quiz_content_form_question',
    answer: 'b-quiz_content_form_question_answer'
  };

    
  $.fn.b_quiz = function() {
    return this.each(function() {
      var self = $(this);
      var form = self.find('.' + classes.form);
      form.submit(function() {
        var checked_all = true;
        form.find('.' + classes.question).each(function() {
          var checked = false;
          $(this).find('.' + classes.answer + ' input').each(function() { 
            checked = checked || this.checked;
          });
          checked_all = checked_all && checked;
        });
        if(!checked_all) {
          $.notice_add({ text: "Please select some answer", type: 'error', stay: false });
          return false;
        } else {
          return true; 
        };
      });
    });
  };

})(jQuery);

// JavaScript Document

;(function($) {

  $.fn.b_ads728_hide = function() {
    return this.each(function() {
      var self = $(this); 
      self.css('visibility', 'hidden');
    });
  };

  $.fn.b_ads728_show = function() {
    return this.each(function() {
      var self = $(this); 
      self.css('visibility', 'visible');
    });
  };

})(jQuery);
;Astrology.runners.blocks.game_fortune = function() {
  jQuery('.b-game-fortune').b_game_fortune();
};

(function($) {

  var classes = {
    self: 'b-game-fortune',
    closed: 'b-game-fortune_closed',
    opened: 'b-game-fortune_opened',
    again: 'b-game-fortune_again',
    random_fortune: 'b-game-fortune_random-fortune'
  }
  
  $.fn.b_game_fortune = function() {
    var self = $(this);
    var closed = self.find('.' + classes.closed);
    var opened = self.find('.' + classes.opened);
    var random_fortune = self.find('.' + classes.random_fortune);
    var messages = random_fortune.find('li');
    var again = self.find('.' + classes.again);

    closed.click(function() {
      var random_number = Math.abs(Math.floor(Math.random() * messages.length));					
      opened.fadeIn('slow', function() {
        messages.filter(':eq(' + random_number + ')').fadeIn('slow');
      });
      closed.fadeOut('slow');
      again.css('visibility', 'visible');
      $.m_tracking(self);
      return false;
    });

    again.click(function() {
      opened.hide();
      closed.show();
      messages.hide();
      again.css('visibility', 'hidden');
      return false;
    });
  };


})(jQuery);
/*
 * ChartWheel block.
 *
 * Allows to show Natal and Transit Chartwheels. Representation of the Chartwheel is
 * contolled by CSS (mostly) and some JS settings.
 *
 * To create your own representation of the Chartwheel with name 'your-name':
 * 1. Create css file in 
 *   stylesheets/framework/block/chartwheel/your-name/b-chartwheel_your-name.css, 
 * and include it to your HTML. Change it as you need, using b-chartwheel_old.css
 * as example.
 *
 * 2. Add HTML to your layout (you can also add additional HTML elements if you need, 
 * but these elements are required):
 *   <div class="b-chartwheel b-chartwheel_your-name">
 *     <div class="b-chartwheel_wheel">
 *     </div>
 *     <div class="b-chartwheel_info">
 *     </div>
 *   </div>
 *
 * 3. Put planets data to somewhere in your code to window.b_chartwheel_your_name_planets:
 *  
 *   window.b_chartwheel_your_name_planets = {
 *     // Planets data...
 *   };
 *
 * 4. Add next JavaScript code:
 *   $('.b-chartwheel_your-name').b_chartwheel({
 *     // Your JSON settings here
 *   });
 *
 * You can use these Javascript settings. Default value is placed after colon, 
 * defaults are adjusted to old ChartWheel. All numbers are in pixels.
 *   { 
 *     // Show house sectors?
 *     show_house_sectors: true,
 *
 *     // Show zodiac signs?
 *     show_signs: true,
 *
 *     // Show aspect lines?
 *     show_aspects: true,
 *
 *     // Show Natal planets?
 *     show_natal_planets: true,
 *
 *     // Show Transit planets?
 *     show_transit_planets: true,
 *
 *     // Radius of circle from where lines of house sectors are started
 *     radius_of_inner_circle: 70,
 *
 *     // Radius of circle where lines of house sectors are ended
 *     radius_of_outer_circle: 165,
 *
 *     // Radius of circle of Natal Planets
 *     radius_of_natal_planets: 107, 
 *
 *     // Radius of circle of Transit Planets
 *     radius_of_transit_planets: 148,
 *
 *     // Radius of Zodiac Signs
 *     radius_of_signs: 176,
 *
 *     // Radius of numbers of house sectors
 *     radius_of_numbers: 81,
 *
 *     // Radius of circle where aspects are placed
 *     radius_of_aspects: 70,
 *
 *     // Distance from the cursor to the popup (tooltip)
 *     x_popup_offset: 20,
 *     y_popup_offset: 50,
 *
 *     // Color of house sectors lines
 *     line_color: 'yellow',
 *
 *     // Colors of aspect lines
 *     line_color_opposition: 'red',
 *     line_color_square: 'blue',
 *     line_color_trine: 'orange',
 *     line_color_semisquare: 'red',
 *
 *     // Offset from Asc planet to place of 'Asc' string (incremented to radius of Asc planet)
 *     offset_asc: 58,
 *
 *     // Offset from Mc planet to place of 'Mc' string (incremented to radius of Mc planet)
 *     offset_mc: 50,
 *
 *     // Offset (in degrees) from sector line to sector number
 *     offset_degrees_for_sector_numbers: 16,
 *
 *     // Offset (in degrees) for zodiac sign
 *     offset_degrees_for_sign: 15,
 *
 *     // Library for drawing. Allowed libraries are 'Raphael' and 'Wz_jsGraphics'
 *     drawer: 'Raphael'
 *   }
 *
 *  Example for HUGE chartwheel:
 *  $('.b-chartwheel_huge').b_chartwheel({   
 *    radius_of_inner_circle: 84,
 *    radius_of_outer_circle: 108,
 *    radius_of_aspects: 80,
 *    radius_of_signs: 95,
 *    radius_of_natal_planets: 120, 
 *    radius_of_transit_planets: 200,
 *    line_color: 'red'
 *  });
 *
 */

;Astrology.runners.blocks.chartwheel = function() {
  jQuery('#b-chartwheel_huge').b_chartwheel({   
    radius_of_inner_circle: 84,
    radius_of_outer_circle: 108,
    radius_of_aspects: 80,
    radius_of_signs: 95,
    radius_of_natal_planets: 120, 
    radius_of_transit_planets: 200,
    show_transit_planets: false,
    line_color: 'red'
  });
};

;Astrology.runners.blocks.chartwheel_example = function() {
  jQuery('#b-chartwheel_huge').b_chartwheel(window.b_chartwheel_huge_example);
};



(function($){ 

  var defaults = {
    // Show house sectors?
    show_house_sectors: true,

    // Show zodiac signs?
    show_signs: true,

    // Show aspect lines?
    show_aspects: true,

    // Show Natal planets?
    show_natal_planets: true,

    // Show Transit planets?
    show_transit_planets: true,

    // Radius of circle from where lines of house sectors are started
    radius_of_inner_circle: 70,

    // Radius of circle where lines of house sectors are ended
    radius_of_outer_circle: 165,

    // Radius of circle of Natal Planets
    radius_of_natal_planets: 107, 

    // Radius of circle of Transit Planets
    radius_of_transit_planets: 148,

    // Radius of Zodiac Signs
    radius_of_signs: 176,

    // Radius of numbers of house sectors
    radius_of_numbers: 81,

    // Radius of circle where aspects are placed
    radius_of_aspects: 70,

    // Distance from the cursor to the popup (tooltip)
    x_popup_offset: 20,
    y_popup_offset: 50,

    // Color of house sectors lines
    line_color: 'yellow',

    // Colors of aspect lines
    line_color_opposition: 'red',
    line_color_square: 'blue',
    line_color_trine: 'orange',
    line_color_semisquare: 'red',

    // Offset from Asc planet to place of 'Asc' string (incremented to radius of Asc planet)
    offset_asc: 58,

    // Offset from Mc planet to place of 'Mc' string (incremented to radius of Mc planet)
    offset_mc: 50,

    // Offset (in degrees) from sector line to sector number
    offset_degrees_for_sector_numbers: 16,

    // Offset (in degrees) for zodiac sign
    offset_degrees_for_sign: 15,

    // Library for drawing. Allowed libraries are 'Raphael' and 'Wz_jsGraphics'
    drawer: 'Raphael'
  };

  // 1 degree: 0.0175 radians
  var RAD = 0.0175;
  // These constants define types of aspect lines
  var OPPOSITION = 1;
  var SQUARE = 2;
  var TRINE =  3;
  var SEMISQUARE = 5;
  var MULTIPLIER_DEGREES_FOR_SIGN = 30;
      
  var SIGNS = [ 
    'aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 
    'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces' 
  ];

  var classes = {
    container: 'b-chartwheel',
    wheel: 'b-chartwheel_wheel',
    info: 'b-chartwheel_info',
    sign: 'b-chartwheel_sign',
    planet: 'b-chartwheel_planet',
    tooltip: 'b-chartwheel_tooltip',
    number: 'b-chartwheel_number',
    planet_data: 'b-chartwheel_planet-data',
    house_cusps: 'b-chartwheel_house-cusps',
    natal_text: 'b-chartwheel_natal-text',
    natal_to_transit_aspects: 'b-chartwheel_natal-to-transit-aspects'
  };


  // Init function. You should use only this one outside the plugin
  $.fn.b_chartwheel = function(options) {
    var opts = $.extend({}, defaults, options);
    this.each(function() {
      var chartwheel = new ChartWheel($(this), opts);
      chartwheel.draw_bi_wheel();
    });
  };

  
  // *** Public methods
  // 
  // Initialize the ChartWheel
  window.ChartWheel = function(self, opts, planets) {
    this.opts = opts;
    this.container = self;
    this.name = self.attr('class').match(/.*_([a-zA-Z0-9\-]*)$/)[1];
    this.planets = window['b_chartwheel_' + this.name.replace('-', '_') + '_planets'];
    this.wheel = self.find('.' + classes.wheel);
    this.info = self.find('.' + classes.info);
    this.drawer = eval("new " + opts.drawer + "(this.wheel.get(0), opts.wheel_size);");
    // Get asc from ascendant natal planet's longitude
    if(this.planets.natal_planets) { 
      this.asc = this._get_asc(this.planets.natal_planets) 
    };
    this.wheel_size = this.wheel.width();
    this.wheel_center = Math.round(this.wheel_size / 2) - 1;
  };
    
    
  // Draw the Wheel. Should be called after initialization of the ChartWheel
  ChartWheel.prototype.draw_bi_wheel = function() {
    if(this.opts.show_house_sectors)   { this._draw_houses(); };
    if(this.opts.show_signs)           { this._draw_signs(); };
    if(this.opts.show_transit_planets) { this._draw_planets(this.planets.transit_planets, this.opts.radius_of_transit_planets, 'transit'); };
    if(this.opts.show_natal_planets)   { this._draw_planets(this.planets.natal_planets, this.opts.radius_of_natal_planets, 'natal'); };
    if(this.opts.show_aspects)         { this._draw_aspects(); };
    this.drawer.paint();
  }


  ChartWheel.prototype.show_planet_data = function() {
    var chartwheel = this;
    var planets = chartwheel.planets;
    if(planets.natal_planets && planets.transit_planets) {
      var output = '<table class="' + classes.planet_data + '"><tr>';
      output += '<th class="planet">Planet</th>';
      output += '<th class="natal-longitude">Natal Longitude</th>';
      output += '<th class="transit-longitude">Transit Longitude</th></tr>';
      $.each(planets.natal_planets, function(index) {
        var planet = this;
        if(planet.name != 'vertex') {
          output += '<tr><td class="planet">' + planet.name + '</td>';
          output += '<td class="natal-longitude">' + planet.zodiac_long + '</td>'; 
          output += '<td class="transit-longitude">' + planets.transit_planets[index].zodiac_long + '</td></tr>';
        };
        output += '</table>';
        chartwheel.info.append(output);
      });
    };
  };


  ChartWheel.prototype.show_house_cusps = function() {
    var chartwheel = this;
    var planets = chartwheel.planets;
    if(planets.natal_cusps) {
      var output = '<table class="' + classes.house_cusps + '"><tr>';
      output += '<th class="cusp">Cusp</th><th class="long">long</th></tr>';
      $.each(planets.natal_cusps, function(index) {
        if(index != 0) { // Skip first cusp
          var natal_cusp = this;
          output += '<tr><td class="cusp">House No: ' + index + '</td><td class="long">' + natal_cusp + '</td></tr>';
        };
      });
      output += '</table>';
      chartwheel.info.append(output);
    };
  };


  ChartWheel.prototype.show_natal_text = function() {
    var chartwheel = this;
    var planets = chartwheel.planets;
    if(planets.natal_planets) {
      var output = "<div class='" + classes.natal_text + "'>"
      $.each(planets.natal_planets, function() {
        var planet = this;
        if(planet.name != 'vertex') { // Skip vertex planet
          output += '<h3 class="planet-name">' + planet.name + '</h3>';
          if (planet.text.sign_text) {
            output += '<h4 class="sign_header">' + planet.text.sign_text.entry_header + '</h4>';
            output += '<p class="sign_text">' + planet.text.sign_text.entry_text + "</p>" ;
          };
          if (planet.text.house_text) {
            output += '<h4 class="house_header">' + planet.text.house_text.entry_header + '</h4>';
            output += '<p class="house_text">' + planet.text.house_text.entry_text + "</p>";
          };             
          if (planet.text.aspect_text && planet.text.aspect_text.length > 0) {
            output += '<h4 class="aspects">Natal Aspects for ' + planet.name + "</h4>";
            $.each(planet.text.aspect_text, function() {
              var text = this;
              output += '<h5 class="aspect_header">' + text.entry_index;
              output += ' -- ' +  text.entry_header + "</h5>";
              output += '<p class="aspect_text">' + text.entry_text  + "</p>";
            });
          };		      
        };
      });
      output += "</div>";
      chartwheel.info.append(output);
    };
  };


  ChartWheel.prototype.show_natal_to_transit_aspects = function() {
    var chartwheel = this;
    var planets = chartwheel.planets;
    if(planets.aspects) {
      var output = "<div class='" + classes.natal_to_transit_aspects + "'>"
      $.each(planets.aspects, function() {
        var aspect = this;
        var aspect_name = aspect[0];
        var aspect_contents = aspect[1];
        output += '<h3 class="aspects_header">Apects for ' + aspect_name + "</h3>";
        $.each(aspect_contents, function() {
          var content = this;
          aspect_text += "<h4 class='aspect_header'>" + content.entry_index + ' -- ' + content.entry_header + "</h4>";
          aspect_text += "<p class='aspect_text'>" + content.entry_text + "</p>";
        });
      });
      output += "</div>";
      chartwheel.info.append(output);
    };
  };

  // *** Private methods




  // ** Aspects draw module
  
  ChartWheel.prototype._draw_aspects = function() {
    var planets = this.planets.natal_planets;
    var chartwheel = this;
    $.each(planets, function() {
      var planet = this;
      $.each(planet.aspects, function() {
        var aspect_type = this[0];
        var aspect_planet = this[1];
        var color;
        switch (aspect_type) {
          case OPPOSITION: color = chartwheel.opts.line_color_opposition; break;
          case SQUARE: color = chartwheel.opts.line_color_square; break; 
          case TRINE: color = chartwheel.opts.line_color_trine; break;
          case SEMISQUARE: color = chartwheel.opts.line_color_semisquare; break;
        }
        // Don't do conjunctions or the south node. TODO: Why?!!! :)
        if(color && aspect_planet != 11) {
          var x = chartwheel.wheel_center;
          var y = x;
          var start_angle = planet.angle;
          var end_angle = planets[aspect_planet].angle;
          var radius = chartwheel.opts.radius_of_aspects;
          var start_coordinates = chartwheel._convert_polar_to_cartesian_coordinates(
            {center: {x: x, y: y}, angle: start_angle, length: radius}
          );
          var end_coordinates = chartwheel._convert_polar_to_cartesian_coordinates(
            {center: {x: x, y: y}, angle: end_angle, length: radius}
          );
          chartwheel.drawer.line(start_coordinates.x, start_coordinates.y, end_coordinates.x, end_coordinates.y, color);
        };
      });
    });
  };

  // ** End of Aspect draw module



  // ** Planets draw module.
  
  ChartWheel.prototype._draw_planets = function(planets, radius, type){
    if(!planets) { return null; }
    var chartwheel = this;
    var planet_wrapper = $("<div class='" + classes.planet + "_" + type + "'></div>");
    chartwheel.wheel.append(planet_wrapper);
    $.each(planets, function(i) {
      var planet = this;
      // Should not show vertex planet, because it is not used in the ChartWheel 
      // and it is just imaginary point
      if(planet.name != 'vertex') {
        // Create DOM object. It will look like: 
        // <div class="b-chartwheel_planet b-chartwheel_planet_sun"></div>
        var planet_dom = $(
          "<div class='" + classes.planet +  " " + classes.planet + "_" + planet.name.replace(' ', '-') + "'></div>"
        );
        planet_wrapper.append(planet_dom);
        planet_size = planet_dom.width();

        switch(planet.name) {
          case 'ascendant': 
            planet_dom.text('Asc'); 
            var planet_radius = radius + chartwheel.opts.offset_asc;
            break;
          case 'midheaven': 
            planet_dom.text('Mc'); 
            var planet_radius = radius + chartwheel.opts.offset_mc;
            break;
          default:
            bind_planet_tooltip(chartwheel, planet, planet_dom, type);
            var planet_radius = radius;
            break;
        };

        // Generate cartesian coordinates from given angle 
        var x = chartwheel.wheel_center - planet_size / 2;
        var y = x;
        var coordinates = chartwheel._convert_polar_to_cartesian_coordinates({ center: { x: x, y: y }, angle: planet.angle, length: planet_radius });

        // Assign these coordinates according to planet name
        planet_dom
          .css('top', coordinates.y.toString() + 'px')
          .css('left', coordinates.x.toString() + 'px');
      };
    });
    return planets;
  };

  function bind_planet_tooltip(chartwheel, planet, planet_dom, type) {
    if(type == 'natal') { // && planet.text && planet.text.sign_text) {
      //var text = '<strong>' + planet.text.sign_text.entry_header + '</strong><br />' + planet.text.sign_text.entry_text;
      var text = '<strong>' + planet.name + '</strong>: ' + planet.zodiac_long + '<br />' + '<strong>long</strong>: ' + planet.longitude;
      chartwheel._bind_tooltip(planet_dom, text)
    } else if(type == 'transit') {
      var text = '<strong>' + planet.name + ': ' + planet.zodiac_long + '</strong><br/>';
      chartwheel._bind_tooltip(planet_dom, text)
    };
  };


  // ** End of Planets draw module

    
  
  // ** House sectors and numbers draw module
  
  ChartWheel.prototype._draw_houses = function() {
    var chartwheel = this;
    if(this.planets.natal_cusps) {
      $.each(this.planets.natal_cusps, function(i) {
        if(i != 0) { // Skip first element
          draw_house_line(chartwheel, this);
          draw_house_number(chartwheel, this, i);
        };
      });
    };
  };

  function draw_house_line(chartwheel, natal_cusp) {
    var x = chartwheel.wheel_center;
    var y = x;
    var angle = natal_cusp - chartwheel.asc
    var start_coordinates = chartwheel._convert_polar_to_cartesian_coordinates(
      {center: {x: x, y: y}, angle: angle, length: chartwheel.opts.radius_of_inner_circle}
    );
    var end_coordinates = chartwheel._convert_polar_to_cartesian_coordinates(
      {center: {x: x, y: y}, angle: angle, length: chartwheel.opts.radius_of_outer_circle}
    );
    chartwheel.drawer.line(start_coordinates.x, start_coordinates.y, end_coordinates.x, end_coordinates.y, chartwheel.opts.line_color);
  };

  function draw_house_number(chartwheel, natal_cusp, number) {
    var number_dom = $("<div class='" + classes.number + "'>" + number + "</div>");
    chartwheel.wheel.append(number_dom);
    var x = chartwheel.wheel_center - number_dom.width() / 2;
    var y = x;
    var angle = natal_cusp - chartwheel.asc + chartwheel.opts.offset_degrees_for_sector_numbers;
    var coordinates = chartwheel._convert_polar_to_cartesian_coordinates(
      {center: {x: x, y: y}, angle: angle, length: chartwheel.opts.radius_of_numbers}
    );
    number_dom
      .css('top', coordinates.y.toString() + 'px')
      .css('left', coordinates.x.toString() + 'px');
  };

  // ** End of House sectors and numbers draw module



  // ** Signs draw module

  ChartWheel.prototype._draw_signs = function() {
    var chartwheel = this;
    $.each(SIGNS, function(i) {
      var sign = this;

      // Will look like: <div class="b-chartwheel_sign b-chartwheel_sign_aries"></div>
      var sign_dom = $("<div class='" + classes.sign +  " " + classes.sign + "_" + sign + "'></div>");
      $(chartwheel.wheel).append(sign_dom);
      sign_size = sign_dom.width();

      chartwheel._bind_tooltip(sign_dom, "Sign: " + sign)

      var x = chartwheel.wheel_center - sign_size / 2;
      var y = x;
      var angle = ((i * MULTIPLIER_DEGREES_FOR_SIGN) + chartwheel.opts.offset_degrees_for_sign) - chartwheel.asc;
      var length = chartwheel.opts.radius_of_signs;
      var coordinates = chartwheel._convert_polar_to_cartesian_coordinates({ center: { x: x, y: y }, angle: angle, length: length });

      sign_dom
        .css('top', coordinates.y.toString() + 'px')
        .css('left', coordinates.x.toString() + 'px')
    });
  };

  // ** End of signs draw module
 


  // ** Auxiliary functions

  ChartWheel.prototype._get_asc = function(planets) {
    var asc;
    $.each(planets, function() { 
      if(this.short_name == 'asc') { asc = this.longitude } 
    });
    return asc;
  };


  // Converts polar coordinates to cartesian coordinates. It receives 'polar' hash with format:
  // { center: { x: 0, y: 0 }, angle: 10, length: 10 }
  // and return 'cartesian' hash with format:
  // { x: 0, y: 0 }
  ChartWheel.prototype._convert_polar_to_cartesian_coordinates = function(polar) {
    var cartesian = {};
    if (polar.angle < 0) {
      polar.angle += 360;
    }
    if (polar.angle > 360) {
      polar.angle -= 360;
    }
    if (polar.angle == 180) {
      cartesian.x = polar.center.x + length;
      cartesian.y = polar.center.y;
    } else {
      switch (Math.floor(Math.abs(polar.angle) / 180)) {
        case 0:
          cartesian.x = polar.center.x - Math.round(Math.cos(Math.abs(polar.angle) * RAD) * polar.length);     
          cartesian.y = polar.center.y + Math.round(Math.sin(Math.abs(polar.angle) * RAD) * polar.length);
          break;
        case 1:
          cartesian.x = polar.center.x + Math.round(Math.cos((Math.abs(polar.angle) - 180) * RAD) * polar.length);     
          cartesian.y = polar.center.y - Math.round(Math.sin((Math.abs(polar.angle) - 180) * RAD) * polar.length);
          break;
      };
    };
    return cartesian;	
  }
  
  
  // Bind events for tooltips
  ChartWheel.prototype._bind_tooltip = function(planet_dom, text) {
    var chartwheel = this;
    var tooltip = $("<p class='" + classes.tooltip + "_" + chartwheel.name + "'>" + text + "</p>");
    planet_dom.hover(
      function(e) {
        $('body').append(tooltip);
        tooltip
          .css("top", (e.pageY - chartwheel.opts.y_popup_offset) + "px")
          .css("left", (e.pageX + chartwheel.opts.x_popup_offset) + "px")
          .fadeIn("fast");
      },
      function() {
        tooltip.remove();
      }
    );	
    planet_dom.mousemove(function(e) {
      tooltip
        .css("top", (e.pageY - chartwheel.opts.y_popup_offset) + "px")
        .css("left", (e.pageX + chartwheel.opts.x_popup_offset) + "px");
    });
  }
 

  // Raphael drawing module
  var Raphael = function(container, size) {
    this.drawer = window.Raphael(container, size, size);
  };
  Raphael.prototype.line = function(x1, y1, x2, y2, color) {
    this.drawer.path({stroke: color}).moveTo(x1, y1).lineTo(x2, y2);
  };
  Raphael.prototype.paint = function() { };

  
  // wz_jsGraphics drawing module 
  var Wz_jsGraphics = function(container, size) {
    this.drawer = new jsGraphics(container);
  };
  Wz_jsGraphics.prototype.line = function(x1, y1, x2, y2, color) {
    this.drawer.setColor(color);
    this.drawer.drawLine(x1, y1, x2, y2);
  };
  Wz_jsGraphics.prototype.paint = function() {
    this.drawer.paint();
  }
    
  // ** End of auxiliary functions
  
})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.bagua_board = function() {
  jQuery('#b-bagua-board').b_bagua_board();
};

(function($) {

  var classes = {
    board: 'b-bagua-board_board',
    original: 'b-bagua-board_description_original',
    description: 'b-bagua-board_description'
  }
  
  $.fn.b_bagua_board = function(options) {
    return this.each(function() {
      var self = $(this);
      var board = self.find('.' + classes.board);
      var links = board.find('a');
      var description = self.find('.' + classes.description);
      links.mouseover(function() { 
        var type = $(this).attr('class');
        board.attr('class', classes.board + " " + classes.board + "_" + type);
        description.find('li').hide();
        description.find('.' + classes.description + "_" + type).show();
      });
      links.mouseout(function() { 
        board.attr('class', classes.board);
        description.find('li').hide();
        description.find('.' + classes.original).show();
      });
    });
  };

})(jQuery);

// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.hero = function() {
  jQuery('#b-hero').b_hero();
};

(function($) {
  
  var classes = {
    self: 'b-hero',
    select_box: 'b-hero_select-sign_select',
    content: 'b-hero_right_content',
    selected_sign: 'selected-sign',
    left: 'b-hero_left'
  };
  
  $.fn.b_hero = function() {
    return this.each(function() {
      var self = $(this);
      var select_box = self.find('.' + classes.select_box);
      var content = self.find('.' + classes.content);
      select_box.change(function() {
        var sign = $(this).val();
        if(sign != "") {
          var selected_text = content.find('li.' + sign);
          if(selected_text.size() > 0) {
            content.children('li').removeClass(classes.selected_sign);
            selected_text.addClass(classes.selected_sign);
            var left_image = self.find('.' + classes.left + ' img');
            var src = left_image.attr('src');
            var changed_src = src.replace(/\/\w+.png/, '/' + sign + '.png');
            left_image.attr('src', changed_src);
          };
        };
      });
    });
  };

})(jQuery);
Astrology.runners.blocks.slideshow = function () {
    jQuery('#b-slideshow').b_slideshow();
};

(function ($) {

    var classes = {
        single: 'b-slideshow_controls_switcher_single',
        all: 'b-slideshow_controls_switcher_all',
        slices_container: 'b-slideshow_slices',
        thumbnails_container: 'b-slideshow_thumbnails',
        slice: 'b-slideshow_slice',
        thumbnail: 'b-slideshow_thumbnail',
        prev: 'b-slideshow_slice_image_prev',
        next: 'b-slideshow_slice_image_next',
        selected: 'selected',
        single_selected: 'b-slideshow_controls_switcher_single_selected',
        all_selected: 'b-slideshow_controls_switcher_all_selected'
    };


    function set_selected_thumbnail(self, slice) {
        var reg_exp = new RegExp(classes.slice + "_(\\d+)");
        var id = slice.attr('class').match(reg_exp)[1];
        self.find('.' + classes.thumbnails_container + ' td').removeClass(classes.selected);
        var selected_thumbnail = self.find('.' + classes.thumbnail + '_' + id);
        selected_thumbnail.closest('td').addClass(classes.selected);
    }


    function show_thumbnails(self, thumbnails_container, slices_container) {
        slices_container.fadeOut(400, function () { 
            thumbnails_container.fadeIn(400);
        });
        self.find('.' + classes.all).addClass(classes.all_selected);
        self.find('.' + classes.single).removeClass(classes.single_selected);
        return false;
    }


    function show_slices(self, thumbnails_container, slices_container) {
        thumbnails_container.fadeOut(400, function () { 
            slices_container.fadeIn(400);
        });
        self.find('.' + classes.single).addClass(classes.single_selected);
        self.find('.' + classes.all).removeClass(classes.all_selected);
        return false;
    }


    function show_slice(self, link, thumbnails_container, slices_container, slices) {
        show_slices(self, thumbnails_container, slices_container);
        var reg_exp = new RegExp(classes.thumbnail + "_(\\d+)");
        var id = link.attr('class').match(reg_exp)[1];
        slices.hide();
        var selected_slice = slices_container.find('.' + classes.slice + "_" + id);
        set_selected_thumbnail(self, selected_slice);
        selected_slice.show();
        return false;
    }


    function show_previous_slice(self, link, slices) {
        var slice = link.closest('.' + classes.slice);
        slices.hide();
        set_selected_thumbnail(self, slice.prev());
        slice.prev().show();
        return false;
    } 


    function show_next_slice(self, link, slices) {
        var slice = link.closest('.' + classes.slice);
        slices.hide();
        set_selected_thumbnail(self, slice.next());
        slice.next().show();
        return false;
    }


    $.fn.b_slideshow = function () {
        return this.each(function () {
            var self = $(this);
            var single = self.find('.' + classes.single);
            var all = self.find('.' + classes.all);
            var thumbnails_container = self.find('.' + classes.thumbnails_container);
            var slices_container = self.find('.' + classes.slices_container);
            var thumbnails = thumbnails_container.find('.' + classes.thumbnail);
            var slices = slices_container.find('.' + classes.slice);
            single.click(function () {
                return show_slices(self, thumbnails_container, slices_container);
            });
            all.click(function () {
                return show_thumbnails(self, thumbnails_container, slices_container);
            });
            if (Astrology.iframe_ads) {
                thumbnails.click(function () {
                    var link = $(this);
                    Astrology.refresh_banners();
                    show_slice(self, link, thumbnails_container, slices_container, slices);
                    return false;
                });
                self.find('.' + classes.prev).click(function () { 
                    var link = $(this);
                    Astrology.refresh_banners();
                    show_previous_slice(self, link, slices);
                    return false;
                });
                self.find('.' + classes.next).click(function () { 
                    var link = $(this);
                    Astrology.refresh_banners();
                    show_next_slice(self, link, slices);
                    return false;
                });
            }
            set_selected_thumbnail(self, slices.filter(':visible'));
        });
    };



})(jQuery);



;Astrology.runners.blocks.syndication_twitter = function() {
  jQuery('#b-syndication_twitter').b_syndication_twitter();
};

(function($) {

  var classes = {
    select: 'b-syndication_twitter_select',
    chinese: 'b-syndication_twitter_content_chinese',
    western: 'b-syndication_twitter_content_western',
    follow: 'b-syndication_twitter_follow'
  };

  $.fn.b_syndication_twitter = function(options) {
    return this.each(function() {
      var self = $(this);
      var select = self.find('.' + classes.select);
      var chinese = self.find('.' + classes.chinese);
      var western = self.find('.' + classes.western);
      select.change(function() {
        var value = $(this).val();
        if(value == "Chinese") {
          western.hide();
          chinese.show();
        } else {
          western.show();
          chinese.hide();
          var follow_buttons = western.find('.' + classes.follow);
          follow_buttons.each(function() { 
            var sign = $(this).attr('href').match(/\w+_(\w+)$/)[1];
            $(this).attr('href', 'http://twitter.com/' + value + '_' + sign);
          });
        };
      });
    });
  };

})(jQuery);
// Popup window for changing user's birthdate or looking at friend's birthdate (p.91 of F.Spec)
// You have to pass 'opener' to b_popup_birthdate_changer (jQuery object, the parent container 
// of the b-popup-birthdate-changer block, if user clicks on them, the window will be opened).
;Astrology.runners.blocks.popup_birthdate_changer = function() {
  var kaleidoscope = jQuery('#b-wheel');
  kaleidoscope.find('.b-popup-birthdate-changer').b_popup_birthdate_changer({
    opener: kaleidoscope.find('.b-wheel_date-container')  
  });

  var hero_numerology = jQuery('#b-hero');
  hero_numerology.find('.b-popup-birthdate-changer').b_popup_birthdate_changer({
    opener: hero_numerology.find('.b-hero_birthdate_edit')  
  });
};

(function($) {
  
  var classes = {
    close_text: 'b-popup-birthdate-changer_close-text',
    close_sign: 'b-popup-birthdate-changer_close-sign'
  };

  $.fn.b_popup_birthdate_changer = function(options) {
    return this.each(function() {
      var self = $(this);
      init(self, options);
    });
  };


  function init(self, options) {
    options.opener.click(function() { self.parent().show(); return false; });
    self.find("." + classes.close_sign).click(function() { self.parent().hide(); return false; });
    self.find("." + classes.close_text).click(function() { self.parent().hide(); return false; });
  };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
Astrology.runners.blocks.match_com = function () {
    jQuery('#b-match-com_300-250').b_match_com({ cols: 4, rows: 2, 'autoshow': false });
    jQuery('#b-match-com_300-600').b_match_com({ cols: 4, rows: 3, 'autoshow': true  });
    jQuery('#b-match-com_636-300').b_match_com({ cols: 4, rows: 3, 'autoshow': true  });
};

(function ($) {
  
    var classes = {
        self: 'b-match-com',
        form: 'b-match-com_form',
        state: 'b-match-com_state',
        rating: 'b-match-com_rating',
        new_search: 'b-match-com_new-search',
        popup: 'b-match-com_random-person_popup',
        random_persons: 'b-match-com_random-persons',
        random_person: 'b-match-com_random-person',
        random_person_image: 'b-match-com_random-person_image',
        matched_persons: 'b-match-com_matched-persons',
        matched_person: 'b-match-com_matched-person',
        matched_person_image: 'b-match-com_matched-person_image',
        matched_person_image_selected: 'b-match-com_matched-person_image_selected',
        matched_person_name: 'b-match-com_matched-person_name',
        details_close: 'b-match-com_details_close',
        details_image: 'b-match-com_details_image',
        details_name: 'b-match-com_details_name',
        details_age: 'b-match-com_details_age',
        details_seekinggender: 'b-match-com_details_seekinggender',
        details_rating: 'b-match-com_details_rating',
        details_body: 'b-match-com_details_body',
        details_url: 'b-match-com_details_url',
        spinner: 'b-match-com_spinner',
        banner_id: 'b-match-com_banner-id',
        ice: 'b-match-com_ice'
    };


    function init_new_search(self, opts) {
        self.find('.' + classes.new_search).click(function () {
            self.find('.' + classes.state + '_1').show();
            self.find('.' + classes.state + '_2').remove();
            self.find('.' + classes.state + '_3').hide();
            return false;
        });
    }


    function find_person_by_id(self, id) {
        var data = self.data("data");
        for (var item in data) {
            if (parseInt(data[item].id, 10) === parseInt(id, 10)) {
                return data[item];
            }
        }
    }


    function get_id_of_person_with_max_rating(self, opts) {
        var data = self.data("data");
        var person = {};
        var rating = 0;
        for (var item in data) {
            if (data.hasOwnProperty(item)) {
                var data_rating = parseInt(data[item].rating, 10);
                if (data_rating > rating) {
                    person = data[item];
                    rating = data_rating;
                }
            }
        }
        return person.id;
    }


    function select_matched_person(self, opts, id) {
        var td = self.find('#' + classes.matched_person + '_' + id);

        // Set border around image
        self.find('.' + classes.matched_person_image + ' img').removeClass(classes.matched_person_image_selected);
        td.find('.' + classes.matched_person_image + ' img').addClass(classes.matched_person_image_selected);

        var state_3 = self.find('.' + classes.state + '_3');
        var item = find_person_by_id(self, id);
        state_3.find('.' + classes.details_image + ' img').attr('src', item.image);
        state_3.find('.' + classes.details_image + ' img').attr('alt', item.name);
        state_3.find('.' + classes.details_name).text(item.name);
        state_3.find('.' + classes.details_age).text(item.age + "-year-old " + item.gender);
        state_3.find('.' + classes.details_seekinggender).text('seeking ' + item.seekinggender);
        state_3.find('.' + classes.details_rating).text(item.rating + "% compatible");
        state_3.find('.' + classes.details_body).text(item.body);
        state_3.find('.' + classes.details_url).attr('href', item.url);

        self.find('.' + classes.state + '_1').hide();
        state_3.show();
    }


    function build_table_of_matched_persons(self, opts, data) {
        var html =  "<div class='" + classes.state + "_2'>";
        html +=   "<table class='" + classes.matched_persons + "' cellpadding='0' cellspacing='0'>";
        for (var i = 0; i < opts.rows; i = i + 1) {
            html += "<tr>";
            for (var j = 0; j < opts.cols; j = j + 1) {
                var item = data[j + (i * opts.cols)];
                if (item) {
                    html += "<td class='" + classes.matched_person + "' id='" + classes.matched_person + "_" + item.id + "'>";
                    html += "<a href='" + item.url + "' class='" + classes.matched_person_image + "' target='_blank'>";
                    html += "<img src='" + item.image + "' alt='" + item.name + "' />";
                    html += "</a>";
                    html += "<a href='" + item.url + "' class='" + classes.matched_person_name + "' target='_blank'>";
                    html += item.name;
                    html += "</a>";
                    html += "<div class='" + classes.rating + " " + classes.rating + "_" + item.rating_stars + "'></div>";
                    html += "</td>";
                }
            }
            html += "</tr>";
        }
        html += "</table>";
        html += "<a href='#' class='" + classes.new_search + "'>New search</a>";
        
        self.append(html);
        self.find('.' + classes.state + '_1').hide();
        self.find('.' + classes.state + '_2').show();
        self.find('.' + classes.state + '_3').hide();
        init_new_search(self, opts);

        if (data.length > 0 && opts.autoshow) {
            var id = get_id_of_person_with_max_rating(self, opts);
            select_matched_person(self, opts, id);
        }
    }


    function init_submit(self, opts) {
        var form = self.find('.' + classes.form);
        form.submit(function () {
            if ($.m_validations_validate_all(form)) {
                var spinner = self.find('.' + classes.spinner);
                spinner.show();
                $.ajax({
                    url: "/match-com.js", 
                    dataType: "json",
                    data: {
                        banner_id: self.find('.' + classes.banner_id).text(),
                        ice: self.find('.' + classes.ice).text(),
                        who: form.find('#who').val(),
                        zip: form.find('#user_zip').val(),
                        year: form.find('#user_birth_date_1_1i').val(),
                        month: form.find('#user_birth_date_1_2i').val(),
                        day: form.find('#user_birth_date_1_3i').val()
                    },
                    success: function (data) {
                        spinner.hide();
                        self.data("data", data);
                        build_table_of_matched_persons(self, opts, data);
                    }
                });
            }
            return false;
        });
    }

    function init_details(self, opts) {
        self.find('.' + classes.matched_person_image + ', .' + classes.matched_person_name).live('click', function () {
            var td = $(this).closest('td');
            var id = td.attr('id').match(/(\d+)$/)[1];
            select_matched_person(self, opts, id);
            return false;
        });
    }


    function init_details_close(self, opts) {
        self.find('.' + classes.details_close).click(function () {
            // Remove borders around images
            self.find('.' + classes.matched_person_image + ' img').removeClass(classes.matched_person_image_selected);

            self.find('.' + classes.state + '_1').hide();
            self.find('.' + classes.state + '_2').show();
            self.find('.' + classes.state + '_3').hide();
            return false;
        });
    }


    function hide_popups(self, opts) {
        self.find('.' + classes.popup).hide();
    }


    function show_popup(self, opts, image) {
        hide_popups(self, opts);
        image.closest('.' + classes.random_person).find('.' + classes.popup).show();
    }


    function move_popup(self, opts, image, e) {
        var random_persons = image.closest('.' + classes.random_persons);
        var popup = image.closest('.' + classes.random_person).find('.' + classes.popup);
        var image_offset = image.offset();
        var random_offset = random_persons.offset();
        if (popup.attr("class").match(/_right$/)) {
            popup.css({
                left: (image_offset.left - random_offset.left + 46) + 'px', 
                top: (image_offset.top - random_offset.top - 2) + 'px'
            });
        } else {
            popup.css({
                left: (image_offset.left - random_offset.left - 142) + 'px', 
                top: (image_offset.top - random_offset.top - 2) + 'px'
            });
        }
    }


    function init_popups(self, opts) {
        var image = self.find('.' + classes.random_person_image);
        image.mouseover(function () {
            show_popup(self, opts, $(this));
        });
        image.mousemove(function (e) {
            move_popup(self, opts, $(this), e);
        });
        image.mouseout(function () {
            hide_popups(self, opts);
        });
    }

  
    $.fn.b_match_com = function (options) {
        var opts = $.extend({}, $.fn.b_match_com.defaults, options);
        return this.each(function () {
            var self = $(this);
            init_submit(self, opts);
            init_popups(self, opts);
            init_details(self, opts);
            init_details_close(self, opts);
        });
    };

    $.fn.b_match_com.defaults = {
    };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.comments = function() {
  jQuery('#b-comments').b_comments();
};

(function($) {

  var classes = {
    self: 'b-comments',
    text: 'b-comments_item_text_data',
    visible: 'b-comments_item_text_visible',
    omission: 'b-comments_item_text_omission',
    invisible: 'b-comments_item_text_invisible',
    show: 'b-comments_item_text_show',
    hide: 'b-comments_item_text_hide',
    flag: 'b-comments_item_text_flag'
  }
  
  $.fn.b_comments = function() {
    return this.each(function() {
      var self = $(this);
      init_hiding_comments(self);
      init_flags(self);
    });
  };


  function init_hiding_comments(self) {
    self.find("." + classes.text).each(function() {
      var comment = $(this);
      var show_link = comment.find("." + classes.show);
      var hide_link = comment.find("." + classes.hide);
      var visible = comment.find("." + classes.visible);
      var invisible = comment.find("." + classes.invisible);
      var omission = comment.find("." + classes.omission);
      show_link.click(function() {
        omission.hide();
        show_link.hide();
        hide_link.show();
        invisible.show();
        return false;
      });
      hide_link.click(function() {
        omission.show();
        show_link.show();
        hide_link.hide();
        invisible.hide();
        return false;
      });
    });
  };


  function init_flags(self) {
    self.find("." + classes.flag + " a").click(function() {
      var href_match = $(this).attr("href").toString().match(/#(\d+)$/);
      if(href_match) {
        var cid = href_match[1];
        $(this).fadeOut(function() { $(this).fadeIn(); });
        $.post("/comments/" + cid + "/flag.js", { "_method": "put" });
      };
      return false;
    });
  };

})(jQuery);

// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.mood_meter = function() {
  jQuery('#b-mood-meter_a').b_mood_meter({ bg: '.l-top-content' });
};

(function($) {
  
  var classes = {
    self: 'b-mood-meter',
    info: 'b-mood-meter_info', 
    handle: 'b-mood-meter_handle',
    mood: 'b-mood-meter_mood'
  };
  
  $.fn.b_mood_meter = function(options) {
    var opts = $.extend({}, $.fn.b_mood_meter.defaults, options);
    return this.each(function() {
      var self = $(this);
      init_slider(self, opts);
    });
  };

  function init_slider(self, opts) {
    var default_value = opts.default_value;
    var value = parseInt(Astrology.cookies.data.mood_meter);
    if (isNaN(value)) {
      value = default_value;
    }
    var handle = self.find('.' + classes.handle);
    var list = self.find('.' + classes.info).children();
    if(list.size() > 0) {
      update_page(self, list, value, opts);
      handle.slider({
        min: 0,
        max: 9,
        step: 1,
        values: [value],
        slide: function(event, ui) {
          if (update_page(self, list, ui.values[0], opts)) {
            Astrology.cookies.data.mood_meter = ui.values[0];
            Astrology.cookies.save();
          };
        }
      });
    };
  };

  function update_page(self, list, value, opts) {
    var bg = self.closest(opts.bg);
    if (list.eq(value)) {
      var setting_string = list.eq(value).text();
      var settings = setting_string.split('|')
      bg.css('background-color', settings[0]);
      self.find('.' + classes.mood).text('the mood is ' + settings[1]);
      return true;
    } else {
      return false;
    };
  }

  $.fn.b_mood_meter.defaults = {
    default_value: 6
  };

})(jQuery);
(function($) {

  var classes = {
    forecast: 'b-products_details_price_forecast'
  };

  $.b_products_details_get_forecast_value = function() {
    return $('.' + classes.forecast + ' input[name=flength]:checked').val();
  };

})(jQuery);





// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.astro_header = function() {
  jQuery('#b-astro-header').b_astro_header();
};

(function($) {

  var classes = {
    navigation: 'b-astro-header_menu',
    dropdown_item: 'b-astro-header_item_dropdown',
    hover: 'b-astro-header_hover',
    submenu: 'b-astro-header_item_sub'
  }
  
  $.fn.b_astro_header = function(options) {
    return this.each(function() {
      var self = $(this);
      var a = self.find("." + classes.dropdown_item);
      a.hoverIntent({
        sensitivity: 7,
        interval: 250, 
        over: function() {
          $('.b-ads_Top_Banner').b_ads728_hide();
          $(this).addClass(classes.hover); //Add background color + image on hovered list item
          $(this).find("." + classes.submenu).show(); //Show the subnav
        },
        timeout: 200,
        out: function() {
          $(this).removeClass(classes.hover); //Add background color + image on hovered list item
          $(this).find("." + classes.submenu).hide(); //Hide the subnav
          $('.b-ads_Top_Banner').b_ads728_show();
        }
      });
    });
  };

})(jQuery);
Astrology.runners.blocks.hat = function () {
    jQuery('#b-hat').b_hat();
};

(function ($) {

    var classes = {
        popup: 'b-hat_popup',
        close: 'b-hat_popup_close',
        signup: 'b-hat_popup_signup',
        signin: 'b-hat_popup_signin',
        forgot: 'b-hat_popup_forgot',
        settings: 'b-hat_popup_settings',
        signin_link: 'b-hat_right_item_signin-link',
        signup_link: 'b-hat_right_item_signup-link',
        settings_link: 'b-hat_right_item_settings-link'
    };

    function init_open_popup(self, name) {
        self.find('.' + classes[name + "_link"]).click(function () {
            self.find('.' + classes.popup).hide();
            self.find('.' + classes[name]).show();
            return false;
        });
    }


    function init_close_popups(self) {
        self.find('.' + classes.close).click(function () {
            self.find('.' + classes.popup).hide();
            return false;
        });
    }


    $.fn.b_hat = function (options) {
        return this.each(function () {
            var self = $(this);
            classes.forgot_link = $.b_profile_hat_get_forgot_link_class();
            init_open_popup(self, 'signin');
            init_open_popup(self, 'signup');
            init_open_popup(self, 'forgot');
            init_open_popup(self, 'settings');
            init_close_popups(self);
        });
    };


})(jQuery);
/* script for zener card start */
jQuery(function($) {
			
  var total_tries = 25; // configure number of total tries from here...
  var tries = 0;
  var hits = 0;
  var prcntg = null;

  // configure result text from here...
  var resultArray = ['You are not psychic' ,
             'You are a tiny bit psychic' ,
             'You are mad' ,
             'Please take consultation from the doctor :D'
             ];


  InitZenerCard();


  function InitZenerCard(){
    tries = 0;
    hits = 0;
    $('#Progress').find('div').width(0+'%');
    $('#Tries').html(tries);
    $('#Mathces').html(hits);
    $('#MainCard').attr('src',"/images/framework/block/game-zener-card/MainCard.png");
    $('#OptionCards li').attr('class','');
    $('#TryAgainButton').css('display', 'none');
    $('#ShowResultButton').css('display', 'none');
    $('#Correct').hide();
    $('#NotCorrect').hide();
    $('#Lock').hide();
  }


  /* check the clicked option and decide if it is true or not */
  function CheckClick(selectedItem, randomItem){
      if(selectedItem == randomItem){
        hits++;
        $('#Mathces').html(hits);
        $('#Correct').fadeIn();
      }else{
        $('#NotCorrect').fadeIn();
      }
  }
  /* updating the progress bar when user click on the card */
  function UpdateProgressBar(currentNum){
    var percent = Math.floor((currentNum/total_tries)*100);
    $('#Progress').find('div').width(percent+'%');
  }

  /* binding function with each card */
  $('#OptionCards li').each(function(index){
        $(this).find('a').click(function(){
          if(tries != total_tries){
            tries++;
            $('#OptionCards li').attr('class','');
            $('#OptionCards').find('li').eq(index).attr('class','Selected');
            
            $('#Lock').show();
            
            var randomCardNum = Math.abs(Math.floor(Math.random()*5));
              UpdateProgressBar(tries);
              $('#Tries').html(tries);
              $('#MainCard').attr('src',"/images/framework/block/game-zener-card/AnswerCard"+eval(randomCardNum+1)+".png");
              
              CheckClick(index, randomCardNum);
              
              if(tries == total_tries){
                $('#ShowResultButton').fadeIn();
                }else{
                $('#TryAgainButton').fadeIn();	
              }
              
          }
            return false;
        })
  })

  /* button handlers */
  $('#TryAgainButton').click(function(){ NextTry(); return false; })
  $('#ShowResultButton').click(function(){ ShowResult(); return false; })
  $('#ResetGame').click(function(){ ResetGame(); return false; })


  function ResetGame(){
    $('#Result').fadeOut('slow', function(){ 
      $('#MainCardArea').fadeIn(); 
      InitZenerCard();	
    });	
  }

  function NextTry(){
      $('#OptionCards li').attr('class','');
      $('#TryAgainButton').fadeOut();
      $('#Correct').fadeOut();
      $('#NotCorrect').fadeOut();
      $('#MainCard').attr('src',"/images/framework/block/game-zener-card/MainCard.png");
      $('#Lock').hide();
  }

  function CalculatePercentage(){
    prcntg = (hits/total_tries)*100;
    return Math.ceil(prcntg);
  }


  function ShowResult(){

    if(CalculatePercentage < 40){
     $('#ResultMessage').html(resultArray[0]);
    }
    if((CalculatePercentage < 40) && (CalculatePercentage > 60)){
     $('#ResultMessage').html(resultArray[1]);	
    }
    if((CalculatePercentage < 60) && (CalculatePercentage > 80)){
     $('#ResultMessage').html(resultArray[2]);	
    }
    
    if((CalculatePercentage < 80) && (CalculatePercentage > 100)){
     $('#ResultMessage').html(resultArray[3]);	
    }
    
    $('#MainCardArea').fadeOut('slow', function(){
          $('#Result').fadeIn();								
    });
  }

  /*function ShowResult(){

    if(hits < 10){
     $('#ResultMessage').html(resultArray[0]);
    }
    if((hits < 10) && (hits > 15)){
     $('#ResultMessage').html(resultArray[1]);	
    }
    if((hits < 15) && (hits > 20)){
     $('#ResultMessage').html(resultArray[2]);	
    }
    
    if((hits < 20) && (hits > 25)){
     $('#ResultMessage').html(resultArray[3]);	
    }
    
    $('#MainCardArea').fadeOut('slow', function(){
          $('#Result').fadeIn();								
    });
  }*/

});

/* script for zener card end */
// JavaScript Document
jQuery(function($) {
var Over = false;
$('#b-game-ballon_BalloonGame').mousemove(function (e) {
									  	
	var mx = e.pageX-0;
	var my = e.pageY - $('#b-game-ballon_ThumbPin').height()-3;
		$('#b-game-ballon_ThumbPin').css({left: mx+'px', top: my+'px'});
		$('#b-game-ballon_ThumbPin').show();
});

$('#b-game-ballon_ThumbPin').mouseover(function(){ $('#b-game-ballon_ThumbPin').show(); })
$('#b-game-ballon_BalloonGame').mouseout(function() { $('#b-game-ballon_ThumbPin').hide() })

var zIndex = 500;
var stateArray=[true, true, true, true, true, true]
$('.b-game-ballon_Balloon').each(function(index){		
		$('.b-game-ballon_Balloon').eq(index).click(function(){
			if(stateArray[index]){
				stateArray[index] = false;
				var randomNum = Math.round(Math.random()* 100);
					var thisWidth = $(this).width();
					$(this).find('.b-game-ballon_State1').animate({ width: (thisWidth+10)+"px", left: (-5)+"px" }, 200, "linear", function(){
						$('.b-game-ballon_Balloon').eq(index).css('z-index', ++zIndex);
						$('.b-game-ballon_Balloon').eq(index).find('label').show();
						$('.b-game-ballon_Balloon').eq(index).find('label').html(randomNum);
						$('.b-game-ballon_Balloon').eq(index).find('.b-game-ballon_State2').show();
						$('.b-game-ballon_Balloon').eq(index).find('.b-game-ballon_State1').hide();
						try{
							PlaySound();
						}
						catch(e){

						}
					});
			}		
			})
		})


});

// get the flash movie
function getMovieName(movieName) {
		if (navigator.appName.indexOf("Microsoft") != -1) {
			return window[movieName];
    	}else {
    		return document[movieName];
    	}
}	 

//sending to flash...
function PlaySound(){
	if(getMovieName("sound")!= null){
		getMovieName("sound").CallPlaySound();	
	}
}
// JavaScript Document
;Astrology.runners.blocks.game_balloon = function() {
  jQuery('.b-game-balloon').b_game_balloon();
};


(function($) {

  var classes = {
    board: 'b-game-balloon_board',
    pin: 'b-game-balloon_pin',
    balloon: 'b-game-balloon_balloon',
    state: 'b-game-balloon_state',
    again: 'b-game-balloon_again',
    mute: 'b-game-balloon_mute'
  };


  $.fn.b_game_balloon = function(options) {
    var opts = $.extend({}, $.fn.b_game_balloon.defaults, options);
    return this.each(function() {
      var self = $(this); 
      init_pin(self, opts);
      init_balloons(self, opts);
      init_try_again(self, opts);
      init_sound(self, opts);
    });
  };


  function init_pin(self, opts) {
    var board = self.find('.' + classes.board);
    var pin = self.find('.' + classes.pin);
    pin.mouseover(function() { pin.show(); });
    board.mouseout(function() { pin.hide(); });
    board.mousemove(function (e) {
      var mx = e.pageX - 0;
      var my = e.pageY - pin.height() - 3;
      pin.css({left: mx + 'px', top: my + 'px'});
      pin.show();
    });
    pin.appendTo('body');
  };


  function init_balloons(self, opts) {
    var balloons = self.find('.' + classes.balloon)
    balloons.click(function(){		
      var balloon = $(this);
      if(balloon.data('state') != 'opened') {
        balloon.data('state', 'opened');
        var random_number = Math.round(Math.random() * 100);
        var state1 = balloon.find('.' + classes.state + '1');
        var state2 = balloon.find('.' + classes.state + '2');
        state1.animate({ width: "+=10px", left: "-=5px" }, 200, "linear", function() {
          var label = balloon.find('label');
          opts.z_index += 1;
          balloon.css('z-index', opts.z_index);
          label.html(random_number);
          label.show();
          state2.show();
          state1.hide();
          play_sound(self, opts);
        });
      };
    });
  };


  function init_try_again(self, opts) {
    self.find('.' + classes.again).click(function() {
      self.find('.' + classes.state + '1').show();
      self.find('.' + classes.state + '2').hide();
      self.find('label').hide();
      self.find('.' + classes.balloon).each(function() { 
        var balloon = $(this);
        if(balloon.data('state') == 'opened') {
          balloon.find('.' + classes.state + '1').animate({ width: "-=10px", left: "+=5px" }, 0, "linear");
        };
        balloon.data('state', 'closed'); 
      });
      return false;
    });
  };


  function init_sound(self, opts) {
    var mute_link = self.find('.' + classes.mute);
    mute_link.text(opts.sound ? "Mute" : "Unmute");
    mute_link.click(function() {
      opts.sound = !opts.sound;
      $(this).text(opts.sound ? "Mute" : "Unmute");
      return false;
    });
  };


  function play_sound(self, opts) {
    if(opts.sound) {
      var element = embed_template(opts.sound_url);
      element.appendTo("body");
      setTimeout(function() { element.remove(); }, 2000);
    }
  };


  function embed_template(src) {
    if($.browser.msie) {
      return $('<bgsound/>').attr({ src: src, loop: 1, autostart: true });
    } else {
      return $('<embed style="height: 0" loop="false" src="' + src + '" autostart="true" hidden="true" />');
    };
  };


  $.fn.b_game_balloon.defaults = {
    z_index: 500,
    sound: false,
    sound_url: '/send.wav'
  };

})(jQuery);
//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2007 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion()
{
	var version;
	var axo;
	var e;

	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}

	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";

			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";

			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");

		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];

        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}

function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblclick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}
/*global init_you_not_you_switcher, init_description_popups, init_forecast_length_retriever */
// Description of the block. Please, show example of HTML of the block here
Astrology.runners.blocks.profile_product = function () {
    jQuery('#b-profile_product').b_profile_product();
};

(function ($) {
  
    var classes = {
        self: 'b-profile_product',
        for_who: 'b-profile_for-who',
        for_you: 'b-profile_for-you',
        not_for_you: 'b-profile_not-for-you',
        your_info: 'b-profile_your-info',
        email_row: 'b-profile_email-wrapper'
    };
    
    $.fn.b_profile_product = function () {
        return this.each(function () {
            var self = $(this);
            init_you_not_you_switcher(self);
            init_forecast_length_retriever(self);
        });
    };


    function show_or_hide_your_info(self, for_you, your_info) {
        var email_row = self.find('.' + classes.email_row);
        var email_value = email_row.find('#user_email');
        if (for_you.get(0).checked) {
            your_info.hide();
            your_info.find('#your_name').get(0).disabled = true;
            your_info.find('#your_email').get(0).disabled = true;
            email_row.show();
            if (!Astrology.logged_in) {
                email_value.get(0).disabled = false;
            }
        } else {
            your_info.show();
            your_info.find('#your_name').get(0).disabled = false;
            if (!Astrology.logged_in) {
                your_info.find('#your_email').get(0).disabled = false;
            }
            email_row.hide();
            email_value.get(0).disabled = true;
        }
    }


    function init_you_not_you_switcher(self) {
        var for_you = self.find('.' + classes.for_you);
        var not_for_you = self.find('.' + classes.not_for_you);
        var your_info = self.find('.' + classes.your_info);

        show_or_hide_your_info(self, for_you, your_info);
        for_you.click(function () { 
            show_or_hide_your_info(self, for_you, your_info);
        });
        not_for_you.click(function () { 
            show_or_hide_your_info(self, for_you, your_info); 
        });
    }


    function init_forecast_length_retriever(self) {
        var form = self.find("form");
        form.submit(function () {
            var forecast_value = $.b_products_details_get_forecast_value();
            if (forecast_value) {
                var period_and_price = forecast_value.match(/(.*)_(.*)/);
                var flength = self.find('input[name=flength]');
                var amount = self.find('input[name=amount]');
                if (flength.size() === 0) {
                    flength = $('<input type="hidden" name="flength" />');
                    form.append(flength);
                }
                flength.val(period_and_price[1]);
                amount.val(period_and_price[2]);
            }
            return true;
        });
    }


})(jQuery);

(function ($) {

    $.b_profile_hat_get_forgot_link_class = function () {
        return "b-profile_hat_signin_forgot-link";
    };

})(jQuery);
// Description of the block. Please, show example of HTML of the block here
;Astrology.runners.blocks.horoscopes_horoscopes = function() {
  jQuery('#b-horoscopes_horoscopes').b_horoscopes_horoscopes();
};

(function($) {
  
  var classes = {
    last: 'b-horoscopes_other-date_last',
    next: 'b-horoscopes_other-date_next',
    featured: 'b-horoscopes_featured'
  };


  var trackings = {
    date_click: 'ast:horoscopes:hero-anotherdate',
    featured_link_click: 'ast:horoscopes:hero-miniperslist'
  };

    
  $.fn.b_horoscopes_horoscopes = function() {
    return this.each(function() {
      var self = $(this);
      init_links_tracking(self);
    });
  };


  function init_links_tracking(self) {
    self.find('.' + classes.last).click(function() { $.m_tracking(null, trackings.date_click); return true; });
    self.find('.' + classes.next).click(function() { $.m_tracking(null, trackings.date_click); return true; });
    self.find('.' + classes.featured + ' a').click(function() { $.m_tracking(null, trackings.featured_link_click); return true; });
  };

 
})(jQuery);


// Description of the block. Please, show example of HTML of the block here
(function($) {
  
  var classes = {
    self: 'b-horoscopes',
    another_sign: 'b-horoscopes_another-sign',
    chinese_sign: 'b-horoscopes_chinese-sign',
    western_sign: 'b-horoscopes_western-sign',
    big: 'b-horoscopes_big',
    current_sign: 'b-horoscopes_current-sign',
    current_type: 'b-horoscopes_current-type',
    horoscopes: 'horoscopes',
    header: 'b-horoscopes_header',
    sign: 'sign',
    selected_horoscopes: 'selected-horoscopes'
  };
    
  $.fn.b_horoscopes_get_chinese_sign = function() {
    var chinese_horoscopes = this.find('.daily-chinese');
    var selected_sign_dom = chinese_horoscopes.find('.' + classes.sign);
    var sign;
    if(selected_sign_dom.size() > 0) {
      sign = selected_sign_dom.attr('class').match(/sign (\w+)/)[1];
    };
    return sign;
  };

  $.fn.b_horoscopes_get_western_sign = function() {
    var western_horoscopes = this.find('.daily-overview');
    var selected_sign_dom = western_horoscopes.find('.' + classes.sign);
    var sign;
    if(selected_sign_dom.size() > 0) {
      sign = selected_sign_dom.attr('class').match(/sign (\w+)/)[1];
    };
    return sign;
  };


  $.fn.b_horoscopes_set_current_horoscope = function(name) {
    return this.each(function() {
      var self = $(this);
      self.find('.' + classes.horoscopes).removeClass(classes.selected_horoscopes);
      self.find('.' + name).addClass(classes.selected_horoscopes);
    });
  };
 
})(jQuery);




;Astrology.runners.blocks.psychics_categories = function() {
  jQuery('#b-psychics_categories').b_psychics_categories();
};

(function($) {

  var classes = {
    self: 'b-psychics_categories',
    list: 'b-psychics_categories_list'    
  };

  $.fn.b_psychics_categories = function() {
    return this.each(function() {
      var self = $(this);
      var list = self.find('.' + classes.list);
      list.find('a').click(function() {
        var that = $(this);
        var id = that.attr('href').match(/category_id=(\d+)/)[1];
        $('.b-psychics_listings').b_psychics_listings_show(id);
        that.fadeOut('slow', function() { $(this).fadeIn(); });
        return false;
      });
    });
  };

})(jQuery);




;Astrology.runners.blocks.psychics_listings = function() {
  jQuery('#b-psychics_listings').b_psychics_listings();
};

(function($) {

  var classes = {
    link: 'b-psychics_listings_pagination a',
    spinner: 'b-psychics_listings_pagination_spinner'
  }

  $.fn.b_psychics_listings = function() {
    return this.each(function() {
      var self = $(this);
      var link = self.find('.' + classes.link);
      link.live('click', function() { 
        var spinner = self.find('.' + classes.spinner);
        spinner.show();
        self.load($(this).attr('href') + " .b-psychics_listings", function() { spinner.hide(); });
        return false;
      });
    });
  };
 

  $.fn.b_psychics_listings_show = function(id) {
    this.load("/psychics.js?category_id=" + id + " .b-psychics_listings");
  };

})(jQuery);
