/** * jQuery fontIconPicker - v2.3 * * An icon picker built on top of font icons and jQuery * * http://codeb.it/fontIconPicker * * Made by Alessandro Benoit & Swashata * Under MIT License * * {@link https://github.com/micc83/fontIconPicker} * * Modified by Visual Composer Dev Team */ (function ( $ ) { 'use strict'; // Create the defaults once var defaults = { theme: 'fip-vc-theme-grey', // The CSS theme to use with this fontIconPicker. You can set different themes on multiple elements on the same page source: false, // Icons source (array|false|object) emptyIcon: true, // Empty icon should be shown? emptyIconValue: '', // The value of the empty icon, change if you select has something else, say "none" iconsPerPage: 20, // Number of icons per page hasSearch: true, // Is search enabled? searchSource: false, // Give a manual search values. If using attributes then for proper search feature we also need to pass icon names under the same order of source useAttribute: false, // Whether to use attribute selector for printing icons attributeName: 'data-icon', // HTML Attribute name convertToHex: true, // Whether or not to convert to hexadecimal for attribute value. If true then please pass decimal integer value to the source (or as value="" attribute of the select field) allCategoryText: 'From all categories', // The text for the select all category option unCategorizedText: 'Uncategorized', // The text for the select uncategorized option iconDownClass: 'fip-icon-down-dir', // Class for icon down iconUpClass: 'fip-icon-up-dir', // Class for icon up iconLeftClass: 'fip-icon-left-dir', // Class for icon left iconRightClass: 'fip-icon-right-dir', // Class for icon right iconSearchClass: 'fip-icon-search', // Class for search iconCancelClass: 'fip-icon-cancel', // Class for search canceling iconSpinClass: 'fip-icon-spin3', // Class for fip-icon-spin3 iconBlockClass: 'fip-icon-block', // Class for block(none icon) searchPlaceholder: 'Search Icon', // Search icon text placeholder mainClass: 'vc-icons-selector' }; // The actual plugin constructor function Plugin( element, options ) { this.element = $( element ); this.settings = $.extend( {}, defaults, options ); if ( this.settings.emptyIcon ) { this.settings.iconsPerPage --; } this.iconPicker = $( '
', { 'class': this.settings.mainClass, style: 'position: relative', html: '
' + '' + '' + '' + '' + '' + '' + '
' + '' } ); this.iconContainer = this.iconPicker.find( '.fip-icons-container' ); this.searchIcon = this.iconPicker.find( '.selector-search i' ); this.iconsSearched = []; this.isSearch = false; this.totalPage = 1; this.currentPage = 1; this.currentIcon = false; this.initialized = false; this.iconsPaged = false; this.iconsCount = 0; this.open = false; // Set the default values for the search related variables this.searchValues = []; this.availableCategoriesSearch = []; // The trigger event for change this.triggerEvent = null; // Backups this.backupSource = []; this.backupSearch = []; // Set the default values of the category related variables this.isCategorized = false; // Automatically detects if the icon listing is categorized this.selectCategory = this.iconPicker.find( '.icon-category-select' ); // The category SELECT input field this.selectedCategory = false; // false means all categories are selected this.availableCategories = []; // Available categories, it is a two dimensional array which holds categorized icons this.unCategorizedKey = null; // Key of the uncategorized category // Initialize plugin this.quickInit(); } Plugin.prototype = { /** * Quick init */ quickInit: function () { var first = true; // Add the theme CSS to the iconPicker this.iconPicker.addClass( this.settings.theme ); // To properly calculate iconPicker height and width // We will first append it to body (with left: -9999px so that it is not visible) this.iconPicker.css( { left: - 9999 } ).appendTo( 'body' ); var iconPickerHeight = this.iconPicker.outerHeight(), iconPickerWidth = this.iconPicker.outerWidth(); // Now reset the iconPicker CSS this.iconPicker.css( { left: '' } ); // Add the icon picker after the select this.element.before( this.iconPicker ); // Hide source element // Instead of doing a display:none, we would rather // make the element invisible // and adjust the margin this.element.css( { visibility: 'hidden', top: 0, position: 'relative', zIndex: '-1', left: '-' + iconPickerWidth + 'px', display: 'none', height: iconPickerHeight + 'px', width: iconPickerWidth + 'px', // Reset all margin, border and padding padding: '0', margin: '0 -' + iconPickerWidth + 'px 0 0', // Left margin adjustment to account for dangling space border: '0 none', verticalAlign: 'top' } ).hide(); // Set the trigger event if ( ! this.element.is( 'select' ) ) { // Determine the event that is fired when user change the field value // Most modern browsers supports input event except IE 7, 8. // IE 9 supports input event but the event is still not fired if I press the backspace key. // Get IE version // https://gist.github.com/padolsey/527683/#comment-7595 var ieVersion = (function () { var v = 3, div = document.createElement( 'div' ), a = div.all || []; while ( div.innerHTML = '', a[ 0 ] ) { ; } return v > 4 ? v : ! v; }()); var el = document.createElement( 'div' ); this.triggerEvent = (ieVersion === 9 || ! ('oninput' in el)) ? [ 'keyup' ] : [ 'input', 'keyup' ]; // Let's keep the keyup event for scripts that listens to it } this.setSelectedIcon( this.element.val() ); /** * Category changer */ this.selectCategory.on( 'change keyup', $.proxy( function ( e ) { // Don't do anything if not categorized if ( this.isCategorized === false ) { return false; } var targetSelect = $( e.currentTarget ), currentCategory = targetSelect.val(); // Check if all categories are selected if ( targetSelect.val() === 'all' ) { // Restore from the backups // @note These backups must be rebuild on source change, otherwise it will lead to error this.settings.source = this.backupSource; this.searchValues = this.backupSearch; // No? So there is a specified category } else { var key = parseInt( currentCategory, 10 ); if ( this.availableCategories[ key ] ) { this.settings.source = this.availableCategories[ key ]; this.searchValues = this.availableCategoriesSearch[ key ]; } } this.resetSearch(); this.loadIcons(); }, this ) ); /** * On down arrow click */ this.iconPicker.find( '.selector-button' ).on( 'click', $.proxy( function () { if ( ! this.open && first ) { first = false; this.initCategories(); } // Open/Close the icon picker this.toggleIconSelector(); }, this ) ); /** * Next page */ this.iconPicker.find( '.selector-arrow-right' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage < this.totalPage ) { this.iconPicker.find( '.selector-arrow-left' ).show(); this.currentPage = this.currentPage + 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === this.totalPage ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Prev page */ this.iconPicker.find( '.selector-arrow-left' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); this.currentPage = this.currentPage - 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === 1 ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Realtime Icon Search */ this.iconPicker.find( '.icons-search-input' ).on( 'keyup', $.proxy( function ( e ) { // Get the search string var searchString = $( e.currentTarget ).val(); // If the string is not empty if ( searchString === '' ) { this.resetSearch(); return; } // Set icon search to X to reset search this.searchIcon.removeClass( this.settings.iconSearchClass ); this.searchIcon.addClass( this.settings.iconCancelClass ); // Set this as a search this.isSearch = true; // Reset current page this.currentPage = 1; // Actual search // This has been modified to search the searchValues instead // Then return the value from the source if match is found this.iconsSearched = []; $.grep( this.searchValues, $.proxy( function ( n, i ) { if ( n.toLowerCase().search( searchString.toLowerCase() ) >= 0 ) { this.iconsSearched[ this.iconsSearched.length ] = this.settings.source[ i ]; return true; } }, this ) ); // Filter duplicates this.iconsSearched = this.iconsSearched.filter( this.getOnlyUnique ); // Render icon list this.renderIconContainer(); this.renderIcons(); }, this ) ); /** * Quit search */ this.iconPicker.find( '.selector-search i' ).on( 'click', $.proxy( function () { this.iconPicker.find( '.icons-search-input' ).focus(); this.resetSearch(); }, this ) ); /** * On icon selected */ this.iconContainer.on( 'click', '.fip-box', $.proxy( function ( e ) { this.setSelectedIcon( $( e.currentTarget ).find( 'i' ).attr( 'data-fip-value' ) ); this.toggleIconSelector(); }, this ) ); /** * Stop click propagation on iconpicker */ this.iconPicker.on( 'click', function ( event ) { event.stopPropagation(); return false; } ); /** * On click out */ $( 'html' ).on( 'click', $.proxy( function () { if ( this.open ) { this.toggleIconSelector(); } }, this ) ); }, /** * Init */ init: function () { // Add the theme CSS to the iconPicker this.iconPicker.addClass( this.settings.theme ); // To properly calculate iconPicker height and width // We will first append it to body (with left: -9999px so that it is not visible) this.iconPicker.css( { left: - 9999 } ).appendTo( 'body' ); var iconPickerHeight = this.iconPicker.outerHeight(), iconPickerWidth = this.iconPicker.outerWidth(); // Now reset the iconPicker CSS this.iconPicker.css( { left: '' } ); // Add the icon picker after the select this.element.before( this.iconPicker ); // Hide source element // Instead of doing a display:none, we would rather // make the element invisible // and adjust the margin this.element.css( { visibility: 'hidden', top: 0, position: 'relative', zIndex: '-1', left: '-' + iconPickerWidth + 'px', display: 'none', height: iconPickerHeight + 'px', width: iconPickerWidth + 'px', // Reset all margin, border and padding padding: '0', margin: '0 -' + iconPickerWidth + 'px 0 0', // Left margin adjustment to account for dangling space border: '0 none', verticalAlign: 'top' } ).hide(); // Set the trigger event if ( ! this.element.is( 'select' ) ) { // Determine the event that is fired when user change the field value // Most modern browsers supports input event except IE 7, 8. // IE 9 supports input event but the event is still not fired if I press the backspace key. // Get IE version // https://gist.github.com/padolsey/527683/#comment-7595 var ieVersion = (function () { var v = 3, div = document.createElement( 'div' ), a = div.all || []; while ( div.innerHTML = '', a[ 0 ] ) { ; } return v > 4 ? v : ! v; }()); var el = document.createElement( 'div' ); this.triggerEvent = (ieVersion === 9 || ! ('oninput' in el)) ? [ 'keyup' ] : [ 'input', 'keyup' ]; // Let's keep the keyup event for scripts that listens to it } this.initCategories(); /** * Category changer */ this.selectCategory.on( 'change keyup', $.proxy( function ( e ) { // Don't do anything if not categorized if ( this.isCategorized === false ) { return false; } var targetSelect = $( e.currentTarget ), currentCategory = targetSelect.val(); // Check if all categories are selected if ( targetSelect.val() === 'all' ) { // Restore from the backups // @note These backups must be rebuild on source change, otherwise it will lead to error this.settings.source = this.backupSource; this.searchValues = this.backupSearch; // No? So there is a specified category } else { var key = parseInt( currentCategory, 10 ); if ( this.availableCategories[ key ] ) { this.settings.source = this.availableCategories[ key ]; this.searchValues = this.availableCategoriesSearch[ key ]; } } this.resetSearch(); this.loadIcons(); }, this ) ); /** * On down arrow click */ this.iconPicker.find( '.selector-button' ).on( 'click', $.proxy( function () { // Open/Close the icon picker this.toggleIconSelector(); }, this ) ); /** * Next page */ this.iconPicker.find( '.selector-arrow-right' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage < this.totalPage ) { this.iconPicker.find( '.selector-arrow-left' ).show(); this.currentPage = this.currentPage + 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === this.totalPage ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Prev page */ this.iconPicker.find( '.selector-arrow-left' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); this.currentPage = this.currentPage - 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === 1 ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Realtime Icon Search */ this.iconPicker.find( '.icons-search-input' ).on( 'keyup', $.proxy( function ( e ) { // Get the search string var searchString = $( e.currentTarget ).val(); // If the string is not empty if ( searchString === '' ) { this.resetSearch(); return; } // Set icon search to X to reset search this.searchIcon.removeClass( this.settings.iconSearchClass ); this.searchIcon.addClass( this.settings.iconCancelClass ); // Set this as a search this.isSearch = true; // Reset current page this.currentPage = 1; // Actual search // This has been modified to search the searchValues instead // Then return the value from the source if match is found this.iconsSearched = []; $.grep( this.searchValues, $.proxy( function ( n, i ) { if ( n.toLowerCase().search( searchString.toLowerCase() ) >= 0 ) { this.iconsSearched[ this.iconsSearched.length ] = this.settings.source[ i ]; return true; } }, this ) ); // Filter duplicates this.iconsSearched = this.iconsSearched.filter( this.getOnlyUnique ); // Render icon list this.renderIconContainer(); this.renderIcons(); }, this ) ); /** * Quit search */ this.iconPicker.find( '.selector-search i' ).on( 'click', $.proxy( function () { this.iconPicker.find( '.icons-search-input' ).focus(); this.resetSearch(); }, this ) ); /** * On icon selected */ this.iconContainer.on( 'click', '.fip-box', $.proxy( function ( e ) { this.setSelectedIcon( $( e.currentTarget ).find( 'i' ).attr( 'data-fip-value' ) ); this.toggleIconSelector(); }, this ) ); /** * Stop click propagation on iconpicker */ this.iconPicker.on( 'click', function ( event ) { event.stopPropagation(); return false; } ); /** * On click out */ $( 'html' ).on( 'click', $.proxy( function () { if ( this.open ) { this.toggleIconSelector(); } }, this ) ); }, initCategories: function () { // If current element is SELECT populate settings.source if ( ! this.settings.source && this.element.is( 'select' ) ) { // Reset the source and searchSource // These will be populated according to the available options this.settings.source = []; this.settings.searchSource = []; // Check if optgroup is present within the select // If it is present then the source has to be grouped if ( this.element.find( 'optgroup' ).length ) { // Set the categorized to true this.isCategorized = true; this.element.find( 'optgroup' ).each( $.proxy( function ( i, el ) { // Get the key of the new category array var thisCategoryKey = this.availableCategories.length, // Create the new option for the selectCategory SELECT field categoryOption = $( '' ).prependTo( this.selectCategory ); // Show it and set default value to all categories this.selectCategory.show().val( 'all' ).trigger( 'change' ); }, /** * Load icons */ loadIcons: function () { // Set the content of the popup as loading this.iconContainer.html( '' ); // If source is set if ( this.settings.source instanceof Array ) { // Render icons this.renderIconContainer(); this.renderIcons(); this.setContainerSelectedItems(); } }, /** * Render icons inside the popup */ renderIconContainer: function () { var offset, iconsPaged = []; // Set a temporary array for icons if ( this.isSearch ) { iconsPaged = this.iconsSearched; } else { iconsPaged = this.settings.source; } // Remove duplicates iconsPaged = [ ...new Set( iconsPaged ) ]; // Count elements this.iconsCount = iconsPaged.length; // Calculate total page number this.totalPage = Math.ceil( this.iconsCount / this.settings.iconsPerPage ); // Hide footer if no pagination is needed if ( this.totalPage > 1 ) { this.iconPicker.find( '.selector-footer' ).show(); } else { this.iconPicker.find( '.selector-footer' ).hide(); } // Set the text for page number index and total icons this.iconPicker.find( '.selector-pages' ).html( this.currentPage + '/' + this.totalPage + ' (' + this.iconsCount + ')' ); // Set the offset for slice offset = (this.currentPage - 1) * this.settings.iconsPerPage; // Should empty icon be shown? if ( this.settings.emptyIcon ) { // Reset icon container HTML and prepend empty icon this.iconContainer.html( '' ); // If not show an error when no icons are found } else if ( iconsPaged.length < 1 ) { this.iconContainer.html( '' ); return; // else empty the container } else { this.iconContainer.html( '' ); } // Set an array of current page icons iconsPaged = iconsPaged.slice( offset, offset + this.settings.iconsPerPage ); this.iconsPaged = iconsPaged; // List icons /*for (var i = 0, item; item = iconsPaged[i++];) { // Set the icon title var flipBoxTitle = item; $.grep(this.settings.source, $.proxy(function (e, i) { if (e === item) { flipBoxTitle = this.searchValues[i]; return true; } return false; }, this)); // Set the icon box $('', { html: '', 'class': 'fip-box', title: flipBoxTitle }).appendTo(this.iconContainer); }*/ }, setContainerSelectedItems: function () { // If no empty icon is allowed and no current value is set or current value is not inside the icon set if ( ! this.settings.emptyIcon && (! this.element.val() || $.inArray( this.element.val(), this.settings.source ) === - 1) ) { // Get the first icon this.setSelectedIcon( this.iconsPaged[ 0 ] ); } else if ( $.inArray( this.element.val(), this.settings.source ) === - 1 ) { // Set empty this.setSelectedIcon(); } else { // Set the default selected icon even if not set this.setSelectedIcon( this.element.val() ); } }, /** * Set Highlighted icon */ setHighlightedIcon: function () { this.iconContainer.find( '.current-icon' ).removeClass( 'current-icon' ); if ( this.currentIcon ) { this.iconContainer.find( '[data-fip-value="' + this.currentIcon + '"]' ).parent( 'span' ).addClass( 'current-icon' ); } }, /** * Set selected icon * * @param {string} theIcon */ setSelectedIcon: function ( theIcon ) { if ( theIcon === this.settings.iconBlockClass ) { theIcon = ''; } // Check if attribute is to be used if ( this.settings.useAttribute ) { if ( theIcon ) { this.iconPicker.find( '.selected-icon' ).html( '' ); } else { this.iconPicker.find( '.selected-icon' ).html( '' ); } // Use class } else { this.iconPicker.find( '.selected-icon' ).html( '' ); } // Set the value of the element and trigger change event this.element.val( (theIcon === '' ? this.settings.emptyIconValue : theIcon ) ).trigger( 'change' ); if ( this.triggerEvent !== null ) { // Trigger other events for ( var eventKey in this.triggerEvent ) { this.element.trigger( this.triggerEvent[ eventKey ] ); } } this.currentIcon = theIcon; this.setHighlightedIcon(); }, /** * Open/close popup (toggle) */ toggleIconSelector: function () { this.open = (! this.open) ? 1 : 0; this.iconPicker.find( '.selector-popup' ).slideToggle( 300 ); this.iconPicker.find( '.selector-button i' ).toggleClass( this.settings.iconDownClass ); this.iconPicker.find( '.selector-button i' ).toggleClass( this.settings.iconUpClass ); if ( this.open ) { this.iconPicker.find( '.icons-search-input' ).focus().select(); if ( ! this.initialized ) { this.renderIconContainer(); this.renderIcons(); this.initialized = true; } } }, renderIcons: function () { for ( var i = 0; i < this.iconsPaged.length; i ++ ) { var item = this.iconsPaged[ i ]; // Set the icon title var flipBoxTitle = item; $.grep( this.settings.source, $.proxy( function ( e, i ) { if ( e === item ) { flipBoxTitle = this.searchValues[ i ]; return true; } return false; }, this ) ); // Set the icon box $( '', { html: '', 'class': 'fip-box', title: flipBoxTitle } ).appendTo( this.iconContainer ); } this.setContainerSelectedItems(); }, /** * Reset search */ resetSearch: function () { // Empty input this.iconPicker.find( '.icons-search-input' ).val( '' ); // Reset search icon class this.searchIcon.removeClass( this.settings.iconCancelClass ); this.searchIcon.addClass( this.settings.iconSearchClass ); // Go back to page 1 and remove back arrow this.iconPicker.find( '.selector-arrow-left' ).hide(); this.currentPage = 1; this.isSearch = false; // Rerender icons this.renderIconContainer(); this.renderIcons(); // Restore pagination if needed if ( this.totalPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); } } }; // Lightweight plugin wrapper $.fn.vcFontIconPicker = function ( options ) { // Instantiate the plugin this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { $.data( this, "vcFontIconPicker", new Plugin( this, options ) ); } } ); // setIcons method this.setIcons = $.proxy( function ( newIcons, iconSearch ) { if ( undefined === newIcons ) { newIcons = false; } if ( undefined === iconSearch ) { iconSearch = false; } this.each( function () { $.data( this, "vcFontIconPicker" ).settings.source = newIcons; $.data( this, "vcFontIconPicker" ).settings.searchSource = iconSearch; $.data( this, "vcFontIconPicker" ).initSourceIndex(); $.data( this, "vcFontIconPicker" ).resetSearch(); $.data( this, "vcFontIconPicker" ).loadIcons(); } ); }, this ); // destroy method this.destroyPicker = $.proxy( function () { this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { return; } // Remove the iconPicker $.data( this, "vcFontIconPicker" ).iconPicker.remove(); // Reset the CSS $.data( this, "vcFontIconPicker" ).element.css( { visibility: '', top: '', position: '', zIndex: '', left: '', display: 'block', height: '', width: '', padding: '', margin: '', border: '', verticalAlign: '' } ).show(); // destroy data $.removeData( this, "vcFontIconPicker" ); } ); }, this ); // reInit method this.refreshPicker = $.proxy( function ( newOptions ) { if ( ! newOptions ) { newOptions = options; } // First destroy this.destroyPicker(); // Now reset this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { $.data( this, "vcFontIconPicker", new Plugin( this, newOptions ) ); } } ); }, this ); return this; }; })( jQuery ); # Changelog ## [Unreleased] ## [1.0.4] - 2024-05-02 ### Fixed - Fix implicit nullable deprecation warning for PHP 8.4 ## [1.0.3] - 2022-01-10 ### Changed - Update PHPstan to 1.0 - Switched to GitHub Actions ## [1.0.2] - 2020-07-15 ### Added - Minor performance improvements ## [1.0.1] - 2020-06-16 ### Fixed - When calling `Punycode::decode()`, the case flags array would fail to populate when given an empty array. ## [1.0.0] - 2020-06-09 - Initial release

Winter Wins: How This Year’s Holiday Tournament Bonuses Stack Up Across the Top Casino Platforms

The festive rush hits online casinos early this year, and the glittering lights aren’t just for show. Operators are loading their tournament ladders with extra spins, match‑play bonuses, and seasonal prize pools that make December feel like a high‑stakes snowball fight. For casual players, a free‑entry tournament can be the perfect excuse to test a new slot or try a live‑dealer showdown without denting the bankroll. High‑rollers, on the other hand, hunt the deep‑pocketed leaderboards where a single win can turn a modest deposit into a six‑figure payday.

Because the holiday season is also a time for joy‑sharing, many sites sprinkle their promotions with charitable nods. One such example is the annual celebration of mirth at https://www.worldlaughterday.org/, a resource that encourages people worldwide to spread happiness. While not a gambling authority, the site reminds us that a smile can be as valuable as any bonus.

This review breaks down the most compelling holiday tournament offers from four leading platforms. We’ll explain the criteria that make a tournament bonus worthwhile, give you a snapshot of each casino’s festive package, compare the numbers side‑by‑side, and hand you a final verdict so you can decide where to place your chips before the Christmas curtain falls.

What Makes a Holiday Tournament Bonus Worthwhile?

A “tournament bonus” is any extra perk that lowers the barrier to entry or inflates the prize pool for a limited‑time competition. Typical forms include a 100 % match deposit limited to a certain amount, free spins granted for tournament play, a cash‑back guarantee on losses, or even a direct boost to the leaderboard’s reward tier.

When weighing these offers, six criteria matter most:

  1. Bonus size – How much extra money or spins does the casino add?
  2. Qualification requirements – Deposit minimums, wagering limits, or specific game selections can turn an appealing bonus into a hidden trap.
  3. Duration – A tournament that runs from December 1‑31 gives plenty of time to climb the ranks, whereas a 48‑hour flash event rewards quick decision‑makers.
  4. Game variety – Slots, video‑poker, and live dealer tables each have distinct RTP profiles and volatility; the more games allowed, the broader the strategy options.
  5. Payout speed – Players love a bonus that clears within 24‑48 hours after the tournament ends.
  6. Seasonal branding – Creative themes (reindeer, snowflakes, candy‑cane jackpots) boost engagement but should not obscure the actual terms.

Early‑bird offers—usually announced the first week of December—often feature larger match percentages but stricter wagering. Last‑minute promotions may lower the deposit hurdle, appealing to players who decide to gamble after the holiday shopping frenzy.

Quick checklist for readers
– Is the deposit requirement realistic for my bankroll?
– Does the bonus apply to my preferred games?
– How many times must I wager before I can withdraw?
– What is the expected payout timeline?
– Does the tournament’s theme enhance or distract from the gameplay?

Use this list as a scanning tool; if a bonus fails more than two items, it’s probably not worth the chase.

Platform A – “Snowflake Spin” Casino

Snowflake Spin greets players with a frosted interface, animated snowflakes drifting across the screen, and a soundtrack of gentle chimes. Navigation is seamless on desktop and mobile, and the “Reindeer Rush” tournament sits front‑and‑center in the holiday hub.

The tournament bonus reads: 100 % match up to €200 plus 50 free spins on the “Winter Wonderland” slot. Entry is free, but players must deposit at least €20 to unlock the match and must wager the bonus amount three times before any winnings become withdrawable. Eligible games include all slot titles from the provider’s 2023 collection, plus a curated list of low‑variance video‑poker variants.

Prize‑pool breakdown: the top 10 leaderboard positions share a €5,000 pool, with the winner receiving €2,000, second place €1,200, and the remaining €1,800 divided among the rest. The tournament runs from December 5‑20, with daily leaderboards refreshed at 02:00 GMT.

Pros
– Low rake on slot play encourages higher win‑rate potential.
– The free‑spin component adds value without extra wagering.
– Mobile‑optimized tournament lobby reduces latency for live‑dealer entries.

Cons
– High competition; the 10‑player leaderboard fills within hours.
– Wagering requirement of 3× on the bonus can be steep for low‑budget players.

Metric Details
Bonus 100 % up to €200 + 50 free spins
Deposit min. €20
Wagering 3× bonus
Eligible games Slots + low‑vol video poker
Prize pool €5,000 total
Duration Dec 5‑20
Payout speed 24 h after tournament

Overall, Snowflake Spin delivers a classic, high‑visibility tournament that rewards both volume and skill, but the competition can be fierce for newcomers.

Platform B – “Frostbite Gaming”

Frostbite Gaming leans into a crisp blue‑and‑white aesthetic, with icy animations that react to user clicks. The “Icicle Invitational” tournament is highlighted on the homepage and promises a tiered reward system that scales with player performance.

The bonus structure consists of a €150 flat bonus credited automatically when a player registers for the tournament, plus tiered leaderboard rewards: €500 for first place, €300 for second, €200 for third, and €100 split among the next ten finishers. A unique “holiday streak” multiplier adds 5 % extra to any win achieved during consecutive days of play, encouraging daily engagement.

Eligibility demands a €30 deposit and a 5× wagering on the bonus amount. Only games from the “Winter Collection” (slots with RTPs between 96‑98 %) qualify, effectively limiting the field to high‑volatility titles like “Arctic Blast” and “Glacier Gold.”

The tournament runs Nov 28‑Dec 31, with weekly checkpoints that reset leaderboards every Sunday. Customer support is available 24/7 via live chat, and response times during the holiday surge average under two minutes.

Strengths
– Tiered rewards keep mid‑range players motivated.
– Holiday streak multiplier adds a strategic layer for daily logins.
– Responsive support mitigates frustration during high‑traffic periods.

Weaknesses
– Restrictive game list may exclude popular live‑dealer options.
– 5× wagering can extend the break‑even point for low‑deposit users.

  • Bonus amount: €150 flat
  • Deposit requirement: €30
  • Wagering: 5× bonus
  • Game range: Winter‑collection slots only
  • Leaderboard: Weekly reset
  • Payout: Within 48 h

Frostbite’s appeal lies in its structured rewards and fast support, making it a solid choice for players who enjoy a steady climb rather than a sudden sprint.

Platform C – “Jolly Jackpot”

Jolly Jackpot embraces the holiday spirit with a calendar that releases a new promotion each week, from “Candy Cane Cash‑Out” to “Nutcracker Knockout.” The flagship event, “Santa’s Sprint,” launches on December 10 and runs until Christmas Eve, offering a €250 bonus plus a 20 % cashback on any tournament losses.

Players must deposit €25 to qualify, after which the €250 bonus is credited instantly. The cashback is calculated on the net loss of tournament play and is reimbursed as bonus credit usable on any slot or live dealer game. Eligible games span the entire library, including high‑RTP slots like “Merry Madness” (RTP 97.6 %) and live blackjack tables with a house edge of 0.5 %.

Prize distribution is heavily weighted toward the top three: €3,000 for first, €1,500 for second, €750 for third, and a “Santa’s Helper” pool of €1,250 spread across positions four through fifteen. The tournament runs continuously, with leaderboards updating in real time.

Jolly Jackpot shines in transparency; the terms page displays a live countdown of the cashback pool and outlines withdrawal limits—players can cash out up to €1,000 per day, which is generous for a holiday promotion. Mobile compatibility is seamless, with a native app that pushes push notifications whenever a player’s rank changes.

Mini‑comparison chart

Feature Snowflake Spin (A) Frostbite Gaming (B) Jolly Jackpot (C)
Bonus 100 % up to €200 + 50 spins €150 flat €250 + 20 % cashback
Deposit min. €20 €30 €25
Wagering 0× (cashback separate)
Game variety Slots + video poker Winter‑collection slots All slots & live dealers
Prize pool €5,000 €1,100 tiered €5,250 total
Payout speed 24 h 48 h 24 h
Mobile Optimized lobby Standard app Native app with push

Jolly Jackpot’s blend of a sizable bonus, zero wagering on the main amount, and cash‑back on losses creates a low‑risk environment that encourages experimentation across game types.

Platform D – “Mistletoe Bet” – The Dark Horse

Mistletoe Bet is a boutique operator that surged in popularity after launching a series of “secret Santa” promotions aimed at niche communities. Its “North Pole Knockout” tournament is a hidden‑entry event revealed through a social‑media clue on December 12.

The tournament waives the entry fee entirely, offering a €100 prize pool and exclusive holiday merchandise (a branded hoodie and a set of LED dice). A “gift‑wrap wagering” mechanic lets players assign a portion of their stake to a “gift” that, if won, doubles the amount before it is added to the leaderboard score.

Eligibility is simple: any registered user may join, but the platform only accepts e‑wallets (PayPal, Skrill) and a limited number of prepaid cards, which narrows the payment options. The tournament runs for a tight 72‑hour window, creating a burst of activity that can be both exhilarating and stressful.

Quick tip for trial players
– Sign up and test the “gift‑wrap” feature with a €5 wager on the “Frosty Frenzy” slot; the mechanic is best understood after one or two rounds, and the low stake minimizes risk while you gauge the community’s competitive tone.

Pros
– No deposit required to enter the tournament.
– Unique gifting mechanic adds a strategic twist.

Cons
– Limited payment methods may exclude players in certain regions.
– Short tournament window favors seasoned players who can commit full‑time over the three days.

Mistletoe Bet’s novelty makes it a compelling alternative for players looking for something off the beaten path, but the logistical constraints keep it from being a mainstream choice.

Side‑by‑Side Verdict: Which Holiday Tournament Bonus Reigns Supreme?

Below is a consolidated comparison table covering the four platforms discussed.

Platform Bonus Amount Deposit Required Wagering Game Range Prize Pool Payout Speed Best For
Snowflake Spin 100 % up to €200 + 50 spins €20 Slots + low‑vol video poker €5,000 24 h High‑volume slot players
Frostbite Gaming €150 flat €30 Winter‑collection slots €1,100 tiered 48 h Players who like weekly checkpoints
Jolly Jackpot €250 + 20 % cashback €25 All slots & live dealers €5,250 24 h Casual & high‑roller mix, low risk
Mistletoe Bet €100 prize + merch None N/A Slots (selected) €100 + merch 24 h Adventurous players seeking novelty

Scoring rubric (out of 10) based on Section 1 criteria:

  • Bonus size (2 pts)
  • Qualification ease (2 pts)
  • Duration & flexibility (1 pt)
  • Game variety (2 pts)
  • Payout speed (1 pt)
  • Seasonal branding & fun factor (2 pts)
Platform Total
Snowflake Spin 8
Frostbite Gaming 7
Jolly Jackpot 9
Mistletoe Bet 6

Narrative synthesis

  • Best overall value: Jolly Jackpot scores highest thanks to a generous bonus, zero wagering, and a cashback shield that protects against loss.
  • Best for high‑rollers: Snowflake Spin offers the deepest prize pool and the most competitive leaderboard, rewarding big‑bet strategies.
  • Best for casual players: Frostbite Gaming provides tiered rewards and a forgiving weekly reset, allowing occasional participants to stay in the race.
  • Best themed experience: Mistletoe Bet delivers a unique “gift‑wrap” mechanic and exclusive merch, perfect for players who value novelty over pure cash.

Player persona recommendations

  • The Day‑Trader (short sessions, high risk) – choose Snowflake Spin for fast‑paced slot action.
  • The Steady Climber (consistent daily play) – Frostbite’s weekly checkpoints keep motivation high.
  • The Balanced Gambler (mix of slots and live tables) – Jolly Jackpot’s unrestricted game list and cash‑back safety net.
  • The Holiday Enthusiast (loves quirky promos) – Mistletoe Bet’s secret entry and merch rewards.

Conclusion

Choosing the right holiday tournament bonus can turn a festive night into a lucrative win, but the decision hinges on value, fun factor, and how quickly you can cash out. Snowflake Spin dazzles with a massive prize pool, Frostbite rewards steady effort, Jolly Jackpot blends cash‑back protection with broad game access, and Mistletoe Bet offers a one‑of‑a‑kind experience for the adventurous.

All four offers expire before Christmas Day, so act quickly to lock in the bonus that matches your style. Remember to gamble responsibly, set limits, and enjoy the season’s excitement without over‑extending your bankroll. Happy hunting, and may your leaderboard climb be as bright as the holiday lights!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top