/* global List */ 'use strict'; var WPMailSMTP = window.WPMailSMTP || {}; WPMailSMTP.Admin = WPMailSMTP.Admin || {}; /** * WP Mail SMTP Admin area Code Snippets module. * * @since 4.9.0 */ WPMailSMTP.Admin.CodeSnippets = WPMailSMTP.Admin.CodeSnippets || ( function( document, window, $ ) { /** * Public functions and properties. * * @since 4.9.0 * * @type {object} */ var app = { /** * List.js instance for the snippet grid. * * @since 4.9.0 * * @type {object} */ snippetSearch: null, /** * Start the engine. DOM is not ready yet, use only to init something. * * @since 4.9.0 */ init: function() { $( app.ready ); }, /** * DOM is fully loaded. * * @since 4.9.0 */ ready: function() { app.snippetSearch = new List( 'wp-mail-smtp-wpcode-snippets-list', { valueNames: [ 'wp-mail-smtp-wpcode-snippet-title' ], } ); app.events(); }, /** * Bind events. * * @since 4.9.0 */ events: function() { // Fallback overlay button installs WPCode directly. $( '.wp-mail-smtp-wpcode-fallback-install-plugin' ).on( 'click', app.onFallbackInstallClick ); // Card "Install Snippet" (WPCode absent) opens the install-plugin popup. $( '.wp-mail-smtp-wpcode-install-plugin' ).on( 'click', app.openInstallPluginPopup ); // Card "Install Snippet" (WPCode installed but inactive) activates WPCode, then installs. $( '.wp-mail-smtp-wpcode-activate-plugin' ).on( 'click', app.onActivatePluginClick ); // "View" opens the code-preview modal. $( '.wp-mail-smtp-wpcode-view-snippet' ).on( 'click', app.openViewSnippetModal ); // Active-state "Install Snippet" shows an installing state before navigating to WPCode. $( '.wp-mail-smtp-wpcode-install-snippet' ).on( 'click', app.installSnippet ); $( '#wp-mail-smtp-wpcode-snippet-search' ).on( 'keyup search', function() { app.searchSnippet( this ); } ); }, /** * POST to an admin-ajax action with the nonce attached. * * @since 4.9.0 * * @param {string} action admin-ajax action name. * @param {object} extra Action-specific fields merged into the request. * * @returns {object} The jQuery jqXHR promise. */ post: function( action, extra ) { var data = $.extend( { action: action, nonce: window.wp_mail_smtp.nonce, }, extra || {} ); return $.post( window.wp_mail_smtp.ajax_url, data ); }, /** * Enter the installing state: hide the badge/label and overlay a spinner * on the button (CSS keeps the button width). * * @since 4.9.0 * * @param {object} $label Badge or "installing" label element. * @param {object} $button Action button element. */ setInstalling: function( $label, $button ) { $label.addClass( 'wp-mail-smtp-wpcode-installing-in-progress' ).text( window.wp_mail_smtp_code_snippets.installing_text ); $button.addClass( 'wp-mail-smtp-btn-loading' ); }, /** * Leave the installing state (used when a flow fails and the UI stays put). * * @since 4.9.0 * * @param {object} $label Badge or "installing" label element. * @param {object} $button Action button element. */ clearInstalling: function( $label, $button ) { $label.removeClass( 'wp-mail-smtp-wpcode-installing-in-progress' ).text( '' ); $button.removeClass( 'wp-mail-smtp-btn-loading' ); }, /** * Filter the snippet grid against the search field value. * * @since 4.9.0 * * @param {object} searchField The search field HTML element. */ searchSnippet: function( searchField ) { var searchTerm = $( searchField ).val(); var searchResults = app.snippetSearch.search( searchTerm ); var $noResults = $( '#wp-mail-smtp-wpcode-no-results' ); if ( searchResults.length === 0 ) { $noResults.show(); } else { $noResults.hide(); } }, /** * Active-state "Install Snippet": show an installing state, then let the * link navigate to WPCode's install screen (perceived-load only, no AJAX). * * @since 4.9.0 */ installSnippet: function() { var $button = $( this ); // Edit is a plain navigation to the WPCode edit screen; no JS needed. if ( $button.data( 'action' ) === 'edit' ) { return; } app.setInstalling( $button.closest( '.wp-mail-smtp-wpcode-snippet' ).find( '.wp-mail-smtp-wpcode-snippet-badge' ), $button ); }, /** * Card "Install Snippet" when WPCode is installed but inactive: activate * WPCode, then navigate to the snippet's install URL. On activation * failure, show the activation popup. * * @since 4.9.0 * * @param {object} event The click event. */ onActivatePluginClick: function( event ) { event.preventDefault(); var $button = $( this ); var $badge = $button.closest( '.wp-mail-smtp-wpcode-snippet' ).find( '.wp-mail-smtp-wpcode-snippet-badge' ); app.setInstalling( $badge, $button ); app.activatePluginThenInstallSnippet( $button.data( 'library-id' ), $button.data( 'plugin' ), function() { app.clearInstalling( $badge, $button ); app.showManualActivationPluginPopup(); } ); }, /** * Activate WPCode via AJAX, then resolve the snippet's install URL via a * second AJAX request and navigate there. If activation fails, run the * provided callback; if only the URL lookup fails, reload so the tab * re-renders in its active state. * * @since 4.9.0 * * @param {number} libraryId The snippet library id. * @param {string} plugin WPCode plugin path. * @param {Function} onActivateFail Called when activation fails. */ activatePluginThenInstallSnippet: function( libraryId, plugin, onActivateFail ) { app.post( 'wp_mail_smtp_ajax', { task: 'about_plugin_activate', plugin: plugin } ) .done( function( response ) { if ( ! response || ! response.success ) { onActivateFail(); return; } app.navigateToSnippetInstall( libraryId ); } ) .fail( function() { onActivateFail(); } ); }, /** * Resolve a snippet's WPCode install URL (now that WPCode is active) via * AJAX and navigate to it. Falls back to a reload if the URL can't be * resolved, so the tab still re-renders in its active state. * * @since 4.9.0 * * @param {number} libraryId The snippet library id. */ navigateToSnippetInstall: function( libraryId ) { var extra = {}; extra['library_id'] = libraryId; // eslint-disable-line dot-notation app.post( 'wp_mail_smtp_get_wpcode_snippet_install_url', extra ) .done( function( response ) { if ( response && response.success && response.data && response.data.install_url ) { window.location.href = response.data.install_url; return; } window.location.reload(); } ) .fail( function() { window.location.reload(); } ); }, /** * Install and activate WPCode via AJAX. Runs onDone on full success, or * onError('install') if the install failed / errored, or onError('activate') * if WPCode installed but silent activation failed. * * WP returns logical failures with HTTP 200 + success:false, so a failed * install lands in .done (not .fail) and must be checked explicitly. * * @since 4.9.0 * * @param {string} plugin WPCode download URL. * @param {Function} onDone Called after a successful install + activation. * @param {Function} onError Called with 'install' or 'activate' on failure. */ installAndActivatePlugin: function( plugin, onDone, onError ) { app.post( 'wp_mail_smtp_ajax', { task: 'about_plugin_install', plugin: plugin } ) .done( function( response ) { if ( ! response || ! response.success ) { onError( 'install' ); return; } if ( response.data && response.data.is_activated === false ) { onError( 'activate' ); return; } onDone(); } ) .fail( function() { onError( 'install' ); } ); }, /** * Show the activate-WPCode popup. Its button forwards to the Plugins page * activation action for the installed WPCode plugin. * * @since 4.9.0 */ showManualActivationPluginPopup: function() { var l10n = window.wp_mail_smtp_code_snippets; $.confirm( { title: l10n.activate_popup_title, container: '#wp-mail-smtp', boxWidth: '600px', useBootstrap: false, closeIcon: true, draggable: false, content: '
' + l10n.activate_popup_desc + '
', buttons: { activate: { text: l10n.activate_popup_btn, btnClass: 'btn btn-confirm', action: function( button ) { button.addClass( 'wp-mail-smtp-btn-loading' ); window.location.href = l10n.activate_url; // Keep the popup open so the loader stays visible during navigation. return false; }, }, }, } ); }, /** * Map a snippet code_type to a CodeMirror mode. * * @since 4.9.0 * * @param {string} codeType Snippet code type. * * @returns {string} CodeMirror mode. */ mapMode: function( codeType ) { switch ( codeType ) { case 'js': case 'javascript': return 'javascript'; case 'css': return 'css'; case 'html': return 'htmlmixed'; default: return 'text/x-php'; } }, /** * Open the read-only code-preview modal for a snippet. * * @since 4.9.0 * * @param {object} event The click event. */ openViewSnippetModal: function( event ) { event.preventDefault(); var $btn = $( this ); var libraryId = $btn.data( 'library-id' ); var installUrl = $btn.data( 'install-url' ); var plugin = $btn.data( 'plugin' ); var l10n = window.wp_mail_smtp_code_snippets; // $.dialog has no jconfirm button row (whose styles can't be overridden // cleanly) — the action button is rendered inside our own content. $.dialog( { title: l10n.loading_text, container: '#wp-mail-smtp', boxWidth: '720px', useBootstrap: false, closeIcon: true, draggable: false, content: 'During the nineteenth century, Sicily underwent a series of political and land reforms that led to dismantling of large land ownership and culminated in the unification with the Italian state in 1861. But the new Italian government was ineffective at enforcing the rule of law on the island. Banditry and a general sense of lawlessness proliferated. In that environment, the mafia emerged as a private response to the inadequate protection by the state. The mafia offered private protection from bandits to landowners who could not rely on protection and enforcement of property rights by the state. The mafia, however, was not equally active on the entire island. This study uses economic principles to explain the emergence of the mafia in wealthier regions and its absence in the poorer districts despite the greater levels of banditry. We develop a feedback model that incorporates causal relationships between the mafia’s activities, predation, law enforcement, and the profitability of the local businesses. Using computational experiments, we explore how various factors impact the mafia’s activities.

The feedback model. Rectangles are state variables Peasants, Bandits and Mafia. If the economy is bad, some peasants turn to banditry; the mafia members are recruited from among the bandits. Arrows indicate causal relationships between variables. If an arrow is positive, the relationship between the cause and effect is positive. A negative arrow implies that an increase in one variable causes a decline in the other variable. Circular causal links form reinforcing and balancing feedback loops. A reinforcing loop is shown with the letter R and a balancing loop is shown with the letter B.
Publication
Pavlov, O. and J. Sardell. “Economic Origins of the Sicilian Mafia: A Simulation Feedback Model.” In: Cavana, R.Y, B.C. Dangerfield , O.V. Pavlov, M.J. Radzicki and I.D. Wheat (Eds). Feedback Economics: Economic Modeling with System Dynamics. New York: Springer. 2021: 137-161. Pre-print on SSRN.
]]>