diff --git a/alt/functions-alt.php b/alt/functions-alt.php
new file mode 100644
index 0000000..e1d8302
--- /dev/null
+++ b/alt/functions-alt.php
@@ -0,0 +1,34 @@
+ $priority) {
+
+ // has_action returns int for the priority
+ if ( $priority = has_action( $hook, $function ) ) {
+
+ // If there's a function hooked in, remove the genesis_* function
+ // from whichever hook we're looping through at the time.
+ remove_action( $hook, $function, $priority );
+ }
+ }
+}
+
+/**
+ * Add navigation menu to the top.
+ *
+ * @since 1.1.0
+ */
+function gs_navigation( $location, $args ) {
+ if ( ! has_nav_menu( $location ) )
+ return;
+
+ $defaults = array(
+ 'theme_location' => $location,
+ 'container_id' => $location . '-nav',
+ 'container_class' => 'menu',
+ );
+
+ $args = wp_parse_args( $args, $defaults );
+
+ return wp_nav_menu( $args );
+}
+
+add_action( 'after_setup_theme', 'gs_responsive', 5 );
+/**
+ * Utilize the dormant Genesis 2.0.0 Responsive Functions.
+ */
+function gs_responsive() {
+
+ if ( current_theme_supports( 'genesis-responsive' ) ) {
+ add_action( 'wp_head', 'genesis_responsive_viewport' );
+ add_action( 'wp_enqueue_scripts', 'genesis_enqueue_responsive_stylesheet' );
+ }
+}
+
+/**
+ * Utilize the dormant Genesis 2.0.0 Responsive Functions.
+ *
+ * @see wp_default_scripts() for min/dev pattern.
+ *
+ * @param string $script Script filename basename.
+ * @param string $suffix Script suffix: 'css' or 'js'
+ * @param string $min Minimization abbreviation. Default = '.min'.
+ * @param string $dev Development abbreviation. Default = ''.
+ */
+function gs_script_suffix( $script, $suffix = 'js', $min = '.min', $dev = '' ) {
+ if ( 'js' != $suffix && 'css' != $suffix )
+ $suffix = 'js';
+
+ $script = ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) ? $script . "$dev.$suffix" : $script . "$min.$suffix";
+
+ return $script;
+}
+
+add_action( 'admin_notices', 'gs_theme_files_to_edit' );
+/**
+ * Remove the specific theme files from the Theme Editor
+ *
+ * @since 1.1.0
+ *
+ * @global array $allowed_files Array of allowed files.
+ * @global WP_Theme Object $theme Current Theme WP_Theme Object.
+ * @global string $current_screen Reference to current screen.
+ */
+function gs_theme_files_to_edit() {
+
+ global $allowed_files, $theme, $current_screen;
+
+ /** Check to see if we are on the editor page */
+ if ( 'theme-editor' == $current_screen->id ) {
+ /** Do not change anything if we are in the Genesis theme */
+ if ( $theme->Name == CHILD_THEME_NAME ) {
+ /** Remove files */
+ foreach ( array( 'functions-alt.php', 'lib/init-alt.php', 'lib/init.php' ) as $f )
+ unset( $allowed_files[ $f ] );
+ }
+ }
+
+}
+
+/*
+ * Usage for a custom post type named 'movies':
+ * unregister_post_type( 'movies' );
+ *
+ * Usage for the built in 'post' post type:
+ * unregister_post_type( 'post', 'edit.php' );
+ *
+ * To be used on admin_menu hook.
+*/
+function gs_unregister_post_type( $post_type, $slug = '' ){
+
+ global $wp_post_types;
+
+ if ( isset( $wp_post_types[ $post_type ] ) ) {
+ unset( $wp_post_types[ $post_type ] );
+
+ $slug = ( !$slug ) ? 'edit.php?post_type=' . $post_type : $slug;
+ remove_menu_page( $slug );
+ }
+}
+
+/**
+ * Edit excerpt read more link
+ *
+ * @param string $more Read More Text, , default: ' ' . '[...]'
+ * @return string Modified Read More Text.
+ */
+function gs_remove_excerpt_more( $more ) {
+ return '...';
+}
+
+/**
+ * Edit read more link.
+ *
+ * @param string $link HTML Read More Link, default: sprintf( '… %s ', get_permalink(), $more_link_text = '(more...)' ).
+ * @return string Modified HTML Read More Link.
+ */
+function gs_read_more_link( $link ) {
+ return 'Read More ';
+}
+
+/**
+ * Custom header callback.
+ *
+ * It outputs special CSS to the document head, modifying the look of the header
+ * based on user input.
+ */
+function gs_header_style() {
+ /** If no options set, don't waste the output. Do nothing. */
+ if ( HEADER_TEXTCOLOR == get_header_textcolor() && HEADER_IMAGE == get_header_image() )
+ return;
+
+ /** Header image CSS */
+ $output = sprintf( '#title-area { background: url(%s) #0a84c9 no-repeat; }', esc_url( get_header_image() ) );
+
+ /** Header text color CSS, if showing text */
+ if ( 'blank' != get_header_textcolor() )
+ $output .= sprintf( '#title a, #title a:hover, #description { color: #%s; }', esc_html( get_header_textcolor() ) );
+
+ printf( '', $output );
+
+}
+
+/**
+ * Register a custom admin callback to display the custom header preview with the
+ * same style as is shown on the front end.
+ *
+ * @see genesis_custom_header_admin_style() For comparison & the default genesis-custom-background admin callback function.
+ */
+function gs_admin_style() {
+
+ $headimg = sprintf( '.appearance_page_custom-header #headimg { background: url(%s) no-repeat; font-family: Georgia, Times, serif; min-height: %spx; text-align: center; text-shadow: #666 1px 1px; }', get_header_image(), HEADER_IMAGE_HEIGHT );
+ $h1 = sprintf( '#headimg h1, #headimg h1 a { color: #%s; font-size: 48px; font-variant: small-caps; font-weight: normal; line-height: 48px; margin: 35px 0 0; text-decoration: none; }', esc_html( get_header_textcolor() ) );
+ $desc = sprintf( '#headimg #desc { color: #%s; font-size: 20px; font-style: italic; line-height: 1; margin: 0; }', esc_html( get_header_textcolor() ) );
+
+ printf( '', $headimg, $h1, $desc );
+
+}
+
+add_action( 'init', 'gs_register_scripts' );
+/**
+ * Registers Appropriate Scripts and Styles when needed based on Debugging.
+ * Assumes that the normal *.min.js/*.min.css is the minified version & *.js is beautified version.
+ * To make the styles appear AFTER your base style, in the array(), place sanitize_title_with_dashes( CHILD_THEME_NAME )
+ * so that: array( sanitize_title_with_dashes( CHILD_THEME_NAME ) )
+ * e.g., wp_register_style( 'gs-twitter-bootstrap', CHILD_CSS . '/' . gs_script_suffix( 'bootstrap', 'css' ), array( sanitize_title_with_dashes( CHILD_THEME_NAME ) ), '1.0.0' );
+ *
+ * @uses wp_enqueue_script() WP adds JS to page safely.
+ * @uses gs_script_suffix() Adds proper CSS/JS suffix based on WP_DEBUG or SCRIPT_DEBUG
+ */
+function gs_register_scripts() {
+
+ /**
+ * Twitter Bootstrap CSS
+ * @link http://www.bootstrapcdn.com/?v=10292012225705
+ * @link http://twitter.github.com/bootstrap/
+ */
+ wp_register_style( 'gs-twitter-bootstrap', CHILD_CSS . '/' . gs_script_suffix( 'bootstrap', 'css' ), array(), '1.0.0' );
+ // Twitter Bootstrap Responsive may conflict with your child theme
+ //wp_register_style( 'gs-twitter-bootstrap-responsive', CHILD_CSS . '/' . gs_script_suffix( 'bootstrap-responsive', 'css' ), array( 'gs-twitter-bootstrap' ), '1.0.0' );
+ wp_register_style( 'gs-twitter-bootstrap-cdn', '//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css', array(), '2.2.2' );
+
+ // Twitter Bootstrap CSS (Font Awesome version)
+ wp_register_style( 'gs-twitter-bootstrap-font-awesome', '//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css', array(), '2.1.1' );
+
+ /**
+ * Twitter Bootstrap JS
+ * @link http://www.bootstrapcdn.com/?v=10292012225705
+ * @link http://twitter.github.com/bootstrap/
+ */
+ wp_register_script( 'gs-twitter-bootstrap', CHILD_JS . '/' . gs_script_suffix( 'bootstrap', 'js' ), array( 'jquery' ), '2.2.2' );
+ wp_register_script( 'gs-twitter-bootstrap-cdn', '//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/js/bootstrap.min.js', array( 'jquery' ), '2.2.2' );
+
+ /**
+ * Font Awesome
+ * @link http://www.bootstrapcdn.com/?v=10292012225705
+ * @link http://fortawesome.github.com/Font-Awesome/
+ */
+ wp_register_style( 'gs-font-awesome', CHILD_CSS . '/' . gs_script_suffix( 'bootstrap', 'css' ), array(), '1.0.0' );
+ wp_register_style( 'gs-font-awesome-cdn', '//netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css', array(), '2.2.2' );
+ wp_register_style( 'gs-font-awesome-ie7', CHILD_CSS . '/' . gs_script_suffix( 'bootstrap', 'css' ), array(), '1.0.0' );
+ wp_register_style( 'gs-font-awesome-ie7-cdn', '//netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome-ie7.css', array(), '2.2.2' );
+
+ /**
+ * Pretty Photo
+ * @link http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/
+ * @link http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/documentation
+ */
+ wp_register_style( 'gs-pretty-photo', CHILD_CSS . '/' . gs_script_suffix( 'prettyPhoto', 'css' ), array(), '3.1.4' );
+ wp_register_script( 'gs-pretty-photo', CHILD_JS . '/' . gs_script_suffix( 'jquery.prettyPhoto', 'js' ), array( 'jquery' ), '3.1.4' );
+
+ /** Common, site specific */
+ wp_register_script( 'gs-common', CHILD_JS . '/' . gs_script_suffix( 'common' ), array( 'jquery' ) , CHILD_THEME_VERSION );
+
+}
+
+/**
+ * Enqueues Appropriate Scripts and Styles when needed based on Debugging.
+ * Assumes that the normal *.min.js/*.min.css is the minified version & *.js is beautified version.
+ *
+ * @uses wp_enqueue_script() WP adds JS to page safely.
+ */
+function gs_enqueue_scripts() {
+ // You can Also register scripts right before enqueing OR simply enqueue the script without registering.
+ // See gs_register_scripts() for examples.
+
+ // Styles
+ //wp_enqueue_style( 'gs-twitter-bootstrap' );
+ //wp_enqueue_style( 'gs-twitter-bootstrap-font-awesome' );
+ //wp_enqueue_style( 'gs-font-awesome' );
+ //wp_enqueue_style( 'gs-pretty-photo' );
+
+ // Scripts
+ //wp_enqueue_script( 'gs-twitter-bootstrap' );
+ //wp_enqueue_script( 'gs-pretty-photo' );
+ //add_action( 'wp_footer', 'gs_init_pretty_photo' );
+ wp_enqueue_script( 'gs-common' );
+
+ // Localize Script
+ /*
+ // This enables you to create variable variables in JS that will be referred to as gs.greeting
+ $l10n_args = array(
+ //REFERENCE => VALUE, example in next line, CHILD_DOMAIN is the text domain for internationalization.
+ 'greeting' => __( 'Hello World!', CHILD_DOMAIN ),
+ );
+
+ // @link http://codex.wordpress.org/Function_Reference/wp_localize_script
+ // wp_localize_script( REGISTERED-HANDLE, OBJECT_NAME, OBJECT_DATA );
+ wp_localize_script( 'gs-common-scripts', 'gs', $l10n_args );
+ */
+}
+
+/**
+ * Add navigation menu to the top.
+ *
+ * @since 1.1.0
+ * @uses gs_navigation() Sandbox Navigation Helper Function.
+ */
+function gs_top_navigation() {
+
+ $top_menu_args = array(
+ 'echo' => true,
+ );
+
+ gs_navigation( 'top', $top_menu_args );
+}
+
+/**
+ * Add navigation menu to mobile.
+ *
+ * @since 1.1.0
+ * @uses gs_navigation() Sandbox Navigation Helper Function.
+ */
+function gs_mobile_navigation() {
+
+ $mobile_menu_args = array(
+ 'echo' => true,
+ );
+
+ gs_navigation( 'mobile', $mobile_menu_args );
+}
+
+/**
+ * Add navigation menu to the top.
+ *
+ * @since 1.1.0
+ * @uses gs_navigation() Sandbox Navigation Helper Function.
+ */
+function gs_footer_navigation() {
+
+ $footer_menu_args = array(
+ 'depth' => 1,
+ );
+
+ return gs_navigation( 'footer', $footer_menu_args );
+}
+
+/**
+ * Customize Contact Methods
+ * This removes jabber, yim, & aim default contact methods.
+ * @since 1.1.0
+ *
+ * @param array $contactmethods Array of contact methods and their labels.
+ * @return array $contactmethods Modified Contact Methods.
+ */
+function gs_contactmethods( $contactmethods ) {
+ $contactmethods = array ( 'twitter' => __( 'Twitter Name (no @)', CHILD_DOMAIN ) );
+
+ return $contactmethods;
+}
+
+/**
+ * Custom Footer based on options
+ *
+ * @uses CHILD_SETTINGS_FIELD
+ * @uses genesis_get_option()
+ * @uses wpautop()
+ * @uses gs_footer_navigation()
+ */
+function gs_do_footer() {
+ $pattern = '
';
+ if ( ! genesis_get_option( 'footer_left_nav', CHILD_SETTINGS_FIELD ) )
+ printf( $pattern, ' first', 'left', wpautop( genesis_get_option( 'footer_left', CHILD_SETTINGS_FIELD ) ) );
+ else
+ printf( $pattern, ' first', 'left', gs_footer_navigation() );
+
+ if ( ! genesis_get_option( 'footer_right_nav', 'gs-settings' ) )
+ printf( $pattern, '', 'right', wpautop( genesis_get_option( 'footer_right', CHILD_SETTINGS_FIELD ) ) );
+ else
+ printf( $pattern, '', 'right', gs_footer_navigation() );
+}
+
+add_action( 'genesis_admin_menu', 'gs_add_settings', 5 );
+/**
+ * Add the Theme Settings Page
+ *
+ * @since 1.1.0
+ */
+function gs_add_settings() {
+ global $_gs_settings;
+
+ $_gs_settings = new Genesis_Sandbox_Settings;
+}
+
+add_action( 'genesis_after_sidebar_widget_area', 'gs_bottom_sidebars' );
+/**
+ * Add two sidebars underneath the primary sidebar
+ */
+function gs_bottom_sidebars() {
+ foreach ( array( 'sidebar-bottom-left', 'sidebar-bottom-right', ) as $area ) {
+ genesis_widget_area(
+ 'home',
+ array(
+ 'before' => '',
+ )
+ );
+
+ }
+}
+
+/**
+ * 04 Register Extra Sidebars (widget areas)
+ * Edit the $sidebars array to create the initial desired sidebars.
+ * This is to be used with genesis_widget_area() on the front end.
+ *
+ * @uses genesis_register_sidebar() Genesis helper function to register WP sidebars.
+ */
+function gs_register_sidebars() {
+ $sidebars = array(
+ array(
+ 'id' => 'home-top',
+ 'name' => __( 'Home Top', CHILD_DOMAIN ),
+ 'description' => __( 'This is the top homepage section.', CHILD_DOMAIN ),
+ ),
+ array(
+ 'id' => 'home-left',
+ 'name' => __( 'Home Left', CHILD_DOMAIN ),
+ 'description' => __( 'This is the homepage left section.', CHILD_DOMAIN ),
+ ),
+ array(
+ 'id' => 'home-right',
+ 'name' => __( 'Home Right', CHILD_DOMAIN ),
+ 'description' => __( 'This is the homepage right section.', CHILD_DOMAIN ),
+ ),
+ array(
+ 'id' => 'home-bottom',
+ 'name' => __( 'Home Bottom', CHILD_DOMAIN ),
+ 'description' => __( 'This is the homepage right section.', CHILD_DOMAIN ),
+ ),
+ array(
+ 'id' => 'portfolio',
+ 'name' => __( 'Portfolio', CHILD_DOMAIN ),
+ 'description' => __( 'This is the portfolio page template', CHILD_DOMAIN ),
+ ),
+ );
+
+ foreach ( $sidebars as $sidebar )
+ genesis_register_sidebar( $sidebar );
+}
\ No newline at end of file
diff --git a/alt/init-alt.php b/alt/init-alt.php
new file mode 100644
index 0000000..61cf9bb
--- /dev/null
+++ b/alt/init-alt.php
@@ -0,0 +1,506 @@
+ '', )
+ );
+
+ echo '
';
+ genesis_widget_area(
+ 'home-left',
+ array(
+ 'before' => '
',
+ )
+ );
+
+ genesis_widget_area(
+ 'home-right',
+ array(
+ 'before' => '
',
+ )
+ );
+ echo '
';
+
+
+ genesis_widget_area(
+ 'home-bottom',
+ array(
+ 'before' => '
',
+ )
+ );
+}
+
+genesis();
\ No newline at end of file
diff --git a/images/blockquote.png b/images/blockquote.png
new file mode 100644
index 0000000..89524c1
Binary files /dev/null and b/images/blockquote.png differ
diff --git a/images/favicon.ico b/images/favicon.ico
new file mode 100644
index 0000000..5ad14c5
Binary files /dev/null and b/images/favicon.ico differ
diff --git a/images/favicon.png b/images/favicon.png
new file mode 100644
index 0000000..c879dda
Binary files /dev/null and b/images/favicon.png differ
diff --git a/images/glyphicons-halflings-white.png b/images/glyphicons-halflings-white.png
new file mode 100644
index 0000000..3bf6484
Binary files /dev/null and b/images/glyphicons-halflings-white.png differ
diff --git a/images/glyphicons-halflings.png b/images/glyphicons-halflings.png
new file mode 100644
index 0000000..a996999
Binary files /dev/null and b/images/glyphicons-halflings.png differ
diff --git a/images/gradient.png b/images/gradient.png
new file mode 100644
index 0000000..e48b479
Binary files /dev/null and b/images/gradient.png differ
diff --git a/images/icon-dot.png b/images/icon-dot.png
new file mode 100644
index 0000000..8c4117b
Binary files /dev/null and b/images/icon-dot.png differ
diff --git a/images/icon-plus-white.png b/images/icon-plus-white.png
new file mode 100644
index 0000000..19dc5a6
Binary files /dev/null and b/images/icon-plus-white.png differ
diff --git a/images/icon-plus.png b/images/icon-plus.png
new file mode 100644
index 0000000..5e7d9f7
Binary files /dev/null and b/images/icon-plus.png differ
diff --git a/images/logo.png b/images/logo.png
new file mode 100644
index 0000000..c2cb0c4
Binary files /dev/null and b/images/logo.png differ
diff --git a/images/post-comments.png b/images/post-comments.png
new file mode 100644
index 0000000..793060c
Binary files /dev/null and b/images/post-comments.png differ
diff --git a/images/prettyPhoto/dark_rounded/btnNext.png b/images/prettyPhoto/dark_rounded/btnNext.png
new file mode 100644
index 0000000..b28c1ef
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/btnNext.png differ
diff --git a/images/prettyPhoto/dark_rounded/btnPrevious.png b/images/prettyPhoto/dark_rounded/btnPrevious.png
new file mode 100644
index 0000000..e0cd9c4
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/btnPrevious.png differ
diff --git a/images/prettyPhoto/dark_rounded/contentPattern.png b/images/prettyPhoto/dark_rounded/contentPattern.png
new file mode 100644
index 0000000..e5a047c
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/contentPattern.png differ
diff --git a/images/prettyPhoto/dark_rounded/default_thumbnail.gif b/images/prettyPhoto/dark_rounded/default_thumbnail.gif
new file mode 100644
index 0000000..2b1280f
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/default_thumbnail.gif differ
diff --git a/images/prettyPhoto/dark_rounded/loader.gif b/images/prettyPhoto/dark_rounded/loader.gif
new file mode 100644
index 0000000..50820ee
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/loader.gif differ
diff --git a/images/prettyPhoto/dark_rounded/sprite.png b/images/prettyPhoto/dark_rounded/sprite.png
new file mode 100644
index 0000000..fb8c0f8
Binary files /dev/null and b/images/prettyPhoto/dark_rounded/sprite.png differ
diff --git a/images/prettyPhoto/dark_square/btnNext.png b/images/prettyPhoto/dark_square/btnNext.png
new file mode 100644
index 0000000..b28c1ef
Binary files /dev/null and b/images/prettyPhoto/dark_square/btnNext.png differ
diff --git a/images/prettyPhoto/dark_square/btnPrevious.png b/images/prettyPhoto/dark_square/btnPrevious.png
new file mode 100644
index 0000000..e0cd9c4
Binary files /dev/null and b/images/prettyPhoto/dark_square/btnPrevious.png differ
diff --git a/images/prettyPhoto/dark_square/contentPattern.png b/images/prettyPhoto/dark_square/contentPattern.png
new file mode 100644
index 0000000..7b50aff
Binary files /dev/null and b/images/prettyPhoto/dark_square/contentPattern.png differ
diff --git a/images/prettyPhoto/dark_square/default_thumbnail.gif b/images/prettyPhoto/dark_square/default_thumbnail.gif
new file mode 100644
index 0000000..2b1280f
Binary files /dev/null and b/images/prettyPhoto/dark_square/default_thumbnail.gif differ
diff --git a/images/prettyPhoto/dark_square/loader.gif b/images/prettyPhoto/dark_square/loader.gif
new file mode 100644
index 0000000..50820ee
Binary files /dev/null and b/images/prettyPhoto/dark_square/loader.gif differ
diff --git a/images/prettyPhoto/dark_square/sprite.png b/images/prettyPhoto/dark_square/sprite.png
new file mode 100644
index 0000000..4fe3547
Binary files /dev/null and b/images/prettyPhoto/dark_square/sprite.png differ
diff --git a/images/prettyPhoto/default/default_thumb.png b/images/prettyPhoto/default/default_thumb.png
new file mode 100644
index 0000000..1a26e4b
Binary files /dev/null and b/images/prettyPhoto/default/default_thumb.png differ
diff --git a/images/prettyPhoto/default/loader.gif b/images/prettyPhoto/default/loader.gif
new file mode 100644
index 0000000..35d397c
Binary files /dev/null and b/images/prettyPhoto/default/loader.gif differ
diff --git a/images/prettyPhoto/default/sprite.png b/images/prettyPhoto/default/sprite.png
new file mode 100644
index 0000000..5f07ddc
Binary files /dev/null and b/images/prettyPhoto/default/sprite.png differ
diff --git a/images/prettyPhoto/default/sprite_next.png b/images/prettyPhoto/default/sprite_next.png
new file mode 100644
index 0000000..379dc0d
Binary files /dev/null and b/images/prettyPhoto/default/sprite_next.png differ
diff --git a/images/prettyPhoto/default/sprite_prev.png b/images/prettyPhoto/default/sprite_prev.png
new file mode 100644
index 0000000..1ee4865
Binary files /dev/null and b/images/prettyPhoto/default/sprite_prev.png differ
diff --git a/images/prettyPhoto/default/sprite_x.png b/images/prettyPhoto/default/sprite_x.png
new file mode 100644
index 0000000..d4433ab
Binary files /dev/null and b/images/prettyPhoto/default/sprite_x.png differ
diff --git a/images/prettyPhoto/default/sprite_y.png b/images/prettyPhoto/default/sprite_y.png
new file mode 100644
index 0000000..7786ab5
Binary files /dev/null and b/images/prettyPhoto/default/sprite_y.png differ
diff --git a/images/prettyPhoto/facebook/btnNext.png b/images/prettyPhoto/facebook/btnNext.png
new file mode 100644
index 0000000..e809c3b
Binary files /dev/null and b/images/prettyPhoto/facebook/btnNext.png differ
diff --git a/images/prettyPhoto/facebook/btnPrevious.png b/images/prettyPhoto/facebook/btnPrevious.png
new file mode 100644
index 0000000..0812542
Binary files /dev/null and b/images/prettyPhoto/facebook/btnPrevious.png differ
diff --git a/images/prettyPhoto/facebook/contentPatternBottom.png b/images/prettyPhoto/facebook/contentPatternBottom.png
new file mode 100644
index 0000000..a9be3b2
Binary files /dev/null and b/images/prettyPhoto/facebook/contentPatternBottom.png differ
diff --git a/images/prettyPhoto/facebook/contentPatternLeft.png b/images/prettyPhoto/facebook/contentPatternLeft.png
new file mode 100644
index 0000000..277c87a
Binary files /dev/null and b/images/prettyPhoto/facebook/contentPatternLeft.png differ
diff --git a/images/prettyPhoto/facebook/contentPatternRight.png b/images/prettyPhoto/facebook/contentPatternRight.png
new file mode 100644
index 0000000..76e50d0
Binary files /dev/null and b/images/prettyPhoto/facebook/contentPatternRight.png differ
diff --git a/images/prettyPhoto/facebook/contentPatternTop.png b/images/prettyPhoto/facebook/contentPatternTop.png
new file mode 100644
index 0000000..8b110ba
Binary files /dev/null and b/images/prettyPhoto/facebook/contentPatternTop.png differ
diff --git a/images/prettyPhoto/facebook/default_thumbnail.gif b/images/prettyPhoto/facebook/default_thumbnail.gif
new file mode 100644
index 0000000..2b1280f
Binary files /dev/null and b/images/prettyPhoto/facebook/default_thumbnail.gif differ
diff --git a/images/prettyPhoto/facebook/loader.gif b/images/prettyPhoto/facebook/loader.gif
new file mode 100644
index 0000000..7ac990c
Binary files /dev/null and b/images/prettyPhoto/facebook/loader.gif differ
diff --git a/images/prettyPhoto/facebook/sprite.png b/images/prettyPhoto/facebook/sprite.png
new file mode 100644
index 0000000..660a254
Binary files /dev/null and b/images/prettyPhoto/facebook/sprite.png differ
diff --git a/images/prettyPhoto/light_rounded/btnNext.png b/images/prettyPhoto/light_rounded/btnNext.png
new file mode 100644
index 0000000..b28c1ef
Binary files /dev/null and b/images/prettyPhoto/light_rounded/btnNext.png differ
diff --git a/images/prettyPhoto/light_rounded/btnPrevious.png b/images/prettyPhoto/light_rounded/btnPrevious.png
new file mode 100644
index 0000000..e0cd9c4
Binary files /dev/null and b/images/prettyPhoto/light_rounded/btnPrevious.png differ
diff --git a/images/prettyPhoto/light_rounded/default_thumbnail.gif b/images/prettyPhoto/light_rounded/default_thumbnail.gif
new file mode 100644
index 0000000..2b1280f
Binary files /dev/null and b/images/prettyPhoto/light_rounded/default_thumbnail.gif differ
diff --git a/images/prettyPhoto/light_rounded/loader.gif b/images/prettyPhoto/light_rounded/loader.gif
new file mode 100644
index 0000000..7ac990c
Binary files /dev/null and b/images/prettyPhoto/light_rounded/loader.gif differ
diff --git a/images/prettyPhoto/light_rounded/sprite.png b/images/prettyPhoto/light_rounded/sprite.png
new file mode 100644
index 0000000..7f28379
Binary files /dev/null and b/images/prettyPhoto/light_rounded/sprite.png differ
diff --git a/images/prettyPhoto/light_square/btnNext.png b/images/prettyPhoto/light_square/btnNext.png
new file mode 100644
index 0000000..b28c1ef
Binary files /dev/null and b/images/prettyPhoto/light_square/btnNext.png differ
diff --git a/images/prettyPhoto/light_square/btnPrevious.png b/images/prettyPhoto/light_square/btnPrevious.png
new file mode 100644
index 0000000..e0cd9c4
Binary files /dev/null and b/images/prettyPhoto/light_square/btnPrevious.png differ
diff --git a/images/prettyPhoto/light_square/default_thumbnail.gif b/images/prettyPhoto/light_square/default_thumbnail.gif
new file mode 100644
index 0000000..2b1280f
Binary files /dev/null and b/images/prettyPhoto/light_square/default_thumbnail.gif differ
diff --git a/images/prettyPhoto/light_square/loader.gif b/images/prettyPhoto/light_square/loader.gif
new file mode 100644
index 0000000..7ac990c
Binary files /dev/null and b/images/prettyPhoto/light_square/loader.gif differ
diff --git a/images/prettyPhoto/light_square/sprite.png b/images/prettyPhoto/light_square/sprite.png
new file mode 100644
index 0000000..4fe3547
Binary files /dev/null and b/images/prettyPhoto/light_square/sprite.png differ
diff --git a/images/rss.png b/images/rss.png
new file mode 100644
index 0000000..c8bbb58
Binary files /dev/null and b/images/rss.png differ
diff --git a/images/twitter-nav.png b/images/twitter-nav.png
new file mode 100644
index 0000000..4d8ecbb
Binary files /dev/null and b/images/twitter-nav.png differ
diff --git a/js/bootstrap.js b/js/bootstrap.js
new file mode 100644
index 0000000..6c15a58
--- /dev/null
+++ b/js/bootstrap.js
@@ -0,0 +1,2159 @@
+/* ===================================================
+ * bootstrap-transition.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#transitions
+ * ===================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
+ * ======================================================= */
+
+ $(function () {
+
+ $.support.transition = (function () {
+
+ var transitionEnd = (function () {
+
+ var el = document.createElement('bootstrap')
+ , transEndEventNames = {
+ 'WebkitTransition' : 'webkitTransitionEnd'
+ , 'MozTransition' : 'transitionend'
+ , 'OTransition' : 'oTransitionEnd otransitionend'
+ , 'transition' : 'transitionend'
+ }
+ , name
+
+ for (name in transEndEventNames){
+ if (el.style[name] !== undefined) {
+ return transEndEventNames[name]
+ }
+ }
+
+ }())
+
+ return transitionEnd && {
+ end: transitionEnd
+ }
+
+ })()
+
+ })
+
+}(window.jQuery);/* ==========================================================
+ * bootstrap-alert.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* ALERT CLASS DEFINITION
+ * ====================== */
+
+ var dismiss = '[data-dismiss="alert"]'
+ , Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ , selector = $this.attr('data-target')
+ , $parent
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = $(selector)
+
+ e && e.preventDefault()
+
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
+
+ $parent.trigger(e = $.Event('close'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ $parent
+ .trigger('closed')
+ .remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent.on($.support.transition.end, removeElement) :
+ removeElement()
+ }
+
+
+ /* ALERT PLUGIN DEFINITION
+ * ======================= */
+
+ var old = $.fn.alert
+
+ $.fn.alert = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('alert')
+ if (!data) $this.data('alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.alert.Constructor = Alert
+
+
+ /* ALERT NO CONFLICT
+ * ================= */
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
+
+
+ /* ALERT DATA-API
+ * ============== */
+
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
+
+}(window.jQuery);/* ============================================================
+ * bootstrap-button.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#buttons
+ * ============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* BUTTON PUBLIC CLASS DEFINITION
+ * ============================== */
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.button.defaults, options)
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ , $el = this.$element
+ , data = $el.data()
+ , val = $el.is('input') ? 'val' : 'html'
+
+ state = state + 'Text'
+ data.resetText || $el.data('resetText', $el[val]())
+
+ $el[val](data[state] || this.options[state])
+
+ // push to event loop to allow forms to submit
+ setTimeout(function () {
+ state == 'loadingText' ?
+ $el.addClass(d).attr(d, d) :
+ $el.removeClass(d).removeAttr(d)
+ }, 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
+
+ $parent && $parent
+ .find('.active')
+ .removeClass('active')
+
+ this.$element.toggleClass('active')
+ }
+
+
+ /* BUTTON PLUGIN DEFINITION
+ * ======================== */
+
+ var old = $.fn.button
+
+ $.fn.button = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('button')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('button', (data = new Button(this, options)))
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ $.fn.button.defaults = {
+ loadingText: 'loading...'
+ }
+
+ $.fn.button.Constructor = Button
+
+
+ /* BUTTON NO CONFLICT
+ * ================== */
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
+
+
+ /* BUTTON DATA-API
+ * =============== */
+
+ $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
+ var $btn = $(e.target)
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+ $btn.button('toggle')
+ })
+
+}(window.jQuery);/* ==========================================================
+ * bootstrap-carousel.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#carousel
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* CAROUSEL CLASS DEFINITION
+ * ========================= */
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.options = options
+ this.options.pause == 'hover' && this.$element
+ .on('mouseenter', $.proxy(this.pause, this))
+ .on('mouseleave', $.proxy(this.cycle, this))
+ }
+
+ Carousel.prototype = {
+
+ cycle: function (e) {
+ if (!e) this.paused = false
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+ return this
+ }
+
+ , to: function (pos) {
+ var $active = this.$element.find('.item.active')
+ , children = $active.parent().children()
+ , activePos = children.index($active)
+ , that = this
+
+ if (pos > (children.length - 1) || pos < 0) return
+
+ if (this.sliding) {
+ return this.$element.one('slid', function () {
+ that.to(pos)
+ })
+ }
+
+ if (activePos == pos) {
+ return this.pause().cycle()
+ }
+
+ return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
+ }
+
+ , pause: function (e) {
+ if (!e) this.paused = true
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle()
+ }
+ clearInterval(this.interval)
+ this.interval = null
+ return this
+ }
+
+ , next: function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ , prev: function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ , slide: function (type, next) {
+ var $active = this.$element.find('.item.active')
+ , $next = next || $active[type]()
+ , isCycling = this.interval
+ , direction = type == 'next' ? 'left' : 'right'
+ , fallback = type == 'next' ? 'first' : 'last'
+ , that = this
+ , e
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
+
+ e = $.Event('slide', {
+ relatedTarget: $next[0]
+ })
+
+ if ($next.hasClass('active')) return
+
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ this.$element.one($.support.transition.end, function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
+ })
+ } else {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger('slid')
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+ }
+
+
+ /* CAROUSEL PLUGIN DEFINITION
+ * ========================== */
+
+ var old = $.fn.carousel
+
+ $.fn.carousel = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('carousel')
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
+ , action = typeof option == 'string' ? option : options.slide
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.cycle()
+ })
+ }
+
+ $.fn.carousel.defaults = {
+ interval: 5000
+ , pause: 'hover'
+ }
+
+ $.fn.carousel.Constructor = Carousel
+
+
+ /* CAROUSEL NO CONFLICT
+ * ==================== */
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
+
+ /* CAROUSEL DATA-API
+ * ================= */
+
+ $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
+ var $this = $(this), href
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ , options = $.extend({}, $target.data(), $this.data())
+ $target.carousel(options)
+ e.preventDefault()
+ })
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-collapse.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* COLLAPSE PUBLIC CLASS DEFINITION
+ * ================================ */
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
+
+ if (this.options.parent) {
+ this.$parent = $(this.options.parent)
+ }
+
+ this.options.toggle && this.toggle()
+ }
+
+ Collapse.prototype = {
+
+ constructor: Collapse
+
+ , dimension: function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ , show: function () {
+ var dimension
+ , scroll
+ , actives
+ , hasData
+
+ if (this.transitioning) return
+
+ dimension = this.dimension()
+ scroll = $.camelCase(['scroll', dimension].join('-'))
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
+
+ if (actives && actives.length) {
+ hasData = actives.data('collapse')
+ if (hasData && hasData.transitioning) return
+ actives.collapse('hide')
+ hasData || actives.data('collapse', null)
+ }
+
+ this.$element[dimension](0)
+ this.transition('addClass', $.Event('show'), 'shown')
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
+ }
+
+ , hide: function () {
+ var dimension
+ if (this.transitioning) return
+ dimension = this.dimension()
+ this.reset(this.$element[dimension]())
+ this.transition('removeClass', $.Event('hide'), 'hidden')
+ this.$element[dimension](0)
+ }
+
+ , reset: function (size) {
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ [dimension](size || 'auto')
+ [0].offsetWidth
+
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
+
+ return this
+ }
+
+ , transition: function (method, startEvent, completeEvent) {
+ var that = this
+ , complete = function () {
+ if (startEvent.type == 'show') that.reset()
+ that.transitioning = 0
+ that.$element.trigger(completeEvent)
+ }
+
+ this.$element.trigger(startEvent)
+
+ if (startEvent.isDefaultPrevented()) return
+
+ this.transitioning = 1
+
+ this.$element[method]('in')
+
+ $.support.transition && this.$element.hasClass('collapse') ?
+ this.$element.one($.support.transition.end, complete) :
+ complete()
+ }
+
+ , toggle: function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ }
+
+
+ /* COLLAPSE PLUGIN DEFINITION
+ * ========================== */
+
+ var old = $.fn.collapse
+
+ $.fn.collapse = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('collapse')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.collapse.defaults = {
+ toggle: true
+ }
+
+ $.fn.collapse.Constructor = Collapse
+
+
+ /* COLLAPSE NO CONFLICT
+ * ==================== */
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
+
+
+ /* COLLAPSE DATA-API
+ * ================= */
+
+ $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
+ var $this = $(this), href
+ , target = $this.attr('data-target')
+ || e.preventDefault()
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
+ $(target).collapse(option)
+ })
+
+}(window.jQuery);/* ============================================================
+ * bootstrap-dropdown.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
+ * ============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* DROPDOWN CLASS DEFINITION
+ * ========================= */
+
+ var toggle = '[data-toggle=dropdown]'
+ , Dropdown = function (element) {
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
+ $('html').on('click.dropdown.data-api', function () {
+ $el.parent().removeClass('open')
+ })
+ }
+
+ Dropdown.prototype = {
+
+ constructor: Dropdown
+
+ , toggle: function (e) {
+ var $this = $(this)
+ , $parent
+ , isActive
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ $parent.toggleClass('open')
+ }
+
+ $this.focus()
+
+ return false
+ }
+
+ , keydown: function (e) {
+ var $this
+ , $items
+ , $active
+ , $parent
+ , isActive
+ , index
+
+ if (!/(38|40|27)/.test(e.keyCode)) return
+
+ $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
+
+ $items = $('[role=menu] li:not(.divider):visible a', $parent)
+
+ if (!$items.length) return
+
+ index = $items.index($items.filter(':focus'))
+
+ if (e.keyCode == 38 && index > 0) index-- // up
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items
+ .eq(index)
+ .focus()
+ }
+
+ }
+
+ function clearMenus() {
+ $(toggle).each(function () {
+ getParent($(this)).removeClass('open')
+ })
+ }
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+ , $parent
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = $(selector)
+ $parent.length || ($parent = $this.parent())
+
+ return $parent
+ }
+
+
+ /* DROPDOWN PLUGIN DEFINITION
+ * ========================== */
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('dropdown')
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ /* DROPDOWN NO CONFLICT
+ * ==================== */
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
+ * =================================== */
+
+ $(document)
+ .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
+ .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('touchstart.dropdown.data-api', '.dropdown-menu', function (e) { e.stopPropagation() })
+ .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
+ .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
+
+}(window.jQuery);/* =========================================================
+ * bootstrap-modal.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#modals
+ * =========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* MODAL CLASS DEFINITION
+ * ====================== */
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$element = $(element)
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
+ }
+
+ Modal.prototype = {
+
+ constructor: Modal
+
+ , toggle: function () {
+ return this[!this.isShown ? 'show' : 'hide']()
+ }
+
+ , show: function () {
+ var that = this
+ , e = $.Event('show')
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.escape()
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(document.body) //don't move modals dom position
+ }
+
+ that.$element
+ .show()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element
+ .addClass('in')
+ .attr('aria-hidden', false)
+
+ that.enforceFocus()
+
+ transition ?
+ that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
+ that.$element.focus().trigger('shown')
+
+ })
+ }
+
+ , hide: function (e) {
+ e && e.preventDefault()
+
+ var that = this
+
+ e = $.Event('hide')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+
+ $(document).off('focusin.modal')
+
+ this.$element
+ .removeClass('in')
+ .attr('aria-hidden', true)
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.hideWithTransition() :
+ this.hideModal()
+ }
+
+ , enforceFocus: function () {
+ var that = this
+ $(document).on('focusin.modal', function (e) {
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
+ that.$element.focus()
+ }
+ })
+ }
+
+ , escape: function () {
+ var that = this
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
+ e.which == 27 && that.hide()
+ })
+ } else if (!this.isShown) {
+ this.$element.off('keyup.dismiss.modal')
+ }
+ }
+
+ , hideWithTransition: function () {
+ var that = this
+ , timeout = setTimeout(function () {
+ that.$element.off($.support.transition.end)
+ that.hideModal()
+ }, 500)
+
+ this.$element.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ that.hideModal()
+ })
+ }
+
+ , hideModal: function (that) {
+ this.$element
+ .hide()
+ .trigger('hidden')
+
+ this.backdrop()
+ }
+
+ , removeBackdrop: function () {
+ this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ , backdrop: function (callback) {
+ var that = this
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $('
')
+ .appendTo(document.body)
+
+ this.$backdrop.click(
+ this.options.backdrop == 'static' ?
+ $.proxy(this.$element[0].focus, this.$element[0])
+ : $.proxy(this.hide, this)
+ )
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ doAnimate ?
+ this.$backdrop.one($.support.transition.end, callback) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade')?
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
+ this.removeBackdrop()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+ }
+
+
+ /* MODAL PLUGIN DEFINITION
+ * ======================= */
+
+ var old = $.fn.modal
+
+ $.fn.modal = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('modal')
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option]()
+ else if (options.show) data.show()
+ })
+ }
+
+ $.fn.modal.defaults = {
+ backdrop: true
+ , keyboard: true
+ , show: true
+ }
+
+ $.fn.modal.Constructor = Modal
+
+
+ /* MODAL NO CONFLICT
+ * ================= */
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ /* MODAL DATA-API
+ * ============== */
+
+ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ , href = $this.attr('href')
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
+
+ e.preventDefault()
+
+ $target
+ .modal(option)
+ .one('hide', function () {
+ $this.focus()
+ })
+ })
+
+}(window.jQuery);
+/* ===========================================================
+ * bootstrap-tooltip.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TOOLTIP PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Tooltip = function (element, options) {
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.prototype = {
+
+ constructor: Tooltip
+
+ , init: function (type, element, options) {
+ var eventIn
+ , eventOut
+
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.enabled = true
+
+ if (this.options.trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (this.options.trigger != 'manual') {
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
+ eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ , getOptions: function (options) {
+ options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay
+ , hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ , enter: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ clearTimeout(this.timeout)
+ self.hoverState = 'in'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ , leave: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (this.timeout) clearTimeout(this.timeout)
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.hoverState = 'out'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ , show: function () {
+ var $tip
+ , inside
+ , pos
+ , actualWidth
+ , actualHeight
+ , placement
+ , tp
+
+ if (this.hasContent() && this.enabled) {
+ $tip = this.tip()
+ this.setContent()
+
+ if (this.options.animation) {
+ $tip.addClass('fade')
+ }
+
+ placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ inside = /in/.test(placement)
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .insertAfter(this.$element)
+
+ pos = this.getPosition(inside)
+
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+
+ switch (inside ? placement.split(' ')[1] : placement) {
+ case 'bottom':
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'top':
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'left':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
+ break
+ case 'right':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+ break
+ }
+
+ $tip
+ .offset(tp)
+ .addClass(placement)
+ .addClass('in')
+ }
+ }
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ , hide: function () {
+ var that = this
+ , $tip = this.tip()
+
+ $tip.removeClass('in')
+
+ function removeWithAnimation() {
+ var timeout = setTimeout(function () {
+ $tip.off($.support.transition.end).detach()
+ }, 500)
+
+ $tip.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ $tip.detach()
+ })
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ removeWithAnimation() :
+ $tip.detach()
+
+ return this
+ }
+
+ , fixTitle: function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
+ }
+ }
+
+ , hasContent: function () {
+ return this.getTitle()
+ }
+
+ , getPosition: function (inside) {
+ return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
+ width: this.$element[0].offsetWidth
+ , height: this.$element[0].offsetHeight
+ })
+ }
+
+ , getTitle: function () {
+ var title
+ , $e = this.$element
+ , o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ , tip: function () {
+ return this.$tip = this.$tip || $(this.options.template)
+ }
+
+ , validate: function () {
+ if (!this.$element[0].parentNode) {
+ this.hide()
+ this.$element = null
+ this.options = null
+ }
+ }
+
+ , enable: function () {
+ this.enabled = true
+ }
+
+ , disable: function () {
+ this.enabled = false
+ }
+
+ , toggleEnabled: function () {
+ this.enabled = !this.enabled
+ }
+
+ , toggle: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+ self[self.tip().hasClass('in') ? 'hide' : 'show']()
+ }
+
+ , destroy: function () {
+ this.hide().$element.off('.' + this.type).removeData(this.type)
+ }
+
+ }
+
+
+ /* TOOLTIP PLUGIN DEFINITION
+ * ========================= */
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tooltip')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tooltip.Constructor = Tooltip
+
+ $.fn.tooltip.defaults = {
+ animation: true
+ , placement: 'top'
+ , selector: false
+ , template: '
'
+ , trigger: 'hover'
+ , title: ''
+ , delay: 0
+ , html: false
+ }
+
+
+ /* TOOLTIP NO CONFLICT
+ * =================== */
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(window.jQuery);/* ===========================================================
+ * bootstrap-popover.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * =========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* POPOVER PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
+ ========================================== */
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
+
+ constructor: Popover
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+ , content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
+
+ $tip.removeClass('fade top bottom left right in')
+ }
+
+ , hasContent: function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ , getContent: function () {
+ var content
+ , $e = this.$element
+ , o = this.options
+
+ content = $e.attr('data-content')
+ || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
+
+ return content
+ }
+
+ , tip: function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ }
+ return this.$tip
+ }
+
+ , destroy: function () {
+ this.hide().$element.off('.' + this.type).removeData(this.type)
+ }
+
+ })
+
+
+ /* POPOVER PLUGIN DEFINITION
+ * ======================= */
+
+ var old = $.fn.popover
+
+ $.fn.popover = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('popover')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.popover.Constructor = Popover
+
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
+ placement: 'right'
+ , trigger: 'click'
+ , content: ''
+ , template: '
'
+ })
+
+
+ /* POPOVER NO CONFLICT
+ * =================== */
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-scrollspy.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* SCROLLSPY CLASS DEFINITION
+ * ========================== */
+
+ function ScrollSpy(element, options) {
+ var process = $.proxy(this.process, this)
+ , $element = $(element).is('body') ? $(window) : $(element)
+ , href
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
+ this.selector = (this.options.target
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ || '') + ' .nav li > a'
+ this.$body = $('body')
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.prototype = {
+
+ constructor: ScrollSpy
+
+ , refresh: function () {
+ var self = this
+ , $targets
+
+ this.offsets = $([])
+ this.targets = $([])
+
+ $targets = this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ , href = $el.data('target') || $el.attr('href')
+ , $href = /^#\w/.test(href) && $(href)
+ return ( $href
+ && $href.length
+ && [[ $href.position().top + self.$scrollElement.scrollTop(), href ]] ) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ self.offsets.push(this[0])
+ self.targets.push(this[1])
+ })
+ }
+
+ , process: function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
+ , maxScroll = scrollHeight - this.$scrollElement.height()
+ , offsets = this.offsets
+ , targets = this.targets
+ , activeTarget = this.activeTarget
+ , i
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets.last()[0])
+ && this.activate ( i )
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+ && this.activate( targets[i] )
+ }
+ }
+
+ , activate: function (target) {
+ var active
+ , selector
+
+ this.activeTarget = target
+
+ $(this.selector)
+ .parent('.active')
+ .removeClass('active')
+
+ selector = this.selector
+ + '[data-target="' + target + '"],'
+ + this.selector + '[href="' + target + '"]'
+
+ active = $(selector)
+ .parent('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active.closest('li.dropdown').addClass('active')
+ }
+
+ active.trigger('activate')
+ }
+
+ }
+
+
+ /* SCROLLSPY PLUGIN DEFINITION
+ * =========================== */
+
+ var old = $.fn.scrollspy
+
+ $.fn.scrollspy = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('scrollspy')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+ $.fn.scrollspy.defaults = {
+ offset: 10
+ }
+
+
+ /* SCROLLSPY NO CONFLICT
+ * ===================== */
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
+
+
+ /* SCROLLSPY DATA-API
+ * ================== */
+
+ $(window).on('load', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ $spy.scrollspy($spy.data())
+ })
+ })
+
+}(window.jQuery);/* ========================================================
+ * bootstrap-tab.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
+ * ========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ======================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TAB CLASS DEFINITION
+ * ==================== */
+
+ var Tab = function (element) {
+ this.element = $(element)
+ }
+
+ Tab.prototype = {
+
+ constructor: Tab
+
+ , show: function () {
+ var $this = this.element
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
+ , selector = $this.attr('data-target')
+ , previous
+ , $target
+ , e
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ if ( $this.parent('li').hasClass('active') ) return
+
+ previous = $ul.find('.active:last a')[0]
+
+ e = $.Event('show', {
+ relatedTarget: previous
+ })
+
+ $this.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $target = $(selector)
+
+ this.activate($this.parent('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $this.trigger({
+ type: 'shown'
+ , relatedTarget: previous
+ })
+ })
+ }
+
+ , activate: function ( element, container, callback) {
+ var $active = container.find('> .active')
+ , transition = callback
+ && $.support.transition
+ && $active.hasClass('fade')
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+
+ element.addClass('active')
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if ( element.parent('.dropdown-menu') ) {
+ element.closest('li.dropdown').addClass('active')
+ }
+
+ callback && callback()
+ }
+
+ transition ?
+ $active.one($.support.transition.end, next) :
+ next()
+
+ $active.removeClass('in')
+ }
+ }
+
+
+ /* TAB PLUGIN DEFINITION
+ * ===================== */
+
+ var old = $.fn.tab
+
+ $.fn.tab = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tab')
+ if (!data) $this.data('tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tab.Constructor = Tab
+
+
+ /* TAB NO CONFLICT
+ * =============== */
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
+
+
+ /* TAB DATA-API
+ * ============ */
+
+ $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
+ e.preventDefault()
+ $(this).tab('show')
+ })
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-typeahead.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function($){
+
+ "use strict"; // jshint ;_;
+
+
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
+ * ================================= */
+
+ var Typeahead = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
+ this.matcher = this.options.matcher || this.matcher
+ this.sorter = this.options.sorter || this.sorter
+ this.highlighter = this.options.highlighter || this.highlighter
+ this.updater = this.options.updater || this.updater
+ this.source = this.options.source
+ this.$menu = $(this.options.menu)
+ this.shown = false
+ this.listen()
+ }
+
+ Typeahead.prototype = {
+
+ constructor: Typeahead
+
+ , select: function () {
+ var val = this.$menu.find('.active').attr('data-value')
+ this.$element
+ .val(this.updater(val))
+ .change()
+ return this.hide()
+ }
+
+ , updater: function (item) {
+ return item
+ }
+
+ , show: function () {
+ var pos = $.extend({}, this.$element.position(), {
+ height: this.$element[0].offsetHeight
+ })
+
+ this.$menu
+ .insertAfter(this.$element)
+ .css({
+ top: pos.top + pos.height
+ , left: pos.left
+ })
+ .show()
+
+ this.shown = true
+ return this
+ }
+
+ , hide: function () {
+ this.$menu.hide()
+ this.shown = false
+ return this
+ }
+
+ , lookup: function (event) {
+ var items
+
+ this.query = this.$element.val()
+
+ if (!this.query || this.query.length < this.options.minLength) {
+ return this.shown ? this.hide() : this
+ }
+
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
+
+ return items ? this.process(items) : this
+ }
+
+ , process: function (items) {
+ var that = this
+
+ items = $.grep(items, function (item) {
+ return that.matcher(item)
+ })
+
+ items = this.sorter(items)
+
+ if (!items.length) {
+ return this.shown ? this.hide() : this
+ }
+
+ return this.render(items.slice(0, this.options.items)).show()
+ }
+
+ , matcher: function (item) {
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
+ }
+
+ , sorter: function (items) {
+ var beginswith = []
+ , caseSensitive = []
+ , caseInsensitive = []
+ , item
+
+ while (item = items.shift()) {
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
+ else caseInsensitive.push(item)
+ }
+
+ return beginswith.concat(caseSensitive, caseInsensitive)
+ }
+
+ , highlighter: function (item) {
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
+ return '
' + match + ' '
+ })
+ }
+
+ , render: function (items) {
+ var that = this
+
+ items = $(items).map(function (i, item) {
+ i = $(that.options.item).attr('data-value', item)
+ i.find('a').html(that.highlighter(item))
+ return i[0]
+ })
+
+ items.first().addClass('active')
+ this.$menu.html(items)
+ return this
+ }
+
+ , next: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , next = active.next()
+
+ if (!next.length) {
+ next = $(this.$menu.find('li')[0])
+ }
+
+ next.addClass('active')
+ }
+
+ , prev: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , prev = active.prev()
+
+ if (!prev.length) {
+ prev = this.$menu.find('li').last()
+ }
+
+ prev.addClass('active')
+ }
+
+ , listen: function () {
+ this.$element
+ .on('blur', $.proxy(this.blur, this))
+ .on('keypress', $.proxy(this.keypress, this))
+ .on('keyup', $.proxy(this.keyup, this))
+
+ if (this.eventSupported('keydown')) {
+ this.$element.on('keydown', $.proxy(this.keydown, this))
+ }
+
+ this.$menu
+ .on('click', $.proxy(this.click, this))
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
+ }
+
+ , eventSupported: function(eventName) {
+ var isSupported = eventName in this.$element
+ if (!isSupported) {
+ this.$element.setAttribute(eventName, 'return;')
+ isSupported = typeof this.$element[eventName] === 'function'
+ }
+ return isSupported
+ }
+
+ , move: function (e) {
+ if (!this.shown) return
+
+ switch(e.keyCode) {
+ case 9: // tab
+ case 13: // enter
+ case 27: // escape
+ e.preventDefault()
+ break
+
+ case 38: // up arrow
+ e.preventDefault()
+ this.prev()
+ break
+
+ case 40: // down arrow
+ e.preventDefault()
+ this.next()
+ break
+ }
+
+ e.stopPropagation()
+ }
+
+ , keydown: function (e) {
+ this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
+ this.move(e)
+ }
+
+ , keypress: function (e) {
+ if (this.suppressKeyPressRepeat) return
+ this.move(e)
+ }
+
+ , keyup: function (e) {
+ switch(e.keyCode) {
+ case 40: // down arrow
+ case 38: // up arrow
+ case 16: // shift
+ case 17: // ctrl
+ case 18: // alt
+ break
+
+ case 9: // tab
+ case 13: // enter
+ if (!this.shown) return
+ this.select()
+ break
+
+ case 27: // escape
+ if (!this.shown) return
+ this.hide()
+ break
+
+ default:
+ this.lookup()
+ }
+
+ e.stopPropagation()
+ e.preventDefault()
+ }
+
+ , blur: function (e) {
+ var that = this
+ setTimeout(function () { that.hide() }, 150)
+ }
+
+ , click: function (e) {
+ e.stopPropagation()
+ e.preventDefault()
+ this.select()
+ }
+
+ , mouseenter: function (e) {
+ this.$menu.find('.active').removeClass('active')
+ $(e.currentTarget).addClass('active')
+ }
+
+ }
+
+
+ /* TYPEAHEAD PLUGIN DEFINITION
+ * =========================== */
+
+ var old = $.fn.typeahead
+
+ $.fn.typeahead = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('typeahead')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.typeahead.defaults = {
+ source: []
+ , items: 8
+ , menu: ''
+ , item: '
'
+ , minLength: 1
+ }
+
+ $.fn.typeahead.Constructor = Typeahead
+
+
+ /* TYPEAHEAD NO CONFLICT
+ * =================== */
+
+ $.fn.typeahead.noConflict = function () {
+ $.fn.typeahead = old
+ return this
+ }
+
+
+ /* TYPEAHEAD DATA-API
+ * ================== */
+
+ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
+ var $this = $(this)
+ if ($this.data('typeahead')) return
+ e.preventDefault()
+ $this.typeahead($this.data())
+ })
+
+}(window.jQuery);
+/* ==========================================================
+ * bootstrap-affix.js v2.2.2
+ * http://twitter.github.com/bootstrap/javascript.html#affix
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* AFFIX CLASS DEFINITION
+ * ====================== */
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, $.fn.affix.defaults, options)
+ this.$window = $(window)
+ .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
+ this.$element = $(element)
+ this.checkPosition()
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var scrollHeight = $(document).height()
+ , scrollTop = this.$window.scrollTop()
+ , position = this.$element.offset()
+ , offset = this.options.offset
+ , offsetBottom = offset.bottom
+ , offsetTop = offset.top
+ , reset = 'affix affix-top affix-bottom'
+ , affix
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
+
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
+ 'top' : false
+
+ if (this.affixed === affix) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
+
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
+ }
+
+
+ /* AFFIX PLUGIN DEFINITION
+ * ======================= */
+
+ var old = $.fn.affix
+
+ $.fn.affix = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('affix')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.affix.Constructor = Affix
+
+ $.fn.affix.defaults = {
+ offset: 0
+ }
+
+
+ /* AFFIX NO CONFLICT
+ * ================= */
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ /* AFFIX DATA-API
+ * ============== */
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ , data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
+ data.offsetTop && (data.offset.top = data.offsetTop)
+
+ $spy.affix(data)
+ })
+ })
+
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js
new file mode 100644
index 0000000..6eeb15c
--- /dev/null
+++ b/js/bootstrap.min.js
@@ -0,0 +1,6 @@
+/*!
+* Bootstrap.js by @fat & @mdo
+* Copyright 2012 Twitter, Inc.
+* http://www.apache.org/licenses/LICENSE-2.0.txt
+*/
+!function($){"use strict";$(function(){$.support.transition=function(){var transitionEnd=function(){var name,el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(name in transEndEventNames)if(void 0!==el.style[name])return transEndEventNames[name]}();return transitionEnd&&{end:transitionEnd}}()})}(window.jQuery),!function($){"use strict";var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.prototype.close=function(e){function removeElement(){$parent.trigger("closed").remove()}var $parent,$this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),e&&e.preventDefault(),$parent.length||($parent=$this.hasClass("alert")?$this:$this.parent()),$parent.trigger(e=$.Event("close")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.on($.support.transition.end,removeElement):removeElement())};var old=$.fn.alert;$.fn.alert=function(option){return this.each(function(){var $this=$(this),data=$this.data("alert");data||$this.data("alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})},$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.alert.data-api",dismiss,Alert.prototype.close)}(window.jQuery),!function($){"use strict";var Button=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.button.defaults,options)};Button.prototype.setState=function(state){var d="disabled",$el=this.$element,data=$el.data(),val=$el.is("input")?"val":"html";state+="Text",data.resetText||$el.data("resetText",$el[val]()),$el[val](data[state]||this.options[state]),setTimeout(function(){"loadingText"==state?$el.addClass(d).attr(d,d):$el.removeClass(d).removeAttr(d)},0)},Button.prototype.toggle=function(){var $parent=this.$element.closest('[data-toggle="buttons-radio"]');$parent&&$parent.find(".active").removeClass("active"),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=function(option){return this.each(function(){var $this=$(this),data=$this.data("button"),options="object"==typeof option&&option;data||$this.data("button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})},$.fn.button.defaults={loadingText:"loading..."},$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.button.data-api","[data-toggle^=button]",function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),$btn.button("toggle")})}(window.jQuery),!function($){"use strict";var Carousel=function(element,options){this.$element=$(element),this.options=options,"hover"==this.options.pause&&this.$element.on("mouseenter",$.proxy(this.pause,this)).on("mouseleave",$.proxy(this.cycle,this))};Carousel.prototype={cycle:function(e){return e||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},to:function(pos){var $active=this.$element.find(".item.active"),children=$active.parent().children(),activePos=children.index($active),that=this;if(!(pos>children.length-1||0>pos))return this.sliding?this.$element.one("slid",function(){that.to(pos)}):activePos==pos?this.pause().cycle():this.slide(pos>activePos?"next":"prev",$(children[pos]))},pause:function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition.end&&(this.$element.trigger($.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){return this.sliding?void 0:this.slide("next")},prev:function(){return this.sliding?void 0:this.slide("prev")},slide:function(type,next){var e,$active=this.$element.find(".item.active"),$next=next||$active[type](),isCycling=this.interval,direction="next"==type?"left":"right",fallback="next"==type?"first":"last",that=this;if(this.sliding=!0,isCycling&&this.pause(),$next=$next.length?$next:this.$element.find(".item")[fallback](),e=$.Event("slide",{relatedTarget:$next[0]}),!$next.hasClass("active")){if($.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(e),e.isDefaultPrevented())return;$next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),this.$element.one($.support.transition.end,function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger("slid")},0)})}else{if(this.$element.trigger(e),e.isDefaultPrevented())return;$active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return isCycling&&this.cycle(),this}}};var old=$.fn.carousel;$.fn.carousel=function(option){return this.each(function(){var $this=$(this),data=$this.data("carousel"),options=$.extend({},$.fn.carousel.defaults,"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.cycle()})},$.fn.carousel.defaults={interval:5e3,pause:"hover"},$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this},$(document).on("click.carousel.data-api","[data-slide]",function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")),options=$.extend({},$target.data(),$this.data());$target.carousel(options),e.preventDefault()})}(window.jQuery),!function($){"use strict";var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.collapse.defaults,options),this.options.parent&&(this.$parent=$(this.options.parent)),this.options.toggle&&this.toggle()};Collapse.prototype={constructor:Collapse,dimension:function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"},show:function(){var dimension,scroll,actives,hasData;if(!this.transitioning){if(dimension=this.dimension(),scroll=$.camelCase(["scroll",dimension].join("-")),actives=this.$parent&&this.$parent.find("> .accordion-group > .in"),actives&&actives.length){if(hasData=actives.data("collapse"),hasData&&hasData.transitioning)return;actives.collapse("hide"),hasData||actives.data("collapse",null)}this.$element[dimension](0),this.transition("addClass",$.Event("show"),"shown"),$.support.transition&&this.$element[dimension](this.$element[0][scroll])}},hide:function(){var dimension;this.transitioning||(dimension=this.dimension(),this.reset(this.$element[dimension]()),this.transition("removeClass",$.Event("hide"),"hidden"),this.$element[dimension](0))},reset:function(size){var dimension=this.dimension();return this.$element.removeClass("collapse")[dimension](size||"auto")[0].offsetWidth,this.$element[null!==size?"addClass":"removeClass"]("collapse"),this},transition:function(method,startEvent,completeEvent){var that=this,complete=function(){"show"==startEvent.type&&that.reset(),that.transitioning=0,that.$element.trigger(completeEvent)};this.$element.trigger(startEvent),startEvent.isDefaultPrevented()||(this.transitioning=1,this.$element[method]("in"),$.support.transition&&this.$element.hasClass("collapse")?this.$element.one($.support.transition.end,complete):complete())},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var old=$.fn.collapse;$.fn.collapse=function(option){return this.each(function(){var $this=$(this),data=$this.data("collapse"),options="object"==typeof option&&option;data||$this.data("collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})},$.fn.collapse.defaults={toggle:!0},$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.collapse.data-api","[data-toggle=collapse]",function(e){var href,$this=$(this),target=$this.attr("data-target")||e.preventDefault()||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),option=$(target).data("collapse")?"toggle":$this.data();$this[$(target).hasClass("in")?"addClass":"removeClass"]("collapsed"),$(target).collapse(option)})}(window.jQuery),!function($){"use strict";function clearMenus(){$(toggle).each(function(){getParent($(this)).removeClass("open")})}function getParent($this){var $parent,selector=$this.attr("data-target");return selector||(selector=$this.attr("href"),selector=selector&&/#/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),$parent.length||($parent=$this.parent()),$parent}var toggle="[data-toggle=dropdown]",Dropdown=function(element){var $el=$(element).on("click.dropdown.data-api",this.toggle);$("html").on("click.dropdown.data-api",function(){$el.parent().removeClass("open")})};Dropdown.prototype={constructor:Dropdown,toggle:function(){var $parent,isActive,$this=$(this);if(!$this.is(".disabled, :disabled"))return $parent=getParent($this),isActive=$parent.hasClass("open"),clearMenus(),isActive||$parent.toggleClass("open"),$this.focus(),!1},keydown:function(e){var $this,$items,$parent,isActive,index;if(/(38|40|27)/.test(e.keyCode)&&($this=$(this),e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled"))){if($parent=getParent($this),isActive=$parent.hasClass("open"),!isActive||isActive&&27==e.keyCode)return $this.click();$items=$("[role=menu] li:not(.divider):visible a",$parent),$items.length&&(index=$items.index($items.filter(":focus")),38==e.keyCode&&index>0&&index--,40==e.keyCode&&$items.length-1>index&&index++,~index||(index=0),$items.eq(index).focus())}}};var old=$.fn.dropdown;$.fn.dropdown=function(option){return this.each(function(){var $this=$(this),data=$this.data("dropdown");data||$this.data("dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})},$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.dropdown.data-api touchstart.dropdown.data-api",clearMenus).on("click.dropdown touchstart.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("touchstart.dropdown.data-api",".dropdown-menu",function(e){e.stopPropagation()}).on("click.dropdown.data-api touchstart.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.dropdown.data-api touchstart.dropdown.data-api",toggle+", [role=menu]",Dropdown.prototype.keydown)}(window.jQuery),!function($){"use strict";var Modal=function(element,options){this.options=options,this.$element=$(element).delegate('[data-dismiss="modal"]',"click.dismiss.modal",$.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};Modal.prototype={constructor:Modal,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var that=this,e=$.Event("show");this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(document.body),that.$element.show(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in").attr("aria-hidden",!1),that.enforceFocus(),transition?that.$element.one($.support.transition.end,function(){that.$element.focus().trigger("shown")}):that.$element.focus().trigger("shown")}))},hide:function(e){e&&e.preventDefault(),e=$.Event("hide"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),$(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),$.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal())},enforceFocus:function(){var that=this;$(document).on("focusin.modal",function(e){that.$element[0]===e.target||that.$element.has(e.target).length||that.$element.focus()})},escape:function(){var that=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(e){27==e.which&&that.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var that=this,timeout=setTimeout(function(){that.$element.off($.support.transition.end),that.hideModal()},500);this.$element.one($.support.transition.end,function(){clearTimeout(timeout),that.hideModal()})},hideModal:function(){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(callback){var animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;this.$backdrop=$('
').appendTo(document.body),this.$backdrop.click("static"==this.options.backdrop?$.proxy(this.$element[0].focus,this.$element[0]):$.proxy(this.hide,this)),doAnimate&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),doAnimate?this.$backdrop.one($.support.transition.end,callback):callback()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one($.support.transition.end,$.proxy(this.removeBackdrop,this)):this.removeBackdrop()):callback&&callback()}};var old=$.fn.modal;$.fn.modal=function(option){return this.each(function(){var $this=$(this),data=$this.data("modal"),options=$.extend({},$.fn.modal.defaults,$this.data(),"object"==typeof option&&option);data||$this.data("modal",data=new Modal(this,options)),"string"==typeof option?data[option]():options.show&&data.show()})},$.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},$.fn.modal.Constructor=Modal,$.fn.modal.noConflict=function(){return $.fn.modal=old,this},$(document).on("click.modal.data-api",'[data-toggle="modal"]',function(e){var $this=$(this),href=$this.attr("href"),$target=$($this.attr("data-target")||href&&href.replace(/.*(?=#[^\s]+$)/,"")),option=$target.data("modal")?"toggle":$.extend({remote:!/#/.test(href)&&href},$target.data(),$this.data());e.preventDefault(),$target.modal(option).one("hide",function(){$this.focus()})})}(window.jQuery),!function($){"use strict";var Tooltip=function(element,options){this.init("tooltip",element,options)};Tooltip.prototype={constructor:Tooltip,init:function(type,element,options){var eventIn,eventOut;this.type=type,this.$element=$(element),this.options=this.getOptions(options),this.enabled=!0,"click"==this.options.trigger?this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this)):"manual"!=this.options.trigger&&(eventIn="hover"==this.options.trigger?"mouseenter":"focus",eventOut="hover"==this.options.trigger?"mouseleave":"blur",this.$element.on(eventIn+"."+this.type,this.options.selector,$.proxy(this.enter,this)),this.$element.on(eventOut+"."+this.type,this.options.selector,$.proxy(this.leave,this))),this.options.selector?this._options=$.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(options){return options=$.extend({},$.fn[this.type].defaults,options,this.$element.data()),options.delay&&"number"==typeof options.delay&&(options.delay={show:options.delay,hide:options.delay}),options},enter:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return self.options.delay&&self.options.delay.show?(clearTimeout(this.timeout),self.hoverState="in",this.timeout=setTimeout(function(){"in"==self.hoverState&&self.show()},self.options.delay.show),void 0):self.show()},leave:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return this.timeout&&clearTimeout(this.timeout),self.options.delay&&self.options.delay.hide?(self.hoverState="out",this.timeout=setTimeout(function(){"out"==self.hoverState&&self.hide()},self.options.delay.hide),void 0):self.hide()},show:function(){var $tip,inside,pos,actualWidth,actualHeight,placement,tp;if(this.hasContent()&&this.enabled){switch($tip=this.tip(),this.setContent(),this.options.animation&&$tip.addClass("fade"),placement="function"==typeof this.options.placement?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement,inside=/in/.test(placement),$tip.detach().css({top:0,left:0,display:"block"}).insertAfter(this.$element),pos=this.getPosition(inside),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,inside?placement.split(" ")[1]:placement){case"bottom":tp={top:pos.top+pos.height,left:pos.left+pos.width/2-actualWidth/2};break;case"top":tp={top:pos.top-actualHeight,left:pos.left+pos.width/2-actualWidth/2};break;case"left":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth};break;case"right":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width}}$tip.offset(tp).addClass(placement).addClass("in")}},setContent:function(){var $tip=this.tip(),title=this.getTitle();$tip.find(".tooltip-inner")[this.options.html?"html":"text"](title),$tip.removeClass("fade in top bottom left right")},hide:function(){function removeWithAnimation(){var timeout=setTimeout(function(){$tip.off($.support.transition.end).detach()},500);$tip.one($.support.transition.end,function(){clearTimeout(timeout),$tip.detach()})}var $tip=this.tip();return $tip.removeClass("in"),$.support.transition&&this.$tip.hasClass("fade")?removeWithAnimation():$tip.detach(),this},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("data-original-title"))&&$e.attr("data-original-title",$e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(inside){return $.extend({},inside?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var title,$e=this.$element,o=this.options;return title=$e.attr("data-original-title")||("function"==typeof o.title?o.title.call($e[0]):o.title)},tip:function(){return this.$tip=this.$tip||$(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);self[self.tip().hasClass("in")?"hide":"show"]()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var old=$.fn.tooltip;$.fn.tooltip=function(option){return this.each(function(){var $this=$(this),data=$this.data("tooltip"),options="object"==typeof option&&option;data||$this.data("tooltip",data=new Tooltip(this,options)),"string"==typeof option&&data[option]()})},$.fn.tooltip.Constructor=Tooltip,$.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
',trigger:"hover",title:"",delay:0,html:!1},$.fn.tooltip.noConflict=function(){return $.fn.tooltip=old,this}}(window.jQuery),!function($){"use strict";var Popover=function(element,options){this.init("popover",element,options)};Popover.prototype=$.extend({},$.fn.tooltip.Constructor.prototype,{constructor:Popover,setContent:function(){var $tip=this.tip(),title=this.getTitle(),content=this.getContent();$tip.find(".popover-title")[this.options.html?"html":"text"](title),$tip.find(".popover-content")[this.options.html?"html":"text"](content),$tip.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var content,$e=this.$element,o=this.options;return content=$e.attr("data-content")||("function"==typeof o.content?o.content.call($e[0]):o.content)},tip:function(){return this.$tip||(this.$tip=$(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var old=$.fn.popover;$.fn.popover=function(option){return this.each(function(){var $this=$(this),data=$this.data("popover"),options="object"==typeof option&&option;data||$this.data("popover",data=new Popover(this,options)),"string"==typeof option&&data[option]()})},$.fn.popover.Constructor=Popover,$.fn.popover.defaults=$.extend({},$.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'
'}),$.fn.popover.noConflict=function(){return $.fn.popover=old,this}}(window.jQuery),!function($){"use strict";function ScrollSpy(element,options){var href,process=$.proxy(this.process,this),$element=$(element).is("body")?$(window):$(element);this.options=$.extend({},$.fn.scrollspy.defaults,options),this.$scrollElement=$element.on("scroll.scroll-spy.data-api",process),this.selector=(this.options.target||(href=$(element).attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=$("body"),this.refresh(),this.process()}ScrollSpy.prototype={constructor:ScrollSpy,refresh:function(){var $targets,self=this;this.offsets=$([]),this.targets=$([]),$targets=this.$body.find(this.selector).map(function(){var $el=$(this),href=$el.data("target")||$el.attr("href"),$href=/^#\w/.test(href)&&$(href);return $href&&$href.length&&[[$href.position().top+self.$scrollElement.scrollTop(),href]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){self.offsets.push(this[0]),self.targets.push(this[1])})},process:function(){var i,scrollTop=this.$scrollElement.scrollTop()+this.options.offset,scrollHeight=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,maxScroll=scrollHeight-this.$scrollElement.height(),offsets=this.offsets,targets=this.targets,activeTarget=this.activeTarget;if(scrollTop>=maxScroll)return activeTarget!=(i=targets.last()[0])&&this.activate(i);for(i=offsets.length;i--;)activeTarget!=targets[i]&&scrollTop>=offsets[i]&&(!offsets[i+1]||offsets[i+1]>=scrollTop)&&this.activate(targets[i])},activate:function(target){var active,selector;this.activeTarget=target,$(this.selector).parent(".active").removeClass("active"),selector=this.selector+'[data-target="'+target+'"],'+this.selector+'[href="'+target+'"]',active=$(selector).parent("li").addClass("active"),active.parent(".dropdown-menu").length&&(active=active.closest("li.dropdown").addClass("active")),active.trigger("activate")}};var old=$.fn.scrollspy;$.fn.scrollspy=function(option){return this.each(function(){var $this=$(this),data=$this.data("scrollspy"),options="object"==typeof option&&option;data||$this.data("scrollspy",data=new ScrollSpy(this,options)),"string"==typeof option&&data[option]()})},$.fn.scrollspy.Constructor=ScrollSpy,$.fn.scrollspy.defaults={offset:10},$.fn.scrollspy.noConflict=function(){return $.fn.scrollspy=old,this},$(window).on("load",function(){$('[data-spy="scroll"]').each(function(){var $spy=$(this);$spy.scrollspy($spy.data())})})}(window.jQuery),!function($){"use strict";var Tab=function(element){this.element=$(element)};Tab.prototype={constructor:Tab,show:function(){var previous,$target,e,$this=this.element,$ul=$this.closest("ul:not(.dropdown-menu)"),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$this.parent("li").hasClass("active")||(previous=$ul.find(".active:last a")[0],e=$.Event("show",{relatedTarget:previous}),$this.trigger(e),e.isDefaultPrevented()||($target=$(selector),this.activate($this.parent("li"),$ul),this.activate($target,$target.parent(),function(){$this.trigger({type:"shown",relatedTarget:previous})})))},activate:function(element,container,callback){function next(){$active.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),element.addClass("active"),transition?(element[0].offsetWidth,element.addClass("in")):element.removeClass("fade"),element.parent(".dropdown-menu")&&element.closest("li.dropdown").addClass("active"),callback&&callback()}var $active=container.find("> .active"),transition=callback&&$.support.transition&&$active.hasClass("fade");transition?$active.one($.support.transition.end,next):next(),$active.removeClass("in")}};var old=$.fn.tab;$.fn.tab=function(option){return this.each(function(){var $this=$(this),data=$this.data("tab");data||$this.data("tab",data=new Tab(this)),"string"==typeof option&&data[option]()})},$.fn.tab.Constructor=Tab,$.fn.tab.noConflict=function(){return $.fn.tab=old,this},$(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(e){e.preventDefault(),$(this).tab("show")})}(window.jQuery),!function($){"use strict";var Typeahead=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.typeahead.defaults,options),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=$(this.options.menu),this.shown=!1,this.listen()};Typeahead.prototype={constructor:Typeahead,select:function(){var val=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(val)).change(),this.hide()},updater:function(item){return item},show:function(){var pos=$.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:pos.top+pos.height,left:pos.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(){var items;return this.query=this.$element.val(),!this.query||this.query.length
"+match+""})},render:function(items){var that=this;return items=$(items).map(function(i,item){return i=$(that.options.item).attr("data-value",item),i.find("a").html(that.highlighter(item)),i[0]}),items.first().addClass("active"),this.$menu.html(items),this},next:function(){var active=this.$menu.find(".active").removeClass("active"),next=active.next();next.length||(next=$(this.$menu.find("li")[0])),next.addClass("active")},prev:function(){var active=this.$menu.find(".active").removeClass("active"),prev=active.prev();prev.length||(prev=this.$menu.find("li").last()),prev.addClass("active")},listen:function(){this.$element.on("blur",$.proxy(this.blur,this)).on("keypress",$.proxy(this.keypress,this)).on("keyup",$.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",$.proxy(this.keydown,this)),this.$menu.on("click",$.proxy(this.click,this)).on("mouseenter","li",$.proxy(this.mouseenter,this))},eventSupported:function(eventName){var isSupported=eventName in this.$element;return isSupported||(this.$element.setAttribute(eventName,"return;"),isSupported="function"==typeof this.$element[eventName]),isSupported},move:function(e){if(this.shown){switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()}},keydown:function(e){this.suppressKeyPressRepeat=~$.inArray(e.keyCode,[40,38,9,13,27]),this.move(e)},keypress:function(e){this.suppressKeyPressRepeat||this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(){var that=this;setTimeout(function(){that.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(e){this.$menu.find(".active").removeClass("active"),$(e.currentTarget).addClass("active")}};var old=$.fn.typeahead;$.fn.typeahead=function(option){return this.each(function(){var $this=$(this),data=$this.data("typeahead"),options="object"==typeof option&&option;data||$this.data("typeahead",data=new Typeahead(this,options)),"string"==typeof option&&data[option]()})},$.fn.typeahead.defaults={source:[],items:8,menu:'',item:' ',minLength:1},$.fn.typeahead.Constructor=Typeahead,$.fn.typeahead.noConflict=function(){return $.fn.typeahead=old,this},$(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(e){var $this=$(this);$this.data("typeahead")||(e.preventDefault(),$this.typeahead($this.data()))})}(window.jQuery),!function($){"use strict";var Affix=function(element,options){this.options=$.extend({},$.fn.affix.defaults,options),this.$window=$(window).on("scroll.affix.data-api",$.proxy(this.checkPosition,this)).on("click.affix.data-api",$.proxy(function(){setTimeout($.proxy(this.checkPosition,this),1)},this)),this.$element=$(element),this.checkPosition()};Affix.prototype.checkPosition=function(){if(this.$element.is(":visible")){var affix,scrollHeight=$(document).height(),scrollTop=this.$window.scrollTop(),position=this.$element.offset(),offset=this.options.offset,offsetBottom=offset.bottom,offsetTop=offset.top,reset="affix affix-top affix-bottom";"object"!=typeof offset&&(offsetBottom=offsetTop=offset),"function"==typeof offsetTop&&(offsetTop=offset.top()),"function"==typeof offsetBottom&&(offsetBottom=offset.bottom()),affix=null!=this.unpin&&scrollTop+this.unpin<=position.top?!1:null!=offsetBottom&&position.top+this.$element.height()>=scrollHeight-offsetBottom?"bottom":null!=offsetTop&&offsetTop>=scrollTop?"top":!1,this.affixed!==affix&&(this.affixed=affix,this.unpin="bottom"==affix?position.top-scrollTop:null,this.$element.removeClass(reset).addClass("affix"+(affix?"-"+affix:"")))}};var old=$.fn.affix;$.fn.affix=function(option){return this.each(function(){var $this=$(this),data=$this.data("affix"),options="object"==typeof option&&option;data||$this.data("affix",data=new Affix(this,options)),"string"==typeof option&&data[option]()})},$.fn.affix.Constructor=Affix,$.fn.affix.defaults={offset:0},$.fn.affix.noConflict=function(){return $.fn.affix=old,this},$(window).on("load",function(){$('[data-spy="affix"]').each(function(){var $spy=$(this),data=$spy.data();data.offset=data.offset||{},data.offsetBottom&&(data.offset.bottom=data.offsetBottom),data.offsetTop&&(data.offset.top=data.offsetTop),$spy.affix(data)})})}(window.jQuery);
\ No newline at end of file
diff --git a/js/common.js b/js/common.js
new file mode 100644
index 0000000..7cccfe8
--- /dev/null
+++ b/js/common.js
@@ -0,0 +1,29 @@
+jQuery(document).ready(function($) {
+ // $() will work as an alias for jQuery() inside of this function
+
+ $('ul.menu-mobile').before('');
+
+ $("#primary-menu-toggle .show").click(function () {
+ if ($(".menu-mobile").is(":hidden")) {
+ $(".menu-mobile").slideDown(500);
+ $(this).attr('class', 'toggle-switch hide').attr('title', 'Hide Menu');
+ $('#primary-menu-toggle span').replaceWith('Hide Menu ');
+ } else {
+ $(".menu-mobile").hide(500);
+ $(this).attr('class', 'toggle-switch show').attr('title', 'Show Menu');
+ $('#primary-menu-toggle span').replaceWith('Show Menu ');
+ }
+ });
+
+
+ /*SMOOTH SCROLLING*/
+ jQuery(".scroll, .gototop a").click(function(event){
+ event.preventDefault();
+ jQuery('html,body').animate({scrollTop:jQuery(this.hash).offset().top}, 500);
+ });
+
+
+});
+
+
+
\ No newline at end of file
diff --git a/js/common.min.js b/js/common.min.js
new file mode 100644
index 0000000..ff228b4
--- /dev/null
+++ b/js/common.min.js
@@ -0,0 +1 @@
+jQuery(document).ready(function(e){e("ul.menu-mobile").before('');e("#primary-menu-toggle .show").click(function(){if(e(".menu-mobile").is(":hidden")){e(".menu-mobile").slideDown(500);e(this).attr("class","toggle-switch hide").attr("title","Hide Menu");e("#primary-menu-toggle span").replaceWith("Hide Menu ")}else{e(".menu-mobile").hide(500);e(this).attr("class","toggle-switch show").attr("title","Show Menu");e("#primary-menu-toggle span").replaceWith("Show Menu ")}});jQuery(".scroll, .gototop a").click(function(e){e.preventDefault();jQuery("html,body").animate({scrollTop:jQuery(this.hash).offset().top},500)})})
\ No newline at end of file
diff --git a/js/html5shiv.js b/js/html5shiv.js
new file mode 100644
index 0000000..b879e50
--- /dev/null
+++ b/js/html5shiv.js
@@ -0,0 +1,299 @@
+/**
+* @preserve HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+;(function(window, document) {
+/*jshint evil:true */
+ /** version */
+ var version = '3.6.2pre';
+
+ /** Preset options */
+ var options = window.html5 || {};
+
+ /** Used to skip problem elements */
+ var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
+
+ /** Not all elements can be cloned in IE **/
+ var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
+
+ /** Detect whether the browser supports default html5 styles */
+ var supportsHtml5Styles;
+
+ /** Name of the expando, to work with multiple documents or to re-shiv one document */
+ var expando = '_html5shiv';
+
+ /** The id for the the documents expando */
+ var expanID = 0;
+
+ /** Cached data for each document */
+ var expandoData = {};
+
+ /** Detect whether the browser supports unknown elements */
+ var supportsUnknownElements;
+
+ (function() {
+ try {
+ var a = document.createElement('a');
+ a.innerHTML = ' ';
+ //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
+ supportsHtml5Styles = ('hidden' in a);
+
+ supportsUnknownElements = a.childNodes.length == 1 || (function() {
+ // assign a false positive if unable to shiv
+ (document.createElement)('a');
+ var frag = document.createDocumentFragment();
+ return (
+ typeof frag.cloneNode == 'undefined' ||
+ typeof frag.createDocumentFragment == 'undefined' ||
+ typeof frag.createElement == 'undefined'
+ );
+ }());
+ } catch(e) {
+ // assign a false positive if detection fails => unable to shiv
+ supportsHtml5Styles = true;
+ supportsUnknownElements = true;
+ }
+
+ }());
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Creates a style sheet with the given CSS text and adds it to the document.
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @param {String} cssText The CSS text.
+ * @returns {StyleSheet} The style element.
+ */
+ function addStyleSheet(ownerDocument, cssText) {
+ var p = ownerDocument.createElement('p'),
+ parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
+
+ p.innerHTML = 'x';
+ return parent.insertBefore(p.lastChild, parent.firstChild);
+ }
+
+ /**
+ * Returns the value of `html5.elements` as an array.
+ * @private
+ * @returns {Array} An array of shived element node names.
+ */
+ function getElements() {
+ var elements = html5.elements;
+ return typeof elements == 'string' ? elements.split(' ') : elements;
+ }
+
+ /**
+ * Returns the data associated to the given document
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @returns {Object} An object of data.
+ */
+ function getExpandoData(ownerDocument) {
+ var data = expandoData[ownerDocument[expando]];
+ if (!data) {
+ data = {};
+ expanID++;
+ ownerDocument[expando] = expanID;
+ expandoData[expanID] = data;
+ }
+ return data;
+ }
+
+ /**
+ * returns a shived element for the given nodeName and document
+ * @memberOf html5
+ * @param {String} nodeName name of the element
+ * @param {Document} ownerDocument The context document.
+ * @returns {Object} The shived element.
+ */
+ function createElement(nodeName, ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createElement(nodeName);
+ }
+ if (!data) {
+ data = getExpandoData(ownerDocument);
+ }
+ var node;
+
+ if (data.cache[nodeName]) {
+ node = data.cache[nodeName].cloneNode();
+ } else if (saveClones.test(nodeName)) {
+ node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
+ } else {
+ node = data.createElem(nodeName);
+ }
+
+ // Avoid adding some elements to fragments in IE < 9 because
+ // * Attributes like `name` or `type` cannot be set/changed once an element
+ // is inserted into a document/fragment
+ // * Link elements with `src` attributes that are inaccessible, as with
+ // a 403 response, will cause the tab/window to crash
+ // * Script elements appended to fragments will execute when their `src`
+ // or `text` property is set
+ return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
+ }
+
+ /**
+ * returns a shived DocumentFragment for the given document
+ * @memberOf html5
+ * @param {Document} ownerDocument The context document.
+ * @returns {Object} The shived DocumentFragment.
+ */
+ function createDocumentFragment(ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createDocumentFragment();
+ }
+ data = data || getExpandoData(ownerDocument);
+ var clone = data.frag.cloneNode(),
+ i = 0,
+ elems = getElements(),
+ l = elems.length;
+ for(;i"+t+"";return r.insertBefore(n.lastChild,r.firstChild)}function h(){var e=y.elements;return typeof e=="string"?e.split(" "):e}function p(e){var t=f[e[u]];if(!t){t={};a++;e[u]=a;f[a]=t}return t}function d(e,n,r){if(!n){n=t}if(l){return n.createElement(e)}if(!r){r=p(n)}var o;if(r.cache[e]){o=r.cache[e].cloneNode()}else if(s.test(e)){o=(r.cache[e]=r.createElem(e)).cloneNode()}else{o=r.createElem(e)}return o.canHaveChildren&&!i.test(e)?r.frag.appendChild(o):o}function v(e,n){if(!e){e=t}if(l){return e.createDocumentFragment()}n=n||p(e);var r=n.frag.cloneNode(),i=0,s=h(),o=s.length;for(;i";o="hidden"in e;l=e.childNodes.length==1||function(){t.createElement("a");var e=t.createDocumentFragment();return typeof e.cloneNode=="undefined"||typeof e.createDocumentFragment=="undefined"||typeof e.createElement=="undefined"}()}catch(n){o=true;l=true}})();var y={elements:r.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:n,shivCSS:r.shivCSS!==false,supportsUnknownElements:l,shivMethods:r.shivMethods!==false,type:"default",shivDocument:g,createElement:d,createDocumentFragment:v};e.html5=y;g(t)})(this,document)
\ No newline at end of file
diff --git a/js/jquery.prettyPhoto.js b/js/jquery.prettyPhoto.js
new file mode 100644
index 0000000..0f9ac8a
--- /dev/null
+++ b/js/jquery.prettyPhoto.js
@@ -0,0 +1,915 @@
+/* ------------------------------------------------------------------------
+ Class: prettyPhoto
+ Use: Lightbox clone for jQuery
+ Author: Stephane Caron (http://www.no-margin-for-errors.com)
+ Version: 3.1.4
+------------------------------------------------------------------------- */
+(function($) {
+ $.prettyPhoto = {version: '3.1.4'};
+
+ $.fn.prettyPhoto = function(pp_settings) {
+ pp_settings = jQuery.extend({
+ hook: 'rel', /* the attribute tag to use for prettyPhoto hooks. default: 'rel'. For HTML5, use "data-rel" or similar. */
+ animation_speed: 'fast', /* fast/slow/normal */
+ ajaxcallback: function() {},
+ slideshow: 5000, /* false OR interval time in ms */
+ autoplay_slideshow: false, /* true/false */
+ opacity: 0.80, /* Value between 0 and 1 */
+ show_title: true, /* true/false */
+ allow_resize: true, /* Resize the photos bigger than viewport. true/false */
+ allow_expand: true, /* Allow the user to expand a resized image. true/false */
+ default_width: 500,
+ default_height: 344,
+ counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
+ theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
+ horizontal_padding: 20, /* The padding on each side of the picture */
+ hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
+ wmode: 'opaque', /* Set the flash wmode attribute */
+ autoplay: true, /* Automatically start videos: True/False */
+ modal: false, /* If set to true, only the close button will close the window */
+ deeplinking: true, /* Allow prettyPhoto to update the url to enable deeplinking. */
+ overlay_gallery: true, /* If set to true, a gallery will overlay the fullscreen image on mouse over */
+ overlay_gallery_max: 30, /* Maximum number of pictures in the overlay gallery */
+ keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */
+ changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
+ callback: function(){}, /* Called when prettyPhoto is closed */
+ ie6_fallback: true,
+ markup: ' \
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
Expand \
+
\
+
\
+
\
+
\
+
\
+
{pp_social}
\
+
Close \
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
',
+ gallery_markup: '',
+ image_markup: ' ',
+ flash_markup: ' ',
+ quicktime_markup: ' ',
+ iframe_markup: '',
+ inline_markup: '{content}
',
+ custom_markup: '',
+ social_tools: '
' /* html or false to disable */
+ }, pp_settings);
+
+ // Global variables accessible only by prettyPhoto
+ var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
+
+ // prettyPhoto container specific
+ pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
+
+ // Window size
+ windowHeight = $(window).height(), windowWidth = $(window).width(),
+
+ // Global elements
+ pp_slideshow;
+
+ doresize = true, scroll_pos = _get_scroll();
+
+ // Window/Keyboard events
+ $(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
+
+ if(pp_settings.keyboard_shortcuts) {
+ $(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
+ if(typeof $pp_pic_holder != 'undefined'){
+ if($pp_pic_holder.is(':visible')){
+ switch(e.keyCode){
+ case 37:
+ $.prettyPhoto.changePage('previous');
+ e.preventDefault();
+ break;
+ case 39:
+ $.prettyPhoto.changePage('next');
+ e.preventDefault();
+ break;
+ case 27:
+ if(!settings.modal)
+ $.prettyPhoto.close();
+ e.preventDefault();
+ break;
+ };
+ // return false;
+ };
+ };
+ });
+ };
+
+ /**
+ * Initialize prettyPhoto.
+ */
+ $.prettyPhoto.initialize = function() {
+
+ settings = pp_settings;
+
+ if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
+ if(settings.ie6_fallback && $.browser.msie && parseInt($.browser.version) == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
+
+ // Find out if the picture is part of a set
+ theRel = $(this).attr(settings.hook);
+ galleryRegExp = /\[(?:.*)\]/;
+ isSet = (galleryRegExp.exec(theRel)) ? true : false;
+
+ // Put the SRCs, TITLEs, ALTs into an array.
+ pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
+ pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
+ pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
+
+ if(pp_images.length > settings.overlay_gallery_max) settings.overlay_gallery = false;
+
+ set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
+ rel_index = (isSet) ? set_position : $("a["+settings.hook+"^='"+theRel+"']").index($(this));
+
+ _build_overlay(this); // Build the overlay {this} being the caller
+
+ if(settings.allow_resize)
+ $(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
+
+
+ $.prettyPhoto.open();
+
+ return false;
+ }
+
+
+ /**
+ * Opens the prettyPhoto modal box.
+ * @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
+ * @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
+ * @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
+ */
+ $.prettyPhoto.open = function(event) {
+ if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
+ settings = pp_settings;
+ if($.browser.msie && $.browser.version == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
+ pp_images = $.makeArray(arguments[0]);
+ pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
+ pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
+ isSet = (pp_images.length > 1) ? true : false;
+ set_position = (arguments[3])? arguments[3]: 0;
+ _build_overlay(event.target); // Build the overlay {this} being the caller
+ }
+
+ if($.browser.msie && $.browser.version == 6) $('select').css('visibility','hidden'); // To fix the bug with IE select boxes
+
+ if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
+
+ _checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
+
+ $('.pp_loaderIcon').show();
+
+ if(settings.deeplinking)
+ setHashtag();
+
+ // Rebuild Facebook Like Button with updated href
+ if(settings.social_tools){
+ facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
+ $pp_pic_holder.find('.pp_social').html(facebook_like_link);
+ }
+
+ // Fade the content in
+ if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
+ $pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
+
+ // Display the current position
+ $pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).size());
+
+ // Set the description
+ if(typeof pp_descriptions[set_position] != 'undefined' && pp_descriptions[set_position] != ""){
+ $pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
+ }else{
+ $pp_pic_holder.find('.pp_description').hide();
+ }
+
+ // Get the dimensions
+ movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
+ movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
+
+ // If the size is % based, calculate according to window dimensions
+ percentBased=false;
+ if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
+ if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
+
+ // Fade the holder
+ $pp_pic_holder.fadeIn(function(){
+ // Set the title
+ (settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html(' ');
+
+ imgPreloader = "";
+ skipInjection = false;
+
+ // Inject the proper content
+ switch(_getFileType(pp_images[set_position])){
+ case 'image':
+ imgPreloader = new Image();
+
+ // Preload the neighbour images
+ nextImage = new Image();
+ if(isSet && set_position < $(pp_images).size() -1) nextImage.src = pp_images[set_position + 1];
+ prevImage = new Image();
+ if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
+
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
+
+ imgPreloader.onload = function(){
+ // Fit item to viewport
+ pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
+
+ _showContent();
+ };
+
+ imgPreloader.onerror = function(){
+ alert('Image cannot be loaded. Make sure the path is correct and image exist.');
+ $.prettyPhoto.close();
+ };
+
+ imgPreloader.src = pp_images[set_position];
+ break;
+
+ case 'youtube':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ // Regular youtube link
+ movie_id = getParam('v',pp_images[set_position]);
+
+ // youtu.be link
+ if(movie_id == ""){
+ movie_id = pp_images[set_position].split('youtu.be/');
+ movie_id = movie_id[1];
+ if(movie_id.indexOf('?') > 0)
+ movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
+
+ if(movie_id.indexOf('&') > 0)
+ movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
+ }
+
+ movie = 'http://www.youtube.com/embed/'+movie_id;
+ (getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
+
+ if(settings.autoplay) movie += "&autoplay=1";
+
+ toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
+ break;
+
+ case 'vimeo':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ movie_id = pp_images[set_position];
+ var regExp = /http:\/\/(www\.)?vimeo.com\/(\d+)/;
+ var match = movie_id.match(regExp);
+
+ movie = 'http://player.vimeo.com/video/'+ match[2] +'?title=0&byline=0&portrait=0';
+ if(settings.autoplay) movie += "&autoplay=1;";
+
+ vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
+
+ toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
+ break;
+
+ case 'quicktime':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+ pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
+
+ toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
+ break;
+
+ case 'flash':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ flash_vars = pp_images[set_position];
+ flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
+
+ filename = pp_images[set_position];
+ filename = filename.substring(0,filename.indexOf('?'));
+
+ toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
+ break;
+
+ case 'iframe':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ frame_url = pp_images[set_position];
+ frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
+
+ toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
+ break;
+
+ case 'ajax':
+ doresize = false; // Make sure the dimensions are not resized.
+ pp_dimensions = _fitToViewport(movie_width,movie_height);
+ doresize = true; // Reset the dimensions
+
+ skipInjection = true;
+ $.get(pp_images[set_position],function(responseHTML){
+ toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
+ _showContent();
+ });
+
+ break;
+
+ case 'custom':
+ pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
+
+ toInject = settings.custom_markup;
+ break;
+
+ case 'inline':
+ // to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
+ myClone = $(pp_images[set_position]).clone().append(' ').css({'width':settings.default_width}).wrapInner('').appendTo($('body')).show();
+ doresize = false; // Make sure the dimensions are not resized.
+ pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
+ doresize = true; // Reset the dimensions
+ $(myClone).remove();
+ toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
+ break;
+ };
+
+ if(!imgPreloader && !skipInjection){
+ $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
+
+ // Show content
+ _showContent();
+ };
+ });
+
+ return false;
+ };
+
+
+ /**
+ * Change page in the prettyPhoto modal box
+ * @param direction {String} Direction of the paging, previous or next.
+ */
+ $.prettyPhoto.changePage = function(direction){
+ currentGalleryPage = 0;
+
+ if(direction == 'previous') {
+ set_position--;
+ if (set_position < 0) set_position = $(pp_images).size()-1;
+ }else if(direction == 'next'){
+ set_position++;
+ if(set_position > $(pp_images).size()-1) set_position = 0;
+ }else{
+ set_position=direction;
+ };
+
+ rel_index = set_position;
+
+ if(!doresize) doresize = true; // Allow the resizing of the images
+ if(settings.allow_expand) {
+ $('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
+ }
+
+ _hideContent(function(){ $.prettyPhoto.open(); });
+ };
+
+
+ /**
+ * Change gallery page in the prettyPhoto modal box
+ * @param direction {String} Direction of the paging, previous or next.
+ */
+ $.prettyPhoto.changeGalleryPage = function(direction){
+ if(direction=='next'){
+ currentGalleryPage ++;
+
+ if(currentGalleryPage > totalPage) currentGalleryPage = 0;
+ }else if(direction=='previous'){
+ currentGalleryPage --;
+
+ if(currentGalleryPage < 0) currentGalleryPage = totalPage;
+ }else{
+ currentGalleryPage = direction;
+ };
+
+ slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
+
+ slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
+
+ $pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
+ };
+
+
+ /**
+ * Start the slideshow...
+ */
+ $.prettyPhoto.startSlideshow = function(){
+ if(typeof pp_slideshow == 'undefined'){
+ $pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+ pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
+ }else{
+ $.prettyPhoto.changePage('next');
+ };
+ }
+
+
+ /**
+ * Stop the slideshow...
+ */
+ $.prettyPhoto.stopSlideshow = function(){
+ $pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
+ $.prettyPhoto.startSlideshow();
+ return false;
+ });
+ clearInterval(pp_slideshow);
+ pp_slideshow=undefined;
+ }
+
+
+ /**
+ * Closes prettyPhoto.
+ */
+ $.prettyPhoto.close = function(){
+ if($pp_overlay.is(":animated")) return;
+
+ $.prettyPhoto.stopSlideshow();
+
+ $pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
+
+ $('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
+
+ $pp_overlay.fadeOut(settings.animation_speed, function(){
+ if($.browser.msie && $.browser.version == 6) $('select').css('visibility','visible'); // To fix the bug with IE select boxes
+
+ if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
+
+ $(this).remove(); // No more need for the prettyPhoto markup
+
+ $(window).unbind('scroll.prettyphoto');
+
+ clearHashtag();
+
+ settings.callback();
+
+ doresize = true;
+
+ pp_open = false;
+
+ delete settings;
+ });
+ };
+
+ /**
+ * Set the proper sizes on the containers and animate the content in.
+ */
+ function _showContent(){
+ $('.pp_loaderIcon').hide();
+
+ // Calculate the opened top position of the pic holder
+ projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
+ if(projectedTop < 0) projectedTop = 0;
+
+ $ppt.fadeTo(settings.animation_speed,1);
+
+ // Resize the content holder
+ $pp_pic_holder.find('.pp_content')
+ .animate({
+ height:pp_dimensions['contentHeight'],
+ width:pp_dimensions['contentWidth']
+ },settings.animation_speed);
+
+ // Resize picture the holder
+ $pp_pic_holder.animate({
+ 'top': projectedTop,
+ 'left': ((windowWidth/2) - (pp_dimensions['containerWidth']/2) < 0) ? 0 : (windowWidth/2) - (pp_dimensions['containerWidth']/2),
+ width:pp_dimensions['containerWidth']
+ },settings.animation_speed,function(){
+ $pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
+
+ $pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
+
+ // Show the nav
+ if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
+
+ if(settings.allow_expand) {
+ if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
+ $('a.pp_expand,a.pp_contract').show();
+ }else{
+ $('a.pp_expand').hide();
+ }
+ }
+
+ if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
+
+ settings.changepicturecallback(); // Callback!
+
+ pp_open = true;
+ });
+
+ _insert_gallery();
+ pp_settings.ajaxcallback();
+ };
+
+ /**
+ * Hide the content...DUH!
+ */
+ function _hideContent(callback){
+ // Fade out the current picture
+ $pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
+ $pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
+ $('.pp_loaderIcon').show();
+
+ callback();
+ });
+ };
+
+ /**
+ * Check the item position in the gallery array, hide or show the navigation links
+ * @param setCount {integer} The total number of items in the set
+ */
+ function _checkPosition(setCount){
+ (setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
+ };
+
+ /**
+ * Resize the item dimensions if it's bigger than the viewport
+ * @param width {integer} Width of the item to be opened
+ * @param height {integer} Height of the item to be opened
+ * @return An array containin the "fitted" dimensions
+ */
+ function _fitToViewport(width,height){
+ resized = false;
+
+ _getDimensions(width,height);
+
+ // Define them in case there's no resize needed
+ imageWidth = width, imageHeight = height;
+
+ if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
+ resized = true, fitting = false;
+
+ while (!fitting){
+ if((pp_containerWidth > windowWidth)){
+ imageWidth = (windowWidth - 200);
+ imageHeight = (height/width) * imageWidth;
+ }else if((pp_containerHeight > windowHeight)){
+ imageHeight = (windowHeight - 200);
+ imageWidth = (width/height) * imageHeight;
+ }else{
+ fitting = true;
+ };
+
+ pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
+ };
+
+ _getDimensions(imageWidth,imageHeight);
+
+ if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
+ _fitToViewport(pp_containerWidth,pp_containerHeight)
+ };
+ };
+
+ return {
+ width:Math.floor(imageWidth),
+ height:Math.floor(imageHeight),
+ containerHeight:Math.floor(pp_containerHeight),
+ containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
+ contentHeight:Math.floor(pp_contentHeight),
+ contentWidth:Math.floor(pp_contentWidth),
+ resized:resized
+ };
+ };
+
+ /**
+ * Get the containers dimensions according to the item size
+ * @param width {integer} Width of the item to be opened
+ * @param height {integer} Height of the item to be opened
+ */
+ function _getDimensions(width,height){
+ width = parseFloat(width);
+ height = parseFloat(height);
+
+ // Get the details height, to do so, I need to clone it since it's invisible
+ $pp_details = $pp_pic_holder.find('.pp_details');
+ $pp_details.width(width);
+ detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
+
+ $pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
+ 'position':'absolute',
+ 'top':-10000
+ });
+ detailsHeight += $pp_details.height();
+ detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
+ if($.browser.msie && $.browser.version==7) detailsHeight+=8;
+ $pp_details.remove();
+
+ // Get the titles height, to do so, I need to clone it since it's invisible
+ $pp_title = $pp_pic_holder.find('.ppt');
+ $pp_title.width(width);
+ titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
+ $pp_title = $pp_title.clone().appendTo($('body')).css({
+ 'position':'absolute',
+ 'top':-10000
+ });
+ titleHeight += $pp_title.height();
+ $pp_title.remove();
+
+ // Get the container size, to resize the holder to the right dimensions
+ pp_contentHeight = height + detailsHeight;
+ pp_contentWidth = width;
+ pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
+ pp_containerWidth = width;
+ }
+
+ function _getFileType(itemSrc){
+ if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
+ return 'youtube';
+ }else if (itemSrc.match(/vimeo\.com/i)) {
+ return 'vimeo';
+ }else if(itemSrc.match(/\b.mov\b/i)){
+ return 'quicktime';
+ }else if(itemSrc.match(/\b.swf\b/i)){
+ return 'flash';
+ }else if(itemSrc.match(/\biframe=true\b/i)){
+ return 'iframe';
+ }else if(itemSrc.match(/\bajax=true\b/i)){
+ return 'ajax';
+ }else if(itemSrc.match(/\bcustom=true\b/i)){
+ return 'custom';
+ }else if(itemSrc.substr(0,1) == '#'){
+ return 'inline';
+ }else{
+ return 'image';
+ };
+ };
+
+ function _center_overlay(){
+ if(doresize && typeof $pp_pic_holder != 'undefined') {
+ scroll_pos = _get_scroll();
+ contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
+
+ projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
+ if(projectedTop < 0) projectedTop = 0;
+
+ if(contentHeight > windowHeight)
+ return;
+
+ $pp_pic_holder.css({
+ 'top': projectedTop,
+ 'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
+ });
+ };
+ };
+
+ function _get_scroll(){
+ if (self.pageYOffset) {
+ return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
+ } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
+ return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
+ } else if (document.body) {// all other Explorers
+ return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
+ };
+ };
+
+ function _resize_overlay() {
+ windowHeight = $(window).height(), windowWidth = $(window).width();
+
+ if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
+ };
+
+ function _insert_gallery(){
+ if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image" && (settings.ie6_fallback && !($.browser.msie && parseInt($.browser.version) == 6))) {
+ itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
+ navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
+
+ itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
+ itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
+ totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
+
+ // Hide the nav in the case there's no need for links
+ if(totalPage == 0){
+ navWidth = 0; // No nav means no width!
+ $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
+ }else{
+ $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
+ };
+
+ galleryWidth = itemsPerPage * itemWidth;
+ fullGalleryWidth = pp_images.length * itemWidth;
+
+ // Set the proper width to the gallery items
+ $pp_gallery
+ .css('margin-left',-((galleryWidth/2) + (navWidth/2)))
+ .find('div:first').width(galleryWidth+5)
+ .find('ul').width(fullGalleryWidth)
+ .find('li.selected').removeClass('selected');
+
+ goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
+
+ $.prettyPhoto.changeGalleryPage(goToPage);
+
+ $pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
+ }else{
+ $pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
+ // $pp_gallery.hide();
+ }
+ }
+
+ function _build_overlay(caller){
+ // Inject Social Tool markup into General markup
+ if(settings.social_tools)
+ facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
+
+ settings.markup = settings.markup.replace('{pp_social}','');
+
+ $('body').append(settings.markup); // Inject the markup
+
+ $pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
+
+ // Inject the inline gallery!
+ if(isSet && settings.overlay_gallery) {
+ currentGalleryPage = 0;
+ toInject = "";
+ for (var i=0; i < pp_images.length; i++) {
+ if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
+ classname = 'default';
+ img_src = '';
+ }else{
+ classname = '';
+ img_src = pp_images[i];
+ }
+ toInject += " ";
+ };
+
+ toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
+
+ $pp_pic_holder.find('#pp_full_res').after(toInject);
+
+ $pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
+
+ $pp_gallery.find('.pp_arrow_next').click(function(){
+ $.prettyPhoto.changeGalleryPage('next');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_gallery.find('.pp_arrow_previous').click(function(){
+ $.prettyPhoto.changeGalleryPage('previous');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_pic_holder.find('.pp_content').hover(
+ function(){
+ $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
+ },
+ function(){
+ $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
+ });
+
+ itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
+ $pp_gallery_li.each(function(i){
+ $(this)
+ .find('a')
+ .click(function(){
+ $.prettyPhoto.changePage(i);
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+ });
+ };
+
+
+ // Inject the play/pause if it's a slideshow
+ if(settings.slideshow){
+ $pp_pic_holder.find('.pp_nav').prepend('Play ')
+ $pp_pic_holder.find('.pp_nav .pp_play').click(function(){
+ $.prettyPhoto.startSlideshow();
+ return false;
+ });
+ }
+
+ $pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
+
+ $pp_overlay
+ .css({
+ 'opacity':0,
+ 'height':$(document).height(),
+ 'width':$(window).width()
+ })
+ .bind('click',function(){
+ if(!settings.modal) $.prettyPhoto.close();
+ });
+
+ $('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
+
+
+ if(settings.allow_expand) {
+ $('a.pp_expand').bind('click',function(e){
+ // Expand the image
+ if($(this).hasClass('pp_expand')){
+ $(this).removeClass('pp_expand').addClass('pp_contract');
+ doresize = false;
+ }else{
+ $(this).removeClass('pp_contract').addClass('pp_expand');
+ doresize = true;
+ };
+
+ _hideContent(function(){ $.prettyPhoto.open(); });
+
+ return false;
+ });
+ }
+
+ $pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
+ $.prettyPhoto.changePage('previous');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ $pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
+ $.prettyPhoto.changePage('next');
+ $.prettyPhoto.stopSlideshow();
+ return false;
+ });
+
+ _center_overlay(); // Center it
+ };
+
+ if(!pp_alreadyInitialized && getHashtag()){
+ pp_alreadyInitialized = true;
+
+ // Grab the rel index to trigger the click on the correct element
+ hashIndex = getHashtag();
+ hashRel = hashIndex;
+ hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
+ hashRel = hashRel.substring(0,hashRel.indexOf('/'));
+
+ // Little timeout to make sure all the prettyPhoto initialize scripts has been run.
+ // Useful in the event the page contain several init scripts.
+ setTimeout(function(){ $("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
+ }
+
+ return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
+ };
+
+ function getHashtag(){
+ url = location.href;
+ hashtag = (url.indexOf('#prettyPhoto') !== -1) ? decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)) : false;
+
+ return hashtag;
+ };
+
+ function setHashtag(){
+ if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
+ location.hash = theRel + '/'+rel_index+'/';
+ };
+
+ function clearHashtag(){
+ if ( location.href.indexOf('#prettyPhoto') !== -1 ) location.hash = "prettyPhoto";
+ }
+
+ function getParam(name,url){
+ name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
+ var regexS = "[\\?&]"+name+"=([^]*)";
+ var regex = new RegExp( regexS );
+ var results = regex.exec( url );
+ return ( results == null ) ? "" : results[1];
+ }
+
+})(jQuery);
+
+var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
diff --git a/js/jquery.prettyPhoto.min.js b/js/jquery.prettyPhoto.min.js
new file mode 100644
index 0000000..7e60981
--- /dev/null
+++ b/js/jquery.prettyPhoto.min.js
@@ -0,0 +1,83 @@
+/* ------------------------------------------------------------------------
+ Class: prettyPhoto
+ Use: Lightbox clone for jQuery
+ Author: Stephane Caron (http://www.no-margin-for-errors.com)
+ Version: 3.1.4
+------------------------------------------------------------------------- */
+
+(function($){$.prettyPhoto={version:'3.1.4'};$.fn.prettyPhoto=function(pp_settings){pp_settings=jQuery.extend({hook:'rel',animation_speed:'fast',ajaxcallback:function(){},slideshow:5000,autoplay_slideshow:false,opacity:0.80,show_title:true,allow_resize:true,allow_expand:true,default_width:500,default_height:344,counter_separator_label:'/',theme:'pp_default',horizontal_padding:20,hideflash:false,wmode:'opaque',autoplay:true,modal:false,deeplinking:true,overlay_gallery:true,overlay_gallery_max:30,keyboard_shortcuts:true,changepicturecallback:function(){},callback:function(){},ie6_fallback:true,markup:' \
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
Expand \
+
\
+
\
+
\
+
\
+
\
+
{pp_social}
\
+
Close \
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
',gallery_markup:'',image_markup:' ',flash_markup:' ',quicktime_markup:' ',iframe_markup:'',inline_markup:'{content}
',custom_markup:'',social_tools:'
'},pp_settings);var matchedObjects=this,percentBased=false,pp_dimensions,pp_open,pp_contentHeight,pp_contentWidth,pp_containerHeight,pp_containerWidth,windowHeight=$(window).height(),windowWidth=$(window).width(),pp_slideshow;doresize=true,scroll_pos=_get_scroll();$(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){_center_overlay();_resize_overlay();});if(pp_settings.keyboard_shortcuts){$(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){if(typeof $pp_pic_holder!='undefined'){if($pp_pic_holder.is(':visible')){switch(e.keyCode){case 37:$.prettyPhoto.changePage('previous');e.preventDefault();break;case 39:$.prettyPhoto.changePage('next');e.preventDefault();break;case 27:if(!settings.modal)
+$.prettyPhoto.close();e.preventDefault();break;};};};});};$.prettyPhoto.initialize=function(){settings=pp_settings;if(settings.theme=='pp_default')settings.horizontal_padding=16;if(settings.ie6_fallback&&$.browser.msie&&parseInt($.browser.version)==6)settings.theme="light_square";theRel=$(this).attr(settings.hook);galleryRegExp=/\[(?:.*)\]/;isSet=(galleryRegExp.exec(theRel))?true:false;pp_images=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr(settings.hook).indexOf(theRel)!=-1)return $(n).attr('href');}):$.makeArray($(this).attr('href'));pp_titles=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr(settings.hook).indexOf(theRel)!=-1)return($(n).find('img').attr('alt'))?$(n).find('img').attr('alt'):"";}):$.makeArray($(this).find('img').attr('alt'));pp_descriptions=(isSet)?jQuery.map(matchedObjects,function(n,i){if($(n).attr(settings.hook).indexOf(theRel)!=-1)return($(n).attr('title'))?$(n).attr('title'):"";}):$.makeArray($(this).attr('title'));if(pp_images.length>settings.overlay_gallery_max)settings.overlay_gallery=false;set_position=jQuery.inArray($(this).attr('href'),pp_images);rel_index=(isSet)?set_position:$("a["+settings.hook+"^='"+theRel+"']").index($(this));_build_overlay(this);if(settings.allow_resize)
+$(window).bind('scroll.prettyphoto',function(){_center_overlay();});$.prettyPhoto.open();return false;}
+$.prettyPhoto.open=function(event){if(typeof settings=="undefined"){settings=pp_settings;if($.browser.msie&&$.browser.version==6)settings.theme="light_square";pp_images=$.makeArray(arguments[0]);pp_titles=(arguments[1])?$.makeArray(arguments[1]):$.makeArray("");pp_descriptions=(arguments[2])?$.makeArray(arguments[2]):$.makeArray("");isSet=(pp_images.length>1)?true:false;set_position=(arguments[3])?arguments[3]:0;_build_overlay(event.target);}
+if($.browser.msie&&$.browser.version==6)$('select').css('visibility','hidden');if(settings.hideflash)$('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden');_checkPosition($(pp_images).size());$('.pp_loaderIcon').show();if(settings.deeplinking)
+setHashtag();if(settings.social_tools){facebook_like_link=settings.social_tools.replace('{location_href}',encodeURIComponent(location.href));$pp_pic_holder.find('.pp_social').html(facebook_like_link);}
+if($ppt.is(':hidden'))$ppt.css('opacity',0).show();$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);$pp_pic_holder.find('.currentTextHolder').text((set_position+1)+settings.counter_separator_label+$(pp_images).size());if(typeof pp_descriptions[set_position]!='undefined'&&pp_descriptions[set_position]!=""){$pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));}else{$pp_pic_holder.find('.pp_description').hide();}
+movie_width=(parseFloat(getParam('width',pp_images[set_position])))?getParam('width',pp_images[set_position]):settings.default_width.toString();movie_height=(parseFloat(getParam('height',pp_images[set_position])))?getParam('height',pp_images[set_position]):settings.default_height.toString();percentBased=false;if(movie_height.indexOf('%')!=-1){movie_height=parseFloat(($(window).height()*parseFloat(movie_height)/100)-150);percentBased=true;}
+if(movie_width.indexOf('%')!=-1){movie_width=parseFloat(($(window).width()*parseFloat(movie_width)/100)-150);percentBased=true;}
+$pp_pic_holder.fadeIn(function(){(settings.show_title&&pp_titles[set_position]!=""&&typeof pp_titles[set_position]!="undefined")?$ppt.html(unescape(pp_titles[set_position])):$ppt.html(' ');imgPreloader="";skipInjection=false;switch(_getFileType(pp_images[set_position])){case'image':imgPreloader=new Image();nextImage=new Image();if(isSet&&set_position<$(pp_images).size()-1)nextImage.src=pp_images[set_position+1];prevImage=new Image();if(isSet&&pp_images[set_position-1])prevImage.src=pp_images[set_position-1];$pp_pic_holder.find('#pp_full_res')[0].innerHTML=settings.image_markup.replace(/{path}/g,pp_images[set_position]);imgPreloader.onload=function(){pp_dimensions=_fitToViewport(imgPreloader.width,imgPreloader.height);_showContent();};imgPreloader.onerror=function(){alert('Image cannot be loaded. Make sure the path is correct and image exist.');$.prettyPhoto.close();};imgPreloader.src=pp_images[set_position];break;case'youtube':pp_dimensions=_fitToViewport(movie_width,movie_height);movie_id=getParam('v',pp_images[set_position]);if(movie_id==""){movie_id=pp_images[set_position].split('youtu.be/');movie_id=movie_id[1];if(movie_id.indexOf('?')>0)
+movie_id=movie_id.substr(0,movie_id.indexOf('?'));if(movie_id.indexOf('&')>0)
+movie_id=movie_id.substr(0,movie_id.indexOf('&'));}
+movie='http://www.youtube.com/embed/'+movie_id;(getParam('rel',pp_images[set_position]))?movie+="?rel="+getParam('rel',pp_images[set_position]):movie+="?rel=1";if(settings.autoplay)movie+="&autoplay=1";toInject=settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);break;case'vimeo':pp_dimensions=_fitToViewport(movie_width,movie_height);movie_id=pp_images[set_position];var regExp=/http:\/\/(www\.)?vimeo.com\/(\d+)/;var match=movie_id.match(regExp);movie='http://player.vimeo.com/video/'+match[2]+'?title=0&byline=0&portrait=0';if(settings.autoplay)movie+="&autoplay=1;";vimeo_width=pp_dimensions['width']+'/embed/?moog_width='+pp_dimensions['width'];toInject=settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);break;case'quicktime':pp_dimensions=_fitToViewport(movie_width,movie_height);pp_dimensions['height']+=15;pp_dimensions['contentHeight']+=15;pp_dimensions['containerHeight']+=15;toInject=settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);break;case'flash':pp_dimensions=_fitToViewport(movie_width,movie_height);flash_vars=pp_images[set_position];flash_vars=flash_vars.substring(pp_images[set_position].indexOf('flashvars')+10,pp_images[set_position].length);filename=pp_images[set_position];filename=filename.substring(0,filename.indexOf('?'));toInject=settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);break;case'iframe':pp_dimensions=_fitToViewport(movie_width,movie_height);frame_url=pp_images[set_position];frame_url=frame_url.substr(0,frame_url.indexOf('iframe')-1);toInject=settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);break;case'ajax':doresize=false;pp_dimensions=_fitToViewport(movie_width,movie_height);doresize=true;skipInjection=true;$.get(pp_images[set_position],function(responseHTML){toInject=settings.inline_markup.replace(/{content}/g,responseHTML);$pp_pic_holder.find('#pp_full_res')[0].innerHTML=toInject;_showContent();});break;case'custom':pp_dimensions=_fitToViewport(movie_width,movie_height);toInject=settings.custom_markup;break;case'inline':myClone=$(pp_images[set_position]).clone().append(' ').css({'width':settings.default_width}).wrapInner('').appendTo($('body')).show();doresize=false;pp_dimensions=_fitToViewport($(myClone).width(),$(myClone).height());doresize=true;$(myClone).remove();toInject=settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());break;};if(!imgPreloader&&!skipInjection){$pp_pic_holder.find('#pp_full_res')[0].innerHTML=toInject;_showContent();};});return false;};$.prettyPhoto.changePage=function(direction){currentGalleryPage=0;if(direction=='previous'){set_position--;if(set_position<0)set_position=$(pp_images).size()-1;}else if(direction=='next'){set_position++;if(set_position>$(pp_images).size()-1)set_position=0;}else{set_position=direction;};rel_index=set_position;if(!doresize)doresize=true;if(settings.allow_expand){$('.pp_contract').removeClass('pp_contract').addClass('pp_expand');}
+_hideContent(function(){$.prettyPhoto.open();});};$.prettyPhoto.changeGalleryPage=function(direction){if(direction=='next'){currentGalleryPage++;if(currentGalleryPage>totalPage)currentGalleryPage=0;}else if(direction=='previous'){currentGalleryPage--;if(currentGalleryPage<0)currentGalleryPage=totalPage;}else{currentGalleryPage=direction;};slide_speed=(direction=='next'||direction=='previous')?settings.animation_speed:0;slide_to=currentGalleryPage*(itemsPerPage*itemWidth);$pp_gallery.find('ul').animate({left:-slide_to},slide_speed);};$.prettyPhoto.startSlideshow=function(){if(typeof pp_slideshow=='undefined'){$pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){$.prettyPhoto.stopSlideshow();return false;});pp_slideshow=setInterval($.prettyPhoto.startSlideshow,settings.slideshow);}else{$.prettyPhoto.changePage('next');};}
+$.prettyPhoto.stopSlideshow=function(){$pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){$.prettyPhoto.startSlideshow();return false;});clearInterval(pp_slideshow);pp_slideshow=undefined;}
+$.prettyPhoto.close=function(){if($pp_overlay.is(":animated"))return;$.prettyPhoto.stopSlideshow();$pp_pic_holder.stop().find('object,embed').css('visibility','hidden');$('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){$(this).remove();});$pp_overlay.fadeOut(settings.animation_speed,function(){if($.browser.msie&&$.browser.version==6)$('select').css('visibility','visible');if(settings.hideflash)$('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible');$(this).remove();$(window).unbind('scroll.prettyphoto');clearHashtag();settings.callback();doresize=true;pp_open=false;delete settings;});};function _showContent(){$('.pp_loaderIcon').hide();projectedTop=scroll_pos['scrollTop']+((windowHeight/2)-(pp_dimensions['containerHeight']/2));if(projectedTop<0)projectedTop=0;$ppt.fadeTo(settings.animation_speed,1);$pp_pic_holder.find('.pp_content').animate({height:pp_dimensions['contentHeight'],width:pp_dimensions['contentWidth']},settings.animation_speed);$pp_pic_holder.animate({'top':projectedTop,'left':((windowWidth/2)-(pp_dimensions['containerWidth']/2)<0)?0:(windowWidth/2)-(pp_dimensions['containerWidth']/2),width:pp_dimensions['containerWidth']},settings.animation_speed,function(){$pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);$pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed);if(isSet&&_getFileType(pp_images[set_position])=="image"){$pp_pic_holder.find('.pp_hoverContainer').show();}else{$pp_pic_holder.find('.pp_hoverContainer').hide();}
+if(settings.allow_expand){if(pp_dimensions['resized']){$('a.pp_expand,a.pp_contract').show();}else{$('a.pp_expand').hide();}}
+if(settings.autoplay_slideshow&&!pp_slideshow&&!pp_open)$.prettyPhoto.startSlideshow();settings.changepicturecallback();pp_open=true;});_insert_gallery();pp_settings.ajaxcallback();};function _hideContent(callback){$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');$pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){$('.pp_loaderIcon').show();callback();});};function _checkPosition(setCount){(setCount>1)?$('.pp_nav').show():$('.pp_nav').hide();};function _fitToViewport(width,height){resized=false;_getDimensions(width,height);imageWidth=width,imageHeight=height;if(((pp_containerWidth>windowWidth)||(pp_containerHeight>windowHeight))&&doresize&&settings.allow_resize&&!percentBased){resized=true,fitting=false;while(!fitting){if((pp_containerWidth>windowWidth)){imageWidth=(windowWidth-200);imageHeight=(height/width)*imageWidth;}else if((pp_containerHeight>windowHeight)){imageHeight=(windowHeight-200);imageWidth=(width/height)*imageHeight;}else{fitting=true;};pp_containerHeight=imageHeight,pp_containerWidth=imageWidth;};_getDimensions(imageWidth,imageHeight);if((pp_containerWidth>windowWidth)||(pp_containerHeight>windowHeight)){_fitToViewport(pp_containerWidth,pp_containerHeight)};};return{width:Math.floor(imageWidth),height:Math.floor(imageHeight),containerHeight:Math.floor(pp_containerHeight),containerWidth:Math.floor(pp_containerWidth)+(settings.horizontal_padding*2),contentHeight:Math.floor(pp_contentHeight),contentWidth:Math.floor(pp_contentWidth),resized:resized};};function _getDimensions(width,height){width=parseFloat(width);height=parseFloat(height);$pp_details=$pp_pic_holder.find('.pp_details');$pp_details.width(width);detailsHeight=parseFloat($pp_details.css('marginTop'))+parseFloat($pp_details.css('marginBottom'));$pp_details=$pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({'position':'absolute','top':-10000});detailsHeight+=$pp_details.height();detailsHeight=(detailsHeight<=34)?36:detailsHeight;if($.browser.msie&&$.browser.version==7)detailsHeight+=8;$pp_details.remove();$pp_title=$pp_pic_holder.find('.ppt');$pp_title.width(width);titleHeight=parseFloat($pp_title.css('marginTop'))+parseFloat($pp_title.css('marginBottom'));$pp_title=$pp_title.clone().appendTo($('body')).css({'position':'absolute','top':-10000});titleHeight+=$pp_title.height();$pp_title.remove();pp_contentHeight=height+detailsHeight;pp_contentWidth=width;pp_containerHeight=pp_contentHeight+titleHeight+$pp_pic_holder.find('.pp_top').height()+$pp_pic_holder.find('.pp_bottom').height();pp_containerWidth=width;}
+function _getFileType(itemSrc){if(itemSrc.match(/youtube\.com\/watch/i)||itemSrc.match(/youtu\.be/i)){return'youtube';}else if(itemSrc.match(/vimeo\.com/i)){return'vimeo';}else if(itemSrc.match(/\b.mov\b/i)){return'quicktime';}else if(itemSrc.match(/\b.swf\b/i)){return'flash';}else if(itemSrc.match(/\biframe=true\b/i)){return'iframe';}else if(itemSrc.match(/\bajax=true\b/i)){return'ajax';}else if(itemSrc.match(/\bcustom=true\b/i)){return'custom';}else if(itemSrc.substr(0,1)=='#'){return'inline';}else{return'image';};};function _center_overlay(){if(doresize&&typeof $pp_pic_holder!='undefined'){scroll_pos=_get_scroll();contentHeight=$pp_pic_holder.height(),contentwidth=$pp_pic_holder.width();projectedTop=(windowHeight/2)+scroll_pos['scrollTop']-(contentHeight/2);if(projectedTop<0)projectedTop=0;if(contentHeight>windowHeight)
+return;$pp_pic_holder.css({'top':projectedTop,'left':(windowWidth/2)+scroll_pos['scrollLeft']-(contentwidth/2)});};};function _get_scroll(){if(self.pageYOffset){return{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};}else if(document.documentElement&&document.documentElement.scrollTop){return{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};}else if(document.body){return{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};};};function _resize_overlay(){windowHeight=$(window).height(),windowWidth=$(window).width();if(typeof $pp_overlay!="undefined")$pp_overlay.height($(document).height()).width(windowWidth);};function _insert_gallery(){if(isSet&&settings.overlay_gallery&&_getFileType(pp_images[set_position])=="image"&&(settings.ie6_fallback&&!($.browser.msie&&parseInt($.browser.version)==6))){itemWidth=52+5;navWidth=(settings.theme=="facebook"||settings.theme=="pp_default")?50:30;itemsPerPage=Math.floor((pp_dimensions['containerWidth']-100-navWidth)/itemWidth);itemsPerPage=(itemsPerPage ";};toInject=settings.gallery_markup.replace(/{gallery}/g,toInject);$pp_pic_holder.find('#pp_full_res').after(toInject);$pp_gallery=$('.pp_pic_holder .pp_gallery'),$pp_gallery_li=$pp_gallery.find('li');$pp_gallery.find('.pp_arrow_next').click(function(){$.prettyPhoto.changeGalleryPage('next');$.prettyPhoto.stopSlideshow();return false;});$pp_gallery.find('.pp_arrow_previous').click(function(){$.prettyPhoto.changeGalleryPage('previous');$.prettyPhoto.stopSlideshow();return false;});$pp_pic_holder.find('.pp_content').hover(function(){$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();},function(){$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();});itemWidth=52+5;$pp_gallery_li.each(function(i){$(this).find('a').click(function(){$.prettyPhoto.changePage(i);$.prettyPhoto.stopSlideshow();return false;});});};if(settings.slideshow){$pp_pic_holder.find('.pp_nav').prepend('Play ')
+$pp_pic_holder.find('.pp_nav .pp_play').click(function(){$.prettyPhoto.startSlideshow();return false;});}
+$pp_pic_holder.attr('class','pp_pic_holder '+settings.theme);$pp_overlay.css({'opacity':0,'height':$(document).height(),'width':$(window).width()}).bind('click',function(){if(!settings.modal)$.prettyPhoto.close();});$('a.pp_close').bind('click',function(){$.prettyPhoto.close();return false;});if(settings.allow_expand){$('a.pp_expand').bind('click',function(e){if($(this).hasClass('pp_expand')){$(this).removeClass('pp_expand').addClass('pp_contract');doresize=false;}else{$(this).removeClass('pp_contract').addClass('pp_expand');doresize=true;};_hideContent(function(){$.prettyPhoto.open();});return false;});}
+$pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){$.prettyPhoto.changePage('previous');$.prettyPhoto.stopSlideshow();return false;});$pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){$.prettyPhoto.changePage('next');$.prettyPhoto.stopSlideshow();return false;});_center_overlay();};if(!pp_alreadyInitialized&&getHashtag()){pp_alreadyInitialized=true;hashIndex=getHashtag();hashRel=hashIndex;hashIndex=hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);hashRel=hashRel.substring(0,hashRel.indexOf('/'));setTimeout(function(){$("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click');},50);}
+return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize);};function getHashtag(){url=location.href;hashtag=(url.indexOf('#prettyPhoto')!==-1)?decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)):false;return hashtag;};function setHashtag(){if(typeof theRel=='undefined')return;location.hash=theRel+'/'+rel_index+'/';};function clearHashtag(){if(location.href.indexOf('#prettyPhoto')!==-1)location.hash="prettyPhoto";}
+function getParam(name,url){name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");var regexS="[\\?&]"+name+"=([^]*)";var regex=new RegExp(regexS);var results=regex.exec(url);return(results==null)?"":results[1];}})(jQuery);var pp_alreadyInitialized=false;
\ No newline at end of file
diff --git a/js/modernizr.js b/js/modernizr.js
new file mode 100644
index 0000000..2678bd7
--- /dev/null
+++ b/js/modernizr.js
@@ -0,0 +1,946 @@
+/*!
+ * Modernizr v2.6.3pre
+ * modernizr.com
+ *
+ * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
+ * MIT License
+ */
+
+/*
+ * Modernizr tests which native CSS3 and HTML5 features are available in the
+ * current UA and makes the results available to you in two ways: as properties on
+ * a global `Modernizr` object, and as classes on the `` element. This
+ * information allows you to progressively enhance your pages with a granular level
+ * of control over the experience.
+ *
+ * Modernizr has an optional (*not included*) conditional resource loader called
+ * `Modernizr.load()`, based on [Yepnope.js](http://yepnopejs.com). You can get a
+ * build that includes `Modernizr.load()`, as well as choosing which feature tests
+ * to include on the [Download page](http://www.modernizr.com/download/).
+ *
+ *
+ * Authors Faruk Ates, Paul Irish, Alex Sexton
+ * Contributors Ryan Seddon, Ben Alman
+ */
+
+window.Modernizr = (function( window, document, undefined ) {
+
+ var version = '2.6.3pre',
+
+ Modernizr = {},
+
+ /*>>cssclasses*/
+ // option for enabling the HTML classes to be added
+ enableClasses = true,
+ /*>>cssclasses*/
+
+ docElement = document.documentElement,
+
+ /**
+ * Create our "modernizr" element that we do most feature tests on.
+ */
+ mod = 'modernizr',
+ modElem = document.createElement(mod),
+ mStyle = modElem.style,
+
+ /**
+ * Create the input element for various Web Forms feature tests.
+ */
+ inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
+
+ /*>>smile*/
+ smile = ':)',
+ /*>>smile*/
+
+ toString = {}.toString,
+
+ // TODO :: make the prefixes more granular
+ /*>>prefixes*/
+ // List of property values to set for css tests. See ticket #21
+ prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
+ /*>>prefixes*/
+
+ /*>>domprefixes*/
+ // Following spec is to expose vendor-specific style properties as:
+ // elem.style.WebkitBorderRadius
+ // and the following would be incorrect:
+ // elem.style.webkitBorderRadius
+
+ // Webkit ghosts their properties in lowercase but Opera & Moz do not.
+ // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
+ // erik.eae.net/archives/2008/03/10/21.48.10/
+
+ // More here: github.com/Modernizr/Modernizr/issues/issue/21
+ omPrefixes = 'Webkit Moz O ms',
+
+ cssomPrefixes = omPrefixes.split(' '),
+
+ domPrefixes = omPrefixes.toLowerCase().split(' '),
+ /*>>domprefixes*/
+
+ tests = {},
+ inputs = {},
+ attrs = {},
+
+ classes = [],
+
+ slice = classes.slice,
+
+ featureName, // used in testing loop
+
+
+ /*>>teststyles*/
+ // Inject element with style element and some CSS rules
+ injectElementWithStyles = function( rule, callback, nodes, testnames ) {
+
+ var style, ret, node, docOverflow,
+ div = document.createElement('div'),
+ // After page load injecting a fake body doesn't work so check if body exists
+ body = document.body,
+ // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
+ fakeBody = body || document.createElement('body');
+
+ if ( parseInt(nodes, 10) ) {
+ // In order not to give false positives we create a node for each test
+ // This also allows the method to scale for unspecified uses
+ while ( nodes-- ) {
+ node = document.createElement('div');
+ node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
+ div.appendChild(node);
+ }
+ }
+
+ // '].join('');
+ div.id = mod;
+ // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
+ // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
+ (body ? div : fakeBody).innerHTML += style;
+ fakeBody.appendChild(div);
+ if ( !body ) {
+ //avoid crashing IE8, if background image is used
+ fakeBody.style.background = '';
+ //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
+ fakeBody.style.overflow = 'hidden';
+ docOverflow = docElement.style.overflow;
+ docElement.style.overflow = 'hidden';
+ docElement.appendChild(fakeBody);
+ }
+
+ ret = callback(div, rule);
+ // If this is done after page load we don't want to remove the body so check if body exists
+ if ( !body ) {
+ fakeBody.parentNode.removeChild(fakeBody);
+ docElement.style.overflow = docOverflow;
+ } else {
+ div.parentNode.removeChild(div);
+ }
+
+ return !!ret;
+
+ },
+ /*>>teststyles*/
+
+ /*>>mq*/
+ // adapted from matchMedia polyfill
+ // by Scott Jehl and Paul Irish
+ // gist.github.com/786768
+ testMediaQuery = function( mq ) {
+
+ var matchMedia = window.matchMedia || window.msMatchMedia;
+ if ( matchMedia ) {
+ return matchMedia(mq).matches;
+ }
+
+ var bool;
+
+ injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
+ bool = (window.getComputedStyle ?
+ getComputedStyle(node, null) :
+ node.currentStyle)['position'] == 'absolute';
+ });
+
+ return bool;
+
+ },
+ /*>>mq*/
+
+
+ /*>>hasevent*/
+ //
+ // isEventSupported determines if a given element supports the given event
+ // kangax.github.com/iseventsupported/
+ //
+ // The following results are known incorrects:
+ // Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
+ // Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
+ // ...
+ isEventSupported = (function() {
+
+ var TAGNAMES = {
+ 'select': 'input', 'change': 'input',
+ 'submit': 'form', 'reset': 'form',
+ 'error': 'img', 'load': 'img', 'abort': 'img'
+ };
+
+ function isEventSupported( eventName, element ) {
+
+ element = element || document.createElement(TAGNAMES[eventName] || 'div');
+ eventName = 'on' + eventName;
+
+ // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
+ var isSupported = eventName in element;
+
+ if ( !isSupported ) {
+ // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
+ if ( !element.setAttribute ) {
+ element = document.createElement('div');
+ }
+ if ( element.setAttribute && element.removeAttribute ) {
+ element.setAttribute(eventName, '');
+ isSupported = is(element[eventName], 'function');
+
+ // If property was created, "remove it" (by setting value to `undefined`)
+ if ( !is(element[eventName], 'undefined') ) {
+ element[eventName] = undefined;
+ }
+ element.removeAttribute(eventName);
+ }
+ }
+
+ element = null;
+ return isSupported;
+ }
+ return isEventSupported;
+ })(),
+ /*>>hasevent*/
+
+ // TODO :: Add flag for hasownprop ? didn't last time
+
+ // hasOwnProperty shim by kangax needed for Safari 2.0 support
+ _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
+
+ if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
+ hasOwnProp = function (object, property) {
+ return _hasOwnProperty.call(object, property);
+ };
+ }
+ else {
+ hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
+ return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
+ };
+ }
+
+ // Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
+ // es5.github.com/#x15.3.4.5
+
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function bind(that) {
+
+ var target = this;
+
+ if (typeof target != "function") {
+ throw new TypeError();
+ }
+
+ var args = slice.call(arguments, 1),
+ bound = function () {
+
+ if (this instanceof bound) {
+
+ var F = function(){};
+ F.prototype = target.prototype;
+ var self = new F();
+
+ var result = target.apply(
+ self,
+ args.concat(slice.call(arguments))
+ );
+ if (Object(result) === result) {
+ return result;
+ }
+ return self;
+
+ } else {
+
+ return target.apply(
+ that,
+ args.concat(slice.call(arguments))
+ );
+
+ }
+
+ };
+
+ return bound;
+ };
+ }
+
+ /**
+ * setCss applies given styles to the Modernizr DOM node.
+ */
+ function setCss( str ) {
+ mStyle.cssText = str;
+ }
+
+ /**
+ * setCssAll extrapolates all vendor-specific css strings.
+ */
+ function setCssAll( str1, str2 ) {
+ return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
+ }
+
+ /**
+ * is returns a boolean for if typeof obj is exactly type.
+ */
+ function is( obj, type ) {
+ return typeof obj === type;
+ }
+
+ /**
+ * contains returns a boolean for if substr is found within str.
+ */
+ function contains( str, substr ) {
+ return !!~('' + str).indexOf(substr);
+ }
+
+ /*>>testprop*/
+
+ // testProps is a generic CSS / DOM property test.
+
+ // In testing support for a given CSS property, it's legit to test:
+ // `elem.style[styleName] !== undefined`
+ // If the property is supported it will return an empty string,
+ // if unsupported it will return undefined.
+
+ // We'll take advantage of this quick test and skip setting a style
+ // on our modernizr element, but instead just testing undefined vs
+ // empty string.
+
+ // Because the testing of the CSS property names (with "-", as
+ // opposed to the camelCase DOM properties) is non-portable and
+ // non-standard but works in WebKit and IE (but not Gecko or Opera),
+ // we explicitly reject properties with dashes so that authors
+ // developing in WebKit or IE first don't end up with
+ // browser-specific content by accident.
+
+ function testProps( props, prefixed ) {
+ for ( var i in props ) {
+ var prop = props[i];
+ if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
+ return prefixed == 'pfx' ? prop : true;
+ }
+ }
+ return false;
+ }
+ /*>>testprop*/
+
+ // TODO :: add testDOMProps
+ /**
+ * testDOMProps is a generic DOM property test; if a browser supports
+ * a certain property, it won't return undefined for it.
+ */
+ function testDOMProps( props, obj, elem ) {
+ for ( var i in props ) {
+ var item = obj[props[i]];
+ if ( item !== undefined) {
+
+ // return the property name as a string
+ if (elem === false) return props[i];
+
+ // let's bind a function (and it has a bind method -- certain native objects that report that they are a
+ // function don't [such as webkitAudioContext])
+ if (is(item, 'function') && 'bind' in item){
+ // default to autobind unless override
+ return item.bind(elem || obj);
+ }
+
+ // return the unbound function or obj or value
+ return item;
+ }
+ }
+ return false;
+ }
+
+ /*>>testallprops*/
+ /**
+ * testPropsAll tests a list of DOM properties we want to check against.
+ * We specify literally ALL possible (known and/or likely) properties on
+ * the element including the non-vendor prefixed one, for forward-
+ * compatibility.
+ */
+ function testPropsAll( prop, prefixed, elem ) {
+
+ var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
+ props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
+
+ // did they call .prefixed('boxSizing') or are we just testing a prop?
+ if(is(prefixed, "string") || is(prefixed, "undefined")) {
+ return testProps(props, prefixed);
+
+ // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
+ } else {
+ props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
+ return testDOMProps(props, prefixed, elem);
+ }
+ }
+ /*>>testallprops*/
+
+
+ /**
+ * Tests
+ * -----
+ */
+
+ /*>>webforms*/
+ // input features and input types go directly onto the ret object, bypassing the tests loop.
+ // Hold this guy to execute in a moment.
+ function webforms() {
+ /*>>input*/
+ // Run through HTML5's new input attributes to see if the UA understands any.
+ // We're using f which is the element created early on
+ // Mike Taylr has created a comprehensive resource for testing these attributes
+ // when applied to all input types:
+ // miketaylr.com/code/input-type-attr.html
+ // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+
+ // Only input placeholder is tested while textarea's placeholder is not.
+ // Currently Safari 4 and Opera 11 have support only for the input placeholder
+ // Both tests are available in feature-detects/forms-placeholder.js
+ Modernizr['input'] = (function( props ) {
+ for ( var i = 0, len = props.length; i < len; i++ ) {
+ attrs[ props[i] ] = !!(props[i] in inputElem);
+ }
+ if (attrs.list){
+ // safari false positive's on datalist: webk.it/74252
+ // see also github.com/Modernizr/Modernizr/issues/146
+ attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
+ }
+ return attrs;
+ })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
+ /*>>input*/
+
+ /*>>inputtypes*/
+ // Run through HTML5's new input types to see if the UA understands any.
+ // This is put behind the tests runloop because it doesn't return a
+ // true/false like all the other tests; instead, it returns an object
+ // containing each input type with its corresponding true/false value
+
+ // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
+ Modernizr['inputtypes'] = (function(props) {
+
+ for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
+
+ inputElem.setAttribute('type', inputElemType = props[i]);
+ bool = inputElem.type !== 'text';
+
+ // We first check to see if the type we give it sticks..
+ // If the type does, we feed it a textual value, which shouldn't be valid.
+ // If the value doesn't stick, we know there's input sanitization which infers a custom UI
+ if ( bool ) {
+
+ inputElem.value = smile;
+ inputElem.style.cssText = 'position:absolute;visibility:hidden;';
+
+ if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
+
+ docElement.appendChild(inputElem);
+ defaultView = document.defaultView;
+
+ // Safari 2-4 allows the smiley as a value, despite making a slider
+ bool = defaultView.getComputedStyle &&
+ defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
+ // Mobile android web browser has false positive, so must
+ // check the height to see if the widget is actually there.
+ (inputElem.offsetHeight !== 0);
+
+ docElement.removeChild(inputElem);
+
+ } else if ( /^(search|tel)$/.test(inputElemType) ){
+ // Spec doesn't define any special parsing or detectable UI
+ // behaviors so we pass these through as true
+
+ // Interestingly, opera fails the earlier test, so it doesn't
+ // even make it here.
+
+ } else if ( /^(url|email)$/.test(inputElemType) ) {
+ // Real url and email support comes with prebaked validation.
+ bool = inputElem.checkValidity && inputElem.checkValidity() === false;
+
+ } else {
+ // If the upgraded input compontent rejects the :) text, we got a winner
+ bool = inputElem.value != smile;
+ }
+ }
+
+ inputs[ props[i] ] = !!bool;
+ }
+ return inputs;
+ })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
+ /*>>inputtypes*/
+ }
+ /*>>webforms*/
+
+
+ // End of test definitions
+ // -----------------------
+
+
+
+ // Run through all tests and detect their support in the current UA.
+ // todo: hypothetically we could be doing an array of tests and use a basic loop here.
+ for ( var feature in tests ) {
+ if ( hasOwnProp(tests, feature) ) {
+ // run the test, throw the return value into the Modernizr,
+ // then based on that boolean, define an appropriate className
+ // and push it into an array of classes we'll join later.
+ featureName = feature.toLowerCase();
+ Modernizr[featureName] = tests[feature]();
+
+ classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
+ }
+ }
+
+ /*>>webforms*/
+ // input tests need to run.
+ Modernizr.input || webforms();
+ /*>>webforms*/
+
+
+ /**
+ * addTest allows the user to define their own feature tests
+ * the result will be added onto the Modernizr object,
+ * as well as an appropriate className set on the html element
+ *
+ * @param feature - String naming the feature
+ * @param test - Function returning true if feature is supported, false if not
+ */
+ Modernizr.addTest = function ( feature, test ) {
+ if ( typeof feature == 'object' ) {
+ for ( var key in feature ) {
+ if ( hasOwnProp( feature, key ) ) {
+ Modernizr.addTest( key, feature[ key ] );
+ }
+ }
+ } else {
+
+ feature = feature.toLowerCase();
+
+ if ( Modernizr[feature] !== undefined ) {
+ // we're going to quit if you're trying to overwrite an existing test
+ // if we were to allow it, we'd do this:
+ // var re = new RegExp("\\b(no-)?" + feature + "\\b");
+ // docElement.className = docElement.className.replace( re, '' );
+ // but, no rly, stuff 'em.
+ return Modernizr;
+ }
+
+ test = typeof test == 'function' ? test() : test;
+
+ if (typeof enableClasses !== "undefined" && enableClasses) {
+ docElement.className += ' ' + (test ? '' : 'no-') + feature;
+ }
+ Modernizr[feature] = test;
+
+ }
+
+ return Modernizr; // allow chaining.
+ };
+
+
+ // Reset modElem.cssText to nothing to reduce memory footprint.
+ setCss('');
+ modElem = inputElem = null;
+
+ /*>>shiv*/
+ /*! HTML5 Shiv v3.6.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */
+ ;(function(window, document) {
+ /*jshint evil:true */
+ /** Preset options */
+ var options = window.html5 || {};
+
+ /** Used to skip problem elements */
+ var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
+
+ /** Not all elements can be cloned in IE **/
+ var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
+
+ /** Detect whether the browser supports default html5 styles */
+ var supportsHtml5Styles;
+
+ /** Name of the expando, to work with multiple documents or to re-shiv one document */
+ var expando = '_html5shiv';
+
+ /** The id for the the documents expando */
+ var expanID = 0;
+
+ /** Cached data for each document */
+ var expandoData = {};
+
+ /** Detect whether the browser supports unknown elements */
+ var supportsUnknownElements;
+
+ (function() {
+ try {
+ var a = document.createElement('a');
+ a.innerHTML = ' ';
+ //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
+ supportsHtml5Styles = ('hidden' in a);
+
+ supportsUnknownElements = a.childNodes.length == 1 || (function() {
+ // assign a false positive if unable to shiv
+ (document.createElement)('a');
+ var frag = document.createDocumentFragment();
+ return (
+ typeof frag.cloneNode == 'undefined' ||
+ typeof frag.createDocumentFragment == 'undefined' ||
+ typeof frag.createElement == 'undefined'
+ );
+ }());
+ } catch(e) {
+ supportsHtml5Styles = true;
+ supportsUnknownElements = true;
+ }
+
+ }());
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Creates a style sheet with the given CSS text and adds it to the document.
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @param {String} cssText The CSS text.
+ * @returns {StyleSheet} The style element.
+ */
+ function addStyleSheet(ownerDocument, cssText) {
+ var p = ownerDocument.createElement('p'),
+ parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
+
+ p.innerHTML = 'x';
+ return parent.insertBefore(p.lastChild, parent.firstChild);
+ }
+
+ /**
+ * Returns the value of `html5.elements` as an array.
+ * @private
+ * @returns {Array} An array of shived element node names.
+ */
+ function getElements() {
+ var elements = html5.elements;
+ return typeof elements == 'string' ? elements.split(' ') : elements;
+ }
+
+ /**
+ * Returns the data associated to the given document
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @returns {Object} An object of data.
+ */
+ function getExpandoData(ownerDocument) {
+ var data = expandoData[ownerDocument[expando]];
+ if (!data) {
+ data = {};
+ expanID++;
+ ownerDocument[expando] = expanID;
+ expandoData[expanID] = data;
+ }
+ return data;
+ }
+
+ /**
+ * returns a shived element for the given nodeName and document
+ * @memberOf html5
+ * @param {String} nodeName name of the element
+ * @param {Document} ownerDocument The context document.
+ * @returns {Object} The shived element.
+ */
+ function createElement(nodeName, ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createElement(nodeName);
+ }
+ if (!data) {
+ data = getExpandoData(ownerDocument);
+ }
+ var node;
+
+ if (data.cache[nodeName]) {
+ node = data.cache[nodeName].cloneNode();
+ } else if (saveClones.test(nodeName)) {
+ node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
+ } else {
+ node = data.createElem(nodeName);
+ }
+
+ // Avoid adding some elements to fragments in IE < 9 because
+ // * Attributes like `name` or `type` cannot be set/changed once an element
+ // is inserted into a document/fragment
+ // * Link elements with `src` attributes that are inaccessible, as with
+ // a 403 response, will cause the tab/window to crash
+ // * Script elements appended to fragments will execute when their `src`
+ // or `text` property is set
+ return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
+ }
+
+ /**
+ * returns a shived DocumentFragment for the given document
+ * @memberOf html5
+ * @param {Document} ownerDocument The context document.
+ * @returns {Object} The shived DocumentFragment.
+ */
+ function createDocumentFragment(ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createDocumentFragment();
+ }
+ data = data || getExpandoData(ownerDocument);
+ var clone = data.frag.cloneNode(),
+ i = 0,
+ elems = getElements(),
+ l = elems.length;
+ for(;i>shiv*/
+
+ // Assign private properties to the return object with prefix
+ Modernizr._version = version;
+
+ // expose these for the plugin API. Look in the source for how to join() them against your input
+ /*>>prefixes*/
+ Modernizr._prefixes = prefixes;
+ /*>>prefixes*/
+ /*>>domprefixes*/
+ Modernizr._domPrefixes = domPrefixes;
+ Modernizr._cssomPrefixes = cssomPrefixes;
+ /*>>domprefixes*/
+
+ /*>>mq*/
+ // Modernizr.mq tests a given media query, live against the current state of the window
+ // A few important notes:
+ // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
+ // * A max-width or orientation query will be evaluated against the current state, which may change later.
+ // * You must specify values. Eg. If you are testing support for the min-width media query use:
+ // Modernizr.mq('(min-width:0)')
+ // usage:
+ // Modernizr.mq('only screen and (max-width:768)')
+ Modernizr.mq = testMediaQuery;
+ /*>>mq*/
+
+ /*>>hasevent*/
+ // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
+ // Modernizr.hasEvent('gesturestart', elem)
+ Modernizr.hasEvent = isEventSupported;
+ /*>>hasevent*/
+
+ /*>>testprop*/
+ // Modernizr.testProp() investigates whether a given style property is recognized
+ // Note that the property names must be provided in the camelCase variant.
+ // Modernizr.testProp('pointerEvents')
+ Modernizr.testProp = function(prop){
+ return testProps([prop]);
+ };
+ /*>>testprop*/
+
+ /*>>testallprops*/
+ // Modernizr.testAllProps() investigates whether a given style property,
+ // or any of its vendor-prefixed variants, is recognized
+ // Note that the property names must be provided in the camelCase variant.
+ // Modernizr.testAllProps('boxSizing')
+ Modernizr.testAllProps = testPropsAll;
+ /*>>testallprops*/
+
+
+ /*>>teststyles*/
+ // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
+ // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
+ Modernizr.testStyles = injectElementWithStyles;
+ /*>>teststyles*/
+
+
+ /*>>prefixed*/
+ // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
+ // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
+
+ // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
+ // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
+ //
+ // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
+
+ // If you're trying to ascertain which transition end event to bind to, you might do something like...
+ //
+ // var transEndEventNames = {
+ // 'WebkitTransition' : 'webkitTransitionEnd',
+ // 'MozTransition' : 'transitionend',
+ // 'OTransition' : 'oTransitionEnd',
+ // 'msTransition' : 'MSTransitionEnd',
+ // 'transition' : 'transitionend'
+ // },
+ // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
+
+ Modernizr.prefixed = function(prop, obj, elem){
+ if(!obj) {
+ return testPropsAll(prop, 'pfx');
+ } else {
+ // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
+ return testPropsAll(prop, obj, elem);
+ }
+ };
+ /*>>prefixed*/
+
+
+ /*>>cssclasses*/
+ // Remove "no-js" class from element, if it exists:
+ docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
+
+ // Add the new classes to the element.
+ (enableClasses ? ' js ' + classes.join(' ') : '');
+ /*>>cssclasses*/
+
+ return Modernizr;
+
+})(this, this.document);
diff --git a/js/modernizr.min.js b/js/modernizr.min.js
new file mode 100644
index 0000000..bcdd3f0
--- /dev/null
+++ b/js/modernizr.min.js
@@ -0,0 +1 @@
+window.Modernizr=function(e,t,n){function L(e){f.cssText=e}function A(e,t){return L(p.join(e+";")+(t||""))}function O(e,t){return typeof e===t}function M(e,t){return!!~(""+e).indexOf(t)}function _(e,t){for(var r in e){var i=e[r];if(!M(i,"-")&&f[i]!==n){return t=="pfx"?i:true}}return false}function D(e,t,r){for(var i in e){var s=t[e[i]];if(s!==n){if(r===false)return e[i];if(O(s,"function")&&"bind"in s){return s.bind(r||t)}return s}}return false}function P(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),i=(e+" "+v.join(r+" ")+r).split(" ");if(O(t,"string")||O(t,"undefined")){return _(i,t)}else{i=(e+" "+m.join(r+" ")+r).split(" ");return D(i,t,n)}}function H(){i["input"]=function(n){for(var r=0,i=n.length;r',e,""].join("");c.id=u;(h?c:p).innerHTML+=s;p.appendChild(c);if(!h){p.style.background="";p.style.overflow="hidden";l=o.style.overflow;o.style.overflow="hidden";o.appendChild(p)}a=n(c,e);if(!h){p.parentNode.removeChild(p);o.style.overflow=l}else{c.parentNode.removeChild(c)}return!!a},T=function(t){var n=e.matchMedia||e.msMatchMedia;if(n){return n(t).matches}var r;x("@media "+t+" { #"+u+" { position: absolute; } }",function(t){r=(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle)["position"]=="absolute"});return r},N=function(){function r(r,i){i=i||t.createElement(e[r]||"div");r="on"+r;var s=r in i;if(!s){if(!i.setAttribute){i=t.createElement("div")}if(i.setAttribute&&i.removeAttribute){i.setAttribute(r,"");s=O(i[r],"function");if(!O(i[r],"undefined")){i[r]=n}i.removeAttribute(r)}}i=null;return s}var e={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return r}(),C={}.hasOwnProperty,k;if(!O(C,"undefined")&&!O(C.call,"undefined")){k=function(e,t){return C.call(e,t)}}else{k=function(e,t){return t in e&&O(e.constructor.prototype[t],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function(t){var n=this;if(typeof n!="function"){throw new TypeError}var r=E.call(arguments,1),i=function(){if(this instanceof i){var e=function(){};e.prototype=n.prototype;var s=new e;var o=n.apply(s,r.concat(E.call(arguments)));if(Object(o)===o){return o}return s}else{return n.apply(t,r.concat(E.call(arguments)))}};return i}}for(var B in g){if(k(g,B)){S=B.toLowerCase();i[S]=g[B]();w.push((i[S]?"":"no-")+S)}}i.input||H();i.addTest=function(e,t){if(typeof e=="object"){for(var r in e){if(k(e,r)){i.addTest(r,e[r])}}}else{e=e.toLowerCase();if(i[e]!==n){return i}t=typeof t=="function"?t():t;if(typeof s!=="undefined"&&s){o.className+=" "+(t?"":"no-")+e}i[e]=t}return i};L("");a=l=null;(function(e,t){function l(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;n.innerHTML="x";return r.insertBefore(n.lastChild,r.firstChild)}function c(){var e=g.elements;return typeof e=="string"?e.split(" "):e}function h(e){var t=a[e[o]];if(!t){t={};u++;e[o]=u;a[u]=t}return t}function p(e,n,s){if(!n){n=t}if(f){return n.createElement(e)}if(!s){s=h(n)}var o;if(s.cache[e]){o=s.cache[e].cloneNode()}else if(i.test(e)){o=(s.cache[e]=s.createElem(e)).cloneNode()}else{o=s.createElem(e)}return o.canHaveChildren&&!r.test(e)?s.frag.appendChild(o):o}function d(e,n){if(!e){e=t}if(f){return e.createDocumentFragment()}n=n||h(e);var r=n.frag.cloneNode(),i=0,s=c(),o=s.length;for(;i";s="hidden"in e;f=e.childNodes.length==1||function(){t.createElement("a");var e=t.createDocumentFragment();return typeof e.cloneNode=="undefined"||typeof e.createDocumentFragment=="undefined"||typeof e.createElement=="undefined"}()}catch(n){s=true;f=true}})();var g={elements:n.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:n.shivCSS!==false,supportsUnknownElements:f,shivMethods:n.shivMethods!==false,type:"default",shivDocument:m,createElement:p,createDocumentFragment:d};e.html5=g;m(t)})(this,t);i._version=r;i._prefixes=p;i._domPrefixes=m;i._cssomPrefixes=v;i.mq=T;i.hasEvent=N;i.testProp=function(e){return _([e])};i.testAllProps=P;i.testStyles=x;i.prefixed=function(e,t,n){if(!t){return P(e,"pfx")}else{return P(e,t,n)}};o.className=o.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(s?" js "+w.join(" "):"");return i}(this,this.document)
\ No newline at end of file
diff --git a/languages/index.php b/languages/index.php
new file mode 100644
index 0000000..c051246
--- /dev/null
+++ b/languages/index.php
@@ -0,0 +1,3 @@
+ __( 'Columns', CHILD_DOMAIN ), ),
+ array(
+ 'title' => __( 'First Half', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-half first',
+ ),
+ array(
+ 'title' => __( 'Half', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-half',
+ ),
+ array(
+ 'title' => __( 'First Third', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-third first',
+ ),
+ array(
+ 'title' => __( 'Third', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-third',
+ ),
+ array(
+ 'title' => __( 'First Quarter', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-fourth first',
+ ),
+ array(
+ 'title' => __( 'Quarter', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-fourth',
+ ),
+ array(
+ 'title' => __( 'First Fifth', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-fifth first',
+ ),
+ array(
+ 'title' => __( 'Fifth', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-fifth',
+ ),
+ array(
+ 'title' => __( 'First Sixth', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-sixth first',
+ ),
+ array(
+ 'title' => __( 'Sixth', CHILD_DOMAIN ),
+ 'block' => 'div',
+ 'classes' => 'one-sixth',
+ ),
+ );
+
+ // Check if there are some styles already
+ if ( isset( $settings['style_formats'] ) ) {
+ // Decode any existing style formats
+ $existing_style_formats = json_decode( $settings['style_formats'] );
+
+ // Merge our new formats with any existing formats and re-encode
+ $settings['style_formats'] = json_encode( array_merge( (array) $existing_style_formats, $style_formats ) );
+ } else {
+ $settings['style_formats'] = json_encode( $style_formats );
+ }
+
+ return $settings;
+
+}
+
+add_filter( 'admin_footer_text', 'gs_admin_footer' );
+/**
+ * Modify Admin Footer Text and Logo
+ *
+ */
+function gs_admin_footer() {
+ echo '';
+}
+
diff --git a/lib/admin/gs-inpost-functions.php b/lib/admin/gs-inpost-functions.php
new file mode 100644
index 0000000..d183878
--- /dev/null
+++ b/lib/admin/gs-inpost-functions.php
@@ -0,0 +1,102 @@
+ true ) ) as $type ) {
+ if ( defined( 'GENESIS_SEO_DISABLED' ) && GENESIS_SEO_DISABLED )
+ add_meta_box( 'gs_inpost_scripts_box', __( 'Scripts Settings', CHILD_DOMAIN ), 'gs_inpost_scripts_box', $type, 'normal', 'high' );
+ }
+
+}
+
+/**
+ * Callback for in-post scripts meta box.
+ *
+ * Echoes out HTML.
+ *
+ * @category Genesis
+ * @package Admin
+ * @subpackage Inpost-Metaboxes
+ *
+ */
+function gs_inpost_scripts_box() {
+ wp_nonce_field( 'gs_inpost_scripts_save', 'gs_inpost_scripts_nonce' );
+ ?>
+
+ [?]
+
+
+
+
+
+
+
+ '',
+ '_genesis_scripts' => '',
+ '_genesis_footer_scripts' => '',
+ ) );
+
+ /** No sanitization necessary for scripts */
+
+ /** Save custom field data */
+ genesis_save_custom_fields( $data, 'gs_inpost_scripts_save', 'gs_inpost_scripts_nonce', $post, $post_id );
+
+}
\ No newline at end of file
diff --git a/lib/admin/gs-settings.php b/lib/admin/gs-settings.php
new file mode 100644
index 0000000..a1b9233
--- /dev/null
+++ b/lib/admin/gs-settings.php
@@ -0,0 +1,245 @@
+ Sandbox Settings.
+ *
+ * @category Genesis_Sandbox
+ * @package Admin
+ * @subpackage Settings
+ * @author Travis Smith, for Surefire Themes
+ * @license http://www.opensource.org/licenses/gpl-license.php GPL v2.0 (or later)
+ * @link http://wpsmith.net/
+ * @since 1.1.0
+ */
+
+/** Exit if accessed directly */
+if ( ! defined( 'ABSPATH' ) ) exit( 'Cheatin’ uh?' );
+
+/**
+ * Registers a new admin page, providing content and corresponding menu item
+ * for the Child Theme Settings page.
+ *
+ * @category Genesis_Sandbox
+ * @since 1.0.0
+ */
+class Genesis_Sandbox_Settings extends Genesis_Admin_Boxes {
+
+ /**
+ * Create an admin menu item and settings page.
+ *
+ * @since 1.1.0
+ */
+ function __construct() {
+
+ // Specify a unique page ID.
+ $page_id = CHILD_SETTINGS_FIELD;
+
+ // Set it as a child to genesis, and define the menu and page titles
+ $menu_ops = array(
+ 'submenu' => array(
+ 'parent_slug' => 'genesis',
+ 'page_title' => __( 'Genesis Sandbox Settings', CHILD_DOMAIN ),
+ 'menu_title' => __( 'Genesis Sandbox Settings', CHILD_DOMAIN ),
+ 'capability' => 'manage_options',
+ )
+ );
+
+ // Set up page options. These are optional, so only uncomment if you want to change the defaults
+ $page_ops = array( 'screen_icon' => 'options-general', );
+
+ // Give it a unique settings field.
+ // You'll access them from genesis_get_option( 'option_name', CHILD_SETTINGS_FIELD );
+ $settings_field = CHILD_SETTINGS_FIELD;
+
+ // Set the default values
+ $default_settings = array(
+ 'footer_left' => 'Copyright © ' . date( 'Y' ) . ' All Rights Reserved',
+ 'footer_right' => 'Site by WP Smith ',
+ );
+
+ // Create the Admin Page
+ $this->create( $page_id, $menu_ops, $page_ops, $settings_field, $default_settings );
+
+ // Initialize the Sanitization Filter
+ add_action( 'genesis_settings_sanitizer_init', array( $this, 'sanitization_filters' ) );
+
+ // Add admin script
+ //add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
+ }
+
+ /**
+ * Set up Sanitization Filters
+ *
+ * See /lib/classes/sanitization.php for all available filters.
+ *
+ * @since 1.1.0
+ */
+ function sanitization_filters() {
+
+ genesis_add_option_filter(
+ 'no_html',
+ $this->settings_field,
+ array() // Enter options here as an array
+ );
+
+ genesis_add_option_filter(
+ 'safe_html',
+ $this->settings_field,
+ array( // Enter options here as an array
+ 'footer_left',
+ 'footer_right',
+ )
+ );
+
+ genesis_add_option_filter(
+ 'one_zero',
+ $this->settings_field,
+ array( // Enter options here as an array
+ 'move_nav',
+ 'move_subnav',
+ 'footer_left_nav',
+ 'footer_right_nav',
+ )
+ );
+
+ genesis_add_option_filter(
+ 'requires_unfiltered_html',
+ $this->settings_field,
+ array(
+ ) // Enter options here as an array
+ );
+
+ }
+
+ /**
+ * Add admin script
+ *
+ * @since 1.1.0
+ */
+ function gs_scripts() {
+ if ( genesis_is_menu_page( $this->page_id ) ) {
+ wp_register_script( 'sandbox-admin', CHILD_LIB . '/js/' . gs_script_suffix( 'admin' ), array( 'jquery' ) , CHILD_THEME_VERSION );
+ }
+ }
+
+ /**
+ * Register metaboxes on Child Theme Settings page
+ *
+ * @since 1.1.0
+ *
+ * @see gs_general_settings() Callback for child theme settings
+ * @see gs_footer_settings() Callback for footer settings
+ */
+ function metaboxes() {
+
+ add_meta_box( 'gs-footer-settings', __( 'Genesis Sandbox Footer Settings', CHILD_DOMAIN ) , array( $this, 'gs_footer_settings' ), $this->pagehook, 'main', 'high' );
+
+ }
+
+ /**
+ * Register contextual help on Child Theme Settings page
+ *
+ * @since 1.1.0
+ *
+ */
+ function help() {
+ global $my_admin_page;
+ $screen = get_current_screen();
+
+ if ( $screen->id != $this->pagehook )
+ return;
+
+ $tab1_help =
+ '' . __( 'Home Settings', CHILD_DOMAIN ) . ' ' .
+ '' . __( 'The home page features the Genesis Grid loop that can be set in this section. To set the number of full content posts, enter the number under Number of Full Posts. To set the number of grid or other posts, enter a numer by Number of Other Posts.', CHILD_DOMAIN ) . '
';
+ $tab2_help =
+ '' . __( 'Post Formats', CHILD_DOMAIN ) . ' ' .
+ '' . __( 'Sandbox features the ability to turn on post formats for the entire site. Simply, check the checkbox by Enable post formats globally. However, this will not affect the portfolio theme.', CHILD_DOMAIN ) . '
';
+ $tab3_help =
+ '' . __( 'Footer Widgets', CHILD_DOMAIN ) . ' ' .
+ '' . __( 'Sandbox features the ability to set the number of footer widgets that you would like to have. First, you must enable footer widgets by checking the Add footer widgets checkbox. Then enter the number of footer widgets you would like to have. Finally, you can optionally remove footer widgets from the home page by checking the checkbox by Hide Footer Widgets on Home Page.', CHILD_DOMAIN ) . '
';
+ $tab4_help =
+ '' . __( 'Portfolio Templates', CHILD_DOMAIN ) . ' ' .
+ '' . __( 'Sandbox\'s features two portfolio templates: the category archive for portfolio and page template for portfolio. Since some people may want to have pages called Portfolio and not use the Portfolio template, I have decided to name the template page_portfolio.php instead of the page-portfolio.php which would force users to use the template based on the WordPress hierarchy. If you prefer to use another category name other than portfolio, please rename the file category-portfolio.php to category-{your-category-slug}.php. For more information see the WordPress ', CHILD_DOMAIN ) .
+ '' . __( 'Category Templates', CHILD_DOMAIN ) . '. ' .
+ __( 'Sandbox\'s portfolio options apply to both templates as appropriate.', CHILD_DOMAIN ) . '
' .
+ '' . __( 'Portfolio Options', CHILD_DOMAIN ) . ' ' .
+ '' . __( 'Sandbox\'s portfolio options contain the typical content archive settings including category designation, category exclusion, post exclusion, number of posts, content type, content limit, formatting tags and the read more text.', CHILD_DOMAIN ) .
+
+ '' . __( 'Category Templates', CHILD_DOMAIN ) . '. ' .
+ __( 'Portfolio Settings', CHILD_DOMAIN ) . '
';
+
+
+ $screen->add_help_tab(
+ array(
+ 'id' => $this->pagehook . '-tab1',
+ 'title' => __( 'Home Settings', CHILD_DOMAIN ),
+ 'content' => $tab1_help,
+ )
+ );
+ $screen->add_help_tab(
+ array(
+ 'id' => $this->pagehook . '-tab2',
+ 'title' => __( 'Post Formats', CHILD_DOMAIN ),
+ 'content' => $tab2_help,
+ )
+ );
+ $screen->add_help_tab(
+ array(
+ 'id' => $this->pagehook . '-tab3',
+ 'title' => __( 'Footer Widgets', CHILD_DOMAIN ),
+ 'content' => $tab3_help,
+ )
+ );
+ $screen->add_help_tab(
+ array(
+ 'id' => $this->pagehook . '-tab4',
+ 'title' => __( 'Portfolio Settings', CHILD_DOMAIN ),
+ 'content' => $tab4_help,
+ )
+ );
+
+ // Add Genesis Sidebar
+ $screen->set_help_sidebar(
+ '' . __( 'For more information:', CHILD_DOMAIN ) . '
'.
+ '' . __( 'Support Forums', CHILD_DOMAIN ) . '
'.
+ '' . __( 'Genesis Plugins', CHILD_DOMAIN ) . '
'.
+ '' . __( 'Genesis Tutorials by WPSmith', CHILD_DOMAIN ) . '
'
+ );
+ }
+
+
+ /**
+ * Callback for Sandbox General Settings metabox
+ *
+ * @since 1.1.0
+ *
+ * @see Genesis_Sandbox_Settings::metaboxes()
+ */
+ function gs_footer_settings() {
+ /**
+ * Add HTML
+ * For name, use echo $this->get_field_name( 'option' );
+ * For id, use echo $this->get_field_id( 'option' );
+ * For value, use echo $this->get_field_value( 'option' );
+ */
+
+ echo 'Footer Left: ';
+ ?>
+ get_field_value( 'footer_left_nav' ) ); ?> />
+ get_field_value( 'footer_left' ), $this->get_field_id( 'footer_left' ), array( 'textarea_rows' => 5 ) );
+
+ echo 'Footer Right: ';
+ ?>
+ get_field_value( 'footer_right_nav' ) ); ?> />
+ get_field_value( 'footer_right' ), $this->get_field_id( 'footer_right' ), array( 'textarea_rows' => 5 ) );
+
+ }
+
+}
diff --git a/lib/functions/gs-functions.php b/lib/functions/gs-functions.php
new file mode 100644
index 0000000..6124fd0
--- /dev/null
+++ b/lib/functions/gs-functions.php
@@ -0,0 +1,363 @@
+ $priority) {
+
+ // has_action returns int for the priority
+ if ( $priority = has_action( $hook, $function ) ) {
+
+ // If there's a function hooked in, remove the genesis_* function
+ // from whichever hook we're looping through at the time.
+ remove_action( $hook, $function, $priority );
+ }
+ }
+}
+
+/**
+ * Replace genesis_* functions hooked into somewhere for gs_* functions
+ * of the same suffix, at the same hook and priority
+ *
+ * Run at get_header to catch all customisations in functions.php
+ *
+ * @author Gary Jones
+ *
+ * @global array $wp_filter
+ * @param array $functions Array of function names without genesis_ prefix.
+ */
+function gs_replace_functions( $functions ) {
+
+ global $wp_filter;
+
+ // Loop through all hooks (yes, stored under the $wp_filter global)
+ foreach ( $wp_filter as $hook => $priority) {
+
+ // Loop through our array of functions for each hook
+ foreach( $functions as $function) {
+
+ // has_action returns int for the priority
+ if ( $priority = has_action( $hook, 'genesis_' . $function ) ) {
+
+ // If there's a function hooked in, remove the genesis_* function
+ // from whichever hook we're looping through at the time.
+ remove_action( $hook, 'genesis_' . $function, $priority );
+
+ // Add a replacement function in at the same time.
+ add_action( $hook, 'gs_' . $function, $priority );
+ }
+ }
+ }
+
+}
+
+/**
+ * Add navigation menu to the top.
+ *
+ * @since 1.0.0
+ */
+function gs_navigation( $location, $args ) {
+ if ( ! has_nav_menu( $location ) )
+ return;
+
+ $defaults = array(
+ 'theme_location' => $location,
+ 'container_id' => $location . '-nav',
+ 'menu_class' => 'genesis-nav-menu menu menu-' . $location,
+ 'echo' => false,
+ );
+
+ $args = wp_parse_args( $args, $defaults );
+ $nav = wp_nav_menu( $args );
+
+ $nav_output = sprintf(
+ '%3$s%2$s%4$s
',
+ $location . '-nav',
+ $nav,
+ genesis_structural_wrap( 'nav', 'open', 0 ),
+ genesis_structural_wrap( 'nav', 'close', 0 )
+ );
+
+ return $nav_output;
+}
+
+add_action( 'after_setup_theme', 'gs_responsive', 5 );
+/**
+ * Create Responsive Functions.
+ * Genesis 2.0 will have something different yet similiar.
+ */
+function gs_responsive() {
+
+ if ( current_theme_supports( 'gs-responsive' ) ) {
+ //add_action( 'wp_head', 'genesis_responsive_viewport' );
+
+ /** Roll our own due to genesis_responsive_viewport() possible changes */
+ add_action( 'wp_head', 'gs_responsive_viewport' );
+ add_action( 'wp_enqueue_scripts', 'gs_enqueue_responsive_stylesheet' );
+ }
+}
+
+/**
+ * If child theme supports responsive, look for and enqueue responsive.css.
+ *
+ * File (responsive.css) can be located either in the root theme directory, or in a /css subdirectory.
+ *
+ * @since 1.9.0
+ */
+function gs_enqueue_responsive_stylesheet() {
+
+ $stylesheet = genesis_get_theme_support_arg( 'gs-responsive', 'css' );
+
+ if ( ! $stylesheet )
+ return;
+
+ $handle = defined( 'CHILD_THEME_NAME' ) && CHILD_THEME_NAME ? sanitize_title( CHILD_THEME_NAME, 'child-theme' ) . '-responsive' : 'child-theme-responsive';
+
+ if ( file_exists( $stylesheet['dir'] ) ) {
+ $version = defined( 'CHILD_THEME_VERSION' ) && CHILD_THEME_VERSION ? CHILD_THEME_VERSION : PARENT_THEME_VERSION;
+ $deps = defined( 'CHILD_THEME_NAME' ) && CHILD_THEME_NAME ? sanitize_title_with_dashes( CHILD_THEME_NAME ) : 'child-theme';
+ wp_enqueue_style( $handle, $stylesheet['src'], array( $deps ), $version );
+ return;
+ }
+
+}
+
+add_action( 'wp_head', 'gs_responsive_viewport' );
+/**
+ * Checks to see if the child theme supports Genesis responsive CSS viewport tag. If so, it echos it.
+ *
+ * @since 1.9.0
+ */
+function gs_responsive_viewport() {
+
+ if ( true === $viewport = genesis_get_theme_support_arg( 'gs-responsive', 'viewport' ) )
+ echo ' ';
+ elseif ( $viewport = genesis_get_theme_support_arg( 'gs-responsive', 'viewport' ) )
+ echo $viewport;
+
+}
+
+/**
+ * Creates proper script/style suffix based on WP_DEBUG or SCRIPT_DEBUG.
+ *
+ * @see wp_default_scripts() for min/dev pattern.
+ *
+ * @param string $script Script filename basename.
+ * @param string $suffix Script suffix: 'css' or 'js'
+ * @param string $min Minimization abbreviation. Default = '.min'.
+ * @param string $dev Development abbreviation. Default = ''.
+ */
+function gs_script_suffix( $script, $suffix = 'js', $min = '.min', $dev = '' ) {
+ // Suffix Sanitization
+ if ( 'js' != $suffix && 'css' != $suffix )
+ $suffix = 'js';
+
+ $script = ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) ? $script . "$dev.$suffix" : $script . "$min.$suffix";
+
+ return $script;
+}
+
+add_action( 'admin_notices', 'gs_theme_files_to_edit' );
+/**
+ * Remove the specific theme files from the Theme Editor
+ *
+ * @since 1.1.0
+ *
+ * @global array $allowed_files Array of allowed files.
+ * @global WP_Theme Object $theme Current Theme WP_Theme Object.
+ * @global string $current_screen Reference to current screen.
+ */
+function gs_theme_files_to_edit() {
+
+ global $allowed_files, $theme, $current_screen;
+
+ /** Check to see if we are on the editor page */
+ if ( 'theme-editor' == $current_screen->id ) {
+ /** Do not change anything if we are in the Genesis theme */
+ if ( $theme->Name == CHILD_THEME_NAME ) {
+ /** Remove files */
+ foreach ( array( 'lib/init.php', 'alt/functions-alt.php', 'alt/gs-functions-alt.php', 'alt/init-alt.php', 'alt/init.php', 'languages/index.php', ) as $f )
+ unset( $allowed_files[ $f ] );
+ }
+ }
+
+}
+
+/*
+ * Usage for a custom post type named 'movies':
+ * unregister_post_type( 'movies' );
+ *
+ * Usage for the built in 'post' post type:
+ * unregister_post_type( 'post', 'edit.php' );
+ *
+ * To be used on admin_menu hook.
+*/
+function gs_unregister_post_type( $post_type, $slug = '' ){
+
+ global $wp_post_types;
+
+ if ( isset( $wp_post_types[ $post_type ] ) ) {
+ unset( $wp_post_types[ $post_type ] );
+
+ $slug = ( !$slug ) ? 'edit.php?post_type=' . $post_type : $slug;
+ remove_menu_page( $slug );
+ }
+}
+
+remove_action( 'genesis_before_footer', 'genesis_footer_widget_areas' );
+add_action( 'genesis_before_footer', 'gs_footer_widget_areas' );
+/**
+ * Echos the markup necessary to facilitate the footer widget areas.
+ *
+ * Checks for a numerical parameter given when adding theme support - if none is
+ * found, then the function returns early.
+ *
+ * Adds column classes based on number of footer widgets registered.
+ *
+ * @uses gs_column_class() Gets column class name for footer widgets 2-6.
+ *
+ * @since 1.1.0
+ *
+ * @return null Returns early if number of widget areas could not be determined,
+ * or nothing is added to the first widget area
+ */
+function gs_footer_widget_areas() {
+
+ $footer_widgets = get_theme_support( 'genesis-footer-widgets' );
+
+ if ( ! $footer_widgets || ! isset( $footer_widgets[0] ) || ! is_numeric( $footer_widgets[0] ) )
+ return;
+
+ $footer_widgets = (int) $footer_widgets[0];
+
+ /**
+ * Check to see if first widget area has widgets. If not,
+ * do nothing. No need to check all footer widget areas.
+ */
+ if ( ! is_active_sidebar( 'footer-1' ) )
+ return;
+
+ $output = '';
+ $counter = 1;
+
+ while ( $counter <= $footer_widgets ) {
+ /** Darn you, WordPress! Gotta output buffer. */
+ ob_start();
+ dynamic_sidebar( 'footer-' . $counter );
+ $widgets = ob_get_clean();
+
+ /** Dynamically create column classes. */
+ $class = 1 == (int) $counter ? 'first ' : '';
+ $class .= gs_column_class( $footer_widgets );
+
+ $output .= sprintf( '', $counter, $class, $widgets );
+
+ $counter++;
+ }
+
+ echo apply_filters( 'genesis_footer_widget_areas', sprintf( '', $output, genesis_structural_wrap( 'footer-widgets', 'open', 0 ), genesis_structural_wrap( 'footer-widgets', 'close', 0 ), $footer_widgets ) );
+
+}
+
+/**
+ * Gets the column class for 2-6 footer widgets.
+ *
+ * @since 1.1.0
+ *
+ * @return string Column class name.
+ */
+function gs_column_class( $i ) {
+ switch ( $i ) {
+ case 1:
+ return '';
+ case 2:
+ return 'one-half';
+ case 3:
+ return 'one-third';
+ case 4:
+ return 'one-fourth';
+ case 5:
+ return 'one-fifth';
+ case 6:
+ return 'one-sixth';
+ default:
+ return '';
+ }
+}
+
+/**
+ * Instantiate Pretty Photo
+ *
+ * @param array $args Future Development
+ */
+function gs_init_pretty_photo( $args = array() ) { ?>
+
+
+
+ class="no-js">
+
+
+
+
+ ';
+}
+
+/*
+03 Remove Genesis in-post metaboxes
+---------------------------------------------------------------------------------------------------- */
+
+/** Remove Genesis in-post SEO Settings */
+remove_action( 'admin_menu', 'genesis_add_inpost_seo_box' );
+
+/** Remove Genesis Layout Settings */
+remove_theme_support( 'genesis-inpost-layouts' );
+
+/*
+04 Remove Genesis admin menus
+---------------------------------------------------------------------------------------------------- */
+
+/** Remove Genesis menu link */
+remove_theme_support( 'genesis-admin-menu' );
+
+/** Remove Genesis SEO Settings menu link */
+remove_theme_support( 'genesis-seo-settings-menu' );
+
+/** Remove README theme support */
+remove_theme_support( 'genesis-readme-menu' );
+
+/*
+05 Genesis Style Selector
+---------------------------------------------------------------------------------------------------- */
+
+/** Create color style options */
+add_theme_support(
+ 'genesis-style-selector',
+ array(
+ 'theme-blue' => __( 'Blue', CHILD_DOMAIN ),
+ 'theme-green' => __( 'Green', CHILD_DOMAIN ),
+ 'theme-orange' => __( 'Orange', CHILD_DOMAIN ),
+ 'theme-red' => __( 'Red', CHILD_DOMAIN )
+ )
+);
+
+/*
+06 Body & Post Classes
+---------------------------------------------------------------------------------------------------- */
+
+add_filter( 'body_class', 'gs_add_body_class' );
+/**
+ * Add custom body class to the head.
+ *
+ * @param array $classes Array of existing body classes.
+ * @return array $classes Modified Array of body classes.
+ */
+function gs_add_body_class( $classes ) {
+ $classes[] = 'custom-class';
+ return $classes;
+}
+
+add_filter( 'post_class', 'gs_post_class' );
+/**
+ * Add custom post classes.
+ *
+ * @param array $classes Array of existing post classes.
+ * @return array $classes Modified Array of body classes.
+ */
+function gs_post_class( $classes ) {
+ $classes[] = 'custom-class';
+ return $classes;
+}
+
+/*
+07 Author Boxes
+---------------------------------------------------------------------------------------------------- */
+/** Remove author box on single posts */
+remove_action( 'genesis_after_post', 'genesis_do_author_box_single' );
+
+/** Display author box on single posts */
+add_filter( 'get_the_author_genesis_author_box_single', '__return_true' );
+
+/** Display author box on archive pages */
+add_filter( 'get_the_author_genesis_author_box_archive', '__return_true' );
+
+add_filter( 'genesis_author_box_title', 'gs_author_box_title' );
+/**
+ * Modify author box title
+ *
+ * @param string $title Default title (default: About {the author's name}).
+ * @return string New author box title.
+ */
+function gs_author_box_title( $title ) {
+ return 'About the Author ';
+}
+
+add_filter( 'genesis_author_box_gravatar_size', 'gs_author_box_gravatar_size', 10, 2 );
+/**
+ * Modify the size of the Gravatar in author box
+ *
+ * @param int $size Size in pixels of gravatar (default: 70).
+ * @param string $context Optional. Allows different author box markup for
+ * different contexts, specifically 'single'. Default is empty string.
+ * @return int New size in pixels of gravatar.
+ */
+function gs_author_box_gravatar_size( $size, $context ) {
+ return 80;
+}
+
+add_filter( 'genesis_author_box', 'gs_author_box', 10, 6 );
+/**
+ * Customize Author Box
+ * @author Bill Erickson
+ * @link http://www.billerickson.net/code/customize-author-box
+ *
+ * @param string $output
+ * @param string $context
+ * @param string $pattern
+ * @param string $gravatar
+ * @param string $title
+ * @param string $description
+ * @return string $output
+ */
+function gs_author_box( $output, $context, $pattern, $gravatar, $title, $description ) {
+ $output = '';
+
+ // Author box on single post
+ if( 'single' == $context ) {
+ $output .= '';
+ $output .= '
';
+ $output .= get_avatar( get_the_author_meta( 'email' ), 200 );
+ $output .= '
';
+ $output .= '
';
+ $name = get_the_author();
+ $title = get_the_author_meta( 'title' );
+ if( !empty( $title ) )
+ $name .= ', ' . $title;
+ $output .= '
' . $name . ' ';
+ $output .= '
' . get_the_author_meta( 'description' ) . '
';
+ $output .= '
';
+ $output .= '
';
+ $output .= '
';
+ $output .= '
';
+ $output .= '
';
+
+ } else {
+ $output .= '';
+ $output .= '
';
+ $output .= get_avatar( get_the_author_meta( 'email' ), 200 );
+ $output .= '
';
+ $output .= '
';
+ $name = get_the_author();
+ $title = get_the_author_meta( 'title' );
+ if( !empty( $title ) )
+ $name .= ', ' . $title;
+ $output .= '
' . $name . ' ';
+ $output .= '';
+ if( get_the_author_meta( 'twitter' ) )
+ $output .= ' ';
+ if( get_the_author_meta( 'gplus' ) )
+ $output .= ' ';
+ if( get_the_author_meta( 'linkedin' ) )
+ $output .= ' ';
+ $output .= ' ';
+ $output .= ' ';
+ $output .= 'Email ' . get_the_author_meta( 'email' ) . ' ';
+ $output .= '';
+ $output .= '
' . get_the_author_meta( 'description' ) . '
';
+ $output .= '
';
+ $output .= '
';
+ }
+ return $output;
+}
+
+/*
+08 Post Info & Post Meta
+---------------------------------------------------------------------------------------------------- */
+add_filter( 'genesis_post_info', 'gs_post_info_filter' );
+/**
+ * Customize the post info function
+ *
+ * @link http://my.studiopress.com/docs/shortcode-reference/
+ * @param string $post_info Default post info.
+ * (default: '[post_date] ' . __( 'by', 'genesis' ) . ' [post_author_posts_link] [post_comments] [post_edit]')
+ * @return string Modified post info.
+ */
+function gs_post_info_filter( $post_info ) {
+ return '[post_date] by [post_author_posts_link] [post_comments] [post_edit]';
+}
+
+/** Remove the post info function */
+remove_action( 'genesis_before_post_content', 'genesis_post_info' );
+//add_filter( 'genesis_post_info', '__return_null' );
+
+add_filter( 'genesis_post_meta', 'gs_post_meta_filter' );
+/**
+ * Customize the post meta function
+ *
+ * @link http://my.studiopress.com/docs/shortcode-reference/
+ * @param string $post_meta Default post meta.
+ * (default: '[post_categories] [post_tags]')
+ * @return string Modified post meta.
+ */
+function gs_post_meta_filter( $post_meta ) {
+ return '[post_categories before="Filed Under: "] [post_tags before="Tagged: "]';
+}
+
+/** Remove the post meta function */
+remove_action( 'genesis_after_post_content', 'genesis_post_meta' );
+//add_filter( 'genesis_post_meta', '__return_null' );
+
+/*
+09 Customize Links
+ a. Next/Previous Links
+---------------------------------------------------------------------------------------------------- */
+
+add_filter ( 'genesis_next_link_text' , 'gs_next_link_text' );
+/**
+ * Customize the next page link
+ *
+ * @param string $text Default next page link.
+ * (default: __( 'Next Page', 'genesis' ) . '»' )
+ * @return string Modified next page link.
+ */
+function gs_next_link_text ( $text ) {
+ return g_ent( '» ' ) . __( 'Custom Next Page Link', CHILD_DOMAIN );
+}
+
+/*
+ b. Newer/Older Links
+---------------------------------------------------------------------------------------------------- */
+
+add_filter ( 'genesis_prev_link_text' , 'gs_prev_link_text' );
+/**
+ * Customize the previous page link
+ *
+ * @param string $text Default previous page link.
+ * (default: __( 'Previous Page', 'genesis' ) . '»' )
+ * @return string Modified previous page link.
+ */
+function gs_prev_link_text ( $text ) {
+ return g_ent( '« ' ) . __( 'Custom Previous Page Link', CHILD_DOMAIN );
+}
+
+add_filter ( 'genesis_newer_link_text' , 'gs_newer_link_text' );
+/**
+ * Customize the newer posts link
+ *
+ * @param string $text Default newer posts link.
+ * (default: __( 'Newer Posts', 'genesis' ) . '»' )
+ * @return string Modified newer posts link.
+ */
+function gs_newer_link_text ( $text ) {
+ return g_ent( '» ' ) . __( 'Custom Newer Posts Link', CHILD_DOMAIN );
+}
+
+add_filter ( 'genesis_older_link_text' , 'gs_older_link_text' );
+/**
+ * Customize the older posts link
+ *
+ * @param string $text Default older posts link.
+ * (default: __( 'Older Posts', 'genesis' ) . '»' )
+ * @return string Modified older posts link.
+ */
+function gs_older_link_text ( $text ) {
+ return g_ent( '« ' ) . __( 'Custom Older Posts Link', CHILD_DOMAIN );
+}
+
+/*
+10 Search Customizations
+---------------------------------------------------------------------------------------------------- */
+
+// Customize search form input box text
+add_filter( 'genesis_search_text', 'gs_search_text' );
+/**
+ * Customize search form input box text
+ *
+ * @param string $text Default search form input box text.
+ * (default: esc_attr__( 'Search this website', 'genesis' ) . '…' )
+ * @return string Modified search form input box text.
+ */
+function gs_search_text($text) {
+ return esc_attr( 'Search my blog...' );
+}
+
+add_filter( 'genesis_search_button_text', 'gs_search_button_text' );
+/**
+ * Customize search form input button text
+ *
+ * @param string $text Default search form input button text.
+ * (default: Search )
+ * @return string Modified search form input button text.
+ */
+function gs_search_button_text($text) {
+ return esc_attr( 'Go' );
+}
+
+/*
+11 Google Fonts
+---------------------------------------------------------------------------------------------------- */
+
+add_action( 'wp_enqueue_scripts', 'gs_load_google_fonts' );
+/**
+ * Enqueue Google fonts
+ */
+function gs_load_google_fonts() {
+ wp_enqueue_style(
+ 'child-google-fonts',
+ 'http://fonts.googleapis.com/css?family=Merriweather|Open+Sans',
+ array(),
+ CHILD_THEME_VERSION
+ );
+}
+
+/*
+12 Remove Genesis Site Title, Site Description, & Header Right
+---------------------------------------------------------------------------------------------------- */
+/** Remove the site title */
+remove_action( 'genesis_site_title', 'genesis_seo_site_title' );
+
+/** Remove the site description */
+remove_action( 'genesis_site_description', 'genesis_seo_site_description' );
+
+/** Remove the header right widget area */
+unregister_sidebar( 'header-right' );
+
+/*
+13 Reposition Items: Breadcrumbs, Footer, Primary & Secondary Navs
+---------------------------------------------------------------------------------------------------- */
+
+/** Reposition the breadcrumbs */
+remove_action( 'genesis_before_loop', 'genesis_do_breadcrumbs' );
+add_action( 'genesis_after_header', 'genesis_do_breadcrumbs' );
+
+/** Reposition the footer */
+remove_action( 'genesis_footer', 'genesis_footer_markup_open', 5 );
+remove_action( 'genesis_footer', 'genesis_do_footer' );
+remove_action( 'genesis_footer', 'genesis_footer_markup_close', 15 );
+add_action( 'genesis_after', 'genesis_footer_markup_open', 11 );
+add_action( 'genesis_after', 'genesis_do_footer', 12 );
+add_action( 'genesis_after', 'genesis_footer_markup_close', 13 );
+
+/** Reposition the primary navigation menu */
+remove_action( 'genesis_after_header', 'genesis_do_nav' );
+add_action( 'genesis_before_header', 'genesis_do_nav' );
+
+/** Reposition the secondary navigation menu */
+remove_action( 'genesis_after_header', 'genesis_do_subnav' );
+add_action( 'genesis_before_header', 'genesis_do_subnav' );
+
+/*
+14 Remove Genesis/WordPress widgets
+---------------------------------------------------------------------------------------------------- */
+
+add_action( 'widgets_init', 'gs_remove_enews_updates_widget', 20 );
+/**
+ * Remove Genesis/WordPress widgets
+ */
+function gs_remove_enews_updates_widget() {
+ // Remove eNews and Updates widget (softly deprecated in Genesis 1.9)
+ unregister_widget( 'Genesis_eNews_Updates' );
+
+ // Remove Latest Tweets widget (softly deprecated in Genesis 1.9)
+ unregister_widget( 'Genesis_Latest_Tweets_Widget' );
+
+ // Remove Featured Page widget
+ unregister_widget( 'Genesis_Featured_Page' );
+
+ // Remove Featured Post widget
+ // Don't do if using Genesis Featured Widget Amplified
+ unregister_widget( 'Genesis_Featured_Post' );
+
+ // Remove User Profile widget
+ unregister_widget( 'Genesis_User_Profile_Widget' );
+
+ // Remove these WordPress widgets:
+ //unregister_widget( 'WP_Widget_Pages' );
+ //unregister_widget( 'WP_Widget_Calendar' );
+ //unregister_widget( 'WP_Widget_Archives' );
+ //unregister_widget( 'WP_Widget_Links' );
+ //unregister_widget( 'WP_Widget_Meta' );
+ //unregister_widget( 'WP_Widget_Search' );
+ //unregister_widget( 'WP_Widget_Text' );
+ //unregister_widget( 'WP_Widget_Categories' );
+ //unregister_widget( 'WP_Widget_Recent_Posts' );
+ //unregister_widget( 'WP_Widget_Recent_Comments' );
+ //unregister_widget( 'WP_Widget_RSS' );
+ //unregister_widget( 'WP_Widget_Tag_Cloud' );
+ //unregister_widget( 'WP_Nav_Menu_Widget' );
+}
+
+/*
+15 Remove Superfish
+---------------------------------------------------------------------------------------------------- */
+
+add_action( 'wp_enqueue_scripts', 'unregister_superfish' );
+/**
+ * Unregister the superfish scripts
+ */
+function unregister_superfish() {
+ wp_deregister_script( 'superfish' );
+ wp_deregister_script( 'superfish-args' );
+}
+
+/*
+16 Enqueue jQuery from Google CDN with Fallback
+---------------------------------------------------------------------------------------------------- */
+
+add_action( 'wp_enqueue_scripts', 'wps_enqueue_jquery' );
+/**
+ * Enqueue jQuery from Google CDN with fallback to local WordPress
+ *
+ * @link https://gist.github.com/4083811
+ * @link http://codex.wordpress.org/Function_Reference/wp_enqueue_script
+ * @link http://codex.wordpress.org/Function_Reference/wp_register_script
+ * @link http://codex.wordpress.org/Function_Reference/wp_deregister_script
+ * @link http://codex.wordpress.org/Function_Reference/get_bloginfo
+ * @link http://codex.wordpress.org/Function_Reference/is_wp_error
+ * @link http://codex.wordpress.org/Function_Reference/set_transient
+ * @link http://codex.wordpress.org/Function_Reference/get_transient
+ *
+ * @uses get_transient() Get the value of a transient.
+ * @uses set_transient() Set/update the value of a transient.
+ * @uses is_wp_error() Check whether the passed variable is a WordPress Error.
+ * @uses get_bloginfo() returns information about your site.
+ * @uses wp_deregister_script() Deregisters javascripts for use with wp_enqueue_script() later.
+ * @uses wp_register_script() Registers javascripts for use with wp_enqueue_script() later.
+ * @uses wp_enqueue_script() Enqueues javascript.
+ */
+function gs_enqueue_jquery() {
+ // Setup Google URI, default
+ $protocol = ( isset( $_SERVER['HTTPS'] ) && 'on' == $_SERVER['HTTPS'] ) ? 'https' : 'http';
+ $url = $protocol . '://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js';
+
+ // Setup WordPress URI
+ $wpurl = get_bloginfo( 'wpurl') . '/wp-includes/js/jquery/jquery.js';
+
+ // Setup version
+ $ver = null;
+
+ // Deregister WordPress default jQuery
+ wp_deregister_script( 'jquery' );
+
+ // Check transient, if false, set URI to WordPress URI
+ delete_transient( 'google_jquery' );
+
+ if ( 'false' == ( $google = get_transient( 'google_jquery' ) ) ) {
+ $url = $wpurl;
+ }
+ // Transient failed
+ elseif ( false === $google ) {
+ // Ping Google
+ $resp = wp_remote_head( $url );
+
+ // Use Google jQuery
+ if ( ! is_wp_error( $resp ) && 200 == $resp['response']['code'] ) {
+ // Set transient for 5 minutes
+ set_transient( 'google_jquery', 'true', 60 * 5 );
+ }
+
+ // Use WordPress jQuery
+ else {
+ // Set transient for 5 minutes
+ set_transient( 'google_jquery', 'false', 60 * 5 );
+
+ // Use WordPress URI
+ $url = $wpurl;
+
+ // Set jQuery Version, WP stanards
+ $ver = '1.8.2';
+ }
+ }
+
+ // Register surefire jQuery
+ wp_register_script( 'jquery', $url, array(), $ver, true );
+
+ // Enqueue jQuery
+ wp_enqueue_script( 'jquery' );
+}
+
+/*
+17 CSS Cache Buster
+---------------------------------------------------------------------------------------------------- */
+
+add_filter( 'stylesheet_uri', 'gs_stylesheet_uri' );
+/**
+ * CSS Cache Buster
+ * Always load CSS regardless of cache.
+ */
+function gs_stylesheet_uri( $stylesheet_uri ) {
+ return add_query_arg( 'v', filemtime( get_stylesheet_directory() . '/style.css' ), $stylesheet_uri );
+}
+
+/*
+18 Genesis Theme Settings
+---------------------------------------------------------------------------------------------------- */
+
+add_filter( 'genesis_options', 'gs_define_genesis_settings', 10, 2 );
+/**
+ * Define Genesis Options
+ *
+ * @param array $options Array of Setting Options.
+ * @param string $setting Specific Setting.
+ */
+function gs_define_genesis_settings( $options, $setting ) {
+ if ( GENESIS_SETTINGS_FIELD === $setting ) {
+ $options['show_info'] = 0; // Display theme info in document source
+ $options['update'] = 1; // Enable Automatic Updates
+ $options['update_email'] = 0; // Notify when updates are available
+ $options['update_email_address'] = ''; // Update email address
+ $options['feed_uri'] = ''; // Custom reed URI
+ $options['redirect_feed'] = 0; // Redirect reed
+ $options['comments_feed_uri'] = ''; // Custom comments feed URI
+ $options['redirect_comments_feed'] = 0; // Redirect feed
+ $options['site_layout'] = 'content-sidebar'; // Default layout
+ $options['blog_title'] = 'text'; // Blog title/logo - 'text' or 'image'
+ $options['nav'] = 1; // Include primary navigation (DEPRECATED)
+ $options['nav_superfish'] = 1; // Enable fancy dropdowns
+ $options['nav_extras_enable'] = 0; // Enable extras
+ $options['nav_extras'] = 'date'; // Extras - 'date', 'rss', 'search', 'twitter'
+ $options['nav_extras_twitter_id'] = ''; // Twitter ID
+ $options['nav_extras_twitter_text'] = 'Follow me on Twitter'; // Twitter link text
+ $options['subnav'] = 0; // Include secondary navigation (DEPRECATED)
+ $options['subnav_superfish'] = 1; // Enable fancy dropdowns
+ $options['breadcrumb_home'] = 1; // Enable breadcrumbs on Front Page
+ $options['breadcrumb_single'] = 1; // Enable breadcrumbs on Posts
+ $options['breadcrumb_page'] = 1; // Enable breadcrumbs on Pages
+ $options['breadcrumb_archive'] = 1; // Enable breadcrumbs on Archives
+ $options['breadcrumb_404'] = 1; // Enable breadcrumbs on 404 Page
+ $options['breadcrumb_attachment'] = 1; // Enable breadcrumbs on Attachment Pages
+ $options['comments_posts'] = 1; // Enable comments on Posts
+ $options['comments_pages'] = 0; // Enable comments on Pages
+ $options['trackbacks_posts'] = 1; // Enable trackbacks on Posts
+ $options['trackbacks_pages'] = 0; // Enable trackbacks on Pages
+ $options['content_archive'] = 'full'; // Content archives display - 'full', 'excerpts'
+ $options['content_archive_limit'] = ''; // Limit content to n characters
+ $options['content_archive_thumbnail'] = 0; // Include featured image
+ $options['posts_nav'] = 'older-newer'; // Post navigation - 'older-newer', 'prev-next', 'numeric'
+ $options['blog_cat'] = '0'; // Blog page displays which category
+ $options['blog_cat_exclude'] = ''; // Blog page excludes which category
+ $options['blog_cat_num'] = 10; // Number of posts to show
+ $options['header_scripts'] = ''; // Header scripts, unfiltered, must include tags
+ $options['footer_scripts'] = ''; // Footer scripts, unfiltered, must include tags
+ }
+
+ return $options;
+}
+
+add_action( 'genesis_theme_settings_metaboxes', 'child_remove_metaboxes' );
+/**
+ * Remove unused theme settings
+ *
+ * @param string $_genesis_theme_settings_pagehook Genesis Admin Pagehook.
+ */
+function child_remove_metaboxes( $_genesis_theme_settings_pagehook ) {
+ remove_meta_box( 'genesis-theme-settings-version', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-feeds', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-header', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-layout', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-nav', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-breadcrumb', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-comments', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-posts', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-blogpage', $_genesis_theme_settings_pagehook, 'main' );
+ remove_meta_box( 'genesis-theme-settings-scripts', $_genesis_theme_settings_pagehook, 'main' );
+}
+
+/** Force Superfish */
+add_filter( 'genesis_pre_get_option_nav_superfish', '__return_true' );
+
+/*
+19 Alternative Doctype
+---------------------------------------------------------------------------------------------------- */
+
+remove_action( 'genesis_doctype', 'genesis_do_doctype' );
+add_action( 'genesis_doctype', 'gs_do_doctype' );
+/**
+ * Conditional html element classes
+ */
+function child_do_doctype() {
+ ?>
+
+
+
+
+
+ >
+
+
+ get('TextDomain') . '-settings' );
+
+ /** @type constant Text Domain. */
+ define( 'CHILD_DOMAIN', $theme->get('TextDomain') );
+
+ /** @type constant Child Theme Version. */
+ define( 'CHILD_THEME_VERSION', $theme->Version );
+
+ /** @type constant Child Theme Name, used in footer. */
+ define( 'CHILD_THEME_NAME', $theme->Name );
+
+ /** @type constant Child Theme URL, used in footer. */
+ define( 'CHILD_THEME_URL', $theme->get('ThemeURI') );
+
+ // Developer Information, see lib/admin/admin-functions.php
+ /** @type constant Child Theme Developer, used in footer. */
+ define( 'CHILD_DEVELOPER', $theme->Author );
+
+ /** @type constant Child Theme Developer URL, used in footer. */
+ define( 'CHILD_DEVELOPER_URL', $theme->{'Author URI'} );
+
+ // Define Directory Location Constants
+ /** @type constant Child Theme Library/Includes URL Location. */
+ define( 'CHILD_LIB_DIR', CHILD_DIR . '/lib' );
+
+ /** @type constant Child Theme Images URL Location. */
+ define( 'CHILD_IMAGES_DIR', CHILD_DIR . '/images' );
+
+ /** @type constant Child Theme Admin URL Location. */
+ define( 'CHILD_ADMIN_DIR', CHILD_LIB_DIR . '/admin' );
+
+ /** @type constant Child Theme JS URL Location. */
+ define( 'CHILD_JS_DIR', CHILD_DIR .'/js' );
+
+ /** @type constant Child Theme JS URL Location. */
+ define( 'CHILD_CSS_DIR', CHILD_DIR .'/css' );
+
+ // Define URL Location Constants
+ /** @type constant Child Theme Library/Includes URL Location. */
+ define( 'CHILD_LIB', CHILD_URL . '/lib' );
+
+ /** @type constant Child Theme Images URL Location. */
+ define( 'CHILD_IMAGES', CHILD_URL . '/images' );
+
+ /** @type constant Child Theme Admin URL Location. */
+ define( 'CHILD_ADMIN', CHILD_LIB . '/admin' );
+
+ /** @type constant Child Theme JS URL Location. */
+ define( 'CHILD_JS', CHILD_URL .'/js' );
+
+ /** @type constant Child Theme JS URL Location. */
+ define( 'CHILD_CSS', CHILD_URL .'/css' );
+}
+
+add_action( 'genesis_init', 'gs_init', 15 );
+/**
+ * This function calls necessary child theme files
+ *
+ * @since 1.1.0
+ */
+function gs_init() {
+
+ /** Theme Specific Functions */
+ include_once( CHILD_LIB_DIR . '/functions/gs-functions.php' );
+
+ // Load admin files when necessary
+ if ( is_admin() ) {
+
+ /** Admin Functions */
+ include_once( CHILD_LIB_DIR . '/admin/gs-admin-functions.php');
+
+ /** New Admin Page */
+ include_once( CHILD_LIB_DIR . '/admin/gs-settings.php');
+
+ /** Inpost Metaboxes */
+ include_once( CHILD_LIB_DIR . '/admin/gs-inpost-functions.php');
+
+ /** Get required plugins */
+ require_once( CHILD_LIB_DIR . '/plugins/plugins.php' );
+
+ }
+
+}
+
+add_filter( 'http_request_args', 'gs_prevent_theme_update', 5, 2 );
+/**
+ * Don't update theme from .org repo.
+ *
+ * If there is a theme in the repo with the same name,
+ * this prevents WP from prompting an update. Future proofs themes.
+ *
+ * @since 1.1.0
+ *
+ * @author Mark Jaquith
+ * @link http://markjaquith.wordpress.com/2009/12/14/excluding-your-plugin-or-theme-from-update-checks/
+ */
+function gs_prevent_theme_update( $r, $url ) {
+ if ( 0 !== strpos( $url, 'http://api.wordpress.org/themes/update-check' ) )
+ return $r; // Not a theme update request. Bail immediately.
+ $themes = unserialize( $r['body']['themes'] );
+ unset( $themes[ get_option( 'template' ) ] );
+ unset( $themes[ get_option( 'stylesheet' ) ] );
+ $r['body']['themes'] = serialize( $themes );
+ return $r;
+}
diff --git a/lib/js/admin.js b/lib/js/admin.js
new file mode 100644
index 0000000..81c1b86
--- /dev/null
+++ b/lib/js/admin.js
@@ -0,0 +1,72 @@
+jQuery(document).ready(function($) {
+ // $() will work as an alias for jQuery() inside of this function
+
+ $("#primary-menu-toggle .show").click(function () {
+ if ($(".menu-primary").is(":hidden")) {
+ $(".menu-primary").slideDown(500);
+ $(this).attr('class', 'toggle-switch hide').attr('title', 'Hide Menu');
+ $('#primary-menu-toggle span').replaceWith('Hide Menu ');
+ } else {
+ $(".menu-primary").hide(500);
+ $(this).attr('class', 'toggle-switch show').attr('title', 'Show Menu');
+ $('#primary-menu-toggle span').replaceWith('Show Menu ');
+ }
+ });
+
+ $("#secondary-menu-toggle .show").click(function () {
+ if ($(".menu-secondary").is(":hidden")) {
+ $(".menu-secondary").slideDown(500);
+ $(this).attr('class', 'toggle-switch hide').attr('title', 'Hide Menu');
+ $('#secondary-menu-toggle span').replaceWith('Hide Menu ');
+ } else {
+ $(".menu-secondary").hide(500);
+ $(this).attr('class', 'toggle-switch show').attr('title', 'Show 2nd Menu');
+ $('#secondary-menu-toggle span').replaceWith('Show 2nd Menu ');
+ }
+ });
+
+ /*SMOOTH SCROLLING*/
+ jQuery(".scroll, .gototop a").click(function(event){
+ event.preventDefault();
+ jQuery('html,body').animate({scrollTop:jQuery(this.hash).offset().top}, 500);
+ });
+
+
+});
+
+
+/*
+ * This script hides or shows the menu on resize if required.
+ */
+
+/*
+ * finds the height of the #sidebar and #sidebar-alt the sets the #content to have a min-height of whichever value is greater
+ */
+function fluidMenuToggle(){
+
+ var body = jQuery( 'body' ).width();
+
+ if( body > 768 ){
+
+ jQuery(".menu-primary").slideDown(500);
+ jQuery(".menu-secondary").slideDown(500);
+
+ }
+ else if( body < 768 ) {
+
+ jQuery(".menu-primary").hide(500);
+ jQuery(".menu-secondary").hide(500);
+
+ }
+
+
+}
+
+
+var menuTimer;
+jQuery(window).resize(function() {
+ clearTimeout(menuTimer);
+ menuTimer = setTimeout(fluidMenuToggle, 100);
+});
+
+
\ No newline at end of file
diff --git a/lib/plugins/class-tgm-plugin-activation.php b/lib/plugins/class-tgm-plugin-activation.php
new file mode 100644
index 0000000..9495add
--- /dev/null
+++ b/lib/plugins/class-tgm-plugin-activation.php
@@ -0,0 +1,2092 @@
+
+ * @author Gary Jones
+ * @copyright Copyright (c) 2012, Thomas Griffin
+ * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later
+ * @link https://github.com/thomasgriffin/TGM-Plugin-Activation
+ */
+
+/*
+ Copyright 2012 Thomas Griffin (email : thomas@thomasgriffinmedia.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 3, as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+if ( ! class_exists( 'TGM_Plugin_Activation' ) ) {
+ /**
+ * Automatic plugin installation and activation library.
+ *
+ * Creates a way to automatically install and activate plugins from within themes.
+ * The plugins can be either pre-packaged, downloaded from the WordPress
+ * Plugin Repository or downloaded from a private repository.
+ *
+ * @since 1.0.0
+ *
+ * @package TGM-Plugin-Activation
+ * @author Thomas Griffin
+ * @author Gary Jones
+ */
+ class TGM_Plugin_Activation {
+
+ /**
+ * Holds a copy of itself, so it can be referenced by the class name.
+ *
+ * @since 1.0.0
+ *
+ * @var TGM_Plugin_Activation
+ */
+ static $instance;
+
+ /**
+ * Holds arrays of plugin details.
+ *
+ * @since 1.0.0
+ *
+ * @var array
+ */
+ public $plugins = array();
+
+ /**
+ * Parent menu slug for plugins page.
+ *
+ * @since 2.2.0
+ *
+ * @var string Parent menu slug. Defaults to 'themes.php'.
+ */
+ public $parent_menu_slug = 'themes.php';
+
+ /**
+ * Parent URL slug for URL references.
+ *
+ * This is useful if you want to place the custom plugins page as a
+ * submenu item under a custom parent menu.
+ *
+ * @since 2.2.0
+ *
+ * @var string Parent URL slug. Defaults to 'themes.php'.
+ */
+ public $parent_url_slug = 'themes.php';
+
+ /**
+ * Name of the querystring argument for the admin page.
+ *
+ * @since 1.0.0
+ *
+ * @var string
+ */
+ public $menu = 'install-required-plugins';
+
+ /**
+ * Text domain for localization support.
+ *
+ * @since 1.1.0
+ *
+ * @var string
+ */
+ public $domain = 'tgmpa';
+
+ /**
+ * Default absolute path to folder containing pre-packaged plugin zip files.
+ *
+ * @since 2.0.0
+ *
+ * @var string Absolute path prefix to packaged zip file location. Default is empty string.
+ */
+ public $default_path = '';
+
+ /**
+ * Flag to show admin notices or not.
+ *
+ * @since 2.1.0
+ *
+ * @var boolean
+ */
+ public $has_notices = true;
+
+ /**
+ * Flag to set automatic activation of plugins. Off by default.
+ *
+ * @since 2.2.0
+ *
+ * @var boolean
+ */
+ public $is_automatic = false;
+
+ /**
+ * Optional message to display before the plugins table.
+ *
+ * @since 2.2.0
+ *
+ * @var string Message filtered by wp_kses_post(). Default is empty string.
+ */
+ public $message = '';
+
+ /**
+ * Holds configurable array of strings.
+ *
+ * Default values are added in the constructor.
+ *
+ * @since 2.0.0
+ *
+ * @var array
+ */
+ public $strings = array();
+
+ /**
+ * Adds a reference of this object to $instance, populates default strings,
+ * does the tgmpa_init action hook, and hooks in the interactions to init.
+ *
+ * @since 1.0.0
+ *
+ * @see TGM_Plugin_Activation::init()
+ */
+ public function __construct() {
+
+ self::$instance =& $this;
+
+ $this->strings = array(
+ 'page_title' => __( 'Install Required Plugins', $this->domain ),
+ 'menu_title' => __( 'Install Plugins', $this->domain ),
+ 'installing' => __( 'Installing Plugin: %s', $this->domain ),
+ 'oops' => __( 'Something went wrong.', $this->domain ),
+ 'notice_can_install_required' => _n_noop( 'This theme requires the following plugin: %1$s.', 'This theme requires the following plugins: %1$s.' ),
+ 'notice_can_install_recommended' => _n_noop( 'This theme recommends the following plugin: %1$s.', 'This theme recommends the following plugins: %1$s.' ),
+ 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ),
+ 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ),
+ 'notice_can_activate_recommended' => _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ),
+ 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ),
+ 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.' ),
+ 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ),
+ 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ),
+ 'activate_link' => _n_noop( 'Activate installed plugin', 'Activate installed plugins' ),
+ 'return' => __( 'Return to Required Plugins Installer', $this->domain ),
+ 'plugin_activated' => __( 'Plugin activated successfully.', $this->domain ),
+ 'complete' => __( 'All plugins installed and activated successfully. %1$s', $this->domain ),
+ );
+
+ /** Annouce that the class is ready, and pass the object (for advanced use) */
+ do_action_ref_array( 'tgmpa_init', array( &$this ) );
+
+ /** When the rest of WP has loaded, kick-start the rest of the class */
+ add_action( 'init', array( &$this, 'init' ) );
+
+ }
+
+ /**
+ * Initialise the interactions between this class and WordPress.
+ *
+ * Hooks in three new methods for the class: admin_menu, notices and styles.
+ *
+ * @since 2.0.0
+ *
+ * @see TGM_Plugin_Activation::admin_menu()
+ * @see TGM_Plugin_Activation::notices()
+ * @see TGM_Plugin_Activation::styles()
+ */
+ public function init() {
+
+ do_action( 'tgmpa_register' );
+ /** After this point, the plugins should be registered and the configuration set */
+
+ /** Proceed only if we have plugins to handle */
+ if ( $this->plugins ) {
+ $sorted = array(); // Prepare variable for sorting
+
+ foreach ( $this->plugins as $plugin )
+ $sorted[] = $plugin['name'];
+
+ array_multisort( $sorted, SORT_ASC, $this->plugins ); // Sort plugins alphabetically by name
+
+ add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
+ add_action( 'admin_head', array( &$this, 'dismiss' ) );
+ add_filter( 'install_plugin_complete_actions', array( &$this, 'actions' ) );
+
+ /** Load admin bar in the header to remove flash when installing plugins */
+ if ( $this->is_tgmpa_page() ) {
+ remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
+ remove_action( 'admin_footer', 'wp_admin_bar_render', 1000 );
+ add_action( 'wp_head', 'wp_admin_bar_render', 1000 );
+ add_action( 'admin_head', 'wp_admin_bar_render', 1000 );
+ }
+
+ if ( $this->has_notices ) {
+ add_action( 'admin_notices', array( &$this, 'notices' ) );
+ add_action( 'admin_init', array( &$this, 'admin_init' ), 1 );
+ add_action( 'admin_enqueue_scripts', array( &$this, 'thickbox' ) );
+ add_action( 'switch_theme', array( &$this, 'update_dismiss' ) );
+ }
+
+ /** Setup the force activation hook */
+ foreach ( $this->plugins as $plugin ) {
+ if ( isset( $plugin['force_activation'] ) && true === $plugin['force_activation'] ) {
+ add_action( 'admin_init', array( &$this, 'force_activation' ) );
+ break;
+ }
+ }
+
+ /** Setup the force deactivation hook */
+ foreach ( $this->plugins as $plugin ) {
+ if ( isset( $plugin['force_deactivation'] ) && true === $plugin['force_deactivation'] ) {
+ add_action( 'switch_theme', array( &$this, 'force_deactivation' ) );
+ break;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Handles calls to show plugin information via links in the notices.
+ *
+ * We get the links in the admin notices to point to the TGMPA page, rather
+ * than the typical plugin-install.php file, so we can prepare everything
+ * beforehand.
+ *
+ * WP doesn't make it easy to show the plugin information in the thickbox -
+ * here we have to require a file that includes a function that does the
+ * main work of displaying it, enqueue some styles, set up some globals and
+ * finally call that function before exiting.
+ *
+ * Down right easy once you know how...
+ *
+ * @since 2.1.0
+ *
+ * @global string $tab Used as iframe div class names, helps with styling
+ * @global string $body_id Used as the iframe body ID, helps with styling
+ * @return null Returns early if not the TGMPA page.
+ */
+ public function admin_init() {
+
+ if ( ! $this->is_tgmpa_page() )
+ return;
+
+ if ( isset( $_REQUEST['tab'] ) && 'plugin-information' == $_REQUEST['tab'] ) {
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for install_plugin_information()
+
+ wp_enqueue_style( 'plugin-install' );
+
+ global $tab, $body_id;
+ $body_id = $tab = 'plugin-information';
+
+ install_plugin_information();
+
+ exit;
+ }
+
+ }
+
+ /**
+ * Enqueues thickbox scripts/styles for plugin info.
+ *
+ * Thickbox is not automatically included on all admin pages, so we must
+ * manually enqueue it for those pages.
+ *
+ * Thickbox is only loaded if the user has not dismissed the admin
+ * notice or if there are any plugins left to install and activate.
+ *
+ * @since 2.1.0
+ */
+ public function thickbox() {
+
+ if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice', true ) )
+ add_thickbox();
+
+ }
+
+ /**
+ * Adds submenu page under 'Appearance' tab.
+ *
+ * This method adds the submenu page letting users know that a required
+ * plugin needs to be installed.
+ *
+ * This page disappears once the plugin has been installed and activated.
+ *
+ * @since 1.0.0
+ *
+ * @see TGM_Plugin_Activation::init()
+ * @see TGM_Plugin_Activation::install_plugins_page()
+ */
+ public function admin_menu() {
+
+ // Make sure privileges are correct to see the page
+ if ( ! current_user_can( 'install_plugins' ) )
+ return;
+
+ $this->populate_file_path();
+
+ foreach ( $this->plugins as $plugin ) {
+ if ( ! is_plugin_active( $plugin['file_path'] ) ) {
+ add_submenu_page(
+ $this->parent_menu_slug, // Parent menu slug
+ $this->strings['page_title'], // Page title
+ $this->strings['menu_title'], // Menu title
+ 'edit_theme_options', // Capability
+ $this->menu, // Menu slug
+ array( &$this, 'install_plugins_page' ) // Callback
+ );
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Echoes plugin installation form.
+ *
+ * This method is the callback for the admin_menu method function.
+ * This displays the admin page and form area where the user can select to install and activate the plugin.
+ *
+ * @since 1.0.0
+ *
+ * @return null Aborts early if we're processing a plugin installation action
+ */
+ public function install_plugins_page() {
+
+ /** Store new instance of plugin table in object */
+ $plugin_table = new TGMPA_List_Table;
+
+ /** Return early if processing a plugin installation action */
+ if ( isset( $_POST[sanitize_key( 'action' )] ) && 'tgmpa-bulk-install' == $_POST[sanitize_key( 'action' )] && $plugin_table->process_bulk_actions() || $this->do_plugin_install() )
+ return;
+
+ ?>
+
+
+
+
+ prepare_items(); ?>
+
+ message ) ) _e( wp_kses_post( $this->message ), $this->domain ); ?>
+
+
+
+
+ $this->menu,
+ 'plugin' => $plugin['slug'],
+ 'plugin_name' => $plugin['name'],
+ 'plugin_source' => $plugin['source'],
+ 'tgmpa-install' => 'install-plugin',
+ ),
+ admin_url( $this->parent_url_slug )
+ ),
+ 'tgmpa-install'
+ );
+ $method = ''; // Leave blank so WP_Filesystem can populate it as necessary
+ $fields = array( sanitize_key( 'tgmpa-install' ) ); // Extra fields to pass to WP_Filesystem
+
+ if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) )
+ return true;
+
+ if ( ! WP_Filesystem( $creds ) ) {
+ request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem
+ return true;
+ }
+
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes
+
+ /** Set plugin source to WordPress API link if available */
+ if ( isset( $plugin['source'] ) && 'repo' == $plugin['source'] ) {
+ $api = plugins_api( 'plugin_information', array( 'slug' => $plugin['slug'], 'fields' => array( 'sections' => false ) ) );
+
+ if ( is_wp_error( $api ) )
+ wp_die( $this->strings['oops'] . var_dump( $api ) );
+
+ if ( isset( $api->download_link ) )
+ $plugin['source'] = $api->download_link;
+ }
+
+ /** Set type, based on whether the source starts with http:// or https:// */
+ $type = preg_match( '|^http(s)?://|', $plugin['source'] ) ? 'web' : 'upload';
+
+ /** Prep variables for Plugin_Installer_Skin class */
+ $title = sprintf( $this->strings['installing'], $plugin['name'] );
+ $url = add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $plugin['slug'] ), 'update.php' );
+ if ( isset( $_GET['from'] ) )
+ $url .= add_query_arg( 'from', urlencode( stripslashes( $_GET['from'] ) ), $url );
+
+ $nonce = 'install-plugin_' . $plugin['slug'];
+
+ /** Prefix a default path to pre-packaged plugins */
+ $source = ( 'upload' == $type ) ? $this->default_path . $plugin['source'] : $plugin['source'];
+
+ /** Create a new instance of Plugin_Upgrader */
+ $upgrader = new Plugin_Upgrader( $skin = new Plugin_Installer_Skin( compact( 'type', 'title', 'url', 'nonce', 'plugin', 'api' ) ) );
+
+ /** Perform the action and install the plugin from the $source urldecode() */
+ $upgrader->install( $source );
+
+ /** Flush plugins cache so we can make sure that the installed plugins list is always up to date */
+ wp_cache_flush();
+
+ /** Only activate plugins if the config option is set to true */
+ if ( $this->is_automatic ) {
+ $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method
+ $activate = activate_plugin( $plugin_activate ); // Activate the plugin
+ $this->populate_file_path(); // Re-populate the file path now that the plugin has been installed and activated
+
+ if ( is_wp_error( $activate ) ) {
+ echo '' . $activate->get_error_message() . '
';
+ echo '' . __( 'Return to Required Plugins Installer', $this->domain ) . '
';
+ return true; // End it here if there is an error with automatic activation
+ }
+ else {
+ echo '' . $this->strings['plugin_activated'] . '
';
+ }
+ }
+
+ /** Display message based on if all plugins are now active or not */
+ $complete = array();
+ foreach ( $this->plugins as $plugin ) {
+ if ( ! is_plugin_active( $plugin['file_path'] ) ) {
+ echo '' . __( $this->strings['return'], $this->domain ) . '
';
+ $complete[] = $plugin;
+ break;
+ }
+ /** Nothing to store */
+ else {
+ $complete[] = '';
+ }
+ }
+
+ /** Filter out any empty entries */
+ $complete = array_filter( $complete );
+
+ /** All plugins are active, so we display the complete string and hide the plugin menu */
+ if ( empty( $complete ) ) {
+ echo '' . sprintf( $this->strings['complete'], '' . __( 'Return to the Dashboard', $this->domain ) . ' ' ) . '
';
+ echo '';
+ }
+
+ return true;
+ }
+ /** Checks for actions from hover links to process the activation */
+ elseif ( isset( $_GET[sanitize_key( 'plugin' )] ) && ( isset( $_GET[sanitize_key( 'tgmpa-activate' )] ) && 'activate-plugin' == $_GET[sanitize_key( 'tgmpa-activate' )] ) ) {
+ check_admin_referer( 'tgmpa-activate', 'tgmpa-activate-nonce' );
+
+ /** Populate $plugin array with necessary information */
+ $plugin['name'] = $_GET[sanitize_key( 'plugin_name' )];
+ $plugin['slug'] = $_GET[sanitize_key( 'plugin' )];
+ $plugin['source'] = $_GET[sanitize_key( 'plugin_source' )];
+
+ $plugin_data = get_plugins( '/' . $plugin['slug'] ); // Retrieve all plugins
+ $plugin_file = array_keys( $plugin_data ); // Retrieve all plugin files from installed plugins
+ $plugin_to_activate = $plugin['slug'] . '/' . $plugin_file[0]; // Match plugin slug with appropriate plugin file
+ $activate = activate_plugin( $plugin_to_activate ); // Activate the plugin
+
+ if ( is_wp_error( $activate ) ) {
+ echo '' . $activate->get_error_message() . '
';
+ echo '' . __( $this->strings['return'], $this->domain ) . '
';
+ return true; // End it here if there is an error with activation
+ }
+ else {
+ /** Make sure message doesn't display again if bulk activation is performed immediately after a single activation */
+ if ( ! isset( $_POST[sanitize_key( 'action' )] ) ) {
+ $msg = sprintf( __( 'The following plugin was activated successfully: %s.', $this->domain ), '' . $plugin['name'] . ' ' );
+ echo '';
+ }
+ }
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Echoes required plugin notice.
+ *
+ * Outputs a message telling users that a specific plugin is required for
+ * their theme. If appropriate, it includes a link to the form page where
+ * users can install and activate the plugin.
+ *
+ * @since 1.0.0
+ *
+ * @global object $current_screen
+ * @return null Returns early if we're on the Install page
+ */
+ public function notices() {
+
+ global $current_screen;
+
+ /** Remove nag on the install page */
+ if ( $this->is_tgmpa_page() )
+ return;
+
+ $installed_plugins = get_plugins(); // Retrieve a list of all the plugins
+ $this->populate_file_path();
+
+ $message = array(); // Store the messages in an array to be outputted after plugins have looped through
+ $install_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'install'
+ $install_link_count = 0; // Used to determine plurality of install action link text
+ $activate_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'activate'
+ $activate_link_count = 0; // Used to determine plurality of activate action link text
+
+ foreach ( $this->plugins as $plugin ) {
+ /** If the plugin is installed and active, check for minimum version argument before moving forward */
+ if ( is_plugin_active( $plugin['file_path'] ) ) {
+ /** A minimum version has been specified */
+ if ( isset( $plugin['version'] ) ) {
+ if ( isset( $installed_plugins[$plugin['file_path']]['Version'] ) ) {
+ /** If the current version is less than the minimum required version, we display a message */
+ if ( version_compare( $installed_plugins[$plugin['file_path']]['Version'], $plugin['version'], '<' ) ) {
+ if ( current_user_can( 'install_plugins' ) )
+ $message['notice_ask_to_update'][] = $plugin['name'];
+ else
+ $message['notice_cannot_update'][] = $plugin['name'];
+ }
+ }
+ /** Can't find the plugin, so iterate to the next condition */
+ else {
+ continue;
+ }
+ }
+ /** No minimum version specified, so iterate over the plugin */
+ else {
+ continue;
+ }
+ }
+
+ /** Not installed */
+ if ( ! isset( $installed_plugins[$plugin['file_path']] ) ) {
+ $install_link = true; // We need to display the 'install' action link
+ $install_link_count++; // Increment the install link count
+ if ( current_user_can( 'install_plugins' ) ) {
+ if ( $plugin['required'] )
+ $message['notice_can_install_required'][] = $plugin['name'];
+ /** This plugin is only recommended */
+ else
+ $message['notice_can_install_recommended'][] = $plugin['name'];
+ }
+ /** Need higher privileges to install the plugin */
+ else {
+ $message['notice_cannot_install'][] = $plugin['name'];
+ }
+ }
+ /** Installed but not active */
+ elseif ( is_plugin_inactive( $plugin['file_path'] ) ) {
+ $activate_link = true; // We need to display the 'activate' action link
+ $activate_link_count++; // Increment the activate link count
+ if ( current_user_can( 'activate_plugins' ) ) {
+ if ( ( isset( $plugin['required'] ) ) && ( $plugin['required'] ) )
+ $message['notice_can_activate_required'][] = $plugin['name'];
+ /** This plugin is only recommended */
+ else {
+ $message['notice_can_activate_recommended'][] = $plugin['name'];
+ }
+ }
+ /** Need higher privileges to activate the plugin */
+ else {
+ $message['notice_cannot_activate'][] = $plugin['name'];
+ }
+ }
+ }
+
+ /** Only process the nag messages if the user has not dismissed them already */
+ if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice', true ) ) {
+ /** If we have notices to display, we move forward */
+ if ( ! empty( $message ) ) {
+ krsort( $message ); // Sort messages
+ $rendered = ''; // Display all nag messages as strings
+
+ /** Grab all plugin names */
+ foreach ( $message as $type => $plugin_groups ) {
+ $linked_plugin_groups = array();
+
+ /** Count number of plugins in each message group to calculate singular/plural message */
+ $count = count( $plugin_groups );
+
+ /** Loop through the plugin names to make the ones pulled from the .org repo linked */
+ foreach ( $plugin_groups as $plugin_group_single_name ) {
+ $external_url = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'external_url' );
+ $source = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'source' );
+
+ if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) {
+ $linked_plugin_groups[] = '' . $plugin_group_single_name . ' ';
+ }
+ elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) {
+ $url = add_query_arg(
+ array(
+ 'tab' => 'plugin-information',
+ 'plugin' => $this->_get_plugin_data_from_name( $plugin_group_single_name ),
+ 'TB_iframe' => 'true',
+ 'width' => '640',
+ 'height' => '500',
+ ),
+ admin_url( 'plugin-install.php' )
+ );
+
+ $linked_plugin_groups[] = '' . $plugin_group_single_name . ' ';
+ }
+ else {
+ $linked_plugin_groups[] = $plugin_group_single_name; // No hyperlink
+ }
+
+ if ( isset( $linked_plugin_groups ) && (array) $linked_plugin_groups )
+ $plugin_groups = $linked_plugin_groups;
+ }
+
+ $last_plugin = array_pop( $plugin_groups ); // Pop off last name to prep for readability
+ $imploded = empty( $plugin_groups ) ? '' . $last_plugin . ' ' : '' . ( implode( ', ', $plugin_groups ) . ' and ' . $last_plugin . ' ' );
+
+ $rendered .= '' . sprintf( translate_nooped_plural( $this->strings[$type], $count, $this->domain ), $imploded, $count ) . '
'; // All messages now stored
+ }
+
+ /** Setup variables to determine if action links are needed */
+ $show_install_link = $install_link ? '' . translate_nooped_plural( $this->strings['install_link'], $install_link_count, $this->domain ) . ' ' : '';
+ $show_activate_link = $activate_link ? '' . translate_nooped_plural( $this->strings['activate_link'], $activate_link_count, $this->domain ) . ' ' : '';
+
+ /** Define all of the action links */
+ $action_links = apply_filters(
+ 'tgmpa_notice_action_links',
+ array(
+ 'install' => ( current_user_can( 'install_plugins' ) ) ? $show_install_link : '',
+ 'activate' => ( current_user_can( 'activate_plugins' ) ) ? $show_activate_link : '',
+ 'dismiss' => '' . __( 'Dismiss this notice', $this->domain ) . ' ',
+ )
+ );
+
+ $action_links = array_filter( $action_links ); // Remove any empty array items
+ if ( $action_links )
+ $rendered .= '' . implode( ' | ', $action_links ) . '
';
+
+ /** Register the nag messages and prepare them to be processed */
+ if ( isset( $this->strings['nag_type'] ) )
+ add_settings_error( 'tgmpa', 'tgmpa', $rendered, sanitize_html_class( strtolower( $this->strings['nag_type'] ), 'updated' ) );
+ else
+ add_settings_error( 'tgmpa', 'tgmpa', $rendered, 'updated' );
+ }
+ }
+
+ /** Admin options pages already output settings_errors, so this is to avoid duplication */
+ if ( 'options-general' !== $current_screen->parent_base )
+ settings_errors( 'tgmpa' );
+
+ }
+
+ /**
+ * Add dismissable admin notices.
+ *
+ * Appends a link to the admin nag messages. If clicked, the admin notice disappears and no longer is visible to users.
+ *
+ * @since 2.1.0
+ */
+ public function dismiss() {
+
+ if ( isset( $_GET[sanitize_key( 'tgmpa-dismiss' )] ) )
+ update_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice', 1 );
+
+ }
+
+ /**
+ * Add individual plugin to our collection of plugins.
+ *
+ * If the required keys are not set, the plugin is not added.
+ *
+ * @since 2.0.0
+ *
+ * @param array $plugin Array of plugin arguments.
+ */
+ public function register( $plugin ) {
+
+ if ( ! isset( $plugin['slug'] ) || ! isset( $plugin['name'] ) )
+ return;
+
+ $this->plugins[] = $plugin;
+
+ }
+
+ /**
+ * Amend default configuration settings.
+ *
+ * @since 2.0.0
+ *
+ * @param array $config
+ */
+ public function config( $config ) {
+
+ $keys = array( 'default_path', 'parent_menu_slug', 'parent_url_slug', 'domain', 'has_notices', 'menu', 'is_automatic', 'message', 'strings' );
+
+ foreach ( $keys as $key ) {
+ if ( isset( $config[$key] ) ) {
+ if ( is_array( $config[$key] ) ) {
+ foreach ( $config[$key] as $subkey => $value )
+ $this->{$key}[$subkey] = $value;
+ } else {
+ $this->$key = $config[$key];
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Amend action link after plugin installation.
+ *
+ * @since 2.0.0
+ *
+ * @param array $install_actions Existing array of actions
+ * @return array Amended array of actions
+ */
+ public function actions( $install_actions ) {
+
+ /** Remove action links on the TGMPA install page */
+ if ( $this->is_tgmpa_page() )
+ return false;
+
+ return $install_actions;
+
+ }
+
+ /**
+ * Set file_path key for each installed plugin.
+ *
+ * @since 2.1.0
+ */
+ public function populate_file_path() {
+
+ /** Add file_path key for all plugins */
+ foreach ( $this->plugins as $plugin => $values )
+ $this->plugins[$plugin]['file_path'] = $this->_get_plugin_basename_from_slug( $values['slug'] );
+
+ }
+
+ /**
+ * Helper function to extract the file path of the plugin file from the
+ * plugin slug, if the plugin is installed.
+ *
+ * @since 2.0.0
+ *
+ * @param string $slug Plugin slug (typically folder name) as provided by the developer
+ * @return string Either file path for plugin if installed, or just the plugin slug
+ */
+ protected function _get_plugin_basename_from_slug( $slug ) {
+
+ $keys = array_keys( get_plugins() );
+
+ foreach ( $keys as $key ) {
+ if ( preg_match( '|^' . $slug .'|', $key ) )
+ return $key;
+ }
+
+ return $slug;
+
+ }
+
+ /**
+ * Retrieve plugin data, given the plugin name.
+ *
+ * Loops through the registered plugins looking for $name. If it finds it,
+ * it returns the $data from that plugin. Otherwise, returns false.
+ *
+ * @since 2.1.0
+ *
+ * @param string $name Name of the plugin, as it was registered
+ * @param string $data Optional. Array key of plugin data to return. Default is slug
+ * @return string|boolean Plugin slug if found, false otherwise.
+ */
+ protected function _get_plugin_data_from_name( $name, $data = 'slug' ) {
+
+ foreach ( $this->plugins as $plugin => $values ) {
+ if ( $name == $values['name'] && isset( $values[$data] ) )
+ return $values[$data];
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Determine if we're on the TGMPA Install page.
+ *
+ * We use $current_screen when it is available, and a slightly less ideal
+ * conditional when it isn't (like when displaying the plugin information
+ * thickbox).
+ *
+ * @since 2.1.0
+ *
+ * @global object $current_screen
+ * @return boolean True when on the TGMPA page, false otherwise.
+ */
+ protected function is_tgmpa_page() {
+
+ global $current_screen;
+
+ if ( ! is_null( $current_screen ) && $this->parent_menu_slug == $current_screen->parent_file && isset( $_GET['page'] ) && $this->menu === $_GET['page'] )
+ return true;
+
+ if ( isset( $_GET['page'] ) && $this->menu === $_GET['page'] )
+ return true;
+
+ return false;
+
+ }
+
+ /**
+ * Delete dismissable nag option when theme is switched.
+ *
+ * This ensures that the user is again reminded via nag of required
+ * and/or recommended plugins if they re-activate the theme.
+ *
+ * @since 2.1.1
+ */
+ public function update_dismiss() {
+
+ delete_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice' );
+
+ }
+
+ /**
+ * Forces plugin activation if the parameter 'force_activation' is
+ * set to true.
+ *
+ * This allows theme authors to specify certain plugins that must be
+ * active at all times while using the current theme.
+ *
+ * Please take special care when using this parameter as it has the
+ * potential to be harmful if not used correctly. Setting this parameter
+ * to true will not allow the specified plugin to be deactivated unless
+ * the user switches themes.
+ *
+ * @since 2.2.0
+ */
+ public function force_activation() {
+
+ /** Set file_path parameter for any installed plugins */
+ $this->populate_file_path();
+
+ $installed_plugins = get_plugins();
+
+ foreach ( $this->plugins as $plugin ) {
+ /** Oops, plugin isn't there so iterate to next condition */
+ if ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && ! isset( $installed_plugins[$plugin['file_path']] ) )
+ continue;
+ /** There we go, activate the plugin */
+ elseif ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && is_plugin_inactive( $plugin['file_path'] ) )
+ activate_plugin( $plugin['file_path'] );
+ }
+
+ }
+
+ /**
+ * Forces plugin deactivation if the parameter 'force_deactivation'
+ * is set to true.
+ *
+ * This allows theme authors to specify certain plugins that must be
+ * deactived upon switching from the current theme to another.
+ *
+ * Please take special care when using this parameter as it has the
+ * potential to be harmful if not used correctly.
+ *
+ * @since 2.2.0
+ */
+ public function force_deactivation() {
+
+ /** Set file_path parameter for any installed plugins */
+ $this->populate_file_path();
+
+ foreach ( $this->plugins as $plugin ) {
+ /** Only proceed forward if the paramter is set to true and plugin is active */
+ if ( isset( $plugin['force_deactivation'] ) && $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) )
+ deactivate_plugins( $plugin['file_path'] );
+ }
+
+ }
+
+ }
+}
+
+/** Create a new instance of the class */
+new TGM_Plugin_Activation;
+
+if ( ! function_exists( 'tgmpa' ) ) {
+ /**
+ * Helper function to register a collection of required plugins.
+ *
+ * @since 2.0.0
+ * @api
+ *
+ * @param array $plugins An array of plugin arrays
+ * @param array $config Optional. An array of configuration values
+ */
+ function tgmpa( $plugins, $config = array() ) {
+
+ foreach ( $plugins as $plugin )
+ TGM_Plugin_Activation::$instance->register( $plugin );
+
+ if ( $config )
+ TGM_Plugin_Activation::$instance->config( $config );
+
+ }
+}
+
+/**
+ * WP_List_Table isn't always available. If it isn't available,
+ * we load it here.
+ *
+ * @since 2.2.0
+ */
+if ( ! class_exists( 'WP_List_Table' ) )
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
+
+if ( ! class_exists( 'TGMPA_List_Table' ) ) {
+ /**
+ * List table class for handling plugins.
+ *
+ * Extends the WP_List_Table class to provide a future-compatible
+ * way of listing out all required/recommended plugins.
+ *
+ * Gives users an interface similar to the Plugin Administration
+ * area with similar (albeit stripped down) capabilities.
+ *
+ * This class also allows for the bulk install of plugins.
+ *
+ * @since 2.2.0
+ *
+ * @package TGM-Plugin-Activation
+ * @author Thomas Griffin
+ * @author Gary Jones
+ */
+ class TGMPA_List_Table extends WP_List_Table {
+
+ /**
+ * References parent constructor and sets defaults for class.
+ *
+ * The constructor also grabs a copy of $instance from the TGMPA class
+ * and stores it in the global object TGM_Plugin_Activation::$instance.
+ *
+ * @since 2.2.0
+ *
+ * @global unknown $status
+ * @global string $page
+ */
+ public function __construct() {
+
+ global $status, $page;
+
+ parent::__construct(
+ array(
+ 'singular' => 'plugin',
+ 'plural' => 'plugins',
+ 'ajax' => false,
+ )
+ );
+
+ }
+
+ /**
+ * Gathers and renames all of our plugin information to be used by
+ * WP_List_Table to create our table.
+ *
+ * @since 2.2.0
+ *
+ * @return array $table_data Information for use in table
+ */
+ protected function _gather_plugin_data() {
+
+ /** Load thickbox for plugin links */
+ TGM_Plugin_Activation::$instance->admin_init();
+ TGM_Plugin_Activation::$instance->thickbox();
+
+ /** Prep variables for use and grab list of all installed plugins */
+ $table_data = array();
+ $i = 0;
+ $installed_plugins = get_plugins();
+
+ foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) {
+ if ( is_plugin_active( $plugin['file_path'] ) )
+ continue; // No need to display plugins if they are installed and activated
+
+ $table_data[$i]['sanitized_plugin'] = $plugin['name'];
+ $table_data[$i]['slug'] = $this->_get_plugin_data_from_name( $plugin['name'] );
+
+ $external_url = $this->_get_plugin_data_from_name( $plugin['name'], 'external_url' );
+ $source = $this->_get_plugin_data_from_name( $plugin['name'], 'source' );
+
+ if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) {
+ $table_data[$i]['plugin'] = '' . $plugin['name'] . ' ';
+ }
+ elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) {
+ $url = add_query_arg(
+ array(
+ 'tab' => 'plugin-information',
+ 'plugin' => $this->_get_plugin_data_from_name( $plugin['name'] ),
+ 'TB_iframe' => 'true',
+ 'width' => '640',
+ 'height' => '500',
+ ),
+ admin_url( 'plugin-install.php' )
+ );
+
+ $table_data[$i]['plugin'] = '' . $plugin['name'] . ' ';
+ }
+ else {
+ $table_data[$i]['plugin'] = '' . $plugin['name'] . ' '; // No hyperlink
+ }
+
+ if ( isset( $table_data[$i]['plugin'] ) && (array) $table_data[$i]['plugin'] )
+ $plugin['name'] = $table_data[$i]['plugin'];
+
+ if ( isset( $plugin['external_url'] ) ) {
+ /** The plugin is linked to an external source */
+ $table_data[$i]['source'] = __( 'External Link', TGM_Plugin_Activation::$instance->domain );
+ }
+ elseif ( isset( $plugin['source'] ) ) {
+ /** The plugin must be from a private repository */
+ if ( preg_match( '|^http(s)?://|', $plugin['source'] ) )
+ $table_data[$i]['source'] = __( 'Private Repository', TGM_Plugin_Activation::$instance->domain );
+ /** The plugin is pre-packaged with the theme */
+ else
+ $table_data[$i]['source'] = __( 'Pre-Packaged', TGM_Plugin_Activation::$instance->domain );
+ }
+ /** The plugin is from the WordPress repository */
+ else {
+ $table_data[$i]['source'] = __( 'WordPress Repository', TGM_Plugin_Activation::$instance->domain );
+ }
+
+ $table_data[$i]['type'] = $plugin['required'] ? __( 'Required', TGM_Plugin_Activation::$instance->domain ) : __( 'Recommended', TGM_Plugin_Activation::$instance->domain );
+
+ if ( ! isset( $installed_plugins[$plugin['file_path']] ) )
+ $table_data[$i]['status'] = sprintf( '%1$s', __( 'Not Installed', TGM_Plugin_Activation::$instance->domain ) );
+ elseif ( is_plugin_inactive( $plugin['file_path'] ) )
+ $table_data[$i]['status'] = sprintf( '%1$s', __( 'Installed But Not Activated', TGM_Plugin_Activation::$instance->domain ) );
+
+ $table_data[$i]['file_path'] = $plugin['file_path'];
+ $table_data[$i]['url'] = isset( $plugin['source'] ) ? $plugin['source'] : 'repo';
+
+ $i++;
+ }
+
+ /** Sort plugins by Required/Recommended type and by alphabetical listing within each type */
+ $resort = array();
+ $req = array();
+ $rec = array();
+
+ /** Grab all the plugin types */
+ foreach ( $table_data as $plugin )
+ $resort[] = $plugin['type'];
+
+ /** Sort each plugin by type */
+ foreach ( $resort as $type )
+ if ( 'Required' == $type )
+ $req[] = $type;
+ else
+ $rec[] = $type;
+
+ /** Sort alphabetically each plugin type array, merge them and then sort in reverse (lists Required plugins first) */
+ sort( $req );
+ sort( $rec );
+ array_merge( $resort, $req, $rec );
+ array_multisort( $resort, SORT_DESC, $table_data );
+
+ return $table_data;
+
+ }
+
+ /**
+ * Retrieve plugin data, given the plugin name. Taken from the
+ * TGM_Plugin_Activation class.
+ *
+ * Loops through the registered plugins looking for $name. If it finds it,
+ * it returns the $data from that plugin. Otherwise, returns false.
+ *
+ * @since 2.2.0
+ *
+ * @param string $name Name of the plugin, as it was registered
+ * @param string $data Optional. Array key of plugin data to return. Default is slug
+ * @return string|boolean Plugin slug if found, false otherwise
+ */
+ protected function _get_plugin_data_from_name( $name, $data = 'slug' ) {
+
+ foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin => $values ) {
+ if ( $name == $values['name'] && isset( $values[$data] ) )
+ return $values[$data];
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Create default columns to display important plugin information
+ * like type, action and status.
+ *
+ * @since 2.2.0
+ *
+ * @param array $item
+ * @param string $column_name
+ */
+ public function column_default( $item, $column_name ) {
+
+ switch ( $column_name ) {
+ case 'source':
+ case 'type':
+ case 'status':
+ return $item[$column_name];
+ }
+
+ }
+
+ /**
+ * Create default title column along with action links of 'Install'
+ * and 'Activate'.
+ *
+ * @since 2.2.0
+ *
+ * @param array $item
+ * @return string The action hover links
+ */
+ public function column_plugin( $item ) {
+
+ $installed_plugins = get_plugins();
+
+ /** No need to display any hover links */
+ if ( is_plugin_active( $item['file_path'] ) )
+ $actions = array();
+
+ /** We need to display the 'Install' hover link */
+ if ( ! isset( $installed_plugins[$item['file_path']] ) ) {
+ $actions = array(
+ 'install' => sprintf(
+ 'Install ',
+ wp_nonce_url(
+ add_query_arg(
+ array(
+ 'page' => TGM_Plugin_Activation::$instance->menu,
+ 'plugin' => $item['slug'],
+ 'plugin_name' => $item['sanitized_plugin'],
+ 'plugin_source' => $item['url'],
+ 'tgmpa-install' => 'install-plugin',
+ ),
+ admin_url( TGM_Plugin_Activation::$instance->parent_url_slug )
+ ),
+ 'tgmpa-install'
+ ),
+ $item['sanitized_plugin']
+ ),
+ );
+ }
+ /** We need to display the 'Activate' hover link */
+ elseif ( is_plugin_inactive( $item['file_path'] ) ) {
+ $actions = array(
+ 'activate' => sprintf(
+ 'Activate ',
+ add_query_arg(
+ array(
+ 'page' => TGM_Plugin_Activation::$instance->menu,
+ 'plugin' => $item['slug'],
+ 'plugin_name' => $item['sanitized_plugin'],
+ 'plugin_source' => $item['url'],
+ 'tgmpa-activate' => 'activate-plugin',
+ 'tgmpa-activate-nonce' => wp_create_nonce( 'tgmpa-activate' ),
+ ),
+ admin_url( TGM_Plugin_Activation::$instance->parent_url_slug )
+ ),
+ $item['sanitized_plugin']
+ ),
+ );
+ }
+
+ return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $actions ) );
+
+ }
+
+ /**
+ * Required for bulk installing.
+ *
+ * Adds a checkbox for each plugin.
+ *
+ * @since 2.2.0
+ *
+ * @param array $item
+ * @return string The input checkbox with all necessary info
+ */
+ public function column_cb( $item ) {
+
+ $value = $item['file_path'] . ',' . $item['url'] . ',' . $item['sanitized_plugin'];
+ return sprintf( ' ', $this->_args['singular'], $value, $item['sanitized_plugin'] );
+
+ }
+
+ /**
+ * Sets default message within the plugins table if no plugins
+ * are left for interaction.
+ *
+ * Hides the menu item to prevent the user from clicking and
+ * getting a permissions error.
+ *
+ * @since 2.2.0
+ */
+ public function no_items() {
+
+ printf( __( 'No plugins to install or activate. Return to the Dashboard ', TGM_Plugin_Activation::$instance->domain ), admin_url() );
+ echo '';
+
+ }
+
+ /**
+ * Output all the column information within the table.
+ *
+ * @since 2.2.0
+ *
+ * @return array $columns The column names
+ */
+ public function get_columns() {
+
+ $columns = array(
+ 'cb' => ' ',
+ 'plugin' => __( 'Plugin', TGM_Plugin_Activation::$instance->domain ),
+ 'source' => __( 'Source', TGM_Plugin_Activation::$instance->domain ),
+ 'type' => __( 'Type', TGM_Plugin_Activation::$instance->domain ),
+ 'status' => __( 'Status', TGM_Plugin_Activation::$instance->domain )
+ );
+
+ return $columns;
+
+ }
+
+ /**
+ * Defines all types of bulk actions for handling
+ * registered plugins.
+ *
+ * @since 2.2.0
+ *
+ * @return array $actions The bulk actions for the plugin install table
+ */
+ public function get_bulk_actions() {
+
+ $actions = array(
+ 'tgmpa-bulk-install' => __( 'Install', TGM_Plugin_Activation::$instance->domain ),
+ 'tgmpa-bulk-activate' => __( 'Activate', TGM_Plugin_Activation::$instance->domain ),
+ );
+
+ return $actions;
+
+ }
+
+ /**
+ * Processes bulk installation and activation actions.
+ *
+ * The bulk installation process looks either for the $_POST
+ * information or for the plugin info within the $_GET variable if
+ * a user has to use WP_Filesystem to enter their credentials.
+ *
+ * @since 2.2.0
+ */
+ public function process_bulk_actions() {
+
+ /** Bulk installation process */
+ if ( 'tgmpa-bulk-install' === $this->current_action() ) {
+ check_admin_referer( 'bulk-' . $this->_args['plural'] );
+
+ /** Prep variables to be populated */
+ $plugins_to_install = array();
+ $plugin_installs = array();
+ $plugin_path = array();
+ $plugin_name = array();
+
+ /** Look first to see if information has been passed via WP_Filesystem */
+ if ( isset( $_GET[sanitize_key( 'plugins' )] ) )
+ $plugins = explode( ',', stripslashes( $_GET[sanitize_key( 'plugins' )] ) );
+ /** Looks like the user can use the direct method, take from $_POST */
+ elseif ( isset( $_POST[sanitize_key( 'plugin' )] ) )
+ $plugins = (array) $_POST[sanitize_key( 'plugin' )];
+ /** Nothing has been submitted */
+ else
+ $plugins = array();
+
+ $a = 0; // Incremental variable
+
+ /** Grab information from $_POST if available */
+ if ( isset( $_POST[sanitize_key( 'plugin' )] ) ) {
+ foreach ( $plugins as $plugin_data )
+ $plugins_to_install[] = explode( ',', $plugin_data );
+
+ foreach ( $plugins_to_install as $plugin_data ) {
+ $plugin_installs[] = $plugin_data[0];
+ $plugin_path[] = $plugin_data[1];
+ $plugin_name[] = $plugin_data[2];
+ }
+ }
+ /** Information has been passed via $_GET */
+ else {
+ foreach ( $plugins as $key => $value ) {
+ /** Grab plugin slug for each plugin */
+ if ( 0 == $key % 3 || 0 == $key ) {
+ $plugins_to_install[] = $value;
+ $plugin_installs[] = $value;
+ }
+ $a++;
+ }
+ }
+
+ /** Look first to see if information has been passed via WP_Filesystem */
+ if ( isset( $_GET[sanitize_key( 'plugin_paths' )] ) )
+ $plugin_paths = explode( ',', stripslashes( $_GET[sanitize_key( 'plugin_paths' )] ) );
+ /** Looks like the user doesn't need to enter his FTP creds */
+ elseif ( isset( $_POST[sanitize_key( 'plugin' )] ) )
+ $plugin_paths = (array) $plugin_path;
+ /** Nothing has been submitted */
+ else
+ $plugin_paths = array();
+
+ /** Look first to see if information has been passed via WP_Filesystem */
+ if ( isset( $_GET[sanitize_key( 'plugin_names' )] ) )
+ $plugin_names = explode( ',', stripslashes( $_GET[sanitize_key( 'plugin_names' )] ) );
+ /** Looks like the user doesn't need to enter his FTP creds */
+ elseif ( isset( $_POST[sanitize_key( 'plugin' )] ) )
+ $plugin_names = (array) $plugin_name;
+ /** Nothing has been submitted */
+ else
+ $plugin_names = array();
+
+ $b = 0; // Incremental variable
+
+ /** Loop through plugin slugs and remove already installed plugins from the list */
+ foreach ( $plugin_installs as $key => $plugin ) {
+ if ( preg_match( '|.php$|', $plugin ) ) {
+ unset( $plugin_installs[$key] );
+
+ /** If the plugin path isn't in the $_GET variable, we can unset the corresponding path */
+ if ( ! isset( $_GET[sanitize_key( 'plugin_paths' )] ) )
+ unset( $plugin_paths[$b] );
+
+ /** If the plugin name isn't in the $_GET variable, we can unset the corresponding name */
+ if ( ! isset( $_GET[sanitize_key( 'plugin_names' )] ) )
+ unset( $plugin_names[$b] );
+ }
+ $b++;
+ }
+
+ /** No need to proceed further if we have no plugins to install */
+ if ( empty( $plugin_installs ) )
+ return false;
+
+ /** Reset array indexes in case we removed already installed plugins */
+ $plugin_installs = array_values( $plugin_installs );
+ $plugin_paths = array_values( $plugin_paths );
+ $plugin_names = array_values( $plugin_names );
+
+ /** If we grabbed our plugin info from $_GET, we need to decode it for use */
+ $plugin_installs = array_map( 'urldecode', $plugin_installs );
+ $plugin_paths = array_map( 'urldecode', $plugin_paths );
+ $plugin_names = array_map( 'urldecode', $plugin_names );
+
+ /** Pass all necessary information via URL if WP_Filesystem is needed */
+ $url = wp_nonce_url(
+ add_query_arg(
+ array(
+ 'page' => TGM_Plugin_Activation::$instance->menu,
+ 'tgmpa-action' => 'install-selected',
+ 'plugins' => urlencode( implode( ',', $plugins ) ),
+ 'plugin_paths' => urlencode( implode( ',', $plugin_paths ) ),
+ 'plugin_names' => urlencode( implode( ',', $plugin_names ) ),
+ ),
+ admin_url( TGM_Plugin_Activation::$instance->parent_url_slug )
+ ),
+ 'bulk-plugins'
+ );
+ $method = ''; // Leave blank so WP_Filesystem can populate it as necessary
+ $fields = array( sanitize_key( 'action' ), sanitize_key( '_wp_http_referer' ), sanitize_key( '_wpnonce' ) ); // Extra fields to pass to WP_Filesystem
+
+ if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) )
+ return true;
+
+ if ( ! WP_Filesystem( $creds ) ) {
+ request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem
+ return true;
+ }
+
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes
+
+ /** Store all information in arrays since we are processing a bulk installation */
+ $api = array();
+ $sources = array();
+ $install_path = array();
+
+ $c = 0; // Incremental variable
+
+ /** Loop through each plugin to install and try to grab information from WordPress API, if not create 'tgmpa-empty' scalar */
+ foreach ( $plugin_installs as $plugin ) {
+ $api[$c] = plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) ? plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) : (object) $api[$c] = 'tgmpa-empty';
+ $c++;
+ }
+
+ if ( is_wp_error( $api ) )
+ wp_die( TGM_Plugin_Activation::$instance->strings['oops'] . var_dump( $api ) );
+
+ $d = 0; // Incremental variable
+
+ /** Capture download links from $api or set install link to pre-packaged/private repo */
+ foreach ( $api as $object ) {
+ $sources[$d] = isset( $object->download_link ) && 'repo' == $plugin_paths[$d] ? $object->download_link : $plugin_paths[$d];
+ $d++;
+ }
+
+ /** Finally, all the data is prepared to be sent to the installer */
+ $url = add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu ), admin_url( TGM_Plugin_Activation::$instance->parent_url_slug ) );
+ $nonce = 'bulk-plugins';
+ $names = $plugin_names;
+
+ /** Create a new instance of TGM_Bulk_Installer */
+ $installer = new TGM_Bulk_Installer( $skin = new TGM_Bulk_Installer_Skin( compact( 'url', 'nonce', 'names' ) ) );
+
+ /** Wrap the install process with the appropriate HTML */
+ echo '';
+ screen_icon( apply_filters( 'tgmpa_default_screen_icon', 'themes' ) );
+ echo '
' . esc_html( get_admin_page_title() ) . ' ';
+ /** Process the bulk installation submissions */
+ $installer->bulk_install( $sources );
+ echo '';
+
+ return true;
+ }
+
+ /** Bulk activation process */
+ if ( 'tgmpa-bulk-activate' === $this->current_action() ) {
+ check_admin_referer( 'bulk-' . $this->_args['plural'] );
+
+ /** Grab plugin data from $_POST */
+ $plugins = isset( $_POST[sanitize_key( 'plugin' )] ) ? (array) $_POST[sanitize_key( 'plugin' )] : array();
+ $plugins_to_activate = array();
+
+ /** Split plugin value into array with plugin file path, plugin source and plugin name */
+ foreach ( $plugins as $i => $plugin )
+ $plugins_to_activate[] = explode( ',', $plugin );
+
+ foreach ( $plugins_to_activate as $i => $array ) {
+ if ( ! preg_match( '|.php$|', $array[0] ) ) // Plugins that haven't been installed yet won't have the correct file path
+ unset( $plugins_to_activate[$i] );
+ }
+
+ /** Return early if there are no plugins to activate */
+ if ( empty( $plugins_to_activate ) )
+ return;
+
+ $plugins = array();
+ $plugin_names = array();
+
+ foreach ( $plugins_to_activate as $plugin_string ) {
+ $plugins[] = $plugin_string[0];
+ $plugin_names[] = $plugin_string[2];
+ }
+
+ $count = count( $plugin_names ); // Count so we can use _n function
+ $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability
+ $imploded = empty( $plugin_names ) ? '' . $last_plugin . ' ' : '' . ( implode( ', ', $plugin_names ) . ' and ' . $last_plugin . ' .' );
+
+ /** Now we are good to go - let's start activating plugins */
+ $activate = activate_plugins( $plugins );
+
+ if ( is_wp_error( $activate ) )
+ echo '' . $activate->get_error_message() . '
';
+ else
+ printf( '', _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, TGM_Plugin_Activation::$instance->domain ), $imploded );
+
+ /** Update recently activated plugins option */
+ $recent = (array) get_option( 'recently_activated' );
+
+ foreach ( $plugins as $plugin => $time )
+ if ( isset( $recent[$plugin] ) )
+ unset( $recent[$plugin] );
+
+ update_option( 'recently_activated', $recent );
+
+ unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another
+ }
+ }
+
+ /**
+ * Prepares all of our information to be outputted into a usable table.
+ *
+ * @since 2.2.0
+ */
+ public function prepare_items() {
+
+ $per_page = 100; // Set it high so we shouldn't have to worry about pagination
+ $columns = $this->get_columns(); // Get all necessary column information
+ $hidden = array(); // No columns to hide, but we must set as an array
+ $sortable = array(); // No reason to make sortable columns
+ $this->_column_headers = array( $columns, $hidden, $sortable ); // Get all necessary column headers
+
+ /** Process our bulk actions here */
+ $this->process_bulk_actions();
+
+ /** Store all of our plugin data into $items array so WP_List_Table can use it */
+ $this->items = $this->_gather_plugin_data();
+
+ }
+
+ }
+}
+
+/**
+ * The WP_Upgrader file isn't always available. If it isn't available,
+ * we load it here.
+ *
+ * We check to make sure no action or activation keys are set so that WordPress
+ * doesn't try to re-include the class when processing upgrades or installs outside
+ * of the class.
+ *
+ * @since 2.2.0
+ */
+if ( ! class_exists( 'WP_Upgrader' ) && ( isset( $_GET[sanitize_key( 'page' )] ) && TGM_Plugin_Activation::$instance->menu = $_GET[sanitize_key( 'page' )] ) ) {
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+
+ if ( ! class_exists( 'TGM_Bulk_Installer' ) ) {
+ /**
+ * Installer class to handle bulk plugin installations.
+ *
+ * Extends WP_Upgrader and customizes to suit the installation of multiple
+ * plugins.
+ *
+ * @since 2.2.0
+ *
+ * @package TGM-Plugin-Activation
+ * @author Thomas Griffin
+ * @author Gary Jones
+ */
+ class TGM_Bulk_Installer extends WP_Upgrader {
+
+ /**
+ * Holds result of bulk plugin installation.
+ *
+ * @since 2.2.0
+ *
+ * @var string
+ */
+ public $result;
+
+ /**
+ * Flag to check if bulk installation is occurring or not.
+ *
+ * @since 2.2.0
+ *
+ * @var boolean
+ */
+ public $bulk = false;
+
+ /**
+ * Processes the bulk installation of plugins.
+ *
+ * @since 2.2.0
+ *
+ * @param array $packages The plugin sources needed for installation
+ * @return string|boolean Install confirmation messages on success, false on failure
+ */
+ public function bulk_install( $packages ) {
+
+ /** Pass installer skin object and set bulk property to true */
+ $this->init();
+ $this->bulk = true;
+
+ /** Set install strings and automatic activation strings (if config option is set to true) */
+ $this->install_strings();
+ if ( TGM_Plugin_Activation::$instance->is_automatic )
+ $this->activate_strings();
+
+ /** Run the header string to notify user that the process has begun */
+ $this->skin->header();
+
+ /** Connect to the Filesystem */
+ $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
+ if ( ! $res ) {
+ $this->skin->footer();
+ return false;
+ }
+
+ /** Set the bulk header and prepare results array */
+ $this->skin->bulk_header();
+ $results = array();
+
+ /** Get the total number of packages being processed and iterate as each package is successfully installed */
+ $this->update_count = count( $packages );
+ $this->update_current = 0;
+
+ /** Loop through each plugin and process the installation */
+ foreach ( $packages as $plugin ) {
+ $this->update_current++; // Increment counter
+
+ /** Do the plugin install */
+ $result = $this->run(
+ array(
+ 'package' => $plugin, // The plugin source
+ 'destination' => WP_PLUGIN_DIR, // The destination dir
+ 'clear_destination' => false, // Do we want to clear the destination or not?
+ 'clear_working' => true, // Remove original install file
+ 'is_multi' => true, // Are we processing multiple installs?
+ 'hook_extra' => array( 'plugin' => $plugin, ), // Pass plugin source as extra data
+ )
+ );
+
+ /** Store installation results in result property */
+ $results[$plugin] = $this->result;
+
+ /** Prevent credentials auth screen from displaying multiple times */
+ if ( false === $result )
+ break;
+ }
+
+ /** Pass footer skin strings */
+ $this->skin->bulk_footer();
+ $this->skin->footer();
+
+ /** Return our results */
+ return $results;
+
+ }
+
+ /**
+ * Performs the actual installation of each plugin.
+ *
+ * This method also activates the plugin in the automatic flag has been
+ * set to true for the TGMPA class.
+ *
+ * @since 2.2.0
+ *
+ * @param array $options The installation cofig options
+ * @return null/array Return early if error, array of installation data on success
+ */
+ public function run( $options ) {
+
+ /** Default config options */
+ $defaults = array(
+ 'package' => '',
+ 'destination' => '',
+ 'clear_destination' => false,
+ 'clear_working' => true,
+ 'is_multi' => false,
+ 'hook_extra' => array(),
+ );
+
+ /** Parse default options with config options from $this->bulk_upgrade and extract them */
+ $options = wp_parse_args( $options, $defaults );
+ extract( $options );
+
+ /** Connect to the Filesystem */
+ $res = $this->fs_connect( array( WP_CONTENT_DIR, $destination ) );
+ if ( ! $res )
+ return false;
+
+ /** Return early if there is an error connecting to the Filesystem */
+ if ( is_wp_error( $res ) ) {
+ $this->skin->error( $res );
+ return $res;
+ }
+
+ /** Call $this->header separately if running multiple times */
+ if ( ! $is_multi )
+ $this->skin->header();
+
+ /** Set strings before the package is installed */
+ $this->skin->before();
+
+ /** Download the package (this just returns the filename of the file if the package is a local file) */
+ $download = $this->download_package( $package );
+ if ( is_wp_error( $download ) ) {
+ $this->skin->error( $download );
+ $this->skin->after();
+ return $download;
+ }
+
+ /** Don't accidentally delete a local file */
+ $delete_package = ( $download != $package );
+
+ /** Unzip file into a temporary working directory */
+ $working_dir = $this->unpack_package( $download, $delete_package );
+ if ( is_wp_error( $working_dir ) ) {
+ $this->skin->error( $working_dir );
+ $this->skin->after();
+ return $working_dir;
+ }
+
+ /** Install the package into the working directory with all passed config options */
+ $result = $this->install_package(
+ array(
+ 'source' => $working_dir,
+ 'destination' => $destination,
+ 'clear_destination' => $clear_destination,
+ 'clear_working' => $clear_working,
+ 'hook_extra' => $hook_extra,
+ )
+ );
+
+ /** Pass the result of the installation */
+ $this->skin->set_result( $result );
+
+ /** Set correct strings based on results */
+ if ( is_wp_error( $result ) ) {
+ $this->skin->error( $result );
+ $this->skin->feedback( 'process_failed' );
+ }
+ /** The plugin install is successful */
+ else {
+ $this->skin->feedback( 'process_success' );
+ }
+
+ /** Only process the activation of installed plugins if the automatic flag is set to true */
+ if ( TGM_Plugin_Activation::$instance->is_automatic ) {
+ /** Flush plugins cache so we can make sure that the installed plugins list is always up to date */
+ wp_cache_flush();
+
+ /** Get the installed plugin file and activate it */
+ $plugin_info = $this->plugin_info( $package );
+ $activate = activate_plugin( $plugin_info );
+
+ /** Re-populate the file path now that the plugin has been installed and activated */
+ TGM_Plugin_Activation::$instance->populate_file_path();
+
+ /** Set correct strings based on results */
+ if ( is_wp_error( $activate ) ) {
+ $this->skin->error( $activate );
+ $this->skin->feedback( 'activation_failed' );
+ }
+ /** The plugin activation is successful */
+ else {
+ $this->skin->feedback( 'activation_success' );
+ }
+ }
+
+ /** Flush plugins cache so we can make sure that the installed plugins list is always up to date */
+ wp_cache_flush();
+
+ /** Set install footer strings */
+ $this->skin->after();
+ if ( ! $is_multi )
+ $this->skin->footer();
+
+ return $result;
+
+ }
+
+ /**
+ * Sets the correct install strings for the installer skin to use.
+ *
+ * @since 2.2.0
+ */
+ public function install_strings() {
+
+ $this->strings['no_package'] = __( 'Install package not available.', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['downloading_package'] = __( 'Downloading install package from %s …', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['unpack_package'] = __( 'Unpacking the package…', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['installing_package'] = __( 'Installing the plugin…', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['process_failed'] = __( 'Plugin install failed.', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['process_success'] = __( 'Plugin installed successfully.', TGM_Plugin_Activation::$instance->domain );
+
+ }
+
+ /**
+ * Sets the correct activation strings for the installer skin to use.
+ *
+ * @since 2.2.0
+ */
+ public function activate_strings() {
+
+ $this->strings['activation_failed'] = __( 'Plugin activation failed.', TGM_Plugin_Activation::$instance->domain );
+ $this->strings['activation_success'] = __( 'Plugin activated successfully.', TGM_Plugin_Activation::$instance->domain );
+
+ }
+
+ /**
+ * Grabs the plugin file from an installed plugin.
+ *
+ * @since 2.2.0
+ *
+ * @return string|boolean Return plugin file on success, false on failure
+ */
+ public function plugin_info() {
+
+ /** Return false if installation result isn't an array or the destination name isn't set */
+ if ( ! is_array( $this->result ) )
+ return false;
+ if ( empty( $this->result['destination_name'] ) )
+ return false;
+
+ /** Get the installed plugin file or return false if it isn't set */
+ $plugin = get_plugins( '/' . $this->result['destination_name'] );
+ if ( empty( $plugin ) )
+ return false;
+
+ /** Assume the requested plugin is the first in the list */
+ $pluginfiles = array_keys( $plugin );
+
+ return $this->result['destination_name'] . '/' . $pluginfiles[0];
+
+ }
+
+ }
+ }
+
+ if ( ! class_exists( 'TGM_Bulk_Installer_Skin' ) ) {
+ /**
+ * Installer skin to set strings for the bulk plugin installations..
+ *
+ * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple
+ * plugins.
+ *
+ * @since 2.2.0
+ *
+ * @package TGM-Plugin-Activation
+ * @author Thomas Griffin
+ * @author Gary Jones
+ */
+ class TGM_Bulk_Installer_Skin extends Bulk_Upgrader_Skin {
+
+ /**
+ * Holds plugin info for each individual plugin installation.
+ *
+ * @since 2.2.0
+ *
+ * @var array
+ */
+ public $plugin_info = array();
+
+ /**
+ * Holds names of plugins that are undergoing bulk installations.
+ *
+ * @since 2.2.0
+ *
+ * @var array
+ */
+ public $plugin_names = array();
+
+ /**
+ * Integer to use for iteration through each plugin installation.
+ *
+ * @since 2.2.0
+ *
+ * @var integer
+ */
+ public $i = 0;
+
+ /**
+ * Constructor. Parses default args with new ones and extracts them for use.
+ *
+ * @since 2.2.0
+ *
+ * @param array $args Arguments to pass for use within the class
+ */
+ public function __construct( $args = array() ) {
+
+ /** Parse default and new args */
+ $defaults = array( 'url' => '', 'nonce' => '', 'names' => array() );
+ $args = wp_parse_args( $args, $defaults );
+
+ /** Set plugin names to $this->plugin_names property */
+ $this->plugin_names = $args['names'];
+
+ /** Extract the new args */
+ parent::__construct( $args );
+
+ }
+
+ /**
+ * Sets install skin strings for each individual plugin.
+ *
+ * Checks to see if the automatic activation flag is set and uses the
+ * the proper strings accordingly.
+ *
+ * @since 2.2.0
+ */
+ public function add_strings() {
+
+ /** Automatic activation strings */
+ if ( TGM_Plugin_Activation::$instance->is_automatic ) {
+ $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', TGM_Plugin_Activation::$instance->domain ) . ' ' . __( 'Show Details', TGM_Plugin_Activation::$instance->domain ) . ' ' . __( 'Hide Details', TGM_Plugin_Activation::$instance->domain ) . ' . ';
+ $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', TGM_Plugin_Activation::$instance->domain );
+ }
+ /** Default installation strings */
+ else {
+ $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s .', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed successfully.', TGM_Plugin_Activation::$instance->domain ) . ' ' . __( 'Show Details', TGM_Plugin_Activation::$instance->domain ) . ' ' . __( 'Hide Details', TGM_Plugin_Activation::$instance->domain ) . ' . ';
+ $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', TGM_Plugin_Activation::$instance->domain );
+ $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', TGM_Plugin_Activation::$instance->domain );
+ }
+
+ }
+
+ /**
+ * Outputs the header strings and necessary JS before each plugin installation.
+ *
+ * @since 2.2.0
+ */
+ public function before() {
+
+ /** We are currently in the plugin installation loop, so set to true */
+ $this->in_loop = true;
+
+ printf( '' . $this->upgrader->strings['skin_before_update_header'] . ' ', $this->plugin_names[$this->i], $this->upgrader->update_current, $this->upgrader->update_count );
+ echo '';
+ echo '';
+
+ /** Flush header output buffer */
+ $this->before_flush_output();
+
+ }
+
+ /**
+ * Outputs the footer strings and necessary JS after each plugin installation.
+ *
+ * Checks for any errors and outputs them if they exist, else output
+ * success strings.
+ *
+ * @since 2.2.0
+ */
+ public function after() {
+
+ /** Close install strings */
+ echo '
';
+
+ /** Output error strings if an error has occurred */
+ if ( $this->error || ! $this->result ) {
+ if ( $this->error )
+ echo '' . sprintf( $this->upgrader->strings['skin_update_failed_error'], $this->plugin_names[$this->i], $this->error ) . '
';
+ else
+ echo '' . sprintf( $this->upgrader->strings['skin_update_failed'], $this->plugin_names[$this->i] ) . '
';
+
+ echo '';
+ }
+
+ /** If the result is set and there are no errors, success! */
+ if ( ! empty( $this->result ) && ! is_wp_error( $this->result ) ) {
+ echo '' . sprintf( $this->upgrader->strings['skin_update_successful'], $this->plugin_names[$this->i], 'jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').toggle();jQuery(\'span\', this).toggle(); return false;' ) . '
';
+ echo '';
+ }
+
+ /** Set in_loop and error to false and flush footer output buffer */
+ $this->reset();
+ $this->after_flush_output();
+
+ }
+
+ /**
+ * Outputs links after bulk plugin installation is complete.
+ *
+ * @since 2.2.0
+ */
+ public function bulk_footer() {
+
+ /** Serve up the string to say installations (and possibly activations) are complete */
+ parent::bulk_footer();
+
+ /** Flush plugins cache so we can make sure that the installed plugins list is always up to date */
+ wp_cache_flush();
+
+ /** Display message based on if all plugins are now active or not */
+ $complete = array();
+ foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) {
+ if ( ! is_plugin_active( $plugin['file_path'] ) ) {
+ echo '' . __( TGM_Plugin_Activation::$instance->strings['return'], TGM_Plugin_Activation::$instance->domain ) . '
';
+ $complete[] = $plugin;
+ break;
+ }
+ /** Nothing to store */
+ else {
+ $complete[] = '';
+ }
+ }
+
+ /** Filter out any empty entries */
+ $complete = array_filter( $complete );
+
+ /** All plugins are active, so we display the complete string and hide the menu to protect users */
+ if ( empty( $complete ) ) {
+ echo '' . sprintf( TGM_Plugin_Activation::$instance->strings['complete'], '' . __( 'Return to the Dashboard', TGM_Plugin_Activation::$instance->domain ) . ' ' ) . '
';
+ echo '';
+ }
+
+ }
+
+ /**
+ * Flush header output buffer.
+ *
+ * @since 2.2.0
+ */
+ public function before_flush_output() {
+
+ wp_ob_end_flush_all();
+ flush();
+
+ }
+
+ /**
+ * Flush footer output buffer and iterate $this->i to make sure the
+ * installation strings reference the correct plugin.
+ *
+ * @since 2.2.0
+ */
+ public function after_flush_output() {
+
+ wp_ob_end_flush_all();
+ flush();
+ $this->i++;
+
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/plugins/plugins.php b/lib/plugins/plugins.php
new file mode 100644
index 0000000..e200a20
--- /dev/null
+++ b/lib/plugins/plugins.php
@@ -0,0 +1,113 @@
+
+ * @author Gary Jones
+ * @author Travis Smith
+ * @copyright Copyright (c) 2012, Thomas Griffin, Travis Smith
+ * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later
+ * @link https://github.com/thomasgriffin/TGM-Plugin-Activation
+ */
+
+/** Exit if accessed directly */
+if ( ! defined( 'ABSPATH' ) ) exit( 'Cheatin’ uh?' );
+
+/**
+ * Include the TGM_Plugin_Activation class.
+ */
+require_once dirname( __FILE__ ) . '/class-tgm-plugin-activation.php';
+
+add_action( 'tgmpa_register', 'gs_register_required_plugins' );
+/**
+ * Register the required plugins for this theme.
+ *
+ * In this example, we register two plugins - one included with the TGMPA library
+ * and one from the .org repo.
+ *
+ * The variable passed to tgmpa_register_plugins() should be an array of plugin
+ * arrays.
+ *
+ * This function is hooked into tgmpa_init, which is fired within the
+ * TGM_Plugin_Activation class constructor.
+ */
+function gs_register_required_plugins() {
+
+ /**
+ * Array of plugin arrays. Required keys are name and slug.
+ * If the source is NOT from the .org repo, then source is also required.
+ */
+ $plugins = array(
+
+ // This is an example of how to include a plugin pre-packaged with a theme (like a core functionality plugin)
+ /*
+ array(
+ 'name' => 'TGM Example Plugin', // The plugin name
+ 'slug' => 'tgm-example-plugin', // The plugin slug (typically the folder name)
+ 'source' => CHILD_LIB_DIR . '/plugins/tgm-example-plugin.zip', // The plugin source
+ 'required' => true, // If false, the plugin is only 'recommended' instead of required
+ 'version' => '', // E.g. 1.0.0. If set, the active plugin must be this version or higher, otherwise a notice is presented
+ 'force_activation' => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch
+ 'force_deactivation' => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins
+ 'external_url' => '', // If set, overrides default API URL and points to an external URL
+ ),
+ */
+
+ // This is an example of how to include a plugin from the WordPress Plugin Repository
+ array(
+ 'name' => 'Genesis Shortcodes',
+ 'slug' => 'genesis-shortcodes',
+ 'required' => true,
+ ),
+
+ );
+
+ /**
+ * Array of configuration settings. Amend each line as needed.
+ * If you want the default strings to be available under your own theme domain,
+ * leave the strings uncommented.
+ * Some of the strings are added into a sprintf, so see the comments at the
+ * end of each line for what each argument will be.
+ */
+ $config = array(
+ 'domain' => CHILD_DOMAIN, // Text domain - likely want to be the same as your theme.
+ 'default_path' => '', // Default absolute path to pre-packaged plugins
+ 'parent_menu_slug' => 'themes.php', // Default parent menu slug
+ 'parent_url_slug' => 'themes.php', // Default parent URL slug
+ 'menu' => 'install-required-plugins', // Menu slug
+ 'has_notices' => true, // Show admin notices or not
+ 'is_automatic' => false, // Automatically activate plugins after installation or not
+ 'message' => '', // Message to output right before the plugins table
+ 'strings' => array(
+ 'page_title' => __( 'Install Required Plugins', CHILD_DOMAIN ),
+ 'menu_title' => __( 'Install Plugins', CHILD_DOMAIN ),
+ 'installing' => __( 'Installing Plugin: %s', CHILD_DOMAIN ), // %1$s = plugin name
+ 'oops' => __( 'Something went wrong with the plugin API.', CHILD_DOMAIN ),
+ 'notice_can_install_required' => _n_noop( 'This theme requires the following plugin: %1$s.', 'This theme requires the following plugins: %1$s.' ), // %1$s = plugin name(s)
+ 'notice_can_install_recommended' => _n_noop( 'This theme recommends the following plugin: %1$s.', 'This theme recommends the following plugins: %1$s.' ), // %1$s = plugin name(s)
+ 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ), // %1$s = plugin name(s)
+ 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s)
+ 'notice_can_activate_recommended' => _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s)
+ 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ), // %1$s = plugin name(s)
+ 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.' ), // %1$s = plugin name(s)
+ 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ), // %1$s = plugin name(s)
+ 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ),
+ 'activate_link' => _n_noop( 'Activate installed plugin', 'Activate installed plugins' ),
+ 'return' => __( 'Return to Required Plugins Installer', CHILD_DOMAIN ),
+ 'plugin_activated' => __( 'Plugin activated successfully.', CHILD_DOMAIN ),
+ 'complete' => __( 'All plugins installed and activated successfully. %s', CHILD_DOMAIN ), // %1$s = dashboard link
+ 'nag_type' => 'updated' // Determines admin notice type - can only be 'updated' or 'error'
+ )
+ );
+
+ tgmpa( $plugins, $config );
+
+}
\ No newline at end of file
diff --git a/lib/plugins/plugins/tgm-example-plugin.zip b/lib/plugins/plugins/tgm-example-plugin.zip
new file mode 100644
index 0000000..4b52df5
Binary files /dev/null and b/lib/plugins/plugins/tgm-example-plugin.zip differ
diff --git a/page-iframe.php b/page-iframe.php
new file mode 100644
index 0000000..eaa8389
--- /dev/null
+++ b/page-iframe.php
@@ -0,0 +1,57 @@
+ '', )
+ );
+}
+
+
+genesis();
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..184bacf
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,63 @@
+
Genesis Sandbox (Free Version)
+
+
Installation
+
+ Upload the theme folder via FTP to your wp-content/themes/ directory.
+ Go to your WordPress dashboard and select Appearance.
+ Be sure to activate the Genesis child theme, and not the Genesis parent theme.
+ Inside your WordPress dashboard, go to Genesis > Theme Settings and configure them to your liking.
+
+
+
Features
+The Free Version of the Genesis Sandbox provides developers with a base theme for quicker child theme development pushing the focus more on CSS and design.
+
+
Functions File (functions.php)
+
This file contains the bulk of the heavy lifting for the child theme. In this file, you will find the following:
+
+ Content Width
+ Structural Wraps
+ Featured Image
+ Genesis Custom Header
+ Footer Widgets
+ Top/Footer Navigation
+ Customized Footer
+ Genesis Responsive
+ Scripts
+ Editor Style
+ Add/Remove Sidebars
+ Remove Unused Layouts
+ Customize More Links
+ Remove Edit Link
+ Remove Unused Contact Methods
+
+
+
Initialization File (init.php)
+This file contains the necessary components to dynamically create the necessary constants for the child theme based on changes made in style.css, so that you make the change once, it is made across the site. Constants created are as follows: Data: CHILD_SETTINGS_FIELD (Text Domain with '-settings' added), CHILD_DOMAIN (Text Domain), CHILD_THEME_VERSION (Version), CHILD_THEME_NAME (Theme Name), CHILD_THEME_URL (Theme URI), CHILD_DEVELOPER (Author), and CHILD_DEVELOPER_URL (Author URI).
+
+The directory and URL constants are structural constants made available to the child theme developer. Directories: CHILD_LIB_DIR, CHILD_IMAGES_DIR, CHILD_ADMIN_DIR, CHILD_JS_DIR, CHILD_CSS_DIR; URLs: CHILD_LIB, CHILD_IMAGES, CHILD_ADMIN, CHILD_JS, CHILD_CSS
+
+
Admin Settings File (gs-settings.php)
+This file contains the proper method of adding an Admin page. The footer metabox is a fully working metabox; however, the navigation metabox is simply a sample metabox to be changed by you to add additional options as needed demonstrating how to use the Genesis Admin class.
+
+
Inpost Functions File (gs-inpost-functions.php)
+If you or your client uses WordPresss SEO or All-in-One SEO (or another SEO plugin) plugins, then this file will create a metabox for page specific scripts and page redirection.
+
+
Plugins Folder
+This folder is great for delivering themes to clients, an alternative to mu-plugins, and ensuring clients cannot break themes/sites. So plugins.php is the configuration file that contains some examples for you to use. Please see
TGMPA site for more information. The plugins folder (/lib/plugins/plugins/) is for packaging any private, propriety plugins for the site (e.g., core functionality plugins, etc.).
+
+
Alternative Files (functions-alt.php, init-alt.php, gs-functions-alt.php)
+When I am developing a non-commercialized child theme or a site for a client, I push all functions out of functions.php which enables me to quickly see what the client has done versus what I have done. This makes it easier for me to manage my client, my client's expectations, etc. enabling me to know when something was my fault and when something was their fault. I highly recommend this approach because as we know, our clients never mess anything up and "It just happened."
+
+In essence, the setup function from functions.php is pushed to init.php, and the other functions are pushed to gs-functions.php resulting in the functions-alt.php. This provides a clean slate for the client to do whatever they'd like to their own product. To use this alternative setup, you will need to remove the original functions (e.g., delete functions.php, init.php, and gs-functions.php) and rename the alt functions to the original names (e.g., functions-alt.php -> functions.php, init-alt.php -> init.php, and gs-functions-alt.php -> gs-functions.php). If you do not wish to use these, please delete the *-alt.php files.
+
+
Snippets File
+This file contains the most popular Genesis snippets for copy and paste use. This file includes the following:
+
+ Upload the theme folder via FTP to your wp-content/themes/ directory.
+ Go to your WordPress dashboard and select Appearance.
+ Be sure to activate the Genesis child theme, and not the Genesis parent theme.
+ Inside your WordPress dashboard, go to Genesis > Theme Settings and configure them to your liking.
+
+
+
Support
+Please visit
Genesis Sandbox for theme support.
\ No newline at end of file
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..b153f39
Binary files /dev/null and b/screenshot.png differ
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..88b1c0f
--- /dev/null
+++ b/style.css
@@ -0,0 +1,1266 @@
+/*
+ Theme Name: Genesis Sandbox Free
+ Theme URI: http://genesissandbox.com/
+ Description: Default Genesis Child Theme.
+ Author: Travis Smith & Jonathan Perez
+ Author URI: http://genesissandbox.com/
+ Version: 1.1.0
+ Text Domain: gs
+ Tags: black, white, red, one-column, two-columns, three-columns, left-sidebar, right-sidebar, fixed-width, custom-background, custom-header, custom-menu, editor-style, full-width-template, sticky-post, theme-options, threaded-comments, translation-ready
+
+ Template: genesis
+ Template Version: 1.9.0
+
+ License: GNU General Public License v3.0 (or later)
+ License URI: http://opensource.org/licenses/gpl-license.php
+*/
+
+/* Table of Contents
+
+ 01 Import Fonts
+ 02 Defaults
+ 03 Typography
+ - Font Color
+ - Font Family
+ - Font Size
+ - Font Miscellaneous
+ 04 Layout
+ - Structure
+ - 1152px CSS Grid
+ - Header
+ - Main Content
+ - Post Info & Meta
+ - Column Classes
+ - Miscellaneous
+ 05 Menus
+ - Primary Navigation Extras
+ 06 Headings
+ 07 Lists
+ 08 Post Navigation
+ 09 Comments
+ 10 Sidebars
+ 11 Footer
+ - Footer Widgets
+ 12 Forms & Buttons
+ - Gravity Forms
+ 13 Images & Captions
+ 14 Media Queries
+ - max-width: 1024px
+ - max-width: 768px
+ - max-width: 480px
+
+*/
+
+
+/*
+01 Import Fonts
+---------------------------------------------------------------------------------------------------- */
+
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700);
+
+
+/*
+02 Defaults
+---------------------------------------------------------------------------------------------------- */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote,
+a, abbr, acronym, address, big, cite,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+input, menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ vertical-align: baseline;
+}
+
+html {
+ font-size: 100%; /* 16px browser default */
+}
+
+body {
+ background-color: #fff;
+ line-height: 1;
+}
+
+body,
+input,
+select,
+textarea,
+.footer-widgets .widget-area {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+a,
+a:visited,
+button,
+input[type="button"],
+input[type="submit"] {
+ -moz-transition: all 0.1s ease-in-out;
+ -webkit-transition: all 0.1s ease-in-out;
+ transition: all 0.1s ease-in-out;
+}
+
+::-moz-selection {
+ background-color: #1e1e1e;
+ color: #fff;
+}
+
+::selection {
+ background-color: #1e1e1e;
+ color: #fff;
+}
+
+a img {
+ border: none;
+}
+
+a.btn {
+ text-decoration: none;
+}
+
+
+/*
+03 Typography
+-------------------------------------------------------------------------------------------------------
+
+ This section covers font colors, families, size, styles and weight.
+
+ This style sheet uses rem values with a pixel fallback.
+ The rem values are calculated per the examples below:
+
+ 12 / 16 = 0.75rem
+ 14 / 16 = 0.875rem
+ 16 / 16 = 1rem
+ 18 / 16 = 1.125rem
+ 20 / 16 = 1.25rem
+ 24 / 16 = 1.5rem
+ 30 / 16 = 1.875rem
+ 36 / 16 = 2.25rem
+ 42 / 16 = 2.625rem
+ 48 / 16 = 3rem
+
+ Further reading on the use and compatibility of rems:
+
+ http://caniuse.com/rem
+ http://snook.ca/archives/html_and_css/font-size-with-rem
+
+*/
+
+/* 03a - Font Color ----------- */
+
+a:hover,
+body,
+h2 a,
+h2 a:visited,
+h4.widgettitle a,
+input,
+.author,
+.date,
+.genesis-nav-menu a,
+.genesis-nav-menu li li a,
+.genesis-nav-menu li li a:link,
+.genesis-nav-menu li li a:visited,
+.post-comments,
+#title a,
+#title a:hover {
+ color: #1e1e1e;
+}
+
+a,
+h2 a:hover,
+.genesis-nav-menu li a:hover,
+.genesis-nav-menu li:hover a,
+.genesis-nav-menu li li a:hover,
+.genesis-nav-menu .current-menu-item a {
+ color: #ff2a00;
+}
+
+.post-info,
+.post-meta,
+#description {
+ color: #636363;
+}
+
+blockquote::before,
+blockquote p,
+input,
+select,
+textarea {
+ color: #999;
+}
+
+button,
+input[type="button"],
+input[type="submit"],
+.genesis-nav-menu .highlight-menu-item a,
+.genesis-nav-menu .highlight-menu-item a:hover,
+.navigation li a,
+.navigation li a:hover,
+.navigation li.active a,
+.navigation li.disabled {
+ color: #fff;
+}
+
+/* 03b - Font Family ----------- */
+
+body,
+input,
+textarea,
+.author-box h1 {
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.entry-title a,
+#title {
+ font-family: 'Lato', sans-serif;
+}
+
+/* 03c - Font Size ----------- */
+
+#title {
+ font-size: 42px;
+ font-size: 2.625rem;
+}
+
+h1,
+.entry-title,
+.entry-title a {
+ font-size: 36px;
+ font-size: 2.25rem;
+}
+
+blockquote::before {
+ font-size: 32px;
+ font-size: 2rem;
+}
+
+h2 {
+ font-size: 30px;
+ font-size: 1.875rem;
+}
+
+h3 {
+ font-size: 24px;
+ font-size: 1.5rem;
+}
+
+h4,
+.archive-title,
+.taxonomy-description h1,
+.widgettitle {
+ font-size: 20px;
+ font-size: 1.25rem;
+}
+
+h5 {
+ font-size: 18px;
+ font-size: 1.125rem;
+}
+
+h6,
+.author-box h1,
+.sidebar h2 a {
+ font-size: 16px;
+ font-size: 1rem;
+}
+
+input,
+select,
+textarea,
+.genesis-nav-menu,
+.post-info,
+.post-meta,
+.wp-caption,
+#footer p {
+ font-size: 14px;
+ font-size: 0.875rem;
+}
+
+
+/* 03d - Font Miscellaneous ----------- */
+
+blockquote p {
+ font-style: italic;
+}
+
+cite {
+ font-style: normal;
+}
+
+button,
+input[type="button"],
+input[type="submit"],
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.entry-title a,
+.genesis-nav-menu,
+.post-comments,
+.post-info .author,
+.post-info .date,
+.wp-caption,
+#footer p,
+#title {
+ font-weight: 700;
+}
+
+.wp-caption {
+ text-align: center;
+}
+
+h2 a,
+h2 a:visited,
+.genesis-nav-menu a,
+.navigation li a,
+.widgettitle a,
+#title a {
+ text-decoration: none;
+}
+
+
+/*
+04 Layout
+---------------------------------------------------------------------------------------------------- */
+
+/* 04a - Structure ----------- */
+
+#wrap {
+ margin: 0 auto;
+ max-width: 1152px;
+}
+
+#inner {
+ clear: both;
+ overflow: hidden;
+ padding-top: 40px;
+ padding-top: 2.5rem;
+}
+
+/* 04b - 1152px CSS Grid ----------- */
+
+#sidebar-alt {
+ width: 15.277777777%; /* 176px / 1152px */
+}
+
+.sidebar,
+#header .widget-area {
+ width: 30.555555555%; /* 352px / 1152px */
+}
+
+.content-sidebar-sidebar .sidebar,
+.sidebar-content-sidebar .sidebar,
+.sidebar-sidebar-content .sidebar {
+ width: 37.931034482%; /* 352px / 928px */
+}
+
+.content-sidebar-sidebar #content,
+.sidebar-content-sidebar #content,
+.sidebar-sidebar-content #content {
+ width: 56.896551724%; /* 528px / 928px */
+}
+
+.content-sidebar #content,
+.sidebar-content #content,
+#title-area {
+ width: 65.277777777%; /* 752px / 1152px */
+}
+
+.content-sidebar-sidebar #content-sidebar-wrap,
+.sidebar-content-sidebar #content-sidebar-wrap,
+.sidebar-sidebar-content #content-sidebar-wrap {
+ width: 80.555555555%; /* 928px / 1152px */
+}
+
+.content-sidebar #content-sidebar-wrap,
+.full-width-content #content,
+.full-width-content #content-sidebar-wrap,
+.sidebar-content #content-sidebar-wrap {
+ width: 100%; /* 1152px / 1152px */
+}
+
+.sidebar-content #sidebar,
+.sidebar-sidebar-content #sidebar,
+#content,
+#content-sidebar-wrap,
+#footer .gototop,
+#sidebar-alt,
+#title-area {
+ float: left;
+}
+
+.content-sidebar-sidebar #sidebar-alt,
+.sidebar,
+.sidebar-content #content,
+.sidebar-content-sidebar #content-sidebar-wrap,
+.sidebar-sidebar-content #content,
+.sidebar-sidebar-content #content-sidebar-wrap,
+#footer .creds,
+#header .widget-area {
+ float: right;
+}
+
+#home-middle {
+ overflow: hidden;
+}
+
+#home-middle,
+#home-top,
+#home-bottom {
+ padding: 1rem 0;
+}
+
+/* 04c - Header ----------- */
+
+#header {
+ border-bottom: 2px solid #1e1e1e;
+ min-height: 120px;
+ overflow: hidden;
+ padding-bottom: 32px;
+ padding-bottom: 2rem;
+}
+
+#title {
+ line-height: 1;
+ margin: 40px 0 8px;
+ margin: 2.5rem 0 0.5rem;
+}
+
+.header-image #title {
+ margin: 0;
+}
+
+#description {
+ line-height: 1.25;
+}
+
+.header-full-width #title,
+.header-full-width #title a,
+.header-full-width #title-area {
+ width: 100%;
+}
+
+.header-image #title,
+.header-image #title a,
+.header-image #title-area {
+ display: block;
+ float: left;
+ min-height: 120px;
+ overflow: hidden;
+ text-indent: -9999px;
+ width: 50%;
+}
+
+.header-image #description {
+ display: block;
+ overflow: hidden;
+}
+
+/* 04d - Main Content ----------- */
+
+#content {
+ padding-bottom: 40px;
+ padding-bottom: 2.5rem;
+}
+
+.entry,
+.page .post.entry {
+ margin-bottom: 80px;
+ margin-bottom: 5rem;
+}
+
+.single .entry {
+ margin-bottom: 48px;
+ margin-bottom: 3rem;
+}
+
+.page .entry {
+ margin: 0;
+}
+
+.entry-content {
+ overflow: hidden;
+}
+
+.entry-content,
+.entry-content p {
+ line-height: 1.625;
+}
+
+.entry-content p {
+ margin-bottom: 26px;
+ margin-bottom: 1.625rem;
+}
+
+blockquote {
+ padding: 24px 64px;
+ padding: 1.5rem 4rem;
+}
+
+blockquote::before {
+ content: "“";
+ display: block;
+ height: 0;
+ left: -20px;
+ position: relative;
+ top: -10px;
+}
+
+/* 04e - Post Info & Meta ----------- */
+
+.post-info,
+.post-meta {
+ clear: both;
+ line-height: 1.5;
+}
+
+.post-info {
+ margin-bottom: 24px;
+ margin-bottom: 1.5rem;
+}
+
+.post-comments {
+ background: url(images/post-comments.png) no-repeat center left;
+ margin-left: 16px;
+ margin-left: 1rem;
+ padding-left: 20px;
+ padding-left: 1.25rem;
+}
+
+.post-meta {
+ border-top: 1px solid #ccc;
+ padding-top: 24px;
+ padding-top: 1.5rem;
+}
+
+.categories,
+.tags {
+ display: block;
+}
+
+/* 04f - Column Classes ----------- */
+
+.five-sixths,
+.four-fifths,
+.four-sixths,
+.one-fifth,
+.one-fourth,
+.one-half,
+.one-sixth,
+.one-third,
+.three-fifths,
+.three-fourths,
+.three-sixths,
+.two-fifths,
+.two-fourths,
+.two-sixths,
+.two-thirds {
+ float: left;
+ margin-left: 4.166666666%; /* 48px / 1152px */
+}
+
+.one-half,
+.three-sixths,
+.two-fourths {
+ width: 47.9166666666%; /* 552px / 1152px */
+}
+
+.one-third,
+.two-sixths {
+ width: 30.555555555%; /* 352px / 1152px */
+}
+
+.four-sixths,
+.two-thirds {
+ width: 65.277777777%; /* 752px / 1152px */
+}
+
+.one-fourth {
+ width: 21.875%; /* 252px / 1152px */
+}
+
+.three-fourths {
+ width: 73.958333333%; /* 852px / 1152px */
+}
+
+.one-fifth {
+ width: 16.666666666%; /* 192px / 1152px */
+}
+
+.two-fifths {
+ width: 37.5%; /* 432px / 1152px */
+}
+
+.three-fifths {
+ width: 58.333333333%; /* 672px / 1152px */
+}
+
+.four-fifths {
+ width: 79.166666666%; /* 912px / 1152px */
+}
+
+.one-sixth {
+ width: 13.194444444%; /* 152px / 1152px */
+}
+
+.five-sixths {
+ width: 82.638888888%; /* 952px / 1152px */
+}
+
+.first {
+ margin-left: 0;
+}
+
+/* 04g - Miscellaneous ----------- */
+
+p.subscribe-to-comments {
+ padding: 24px 0 16px;
+ padding: 1.5rem 0 1rem;
+}
+
+p.pages,
+.clear,
+.clear-line,
+.first {
+ clear: both;
+}
+
+.clear-line {
+ border-bottom: 1px solid #ccc;
+ margin-bottom: 26px;
+ margin-bottom: 1.625rem;
+}
+
+.alignleft,
+.archive-page {
+ float: left;
+}
+
+.alignright {
+ float: right;
+}
+
+.archive-page {
+ width: 50%;
+}
+
+.author-box,
+.sticky {
+ margin-bottom: 80px;
+ margin-bottom: 5rem;
+}
+
+.author-box,
+.author-box h1,
+.taxonomy-description {
+ line-height: 1.5;
+}
+
+.author-box,
+.breadcrumb,
+.sticky,
+.taxonomy-description {
+ background-color: #f5f5f5;
+ margin-bottom: 48px;
+ margin-bottom: 3rem;
+ overflow: hidden;
+ padding: 32px;
+ padding: 2rem;
+}
+
+
+/*
+05 Menus
+---------------------------------------------------------------------------------------------------- */
+
+.genesis-nav-menu {
+ clear: both;
+ overflow: hidden;
+}
+
+#header .genesis-nav-menu {
+ float: right;
+ margin-top: 48px;
+ margin-top: 3rem;
+ width: auto;
+}
+
+.genesis-nav-menu.menu-primary,
+.genesis-nav-menu.menu-secondary {
+ border-bottom: 1px solid #ccc;
+}
+
+.genesis-nav-menu ul {
+ float: left;
+ width: 100%;
+}
+
+.genesis-nav-menu li {
+ display: inline-block;
+ float: left;
+ list-style-type: none;
+ text-align: left;
+}
+
+.genesis-nav-menu a {
+ display: block;
+ padding: 24px 20px;
+ padding: 1.5rem 1.25rem;
+ position: relative;
+}
+
+.genesis-nav-menu li.highlight-menu-item {
+ margin-left: 20px;
+ margin-left: 1.25rem;
+}
+
+.genesis-nav-menu .highlight-menu-item a {
+ background-color: #1e1e1e;
+}
+
+.genesis-nav-menu .highlight-menu-item a:hover {
+ background-color: #ff2a00;
+}
+
+.genesis-nav-menu li li a,
+.genesis-nav-menu li li a:link,
+.genesis-nav-menu li li a:visited {
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-top: none;
+ padding: 20px;
+ padding: 1.25rem;
+ position: relative;
+ width: 170px;
+}
+
+.genesis-nav-menu li ul {
+ left: -9999px;
+ position: absolute;
+ width: 212px;
+ z-index: 99;
+}
+
+.genesis-nav-menu li ul ul {
+ margin: -55px 0 0 211px;
+}
+
+.genesis-nav-menu li:hover ul ul,
+.genesis-nav-menu li.sfHover ul ul {
+ left: -9999px;
+}
+
+.genesis-nav-menu li:hover,
+.genesis-nav-menu li.sfHover {
+ position: static;
+}
+
+ul.genesis-nav-menu li:hover>ul,
+ul.genesis-nav-menu li.sfHover ul,
+#header .genesis-nav-menu li:hover>ul,
+#header .genesis-nav-menu li.sfHover ul {
+ left: auto;
+}
+
+.genesis-nav-menu li a .sf-sub-indicator,
+.genesis-nav-menu li li a .sf-sub-indicator,
+.genesis-nav-menu li li li a .sf-sub-indicator {
+ position: absolute;
+ text-indent: -9999px;
+}
+
+#wpadminbar li:hover ul ul {
+ left: 0;
+}
+
+/* 05a - Primary Navigation Extras ----------- */
+
+.genesis-nav-menu li.right {
+ float: right;
+ padding: 24px 20px;
+ padding: 1.5rem 1.25rem;
+}
+
+.genesis-nav-menu li.right a {
+ display: inline;
+ padding: 0;
+}
+
+.genesis-nav-menu li.search {
+ padding: 6px 0 0;
+ padding: 0.375rem 0 0;
+}
+
+.genesis-nav-menu li.rss a {
+ background: url(images/rss.png) no-repeat center left;
+ margin-left: 20px;
+ margin-left: 1.25rem;
+ padding-left: 20px;
+ padding-left: 1.25rem;
+}
+
+.genesis-nav-menu li.twitter a {
+ background: url(images/twitter-nav.png) no-repeat center left;
+ padding-left: 24px;
+ padding-left: 1.5rem;
+}
+
+
+/*
+06 Headings
+---------------------------------------------------------------------------------------------------- */
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.entry-title a {
+ line-height: 1.2;
+ margin-bottom: 16px;
+ margin-bottom: 1rem;
+}
+
+.author-box h1 {
+ margin: 0
+}
+
+.taxonomy-description h1 {
+ margin-bottom: 4px;
+ margin-bottom: 0.25rem;
+}
+
+.archive-title {
+ margin-bottom: 24px;
+ margin-bottom: 1.5rem;
+}
+
+
+/*
+07 Lists
+---------------------------------------------------------------------------------------------------- */
+
+.entry-content ol,
+.entry-content ul {
+ margin-bottom: 26px;
+ margin-bottom: 1.625rem;
+}
+
+.entry-content ol li,
+.entry-content ul li {
+ line-height: 1.625;
+}
+
+.entry-content ol li,
+.entry-content ul li {
+ margin-left: 40px;
+ margin-left: 2.5rem;
+}
+
+.entry-content ol li {
+ list-style-type: decimal;
+}
+
+.entry-content ul li {
+ list-style-type: disc;
+}
+
+.entry-content ol ol,
+.entry-content ul ul {
+ margin-bottom: 0;
+}
+
+
+/*
+08 Post Navigation
+---------------------------------------------------------------------------------------------------- */
+
+.navigation li {
+ display: inline;
+}
+
+.navigation li a,
+.navigation li a:hover,
+.navigation li.active a,
+.navigation li.disabled {
+ background-color: #1e1e1e;
+ border-radius: 3px;
+ cursor: pointer;
+ padding: 12px;
+ padding: 0.75rem;
+}
+
+.navigation li a:hover,
+.navigation li.active a {
+ background-color: #ff2a00;
+}
+
+
+/*
+09 Comments
+---------------------------------------------------------------------------------------------------- */
+
+#comments,
+#respond {
+ line-height: 1.5;
+ overflow: hidden;
+}
+
+.ping-list,
+#comments {
+ margin-bottom: 48px;
+ margin-bottom: 3rem;
+}
+
+#author,
+#email,
+#url {
+ width: 50%;
+}
+
+.commentmetadata,
+#author,
+#email,
+#url {
+ margin-bottom: 12px;
+ margin-bottom: 0.75rem;
+}
+
+#comment {
+ margin: 12px 0;
+ margin: 0.75rem 0;
+}
+
+label {
+ margin-left: 12px;
+ margin-left: 0.75rem;
+}
+
+.comment-list li,
+.ping-list li {
+ list-style-type: none;
+ margin-top: 24px;
+ margin-top: 1.5rem;
+ padding: 32px;
+ padding: 2rem;
+}
+
+.comment-list li ul li {
+ margin-right: -32px;
+ margin-right: -2rem;
+}
+
+.comment-header {
+ overflow: hidden;
+}
+
+.comment {
+ background-color: #f5f5f5;
+ border: 2px solid #fff;
+ border-right: none;
+}
+
+.comment-content p {
+ margin-bottom: 24px;
+ margin-bottom: 1.5rem;
+}
+
+.bypostauthor {
+}
+
+#comments .navigation {
+ margin-top: 32px;
+ margin-top: 2rem;
+}
+
+
+/*
+10 Sidebars
+---------------------------------------------------------------------------------------------------- */
+
+.sidebar {
+ display: inline;
+ line-height: 1.5;
+}
+
+.sidebar p {
+ margin-bottom: 16px;
+ margin-bottom: 1rem;
+}
+
+.sidebar .widget {
+ border-bottom: 1px solid #ccc;
+ margin-bottom: 32px;
+ margin-bottom: 2rem;
+ padding-bottom: 32px;
+ padding-bottom: 2rem;
+ overflow: hidden;
+}
+
+.sidebar.widget-area ul li {
+ list-style-type: none;
+ margin-bottom: 6px;
+ margin-bottom: 0.375rem;
+ word-wrap: break-word;
+}
+
+
+/*
+11 Footer
+---------------------------------------------------------------------------------------------------- */
+
+#footer {
+ clear: both;
+}
+
+#footer .wrap {
+ border-top: 2px solid #1e1e1e;
+ overflow: hidden;
+ padding: 48px 0;
+ padding: 3rem 0;
+}
+
+#footer .creds {
+ text-align: right;
+}
+
+#footer .creds,
+#footer .gototop {
+ margin: 8px 0;
+ margin: 0.5rem 0;
+}
+
+/* 11a - Footer Widgets ----------- */
+
+.footer-widgets {
+ border-top: 2px solid #1e1e1e;
+ clear: both;
+ line-height: 1.5;
+ overflow: hidden;
+ padding: 32px 0 16px;
+ padding: 2rem 0 1rem;
+}
+
+.footer-widgets p {
+ margin-bottom: 16px;
+ margin-bottom: 1rem;
+}
+
+.footer-widgets .widget {
+ margin-bottom: 24px;
+ margin-bottom: 1.5rem;
+}
+
+.footer-widgets .widget-area ul li {
+ list-style-type: none;
+ margin-bottom: 6px;
+ margin-bottom: 0.375rem;
+ word-wrap: break-word;
+}
+
+
+/*
+12 Forms & Buttons
+---------------------------------------------------------------------------------------------------- */
+
+input,
+select,
+textarea {
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 3px;
+ box-shadow: 0 0 5px #ddd inset;
+ padding: 16px;
+ padding: 1rem;
+ width: 100%;
+}
+
+#header .search-form {
+ float: right;
+ margin-top: 56px;
+ margin-top: 3.5rem;
+ width: 100%;
+}
+
+button,
+input[type="button"],
+input[type="submit"],
+{
+ background-color: #1e1e1e;
+ border: none;
+ box-shadow: none;
+ cursor: pointer;
+ padding: 16px 24px;
+ padding: 1rem 1.5rem;
+ width: auto;
+}
+
+button:hover,
+input:hover[type="button"],
+input:hover[type="submit"] {
+ background-color: #ff2a00;
+}
+
+.enews input[type="submit"],
+.search-form input[type="submit"] {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+
+/* 12a - Gravity Forms ----------- */
+
+#content div.gform_wrapper input,
+#content div.gform_wrapper select,
+#content div.gform_wrapper textarea,
+#content div.gform_wrapper .ginput_complex label {
+ font-size: 16px;
+ font-size: 1rem;
+ padding: 16px;
+ padding: 1rem;
+}
+
+#content div.gform_wrapper input[type="submit"] {
+ padding: 16px 24px;
+ padding: 1rem 1.5rem;
+}
+
+#content div.gform_wrapper .ginput_complex label {
+ padding: 0;
+}
+
+div.gform_wrapper li,
+div.gform_wrapper form li {
+ margin: 16px 0 0;
+ margin: 1rem 0 0;
+}
+
+
+/*
+13 Images & Captions
+---------------------------------------------------------------------------------------------------- */
+
+embed,
+img,
+object,
+video {
+ max-width: 100%;
+}
+
+img {
+ height: auto;
+}
+
+.alignleft .avatar {
+ margin-right: 24px;
+ margin-right: 1.5rem;
+}
+
+.alignright .avatar {
+ margin-left: 24px;
+ margin-left: 1.5rem;
+}
+
+.author-box .avatar {
+ float: left;
+ margin-right: 24px;
+ margin-right: 1.5rem
+}
+
+.comment-list li .avatar {
+ float: left;
+ margin: 0 16px 24px 0;
+ margin: 0 1rem 1.5rem 0;
+}
+
+img.centered,
+.aligncenter {
+ display: block;
+ margin: 0 auto 24px;
+ margin: 0 auto 1.5rem
+}
+
+img.alignnone {
+ display: inline;
+ margin-bottom: 12px;
+ margin-bottom: 0.75rem;
+}
+
+img.alignleft,
+.post-image,
+.wp-caption.alignleft {
+ display: inline;
+ margin: 0 24px 24px 0;
+ margin: 0 1.5rem 1.5rem 0;
+}
+
+img.alignright,
+.wp-caption.alignright {
+ display: inline;
+ margin: 0 0 24px 24px;
+ margin: 0 0 1.5rem 1.5rem;
+}
+
+p.wp-caption-text {
+ line-height: 1.2;
+ margin-top: 12px;
+ margin-top: 0.75rem;
+}
+
+.gallery-caption {
+}
+
+/* FOOTER NAV */
+#footer #footer-nav .wrap {
+ border: none;
+ padding: 0;
+}
+
+#footer ul.menu-footer {
+ font-size: 13px;
+ font-weight: normal;
+}
+
+#footer ul.menu-footer a {
+ padding: 0rem .75rem;
+}
+
+/* MOBILE STYLES */
+
+#mobile-nav, #mobile-nav ul {
+ display: none;
+}
+
+#mobile-nav ul {
+ background-color: rgba(78,78,78,1);
+}
+
+#mobile-nav ul li a {
+ color: #fff;
+ font-weight: normal;
+}
\ No newline at end of file