Mini Shell

Direktori : /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-admin/js/
Upload File :
Current File : /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-admin/js/dashboard.js

/**
 * @output wp-admin/js/dashboard.js
 */

/* global pagenow, ajaxurl, postboxes, wpActiveEditor:true, ajaxWidgets */
/* global ajaxPopulateWidgets, quickPressLoad,  */
window.wp = window.wp || {};
window.communityEventsData = window.communityEventsData || {};

/**
 * Initializes the dashboard widget functionality.
 *
 * @since 2.7.0
 */
jQuery( function($) {
	var welcomePanel = $( '#welcome-panel' ),
		welcomePanelHide = $('#wp_welcome_panel-hide'),
		updateWelcomePanel;

	/**
	 * Saves the visibility of the welcome panel.
	 *
	 * @since 3.3.0
	 *
	 * @param {boolean} visible Should it be visible or not.
	 *
	 * @return {void}
	 */
	updateWelcomePanel = function( visible ) {
		$.post( ajaxurl, {
			action: 'update-welcome-panel',
			visible: visible,
			welcomepanelnonce: $( '#welcomepanelnonce' ).val()
		});
	};

	// Unhide the welcome panel if the Welcome Option checkbox is checked.
	if ( welcomePanel.hasClass('hidden') && welcomePanelHide.prop('checked') ) {
		welcomePanel.removeClass('hidden');
	}

	// Hide the welcome panel when the dismiss button or close button is clicked.
	$('.welcome-panel-close, .welcome-panel-dismiss a', welcomePanel).on( 'click', function(e) {
		e.preventDefault();
		welcomePanel.addClass('hidden');
		updateWelcomePanel( 0 );
		$('#wp_welcome_panel-hide').prop('checked', false);
	});

	// Set welcome panel visibility based on Welcome Option checkbox value.
	welcomePanelHide.on( 'click', function() {
		welcomePanel.toggleClass('hidden', ! this.checked );
		updateWelcomePanel( this.checked ? 1 : 0 );
	});

	/**
	 * These widgets can be populated via ajax.
	 *
	 * @since 2.7.0
	 *
	 * @type {string[]}
	 *
	 * @global
 	 */
	window.ajaxWidgets = ['dashboard_primary'];

	/**
	 * Triggers widget updates via Ajax.
	 *
	 * @since 2.7.0
	 *
	 * @global
	 *
	 * @param {string} el Optional. Widget to fetch or none to update all.
	 *
	 * @return {void}
	 */
	window.ajaxPopulateWidgets = function(el) {
		/**
		 * Fetch the latest representation of the widget via Ajax and show it.
		 *
		 * @param {number} i Number of half-seconds to use as the timeout.
		 * @param {string} id ID of the element which is going to be checked for changes.
		 *
		 * @return {void}
		 */
		function show(i, id) {
			var p, e = $('#' + id + ' div.inside:visible').find('.widget-loading');
			// If the element is found in the dom, queue to load latest representation.
			if ( e.length ) {
				p = e.parent();
				setTimeout( function(){
					// Request the widget content.
					p.load( ajaxurl + '?action=dashboard-widgets&widget=' + id + '&pagenow=' + pagenow, '', function() {
						// Hide the parent and slide it out for visual fancyness.
						p.hide().slideDown('normal', function(){
							$(this).css('display', '');
						});
					});
				}, i * 500 );
			}
		}

		// If we have received a specific element to fetch, check if it is valid.
		if ( el ) {
			el = el.toString();
			// If the element is available as Ajax widget, show it.
			if ( $.inArray(el, ajaxWidgets) !== -1 ) {
				// Show element without any delay.
				show(0, el);
			}
		} else {
			// Walk through all ajaxWidgets, loading them after each other.
			$.each( ajaxWidgets, show );
		}
	};

	// Initially populate ajax widgets.
	ajaxPopulateWidgets();

	// Register ajax widgets as postbox toggles.
	postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );

	/**
	 * Control the Quick Press (Quick Draft) widget.
	 *
	 * @since 2.7.0
	 *
	 * @global
	 *
	 * @return {void}
	 */
	window.quickPressLoad = function() {
		var act = $('#quickpost-action'), t;

		// Enable the submit buttons.
		$( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );

		t = $('#quick-press').on( 'submit', function( e ) {
			e.preventDefault();

			// Show a spinner.
			$('#dashboard_quick_press #publishing-action .spinner').show();

			// Disable the submit button to prevent duplicate submissions.
			$('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);

			// Post the entered data to save it.
			$.post( t.attr( 'action' ), t.serializeArray(), function( data ) {
				// Replace the form, and prepend the published post.
				$('#dashboard_quick_press .inside').html( data );
				$('#quick-press').removeClass('initial-form');
				quickPressLoad();
				highlightLatestPost();

				// Focus the title to allow for quickly drafting another post.
				$('#title').trigger( 'focus' );
			});

			/**
			 * Highlights the latest post for one second.
			 *
			 * @return {void}
 			 */
			function highlightLatestPost () {
				var latestPost = $('.drafts ul li').first();
				latestPost.css('background', '#fffbe5');
				setTimeout(function () {
					latestPost.css('background', 'none');
				}, 1000);
			}
		} );

		// Change the QuickPost action to the publish value.
		$('#publish').on( 'click', function() { act.val( 'post-quickpress-publish' ); } );

		$('#quick-press').on( 'click focusin', function() {
			wpActiveEditor = 'content';
		});

		autoResizeTextarea();
	};
	window.quickPressLoad();

	// Enable the dragging functionality of the widgets.
	$( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );

	/**
	 * Adjust the height of the textarea based on the content.
	 *
	 * @since 3.6.0
	 *
	 * @return {void}
	 */
	function autoResizeTextarea() {
		// When IE8 or older is used to render this document, exit.
		if ( document.documentMode && document.documentMode < 9 ) {
			return;
		}

		// Add a hidden div. We'll copy over the text from the textarea to measure its height.
		$('body').append( '<div class="quick-draft-textarea-clone" style="display: none;"></div>' );

		var clone = $('.quick-draft-textarea-clone'),
			editor = $('#content'),
			editorHeight = editor.height(),
			/*
			 * 100px roughly accounts for browser chrome and allows the
			 * save draft button to show on-screen at the same time.
			 */
			editorMaxHeight = $(window).height() - 100;

		/*
		 * Match up textarea and clone div as much as possible.
		 * Padding cannot be reliably retrieved using shorthand in all browsers.
		 */
		clone.css({
			'font-family': editor.css('font-family'),
			'font-size':   editor.css('font-size'),
			'line-height': editor.css('line-height'),
			'padding-bottom': editor.css('paddingBottom'),
			'padding-left': editor.css('paddingLeft'),
			'padding-right': editor.css('paddingRight'),
			'padding-top': editor.css('paddingTop'),
			'white-space': 'pre-wrap',
			'word-wrap': 'break-word',
			'display': 'none'
		});

		// The 'propertychange' is used in IE < 9.
		editor.on('focus input propertychange', function() {
			var $this = $(this),
				// Add a non-breaking space to ensure that the height of a trailing newline is
				// included.
				textareaContent = $this.val() + '&nbsp;',
				// Add 2px to compensate for border-top & border-bottom.
				cloneHeight = clone.css('width', $this.css('width')).text(textareaContent).outerHeight() + 2;

			// Default to show a vertical scrollbar, if needed.
			editor.css('overflow-y', 'auto');

			// Only change the height if it has changed and both heights are below the max.
			if ( cloneHeight === editorHeight || ( cloneHeight >= editorMaxHeight && editorHeight >= editorMaxHeight ) ) {
				return;
			}

			/*
			 * Don't allow editor to exceed the height of the window.
			 * This is also bound in CSS to a max-height of 1300px to be extra safe.
			 */
			if ( cloneHeight > editorMaxHeight ) {
				editorHeight = editorMaxHeight;
			} else {
				editorHeight = cloneHeight;
			}

			// Disable scrollbars because we adjust the height to the content.
			editor.css('overflow', 'hidden');

			$this.css('height', editorHeight + 'px');
		});
	}

} );

jQuery( function( $ ) {
	'use strict';

	var communityEventsData = window.communityEventsData,
		dateI18n = wp.date.dateI18n,
		format = wp.date.format,
		sprintf = wp.i18n.sprintf,
		__ = wp.i18n.__,
		_x = wp.i18n._x,
		app;

	/**
	 * Global Community Events namespace.
	 *
	 * @since 4.8.0
	 *
	 * @memberOf wp
	 * @namespace wp.communityEvents
	 */
	app = window.wp.communityEvents = /** @lends wp.communityEvents */{
		initialized: false,
		model: null,

		/**
		 * Initializes the wp.communityEvents object.
		 *
		 * @since 4.8.0
		 *
		 * @return {void}
		 */
		init: function() {
			if ( app.initialized ) {
				return;
			}

			var $container = $( '#community-events' );

			/*
			 * When JavaScript is disabled, the errors container is shown, so
			 * that "This widget requires JavaScript" message can be seen.
			 *
			 * When JS is enabled, the container is hidden at first, and then
			 * revealed during the template rendering, if there actually are
			 * errors to show.
			 *
			 * The display indicator switches from `hide-if-js` to `aria-hidden`
			 * here in order to maintain consistency with all the other fields
			 * that key off of `aria-hidden` to determine their visibility.
			 * `aria-hidden` can't be used initially, because there would be no
			 * way to set it to false when JavaScript is disabled, which would
			 * prevent people from seeing the "This widget requires JavaScript"
			 * message.
			 */
			$( '.community-events-errors' )
				.attr( 'aria-hidden', 'true' )
				.removeClass( 'hide-if-js' );

			$container.on( 'click', '.community-events-toggle-location, .community-events-cancel', app.toggleLocationForm );

			/**
			 * Filters events based on entered location.
			 *
			 * @return {void}
			 */
			$container.on( 'submit', '.community-events-form', function( event ) {
				var location = $( '#community-events-location' ).val().trim();

				event.preventDefault();

				/*
				 * Don't trigger a search if the search field is empty or the
				 * search term was made of only spaces before being trimmed.
				 */
				if ( ! location ) {
					return;
				}

				app.getEvents({
					location: location
				});
			});

			if ( communityEventsData && communityEventsData.cache && communityEventsData.cache.location && communityEventsData.cache.events ) {
				app.renderEventsTemplate( communityEventsData.cache, 'app' );
			} else {
				app.getEvents();
			}

			app.initialized = true;
		},

		/**
		 * Toggles the visibility of the Edit Location form.
		 *
		 * @since 4.8.0
		 *
		 * @param {event|string} action 'show' or 'hide' to specify a state;
		 *                              or an event object to flip between states.
		 *
		 * @return {void}
		 */
		toggleLocationForm: function( action ) {
			var $toggleButton = $( '.community-events-toggle-location' ),
				$cancelButton = $( '.community-events-cancel' ),
				$form         = $( '.community-events-form' ),
				$target       = $();

			if ( 'object' === typeof action ) {
				// The action is the event object: get the clicked element.
				$target = $( action.target );
				/*
				 * Strict comparison doesn't work in this case because sometimes
				 * we explicitly pass a string as value of aria-expanded and
				 * sometimes a boolean as the result of an evaluation.
				 */
				action = 'true' == $toggleButton.attr( 'aria-expanded' ) ? 'hide' : 'show';
			}

			if ( 'hide' === action ) {
				$toggleButton.attr( 'aria-expanded', 'false' );
				$cancelButton.attr( 'aria-expanded', 'false' );
				$form.attr( 'aria-hidden', 'true' );
				/*
				 * If the Cancel button has been clicked, bring the focus back
				 * to the toggle button so users relying on screen readers don't
				 * lose their place.
				 */
				if ( $target.hasClass( 'community-events-cancel' ) ) {
					$toggleButton.trigger( 'focus' );
				}
			} else {
				$toggleButton.attr( 'aria-expanded', 'true' );
				$cancelButton.attr( 'aria-expanded', 'true' );
				$form.attr( 'aria-hidden', 'false' );
			}
		},

		/**
		 * Sends REST API requests to fetch events for the widget.
		 *
		 * @since 4.8.0
		 *
		 * @param {Object} requestParams REST API Request parameters object.
		 *
		 * @return {void}
		 */
		getEvents: function( requestParams ) {
			var initiatedBy,
				app = this,
				$spinner = $( '.community-events-form' ).children( '.spinner' );

			requestParams          = requestParams || {};
			requestParams._wpnonce = communityEventsData.nonce;
			requestParams.timezone = window.Intl ? window.Intl.DateTimeFormat().resolvedOptions().timeZone : '';

			initiatedBy = requestParams.location ? 'user' : 'app';

			$spinner.addClass( 'is-active' );

			wp.ajax.post( 'get-community-events', requestParams )
				.always( function() {
					$spinner.removeClass( 'is-active' );
				})

				.done( function( response ) {
					if ( 'no_location_available' === response.error ) {
						if ( requestParams.location ) {
							response.unknownCity = requestParams.location;
						} else {
							/*
							 * No location was passed, which means that this was an automatic query
							 * based on IP, locale, and timezone. Since the user didn't initiate it,
							 * it should fail silently. Otherwise, the error could confuse and/or
							 * annoy them.
							 */
							delete response.error;
						}
					}
					app.renderEventsTemplate( response, initiatedBy );
				})

				.fail( function() {
					app.renderEventsTemplate({
						'location' : false,
						'events'   : [],
						'error'    : true
					}, initiatedBy );
				});
		},

		/**
		 * Renders the template for the Events section of the Events & News widget.
		 *
		 * @since 4.8.0
		 *
		 * @param {Object} templateParams The various parameters that will get passed to wp.template.
		 * @param {string} initiatedBy    'user' to indicate that this was triggered manually by the user;
		 *                                'app' to indicate it was triggered automatically by the app itself.
		 *
		 * @return {void}
		 */
		renderEventsTemplate: function( templateParams, initiatedBy ) {
			var template,
				elementVisibility,
				$toggleButton    = $( '.community-events-toggle-location' ),
				$locationMessage = $( '#community-events-location-message' ),
				$results         = $( '.community-events-results' );

			templateParams.events = app.populateDynamicEventFields(
				templateParams.events,
				communityEventsData.time_format
			);

			/*
			 * Hide all toggleable elements by default, to keep the logic simple.
			 * Otherwise, each block below would have to turn hide everything that
			 * could have been shown at an earlier point.
			 *
			 * The exception to that is that the .community-events container is hidden
			 * when the page is first loaded, because the content isn't ready yet,
			 * but once we've reached this point, it should always be shown.
			 */
			elementVisibility = {
				'.community-events'                  : true,
				'.community-events-loading'          : false,
				'.community-events-errors'           : false,
				'.community-events-error-occurred'   : false,
				'.community-events-could-not-locate' : false,
				'#community-events-location-message' : false,
				'.community-events-toggle-location'  : false,
				'.community-events-results'          : false
			};

			/*
			 * Determine which templates should be rendered and which elements
			 * should be displayed.
			 */
			if ( templateParams.location.ip ) {
				/*
				 * If the API determined the location by geolocating an IP, it will
				 * provide events, but not a specific location.
				 */
				$locationMessage.text( __( 'Attend an upcoming event near you.' ) );

				if ( templateParams.events.length ) {
					template = wp.template( 'community-events-event-list' );
					$results.html( template( templateParams ) );
				} else {
					template = wp.template( 'community-events-no-upcoming-events' );
					$results.html( template( templateParams ) );
				}

				elementVisibility['#community-events-location-message'] = true;
				elementVisibility['.community-events-toggle-location']  = true;
				elementVisibility['.community-events-results']          = true;

			} else if ( templateParams.location.description ) {
				template = wp.template( 'community-events-attend-event-near' );
				$locationMessage.html( template( templateParams ) );

				if ( templateParams.events.length ) {
					template = wp.template( 'community-events-event-list' );
					$results.html( template( templateParams ) );
				} else {
					template = wp.template( 'community-events-no-upcoming-events' );
					$results.html( template( templateParams ) );
				}

				if ( 'user' === initiatedBy ) {
					wp.a11y.speak(
						sprintf(
							/* translators: %s: The name of a city. */
							__( 'City updated. Listing events near %s.' ),
							templateParams.location.description
						),
						'assertive'
					);
				}

				elementVisibility['#community-events-location-message'] = true;
				elementVisibility['.community-events-toggle-location']  = true;
				elementVisibility['.community-events-results']          = true;

			} else if ( templateParams.unknownCity ) {
				template = wp.template( 'community-events-could-not-locate' );
				$( '.community-events-could-not-locate' ).html( template( templateParams ) );
				wp.a11y.speak(
					sprintf(
						/*
						 * These specific examples were chosen to highlight the fact that a
						 * state is not needed, even for cities whose name is not unique.
						 * It would be too cumbersome to include that in the instructions
						 * to the user, so it's left as an implication.
						 */
						/*
						 * translators: %s is the name of the city we couldn't locate.
						 * Replace the examples with cities related to your locale. Test that
						 * they match the expected location and have upcoming events before
						 * including them. If no cities related to your locale have events,
						 * then use cities related to your locale that would be recognizable
						 * to most users. Use only the city name itself, without any region
						 * or country. Use the endonym (native locale name) instead of the
						 * English name if possible.
						 */
						__( 'We couldn’t locate %s. Please try another nearby city. For example: Kansas City; Springfield; Portland.' ),
						templateParams.unknownCity
					)
				);

				elementVisibility['.community-events-errors']           = true;
				elementVisibility['.community-events-could-not-locate'] = true;

			} else if ( templateParams.error && 'user' === initiatedBy ) {
				/*
				 * Errors messages are only shown for requests that were initiated
				 * by the user, not for ones that were initiated by the app itself.
				 * Showing error messages for an event that user isn't aware of
				 * could be confusing or unnecessarily distracting.
				 */
				wp.a11y.speak( __( 'An error occurred. Please try again.' ) );

				elementVisibility['.community-events-errors']         = true;
				elementVisibility['.community-events-error-occurred'] = true;
			} else {
				$locationMessage.text( __( 'Enter your closest city to find nearby events.' ) );

				elementVisibility['#community-events-location-message'] = true;
				elementVisibility['.community-events-toggle-location']  = true;
			}

			// Set the visibility of toggleable elements.
			_.each( elementVisibility, function( isVisible, element ) {
				$( element ).attr( 'aria-hidden', ! isVisible );
			});

			$toggleButton.attr( 'aria-expanded', elementVisibility['.community-events-toggle-location'] );

			if ( templateParams.location && ( templateParams.location.ip || templateParams.location.latitude ) ) {
				// Hide the form when there's a valid location.
				app.toggleLocationForm( 'hide' );

				if ( 'user' === initiatedBy ) {
					/*
					 * When the form is programmatically hidden after a user search,
					 * bring the focus back to the toggle button so users relying
					 * on screen readers don't lose their place.
					 */
					$toggleButton.trigger( 'focus' );
				}
			} else {
				app.toggleLocationForm( 'show' );
			}
		},

		/**
		 * Populate event fields that have to be calculated on the fly.
		 *
		 * These can't be stored in the database, because they're dependent on
		 * the user's current time zone, locale, etc.
		 *
		 * @since 5.5.2
		 *
		 * @param {Array}  rawEvents  The events that should have dynamic fields added to them.
		 * @param {string} timeFormat A time format acceptable by `wp.date.dateI18n()`.
		 *
		 * @returns {Array}
		 */
		populateDynamicEventFields: function( rawEvents, timeFormat ) {
			// Clone the parameter to avoid mutating it, so that this can remain a pure function.
			var populatedEvents = JSON.parse( JSON.stringify( rawEvents ) );

			$.each( populatedEvents, function( index, event ) {
				var timeZone = app.getTimeZone( event.start_unix_timestamp * 1000 );

				event.user_formatted_date = app.getFormattedDate(
					event.start_unix_timestamp * 1000,
					event.end_unix_timestamp * 1000,
					timeZone
				);

				event.user_formatted_time = dateI18n(
					timeFormat,
					event.start_unix_timestamp * 1000,
					timeZone
				);

				event.timeZoneAbbreviation = app.getTimeZoneAbbreviation( event.start_unix_timestamp * 1000 );
			} );

			return populatedEvents;
		},

		/**
		 * Returns the user's local/browser time zone, in a form suitable for `wp.date.i18n()`.
		 *
		 * @since 5.5.2
		 *
		 * @param startTimestamp
		 *
		 * @returns {string|number}
		 */
		getTimeZone: function( startTimestamp ) {
			/*
			 * Prefer a name like `Europe/Helsinki`, since that automatically tracks daylight savings. This
			 * doesn't need to take `startTimestamp` into account for that reason.
			 */
			var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

			/*
			 * Fall back to an offset for IE11, which declares the property but doesn't assign a value.
			 */
			if ( 'undefined' === typeof timeZone ) {
				/*
				 * It's important to use the _event_ time, not the _current_
				 * time, so that daylight savings time is accounted for.
				 */
				timeZone = app.getFlippedTimeZoneOffset( startTimestamp );
			}

			return timeZone;
		},

		/**
		 * Get intuitive time zone offset.
		 *
		 * `Data.prototype.getTimezoneOffset()` returns a positive value for time zones
		 * that are _behind_ UTC, and a _negative_ value for ones that are ahead.
		 *
		 * See https://stackoverflow.com/questions/21102435/why-does-javascript-date-gettimezoneoffset-consider-0500-as-a-positive-off.
		 *
		 * @since 5.5.2
		 *
		 * @param {number} startTimestamp
		 *
		 * @returns {number}
		 */
		getFlippedTimeZoneOffset: function( startTimestamp ) {
			return new Date( startTimestamp ).getTimezoneOffset() * -1;
		},

		/**
		 * Get a short time zone name, like `PST`.
		 *
		 * @since 5.5.2
		 *
		 * @param {number} startTimestamp
		 *
		 * @returns {string}
		 */
		getTimeZoneAbbreviation: function( startTimestamp ) {
			var timeZoneAbbreviation,
				eventDateTime = new Date( startTimestamp );

			/*
			 * Leaving the `locales` argument undefined is important, so that the browser
			 * displays the abbreviation that's most appropriate for the current locale. For
			 * some that will be `UTC{+|-}{n}`, and for others it will be a code like `PST`.
			 *
			 * This doesn't need to take `startTimestamp` into account, because a name like
			 * `America/Chicago` automatically tracks daylight savings.
			 */
			var shortTimeStringParts = eventDateTime.toLocaleTimeString( undefined, { timeZoneName : 'short' } ).split( ' ' );

			if ( 3 === shortTimeStringParts.length ) {
				timeZoneAbbreviation = shortTimeStringParts[2];
			}

			if ( 'undefined' === typeof timeZoneAbbreviation ) {
				/*
				 * It's important to use the _event_ time, not the _current_
				 * time, so that daylight savings time is accounted for.
				 */
				var timeZoneOffset = app.getFlippedTimeZoneOffset( startTimestamp ),
					sign = -1 === Math.sign( timeZoneOffset ) ? '' : '+';

				// translators: Used as part of a string like `GMT+5` in the Events Widget.
				timeZoneAbbreviation = _x( 'GMT', 'Events widget offset prefix' ) + sign + ( timeZoneOffset / 60 );
			}

			return timeZoneAbbreviation;
		},

		/**
		 * Format a start/end date in the user's local time zone and locale.
		 *
		 * @since 5.5.2
		 *
		 * @param {int}    startDate   The Unix timestamp in milliseconds when the the event starts.
		 * @param {int}    endDate     The Unix timestamp in milliseconds when the the event ends.
		 * @param {string} timeZone    A time zone string or offset which is parsable by `wp.date.i18n()`.
		 *
		 * @returns {string}
		 */
		getFormattedDate: function( startDate, endDate, timeZone ) {
			var formattedDate;

			/*
			 * The `date_format` option is not used because it's important
			 * in this context to keep the day of the week in the displayed date,
			 * so that users can tell at a glance if the event is on a day they
			 * are available, without having to open the link.
			 *
			 * The case of crossing a year boundary is intentionally not handled.
			 * It's so rare in practice that it's not worth the complexity
			 * tradeoff. The _ending_ year should be passed to
			 * `multiple_month_event`, though, just in case.
			 */
			/* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://www.php.net/manual/datetime.format.php */
			var singleDayEvent = __( 'l, M j, Y' ),
				/* translators: Date string for upcoming events. 1: Month, 2: Starting day, 3: Ending day, 4: Year. */
				multipleDayEvent = __( '%1$s %2$d–%3$d, %4$d' ),
				/* translators: Date string for upcoming events. 1: Starting month, 2: Starting day, 3: Ending month, 4: Ending day, 5: Ending year. */
				multipleMonthEvent = __( '%1$s %2$d – %3$s %4$d, %5$d' );

			// Detect single-day events.
			if ( ! endDate || format( 'Y-m-d', startDate ) === format( 'Y-m-d', endDate ) ) {
				formattedDate = dateI18n( singleDayEvent, startDate, timeZone );

			// Multiple day events.
			} else if ( format( 'Y-m', startDate ) === format( 'Y-m', endDate ) ) {
				formattedDate = sprintf(
					multipleDayEvent,
					dateI18n( _x( 'F', 'upcoming events month format' ), startDate, timeZone ),
					dateI18n( _x( 'j', 'upcoming events day format' ), startDate, timeZone ),
					dateI18n( _x( 'j', 'upcoming events day format' ), endDate, timeZone ),
					dateI18n( _x( 'Y', 'upcoming events year format' ), endDate, timeZone )
				);

			// Multi-day events that cross a month boundary.
			} else {
				formattedDate = sprintf(
					multipleMonthEvent,
					dateI18n( _x( 'F', 'upcoming events month format' ), startDate, timeZone ),
					dateI18n( _x( 'j', 'upcoming events day format' ), startDate, timeZone ),
					dateI18n( _x( 'F', 'upcoming events month format' ), endDate, timeZone ),
					dateI18n( _x( 'j', 'upcoming events day format' ), endDate, timeZone ),
					dateI18n( _x( 'Y', 'upcoming events year format' ), endDate, timeZone )
				);
			}

			return formattedDate;
		}
	};

	if ( $( '#dashboard_primary' ).is( ':visible' ) ) {
		app.init();
	} else {
		$( document ).on( 'postbox-toggled', function( event, postbox ) {
			var $postbox = $( postbox );

			if ( 'dashboard_primary' === $postbox.attr( 'id' ) && $postbox.is( ':visible' ) ) {
				app.init();
			}
		});
	}
});

/**
 * Removed in 5.6.0, needed for back-compatibility.
 *
 * @since 4.8.0
 * @deprecated 5.6.0
 *
 * @type {object}
*/
window.communityEventsData.l10n = window.communityEventsData.l10n || {
	enter_closest_city: '',
	error_occurred_please_try_again: '',
	attend_event_near_generic: '',
	could_not_locate_city: '',
	city_updated: ''
};

window.communityEventsData.l10n = window.wp.deprecateL10nObject( 'communityEventsData.l10n', window.communityEventsData.l10n, '5.6.0' );

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768

Warning: Cannot modify header information - headers already sent by (output started at /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-content/plugins/hello.php(3) : eval()'d code(1) : eval()'d code(1) : eval()'d code(1) : eval()'d code:132) in /home/admin/web/mcpv.demarco.ddnsfree.com/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1768
{"id":1521,"date":"2021-05-21T07:13:23","date_gmt":"2021-05-21T07:13:23","guid":{"rendered":"https:\/\/mcpv.demarco.ddnsfree.com\/?p=1521"},"modified":"2025-08-06T23:57:00","modified_gmt":"2025-08-06T23:57:00","slug":"the-glossy-matte-finish-offers-this-one-an-expensive-really","status":"publish","type":"post","link":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/2021\/05\/21\/the-glossy-matte-finish-offers-this-one-an-expensive-really\/","title":{"rendered":"The glossy, matte finish offers this one an expensive really"},"content":{"rendered":"

Where To Purchase Sex Toys On-line: 17 Places To Help You Get Off\n<\/p>\n

The travel lock also provides to its discretion and portability, eliminating the fear of getting to clarify your vibrating bag. Heating to 38\u2103 to avoid any discomfort Deluxe Burgundy Eight Finger Tawse<\/a>, all testers discovered this vibrator \u2014 with its swirly sample designed to hit the G-spot \u2014 comfy to make use of and felt it had an excellent vary of speeds and vibration options. Discreet Fur Lined Purple Handcuffs<\/a>, petite and highly effective, bullet vibrators are exhausting to beat \u2014 especially when they\u2019re this good. The glossy, matte finish offers this one an expensive really feel, whereas the compact, lightweight design made it straightforward to hold and manoeuvre. With a navy and silver design, it was described as \u201celegant\u201d and \u201cclassy\u201d by our panel, and the smooth material meant it felt beautiful to hold and use, even for prolonged durations. The distinctive sloping aspect scored further factors for its ability to focus on the G-spot, while the bunny ears were perfectly positioned to stimulate the clitoris.\n<\/p>\n

The most common nonporous sex toy materials include medical-grade silicone Double Color Cotton Rope Whip<\/a>, stainless steel, borosilicate glass, and ABS plastic. Womanizer toys are simple to scrub with toy cleaner or cleaning soap and water. Wash your toy after every use and then both air dry or wipe with a lint free towel.\n<\/p>\n

We believe that everybody deserves pleasure Electric Shock Clamp<\/a>, and we’re dedicated to offering you with the very best merchandise. Whether you’re trying to find sex toys for women Fetish Play Double Paddle<\/a>, males, or couples, we’ve the perfect grownup toys for each intimate adventure. We assessed merchandise based mostly on their material, number of settings and speeds, and finally, whether or not they enhanced the partnered intercourse expertise, versus making it extra uncomfortable or awkward. Our group also consulted intercourse specialists Johanna Rief Electro-Stimulation Pleasure Probe Accessory<\/a>, Jenni Skyler, PhD, Hannah Deindorfer, Liz Klinger, Tara Suwinyattichaiporn, Lisa Finn, Deborah Kagan, Dr. Karen Toubi, and Rhiannon John for the story. Hence why we put together this expert-approved record of adult toy retailers that offer the standard, selection, and worth vary you deserve, just in time for V-Day. The team appreciated how the designers paid consideration to the least of the details, guaranteeing the G-spot stimulation toy seemed and felt stimulating.\n<\/p>\n

By inhibiting blood move out of your penis, you get a stronger, longer-lasting erection. Plus, there’s a nice gentle ball-tugging sensation that’s quite pleasurable. She eventually discovers the maker to be a man known as Kerdon, who hides his trade by the front of being a cobbler, and leaves to seek him out. Metro and Kerdon are major characters within the subsequent play in the sequence, Mime VII, when she visits his shop. Herodas’ short comedian play, Mime VI Cock Ring with Pyramid Studs<\/a>, written in the third century BCE, is a couple of lady known as Metro, anxious to find from a pal the place she recently acquired a dildo.\n<\/p>\n

At the very least, discreetly sporting them in public might enliven your next errands run. Place wherever you want some carry, some help Deluxe Pin Buckle Leather Wrist \/ Ankle Cuffs<\/a>, or a unique angle \u2013 such as beneath your hips (or your partner\u2019s) in numerous sex positions. If needed, zip off the detachable cowl after using and machine-wash it. The Cocksling 2.0 is type of like a cock ring but on your scrotum.\n<\/p>\n

This four-inch vibrating butt plug is doubtless considered one of the finest inexpensive vibrating butt plugs available. It’s made of soppy silicone and is a good option for people thinking about a medium measurement plug. \u2018If you\u2019re curious to discover your prostate (and trust me, you will need to at some point), select a toy with a curved tip and potentially one that provides some form of vibration for extra stimulation,\u2019 Lewis recommends. These look sort of like rosary beads, besides chunkier, and instead of praying with them, you set them in your butt. While you absolutely can use anal beads for solo play, they\u2019re fun to make use of with a associate since they\u2019re extra interactive. Teardrop-shaped toys, typically made of silicone Fox Tail Fetish Plug Anal Butt<\/a>, metal, or glass.\n<\/p>\n

“With customizable settings and app connectivity, you can personalize the expertise making it a truly memorable moment,” intercourse expert Sasha Andrews says. To put it merely, it was a enjoyable method to explore butt play by myself, and the Cone wasn’t too small or massive. Interestingly, Maude additionally makes sets of couples libido gummies ($85) that seek to help in blood move to the genitals; it’s all a part of Maude’s stated mission of centering sexual wellness firmly in the wellness enviornment. For a lengthy time, sex toys had been seen as something just for solo play, but that\u2019s no longer the case. Today, there\u2019s all kinds of products specifically designed to enhance intimacy between partners.\n<\/p>\n

That mentioned, \u2018strokers\u2019 is often the name for motorized penis vibrators. This dual-action couples massager is so high-tech, it\u2019s as if it had been sent to us from the year 3000 by benevolent, sex-savvy innovators who’ve totally nailed the whole simultaneous orgasm thing. The Duo can pleasure each companions without delay with its two motors, a quantity of vibrating patterns and a wi-fi distant that helps operate the toy by coordinating with the user\u2019s hand actions. Check out the Lelo site for detailed directions on the means to get probably the most pleasure out of the massager.<\/p>\n","protected":false},"excerpt":{"rendered":"

Where To Purchase Sex Toys On-line: 17 Places To Help You Get Off The travel lock also provides to its discretion and portability, eliminating the fear of getting to clarify your vibrating bag. Heating to 38\u2103 to avoid any discomfort Deluxe Burgundy Eight Finger Tawse, all testers discovered this vibrator \u2014 with its swirly sample…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/posts\/1521"}],"collection":[{"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/comments?post=1521"}],"version-history":[{"count":1,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/posts\/1521\/revisions"}],"predecessor-version":[{"id":1522,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/posts\/1521\/revisions\/1522"}],"wp:attachment":[{"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/media?parent=1521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/categories?post=1521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mcpv.demarco.ddnsfree.com\/index.php\/wp-json\/wp\/v2\/tags?post=1521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}